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/debug-channels.h"
25 #include "common/file.h"
26 #include "common/fs.h"
27 #include "common/textconsole.h"
28
29 #include "engines/util.h"
30
31 #include "agos/debugger.h"
32 #include "agos/intern.h"
33 #include "agos/agos.h"
34 #include "agos/midi.h"
35 #include "agos/sound.h"
36
37 #include "backends/audiocd/audiocd.h"
38
39 #include "graphics/surface.h"
40
41 #include "audio/mididrv.h"
42
43 namespace AGOS {
44
45 static const GameSpecificSettings simon1_settings = {
46 "", // base_filename
47 "", // restore_filename
48 "", // tbl_filename
49 "EFFECTS", // effects_filename
50 "SIMON", // speech_filename
51 };
52
53 static const GameSpecificSettings simon2_settings = {
54 "", // base_filename
55 "", // restore_filename
56 "", // tbl_filename
57 "", // effects_filename
58 "SIMON2", // speech_filename
59 };
60
61 static const GameSpecificSettings dimp_settings = {
62 "Gdimp", // base_filename
63 "", // restore_filename
64 "", // tbl_filename
65 "", // effects_filename
66 "MUSIC", // speech_filename
67 };
68
69 static const GameSpecificSettings jumble_settings = {
70 "Gjumble", // base_filename
71 "", // restore_filename
72 "", // tbl_filename
73 "", // effects_filename
74 "MUSIC", // speech_filename
75 };
76
77 static const GameSpecificSettings puzzle_settings = {
78 "Gpuzzle", // base_filename
79 "", // restore_filename
80 "", // tbl_filename
81 "", // effects_filename
82 "MUSIC", // speech_filename
83 };
84
85 static const GameSpecificSettings swampy_settings = {
86 "Gswampy", // base_filename
87 "", // restore_filename
88 "", // tbl_filename
89 "", // effects_filename
90 "MUSIC", // speech_filename
91 };
92
93 #ifdef ENABLE_AGOS2
AGOSEngine_DIMP(OSystem * system,const AGOSGameDescription * gd)94 AGOSEngine_DIMP::AGOSEngine_DIMP(OSystem *system, const AGOSGameDescription *gd)
95 : AGOSEngine_PuzzlePack(system, gd) {
96
97 _iconToggleCount = 0;
98 _voiceCount = 0;
99
100 _lastTickCount = 0;
101 _startSecondCount = 0;
102 _tSecondCount = 0;
103 }
104
AGOSEngine_PuzzlePack(OSystem * system,const AGOSGameDescription * gd)105 AGOSEngine_PuzzlePack::AGOSEngine_PuzzlePack(OSystem *system, const AGOSGameDescription *gd)
106 : AGOSEngine_Feeble(system, gd) {
107
108 _oopsValid = false;
109 _gameTime = 0;
110 }
111 #endif
112
AGOSEngine_Simon2(OSystem * system,const AGOSGameDescription * gd)113 AGOSEngine_Simon2::AGOSEngine_Simon2(OSystem *system, const AGOSGameDescription *gd)
114 : AGOSEngine_Simon1(system, gd) {
115 }
116
AGOSEngine_Simon1(OSystem * system,const AGOSGameDescription * gd)117 AGOSEngine_Simon1::AGOSEngine_Simon1(OSystem *system, const AGOSGameDescription *gd)
118 : AGOSEngine_Waxworks(system, gd) {
119 }
120
AGOSEngine_Waxworks(OSystem * system,const AGOSGameDescription * gd)121 AGOSEngine_Waxworks::AGOSEngine_Waxworks(OSystem *system, const AGOSGameDescription *gd)
122 : AGOSEngine_Elvira2(system, gd) {
123
124 _boxCR = false;
125 _boxLineCount = 0;
126 memset(_boxBuffer, 0, sizeof(_boxBuffer));
127 _boxBufferPtr = _boxBuffer;
128
129 _linePtrs[0] = 0;
130 _linePtrs[1] = 0;
131 _linePtrs[2] = 0;
132 _linePtrs[3] = 0;
133 _linePtrs[4] = 0;
134 _linePtrs[5] = 0;
135 memset(_lineCounts, 0, sizeof(_lineCounts));
136 }
137
AGOSEngine_Elvira2(OSystem * system,const AGOSGameDescription * gd)138 AGOSEngine_Elvira2::AGOSEngine_Elvira2(OSystem *system, const AGOSGameDescription *gd)
139 : AGOSEngine_Elvira1(system, gd) {
140 }
141
AGOSEngine_Elvira1(OSystem * system,const AGOSGameDescription * gd)142 AGOSEngine_Elvira1::AGOSEngine_Elvira1(OSystem *system, const AGOSGameDescription *gd)
143 : AGOSEngine(system, gd) {
144 }
145
AGOSEngine(OSystem * system,const AGOSGameDescription * gd)146 AGOSEngine::AGOSEngine(OSystem *system, const AGOSGameDescription *gd)
147 : Engine(system), _rnd("agos"), _gameDescription(gd) {
148
149 DebugMan.addDebugChannel(kDebugOpcode, "opcode", "Opcode debug level");
150 DebugMan.addDebugChannel(kDebugVGAOpcode, "vga_opcode", "VGA Opcode debug level");
151 DebugMan.addDebugChannel(kDebugSubroutine, "subroutine", "Subroutine debug level");
152 DebugMan.addDebugChannel(kDebugVGAScript, "vga_script", "VGA Script debug level");
153 //Image dumping command disabled as it doesn't work well
154 #if 0
155 DebugMan.addDebugChannel(kDebugImageDump, "image_dump", "Enable dumping of images to files");
156 #endif
157 _vcPtr = 0;
158 _vcGetOutOfCode = 0;
159 _gameOffsetsPtr = 0;
160
161 _debugger = 0;
162
163 _gameFile = 0;
164 _opcode = 0;
165
166 _itemMemSize = 0;
167 _tableMemSize = 0;
168 _vgaMemSize = 0;
169
170 _musicIndexBase = 0;
171 _soundIndexBase = 0;
172 _tableIndexBase = 0;
173 _textIndexBase = 0;
174
175 _numMusic = 0;
176 _numSFX = 0;
177 _numSpeech = 0;
178 _numZone = 0;
179
180 _numBitArray1 = 0;
181 _numBitArray2 = 0;
182 _numBitArray3 = 0;
183 _numItemStore = 0;
184 _numTextBoxes = 0;
185 _numVars = 0;
186 _numVideoOpcodes = 0;
187 _vgaBaseDelay = 0;
188 _vgaPeriod = 0;
189
190 _strippedTxtMem = 0;
191 _textMem = 0;
192 _textSize = 0;
193 _stringTabNum = 0;
194 _stringTabPos = 0;
195 _stringTabSize = 0;
196 _stringTabPtr = 0;
197
198 _itemArrayPtr = 0;
199 _itemArraySize = 0;
200 _itemArrayInited = 0;
201
202 _iconFilePtr = 0;
203
204 _codePtr = 0;
205
206 _localStringtable = 0;
207 _stringIdLocalMin = 0;
208 _stringIdLocalMax = 0;
209
210 _roomStates = 0;
211 _numRoomStates = 0;
212
213 _menuBase = 0;
214 _roomsList = 0;
215 _roomsListPtr = 0;
216
217 _xtblList = 0;
218 _xtablesHeapPtrOrg = 0;
219 _xtablesHeapCurPosOrg = 0;
220 _xsubroutineListOrg = 0;
221
222 _tblList = 0;
223 _tablesHeapPtr = 0;
224 _tablesHeapPtrOrg = 0;
225 _tablesheapPtrNew = 0;
226 _tablesHeapSize = 0;
227 _tablesHeapCurPos = 0;
228 _tablesHeapCurPosOrg = 0;
229 _tablesHeapCurPosNew = 0;
230 _subroutineListOrg = 0;
231
232 _subroutineList = 0;
233
234 _recursionDepth = 0;
235
236 _lastVgaTick = 0;
237
238 _marks = 0;
239 _scanFlag = false;
240
241 _scriptVar2 = 0;
242 _runScriptReturn1 = false;
243 _skipVgaWait = false;
244 _noParentNotify = false;
245 _beardLoaded = false;
246 _litBoxFlag = false;
247 _mortalFlag = false;
248 _displayFlag = 0;
249 _syncFlag2 = false;
250 _inCallBack = false;
251 _cepeFlag = false;
252 _fastMode = false;
253
254 _backFlag = false;
255
256 _copyProtection = false;
257 _pause = false;
258 _speech = false;
259 _subtitles = false;
260
261 _animatePointer = 0;
262 _maxCursorWidth = 0;
263 _maxCursorHeight = 0;
264 _mouseAnim = 0;
265 _mouseAnimMax = 0;
266 _mouseCursor = 0;
267 _mouseData = 0;
268 _oldMouseCursor = 0;
269 _currentMouseCursor = 0;
270 _currentMouseAnim = 0;
271 _oldMouseAnimMax = 0;
272
273 _vgaVar9 = 0;
274 _chanceModifier = 0;
275 _restoreWindow6 = 0;
276 _scrollX = 0;
277 _scrollY = 0;
278 _scrollXMax = 0;
279 _scrollYMax = 0;
280 _scrollCount = 0;
281 _scrollFlag = 0;
282 _scrollHeight = 0;
283 _scrollWidth = 0;
284 _scrollImage = 0;
285 _boxStarHeight = 0;
286
287 _scriptVerb = 0;
288 _scriptNoun1 = 0;
289 _scriptNoun2 = 0;
290 _scriptAdj1 = 0;
291 _scriptAdj2 = 0;
292
293 _curWindow = 0;
294 _textWindow = 0;
295
296 _subjectItem = 0;
297 _objectItem = 0;
298 _currentPlayer = 0;
299
300 _iOverflow = false;
301 _nameLocked = false;
302 _hitAreaObjectItem = 0;
303 _lastHitArea = 0;
304 _lastNameOn = 0;
305 _lastHitArea3 = 0;
306 _hitAreaSubjectItem = 0;
307 _currentBox = 0;
308 _currentBoxNum = 0;
309 _currentVerbBox = 0;
310 _lastVerbOn = 0;
311 _needHitAreaRecalc = 0;
312 _verbHitArea = 0;
313 _defaultVerb = 0;
314 _mouseHideCount = 0;
315
316 _dragAccept = false;
317 _dragEnd = false;
318 _dragFlag = false;
319 _dragMode = false;
320 _dragCount = 0;
321 _lastClickRem = 0;
322
323 _windowNum = 0;
324
325 _printCharCurPos = 0;
326 _printCharMaxPos = 0;
327 _printCharPixelCount = 0;
328 _numLettersToPrint = 0;
329
330 _clockStopped = 0;
331 _gameStoppedClock = 0;
332 _lastTime = 0;
333 _lastMinute = 0;
334
335 _firstTimeStruct = 0;
336 _pendingDeleteTimeEvent = 0;
337
338 _initMouse = 0;
339 _leftButtonDown = false;
340 _rightButtonDown = false;
341 _clickOnly = false;
342 _oneClick = 0;
343 _leftClick = 0;
344 _rightClick = 0;
345 _noRightClick = false;
346
347 _leftButton = 0;
348 _leftButtonCount = 0;
349 _leftButtonOld = 0;
350
351 _dummyItem1 = new Item();
352 _dummyItem2 = new Item();
353 _dummyItem3 = new Item();
354
355 _videoLockOut = 0;
356 _scrollUpHitArea = 0;
357 _scrollDownHitArea = 0;
358
359 _noOverWrite = 0;
360 _rejectBlock = false;
361
362 _fastFadeCount = 0;
363 _fastFadeInFlag = 0;
364 _fastFadeOutFlag = 0;
365 _exitCutscene = 0;
366 _paletteFlag = 0;
367 _bottomPalette = false;
368 _picture8600 = 0;
369
370 _soundFileId = 0;
371 _lastMusicPlayed = 0;
372 _nextMusicToPlay = 0;
373 _sampleEnd = 0;
374 _sampleWait = 0;
375
376 _showPreposition = 0;
377 _showMessageFlag = 0;
378
379 _newDirtyClip = false;
380 _wiped = false;
381 _copyScnFlag = 0;
382 _vgaSpriteChanged = 0;
383
384 _block = 0;
385 _blockEnd = 0;
386 _vgaMemPtr = 0;
387 _vgaMemEnd = 0;
388 _vgaMemBase = 0;
389 _vgaFrozenBase = 0;
390 _vgaRealBase = 0;
391 _zoneBuffers = 0;
392
393 _curVgaFile1 = 0;
394 _curVgaFile2 = 0;
395 _curSfxFile = 0;
396 _curSfxFileSize = 0;
397
398 _syncCount = 0;
399
400 _frameCount = 0;
401
402 _zoneNumber = 0;
403
404 _vgaWaitFor = 0;
405 _lastVgaWaitFor = 0;
406
407 _vgaCurZoneNum = 0;
408 _vgaCurSpriteId = 0;
409
410 _baseY = 0;
411 _scale = 0;
412
413 _feebleRect.left = 0;
414 _feebleRect.right = 0;
415 _feebleRect.top = 0;
416 _feebleRect.bottom = 0;
417
418 _scaleX = 0;
419 _scaleY = 0;
420 _scaleWidth = 0;
421 _scaleHeight = 0;
422
423 _nextVgaTimerToProcess = 0;
424
425 _opcode177Var1 = 1;
426 _opcode177Var2 = 0;
427 _opcode178Var1 = 1;
428 _opcode178Var2 = 0;
429
430 _classLine = 0;
431 _classMask = 0;
432 _classMode1 = 0;
433 _classMode2 = 0;
434 _currentLine = 0;
435 _currentTable = 0;
436 _findNextPtr = 0;
437
438 _agosMenu = 0;
439 _currentRoom = 0;
440 _superRoomNumber = 0;
441 _wallOn = 0;
442
443 memset(_objectArray, 0, sizeof(_objectArray));
444 memset(_itemStore, 0, sizeof(_itemStore));
445 memset(_textMenu, 0, sizeof(_textMenu));
446
447 memset(_shortText, 0, sizeof(_shortText));
448 memset(_shortTextX, 0, sizeof(_shortText));
449 memset(_shortTextY, 0, sizeof(_shortText));
450 memset(_longText, 0, sizeof(_longText));
451 memset(_longSound, 0, sizeof(_longSound));
452
453 memset(_bitArray, 0, sizeof(_bitArray));
454 memset(_bitArrayTwo, 0, sizeof(_bitArrayTwo));
455 memset(_bitArrayThree, 0, sizeof(_bitArrayThree));
456
457 _variableArray = 0;
458 _variableArray2 = 0;
459 _variableArrayPtr = 0;
460
461 memset(_windowArray, 0, sizeof(_windowArray));
462
463 memset(_fcsData1, 0, sizeof(_fcsData1));
464 memset(_fcsData2, 0, sizeof(_fcsData2));
465
466 _awaitTwoByteToken = 0;
467 _byteTokens = 0;
468 _byteTokenStrings = 0;
469 _twoByteTokens = 0;
470 _twoByteTokenStrings = 0;
471 _secondTwoByteTokenStrings = 0;
472 _thirdTwoByteTokenStrings = 0;
473 memset(_textBuffer, 0, sizeof(_textBuffer));
474 _textCount = 0;
475
476 _freeStringSlot = 0;
477
478 memset(_stringReturnBuffer, 0, sizeof(_stringReturnBuffer));
479
480 memset(_pathFindArray, 0, sizeof(_pathFindArray));
481
482 memset(_pathValues, 0, sizeof(_pathValues));
483 _PVCount = 0;
484 _GPVCount = 0;
485
486 memset(_pathValues1, 0, sizeof(_pathValues1));
487 _PVCount1 = 0;
488 _GPVCount1 = 0;
489
490 memset(_currentPalette, 0, sizeof(_currentPalette));
491 memset(_displayPalette, 0, sizeof(_displayPalette));
492
493 memset(_videoBuf1, 0, sizeof(_videoBuf1));
494 memset(_videoWindows, 0, sizeof(_videoWindows));
495
496 _dummyWindow = new WindowBlock;
497 _windowList = new WindowBlock[16];
498
499 memset(_lettersToPrintBuf, 0, sizeof(_lettersToPrintBuf));
500
501 _planarBuf = 0;
502
503 _midiEnabled = false;
504
505 _vgaTickCounter = 0;
506
507 _sound = 0;
508
509 _effectsPaused = false;
510 _ambientPaused = false;
511 _musicPaused = false;
512
513 _saveLoadType = 0;
514 _saveLoadSlot = 0;
515 memset(_saveLoadName, 0, sizeof(_saveLoadName));
516 memset(_saveBuf, 0, sizeof(_saveBuf));
517
518 _saveGameNameLen = 0;
519 _saveLoadRowCurPos = 0;
520 _numSaveGameRows = 0;
521 _saveDialogFlag = false;
522 _saveOrLoad = false;
523 _saveLoadEdit = false;
524
525 _hyperLink = 0;
526 _interactY = 0;
527 _oracleMaxScrollY = 0;
528 _noOracleScroll = 0;
529
530 _backGroundBuf = 0;
531 _backBuf = 0;
532 _scaleBuf = 0;
533 _window4BackScn = 0;
534 _window6BackScn = 0;
535
536 _window3Flag = 0;
537 _window4Flag = 0;
538 _window6Flag = 0;
539
540 _moveXMin = 0;
541 _moveYMin = 0;
542 _moveXMax = 0;
543 _moveYMax = 0;
544
545 _vc10BasePtrOld = 0;
546 memcpy (_hebrewCharWidths,
547 "\x5\x5\x4\x6\x5\x3\x4\x5\x6\x3\x5\x5\x4\x6\x5\x3\x4\x6\x5\x6\x6\x6\x5\x5\x5\x6\x5\x6\x6\x6\x6\x6", 32);
548
549
550 const Common::FSNode gameDataDir(ConfMan.get("path"));
551
552 // Add default file directories for Acorn version of
553 // Simon the Sorcerer 1
554 SearchMan.addSubDirectoryMatching(gameDataDir, "execute");
555
556 // Add default file directories for Amiga/Macintosh
557 // versions of Simon the Sorcerer 2
558 SearchMan.addSubDirectoryMatching(gameDataDir, "voices");
559
560 // Add default file directories for Amiga & Macintosh
561 // versions of The Feeble Files
562 SearchMan.addSubDirectoryMatching(gameDataDir, "gfx");
563 SearchMan.addSubDirectoryMatching(gameDataDir, "movies");
564 SearchMan.addSubDirectoryMatching(gameDataDir, "sfx");
565 SearchMan.addSubDirectoryMatching(gameDataDir, "speech");
566 }
567
init()568 Common::Error AGOSEngine::init() {
569 if (getGameId() == GID_DIMP) {
570 _screenWidth = 496;
571 _screenHeight = 400;
572 } else if (getGameType() == GType_FF || getGameType() == GType_PP) {
573 _screenWidth = 640;
574 _screenHeight = 480;
575 } else {
576 _screenWidth = 320;
577 _screenHeight = 200;
578 }
579
580 initGraphics(_screenWidth, _screenHeight);
581
582 _midi = new MidiPlayer();
583
584 if ((getGameType() == GType_SIMON2 && getPlatform() == Common::kPlatformWindows) ||
585 (getGameType() == GType_SIMON1 && getPlatform() == Common::kPlatformWindows) ||
586 ((getFeatures() & GF_TALKIE) && getPlatform() == Common::kPlatformAcorn) ||
587 (getPlatform() == Common::kPlatformDOS)) {
588
589 bool isDemo = (getFeatures() & GF_DEMO) ? true : false;
590
591 int ret = _midi->open(getGameType(), isDemo);
592 if (ret)
593 warning("MIDI Player init failed: \"%s\"", MidiDriver::getErrorName(ret));
594
595 _midi->setVolume(ConfMan.getInt("music_volume"), ConfMan.getInt("sfx_volume"));
596
597 _midiEnabled = true;
598 }
599
600 // Setup mixer
601 syncSoundSettings();
602
603 // allocate buffers
604 _backGroundBuf = new Graphics::Surface();
605 _backGroundBuf->create(_screenWidth, _screenHeight, Graphics::PixelFormat::createFormatCLUT8());
606
607 if (getGameType() == GType_FF || getGameType() == GType_PP) {
608 _backBuf = new Graphics::Surface();
609 _backBuf->create(_screenWidth, _screenHeight, Graphics::PixelFormat::createFormatCLUT8());
610 _scaleBuf = new Graphics::Surface();
611 _scaleBuf->create(_screenWidth, _screenHeight, Graphics::PixelFormat::createFormatCLUT8());
612 }
613
614 if (getGameType() == GType_SIMON2) {
615 _window4BackScn = new Graphics::Surface();
616 _window4BackScn->create(_screenWidth, _screenHeight, Graphics::PixelFormat::createFormatCLUT8());
617 } else if (getGameType() == GType_SIMON1) {
618 _window4BackScn = new Graphics::Surface();
619 _window4BackScn->create(_screenWidth, 134, Graphics::PixelFormat::createFormatCLUT8());
620 } else if (getGameType() == GType_WW || getGameType() == GType_ELVIRA2) {
621 _window4BackScn = new Graphics::Surface();
622 _window4BackScn->create(224, 127, Graphics::PixelFormat::createFormatCLUT8());
623 } else if (getGameType() == GType_ELVIRA1) {
624 _window4BackScn = new Graphics::Surface();
625 if (getPlatform() == Common::kPlatformAmiga && (getFeatures() & GF_DEMO)) {
626 _window4BackScn->create(224, 196, Graphics::PixelFormat::createFormatCLUT8());
627 } else {
628 _window4BackScn->create(224, 144, Graphics::PixelFormat::createFormatCLUT8());
629 }
630 _window6BackScn = new Graphics::Surface();
631 _window6BackScn->create(48, 80, Graphics::PixelFormat::createFormatCLUT8());
632 }
633
634 setupGame();
635
636 _debugger = new Debugger(this);
637 _sound = new Sound(this, gss, _mixer);
638
639 if (ConfMan.hasKey("music_mute") && ConfMan.getBool("music_mute") == 1) {
640 _musicPaused = true;
641 if (_midiEnabled) {
642 _midi->pause(_musicPaused);
643 }
644 _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, 0);
645 }
646
647 if (ConfMan.hasKey("sfx_mute") && ConfMan.getBool("sfx_mute") == 1) {
648 if (getGameId() == GID_SIMON1DOS)
649 _midi->_enable_sfx = !_midi->_enable_sfx;
650 else {
651 _effectsPaused = !_effectsPaused;
652 _sound->effectsPause(_effectsPaused);
653 }
654 }
655
656 _copyProtection = ConfMan.getBool("copy_protection");
657 _language = Common::parseLanguage(ConfMan.get("language"));
658
659 if (getGameType() == GType_PP) {
660 _speech = true;
661 _subtitles = false;
662 } else if (getFeatures() & GF_TALKIE) {
663 _speech = !ConfMan.getBool("speech_mute");
664 _subtitles = ConfMan.getBool("subtitles");
665
666 if (getGameType() == GType_SIMON1) {
667 // English and German versions don't have full subtitles
668 if (_language == Common::EN_ANY || _language == Common::DE_DEU)
669 _subtitles = false;
670 // Other versions require speech to be enabled
671 else
672 _speech = true;
673 }
674
675 // Default to speech only, if both speech and subtitles disabled
676 if (!_speech && !_subtitles)
677 _speech = true;
678 } else {
679 _speech = false;
680 _subtitles = true;
681 }
682
683 return Common::kNoError;
684 }
685
686 static const uint16 initialVideoWindows_Simon[20] = {
687 0, 0, 20, 200,
688 0, 0, 3, 136,
689 17, 0, 3, 136,
690 0, 0, 20, 200,
691 0, 0, 20, 134
692 };
693
694 static const uint16 initialVideoWindows_Common[20] = {
695 3, 0, 14, 136,
696 0, 0, 3, 136,
697 17, 0, 3, 136,
698 0, 0, 20, 200,
699 3, 3, 14, 127,
700 };
701
702 static const uint16 initialVideoWindows_PN[20] = {
703 3, 0, 14, 136,
704 0, 0, 3, 136,
705 17, 0, 3, 136,
706 0, 0, 20, 200,
707 3, 2, 14, 129,
708 };
709
710 #ifdef ENABLE_AGOS2
setupGame()711 void AGOSEngine_PuzzlePack::setupGame() {
712 if (getGameId() == GID_DIMP) {
713 gss = &dimp_settings;
714 } else if (getGameId() == GID_JUMBLE) {
715 gss = &jumble_settings;
716 } else if (getGameId() == GID_PUZZLE) {
717 gss = &puzzle_settings;
718 } else if (getGameId() == GID_SWAMPY) {
719 gss = &swampy_settings;
720 }
721 _numVideoOpcodes = 85;
722 _vgaMemSize = 7500000;
723 _itemMemSize = 20000;
724 _tableMemSize = 200000;
725 _frameCount = 1;
726 _vgaBaseDelay = 5;
727 _vgaPeriod = (getGameId() == GID_DIMP) ? 35 : 30;
728 _numBitArray1 = 128;
729 _numItemStore = 10;
730 _numTextBoxes = 40;
731 _numVars = 2048;
732
733 _numZone = 450;
734
735 AGOSEngine::setupGame();
736 }
737 #endif
738
setupGame()739 void AGOSEngine_Simon2::setupGame() {
740 gss = &simon2_settings;
741 _tableIndexBase = 1580 / 4;
742 _textIndexBase = 1500 / 4;
743 _numVideoOpcodes = 75;
744 #if defined(__DS__)
745 _vgaMemSize = 1300000;
746 #else
747 _vgaMemSize = 2000000;
748 #endif
749 _itemMemSize = 20000;
750 _tableMemSize = 100000;
751 // Check whether to use MT-32 MIDI tracks in Simon the Sorcerer 2
752 if (getGameType() == GType_SIMON2 && _midi->hasNativeMT32())
753 _musicIndexBase = (1128 + 612) / 4;
754 else
755 _musicIndexBase = 1128 / 4;
756 _soundIndexBase = 1660 / 4;
757 _frameCount = 1;
758 _vgaBaseDelay = 1;
759 _vgaPeriod = 45;
760 _numBitArray1 = 16;
761 _numBitArray2 = 16;
762 _numItemStore = 10;
763 _numTextBoxes = 20;
764 _numVars = 255;
765
766 _numMusic = 93;
767 _numSFX = 222;
768 _numSpeech = 11997;
769 _numZone = 140;
770
771 AGOSEngine::setupGame();
772 }
773
setupGame()774 void AGOSEngine_Simon1::setupGame() {
775 gss = &simon1_settings;
776 _tableIndexBase = 1576 / 4;
777 _textIndexBase = 1460 / 4;
778 _numVideoOpcodes = 64;
779 _vgaMemSize = 1000000;
780 _itemMemSize = 20000;
781 _tableMemSize = 50000;
782 _musicIndexBase = 1316 / 4;
783 _soundIndexBase = 0;
784 _frameCount = 1;
785 _vgaBaseDelay = 1;
786 _vgaPeriod = 50;
787 _numBitArray1 = 16;
788 _numBitArray2 = 16;
789 _numItemStore = 10;
790 _numTextBoxes = 20;
791 _numVars = 255;
792
793 _numMusic = 34;
794 _numSFX = 127;
795 _numSpeech = 3623;
796 _numZone = 164;
797
798 AGOSEngine::setupGame();
799 }
800
setupGame()801 void AGOSEngine_Waxworks::setupGame() {
802 gss = &simon1_settings;
803 _numVideoOpcodes = 64;
804 _vgaMemSize = 1000000;
805 _itemMemSize = 80000;
806 _tableMemSize = 50000;
807 _frameCount = 4;
808 _vgaBaseDelay = 1;
809 _vgaPeriod = 50;
810 _numBitArray1 = 16;
811 _numBitArray2 = 15;
812 _numItemStore = 50;
813 _numTextBoxes = 10;
814 _numVars = 255;
815
816 _numMusic = 26;
817 _numZone = 155;
818
819 AGOSEngine::setupGame();
820 }
821
setupGame()822 void AGOSEngine_Elvira2::setupGame() {
823 gss = &simon1_settings;
824 _numVideoOpcodes = 60;
825 _vgaMemSize = 1000000;
826 _itemMemSize = 64000;
827 _tableMemSize = 100000;
828 _frameCount = 4;
829 _vgaBaseDelay = 1;
830 _vgaPeriod = 50;
831 _numBitArray1 = 16;
832 _numBitArray2 = 15;
833 _numItemStore = 50;
834 _numVars = 255;
835
836 _numMusic = 9;
837 _numZone = 99;
838
839 AGOSEngine::setupGame();
840 }
841
setupGame()842 void AGOSEngine_Elvira1::setupGame() {
843 gss = &simon1_settings;
844 _numVideoOpcodes = 57;
845 _vgaMemSize = 1000000;
846 _itemMemSize = 64000;
847 _tableMemSize = 256000;
848 _frameCount = 4;
849 _vgaBaseDelay = 1;
850 _vgaPeriod = 50;
851 _numVars = 512;
852
853 _numMusic = 14;
854 _numZone = 74;
855
856 AGOSEngine::setupGame();
857 }
858
setupGame()859 void AGOSEngine_PN::setupGame() {
860 gss = &simon1_settings;
861 _numVideoOpcodes = 57;
862 _vgaMemSize = 1000000;
863 _frameCount = 4;
864 _vgaBaseDelay = 1;
865 _vgaPeriod = 50;
866 _numVars = 256;
867
868 _numZone = 26;
869
870 AGOSEngine::setupGame();
871 }
872
setupGame()873 void AGOSEngine::setupGame() {
874 allocItemHeap();
875 allocTablesHeap();
876
877 if (getGameType() != GType_SIMON2)
878 initMouse();
879
880 _variableArray = (int16 *)calloc(_numVars, sizeof(int16));
881 _variableArrayPtr = _variableArray;
882 if (getGameType() == GType_FF || getGameType() == GType_PP) {
883 _variableArray2 = (int16 *)calloc(_numVars, sizeof(int16));
884 }
885
886 setupOpcodes();
887 setupVgaOpcodes();
888
889 setZoneBuffers();
890
891 _currentMouseCursor = 255;
892 _currentMouseAnim = 255;
893
894 _lastMusicPlayed = -1;
895 _nextMusicToPlay = -1;
896
897 _noOverWrite = 0xFFFF;
898
899 _stringIdLocalMin = 1;
900
901 _agosMenu = 1;
902 _superRoomNumber = 1;
903
904 for (int i = 0; i < 20; i++) {
905 if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) {
906 _videoWindows[i] = initialVideoWindows_Simon[i];
907 } else if (getGameType() == GType_PN) {
908 _videoWindows[i] = initialVideoWindows_PN[i];
909 } else {
910 _videoWindows[i] = initialVideoWindows_Common[i];
911 }
912 }
913
914 if (getGameType() == GType_ELVIRA2 && getPlatform() == Common::kPlatformAtariST) {
915 _videoWindows[9] = 75;
916 }
917 }
918
~AGOSEngine()919 AGOSEngine::~AGOSEngine() {
920 _system->getAudioCDManager()->stop();
921
922 for (uint i = 0; i < _itemHeap.size(); i++) {
923 delete[] _itemHeap[i];
924 }
925 _itemHeap.clear();
926
927 free(_tablesHeapPtr - _tablesHeapCurPos);
928
929 free(_mouseData);
930
931 free(_gameOffsetsPtr);
932 free(_iconFilePtr);
933 free(_itemArrayPtr);
934 free(_menuBase);
935 free(_roomsList);
936 free(_roomStates);
937 free(_stringTabPtr);
938 free(_strippedTxtMem);
939 free(_tblList);
940 free(_textMem);
941 free(_xtblList);
942
943 if (_backGroundBuf)
944 _backGroundBuf->free();
945 delete _backGroundBuf;
946 if (_backBuf)
947 _backBuf->free();
948 delete _backBuf;
949 free(_planarBuf);
950 if (_scaleBuf)
951 _scaleBuf->free();
952 delete _scaleBuf;
953 free(_zoneBuffers);
954
955 if (_window4BackScn)
956 _window4BackScn->free();
957 delete _window4BackScn;
958 if (_window6BackScn)
959 _window6BackScn->free();
960 delete _window6BackScn;
961
962 delete _midi;
963
964 free(_firstTimeStruct);
965 free(_pendingDeleteTimeEvent);
966
967 free(_variableArray);
968 free(_variableArray2);
969
970 delete _dummyItem1;
971 delete _dummyItem2;
972 delete _dummyItem3;
973
974 delete _dummyWindow;
975 delete[] _windowList;
976
977 delete _debugger;
978 delete _sound;
979 delete _gameFile;
980 }
981
getDebugger()982 GUI::Debugger *AGOSEngine::getDebugger() {
983 return _debugger;
984 }
985
pauseEngineIntern(bool pauseIt)986 void AGOSEngine::pauseEngineIntern(bool pauseIt) {
987 if (pauseIt) {
988 _keyPressed.reset();
989 _pause = true;
990
991 _midi->pause(true);
992 _mixer->pauseAll(true);
993 } else {
994 _pause = false;
995
996 _midi->pause(_musicPaused);
997 _mixer->pauseAll(false);
998 }
999 }
1000
pause()1001 void AGOSEngine::pause() {
1002 pauseEngine(true);
1003
1004 while (_pause && !shouldQuit()) {
1005 delay(1);
1006 if (_keyPressed.keycode == Common::KEYCODE_PAUSE) {
1007 pauseEngine(false);
1008 _keyPressed.reset();
1009 }
1010 }
1011 }
1012
go()1013 Common::Error AGOSEngine::go() {
1014 #ifdef ENABLE_AGOS2
1015 loadArchives();
1016 #endif
1017
1018 loadGamePcFile();
1019
1020 addTimeEvent(0, 1);
1021
1022 if (getFileName(GAME_GMEFILE) != NULL) {
1023 openGameFile();
1024 }
1025
1026 if (getGameType() == GType_FF) {
1027 loadIconData();
1028 } else if (getFileName(GAME_ICONFILE) != NULL) {
1029 loadIconFile();
1030 }
1031
1032 if (getFileName(GAME_MENUFILE) != NULL) {
1033 loadMenuFile();
1034 }
1035
1036 vc34_setMouseOff();
1037
1038 if (getGameType() != GType_PP && getGameType() != GType_FF) {
1039 uint16 count = (getGameType() == GType_SIMON2) ? 5 : _frameCount;
1040 addVgaEvent(count, ANIMATE_INT, NULL, 0, 0);
1041 }
1042
1043 if (getGameType() == GType_ELVIRA1 && getPlatform() == Common::kPlatformAtariST &&
1044 (getFeatures() & GF_DEMO)) {
1045 setWindowImage(3, 9900);
1046 while (!shouldQuit())
1047 delay(0);
1048 }
1049
1050 if (getGameType() == GType_ELVIRA1 && getPlatform() == Common::kPlatformAmiga &&
1051 (getFeatures() & GF_DEMO)) {
1052 playMusic(0, 0);
1053 }
1054
1055 runSubroutine101();
1056 permitInput();
1057
1058 while (!shouldQuit()) {
1059 waitForInput();
1060 handleVerbClicked(_verbHitArea);
1061 delay(100);
1062 }
1063
1064 return Common::kNoError;
1065 }
1066
1067
getTime() const1068 uint32 AGOSEngine::getTime() const {
1069 return _system->getMillis() / 1000;
1070 }
1071
syncSoundSettings()1072 void AGOSEngine::syncSoundSettings() {
1073 Engine::syncSoundSettings();
1074
1075 bool mute = false;
1076 if (ConfMan.hasKey("mute"))
1077 mute = ConfMan.getBool("mute");
1078
1079 // Sync the engine with the config manager
1080 int soundVolumeMusic = ConfMan.getInt("music_volume");
1081 int soundVolumeSFX = ConfMan.getInt("sfx_volume");
1082
1083 if (_midiEnabled)
1084 _midi->setVolume((mute ? 0 : soundVolumeMusic), (mute ? 0 : soundVolumeSFX));
1085 }
1086
1087 } // End of namespace AGOS
1088