aboutsummaryrefslogtreecommitdiff
path: root/engines/kyra
diff options
context:
space:
mode:
authorJohannes Schickel2008-05-11 15:24:25 +0000
committerJohannes Schickel2008-05-11 15:24:25 +0000
commit4932660f13b08aa30a88d53c1948c1df190201b7 (patch)
tree3ece7a7c9c96e0b95ef9d0f95ee5a5d01ba89f7a /engines/kyra
parent57dfdbc6c865bfc804fd93b813982b9ca41931e4 (diff)
downloadscummvm-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.cpp447
-rw-r--r--engines/kyra/kyra_mr.cpp13
-rw-r--r--engines/kyra/kyra_mr.h55
-rw-r--r--engines/kyra/script_mr.cpp8
-rw-r--r--engines/kyra/staticres.cpp10
-rw-r--r--engines/kyra/text_mr.cpp133
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()");