1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  */
22 
23 #include "common/config-manager.h"
24 #include "common/file.h"
25 
26 #include "agos/intern.h"
27 #include "agos/agos.h"
28 #include "agos/midi.h"
29 #include "agos/sound.h"
30 #include "agos/vga.h"
31 
32 namespace AGOS {
33 
setVerbText(HitArea * ha)34 uint AGOSEngine::setVerbText(HitArea *ha) {
35 	uint id = 0xFFFF;
36 
37 	if (getGameType() == GType_ELVIRA1 || getGameType() == GType_ELVIRA2)
38 		return id;
39 
40 	if (ha->flags & kBFTextBox) {
41 		if (getGameType() == GType_PP)
42 			id = ha->id;
43 		else if (getGameType() == GType_FF && (ha->flags & kBFHyperBox))
44 			id = ha->data;
45 		else
46 			id = ha->flags / 256;
47 	}
48 	if (getGameType() == GType_PP)
49 		_variableArray[199] = id;
50 	else if (getGameType() == GType_WW)
51 		_variableArray[10] = id;
52 	else
53 		_variableArray[60] = id;
54 
55 	return id;
56 }
57 
setup_cond_c_helper()58 void AGOSEngine::setup_cond_c_helper() {
59 	HitArea *last;
60 
61 	_noRightClick = 1;
62 
63 	if (getGameType() == GType_WW)
64 		clearMenuStrip();
65 
66 	if (getGameType() == GType_FF) {
67 		int cursor = 5;
68 		int animMax = 16;
69 
70 		if (getBitFlag(200)) {
71 			cursor = 11;
72 			animMax = 5;
73 		} else if (getBitFlag(201)) {
74 			cursor = 12;
75 			animMax = 5;
76 		} else if (getBitFlag(202)) {
77 			cursor = 13;
78 			animMax = 5;
79 		} else if (getBitFlag(203)) {
80 			cursor = 14;
81 			animMax = 9;
82 		} else if (getBitFlag(205)) {
83 			cursor = 17;
84 			animMax = 11;
85 		} else if (getBitFlag(206)) {
86 			cursor = 16;
87 			animMax = 2;
88 		} else if (getBitFlag(208)) {
89 			cursor = 26;
90 			animMax = 2;
91 		} else if (getBitFlag(209)) {
92 			cursor = 27;
93 			animMax = 9;
94 		} else if (getBitFlag(210)) {
95 			cursor = 28;
96 			animMax = 9;
97 		}
98 
99 		_animatePointer = false;
100 		_mouseCursor = cursor;
101 		_mouseAnimMax = animMax;
102 		_mouseAnim = 1;
103 		_needHitAreaRecalc++;
104 	}
105 
106 	if (getGameType() == GType_SIMON2) {
107 		_mouseCursor = 0;
108 		if (_defaultVerb != 999) {
109 			_mouseCursor = 9;
110 			_needHitAreaRecalc++;
111 			_defaultVerb = 0;
112 		}
113 	}
114 
115 	_lastHitArea = 0;
116 	_hitAreaObjectItem = NULL;
117 	_nameLocked = false;
118 
119 	last = _lastNameOn;
120 	clearName();
121 	_lastNameOn = last;
122 
123 	while (!shouldQuit()) {
124 		_lastHitArea = NULL;
125 		_lastHitArea3 = 0;
126 		_leftButtonDown = false;
127 
128 		do {
129 			if (_exitCutscene && getBitFlag(9)) {
130 				endCutscene();
131 				goto out_of_here;
132 			}
133 
134 			if (getGameType() == GType_FF) {
135 				if (_variableArray[254] == 63) {
136 					hitarea_stuff_helper_2();
137 				} else if (_variableArray[254] == 75) {
138 					hitarea_stuff_helper_2();
139 					_variableArray[60] = 9999;
140 					goto out_of_here;
141 				}
142 			}
143 
144 			delay(100);
145 		} while ((_lastHitArea3 == (HitArea *) -1 || _lastHitArea3 == 0) && !shouldQuit());
146 
147 		if (_lastHitArea == NULL) {
148 		} else if (_lastHitArea->id == 0x7FFB) {
149 			inventoryUp(_lastHitArea->window);
150 		} else if (_lastHitArea->id == 0x7FFC) {
151 			inventoryDown(_lastHitArea->window);
152 		} else if (_lastHitArea->itemPtr != NULL) {
153 			_hitAreaObjectItem = _lastHitArea->itemPtr;
154 			setVerbText(_lastHitArea);
155 			break;
156 		}
157 	}
158 
159 out_of_here:
160 	_lastHitArea3 = 0;
161 	_lastHitArea = 0;
162 	_lastNameOn = NULL;
163 
164 	_mouseCursor = 0;
165 	_noRightClick = 0;
166 }
167 
waitForInput()168 void AGOSEngine::waitForInput() {
169 	HitArea *ha;
170 	uint id;
171 
172 	_leftButtonDown = false;
173 	_lastHitArea = 0;
174 	//_lastClickRem = 0;
175 	_verbHitArea = 0;
176 	_hitAreaSubjectItem = NULL;
177 	_hitAreaObjectItem = NULL;
178 	_clickOnly = false;
179 	_nameLocked = false;
180 
181 	if (getGameType() == GType_WW) {
182 		_mouseCursor = 0;
183 		_needHitAreaRecalc++;
184 		clearMenuStrip();
185 	} else {
186 		resetVerbs();
187 	}
188 
189 	while (!shouldQuit()) {
190 		_lastHitArea = NULL;
191 		_lastHitArea3 = NULL;
192 		_dragAccept = true;
193 
194 		while (!shouldQuit()) {
195 			if ((getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) &&
196 					_keyPressed.keycode == Common::KEYCODE_F10)
197 				displayBoxStars();
198 			if (processSpecialKeys()) {
199 				if (getGameId() != GID_DIMP)
200 					goto out_of_here;
201 			}
202 			if (_lastHitArea3 == (HitArea *) -1) {
203 				_lastHitArea = NULL;
204 				_lastHitArea3 = NULL;
205 				_dragAccept = true;
206 			} else {
207 				if (_lastHitArea3 || _dragMode)
208 					break;
209 				hitarea_stuff_helper();
210 				delay(100);
211 			}
212 		}
213 
214 		if (!_lastHitArea3 && _dragMode) {
215 			ha = _lastClickRem;
216 
217 			if (ha == 0 || ha->itemPtr == NULL || !(ha->flags & kBFDragBox)) {
218 				_dragFlag = false;
219 				_dragMode = false;
220 				_dragCount = 0;
221 				_dragEnd = false;
222 				continue;
223 			}
224 
225 			_hitAreaSubjectItem = ha->itemPtr;
226 			_verbHitArea = 500;
227 
228 			do {
229 				processSpecialKeys();
230 				hitarea_stuff_helper();
231 				delay(100);
232 
233 				if (!_dragFlag) {
234 					_dragFlag = false;
235 					_dragMode = false;
236 					_dragCount = 0;
237 					_dragEnd = false;
238 				}
239 			} while (!_dragEnd);
240 
241 			_dragFlag = false;
242 			_dragMode = false;
243 			_dragCount = 0;
244 			_dragEnd = false;
245 
246 			boxController(_mouse.x, _mouse.y, 1);
247 
248 			if (_currentBox != NULL) {
249 				_hitAreaObjectItem = _currentBox->itemPtr;
250 				setVerbText(_currentBox);
251 			}
252 
253 			break;
254 		}
255 
256 		ha = _lastHitArea;
257 		if (ha == NULL) {
258 		} else if (ha->id == 0x7FFB) {
259 			inventoryUp(ha->window);
260 		} else if (ha->id == 0x7FFC) {
261 			inventoryDown(ha->window);
262 		} else if ((getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) &&
263 			(ha->id >= 101 && ha->id < 113)) {
264 			_verbHitArea = ha->verb;
265 			setVerb(ha);
266 			_defaultVerb = 0;
267 		} else {
268 			if (getGameType() == GType_WW) {
269 				if (_mouseCursor == 3)
270 					_verbHitArea = 236;
271 
272 				if (ha->id == 98) {
273 					animate(2, 1, 110, 0, 0, 0);
274 					waitForSync(34);
275 				} else if (ha->id == 108) {
276 					animate(2, 1, 106, 0, 0, 0);
277 					waitForSync(34);
278 				} else if (ha->id == 109) {
279 					animate(2, 1, 107, 0, 0, 0);
280 					waitForSync(34);
281 				} else if (ha->id == 115) {
282 					animate(2, 1, 109, 0, 0, 0);
283 					waitForSync(34);
284 				} else if (ha->id == 116) {
285 					animate(2, 1, 113, 0, 0, 0);
286 					waitForSync(34);
287 				} else if (ha->id == 117) {
288 					animate(2, 1, 112, 0, 0, 0);
289 					waitForSync(34);
290 				} else if (ha->id == 118) {
291 					animate(2, 1, 108, 0, 0, 0);
292 					waitForSync(34);
293 				} else if (ha->id == 119) {
294 					animate(2, 1, 111, 0, 0, 0);
295 					waitForSync(34);
296 				}
297 			}
298 			if (ha->itemPtr && (!ha->verb || _verbHitArea ||
299 					(_hitAreaSubjectItem != ha->itemPtr && (ha->flags & kBFBoxItem)))
300 				) {
301 				_hitAreaSubjectItem = ha->itemPtr;
302 				id = setVerbText(ha);
303 				_nameLocked = false;
304 				displayName(ha);
305 				_nameLocked = true;
306 
307 				if (_verbHitArea) {
308 					break;
309 				}
310 
311 				if (getGameType() == GType_WW)
312 					doMenuStrip(menuFor_ww(ha->itemPtr, id));
313 				else if (getGameType() == GType_ELVIRA2)
314 					doMenuStrip(menuFor_e2(ha->itemPtr));
315 				else if (getGameType() == GType_ELVIRA1)
316 					lightMenuStrip(getUserFlag1(ha->itemPtr, 6));
317 			} else {
318 				if (ha->verb) {
319 					if (getGameType() == GType_WW && _mouseCursor && _mouseCursor < 4) {
320 						_hitAreaSubjectItem = ha->itemPtr;
321 						break;
322 					}
323 
324 					_verbHitArea = ha->verb & 0xBFFF;
325 					if (ha->verb & 0x4000) {
326 						_hitAreaSubjectItem = ha->itemPtr;
327 						break;
328 					}
329 					if (_hitAreaSubjectItem != NULL)
330 						break;
331 
332 					if (getGameType() == GType_WW) {
333 						if (ha->id == 109) {
334 							_mouseCursor = 2;
335 							_needHitAreaRecalc++;
336 						} else if (ha->id == 117) {
337 							_mouseCursor = 3;
338 							_needHitAreaRecalc++;
339 						}
340 					}
341 				}
342 			}
343 		}
344 	}
345 
346 out_of_here:
347 	if (getGameType() == GType_ELVIRA2 || getGameType() == GType_WW)
348 		clearMenuStrip();
349 	else if (getGameType() == GType_ELVIRA1)
350 		unlightMenuStrip();
351 
352 	_nameLocked = false;
353 	_needHitAreaRecalc++;
354 	_dragAccept = false;
355 
356 	if (getGameType() == GType_WW && _mouseCursor < 3)
357 		_mouseCursor = 0;
358 }
359 
hitarea_stuff_helper()360 void AGOSEngine::hitarea_stuff_helper() {
361 	if (getGameType() == GType_SIMON2 || getGameType() == GType_FF ||
362 		getGameType() == GType_PP) {
363 		if (_variableArray[254] || _variableArray[249]) {
364 			hitarea_stuff_helper_2();
365 		}
366 	} else if (getGameType() == GType_ELVIRA2 || getGameType() == GType_WW ||
367 		getGameType() == GType_SIMON1) {
368 		uint subr_id = (uint16)_variableArray[254];
369 		if (subr_id) {
370 			Subroutine *sub = getSubroutineByID(subr_id);
371 			if (sub != NULL) {
372 				startSubroutineEx(sub);
373 				permitInput();
374 			}
375 			_variableArray[254] = 0;
376 			_runScriptReturn1 = false;
377 		}
378 	}
379 
380 	uint32 cur_time = getTime();
381 	if (cur_time != _lastTime) {
382 		_lastTime = cur_time;
383 		if (kickoffTimeEvents())
384 			permitInput();
385 	}
386 
387 	if (getGameId() == GID_DIMP)
388 		delay(200);
389 }
390 
hitarea_stuff_helper_2()391 void AGOSEngine::hitarea_stuff_helper_2() {
392 	uint subr_id;
393 	Subroutine *sub;
394 
395 	subr_id = (uint16)_variableArray[249];
396 	if (subr_id) {
397 		sub = getSubroutineByID(subr_id);
398 		if (sub != NULL) {
399 			_variableArray[249] = 0;
400 			startSubroutineEx(sub);
401 			permitInput();
402 		}
403 		_variableArray[249] = 0;
404 	}
405 
406 	subr_id = (uint16)_variableArray[254];
407 	if (subr_id) {
408 		sub = getSubroutineByID(subr_id);
409 		if (sub != NULL) {
410 			_variableArray[254] = 0;
411 			startSubroutineEx(sub);
412 			permitInput();
413 		}
414 		_variableArray[254] = 0;
415 	}
416 
417 	_runScriptReturn1 = false;
418 }
419 
420 #ifdef ENABLE_AGOS2
handleMouseWheelUp()421 void AGOSEngine_Feeble::handleMouseWheelUp() {
422 	if (getGameType() == GType_PP || !(getBitFlag(99)))
423 		return;
424 
425 	if (_mouse.x >= 128 && _mouse.x <= 515 && _mouse.y >= 102 && _mouse.y <= 206) {
426 		oracleTextDown();
427 	} else if (_mouse.x >= 172 && _mouse.x <= 469 && _mouse.y >= 287 && _mouse.y <= 382) {
428 		HitArea *ha = findBox(0x7FFB);
429 		if (ha != NULL && (ha->flags & kBFBoxInUse)) {
430 			if (!isSpriteLoaded(21, 9) && !isSpriteLoaded(23, 9))
431 				inventoryUp(ha->window);
432 		}
433 	}
434 }
435 
handleMouseWheelDown()436 void AGOSEngine_Feeble::handleMouseWheelDown() {
437 	if (getGameType() == GType_PP || !(getBitFlag(99)))
438 		return;
439 
440 	if (_mouse.x >= 128 && _mouse.x <= 515 && _mouse.y >= 102 && _mouse.y <= 206) {
441 		oracleTextUp();
442 	} else if (_mouse.x >= 172 && _mouse.x <= 469 && _mouse.y >= 287 && _mouse.y <= 382) {
443 		HitArea *ha = findBox(0x7FFC);
444 		if (ha != NULL && (ha->flags & kBFBoxInUse)) {
445 			if (!isSpriteLoaded(21, 9) && !isSpriteLoaded(23, 9))
446 					inventoryDown(ha->window);
447 		}
448 	}
449 }
450 #endif
451 
handleMouseWheelUp()452 void AGOSEngine_Simon1::handleMouseWheelUp() {
453 	HitArea *ha = findBox(206);
454 	if (ha != NULL && (ha->flags & kBFBoxInUse) && !(ha->flags & kBFBoxDead)) {
455 			if (_saveLoadRowCurPos != 1) {
456 				if (_saveLoadRowCurPos < 7)
457 					_saveLoadRowCurPos = 1;
458 				else
459 					_saveLoadRowCurPos -= 1;
460 
461 				_saveLoadEdit = false;
462 				listSaveGames();
463 			}
464 	} else {
465 		AGOSEngine::handleMouseWheelUp();
466 	}
467 }
468 
handleMouseWheelDown()469 void AGOSEngine_Simon1::handleMouseWheelDown() {
470 	HitArea *ha = findBox(207);
471 	if (ha != NULL && (ha->flags & kBFBoxInUse) && !(ha->flags & kBFBoxDead)) {
472 			if (_saveDialogFlag) {
473 				_saveLoadRowCurPos += 1;
474 				if (_saveLoadRowCurPos >= _numSaveGameRows)
475 					_saveLoadRowCurPos = _numSaveGameRows;
476 
477 				_saveLoadEdit = false;
478 				listSaveGames();
479 			}
480 	} else {
481 		AGOSEngine::handleMouseWheelDown();
482 	}
483 }
484 
handleMouseWheelUp()485 void AGOSEngine_Elvira2::handleMouseWheelUp() {
486 	HitArea *ha = findBox(224);
487 	if (ha != NULL && (ha->flags & kBFBoxInUse)) {
488 			_saveGameNameLen = 0;
489 
490 			if (_saveLoadRowCurPos < 3)
491 				_saveLoadRowCurPos = 1;
492 			else
493 				_saveLoadRowCurPos -= 3;
494 
495 			listSaveGames();
496 	} else {
497 		AGOSEngine::handleMouseWheelUp();
498 	}
499 }
500 
handleMouseWheelDown()501 void AGOSEngine_Elvira2::handleMouseWheelDown() {
502 	HitArea *ha =  findBox(224);
503 	if (ha != NULL && (ha->flags & kBFBoxInUse)) {
504 			_saveGameNameLen = 0;
505 			_saveLoadRowCurPos += 3;
506 			if (_saveLoadRowCurPos >= _numSaveGameRows)
507 				_saveLoadRowCurPos = 1;
508 
509 			listSaveGames();
510 	} else {
511 		AGOSEngine::handleMouseWheelDown();
512 	}
513 }
514 
handleMouseWheelUp()515 void AGOSEngine::handleMouseWheelUp() {
516 	HitArea *ha = findBox(0x7FFB);
517 	if (ha != NULL && (ha->flags & kBFBoxInUse)) {
518 		inventoryUp(ha->window);
519 	}
520 }
521 
handleMouseWheelDown()522 void AGOSEngine::handleMouseWheelDown() {
523 	HitArea *ha = findBox(0x7FFC);
524 	if (ha != NULL && (ha->flags & kBFBoxInUse)) {
525 		inventoryDown(ha->window);
526 	}
527 }
528 
permitInput()529 void AGOSEngine::permitInput() {
530 	if (_mortalFlag)
531 		return;
532 
533 	_mortalFlag = true;
534 	justifyOutPut(0);
535 
536 	if (getGameType() == GType_ELVIRA1 || getGameType() == GType_ELVIRA2 || getGameType() == GType_WW) {
537 		int n = 0;
538 		while (n < 8) {
539 			if ((_fcsData1[n]) && (_windowArray[n]) && (_windowArray[n]->flags & 128)) {
540 				_textWindow = _windowArray[n];
541 				waitWindow(_textWindow);
542 				clsCheck(_textWindow);
543 			}
544 			_fcsData1[n]=0;
545 			n++;
546 		}
547 
548 		restartAnimation();
549 	}
550 
551 	_curWindow = 0;
552 	if (_windowArray[0]) {
553 		_textWindow = _windowArray[0];
554 		justifyStart();
555 	}
556 	_mortalFlag = false;
557 
558 }
559 
processSpecialKeys()560 bool AGOSEngine::processSpecialKeys() {
561 	bool verbCode = false;
562 
563 	if (getGameId() == GID_DIMP) {
564 		uint32 t1 = getTime() / 30;
565 		if (!_lastMinute)
566 			_lastMinute = t1;
567 		if (t1 - _lastMinute) {
568 			_variableArray[120] += (t1 - _lastMinute);
569 			_lastMinute = t1;
570 		}
571 	}
572 
573 	if (shouldQuit())
574 		_exitCutscene = true;
575 
576 	switch (_keyPressed.keycode) {
577 	case Common::KEYCODE_UP:
578 		if (getGameType() == GType_PP)
579 			_verbHitArea = 302;
580 		else if (getGameType() == GType_WW)
581 			_verbHitArea = 239;
582 		else if (getGameType() == GType_ELVIRA2 && isBoxDead(101))
583 			_verbHitArea = 200;
584 		else if (getGameType() == GType_ELVIRA1 && isBoxDead(101))
585 			_verbHitArea = 214;
586 		verbCode = true;
587 		break;
588 	case Common::KEYCODE_DOWN:
589 		if (getGameType() == GType_PP)
590 			_verbHitArea = 304;
591 		else if (getGameType() == GType_WW)
592 			_verbHitArea = 241;
593 		else if (getGameType() == GType_ELVIRA2 && isBoxDead(107))
594 			_verbHitArea = 202;
595 		else if (getGameType() == GType_ELVIRA1 && isBoxDead(105))
596 			_verbHitArea = 215;
597 		verbCode = true;
598 		break;
599 	case Common::KEYCODE_RIGHT:
600 		if (getGameType() == GType_PP)
601 			_verbHitArea = 303;
602 		else if (getGameType() == GType_WW)
603 			_verbHitArea = 240;
604 		else if (getGameType() == GType_ELVIRA2 && isBoxDead(102))
605 			_verbHitArea = 201;
606 		else if (getGameType() == GType_ELVIRA1 && isBoxDead(103))
607 			_verbHitArea = 216;
608 		verbCode = true;
609 		break;
610 	case Common::KEYCODE_LEFT:
611 		if (getGameType() == GType_PP)
612 			_verbHitArea = 301;
613 		else if (getGameType() == GType_WW)
614 			_verbHitArea = 242;
615 		else if (getGameType() == GType_ELVIRA2 && isBoxDead(104))
616 			_verbHitArea = 203;
617 		else if (getGameType() == GType_ELVIRA1 && isBoxDead(107))
618 			_verbHitArea = 217;
619 		verbCode = true;
620 		break;
621 	case Common::KEYCODE_ESCAPE:
622 		_exitCutscene = true;
623 		break;
624 	case Common::KEYCODE_F1:
625 		if (getGameType() == GType_SIMON2) {
626 			vcWriteVar(5, 50);
627 			vcWriteVar(86, 0);
628 		} else if (getGameType() == GType_SIMON1) {
629 			vcWriteVar(5, 40);
630 			vcWriteVar(86, 0);
631 		}
632 		break;
633 	case Common::KEYCODE_F2:
634 		if (getGameType() == GType_SIMON2) {
635 			vcWriteVar(5, 75);
636 			vcWriteVar(86, 1);
637 		} else if (getGameType() == GType_SIMON1) {
638 			vcWriteVar(5, 60);
639 			vcWriteVar(86, 1);
640 		}
641 		break;
642 	case Common::KEYCODE_F3:
643 		if (getGameType() == GType_SIMON2) {
644 			vcWriteVar(5, 125);
645 			vcWriteVar(86, 2);
646 		} else if (getGameType() == GType_SIMON1) {
647 			vcWriteVar(5, 100);
648 			vcWriteVar(86, 2);
649 		}
650 		break;
651 	case Common::KEYCODE_F5:
652 		if (getGameType() == GType_SIMON2 || getGameType() == GType_FF)
653 			_exitCutscene = true;
654 		break;
655 	case Common::KEYCODE_F7:
656 		if (getGameType() == GType_FF && getBitFlag(76))
657 			_variableArray[254] = 70;
658 		break;
659 	case Common::KEYCODE_F9:
660 		if (getGameType() == GType_FF)
661 			setBitFlag(73, !getBitFlag(73));
662 		break;
663 	case Common::KEYCODE_F12:
664 		if (getGameType() == GType_PP && getGameId() != GID_DIMP) {
665 			if (!getBitFlag(110)) {
666 				setBitFlag(107, !getBitFlag(107));
667 				_vgaPeriod = (getBitFlag(107) != 0) ? 15 : 30;
668 			}
669 		}
670 		break;
671 	case Common::KEYCODE_PAUSE:
672 		pause();
673 		break;
674 	default:
675 		break;
676 	}
677 
678 	switch (_keyPressed.ascii) {
679 	case 't':
680 		if (getGameType() == GType_FF || (getGameType() == GType_SIMON2 && (getFeatures() & GF_TALKIE)) ||
681 			((getFeatures() & GF_TALKIE) && _language != Common::EN_ANY && _language != Common::DE_DEU)) {
682 			if (_speech)
683 				_subtitles = !_subtitles;
684 		}
685 		break;
686 	case 'v':
687 		if (getGameType() == GType_FF || (getGameType() == GType_SIMON2 && (getFeatures() & GF_TALKIE))) {
688 			if (_subtitles)
689 				_speech = !_speech;
690 		}
691 		break;
692 	case '+':
693 		if (_midiEnabled) {
694 			_midi->setVolume(_midi->getMusicVolume() + 16, _midi->getSFXVolume() + 16);
695 		}
696 		ConfMan.setInt("music_volume", _mixer->getVolumeForSoundType(Audio::Mixer::kMusicSoundType) + 16);
697 		syncSoundSettings();
698 		break;
699 	case '-':
700 		if (_midiEnabled) {
701 			_midi->setVolume(_midi->getMusicVolume() - 16, _midi->getSFXVolume() - 16);
702 		}
703 		ConfMan.setInt("music_volume", _mixer->getVolumeForSoundType(Audio::Mixer::kMusicSoundType) - 16);
704 		syncSoundSettings();
705 		break;
706 	case 'm':
707 		_musicPaused = !_musicPaused;
708 		if (_midiEnabled) {
709 			_midi->pause(_musicPaused);
710 		}
711 		_mixer->pauseHandle(_modHandle, _musicPaused);
712 		syncSoundSettings();
713 		break;
714 	case 's':
715 		if (getGameId() == GID_SIMON1DOS) {
716 			_midi->_enable_sfx = !_midi->_enable_sfx;
717 		} else {
718 			_effectsPaused = !_effectsPaused;
719 			_sound->effectsPause(_effectsPaused);
720 		}
721 		break;
722 	case 'b':
723 		if (getGameType() == GType_SIMON2) {
724 			_ambientPaused = !_ambientPaused;
725 			_sound->ambientPause(_ambientPaused);
726 		}
727 		break;
728 	default:
729 		break;
730 	}
731 
732 	_keyPressed.reset();
733 	return verbCode;
734 }
735 
736 } // End of namespace AGOS
737