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 #ifndef KYRA_KYRA_MR_H 24 #define KYRA_KYRA_MR_H 25 26 #include "kyra/engine/kyra_v2.h" 27 #include "kyra/graphics/screen_mr.h" 28 #include "kyra/script/script.h" 29 #include "kyra/gui/gui_mr.h" 30 31 #include "common/hashmap.h" 32 #include "common/list.h" 33 34 namespace Kyra { 35 36 class SoundDigital_MR; 37 class Screen_MR; 38 class MainMenu; 39 class WSAMovie_v2; 40 class TextDisplayer_MR; 41 struct Button; 42 43 class KyraEngine_MR : public KyraEngine_v2 { 44 friend class TextDisplayer_MR; 45 friend class GUI_MR; 46 public: 47 KyraEngine_MR(OSystem *system, const GameFlags &flags); 48 ~KyraEngine_MR() override; 49 50 // Regarding pausing of the engine: 51 // Idle animation time, item animations and album animations should be taken 52 // care of, but since those would just produce minor glitches it's not that 53 // important. 54 screen()55 Screen *screen() override { return _screen; } screen_v2()56 Screen_v2 *screen_v2() const override { return _screen; } gui()57 GUI *gui() const override { return _gui; } soundDigital()58 SoundDigital_MR *soundDigital() { return _soundDigital; } language()59 int language() const { return _lang; } heliumMode()60 bool heliumMode() const { return _configHelium; } 61 62 Common::Error go() override; 63 64 void playVQA(const char *name); 65 66 private: 67 static const EngineDesc _mrEngineDesc; 68 69 // config 70 bool _configStudio; 71 bool _configSkip; 72 bool _configHelium; 73 int _configVQAQuality; 74 75 void registerDefaultSettings() override; 76 void writeSettings() override; 77 void readSettings() override; 78 79 void initStaticResource(); 80 81 // -- 82 Screen_MR *_screen; 83 SoundDigital_MR *_soundDigital; 84 85 Common::Error init() override; 86 87 void preinit(); 88 void startup(); 89 void runStartupScript(int script, int unk1); 90 91 void setupOpcodeTable() override; 92 93 // input 94 bool skipFlag() const override; 95 void resetSkipFlag(bool removeEvent = true) override; 96 97 // run 98 bool _menuDirectlyToLoad; 99 100 void runLoop(); 101 void handleInput(int x, int y); 102 int inputSceneChange(int x, int y, int unk1, int unk2) override; 103 104 void update() override; 105 void updateWithText() override; 106 void updateMouse(); 107 108 // sound specific 109 private: 110 void playMenuAudioFile(); 111 112 int _musicSoundChannel; 113 int _fadeOutMusicChannel; 114 const char *_menuAudioFile; 115 116 const char *const *_soundList; 117 int _soundListSize; 118 119 void snd_playWanderScoreViaMap(int track, int force) override; 120 void stopMusicTrack(); 121 122 void fadeOutMusic(int ticks); 123 124 void snd_playSoundEffect(int item, int volume) override; 125 126 const uint8 *_sfxFileMap; 127 int _sfxFileMapSize; 128 const char *const *_sfxFileList; 129 int _sfxFileListSize; 130 131 int _voiceSoundChannel; 132 133 void playVoice(int high, int low); 134 void snd_playVoiceFile(int file) override; 135 bool snd_voiceIsPlaying() override; 136 void snd_stopVoice() override; 137 138 int _curStudioSFX; 139 void playStudioSFX(const char *str); 140 141 // gui 142 GUI_MR *_gui; 143 144 Button *_mainButtonData; 145 Button *_mainButtonList; 146 bool _mainButtonListInitialized; 147 void initMainButtonList(bool disable); 148 149 bool _enableInventory; 150 int buttonInventory(Button *button); 151 int buttonMoodChange(Button *button); 152 int buttonShowScore(Button *button); 153 int buttonJesterStaff(Button *button); 154 155 void loadButtonShapes(); 156 int callbackButton1(Button *button); 157 int callbackButton2(Button *button); 158 int callbackButton3(Button *button); 159 160 // -> main menu 161 void initMainMenu(); 162 void uninitMainMenu(); 163 164 MainMenu *_menu; 165 WSAMovie_v2 *_menuAnim; 166 167 // timer 168 void setupTimers() override; 169 170 void setWalkspeed(uint8) override; 171 void setCommandLineRestoreTimer(int secs); 172 173 void timerRestoreCommandLine(int arg); 174 void timerRunSceneScript7(int arg); 175 void timerFleaDeath(int arg); 176 177 uint32 _nextIdleAnim; 178 void setNextIdleAnimTimer(); 179 180 // pathfinder 181 bool lineIsPassable(int x, int y) override; 182 183 private: 184 // main menu 185 const char *const *_mainMenuStrings; 186 int _mainMenuStringsSize; 187 188 // animator 189 uint8 *_gamePlayBuffer; 190 void restorePage3() override; 191 192 void clearAnimObjects() override; 193 194 void animSetupPaletteEntry(AnimObj *anim) override; 195 196 void drawAnimObjects() override; 197 void drawSceneAnimObject(AnimObj *obj, int x, int y, int drawLayer) override; 198 void drawCharacterAnimObject(AnimObj *obj, int x, int y, int drawLayer) override; 199 200 void refreshAnimObjects(int force) override; 201 202 bool _loadingState; 203 void updateItemAnimations(); 204 void updateCharacterAnim(int charId) override; 205 206 void updateSceneAnim(int anim, int newFrame) override; 207 void setupSceneAnimObject(int anim, uint16 flags, int x, int y, int x2, int y2, int w, int h, int unk10, int specialSize, int unk14, int shape, const char *filename); 208 void removeSceneAnimObject(int anim, int refresh); 209 210 int _charBackUpWidth2, _charBackUpHeight2; 211 int _charBackUpWidth, _charBackUpHeight; 212 213 void setCharacterAnimDim(int w, int h) override; 214 void resetCharacterAnimDim() override; 215 216 bool _nextIdleType; 217 void showIdleAnim(); 218 219 const ItemAnimDefinition *_itemAnimDefinition; 220 ActiveItemAnim _activeItemAnim[10]; 221 int _nextAnimItem; 222 223 // interface 224 uint8 *_interface; 225 uint32 _interfaceSize; 226 uint16 _interfaceH; 227 uint8 *_interfaceCommandLine; 228 uint32 _interfaceCommandLineSize; 229 uint16 _interfaceCommandLineY1; 230 uint16 _interfaceCommandLineY2; 231 uint16 _interfaceCommandLineH; 232 233 void loadInterfaceShapes(); 234 void loadInterface(); 235 236 void showMessage(const char *string, uint8 c0, uint8 c1); 237 void showMessageFromCCode(int string, uint8 c0, int); 238 void updateItemCommand(Item item, int str, uint8 c0); 239 240 void updateCommandLine(); 241 void restoreCommandLine(); 242 void updateCLState(); 243 244 int _commandLineY; 245 const char *_shownMessage; 246 bool _restoreCommandLine; 247 bool _inventoryState; 248 int _inventoryScrollSpeed; 249 250 void showInventory(); 251 void hideInventory(); 252 253 void drawMalcolmsMoodText(); 254 void drawMalcolmsMoodPointer(int frame, int page); 255 void drawJestersStaff(int type, int page); 256 257 void drawScore(int page, int x, int y); 258 void drawScoreCounting(int oldScore, int newScore, int drawOld, const int x); 259 int getScoreX(const char *str); 260 261 static const uint8 _inventoryX[]; 262 static const uint8 _inventoryY[]; 263 void redrawInventory(int page); 264 void clearInventorySlot(int slot, int page); 265 void drawInventorySlot(int page, Item item, int slot); 266 267 WSAMovie_v2 *_invWsa; 268 int _invWsaFrame; 269 270 // localization 271 uint8 *_scoreFile; 272 uint8 *_cCodeFile; 273 uint8 *_scenesFile; 274 uint8 *_itemFile; 275 uint8 *_optionsFile; 276 uint8 *_actorFile; 277 uint32 _actorFileSize; 278 uint8 *_sceneStrings; 279 280 uint8 *getTableEntry(uint8 *buffer, int id); 281 void getTableEntry(Common::SeekableReadStream *stream, int id, char *dst); 282 283 // items 284 int8 *_itemBuffer1; 285 int8 *_itemBuffer2; 286 287 static const Item _trashItemList[]; 288 void removeTrashItems(); 289 290 void initItems(); 291 292 int checkItemCollision(int x, int y); 293 294 bool dropItem(int unk1, Item item, int x, int y, int unk2); 295 bool processItemDrop(uint16 sceneId, Item item, int x, int y, int unk1, int unk2); 296 void itemDropDown(int startX, int startY, int dstX, int dstY, int itemSlot, Item item, int remove); 297 void exchangeMouseItem(int itemPos, int runScript); 298 bool pickUpItem(int x, int y, int runScript); 299 300 bool isDropable(int x, int y); 301 302 const uint8 *_itemMagicTable; 303 bool itemListMagic(Item handItem, int itemSlot); 304 bool itemInventoryMagic(Item handItem, int invSlot); 305 306 const uint8 *_itemStringMap; 307 int _itemStringMapSize; 308 static const uint8 _itemStringPickUp[]; 309 static const uint8 _itemStringDrop[]; 310 static const uint8 _itemStringInv[]; 311 312 int getItemCommandStringPickUp(uint16 item); 313 int getItemCommandStringDrop(uint16 item); 314 int getItemCommandStringInv(uint16 item); 315 316 // -> hand item 317 void setItemMouseCursor(); 318 void setMouseCursor(Item item) override; 319 320 // shapes 321 void initMouseShapes(); 322 323 void loadCharacterShapes(int newShapes) override; 324 void updateMalcolmShapes(); 325 326 int _malcolmShapeXOffset, _malcolmShapeYOffset; 327 328 struct ShapeDesc { 329 uint8 width, height; 330 int8 xOffset, yOffset; 331 }; 332 static const ShapeDesc _shapeDescs[]; 333 static const int _shapeDescsSize; 334 335 // scene animation 336 uint8 *_sceneShapes[20]; 337 338 void freeSceneShapes(); 339 340 // voice 341 int _currentTalkFile; 342 void openTalkFile(int file); 343 344 // scene 345 bool _noScriptEnter; 346 void enterNewScene(uint16 scene, int facing, int unk1, int unk2, int unk3) override; 347 void enterNewSceneUnk1(int facing, int unk1, int unk2); 348 void enterNewSceneUnk2(int unk1); 349 int _enterNewSceneLock; 350 351 void unloadScene(); 352 353 void loadScenePal(); 354 void loadSceneMsc(); 355 void initSceneScript(int unk1); 356 void initSceneAnims(int unk1); 357 void initSceneScreen(int unk1); 358 359 int runSceneScript1(int x, int y); 360 int runSceneScript2(); 361 bool _noStartupChat; 362 void runSceneScript4(int unk1); 363 void runSceneScript8(); 364 365 int _sceneMinX, _sceneMaxX; 366 int _maskPageMinY, _maskPageMaxY; 367 368 int trySceneChange(int *moveTable, int unk1, int unk2) override; 369 int checkSceneChange(); 370 371 int8 _sceneDatPalette[45]; 372 int8 _sceneDatLayerTable[15]; 373 struct SceneShapeDesc { 374 // the original saves those variables, we don't, since 375 // they are just needed on scene load 376 /*int x, y; 377 int w, h;*/ 378 int drawX, drawY; 379 }; 380 SceneShapeDesc _sceneShapeDescs[20]; 381 382 int getDrawLayer(int x, int y); 383 384 int getScale(int x, int y) override; 385 int _scaleTable[15]; 386 387 // character 388 int getCharacterWalkspeed() const override; 389 void updateCharAnimFrame(int *table) override; 390 int8 _characterAnimTable[2]; 391 static const uint8 _characterFrameTable[]; 392 393 void updateCharPal(int unk1); 394 int _lastCharPalLayer; 395 bool _charPalUpdate; 396 397 bool checkCharCollision(int x, int y); 398 399 int _malcolmsMood; 400 401 void makeCharFacingMouse(); 402 403 int findFreeInventorySlot(); 404 405 // talk object 406 struct TalkObject { 407 char filename[13]; 408 int8 sceneAnim; 409 int8 sceneScript; 410 int16 x, y; 411 uint8 color; 412 uint8 sceneId; 413 }; 414 415 TalkObject *_talkObjectList; 416 417 bool talkObjectsInCurScene(); 418 419 // chat 420 int chatGetType(const char *text); 421 int chatCalcDuration(const char *text); 422 423 void objectChat(const char *text, int object, int vocHigh, int vocLow); 424 void objectChatInit(const char *text, int object, int vocHigh, int vocLow); 425 void objectChatPrintText(const Common::String &text, int object); 426 void objectChatProcess(const char *script); 427 void objectChatWaitToFinish(); 428 429 void badConscienceChat(const char *str, int vocHigh, int vocLow); 430 void badConscienceChatWaitToFinish(); 431 432 void goodConscienceChat(const char *str, int vocHigh, int vocLow); 433 void goodConscienceChatWaitToFinish(); 434 435 bool _albumChatActive; 436 void albumChat(const char *str, int vocHigh, int vocLow); 437 void albumChatInit(const char *str, int object, int vocHigh, int vocLow); 438 void albumChatWaitToFinish(); 439 440 void malcolmSceneStartupChat(); 441 442 byte _newSceneDlgState[40]; 443 int8 _conversationState[30][30]; 444 bool _chatAltFlag; 445 void setDlgIndex(int index) override; 446 void updateDlgIndex(); 447 448 Common::SeekableReadStream *_cnvFile; 449 Common::SeekableReadStream *_dlgBuffer; 450 int _curDlgChapter, _curDlgIndex, _curDlgLang; 451 void updateDlgBuffer(); 452 void loadDlgHeader(int &vocHighBase, int &vocHighIndex, int &index1, int &index2); 453 454 static const uint8 _vocHighTable[]; 455 bool _isStartupDialog; 456 void processDialog(int vocHighIndex, int vocHighBase, int funcNum); 457 458 EMCData _dialogScriptData; 459 EMCState _dialogScriptState; 460 int _dialogSceneAnim; 461 int _dialogSceneScript; 462 int _dialogScriptFuncStart, _dialogScriptFuncProc, _dialogScriptFuncEnd; 463 464 void dialogStartScript(int object, int funcNum); 465 void dialogEndScript(int object); 466 467 void npcChatSequence(const char *str, int object, int vocHigh, int vocLow); 468 469 Common::Array<const Opcode *> _opcodesDialog; 470 471 int o3d_updateAnim(EMCState *script); 472 int o3d_delay(EMCState *script); 473 474 void randomSceneChat() override; 475 void doDialog(int dlgIndex, int funcNum); 476 477 // conscience 478 bool _badConscienceShown; 479 int _badConscienceAnim; 480 bool _badConsciencePosition; 481 482 static const uint8 _badConscienceFrameTable[]; 483 484 void showBadConscience(); 485 void hideBadConscience(); 486 487 bool _goodConscienceShown; 488 int _goodConscienceAnim; 489 bool _goodConsciencePosition; 490 491 static const uint8 _goodConscienceFrameTable[]; 492 493 void showGoodConscience(); 494 void hideGoodConscience(); 495 496 // special script code 497 bool _useFrameTable; 498 499 int o3a_setCharacterFrame(EMCState *script); 500 int o3a_playSoundEffect(EMCState *script); 501 502 // special shape code 503 int initAnimationShapes(uint8 *filedata) override; 504 void uninitAnimationShapes(int count, uint8 *filedata) override; 505 506 // unk 507 uint8 *_costPalBuffer; 508 uint8 *_paletteOverlay; 509 bool _useActorBuffer; 510 511 int _currentChapter; 512 void changeChapter(int newChapter, int sceneId, int malcolmShapes, int facing); 513 514 static const uint8 _chapterLowestScene[]; 515 516 void loadCostPal(); 517 void loadShadowShape(); 518 void loadExtrasShapes(); 519 520 uint8 *_gfxBackUpRect; 521 void backUpGfxRect32x32(int x, int y); 522 void restoreGfxRect32x32(int x, int y); 523 524 char *_stringBuffer; 525 526 int _score; 527 int _scoreMax; 528 529 const uint8 *_scoreTable; 530 int _scoreTableSize; 531 532 int8 _scoreFlagTable[26]; 533 bool updateScore(int scoreId, int strId); 534 void scoreIncrease(int count, const char *str); 535 536 void eelScript(); 537 538 // Album 539 struct Album { 540 uint8 *backUpPage; 541 uint8 *file; 542 WSAMovie_v2 *wsa; 543 uint8 *backUpRect; 544 545 struct PageMovie { 546 WSAMovie_v2 *wsa; 547 int curFrame; 548 int maxFrame; 549 uint32 timer; 550 }; 551 552 PageMovie leftPage, rightPage; 553 554 int curPage, nextPage; 555 bool running; 556 bool isPage14; 557 } _album; 558 559 static const int8 _albumWSAX[]; 560 static const int8 _albumWSAY[]; 561 562 void showAlbum(); 563 564 void loadAlbumPage(); 565 void loadAlbumPageWSA(); 566 567 void printAlbumPageText(); 568 void printAlbumText(int page, const char *str, int x, int y, uint8 c0); 569 570 void processAlbum(); 571 572 void albumNewPage(); 573 void albumUpdateAnims(); 574 void albumAnim1(); 575 void albumAnim2(); 576 577 void albumBackUpRect(); 578 void albumRestoreRect(); 579 void albumUpdateRect(); 580 581 void albumSwitchPages(int oldPage, int newPage, int srcPage); 582 583 int albumNextPage(Button *caller); 584 int albumPrevPage(Button *caller); 585 int albumClose(Button *caller); 586 587 // save/load 588 Common::Error saveGameStateIntern(int slot, const char *saveName, const Graphics::Surface *thumbnail) override; 589 Common::Error loadGameState(int slot) override; 590 591 // opcodes 592 int o3_getMalcolmShapes(EMCState *script); 593 int o3_setCharacterPos(EMCState *script); 594 int o3_defineObject(EMCState *script); 595 int o3_refreshCharacter(EMCState *script); 596 int o3_getMalcolmsMood(EMCState *script); 597 int o3_getCharacterFrameFromFacing(EMCState *script); 598 int o3_setCharacterFacing(EMCState *script); 599 int o3_showSceneFileMessage(EMCState *script); 600 int o3_setCharacterAnimFrameFromFacing(EMCState *script); 601 int o3_showBadConscience(EMCState *script); 602 int o3_hideBadConscience(EMCState *script); 603 int o3_showAlbum(EMCState *script); 604 int o3_setInventorySlot(EMCState *script); 605 int o3_getInventorySlot(EMCState *script); 606 int o3_addItemToInventory(EMCState *script); 607 int o3_addItemToCurScene(EMCState *script); 608 int o3_objectChat(EMCState *script); 609 int o3_resetInventory(EMCState *script); 610 int o3_removeInventoryItemInstances(EMCState *script); 611 int o3_countInventoryItemInstances(EMCState *script); 612 int o3_npcChatSequence(EMCState *script); 613 int o3_badConscienceChat(EMCState *script); 614 int o3_wipeDownMouseItem(EMCState *script); 615 int o3_setMalcolmsMood(EMCState *script); 616 int o3_updateScore(EMCState *script); 617 int o3_makeSecondChanceSave(EMCState *script); 618 int o3_setSceneFilename(EMCState *script); 619 int o3_removeItemsFromScene(EMCState *script); 620 int o3_disguiseMalcolm(EMCState *script); 621 int o3_drawSceneShape(EMCState *script); 622 int o3_drawSceneShapeOnPage(EMCState *script); 623 int o3_checkInRect(EMCState *script); 624 int o3_updateConversations(EMCState *script); 625 int o3_removeItemSlot(EMCState *script); 626 int o3_setSceneDim(EMCState *script); 627 int o3_setSceneAnimPosAndFrame(EMCState *script); 628 int o3_removeItemInstances(EMCState *script); 629 int o3_disableInventory(EMCState *script); 630 int o3_enableInventory(EMCState *script); 631 int o3_enterNewScene(EMCState *script); 632 int o3_switchScene(EMCState *script); 633 int o3_setMalcolmPos(EMCState *script); 634 int o3_stopMusic(EMCState *script); 635 int o3_playSoundEffect(EMCState *script); 636 int o3_getScore(EMCState *script); 637 int o3_daggerWarning(EMCState *script); 638 int o3_blockOutWalkableRegion(EMCState *script); 639 int o3_showSceneStringsMessage(EMCState *script); 640 int o3_showGoodConscience(EMCState *script); 641 int o3_goodConscienceChat(EMCState *script); 642 int o3_hideGoodConscience(EMCState *script); 643 int o3_defineSceneAnim(EMCState *script); 644 int o3_updateSceneAnim(EMCState *script); 645 int o3_runActorScript(EMCState *script); 646 int o3_doDialog(EMCState *script); 647 int o3_setConversationState(EMCState *script); 648 int o3_getConversationState(EMCState *script); 649 int o3_changeChapter(EMCState *script); 650 int o3_countItemInstances(EMCState *script); 651 int o3_dialogStartScript(EMCState *script); 652 int o3_dialogEndScript(EMCState *script); 653 int o3_customChat(EMCState *script); 654 int o3_customChatFinish(EMCState *script); 655 int o3_setupSceneAnimObject(EMCState *script); 656 int o3_removeSceneAnimObject(EMCState *script); 657 int o3_dummy(EMCState *script); 658 659 // misc 660 TextDisplayer_MR *_text; 661 bool _wasPlayingVQA; 662 663 // resource specific 664 private: 665 static const char *const _languageExtension[]; 666 static const int _languageExtensionSize; 667 668 int loadLanguageFile(const char *file, uint8 *&buffer); 669 }; 670 671 } // End of namespace Kyra 672 673 #endif 674