diff options
author | Johannes Schickel | 2008-05-11 15:24:25 +0000 |
---|---|---|
committer | Johannes Schickel | 2008-05-11 15:24:25 +0000 |
commit | 4932660f13b08aa30a88d53c1948c1df190201b7 (patch) | |
tree | 3ece7a7c9c96e0b95ef9d0f95ee5a5d01ba89f7a /engines/kyra | |
parent | 57dfdbc6c865bfc804fd93b813982b9ca41931e4 (diff) | |
download | scummvm-rg350-4932660f13b08aa30a88d53c1948c1df190201b7.tar.gz scummvm-rg350-4932660f13b08aa30a88d53c1948c1df190201b7.tar.bz2 scummvm-rg350-4932660f13b08aa30a88d53c1948c1df190201b7.zip |
- Implemented kyra3 album (page switch animation not yet implemented)
- Implemented opcode 25: o3_showAlbum
svn-id: r32022
Diffstat (limited to 'engines/kyra')
-rw-r--r-- | engines/kyra/gui_mr.cpp | 447 | ||||
-rw-r--r-- | engines/kyra/kyra_mr.cpp | 13 | ||||
-rw-r--r-- | engines/kyra/kyra_mr.h | 55 | ||||
-rw-r--r-- | engines/kyra/script_mr.cpp | 8 | ||||
-rw-r--r-- | engines/kyra/staticres.cpp | 10 | ||||
-rw-r--r-- | engines/kyra/text_mr.cpp | 133 |
6 files changed, 665 insertions, 1 deletions
diff --git a/engines/kyra/gui_mr.cpp b/engines/kyra/gui_mr.cpp index a7fc742b6f..0408c68317 100644 --- a/engines/kyra/gui_mr.cpp +++ b/engines/kyra/gui_mr.cpp @@ -559,6 +559,7 @@ int KyraEngine_MR::buttonInventory(Button *button) { } int KyraEngine_MR::buttonMoodChange(Button *button) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::buttonMoodChange(%p)", (const void*)button); if (queryGameFlag(0x219)) { snd_playSoundEffect(0x0D, 0xC8); return 0; @@ -626,6 +627,7 @@ int KyraEngine_MR::buttonMoodChange(Button *button) { } int KyraEngine_MR::buttonShowScore(Button *button) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::buttonShowScore(%p)", (const void*)button); strcpy(_stringBuffer, (const char*)getTableEntry(_cCodeFile, 18)); char *buffer = _stringBuffer; @@ -649,6 +651,7 @@ int KyraEngine_MR::buttonShowScore(Button *button) { } int KyraEngine_MR::buttonJesterStaff(Button *button) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::buttonJesterStaff(%p)", (const void*)button); makeCharFacingMouse(); if (_itemInHand == 27) { _screen->hideMouse(); @@ -679,6 +682,450 @@ int KyraEngine_MR::buttonJesterStaff(Button *button) { return 0; } +void KyraEngine_MR::showAlbum() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::showAlbum()"); + if (!_screen->isMouseVisible() || queryGameFlag(4) || _handItemSet != -1) + return; + + if (!loadLanguageFile("ALBUM.", _album.file)) + error("Couldn't load ALBUM"); + + if (!queryGameFlag(0x8B)) + _album.wsa->open("ALBMGNTH.WSA", 1, 0); + _album.backUpRect = new uint8[3100]; + assert(_album.backUpRect); + _album.backUpPage = new uint8[64000]; + assert(_album.backUpPage); + _album.nextPage = _album.curPage; + + _screen->copyRegionToBuffer(0, 0, 0, 320, 200, _screenBuffer); + _screen->copyRegionToBuffer(4, 0, 0, 320, 200, _album.backUpPage); + + memcpy(_screen->getPalette(1), _screen->getPalette(0), 768); + _screen->fadeToBlack(9); + + int itemInHand = _itemInHand; + removeHandItem(); + + _res->loadFileToBuf("ALBUM.COL", _screen->getPalette(0), 768); + loadAlbumPage(); + loadAlbumPageWSA(); + + if (_album.leftPage.wsa->opened()) { + _album.leftPage.wsa->setX(_albumWSAX[_album.nextPage+0]); + _album.leftPage.wsa->setY(_albumWSAY[_album.nextPage+0]); + _album.leftPage.wsa->setDrawPage(2); + + _album.leftPage.wsa->displayFrame(_album.leftPage.curFrame, 0x4000); + } + if (_album.rightPage.wsa->opened()) { + _album.rightPage.wsa->setX(_albumWSAX[_album.nextPage+1]); + _album.rightPage.wsa->setY(_albumWSAY[_album.nextPage+1]); + _album.rightPage.wsa->setDrawPage(2); + + _album.rightPage.wsa->displayFrame(_album.rightPage.curFrame, 0x4000); + } + + printAlbumPageText(); + _screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0, Screen::CR_NO_P_CHECK); + _screen->updateScreen(); + _screen->fadePalette(_screen->getPalette(0), 9); + + processAlbum(); + + _screen->fadeToBlack(9); + _album.wsa->close(); + + setHandItem(itemInHand); + updateMouse(); + + restorePage3(); + _screen->copyBlockToPage(0, 0, 0, 320, 200, _screenBuffer); + _screen->copyBlockToPage(4, 0, 0, 320, 200, _album.backUpPage); + delete[] _album.backUpPage; + _album.backUpPage = 0; + + memcpy(_screen->getPalette(0), _screen->getPalette(1), 768); + _screen->fadePalette(_screen->getPalette(0), 9); + delete[] _album.file; + _album.file = 0; + + _eventList.clear(); +} + +void KyraEngine_MR::loadAlbumPage() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::loadAlbumPage()"); + + char filename[16]; + int num = _album.curPage / 2; + + if (num == 0) { + strcpy(filename, "ALBUM0.CPS"); + } else if (num >= 1 && num <= 6) { + --num; + num %= 2; + snprintf(filename, 16, "ALBUM%d.CPS", num+1); + } else { + strcpy(filename, "ALBUM3.CPS"); + } + + _screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 4, Screen::CR_NO_P_CHECK); + _screen->loadBitmap(filename, 3, 3, 0); +} + +void KyraEngine_MR::loadAlbumPageWSA() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::loadAlbumPageWSA()"); + char filename[16]; + + _album.leftPage.curFrame = 0; + _album.leftPage.maxFrame = 0; + _album.leftPage.wsa->close(); + + _album.rightPage.curFrame = 0; + _album.rightPage.maxFrame = 0; + _album.rightPage.wsa->close(); + + if (_album.curPage) { + snprintf(filename, 16, "PAGE%x.WSA", _album.curPage); + _album.leftPage.wsa->open(filename, 1, 0); + _album.leftPage.maxFrame = _album.leftPage.wsa->frames()-1; + } + + if (_album.curPage != 14) { + snprintf(filename, 16, "PAGE%x.WSA", _album.curPage+1); + _album.rightPage.wsa->open(filename, 1, 0); + _album.rightPage.maxFrame = _album.leftPage.wsa->frames()-1; + } +} + +void KyraEngine_MR::printAlbumPageText() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::printAlbumPageText()"); + + static const uint8 posY[] = { + 0x41, 0x55, 0x55, 0x55, 0x55, 0x55, 0x5A, 0x5A, + 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x3C + }; + + const int leftY = posY[_album.curPage]; + const int rightY = posY[_album.curPage+1]; + + for (int i = 0; i < 5; ++i) { + const char *str = (const char *)getTableEntry(_album.file, _album.curPage*5+i); + int y = i * 10 + leftY + 20; + printAlbumText(2, str, 20, y, 10); + } + + for (int i = 0; i < 5; ++i) { + const char *str = (const char *)getTableEntry(_album.file, (_album.curPage+1)*5+i); + int y = i * 10 + rightY + 20; + printAlbumText(2, str, 176, y, 10); + } + + albumBackUpRect(); +} + +void KyraEngine_MR::printAlbumText(int page, const char *str, int x, int y, uint8 c0) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::printAlbumText(%d, '%s', %d, %d, %d)", page, str, x, y, c0); + int oldPage = _screen->_curPage; + _screen->_curPage = page; + + static const uint8 colorMap[] = { 0, 0x87, 0xA3, 0 }; + _screen->setTextColor(colorMap, 0, 3); + + Screen::FontId oldFont = _screen->setFont(Screen::FID_BOOKFONT_FNT); + _screen->_charWidth = -2; + + _screen->printText(str, x, y, c0, 0); + + _screen->_charWidth = 0; + _screen->setFont(oldFont); + _screen->_curPage = oldPage; +} + +void KyraEngine_MR::processAlbum() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::processAlbum()"); + Button albumButtons[5]; + + GUI_V2_BUTTON(albumButtons[0], 36, 0, 0, 1, 1, 1, 0x4487, 0, 130, 190, 10, 10, 0xFF, 0xF0, 0xFF, 0xF0, 0xFF, 0xF0, 0); + albumButtons[0].buttonCallback = BUTTON_FUNCTOR(KyraEngine_MR, this, &KyraEngine_MR::albumPrevPage); + GUI_V2_BUTTON(albumButtons[1], 37, 0, 0, 1, 1, 1, 0x4487, 0, 177, 190, 10, 10, 0xFF, 0xF0, 0xFF, 0xF0, 0xFF, 0xF0, 0); + albumButtons[1].buttonCallback = BUTTON_FUNCTOR(KyraEngine_MR, this, &KyraEngine_MR::albumNextPage); + GUI_V2_BUTTON(albumButtons[2], 38, 0, 0, 1, 1, 1, 0x4487, 0, 0, 0, 320, 8, 0xFF, 0xF0, 0xFF, 0xF0, 0xFF, 0xF0, 0); + albumButtons[2].buttonCallback = BUTTON_FUNCTOR(KyraEngine_MR, this, &KyraEngine_MR::albumClose); + GUI_V2_BUTTON(albumButtons[3], 39, 0, 0, 1, 1, 1, 0x4487, 0, 8, 8, 144, 180, 0xFF, 0xF0, 0xFF, 0xF0, 0xFF, 0xF0, 0); + albumButtons[3].buttonCallback = BUTTON_FUNCTOR(KyraEngine_MR, this, &KyraEngine_MR::albumPrevPage); + GUI_V2_BUTTON(albumButtons[4], 40, 0, 0, 1, 1, 1, 0x4487, 0, 170, 8, 142, 180, 0xFF, 0xF0, 0xFF, 0xF0, 0xFF, 0xF0, 0); + albumButtons[4].buttonCallback = BUTTON_FUNCTOR(KyraEngine_MR, this, &KyraEngine_MR::albumNextPage); + + Button *buttonList = 0; + for (int i = 0; i < 5; ++i) + buttonList = _gui->addButtonToList(buttonList, &albumButtons[i]); + + _album.leftPage.timer = _album.rightPage.timer = _system->getMillis(); + albumNewPage(); + _album.running = true; + + while (_album.running && !_quitFlag) { + updateInput(); + checkInput(buttonList); + removeInputTop(); + + musicUpdate(0); + + if (_album.curPage != _album.nextPage) { + int oldPage = _album.curPage; + _album.curPage = _album.nextPage; + + _album.leftPage.wsa->close(); + _album.rightPage.wsa->close(); + + loadAlbumPage(); + loadAlbumPageWSA(); + + if (_album.leftPage.wsa->opened()) { + _album.leftPage.wsa->setX(_albumWSAX[_album.nextPage+0]); + _album.leftPage.wsa->setY(_albumWSAY[_album.nextPage+0]); + _album.leftPage.wsa->setDrawPage(2); + + _album.leftPage.wsa->displayFrame(_album.leftPage.curFrame, 0x4000); + } + if (_album.rightPage.wsa->opened()) { + _album.rightPage.wsa->setX(_albumWSAX[_album.nextPage+1]); + _album.rightPage.wsa->setY(_albumWSAY[_album.nextPage+1]); + _album.rightPage.wsa->setDrawPage(2); + + _album.rightPage.wsa->displayFrame(_album.rightPage.curFrame, 0x4000); + } + + printAlbumPageText(); + + snd_playSoundEffect(0x85, 0x80); + albumSwitchPages(oldPage, _album.nextPage, 4); + + _album.leftPage.timer = _album.rightPage.timer = 0; + albumNewPage(); + + _eventList.clear(); + } + + albumUpdateAnims(); + _system->delayMillis(10); + } + + _album.leftPage.wsa->close(); + _album.rightPage.wsa->close(); +} + +void KyraEngine_MR::albumNewPage() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::albumNewPage()"); + int page = _album.nextPage / 2; + if (!queryGameFlag(0x84+page)) { + albumAnim1(); + delayWithTicks(8); + + int id = _album.curPage / 2 + 100; + albumChat((const char *)getTableEntry(_album.file, id), 205, id); + + if (id == 107) { + _screen->copyRegion(76, 100, 76, 100, 244, 100, 2, 0, Screen::CR_NO_P_CHECK); + albumChat((const char *)getTableEntry(_album.file, 108), 205, 108); + _screen->copyRegion(76, 100, 76, 100, 244, 100, 2, 0, Screen::CR_NO_P_CHECK); + albumChat((const char *)getTableEntry(_album.file, 109), 205, 109); + } + + delayWithTicks(5); + albumAnim2(); + + setGameFlag(0x84+page); + _album.isPage14 = (_album.nextPage == 14); + } +} + +void KyraEngine_MR::albumUpdateAnims() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::albumUpdateAnims()"); + if (_album.nextPage == 14 && !_album.isPage14) + return; + + uint32 nextRun = 0; + + nextRun = _album.leftPage.timer + 5 * _tickLength; + if (nextRun < _system->getMillis() && _album.leftPage.wsa->opened()) { + _album.leftPage.wsa->setX(_albumWSAX[_album.nextPage+0]); + _album.leftPage.wsa->setY(_albumWSAY[_album.nextPage+0]); + _album.leftPage.wsa->setDrawPage(2); + + _album.leftPage.wsa->displayFrame(_album.leftPage.curFrame, 0x4000); + _screen->copyRegion(40, 17, 40, 17, 87, 73, 2, 0, Screen::CR_NO_P_CHECK); + + ++_album.leftPage.curFrame; + _album.leftPage.timer = _system->getMillis(); + + if (_album.leftPage.curFrame > _album.leftPage.maxFrame) { + _album.leftPage.curFrame = 0; + if (_album.nextPage == 14) { + _album.isPage14 = false; + _album.leftPage.timer += 100000 * _tickLength; + } else { + _album.leftPage.timer += 180 * _tickLength; + } + } + } + + nextRun = _album.rightPage.timer + 5 * _tickLength; + if (nextRun < _system->getMillis() && _album.rightPage.wsa->opened()) { + _album.rightPage.wsa->setX(_albumWSAX[_album.nextPage+1]); + _album.rightPage.wsa->setY(_albumWSAY[_album.nextPage+1]); + _album.rightPage.wsa->setDrawPage(2); + + _album.rightPage.wsa->displayFrame(_album.rightPage.curFrame, 0x4000); + _screen->copyRegion(194, 20, 194, 20, 85, 69, 2, 0, Screen::CR_NO_P_CHECK); + + ++_album.rightPage.curFrame; + _album.rightPage.timer = _system->getMillis(); + + if (_album.rightPage.curFrame > _album.rightPage.maxFrame) { + _album.rightPage.curFrame = 0; + _album.rightPage.timer += 180 * _tickLength; + } + } + + _screen->updateScreen(); +} + +void KyraEngine_MR::albumAnim1() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::albumAnim1()"); + _album.wsa->setX(-100); + _album.wsa->setY(90); + _album.wsa->setDrawPage(2); + + for (int i = 6; i >= 3; --i) { + albumRestoreRect(); + _album.wsa->displayFrame(i, 0x4000); + albumUpdateRect(); + delayWithTicks(1); + } + + albumRestoreRect(); + _album.wsa->displayFrame(14, 0x4000); + albumUpdateRect(); + delayWithTicks(1); +} + +void KyraEngine_MR::albumAnim2() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::albumAnim2()"); + _album.wsa->setX(-100); + _album.wsa->setY(90); + _album.wsa->setDrawPage(2); + + for (int i = 3; i <= 6; ++i) { + albumRestoreRect(); + _album.wsa->displayFrame(i, 0x4000); + albumUpdateRect(); + delayWithTicks(1); + } + + albumRestoreRect(); + _screen->copyRegion(0, 100, 0, 100, 320, 100, 2, 0, Screen::CR_NO_P_CHECK); + _screen->updateScreen(); +} + +void KyraEngine_MR::albumBackUpRect() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::albumBackUpRect()"); + _screen->copyRegionToBuffer(2, 0, 146, 62, 50, _album.backUpRect); +} + +void KyraEngine_MR::albumRestoreRect() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::albumRestoreRect()"); + _screen->copyBlockToPage(2, 0, 146, 62, 50, _album.backUpRect); +} + +void KyraEngine_MR::albumUpdateRect() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::albumUpdateRect()"); + _screen->copyRegion(0, 146, 0, 146, 62, 50, 2, 0, Screen::CR_NO_P_CHECK); + _screen->updateScreen(); +} + +void KyraEngine_MR::albumSwitchPages(int oldPage, int newPage, int unk) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::albumSwitchPages()"); + if (newPage > oldPage) { + //XXX + + _screen->copyRegion(260, 7, 260, 7, 50, 186, 2, 0, Screen::CR_NO_P_CHECK); + _screen->updateScreen(); + delayWithTicks(1); + + //XXX + + _screen->copyRegion(210, 7, 210, 7, 50, 186, 2, 0, Screen::CR_NO_P_CHECK); + _screen->updateScreen(); + delayWithTicks(1); + + _screen->copyRegion(160, 7, 160, 7, 50, 186, 2, 0, Screen::CR_NO_P_CHECK); + _screen->updateScreen(); + delayWithTicks(1); + + //XXX + delayWithTicks(1); + + //XXX + delayWithTicks(1); + + _screen->copyRegion(10, 7, 10, 7, 150, 186, 2, 0, Screen::CR_NO_P_CHECK); + _screen->updateScreen(); + } else { + //XXX + + _screen->copyRegion(10, 7, 10, 7, 50, 186, 2, 0, Screen::CR_NO_P_CHECK); + _screen->updateScreen(); + delayWithTicks(1); + + //XXX + + _screen->copyRegion(60, 7, 60, 7, 50, 186, 2, 0, Screen::CR_NO_P_CHECK); + _screen->updateScreen(); + delayWithTicks(1); + + _screen->copyRegion(110, 7, 110, 7, 50, 186, 2, 0, Screen::CR_NO_P_CHECK); + _screen->updateScreen(); + delayWithTicks(1); + + //XXX + delayWithTicks(1); + + //XXX + delayWithTicks(1); + + _screen->copyRegion(160, 7, 160, 7, 150, 186, 2, 0, Screen::CR_NO_P_CHECK); + _screen->updateScreen(); + } +} + +int KyraEngine_MR::albumNextPage(Button *caller) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::albumNextPage(%p)", (const void *)caller); + _album.nextPage = _album.curPage + 2; + if (_album.nextPage >= 16) { + _album.nextPage -= 2; + _album.running = false; + } + return 0; +} + +int KyraEngine_MR::albumPrevPage(Button *caller) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::albumPrevPage(%p)", (const void *)caller); + _album.nextPage = _album.curPage - 2; + if (_album.nextPage < 0) { + _album.nextPage = 0; + _album.running = false; + } + return 0; +} + +int KyraEngine_MR::albumClose(Button *caller) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::albumClose(%p)", (const void *)caller); + _album.running = false; + return 0; +} + #pragma mark - GUI_MR::GUI_MR(KyraEngine_MR *vm) : GUI_v2(vm), _vm(vm), _screen(vm->_screen) { diff --git a/engines/kyra/kyra_mr.cpp b/engines/kyra/kyra_mr.cpp index be788f5a64..c89e4eae89 100644 --- a/engines/kyra/kyra_mr.cpp +++ b/engines/kyra/kyra_mr.cpp @@ -144,6 +144,8 @@ KyraEngine_MR::KyraEngine_MR(OSystem *system, const GameFlags &flags) : KyraEngi _optionsFile = 0; _actorFile = 0; _chatAltFlag = false; + _albumChatActive = false; + memset(&_album, 0, sizeof(_album)); } KyraEngine_MR::~KyraEngine_MR() { @@ -191,6 +193,10 @@ KyraEngine_MR::~KyraEngine_MR() { delete[] _mainButtonData; delete _gui; delete[] _optionsFile; + + delete _album.wsa; + delete _album.leftPage.wsa; + delete _album.rightPage.wsa; } int KyraEngine_MR::init() { @@ -542,6 +548,13 @@ void KyraEngine_MR::initMouseShapes() { void KyraEngine_MR::startup() { debugC(9, kDebugLevelMain, "KyraEngine_MR::startup()"); + + _album.wsa = new WSAMovieV2(this, _screen); + assert(_album.wsa); + _album.leftPage.wsa = new WSAMovieV2(this, _screen); + assert(_album.leftPage.wsa); + _album.rightPage.wsa = new WSAMovieV2(this, _screen); + assert(_album.rightPage.wsa); musicUpdate(0); _gamePlayBuffer = new uint8[64000]; diff --git a/engines/kyra/kyra_mr.h b/engines/kyra/kyra_mr.h index 306438ac1b..2921ab7abc 100644 --- a/engines/kyra/kyra_mr.h +++ b/engines/kyra/kyra_mr.h @@ -428,6 +428,11 @@ private: void goodConscienceChat(const char *str, int vocHigh, int vocLow); void goodConscienceChatWaitToFinish(); + bool _albumChatActive; + void albumChat(const char *str, int vocHigh, int vocLow); + void albumChatInit(const char *str, int object, int vocHigh, int vocLow); + void albumChatWaitToFinish(); + void malcolmSceneStartupChat(); byte _newSceneDlgState[40]; @@ -524,6 +529,55 @@ private: void eelScript(); + // Album + struct Album { + uint8 *backUpPage; + uint8 *file; + WSAMovieV2 *wsa; + uint8 *backUpRect; + + struct PageMovie { + WSAMovieV2 *wsa; + int curFrame; + int maxFrame; + uint32 timer; + }; + + PageMovie leftPage, rightPage; + + int curPage, nextPage; + bool running; + bool isPage14; + } _album; + + static const int8 _albumWSAX[]; + static const int8 _albumWSAY[]; + + void showAlbum(); + + void loadAlbumPage(); + void loadAlbumPageWSA(); + + void printAlbumPageText(); + void printAlbumText(int page, const char *str, int x, int y, uint8 c0); + + void processAlbum(); + + void albumNewPage(); + void albumUpdateAnims(); + void albumAnim1(); + void albumAnim2(); + + void albumBackUpRect(); + void albumRestoreRect(); + void albumUpdateRect(); + + void albumSwitchPages(int oldPage, int newPage, int unk); + + int albumNextPage(Button *caller); + int albumPrevPage(Button *caller); + int albumClose(Button *caller); + // save/load void saveGame(const char *fileName, const char *saveName); void loadGame(const char *fileName); @@ -540,6 +594,7 @@ private: int o3_setCharacterAnimFrameFromFacing(EMCState *script); int o3_showBadConscience(EMCState *script); int o3_hideBadConscience(EMCState *script); + int o3_showAlbum(EMCState *script); int o3_setInventorySlot(EMCState *script); int o3_getInventorySlot(EMCState *script); int o3_addItemToInventory(EMCState *script); diff --git a/engines/kyra/script_mr.cpp b/engines/kyra/script_mr.cpp index 6cbe58c0c1..0142a06b7d 100644 --- a/engines/kyra/script_mr.cpp +++ b/engines/kyra/script_mr.cpp @@ -134,6 +134,12 @@ int KyraEngine_MR::o3_hideBadConscience(EMCState *script) { return 0; } +int KyraEngine_MR::o3_showAlbum(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_showAlbum(%p) ()", (const void *)script); + showAlbum(); + return 0; +} + int KyraEngine_MR::o3_setInventorySlot(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_setInventorySlot(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); const int slot = MAX<int16>(0, MIN<int16>(10, stackPos(0))); @@ -1176,7 +1182,7 @@ void KyraEngine_MR::setupOpcodeTable() { Opcode(o3_hideBadConscience); // 0x18 OpcodeUnImpl(); - OpcodeUnImpl(); + Opcode(o3_showAlbum); Opcode(o3_setInventorySlot); Opcode(o3_getInventorySlot); // 0x1c diff --git a/engines/kyra/staticres.cpp b/engines/kyra/staticres.cpp index 051d4d9025..85a822cccf 100644 --- a/engines/kyra/staticres.cpp +++ b/engines/kyra/staticres.cpp @@ -2665,5 +2665,15 @@ void GUI_MR::initStaticData() { _deathMenu.item[i].enabled = false; } +const int8 KyraEngine_MR::_albumWSAX[] = { + 0, 77, -50, 99, -61, 82, -58, 85, + -64, 80, -63, 88, -63, 88, -64, 0 +}; + +const int8 KyraEngine_MR::_albumWSAY[] = { + 0, -1, 3, 0, -1, 0, -2, 0, + -1, -2, 2, 2, -6, -6, -6, 0 +}; + } // End of namespace Kyra diff --git a/engines/kyra/text_mr.cpp b/engines/kyra/text_mr.cpp index 35f91c1ccc..70c24106f9 100644 --- a/engines/kyra/text_mr.cpp +++ b/engines/kyra/text_mr.cpp @@ -131,6 +131,12 @@ int TextDisplayer_MR::dropCRIntoString(char *str, int minOffs, int maxOffs) { void TextDisplayer_MR::printText(const char *str, int x, int y, uint8 c0, uint8 c1, uint8 c2, Screen::FontId font) { debugC(9, kDebugLevelMain, "TextDisplayer_MR::printText('%s', %d, %d, %d, %d, %d)", str, x, y, c0, c1, c2); + if (_vm->_albumChatActive) { + c0 = 0xEE; + c1 = 0xE3; + c2 = 0x00; + } + uint8 colorMap[] = { 0, 255, 240, 240 }; colorMap[3] = c1; _screen->setTextColor(colorMap, 0, 3); @@ -496,6 +502,133 @@ void KyraEngine_MR::goodConscienceChatWaitToFinish() { } } +void KyraEngine_MR::albumChat(const char *str, int vocHigh, int vocLow) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::albumChat('%s', %d, %d)", str, vocHigh, vocLow); + + _talkObjectList[1].x = 190; + _talkObjectList[1].y = 188; + + _chatVocHigh = _chatVocLow = -1; + _albumChatActive = true; + albumChatInit(str, 1, vocHigh, vocLow); + _albumChatActive = false; + + _chatText = str; + _chatObject = 1; + _screen->hideMouse(); + albumChatWaitToFinish(); + _screen->showMouse(); + + _chatText = 0; + _chatObject = -1; +} + +void KyraEngine_MR::albumChatInit(const char *str, int object, int vocHigh, int vocLow) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::albumChatInit('%s', %d, %d, %d)", str, object, vocHigh, vocLow); + Common::String realString; + + while (*str) { + if (str[0] == '\\' && str[1] == 'r') { + realString += '\r'; + ++str; + } else { + realString += *str; + } + + ++str; + } + + str = realString.c_str(); + + str = _text->preprocessString(str); + int lineNum = _text->buildMessageSubstrings(str); + + int xPos = 0, yPos = 0; + + if (!object) { + int scale = getScale(_mainCharacter.x1, _mainCharacter.y1); + yPos = _mainCharacter.y1 - ((_mainCharacter.height * scale) >> 8) - 8; + xPos = _mainCharacter.x1; + } else { + yPos = _talkObjectList[object].y; + xPos = _talkObjectList[object].x; + } + + yPos -= lineNum * 10; + yPos = MAX(yPos, 0); + _text->_talkMessageY = yPos; + _text->_talkMessageH = lineNum*10; + + int width = _text->getWidestLineWidth(lineNum); + _text->calcWidestLineBounds(xPos, yPos, width, xPos); + _text->_talkCoords.x = xPos; + _text->_talkCoords.w = width + 2; + + _screen->hideMouse(); + + if (textEnabled()) { + objectChatPrintText(str, object); + _chatEndTime = _system->getMillis() + chatCalcDuration(str) * _tickLength; + } else { + _chatEndTime = _system->getMillis(); + } + + if (speechEnabled()) { + _chatVocHigh = vocHigh; + _chatVocLow = vocLow; + } else { + _chatVocHigh = _chatVocLow = -1; + } + + _screen->showMouse(); +} + +void KyraEngine_MR::albumChatWaitToFinish() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::albumChatWaitToFinish()"); + if (_chatVocHigh) { + playVoice(_chatVocHigh, _chatVocLow); + _chatVocHigh = _chatVocLow = -1; + } + + bool running = true; + const uint32 endTime = _chatEndTime; + resetSkipFlag(); + + uint32 nextFrame = 0; + int frame = 12; + while (running && !_quitFlag) { + if (nextFrame < _system->getMillis()) { + ++frame; + if (frame > 22) + frame = 13; + + _album.wsa->setX(-100); + _album.wsa->setY(90); + _album.wsa->setDrawPage(2); + + _album.wsa->displayFrame(frame, 0x4000); + albumUpdateRect(); + + nextFrame = _system->getMillis() + _rnd.getRandomNumberRng(4, 8) * _tickLength; + } + + if (_album.nextPage != 14) + albumUpdateAnims(); + else + _screen->updateScreen(); + + const uint32 curTime = _system->getMillis(); + if ((textEnabled() && !speechEnabled() && curTime > endTime) || (speechEnabled() && !snd_voiceIsPlaying()) || skipFlag()) { + snd_stopVoice(); + resetSkipFlag(); + nextFrame = curTime; + running = false; + } + + delay(10); + } +} + void KyraEngine_MR::malcolmSceneStartupChat() { debugC(9, kDebugLevelMain, "KyraEngine_MR::malcolmSceneStartupChat()"); |