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