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/avi_frames.h"
27 #include "buried/biochip_right.h"
28 #include "buried/buried.h"
29 #include "buried/gameui.h"
30 #include "buried/graphics.h"
31 #include "buried/invdata.h"
32 #include "buried/inventory_window.h"
33 #include "buried/navarrow.h"
34 #include "buried/resources.h"
35 #include "buried/scene_view.h"
36 #include "buried/sound.h"
37 #include "buried/environ/scene_base.h"
38 #include "buried/environ/scene_common.h"
39 
40 #include "graphics/surface.h"
41 
42 namespace Buried {
43 
44 class SwapStillOnFlag : public SceneBase {
45 public:
46 	SwapStillOnFlag(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
47 			int flagOffset = -1, int flagValue = -1);
48 };
49 
SwapStillOnFlag(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation,int flagOffset,int flagValue)50 SwapStillOnFlag::SwapStillOnFlag(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
51 		int flagOffset, int flagValue) :
52 		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
53 	if (((SceneViewWindow *)viewWindow)->getGlobalFlagByte(flagOffset) >= flagValue) {
54 		int curStillFrame = _staticData.navFrameIndex;
55 		_staticData.navFrameIndex = _staticData.miscFrameIndex;
56 		_staticData.miscFrameIndex = curStillFrame;
57 	}
58 }
59 
60 class CapturePaintingTowerFootprint : public SceneBase {
61 public:
62 	CapturePaintingTowerFootprint(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
63 	int locateAttempted(Window *viewWindow, const Common::Point &pointLocation);
64 	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
65 
66 private:
67 	Common::Rect _footprint;
68 };
69 
CapturePaintingTowerFootprint(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation)70 CapturePaintingTowerFootprint::CapturePaintingTowerFootprint(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
71 		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
72 
73 	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsPTElevatorPresent >= 1) {
74 		int curStillFrame = _staticData.navFrameIndex;
75 		_staticData.navFrameIndex = _staticData.miscFrameIndex;
76 		_staticData.miscFrameIndex = curStillFrame;
77 	}
78 
79 	_footprint = Common::Rect(218, 112, 244, 132);
80 }
81 
locateAttempted(Window * viewWindow,const Common::Point & pointLocation)82 int CapturePaintingTowerFootprint::locateAttempted(Window *viewWindow, const Common::Point &pointLocation) {
83 	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().bcLocateEnabled == 1 && _footprint.contains(pointLocation)) {
84 		// Play the capture animation
85 		if (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsPTElevatorPresent >= 1)
86 			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(1);
87 		else
88 			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(0);
89 
90 		// Attempt to add it to the biochip
91 		if (((SceneViewWindow *)viewWindow)->addNumberToGlobalFlagTable(offsetof(GlobalFlags, evcapBaseID), offsetof(GlobalFlags, evcapNumCaptured), 12, DAVINCI_EVIDENCE_FOOTPRINT))
92 			((SceneViewWindow *)viewWindow)->displayLiveText(_vm->getString(IDS_MBT_EVIDENCE_ACQUIRED));
93 		else
94 			((SceneViewWindow *)viewWindow)->displayLiveText(_vm->getString(IDS_MBT_EVIDENCE_ALREADY_ACQUIRED));
95 
96 		// Disable capture
97 		((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->disableEvidenceCapture();
98 		return SC_TRUE;
99 	}
100 
101 	return SC_FALSE;
102 }
103 
specifyCursor(Window * viewWindow,const Common::Point & pointLocation)104 int CapturePaintingTowerFootprint::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
105 	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().bcLocateEnabled == 1) {
106 		if (_footprint.contains(pointLocation)) // Cursor change
107 			return -2;
108 
109 		// Use locate A
110 		return -1;
111 	}
112 
113 	return kCursorArrow;
114 }
115 
116 class PaintingTowerWalkOntoElevator : public SceneBase {
117 public:
118 	PaintingTowerWalkOntoElevator(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
119 	int postExitRoom(Window *viewWindow, const Location &newLocation);
120 };
121 
PaintingTowerWalkOntoElevator(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation)122 PaintingTowerWalkOntoElevator::PaintingTowerWalkOntoElevator(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
123 		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
124 
125 	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsPTElevatorPresent >= 1) {
126 		// If the elevator is present, don't die
127 		int curStillFrame = _staticData.navFrameIndex;
128 		_staticData.navFrameIndex = _staticData.miscFrameIndex;
129 		_staticData.miscFrameIndex = curStillFrame;
130 
131 		_staticData.destForward.destinationScene.timeZone = 5;
132 		_staticData.destForward.destinationScene.environment = 1;
133 		_staticData.destForward.destinationScene.node = 8;
134 		_staticData.destForward.destinationScene.facing = 0;
135 		_staticData.destForward.destinationScene.orientation = 1;
136 		_staticData.destForward.destinationScene.depth = 0;
137 		_staticData.destForward.transitionType = TRANSITION_WALK;
138 		_staticData.destForward.transitionData = 6;
139 		_staticData.destForward.transitionStartFrame = 56;
140 		_staticData.destForward.transitionLength = 16;
141 	}
142 }
143 
postExitRoom(Window * viewWindow,const Location & newLocation)144 int PaintingTowerWalkOntoElevator::postExitRoom(Window *viewWindow, const Location &newLocation) {
145 	if (newLocation.timeZone == _staticData.location.timeZone &&
146 			newLocation.environment == _staticData.location.environment &&
147 			newLocation.node == _staticData.location.node &&
148 			newLocation.facing == _staticData.location.facing &&
149 			newLocation.orientation == _staticData.location.orientation &&
150 			newLocation.depth == _staticData.location.depth) {
151 		// Notify the player of his gruesome death
152 		((SceneViewWindow *)viewWindow)->showDeathScene(30);
153 		return SC_DEATH;
154 	}
155 
156 	// Reset the elevator since we walked down (clone2727 asks if this is possible)
157 	if (newLocation.timeZone == _staticData.location.timeZone && newLocation.environment == 3)
158 		((SceneViewWindow *)viewWindow)->getGlobalFlags().dsPTElevatorPresent = 0;
159 
160 	return SC_TRUE;
161 }
162 
163 class PaintingTowerRetrieveKey : public SceneBase {
164 public:
165 	PaintingTowerRetrieveKey(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
166 	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
167 	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
168 
169 private:
170 	Common::Rect _key;
171 };
172 
PaintingTowerRetrieveKey(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation)173 PaintingTowerRetrieveKey::PaintingTowerRetrieveKey(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
174 		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
175 	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsPTDoorLocked >= 1) {
176 		int curStillFrame = _staticData.navFrameIndex;
177 		_staticData.navFrameIndex = _staticData.miscFrameIndex;
178 		_staticData.miscFrameIndex = curStillFrame;
179 	}
180 
181 	_key = Common::Rect(268, 50, 298, 88);
182 }
183 
mouseUp(Window * viewWindow,const Common::Point & pointLocation)184 int PaintingTowerRetrieveKey::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
185 	if (_key.contains(pointLocation) && ((SceneViewWindow *)viewWindow)->getGlobalFlags().dsPTDoorLocked == 0) {
186 		// Play the unlocking movie
187 		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(2);
188 
189 		// Swap the still frame
190 		int curStillFrame = _staticData.navFrameIndex;
191 		_staticData.navFrameIndex = _staticData.miscFrameIndex;
192 		_staticData.miscFrameIndex = curStillFrame;
193 
194 		// Add the key to the inventory
195 		((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->addItem(kItemBalconyKey);
196 
197 		// Change the locked door flag
198 		((SceneViewWindow *)viewWindow)->getGlobalFlags().dsPTDoorLocked = 1;
199 	}
200 
201 	return SC_TRUE;
202 }
203 
specifyCursor(Window * viewWindow,const Common::Point & pointLocation)204 int PaintingTowerRetrieveKey::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
205 	if (_key.contains(pointLocation) && ((SceneViewWindow *)viewWindow)->getGlobalFlags().dsPTDoorLocked == 0)
206 		return kCursorFinger;
207 
208 	return kCursorArrow;
209 }
210 
211 class PaintingTowerElevatorControls : public SceneBase {
212 public:
213 	PaintingTowerElevatorControls(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
214 	int gdiPaint(Window *viewWindow);
215 	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
216 	int mouseMove(Window *viewWindow, const Common::Point &pointLocation);
217 	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
218 
219 private:
220 	Common::Rect _lockHandle[2];
221 	Common::Rect _directionHandle[2];
222 	Common::Rect _transText[4];
223 	int _textTranslated;
224 };
225 
PaintingTowerElevatorControls(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation)226 PaintingTowerElevatorControls::PaintingTowerElevatorControls(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
227 		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
228 	_lockHandle[0] = Common::Rect(152, 72, 186, 109);
229 	_lockHandle[1] = Common::Rect(152, 108, 186, 146);
230 	_directionHandle[0] = Common::Rect(252, 72, 312, 108);
231 	_directionHandle[1] = Common::Rect(252, 109, 312, 144);
232 	_transText[0] = Common::Rect(134, 50, 202, 70);
233 	_transText[1] = Common::Rect(136, 150, 198, 168);
234 	_transText[2] = Common::Rect(226, 52, 278, 70);
235 	_transText[3] = Common::Rect(224, 148, 288, 166);
236 	_textTranslated = -1;
237 }
238 
gdiPaint(Window * viewWindow)239 int PaintingTowerElevatorControls::gdiPaint(Window *viewWindow) {
240 	if (_textTranslated >= 0 && ((SceneViewWindow *)viewWindow)->getGlobalFlags().bcTranslateEnabled == 1) {
241 		Common::Rect absoluteRect = viewWindow->getAbsoluteRect();
242 		Common::Rect rect(_transText[_textTranslated]);
243 		rect.translate(absoluteRect.left, absoluteRect.top);
244 		_vm->_gfx->getScreen()->frameRect(rect, _vm->_gfx->getColor(255, 0, 0));
245 	}
246 
247 	return SC_REPAINT;
248 }
249 
mouseUp(Window * viewWindow,const Common::Point & pointLocation)250 int PaintingTowerElevatorControls::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
251 	if (_lockHandle[0].contains(pointLocation)) {
252 		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(4);
253 		((SceneViewWindow *)viewWindow)->getGlobalFlags().dsPTElevatorLeverA = 0;
254 		((SceneViewWindow *)viewWindow)->getGlobalFlags().dsPTUseElevatorControls = 1;
255 		return SC_TRUE;
256 	} else if (_lockHandle[1].contains(pointLocation)) {
257 		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(3);
258 		((SceneViewWindow *)viewWindow)->getGlobalFlags().dsPTElevatorLeverA = 1;
259 		((SceneViewWindow *)viewWindow)->getGlobalFlags().dsPTUseElevatorControls = 1;
260 		return SC_TRUE;
261 	} else if (_directionHandle[0].contains(pointLocation)) {
262 		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(6);
263 		((SceneViewWindow *)viewWindow)->getGlobalFlags().dsPTElevatorLeverB = 1;
264 		((SceneViewWindow *)viewWindow)->getGlobalFlags().dsPTUseElevatorControls = 1;
265 		return SC_TRUE;
266 	} else if (_directionHandle[1].contains(pointLocation)) {
267 		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(5);
268 		((SceneViewWindow *)viewWindow)->getGlobalFlags().dsPTElevatorLeverB = 0;
269 		((SceneViewWindow *)viewWindow)->getGlobalFlags().dsPTUseElevatorControls = 1;
270 		return SC_TRUE;
271 	}
272 
273 	return SC_FALSE;
274 }
275 
mouseMove(Window * viewWindow,const Common::Point & pointLocation)276 int PaintingTowerElevatorControls::mouseMove(Window *viewWindow, const Common::Point &pointLocation) {
277 	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().bcTranslateEnabled == 1) {
278 		int newTextTrans = -1;
279 
280 		for (int i = 0; i < 4; i++) {
281 			if (_transText[i].contains(pointLocation)) {
282 				((SceneViewWindow *)viewWindow)->getGlobalFlags().dsPTTransElevatorControls = 1;
283 				newTextTrans = i;
284 
285 				if (newTextTrans != _textTranslated) {
286 					// Load and display the new text
287 					((SceneViewWindow *)viewWindow)->displayTranslationText(_vm->getString(IDDS_ELEVATOR_CONTROLS_TEXT_A + newTextTrans));
288 					_textTranslated = newTextTrans;
289 					viewWindow->invalidateWindow(false);
290 					break;
291 				}
292 			}
293 		}
294 	} else {
295 		if (_textTranslated != -1) {
296 			_textTranslated = -1;
297 			viewWindow->invalidateWindow(false);
298 		}
299 	}
300 
301 	return SC_FALSE;
302 }
303 
specifyCursor(Window * viewWindow,const Common::Point & pointLocation)304 int PaintingTowerElevatorControls::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
305 	if (_lockHandle[0].contains(pointLocation))
306 		return kCursorArrowUp;
307 	else if (_lockHandle[1].contains(pointLocation))
308 		return kCursorArrowDown;
309 	else if (_directionHandle[0].contains(pointLocation))
310 		return kCursorArrowUp;
311 	else if (_directionHandle[1].contains(pointLocation))
312 		return kCursorArrowDown;
313 
314 	return kCursorArrow;
315 }
316 
317 class PaintingTowerElevatorWheel : public SceneBase {
318 public:
319 	PaintingTowerElevatorWheel(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
320 	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
321 	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
322 
323 private:
324 	Common::Rect _wheel;
325 };
326 
PaintingTowerElevatorWheel(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation)327 PaintingTowerElevatorWheel::PaintingTowerElevatorWheel(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
328 		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
329 	_wheel = Common::Rect(94, 0, 380, 189);
330 }
331 
mouseUp(Window * viewWindow,const Common::Point & pointLocation)332 int PaintingTowerElevatorWheel::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
333 	if (_wheel.contains(pointLocation)) {
334 		byte lockStatus = ((SceneViewWindow *)viewWindow)->getGlobalFlags().dsPTElevatorLeverA;
335 		byte direction = ((SceneViewWindow *)viewWindow)->getGlobalFlags().dsPTElevatorLeverB;
336 		byte elevatorPosition = ((SceneViewWindow *)viewWindow)->getGlobalFlags().dsPTElevatorPresent;
337 
338 		if (lockStatus == 1) {
339 			if (direction == 0 && elevatorPosition == 1) {
340 				((SceneViewWindow *)viewWindow)->playSynchronousAnimation(7);
341 				((SceneViewWindow *)viewWindow)->getGlobalFlags().dsPTElevatorPresent = 0;
342 				((SceneViewWindow *)viewWindow)->getGlobalFlags().dsPTRaisedPlatform = 0;
343 				return SC_TRUE;
344 			} else if (direction == 1 && elevatorPosition == 0) {
345 				((SceneViewWindow *)viewWindow)->playSynchronousAnimation(8);
346 				((SceneViewWindow *)viewWindow)->getGlobalFlags().dsPTElevatorPresent = 1;
347 				((SceneViewWindow *)viewWindow)->getGlobalFlags().dsPTRaisedPlatform = 1;
348 				return SC_TRUE;
349 			}
350 		}
351 	}
352 
353 	return SC_FALSE;
354 }
355 
specifyCursor(Window * viewWindow,const Common::Point & pointLocation)356 int PaintingTowerElevatorWheel::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
357 	if (_wheel.contains(pointLocation)) {
358 		byte lockStatus = ((SceneViewWindow *)viewWindow)->getGlobalFlags().dsPTElevatorLeverA;
359 		byte direction = ((SceneViewWindow *)viewWindow)->getGlobalFlags().dsPTElevatorLeverB;
360 		byte elevatorPosition = ((SceneViewWindow *)viewWindow)->getGlobalFlags().dsPTElevatorPresent;
361 
362 		if (lockStatus == 1) {
363 			if (direction == 1 && elevatorPosition == 0)
364 				return kCursorArrowLeft;
365 			else if (direction == 0 && elevatorPosition == 1)
366 				return kCursorArrowRight;
367 		}
368 	}
369 
370 	return kCursorArrow;
371 }
372 
373 class PaintingTowerOutsideDoor : public SceneBase {
374 public:
375 	PaintingTowerOutsideDoor(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
376 	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
377 	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
378 
379 private:
380 	Common::Rect _clickableArea;
381 };
382 
PaintingTowerOutsideDoor(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation)383 PaintingTowerOutsideDoor::PaintingTowerOutsideDoor(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
384 		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
385 	_clickableArea = Common::Rect(0, 0, 236, 189);
386 }
387 
mouseUp(Window * viewWindow,const Common::Point & pointLocation)388 int PaintingTowerOutsideDoor::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
389 	if (_clickableArea.contains(pointLocation)) {
390 		if (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsPTElevatorPresent >= 1) {
391 			DestinationScene destData;
392 			destData.destinationScene.timeZone = 5;
393 			destData.destinationScene.environment = 1;
394 			destData.destinationScene.node = 7;
395 			destData.destinationScene.facing = 3;
396 			destData.destinationScene.orientation = 1;
397 			destData.destinationScene.depth = 2;
398 			destData.transitionType = TRANSITION_WALK;
399 			destData.transitionData = 11;
400 			destData.transitionStartFrame = 28;
401 			destData.transitionLength = 12;
402 			((SceneViewWindow *)viewWindow)->moveToDestination(destData);
403 		} else {
404 			DestinationScene destData;
405 			destData.destinationScene.timeZone = 5;
406 			destData.destinationScene.environment = 1;
407 			destData.destinationScene.node = 7;
408 			destData.destinationScene.facing = 3;
409 			destData.destinationScene.orientation = 1;
410 			destData.destinationScene.depth = 1;
411 			destData.transitionType = TRANSITION_WALK;
412 			destData.transitionData = 11;
413 			destData.transitionStartFrame = 0;
414 			destData.transitionLength = 12;
415 			((SceneViewWindow *)viewWindow)->moveToDestination(destData);
416 		}
417 	}
418 
419 	return SC_FALSE;
420 }
421 
specifyCursor(Window * viewWindow,const Common::Point & pointLocation)422 int PaintingTowerOutsideDoor::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
423 	if (_clickableArea.contains(pointLocation))
424 		return kCursorFinger;
425 
426 	return kCursorArrow;
427 }
428 
429 class PaintingTowerInsideDoor : public SceneBase {
430 public:
431 	PaintingTowerInsideDoor(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
432 	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
433 	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
434 
435 private:
436 	Common::Rect _clickableArea;
437 };
438 
PaintingTowerInsideDoor(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation)439 PaintingTowerInsideDoor::PaintingTowerInsideDoor(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
440 		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
441 	_clickableArea = Common::Rect(290, 0, 432, 189);
442 }
443 
mouseUp(Window * viewWindow,const Common::Point & pointLocation)444 int PaintingTowerInsideDoor::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
445 	if (_clickableArea.contains(pointLocation)) {
446 		if (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsPTDoorLocked >= 1) {
447 			DestinationScene destData;
448 			destData.destinationScene.timeZone = 5;
449 			destData.destinationScene.environment = 1;
450 			destData.destinationScene.node = 2;
451 			destData.destinationScene.facing = 2;
452 			destData.destinationScene.orientation = 1;
453 			destData.destinationScene.depth = 1;
454 			destData.transitionType = TRANSITION_WALK;
455 			destData.transitionData = 11;
456 			destData.transitionStartFrame = 338;
457 			destData.transitionLength = 22;
458 			((SceneViewWindow *)viewWindow)->moveToDestination(destData);
459 		} else {
460 			_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 13), 127, false, true);
461 		}
462 	}
463 
464 	return SC_FALSE;
465 }
466 
specifyCursor(Window * viewWindow,const Common::Point & pointLocation)467 int PaintingTowerInsideDoor::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
468 	if (_clickableArea.contains(pointLocation))
469 		return kCursorFinger;
470 
471 	return kCursorArrow;
472 }
473 
474 class WheelAssemblyItemAcquire : public SceneBase {
475 public:
476 	WheelAssemblyItemAcquire(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
477 			int left = 0, int top = 0, int right = 0, int bottom = 0, int itemID = 0, int clearStillFrame = 0, int itemFlagOffset = 0);
478 	int mouseDown(Window *viewWindow, const Common::Point &pointLocation);
479 	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
480 	int droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
481 	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
482 
483 private:
484 	bool _itemPresent;
485 	Common::Rect _acquireRegion;
486 	int _fullFrameIndex;
487 	int _clearFrameIndex;
488 	int _itemID;
489 	int _itemFlagOffset;
490 	Common::Rect _zoomUpRegion;
491 };
492 
WheelAssemblyItemAcquire(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation,int left,int top,int right,int bottom,int itemID,int clearStillFrame,int itemFlagOffset)493 WheelAssemblyItemAcquire::WheelAssemblyItemAcquire(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
494 		int left, int top, int right, int bottom, int itemID, int clearStillFrame, int itemFlagOffset) :
495 		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
496 	_itemPresent = true;
497 	_itemID = itemID;
498 	_acquireRegion = Common::Rect(left, top, right, bottom);
499 	_fullFrameIndex = _staticData.navFrameIndex;
500 	_clearFrameIndex = clearStillFrame;
501 	_itemFlagOffset = itemFlagOffset;
502 	_zoomUpRegion = Common::Rect(134, 168, 200, 189);
503 
504 	if (((SceneViewWindow *)viewWindow)->getGlobalFlagByte(_itemFlagOffset) != 0) {
505 		_itemPresent = false;
506 		_staticData.navFrameIndex = _clearFrameIndex;
507 	}
508 }
509 
mouseDown(Window * viewWindow,const Common::Point & pointLocation)510 int WheelAssemblyItemAcquire::mouseDown(Window *viewWindow, const Common::Point &pointLocation) {
511 	if (_itemPresent && _acquireRegion.contains(pointLocation)) {
512 		_itemPresent = false;
513 		_staticData.navFrameIndex = _clearFrameIndex;
514 		viewWindow->invalidateWindow(false);
515 
516 		if (_itemFlagOffset >= 0)
517 			((SceneViewWindow *)viewWindow)->setGlobalFlagByte(_itemFlagOffset, 1);
518 
519 		Common::Point ptInventoryWindow = viewWindow->convertPointToGlobal(pointLocation);
520 		ptInventoryWindow = ((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->convertPointToLocal(ptInventoryWindow);
521 		((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->startDraggingNewItem(_itemID, ptInventoryWindow);
522 		return SC_TRUE;
523 	}
524 
525 	return SC_FALSE;
526 }
527 
mouseUp(Window * viewWindow,const Common::Point & pointLocation)528 int WheelAssemblyItemAcquire::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
529 	if (!_itemPresent && _zoomUpRegion.contains(pointLocation)) {
530 		DestinationScene destData;
531 		destData.destinationScene = Location(5, 4, 8, 1, 1, 1);
532 		destData.transitionType = TRANSITION_VIDEO;
533 		destData.transitionData = 15;
534 		destData.transitionStartFrame = -1;
535 		destData.transitionLength = -1;
536 		((SceneViewWindow *)viewWindow)->moveToDestination(destData);
537 	}
538 
539 	return SC_FALSE;
540 }
541 
droppedItem(Window * viewWindow,int itemID,const Common::Point & pointLocation,int itemFlags)542 int WheelAssemblyItemAcquire::droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
543 	if (pointLocation.x == -1 && pointLocation.y == -1)
544 		return SIC_REJECT;
545 
546 	if (_itemID == itemID && !_itemPresent && pointLocation.x >= 0 && pointLocation.y >= 0) {
547 		_itemPresent = true;
548 		_staticData.navFrameIndex = _fullFrameIndex;
549 
550 		if (_itemFlagOffset >= 0)
551 			((SceneViewWindow *)viewWindow)->setGlobalFlagByte(_itemFlagOffset, 0);
552 
553 		viewWindow->invalidateWindow(false);
554 		return SIC_ACCEPT;
555 	}
556 
557 	return SIC_REJECT;
558 }
559 
specifyCursor(Window * viewWindow,const Common::Point & pointLocation)560 int WheelAssemblyItemAcquire::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
561 	if (_itemPresent && _acquireRegion.contains(pointLocation))
562 		return kCursorOpenHand;
563 
564 	if (!_itemPresent && _zoomUpRegion.contains(pointLocation))
565 		return kCursorMagnifyingGlass;
566 
567 	return kCursorArrow;
568 }
569 
570 enum {
571 	DS_SC_DRIVE_ASSEMBLY = 1,
572 	DS_SC_WHEEL_ASSEMBLY = 2,
573 	DS_SC_PEGS = 4,
574 	DS_SC_COMPLETED = 8
575 };
576 
577 class AssembleSiegeCycle : public SceneBase {
578 public:
579 	AssembleSiegeCycle(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
580 	int mouseDown(Window *viewWindow, const Common::Point &pointLocation);
581 	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
582 	int draggingItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
583 	int droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
584 
585 private:
586 	Common::Rect _driveDropRegion;
587 	Common::Rect _wheelDropRegion;
588 	Common::Rect _pegDropRegion;
589 	Common::Rect _completedCycle;
590 
591 	bool resetStillFrame(Window *viewWindow);
592 };
593 
AssembleSiegeCycle(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation)594 AssembleSiegeCycle::AssembleSiegeCycle(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
595 		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
596 	_driveDropRegion = Common::Rect(102, 0, 170, 140);
597 	_wheelDropRegion = Common::Rect(264, 0, 334, 170);
598 	_pegDropRegion = Common::Rect(260, 10, 310, 162);
599 	_completedCycle = Common::Rect(102, 0, 330, 189);
600 
601 	// Determine which still frame to display
602 	resetStillFrame(viewWindow);
603 }
604 
mouseDown(Window * viewWindow,const Common::Point & pointLocation)605 int AssembleSiegeCycle::mouseDown(Window *viewWindow, const Common::Point &pointLocation) {
606 	if (_completedCycle.contains(pointLocation) && ((SceneViewWindow *)viewWindow)->getGlobalFlags().dsWSGrabbedSiegeCycle == 0) {
607 		if (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsWSSiegeCycleStatus & DS_SC_COMPLETED) {
608 			// Reset the present flag and change frame index of background
609 			((SceneViewWindow *)viewWindow)->getGlobalFlags().dsWSGrabbedSiegeCycle = 1;
610 			resetStillFrame(viewWindow);
611 
612 			// Begin dragging
613 			Common::Point ptInventoryWindow = viewWindow->convertPointToGlobal(pointLocation);
614 			ptInventoryWindow = ((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->convertPointToLocal(ptInventoryWindow);
615 			((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->startDraggingNewItem(kItemSiegeCycle, ptInventoryWindow);
616 			return SC_TRUE;
617 		} else {
618 			// Otherwise, check to see if the pegs have been placed and haven't been hammer in
619 			if (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsWSSiegeCycleStatus & DS_SC_PEGS)
620 				((SceneViewWindow *)viewWindow)->displayLiveText(_vm->getString(IDS_DS_WS_UNSTABLE_CYCLE_MESSAGE));
621 		}
622 	}
623 
624 	return SC_FALSE;
625 }
626 
specifyCursor(Window * viewWindow,const Common::Point & pointLocation)627 int AssembleSiegeCycle::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
628 	if (_completedCycle.contains(pointLocation) && ((SceneViewWindow *)viewWindow)->getGlobalFlags().dsWSGrabbedSiegeCycle == 0 && (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsWSSiegeCycleStatus & DS_SC_COMPLETED) != 0)
629 		return kCursorOpenHand;
630 
631 	if (_completedCycle.contains(pointLocation) && ((SceneViewWindow *)viewWindow)->getGlobalFlags().dsWSGrabbedSiegeCycle == 0 && (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsWSSiegeCycleStatus & DS_SC_DRIVE_ASSEMBLY) != 0
632 			&& (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsWSSiegeCycleStatus & DS_SC_WHEEL_ASSEMBLY) != 0 && (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsWSSiegeCycleStatus & DS_SC_PEGS) != 0)
633 		return kCursorOpenHand;
634 
635 	return kCursorArrow;
636 }
637 
draggingItem(Window * viewWindow,int itemID,const Common::Point & pointLocation,int itemFlags)638 int AssembleSiegeCycle::draggingItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
639 	switch (itemID) {
640 	case kItemDriveAssembly:
641 		if (_driveDropRegion.contains(pointLocation) && (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsWSSiegeCycleStatus & DS_SC_DRIVE_ASSEMBLY) == 0)
642 			return 1;
643 		break;
644 	case kItemWheelAssembly:
645 		if (_wheelDropRegion.contains(pointLocation) && (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsWSSiegeCycleStatus & DS_SC_WHEEL_ASSEMBLY) == 0)
646 			return 1;
647 		break;
648 	case kItemWoodenPegs:
649 		if (_pegDropRegion.contains(pointLocation) && (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsWSSiegeCycleStatus & DS_SC_PEGS) == 0 && (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsWSSiegeCycleStatus & DS_SC_WHEEL_ASSEMBLY) != 0 && (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsWSSiegeCycleStatus & DS_SC_DRIVE_ASSEMBLY) != 0)
650 			return 1;
651 		break;
652 	case kItemHammer:
653 		if (_pegDropRegion.contains(pointLocation) && (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsWSSiegeCycleStatus & DS_SC_PEGS) != 0 && (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsWSSiegeCycleStatus & DS_SC_WHEEL_ASSEMBLY) != 0 && (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsWSSiegeCycleStatus & DS_SC_DRIVE_ASSEMBLY) != 0)
654 			return 1;
655 		break;
656 	}
657 
658 	return 0;
659 }
660 
droppedItem(Window * viewWindow,int itemID,const Common::Point & pointLocation,int itemFlags)661 int AssembleSiegeCycle::droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
662 	if (pointLocation.x == -1 && pointLocation.y == -1)
663 		return SIC_REJECT;
664 
665 	switch (itemID) {
666 	case kItemDriveAssembly:
667 		if (_driveDropRegion.contains(pointLocation) && (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsWSSiegeCycleStatus & DS_SC_DRIVE_ASSEMBLY) == 0) {
668 			((SceneViewWindow *)viewWindow)->getGlobalFlags().dsWSSiegeCycleStatus |= DS_SC_DRIVE_ASSEMBLY;
669 			resetStillFrame(viewWindow);
670 			viewWindow->invalidateWindow(false);
671 			return SIC_ACCEPT;
672 		}
673 		break;
674 	case kItemWheelAssembly:
675 		if (_wheelDropRegion.contains(pointLocation) && (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsWSSiegeCycleStatus & DS_SC_WHEEL_ASSEMBLY) == 0) {
676 			((SceneViewWindow *)viewWindow)->getGlobalFlags().dsWSSiegeCycleStatus |= DS_SC_WHEEL_ASSEMBLY;
677 			resetStillFrame(viewWindow);
678 			viewWindow->invalidateWindow(false);
679 			return SIC_ACCEPT;
680 		}
681 		break;
682 	case kItemWoodenPegs:
683 		if (_pegDropRegion.contains(pointLocation) && (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsWSSiegeCycleStatus & DS_SC_PEGS) == 0 && (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsWSSiegeCycleStatus & DS_SC_WHEEL_ASSEMBLY) != 0 && (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsWSSiegeCycleStatus & DS_SC_DRIVE_ASSEMBLY) != 0) {
684 			((SceneViewWindow *)viewWindow)->getGlobalFlags().dsWSSiegeCycleStatus |= DS_SC_PEGS;
685 			resetStillFrame(viewWindow);
686 			viewWindow->invalidateWindow(false);
687 			return SIC_ACCEPT;
688 		}
689 		break;
690 	case kItemHammer:
691 		if (_pegDropRegion.contains(pointLocation) && (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsWSSiegeCycleStatus & DS_SC_PEGS) != 0 && (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsWSSiegeCycleStatus & DS_SC_WHEEL_ASSEMBLY) != 0 && (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsWSSiegeCycleStatus & DS_SC_DRIVE_ASSEMBLY) != 0) {
692 			((SceneViewWindow *)viewWindow)->getGlobalFlags().dsWSSiegeCycleStatus |= DS_SC_COMPLETED;
693 			resetStillFrame(viewWindow);
694 
695 			// Play the hammer movie
696 			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(3);
697 
698 			viewWindow->invalidateWindow(false);
699 		}
700 		break;
701 	}
702 
703 	return SIC_REJECT;
704 }
705 
resetStillFrame(Window * viewWindow)706 bool AssembleSiegeCycle::resetStillFrame(Window *viewWindow) {
707 	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsWSGrabbedSiegeCycle >= 1) {
708 		_staticData.navFrameIndex = 213;
709 	} else {
710 		byte status = ((SceneViewWindow *)viewWindow)->getGlobalFlags().dsWSSiegeCycleStatus;
711 		_staticData.navFrameIndex = 105;
712 
713 		if (status & DS_SC_COMPLETED) {
714 			_staticData.navFrameIndex = 220;
715 		} else {
716 			if ((status & DS_SC_DRIVE_ASSEMBLY) != 0 && (status & DS_SC_WHEEL_ASSEMBLY) != 0 && (status & DS_SC_PEGS) != 0) {
717 				_staticData.navFrameIndex = 215;
718 			} else {
719 				if ((status & DS_SC_DRIVE_ASSEMBLY) != 0 && (status & DS_SC_WHEEL_ASSEMBLY) != 0) {
720 					_staticData.navFrameIndex = 220;
721 				} else {
722 					if ((status & DS_SC_DRIVE_ASSEMBLY) != 0)
723 						_staticData.navFrameIndex = 216;
724 					else if ((status & DS_SC_WHEEL_ASSEMBLY) != 0)
725 						_staticData.navFrameIndex = 218;
726 				}
727 			}
728 		}
729 	}
730 
731 	return true;
732 }
733 
734 class SiegeCycleTopView : public SceneBase {
735 public:
736 	SiegeCycleTopView(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
737 };
738 
SiegeCycleTopView(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation)739 SiegeCycleTopView::SiegeCycleTopView(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
740 		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
741 	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsWSGrabbedSiegeCycle >= 1) {
742 		_staticData.navFrameIndex = 214;
743 	} else {
744 		byte status = ((SceneViewWindow *)viewWindow)->getGlobalFlags().dsWSSiegeCycleStatus;
745 		_staticData.navFrameIndex = 106;
746 
747 		if (status & DS_SC_COMPLETED) {
748 			_staticData.navFrameIndex = 221;
749 		} else {
750 			if ((status & DS_SC_DRIVE_ASSEMBLY) != 0 && (status & DS_SC_WHEEL_ASSEMBLY) != 0 && (status & DS_SC_PEGS) != 0) {
751 				_staticData.navFrameIndex = 221;
752 			} else {
753 				if ((status & DS_SC_DRIVE_ASSEMBLY) != 0 && (status & DS_SC_WHEEL_ASSEMBLY) != 0) {
754 					_staticData.navFrameIndex = 221;
755 				} else {
756 					if ((status & DS_SC_DRIVE_ASSEMBLY) != 0)
757 						_staticData.navFrameIndex = 217;
758 					else if ((status & DS_SC_WHEEL_ASSEMBLY) != 0)
759 						_staticData.navFrameIndex = 219;
760 				}
761 			}
762 		}
763 	}
764 }
765 
766 class UnlockCodexTowerDoor : public SceneBase {
767 public:
768 	UnlockCodexTowerDoor(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
769 	int draggingItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
770 	int droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
771 
772 private:
773 	Common::Rect _dropRect;
774 };
775 
UnlockCodexTowerDoor(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation)776 UnlockCodexTowerDoor::UnlockCodexTowerDoor(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
777 		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
778 	_dropRect = Common::Rect(138, 120, 198, 189);
779 }
780 
draggingItem(Window * viewWindow,int itemID,const Common::Point & pointLocation,int itemFlags)781 int UnlockCodexTowerDoor::draggingItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
782 	if (itemID == kItemBalconyKey && _dropRect.contains(pointLocation))
783 		return 1;
784 
785 	return 0;
786 }
787 
droppedItem(Window * viewWindow,int itemID,const Common::Point & pointLocation,int itemFlags)788 int UnlockCodexTowerDoor::droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
789 	if (pointLocation.x == -1 && pointLocation.y == -1)
790 		return SIC_REJECT;
791 
792 	if (itemID == kItemBalconyKey && _dropRect.contains(pointLocation)) {
793 		// Play the unlocking animation
794 		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(0);
795 
796 		// Set the unlocked door flag
797 		((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCTUnlockedDoor = 1;
798 	}
799 
800 	// Player keeps the item
801 	return SIC_REJECT;
802 }
803 
804 class CodexTowerOutsideDoor : public SceneBase {
805 public:
806 	CodexTowerOutsideDoor(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
807 	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
808 	int draggingItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
809 	int droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
810 	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
811 
812 private:
813 	Common::Rect _dropRect;
814 	Common::Rect _doorRect;
815 };
816 
CodexTowerOutsideDoor(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation)817 CodexTowerOutsideDoor::CodexTowerOutsideDoor(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
818 		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
819 	_dropRect = Common::Rect(130, 0, 200, 189);
820 	_doorRect = Common::Rect(0, 0, 166, 189);
821 }
822 
mouseUp(Window * viewWindow,const Common::Point & pointLocation)823 int CodexTowerOutsideDoor::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
824 	if (_doorRect.contains(pointLocation)) {
825 		if (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCTUnlockedDoor >= 1) {
826 			// Set the opened door flag
827 			((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYNeverOpenedBalconyDoor = 1;
828 
829 			DestinationScene destData;
830 			destData.destinationScene = _staticData.location;
831 			destData.destinationScene.depth = 1;
832 			destData.transitionType = TRANSITION_WALK;
833 			destData.transitionData = 11;
834 			destData.transitionStartFrame = 196;
835 			destData.transitionLength = 20;
836 
837 			// Play a different video otherwise
838 			if (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCTViewedAgent3 == 0) {
839 				destData.transitionType = TRANSITION_VIDEO;
840 				destData.transitionData = 1;
841 				destData.transitionStartFrame = -1;
842 				destData.transitionLength = -1;
843 				((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCTViewedAgent3 = 1;
844 			}
845 
846 			((SceneViewWindow *)viewWindow)->moveToDestination(destData);
847 		} else {
848 			// Door is locked, play the door lock sound and set the tried flag
849 			((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCTTriedLockedDoor = 1;
850 			((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYTriedOpeningDoor = 1;
851 			_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 13));
852 
853 			// Check for spontaneous AI comments
854 			if (((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->isItemInInventory(kItemBioChipAI))
855 				((SceneViewWindow *)viewWindow)->playAIComment(_staticData.location, AI_COMMENT_TYPE_SPONTANEOUS);
856 
857 			((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->sceneChanged();
858 		}
859 	}
860 
861 	return SC_FALSE;
862 }
863 
draggingItem(Window * viewWindow,int itemID,const Common::Point & pointLocation,int itemFlags)864 int CodexTowerOutsideDoor::draggingItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
865 	// Little known fact that the metal bar can be used to unlock the door
866 	if (itemID == kItemMetalBar && _dropRect.contains(pointLocation) && ((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCTUnlockedDoor == 0 && ((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCTViewedAgent3 == 0)
867 		return 1;
868 
869 	return 0;
870 }
871 
droppedItem(Window * viewWindow,int itemID,const Common::Point & pointLocation,int itemFlags)872 int CodexTowerOutsideDoor::droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
873 	if (pointLocation.x == -1 && pointLocation.y == -1)
874 		return SIC_REJECT;
875 
876 	if (itemID == kItemMetalBar && _dropRect.contains(pointLocation) && ((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCTUnlockedDoor == 0 && ((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCTViewedAgent3 == 0) {
877 		// Move to the next scene
878 		DestinationScene destData;
879 		destData.destinationScene = _staticData.location;
880 		destData.destinationScene.depth = 1;
881 		destData.transitionType = TRANSITION_VIDEO;
882 		destData.transitionData = 2;
883 		destData.transitionStartFrame = -1;
884 		destData.transitionLength = -1;
885 		((SceneViewWindow *)viewWindow)->moveToDestination(destData);
886 
887 		// Set the unlocked door flag
888 		((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCTUnlockedDoor = 1;
889 		((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCTViewedAgent3 = 1;
890 	}
891 
892 	// Player keeps the item
893 	return SIC_REJECT;
894 }
895 
specifyCursor(Window * viewWindow,const Common::Point & pointLocation)896 int CodexTowerOutsideDoor::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
897 	if (_doorRect.contains(pointLocation))
898 		return kCursorFinger;
899 
900 	return kCursorArrow;
901 }
902 
903 class CodexTowerLensEvidenceCapture : public SceneBase {
904 public:
905 	CodexTowerLensEvidenceCapture(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
906 	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
907 	int locateAttempted(Window *viewWindow, const Common::Point &pointLocation);
908 	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
909 
910 private:
911 	Common::Rect _evidenceRegion;
912 	bool _captured;
913 	Common::Rect _drum;
914 };
915 
CodexTowerLensEvidenceCapture(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation)916 CodexTowerLensEvidenceCapture::CodexTowerLensEvidenceCapture(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
917 		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
918 	_evidenceRegion = Common::Rect(210, 106, 238, 132);
919 	_drum = Common::Rect(288, 0, 368, 52);
920 	_captured = false;
921 
922 	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCTRetrievedLens >= 1) {
923 		_staticData.navFrameIndex = 172;
924 		_captured = true;
925 	}
926 }
927 
mouseUp(Window * viewWindow,const Common::Point & pointLocation)928 int CodexTowerLensEvidenceCapture::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
929 	if (_drum.contains(pointLocation)) {
930 		// Play the drum animation
931 		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(9);
932 		return SC_TRUE;
933 	}
934 
935 	return SC_FALSE;
936 }
937 
locateAttempted(Window * viewWindow,const Common::Point & pointLocation)938 int CodexTowerLensEvidenceCapture::locateAttempted(Window *viewWindow, const Common::Point &pointLocation) {
939 	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCTRetrievedLens == 0 && ((SceneViewWindow *)viewWindow)->getGlobalFlags().bcLocateEnabled == 1) {
940 		if (_evidenceRegion.contains(pointLocation)) {
941 			BuriedEngine *vm = _vm;
942 
943 			DestinationScene destData;
944 			destData.destinationScene = _staticData.location;
945 			destData.destinationScene.depth = 1;
946 			destData.transitionType = TRANSITION_VIDEO;
947 			destData.transitionData = 3;
948 			destData.transitionStartFrame = -1;
949 			destData.transitionLength = -1;
950 			((SceneViewWindow *)viewWindow)->moveToDestination(destData);
951 
952 			// Add it to the list
953 			if (((SceneViewWindow *)viewWindow)->addNumberToGlobalFlagTable(offsetof(GlobalFlags, evcapBaseID), offsetof(GlobalFlags, evcapNumCaptured), 12, DAVINCI_EVIDENCE_LENS_FILTER))
954 				((SceneViewWindow *)viewWindow)->displayLiveText(vm->getString(IDS_MBT_EVIDENCE_ACQUIRED));
955 			else
956 				((SceneViewWindow *)viewWindow)->displayLiveText(vm->getString(IDS_MBT_EVIDENCE_ALREADY_ACQUIRED));
957 
958 			// Turn off capture
959 			((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->disableEvidenceCapture();
960 		}
961 
962 		return SC_TRUE;
963 	}
964 
965 	return SC_FALSE;
966 }
967 
specifyCursor(Window * viewWindow,const Common::Point & pointLocation)968 int CodexTowerLensEvidenceCapture::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
969 	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCTRetrievedLens == 0 && ((SceneViewWindow *)viewWindow)->getGlobalFlags().bcLocateEnabled == 1) {
970 		if (_evidenceRegion.contains(pointLocation))
971 			return -2;
972 
973 		return -1;
974 	}
975 
976 	if (_drum.contains(pointLocation))
977 		return kCursorFinger;
978 
979 	return kCursorArrow;
980 }
981 
982 class CodexTowerGrabLens : public GenericItemAcquire {
983 public:
984 	CodexTowerGrabLens(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
985 	int droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
986 };
987 
CodexTowerGrabLens(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation)988 CodexTowerGrabLens::CodexTowerGrabLens(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
989 		GenericItemAcquire(vm, viewWindow, sceneStaticData, priorLocation, 200, 78, 262, 123, kItemLensFilter, 169, offsetof(GlobalFlags, dsCTRetrievedLens)) {
990 }
991 
droppedItem(Window * viewWindow,int itemID,const Common::Point & pointLocation,int itemFlags)992 int CodexTowerGrabLens::droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
993 	if (pointLocation.x == -1 && pointLocation.y == -1 && itemID == _itemID && !_itemPresent) {
994 		if (((SceneViewWindow *)viewWindow)->getGlobalFlags().generalWalkthroughMode == 1) {
995 			((SceneViewWindow *)viewWindow)->getGlobalFlags().lensFilterActivated = 1;
996 			((SceneViewWindow *)viewWindow)->displayLiveText(_vm->getString(IDS_LENS_FILTER_ACTIVATED));
997 		}
998 
999 		// Move back
1000 		DestinationScene destData;
1001 		destData.destinationScene = _staticData.location;
1002 		destData.destinationScene.depth = 0;
1003 		destData.transitionType = TRANSITION_VIDEO;
1004 		destData.transitionData = 4;
1005 		destData.transitionStartFrame = -1;
1006 		destData.transitionLength = -1;
1007 		((SceneViewWindow *)viewWindow)->moveToDestination(destData);
1008 		return 0;
1009 	}
1010 
1011 	return GenericItemAcquire::droppedItem(viewWindow, itemID, pointLocation, itemFlags);
1012 }
1013 
1014 class CodexCabinetOpenDoor : public SceneBase {
1015 public:
1016 	CodexCabinetOpenDoor(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
1017 	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
1018 	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
1019 
1020 private:
1021 	Common::Rect _openDoor;
1022 };
1023 
CodexCabinetOpenDoor(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation)1024 CodexCabinetOpenDoor::CodexCabinetOpenDoor(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
1025 		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
1026 
1027 	_openDoor = Common::Rect(80, 0, 302, 189);
1028 }
1029 
mouseUp(Window * viewWindow,const Common::Point & pointLocation)1030 int CodexCabinetOpenDoor::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
1031 	if (_openDoor.contains(pointLocation)) {
1032 		DestinationScene destData;
1033 		destData.destinationScene = _staticData.location;
1034 		destData.destinationScene.depth = 1;
1035 		destData.transitionType = TRANSITION_VIDEO;
1036 		destData.transitionStartFrame = -1;
1037 		destData.transitionLength = -1;
1038 
1039 		if (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCTTakenHeart == 0)
1040 			destData.transitionData = 5;
1041 		else
1042 			destData.transitionData = 6;
1043 
1044 		((SceneViewWindow *)viewWindow)->moveToDestination(destData);
1045 		return SC_TRUE;
1046 	}
1047 
1048 	return SC_FALSE;
1049 }
1050 
specifyCursor(Window * viewWindow,const Common::Point & pointLocation)1051 int CodexCabinetOpenDoor::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
1052 	if (_openDoor.contains(pointLocation))
1053 		return kCursorFinger;
1054 
1055 	return kCursorArrow;
1056 }
1057 
1058 class CodexTowerGrabHeart : public SceneBase {
1059 public:
1060 	CodexTowerGrabHeart(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
1061 	int postExitRoom(Window *viewWindow, const Location &newLocation);
1062 	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
1063 	int mouseDown(Window *viewWindow, const Common::Point &pointLocation);
1064 	int droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
1065 	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
1066 
1067 private:
1068 	bool _itemPresent;
1069 	Common::Rect _acquireRegion;
1070 	int _fullFrameIndex;
1071 	int _clearFrameIndex;
1072 	int _itemID;
1073 	int _itemFlagOffset;
1074 	Common::Rect _eyeRegion;
1075 };
1076 
CodexTowerGrabHeart(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation)1077 CodexTowerGrabHeart::CodexTowerGrabHeart(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
1078 		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
1079 	_itemPresent = true;
1080 	_itemID = kItemPreservedHeart;
1081 	_acquireRegion = Common::Rect(214, 118, 270, 189);
1082 	_fullFrameIndex = _staticData.navFrameIndex;
1083 	_clearFrameIndex = 162;
1084 	_itemFlagOffset = offsetof(GlobalFlags, dsCTTakenHeart);
1085 	_eyeRegion = Common::Rect(248, 116, 286, 180);
1086 
1087 	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCTTakenHeart != 0) {
1088 		_itemPresent = false;
1089 		_staticData.navFrameIndex = _clearFrameIndex;
1090 	}
1091 }
1092 
postExitRoom(Window * viewWindow,const Location & newLocation)1093 int CodexTowerGrabHeart::postExitRoom(Window *viewWindow, const Location &newLocation) {
1094 	if (_staticData.location.depth != newLocation.depth && _staticData.location.timeZone == newLocation.timeZone)
1095 		_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 14));
1096 
1097 	return SC_TRUE;
1098 }
1099 
mouseDown(Window * viewWindow,const Common::Point & pointLocation)1100 int CodexTowerGrabHeart::mouseDown(Window *viewWindow, const Common::Point &pointLocation) {
1101 	if (_acquireRegion.contains(pointLocation) && _itemPresent) {
1102 		_itemPresent = false;
1103 		_staticData.navFrameIndex = _clearFrameIndex;
1104 
1105 		if (_itemFlagOffset >= 0)
1106 			((SceneViewWindow *)viewWindow)->setGlobalFlagByte(_itemFlagOffset, 1);
1107 
1108 		// Call inventory drag start function
1109 		Common::Point ptInventoryWindow = viewWindow->convertPointToGlobal(pointLocation);
1110 		ptInventoryWindow = ((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->convertPointToLocal(ptInventoryWindow);
1111 		((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->startDraggingNewItem(_itemID, ptInventoryWindow);
1112 
1113 		// Update the biochips
1114 		((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->sceneChanged();
1115 
1116 		return SC_TRUE;
1117 	}
1118 
1119 	return SC_FALSE;
1120 }
1121 
mouseUp(Window * viewWindow,const Common::Point & pointLocation)1122 int CodexTowerGrabHeart::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
1123 	if (_eyeRegion.contains(pointLocation) && !_itemPresent) {
1124 		// Play the spinning eyes animation
1125 		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(7);
1126 		return SC_TRUE;
1127 	}
1128 
1129 	return SC_FALSE;
1130 }
1131 
droppedItem(Window * viewWindow,int itemID,const Common::Point & pointLocation,int itemFlags)1132 int CodexTowerGrabHeart::droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
1133 	if (pointLocation.x == -1 && pointLocation.y == -1)
1134 		return SIC_REJECT;
1135 
1136 	if (itemID == _itemID && !_itemPresent) {
1137 		// Redraw the background
1138 		_itemPresent = true;
1139 		_staticData.navFrameIndex = _fullFrameIndex;
1140 
1141 		if (_itemFlagOffset >= 0)
1142 			((SceneViewWindow *)viewWindow)->setGlobalFlagByte(_itemFlagOffset, 0);
1143 
1144 		viewWindow->invalidateWindow();
1145 
1146 		// Update the biochips
1147 		((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->sceneChanged();
1148 
1149 		return SIC_ACCEPT;
1150 	}
1151 
1152 	return SIC_REJECT;
1153 }
1154 
specifyCursor(Window * viewWindow,const Common::Point & pointLocation)1155 int CodexTowerGrabHeart::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
1156 	if (_acquireRegion.contains(pointLocation) && _itemPresent)
1157 		return kCursorOpenHand;
1158 
1159 	if (_eyeRegion.contains(pointLocation) && !_itemPresent)
1160 		return kCursorFinger;
1161 
1162 	return kCursorArrow;
1163 }
1164 
1165 class ZoomInOnCodexes : public SceneBase {
1166 public:
1167 	ZoomInOnCodexes(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
1168 	int postEnterRoom(Window *viewWindow, const Location &priorLocation);
1169 	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
1170 	int locateAttempted(Window *viewWindow, const Common::Point &pointLocation);
1171 	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
1172 
1173 private:
1174 	Common::Rect _leftCodex;
1175 	Common::Rect _middleCodex;
1176 	Common::Rect _rightCodex;
1177 };
1178 
ZoomInOnCodexes(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation)1179 ZoomInOnCodexes::ZoomInOnCodexes(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
1180 		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
1181 	_leftCodex = Common::Rect(82, 32, 212, 92);
1182 	_middleCodex = Common::Rect(218, 58, 284, 128);
1183 	_rightCodex = Common::Rect(285, 35, 345, 91);
1184 }
1185 
postEnterRoom(Window * viewWindow,const Location & priorLocation)1186 int ZoomInOnCodexes::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
1187 	// If we have not yet captured the codex evidence, display a message
1188 	if (!((SceneViewWindow *)viewWindow)->isNumberInGlobalFlagTable(offsetof(GlobalFlags, evcapBaseID), offsetof(GlobalFlags, evcapNumCaptured), DAVINCI_EVIDENCE_CODEX))
1189 		((SceneViewWindow *)viewWindow)->displayLiveText(_vm->getString(IDS_MBT_EVIDENCE_PRESENT));
1190 
1191 	((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYFoundCodexes = 1;
1192 	return SC_TRUE;
1193 }
1194 
mouseUp(Window * viewWindow,const Common::Point & pointLocation)1195 int ZoomInOnCodexes::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
1196 	if (_leftCodex.contains(pointLocation)) {
1197 		DestinationScene destData;
1198 		destData.destinationScene = _staticData.location;
1199 		destData.destinationScene.depth = 1;
1200 		destData.transitionType = TRANSITION_VIDEO;
1201 		destData.transitionData = 17;
1202 		destData.transitionStartFrame = -1;
1203 		destData.transitionLength = -1;
1204 		((SceneViewWindow *)viewWindow)->moveToDestination(destData);
1205 		return SC_TRUE;
1206 	} else if (_middleCodex.contains(pointLocation)) {
1207 		DestinationScene destData;
1208 		destData.destinationScene = _staticData.location;
1209 		destData.destinationScene.depth = 2;
1210 		destData.transitionType = TRANSITION_VIDEO;
1211 		destData.transitionData = 21;
1212 		destData.transitionStartFrame = -1;
1213 		destData.transitionLength = -1;
1214 		((SceneViewWindow *)viewWindow)->moveToDestination(destData);
1215 		return SC_TRUE;
1216 	} else if (_rightCodex.contains(pointLocation)) {
1217 		DestinationScene destData;
1218 		destData.destinationScene = _staticData.location;
1219 		destData.destinationScene.depth = 3;
1220 		destData.transitionType = TRANSITION_VIDEO;
1221 		destData.transitionData = 19;
1222 		destData.transitionStartFrame = -1;
1223 		destData.transitionLength = -1;
1224 		((SceneViewWindow *)viewWindow)->moveToDestination(destData);
1225 		return SC_TRUE;
1226 	}
1227 
1228 	return SC_FALSE;
1229 }
1230 
locateAttempted(Window * viewWindow,const Common::Point & pointLocation)1231 int ZoomInOnCodexes::locateAttempted(Window *viewWindow, const Common::Point &pointLocation) {
1232 	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().bcLocateEnabled == 1 && _middleCodex.contains(pointLocation) && !((SceneViewWindow *)viewWindow)->isNumberInGlobalFlagTable(offsetof(GlobalFlags, evcapBaseID), offsetof(GlobalFlags, evcapNumCaptured), DAVINCI_EVIDENCE_CODEX)) {
1233 		((SceneViewWindow *)viewWindow)->displayLiveText(_vm->getString(IDS_MBT_EVIDENCE_MUST_BE_REVEALED));
1234 		((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->disableEvidenceCapture();
1235 		return SC_TRUE;
1236 	}
1237 
1238 	return SC_FALSE;
1239 }
1240 
specifyCursor(Window * viewWindow,const Common::Point & pointLocation)1241 int ZoomInOnCodexes::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
1242 	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().bcLocateEnabled == 1) {
1243 		if (_middleCodex.contains(pointLocation))
1244 			return -2;
1245 
1246 		return -1;
1247 	}
1248 
1249 	if (_leftCodex.contains(pointLocation) || _middleCodex.contains(pointLocation) || _rightCodex.contains(pointLocation))
1250 		return kCursorMagnifyingGlass;
1251 
1252 	return kCursorArrow;
1253 }
1254 
1255 class BrowseCodex : public SceneBase {
1256 public:
1257 	BrowseCodex(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
1258 			int timeZone = -1, int environment = -1, int node = -1, int facing = -1, int orientation = -1,
1259 			int depth = -1, int transitionType = -1, int transitionData = -1, int transitionStartFrame = -1, int transitionLength = -1,
1260 			int startFrame = -1, int frameCount = -1, int lensStartFrame = -1);
1261 	int gdiPaint(Window *viewWindow);
1262 	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
1263 	int mouseMove(Window *viewWindow, const Common::Point &pointLocation);
1264 	int timerCallback(Window *viewWindow);
1265 	int locateAttempted(Window *viewWindow, const Common::Point &pointLocation);
1266 	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
1267 
1268 private:
1269 	int _curPage;
1270 	Common::Rect _top, _bottom, _left, _right, _putDown;
1271 	DestinationScene _putDownDestination;
1272 	int _startFrame;
1273 	int _frameCount;
1274 	int _lensStartFrame;
1275 	bool _translateAttempted;
1276 	bool _lensActivated;
1277 };
1278 
BrowseCodex(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation,int timeZone,int environment,int node,int facing,int orientation,int depth,int transitionType,int transitionData,int transitionStartFrame,int transitionLength,int startFrame,int frameCount,int lensStartFrame)1279 BrowseCodex::BrowseCodex(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
1280 		int timeZone, int environment, int node, int facing, int orientation,
1281 		int depth, int transitionType, int transitionData, int transitionStartFrame, int transitionLength,
1282 		int startFrame, int frameCount, int lensStartFrame) :
1283 		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
1284 	_curPage = 0;
1285 	_lensActivated = false;
1286 	_translateAttempted = false;
1287 	_startFrame = startFrame;
1288 	_frameCount = frameCount;
1289 	_lensStartFrame = lensStartFrame;
1290 	_putDownDestination.destinationScene = Location(timeZone, environment, node, facing, orientation, depth);
1291 	_putDownDestination.transitionType = transitionType;
1292 	_putDownDestination.transitionData = transitionData;
1293 	_putDownDestination.transitionStartFrame = transitionStartFrame;
1294 	_putDownDestination.transitionLength = transitionLength;
1295 
1296 	_staticData.navFrameIndex = startFrame;
1297 
1298 	_top = Common::Rect(150, 0, 282, 70);
1299 	_bottom = Common::Rect(150, 119, 282, 189);
1300 	_left = Common::Rect(0, 0, 150, 189);
1301 	_right = Common::Rect(282, 0, 432, 189);
1302 	_putDown = Common::Rect(150, 70, 282, 119);
1303 }
1304 
gdiPaint(Window * viewWindow)1305 int BrowseCodex::gdiPaint(Window *viewWindow) {
1306 	if (_translateAttempted) {
1307 		Common::Rect absoluteRect = viewWindow->getAbsoluteRect();
1308 		Common::Rect rect(5, 5, 427, 184);
1309 		rect.translate(absoluteRect.left, absoluteRect.top);
1310 		_vm->_gfx->getScreen()->frameRect(rect, _vm->_gfx->getColor(255, 0, 0));
1311 	}
1312 
1313 	return SC_REPAINT;
1314 }
1315 
mouseUp(Window * viewWindow,const Common::Point & pointLocation)1316 int BrowseCodex::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
1317 	int startingPage = _startFrame;
1318 	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().lensFilterActivated == 1 && _lensStartFrame >= 0)
1319 		startingPage = _lensStartFrame;
1320 
1321 	if (_top.contains(pointLocation) && (_curPage % 2) != 0) {
1322 		_curPage--;
1323 		_staticData.navFrameIndex = startingPage + _curPage;
1324 
1325 		Graphics::Surface *newBackground = ((SceneViewWindow *)viewWindow)->getStillFrameCopy(_staticData.navFrameIndex);
1326 		((SceneViewWindow *)viewWindow)->pushNewTransition(newBackground, 0, _vm->_gfx->computeVPushOffset(_vm->getTransitionSpeed()), 0);
1327 		newBackground->free();
1328 		delete newBackground;
1329 		viewWindow->invalidateWindow(false);
1330 		return SC_TRUE;
1331 	} else if (_bottom.contains(pointLocation) && (_curPage % 2) == 0) {
1332 		_curPage++;
1333 		_staticData.navFrameIndex = startingPage + _curPage;
1334 
1335 		Graphics::Surface *newBackground = ((SceneViewWindow *)viewWindow)->getStillFrameCopy(_staticData.navFrameIndex);
1336 		((SceneViewWindow *)viewWindow)->pushNewTransition(newBackground, 3, _vm->_gfx->computeVPushOffset(_vm->getTransitionSpeed()), 0);
1337 		newBackground->free();
1338 		delete newBackground;
1339 		viewWindow->invalidateWindow(false);
1340 		return SC_TRUE;
1341 	} else if (_left.contains(pointLocation) && _curPage >= 2) {
1342 		_curPage -= 2;
1343 		_staticData.navFrameIndex = startingPage + _curPage;
1344 
1345 		Graphics::Surface *newBackground = ((SceneViewWindow *)viewWindow)->getStillFrameCopy(_staticData.navFrameIndex);
1346 		((SceneViewWindow *)viewWindow)->slideInTransition(newBackground, 1, _vm->_gfx->computeHPushOffset(_vm->getTransitionSpeed()), 0);
1347 		newBackground->free();
1348 		delete newBackground;
1349 		viewWindow->invalidateWindow(false);
1350 		return SC_TRUE;
1351 	} else if (_right.contains(pointLocation) && _curPage < _frameCount - 2) {
1352 		_curPage += 2;
1353 		_staticData.navFrameIndex = startingPage + _curPage;
1354 
1355 		if (_staticData.location.timeZone == 5 && _staticData.location.environment == 2 &&
1356 				_staticData.location.node == 5 && _staticData.location.facing == 2 &&
1357 				_staticData.location.orientation == 5 && _staticData.location.depth == 2 &&
1358 				_curPage == 2) {
1359 			((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCTCodexAtlanticusPage2 = 1;
1360 		} else {
1361 			((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCTCodexAtlanticusPage2 = 0;
1362 		}
1363 
1364 		Graphics::Surface *newBackground = ((SceneViewWindow *)viewWindow)->getStillFrameCopy(_staticData.navFrameIndex);
1365 		((SceneViewWindow *)viewWindow)->slideOutTransition(newBackground, 1, _vm->_gfx->computeHPushOffset(_vm->getTransitionSpeed()), 0);
1366 		newBackground->free();
1367 		delete newBackground;
1368 		viewWindow->invalidateWindow(false);
1369 		return SC_TRUE;
1370 	} else if (_putDown.contains(pointLocation) && _putDownDestination.destinationScene.timeZone >= 0) {
1371 		((SceneViewWindow *)viewWindow)->moveToDestination(_putDownDestination);
1372 		return SC_TRUE;
1373 	}
1374 
1375 	return SC_FALSE;
1376 }
1377 
mouseMove(Window * viewWindow,const Common::Point & pointLocation)1378 int BrowseCodex::mouseMove(Window *viewWindow, const Common::Point &pointLocation) {
1379 	Common::Rect transRegion(25, 25, 382, 139);
1380 
1381 	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().bcTranslateEnabled == 1) {
1382 		((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYTranslatedCodex = 1;
1383 
1384 		if (transRegion.contains(pointLocation)) {
1385 			if (!_translateAttempted) {
1386 				_translateAttempted = true;
1387 				viewWindow->invalidateWindow(false);
1388 				((SceneViewWindow *)viewWindow)->displayTranslationText("");
1389 			}
1390 		} else {
1391 			if (_translateAttempted) {
1392 				_translateAttempted = false;
1393 				viewWindow->invalidateWindow(false);
1394 				((SceneViewWindow *)viewWindow)->displayTranslationText("");
1395 			}
1396 		}
1397 	} else {
1398 		if (_translateAttempted) {
1399 			_translateAttempted = false;
1400 			viewWindow->invalidateWindow(false);
1401 			((SceneViewWindow *)viewWindow)->displayTranslationText("");
1402 		}
1403 	}
1404 
1405 	return SC_FALSE;
1406 }
1407 
timerCallback(Window * viewWindow)1408 int BrowseCodex::timerCallback(Window *viewWindow) {
1409 	if (_translateAttempted && ((SceneViewWindow *)viewWindow)->getGlobalFlags().bcTranslateEnabled == 0) {
1410 		_translateAttempted = false;
1411 		viewWindow->invalidateWindow(false);
1412 	}
1413 
1414 	// Are we looking at the proper codex?
1415 	if (_lensStartFrame >= 0) {
1416 		if (((SceneViewWindow *)viewWindow)->getGlobalFlags().lensFilterActivated == 1) {
1417 			if (!_lensActivated) {
1418 				_lensActivated = true;
1419 				_staticData.navFrameIndex = _lensStartFrame;
1420 				((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCTCodexFormulaeFound = 1;
1421 				_curPage = 0;
1422 				viewWindow->invalidateWindow(false);
1423 
1424 				// Play the capture animation
1425 				((SceneViewWindow *)viewWindow)->playSynchronousAnimation(24);
1426 
1427 				// Attempt to add it to your evidence biochip
1428 				if (((SceneViewWindow *)viewWindow)->addNumberToGlobalFlagTable(offsetof(GlobalFlags, evcapBaseID), offsetof(GlobalFlags, evcapNumCaptured), 12, DAVINCI_EVIDENCE_CODEX))
1429 					((SceneViewWindow *)viewWindow)->displayLiveText(_vm->getString(IDS_MBT_EVIDENCE_RIPPLE_DOCUMENTED));
1430 				else
1431 					((SceneViewWindow *)viewWindow)->displayLiveText(_vm->getString(IDS_MBT_EVIDENCE_ALREADY_ACQUIRED));
1432 
1433 				// Set the scoring flag
1434 				((SceneViewWindow *)viewWindow)->getGlobalFlags().scoreLoggedCodexEvidence = 1;
1435 			}
1436 		} else {
1437 			if (_lensActivated) {
1438 				_lensActivated = false;
1439 				_staticData.navFrameIndex = _startFrame + _curPage;
1440 				viewWindow->invalidateWindow(false);
1441 			}
1442 		}
1443 	}
1444 
1445 	return SC_TRUE;
1446 }
1447 
locateAttempted(Window * viewWindow,const Common::Point & pointLocation)1448 int BrowseCodex::locateAttempted(Window *viewWindow, const Common::Point &pointLocation) {
1449 	if (_lensStartFrame >= 0 && !((SceneViewWindow *)viewWindow)->isNumberInGlobalFlagTable(offsetof(GlobalFlags, evcapBaseID), offsetof(GlobalFlags, evcapNumCaptured), DAVINCI_EVIDENCE_CODEX)) {
1450 		((SceneViewWindow *)viewWindow)->displayLiveText(_vm->getString(IDS_MBT_EVIDENCE_MUST_BE_REVEALED));
1451 		((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->disableEvidenceCapture();
1452 		return SC_TRUE;
1453 	}
1454 
1455 	return SC_FALSE;
1456 }
1457 
specifyCursor(Window * viewWindow,const Common::Point & pointLocation)1458 int BrowseCodex::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
1459 	if (_lensStartFrame >= 0 && ((SceneViewWindow *)viewWindow)->getGlobalFlags().bcLocateEnabled == 1 && !((SceneViewWindow *)viewWindow)->isNumberInGlobalFlagTable(offsetof(GlobalFlags, evcapBaseID), offsetof(GlobalFlags, evcapNumCaptured), DAVINCI_EVIDENCE_CODEX))
1460 		return -2;
1461 
1462 	if (_top.contains(pointLocation) && (_curPage % 2) != 0)
1463 		return kCursorMoveUp;
1464 
1465 	if (_left.contains(pointLocation) && _curPage >= 2)
1466 		return kCursorPrevPage;
1467 
1468 	if (_right.contains(pointLocation) && _curPage < _frameCount - 2)
1469 		return kCursorNextPage;
1470 
1471 	if (_bottom.contains(pointLocation) && (_curPage % 2) == 0)
1472 		return kCursorMoveDown;
1473 
1474 	if (_putDown.contains(pointLocation) && _putDownDestination.destinationScene.timeZone >= 0)
1475 		return kCursorPutDown;
1476 
1477 	return kCursorArrow;
1478 }
1479 
1480 class ClickBirdDevice : public SceneBase {
1481 public:
1482 	ClickBirdDevice(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
1483 	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
1484 	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
1485 
1486 private:
1487 	Common::Rect _birdToy;
1488 };
1489 
ClickBirdDevice(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation)1490 ClickBirdDevice::ClickBirdDevice(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
1491 		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
1492 	_birdToy = Common::Rect(90, 52, 198, 98);
1493 }
1494 
mouseUp(Window * viewWindow,const Common::Point & pointLocation)1495 int ClickBirdDevice::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
1496 	if (_birdToy.contains(pointLocation)) {
1497 		// Play the animation
1498 		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(10);
1499 	} else {
1500 		// Return back
1501 		DestinationScene destData;
1502 		destData.destinationScene = _staticData.location;
1503 		destData.destinationScene.depth = 0;
1504 		destData.transitionType = TRANSITION_VIDEO;
1505 		destData.transitionData = 16;
1506 		destData.transitionStartFrame = -1;
1507 		destData.transitionLength = -1;
1508 		((SceneViewWindow *)viewWindow)->moveToDestination(destData);
1509 	}
1510 
1511 	return SC_TRUE;
1512 }
1513 
specifyCursor(Window * viewWindow,const Common::Point & pointLocation)1514 int ClickBirdDevice::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
1515 	if (_birdToy.contains(pointLocation))
1516 		return kCursorFinger;
1517 
1518 	return kCursorPutDown;
1519 }
1520 
1521 class CourtyardCannon : public SceneBase {
1522 public:
1523 	CourtyardCannon(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
1524 	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
1525 	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
1526 
1527 private:
1528 	Common::Rect _cannon;
1529 };
1530 
CourtyardCannon(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation)1531 CourtyardCannon::CourtyardCannon(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
1532 		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
1533 	_cannon = Common::Rect(160, 10, 280, 140);
1534 }
1535 
mouseUp(Window * viewWindow,const Common::Point & pointLocation)1536 int CourtyardCannon::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
1537 	if (_cannon.contains(pointLocation))
1538 		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(0);
1539 
1540 	return SC_TRUE;
1541 }
1542 
specifyCursor(Window * viewWindow,const Common::Point & pointLocation)1543 int CourtyardCannon::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
1544 	if (_cannon.contains(pointLocation))
1545 		return kCursorFinger;
1546 
1547 	return kCursorArrow;
1548 }
1549 
1550 class CourtyardGunDeath : public SceneBase {
1551 public:
1552 	CourtyardGunDeath(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
1553 	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
1554 	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
1555 
1556 private:
1557 	Common::Rect _gun;
1558 };
1559 
CourtyardGunDeath(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation)1560 CourtyardGunDeath::CourtyardGunDeath(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
1561 		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
1562 	_gun = Common::Rect(140, 68, 294, 189);
1563 }
1564 
mouseUp(Window * viewWindow,const Common::Point & pointLocation)1565 int CourtyardGunDeath::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
1566 	if (_gun.contains(pointLocation)) {
1567 		// Play the animation
1568 		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(4);
1569 
1570 		// Kill the player
1571 		((SceneViewWindow *)viewWindow)->showDeathScene(31);
1572 	}
1573 
1574 	// Success!
1575 	return SC_TRUE;
1576 }
1577 
specifyCursor(Window * viewWindow,const Common::Point & pointLocation)1578 int CourtyardGunDeath::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
1579 	if (_gun.contains(pointLocation))
1580 		return kCursorFinger;
1581 
1582 	return kCursorArrow;
1583 }
1584 
1585 class ChangeBallistaDepth : public SceneBase {
1586 public:
1587 	ChangeBallistaDepth(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
1588 };
1589 
ChangeBallistaDepth(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation)1590 ChangeBallistaDepth::ChangeBallistaDepth(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
1591 		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
1592 	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYBallistaStatus != _staticData.location.depth) {
1593 		Location newLocation = _staticData.location;
1594 		newLocation.depth = ((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYBallistaStatus;
1595 		((SceneViewWindow *)viewWindow)->getSceneStaticData(newLocation, _staticData);
1596 	}
1597 }
1598 
1599 class SpinBallista : public SceneBase {
1600 public:
1601 	SpinBallista(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
1602 	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
1603 	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
1604 
1605 private:
1606 	Common::Rect _handle;
1607 };
1608 
SpinBallista(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation)1609 SpinBallista::SpinBallista(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
1610 		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
1611 	_handle = Common::Rect(126, 106, 190, 162);
1612 }
1613 
mouseUp(Window * viewWindow,const Common::Point & pointLocation)1614 int SpinBallista::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
1615 	if (_handle.contains(pointLocation) && ((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYBallistaStatus < 2) {
1616 		DestinationScene destData;
1617 		destData.destinationScene = _staticData.location;
1618 		destData.transitionType = TRANSITION_VIDEO;
1619 		destData.transitionStartFrame = -1;
1620 		destData.transitionLength = -1;
1621 
1622 		if (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYBallistaStatus == 1) {
1623 			destData.transitionData = 7;
1624 			destData.destinationScene.depth = 0;
1625 			((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYBallistaStatus = 0;
1626 		} else {
1627 			destData.transitionData = 6;
1628 			destData.destinationScene.depth = 1;
1629 			((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYBallistaStatus = 1;
1630 		}
1631 
1632 		((SceneViewWindow *)viewWindow)->moveToDestination(destData);
1633 	}
1634 
1635 	return SC_TRUE;
1636 }
1637 
specifyCursor(Window * viewWindow,const Common::Point & pointLocation)1638 int SpinBallista::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
1639 	if (_handle.contains(pointLocation) && ((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYBallistaStatus < 2)
1640 		return kCursorFinger;
1641 
1642 	return kCursorArrow;
1643 }
1644 
1645 class PlaceSiegeCycleOnTrack : public SceneBase {
1646 public:
1647 	PlaceSiegeCycleOnTrack(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
1648 	int draggingItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
1649 	int droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
1650 
1651 private:
1652 	Common::Rect _cycleRect;
1653 	void setArrows(Window *viewWindow);
1654 };
1655 
PlaceSiegeCycleOnTrack(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation)1656 PlaceSiegeCycleOnTrack::PlaceSiegeCycleOnTrack(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
1657 		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
1658 	_cycleRect = Common::Rect(0, 0, 350, 160);
1659 
1660 	// If we placed the cycle on the track, change the still frame
1661 	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYPlacedSiegeCycle != 0) {
1662 		_staticData.navFrameIndex = 229;
1663 		setArrows(viewWindow);
1664 	}
1665 }
1666 
draggingItem(Window * viewWindow,int itemID,const Common::Point & pointLocation,int itemFlags)1667 int PlaceSiegeCycleOnTrack::draggingItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
1668 	if (itemID == kItemSiegeCycle && _cycleRect.contains(pointLocation) && ((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYPlacedSiegeCycle == 0)
1669 		return 1;
1670 
1671 	return 0;
1672 }
1673 
droppedItem(Window * viewWindow,int itemID,const Common::Point & pointLocation,int itemFlags)1674 int PlaceSiegeCycleOnTrack::droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
1675 	if (pointLocation.x == -1 && pointLocation.y == -1)
1676 		return SIC_REJECT;
1677 
1678 	if (itemID == kItemSiegeCycle && _cycleRect.contains(pointLocation) && ((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYPlacedSiegeCycle == 0) {
1679 		_staticData.navFrameIndex = 229;
1680 		((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYPlacedSiegeCycle = 1;
1681 		viewWindow->invalidateWindow(false);
1682 		setArrows(viewWindow);
1683 		return SIC_ACCEPT;
1684 	}
1685 
1686 	return SIC_REJECT;
1687 }
1688 
setArrows(Window * viewWindow)1689 void PlaceSiegeCycleOnTrack::setArrows(Window *viewWindow) {
1690 	// Can only walk to the siege cycle
1691 	_staticData.destForward.destinationScene = Location(5, 5, 13, 0, 0, 0);
1692 	_staticData.destForward.transitionType = TRANSITION_VIDEO;
1693 	_staticData.destForward.transitionData = 12;
1694 	_staticData.destForward.transitionStartFrame = -1;
1695 	_staticData.destForward.transitionLength = -1;
1696 
1697 	_staticData.destUp.destinationScene = Location(-1, -1, -1, -1, -1, -1);
1698 	_staticData.destUp.transitionType = -1;
1699 	_staticData.destUp.transitionData = -1;
1700 	_staticData.destUp.transitionStartFrame = -1;
1701 	_staticData.destUp.transitionLength = -1;
1702 
1703 	_staticData.destLeft.destinationScene = Location(-1, -1, -1, -1, -1, -1);
1704 	_staticData.destLeft.transitionType = -1;
1705 	_staticData.destLeft.transitionData = -1;
1706 	_staticData.destLeft.transitionStartFrame = -1;
1707 	_staticData.destLeft.transitionLength = -1;
1708 
1709 	_staticData.destRight.destinationScene = Location(-1, -1, -1, -1, -1, -1);
1710 	_staticData.destRight.transitionType = -1;
1711 	_staticData.destRight.transitionData = -1;
1712 	_staticData.destRight.transitionStartFrame = -1;
1713 	_staticData.destRight.transitionLength = -1;
1714 
1715 	_staticData.destDown.destinationScene = Location(-1, -1, -1, -1, -1, -1);
1716 	_staticData.destDown.transitionType = -1;
1717 	_staticData.destDown.transitionData = -1;
1718 	_staticData.destDown.transitionStartFrame = -1;
1719 	_staticData.destDown.transitionLength = -1;
1720 
1721 	((GameUIWindow *)viewWindow->getParent())->_navArrowWindow->updateAllArrows(_staticData);
1722 }
1723 
1724 class AimBallistaAwayFromTower : public SceneBase {
1725 public:
1726 	AimBallistaAwayFromTower(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
1727 	~AimBallistaAwayFromTower();
1728 	void preDestructor();
1729 	int paint(Window *viewWindow, Graphics::Surface *preBuffer);
1730 	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
1731 	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
1732 
1733 private:
1734 	Common::Rect _raiseBallista;
1735 	Common::Rect _lowerBallista;
1736 	Common::Rect _turnBallistaLeft;
1737 	Common::Rect _turnBallistaRight;
1738 	Common::Rect _ballistaHandle;
1739 	AVIFrames *_viewFrameExtractor;
1740 };
1741 
AimBallistaAwayFromTower(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation)1742 AimBallistaAwayFromTower::AimBallistaAwayFromTower(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
1743 		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
1744 	_turnBallistaLeft = Common::Rect(0, 84, 44, 189);
1745 	_turnBallistaRight = Common::Rect(45, 84, 90, 189);
1746 	_lowerBallista = Common::Rect(368, 82, 432, 189);
1747 	_raiseBallista = Common::Rect(304, 82, 367, 189);
1748 	_ballistaHandle = Common::Rect(170, 116, 212, 189);
1749 
1750 	_viewFrameExtractor = new AVIFrames(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 6));
1751 }
1752 
~AimBallistaAwayFromTower()1753 AimBallistaAwayFromTower::~AimBallistaAwayFromTower() {
1754 	preDestructor();
1755 }
1756 
preDestructor()1757 void AimBallistaAwayFromTower::preDestructor() {
1758 	delete _viewFrameExtractor;
1759 	_viewFrameExtractor = nullptr;
1760 }
1761 
paint(Window * viewWindow,Graphics::Surface * preBuffer)1762 int AimBallistaAwayFromTower::paint(Window *viewWindow, Graphics::Surface *preBuffer) {
1763 	SceneBase::paint(viewWindow, preBuffer);
1764 
1765 	byte xPos = ((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYBallistaXPos;
1766 	byte yPos = ((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYBallistaYPos;
1767 	const Graphics::Surface *frame = _viewFrameExtractor->getFrame(yPos * 20 + xPos + 200);
1768 
1769 	if (frame)
1770 		_vm->_gfx->crossBlit(preBuffer, 120, 51, 160, 56, frame, 0, 0);
1771 
1772 	return SC_REPAINT;
1773 }
1774 
mouseUp(Window * viewWindow,const Common::Point & pointLocation)1775 int AimBallistaAwayFromTower::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
1776 	if (_ballistaHandle.contains(pointLocation)) {
1777 		((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYNeverShotBallista = 1;
1778 
1779 		// Play the handle movie
1780 		((SceneViewWindow *)viewWindow)->playClippedSynchronousAnimation(14, 96, 110, 296, 189);
1781 
1782 		return SC_TRUE;
1783 	} else if (_raiseBallista.contains(pointLocation)) {
1784 		byte &yPos = ((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYBallistaYPos;
1785 
1786 		if (yPos == 0)
1787 			return SC_FALSE;
1788 
1789 		yPos--;
1790 		((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYNeverUsedCrank = 1;
1791 
1792 		// Start the spin sound
1793 		int soundID = _vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 12), 128, true, false);
1794 
1795 		// Spin the wheel halfway
1796 		((SceneViewWindow *)viewWindow)->playClippedSynchronousAnimation(17, 300, 70, 432, 189);
1797 
1798 		// Stop the spin sound
1799 		_vm->_sound->stopSoundEffect(soundID);
1800 
1801 		// Repaint
1802 		viewWindow->invalidateWindow(false);
1803 		return SC_TRUE;
1804 	} else if (_lowerBallista.contains(pointLocation)) {
1805 		byte &yPos = ((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYBallistaYPos;
1806 
1807 		if (yPos >= 4)
1808 			return SC_FALSE;
1809 
1810 		yPos++;
1811 		((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYNeverUsedCrank = 1;
1812 
1813 		// Start the spin sound
1814 		int soundID = _vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 12), 128, true, false);
1815 
1816 		// Spin the wheel halfway
1817 		((SceneViewWindow *)viewWindow)->playClippedSynchronousAnimation(18, 300, 70, 432, 189);
1818 
1819 		// Stop the spin sound
1820 		_vm->_sound->stopSoundEffect(soundID);
1821 
1822 		// Repaint
1823 		viewWindow->invalidateWindow(false);
1824 		return SC_TRUE;
1825 	} else if (_turnBallistaRight.contains(pointLocation)) {
1826 		byte &xPos = ((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYBallistaXPos;
1827 
1828 		if (xPos >= 19)
1829 			return SC_FALSE;
1830 
1831 		xPos++;
1832 		((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYNeverUsedCrank = 1;
1833 
1834 		// Start the spin sound
1835 		int soundID = _vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 12), 128, true, false);
1836 
1837 		// Spin the wheel halfway
1838 		((SceneViewWindow *)viewWindow)->playClippedSynchronousAnimation(16, 0, 70, 100, 189);
1839 
1840 		// Stop the spin sound
1841 		_vm->_sound->stopSoundEffect(soundID);
1842 
1843 		// Repaint
1844 		viewWindow->invalidateWindow(false);
1845 		return SC_TRUE;
1846 	} else if (_turnBallistaLeft.contains(pointLocation)) {
1847 		byte &xPos = ((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYBallistaXPos;
1848 
1849 		if (xPos == 0)
1850 			return SC_FALSE;
1851 
1852 		xPos--;
1853 		((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYNeverUsedCrank = 1;
1854 
1855 		// Start the spin sound
1856 		int soundID = _vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 12), 128, true, false);
1857 
1858 		// Spin the wheel halfway
1859 		((SceneViewWindow *)viewWindow)->playClippedSynchronousAnimation(15, 0, 70, 100, 189);
1860 
1861 		// Stop the spin sound
1862 		_vm->_sound->stopSoundEffect(soundID);
1863 
1864 		// Repaint
1865 		viewWindow->invalidateWindow(false);
1866 		return SC_TRUE;
1867 	}
1868 
1869 	// Return to previous scene
1870 	DestinationScene destData;
1871 	destData.destinationScene = Location(5, 5, 8, 5, 1, 0);
1872 	destData.transitionType = TRANSITION_VIDEO;
1873 	destData.transitionData = 10;
1874 	destData.transitionStartFrame = -1;
1875 	destData.transitionLength = -1;
1876 	((SceneViewWindow *)viewWindow)->moveToDestination(destData);
1877 	return SC_TRUE;
1878 }
1879 
specifyCursor(Window * viewWindow,const Common::Point & pointLocation)1880 int AimBallistaAwayFromTower::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
1881 	if (_raiseBallista.contains(pointLocation))
1882 		return kCursorArrowUp;
1883 
1884 	if (_lowerBallista.contains(pointLocation))
1885 		return kCursorArrowDown;
1886 
1887 	if (_turnBallistaRight.contains(pointLocation))
1888 		return kCursorArrowRight;
1889 
1890 	if (_turnBallistaLeft.contains(pointLocation))
1891 		return kCursorArrowLeft;
1892 
1893 	if (_ballistaHandle.contains(pointLocation))
1894 		return kCursorFinger;
1895 
1896 	return kCursorPutDown;
1897 }
1898 
1899 class PaintingTowerCapAgent : public SceneBase {
1900 public:
1901 	PaintingTowerCapAgent(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
1902 	int postEnterRoom(Window *viewWindow, const Location &priorLocation);
1903 };
1904 
PaintingTowerCapAgent(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation)1905 PaintingTowerCapAgent::PaintingTowerCapAgent(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
1906 		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
1907 }
1908 
postEnterRoom(Window * viewWindow,const Location & priorLocation)1909 int PaintingTowerCapAgent::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
1910 	((SceneViewWindow *)viewWindow)->getGlobalFlags().dsPTBeenOnBalcony = 1;
1911 
1912 	if (!((SceneViewWindow *)viewWindow)->isNumberInGlobalFlagTable(offsetof(GlobalFlags, evcapBaseID), offsetof(GlobalFlags, evcapNumCaptured), DAVINCI_EVIDENCE_AGENT3)) {
1913 		// Play animation of capturing the evidence
1914 		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(11);
1915 
1916 		// Attempt to add the evidence to the biochip
1917 		((SceneViewWindow *)viewWindow)->addNumberToGlobalFlagTable(offsetof(GlobalFlags, evcapBaseID), offsetof(GlobalFlags, evcapNumCaptured), 12, DAVINCI_EVIDENCE_AGENT3);
1918 		((SceneViewWindow *)viewWindow)->displayLiveText(_vm->getString(IDS_MBT_EVIDENCE_ACQUIRED));
1919 
1920 		// Turn off evidence capture
1921 		((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->disableEvidenceCapture();
1922 
1923 		// Set flag for scoring
1924 		((SceneViewWindow *)viewWindow)->getGlobalFlags().scoreResearchAgent3DaVinci = 1;
1925 	} else {
1926 		// Moonwalk
1927 		if (_vm->isControlDown())
1928 			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(12);
1929 	}
1930 
1931 	return SC_TRUE;
1932 }
1933 
1934 class CodexTowerElevatorControls : public SceneBase {
1935 public:
1936 	CodexTowerElevatorControls(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
1937 	int gdiPaint(Window *viewWindow);
1938 	int mouseMove(Window *viewWindow, const Common::Point &pointLocation);
1939 	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
1940 	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
1941 
1942 private:
1943 	Common::Rect _transText[4];
1944 	Common::Rect _controls[2];
1945 	int _textTranslated;
1946 };
1947 
CodexTowerElevatorControls(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation)1948 CodexTowerElevatorControls::CodexTowerElevatorControls(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
1949 		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
1950 	_transText[0] = Common::Rect(234, 52, 301, 72);
1951 	_transText[1] = Common::Rect(232, 147, 299, 167);
1952 	_transText[2] = Common::Rect(325, 51, 380, 71);
1953 	_transText[3] = Common::Rect(321, 147, 388, 168);
1954 	_controls[0] = Common::Rect(236, 38, 296, 264);
1955 	_controls[1] = Common::Rect(350, 70, 432, 140);
1956 	_textTranslated = -1;
1957 }
1958 
gdiPaint(Window * viewWindow)1959 int CodexTowerElevatorControls::gdiPaint(Window *viewWindow) {
1960 	if (_textTranslated >= 0 && ((SceneViewWindow *)viewWindow)->getGlobalFlags().bcTranslateEnabled == 1) {
1961 		Common::Rect absoluteRect = viewWindow->getAbsoluteRect();
1962 		Common::Rect rect(_transText[_textTranslated]);
1963 		rect.translate(absoluteRect.left, absoluteRect.top);
1964 		_vm->_gfx->getScreen()->frameRect(rect, _vm->_gfx->getColor(255, 0, 0));
1965 	}
1966 
1967 	return SC_REPAINT;
1968 }
1969 
mouseMove(Window * viewWindow,const Common::Point & pointLocation)1970 int CodexTowerElevatorControls::mouseMove(Window *viewWindow, const Common::Point &pointLocation) {
1971 	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().bcTranslateEnabled == 1) {
1972 		for (int i = 0; i < 4; i++) {
1973 			if (_transText[i].contains(pointLocation)) {
1974 				((SceneViewWindow *)viewWindow)->getGlobalFlags().dsPTTransElevatorControls = 1;
1975 
1976 				Common::String text = _vm->getString(IDDS_ELEVATOR_CONTROLS_TEXT_A + i);
1977 				((SceneViewWindow *)viewWindow)->displayTranslationText(text);
1978 				_textTranslated = i;
1979 				viewWindow->invalidateWindow(false);
1980 				break;
1981 			}
1982 		}
1983 	} else {
1984 		if (_textTranslated >= 0) {
1985 			_textTranslated = -1;
1986 			viewWindow->invalidateWindow(false);
1987 		}
1988 	}
1989 
1990 	return SC_FALSE;
1991 }
1992 
mouseUp(Window * viewWindow,const Common::Point & pointLocation)1993 int CodexTowerElevatorControls::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
1994 	if (_controls[0].contains(pointLocation) || _controls[1].contains(pointLocation)) {
1995 		_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 13));
1996 		((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCTTriedElevatorControls = 1;
1997 		return SC_TRUE;
1998 	}
1999 
2000 	return SC_FALSE;
2001 }
2002 
specifyCursor(Window * viewWindow,const Common::Point & pointLocation)2003 int CodexTowerElevatorControls::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
2004 	if (_controls[0].contains(pointLocation) || _controls[1].contains(pointLocation))
2005 		return kCursorFinger;
2006 
2007 	return kCursorArrow;
2008 }
2009 
2010 class ClickChangeSceneTranslate : public SceneBase {
2011 public:
2012 	ClickChangeSceneTranslate(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
2013 			int left = -1, int top = -1, int right = -1, int bottom = -1, int cursorID = 0, int timeZone = -1, int environment = -1,
2014 			int node = -1, int facing = -1, int orientation = -1, int depth = -1, int transitionType = -1, int transitionData = -1,
2015 			int transitionStartFrame = -1, int transitionLength = -1, int transLeft = -1, int transTop = -1, int transRight = -1,
2016 			int transBottom = -1, int transTextID = -1);
2017 	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
2018 	int gdiPaint(Window *viewWindow);
2019 	int mouseMove(Window *viewWindow, const Common::Point &pointLocation);
2020 	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
2021 
2022 private:
2023 	int _cursorID;
2024 	Common::Rect _clickRegion;
2025 	DestinationScene _clickDestination;
2026 	Common::Rect _translateRect;
2027 	int _textID;
2028 	bool _textTranslated;
2029 };
2030 
ClickChangeSceneTranslate(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 transLeft,int transTop,int transRight,int transBottom,int transTextID)2031 ClickChangeSceneTranslate::ClickChangeSceneTranslate(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
2032 		int left, int top, int right, int bottom, int cursorID, int timeZone, int environment,
2033 		int node, int facing, int orientation, int depth, int transitionType, int transitionData,
2034 		int transitionStartFrame, int transitionLength, int transLeft, int transTop, int transRight,
2035 		int transBottom, int transTextID) :
2036 		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
2037 	_clickRegion = Common::Rect(left, top, right, bottom);
2038 	_cursorID = cursorID;
2039 	_clickDestination.destinationScene.timeZone = timeZone;
2040 	_clickDestination.destinationScene.environment = environment;
2041 	_clickDestination.destinationScene.node = node;
2042 	_clickDestination.destinationScene.facing = facing;
2043 	_clickDestination.destinationScene.orientation = orientation;
2044 	_clickDestination.destinationScene.depth = depth;
2045 	_clickDestination.transitionType = transitionType;
2046 	_clickDestination.transitionData = transitionData;
2047 	_clickDestination.transitionStartFrame = transitionStartFrame;
2048 	_clickDestination.transitionLength = transitionLength;
2049 	_translateRect = Common::Rect(transLeft, transTop, transRight, transBottom);
2050 	_textTranslated = false;
2051 	_textID = transTextID;
2052 }
2053 
mouseUp(Window * viewWindow,const Common::Point & pointLocation)2054 int ClickChangeSceneTranslate::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
2055 	if (_clickRegion.contains(pointLocation))
2056 		((SceneViewWindow *)viewWindow)->moveToDestination(_clickDestination);
2057 
2058 	return SC_FALSE;
2059 }
2060 
gdiPaint(Window * viewWindow)2061 int ClickChangeSceneTranslate::gdiPaint(Window *viewWindow) {
2062 	if (_textTranslated && ((SceneViewWindow *)viewWindow)->getGlobalFlags().bcTranslateEnabled == 1) {
2063 		Common::Rect absoluteRect = viewWindow->getAbsoluteRect();
2064 		Common::Rect rect(_translateRect);
2065 		rect.translate(absoluteRect.left, absoluteRect.top);
2066 		_vm->_gfx->getScreen()->frameRect(rect, _vm->_gfx->getColor(255, 0, 0));
2067 	}
2068 
2069 	return SC_REPAINT;
2070 }
2071 
mouseMove(Window * viewWindow,const Common::Point & pointLocation)2072 int ClickChangeSceneTranslate::mouseMove(Window *viewWindow, const Common::Point &pointLocation) {
2073 	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().bcTranslateEnabled == 1) {
2074 		if (_translateRect.contains(pointLocation)) {
2075 			((SceneViewWindow *)viewWindow)->displayTranslationText(_vm->getString(_textID));
2076 			_textTranslated = true;
2077 			viewWindow->invalidateWindow(false);
2078 		} else {
2079 			if (_textTranslated) {
2080 				_textTranslated = false;
2081 				viewWindow->invalidateWindow(false);
2082 			}
2083 		}
2084 	} else {
2085 		if (_textTranslated) {
2086 			_textTranslated = false;
2087 			viewWindow->invalidateWindow(false);
2088 		}
2089 	}
2090 
2091 	return SC_FALSE;
2092 }
2093 
specifyCursor(Window * viewWindow,const Common::Point & pointLocation)2094 int ClickChangeSceneTranslate::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
2095 	if (_clickRegion.contains(pointLocation))
2096 		return _cursorID;
2097 
2098 	return 0;
2099 }
2100 
2101 class AimBallistaToTower : public SceneBase {
2102 public:
2103 	AimBallistaToTower(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
2104 	~AimBallistaToTower();
2105 	void preDestructor();
2106 	int paint(Window *viewWindow, Graphics::Surface *preBuffer);
2107 	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
2108 	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
2109 
2110 private:
2111 	Common::Rect _raiseBallista;
2112 	Common::Rect _lowerBallista;
2113 	Common::Rect _turnBallistaLeft;
2114 	Common::Rect _turnBallistaRight;
2115 	Common::Rect _ballistaHandle;
2116 	AVIFrames *_viewFrameExtractor;
2117 };
2118 
AimBallistaToTower(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation)2119 AimBallistaToTower::AimBallistaToTower(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
2120 		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
2121 	_turnBallistaLeft = Common::Rect(0, 84, 44, 189);
2122 	_turnBallistaRight = Common::Rect(45, 84, 90, 189);
2123 	_lowerBallista = Common::Rect(368, 82, 432, 189);
2124 	_raiseBallista = Common::Rect(304, 82, 367, 189);
2125 	_ballistaHandle = Common::Rect(170, 116, 212, 189);
2126 
2127 	_viewFrameExtractor = new AVIFrames(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 6));
2128 }
2129 
~AimBallistaToTower()2130 AimBallistaToTower::~AimBallistaToTower() {
2131 	preDestructor();
2132 }
2133 
preDestructor()2134 void AimBallistaToTower::preDestructor() {
2135 	delete _viewFrameExtractor;
2136 	_viewFrameExtractor = nullptr;
2137 }
2138 
paint(Window * viewWindow,Graphics::Surface * preBuffer)2139 int AimBallistaToTower::paint(Window *viewWindow, Graphics::Surface *preBuffer) {
2140 	SceneBase::paint(viewWindow, preBuffer);
2141 
2142 	byte xPos = ((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYBallistaXPos;
2143 	byte yPos = ((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYBallistaYPos;
2144 	const Graphics::Surface *frame = _viewFrameExtractor->getFrame(yPos * 20 + xPos);
2145 
2146 	if (frame)
2147 		_vm->_gfx->crossBlit(preBuffer, 120, 51, 160, 56, frame, 0, 0);
2148 
2149 	return SC_REPAINT;
2150 }
2151 
mouseUp(Window * viewWindow,const Common::Point & pointLocation)2152 int AimBallistaToTower::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
2153 	if (_ballistaHandle.contains(pointLocation)) {
2154 		byte xPos = ((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYBallistaXPos;
2155 		byte yPos = ((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYBallistaYPos;
2156 		((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYNeverShotBallista = 1;
2157 
2158 		if (xPos == 9 && yPos == 2) {
2159 			// Play the launch movie
2160 			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(20);
2161 
2162 			// Reset the ballista status
2163 			((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYBallistaStatus = 2;
2164 			((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYNeverConnectedHook = 1;
2165 
2166 			// Step down
2167 			DestinationScene destData;
2168 			destData.destinationScene = Location(5, 5, 8, 5, 1, 2);
2169 			destData.transitionType = TRANSITION_VIDEO;
2170 			destData.transitionData = 11;
2171 			destData.transitionStartFrame = -1;
2172 			destData.transitionLength = -1;
2173 			((SceneViewWindow *)viewWindow)->moveToDestination(destData);
2174 		} else {
2175 			// Play the launch movie
2176 			((SceneViewWindow *)viewWindow)->playClippedSynchronousAnimation(19, 110, 108, 290, 189);
2177 		}
2178 
2179 		return SC_TRUE;
2180 	} else if (_raiseBallista.contains(pointLocation)) {
2181 		byte &yPos = ((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYBallistaYPos;
2182 
2183 		if (yPos == 0)
2184 			return SC_FALSE;
2185 
2186 		yPos--;
2187 		((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYNeverUsedCrank = 1;
2188 
2189 		// Start the spin sound
2190 		int soundID = _vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 12), 128, true, false);
2191 
2192 		// Spin the wheel halfway
2193 		((SceneViewWindow *)viewWindow)->playClippedSynchronousAnimation(23, 300, 70, 432, 189);
2194 
2195 		// Stop the spin sound
2196 		_vm->_sound->stopSoundEffect(soundID);
2197 
2198 		// Repaint
2199 		viewWindow->invalidateWindow(false);
2200 		return SC_TRUE;
2201 	} else if (_lowerBallista.contains(pointLocation)) {
2202 		byte &yPos = ((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYBallistaYPos;
2203 
2204 		if (yPos >= 4)
2205 			return SC_FALSE;
2206 
2207 		yPos++;
2208 		((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYNeverUsedCrank = 1;
2209 
2210 		// Start the spin sound
2211 		int soundID = _vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 12), 128, true, false);
2212 
2213 		// Spin the wheel halfway
2214 		((SceneViewWindow *)viewWindow)->playClippedSynchronousAnimation(24, 300, 70, 432, 189);
2215 
2216 		// Stop the spin sound
2217 		_vm->_sound->stopSoundEffect(soundID);
2218 
2219 		// Repaint
2220 		viewWindow->invalidateWindow(false);
2221 		return SC_TRUE;
2222 	} else if (_turnBallistaRight.contains(pointLocation)) {
2223 		byte &xPos = ((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYBallistaXPos;
2224 
2225 		if (xPos >= 19)
2226 			return SC_FALSE;
2227 
2228 		xPos++;
2229 		((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYNeverUsedCrank = 1;
2230 
2231 		// Start the spin sound
2232 		int soundID = _vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 12), 128, true, false);
2233 
2234 		// Spin the wheel halfway
2235 		((SceneViewWindow *)viewWindow)->playClippedSynchronousAnimation(22, 0, 70, 100, 189);
2236 
2237 		// Stop the spin sound
2238 		_vm->_sound->stopSoundEffect(soundID);
2239 
2240 		// Repaint
2241 		viewWindow->invalidateWindow(false);
2242 		return SC_TRUE;
2243 	} else if (_turnBallistaLeft.contains(pointLocation)) {
2244 		byte &xPos = ((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYBallistaXPos;
2245 
2246 		if (xPos == 0)
2247 			return SC_FALSE;
2248 
2249 		xPos--;
2250 		((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYNeverUsedCrank = 1;
2251 
2252 		// Start the spin sound
2253 		int soundID = _vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 12), 128, true, false);
2254 
2255 		// Spin the wheel halfway
2256 		((SceneViewWindow *)viewWindow)->playClippedSynchronousAnimation(21, 0, 70, 100, 189);
2257 
2258 		// Stop the spin sound
2259 		_vm->_sound->stopSoundEffect(soundID);
2260 
2261 		// Repaint
2262 		viewWindow->invalidateWindow(false);
2263 		return SC_TRUE;
2264 	}
2265 
2266 	// Return to previous scene
2267 	DestinationScene destData;
2268 	destData.destinationScene = Location(5, 5, 8, 5, 1, 1);
2269 	destData.transitionType = TRANSITION_VIDEO;
2270 	destData.transitionData = 11;
2271 	destData.transitionStartFrame = -1;
2272 	destData.transitionLength = -1;
2273 	((SceneViewWindow *)viewWindow)->moveToDestination(destData);
2274 	return SC_TRUE;
2275 }
2276 
specifyCursor(Window * viewWindow,const Common::Point & pointLocation)2277 int AimBallistaToTower::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
2278 	if (_raiseBallista.contains(pointLocation))
2279 		return kCursorArrowUp;
2280 
2281 	if (_lowerBallista.contains(pointLocation))
2282 		return kCursorArrowDown;
2283 
2284 	if (_turnBallistaRight.contains(pointLocation))
2285 		return kCursorArrowRight;
2286 
2287 	if (_turnBallistaLeft.contains(pointLocation))
2288 		return kCursorArrowLeft;
2289 
2290 	if (_ballistaHandle.contains(pointLocation))
2291 		return kCursorFinger;
2292 
2293 	return kCursorPutDown;
2294 }
2295 
2296 class WalkDownPaintingTowerElevator : public SceneBase {
2297 public:
2298 	WalkDownPaintingTowerElevator(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
2299 	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
2300 	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
2301 
2302 private:
2303 	int _cursorID;
2304 	Common::Rect _clickRegion;
2305 	DestinationScene _clickDestination;
2306 };
2307 
WalkDownPaintingTowerElevator(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation)2308 WalkDownPaintingTowerElevator::WalkDownPaintingTowerElevator(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
2309 		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
2310 	_clickRegion = Common::Rect(48, 136, 306, 184);
2311 	_cursorID = kCursorFinger;
2312 	_clickDestination.destinationScene = Location(5, 3, 10, 0, 0, 0);
2313 	_clickDestination.transitionType = TRANSITION_VIDEO;
2314 	_clickDestination.transitionData = 9;
2315 	_clickDestination.transitionStartFrame = -1;
2316 	_clickDestination.transitionLength = -1;
2317 }
2318 
mouseUp(Window * viewWindow,const Common::Point & pointLocation)2319 int WalkDownPaintingTowerElevator::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
2320 	if (_clickRegion.contains(pointLocation)) {
2321 		if (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsPTElevatorLeverA == 1) {
2322 			((SceneViewWindow *)viewWindow)->moveToDestination(_clickDestination);
2323 			((SceneViewWindow *)viewWindow)->getGlobalFlags().dsPTWalkedDownElevator = 1;
2324 		} else {
2325 			_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 13), 127, false, true);
2326 		}
2327 	}
2328 
2329 	return SC_FALSE;
2330 }
2331 
specifyCursor(Window * viewWindow,const Common::Point & pointLocation)2332 int WalkDownPaintingTowerElevator::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
2333 	if (_clickRegion.contains(pointLocation))
2334 		return _cursorID;
2335 
2336 	return kCursorArrow;
2337 }
2338 
2339 class LensFilterNotify : public SceneBase {
2340 public:
2341 	LensFilterNotify(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
2342 	int postEnterRoom(Window *viewWindow, const Location &newLocation);
2343 };
2344 
LensFilterNotify(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation)2345 LensFilterNotify::LensFilterNotify(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
2346 		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
2347 }
2348 
postEnterRoom(Window * viewWindow,const Location & newLocation)2349 int LensFilterNotify::postEnterRoom(Window *viewWindow, const Location &newLocation) {
2350 	if (newLocation.node != _staticData.location.node && !((SceneViewWindow *)viewWindow)->isNumberInGlobalFlagTable(offsetof(GlobalFlags, evcapBaseID), offsetof(GlobalFlags, evcapNumCaptured), DAVINCI_EVIDENCE_LENS_FILTER))
2351 		((SceneViewWindow *)viewWindow)->displayLiveText(_vm->getString(IDS_MBT_EVIDENCE_PRESENT));
2352 
2353 	return SC_TRUE;
2354 }
2355 
2356 class CodexFormulaeNotify : public SceneBase {
2357 public:
2358 	CodexFormulaeNotify(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
2359 	int postEnterRoom(Window *viewWindow, const Location &newLocation);
2360 };
2361 
CodexFormulaeNotify(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation)2362 CodexFormulaeNotify::CodexFormulaeNotify(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
2363 		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
2364 }
2365 
postEnterRoom(Window * viewWindow,const Location & newLocation)2366 int CodexFormulaeNotify::postEnterRoom(Window *viewWindow, const Location &newLocation) {
2367 	if (newLocation.node != _staticData.location.node && !((SceneViewWindow *)viewWindow)->isNumberInGlobalFlagTable(offsetof(GlobalFlags, evcapBaseID), offsetof(GlobalFlags, evcapNumCaptured), DAVINCI_EVIDENCE_CODEX))
2368 		((SceneViewWindow *)viewWindow)->displayLiveText(_vm->getString(IDS_MBT_EVIDENCE_PRESENT));
2369 
2370 	return SC_TRUE;
2371 }
2372 
2373 class ViewSiegeCyclePlans : public SceneBase {
2374 public:
2375 	ViewSiegeCyclePlans(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
2376 	int gdiPaint(Window *viewWindow);
2377 	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
2378 	int mouseMove(Window *viewWindow, const Common::Point &pointLocation);
2379 	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
2380 
2381 private:
2382 	Common::Rect _transText[3];
2383 	int _textTranslated;
2384 };
2385 
ViewSiegeCyclePlans(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation)2386 ViewSiegeCyclePlans::ViewSiegeCyclePlans(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
2387 		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
2388 	_transText[0] = Common::Rect(245, 8, 307, 24);
2389 	_transText[1] = Common::Rect(132, 40, 188, 76);
2390 	_transText[2] = Common::Rect(278, 146, 332, 178);
2391 	_textTranslated = -1;
2392 
2393 	// Set the scene visited flag
2394 	((SceneViewWindow *)viewWindow)->getGlobalFlags().dsWSSeenCycleSketch = 1;
2395 }
2396 
gdiPaint(Window * viewWindow)2397 int ViewSiegeCyclePlans::gdiPaint(Window *viewWindow) {
2398 	if (_textTranslated >= 0 && ((SceneViewWindow *)viewWindow)->getGlobalFlags().bcTranslateEnabled == 1) {
2399 		Common::Rect absoluteRect = viewWindow->getAbsoluteRect();
2400 		Common::Rect rect(_transText[_textTranslated]);
2401 		rect.translate(absoluteRect.left, absoluteRect.top);
2402 		_vm->_gfx->getScreen()->frameRect(rect, _vm->_gfx->getColor(255, 0, 0));
2403 	}
2404 
2405 	return SC_REPAINT;
2406 }
2407 
mouseUp(Window * viewWindow,const Common::Point & pointLocation)2408 int ViewSiegeCyclePlans::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
2409 	// Return to depth zero
2410 	DestinationScene destData;
2411 	destData.destinationScene = _staticData.location;
2412 	destData.destinationScene.depth = 0;
2413 	destData.transitionType = TRANSITION_VIDEO;
2414 	destData.transitionData = 16;
2415 	destData.transitionStartFrame = -1;
2416 	destData.transitionLength = -1;
2417 	((SceneViewWindow *)viewWindow)->moveToDestination(destData);
2418 	return SC_TRUE;
2419 }
2420 
mouseMove(Window * viewWindow,const Common::Point & pointLocation)2421 int ViewSiegeCyclePlans::mouseMove(Window *viewWindow, const Common::Point &pointLocation) {
2422 	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().bcTranslateEnabled == 1) {
2423 		for (int i = 0; i < 3; i++) {
2424 			if (_transText[i].contains(pointLocation)) {
2425 				((SceneViewWindow *)viewWindow)->getGlobalFlags().dsPTTransElevatorControls = 1;
2426 
2427 				Common::String text = _vm->getString(IDS_DS_WS_CYCLE_PLANS_TEXT_A + i);
2428 				((SceneViewWindow *)viewWindow)->displayTranslationText(text);
2429 				_textTranslated = i;
2430 				viewWindow->invalidateWindow(false);
2431 				break;
2432 			}
2433 		}
2434 	} else {
2435 		if (_textTranslated >= 0) {
2436 			_textTranslated = -1;
2437 			viewWindow->invalidateWindow(false);
2438 		}
2439 	}
2440 
2441 	return SC_FALSE;
2442 }
2443 
specifyCursor(Window * viewWindow,const Common::Point & pointLocation)2444 int ViewSiegeCyclePlans::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
2445 	return kCursorPutDown;
2446 }
2447 
initializeDaVinciTimeZoneAndEnvironment(Window * viewWindow,int environment)2448 bool SceneViewWindow::initializeDaVinciTimeZoneAndEnvironment(Window *viewWindow, int environment) {
2449 	if (environment == -1) {
2450 		GlobalFlags &flags = ((SceneViewWindow *)viewWindow)->getGlobalFlags();
2451 
2452 		flags.dsPTElevatorPresent = flags.generalWalkthroughMode;
2453 		flags.dsPTElevatorLeverA = flags.generalWalkthroughMode;
2454 		flags.dsPTElevatorLeverB = flags.generalWalkthroughMode;
2455 		flags.dsCYBallistaStatus = flags.generalWalkthroughMode;
2456 		flags.dsWSSiegeCycleStatus = 0;
2457 		flags.dsCTUnlockedDoor = flags.generalWalkthroughMode;
2458 		flags.dsCTPlayedBallistaFalling = 0;
2459 		flags.dsCYPlacedSiegeCycle = 0;
2460 		flags.dsCYBallistaXPos = 0;
2461 		flags.dsCYBallistaYPos = 0;
2462 
2463 		flags.dsWSPickedUpWheelAssembly = ((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->isItemInInventory(kItemWheelAssembly) ? 1 : 0;
2464 		flags.dsWSPickedUpGearAssembly = ((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->isItemInInventory(kItemDriveAssembly) ? 1 : 0;
2465 		flags.dsWSPickedUpPegs = ((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->isItemInInventory(kItemWoodenPegs) ? 1 : 0;
2466 		flags.dsWSGrabbedSiegeCycle = ((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->isItemInInventory(kItemSiegeCycle) ? 1 : 0;
2467 		flags.dsGDTakenCoilOfRope = ((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->isItemInInventory(kItemCoilOfRope) ? 1 : 0;
2468 		flags.dsCTRetrievedLens = ((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->isItemInInventory(kItemLensFilter) ? 1 : 0;
2469 		flags.dsCTTakenHeart = ((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->isItemInInventory(kItemPreservedHeart) ? 1 : 0;
2470 
2471 		if (flags.generalWalkthroughMode == 1) {
2472 			flags.dsWSSiegeCycleStatus = DS_SC_COMPLETED;
2473 			flags.dsWSPickedUpWheelAssembly = 1;
2474 			flags.dsWSPickedUpGearAssembly = 1;
2475 			flags.dsWSPickedUpPegs = 1;
2476 		}
2477 	} else if (environment == 2) {
2478 		((SceneViewWindow *)viewWindow)->getGlobalFlags().scoreEnteredCodexTower = 1;
2479 		((SceneViewWindow *)viewWindow)->getGlobalFlags().dsVisitedCodexTower = 1;
2480 	}
2481 
2482 	return true;
2483 }
2484 
startDaVinciAmbient(int oldTimeZone,int oldEnvironment,int environment,bool fade)2485 bool SceneViewWindow::startDaVinciAmbient(int oldTimeZone, int oldEnvironment, int environment, bool fade) {
2486 	_vm->_sound->setAmbientSound(_vm->getFilePath(5, environment, SF_AMBIENT), fade, 64);
2487 	return true;
2488 }
2489 
checkCustomDaVinciAICommentDependencies(const Location & commentLocation,const AIComment & commentData)2490 bool SceneViewWindow::checkCustomDaVinciAICommentDependencies(const Location &commentLocation, const AIComment &commentData) {
2491 	switch (commentData.dependencyFlagOffsetB) {
2492 	case 1: // Has not raised platform
2493 		return _globalFlags.dsPTRaisedPlatform == 0;
2494 	case 2: // Has raised platform
2495 		return _globalFlags.dsPTRaisedPlatform == 1;
2496 	case 3: // Has not been to codec tower
2497 		return _globalFlags.dsVisitedCodexTower == 0;
2498 	case 4: // Has not been on balcony, has not been down elevator
2499 		return _globalFlags.dsPTBeenOnBalcony == 0 && _globalFlags.dsPTWalkedDownElevator == 0;
2500 	case 5: // Has not raised platform, has not translated levers
2501 		return _globalFlags.dsPTRaisedPlatform == 0 && _globalFlags.dsPTTransElevatorControls == 0;
2502 	case 6: // Has not raised platform, has not translated levers, translation biochip is in inventory
2503 		return _globalFlags.dsPTRaisedPlatform == 0 && _globalFlags.dsPTTransElevatorControls == 0 && ((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemBioChipTranslate);
2504 	case 7: // If clicked on codex door
2505 		return _globalFlags.dsGDClickedOnCodexDoor == 1;
2506 	case 8: // If clicked on codex door, siege cycle not in inventory
2507 		return _globalFlags.dsGDClickedOnCodexDoor == 1 && ((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemSiegeCycle);
2508 	case 9: // If gear assembly has never been in inventory
2509 		return _globalFlags.genHadDriveAssembly == 0;
2510 	case 10: // If siege cycle has never been inventory
2511 		return _globalFlags.genHadSiegeCycle == 0;
2512 	case 11: // If neither wheel assembly or drive assembly have ever been in inventory, and after viewing siege cycle plans
2513 		return _globalFlags.genHadDriveAssembly == 0 && _globalFlags.genHadWheelAssembly == 0;
2514 	case 12: // After player has been to 5/4/8/1/1/1, siege cycle has never been in inventory
2515 		return (_globalFlags.dsWSSiegeCycleStatus & DS_SC_DRIVE_ASSEMBLY) != 0 && (_globalFlags.dsWSSiegeCycleStatus & DS_SC_WHEEL_ASSEMBLY) != 0;
2516 	case 13: // After player has been to 5/4/4/2/0/1 or 5/4/4/3/0/1, siege cycle has never been in inventory
2517 		return _globalFlags.dsWSSeenBallistaSketch == 1 && _globalFlags.genHadSiegeCycle == 0;
2518 	case 14: // After player has been to (5/4/4/2/0/1 or 5/4/4/3/0/1) and 5/4/8/1/1/1, before any parts are on the jig
2519 		return _globalFlags.dsWSSeenCycleSketch == 1 && _globalFlags.dsWSSeenBallistaSketch == 1 && _globalFlags.dsWSSiegeCycleStatus == 0 && _globalFlags.dsWSGrabbedSiegeCycle == 0;
2520 	case 15: // After player has been to 5/4/4/2/0/1 or 5/4/4/3/0/1, before any parts are on the jig
2521 		return _globalFlags.dsWSSeenBallistaSketch == 1 && _globalFlags.dsWSSiegeCycleStatus == 0 && _globalFlags.dsWSGrabbedSiegeCycle == 0;
2522 	case 16: // After player has been to 5/4/4/2/0/1 or 5/4/4/3/0/1, if wheel assembly and drive assembly have never been in inventory
2523 		return _globalFlags.dsWSSeenBallistaSketch == 1 && _globalFlags.dsWSSiegeCycleStatus == 0 && _globalFlags.dsWSGrabbedSiegeCycle == 0 && !((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemDriveAssembly) && !((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemWoodenPegs);
2524 	case 17: // After player has been to 5/4/4/2/0/1 or 5/4/4/3/0/1
2525 		return _globalFlags.dsWSSeenBallistaSketch == 1;
2526 	case 18: // Has tried door of codex tower, has never connected ballista hook, has not seen 5/4/4/2/0/1 or 5/4/4/3/0/1
2527 		return _globalFlags.dsGDClickedOnCodexDoor == 1 && _globalFlags.dsCYNeverConnectedHook == 0 && _globalFlags.dsWSSeenBallistaSketch == 0;
2528 	case 19: // Has tried door of codex tower, has not seen 5/4/4/2/0/1 or 5/4/4/3/0/1, has not been to codex tower
2529 		return _globalFlags.dsGDClickedOnCodexDoor == 1 && _globalFlags.dsWSSeenBallistaSketch == 0 && _globalFlags.dsVisitedCodexTower == 0;
2530 	case 20: // Has tried door of codex tower, has seen 5/4/4/2/0/1 or 5/4/4/3/0/1, has never shot ballista
2531 		return _globalFlags.dsGDClickedOnCodexDoor == 1 && _globalFlags.dsWSSeenBallistaSketch == 1 && _globalFlags.dsCYNeverShotBallista == 0;
2532 	case 21: // Has tried door of codex tower, has seen 5/4/4/2/0/1 or 5/4/4/3/0/1, has never used crank
2533 		return _globalFlags.dsGDClickedOnCodexDoor == 1 && _globalFlags.dsWSSeenBallistaSketch == 1 && _globalFlags.dsCYNeverUsedCrank == 0;
2534 	case 22: // Has never connected ballista hook to codex tower
2535 		return _globalFlags.dsCYNeverConnectedHook == 0;
2536 	case 23: // Has tried door of codex tower, has not seen 5/4/4/2/0/1 or 5/4/4/3/0/1, has not been to codex tower
2537 		return _globalFlags.dsGDClickedOnCodexDoor == 1 && _globalFlags.dsWSSeenBallistaSketch == 0 && _globalFlags.dsVisitedCodexTower == 0;
2538 	case 24: // Has tried door of codex tower, has seen 5/4/4/2/0/1 or 5/4/4/3/0/1, has not been to codex tower, siege cycle not in inventory
2539 		return _globalFlags.dsGDClickedOnCodexDoor == 1 && _globalFlags.dsWSSeenBallistaSketch == 1 && _globalFlags.dsVisitedCodexTower == 0 && _globalFlags.dsCYBallistaStatus == 2 && !((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemSiegeCycle);
2540 	case 25: // Has tried door of codex tower, has seen 5/4/4/2/0/1 or 5/4/4/3/0/1, has not been to codex tower, has siege cycle in inventory
2541 		return _globalFlags.dsGDClickedOnCodexDoor == 1 && _globalFlags.dsWSSeenBallistaSketch == 1 && _globalFlags.dsVisitedCodexTower == 0 && ((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemSiegeCycle);
2542 	case 26: // Has tried door of codex tower, has not seen 5/4/4/2/0/1 or 5/4/4/3/0/1, has not been to codex tower, has siege cycle in inventory
2543 		return _globalFlags.dsGDClickedOnCodexDoor == 1 && _globalFlags.dsWSSeenBallistaSketch == 0 && _globalFlags.dsVisitedCodexTower == 0 && ((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemSiegeCycle);
2544 	case 27: // Has tried door of codex tower, has not connected ballista hook to codex tower
2545 		return _globalFlags.dsGDClickedOnCodexDoor == 1 && _globalFlags.dsCYBallistaStatus < 2;
2546 	case 28: // Before ever opening codex tower balcony door
2547 		return _globalFlags.dsCYNeverOpenedBalconyDoor == 0;
2548 	case 29: // Before ever opening codex tower balcony door, after trying unsuccessfully to open door
2549 		return _globalFlags.dsCYNeverOpenedBalconyDoor == 0 && _globalFlags.dsCYTriedOpeningDoor == 1;
2550 	case 30: // Before ever opening codex tower balcony door, after trying unsuccessfully to open door, balcony key in inventory
2551 		return _globalFlags.dsCYNeverOpenedBalconyDoor == 0 && _globalFlags.dsCYTriedOpeningDoor == 1 && ((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemBalconyKey);
2552 	case 31: // Before ever opening codex tower balcony door, after trying unsuccessfully to open door, metal bar in inventory, balcony key not in inventory
2553 		return _globalFlags.dsCYNeverOpenedBalconyDoor == 0 && _globalFlags.dsCYTriedOpeningDoor == 1 && ((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemMetalBar) && !((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemBalconyKey);
2554 	case 32: // Lens filter not in ineventory
2555 		return !((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemLensFilter);
2556 	case 33: // Player has not found formulae, before trying to translate any codex
2557 		return _globalFlags.dsCTCodexFormulaeFound == 0 && _globalFlags.dsCYTranslatedCodex == 0;
2558 	case 34: // Player has not found formulae, after trying to translate any codex
2559 		return _globalFlags.dsCTCodexFormulaeFound == 0 && _globalFlags.dsCYTranslatedCodex == 1;
2560 	case 35: // Player has not found formulae, after trying to translate any codex, lens filter in inventory, lens filter not being used
2561 		return _globalFlags.dsCTCodexFormulaeFound == 0 && _globalFlags.dsCYTranslatedCodex == 1 && ((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemLensFilter) && _globalFlags.lensFilterActivated == 0;
2562 	case 36: // After trying unsuccessfully to open the door
2563 		return _globalFlags.dsCYTriedOpeningDoor == 1;
2564 	case 37: // Player has not found formulae
2565 		return _globalFlags.dsCTCodexFormulaeFound == 0;
2566 	case 38: // Heart not in inventory
2567 		return !((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemPreservedHeart);
2568 	case 39: // After trying to use the codex tower elevator
2569 		return _globalFlags.dsCYTriedElevator == 1;
2570 	case 40: // After trying to translate any codex
2571 		return _globalFlags.dsCYTranslatedCodex == 1;
2572 	case 41: // Not node 8, 9, 10, or 11, player has not found codex
2573 		return commentLocation.node != 8 && commentLocation.node != 9 && commentLocation.node != 10 && commentLocation.node != 11 && _globalFlags.dsCYFoundCodexes == 1;
2574 	case 42: // Not node 8, 9, 10, or 11
2575 		return commentLocation.node != 8 && commentLocation.node != 9 && commentLocation.node != 10 && commentLocation.node != 11;
2576 	case 43: // Not node 8, 9, 10, or 11, player has not found formulae, lens filter in inventory
2577 		return commentLocation.node != 8 && commentLocation.node != 9 && commentLocation.node != 10 && commentLocation.node != 11 && _globalFlags.dsCTCodexFormulaeFound == 0 && ((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemLensFilter);
2578 	case 44: // After player has been to 5/4/4/2/0/1 or 5/4/4/3/0/1, before building siege cycle, drive/gear assembly not in inventory
2579 		return _globalFlags.dsWSSeenBallistaSketch == 1 && _globalFlags.dsWSSiegeCycleStatus == 0 && _globalFlags.dsWSPickedUpWheelAssembly == 0;
2580 	case 45: // After weeble has been spun/clicked
2581 		return _globalFlags.dsCYWeebleClicked == 1;
2582 	}
2583 
2584 	return false;
2585 }
2586 
constructDaVinciSceneObject(Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation)2587 SceneBase *SceneViewWindow::constructDaVinciSceneObject(Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) {
2588 	// Special scene for the trial version
2589 	if (_vm->isTrial())
2590 		return new TrialRecallScene(_vm, viewWindow, sceneStaticData, priorLocation);
2591 
2592 	switch (sceneStaticData.classID) {
2593 	case 0:
2594 		// Default scene
2595 		break;
2596 	case 1:
2597 		return new SwapStillOnFlag(_vm, viewWindow, sceneStaticData, priorLocation, offsetof(GlobalFlags, dsPTElevatorPresent), 1);
2598 	case 2:
2599 		return new DisplayMessageWithEvidenceWhenEnteringNode(_vm, viewWindow, sceneStaticData, priorLocation, DAVINCI_EVIDENCE_FOOTPRINT, IDS_MBT_EVIDENCE_PRESENT);
2600 	case 3:
2601 		return new CapturePaintingTowerFootprint(_vm, viewWindow, sceneStaticData, priorLocation);
2602 	case 4:
2603 		return new PaintingTowerRetrieveKey(_vm, viewWindow, sceneStaticData, priorLocation);
2604 	case 5:
2605 		return new PaintingTowerElevatorControls(_vm, viewWindow, sceneStaticData, priorLocation);
2606 	case 6:
2607 		return new PaintingTowerElevatorWheel(_vm, viewWindow, sceneStaticData, priorLocation);
2608 	case 7:
2609 		return new WalkDownPaintingTowerElevator(_vm, viewWindow, sceneStaticData, priorLocation);
2610 	case 8:
2611 		return new PaintingTowerWalkOntoElevator(_vm, viewWindow, sceneStaticData, priorLocation);
2612 	case 9:
2613 		return new ClickChangeScene(_vm, viewWindow, sceneStaticData, priorLocation, 170, 80, 428, 184, kCursorFinger, 5, 1, 8, 3, 0, 0, TRANSITION_VIDEO, 0, -1, -1);
2614 	case 10:
2615 		return new PlaySoundExitingFromScene(_vm, viewWindow, sceneStaticData, priorLocation, 14);
2616 	case 11:
2617 		return new PaintingTowerOutsideDoor(_vm, viewWindow, sceneStaticData, priorLocation);
2618 	case 12:
2619 		return new PaintingTowerInsideDoor(_vm, viewWindow, sceneStaticData, priorLocation);
2620 	case 13:
2621 		return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation, 196, 0, 262, 189, 5, 3, 10, 1, 1, 1, TRANSITION_WALK, 11, 881, 20);
2622 	case 14:
2623 		return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation, 208, 0, 306, 189, 5, 3, 0, 2, 1, 1, TRANSITION_WALK, 11, 740, 23);
2624 	case 15:
2625 		return new ClickPlaySound(_vm, viewWindow, sceneStaticData, priorLocation, -1, 13, kCursorFinger, 0, 0, 384, 189);
2626 	case 16:
2627 		return new PlaySoundExitingFromScene(_vm, viewWindow, sceneStaticData, priorLocation, 14);
2628 	case 17:
2629 		return new ClickPlaySound(_vm, viewWindow, sceneStaticData, priorLocation, offsetof(GlobalFlags, dsGDClickedOnCodexDoor), 13, kCursorFinger, 222, 0, 318, 189);
2630 	case 18:
2631 		return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation, 216, 0, 324, 189, 5, 3, 2, 0, 1, 1, TRANSITION_WALK, 11, 833, 26);
2632 	case 19:
2633 		return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation, 194, 0, 354, 189, 5, 3, 9, 1, 1, 1, TRANSITION_WALK, 11, 791, 21);
2634 	case 20:
2635 		return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation, 102, 0, 208, 189, 5, 4, 14, 0, 1, 1, TRANSITION_WALK, 11, 1169, 28);
2636 	case 21:
2637 		return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation, 80, 0, 250, 189, 5, 4, 15, 3, 1, 1, TRANSITION_WALK, 11, 1126, 26);
2638 	case 22:
2639 		return new ClickPlayVideo(_vm, viewWindow, sceneStaticData, priorLocation, 2, kCursorFinger, 110, 138, 170, 189);
2640 	case 23:
2641 		return new ClickPlayVideo(_vm, viewWindow, sceneStaticData, priorLocation, 4, kCursorFinger, 180, 122, 290, 189);
2642 	case 24:
2643 		return new ClickChangeScene(_vm, viewWindow, sceneStaticData, priorLocation, 186, 28, 292, 158, kCursorMagnifyingGlass, 5, 4, 4, 2, 1, 1, TRANSITION_VIDEO, 5, -1, -1);
2644 	case 25:
2645 		return new ClickChangeSceneTranslate(_vm, viewWindow, sceneStaticData, priorLocation, 0, 0, 432, 189, kCursorPutDown, 5, 4, 4, 2, 1, 0, TRANSITION_VIDEO, 6, -1, -1, 190, 88, 308, 160, IDDS_WORKSHOP_TOOLS_TEXT);
2646 	case 26:
2647 		return new ClickChangeScene(_vm, viewWindow, sceneStaticData, priorLocation, 0, 44, 232, 189, kCursorMagnifyingGlass, 5, 4, 4, 3, 0, 1, TRANSITION_VIDEO, 7, -1, -1);
2648 	case 27:
2649 		return new ClickChangeSceneSetFlag(_vm, viewWindow, sceneStaticData, priorLocation, 0, 0, 432, 189, kCursorPutDown, 5, 4, 4, 3, 0, 0, TRANSITION_VIDEO, 8, -1, -1, offsetof(GlobalFlags, dsWSSeenBallistaSketch));
2650 	case 28:
2651 		return new ClickChangeScene(_vm, viewWindow, sceneStaticData, priorLocation, 112, 52, 380, 189, kCursorMagnifyingGlass, 5, 4, 4, 2, 0, 1, TRANSITION_VIDEO, 9, -1, -1);
2652 	case 29:
2653 		return new ClickChangeSceneSetFlag(_vm, viewWindow, sceneStaticData, priorLocation, 0, 0, 432, 189, kCursorPutDown, 5, 4, 4, 2, 0, 0, TRANSITION_VIDEO, 10, -1, -1, offsetof(GlobalFlags, dsWSSeenBallistaSketch));
2654 	case 30:
2655 		return new ClickChangeScene(_vm, viewWindow, sceneStaticData, priorLocation, 96, 130, 222, 164, kCursorMagnifyingGlass, 5, 4, 7, 3, 1, 1, TRANSITION_VIDEO, 11, -1, -1 );
2656 	case 31:
2657 		return new ClickChangeScene(_vm, viewWindow, sceneStaticData, priorLocation, 0, 0, 432, 189, kCursorPutDown, 5, 4, 7, 3, 1, 0, TRANSITION_VIDEO, 12, -1, -1);
2658 	case 32:
2659 		return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 158, 90, 328, 162, kItemDriveAssembly, 145, offsetof(GlobalFlags, dsWSPickedUpGearAssembly));
2660 	case 33:
2661 		return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 164, 126, 276, 160, kItemWoodenPegs, 96, offsetof(GlobalFlags, dsWSPickedUpPegs));
2662 	case 34:
2663 		return new WheelAssemblyItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 150, 150, 276, 189, kItemWheelAssembly, 100, offsetof(GlobalFlags, dsWSPickedUpWheelAssembly));
2664 	case 35:
2665 		return new ViewSiegeCyclePlans(_vm, viewWindow, sceneStaticData, priorLocation);
2666 	case 36:
2667 		return new AssembleSiegeCycle(_vm, viewWindow, sceneStaticData, priorLocation);
2668 	case 37:
2669 		return new SiegeCycleTopView(_vm, viewWindow, sceneStaticData, priorLocation);
2670 	case 38:
2671 		return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 130, 74, 182, 120, kItemCoilOfRope, 48, offsetof(GlobalFlags, dsGDTakenCoilOfRope));
2672 	case 39:
2673 		return new UnlockCodexTowerDoor(_vm, viewWindow, sceneStaticData, priorLocation);
2674 	case 40:
2675 		return new CodexTowerOutsideDoor(_vm, viewWindow, sceneStaticData, priorLocation);
2676 	case 41:
2677 		return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation, 116, 0, 326, 189, 5, 2, 2, 1, 1, 1, TRANSITION_WALK, 11, 225, 15);
2678 	case 42:
2679 		return new CodexTowerLensEvidenceCapture(_vm, viewWindow, sceneStaticData, priorLocation);
2680 	case 43:
2681 		return new CodexTowerGrabLens(_vm, viewWindow, sceneStaticData, priorLocation);
2682 	case 44:
2683 		return new CodexCabinetOpenDoor(_vm, viewWindow, sceneStaticData, priorLocation);
2684 	case 45:
2685 		return new CodexTowerGrabHeart(_vm, viewWindow, sceneStaticData, priorLocation);
2686 	case 46:
2687 		return new ClickPlayVideo(_vm, viewWindow, sceneStaticData, priorLocation, 8, kCursorFinger, 102, 124, 164, 189);
2688 	case 47:
2689 		return new ZoomInOnCodexes(_vm, viewWindow, sceneStaticData, priorLocation);
2690 	case 48:
2691 		return new BrowseCodex(_vm, viewWindow, sceneStaticData, priorLocation, 5, 2, 3, 1, 0, 0, TRANSITION_VIDEO, 18, -1, -1, 181, 8, -1);
2692 	case 49:
2693 		return new BrowseCodex(_vm, viewWindow, sceneStaticData, priorLocation, 5, 2, 3, 1, 0, 0, TRANSITION_VIDEO, 22, -1, -1, 189, 10, 199);
2694 	case 50:
2695 		return new BrowseCodex(_vm, viewWindow, sceneStaticData, priorLocation, 5, 2, 3, 1, 0, 0, TRANSITION_VIDEO, 20, -1, -1, 173, 8, -1);
2696 	case 51:
2697 		return new ClickChangeScene(_vm, viewWindow, sceneStaticData, priorLocation, 0, 36, 240, 189, kCursorMagnifyingGlass, 5, 2, 4, 0, 0, 1, TRANSITION_VIDEO, 11, -1, -1);
2698 	case 52:
2699 		return new ClickChangeScene(_vm, viewWindow, sceneStaticData, priorLocation, 0, 0, 432, 189, kCursorPutDown, 5, 2, 4, 0, 0, 0, TRANSITION_VIDEO, 12, -1, -1);
2700 	case 53:
2701 		return new ClickChangeScene(_vm, viewWindow, sceneStaticData, priorLocation, 284, 46, 350, 182, kCursorMagnifyingGlass, 5, 2, 0, 2, 1, 1, TRANSITION_VIDEO, 13, -1, -1);
2702 	case 54:
2703 		return new ClickChangeScene(_vm, viewWindow, sceneStaticData, priorLocation, 0, 0, 432, 189, kCursorPutDown, 5, 2, 0, 2, 1, 0, TRANSITION_VIDEO, 14, -1, -1);
2704 	case 55:
2705 		return new ClickChangeScene(_vm, viewWindow, sceneStaticData, priorLocation, 210, 0, 330, 110, kCursorMagnifyingGlass, 5, 2, 3, 4, 1, 1, TRANSITION_VIDEO, 15, -1, -1);
2706 	case 56:
2707 		return new ClickBirdDevice(_vm, viewWindow, sceneStaticData, priorLocation);
2708 	case 57:
2709 		return new CourtyardCannon(_vm, viewWindow, sceneStaticData, priorLocation);
2710 	case 58:
2711 		return new ClickPlayVideoSwitch(_vm, viewWindow, sceneStaticData, priorLocation, 1, kCursorFinger, offsetof(GlobalFlags, dsCYWeebleClicked), 200, 88, 270, 189);
2712 	case 59:
2713 		return new ClickPlayVideo(_vm, viewWindow, sceneStaticData, priorLocation, 2, kCursorFinger, 70, 136, 190, 189);
2714 	case 60:
2715 		return new ClickPlayVideo(_vm, viewWindow, sceneStaticData, priorLocation, 5, kCursorFinger, 42, 0, 418, 100);
2716 	case 61:
2717 		return new ClickPlayVideo(_vm, viewWindow, sceneStaticData, priorLocation, 3, kCursorFinger, 178, 144, 288, 189);
2718 	case 62:
2719 		return new CourtyardGunDeath(_vm, viewWindow, sceneStaticData, priorLocation);
2720 	case 63:
2721 		return new ChangeBallistaDepth(_vm, viewWindow, sceneStaticData, priorLocation);
2722 	case 64:
2723 		return new SpinBallista(_vm, viewWindow, sceneStaticData, priorLocation);
2724 	case 65:
2725 		return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation, 122, 8, 326, 189, 5, 5, 0, 2, 1, 1, TRANSITION_WALK, 11, 738, 18);
2726 	case 66:
2727 		return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation, 170, 0, 432, 189, 5, 4, 0, 0, 1, 1, TRANSITION_WALK, 11, 1220, 12);
2728 	case 67:
2729 		return new PlaceSiegeCycleOnTrack(_vm, viewWindow, sceneStaticData, priorLocation);
2730 	case 68:
2731 		return new AimBallistaAwayFromTower(_vm, viewWindow, sceneStaticData, priorLocation);
2732 	case 69:
2733 		return new AimBallistaToTower(_vm, viewWindow, sceneStaticData, priorLocation);
2734 	case 70:
2735 		return new PaintingTowerCapAgent(_vm, viewWindow, sceneStaticData, priorLocation);
2736 	case 71:
2737 		return new CodexTowerElevatorControls(_vm, viewWindow, sceneStaticData, priorLocation);
2738 	case 72:
2739 		return new PlaySoundExitingFromScene(_vm, viewWindow, sceneStaticData, priorLocation, 13);
2740 	case 73:
2741 		return new LensFilterNotify(_vm, viewWindow, sceneStaticData, priorLocation);
2742 	case 74:
2743 		return new ClickPlaySound(_vm, viewWindow, sceneStaticData, priorLocation, -1, 13, kCursorFinger, 140, 0, 432, 189);
2744 	case 75:
2745 		return new ClickPlaySound(_vm, viewWindow, sceneStaticData, priorLocation, offsetof(GlobalFlags, dsCYTriedElevator), 13, kCursorFinger, 140, 130, 432, 189);
2746 	case 76:
2747 		return new PlaySoundEnteringScene(_vm, viewWindow, sceneStaticData, priorLocation, 12, offsetof(GlobalFlags, dsCTPlayedBallistaFalling));
2748 	case 77:
2749 		return new CodexFormulaeNotify(_vm, viewWindow, sceneStaticData, priorLocation);
2750 	default:
2751 		warning("Unknown Da Vinci scene object %d", sceneStaticData.classID);
2752 		break;
2753 	}
2754 
2755 	return new SceneBase(_vm, viewWindow, sceneStaticData, priorLocation);
2756 }
2757 
2758 } // End of namespace Buried
2759