From 6e0c56996662dec6ccd9e724161e55562b728d8b Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Sun, 11 May 2008 22:32:37 +0000 Subject: Consisteny fixes: - Renamed classes *_v1 -> *_LoK - Renamed files *_v1.* -> *_lok.* - Renamed WSAMovieV1 -> WSAMovie_v1 - Renamed WSAMovieV2 -> WSAMovie_v2 svn-id: r32042 --- engines/kyra/animator_lok.cpp | 691 ++++++++++++++ engines/kyra/animator_lok.h | 132 +++ engines/kyra/animator_v1.cpp | 691 -------------- engines/kyra/animator_v1.h | 132 --- engines/kyra/debugger.cpp | 22 +- engines/kyra/debugger.h | 10 +- engines/kyra/detection.cpp | 4 +- engines/kyra/gui_hof.cpp | 2 +- engines/kyra/gui_lok.cpp | 1115 ++++++++++++++++++++++ engines/kyra/gui_lok.h | 177 ++++ engines/kyra/gui_v1.cpp | 1115 ---------------------- engines/kyra/gui_v1.h | 177 ---- engines/kyra/items_lok.cpp | 944 +++++++++++++++++++ engines/kyra/items_v1.cpp | 944 ------------------- engines/kyra/kyra_hof.cpp | 6 +- engines/kyra/kyra_hof.h | 106 +-- engines/kyra/kyra_lok.cpp | 1044 +++++++++++++++++++++ engines/kyra/kyra_lok.h | 819 ++++++++++++++++ engines/kyra/kyra_mr.cpp | 12 +- engines/kyra/kyra_mr.h | 10 +- engines/kyra/kyra_v1.cpp | 1044 --------------------- engines/kyra/kyra_v1.h | 819 ---------------- engines/kyra/kyra_v2.h | 2 +- engines/kyra/module.mk | 24 +- engines/kyra/saveload_lok.cpp | 300 ++++++ engines/kyra/saveload_v1.cpp | 300 ------ engines/kyra/scene_hof.cpp | 2 +- engines/kyra/scene_lok.cpp | 1284 +++++++++++++++++++++++++ engines/kyra/scene_v1.cpp | 1284 ------------------------- engines/kyra/screen_lok.cpp | 243 +++++ engines/kyra/screen_lok.h | 77 ++ engines/kyra/screen_v1.cpp | 243 ----- engines/kyra/screen_v1.h | 77 -- engines/kyra/script_lok.cpp | 2031 ++++++++++++++++++++++++++++++++++++++++ engines/kyra/script_v1.cpp | 2031 ---------------------------------------- engines/kyra/seqplayer.cpp | 2 +- engines/kyra/seqplayer.h | 6 +- engines/kyra/sequences_hof.cpp | 90 +- engines/kyra/sequences_lok.cpp | 1884 +++++++++++++++++++++++++++++++++++++ engines/kyra/sequences_v1.cpp | 1884 ------------------------------------- engines/kyra/sound_lok.cpp | 83 ++ engines/kyra/sound_v1.cpp | 83 -- engines/kyra/sprites.cpp | 8 +- engines/kyra/sprites.h | 8 +- engines/kyra/staticres.cpp | 90 +- engines/kyra/text_lok.cpp | 399 ++++++++ engines/kyra/text_v1.cpp | 399 -------- engines/kyra/timer_lok.cpp | 180 ++++ engines/kyra/timer_v1.cpp | 180 ---- engines/kyra/wsamovie.cpp | 36 +- engines/kyra/wsamovie.h | 12 +- 51 files changed, 11629 insertions(+), 11629 deletions(-) create mode 100644 engines/kyra/animator_lok.cpp create mode 100644 engines/kyra/animator_lok.h delete mode 100644 engines/kyra/animator_v1.cpp delete mode 100644 engines/kyra/animator_v1.h create mode 100644 engines/kyra/gui_lok.cpp create mode 100644 engines/kyra/gui_lok.h delete mode 100644 engines/kyra/gui_v1.cpp delete mode 100644 engines/kyra/gui_v1.h create mode 100644 engines/kyra/items_lok.cpp delete mode 100644 engines/kyra/items_v1.cpp create mode 100644 engines/kyra/kyra_lok.cpp create mode 100644 engines/kyra/kyra_lok.h delete mode 100644 engines/kyra/kyra_v1.cpp delete mode 100644 engines/kyra/kyra_v1.h create mode 100644 engines/kyra/saveload_lok.cpp delete mode 100644 engines/kyra/saveload_v1.cpp create mode 100644 engines/kyra/scene_lok.cpp delete mode 100644 engines/kyra/scene_v1.cpp create mode 100644 engines/kyra/screen_lok.cpp create mode 100644 engines/kyra/screen_lok.h delete mode 100644 engines/kyra/screen_v1.cpp delete mode 100644 engines/kyra/screen_v1.h create mode 100644 engines/kyra/script_lok.cpp delete mode 100644 engines/kyra/script_v1.cpp create mode 100644 engines/kyra/sequences_lok.cpp delete mode 100644 engines/kyra/sequences_v1.cpp create mode 100644 engines/kyra/sound_lok.cpp delete mode 100644 engines/kyra/sound_v1.cpp create mode 100644 engines/kyra/text_lok.cpp delete mode 100644 engines/kyra/text_v1.cpp create mode 100644 engines/kyra/timer_lok.cpp delete mode 100644 engines/kyra/timer_v1.cpp (limited to 'engines/kyra') diff --git a/engines/kyra/animator_lok.cpp b/engines/kyra/animator_lok.cpp new file mode 100644 index 0000000000..1baa78b203 --- /dev/null +++ b/engines/kyra/animator_lok.cpp @@ -0,0 +1,691 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "common/endian.h" + +#include "kyra/kyra_lok.h" +#include "kyra/screen.h" +#include "kyra/animator_lok.h" +#include "kyra/sprites.h" + +#include "common/system.h" + +namespace Kyra { +Animator_LoK::Animator_LoK(KyraEngine_LoK *vm, OSystem *system) { + _vm = vm; + _screen = vm->screen(); + _initOk = false; + _updateScreen = false; + _system = system; + _screenObjects = _actors = _items = _sprites = _objectQueue = 0; + _noDrawShapesFlag = 0; + + _actorBkgBackUp[0] = new uint8[_screen->getRectSize(8, 69)]; + memset(_actorBkgBackUp[0], 0, _screen->getRectSize(8, 69)); + _actorBkgBackUp[1] = new uint8[_screen->getRectSize(8, 69)]; + memset(_actorBkgBackUp[1], 0, _screen->getRectSize(8, 69)); +} + +Animator_LoK::~Animator_LoK() { + close(); + delete[] _actorBkgBackUp[0]; + delete[] _actorBkgBackUp[1]; +} + +void Animator_LoK::init(int actors_, int items_, int sprites_) { + debugC(9, kDebugLevelAnimator, "Animator_LoK::init(%d, %d, %d)", actors_, items_, sprites_); + _screenObjects = new AnimObject[actors_ + items_ + sprites_]; + assert(_screenObjects); + memset(_screenObjects, 0, sizeof(AnimObject) * (actors_ + items_ + sprites_)); + _actors = _screenObjects; + _sprites = &_screenObjects[actors_]; + _items = &_screenObjects[actors_ + items_]; + _brandonDrawFrame = 113; + + _initOk = true; +} + +void Animator_LoK::close() { + debugC(9, kDebugLevelAnimator, "Animator_LoK::close()"); + if (_initOk) { + _initOk = false; + delete[] _screenObjects; + _screenObjects = _actors = _items = _sprites = _objectQueue = 0; + } +} + +void Animator_LoK::initAnimStateList() { + AnimObject *animStates = _screenObjects; + animStates[0].index = 0; + animStates[0].active = 1; + animStates[0].flags = 0x800; + animStates[0].background = _actorBkgBackUp[0]; + animStates[0].rectSize = _screen->getRectSize(4, 48); + animStates[0].width = 4; + animStates[0].height = 48; + animStates[0].width2 = 4; + animStates[0].height2 = 3; + + for (int i = 1; i <= 4; ++i) { + animStates[i].index = i; + animStates[i].active = 0; + animStates[i].flags = 0x800; + animStates[i].background = _actorBkgBackUp[1]; + animStates[i].rectSize = _screen->getRectSize(4, 64); + animStates[i].width = 4; + animStates[i].height = 48; + animStates[i].width2 = 4; + animStates[i].height2 = 3; + } + + for (int i = 5; i < 16; ++i) { + animStates[i].index = i; + animStates[i].active = 0; + animStates[i].flags = 0; + } + + for (int i = 16; i < 28; ++i) { + animStates[i].index = i; + animStates[i].flags = 0; + animStates[i].background = _vm->_shapes[345+i]; + animStates[i].rectSize = _screen->getRectSize(3, 24); + animStates[i].width = 3; + animStates[i].height = 16; + animStates[i].width2 = 0; + animStates[i].height2 = 0; + } +} + +void Animator_LoK::preserveAllBackgrounds() { + debugC(9, kDebugLevelAnimator, "Animator_LoK::preserveAllBackgrounds()"); + uint8 curPage = _screen->_curPage; + _screen->_curPage = 2; + + AnimObject *curObject = _objectQueue; + while (curObject) { + if (curObject->active && !curObject->disable) { + preserveOrRestoreBackground(curObject, false); + curObject->bkgdChangeFlag = 0; + } + curObject = curObject->nextAnimObject; + } + _screen->_curPage = curPage; +} + +void Animator_LoK::flagAllObjectsForBkgdChange() { + debugC(9, kDebugLevelAnimator, "Animator_LoK::flagAllObjectsForBkgdChange()"); + AnimObject *curObject = _objectQueue; + while (curObject) { + curObject->bkgdChangeFlag = 1; + curObject = curObject->nextAnimObject; + } +} + +void Animator_LoK::flagAllObjectsForRefresh() { + debugC(9, kDebugLevelAnimator, "Animator_LoK::flagAllObjectsForRefresh()"); + AnimObject *curObject = _objectQueue; + while (curObject) { + curObject->refreshFlag = 1; + curObject = curObject->nextAnimObject; + } +} + +void Animator_LoK::restoreAllObjectBackgrounds() { + debugC(9, kDebugLevelAnimator, "Animator_LoK::restoreAllObjectBackground()"); + AnimObject *curObject = _objectQueue; + _screen->_curPage = 2; + + while (curObject) { + if (curObject->active && !curObject->disable) { + preserveOrRestoreBackground(curObject, true); + curObject->x2 = curObject->x1; + curObject->y2 = curObject->y1; + } + curObject = curObject->nextAnimObject; + } + + _screen->_curPage = 0; +} + +void Animator_LoK::preserveAnyChangedBackgrounds() { + debugC(9, kDebugLevelAnimator, "Animator_LoK::preserveAnyChangedBackgrounds()"); + AnimObject *curObject = _objectQueue; + _screen->_curPage = 2; + + while (curObject) { + if (curObject->active && !curObject->disable && curObject->bkgdChangeFlag) { + preserveOrRestoreBackground(curObject, false); + curObject->bkgdChangeFlag = 0; + } + curObject = curObject->nextAnimObject; + } + + _screen->_curPage = 0; +} + +void Animator_LoK::preserveOrRestoreBackground(AnimObject *obj, bool restore) { + debugC(9, kDebugLevelAnimator, "Animator_LoK::preserveOrRestoreBackground(%p, %d)", (const void *)obj, restore); + int x = 0, y = 0, width = obj->width, height = obj->height; + + if (restore) { + x = obj->x2 >> 3; + y = obj->y2; + } else { + x = obj->x1 >> 3; + y = obj->y1; + } + + if (x < 0) + x = 0; + if (y < 0) + y = 0; + + int temp; + + temp = x + width; + if (temp >= 39) + x = 39 - width; + temp = y + height; + if (temp >= 136) + y = 136 - height; + + if (restore) + _screen->copyBlockToPage(_screen->_curPage, x << 3, y, width << 3, height, obj->background); + else + _screen->copyRegionToBuffer(_screen->_curPage, x << 3, y, width << 3, height, obj->background); +} + +void Animator_LoK::prepDrawAllObjects() { + debugC(9, kDebugLevelAnimator, "Animator_LoK::prepDrawAllObjects()"); + AnimObject *curObject = _objectQueue; + int drawPage = 2; + int flagUnk1 = 0, flagUnk2 = 0, flagUnk3 = 0; + if (_noDrawShapesFlag) + return; + if (_vm->_brandonStatusBit & 0x20) + flagUnk1 = 0x200; + if (_vm->_brandonStatusBit & 0x40) + flagUnk2 = 0x4000; + + while (curObject) { + if (curObject->active) { + int xpos = curObject->x1; + int ypos = curObject->y1; + + int drawLayer = 0; + if (!(curObject->flags & 0x800)) + drawLayer = 7; + else if (curObject->disable) + drawLayer = 0; + else + drawLayer = _vm->_sprites->getDrawLayer(curObject->drawY); + + // talking head functionallity + if (_vm->_talkingCharNum != -1 && (_vm->_currentCharacter->currentAnimFrame != 88 || curObject->index != 0)) { + const int16 baseAnimFrameTable1[] = { 0x11, 0x35, 0x59, 0x00, 0x00, 0x00 }; + const int16 baseAnimFrameTable2[] = { 0x15, 0x39, 0x5D, 0x00, 0x00, 0x00 }; + const int8 xOffsetTable1[] = { 2, 4, 0, 5, 2, 0, 0, 0 }; + const int8 xOffsetTable2[] = { 6, 4, 8, 3, 6, 0, 0, 0 }; + const int8 yOffsetTable1[] = { 0, 8, 1, 1, 0, 0, 0, 0 }; + const int8 yOffsetTable2[] = { 0, 8, 1, 1, 0, 0, 0, 0 }; + if (curObject->index == 0 || curObject->index <= 4) { + int shapesIndex = 0; + if (curObject->index == _vm->_charSayUnk3) { + shapesIndex = _vm->_currHeadShape + baseAnimFrameTable1[curObject->index]; + } else { + shapesIndex = baseAnimFrameTable2[curObject->index]; + int temp2 = 0; + if (curObject->index == 2) { + if (_vm->_characterList[2].sceneId == 77 || _vm->_characterList[2].sceneId == 86) + temp2 = 1; + else + temp2 = 0; + } else { + temp2 = 1; + } + + if (!temp2) + shapesIndex = -1; + } + + xpos = curObject->x1; + ypos = curObject->y1; + + int tempX = 0, tempY = 0; + if (curObject->flags & 0x1) { + tempX = (xOffsetTable1[curObject->index] * _brandonScaleX) >> 8; + tempY = yOffsetTable1[curObject->index]; + } else { + tempX = (xOffsetTable2[curObject->index] * _brandonScaleX) >> 8; + tempY = yOffsetTable2[curObject->index]; + } + tempY = (tempY * _brandonScaleY) >> 8; + xpos += tempX; + ypos += tempY; + + if (_vm->_scaleMode && _brandonScaleX != 256) + ++xpos; + + if (curObject->index == 0 && shapesIndex != -1) { + if (!(_vm->_brandonStatusBit & 2)) { + flagUnk3 = 0x100; + if ((flagUnk1 & 0x200) || (flagUnk2 & 0x4000)) + flagUnk3 = 0; + + int tempFlags = 0; + if (flagUnk3 & 0x100) { + tempFlags = curObject->flags & 1; + tempFlags |= 0x800 | flagUnk1 | 0x100; + } + + if (!(flagUnk3 & 0x100) && (flagUnk2 & 0x4000)) { + tempFlags = curObject->flags & 1; + tempFlags |= 0x900 | flagUnk1 | 0x4000; + _screen->drawShape(drawPage, _vm->_shapes[shapesIndex], xpos, ypos, 2, tempFlags | 4, _vm->_brandonPoisonFlagsGFX, int(1), int(_vm->_brandonInvFlag), drawLayer, _brandonScaleX, _brandonScaleY); + } else { + if (!(flagUnk2 & 0x4000)) { + tempFlags = curObject->flags & 1; + tempFlags |= 0x900 | flagUnk1; + } + + _screen->drawShape(drawPage, _vm->_shapes[shapesIndex], xpos, ypos, 2, tempFlags | 4, _vm->_brandonPoisonFlagsGFX, int(1), drawLayer, _brandonScaleX, _brandonScaleY); + } + } + } else { + if (shapesIndex != -1) { + int tempFlags = 0; + if (curObject->flags & 1) + tempFlags = 1; + _screen->drawShape(drawPage, _vm->_shapes[shapesIndex], xpos, ypos, 2, tempFlags | 0x800, drawLayer); + } + } + } + } + + xpos = curObject->x1; + ypos = curObject->y1; + + curObject->flags |= 0x800; + if (curObject->index == 0) { + flagUnk3 = 0x100; + + if (flagUnk1 & 0x200 || flagUnk2 & 0x4000) + flagUnk3 = 0; + + if (_vm->_brandonStatusBit & 2) + curObject->flags &= 0xFFFFFFFE; + + if (!_vm->_scaleMode) { + if (flagUnk3 & 0x100) + _screen->drawShape(drawPage, curObject->sceneAnimPtr, xpos, ypos, 2, curObject->flags | flagUnk1 | 0x100, (uint8*)_vm->_brandonPoisonFlagsGFX, int(1), drawLayer); + else if (flagUnk2 & 0x4000) + _screen->drawShape(drawPage, curObject->sceneAnimPtr, xpos, ypos, 2, curObject->flags | flagUnk1 | 0x4000, int(_vm->_brandonInvFlag), drawLayer); + else + _screen->drawShape(drawPage, curObject->sceneAnimPtr, xpos, ypos, 2, curObject->flags | flagUnk1, drawLayer); + } else { + if (flagUnk3 & 0x100) + _screen->drawShape(drawPage, curObject->sceneAnimPtr, xpos, ypos, 2, curObject->flags | flagUnk1 | 0x104, (uint8*)_vm->_brandonPoisonFlagsGFX, int(1), drawLayer, _brandonScaleX, _brandonScaleY); + else if (flagUnk2 & 0x4000) + _screen->drawShape(drawPage, curObject->sceneAnimPtr, xpos, ypos, 2, curObject->flags | flagUnk1 | 0x4004, int(_vm->_brandonInvFlag), drawLayer, _brandonScaleX, _brandonScaleY); + else + _screen->drawShape(drawPage, curObject->sceneAnimPtr, xpos, ypos, 2, curObject->flags | flagUnk1 | 0x4, drawLayer, _brandonScaleX, _brandonScaleY); + } + } else { + if (curObject->index >= 16 && curObject->index <= 27) + _screen->drawShape(drawPage, curObject->sceneAnimPtr, xpos, ypos, 2, curObject->flags | 4, drawLayer, (int)_vm->_scaleTable[curObject->drawY], (int)_vm->_scaleTable[curObject->drawY]); + else + _screen->drawShape(drawPage, curObject->sceneAnimPtr, xpos, ypos, 2, curObject->flags, drawLayer); + } + } + curObject = curObject->nextAnimObject; + } +} + +void Animator_LoK::copyChangedObjectsForward(int refreshFlag) { + debugC(9, kDebugLevelAnimator, "Animator_LoK::copyChangedObjectsForward(%d)", refreshFlag); + + for (AnimObject *curObject = _objectQueue; curObject; curObject = curObject->nextAnimObject) { + if (curObject->active) { + if (curObject->refreshFlag || refreshFlag) { + int xpos = 0, ypos = 0, width = 0, height = 0; + xpos = (curObject->x1>>3) - (curObject->width2>>3) - 1; + ypos = curObject->y1 - curObject->height2; + width = curObject->width + (curObject->width2>>3) + 2; + height = curObject->height + curObject->height2*2; + + if (xpos < 1) + xpos = 1; + else if (xpos > 39) + continue; + + if (xpos + width > 39) + width = 39 - xpos; + + if (ypos < 8) + ypos = 8; + else if (ypos > 136) + continue; + + if (ypos + height > 136) + height = 136 - ypos; + + _screen->copyRegion(xpos << 3, ypos, xpos << 3, ypos, width << 3, height, 2, 0); + curObject->refreshFlag = 0; + _updateScreen = true; + } + } + } + + if (_updateScreen) { + _screen->updateScreen(); + _updateScreen = false; + } +} + +void Animator_LoK::updateAllObjectShapes() { + debugC(9, kDebugLevelAnimator, "Animator_LoK::updateAllObjectShapes()"); + restoreAllObjectBackgrounds(); + preserveAnyChangedBackgrounds(); + prepDrawAllObjects(); + copyChangedObjectsForward(0); +} + +void Animator_LoK::animRemoveGameItem(int index) { + debugC(9, kDebugLevelAnimator, "Animator_LoK::animRemoveGameItem(%d)", index); + restoreAllObjectBackgrounds(); + + AnimObject *animObj = &_items[index]; + animObj->sceneAnimPtr = 0; + animObj->animFrameNumber = -1; + animObj->refreshFlag = 1; + animObj->bkgdChangeFlag = 1; + updateAllObjectShapes(); + animObj->active = 0; + + objectRemoveQueue(_objectQueue, animObj); +} + +void Animator_LoK::animAddGameItem(int index, uint16 sceneId) { + debugC(9, kDebugLevelAnimator, "Animator_LoK::animRemoveGameItem(%d, %d)", index, sceneId); + restoreAllObjectBackgrounds(); + assert(sceneId < _vm->_roomTableSize); + Room *currentRoom = &_vm->_roomTable[sceneId]; + AnimObject *animObj = &_items[index]; + animObj->active = 1; + animObj->refreshFlag = 1; + animObj->bkgdChangeFlag = 1; + animObj->drawY = currentRoom->itemsYPos[index]; + animObj->sceneAnimPtr = _vm->_shapes[216+currentRoom->itemsTable[index]]; + animObj->animFrameNumber = -1; + animObj->x1 = currentRoom->itemsXPos[index]; + animObj->y1 = currentRoom->itemsYPos[index]; + animObj->x1 -= fetchAnimWidth(animObj->sceneAnimPtr, _vm->_scaleTable[animObj->drawY]) >> 1; + animObj->y1 -= fetchAnimHeight(animObj->sceneAnimPtr, _vm->_scaleTable[animObj->drawY]); + animObj->x2 = animObj->x1; + animObj->y2 = animObj->y1; + animObj->width2 = 0; + animObj->height2 = 0; + _objectQueue = objectQueue(_objectQueue, animObj); + preserveAnyChangedBackgrounds(); + animObj->refreshFlag = 1; + animObj->bkgdChangeFlag = 1; +} + +void Animator_LoK::animAddNPC(int character) { + debugC(9, kDebugLevelAnimator, "Animator_LoK::animAddNPC(%d)", character); + restoreAllObjectBackgrounds(); + AnimObject *animObj = &_actors[character]; + const Character *ch = &_vm->_characterList[character]; + + animObj->active = 1; + animObj->refreshFlag = 1; + animObj->bkgdChangeFlag = 1; + animObj->drawY = ch->y1; + animObj->sceneAnimPtr = _vm->_shapes[ch->currentAnimFrame]; + animObj->x1 = animObj->x2 = ch->x1 + _vm->_defaultShapeTable[ch->currentAnimFrame-7].xOffset; + animObj->y1 = animObj->y2 = ch->y1 + _vm->_defaultShapeTable[ch->currentAnimFrame-7].yOffset; + + if (ch->facing >= 1 && ch->facing <= 3) + animObj->flags |= 1; + else if (ch->facing >= 5 && ch->facing <= 7) + animObj->flags &= 0xFFFFFFFE; + + _objectQueue = objectQueue(_objectQueue, animObj); + preserveAnyChangedBackgrounds(); + animObj->refreshFlag = 1; + animObj->bkgdChangeFlag = 1; +} + +Animator_LoK::AnimObject *Animator_LoK::objectRemoveQueue(AnimObject *queue, AnimObject *rem) { + debugC(9, kDebugLevelAnimator, "Animator_LoK::objectRemoveQueue(%p, %p)", (const void *)queue, (const void *)rem); + AnimObject *cur = queue; + AnimObject *prev = queue; + + while (cur != rem && cur) { + AnimObject *temp = cur->nextAnimObject; + if (!temp) + break; + prev = cur; + cur = temp; + } + + if (cur == queue) { + if (!cur) + return 0; + return cur->nextAnimObject; + } + + if (!cur->nextAnimObject) { + if (cur == rem) { + if (!prev) + return 0; + else + prev->nextAnimObject = 0; + } + } else { + if (cur == rem) + prev->nextAnimObject = rem->nextAnimObject; + } + + return queue; +} + +Animator_LoK::AnimObject *Animator_LoK::objectAddHead(AnimObject *queue, AnimObject *head) { + debugC(9, kDebugLevelAnimator, "Animator_LoK::objectAddHead(%p, %p)", (const void *)queue, (const void *)head); + head->nextAnimObject = queue; + return head; +} + +Animator_LoK::AnimObject *Animator_LoK::objectQueue(AnimObject *queue, AnimObject *add) { + debugC(9, kDebugLevelAnimator, "Animator_LoK::objectQueue(%p, %p)", (const void *)queue, (const void *)add); + if (add->drawY <= queue->drawY || !queue) { + add->nextAnimObject = queue; + return add; + } + AnimObject *cur = queue; + AnimObject *prev = queue; + while (add->drawY > cur->drawY) { + AnimObject *temp = cur->nextAnimObject; + if (!temp) + break; + prev = cur; + cur = temp; + } + + if (add->drawY <= cur->drawY) { + prev->nextAnimObject = add; + add->nextAnimObject = cur; + } else { + cur->nextAnimObject = add; + add->nextAnimObject = 0; + } + return queue; +} + +void Animator_LoK::addObjectToQueue(AnimObject *object) { + debugC(9, kDebugLevelAnimator, "Animator_LoK::addObjectToQueue(%p)", (const void *)object); + if (!_objectQueue) + _objectQueue = objectAddHead(0, object); + else + _objectQueue = objectQueue(_objectQueue, object); +} + +void Animator_LoK::refreshObject(AnimObject *object) { + debugC(9, kDebugLevelAnimator, "Animator_LoK::refreshObject(%p)", (const void *)object); + _objectQueue = objectRemoveQueue(_objectQueue, object); + if (_objectQueue) + _objectQueue = objectQueue(_objectQueue, object); + else + _objectQueue = objectAddHead(0, object); +} + +void Animator_LoK::makeBrandonFaceMouse() { + debugC(9, kDebugLevelAnimator, "Animator_LoK::makeBrandonFaceMouse()"); + Common::Point mouse = _vm->getMousePos(); + if (mouse.x >= _vm->_currentCharacter->x1) + _vm->_currentCharacter->facing = 3; + else + _vm->_currentCharacter->facing = 5; + animRefreshNPC(0); + updateAllObjectShapes(); +} + +int16 Animator_LoK::fetchAnimWidth(const uint8 *shape, int16 mult) { + debugC(9, kDebugLevelAnimator, "Animator_LoK::fetchAnimWidth(%p, %d)", (const void *)shape, mult); + if (_vm->gameFlags().useAltShapeHeader) + shape += 2; + return (((int16)READ_LE_UINT16((shape+3))) * mult) >> 8; +} + +int16 Animator_LoK::fetchAnimHeight(const uint8 *shape, int16 mult) { + debugC(9, kDebugLevelAnimator, "Animator_LoK::fetchAnimHeight(%p, %d)", (const void *)shape, mult); + if (_vm->gameFlags().useAltShapeHeader) + shape += 2; + return (int16)(((int8)*(shape+2)) * mult) >> 8; +} + +void Animator_LoK::setBrandonAnimSeqSize(int width, int height) { + debugC(9, kDebugLevelAnimator, "Animator_LoK::setBrandonAnimSeqSize(%d, %d)", width, height); + restoreAllObjectBackgrounds(); + _brandonAnimSeqSizeWidth = _actors[0].width; + _brandonAnimSeqSizeHeight = _actors[0].height; + _actors[0].width = width + 1; + _actors[0].height = height; + preserveAllBackgrounds(); +} + +void Animator_LoK::resetBrandonAnimSeqSize() { + debugC(9, kDebugLevelAnimator, "Animator_LoK::resetBrandonAnimSeqSize()"); + restoreAllObjectBackgrounds(); + _actors[0].width = _brandonAnimSeqSizeWidth; + _actors[0].height = _brandonAnimSeqSizeHeight; + preserveAllBackgrounds(); +} + +void Animator_LoK::animRefreshNPC(int character) { + debugC(9, kDebugLevelAnimator, "Animator_LoK::animRefreshNPC(%d)", character); + AnimObject *animObj = &_actors[character]; + Character *ch = &_vm->characterList()[character]; + + animObj->refreshFlag = 1; + animObj->bkgdChangeFlag = 1; + int facing = ch->facing; + if (facing >= 1 && facing <= 3) + animObj->flags |= 1; + else if (facing >= 5 && facing <= 7) + animObj->flags &= 0xFFFFFFFE; + + animObj->drawY = ch->y1; + animObj->sceneAnimPtr = _vm->shapes()[ch->currentAnimFrame]; + animObj->animFrameNumber = ch->currentAnimFrame; + if (character == 0) { + if (_vm->brandonStatus() & 10) { + animObj->animFrameNumber = 88; + ch->currentAnimFrame = 88; + } + if (_vm->brandonStatus() & 2) { + animObj->animFrameNumber = _brandonDrawFrame; + ch->currentAnimFrame = _brandonDrawFrame; + animObj->sceneAnimPtr = _vm->shapes()[_brandonDrawFrame]; + if (_vm->_brandonStatusBit0x02Flag) { + ++_brandonDrawFrame; + // TODO: check this + if (_brandonDrawFrame >= 122) { + _brandonDrawFrame = 113; + _vm->_brandonStatusBit0x02Flag = 0; + } + } + } + } + + int xOffset = _vm->_defaultShapeTable[ch->currentAnimFrame-7].xOffset; + int yOffset = _vm->_defaultShapeTable[ch->currentAnimFrame-7].yOffset; + + if (_vm->_scaleMode) { + animObj->x1 = ch->x1; + animObj->y1 = ch->y1; + + int newScale = _vm->_scaleTable[ch->y1]; + _brandonScaleX = newScale; + _brandonScaleY = newScale; + + animObj->x1 += (_brandonScaleX * xOffset) >> 8; + animObj->y1 += (_brandonScaleY * yOffset) >> 8; + } else { + animObj->x1 = ch->x1 + xOffset; + animObj->y1 = ch->y1 + yOffset; + } + animObj->width2 = 4; + animObj->height2 = 3; + + refreshObject(animObj); +} + +void Animator_LoK::setCharacterDefaultFrame(int character) { + debugC(9, kDebugLevelAnimator, "Animator_LoK::setCharacterDefaultFrame()"); + static uint16 initFrameTable[] = { + 7, 41, 77, 0, 0 + }; + assert(character < ARRAYSIZE(initFrameTable)); + Character *edit = &_vm->characterList()[character]; + edit->sceneId = 0xFFFF; + edit->facing = 0; + edit->currentAnimFrame = initFrameTable[character]; + // edit->unk6 = 1; +} + +void Animator_LoK::setCharactersHeight() { + debugC(9, kDebugLevelAnimator, "Animator_LoK::setCharactersHeight()"); + static int8 initHeightTable[] = { + 48, 40, 48, 47, 56, + 44, 42, 47, 38, 35, + 40 + }; + for (int i = 0; i < 11; ++i) + _vm->characterList()[i].height = initHeightTable[i]; +} + +} // end of namespace Kyra + diff --git a/engines/kyra/animator_lok.h b/engines/kyra/animator_lok.h new file mode 100644 index 0000000000..c7d564e0c6 --- /dev/null +++ b/engines/kyra/animator_lok.h @@ -0,0 +1,132 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#ifndef KYRA_ANIMATOR_V1_H +#define KYRA_ANIMATOR_V1_H + +namespace Kyra { +class KyraEngine_LoK; +class Screen; + +class Animator_LoK { +public: + struct AnimObject { + uint8 index; + uint32 active; + uint32 refreshFlag; + uint32 bkgdChangeFlag; + bool disable; + uint32 flags; + int16 drawY; + uint8 *sceneAnimPtr; + int16 animFrameNumber; + uint8 *background; + uint16 rectSize; + int16 x1, y1; + int16 x2, y2; + uint16 width; + uint16 height; + uint16 width2; + uint16 height2; + AnimObject *nextAnimObject; + }; + + Animator_LoK(KyraEngine_LoK *vm, OSystem *system); + virtual ~Animator_LoK(); + + operator bool() const { return _initOk; } + + void init(int actors, int items, int sprites); + void close(); + + AnimObject *objects() { return _screenObjects; } + AnimObject *actors() { return _actors; } + AnimObject *items() { return _items; } + AnimObject *sprites() { return _sprites; } + + void initAnimStateList(); + void preserveAllBackgrounds(); + void flagAllObjectsForBkgdChange(); + void flagAllObjectsForRefresh(); + void restoreAllObjectBackgrounds(); + void preserveAnyChangedBackgrounds(); + virtual void prepDrawAllObjects(); + void copyChangedObjectsForward(int refreshFlag); + + void updateAllObjectShapes(); + void animRemoveGameItem(int index); + void animAddGameItem(int index, uint16 sceneId); + void animAddNPC(int character); + void animRefreshNPC(int character); + + void clearQueue() { _objectQueue = 0; } + void addObjectToQueue(AnimObject *object); + void refreshObject(AnimObject *object); + + void makeBrandonFaceMouse(); + void setBrandonAnimSeqSize(int width, int height); + void resetBrandonAnimSeqSize(); + void setCharacterDefaultFrame(int character); + void setCharactersHeight(); + + int16 fetchAnimWidth(const uint8 *shape, int16 mult); + int16 fetchAnimHeight(const uint8 *shape, int16 mult); + + int _noDrawShapesFlag; + bool _updateScreen; + uint16 _brandonDrawFrame; + int _brandonScaleX; + int _brandonScaleY; + +protected: + KyraEngine_LoK *_vm; + Screen *_screen; + OSystem *_system; + bool _initOk; + + AnimObject *_screenObjects; + + AnimObject *_actors; + AnimObject *_items; + AnimObject *_sprites; + + uint8 *_actorBkgBackUp[2]; + + AnimObject *objectRemoveQueue(AnimObject *queue, AnimObject *rem); + AnimObject *objectAddHead(AnimObject *queue, AnimObject *head); + AnimObject *objectQueue(AnimObject *queue, AnimObject *add); + + void preserveOrRestoreBackground(AnimObject *obj, bool restore); + + AnimObject *_objectQueue; + + int _brandonAnimSeqSizeWidth; + int _brandonAnimSeqSizeHeight; + +}; +} // end of namespace Kyra + +#endif + diff --git a/engines/kyra/animator_v1.cpp b/engines/kyra/animator_v1.cpp deleted file mode 100644 index 619c6c3d70..0000000000 --- a/engines/kyra/animator_v1.cpp +++ /dev/null @@ -1,691 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include "common/endian.h" - -#include "kyra/kyra_v1.h" -#include "kyra/screen.h" -#include "kyra/animator_v1.h" -#include "kyra/sprites.h" - -#include "common/system.h" - -namespace Kyra { -Animator_v1::Animator_v1(KyraEngine_v1 *vm, OSystem *system) { - _vm = vm; - _screen = vm->screen(); - _initOk = false; - _updateScreen = false; - _system = system; - _screenObjects = _actors = _items = _sprites = _objectQueue = 0; - _noDrawShapesFlag = 0; - - _actorBkgBackUp[0] = new uint8[_screen->getRectSize(8, 69)]; - memset(_actorBkgBackUp[0], 0, _screen->getRectSize(8, 69)); - _actorBkgBackUp[1] = new uint8[_screen->getRectSize(8, 69)]; - memset(_actorBkgBackUp[1], 0, _screen->getRectSize(8, 69)); -} - -Animator_v1::~Animator_v1() { - close(); - delete[] _actorBkgBackUp[0]; - delete[] _actorBkgBackUp[1]; -} - -void Animator_v1::init(int actors_, int items_, int sprites_) { - debugC(9, kDebugLevelAnimator, "Animator_v1::init(%d, %d, %d)", actors_, items_, sprites_); - _screenObjects = new AnimObject[actors_ + items_ + sprites_]; - assert(_screenObjects); - memset(_screenObjects, 0, sizeof(AnimObject) * (actors_ + items_ + sprites_)); - _actors = _screenObjects; - _sprites = &_screenObjects[actors_]; - _items = &_screenObjects[actors_ + items_]; - _brandonDrawFrame = 113; - - _initOk = true; -} - -void Animator_v1::close() { - debugC(9, kDebugLevelAnimator, "Animator_v1::close()"); - if (_initOk) { - _initOk = false; - delete[] _screenObjects; - _screenObjects = _actors = _items = _sprites = _objectQueue = 0; - } -} - -void Animator_v1::initAnimStateList() { - AnimObject *animStates = _screenObjects; - animStates[0].index = 0; - animStates[0].active = 1; - animStates[0].flags = 0x800; - animStates[0].background = _actorBkgBackUp[0]; - animStates[0].rectSize = _screen->getRectSize(4, 48); - animStates[0].width = 4; - animStates[0].height = 48; - animStates[0].width2 = 4; - animStates[0].height2 = 3; - - for (int i = 1; i <= 4; ++i) { - animStates[i].index = i; - animStates[i].active = 0; - animStates[i].flags = 0x800; - animStates[i].background = _actorBkgBackUp[1]; - animStates[i].rectSize = _screen->getRectSize(4, 64); - animStates[i].width = 4; - animStates[i].height = 48; - animStates[i].width2 = 4; - animStates[i].height2 = 3; - } - - for (int i = 5; i < 16; ++i) { - animStates[i].index = i; - animStates[i].active = 0; - animStates[i].flags = 0; - } - - for (int i = 16; i < 28; ++i) { - animStates[i].index = i; - animStates[i].flags = 0; - animStates[i].background = _vm->_shapes[345+i]; - animStates[i].rectSize = _screen->getRectSize(3, 24); - animStates[i].width = 3; - animStates[i].height = 16; - animStates[i].width2 = 0; - animStates[i].height2 = 0; - } -} - -void Animator_v1::preserveAllBackgrounds() { - debugC(9, kDebugLevelAnimator, "Animator_v1::preserveAllBackgrounds()"); - uint8 curPage = _screen->_curPage; - _screen->_curPage = 2; - - AnimObject *curObject = _objectQueue; - while (curObject) { - if (curObject->active && !curObject->disable) { - preserveOrRestoreBackground(curObject, false); - curObject->bkgdChangeFlag = 0; - } - curObject = curObject->nextAnimObject; - } - _screen->_curPage = curPage; -} - -void Animator_v1::flagAllObjectsForBkgdChange() { - debugC(9, kDebugLevelAnimator, "Animator_v1::flagAllObjectsForBkgdChange()"); - AnimObject *curObject = _objectQueue; - while (curObject) { - curObject->bkgdChangeFlag = 1; - curObject = curObject->nextAnimObject; - } -} - -void Animator_v1::flagAllObjectsForRefresh() { - debugC(9, kDebugLevelAnimator, "Animator_v1::flagAllObjectsForRefresh()"); - AnimObject *curObject = _objectQueue; - while (curObject) { - curObject->refreshFlag = 1; - curObject = curObject->nextAnimObject; - } -} - -void Animator_v1::restoreAllObjectBackgrounds() { - debugC(9, kDebugLevelAnimator, "Animator_v1::restoreAllObjectBackground()"); - AnimObject *curObject = _objectQueue; - _screen->_curPage = 2; - - while (curObject) { - if (curObject->active && !curObject->disable) { - preserveOrRestoreBackground(curObject, true); - curObject->x2 = curObject->x1; - curObject->y2 = curObject->y1; - } - curObject = curObject->nextAnimObject; - } - - _screen->_curPage = 0; -} - -void Animator_v1::preserveAnyChangedBackgrounds() { - debugC(9, kDebugLevelAnimator, "Animator_v1::preserveAnyChangedBackgrounds()"); - AnimObject *curObject = _objectQueue; - _screen->_curPage = 2; - - while (curObject) { - if (curObject->active && !curObject->disable && curObject->bkgdChangeFlag) { - preserveOrRestoreBackground(curObject, false); - curObject->bkgdChangeFlag = 0; - } - curObject = curObject->nextAnimObject; - } - - _screen->_curPage = 0; -} - -void Animator_v1::preserveOrRestoreBackground(AnimObject *obj, bool restore) { - debugC(9, kDebugLevelAnimator, "Animator_v1::preserveOrRestoreBackground(%p, %d)", (const void *)obj, restore); - int x = 0, y = 0, width = obj->width, height = obj->height; - - if (restore) { - x = obj->x2 >> 3; - y = obj->y2; - } else { - x = obj->x1 >> 3; - y = obj->y1; - } - - if (x < 0) - x = 0; - if (y < 0) - y = 0; - - int temp; - - temp = x + width; - if (temp >= 39) - x = 39 - width; - temp = y + height; - if (temp >= 136) - y = 136 - height; - - if (restore) - _screen->copyBlockToPage(_screen->_curPage, x << 3, y, width << 3, height, obj->background); - else - _screen->copyRegionToBuffer(_screen->_curPage, x << 3, y, width << 3, height, obj->background); -} - -void Animator_v1::prepDrawAllObjects() { - debugC(9, kDebugLevelAnimator, "Animator_v1::prepDrawAllObjects()"); - AnimObject *curObject = _objectQueue; - int drawPage = 2; - int flagUnk1 = 0, flagUnk2 = 0, flagUnk3 = 0; - if (_noDrawShapesFlag) - return; - if (_vm->_brandonStatusBit & 0x20) - flagUnk1 = 0x200; - if (_vm->_brandonStatusBit & 0x40) - flagUnk2 = 0x4000; - - while (curObject) { - if (curObject->active) { - int xpos = curObject->x1; - int ypos = curObject->y1; - - int drawLayer = 0; - if (!(curObject->flags & 0x800)) - drawLayer = 7; - else if (curObject->disable) - drawLayer = 0; - else - drawLayer = _vm->_sprites->getDrawLayer(curObject->drawY); - - // talking head functionallity - if (_vm->_talkingCharNum != -1 && (_vm->_currentCharacter->currentAnimFrame != 88 || curObject->index != 0)) { - const int16 baseAnimFrameTable1[] = { 0x11, 0x35, 0x59, 0x00, 0x00, 0x00 }; - const int16 baseAnimFrameTable2[] = { 0x15, 0x39, 0x5D, 0x00, 0x00, 0x00 }; - const int8 xOffsetTable1[] = { 2, 4, 0, 5, 2, 0, 0, 0 }; - const int8 xOffsetTable2[] = { 6, 4, 8, 3, 6, 0, 0, 0 }; - const int8 yOffsetTable1[] = { 0, 8, 1, 1, 0, 0, 0, 0 }; - const int8 yOffsetTable2[] = { 0, 8, 1, 1, 0, 0, 0, 0 }; - if (curObject->index == 0 || curObject->index <= 4) { - int shapesIndex = 0; - if (curObject->index == _vm->_charSayUnk3) { - shapesIndex = _vm->_currHeadShape + baseAnimFrameTable1[curObject->index]; - } else { - shapesIndex = baseAnimFrameTable2[curObject->index]; - int temp2 = 0; - if (curObject->index == 2) { - if (_vm->_characterList[2].sceneId == 77 || _vm->_characterList[2].sceneId == 86) - temp2 = 1; - else - temp2 = 0; - } else { - temp2 = 1; - } - - if (!temp2) - shapesIndex = -1; - } - - xpos = curObject->x1; - ypos = curObject->y1; - - int tempX = 0, tempY = 0; - if (curObject->flags & 0x1) { - tempX = (xOffsetTable1[curObject->index] * _brandonScaleX) >> 8; - tempY = yOffsetTable1[curObject->index]; - } else { - tempX = (xOffsetTable2[curObject->index] * _brandonScaleX) >> 8; - tempY = yOffsetTable2[curObject->index]; - } - tempY = (tempY * _brandonScaleY) >> 8; - xpos += tempX; - ypos += tempY; - - if (_vm->_scaleMode && _brandonScaleX != 256) - ++xpos; - - if (curObject->index == 0 && shapesIndex != -1) { - if (!(_vm->_brandonStatusBit & 2)) { - flagUnk3 = 0x100; - if ((flagUnk1 & 0x200) || (flagUnk2 & 0x4000)) - flagUnk3 = 0; - - int tempFlags = 0; - if (flagUnk3 & 0x100) { - tempFlags = curObject->flags & 1; - tempFlags |= 0x800 | flagUnk1 | 0x100; - } - - if (!(flagUnk3 & 0x100) && (flagUnk2 & 0x4000)) { - tempFlags = curObject->flags & 1; - tempFlags |= 0x900 | flagUnk1 | 0x4000; - _screen->drawShape(drawPage, _vm->_shapes[shapesIndex], xpos, ypos, 2, tempFlags | 4, _vm->_brandonPoisonFlagsGFX, int(1), int(_vm->_brandonInvFlag), drawLayer, _brandonScaleX, _brandonScaleY); - } else { - if (!(flagUnk2 & 0x4000)) { - tempFlags = curObject->flags & 1; - tempFlags |= 0x900 | flagUnk1; - } - - _screen->drawShape(drawPage, _vm->_shapes[shapesIndex], xpos, ypos, 2, tempFlags | 4, _vm->_brandonPoisonFlagsGFX, int(1), drawLayer, _brandonScaleX, _brandonScaleY); - } - } - } else { - if (shapesIndex != -1) { - int tempFlags = 0; - if (curObject->flags & 1) - tempFlags = 1; - _screen->drawShape(drawPage, _vm->_shapes[shapesIndex], xpos, ypos, 2, tempFlags | 0x800, drawLayer); - } - } - } - } - - xpos = curObject->x1; - ypos = curObject->y1; - - curObject->flags |= 0x800; - if (curObject->index == 0) { - flagUnk3 = 0x100; - - if (flagUnk1 & 0x200 || flagUnk2 & 0x4000) - flagUnk3 = 0; - - if (_vm->_brandonStatusBit & 2) - curObject->flags &= 0xFFFFFFFE; - - if (!_vm->_scaleMode) { - if (flagUnk3 & 0x100) - _screen->drawShape(drawPage, curObject->sceneAnimPtr, xpos, ypos, 2, curObject->flags | flagUnk1 | 0x100, (uint8*)_vm->_brandonPoisonFlagsGFX, int(1), drawLayer); - else if (flagUnk2 & 0x4000) - _screen->drawShape(drawPage, curObject->sceneAnimPtr, xpos, ypos, 2, curObject->flags | flagUnk1 | 0x4000, int(_vm->_brandonInvFlag), drawLayer); - else - _screen->drawShape(drawPage, curObject->sceneAnimPtr, xpos, ypos, 2, curObject->flags | flagUnk1, drawLayer); - } else { - if (flagUnk3 & 0x100) - _screen->drawShape(drawPage, curObject->sceneAnimPtr, xpos, ypos, 2, curObject->flags | flagUnk1 | 0x104, (uint8*)_vm->_brandonPoisonFlagsGFX, int(1), drawLayer, _brandonScaleX, _brandonScaleY); - else if (flagUnk2 & 0x4000) - _screen->drawShape(drawPage, curObject->sceneAnimPtr, xpos, ypos, 2, curObject->flags | flagUnk1 | 0x4004, int(_vm->_brandonInvFlag), drawLayer, _brandonScaleX, _brandonScaleY); - else - _screen->drawShape(drawPage, curObject->sceneAnimPtr, xpos, ypos, 2, curObject->flags | flagUnk1 | 0x4, drawLayer, _brandonScaleX, _brandonScaleY); - } - } else { - if (curObject->index >= 16 && curObject->index <= 27) - _screen->drawShape(drawPage, curObject->sceneAnimPtr, xpos, ypos, 2, curObject->flags | 4, drawLayer, (int)_vm->_scaleTable[curObject->drawY], (int)_vm->_scaleTable[curObject->drawY]); - else - _screen->drawShape(drawPage, curObject->sceneAnimPtr, xpos, ypos, 2, curObject->flags, drawLayer); - } - } - curObject = curObject->nextAnimObject; - } -} - -void Animator_v1::copyChangedObjectsForward(int refreshFlag) { - debugC(9, kDebugLevelAnimator, "Animator_v1::copyChangedObjectsForward(%d)", refreshFlag); - - for (AnimObject *curObject = _objectQueue; curObject; curObject = curObject->nextAnimObject) { - if (curObject->active) { - if (curObject->refreshFlag || refreshFlag) { - int xpos = 0, ypos = 0, width = 0, height = 0; - xpos = (curObject->x1>>3) - (curObject->width2>>3) - 1; - ypos = curObject->y1 - curObject->height2; - width = curObject->width + (curObject->width2>>3) + 2; - height = curObject->height + curObject->height2*2; - - if (xpos < 1) - xpos = 1; - else if (xpos > 39) - continue; - - if (xpos + width > 39) - width = 39 - xpos; - - if (ypos < 8) - ypos = 8; - else if (ypos > 136) - continue; - - if (ypos + height > 136) - height = 136 - ypos; - - _screen->copyRegion(xpos << 3, ypos, xpos << 3, ypos, width << 3, height, 2, 0); - curObject->refreshFlag = 0; - _updateScreen = true; - } - } - } - - if (_updateScreen) { - _screen->updateScreen(); - _updateScreen = false; - } -} - -void Animator_v1::updateAllObjectShapes() { - debugC(9, kDebugLevelAnimator, "Animator_v1::updateAllObjectShapes()"); - restoreAllObjectBackgrounds(); - preserveAnyChangedBackgrounds(); - prepDrawAllObjects(); - copyChangedObjectsForward(0); -} - -void Animator_v1::animRemoveGameItem(int index) { - debugC(9, kDebugLevelAnimator, "Animator_v1::animRemoveGameItem(%d)", index); - restoreAllObjectBackgrounds(); - - AnimObject *animObj = &_items[index]; - animObj->sceneAnimPtr = 0; - animObj->animFrameNumber = -1; - animObj->refreshFlag = 1; - animObj->bkgdChangeFlag = 1; - updateAllObjectShapes(); - animObj->active = 0; - - objectRemoveQueue(_objectQueue, animObj); -} - -void Animator_v1::animAddGameItem(int index, uint16 sceneId) { - debugC(9, kDebugLevelAnimator, "Animator_v1::animRemoveGameItem(%d, %d)", index, sceneId); - restoreAllObjectBackgrounds(); - assert(sceneId < _vm->_roomTableSize); - Room *currentRoom = &_vm->_roomTable[sceneId]; - AnimObject *animObj = &_items[index]; - animObj->active = 1; - animObj->refreshFlag = 1; - animObj->bkgdChangeFlag = 1; - animObj->drawY = currentRoom->itemsYPos[index]; - animObj->sceneAnimPtr = _vm->_shapes[216+currentRoom->itemsTable[index]]; - animObj->animFrameNumber = -1; - animObj->x1 = currentRoom->itemsXPos[index]; - animObj->y1 = currentRoom->itemsYPos[index]; - animObj->x1 -= fetchAnimWidth(animObj->sceneAnimPtr, _vm->_scaleTable[animObj->drawY]) >> 1; - animObj->y1 -= fetchAnimHeight(animObj->sceneAnimPtr, _vm->_scaleTable[animObj->drawY]); - animObj->x2 = animObj->x1; - animObj->y2 = animObj->y1; - animObj->width2 = 0; - animObj->height2 = 0; - _objectQueue = objectQueue(_objectQueue, animObj); - preserveAnyChangedBackgrounds(); - animObj->refreshFlag = 1; - animObj->bkgdChangeFlag = 1; -} - -void Animator_v1::animAddNPC(int character) { - debugC(9, kDebugLevelAnimator, "Animator_v1::animAddNPC(%d)", character); - restoreAllObjectBackgrounds(); - AnimObject *animObj = &_actors[character]; - const Character *ch = &_vm->_characterList[character]; - - animObj->active = 1; - animObj->refreshFlag = 1; - animObj->bkgdChangeFlag = 1; - animObj->drawY = ch->y1; - animObj->sceneAnimPtr = _vm->_shapes[ch->currentAnimFrame]; - animObj->x1 = animObj->x2 = ch->x1 + _vm->_defaultShapeTable[ch->currentAnimFrame-7].xOffset; - animObj->y1 = animObj->y2 = ch->y1 + _vm->_defaultShapeTable[ch->currentAnimFrame-7].yOffset; - - if (ch->facing >= 1 && ch->facing <= 3) - animObj->flags |= 1; - else if (ch->facing >= 5 && ch->facing <= 7) - animObj->flags &= 0xFFFFFFFE; - - _objectQueue = objectQueue(_objectQueue, animObj); - preserveAnyChangedBackgrounds(); - animObj->refreshFlag = 1; - animObj->bkgdChangeFlag = 1; -} - -Animator_v1::AnimObject *Animator_v1::objectRemoveQueue(AnimObject *queue, AnimObject *rem) { - debugC(9, kDebugLevelAnimator, "Animator_v1::objectRemoveQueue(%p, %p)", (const void *)queue, (const void *)rem); - AnimObject *cur = queue; - AnimObject *prev = queue; - - while (cur != rem && cur) { - AnimObject *temp = cur->nextAnimObject; - if (!temp) - break; - prev = cur; - cur = temp; - } - - if (cur == queue) { - if (!cur) - return 0; - return cur->nextAnimObject; - } - - if (!cur->nextAnimObject) { - if (cur == rem) { - if (!prev) - return 0; - else - prev->nextAnimObject = 0; - } - } else { - if (cur == rem) - prev->nextAnimObject = rem->nextAnimObject; - } - - return queue; -} - -Animator_v1::AnimObject *Animator_v1::objectAddHead(AnimObject *queue, AnimObject *head) { - debugC(9, kDebugLevelAnimator, "Animator_v1::objectAddHead(%p, %p)", (const void *)queue, (const void *)head); - head->nextAnimObject = queue; - return head; -} - -Animator_v1::AnimObject *Animator_v1::objectQueue(AnimObject *queue, AnimObject *add) { - debugC(9, kDebugLevelAnimator, "Animator_v1::objectQueue(%p, %p)", (const void *)queue, (const void *)add); - if (add->drawY <= queue->drawY || !queue) { - add->nextAnimObject = queue; - return add; - } - AnimObject *cur = queue; - AnimObject *prev = queue; - while (add->drawY > cur->drawY) { - AnimObject *temp = cur->nextAnimObject; - if (!temp) - break; - prev = cur; - cur = temp; - } - - if (add->drawY <= cur->drawY) { - prev->nextAnimObject = add; - add->nextAnimObject = cur; - } else { - cur->nextAnimObject = add; - add->nextAnimObject = 0; - } - return queue; -} - -void Animator_v1::addObjectToQueue(AnimObject *object) { - debugC(9, kDebugLevelAnimator, "Animator_v1::addObjectToQueue(%p)", (const void *)object); - if (!_objectQueue) - _objectQueue = objectAddHead(0, object); - else - _objectQueue = objectQueue(_objectQueue, object); -} - -void Animator_v1::refreshObject(AnimObject *object) { - debugC(9, kDebugLevelAnimator, "Animator_v1::refreshObject(%p)", (const void *)object); - _objectQueue = objectRemoveQueue(_objectQueue, object); - if (_objectQueue) - _objectQueue = objectQueue(_objectQueue, object); - else - _objectQueue = objectAddHead(0, object); -} - -void Animator_v1::makeBrandonFaceMouse() { - debugC(9, kDebugLevelAnimator, "Animator_v1::makeBrandonFaceMouse()"); - Common::Point mouse = _vm->getMousePos(); - if (mouse.x >= _vm->_currentCharacter->x1) - _vm->_currentCharacter->facing = 3; - else - _vm->_currentCharacter->facing = 5; - animRefreshNPC(0); - updateAllObjectShapes(); -} - -int16 Animator_v1::fetchAnimWidth(const uint8 *shape, int16 mult) { - debugC(9, kDebugLevelAnimator, "Animator_v1::fetchAnimWidth(%p, %d)", (const void *)shape, mult); - if (_vm->gameFlags().useAltShapeHeader) - shape += 2; - return (((int16)READ_LE_UINT16((shape+3))) * mult) >> 8; -} - -int16 Animator_v1::fetchAnimHeight(const uint8 *shape, int16 mult) { - debugC(9, kDebugLevelAnimator, "Animator_v1::fetchAnimHeight(%p, %d)", (const void *)shape, mult); - if (_vm->gameFlags().useAltShapeHeader) - shape += 2; - return (int16)(((int8)*(shape+2)) * mult) >> 8; -} - -void Animator_v1::setBrandonAnimSeqSize(int width, int height) { - debugC(9, kDebugLevelAnimator, "Animator_v1::setBrandonAnimSeqSize(%d, %d)", width, height); - restoreAllObjectBackgrounds(); - _brandonAnimSeqSizeWidth = _actors[0].width; - _brandonAnimSeqSizeHeight = _actors[0].height; - _actors[0].width = width + 1; - _actors[0].height = height; - preserveAllBackgrounds(); -} - -void Animator_v1::resetBrandonAnimSeqSize() { - debugC(9, kDebugLevelAnimator, "Animator_v1::resetBrandonAnimSeqSize()"); - restoreAllObjectBackgrounds(); - _actors[0].width = _brandonAnimSeqSizeWidth; - _actors[0].height = _brandonAnimSeqSizeHeight; - preserveAllBackgrounds(); -} - -void Animator_v1::animRefreshNPC(int character) { - debugC(9, kDebugLevelAnimator, "Animator_v1::animRefreshNPC(%d)", character); - AnimObject *animObj = &_actors[character]; - Character *ch = &_vm->characterList()[character]; - - animObj->refreshFlag = 1; - animObj->bkgdChangeFlag = 1; - int facing = ch->facing; - if (facing >= 1 && facing <= 3) - animObj->flags |= 1; - else if (facing >= 5 && facing <= 7) - animObj->flags &= 0xFFFFFFFE; - - animObj->drawY = ch->y1; - animObj->sceneAnimPtr = _vm->shapes()[ch->currentAnimFrame]; - animObj->animFrameNumber = ch->currentAnimFrame; - if (character == 0) { - if (_vm->brandonStatus() & 10) { - animObj->animFrameNumber = 88; - ch->currentAnimFrame = 88; - } - if (_vm->brandonStatus() & 2) { - animObj->animFrameNumber = _brandonDrawFrame; - ch->currentAnimFrame = _brandonDrawFrame; - animObj->sceneAnimPtr = _vm->shapes()[_brandonDrawFrame]; - if (_vm->_brandonStatusBit0x02Flag) { - ++_brandonDrawFrame; - // TODO: check this - if (_brandonDrawFrame >= 122) { - _brandonDrawFrame = 113; - _vm->_brandonStatusBit0x02Flag = 0; - } - } - } - } - - int xOffset = _vm->_defaultShapeTable[ch->currentAnimFrame-7].xOffset; - int yOffset = _vm->_defaultShapeTable[ch->currentAnimFrame-7].yOffset; - - if (_vm->_scaleMode) { - animObj->x1 = ch->x1; - animObj->y1 = ch->y1; - - int newScale = _vm->_scaleTable[ch->y1]; - _brandonScaleX = newScale; - _brandonScaleY = newScale; - - animObj->x1 += (_brandonScaleX * xOffset) >> 8; - animObj->y1 += (_brandonScaleY * yOffset) >> 8; - } else { - animObj->x1 = ch->x1 + xOffset; - animObj->y1 = ch->y1 + yOffset; - } - animObj->width2 = 4; - animObj->height2 = 3; - - refreshObject(animObj); -} - -void Animator_v1::setCharacterDefaultFrame(int character) { - debugC(9, kDebugLevelAnimator, "Animator_v1::setCharacterDefaultFrame()"); - static uint16 initFrameTable[] = { - 7, 41, 77, 0, 0 - }; - assert(character < ARRAYSIZE(initFrameTable)); - Character *edit = &_vm->characterList()[character]; - edit->sceneId = 0xFFFF; - edit->facing = 0; - edit->currentAnimFrame = initFrameTable[character]; - // edit->unk6 = 1; -} - -void Animator_v1::setCharactersHeight() { - debugC(9, kDebugLevelAnimator, "Animator_v1::setCharactersHeight()"); - static int8 initHeightTable[] = { - 48, 40, 48, 47, 56, - 44, 42, 47, 38, 35, - 40 - }; - for (int i = 0; i < 11; ++i) - _vm->characterList()[i].height = initHeightTable[i]; -} - -} // end of namespace Kyra - diff --git a/engines/kyra/animator_v1.h b/engines/kyra/animator_v1.h deleted file mode 100644 index 3ae0b23da4..0000000000 --- a/engines/kyra/animator_v1.h +++ /dev/null @@ -1,132 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#ifndef KYRA_ANIMATOR_V1_H -#define KYRA_ANIMATOR_V1_H - -namespace Kyra { -class KyraEngine_v1; -class Screen; - -class Animator_v1 { -public: - struct AnimObject { - uint8 index; - uint32 active; - uint32 refreshFlag; - uint32 bkgdChangeFlag; - bool disable; - uint32 flags; - int16 drawY; - uint8 *sceneAnimPtr; - int16 animFrameNumber; - uint8 *background; - uint16 rectSize; - int16 x1, y1; - int16 x2, y2; - uint16 width; - uint16 height; - uint16 width2; - uint16 height2; - AnimObject *nextAnimObject; - }; - - Animator_v1(KyraEngine_v1 *vm, OSystem *system); - virtual ~Animator_v1(); - - operator bool() const { return _initOk; } - - void init(int actors, int items, int sprites); - void close(); - - AnimObject *objects() { return _screenObjects; } - AnimObject *actors() { return _actors; } - AnimObject *items() { return _items; } - AnimObject *sprites() { return _sprites; } - - void initAnimStateList(); - void preserveAllBackgrounds(); - void flagAllObjectsForBkgdChange(); - void flagAllObjectsForRefresh(); - void restoreAllObjectBackgrounds(); - void preserveAnyChangedBackgrounds(); - virtual void prepDrawAllObjects(); - void copyChangedObjectsForward(int refreshFlag); - - void updateAllObjectShapes(); - void animRemoveGameItem(int index); - void animAddGameItem(int index, uint16 sceneId); - void animAddNPC(int character); - void animRefreshNPC(int character); - - void clearQueue() { _objectQueue = 0; } - void addObjectToQueue(AnimObject *object); - void refreshObject(AnimObject *object); - - void makeBrandonFaceMouse(); - void setBrandonAnimSeqSize(int width, int height); - void resetBrandonAnimSeqSize(); - void setCharacterDefaultFrame(int character); - void setCharactersHeight(); - - int16 fetchAnimWidth(const uint8 *shape, int16 mult); - int16 fetchAnimHeight(const uint8 *shape, int16 mult); - - int _noDrawShapesFlag; - bool _updateScreen; - uint16 _brandonDrawFrame; - int _brandonScaleX; - int _brandonScaleY; - -protected: - KyraEngine_v1 *_vm; - Screen *_screen; - OSystem *_system; - bool _initOk; - - AnimObject *_screenObjects; - - AnimObject *_actors; - AnimObject *_items; - AnimObject *_sprites; - - uint8 *_actorBkgBackUp[2]; - - AnimObject *objectRemoveQueue(AnimObject *queue, AnimObject *rem); - AnimObject *objectAddHead(AnimObject *queue, AnimObject *head); - AnimObject *objectQueue(AnimObject *queue, AnimObject *add); - - void preserveOrRestoreBackground(AnimObject *obj, bool restore); - - AnimObject *_objectQueue; - - int _brandonAnimSeqSizeWidth; - int _brandonAnimSeqSizeHeight; - -}; -} // end of namespace Kyra - -#endif - diff --git a/engines/kyra/debugger.cpp b/engines/kyra/debugger.cpp index f90cf5a37b..932f5aa7dd 100644 --- a/engines/kyra/debugger.cpp +++ b/engines/kyra/debugger.cpp @@ -27,7 +27,7 @@ #include "common/config-manager.h" #include "common/system.h" #include "kyra/debugger.h" -#include "kyra/kyra_v1.h" +#include "kyra/kyra_lok.h" #include "kyra/kyra_v2.h" #include "kyra/kyra_hof.h" #include "kyra/screen.h" @@ -190,22 +190,22 @@ bool Debugger::cmd_setTimerCountdown(int argc, const char **argv) { #pragma mark - -Debugger_v1::Debugger_v1(KyraEngine_v1 *vm) +Debugger_LoK::Debugger_LoK(KyraEngine_LoK *vm) : Debugger(vm), _vm(vm) { - DCmd_Register("rooms", WRAP_METHOD(Debugger_v1, cmd_listRooms)); - DCmd_Register("give", WRAP_METHOD(Debugger_v1, cmd_giveItem)); - DCmd_Register("birthstones", WRAP_METHOD(Debugger_v1, cmd_listBirthstones)); + DCmd_Register("rooms", WRAP_METHOD(Debugger_LoK, cmd_listRooms)); + DCmd_Register("give", WRAP_METHOD(Debugger_LoK, cmd_giveItem)); + DCmd_Register("birthstones", WRAP_METHOD(Debugger_LoK, cmd_listBirthstones)); } -void Debugger_v1::preEnter() { +void Debugger_LoK::preEnter() { //_vm->midi.pause(1); } -void Debugger_v1::postEnter() { +void Debugger_LoK::postEnter() { //_vm->midi.pause(0); } -bool Debugger_v1::cmd_enterRoom(int argc, const char **argv) { +bool Debugger_LoK::cmd_enterRoom(int argc, const char **argv) { uint direction = 0; if (argc > 1) { int room = atoi(argv[1]); @@ -244,7 +244,7 @@ bool Debugger_v1::cmd_enterRoom(int argc, const char **argv) { return true; } -bool Debugger_v1::cmd_listRooms(int argc, const char **argv) { +bool Debugger_LoK::cmd_listRooms(int argc, const char **argv) { for (int i = 0; i < _vm->_roomTableSize; i++) { DebugPrintf("%-3i: %-10s", i, _vm->_roomFilenameTable[_vm->_roomTable[i].nameIndex]); if (!(i % 8)) @@ -255,7 +255,7 @@ bool Debugger_v1::cmd_listRooms(int argc, const char **argv) { return true; } -bool Debugger_v1::cmd_giveItem(int argc, const char **argv) { +bool Debugger_LoK::cmd_giveItem(int argc, const char **argv) { if (argc == 2) { int item = atoi(argv[1]); @@ -274,7 +274,7 @@ bool Debugger_v1::cmd_giveItem(int argc, const char **argv) { return true; } -bool Debugger_v1::cmd_listBirthstones(int argc, const char **argv) { +bool Debugger_LoK::cmd_listBirthstones(int argc, const char **argv) { DebugPrintf("Needed Birthstone gems:\n"); for (int i = 0; i < ARRAYSIZE(_vm->_birthstoneGemTable); ++i) DebugPrintf("%-2d '%s'\n", _vm->_birthstoneGemTable[i], _vm->_itemList[_vm->_birthstoneGemTable[i]]); diff --git a/engines/kyra/debugger.h b/engines/kyra/debugger.h index ab5657bbde..7b1d870daa 100644 --- a/engines/kyra/debugger.h +++ b/engines/kyra/debugger.h @@ -31,7 +31,7 @@ namespace Kyra { class KyraEngine; -class KyraEngine_v1; +class KyraEngine_LoK; class KyraEngine_v2; class KyraEngine_HoF; @@ -54,13 +54,13 @@ protected: bool cmd_setTimerCountdown(int argc, const char **argv); }; -class Debugger_v1 : public Debugger { +class Debugger_LoK : public Debugger { public: - Debugger_v1(KyraEngine_v1 *vm); - virtual ~Debugger_v1() {} // we need this for __SYMBIAN32__ archaic gcc/UIQ + Debugger_LoK(KyraEngine_LoK *vm); + virtual ~Debugger_LoK() {} // we need this for __SYMBIAN32__ archaic gcc/UIQ protected: - KyraEngine_v1 *_vm; + KyraEngine_LoK *_vm; virtual void preEnter(); virtual void postEnter(); diff --git a/engines/kyra/detection.cpp b/engines/kyra/detection.cpp index b921314e68..2b272fd7d7 100644 --- a/engines/kyra/detection.cpp +++ b/engines/kyra/detection.cpp @@ -23,7 +23,7 @@ */ #include "kyra/kyra.h" -#include "kyra/kyra_v1.h" +#include "kyra/kyra_lok.h" #include "kyra/kyra_hof.h" #include "kyra/kyra_mr.h" @@ -506,7 +506,7 @@ bool KyraMetaEngine::createInstance(OSystem *syst, Engine **engine, const Common switch (flags.gameID) { case Kyra::GI_KYRA1: - *engine = new Kyra::KyraEngine_v1(syst, flags); + *engine = new Kyra::KyraEngine_LoK(syst, flags); break; case Kyra::GI_KYRA2: *engine = new Kyra::KyraEngine_HoF(syst, flags); diff --git a/engines/kyra/gui_hof.cpp b/engines/kyra/gui_hof.cpp index 74701f109e..12e4065ec6 100644 --- a/engines/kyra/gui_hof.cpp +++ b/engines/kyra/gui_hof.cpp @@ -271,7 +271,7 @@ void KyraEngine_HoF::redrawInventory(int page) { } void KyraEngine_HoF::scrollInventoryWheel() { - WSAMovieV2 movie(this, _screen); + WSAMovie_v2 movie(this, _screen); movie.open("INVWHEEL.WSA", 0, 0); int frames = movie.opened() ? movie.frames() : 6; memcpy(_screenBuffer, _screen->getCPagePtr(2), 64000); diff --git a/engines/kyra/gui_lok.cpp b/engines/kyra/gui_lok.cpp new file mode 100644 index 0000000000..844574c5be --- /dev/null +++ b/engines/kyra/gui_lok.cpp @@ -0,0 +1,1115 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "kyra/kyra_lok.h" +#include "kyra/screen.h" +#include "kyra/script.h" +#include "kyra/text.h" +#include "kyra/animator_lok.h" +#include "kyra/sound.h" +#include "kyra/gui_lok.h" +#include "kyra/timer.h" + +#include "common/config-manager.h" +#include "common/savefile.h" +#include "common/events.h" +#include "common/system.h" + +namespace Kyra { + +void KyraEngine_LoK::initMainButtonList() { + _buttonList = &_buttonData[0]; + for (int i = 0; _buttonDataListPtr[i]; ++i) + _buttonList = _gui->addButtonToList(_buttonList, _buttonDataListPtr[i]); +} + +int KyraEngine_LoK::buttonInventoryCallback(Button *caller) { + int itemOffset = caller->index - 2; + uint8 inventoryItem = _currentCharacter->inventoryItems[itemOffset]; + if (_itemInHand == -1) { + if (inventoryItem == 0xFF) { + snd_playSoundEffect(0x36); + return 0; + } else { + _screen->hideMouse(); + _screen->fillRect(_itemPosX[itemOffset], _itemPosY[itemOffset], _itemPosX[itemOffset] + 15, _itemPosY[itemOffset] + 15, 12); + snd_playSoundEffect(0x35); + setMouseItem(inventoryItem); + updateSentenceCommand(_itemList[inventoryItem], _takenList[0], 179); + _itemInHand = inventoryItem; + _screen->showMouse(); + _currentCharacter->inventoryItems[itemOffset] = 0xFF; + } + } else { + if (inventoryItem != 0xFF) { + snd_playSoundEffect(0x35); + _screen->hideMouse(); + _screen->fillRect(_itemPosX[itemOffset], _itemPosY[itemOffset], _itemPosX[itemOffset] + 15, _itemPosY[itemOffset] + 15, 12); + _screen->drawShape(0, _shapes[216+_itemInHand], _itemPosX[itemOffset], _itemPosY[itemOffset], 0, 0); + setMouseItem(inventoryItem); + updateSentenceCommand(_itemList[inventoryItem], _takenList[1], 179); + _screen->showMouse(); + _currentCharacter->inventoryItems[itemOffset] = _itemInHand; + _itemInHand = inventoryItem; + } else { + snd_playSoundEffect(0x32); + _screen->hideMouse(); + _screen->drawShape(0, _shapes[216+_itemInHand], _itemPosX[itemOffset], _itemPosY[itemOffset], 0, 0); + _screen->setMouseCursor(1, 1, _shapes[0]); + updateSentenceCommand(_itemList[_itemInHand], _placedList[0], 179); + _screen->showMouse(); + _currentCharacter->inventoryItems[itemOffset] = _itemInHand; + _itemInHand = -1; + } + } + _screen->updateScreen(); + // XXX clearKyrandiaButtonIO + return 0; +} + +int KyraEngine_LoK::buttonAmuletCallback(Button *caller) { + if (!(_deathHandler & 8)) + return 1; + int jewel = caller->index - 0x14; + if (_currentCharacter->sceneId == 210) { + if (_beadStateVar == 4 || _beadStateVar == 6) + return 1; + } + if (!queryGameFlag(0x2D)) + return 1; + if (_itemInHand != -1) { + assert(_putDownFirst); + characterSays(2000, _putDownFirst[0], 0, -2); + return 1; + } + if (queryGameFlag(0xF1)) { + assert(_waitForAmulet); + characterSays(2001, _waitForAmulet[0], 0, -2); + return 1; + } + if (!queryGameFlag(0x55+jewel)) { + assert(_blackJewel); + _animator->makeBrandonFaceMouse(); + drawJewelPress(jewel, 1); + characterSays(2002, _blackJewel[0], 0, -2); + return 1; + } + drawJewelPress(jewel, 0); + drawJewelsFadeOutStart(); + drawJewelsFadeOutEnd(jewel); + + _emc->init(&_scriptClick, &_scriptClickData); + _scriptClick.regs[3] = 0; + _scriptClick.regs[6] = jewel; + _emc->start(&_scriptClick, 4); + + while (_emc->isValid(&_scriptClick)) + _emc->run(&_scriptClick); + + if (_scriptClick.regs[3]) + return 1; + + _unkAmuletVar = 1; + switch (jewel-1) { + case 0: + if (_brandonStatusBit & 1) { + seq_brandonHealing2(); + } else if (_brandonStatusBit == 0) { + seq_brandonHealing(); + assert(_healingTip); + characterSays(2003, _healingTip[0], 0, -2); + } + break; + + case 1: + seq_makeBrandonInv(); + break; + + case 2: + if (_brandonStatusBit & 1) { + assert(_wispJewelStrings); + characterSays(2004, _wispJewelStrings[0], 0, -2); + } else { + if (_brandonStatusBit & 2) { + // XXX + seq_makeBrandonNormal2(); + // XXX + } else { + // do not check for item in hand again as in the original since some strings are missing + // in the cd version + if (_currentCharacter->sceneId >= 109 && _currentCharacter->sceneId <= 198) { + snd_playWanderScoreViaMap(1, 0); + seq_makeBrandonWisp(); + snd_playWanderScoreViaMap(17, 0); + } else { + seq_makeBrandonWisp(); + } + setGameFlag(0x9E); + } + } + break; + + case 3: + seq_dispelMagicAnimation(); + assert(_magicJewelString); + characterSays(2007, _magicJewelString[0], 0, -2); + break; + + default: + break; + } + _unkAmuletVar = 0; + // XXX clearKyrandiaButtonIO (!used before every return in this function!) + return 1; +} + +#pragma mark - + +GUI_LoK::GUI_LoK(KyraEngine_LoK *vm, Screen_LoK *screen) : GUI(vm), _vm(vm), _screen(screen) { + _menu = 0; + initStaticResource(); + _scrollUpFunctor = BUTTON_FUNCTOR(GUI_LoK, this, &GUI_LoK::scrollUp); + _scrollDownFunctor = BUTTON_FUNCTOR(GUI_LoK, this, &GUI_LoK::scrollDown); +} + +GUI_LoK::~GUI_LoK() { + delete[] _menu; +} + +int GUI_LoK::processButtonList(Button *list, uint16 inputFlag, int8 mouseWheel) { + while (list) { + if (list->flags & 8) { + list = list->nextButton; + continue; + } + + if (mouseWheel && list->mouseWheel == mouseWheel && list->buttonCallback) { + if ((*list->buttonCallback.get())(list)) { + break; + } + } + + int x = list->x; + int y = list->y; + assert(_screen->getScreenDim(list->dimTableIndex) != 0); + if (x < 0) { + x += _screen->getScreenDim(list->dimTableIndex)->w << 3; + } + x += _screen->getScreenDim(list->dimTableIndex)->sx << 3; + + if (y < 0) { + y += _screen->getScreenDim(list->dimTableIndex)->h; + } + y += _screen->getScreenDim(list->dimTableIndex)->sy; + + Common::Point mouse = _vm->getMousePos(); + if (mouse.x >= x && mouse.y >= y && x + list->width >= mouse.x && y + list->height >= mouse.y) { + int processMouseClick = 0; + if (list->flags & 0x400) { + if (_vm->_mousePressFlag) { + if (!(list->flags2 & 1)) { + list->flags2 |= 1; + list->flags2 |= 4; + processButton(list); + _screen->updateScreen(); + } + } else { + if (list->flags2 & 1) { + list->flags2 &= 0xFFFE; + processButton(list); + processMouseClick = 1; + } + } + } else if (_vm->_mousePressFlag) { + processMouseClick = 1; + } + + if (processMouseClick) { + if (list->buttonCallback) { + if ((*list->buttonCallback.get())(list)) { + break; + } + } + } + } else { + if (list->flags2 & 1) { + list->flags2 &= 0xFFFE; + processButton(list); + } + if (list->flags2 & 4) { + list->flags2 &= 0xFFFB; + processButton(list); + _screen->updateScreen(); + } + list = list->nextButton; + continue; + } + + list = list->nextButton; + } + return 0; +} + +void GUI_LoK::processButton(Button *button) { + if (!button) + return; + + int processType = 0; + const uint8 *shape = 0; + Button::Callback callback; + + int flags = (button->flags2 & 5); + if (flags == 1) { + processType = button->data2Val1; + if (processType == 1) + shape = button->data2ShapePtr; + else if (processType == 4) + callback = button->data2Callback; + } else if (flags == 4 || flags == 5) { + processType = button->data1Val1; + if (processType == 1) + shape = button->data1ShapePtr; + else if (processType == 4) + callback = button->data1Callback; + } else { + processType = button->data0Val1; + if (processType == 1) + shape = button->data0ShapePtr; + else if (processType == 4) + callback = button->data0Callback; + } + + int x = button->x; + int y = button->y; + assert(_screen->getScreenDim(button->dimTableIndex) != 0); + if (x < 0) + x += _screen->getScreenDim(button->dimTableIndex)->w << 3; + + if (y < 0) + y += _screen->getScreenDim(button->dimTableIndex)->h; + + if (processType == 1 && shape) + _screen->drawShape(_screen->_curPage, shape, x, y, button->dimTableIndex, 0x10); + else if (processType == 4 && callback) + (*callback.get())(button); +} + +void GUI_LoK::setGUILabels() { + int offset = 0; + int offsetOptions = 0; + int offsetMainMenu = 0; + int offsetOn = 0; + + int walkspeedGarbageOffset = 36; + int menuLabelGarbageOffset = 0; + + if (_vm->gameFlags().isTalkie) { + if (_vm->gameFlags().lang == Common::EN_ANY) + offset = 52; + else if (_vm->gameFlags().lang == Common::DE_DEU) + offset = 30; + else if (_vm->gameFlags().lang == Common::FR_FRA || _vm->gameFlags().lang == Common::IT_ITA) + offset = 6; + offsetOn = offsetMainMenu = offsetOptions = offset; + walkspeedGarbageOffset = 48; + } else if (_vm->gameFlags().lang == Common::ES_ESP) { + offsetOn = offsetMainMenu = offsetOptions = offset = -4; + menuLabelGarbageOffset = 72; + } else if (_vm->gameFlags().lang == Common::DE_DEU) { + offset = offsetMainMenu = offsetOn = offsetOptions = 24; + } else if (_vm->gameFlags().platform == Common::kPlatformFMTowns || _vm->gameFlags().platform == Common::kPlatformPC98) { + offset = 1; + offsetOptions = 10; + offsetOn = 0; + walkspeedGarbageOffset = 0; + } + + assert(offset + 27 < _vm->_guiStringsSize); + + // The Legend of Kyrandia + _menu[0].menuNameString = _vm->_guiStrings[0]; + // Load a Game + _menu[0].item[0].itemString = _vm->_guiStrings[1]; + // Save a Game + _menu[0].item[1].itemString = _vm->_guiStrings[2]; + // Game controls + _menu[0].item[2].itemString = _vm->_guiStrings[3]; + // Quit playing + _menu[0].item[3].itemString = _vm->_guiStrings[4]; + // Resume game + _menu[0].item[4].itemString = _vm->_guiStrings[5]; + + // Cancel + _menu[2].item[5].itemString = _vm->_guiStrings[10]; + + // Enter a description of your saved game: + _menu[3].menuNameString = _vm->_guiStrings[11]; + // Save + _menu[3].item[0].itemString = _vm->_guiStrings[12]; + // Cancel + _menu[3].item[1].itemString = _vm->_guiStrings[10]; + + // Rest in peace, Brandon + _menu[4].menuNameString = _vm->_guiStrings[13]; + // Load a game + _menu[4].item[0].itemString = _vm->_guiStrings[1]; + // Quit playing + _menu[4].item[1].itemString = _vm->_guiStrings[4]; + + // Game Controls + _menu[5].menuNameString = _vm->_guiStrings[6]; + // Yes + _menu[1].item[0].itemString = _vm->_guiStrings[22 + offset]; + // No + _menu[1].item[1].itemString = _vm->_guiStrings[23 + offset]; + + // Music is + _menu[5].item[0].labelString = _vm->_guiStrings[26 + offsetOptions]; + // Sounds are + _menu[5].item[1].labelString = _vm->_guiStrings[27 + offsetOptions]; + // Walk speed + _menu[5].item[2].labelString = &_vm->_guiStrings[24 + offsetOptions][walkspeedGarbageOffset]; + // Text speed + _menu[5].item[4].labelString = _vm->_guiStrings[25 + offsetOptions]; + // Main Menu + _menu[5].item[5].itemString = &_vm->_guiStrings[19 + offsetMainMenu][menuLabelGarbageOffset]; + + if (_vm->gameFlags().isTalkie) + // Text & Voice + _voiceTextString = _vm->_guiStrings[28 + offset]; + + _textSpeedString = _vm->_guiStrings[25 + offsetOptions]; + _onString = _vm->_guiStrings[20 + offsetOn]; + _offString = _vm->_guiStrings[21 + offset]; + _onCDString = _vm->_guiStrings[21]; +} + +int GUI_LoK::buttonMenuCallback(Button *caller) { + PauseTimer pause(*_vm->_timer); + + _displayMenu = true; + + assert(_vm->_guiStrings); + assert(_vm->_configStrings); + + /* + for (int i = 0; i < _vm->_guiStringsSize; i++) + debug("GUI string %i: %s", i, _vm->_guiStrings[i]); + + for (int i = 0; i < _vm->_configStringsSize; i++) + debug("Config string %i: %s", i, _vm->_configStrings[i]); + */ + + setGUILabels(); + if (_vm->_currentCharacter->sceneId == 210 && _vm->_deathHandler == 0xFF) { + _vm->snd_playSoundEffect(0x36); + return 0; + } + // XXX + _screen->setPaletteIndex(0xFE, 60, 60, 0); + for (int i = 0; i < 6; i++) { + _menuButtonData[i].data0Val1 = _menuButtonData[i].data1Val1 = _menuButtonData[i].data2Val1 = 4; + _menuButtonData[i].data0Callback = _redrawShadedButtonFunctor; + _menuButtonData[i].data1Callback = _redrawButtonFunctor; + _menuButtonData[i].data2Callback = _redrawButtonFunctor; + } + + _screen->savePageToDisk("SEENPAGE.TMP", 0); + fadePalette(); + + for (int i = 0; i < 5; i++) + initMenuLayout(_menu[i]); + + _menuRestoreScreen = true; + _keyPressed.reset(); + _vm->_mousePressFlag = false; + + _toplevelMenu = 0; + if (_vm->_menuDirectlyToLoad) { + loadGameMenu(0); + } else { + if (!caller) + _toplevelMenu = 4; + + initMenu(_menu[_toplevelMenu]); + updateAllMenuButtons(); + } + + while (_displayMenu && !_vm->_quitFlag) { + Common::Point mouse = _vm->getMousePos(); + processHighlights(_menu[_toplevelMenu], mouse.x, mouse.y); + processButtonList(_menuButtonList, 0, 0); + getInput(); + } + + if (_menuRestoreScreen) { + restorePalette(); + _screen->loadPageFromDisk("SEENPAGE.TMP", 0); + _vm->_animator->_updateScreen = true; + } else { + _screen->deletePageFromDisk(0); + } + + return 0; +} + +void GUI_LoK::getInput() { + Common::Event event; + static uint32 lastScreenUpdate = 0; + uint32 now = _vm->_system->getMillis(); + + _mouseWheel = 0; + while (_vm->_eventMan->pollEvent(event)) { + switch (event.type) { + case Common::EVENT_QUIT: + _vm->quitGame(); + break; + case Common::EVENT_LBUTTONDOWN: + _vm->_mousePressFlag = true; + break; + case Common::EVENT_LBUTTONUP: + _vm->_mousePressFlag = false; + break; + case Common::EVENT_MOUSEMOVE: + _vm->_system->updateScreen(); + lastScreenUpdate = now; + break; + case Common::EVENT_WHEELUP: + _mouseWheel = -1; + break; + case Common::EVENT_WHEELDOWN: + _mouseWheel = 1; + break; + case Common::EVENT_KEYDOWN: + _keyPressed = event.kbd; + break; + default: + break; + } + } + + if (now - lastScreenUpdate > 50) { + _vm->_system->updateScreen(); + lastScreenUpdate = now; + } + + _vm->_system->delayMillis(3); +} + +int GUI_LoK::resumeGame(Button *button) { + debugC(9, kDebugLevelGUI, "GUI_LoK::resumeGame()"); + updateMenuButton(button); + _displayMenu = false; + + return 0; +} + +void GUI_LoK::setupSavegames(Menu &menu, int num) { + Common::InSaveFile *in; + static char savenames[5][31]; + uint8 startSlot; + assert(num <= 5); + + if (_savegameOffset == 0) { + menu.item[0].itemString = _specialSavegameString; + menu.item[0].enabled = 1; + menu.item[0].saveSlot = 0; + startSlot = 1; + } else { + startSlot = 0; + } + + for (int i = startSlot; i < num; ++i) + menu.item[i].enabled = 0; + + KyraEngine::SaveHeader header; + for (int i = startSlot; i < num && uint(_savegameOffset + i) < _saveSlots.size(); i++) { + if ((in = _vm->openSaveForReading(_vm->getSavegameFilename(_saveSlots[i + _savegameOffset]), header))) { + strncpy(savenames[i], header.description.c_str(), 31); + menu.item[i].itemString = savenames[i]; + menu.item[i].enabled = 1; + menu.item[i].saveSlot = _saveSlots[i + _savegameOffset]; + delete in; + } + } +} + +int GUI_LoK::saveGameMenu(Button *button) { + debugC(9, kDebugLevelGUI, "GUI_LoK::saveGameMenu()"); + updateSaveList(); + + updateMenuButton(button); + _menu[2].item[5].enabled = true; + + _screen->loadPageFromDisk("SEENPAGE.TMP", 0); + _screen->savePageToDisk("SEENPAGE.TMP", 0); + + _menu[2].menuNameString = _vm->_guiStrings[8]; // Select a position to save to: + _specialSavegameString = _vm->_guiStrings[9]; // [ EMPTY SLOT ] + for (int i = 0; i < 5; i++) + _menu[2].item[i].callback = BUTTON_FUNCTOR(GUI_LoK, this, &GUI_LoK::saveGame); + + _savegameOffset = 0; + setupSavegames(_menu[2], 5); + + initMenu(_menu[2]); + updateAllMenuButtons(); + + _displaySubMenu = true; + _cancelSubMenu = false; + + while (_displaySubMenu && !_vm->_quitFlag) { + getInput(); + Common::Point mouse = _vm->getMousePos(); + processHighlights(_menu[2], mouse.x, mouse.y); + processButtonList(_menuButtonList, 0, _mouseWheel); + } + + _screen->loadPageFromDisk("SEENPAGE.TMP", 0); + _screen->savePageToDisk("SEENPAGE.TMP", 0); + + if (_cancelSubMenu) { + initMenu(_menu[0]); + updateAllMenuButtons(); + } else { + _displayMenu = false; + } + return 0; +} + +int GUI_LoK::loadGameMenu(Button *button) { + debugC(9, kDebugLevelGUI, "GUI_LoK::loadGameMenu()"); + updateSaveList(); + + if (_vm->_menuDirectlyToLoad) { + _menu[2].item[5].enabled = false; + } else { + updateMenuButton(button); + _menu[2].item[5].enabled = true; + } + + _screen->loadPageFromDisk("SEENPAGE.TMP", 0); + _screen->savePageToDisk("SEENPAGE.TMP", 0); + + _specialSavegameString = _vm->_newGameString[0]; //[ START A NEW GAME ] + _menu[2].menuNameString = _vm->_guiStrings[7]; // Which game would you like to reload? + for (int i = 0; i < 5; i++) + _menu[2].item[i].callback = BUTTON_FUNCTOR(GUI_LoK, this, &GUI_LoK::loadGame); + + _savegameOffset = 0; + setupSavegames(_menu[2], 5); + + initMenu(_menu[2]); + updateAllMenuButtons(); + + _displaySubMenu = true; + _cancelSubMenu = false; + + _vm->_gameToLoad = -1; + + while (_displaySubMenu && !_vm->_quitFlag) { + getInput(); + Common::Point mouse = _vm->getMousePos(); + processHighlights(_menu[2], mouse.x, mouse.y); + processButtonList(_menuButtonList, 0, _mouseWheel); + } + + _screen->loadPageFromDisk("SEENPAGE.TMP", 0); + _screen->savePageToDisk("SEENPAGE.TMP", 0); + + if (_cancelSubMenu) { + initMenu(_menu[_toplevelMenu]); + updateAllMenuButtons(); + } else { + restorePalette(); + if (_vm->_gameToLoad != -1) + _vm->loadGame(_vm->getSavegameFilename(_vm->_gameToLoad)); + _displayMenu = false; + _menuRestoreScreen = false; + } + return 0; +} + +void GUI_LoK::redrawTextfield() { + _screen->fillRect(38, 91, 287, 102, 250); + _text->printText(_savegameName, 38, 92, 253, 0, 0); + + _screen->_charWidth = -2; + int width = _screen->getTextWidth(_savegameName); + _screen->fillRect(39 + width, 93, 45 + width, 100, 254); + _screen->_charWidth = 0; + + _screen->updateScreen(); +} + +void GUI_LoK::updateSavegameString() { + int length; + + if (_keyPressed.keycode) { + length = strlen(_savegameName); + + if (_keyPressed.ascii > 31 && _keyPressed.ascii < 127) { + if (length < 31) { + _savegameName[length] = _keyPressed.ascii; + _savegameName[length+1] = 0; + redrawTextfield(); + } + } else if (_keyPressed.keycode == Common::KEYCODE_BACKSPACE || + _keyPressed.keycode == Common::KEYCODE_DELETE) { + if (length > 0) { + _savegameName[length-1] = 0; + redrawTextfield(); + } + } else if (_keyPressed.keycode == Common::KEYCODE_RETURN || + _keyPressed.keycode == Common::KEYCODE_KP_ENTER) { + _displaySubMenu = false; + } + } + + _keyPressed.reset(); +} + +int GUI_LoK::saveGame(Button *button) { + debugC(9, kDebugLevelGUI, "GUI_LoK::saveGame()"); + updateMenuButton(button); + _vm->_gameToLoad = _menu[2].item[button->index-0xC].saveSlot; + + _screen->loadPageFromDisk("SEENPAGE.TMP", 0); + _screen->savePageToDisk("SEENPAGE.TMP", 0); + + initMenu(_menu[3]); + updateAllMenuButtons(); + + _displaySubMenu = true; + _cancelSubMenu = false; + + if (_savegameOffset == 0 && _vm->_gameToLoad == 0) { + _savegameName[0] = 0; + } else { + for (int i = 0; i < 5; i++) { + if (_menu[2].item[i].saveSlot == _vm->_gameToLoad) { + strncpy(_savegameName, _menu[2].item[i].itemString, 31); + break; + } + } + } + redrawTextfield(); + + while (_displaySubMenu && !_vm->_quitFlag) { + getInput(); + updateSavegameString(); + Common::Point mouse = _vm->getMousePos(); + processHighlights(_menu[3], mouse.x, mouse.y); + processButtonList(_menuButtonList, 0, 0); + } + + if (_cancelSubMenu) { + _displaySubMenu = true; + _cancelSubMenu = false; + initMenu(_menu[2]); + updateAllMenuButtons(); + } else { + if (_savegameOffset == 0 && _vm->_gameToLoad == 0) + _vm->_gameToLoad = getNextSavegameSlot(); + if (_vm->_gameToLoad > 0) + _vm->saveGame(_vm->getSavegameFilename(_vm->_gameToLoad), _savegameName); + } + + return 0; +} + +int GUI_LoK::savegameConfirm(Button *button) { + debugC(9, kDebugLevelGUI, "GUI_LoK::savegameConfirm()"); + updateMenuButton(button); + _displaySubMenu = false; + + return 0; +} + +int GUI_LoK::loadGame(Button *button) { + debugC(9, kDebugLevelGUI, "GUI_LoK::loadGame()"); + updateMenuButton(button); + _displaySubMenu = false; + _vm->_gameToLoad = _menu[2].item[button->index-0xC].saveSlot; + + return 0; +} + +int GUI_LoK::cancelSubMenu(Button *button) { + debugC(9, kDebugLevelGUI, "GUI_LoK::cancelSubMenu()"); + updateMenuButton(button); + _displaySubMenu = false; + _cancelSubMenu = true; + + return 0; +} + +int GUI_LoK::quitPlaying(Button *button) { + debugC(9, kDebugLevelGUI, "GUI_LoK::quitPlaying()"); + updateMenuButton(button); + + if (quitConfirm(_vm->_guiStrings[14])) { // Are you sure you want to quit playing? + _vm->quitGame(); + } else { + initMenu(_menu[_toplevelMenu]); + updateAllMenuButtons(); + } + + return 0; +} + +bool GUI_LoK::quitConfirm(const char *str) { + debugC(9, kDebugLevelGUI, "GUI_LoK::quitConfirm()"); + + _screen->loadPageFromDisk("SEENPAGE.TMP", 0); + _screen->savePageToDisk("SEENPAGE.TMP", 0); + + _menu[1].menuNameString = str; + initMenuLayout(_menu[1]); + initMenu(_menu[1]); + + _displaySubMenu = true; + _cancelSubMenu = true; + + while (_displaySubMenu && !_vm->_quitFlag) { + getInput(); + Common::Point mouse = _vm->getMousePos(); + processHighlights(_menu[1], mouse.x, mouse.y); + processButtonList(_menuButtonList, 0, 0); + } + + _screen->loadPageFromDisk("SEENPAGE.TMP", 0); + _screen->savePageToDisk("SEENPAGE.TMP", 0); + + return !_cancelSubMenu; +} + +int GUI_LoK::quitConfirmYes(Button *button) { + debugC(9, kDebugLevelGUI, "GUI_LoK::quitConfirmYes()"); + updateMenuButton(button); + _displaySubMenu = false; + _cancelSubMenu = false; + + return 0; +} + +int GUI_LoK::quitConfirmNo(Button *button) { + debugC(9, kDebugLevelGUI, "GUI_LoK::quitConfirmNo()"); + updateMenuButton(button); + _displaySubMenu = false; + _cancelSubMenu = true; + + return 0; +} + +int GUI_LoK::gameControlsMenu(Button *button) { + debugC(9, kDebugLevelGUI, "GUI_LoK::gameControlsMenu()"); + + _vm->readSettings(); + + _screen->loadPageFromDisk("SEENPAGE.TMP", 0); + _screen->savePageToDisk("SEENPAGE.TMP", 0); + + if (_vm->gameFlags().isTalkie) { + //_menu[5].width = 230; + + for (int i = 0; i < 5; i++) { + //_menu[5].item[i].labelX = 24; + //_menu[5].item[i].x = 115; + //_menu[5].item[i].width = 94; + } + + _menu[5].item[3].labelString = _voiceTextString; //"Voice / Text " + _menu[5].item[3].callback = BUTTON_FUNCTOR(GUI_LoK, this, &GUI_LoK::controlsChangeVoice); + + } else { + //_menu[5].height = 136; + //_menu[5].item[5].y = 110; + _menu[5].item[4].enabled = 0; + _menu[5].item[3].labelString = _textSpeedString; // "Text speed " + _menu[5].item[3].callback = BUTTON_FUNCTOR(GUI_LoK, this, &GUI_LoK::controlsChangeText); + } + + setupControls(_menu[5]); + + updateAllMenuButtons(); + + _displaySubMenu = true; + _cancelSubMenu = false; + + while (_displaySubMenu && !_vm->_quitFlag) { + getInput(); + Common::Point mouse = _vm->getMousePos(); + processHighlights(_menu[5], mouse.x, mouse.y); + processButtonList(_menuButtonList, 0, 0); + } + + _screen->loadPageFromDisk("SEENPAGE.TMP", 0); + _screen->savePageToDisk("SEENPAGE.TMP", 0); + + if (_cancelSubMenu) { + initMenu(_menu[_toplevelMenu]); + updateAllMenuButtons(); + } + return 0; +} + +void GUI_LoK::setupControls(Menu &menu) { + debugC(9, kDebugLevelGUI, "GUI_LoK::setupControls()"); + + switch (_vm->_configMusic) { + case 0: + menu.item[0].itemString = _offString; //"Off" + break; + case 1: + menu.item[0].itemString = _onString; //"On" + break; + case 2: + menu.item[0].itemString = _onCDString; //"On + CD" + break; + } + + if (_vm->_configSounds) + menu.item[1].itemString = _onString; //"On" + else + menu.item[1].itemString = _offString; //"Off" + + + switch (_vm->_configWalkspeed) { + case 0: + menu.item[2].itemString = _vm->_configStrings[0]; //"Slowest" + break; + case 1: + menu.item[2].itemString = _vm->_configStrings[1]; //"Slow" + break; + case 2: + menu.item[2].itemString = _vm->_configStrings[2]; //"Normal" + break; + case 3: + menu.item[2].itemString = _vm->_configStrings[3]; //"Fast" + break; + case 4: + menu.item[2].itemString = _vm->_configStrings[4]; //"Fastest" + break; + default: + menu.item[2].itemString = "ERROR"; + break; + } + + int textControl = 3; + int clickableOffset = 8; + if (_vm->gameFlags().isTalkie) { + textControl = 4; + clickableOffset = 11; + + if (_vm->_configVoice == 0) { + menu.item[4].enabled = 1; + menu.item[4].labelString = _textSpeedString; + } else { + menu.item[4].enabled = 0; + menu.item[4].labelString = 0; + } + + switch (_vm->_configVoice) { + case 0: + menu.item[3].itemString = _vm->_configStrings[5]; //"Text only" + break; + case 1: + menu.item[3].itemString = _vm->_configStrings[6]; //"Voice only" + break; + case 2: + menu.item[3].itemString = _vm->_configStrings[7]; //"Voice & Text" + break; + default: + menu.item[3].itemString = "ERROR"; + break; + } + } else { + menu.item[4].enabled = 0; + menu.item[4].labelString = 0; + } + + switch (_vm->_configTextspeed) { + case 0: + menu.item[textControl].itemString = _vm->_configStrings[1]; //"Slow" + break; + case 1: + menu.item[textControl].itemString = _vm->_configStrings[2]; //"Normal" + break; + case 2: + menu.item[textControl].itemString = _vm->_configStrings[3]; //"Fast" + break; + case 3: + menu.item[textControl].itemString = _vm->_configStrings[clickableOffset]; //"Clickable" + break; + default: + menu.item[textControl].itemString = "ERROR"; + break; + } + + initMenuLayout(menu); + initMenu(menu); +} + +int GUI_LoK::controlsChangeMusic(Button *button) { + debugC(9, kDebugLevelGUI, "GUI_LoK::controlsChangeMusic()"); + updateMenuButton(button); + + _vm->_configMusic = ++_vm->_configMusic % ((_vm->gameFlags().platform == Common::kPlatformFMTowns || _vm->gameFlags().platform == Common::kPlatformPC98) ? 3 : 2); + setupControls(_menu[5]); + return 0; +} + +int GUI_LoK::controlsChangeSounds(Button *button) { + debugC(9, kDebugLevelGUI, "GUI_LoK::controlsChangeSounds()"); + updateMenuButton(button); + + _vm->_configSounds = !_vm->_configSounds; + setupControls(_menu[5]); + return 0; +} + +int GUI_LoK::controlsChangeWalk(Button *button) { + debugC(9, kDebugLevelGUI, "GUI_LoK::controlsChangeWalk()"); + updateMenuButton(button); + + _vm->_configWalkspeed = ++_vm->_configWalkspeed % 5; + _vm->setWalkspeed(_vm->_configWalkspeed); + setupControls(_menu[5]); + return 0; +} + +int GUI_LoK::controlsChangeText(Button *button) { + debugC(9, kDebugLevelGUI, "GUI_LoK::controlsChangeText()"); + updateMenuButton(button); + + _vm->_configTextspeed = ++_vm->_configTextspeed % 4; + setupControls(_menu[5]); + return 0; +} + +int GUI_LoK::controlsChangeVoice(Button *button) { + debugC(9, kDebugLevelGUI, "GUI_LoK::controlsChangeVoice()"); + updateMenuButton(button); + + _vm->_configVoice = ++_vm->_configVoice % 3; + setupControls(_menu[5]); + return 0; +} + +int GUI_LoK::controlsApply(Button *button) { + debugC(9, kDebugLevelGUI, "GUI_LoK::controlsApply()"); + _vm->writeSettings(); + return cancelSubMenu(button); +} + +int GUI_LoK::scrollUp(Button *button) { + debugC(9, kDebugLevelGUI, "GUI_LoK::scrollUp()"); + updateMenuButton(button); + + if (_savegameOffset > 0) { + _savegameOffset--; + setupSavegames(_menu[2], 5); + initMenu(_menu[2]); + } + return 0; +} + +int GUI_LoK::scrollDown(Button *button) { + debugC(9, kDebugLevelGUI, "GUI_LoK::scrollDown()"); + updateMenuButton(button); + + _savegameOffset++; + if (uint(_savegameOffset + 5) >= _saveSlots.size()) + _savegameOffset = MAX(_saveSlots.size() - 5, 0); + setupSavegames(_menu[2], 5); + initMenu(_menu[2]); + + return 0; +} + +void GUI_LoK::fadePalette() { + if (_vm->gameFlags().platform == Common::kPlatformAmiga) + return; + + static int16 menuPalIndexes[] = {248, 249, 250, 251, 252, 253, 254, -1}; + int index = 0; + + memcpy(_screen->getPalette(2), _screen->_currentPalette, 768); + + for (int i = 0; i < 768; i++) + _screen->_currentPalette[i] >>= 1; + + while (menuPalIndexes[index] != -1) { + memcpy(&_screen->_currentPalette[menuPalIndexes[index]*3], &_screen->getPalette(2)[menuPalIndexes[index]*3], 3); + index++; + } + + _screen->fadePalette(_screen->_currentPalette, 2); +} + +void GUI_LoK::restorePalette() { + if (_vm->gameFlags().platform == Common::kPlatformAmiga) + return; + + memcpy(_screen->_currentPalette, _screen->getPalette(2), 768); + _screen->fadePalette(_screen->_currentPalette, 2); +} + +#pragma mark - + +void KyraEngine_LoK::drawAmulet() { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::drawAmulet()"); + static const int16 amuletTable1[] = {0x167, 0x162, 0x15D, 0x158, 0x153, 0x150, 0x155, 0x15A, 0x15F, 0x164, 0x145, -1}; + static const int16 amuletTable3[] = {0x167, 0x162, 0x15D, 0x158, 0x153, 0x14F, 0x154, 0x159, 0x15E, 0x163, 0x144, -1}; + static const int16 amuletTable2[] = {0x167, 0x162, 0x15D, 0x158, 0x153, 0x152, 0x157, 0x15C, 0x161, 0x166, 0x147, -1}; + static const int16 amuletTable4[] = {0x167, 0x162, 0x15D, 0x158, 0x153, 0x151, 0x156, 0x15B, 0x160, 0x165, 0x146, -1}; + + resetGameFlag(0xF1); + _screen->hideMouse(); + + int i = 0; + while (amuletTable1[i] != -1) { + if (queryGameFlag(87)) + _screen->drawShape(0, _shapes[amuletTable1[i]], _amuletX[0], _amuletY[0], 0, 0); + + if (queryGameFlag(89)) + _screen->drawShape(0, _shapes[amuletTable2[i]], _amuletX[1], _amuletY[1], 0, 0); + + if (queryGameFlag(86)) + _screen->drawShape(0, _shapes[amuletTable3[i]], _amuletX[2], _amuletY[2], 0, 0); + + if (queryGameFlag(88)) + _screen->drawShape(0, _shapes[amuletTable4[i]], _amuletX[3], _amuletY[3], 0, 0); + + _screen->updateScreen(); + delayWithTicks(3); + i++; + } + _screen->showMouse(); +} + +} // end of namespace Kyra + diff --git a/engines/kyra/gui_lok.h b/engines/kyra/gui_lok.h new file mode 100644 index 0000000000..78284e5ec1 --- /dev/null +++ b/engines/kyra/gui_lok.h @@ -0,0 +1,177 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#ifndef KYRA_GUI_V1_H +#define KYRA_GUI_V1_H + +#include "kyra/gui.h" + +namespace Kyra { + +#define GUI_V1_BUTTON(button, a, b, c, d, e, f, g, h, i, j, k) \ + button.nextButton = 0; \ + button.index = a; \ + button.unk6 = button.unk8 = 0; \ + button.data0Val1 = b; \ + button.data1Val1 = c; \ + button.data2Val1 = d; \ + button.data0ShapePtr = button.data1ShapePtr = button.data2ShapePtr = 0; \ + button.flags = e; \ + button.dimTableIndex = f; \ + button.x = g; \ + button.y = h; \ + button.width = i; \ + button.height = j; \ + button.flags2 = k; \ + button.mouseWheel = 0 + +#define GUI_V1_MENU(menu, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q) \ + menu.x = a; \ + menu.y = b; \ + menu.width = c; \ + menu.height = d; \ + menu.bkgdColor = e; \ + menu.color1 = f; \ + menu.color2 = g; \ + menu.menuNameString = h; \ + menu.textColor = i; \ + menu.titleX = j; \ + menu.titleY = k; \ + menu.highlightedItem = l; \ + menu.numberOfItems = m; \ + menu.scrollUpButtonX = n; \ + menu.scrollUpButtonY = o; \ + menu.scrollDownButtonX = p; \ + menu.scrollDownButtonY = q + +#define GUI_V1_MENU_ITEM(item, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v) \ + item.enabled = a; \ + item.itemString = d; \ + item.x = e; \ + item.y = g; \ + item.width = h; \ + item.height = i; \ + item.textColor = j; \ + item.highlightColor = k; \ + item.titleX = l; \ + item.bkgdColor = n; \ + item.color1 = o; \ + item.color2 = p; \ + item.saveSlot = q; \ + item.labelString = r; \ + item.labelX = s; \ + item.labelY = t; \ + item.unk1F = v + +class KyraEngine_LoK; + +class GUI_LoK : public GUI { + friend class KyraEngine_LoK; +public: + GUI_LoK(KyraEngine_LoK *vm, Screen_LoK *screen); + ~GUI_LoK(); + + void processButton(Button *button); + int processButtonList(Button *buttonList, uint16 inputFlags, int8 mouseWheel); + + int buttonMenuCallback(Button *caller); +private: + void initStaticResource(); + + Button _menuButtonData[6]; + Button _scrollUpButton; + Button _scrollDownButton; + Button *getButtonListData() { return _menuButtonData; } + Button *getScrollUpButton() { return &_scrollUpButton; } + Button *getScrollDownButton() { return &_scrollDownButton; } + + Menu *_menu; + + void setGUILabels(); + + void setupSavegames(Menu &menu, int num); + + int resumeGame(Button *button); + int loadGameMenu(Button *button); + int saveGameMenu(Button *button); + int gameControlsMenu(Button *button); + int quitPlaying(Button *button); + int quitConfirmYes(Button *button); + int quitConfirmNo(Button *button); + int loadGame(Button *button); + int saveGame(Button *button); + int savegameConfirm(Button *button); + int cancelSubMenu(Button *button); + int scrollUp(Button *button); + int scrollDown(Button *button); + int controlsChangeMusic(Button *button); + int controlsChangeSounds(Button *button); + int controlsChangeWalk(Button *button); + int controlsChangeText(Button *button); + int controlsChangeVoice(Button *button); + int controlsApply(Button *button); + + bool quitConfirm(const char *str); + void getInput(); + void updateSavegameString(); + void redrawTextfield(); + void fadePalette(); + void restorePalette(); + void setupControls(Menu &menu); + + uint8 defaultColor1() const { return 12; } + uint8 defaultColor2() const { return 248; } + + const char *getMenuTitle(const Menu &menu) { return menu.menuNameString; } + const char *getMenuItemTitle(const MenuItem &menuItem) { return menuItem.itemString; } + const char *getMenuItemLabel(const MenuItem &menuItem) { return menuItem.labelString; } + + KyraEngine_LoK *_vm; + Screen_LoK *_screen; + + bool _menuRestoreScreen; + uint8 _toplevelMenu; + int _savegameOffset; + char _savegameName[31]; + const char *_specialSavegameString; + Common::KeyState _keyPressed; + int8 _mouseWheel; + + Button::Callback _scrollUpFunctor; + Button::Callback _scrollDownFunctor; + Button::Callback getScrollUpButtonHandler() const { return _scrollUpFunctor; } + Button::Callback getScrollDownButtonHandler() const { return _scrollDownFunctor; } + + const char *_voiceTextString; + const char *_textSpeedString; + const char *_onString; + const char *_offString; + const char *_onCDString; +}; + +} // end of namespace Kyra + +#endif + diff --git a/engines/kyra/gui_v1.cpp b/engines/kyra/gui_v1.cpp deleted file mode 100644 index fab5db0a01..0000000000 --- a/engines/kyra/gui_v1.cpp +++ /dev/null @@ -1,1115 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include "kyra/kyra_v1.h" -#include "kyra/screen.h" -#include "kyra/script.h" -#include "kyra/text.h" -#include "kyra/animator_v1.h" -#include "kyra/sound.h" -#include "kyra/gui_v1.h" -#include "kyra/timer.h" - -#include "common/config-manager.h" -#include "common/savefile.h" -#include "common/events.h" -#include "common/system.h" - -namespace Kyra { - -void KyraEngine_v1::initMainButtonList() { - _buttonList = &_buttonData[0]; - for (int i = 0; _buttonDataListPtr[i]; ++i) - _buttonList = _gui->addButtonToList(_buttonList, _buttonDataListPtr[i]); -} - -int KyraEngine_v1::buttonInventoryCallback(Button *caller) { - int itemOffset = caller->index - 2; - uint8 inventoryItem = _currentCharacter->inventoryItems[itemOffset]; - if (_itemInHand == -1) { - if (inventoryItem == 0xFF) { - snd_playSoundEffect(0x36); - return 0; - } else { - _screen->hideMouse(); - _screen->fillRect(_itemPosX[itemOffset], _itemPosY[itemOffset], _itemPosX[itemOffset] + 15, _itemPosY[itemOffset] + 15, 12); - snd_playSoundEffect(0x35); - setMouseItem(inventoryItem); - updateSentenceCommand(_itemList[inventoryItem], _takenList[0], 179); - _itemInHand = inventoryItem; - _screen->showMouse(); - _currentCharacter->inventoryItems[itemOffset] = 0xFF; - } - } else { - if (inventoryItem != 0xFF) { - snd_playSoundEffect(0x35); - _screen->hideMouse(); - _screen->fillRect(_itemPosX[itemOffset], _itemPosY[itemOffset], _itemPosX[itemOffset] + 15, _itemPosY[itemOffset] + 15, 12); - _screen->drawShape(0, _shapes[216+_itemInHand], _itemPosX[itemOffset], _itemPosY[itemOffset], 0, 0); - setMouseItem(inventoryItem); - updateSentenceCommand(_itemList[inventoryItem], _takenList[1], 179); - _screen->showMouse(); - _currentCharacter->inventoryItems[itemOffset] = _itemInHand; - _itemInHand = inventoryItem; - } else { - snd_playSoundEffect(0x32); - _screen->hideMouse(); - _screen->drawShape(0, _shapes[216+_itemInHand], _itemPosX[itemOffset], _itemPosY[itemOffset], 0, 0); - _screen->setMouseCursor(1, 1, _shapes[0]); - updateSentenceCommand(_itemList[_itemInHand], _placedList[0], 179); - _screen->showMouse(); - _currentCharacter->inventoryItems[itemOffset] = _itemInHand; - _itemInHand = -1; - } - } - _screen->updateScreen(); - // XXX clearKyrandiaButtonIO - return 0; -} - -int KyraEngine_v1::buttonAmuletCallback(Button *caller) { - if (!(_deathHandler & 8)) - return 1; - int jewel = caller->index - 0x14; - if (_currentCharacter->sceneId == 210) { - if (_beadStateVar == 4 || _beadStateVar == 6) - return 1; - } - if (!queryGameFlag(0x2D)) - return 1; - if (_itemInHand != -1) { - assert(_putDownFirst); - characterSays(2000, _putDownFirst[0], 0, -2); - return 1; - } - if (queryGameFlag(0xF1)) { - assert(_waitForAmulet); - characterSays(2001, _waitForAmulet[0], 0, -2); - return 1; - } - if (!queryGameFlag(0x55+jewel)) { - assert(_blackJewel); - _animator->makeBrandonFaceMouse(); - drawJewelPress(jewel, 1); - characterSays(2002, _blackJewel[0], 0, -2); - return 1; - } - drawJewelPress(jewel, 0); - drawJewelsFadeOutStart(); - drawJewelsFadeOutEnd(jewel); - - _emc->init(&_scriptClick, &_scriptClickData); - _scriptClick.regs[3] = 0; - _scriptClick.regs[6] = jewel; - _emc->start(&_scriptClick, 4); - - while (_emc->isValid(&_scriptClick)) - _emc->run(&_scriptClick); - - if (_scriptClick.regs[3]) - return 1; - - _unkAmuletVar = 1; - switch (jewel-1) { - case 0: - if (_brandonStatusBit & 1) { - seq_brandonHealing2(); - } else if (_brandonStatusBit == 0) { - seq_brandonHealing(); - assert(_healingTip); - characterSays(2003, _healingTip[0], 0, -2); - } - break; - - case 1: - seq_makeBrandonInv(); - break; - - case 2: - if (_brandonStatusBit & 1) { - assert(_wispJewelStrings); - characterSays(2004, _wispJewelStrings[0], 0, -2); - } else { - if (_brandonStatusBit & 2) { - // XXX - seq_makeBrandonNormal2(); - // XXX - } else { - // do not check for item in hand again as in the original since some strings are missing - // in the cd version - if (_currentCharacter->sceneId >= 109 && _currentCharacter->sceneId <= 198) { - snd_playWanderScoreViaMap(1, 0); - seq_makeBrandonWisp(); - snd_playWanderScoreViaMap(17, 0); - } else { - seq_makeBrandonWisp(); - } - setGameFlag(0x9E); - } - } - break; - - case 3: - seq_dispelMagicAnimation(); - assert(_magicJewelString); - characterSays(2007, _magicJewelString[0], 0, -2); - break; - - default: - break; - } - _unkAmuletVar = 0; - // XXX clearKyrandiaButtonIO (!used before every return in this function!) - return 1; -} - -#pragma mark - - -GUI_v1::GUI_v1(KyraEngine_v1 *vm, Screen_v1 *screen) : GUI(vm), _vm(vm), _screen(screen) { - _menu = 0; - initStaticResource(); - _scrollUpFunctor = BUTTON_FUNCTOR(GUI_v1, this, &GUI_v1::scrollUp); - _scrollDownFunctor = BUTTON_FUNCTOR(GUI_v1, this, &GUI_v1::scrollDown); -} - -GUI_v1::~GUI_v1() { - delete[] _menu; -} - -int GUI_v1::processButtonList(Button *list, uint16 inputFlag, int8 mouseWheel) { - while (list) { - if (list->flags & 8) { - list = list->nextButton; - continue; - } - - if (mouseWheel && list->mouseWheel == mouseWheel && list->buttonCallback) { - if ((*list->buttonCallback.get())(list)) { - break; - } - } - - int x = list->x; - int y = list->y; - assert(_screen->getScreenDim(list->dimTableIndex) != 0); - if (x < 0) { - x += _screen->getScreenDim(list->dimTableIndex)->w << 3; - } - x += _screen->getScreenDim(list->dimTableIndex)->sx << 3; - - if (y < 0) { - y += _screen->getScreenDim(list->dimTableIndex)->h; - } - y += _screen->getScreenDim(list->dimTableIndex)->sy; - - Common::Point mouse = _vm->getMousePos(); - if (mouse.x >= x && mouse.y >= y && x + list->width >= mouse.x && y + list->height >= mouse.y) { - int processMouseClick = 0; - if (list->flags & 0x400) { - if (_vm->_mousePressFlag) { - if (!(list->flags2 & 1)) { - list->flags2 |= 1; - list->flags2 |= 4; - processButton(list); - _screen->updateScreen(); - } - } else { - if (list->flags2 & 1) { - list->flags2 &= 0xFFFE; - processButton(list); - processMouseClick = 1; - } - } - } else if (_vm->_mousePressFlag) { - processMouseClick = 1; - } - - if (processMouseClick) { - if (list->buttonCallback) { - if ((*list->buttonCallback.get())(list)) { - break; - } - } - } - } else { - if (list->flags2 & 1) { - list->flags2 &= 0xFFFE; - processButton(list); - } - if (list->flags2 & 4) { - list->flags2 &= 0xFFFB; - processButton(list); - _screen->updateScreen(); - } - list = list->nextButton; - continue; - } - - list = list->nextButton; - } - return 0; -} - -void GUI_v1::processButton(Button *button) { - if (!button) - return; - - int processType = 0; - const uint8 *shape = 0; - Button::Callback callback; - - int flags = (button->flags2 & 5); - if (flags == 1) { - processType = button->data2Val1; - if (processType == 1) - shape = button->data2ShapePtr; - else if (processType == 4) - callback = button->data2Callback; - } else if (flags == 4 || flags == 5) { - processType = button->data1Val1; - if (processType == 1) - shape = button->data1ShapePtr; - else if (processType == 4) - callback = button->data1Callback; - } else { - processType = button->data0Val1; - if (processType == 1) - shape = button->data0ShapePtr; - else if (processType == 4) - callback = button->data0Callback; - } - - int x = button->x; - int y = button->y; - assert(_screen->getScreenDim(button->dimTableIndex) != 0); - if (x < 0) - x += _screen->getScreenDim(button->dimTableIndex)->w << 3; - - if (y < 0) - y += _screen->getScreenDim(button->dimTableIndex)->h; - - if (processType == 1 && shape) - _screen->drawShape(_screen->_curPage, shape, x, y, button->dimTableIndex, 0x10); - else if (processType == 4 && callback) - (*callback.get())(button); -} - -void GUI_v1::setGUILabels() { - int offset = 0; - int offsetOptions = 0; - int offsetMainMenu = 0; - int offsetOn = 0; - - int walkspeedGarbageOffset = 36; - int menuLabelGarbageOffset = 0; - - if (_vm->gameFlags().isTalkie) { - if (_vm->gameFlags().lang == Common::EN_ANY) - offset = 52; - else if (_vm->gameFlags().lang == Common::DE_DEU) - offset = 30; - else if (_vm->gameFlags().lang == Common::FR_FRA || _vm->gameFlags().lang == Common::IT_ITA) - offset = 6; - offsetOn = offsetMainMenu = offsetOptions = offset; - walkspeedGarbageOffset = 48; - } else if (_vm->gameFlags().lang == Common::ES_ESP) { - offsetOn = offsetMainMenu = offsetOptions = offset = -4; - menuLabelGarbageOffset = 72; - } else if (_vm->gameFlags().lang == Common::DE_DEU) { - offset = offsetMainMenu = offsetOn = offsetOptions = 24; - } else if (_vm->gameFlags().platform == Common::kPlatformFMTowns || _vm->gameFlags().platform == Common::kPlatformPC98) { - offset = 1; - offsetOptions = 10; - offsetOn = 0; - walkspeedGarbageOffset = 0; - } - - assert(offset + 27 < _vm->_guiStringsSize); - - // The Legend of Kyrandia - _menu[0].menuNameString = _vm->_guiStrings[0]; - // Load a Game - _menu[0].item[0].itemString = _vm->_guiStrings[1]; - // Save a Game - _menu[0].item[1].itemString = _vm->_guiStrings[2]; - // Game controls - _menu[0].item[2].itemString = _vm->_guiStrings[3]; - // Quit playing - _menu[0].item[3].itemString = _vm->_guiStrings[4]; - // Resume game - _menu[0].item[4].itemString = _vm->_guiStrings[5]; - - // Cancel - _menu[2].item[5].itemString = _vm->_guiStrings[10]; - - // Enter a description of your saved game: - _menu[3].menuNameString = _vm->_guiStrings[11]; - // Save - _menu[3].item[0].itemString = _vm->_guiStrings[12]; - // Cancel - _menu[3].item[1].itemString = _vm->_guiStrings[10]; - - // Rest in peace, Brandon - _menu[4].menuNameString = _vm->_guiStrings[13]; - // Load a game - _menu[4].item[0].itemString = _vm->_guiStrings[1]; - // Quit playing - _menu[4].item[1].itemString = _vm->_guiStrings[4]; - - // Game Controls - _menu[5].menuNameString = _vm->_guiStrings[6]; - // Yes - _menu[1].item[0].itemString = _vm->_guiStrings[22 + offset]; - // No - _menu[1].item[1].itemString = _vm->_guiStrings[23 + offset]; - - // Music is - _menu[5].item[0].labelString = _vm->_guiStrings[26 + offsetOptions]; - // Sounds are - _menu[5].item[1].labelString = _vm->_guiStrings[27 + offsetOptions]; - // Walk speed - _menu[5].item[2].labelString = &_vm->_guiStrings[24 + offsetOptions][walkspeedGarbageOffset]; - // Text speed - _menu[5].item[4].labelString = _vm->_guiStrings[25 + offsetOptions]; - // Main Menu - _menu[5].item[5].itemString = &_vm->_guiStrings[19 + offsetMainMenu][menuLabelGarbageOffset]; - - if (_vm->gameFlags().isTalkie) - // Text & Voice - _voiceTextString = _vm->_guiStrings[28 + offset]; - - _textSpeedString = _vm->_guiStrings[25 + offsetOptions]; - _onString = _vm->_guiStrings[20 + offsetOn]; - _offString = _vm->_guiStrings[21 + offset]; - _onCDString = _vm->_guiStrings[21]; -} - -int GUI_v1::buttonMenuCallback(Button *caller) { - PauseTimer pause(*_vm->_timer); - - _displayMenu = true; - - assert(_vm->_guiStrings); - assert(_vm->_configStrings); - - /* - for (int i = 0; i < _vm->_guiStringsSize; i++) - debug("GUI string %i: %s", i, _vm->_guiStrings[i]); - - for (int i = 0; i < _vm->_configStringsSize; i++) - debug("Config string %i: %s", i, _vm->_configStrings[i]); - */ - - setGUILabels(); - if (_vm->_currentCharacter->sceneId == 210 && _vm->_deathHandler == 0xFF) { - _vm->snd_playSoundEffect(0x36); - return 0; - } - // XXX - _screen->setPaletteIndex(0xFE, 60, 60, 0); - for (int i = 0; i < 6; i++) { - _menuButtonData[i].data0Val1 = _menuButtonData[i].data1Val1 = _menuButtonData[i].data2Val1 = 4; - _menuButtonData[i].data0Callback = _redrawShadedButtonFunctor; - _menuButtonData[i].data1Callback = _redrawButtonFunctor; - _menuButtonData[i].data2Callback = _redrawButtonFunctor; - } - - _screen->savePageToDisk("SEENPAGE.TMP", 0); - fadePalette(); - - for (int i = 0; i < 5; i++) - initMenuLayout(_menu[i]); - - _menuRestoreScreen = true; - _keyPressed.reset(); - _vm->_mousePressFlag = false; - - _toplevelMenu = 0; - if (_vm->_menuDirectlyToLoad) { - loadGameMenu(0); - } else { - if (!caller) - _toplevelMenu = 4; - - initMenu(_menu[_toplevelMenu]); - updateAllMenuButtons(); - } - - while (_displayMenu && !_vm->_quitFlag) { - Common::Point mouse = _vm->getMousePos(); - processHighlights(_menu[_toplevelMenu], mouse.x, mouse.y); - processButtonList(_menuButtonList, 0, 0); - getInput(); - } - - if (_menuRestoreScreen) { - restorePalette(); - _screen->loadPageFromDisk("SEENPAGE.TMP", 0); - _vm->_animator->_updateScreen = true; - } else { - _screen->deletePageFromDisk(0); - } - - return 0; -} - -void GUI_v1::getInput() { - Common::Event event; - static uint32 lastScreenUpdate = 0; - uint32 now = _vm->_system->getMillis(); - - _mouseWheel = 0; - while (_vm->_eventMan->pollEvent(event)) { - switch (event.type) { - case Common::EVENT_QUIT: - _vm->quitGame(); - break; - case Common::EVENT_LBUTTONDOWN: - _vm->_mousePressFlag = true; - break; - case Common::EVENT_LBUTTONUP: - _vm->_mousePressFlag = false; - break; - case Common::EVENT_MOUSEMOVE: - _vm->_system->updateScreen(); - lastScreenUpdate = now; - break; - case Common::EVENT_WHEELUP: - _mouseWheel = -1; - break; - case Common::EVENT_WHEELDOWN: - _mouseWheel = 1; - break; - case Common::EVENT_KEYDOWN: - _keyPressed = event.kbd; - break; - default: - break; - } - } - - if (now - lastScreenUpdate > 50) { - _vm->_system->updateScreen(); - lastScreenUpdate = now; - } - - _vm->_system->delayMillis(3); -} - -int GUI_v1::resumeGame(Button *button) { - debugC(9, kDebugLevelGUI, "GUI_v1::resumeGame()"); - updateMenuButton(button); - _displayMenu = false; - - return 0; -} - -void GUI_v1::setupSavegames(Menu &menu, int num) { - Common::InSaveFile *in; - static char savenames[5][31]; - uint8 startSlot; - assert(num <= 5); - - if (_savegameOffset == 0) { - menu.item[0].itemString = _specialSavegameString; - menu.item[0].enabled = 1; - menu.item[0].saveSlot = 0; - startSlot = 1; - } else { - startSlot = 0; - } - - for (int i = startSlot; i < num; ++i) - menu.item[i].enabled = 0; - - KyraEngine::SaveHeader header; - for (int i = startSlot; i < num && uint(_savegameOffset + i) < _saveSlots.size(); i++) { - if ((in = _vm->openSaveForReading(_vm->getSavegameFilename(_saveSlots[i + _savegameOffset]), header))) { - strncpy(savenames[i], header.description.c_str(), 31); - menu.item[i].itemString = savenames[i]; - menu.item[i].enabled = 1; - menu.item[i].saveSlot = _saveSlots[i + _savegameOffset]; - delete in; - } - } -} - -int GUI_v1::saveGameMenu(Button *button) { - debugC(9, kDebugLevelGUI, "GUI_v1::saveGameMenu()"); - updateSaveList(); - - updateMenuButton(button); - _menu[2].item[5].enabled = true; - - _screen->loadPageFromDisk("SEENPAGE.TMP", 0); - _screen->savePageToDisk("SEENPAGE.TMP", 0); - - _menu[2].menuNameString = _vm->_guiStrings[8]; // Select a position to save to: - _specialSavegameString = _vm->_guiStrings[9]; // [ EMPTY SLOT ] - for (int i = 0; i < 5; i++) - _menu[2].item[i].callback = BUTTON_FUNCTOR(GUI_v1, this, &GUI_v1::saveGame); - - _savegameOffset = 0; - setupSavegames(_menu[2], 5); - - initMenu(_menu[2]); - updateAllMenuButtons(); - - _displaySubMenu = true; - _cancelSubMenu = false; - - while (_displaySubMenu && !_vm->_quitFlag) { - getInput(); - Common::Point mouse = _vm->getMousePos(); - processHighlights(_menu[2], mouse.x, mouse.y); - processButtonList(_menuButtonList, 0, _mouseWheel); - } - - _screen->loadPageFromDisk("SEENPAGE.TMP", 0); - _screen->savePageToDisk("SEENPAGE.TMP", 0); - - if (_cancelSubMenu) { - initMenu(_menu[0]); - updateAllMenuButtons(); - } else { - _displayMenu = false; - } - return 0; -} - -int GUI_v1::loadGameMenu(Button *button) { - debugC(9, kDebugLevelGUI, "GUI_v1::loadGameMenu()"); - updateSaveList(); - - if (_vm->_menuDirectlyToLoad) { - _menu[2].item[5].enabled = false; - } else { - updateMenuButton(button); - _menu[2].item[5].enabled = true; - } - - _screen->loadPageFromDisk("SEENPAGE.TMP", 0); - _screen->savePageToDisk("SEENPAGE.TMP", 0); - - _specialSavegameString = _vm->_newGameString[0]; //[ START A NEW GAME ] - _menu[2].menuNameString = _vm->_guiStrings[7]; // Which game would you like to reload? - for (int i = 0; i < 5; i++) - _menu[2].item[i].callback = BUTTON_FUNCTOR(GUI_v1, this, &GUI_v1::loadGame); - - _savegameOffset = 0; - setupSavegames(_menu[2], 5); - - initMenu(_menu[2]); - updateAllMenuButtons(); - - _displaySubMenu = true; - _cancelSubMenu = false; - - _vm->_gameToLoad = -1; - - while (_displaySubMenu && !_vm->_quitFlag) { - getInput(); - Common::Point mouse = _vm->getMousePos(); - processHighlights(_menu[2], mouse.x, mouse.y); - processButtonList(_menuButtonList, 0, _mouseWheel); - } - - _screen->loadPageFromDisk("SEENPAGE.TMP", 0); - _screen->savePageToDisk("SEENPAGE.TMP", 0); - - if (_cancelSubMenu) { - initMenu(_menu[_toplevelMenu]); - updateAllMenuButtons(); - } else { - restorePalette(); - if (_vm->_gameToLoad != -1) - _vm->loadGame(_vm->getSavegameFilename(_vm->_gameToLoad)); - _displayMenu = false; - _menuRestoreScreen = false; - } - return 0; -} - -void GUI_v1::redrawTextfield() { - _screen->fillRect(38, 91, 287, 102, 250); - _text->printText(_savegameName, 38, 92, 253, 0, 0); - - _screen->_charWidth = -2; - int width = _screen->getTextWidth(_savegameName); - _screen->fillRect(39 + width, 93, 45 + width, 100, 254); - _screen->_charWidth = 0; - - _screen->updateScreen(); -} - -void GUI_v1::updateSavegameString() { - int length; - - if (_keyPressed.keycode) { - length = strlen(_savegameName); - - if (_keyPressed.ascii > 31 && _keyPressed.ascii < 127) { - if (length < 31) { - _savegameName[length] = _keyPressed.ascii; - _savegameName[length+1] = 0; - redrawTextfield(); - } - } else if (_keyPressed.keycode == Common::KEYCODE_BACKSPACE || - _keyPressed.keycode == Common::KEYCODE_DELETE) { - if (length > 0) { - _savegameName[length-1] = 0; - redrawTextfield(); - } - } else if (_keyPressed.keycode == Common::KEYCODE_RETURN || - _keyPressed.keycode == Common::KEYCODE_KP_ENTER) { - _displaySubMenu = false; - } - } - - _keyPressed.reset(); -} - -int GUI_v1::saveGame(Button *button) { - debugC(9, kDebugLevelGUI, "GUI_v1::saveGame()"); - updateMenuButton(button); - _vm->_gameToLoad = _menu[2].item[button->index-0xC].saveSlot; - - _screen->loadPageFromDisk("SEENPAGE.TMP", 0); - _screen->savePageToDisk("SEENPAGE.TMP", 0); - - initMenu(_menu[3]); - updateAllMenuButtons(); - - _displaySubMenu = true; - _cancelSubMenu = false; - - if (_savegameOffset == 0 && _vm->_gameToLoad == 0) { - _savegameName[0] = 0; - } else { - for (int i = 0; i < 5; i++) { - if (_menu[2].item[i].saveSlot == _vm->_gameToLoad) { - strncpy(_savegameName, _menu[2].item[i].itemString, 31); - break; - } - } - } - redrawTextfield(); - - while (_displaySubMenu && !_vm->_quitFlag) { - getInput(); - updateSavegameString(); - Common::Point mouse = _vm->getMousePos(); - processHighlights(_menu[3], mouse.x, mouse.y); - processButtonList(_menuButtonList, 0, 0); - } - - if (_cancelSubMenu) { - _displaySubMenu = true; - _cancelSubMenu = false; - initMenu(_menu[2]); - updateAllMenuButtons(); - } else { - if (_savegameOffset == 0 && _vm->_gameToLoad == 0) - _vm->_gameToLoad = getNextSavegameSlot(); - if (_vm->_gameToLoad > 0) - _vm->saveGame(_vm->getSavegameFilename(_vm->_gameToLoad), _savegameName); - } - - return 0; -} - -int GUI_v1::savegameConfirm(Button *button) { - debugC(9, kDebugLevelGUI, "GUI_v1::savegameConfirm()"); - updateMenuButton(button); - _displaySubMenu = false; - - return 0; -} - -int GUI_v1::loadGame(Button *button) { - debugC(9, kDebugLevelGUI, "GUI_v1::loadGame()"); - updateMenuButton(button); - _displaySubMenu = false; - _vm->_gameToLoad = _menu[2].item[button->index-0xC].saveSlot; - - return 0; -} - -int GUI_v1::cancelSubMenu(Button *button) { - debugC(9, kDebugLevelGUI, "GUI_v1::cancelSubMenu()"); - updateMenuButton(button); - _displaySubMenu = false; - _cancelSubMenu = true; - - return 0; -} - -int GUI_v1::quitPlaying(Button *button) { - debugC(9, kDebugLevelGUI, "GUI_v1::quitPlaying()"); - updateMenuButton(button); - - if (quitConfirm(_vm->_guiStrings[14])) { // Are you sure you want to quit playing? - _vm->quitGame(); - } else { - initMenu(_menu[_toplevelMenu]); - updateAllMenuButtons(); - } - - return 0; -} - -bool GUI_v1::quitConfirm(const char *str) { - debugC(9, kDebugLevelGUI, "GUI_v1::quitConfirm()"); - - _screen->loadPageFromDisk("SEENPAGE.TMP", 0); - _screen->savePageToDisk("SEENPAGE.TMP", 0); - - _menu[1].menuNameString = str; - initMenuLayout(_menu[1]); - initMenu(_menu[1]); - - _displaySubMenu = true; - _cancelSubMenu = true; - - while (_displaySubMenu && !_vm->_quitFlag) { - getInput(); - Common::Point mouse = _vm->getMousePos(); - processHighlights(_menu[1], mouse.x, mouse.y); - processButtonList(_menuButtonList, 0, 0); - } - - _screen->loadPageFromDisk("SEENPAGE.TMP", 0); - _screen->savePageToDisk("SEENPAGE.TMP", 0); - - return !_cancelSubMenu; -} - -int GUI_v1::quitConfirmYes(Button *button) { - debugC(9, kDebugLevelGUI, "GUI_v1::quitConfirmYes()"); - updateMenuButton(button); - _displaySubMenu = false; - _cancelSubMenu = false; - - return 0; -} - -int GUI_v1::quitConfirmNo(Button *button) { - debugC(9, kDebugLevelGUI, "GUI_v1::quitConfirmNo()"); - updateMenuButton(button); - _displaySubMenu = false; - _cancelSubMenu = true; - - return 0; -} - -int GUI_v1::gameControlsMenu(Button *button) { - debugC(9, kDebugLevelGUI, "GUI_v1::gameControlsMenu()"); - - _vm->readSettings(); - - _screen->loadPageFromDisk("SEENPAGE.TMP", 0); - _screen->savePageToDisk("SEENPAGE.TMP", 0); - - if (_vm->gameFlags().isTalkie) { - //_menu[5].width = 230; - - for (int i = 0; i < 5; i++) { - //_menu[5].item[i].labelX = 24; - //_menu[5].item[i].x = 115; - //_menu[5].item[i].width = 94; - } - - _menu[5].item[3].labelString = _voiceTextString; //"Voice / Text " - _menu[5].item[3].callback = BUTTON_FUNCTOR(GUI_v1, this, &GUI_v1::controlsChangeVoice); - - } else { - //_menu[5].height = 136; - //_menu[5].item[5].y = 110; - _menu[5].item[4].enabled = 0; - _menu[5].item[3].labelString = _textSpeedString; // "Text speed " - _menu[5].item[3].callback = BUTTON_FUNCTOR(GUI_v1, this, &GUI_v1::controlsChangeText); - } - - setupControls(_menu[5]); - - updateAllMenuButtons(); - - _displaySubMenu = true; - _cancelSubMenu = false; - - while (_displaySubMenu && !_vm->_quitFlag) { - getInput(); - Common::Point mouse = _vm->getMousePos(); - processHighlights(_menu[5], mouse.x, mouse.y); - processButtonList(_menuButtonList, 0, 0); - } - - _screen->loadPageFromDisk("SEENPAGE.TMP", 0); - _screen->savePageToDisk("SEENPAGE.TMP", 0); - - if (_cancelSubMenu) { - initMenu(_menu[_toplevelMenu]); - updateAllMenuButtons(); - } - return 0; -} - -void GUI_v1::setupControls(Menu &menu) { - debugC(9, kDebugLevelGUI, "GUI_v1::setupControls()"); - - switch (_vm->_configMusic) { - case 0: - menu.item[0].itemString = _offString; //"Off" - break; - case 1: - menu.item[0].itemString = _onString; //"On" - break; - case 2: - menu.item[0].itemString = _onCDString; //"On + CD" - break; - } - - if (_vm->_configSounds) - menu.item[1].itemString = _onString; //"On" - else - menu.item[1].itemString = _offString; //"Off" - - - switch (_vm->_configWalkspeed) { - case 0: - menu.item[2].itemString = _vm->_configStrings[0]; //"Slowest" - break; - case 1: - menu.item[2].itemString = _vm->_configStrings[1]; //"Slow" - break; - case 2: - menu.item[2].itemString = _vm->_configStrings[2]; //"Normal" - break; - case 3: - menu.item[2].itemString = _vm->_configStrings[3]; //"Fast" - break; - case 4: - menu.item[2].itemString = _vm->_configStrings[4]; //"Fastest" - break; - default: - menu.item[2].itemString = "ERROR"; - break; - } - - int textControl = 3; - int clickableOffset = 8; - if (_vm->gameFlags().isTalkie) { - textControl = 4; - clickableOffset = 11; - - if (_vm->_configVoice == 0) { - menu.item[4].enabled = 1; - menu.item[4].labelString = _textSpeedString; - } else { - menu.item[4].enabled = 0; - menu.item[4].labelString = 0; - } - - switch (_vm->_configVoice) { - case 0: - menu.item[3].itemString = _vm->_configStrings[5]; //"Text only" - break; - case 1: - menu.item[3].itemString = _vm->_configStrings[6]; //"Voice only" - break; - case 2: - menu.item[3].itemString = _vm->_configStrings[7]; //"Voice & Text" - break; - default: - menu.item[3].itemString = "ERROR"; - break; - } - } else { - menu.item[4].enabled = 0; - menu.item[4].labelString = 0; - } - - switch (_vm->_configTextspeed) { - case 0: - menu.item[textControl].itemString = _vm->_configStrings[1]; //"Slow" - break; - case 1: - menu.item[textControl].itemString = _vm->_configStrings[2]; //"Normal" - break; - case 2: - menu.item[textControl].itemString = _vm->_configStrings[3]; //"Fast" - break; - case 3: - menu.item[textControl].itemString = _vm->_configStrings[clickableOffset]; //"Clickable" - break; - default: - menu.item[textControl].itemString = "ERROR"; - break; - } - - initMenuLayout(menu); - initMenu(menu); -} - -int GUI_v1::controlsChangeMusic(Button *button) { - debugC(9, kDebugLevelGUI, "GUI_v1::controlsChangeMusic()"); - updateMenuButton(button); - - _vm->_configMusic = ++_vm->_configMusic % ((_vm->gameFlags().platform == Common::kPlatformFMTowns || _vm->gameFlags().platform == Common::kPlatformPC98) ? 3 : 2); - setupControls(_menu[5]); - return 0; -} - -int GUI_v1::controlsChangeSounds(Button *button) { - debugC(9, kDebugLevelGUI, "GUI_v1::controlsChangeSounds()"); - updateMenuButton(button); - - _vm->_configSounds = !_vm->_configSounds; - setupControls(_menu[5]); - return 0; -} - -int GUI_v1::controlsChangeWalk(Button *button) { - debugC(9, kDebugLevelGUI, "GUI_v1::controlsChangeWalk()"); - updateMenuButton(button); - - _vm->_configWalkspeed = ++_vm->_configWalkspeed % 5; - _vm->setWalkspeed(_vm->_configWalkspeed); - setupControls(_menu[5]); - return 0; -} - -int GUI_v1::controlsChangeText(Button *button) { - debugC(9, kDebugLevelGUI, "GUI_v1::controlsChangeText()"); - updateMenuButton(button); - - _vm->_configTextspeed = ++_vm->_configTextspeed % 4; - setupControls(_menu[5]); - return 0; -} - -int GUI_v1::controlsChangeVoice(Button *button) { - debugC(9, kDebugLevelGUI, "GUI_v1::controlsChangeVoice()"); - updateMenuButton(button); - - _vm->_configVoice = ++_vm->_configVoice % 3; - setupControls(_menu[5]); - return 0; -} - -int GUI_v1::controlsApply(Button *button) { - debugC(9, kDebugLevelGUI, "GUI_v1::controlsApply()"); - _vm->writeSettings(); - return cancelSubMenu(button); -} - -int GUI_v1::scrollUp(Button *button) { - debugC(9, kDebugLevelGUI, "GUI_v1::scrollUp()"); - updateMenuButton(button); - - if (_savegameOffset > 0) { - _savegameOffset--; - setupSavegames(_menu[2], 5); - initMenu(_menu[2]); - } - return 0; -} - -int GUI_v1::scrollDown(Button *button) { - debugC(9, kDebugLevelGUI, "GUI_v1::scrollDown()"); - updateMenuButton(button); - - _savegameOffset++; - if (uint(_savegameOffset + 5) >= _saveSlots.size()) - _savegameOffset = MAX(_saveSlots.size() - 5, 0); - setupSavegames(_menu[2], 5); - initMenu(_menu[2]); - - return 0; -} - -void GUI_v1::fadePalette() { - if (_vm->gameFlags().platform == Common::kPlatformAmiga) - return; - - static int16 menuPalIndexes[] = {248, 249, 250, 251, 252, 253, 254, -1}; - int index = 0; - - memcpy(_screen->getPalette(2), _screen->_currentPalette, 768); - - for (int i = 0; i < 768; i++) - _screen->_currentPalette[i] >>= 1; - - while (menuPalIndexes[index] != -1) { - memcpy(&_screen->_currentPalette[menuPalIndexes[index]*3], &_screen->getPalette(2)[menuPalIndexes[index]*3], 3); - index++; - } - - _screen->fadePalette(_screen->_currentPalette, 2); -} - -void GUI_v1::restorePalette() { - if (_vm->gameFlags().platform == Common::kPlatformAmiga) - return; - - memcpy(_screen->_currentPalette, _screen->getPalette(2), 768); - _screen->fadePalette(_screen->_currentPalette, 2); -} - -#pragma mark - - -void KyraEngine_v1::drawAmulet() { - debugC(9, kDebugLevelMain, "KyraEngine_v1::drawAmulet()"); - static const int16 amuletTable1[] = {0x167, 0x162, 0x15D, 0x158, 0x153, 0x150, 0x155, 0x15A, 0x15F, 0x164, 0x145, -1}; - static const int16 amuletTable3[] = {0x167, 0x162, 0x15D, 0x158, 0x153, 0x14F, 0x154, 0x159, 0x15E, 0x163, 0x144, -1}; - static const int16 amuletTable2[] = {0x167, 0x162, 0x15D, 0x158, 0x153, 0x152, 0x157, 0x15C, 0x161, 0x166, 0x147, -1}; - static const int16 amuletTable4[] = {0x167, 0x162, 0x15D, 0x158, 0x153, 0x151, 0x156, 0x15B, 0x160, 0x165, 0x146, -1}; - - resetGameFlag(0xF1); - _screen->hideMouse(); - - int i = 0; - while (amuletTable1[i] != -1) { - if (queryGameFlag(87)) - _screen->drawShape(0, _shapes[amuletTable1[i]], _amuletX[0], _amuletY[0], 0, 0); - - if (queryGameFlag(89)) - _screen->drawShape(0, _shapes[amuletTable2[i]], _amuletX[1], _amuletY[1], 0, 0); - - if (queryGameFlag(86)) - _screen->drawShape(0, _shapes[amuletTable3[i]], _amuletX[2], _amuletY[2], 0, 0); - - if (queryGameFlag(88)) - _screen->drawShape(0, _shapes[amuletTable4[i]], _amuletX[3], _amuletY[3], 0, 0); - - _screen->updateScreen(); - delayWithTicks(3); - i++; - } - _screen->showMouse(); -} - -} // end of namespace Kyra - diff --git a/engines/kyra/gui_v1.h b/engines/kyra/gui_v1.h deleted file mode 100644 index 65ccad6eeb..0000000000 --- a/engines/kyra/gui_v1.h +++ /dev/null @@ -1,177 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#ifndef KYRA_GUI_V1_H -#define KYRA_GUI_V1_H - -#include "kyra/gui.h" - -namespace Kyra { - -#define GUI_V1_BUTTON(button, a, b, c, d, e, f, g, h, i, j, k) \ - button.nextButton = 0; \ - button.index = a; \ - button.unk6 = button.unk8 = 0; \ - button.data0Val1 = b; \ - button.data1Val1 = c; \ - button.data2Val1 = d; \ - button.data0ShapePtr = button.data1ShapePtr = button.data2ShapePtr = 0; \ - button.flags = e; \ - button.dimTableIndex = f; \ - button.x = g; \ - button.y = h; \ - button.width = i; \ - button.height = j; \ - button.flags2 = k; \ - button.mouseWheel = 0 - -#define GUI_V1_MENU(menu, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q) \ - menu.x = a; \ - menu.y = b; \ - menu.width = c; \ - menu.height = d; \ - menu.bkgdColor = e; \ - menu.color1 = f; \ - menu.color2 = g; \ - menu.menuNameString = h; \ - menu.textColor = i; \ - menu.titleX = j; \ - menu.titleY = k; \ - menu.highlightedItem = l; \ - menu.numberOfItems = m; \ - menu.scrollUpButtonX = n; \ - menu.scrollUpButtonY = o; \ - menu.scrollDownButtonX = p; \ - menu.scrollDownButtonY = q - -#define GUI_V1_MENU_ITEM(item, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v) \ - item.enabled = a; \ - item.itemString = d; \ - item.x = e; \ - item.y = g; \ - item.width = h; \ - item.height = i; \ - item.textColor = j; \ - item.highlightColor = k; \ - item.titleX = l; \ - item.bkgdColor = n; \ - item.color1 = o; \ - item.color2 = p; \ - item.saveSlot = q; \ - item.labelString = r; \ - item.labelX = s; \ - item.labelY = t; \ - item.unk1F = v - -class KyraEngine_v1; - -class GUI_v1 : public GUI { - friend class KyraEngine_v1; -public: - GUI_v1(KyraEngine_v1 *vm, Screen_v1 *screen); - ~GUI_v1(); - - void processButton(Button *button); - int processButtonList(Button *buttonList, uint16 inputFlags, int8 mouseWheel); - - int buttonMenuCallback(Button *caller); -private: - void initStaticResource(); - - Button _menuButtonData[6]; - Button _scrollUpButton; - Button _scrollDownButton; - Button *getButtonListData() { return _menuButtonData; } - Button *getScrollUpButton() { return &_scrollUpButton; } - Button *getScrollDownButton() { return &_scrollDownButton; } - - Menu *_menu; - - void setGUILabels(); - - void setupSavegames(Menu &menu, int num); - - int resumeGame(Button *button); - int loadGameMenu(Button *button); - int saveGameMenu(Button *button); - int gameControlsMenu(Button *button); - int quitPlaying(Button *button); - int quitConfirmYes(Button *button); - int quitConfirmNo(Button *button); - int loadGame(Button *button); - int saveGame(Button *button); - int savegameConfirm(Button *button); - int cancelSubMenu(Button *button); - int scrollUp(Button *button); - int scrollDown(Button *button); - int controlsChangeMusic(Button *button); - int controlsChangeSounds(Button *button); - int controlsChangeWalk(Button *button); - int controlsChangeText(Button *button); - int controlsChangeVoice(Button *button); - int controlsApply(Button *button); - - bool quitConfirm(const char *str); - void getInput(); - void updateSavegameString(); - void redrawTextfield(); - void fadePalette(); - void restorePalette(); - void setupControls(Menu &menu); - - uint8 defaultColor1() const { return 12; } - uint8 defaultColor2() const { return 248; } - - const char *getMenuTitle(const Menu &menu) { return menu.menuNameString; } - const char *getMenuItemTitle(const MenuItem &menuItem) { return menuItem.itemString; } - const char *getMenuItemLabel(const MenuItem &menuItem) { return menuItem.labelString; } - - KyraEngine_v1 *_vm; - Screen_v1 *_screen; - - bool _menuRestoreScreen; - uint8 _toplevelMenu; - int _savegameOffset; - char _savegameName[31]; - const char *_specialSavegameString; - Common::KeyState _keyPressed; - int8 _mouseWheel; - - Button::Callback _scrollUpFunctor; - Button::Callback _scrollDownFunctor; - Button::Callback getScrollUpButtonHandler() const { return _scrollUpFunctor; } - Button::Callback getScrollDownButtonHandler() const { return _scrollDownFunctor; } - - const char *_voiceTextString; - const char *_textSpeedString; - const char *_onString; - const char *_offString; - const char *_onCDString; -}; - -} // end of namespace Kyra - -#endif - diff --git a/engines/kyra/items_lok.cpp b/engines/kyra/items_lok.cpp new file mode 100644 index 0000000000..c468a6e197 --- /dev/null +++ b/engines/kyra/items_lok.cpp @@ -0,0 +1,944 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "kyra/kyra_lok.h" +#include "kyra/seqplayer.h" +#include "kyra/screen.h" +#include "kyra/resource.h" +#include "kyra/sound.h" +#include "kyra/sprites.h" +#include "kyra/wsamovie.h" +#include "kyra/animator_lok.h" +#include "kyra/text.h" + +#include "common/system.h" +#include "common/savefile.h" + +namespace Kyra { + +int KyraEngine_LoK::findDuplicateItemShape(int shape) { + static uint8 dupTable[] = { + 0x48, 0x46, 0x49, 0x47, 0x4a, 0x46, 0x4b, 0x47, + 0x4c, 0x46, 0x4d, 0x47, 0x5b, 0x5a, 0x5c, 0x5a, + 0x5d, 0x5a, 0x5e, 0x5a, 0xFF, 0xFF + }; + + int i = 0; + + while (dupTable[i] != 0xFF) { + if (dupTable[i] == shape) + return dupTable[i+1]; + i += 2; + } + return -1; +} + +void KyraEngine_LoK::addToNoDropRects(int x, int y, int w, int h) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::addToNoDropRects(%d, %d, %d, %d)", x, y, w, h); + for (int rect = 0; rect < 11; ++rect) { + if (_noDropRects[rect].x == -1) { + _noDropRects[rect].x = x; + _noDropRects[rect].y = y; + _noDropRects[rect].x2 = x + w - 1; + _noDropRects[rect].y2 = y + h - 1; + break; + } + } +} + +void KyraEngine_LoK::clearNoDropRects() { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::clearNoDropRects()"); + memset(_noDropRects, -1, sizeof(_noDropRects)); +} + +byte KyraEngine_LoK::findFreeItemInScene(int scene) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::findFreeItemInScene(%d)", scene); + assert(scene < _roomTableSize); + Room *room = &_roomTable[scene]; + for (int i = 0; i < 12; ++i) { + if (room->itemsTable[i] == 0xFF) + return i; + } + return 0xFF; +} + +byte KyraEngine_LoK::findItemAtPos(int x, int y) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::findItemAtPos(%d, %d)", x, y); + assert(_currentCharacter->sceneId < _roomTableSize); + const uint8 *itemsTable = _roomTable[_currentCharacter->sceneId].itemsTable; + const uint16 *xposOffset = _roomTable[_currentCharacter->sceneId].itemsXPos; + const uint8 *yposOffset = _roomTable[_currentCharacter->sceneId].itemsYPos; + + int highestYPos = -1; + byte returnValue = 0xFF; + + for (int i = 0; i < 12; ++i) { + if (*itemsTable != 0xFF) { + int xpos = *xposOffset - 11; + int xpos2 = *xposOffset + 10; + if (x > xpos && x < xpos2) { + assert(*itemsTable < ARRAYSIZE(_itemTable)); + int itemHeight = _itemTable[*itemsTable].height; + int ypos = *yposOffset + 3; + int ypos2 = ypos - itemHeight - 3; + + if (y > ypos2 && ypos > y) { + if (highestYPos <= ypos) { + returnValue = i; + highestYPos = ypos; + } + } + } + } + ++xposOffset; + ++yposOffset; + ++itemsTable; + } + + return returnValue; +} + +void KyraEngine_LoK::placeItemInGenericMapScene(int item, int index) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::placeItemInGenericMapScene(%d, %d)", item, index); + static const uint16 itemMapSceneMinTable[] = { + 0x0000, 0x0011, 0x006D, 0x0025, 0x00C7, 0x0000 + }; + static const uint16 itemMapSceneMaxTable[] = { + 0x0010, 0x0024, 0x00C6, 0x006C, 0x00F5, 0x0000 + }; + + int minValue = itemMapSceneMinTable[index]; + int maxValue = itemMapSceneMaxTable[index]; + + while (true) { + int room = _rnd.getRandomNumberRng(minValue, maxValue); + assert(room < _roomTableSize); + int nameIndex = _roomTable[room].nameIndex; + bool placeItem = false; + + switch (nameIndex) { + case 0: case 1: case 2: case 3: + case 4: case 5: case 6: case 11: + case 12: case 16: case 17: case 20: + case 22: case 23: case 25: case 26: + case 27: case 31: case 33: case 34: + case 36: case 37: case 58: case 59: + case 60: case 61: case 83: case 84: + case 85: case 104: case 105: case 106: + placeItem = true; + break; + + case 51: + if (room != 46) + placeItem = true; + break; + + default: + break; + } + + if (placeItem) { + Room *roomPtr = &_roomTable[room]; + if (roomPtr->northExit == 0xFFFF && roomPtr->eastExit == 0xFFFF && roomPtr->southExit == 0xFFFF && roomPtr->westExit == 0xFFFF) + placeItem = false; + else if (_currentCharacter->sceneId == room) + placeItem = false; + } + + if (placeItem) { + if (!processItemDrop(room, item, -1, -1, 2, 0)) + continue; + break; + } + } +} + +void KyraEngine_LoK::createMouseItem(int item) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::createMouseItem(%d)", item); + _screen->hideMouse(); + setMouseItem(item); + _itemInHand = item; + _screen->showMouse(); +} + +void KyraEngine_LoK::destroyMouseItem() { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::destroyMouseItem()"); + _screen->hideMouse(); + _screen->setMouseCursor(1, 1, _shapes[0]); + _itemInHand = -1; + _screen->showMouse(); +} + +void KyraEngine_LoK::setMouseItem(int item) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::setMouseItem(%d)", item); + if (item == -1) + _screen->setMouseCursor(1, 1, _shapes[6]); + else + _screen->setMouseCursor(8, 15, _shapes[216+item]); +} + +void KyraEngine_LoK::wipeDownMouseItem(int xpos, int ypos) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::wipeDownMouseItem(%d, %d)", xpos, ypos); + if (_itemInHand == -1) + return; + xpos -= 8; + ypos -= 15; + _screen->hideMouse(); + backUpItemRect1(xpos, ypos); + int y = ypos; + int height = 16; + + while (height >= 0) { + restoreItemRect1(xpos, ypos); + _screen->setNewShapeHeight(_shapes[216+_itemInHand], height); + uint32 nextTime = _system->getMillis() + 1 * _tickLength; + _screen->drawShape(0, _shapes[216+_itemInHand], xpos, y, 0, 0); + _screen->updateScreen(); + y += 2; + height -= 2; + delayUntil(nextTime); + } + restoreItemRect1(xpos, ypos); + _screen->resetShapeHeight(_shapes[216+_itemInHand]); + destroyMouseItem(); + _screen->showMouse(); +} + +void KyraEngine_LoK::setupSceneItems() { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::setupSceneItems()"); + uint16 sceneId = _currentCharacter->sceneId; + assert(sceneId < _roomTableSize); + Room *currentRoom = &_roomTable[sceneId]; + for (int i = 0; i < 12; ++i) { + uint8 item = currentRoom->itemsTable[i]; + if (item == 0xFF || !currentRoom->needInit[i]) + continue; + + int xpos = 0; + int ypos = 0; + + if (currentRoom->itemsXPos[i] == 0xFFFF) { + xpos = currentRoom->itemsXPos[i] = _rnd.getRandomNumberRng(24, 296); + ypos = currentRoom->itemsYPos[i] = _rnd.getRandomNumberRng(_northExitHeight & 0xFF, 130); + } else { + xpos = currentRoom->itemsXPos[i]; + ypos = currentRoom->itemsYPos[i]; + } + + _lastProcessedItem = i; + + int stop = 0; + while (!stop) { + stop = processItemDrop(sceneId, item, xpos, ypos, 3, 0); + if (!stop) { + xpos = currentRoom->itemsXPos[i] = _rnd.getRandomNumberRng(24, 296); + ypos = currentRoom->itemsYPos[i] = _rnd.getRandomNumberRng(_northExitHeight & 0xFF, 130); + if (countItemsInScene(sceneId) >= 12) + break; + } else { + currentRoom->needInit[i] = 0; + } + } + } +} + +int KyraEngine_LoK::countItemsInScene(uint16 sceneId) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::countItemsInScene(%d)", sceneId); + assert(sceneId < _roomTableSize); + Room *currentRoom = &_roomTable[sceneId]; + + int items = 0; + + for (int i = 0; i < 12; ++i) { + if (currentRoom->itemsTable[i] != 0xFF) + ++items; + } + + return items; +} + +int KyraEngine_LoK::processItemDrop(uint16 sceneId, uint8 item, int x, int y, int unk1, int unk2) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::processItemDrop(%d, %d, %d, %d, %d, %d)", sceneId, item, x, y, unk1, unk2); + int freeItem = -1; + uint8 itemIndex = findItemAtPos(x, y); + if (unk1) + itemIndex = 0xFF; + + if (itemIndex != 0xFF) { + exchangeItemWithMouseItem(sceneId, itemIndex); + return 0; + } + + assert(sceneId < _roomTableSize); + Room *currentRoom = &_roomTable[sceneId]; + + if (unk1 != 3) { + for (int i = 0; i < 12; ++i) { + if (currentRoom->itemsTable[i] == 0xFF) { + freeItem = i; + break; + } + } + } else { + freeItem = _lastProcessedItem; + } + + if (freeItem == -1) + return 0; + + if (sceneId != _currentCharacter->sceneId) { + addItemToRoom(sceneId, item, freeItem, x, y); + return 1; + } + + int itemHeight = _itemTable[item].height; + _lastProcessedItemHeight = itemHeight; + + if (x == -1 && x == -1) { + x = _rnd.getRandomNumberRng(16, 304); + y = _rnd.getRandomNumberRng(_northExitHeight & 0xFF, 135); + } + + int xpos = x; + int ypos = y; + int destY = -1; + int destX = -1; + int running = 1; + + while (running) { + if ((_northExitHeight & 0xFF) <= ypos) { + bool running2 = true; + + if (_screen->getDrawLayer(xpos, ypos) > 1) { + if (((_northExitHeight >> 8) & 0xFF) != ypos) + running2 = false; + } + + if (_screen->getDrawLayer2(xpos, ypos, itemHeight) > 1) { + if (((_northExitHeight >> 8) & 0xFF) != ypos) + running2 = false; + } + + if (!isDropable(xpos, ypos)) { + if (((_northExitHeight >> 8) & 0xFF) != ypos) + running2 = false; + } + + int xpos2 = xpos; + int xpos3 = xpos; + + while (running2) { + if (isDropable(xpos2, ypos)) { + if (_screen->getDrawLayer2(xpos2, ypos, itemHeight) < 7) { + if (findItemAtPos(xpos2, ypos) == 0xFF) { + destX = xpos2; + destY = ypos; + running = 0; + running2 = false; + } + } + } + + if (isDropable(xpos3, ypos)) { + if (_screen->getDrawLayer2(xpos3, ypos, itemHeight) < 7) { + if (findItemAtPos(xpos3, ypos) == 0xFF) { + destX = xpos3; + destY = ypos; + running = 0; + running2 = false; + } + } + } + + if (!running2) + continue; + + xpos2 -= 2; + if (xpos2 < 16) + xpos2 = 16; + + xpos3 += 2; + if (xpos3 > 304) + xpos3 = 304; + + if (xpos2 > 16) + continue; + if (xpos3 < 304) + continue; + running2 = false; + } + } + + if (((_northExitHeight >> 8) & 0xFF) == ypos) { + running = 0; + destY -= _rnd.getRandomNumberRng(0, 3); + + if ((_northExitHeight & 0xFF) < destY) + continue; + + destY = (_northExitHeight & 0xFF) + 1; + continue; + } + ypos += 2; + if (((_northExitHeight >> 8) & 0xFF) >= ypos) + continue; + ypos = (_northExitHeight >> 8) & 0xFF; + } + + if (destX == -1 || destY == -1) + return 0; + + if (unk1 == 3) { + currentRoom->itemsXPos[freeItem] = destX; + currentRoom->itemsYPos[freeItem] = destY; + return 1; + } + + if (unk1 == 2) + itemSpecialFX(x, y, item); + + if (unk1 == 0) + destroyMouseItem(); + + itemDropDown(x, y, destX, destY, freeItem, item); + + if (unk1 == 0 && unk2 != 0) { + assert(_itemList && _droppedList); + updateSentenceCommand(_itemList[item], _droppedList[0], 179); + } + + return 1; +} + +void KyraEngine_LoK::exchangeItemWithMouseItem(uint16 sceneId, int itemIndex) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::exchangeItemWithMouseItem(%d, %d)", sceneId, itemIndex); + _screen->hideMouse(); + _animator->animRemoveGameItem(itemIndex); + assert(sceneId < _roomTableSize); + Room *currentRoom = &_roomTable[sceneId]; + + int item = currentRoom->itemsTable[itemIndex]; + currentRoom->itemsTable[itemIndex] = _itemInHand; + _itemInHand = item; + _animator->animAddGameItem(itemIndex, sceneId); + snd_playSoundEffect(53); + + setMouseItem(_itemInHand); + assert(_itemList && _takenList); + updateSentenceCommand(_itemList[_itemInHand], _takenList[1], 179); + _screen->showMouse(); + clickEventHandler2(); +} + +void KyraEngine_LoK::addItemToRoom(uint16 sceneId, uint8 item, int itemIndex, int x, int y) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::addItemToRoom(%d, %d, %d, %d, %d)", sceneId, item, itemIndex, x, y); + assert(sceneId < _roomTableSize); + Room *currentRoom = &_roomTable[sceneId]; + currentRoom->itemsTable[itemIndex] = item; + currentRoom->itemsXPos[itemIndex] = x; + currentRoom->itemsYPos[itemIndex] = y; + currentRoom->needInit[itemIndex] = 1; +} + +int KyraEngine_LoK::checkNoDropRects(int x, int y) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::checkNoDropRects(%d, %d)", x, y); + if (_lastProcessedItemHeight < 1 || _lastProcessedItemHeight > 16) + _lastProcessedItemHeight = 16; + if (_noDropRects[0].x == -1) + return 0; + + for (int i = 0; i < 11; ++i) { + if (_noDropRects[i].x == -1) + break; + + int xpos = _noDropRects[i].x; + int ypos = _noDropRects[i].y; + int xpos2 = _noDropRects[i].x2; + int ypos2 = _noDropRects[i].y2; + + if (xpos > x + 16) + continue; + if (xpos2 < x) + continue; + if (y < ypos) + continue; + if (ypos2 < y - _lastProcessedItemHeight) + continue; + return 1; + } + + return 0; +} + +int KyraEngine_LoK::isDropable(int x, int y) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::isDropable(%d, %d)", x, y); + x -= 8; + y -= 1; + + if (checkNoDropRects(x, y)) + return 0; + + for (int xpos = x; xpos < x + 16; ++xpos) { + if (_screen->getShapeFlag1(xpos, y) == 0) + return 0; + } + return 1; +} + +void KyraEngine_LoK::itemDropDown(int x, int y, int destX, int destY, byte freeItem, int item) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::itemDropDown(%d, %d, %d, %d, %d, %d)", x, y, destX, destY, freeItem, item); + assert(_currentCharacter->sceneId < _roomTableSize); + Room *currentRoom = &_roomTable[_currentCharacter->sceneId]; + if (x == destX && y == destY) { + currentRoom->itemsXPos[freeItem] = destX; + currentRoom->itemsYPos[freeItem] = destY; + currentRoom->itemsTable[freeItem] = item; + snd_playSoundEffect(0x32); + _animator->animAddGameItem(freeItem, _currentCharacter->sceneId); + return; + } + _screen->hideMouse(); + if (y <= destY) { + int tempY = y; + int addY = 2; + int drawX = x - 8; + int drawY = 0; + + backUpItemRect0(drawX, y - 16); + + while (tempY < destY) { + restoreItemRect0(drawX, tempY - 16); + tempY += addY; + if (tempY > destY) + tempY = destY; + ++addY; + drawY = tempY - 16; + backUpItemRect0(drawX, drawY); + uint32 nextTime = _system->getMillis() + 1 * _tickLength; + _screen->drawShape(0, _shapes[216+item], drawX, drawY, 0, 0); + _screen->updateScreen(); + delayUntil(nextTime); + } + + bool skip = false; + if (x == destX) { + if (destY - y <= 16) + skip = true; + } + + if (!skip) { + snd_playSoundEffect(0x47); + if (addY < 6) + addY = 6; + + int xDiff = (destX - x) << 4; + xDiff /= addY; + int startAddY = addY; + addY >>= 1; + if (destY - y <= 8) + addY >>= 1; + addY = -addY; + int unkX = x << 4; + while (--startAddY) { + drawX = (unkX >> 4) - 8; + drawY = tempY - 16; + restoreItemRect0(drawX, drawY); + tempY += addY; + unkX += xDiff; + if (tempY > destY) + tempY = destY; + ++addY; + drawX = (unkX >> 4) - 8; + drawY = tempY - 16; + backUpItemRect0(drawX, drawY); + uint32 nextTime = _system->getMillis() + 1 * _tickLength; + _screen->drawShape(0, _shapes[216+item], drawX, drawY, 0, 0); + _screen->updateScreen(); + delayUntil(nextTime); + } + restoreItemRect0(drawX, drawY); + } else { + restoreItemRect0(drawX, tempY - 16); + } + } + currentRoom->itemsXPos[freeItem] = destX; + currentRoom->itemsYPos[freeItem] = destY; + currentRoom->itemsTable[freeItem] = item; + snd_playSoundEffect(0x32); + _animator->animAddGameItem(freeItem, _currentCharacter->sceneId); + _screen->showMouse(); +} + +void KyraEngine_LoK::dropItem(int unk1, int item, int x, int y, int unk2) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::dropItem(%d, %d, %d, %d, %d)", unk1, item, x, y, unk2); + if (processItemDrop(_currentCharacter->sceneId, item, x, y, unk1, unk2)) + return; + snd_playSoundEffect(54); + assert(_noDropList); + if (12 == countItemsInScene(_currentCharacter->sceneId)) + drawSentenceCommand(_noDropList[0], 6); + else + drawSentenceCommand(_noDropList[1], 6); +} + +void KyraEngine_LoK::itemSpecialFX(int x, int y, int item) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::itemSpecialFX(%d, %d, %d)", x, y, item); + if (item == 41) + itemSpecialFX1(x, y, item); + else + itemSpecialFX2(x, y, item); +} + +void KyraEngine_LoK::itemSpecialFX1(int x, int y, int item) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::itemSpecialFX1(%d, %d, %d)", x, y, item); + uint8 *shape = _shapes[216+item]; + x -= 8; + int startY = y; + y -= 15; + _screen->hideMouse(); + backUpItemRect0(x, y); + for (int i = 1; i <= 16; ++i) { + _screen->setNewShapeHeight(shape, i); + --startY; + restoreItemRect0(x, y); + uint32 nextTime = _system->getMillis() + 1 * _tickLength; + _screen->drawShape(0, shape, x, startY, 0, 0); + _screen->updateScreen(); + delayUntil(nextTime); + } + restoreItemRect0(x, y); + _screen->showMouse(); +} + +void KyraEngine_LoK::itemSpecialFX2(int x, int y, int item) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::itemSpecialFX2(%d, %d, %d)", x, y, item); + x -= 8; + y -= 15; + int yAdd = (int8)(((16 - _itemTable[item].height) >> 1) & 0xFF); + backUpItemRect0(x, y); + if (item >= 80 && item <= 89) + snd_playSoundEffect(55); + + for (int i = 201; i <= 205; ++i) { + restoreItemRect0(x, y); + uint32 nextTime = _system->getMillis() + 3 * _tickLength; + _screen->drawShape(0, _shapes[i], x, y + yAdd, 0, 0); + _screen->updateScreen(); + delayUntil(nextTime); + } + + for (int i = 204; i >= 201; --i) { + restoreItemRect0(x, y); + uint32 nextTime = _system->getMillis() + 3 * _tickLength; + _screen->drawShape(0, _shapes[216+item], x, y, 0, 0); + _screen->drawShape(0, _shapes[i], x, y + yAdd, 0, 0); + _screen->updateScreen(); + delayUntil(nextTime); + } + restoreItemRect0(x, y); +} + +void KyraEngine_LoK::magicOutMouseItem(int animIndex, int itemPos) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::magicOutMouseItem(%d, %d)", animIndex, itemPos); + int videoPageBackUp = _screen->_curPage; + _screen->_curPage = 0; + int x = 0, y = 0; + if (itemPos == -1) { + Common::Point mouse = getMousePos(); + x = mouse.x - 12; + y = mouse.y - 18; + } else { + x = _itemPosX[itemPos] - 4; + y = _itemPosY[itemPos] - 3; + } + + if (_itemInHand == -1 && itemPos == -1) + return; + + int tableIndex = 0, loopStart = 0, maxLoops = 0; + if (animIndex == 0) { + tableIndex = _rnd.getRandomNumberRng(0, 5); + loopStart = 35; + maxLoops = 9; + } else if (animIndex == 1) { + tableIndex = _rnd.getRandomNumberRng(0, 11); + loopStart = 115; + maxLoops = 8; + } else if (animIndex == 2) { + tableIndex = 0; + loopStart = 124; + maxLoops = 4; + } else { + tableIndex = -1; + } + + if (animIndex == 2) + snd_playSoundEffect(0x5E); + else + snd_playSoundEffect(0x37); + _screen->hideMouse(); + backUpItemRect1(x, y); + + for (int shape = _magicMouseItemStartFrame[animIndex]; shape <= _magicMouseItemEndFrame[animIndex]; ++shape) { + restoreItemRect1(x, y); + uint32 nextTime = _system->getMillis() + 4 * _tickLength; + _screen->drawShape(0, _shapes[216+_itemInHand], x + 4, y + 3, 0, 0); + if (tableIndex == -1) + _screen->drawShape(0, _shapes[shape], x, y, 0, 0); + else + specialMouseItemFX(shape, x, y, animIndex, tableIndex, loopStart, maxLoops); + _screen->updateScreen(); + delayUntil(nextTime); + } + + if (itemPos != -1) { + restoreItemRect1(x, y); + _screen->fillRect(_itemPosX[itemPos], _itemPosY[itemPos], _itemPosX[itemPos] + 15, _itemPosY[itemPos] + 15, 12, 0); + backUpItemRect1(x, y); + } + + for (int shape = _magicMouseItemStartFrame2[animIndex]; shape <= _magicMouseItemEndFrame2[animIndex]; ++shape) { + restoreItemRect1(x, y); + uint32 nextTime = _system->getMillis() + 4 * _tickLength; + _screen->drawShape(0, _shapes[216+_itemInHand], x + 4, y + 3, 0, 0); + if (tableIndex == -1) + _screen->drawShape(0, _shapes[shape], x, y, 0, 0); + else + specialMouseItemFX(shape, x, y, animIndex, tableIndex, loopStart, maxLoops); + _screen->updateScreen(); + delayUntil(nextTime); + } + restoreItemRect1(x, y); + if (itemPos == -1) { + _screen->setMouseCursor(1, 1, _shapes[0]); + _itemInHand = -1; + } else { + _characterList[0].inventoryItems[itemPos] = 0xFF; + _screen->hideMouse(); + _screen->fillRect(_itemPosX[itemPos], _itemPosY[itemPos], _itemPosX[itemPos] + 15, _itemPosY[itemPos] + 15, 12, 0); + _screen->showMouse(); + } + _screen->showMouse(); + _screen->_curPage = videoPageBackUp; +} + +void KyraEngine_LoK::magicInMouseItem(int animIndex, int item, int itemPos) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::magicInMouseItem(%d, %d, %d)", animIndex, item, itemPos); + int videoPageBackUp = _screen->_curPage; + _screen->_curPage = 0; + int x = 0, y = 0; + if (itemPos == -1) { + Common::Point mouse = getMousePos(); + x = mouse.x - 12; + y = mouse.y - 18; + } else { + x = _itemPosX[itemPos] - 4; + y = _itemPosX[itemPos] - 3; + } + if (item < 0) + return; + + int tableIndex = -1, loopStart = 0, maxLoops = 0; + if (animIndex == 0) { + tableIndex = _rnd.getRandomNumberRng(0, 5); + loopStart = 35; + maxLoops = 9; + } else if (animIndex == 1) { + tableIndex = _rnd.getRandomNumberRng(0, 11); + loopStart = 115; + maxLoops = 8; + } else if (animIndex == 2) { + tableIndex = 0; + loopStart = 124; + maxLoops = 4; + } + + _screen->hideMouse(); + backUpItemRect1(x, y); + if (animIndex == 2) + snd_playSoundEffect(0x5E); + else + snd_playSoundEffect(0x37); + + for (int shape = _magicMouseItemStartFrame[animIndex]; shape <= _magicMouseItemEndFrame[animIndex]; ++shape) { + restoreItemRect1(x, y); + uint32 nextTime = _system->getMillis() + 4 * _tickLength; + if (tableIndex == -1) + _screen->drawShape(0, _shapes[shape], x, y, 0, 0); + else + specialMouseItemFX(shape, x, y, animIndex, tableIndex, loopStart, maxLoops); + _screen->updateScreen(); + delayUntil(nextTime); + } + + for (int shape = _magicMouseItemStartFrame2[animIndex]; shape <= _magicMouseItemEndFrame2[animIndex]; ++shape) { + restoreItemRect1(x, y); + uint32 nextTime = _system->getMillis() + 4 * _tickLength; + if (tableIndex == -1) + _screen->drawShape(0, _shapes[shape], x, y, 0, 0); + else + specialMouseItemFX(shape, x, y, animIndex, tableIndex, loopStart, maxLoops); + _screen->updateScreen(); + delayUntil(nextTime); + } + restoreItemRect1(x, y); + if (itemPos == -1) { + _screen->setMouseCursor(8, 15, _shapes[216+item]); + _itemInHand = item; + } else { + _characterList[0].inventoryItems[itemPos] = item; + _screen->hideMouse(); + _screen->drawShape(0, _shapes[216+item], _itemPosX[itemPos], _itemPosY[itemPos], 0, 0); + _screen->showMouse(); + } + _screen->showMouse(); + _screen->_curPage = videoPageBackUp; +} + +void KyraEngine_LoK::specialMouseItemFX(int shape, int x, int y, int animIndex, int tableIndex, int loopStart, int maxLoops) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::specialMouseItemFX(%d, %d, %d, %d, %d, %d, %d)", shape, x, y, animIndex, tableIndex, loopStart, maxLoops); + static const uint8 table1[] = { + 0x23, 0x45, 0x55, 0x72, 0x84, 0xCF, 0x00, 0x00 + }; + static const uint8 table2[] = { + 0x73, 0xB5, 0x80, 0x21, 0x13, 0x39, 0x45, 0x55, 0x62, 0xB4, 0xCF, 0xD8 + }; + static const uint8 table3[] = { + 0x7C, 0xD0, 0x74, 0x84, 0x87, 0x00, 0x00, 0x00 + }; + int tableValue = 0; + if (animIndex == 0) + tableValue = table1[tableIndex]; + else if (animIndex == 1) + tableValue = table2[tableIndex]; + else if (animIndex == 2) + tableValue = table3[tableIndex]; + else + return; + processSpecialMouseItemFX(shape, x, y, tableValue, loopStart, maxLoops); +} + +void KyraEngine_LoK::processSpecialMouseItemFX(int shape, int x, int y, int tableValue, int loopStart, int maxLoops) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::processSpecialMouseItemFX(%d, %d, %d, %d, %d, %d)", shape, x, y, tableValue, loopStart, maxLoops); + uint8 shapeColorTable[16]; + uint8 *shapePtr = _shapes[shape] + 10; + if (_flags.useAltShapeHeader) + shapePtr += 2; + + for (int i = 0; i < 16; ++i) + shapeColorTable[i] = shapePtr[i]; + + for (int i = loopStart; i < loopStart + maxLoops; ++i) { + for (int i2 = 0; i2 < 16; ++i2) { + if (shapePtr[i2] == i) + shapeColorTable[i2] = (i + tableValue) - loopStart; + } + } + _screen->drawShape(0, _shapes[shape], x, y, 0, 0x8000, shapeColorTable); +} + +void KyraEngine_LoK::updatePlayerItemsForScene() { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::updatePlayerItemsForScene()"); + if (_itemInHand >= 29 && _itemInHand < 33) { + ++_itemInHand; + if (_itemInHand > 33) + _itemInHand = 33; + _screen->hideMouse(); + _screen->setMouseCursor(8, 15, _shapes[216+_itemInHand]); + _screen->showMouse(); + } + + bool redraw = false; + for (int i = 0; i < 10; ++i) { + uint8 item = _currentCharacter->inventoryItems[i]; + if (item >= 29 && item < 33) { + ++item; + if (item > 33) + item = 33; + _currentCharacter->inventoryItems[i] = item; + redraw = true; + } + } + + if (redraw) { + _screen->hideMouse(); + redrawInventory(0); + _screen->showMouse(); + } + + if (_itemInHand == 33) + magicOutMouseItem(2, -1); + + _screen->hideMouse(); + for (int i = 0; i < 10; ++i) { + uint8 item = _currentCharacter->inventoryItems[i]; + if (item == 33) + magicOutMouseItem(2, i); + } + _screen->showMouse(); +} + +void KyraEngine_LoK::redrawInventory(int page) { + int videoPageBackUp = _screen->_curPage; + _screen->_curPage = page; + _screen->hideMouse(); + for (int i = 0; i < 10; ++i) { + _screen->fillRect(_itemPosX[i], _itemPosY[i], _itemPosX[i] + 15, _itemPosY[i] + 15, 12, page); + if (_currentCharacter->inventoryItems[i] != 0xFF) { + uint8 item = _currentCharacter->inventoryItems[i]; + _screen->drawShape(page, _shapes[216+item], _itemPosX[i], _itemPosY[i], 0, 0); + } + } + _screen->showMouse(); + _screen->_curPage = videoPageBackUp; + _screen->updateScreen(); +} + +void KyraEngine_LoK::backUpItemRect0(int xpos, int ypos) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::backUpItemRect0(%d, %d)", xpos, ypos); + _screen->rectClip(xpos, ypos, 3<<3, 24); + _screen->copyRegionToBuffer(_screen->_curPage, xpos, ypos, 3<<3, 24, _itemBkgBackUp[0]); +} + +void KyraEngine_LoK::restoreItemRect0(int xpos, int ypos) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::restoreItemRect0(%d, %d)", xpos, ypos); + _screen->rectClip(xpos, ypos, 3<<3, 24); + _screen->copyBlockToPage(_screen->_curPage, xpos, ypos, 3<<3, 24, _itemBkgBackUp[0]); +} + +void KyraEngine_LoK::backUpItemRect1(int xpos, int ypos) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::backUpItemRect1(%d, %d)", xpos, ypos); + _screen->rectClip(xpos, ypos, 4<<3, 32); + _screen->copyRegionToBuffer(_screen->_curPage, xpos, ypos, 4<<3, 32, _itemBkgBackUp[1]); +} + +void KyraEngine_LoK::restoreItemRect1(int xpos, int ypos) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::restoreItemRect1(%d, %d)", xpos, ypos); + _screen->rectClip(xpos, ypos, 4<<3, 32); + _screen->copyBlockToPage(_screen->_curPage, xpos, ypos, 4<<3, 32, _itemBkgBackUp[1]); +} + +} // end of namespace Kyra + diff --git a/engines/kyra/items_v1.cpp b/engines/kyra/items_v1.cpp deleted file mode 100644 index ae3ba2821a..0000000000 --- a/engines/kyra/items_v1.cpp +++ /dev/null @@ -1,944 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include "kyra/kyra_v1.h" -#include "kyra/seqplayer.h" -#include "kyra/screen.h" -#include "kyra/resource.h" -#include "kyra/sound.h" -#include "kyra/sprites.h" -#include "kyra/wsamovie.h" -#include "kyra/animator_v1.h" -#include "kyra/text.h" - -#include "common/system.h" -#include "common/savefile.h" - -namespace Kyra { - -int KyraEngine_v1::findDuplicateItemShape(int shape) { - static uint8 dupTable[] = { - 0x48, 0x46, 0x49, 0x47, 0x4a, 0x46, 0x4b, 0x47, - 0x4c, 0x46, 0x4d, 0x47, 0x5b, 0x5a, 0x5c, 0x5a, - 0x5d, 0x5a, 0x5e, 0x5a, 0xFF, 0xFF - }; - - int i = 0; - - while (dupTable[i] != 0xFF) { - if (dupTable[i] == shape) - return dupTable[i+1]; - i += 2; - } - return -1; -} - -void KyraEngine_v1::addToNoDropRects(int x, int y, int w, int h) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::addToNoDropRects(%d, %d, %d, %d)", x, y, w, h); - for (int rect = 0; rect < 11; ++rect) { - if (_noDropRects[rect].x == -1) { - _noDropRects[rect].x = x; - _noDropRects[rect].y = y; - _noDropRects[rect].x2 = x + w - 1; - _noDropRects[rect].y2 = y + h - 1; - break; - } - } -} - -void KyraEngine_v1::clearNoDropRects() { - debugC(9, kDebugLevelMain, "KyraEngine_v1::clearNoDropRects()"); - memset(_noDropRects, -1, sizeof(_noDropRects)); -} - -byte KyraEngine_v1::findFreeItemInScene(int scene) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::findFreeItemInScene(%d)", scene); - assert(scene < _roomTableSize); - Room *room = &_roomTable[scene]; - for (int i = 0; i < 12; ++i) { - if (room->itemsTable[i] == 0xFF) - return i; - } - return 0xFF; -} - -byte KyraEngine_v1::findItemAtPos(int x, int y) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::findItemAtPos(%d, %d)", x, y); - assert(_currentCharacter->sceneId < _roomTableSize); - const uint8 *itemsTable = _roomTable[_currentCharacter->sceneId].itemsTable; - const uint16 *xposOffset = _roomTable[_currentCharacter->sceneId].itemsXPos; - const uint8 *yposOffset = _roomTable[_currentCharacter->sceneId].itemsYPos; - - int highestYPos = -1; - byte returnValue = 0xFF; - - for (int i = 0; i < 12; ++i) { - if (*itemsTable != 0xFF) { - int xpos = *xposOffset - 11; - int xpos2 = *xposOffset + 10; - if (x > xpos && x < xpos2) { - assert(*itemsTable < ARRAYSIZE(_itemTable)); - int itemHeight = _itemTable[*itemsTable].height; - int ypos = *yposOffset + 3; - int ypos2 = ypos - itemHeight - 3; - - if (y > ypos2 && ypos > y) { - if (highestYPos <= ypos) { - returnValue = i; - highestYPos = ypos; - } - } - } - } - ++xposOffset; - ++yposOffset; - ++itemsTable; - } - - return returnValue; -} - -void KyraEngine_v1::placeItemInGenericMapScene(int item, int index) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::placeItemInGenericMapScene(%d, %d)", item, index); - static const uint16 itemMapSceneMinTable[] = { - 0x0000, 0x0011, 0x006D, 0x0025, 0x00C7, 0x0000 - }; - static const uint16 itemMapSceneMaxTable[] = { - 0x0010, 0x0024, 0x00C6, 0x006C, 0x00F5, 0x0000 - }; - - int minValue = itemMapSceneMinTable[index]; - int maxValue = itemMapSceneMaxTable[index]; - - while (true) { - int room = _rnd.getRandomNumberRng(minValue, maxValue); - assert(room < _roomTableSize); - int nameIndex = _roomTable[room].nameIndex; - bool placeItem = false; - - switch (nameIndex) { - case 0: case 1: case 2: case 3: - case 4: case 5: case 6: case 11: - case 12: case 16: case 17: case 20: - case 22: case 23: case 25: case 26: - case 27: case 31: case 33: case 34: - case 36: case 37: case 58: case 59: - case 60: case 61: case 83: case 84: - case 85: case 104: case 105: case 106: - placeItem = true; - break; - - case 51: - if (room != 46) - placeItem = true; - break; - - default: - break; - } - - if (placeItem) { - Room *roomPtr = &_roomTable[room]; - if (roomPtr->northExit == 0xFFFF && roomPtr->eastExit == 0xFFFF && roomPtr->southExit == 0xFFFF && roomPtr->westExit == 0xFFFF) - placeItem = false; - else if (_currentCharacter->sceneId == room) - placeItem = false; - } - - if (placeItem) { - if (!processItemDrop(room, item, -1, -1, 2, 0)) - continue; - break; - } - } -} - -void KyraEngine_v1::createMouseItem(int item) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::createMouseItem(%d)", item); - _screen->hideMouse(); - setMouseItem(item); - _itemInHand = item; - _screen->showMouse(); -} - -void KyraEngine_v1::destroyMouseItem() { - debugC(9, kDebugLevelMain, "KyraEngine_v1::destroyMouseItem()"); - _screen->hideMouse(); - _screen->setMouseCursor(1, 1, _shapes[0]); - _itemInHand = -1; - _screen->showMouse(); -} - -void KyraEngine_v1::setMouseItem(int item) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::setMouseItem(%d)", item); - if (item == -1) - _screen->setMouseCursor(1, 1, _shapes[6]); - else - _screen->setMouseCursor(8, 15, _shapes[216+item]); -} - -void KyraEngine_v1::wipeDownMouseItem(int xpos, int ypos) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::wipeDownMouseItem(%d, %d)", xpos, ypos); - if (_itemInHand == -1) - return; - xpos -= 8; - ypos -= 15; - _screen->hideMouse(); - backUpItemRect1(xpos, ypos); - int y = ypos; - int height = 16; - - while (height >= 0) { - restoreItemRect1(xpos, ypos); - _screen->setNewShapeHeight(_shapes[216+_itemInHand], height); - uint32 nextTime = _system->getMillis() + 1 * _tickLength; - _screen->drawShape(0, _shapes[216+_itemInHand], xpos, y, 0, 0); - _screen->updateScreen(); - y += 2; - height -= 2; - delayUntil(nextTime); - } - restoreItemRect1(xpos, ypos); - _screen->resetShapeHeight(_shapes[216+_itemInHand]); - destroyMouseItem(); - _screen->showMouse(); -} - -void KyraEngine_v1::setupSceneItems() { - debugC(9, kDebugLevelMain, "KyraEngine_v1::setupSceneItems()"); - uint16 sceneId = _currentCharacter->sceneId; - assert(sceneId < _roomTableSize); - Room *currentRoom = &_roomTable[sceneId]; - for (int i = 0; i < 12; ++i) { - uint8 item = currentRoom->itemsTable[i]; - if (item == 0xFF || !currentRoom->needInit[i]) - continue; - - int xpos = 0; - int ypos = 0; - - if (currentRoom->itemsXPos[i] == 0xFFFF) { - xpos = currentRoom->itemsXPos[i] = _rnd.getRandomNumberRng(24, 296); - ypos = currentRoom->itemsYPos[i] = _rnd.getRandomNumberRng(_northExitHeight & 0xFF, 130); - } else { - xpos = currentRoom->itemsXPos[i]; - ypos = currentRoom->itemsYPos[i]; - } - - _lastProcessedItem = i; - - int stop = 0; - while (!stop) { - stop = processItemDrop(sceneId, item, xpos, ypos, 3, 0); - if (!stop) { - xpos = currentRoom->itemsXPos[i] = _rnd.getRandomNumberRng(24, 296); - ypos = currentRoom->itemsYPos[i] = _rnd.getRandomNumberRng(_northExitHeight & 0xFF, 130); - if (countItemsInScene(sceneId) >= 12) - break; - } else { - currentRoom->needInit[i] = 0; - } - } - } -} - -int KyraEngine_v1::countItemsInScene(uint16 sceneId) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::countItemsInScene(%d)", sceneId); - assert(sceneId < _roomTableSize); - Room *currentRoom = &_roomTable[sceneId]; - - int items = 0; - - for (int i = 0; i < 12; ++i) { - if (currentRoom->itemsTable[i] != 0xFF) - ++items; - } - - return items; -} - -int KyraEngine_v1::processItemDrop(uint16 sceneId, uint8 item, int x, int y, int unk1, int unk2) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::processItemDrop(%d, %d, %d, %d, %d, %d)", sceneId, item, x, y, unk1, unk2); - int freeItem = -1; - uint8 itemIndex = findItemAtPos(x, y); - if (unk1) - itemIndex = 0xFF; - - if (itemIndex != 0xFF) { - exchangeItemWithMouseItem(sceneId, itemIndex); - return 0; - } - - assert(sceneId < _roomTableSize); - Room *currentRoom = &_roomTable[sceneId]; - - if (unk1 != 3) { - for (int i = 0; i < 12; ++i) { - if (currentRoom->itemsTable[i] == 0xFF) { - freeItem = i; - break; - } - } - } else { - freeItem = _lastProcessedItem; - } - - if (freeItem == -1) - return 0; - - if (sceneId != _currentCharacter->sceneId) { - addItemToRoom(sceneId, item, freeItem, x, y); - return 1; - } - - int itemHeight = _itemTable[item].height; - _lastProcessedItemHeight = itemHeight; - - if (x == -1 && x == -1) { - x = _rnd.getRandomNumberRng(16, 304); - y = _rnd.getRandomNumberRng(_northExitHeight & 0xFF, 135); - } - - int xpos = x; - int ypos = y; - int destY = -1; - int destX = -1; - int running = 1; - - while (running) { - if ((_northExitHeight & 0xFF) <= ypos) { - bool running2 = true; - - if (_screen->getDrawLayer(xpos, ypos) > 1) { - if (((_northExitHeight >> 8) & 0xFF) != ypos) - running2 = false; - } - - if (_screen->getDrawLayer2(xpos, ypos, itemHeight) > 1) { - if (((_northExitHeight >> 8) & 0xFF) != ypos) - running2 = false; - } - - if (!isDropable(xpos, ypos)) { - if (((_northExitHeight >> 8) & 0xFF) != ypos) - running2 = false; - } - - int xpos2 = xpos; - int xpos3 = xpos; - - while (running2) { - if (isDropable(xpos2, ypos)) { - if (_screen->getDrawLayer2(xpos2, ypos, itemHeight) < 7) { - if (findItemAtPos(xpos2, ypos) == 0xFF) { - destX = xpos2; - destY = ypos; - running = 0; - running2 = false; - } - } - } - - if (isDropable(xpos3, ypos)) { - if (_screen->getDrawLayer2(xpos3, ypos, itemHeight) < 7) { - if (findItemAtPos(xpos3, ypos) == 0xFF) { - destX = xpos3; - destY = ypos; - running = 0; - running2 = false; - } - } - } - - if (!running2) - continue; - - xpos2 -= 2; - if (xpos2 < 16) - xpos2 = 16; - - xpos3 += 2; - if (xpos3 > 304) - xpos3 = 304; - - if (xpos2 > 16) - continue; - if (xpos3 < 304) - continue; - running2 = false; - } - } - - if (((_northExitHeight >> 8) & 0xFF) == ypos) { - running = 0; - destY -= _rnd.getRandomNumberRng(0, 3); - - if ((_northExitHeight & 0xFF) < destY) - continue; - - destY = (_northExitHeight & 0xFF) + 1; - continue; - } - ypos += 2; - if (((_northExitHeight >> 8) & 0xFF) >= ypos) - continue; - ypos = (_northExitHeight >> 8) & 0xFF; - } - - if (destX == -1 || destY == -1) - return 0; - - if (unk1 == 3) { - currentRoom->itemsXPos[freeItem] = destX; - currentRoom->itemsYPos[freeItem] = destY; - return 1; - } - - if (unk1 == 2) - itemSpecialFX(x, y, item); - - if (unk1 == 0) - destroyMouseItem(); - - itemDropDown(x, y, destX, destY, freeItem, item); - - if (unk1 == 0 && unk2 != 0) { - assert(_itemList && _droppedList); - updateSentenceCommand(_itemList[item], _droppedList[0], 179); - } - - return 1; -} - -void KyraEngine_v1::exchangeItemWithMouseItem(uint16 sceneId, int itemIndex) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::exchangeItemWithMouseItem(%d, %d)", sceneId, itemIndex); - _screen->hideMouse(); - _animator->animRemoveGameItem(itemIndex); - assert(sceneId < _roomTableSize); - Room *currentRoom = &_roomTable[sceneId]; - - int item = currentRoom->itemsTable[itemIndex]; - currentRoom->itemsTable[itemIndex] = _itemInHand; - _itemInHand = item; - _animator->animAddGameItem(itemIndex, sceneId); - snd_playSoundEffect(53); - - setMouseItem(_itemInHand); - assert(_itemList && _takenList); - updateSentenceCommand(_itemList[_itemInHand], _takenList[1], 179); - _screen->showMouse(); - clickEventHandler2(); -} - -void KyraEngine_v1::addItemToRoom(uint16 sceneId, uint8 item, int itemIndex, int x, int y) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::addItemToRoom(%d, %d, %d, %d, %d)", sceneId, item, itemIndex, x, y); - assert(sceneId < _roomTableSize); - Room *currentRoom = &_roomTable[sceneId]; - currentRoom->itemsTable[itemIndex] = item; - currentRoom->itemsXPos[itemIndex] = x; - currentRoom->itemsYPos[itemIndex] = y; - currentRoom->needInit[itemIndex] = 1; -} - -int KyraEngine_v1::checkNoDropRects(int x, int y) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::checkNoDropRects(%d, %d)", x, y); - if (_lastProcessedItemHeight < 1 || _lastProcessedItemHeight > 16) - _lastProcessedItemHeight = 16; - if (_noDropRects[0].x == -1) - return 0; - - for (int i = 0; i < 11; ++i) { - if (_noDropRects[i].x == -1) - break; - - int xpos = _noDropRects[i].x; - int ypos = _noDropRects[i].y; - int xpos2 = _noDropRects[i].x2; - int ypos2 = _noDropRects[i].y2; - - if (xpos > x + 16) - continue; - if (xpos2 < x) - continue; - if (y < ypos) - continue; - if (ypos2 < y - _lastProcessedItemHeight) - continue; - return 1; - } - - return 0; -} - -int KyraEngine_v1::isDropable(int x, int y) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::isDropable(%d, %d)", x, y); - x -= 8; - y -= 1; - - if (checkNoDropRects(x, y)) - return 0; - - for (int xpos = x; xpos < x + 16; ++xpos) { - if (_screen->getShapeFlag1(xpos, y) == 0) - return 0; - } - return 1; -} - -void KyraEngine_v1::itemDropDown(int x, int y, int destX, int destY, byte freeItem, int item) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::itemDropDown(%d, %d, %d, %d, %d, %d)", x, y, destX, destY, freeItem, item); - assert(_currentCharacter->sceneId < _roomTableSize); - Room *currentRoom = &_roomTable[_currentCharacter->sceneId]; - if (x == destX && y == destY) { - currentRoom->itemsXPos[freeItem] = destX; - currentRoom->itemsYPos[freeItem] = destY; - currentRoom->itemsTable[freeItem] = item; - snd_playSoundEffect(0x32); - _animator->animAddGameItem(freeItem, _currentCharacter->sceneId); - return; - } - _screen->hideMouse(); - if (y <= destY) { - int tempY = y; - int addY = 2; - int drawX = x - 8; - int drawY = 0; - - backUpItemRect0(drawX, y - 16); - - while (tempY < destY) { - restoreItemRect0(drawX, tempY - 16); - tempY += addY; - if (tempY > destY) - tempY = destY; - ++addY; - drawY = tempY - 16; - backUpItemRect0(drawX, drawY); - uint32 nextTime = _system->getMillis() + 1 * _tickLength; - _screen->drawShape(0, _shapes[216+item], drawX, drawY, 0, 0); - _screen->updateScreen(); - delayUntil(nextTime); - } - - bool skip = false; - if (x == destX) { - if (destY - y <= 16) - skip = true; - } - - if (!skip) { - snd_playSoundEffect(0x47); - if (addY < 6) - addY = 6; - - int xDiff = (destX - x) << 4; - xDiff /= addY; - int startAddY = addY; - addY >>= 1; - if (destY - y <= 8) - addY >>= 1; - addY = -addY; - int unkX = x << 4; - while (--startAddY) { - drawX = (unkX >> 4) - 8; - drawY = tempY - 16; - restoreItemRect0(drawX, drawY); - tempY += addY; - unkX += xDiff; - if (tempY > destY) - tempY = destY; - ++addY; - drawX = (unkX >> 4) - 8; - drawY = tempY - 16; - backUpItemRect0(drawX, drawY); - uint32 nextTime = _system->getMillis() + 1 * _tickLength; - _screen->drawShape(0, _shapes[216+item], drawX, drawY, 0, 0); - _screen->updateScreen(); - delayUntil(nextTime); - } - restoreItemRect0(drawX, drawY); - } else { - restoreItemRect0(drawX, tempY - 16); - } - } - currentRoom->itemsXPos[freeItem] = destX; - currentRoom->itemsYPos[freeItem] = destY; - currentRoom->itemsTable[freeItem] = item; - snd_playSoundEffect(0x32); - _animator->animAddGameItem(freeItem, _currentCharacter->sceneId); - _screen->showMouse(); -} - -void KyraEngine_v1::dropItem(int unk1, int item, int x, int y, int unk2) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::dropItem(%d, %d, %d, %d, %d)", unk1, item, x, y, unk2); - if (processItemDrop(_currentCharacter->sceneId, item, x, y, unk1, unk2)) - return; - snd_playSoundEffect(54); - assert(_noDropList); - if (12 == countItemsInScene(_currentCharacter->sceneId)) - drawSentenceCommand(_noDropList[0], 6); - else - drawSentenceCommand(_noDropList[1], 6); -} - -void KyraEngine_v1::itemSpecialFX(int x, int y, int item) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::itemSpecialFX(%d, %d, %d)", x, y, item); - if (item == 41) - itemSpecialFX1(x, y, item); - else - itemSpecialFX2(x, y, item); -} - -void KyraEngine_v1::itemSpecialFX1(int x, int y, int item) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::itemSpecialFX1(%d, %d, %d)", x, y, item); - uint8 *shape = _shapes[216+item]; - x -= 8; - int startY = y; - y -= 15; - _screen->hideMouse(); - backUpItemRect0(x, y); - for (int i = 1; i <= 16; ++i) { - _screen->setNewShapeHeight(shape, i); - --startY; - restoreItemRect0(x, y); - uint32 nextTime = _system->getMillis() + 1 * _tickLength; - _screen->drawShape(0, shape, x, startY, 0, 0); - _screen->updateScreen(); - delayUntil(nextTime); - } - restoreItemRect0(x, y); - _screen->showMouse(); -} - -void KyraEngine_v1::itemSpecialFX2(int x, int y, int item) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::itemSpecialFX2(%d, %d, %d)", x, y, item); - x -= 8; - y -= 15; - int yAdd = (int8)(((16 - _itemTable[item].height) >> 1) & 0xFF); - backUpItemRect0(x, y); - if (item >= 80 && item <= 89) - snd_playSoundEffect(55); - - for (int i = 201; i <= 205; ++i) { - restoreItemRect0(x, y); - uint32 nextTime = _system->getMillis() + 3 * _tickLength; - _screen->drawShape(0, _shapes[i], x, y + yAdd, 0, 0); - _screen->updateScreen(); - delayUntil(nextTime); - } - - for (int i = 204; i >= 201; --i) { - restoreItemRect0(x, y); - uint32 nextTime = _system->getMillis() + 3 * _tickLength; - _screen->drawShape(0, _shapes[216+item], x, y, 0, 0); - _screen->drawShape(0, _shapes[i], x, y + yAdd, 0, 0); - _screen->updateScreen(); - delayUntil(nextTime); - } - restoreItemRect0(x, y); -} - -void KyraEngine_v1::magicOutMouseItem(int animIndex, int itemPos) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::magicOutMouseItem(%d, %d)", animIndex, itemPos); - int videoPageBackUp = _screen->_curPage; - _screen->_curPage = 0; - int x = 0, y = 0; - if (itemPos == -1) { - Common::Point mouse = getMousePos(); - x = mouse.x - 12; - y = mouse.y - 18; - } else { - x = _itemPosX[itemPos] - 4; - y = _itemPosY[itemPos] - 3; - } - - if (_itemInHand == -1 && itemPos == -1) - return; - - int tableIndex = 0, loopStart = 0, maxLoops = 0; - if (animIndex == 0) { - tableIndex = _rnd.getRandomNumberRng(0, 5); - loopStart = 35; - maxLoops = 9; - } else if (animIndex == 1) { - tableIndex = _rnd.getRandomNumberRng(0, 11); - loopStart = 115; - maxLoops = 8; - } else if (animIndex == 2) { - tableIndex = 0; - loopStart = 124; - maxLoops = 4; - } else { - tableIndex = -1; - } - - if (animIndex == 2) - snd_playSoundEffect(0x5E); - else - snd_playSoundEffect(0x37); - _screen->hideMouse(); - backUpItemRect1(x, y); - - for (int shape = _magicMouseItemStartFrame[animIndex]; shape <= _magicMouseItemEndFrame[animIndex]; ++shape) { - restoreItemRect1(x, y); - uint32 nextTime = _system->getMillis() + 4 * _tickLength; - _screen->drawShape(0, _shapes[216+_itemInHand], x + 4, y + 3, 0, 0); - if (tableIndex == -1) - _screen->drawShape(0, _shapes[shape], x, y, 0, 0); - else - specialMouseItemFX(shape, x, y, animIndex, tableIndex, loopStart, maxLoops); - _screen->updateScreen(); - delayUntil(nextTime); - } - - if (itemPos != -1) { - restoreItemRect1(x, y); - _screen->fillRect(_itemPosX[itemPos], _itemPosY[itemPos], _itemPosX[itemPos] + 15, _itemPosY[itemPos] + 15, 12, 0); - backUpItemRect1(x, y); - } - - for (int shape = _magicMouseItemStartFrame2[animIndex]; shape <= _magicMouseItemEndFrame2[animIndex]; ++shape) { - restoreItemRect1(x, y); - uint32 nextTime = _system->getMillis() + 4 * _tickLength; - _screen->drawShape(0, _shapes[216+_itemInHand], x + 4, y + 3, 0, 0); - if (tableIndex == -1) - _screen->drawShape(0, _shapes[shape], x, y, 0, 0); - else - specialMouseItemFX(shape, x, y, animIndex, tableIndex, loopStart, maxLoops); - _screen->updateScreen(); - delayUntil(nextTime); - } - restoreItemRect1(x, y); - if (itemPos == -1) { - _screen->setMouseCursor(1, 1, _shapes[0]); - _itemInHand = -1; - } else { - _characterList[0].inventoryItems[itemPos] = 0xFF; - _screen->hideMouse(); - _screen->fillRect(_itemPosX[itemPos], _itemPosY[itemPos], _itemPosX[itemPos] + 15, _itemPosY[itemPos] + 15, 12, 0); - _screen->showMouse(); - } - _screen->showMouse(); - _screen->_curPage = videoPageBackUp; -} - -void KyraEngine_v1::magicInMouseItem(int animIndex, int item, int itemPos) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::magicInMouseItem(%d, %d, %d)", animIndex, item, itemPos); - int videoPageBackUp = _screen->_curPage; - _screen->_curPage = 0; - int x = 0, y = 0; - if (itemPos == -1) { - Common::Point mouse = getMousePos(); - x = mouse.x - 12; - y = mouse.y - 18; - } else { - x = _itemPosX[itemPos] - 4; - y = _itemPosX[itemPos] - 3; - } - if (item < 0) - return; - - int tableIndex = -1, loopStart = 0, maxLoops = 0; - if (animIndex == 0) { - tableIndex = _rnd.getRandomNumberRng(0, 5); - loopStart = 35; - maxLoops = 9; - } else if (animIndex == 1) { - tableIndex = _rnd.getRandomNumberRng(0, 11); - loopStart = 115; - maxLoops = 8; - } else if (animIndex == 2) { - tableIndex = 0; - loopStart = 124; - maxLoops = 4; - } - - _screen->hideMouse(); - backUpItemRect1(x, y); - if (animIndex == 2) - snd_playSoundEffect(0x5E); - else - snd_playSoundEffect(0x37); - - for (int shape = _magicMouseItemStartFrame[animIndex]; shape <= _magicMouseItemEndFrame[animIndex]; ++shape) { - restoreItemRect1(x, y); - uint32 nextTime = _system->getMillis() + 4 * _tickLength; - if (tableIndex == -1) - _screen->drawShape(0, _shapes[shape], x, y, 0, 0); - else - specialMouseItemFX(shape, x, y, animIndex, tableIndex, loopStart, maxLoops); - _screen->updateScreen(); - delayUntil(nextTime); - } - - for (int shape = _magicMouseItemStartFrame2[animIndex]; shape <= _magicMouseItemEndFrame2[animIndex]; ++shape) { - restoreItemRect1(x, y); - uint32 nextTime = _system->getMillis() + 4 * _tickLength; - if (tableIndex == -1) - _screen->drawShape(0, _shapes[shape], x, y, 0, 0); - else - specialMouseItemFX(shape, x, y, animIndex, tableIndex, loopStart, maxLoops); - _screen->updateScreen(); - delayUntil(nextTime); - } - restoreItemRect1(x, y); - if (itemPos == -1) { - _screen->setMouseCursor(8, 15, _shapes[216+item]); - _itemInHand = item; - } else { - _characterList[0].inventoryItems[itemPos] = item; - _screen->hideMouse(); - _screen->drawShape(0, _shapes[216+item], _itemPosX[itemPos], _itemPosY[itemPos], 0, 0); - _screen->showMouse(); - } - _screen->showMouse(); - _screen->_curPage = videoPageBackUp; -} - -void KyraEngine_v1::specialMouseItemFX(int shape, int x, int y, int animIndex, int tableIndex, int loopStart, int maxLoops) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::specialMouseItemFX(%d, %d, %d, %d, %d, %d, %d)", shape, x, y, animIndex, tableIndex, loopStart, maxLoops); - static const uint8 table1[] = { - 0x23, 0x45, 0x55, 0x72, 0x84, 0xCF, 0x00, 0x00 - }; - static const uint8 table2[] = { - 0x73, 0xB5, 0x80, 0x21, 0x13, 0x39, 0x45, 0x55, 0x62, 0xB4, 0xCF, 0xD8 - }; - static const uint8 table3[] = { - 0x7C, 0xD0, 0x74, 0x84, 0x87, 0x00, 0x00, 0x00 - }; - int tableValue = 0; - if (animIndex == 0) - tableValue = table1[tableIndex]; - else if (animIndex == 1) - tableValue = table2[tableIndex]; - else if (animIndex == 2) - tableValue = table3[tableIndex]; - else - return; - processSpecialMouseItemFX(shape, x, y, tableValue, loopStart, maxLoops); -} - -void KyraEngine_v1::processSpecialMouseItemFX(int shape, int x, int y, int tableValue, int loopStart, int maxLoops) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::processSpecialMouseItemFX(%d, %d, %d, %d, %d, %d)", shape, x, y, tableValue, loopStart, maxLoops); - uint8 shapeColorTable[16]; - uint8 *shapePtr = _shapes[shape] + 10; - if (_flags.useAltShapeHeader) - shapePtr += 2; - - for (int i = 0; i < 16; ++i) - shapeColorTable[i] = shapePtr[i]; - - for (int i = loopStart; i < loopStart + maxLoops; ++i) { - for (int i2 = 0; i2 < 16; ++i2) { - if (shapePtr[i2] == i) - shapeColorTable[i2] = (i + tableValue) - loopStart; - } - } - _screen->drawShape(0, _shapes[shape], x, y, 0, 0x8000, shapeColorTable); -} - -void KyraEngine_v1::updatePlayerItemsForScene() { - debugC(9, kDebugLevelMain, "KyraEngine_v1::updatePlayerItemsForScene()"); - if (_itemInHand >= 29 && _itemInHand < 33) { - ++_itemInHand; - if (_itemInHand > 33) - _itemInHand = 33; - _screen->hideMouse(); - _screen->setMouseCursor(8, 15, _shapes[216+_itemInHand]); - _screen->showMouse(); - } - - bool redraw = false; - for (int i = 0; i < 10; ++i) { - uint8 item = _currentCharacter->inventoryItems[i]; - if (item >= 29 && item < 33) { - ++item; - if (item > 33) - item = 33; - _currentCharacter->inventoryItems[i] = item; - redraw = true; - } - } - - if (redraw) { - _screen->hideMouse(); - redrawInventory(0); - _screen->showMouse(); - } - - if (_itemInHand == 33) - magicOutMouseItem(2, -1); - - _screen->hideMouse(); - for (int i = 0; i < 10; ++i) { - uint8 item = _currentCharacter->inventoryItems[i]; - if (item == 33) - magicOutMouseItem(2, i); - } - _screen->showMouse(); -} - -void KyraEngine_v1::redrawInventory(int page) { - int videoPageBackUp = _screen->_curPage; - _screen->_curPage = page; - _screen->hideMouse(); - for (int i = 0; i < 10; ++i) { - _screen->fillRect(_itemPosX[i], _itemPosY[i], _itemPosX[i] + 15, _itemPosY[i] + 15, 12, page); - if (_currentCharacter->inventoryItems[i] != 0xFF) { - uint8 item = _currentCharacter->inventoryItems[i]; - _screen->drawShape(page, _shapes[216+item], _itemPosX[i], _itemPosY[i], 0, 0); - } - } - _screen->showMouse(); - _screen->_curPage = videoPageBackUp; - _screen->updateScreen(); -} - -void KyraEngine_v1::backUpItemRect0(int xpos, int ypos) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::backUpItemRect0(%d, %d)", xpos, ypos); - _screen->rectClip(xpos, ypos, 3<<3, 24); - _screen->copyRegionToBuffer(_screen->_curPage, xpos, ypos, 3<<3, 24, _itemBkgBackUp[0]); -} - -void KyraEngine_v1::restoreItemRect0(int xpos, int ypos) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::restoreItemRect0(%d, %d)", xpos, ypos); - _screen->rectClip(xpos, ypos, 3<<3, 24); - _screen->copyBlockToPage(_screen->_curPage, xpos, ypos, 3<<3, 24, _itemBkgBackUp[0]); -} - -void KyraEngine_v1::backUpItemRect1(int xpos, int ypos) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::backUpItemRect1(%d, %d)", xpos, ypos); - _screen->rectClip(xpos, ypos, 4<<3, 32); - _screen->copyRegionToBuffer(_screen->_curPage, xpos, ypos, 4<<3, 32, _itemBkgBackUp[1]); -} - -void KyraEngine_v1::restoreItemRect1(int xpos, int ypos) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::restoreItemRect1(%d, %d)", xpos, ypos); - _screen->rectClip(xpos, ypos, 4<<3, 32); - _screen->copyBlockToPage(_screen->_curPage, xpos, ypos, 4<<3, 32, _itemBkgBackUp[1]); -} - -} // end of namespace Kyra - diff --git a/engines/kyra/kyra_hof.cpp b/engines/kyra/kyra_hof.cpp index ebe39ee02c..5a2d36d612 100644 --- a/engines/kyra/kyra_hof.cpp +++ b/engines/kyra/kyra_hof.cpp @@ -325,10 +325,10 @@ void KyraEngine_HoF::startup() { memset(_sceneAnims, 0, sizeof(_sceneAnims)); for (int i = 0; i < ARRAYSIZE(_sceneAnimMovie); ++i) - _sceneAnimMovie[i] = new WSAMovieV2(this, _screen); + _sceneAnimMovie[i] = new WSAMovie_v2(this, _screen); memset(_wsaSlots, 0, sizeof(_wsaSlots)); for (int i = 0; i < ARRAYSIZE(_wsaSlots); ++i) - _wsaSlots[i] = new WSAMovieV2(this, _screen); + _wsaSlots[i] = new WSAMovie_v2(this, _screen); _screen->_curPage = 0; @@ -1537,7 +1537,7 @@ void KyraEngine_HoF::loadInvWsa(const char *filename, int run, int delayTime, in wsaFlags |= 2; if (!_invWsa.wsa) - _invWsa.wsa = new WSAMovieV2(this, _screen); + _invWsa.wsa = new WSAMovie_v2(this, _screen); if (!_invWsa.wsa->open(filename, wsaFlags, 0)) error("Couldn't open inventory WSA file '%s'", filename); diff --git a/engines/kyra/kyra_hof.h b/engines/kyra/kyra_hof.h index 5ee13eb261..8b03cbc019 100644 --- a/engines/kyra/kyra_hof.h +++ b/engines/kyra/kyra_hof.h @@ -97,17 +97,17 @@ enum kNestedSequencesDemo { kSequenceDemoDig }; -class WSAMovieV2; +class WSAMovie_v2; class KyraEngine_HoF; class TextDisplayer_HoF; struct TIM; -typedef int (KyraEngine_HoF::*SeqProc)(WSAMovieV2*, int, int, int); +typedef int (KyraEngine_HoF::*SeqProc)(WSAMovie_v2*, int, int, int); struct ActiveWSA { int16 flags; - WSAMovieV2 *movie; + WSAMovie_v2 *movie; uint16 startFrame; uint16 endFrame; uint16 frameDelay; @@ -193,52 +193,52 @@ protected: // intro/outro void seq_playSequences(int startSeq, int endSeq = -1); - int seq_introWestwood(WSAMovieV2 *wsaObj, int x, int y, int frm); - int seq_introTitle(WSAMovieV2 *wsaObj, int x, int y, int frm); - int seq_introOverview(WSAMovieV2 *wsaObj, int x, int y, int frm); - int seq_introLibrary(WSAMovieV2 *wsaObj, int x, int y, int frm); - int seq_introHand(WSAMovieV2 *wsaObj, int x, int y, int frm); - int seq_introPoint(WSAMovieV2 *wsaObj, int x, int y, int frm); - int seq_introZanfaun(WSAMovieV2 *wsaObj, int x, int y, int frm); - - int seq_introOver1(WSAMovieV2 *wsaObj, int x, int y, int frm); - int seq_introOver2(WSAMovieV2 *wsaObj, int x, int y, int frm); - int seq_introForest(WSAMovieV2 *wsaObj, int x, int y, int frm); - int seq_introDragon(WSAMovieV2 *wsaObj, int x, int y, int frm); - int seq_introDarm(WSAMovieV2 *wsaObj, int x, int y, int frm); - int seq_introLibrary2(WSAMovieV2 *wsaObj, int x, int y, int frm); - int seq_introMarco(WSAMovieV2 *wsaObj, int x, int y, int frm); - int seq_introHand1a(WSAMovieV2 *wsaObj, int x, int y, int frm); - int seq_introHand1b(WSAMovieV2 *wsaObj, int x, int y, int frm); - int seq_introHand1c(WSAMovieV2 *wsaObj, int x, int y, int frm); - int seq_introHand2(WSAMovieV2 *wsaObj, int x, int y, int frm); - int seq_introHand3(WSAMovieV2 *wsaObj, int x, int y, int frm); - - int seq_finaleFunters(WSAMovieV2 *wsaObj, int x, int y, int frm); - int seq_finaleFerb(WSAMovieV2 *wsaObj, int x, int y, int frm); - int seq_finaleFish(WSAMovieV2 *wsaObj, int x, int y, int frm); - int seq_finaleFheep(WSAMovieV2 *wsaObj, int x, int y, int frm); - int seq_finaleFarmer(WSAMovieV2 *wsaObj, int x, int y, int frm); - int seq_finaleFuards(WSAMovieV2 *wsaObj, int x, int y, int frm); - int seq_finaleFirates(WSAMovieV2 *wsaObj, int x, int y, int frm); - int seq_finaleFrash(WSAMovieV2 *wsaObj, int x, int y, int frm); - - int seq_finaleFiggle(WSAMovieV2 *wsaObj, int x, int y, int frm); - - int seq_demoVirgin(WSAMovieV2 *wsaObj, int x, int y, int frm); - int seq_demoWestwood(WSAMovieV2 *wsaObj, int x, int y, int frm); - int seq_demoTitle(WSAMovieV2 *wsaObj, int x, int y, int frm); - int seq_demoHill(WSAMovieV2 *wsaObj, int x, int y, int frm); - int seq_demoOuthome(WSAMovieV2 *wsaObj, int x, int y, int frm); - int seq_demoWharf(WSAMovieV2 *wsaObj, int x, int y, int frm); - int seq_demoDinob(WSAMovieV2 *wsaObj, int x, int y, int frm); - int seq_demoFisher(WSAMovieV2 *wsaObj, int x, int y, int frm); - - int seq_demoWharf2(WSAMovieV2 *wsaObj, int x, int y, int frm); - int seq_demoDinob2(WSAMovieV2 *wsaObj, int x, int y, int frm); - int seq_demoWater(WSAMovieV2 *wsaObj, int x, int y, int frm); - int seq_demoBail(WSAMovieV2 *wsaObj, int x, int y, int frm); - int seq_demoDig(WSAMovieV2 *wsaObj, int x, int y, int frm); + int seq_introWestwood(WSAMovie_v2 *wsaObj, int x, int y, int frm); + int seq_introTitle(WSAMovie_v2 *wsaObj, int x, int y, int frm); + int seq_introOverview(WSAMovie_v2 *wsaObj, int x, int y, int frm); + int seq_introLibrary(WSAMovie_v2 *wsaObj, int x, int y, int frm); + int seq_introHand(WSAMovie_v2 *wsaObj, int x, int y, int frm); + int seq_introPoint(WSAMovie_v2 *wsaObj, int x, int y, int frm); + int seq_introZanfaun(WSAMovie_v2 *wsaObj, int x, int y, int frm); + + int seq_introOver1(WSAMovie_v2 *wsaObj, int x, int y, int frm); + int seq_introOver2(WSAMovie_v2 *wsaObj, int x, int y, int frm); + int seq_introForest(WSAMovie_v2 *wsaObj, int x, int y, int frm); + int seq_introDragon(WSAMovie_v2 *wsaObj, int x, int y, int frm); + int seq_introDarm(WSAMovie_v2 *wsaObj, int x, int y, int frm); + int seq_introLibrary2(WSAMovie_v2 *wsaObj, int x, int y, int frm); + int seq_introMarco(WSAMovie_v2 *wsaObj, int x, int y, int frm); + int seq_introHand1a(WSAMovie_v2 *wsaObj, int x, int y, int frm); + int seq_introHand1b(WSAMovie_v2 *wsaObj, int x, int y, int frm); + int seq_introHand1c(WSAMovie_v2 *wsaObj, int x, int y, int frm); + int seq_introHand2(WSAMovie_v2 *wsaObj, int x, int y, int frm); + int seq_introHand3(WSAMovie_v2 *wsaObj, int x, int y, int frm); + + int seq_finaleFunters(WSAMovie_v2 *wsaObj, int x, int y, int frm); + int seq_finaleFerb(WSAMovie_v2 *wsaObj, int x, int y, int frm); + int seq_finaleFish(WSAMovie_v2 *wsaObj, int x, int y, int frm); + int seq_finaleFheep(WSAMovie_v2 *wsaObj, int x, int y, int frm); + int seq_finaleFarmer(WSAMovie_v2 *wsaObj, int x, int y, int frm); + int seq_finaleFuards(WSAMovie_v2 *wsaObj, int x, int y, int frm); + int seq_finaleFirates(WSAMovie_v2 *wsaObj, int x, int y, int frm); + int seq_finaleFrash(WSAMovie_v2 *wsaObj, int x, int y, int frm); + + int seq_finaleFiggle(WSAMovie_v2 *wsaObj, int x, int y, int frm); + + int seq_demoVirgin(WSAMovie_v2 *wsaObj, int x, int y, int frm); + int seq_demoWestwood(WSAMovie_v2 *wsaObj, int x, int y, int frm); + int seq_demoTitle(WSAMovie_v2 *wsaObj, int x, int y, int frm); + int seq_demoHill(WSAMovie_v2 *wsaObj, int x, int y, int frm); + int seq_demoOuthome(WSAMovie_v2 *wsaObj, int x, int y, int frm); + int seq_demoWharf(WSAMovie_v2 *wsaObj, int x, int y, int frm); + int seq_demoDinob(WSAMovie_v2 *wsaObj, int x, int y, int frm); + int seq_demoFisher(WSAMovie_v2 *wsaObj, int x, int y, int frm); + + int seq_demoWharf2(WSAMovie_v2 *wsaObj, int x, int y, int frm); + int seq_demoDinob2(WSAMovie_v2 *wsaObj, int x, int y, int frm); + int seq_demoWater(WSAMovie_v2 *wsaObj, int x, int y, int frm); + int seq_demoBail(WSAMovie_v2 *wsaObj, int x, int y, int frm); + int seq_demoDig(WSAMovie_v2 *wsaObj, int x, int y, int frm); void seq_sequenceCommand(int command); void seq_loadNestedSequence(int wsaNum, int seqNum); @@ -259,7 +259,7 @@ protected: char *seq_preprocessString(const char *str, int width); void seq_printCreditsString(uint16 strIndex, int x, int y, const uint8 *colorMap, uint8 textcolor); void seq_playWsaSyncDialogue(uint16 strIndex, uint16 vocIndex, int textColor, int x, int y, int width, - WSAMovieV2 * wsa, int firstframe, int lastframe, int wsaXpos, int wsaYpos); + WSAMovie_v2 * wsa, int firstframe, int lastframe, int wsaXpos, int wsaYpos); void seq_finaleActorScreen(); void seq_displayScrollText(uint8 *data, const ScreenDim *d, int tempPage1, int tempPage2, int speed, int step, Screen::FontId fid1, Screen::FontId fid2, const uint8 *shapeData = 0, const char *const *specialData = 0); void seq_scrollPage(); @@ -330,7 +330,7 @@ protected: uint8 *_sceneShapeTable[50]; - WSAMovieV2 *_wsaSlots[10]; + WSAMovie_v2 *_wsaSlots[10]; void freeSceneShapePtrs(); @@ -667,7 +667,7 @@ protected: int delay; bool running; uint32 timer; - WSAMovieV2 *wsa; + WSAMovie_v2 *wsa; } _invWsa; // TODO: move inside KyraEngine_HoF::InventoryWsa? @@ -854,7 +854,7 @@ protected: static const uint8 _seqTextColorPresets[]; char *_seqProcessedString; - WSAMovieV2 *_seqWsa; + WSAMovie_v2 *_seqWsa; bool _abortIntroFlag; int _menuChoice; diff --git a/engines/kyra/kyra_lok.cpp b/engines/kyra/kyra_lok.cpp new file mode 100644 index 0000000000..175a635157 --- /dev/null +++ b/engines/kyra/kyra_lok.cpp @@ -0,0 +1,1044 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "kyra/kyra_lok.h" + +#include "common/file.h" +#include "common/events.h" +#include "common/system.h" +#include "common/savefile.h" + +#include "gui/message.h" + +#include "kyra/resource.h" +#include "kyra/screen.h" +#include "kyra/script.h" +#include "kyra/seqplayer.h" +#include "kyra/sound.h" +#include "kyra/sprites.h" +#include "kyra/wsamovie.h" +#include "kyra/animator_lok.h" +#include "kyra/text.h" +#include "kyra/debugger.h" +#include "kyra/timer.h" + +namespace Kyra { + +KyraEngine_LoK::KyraEngine_LoK(OSystem *system, const GameFlags &flags) + : KyraEngine(system, flags) { + _skipFlag = false; + + _seq_Forest = _seq_KallakWriting = _seq_KyrandiaLogo = _seq_KallakMalcolm = + _seq_MalcolmTree = _seq_WestwoodLogo = _seq_Demo1 = _seq_Demo2 = _seq_Demo3 = + _seq_Demo4 = 0; + + _seq_WSATable = _seq_CPSTable = _seq_COLTable = _seq_textsTable = 0; + _seq_WSATable_Size = _seq_CPSTable_Size = _seq_COLTable_Size = _seq_textsTable_Size = 0; + + _roomFilenameTable = _characterImageTable = 0; + _roomFilenameTableSize = _characterImageTableSize = 0; + _itemList = _takenList = _placedList = _droppedList = _noDropList = 0; + _itemList_Size = _takenList_Size = _placedList_Size = _droppedList_Size = _noDropList_Size = 0; + _putDownFirst = _waitForAmulet = _blackJewel = _poisonGone = _healingTip = 0; + _putDownFirst_Size = _waitForAmulet_Size = _blackJewel_Size = _poisonGone_Size = _healingTip_Size = 0; + _thePoison = _fluteString = _wispJewelStrings = _magicJewelString = _flaskFull = _fullFlask = 0; + _thePoison_Size = _fluteString_Size = _wispJewelStrings_Size = 0; + _magicJewelString_Size = _flaskFull_Size = _fullFlask_Size = 0; + + _defaultShapeTable = 0; + _healingShapeTable = _healingShape2Table = 0; + _defaultShapeTableSize = _healingShapeTableSize = _healingShape2TableSize = 0; + _posionDeathShapeTable = _fluteAnimShapeTable = 0; + _posionDeathShapeTableSize = _fluteAnimShapeTableSize = 0; + _winterScrollTable = _winterScroll1Table = _winterScroll2Table = 0; + _winterScrollTableSize = _winterScroll1TableSize = _winterScroll2TableSize = 0; + _drinkAnimationTable = _brandonToWispTable = _magicAnimationTable = _brandonStoneTable = 0; + _drinkAnimationTableSize = _brandonToWispTableSize = _magicAnimationTableSize = _brandonStoneTableSize = 0; + memset(&_specialPalettes, 0, sizeof(_specialPalettes)); + _sprites = 0; + _animator = 0; + _seq = 0; + _characterList = 0; + _movFacingTable = 0; + _buttonData = 0; + _buttonDataListPtr = 0; + memset(_shapes, 0, sizeof(_shapes)); + memset(_movieObjects, 0, sizeof(_movieObjects)); + _finalA = _finalB = _finalC = 0; + _endSequenceBackUpRect = 0; + memset(_panPagesTable, 0, sizeof(_panPagesTable)); + memset(_sceneAnimTable, 0, sizeof(_sceneAnimTable)); + _currHeadShape = 0; + + memset(&_itemBkgBackUp, 0, sizeof(_itemBkgBackUp)); +} + +KyraEngine_LoK::~KyraEngine_LoK() { + for (int i = 0; i < ARRAYSIZE(_movieObjects); ++i) { + if (_movieObjects[i]) + _movieObjects[i]->close(); + delete _movieObjects[i]; + _movieObjects[i] = 0; + } + + closeFinalWsa(); + if (_emc) { + _emc->unload(&_npcScriptData); + _emc->unload(&_scriptClickData); + } + + Common::clearAllSpecialDebugLevels(); + + delete _screen; + delete _sprites; + delete _animator; + delete _seq; + + delete[] _characterList; + + delete[] _movFacingTable; + + delete[] _gui->_scrollUpButton.data0ShapePtr; + delete[] _gui->_scrollUpButton.data1ShapePtr; + delete[] _gui->_scrollUpButton.data2ShapePtr; + delete[] _gui->_scrollDownButton.data0ShapePtr; + delete[] _gui->_scrollDownButton.data1ShapePtr; + delete[] _gui->_scrollDownButton.data2ShapePtr; + + delete[] _buttonData; + delete[] _buttonDataListPtr; + + delete _gui; + + delete[] _itemBkgBackUp[0]; + delete[] _itemBkgBackUp[1]; + + for (int i = 0; i < ARRAYSIZE(_shapes); ++i) { + if (_shapes[i] != 0) { + delete[] _shapes[i]; + for (int i2 = 0; i2 < ARRAYSIZE(_shapes); i2++) { + if (_shapes[i2] == _shapes[i] && i2 != i) { + _shapes[i2] = 0; + } + } + _shapes[i] = 0; + } + } + + for (int i = 0; i < ARRAYSIZE(_sceneAnimTable); ++i) + delete[] _sceneAnimTable[i]; +} + +int KyraEngine_LoK::init() { + _screen = new Screen_LoK(this, _system); + assert(_screen); + _screen->setResolution(); + + KyraEngine::init(); + + _sprites = new Sprites(this, _system); + assert(_sprites); + _seq = new SeqPlayer(this, _system); + assert(_seq); + _animator = new Animator_LoK(this, _system); + assert(_animator); + _animator->init(5, 11, 12); + assert(*_animator); + _text = new TextDisplayer(this, screen()); + assert(_text); + _gui = new GUI_LoK(this, _screen); + assert(_gui); + + initStaticResource(); + + _sound->setSoundList(&_soundData[kMusicIntro]); + + _trackMap = _dosTrackMap; + _trackMapSize = _dosTrackMapSize; + + if (!_sound->init()) + error("Couldn't init sound"); + + _sound->loadSoundFile(0); + + setupButtonData(); + + _paletteChanged = 1; + _currentCharacter = 0; + _characterList = new Character[11]; + assert(_characterList); + memset(_characterList, 0, sizeof(Character)*11); + + for (int i = 0; i < 11; ++i) + memset(_characterList[i].inventoryItems, 0xFF, sizeof(_characterList[i].inventoryItems)); + + _characterList[0].sceneId = 5; + _characterList[0].height = 48; + _characterList[0].facing = 3; + _characterList[0].currentAnimFrame = 7; + + memset(&_npcScriptData, 0, sizeof(EMCData)); + memset(&_scriptClickData, 0, sizeof(EMCData)); + + memset(&_npcScript, 0, sizeof(EMCState)); + memset(&_scriptMain, 0, sizeof(EMCState)); + memset(&_scriptClick, 0, sizeof(EMCState)); + + _debugger = new Debugger_LoK(this); + assert(_debugger); + memset(_shapes, 0, sizeof(_shapes)); + + for (int i = 0; i < ARRAYSIZE(_movieObjects); ++i) + _movieObjects[i] = createWSAMovie(); + + memset(_flagsTable, 0, sizeof(_flagsTable)); + + _abortWalkFlag = false; + _abortWalkFlag2 = false; + _talkingCharNum = -1; + _charSayUnk3 = -1; + memset(_currSentenceColor, 0, 3); + _startSentencePalIndex = -1; + _fadeText = false; + + _cauldronState = 0; + _crystalState[0] = _crystalState[1] = -1; + + _brandonStatusBit = 0; + _brandonStatusBit0x02Flag = _brandonStatusBit0x20Flag = 10; + _brandonPosX = _brandonPosY = -1; + _deathHandler = 0xFF; + _poisonDeathCounter = 0; + + memset(_itemTable, 0, sizeof(_itemTable)); + memset(_exitList, 0xFFFF, sizeof(_exitList)); + _exitListPtr = 0; + _pathfinderFlag = _pathfinderFlag2 = 0; + _lastFindWayRet = 0; + _sceneChangeState = _loopFlag2 = 0; + + _movFacingTable = new int[150]; + assert(_movFacingTable); + _movFacingTable[0] = 8; + + _skipFlag = false; + + _marbleVaseItem = -1; + memset(_foyerItemTable, -1, sizeof(_foyerItemTable)); + _mouseState = _itemInHand = -1; + _handleInput = false; + + _currentRoom = 0xFFFF; + _scenePhasingFlag = 0; + _lastProcessedItem = 0; + _lastProcessedItemHeight = 16; + + _unkScreenVar1 = 1; + _unkScreenVar2 = 0; + _unkScreenVar3 = 0; + _unkAmuletVar = 0; + + _endSequenceNeedLoading = 1; + _malcolmFlag = 0; + _beadStateVar = 0; + _endSequenceSkipFlag = 0; + _unkEndSeqVar2 = 0; + _endSequenceBackUpRect = 0; + _unkEndSeqVar4 = 0; + _unkEndSeqVar5 = 0; + _lastDisplayedPanPage = 0; + memset(_panPagesTable, 0, sizeof(_panPagesTable)); + _finalA = _finalB = _finalC = 0; + memset(&_kyragemFadingState, 0, sizeof(_kyragemFadingState)); + _kyragemFadingState.gOffset = 0x13; + _kyragemFadingState.bOffset = 0x13; + + _mousePressFlag = false; + + _menuDirectlyToLoad = false; + + _lastMusicCommand = 0; + + return 0; +} + +int KyraEngine_LoK::go() { + if (_res->getFileSize("6.FNT")) + _screen->loadFont(Screen::FID_6_FNT, "6.FNT"); + _screen->loadFont(Screen::FID_8_FNT, "8FAT.FNT"); + _screen->setScreenDim(0); + + _abortIntroFlag = false; + + if (_flags.isDemo) { + seq_demo(); + } else { + setGameFlag(0xF3); + setGameFlag(0xFD); + if (_gameToLoad == -1) { + setGameFlag(0xEF); + seq_intro(); + if (_quitFlag) + return 0; + if (_skipIntroFlag && _abortIntroFlag) + resetGameFlag(0xEF); + } + startup(); + resetGameFlag(0xEF); + mainLoop(); + } + return 0; +} + + +void KyraEngine_LoK::startup() { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::startup()"); + static const uint8 colorMap[] = { 0, 0, 0, 0, 12, 12, 12, 0, 0, 0, 0, 0 }; + _screen->setTextColorMap(colorMap); + _sound->setSoundList(&_soundData[kMusicIngame]); + _sound->loadSoundFile(0); +// _screen->setFont(Screen::FID_6_FNT); + _screen->setAnimBlockPtr(3750); + memset(_sceneAnimTable, 0, sizeof(_sceneAnimTable)); + loadMouseShapes(); + _currentCharacter = &_characterList[0]; + for (int i = 1; i < 5; ++i) + _animator->setCharacterDefaultFrame(i); + for (int i = 5; i <= 10; ++i) + setCharactersPositions(i); + _animator->setCharactersHeight(); + resetBrandonPoisonFlags(); + _screen->_curPage = 0; + // XXX + for (int i = 0; i < 12; ++i) { + int size = _screen->getRectSize(3, 24); + _shapes[361+i] = new byte[size]; + } + + _itemBkgBackUp[0] = new uint8[_screen->getRectSize(3, 24)]; + memset(_itemBkgBackUp[0], 0, _screen->getRectSize(3, 24)); + _itemBkgBackUp[1] = new uint8[_screen->getRectSize(4, 32)]; + memset(_itemBkgBackUp[1], 0, _screen->getRectSize(4, 32)); + + for (int i = 0; i < _roomTableSize; ++i) { + for (int item = 0; item < 12; ++item) { + _roomTable[i].itemsTable[item] = 0xFF; + _roomTable[i].itemsXPos[item] = 0xFFFF; + _roomTable[i].itemsYPos[item] = 0xFF; + _roomTable[i].needInit[item] = 0; + } + } + + loadCharacterShapes(); + loadSpecialEffectShapes(); + loadItems(); + loadButtonShapes(); + initMainButtonList(); + loadMainScreen(); + _screen->loadPalette("PALETTE.COL", _screen->_currentPalette); + + // XXX + _animator->initAnimStateList(); + setCharactersInDefaultScene(); + + if (!_emc->load("_STARTUP.EMC", &_npcScriptData, &_opcodes)) + error("Could not load \"_STARTUP.EMC\" script"); + _emc->init(&_scriptMain, &_npcScriptData); + + if (!_emc->start(&_scriptMain, 0)) + error("Could not start script function 0 of script \"_STARTUP.EMC\""); + + while (_emc->isValid(&_scriptMain)) + _emc->run(&_scriptMain); + + _emc->unload(&_npcScriptData); + + if (!_emc->load("_NPC.EMC", &_npcScriptData, &_opcodes)) + error("Could not load \"_NPC.EMC\" script"); + + snd_playTheme(1, -1); + if (_gameToLoad == -1) { + enterNewScene(_currentCharacter->sceneId, _currentCharacter->facing, 0, 0, 1); + if (_abortIntroFlag && _skipIntroFlag) { + _menuDirectlyToLoad = true; + _screen->setMouseCursor(1, 1, _shapes[0]); + _screen->showMouse(); + _gui->buttonMenuCallback(0); + _menuDirectlyToLoad = false; + } else + saveGame(getSavegameFilename(0), "New game"); + } else { + _screen->setFont(Screen::FID_8_FNT); + loadGame(getSavegameFilename(_gameToLoad)); + _gameToLoad = -1; + } +} + +void KyraEngine_LoK::mainLoop() { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::mainLoop()"); + + while (!_quitFlag) { + int32 frameTime = (int32)_system->getMillis(); + _skipFlag = false; + + if (_currentCharacter->sceneId == 210) { + updateKyragemFading(); + if (seq_playEnd() && _deathHandler != 8) + break; + } + + if (_deathHandler != 0xFF) { + snd_playWanderScoreViaMap(0, 1); + snd_playSoundEffect(49); + _screen->hideMouse(); + _screen->setMouseCursor(1, 1, _shapes[0]); + destroyMouseItem(); + _screen->showMouse(); + _gui->buttonMenuCallback(0); + _deathHandler = 0xFF; + } + + if ((_brandonStatusBit & 2) && _brandonStatusBit0x02Flag) + _animator->animRefreshNPC(0); + + if ((_brandonStatusBit & 0x20) && _brandonStatusBit0x20Flag) { + _animator->animRefreshNPC(0); + _brandonStatusBit0x20Flag = 0; + } + + _screen->showMouse(); + + _gui->processButtonList(_buttonList, 0, 0); + updateMousePointer(); + _timer->update(); + updateTextFade(); + + _handleInput = true; + delay((frameTime + _gameSpeed) - _system->getMillis(), true, true); + _handleInput = false; + + _sound->process(); + } +} + +void KyraEngine_LoK::delayUntil(uint32 timestamp, bool updateTimers, bool update, bool isMainLoop) { + while (_system->getMillis() < timestamp && !_quitFlag) { + if (updateTimers) + _timer->update(); + + if (timestamp - _system->getMillis() >= 10) + delay(10, update, isMainLoop); + } +} + +void KyraEngine_LoK::delay(uint32 amount, bool update, bool isMainLoop) { + Common::Event event; + + uint32 start = _system->getMillis(); + do { + while (_eventMan->pollEvent(event)) { + switch (event.type) { + case Common::EVENT_KEYDOWN: + if (event.kbd.keycode >= '1' && event.kbd.keycode <= '9' && + (event.kbd.flags == Common::KBD_CTRL || event.kbd.flags == Common::KBD_ALT) && isMainLoop) { + const char *saveLoadSlot = getSavegameFilename(9 - (event.kbd.keycode - '0') + 990); + + if (event.kbd.flags == Common::KBD_CTRL) + loadGame(saveLoadSlot); + else { + char savegameName[14]; + sprintf(savegameName, "Quicksave %d", event.kbd.keycode - '0'); + saveGame(saveLoadSlot, savegameName); + } + } else if (event.kbd.flags == Common::KBD_CTRL) { + if (event.kbd.keycode == 'd') + _debugger->attach(); + else if (event.kbd.keycode == 'q') + _quitFlag = true; + } else if (event.kbd.keycode == '.') { + _skipFlag = true; + } else if (event.kbd.keycode == Common::KEYCODE_RETURN || event.kbd.keycode == Common::KEYCODE_SPACE || event.kbd.keycode == Common::KEYCODE_ESCAPE) { + _abortIntroFlag = true; + _skipFlag = true; + } + + break; + case Common::EVENT_MOUSEMOVE: + _animator->_updateScreen = true; + break; + case Common::EVENT_QUIT: + quitGame(); + break; + case Common::EVENT_LBUTTONDOWN: + _mousePressFlag = true; + break; + case Common::EVENT_LBUTTONUP: + _mousePressFlag = false; + + if (_abortWalkFlag2) + _abortWalkFlag = true; + + if (_handleInput) { + _handleInput = false; + processInput(); + _handleInput = true; + } else + _skipFlag = true; + + break; + default: + break; + } + } + + if (_debugger->isAttached()) + _debugger->onFrame(); + + if (update) { + _sprites->updateSceneAnims(); + _animator->updateAllObjectShapes(); + updateTextFade(); + updateMousePointer(); + } + + if (_currentCharacter && _currentCharacter->sceneId == 210 && update) + updateKyragemFading(); + + if (_skipFlag && !_abortIntroFlag && !queryGameFlag(0xFE)) + _skipFlag = false; + + if (amount > 0 && !_skipFlag && !_quitFlag) + _system->delayMillis(10); + + if (_skipFlag) + _sound->voiceStop(); + } while (!_skipFlag && _system->getMillis() < start + amount && !_quitFlag); +} + +void KyraEngine_LoK::waitForEvent() { + bool finished = false; + Common::Event event; + + while (!finished && !_quitFlag) { + while (_eventMan->pollEvent(event)) { + switch (event.type) { + case Common::EVENT_KEYDOWN: + finished = true; + break; + case Common::EVENT_QUIT: + quitGame(); + break; + case Common::EVENT_LBUTTONDOWN: + finished = true; + _skipFlag = true; + break; + default: + break; + } + } + + if (_debugger->isAttached()) + _debugger->onFrame(); + + _system->delayMillis(10); + } +} + +void KyraEngine_LoK::delayWithTicks(int ticks) { + uint32 nextTime = _system->getMillis() + ticks * _tickLength; + + while (_system->getMillis() < nextTime) { + _sprites->updateSceneAnims(); + _animator->updateAllObjectShapes(); + + if (_currentCharacter->sceneId == 210) { + updateKyragemFading(); + seq_playEnd(); + } + + if (_skipFlag) + break; + + if (nextTime - _system->getMillis() >= 10) + delay(10); + } +} + +#pragma mark - +#pragma mark - Animation/shape specific code +#pragma mark - + +void KyraEngine_LoK::setupShapes123(const Shape *shapeTable, int endShape, int flags) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::setupShapes123(%p, %d, %d)", (const void *)shapeTable, endShape, flags); + + for (int i = 123; i <= 172; ++i) + _shapes[i] = 0; + + uint8 curImage = 0xFF; + int curPageBackUp = _screen->_curPage; + _screen->_curPage = 8; // we are using page 8 here in the original page 2 was backuped and then used for this stuff + int shapeFlags = 2; + if (flags) + shapeFlags = 3; + for (int i = 123; i < 123+endShape; ++i) { + uint8 newImage = shapeTable[i-123].imageIndex; + if (newImage != curImage && newImage != 0xFF) { + assert(_characterImageTable); + _screen->loadBitmap(_characterImageTable[newImage], 8, 8, 0); + curImage = newImage; + } + _shapes[i] = _screen->encodeShape(shapeTable[i-123].x<<3, shapeTable[i-123].y, shapeTable[i-123].w<<3, shapeTable[i-123].h, shapeFlags); + assert(i-7 < _defaultShapeTableSize); + _defaultShapeTable[i-7].xOffset = shapeTable[i-123].xOffset; + _defaultShapeTable[i-7].yOffset = shapeTable[i-123].yOffset; + _defaultShapeTable[i-7].w = shapeTable[i-123].w; + _defaultShapeTable[i-7].h = shapeTable[i-123].h; + } + _screen->_curPage = curPageBackUp; +} + +void KyraEngine_LoK::freeShapes123() { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::freeShapes123()"); + + for (int i = 123; i <= 172; ++i) { + delete[] _shapes[i]; + _shapes[i] = 0; + } +} + +#pragma mark - +#pragma mark - Misc stuff +#pragma mark - + +Movie *KyraEngine_LoK::createWSAMovie() { + if (_flags.platform == Common::kPlatformAmiga) + return new WSAMovieAmiga(this); + + return new WSAMovie_v1(this); +} + +void KyraEngine_LoK::setBrandonPoisonFlags(int reset) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::setBrandonPoisonFlags(%d)", reset); + _brandonStatusBit |= 1; + + if (reset) + _poisonDeathCounter = 0; + + for (int i = 0; i < 0x100; ++i) + _brandonPoisonFlagsGFX[i] = i; + + _brandonPoisonFlagsGFX[0x99] = 0x34; + _brandonPoisonFlagsGFX[0x9A] = 0x35; + _brandonPoisonFlagsGFX[0x9B] = 0x37; + _brandonPoisonFlagsGFX[0x9C] = 0x38; + _brandonPoisonFlagsGFX[0x9D] = 0x2B; +} + +void KyraEngine_LoK::resetBrandonPoisonFlags() { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::resetBrandonPoisonFlags()"); + _brandonStatusBit = 0; + + for (int i = 0; i < 0x100; ++i) + _brandonPoisonFlagsGFX[i] = i; +} + +#pragma mark - +#pragma mark - Input +#pragma mark - + +void KyraEngine_LoK::processInput() { + Common::Point mouse = getMousePos(); + int xpos = mouse.x; + int ypos = mouse.y; + + debugC(9, kDebugLevelMain, "KyraEngine_LoK::processInput(%d, %d)", xpos, ypos); + _abortWalkFlag2 = false; + + if (processInputHelper(xpos, ypos)) + return; + + uint8 item = findItemAtPos(xpos, ypos); + if (item == 0xFF) { + _changedScene = false; + int handled = clickEventHandler(xpos, ypos); + if (_changedScene || handled) + return; + } + + // XXX _deathHandler specific + if (ypos <= 158) { + uint16 exit = 0xFFFF; + if (xpos < 12) { + exit = _walkBlockWest; + } else if (xpos >= 308) { + exit = _walkBlockEast; + } else if (ypos >= 136) { + exit = _walkBlockSouth; + } else if (ypos < 12) { + exit = _walkBlockNorth; + } + + if (exit != 0xFFFF) { + _abortWalkFlag2 = true; + handleSceneChange(xpos, ypos, 1, 1); + _abortWalkFlag2 = false; + return; + } else { + int script = checkForNPCScriptRun(xpos, ypos); + if (script >= 0) { + runNpcScript(script); + return; + } + if (_itemInHand != -1) { + if (ypos < 155) { + if (hasClickedOnExit(xpos, ypos)) { + _abortWalkFlag2 = true; + handleSceneChange(xpos, ypos, 1, 1); + _abortWalkFlag2 = false; + return; + } + dropItem(0, _itemInHand, xpos, ypos, 1); + } + } else { + if (ypos <= 155) { + _abortWalkFlag2 = true; + handleSceneChange(xpos, ypos, 1, 1); + _abortWalkFlag2 = false; + } + } + } + } +} + +int KyraEngine_LoK::processInputHelper(int xpos, int ypos) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::processInputHelper(%d, %d)", xpos, ypos); + uint8 item = findItemAtPos(xpos, ypos); + if (item != 0xFF) { + if (_itemInHand == -1) { + _screen->hideMouse(); + _animator->animRemoveGameItem(item); + snd_playSoundEffect(53); + assert(_currentCharacter->sceneId < _roomTableSize); + Room *currentRoom = &_roomTable[_currentCharacter->sceneId]; + int item2 = currentRoom->itemsTable[item]; + currentRoom->itemsTable[item] = 0xFF; + setMouseItem(item2); + assert(_itemList && _takenList); + updateSentenceCommand(_itemList[item2], _takenList[0], 179); + _itemInHand = item2; + _screen->showMouse(); + clickEventHandler2(); + return 1; + } else { + exchangeItemWithMouseItem(_currentCharacter->sceneId, item); + return 1; + } + } + return 0; +} + +int KyraEngine_LoK::clickEventHandler(int xpos, int ypos) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::clickEventHandler(%d, %d)", xpos, ypos); + _emc->init(&_scriptClick, &_scriptClickData); + _scriptClick.regs[1] = xpos; + _scriptClick.regs[2] = ypos; + _scriptClick.regs[3] = 0; + _scriptClick.regs[4] = _itemInHand; + _emc->start(&_scriptClick, 1); + + while (_emc->isValid(&_scriptClick)) + _emc->run(&_scriptClick); + + return _scriptClick.regs[3]; +} + +void KyraEngine_LoK::updateMousePointer(bool forceUpdate) { + int shape = 0; + + int newMouseState = 0; + int newX = 0; + int newY = 0; + Common::Point mouse = getMousePos(); + if (mouse.y <= 158) { + if (mouse.x >= 12) { + if (mouse.x >= 308) { + if (_walkBlockEast == 0xFFFF) { + newMouseState = -2; + } else { + newMouseState = -5; + shape = 3; + newX = 7; + newY = 5; + } + } else if (mouse.y >= 136) { + if (_walkBlockSouth == 0xFFFF) { + newMouseState = -2; + } else { + newMouseState = -4; + shape = 4; + newX = 5; + newY = 7; + } + } else if (mouse.y < 12) { + if (_walkBlockNorth == 0xFFFF) { + newMouseState = -2; + } else { + newMouseState = -6; + shape = 2; + newX = 5; + newY = 1; + } + } + } else { + if (_walkBlockWest == 0xFFFF) { + newMouseState = -2; + } else { + newMouseState = -3; + newX = 1; + newY = shape = 5; + } + } + } + + if (mouse.x >= _entranceMouseCursorTracks[0] && mouse.y >= _entranceMouseCursorTracks[1] + && mouse.x <= _entranceMouseCursorTracks[2] && mouse.y <= _entranceMouseCursorTracks[3]) { + switch (_entranceMouseCursorTracks[4]) { + case 0: + newMouseState = -6; + shape = 2; + newX = 5; + newY = 1; + break; + + case 2: + newMouseState = -5; + shape = 3; + newX = 7; + newY = 5; + break; + + case 4: + newMouseState = -4; + shape = 4; + newX = 5; + newY = 7; + break; + + case 6: + newMouseState = -3; + shape = 5; + newX = 1; + newY = 5; + break; + + default: + break; + } + } + + if (newMouseState == -2) { + shape = 6; + newX = 4; + newY = 4; + } + + if ((newMouseState && _mouseState != newMouseState) || (newMouseState && forceUpdate)) { + _mouseState = newMouseState; + _screen->hideMouse(); + _screen->setMouseCursor(newX, newY, _shapes[shape]); + _screen->showMouse(); + } + + if (!newMouseState) { + if (_mouseState != _itemInHand || forceUpdate) { + if (mouse.y > 158 || (mouse.x >= 12 && mouse.x < 308 && mouse.y < 136 && mouse.y >= 12) || forceUpdate) { + _mouseState = _itemInHand; + _screen->hideMouse(); + if (_itemInHand == -1) + _screen->setMouseCursor(1, 1, _shapes[0]); + else + _screen->setMouseCursor(8, 15, _shapes[216+_itemInHand]); + _screen->showMouse(); + } + } + } +} + +bool KyraEngine_LoK::hasClickedOnExit(int xpos, int ypos) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::hasClickedOnExit(%d, %d)", xpos, ypos); + if (xpos < 16 || xpos >= 304) + return true; + + if (ypos < 8) + return true; + + if (ypos < 136 || ypos > 155) + return false; + + return true; +} + +void KyraEngine_LoK::clickEventHandler2() { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::clickEventHandler2()"); + + Common::Point mouse = getMousePos(); + + _emc->init(&_scriptClick, &_scriptClickData); + _scriptClick.regs[0] = _currentCharacter->sceneId; + _scriptClick.regs[1] = mouse.x; + _scriptClick.regs[2] = mouse.y; + _scriptClick.regs[4] = _itemInHand; + _emc->start(&_scriptClick, 6); + + while (_emc->isValid(&_scriptClick)) + _emc->run(&_scriptClick); +} + +int KyraEngine_LoK::checkForNPCScriptRun(int xpos, int ypos) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::checkForNPCScriptRun(%d, %d)", xpos, ypos); + int returnValue = -1; + const Character *currentChar = _currentCharacter; + int charLeft = 0, charRight = 0, charTop = 0, charBottom = 0; + + int scaleFactor = _scaleTable[currentChar->y1]; + int addX = (((scaleFactor*8)*3)>>8)>>1; + int addY = ((scaleFactor*3)<<4)>>8; + + charLeft = currentChar->x1 - addX; + charRight = currentChar->x1 + addX; + charTop = currentChar->y1 - addY; + charBottom = currentChar->y1; + + if (xpos >= charLeft && charRight >= xpos && charTop <= ypos && charBottom >= ypos) + return 0; + + if (xpos > 304 || xpos < 16) + return -1; + + for (int i = 1; i < 5; ++i) { + currentChar = &_characterList[i]; + + if (currentChar->sceneId != _currentCharacter->sceneId) + continue; + + charLeft = currentChar->x1 - 12; + charRight = currentChar->x1 + 11; + charTop = currentChar->y1 - 48; + // if (!i) + // charBottom = currentChar->y2 - 16; + // else + charBottom = currentChar->y1; + + if (xpos < charLeft || xpos > charRight || ypos < charTop || charBottom < ypos) + continue; + + if (returnValue != -1) { + if (currentChar->y1 >= _characterList[returnValue].y1) + returnValue = i; + } else { + returnValue = i; + } + } + + return returnValue; +} + +void KyraEngine_LoK::runNpcScript(int func) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::runNpcScript(%d)", func); + _emc->init(&_npcScript, &_npcScriptData); + _emc->start(&_npcScript, func); + _npcScript.regs[0] = _currentCharacter->sceneId; + _npcScript.regs[4] = _itemInHand; + _npcScript.regs[5] = func; + + while (_emc->isValid(&_npcScript)) + _emc->run(&_npcScript); +} + +void KyraEngine_LoK::checkAmuletAnimFlags() { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::checkSpecialAnimFlags()"); + + if (_brandonStatusBit & 2) { + seq_makeBrandonNormal2(); + _timer->setCountdown(19, 300); + } + + if (_brandonStatusBit & 0x20) { + seq_makeBrandonNormal(); + _timer->setCountdown(19, 300); + } +} + +#pragma mark - + +void KyraEngine_LoK::registerDefaultSettings() { + KyraEngine::registerDefaultSettings(); + + // Most settings already have sensible defaults. This one, however, is + // specific to the Kyra engine. + ConfMan.registerDefault("walkspeed", 2); +} + +void KyraEngine_LoK::readSettings() { + int talkspeed = ConfMan.getInt("talkspeed"); + + // The default talk speed is 60. This should be mapped to "Normal". + + if (talkspeed == 0) + _configTextspeed = 3; // Clickable + if (talkspeed <= 50) + _configTextspeed = 0; // Slow + else if (talkspeed <= 150) + _configTextspeed = 1; // Normal + else + _configTextspeed = 2; // Fast + + KyraEngine::readSettings(); +} + +void KyraEngine_LoK::writeSettings() { + int talkspeed; + + switch (_configTextspeed) { + case 0: // Slow + talkspeed = 1; + break; + case 1: // Normal + talkspeed = 60; + break; + case 2: // Fast + talkspeed = 255; + break; + default: // Clickable + talkspeed = 0; + break; + } + + ConfMan.setInt("talkspeed", talkspeed); + + KyraEngine::writeSettings(); +} + +} // end of namespace Kyra diff --git a/engines/kyra/kyra_lok.h b/engines/kyra/kyra_lok.h new file mode 100644 index 0000000000..fe742a1da9 --- /dev/null +++ b/engines/kyra/kyra_lok.h @@ -0,0 +1,819 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#ifndef KYRA_KYRA_V1_H +#define KYRA_KYRA_V1_H + +#include "kyra/kyra.h" +#include "kyra/script.h" +#include "kyra/screen_lok.h" +#include "kyra/gui_lok.h" + +namespace Kyra { + +class Movie; +class SoundDigital; +class SeqPlayer; +class Sprites; +class Animator_LoK; +class TextDisplayer; +class KyraEngine_LoK; + +struct Character { + uint16 sceneId; + uint8 height; + uint8 facing; + uint16 currentAnimFrame; + uint8 inventoryItems[10]; + int16 x1, y1, x2, y2; +}; + +struct Shape { + uint8 imageIndex; + int8 xOffset, yOffset; + uint8 x, y, w, h; +}; + +struct Room { + uint8 nameIndex; + uint16 northExit; + uint16 eastExit; + uint16 southExit; + uint16 westExit; + uint8 itemsTable[12]; + uint16 itemsXPos[12]; + uint8 itemsYPos[12]; + uint8 needInit[12]; +}; + +struct Item { + uint8 unk1; + uint8 height; + uint8 unk2; + uint8 unk3; +}; + +struct SeqLoop { + const uint8 *ptr; + uint16 count; +}; + +struct SceneExits { + uint16 northXPos; + uint8 northYPos; + uint16 eastXPos; + uint8 eastYPos; + uint16 southXPos; + uint8 southYPos; + uint16 westXPos; + uint8 westYPos; +}; + +struct BeadState { + int16 x; + int16 y; + int16 width; + int16 height; + int16 dstX; + int16 dstY; + int16 width2; + int16 unk8; + int16 unk9; + int16 tableIndex; +}; + +class KyraEngine_LoK : public KyraEngine { + friend class MusicPlayer; + friend class Debugger_LoK; + friend class Animator_LoK; + friend class GUI_LoK; +public: + KyraEngine_LoK(OSystem *system, const GameFlags &flags); + ~KyraEngine_LoK(); + + Screen *screen() { return _screen; } + Animator_LoK *animator() { return _animator; } + virtual Movie *createWSAMovie(); + + uint8 **shapes() { return _shapes; } + Character *currentCharacter() { return _currentCharacter; } + Character *characterList() { return _characterList; } + uint16 brandonStatus() { return _brandonStatusBit; } + + // TODO: remove me with workaround in animator.cpp l209 + uint16 getScene() { return _currentRoom; } + + int _paletteChanged; + int16 _northExitHeight; + + typedef void (KyraEngine_LoK::*IntroProc)(); + + // static data access + const char * const*seqWSATable() { return _seq_WSATable; } + const char * const*seqCPSTable() { return _seq_CPSTable; } + const char * const*seqCOLTable() { return _seq_COLTable; } + const char * const*seqTextsTable() { return _seq_textsTable; } + + const uint8 * const*palTable1() { return &_specialPalettes[0]; } + const uint8 * const*palTable2() { return &_specialPalettes[29]; } + +protected: + virtual int go(); + virtual int init(); + +public: + // sequences + // -> misc + bool seq_skipSequence() const; +protected: + // -> demo + void seq_demo(); + + // -> intro + void seq_intro(); + void seq_introLogos(); + void seq_introStory(); + void seq_introMalcolmTree(); + void seq_introKallakWriting(); + void seq_introKallakMalcolm(); + + // -> ingame animations + void seq_createAmuletJewel(int jewel, int page, int noSound, int drawOnly); + void seq_brandonHealing(); + void seq_brandonHealing2(); + void seq_poisonDeathNow(int now); + void seq_poisonDeathNowAnim(); + void seq_playFluteAnimation(); + void seq_winterScroll1(); + void seq_winterScroll2(); + void seq_makeBrandonInv(); + void seq_makeBrandonNormal(); + void seq_makeBrandonNormal2(); + void seq_makeBrandonWisp(); + void seq_dispelMagicAnimation(); + void seq_fillFlaskWithWater(int item, int type); + void seq_playDrinkPotionAnim(int item, int unk2, int flags); + void seq_brandonToStone(); + + // -> end fight + int seq_playEnd(); + void seq_playEnding(); + + int handleMalcolmFlag(); + int handleBeadState(); + void initBeadState(int x, int y, int x2, int y2, int unk1, BeadState *ptr); + int processBead(int x, int y, int &x2, int &y2, BeadState *ptr); + + // -> credits + void seq_playCredits(); + +public: + // delay + void delayUntil(uint32 timestamp, bool updateGameTimers = false, bool update = false, bool isMainLoop = false); + void delay(uint32 millis, bool update = false, bool isMainLoop = false); + void delayWithTicks(int ticks); + void waitForEvent(); + + // TODO + void registerDefaultSettings(); + void readSettings(); + void writeSettings(); + + void snd_playSoundEffect(int track, int volume=0xFF); + void snd_playWanderScoreViaMap(int command, int restart); + virtual void snd_playVoiceFile(int id); + void snd_voiceWaitForFinish(bool ingame = true); + +protected: + void saveGame(const char *fileName, const char *saveName); + void loadGame(const char *fileName); + +protected: + // input + void processInput(); + int processInputHelper(int xpos, int ypos); + int clickEventHandler(int xpos, int ypos); + void clickEventHandler2(); + void updateMousePointer(bool forceUpdate = false); + bool hasClickedOnExit(int xpos, int ypos); + + bool _skipFlag; + bool skipFlag() const { return _skipFlag; } + void resetSkipFlag(bool removeEvent = true) { _skipFlag = false; } + + // scene + // -> init + void loadSceneMsc(); + void startSceneScript(int brandonAlive); + void setupSceneItems(); + void initSceneData(int facing, int unk1, int brandonAlive); + void initSceneObjectList(int brandonAlive); + void initSceneScreen(int brandonAlive); + void setupSceneResource(int sceneId); + + // -> process + void enterNewScene(int sceneId, int facing, int unk1, int unk2, int brandonAlive); + int handleSceneChange(int xpos, int ypos, int unk1, int frameReset); + int processSceneChange(int *table, int unk1, int frameReset); + int changeScene(int facing); + + // -> modification + void transcendScenes(int roomIndex, int roomName); + void setSceneFile(int roomIndex, int roomName); + + // -> pathfinder + int findWay(int x, int y, int toX, int toY, int *moveTable, int moveTableSize); + bool lineIsPassable(int x, int y); + + // -> item handling + // --> misc + void addItemToRoom(uint16 sceneId, uint8 item, int itemIndex, int x, int y); + + // --> drop handling + void itemDropDown(int x, int y, int destX, int destY, byte freeItem, int item); + int processItemDrop(uint16 sceneId, uint8 item, int x, int y, int unk1, int unk2); + void dropItem(int unk1, int item, int x, int y, int unk2); + + // --> dropped item handling + int countItemsInScene(uint16 sceneId); + void exchangeItemWithMouseItem(uint16 sceneId, int itemIndex); + byte findFreeItemInScene(int scene); + byte findItemAtPos(int x, int y); + + // --> drop area handling + void addToNoDropRects(int x, int y, int w, int h); + void clearNoDropRects(); + int isDropable(int x, int y); + int checkNoDropRects(int x, int y); + + // --> player items handling + void updatePlayerItemsForScene(); + + // --> item GFX handling + void backUpItemRect0(int xpos, int ypos); + void restoreItemRect0(int xpos, int ypos); + void backUpItemRect1(int xpos, int ypos); + void restoreItemRect1(int xpos, int ypos); + + // items + // -> misc + void placeItemInGenericMapScene(int item, int index); + + // -> mouse item + void createMouseItem(int item); + void destroyMouseItem(); + void setMouseItem(int item); + + // -> graphics effects + void wipeDownMouseItem(int xpos, int ypos); + void itemSpecialFX(int x, int y, int item); + void itemSpecialFX1(int x, int y, int item); + void itemSpecialFX2(int x, int y, int item); + void magicOutMouseItem(int animIndex, int itemPos); + void magicInMouseItem(int animIndex, int item, int itemPos); + void specialMouseItemFX(int shape, int x, int y, int animIndex, int tableIndex, int loopStart, int maxLoops); + void processSpecialMouseItemFX(int shape, int x, int y, int tableValue, int loopStart, int maxLoops); + + // character + // -> movement + void moveCharacterToPos(int character, int facing, int xpos, int ypos); + void setCharacterPositionWithUpdate(int character); + int setCharacterPosition(int character, int *facingTable); + void setCharacterPositionHelper(int character, int *facingTable); + void setCharactersPositions(int character); + + // -> brandon + void setBrandonPoisonFlags(int reset); + void resetBrandonPoisonFlags(); + + // chat + // -> process + void characterSays(int vocFile, const char *chatStr, int8 charNum, int8 chatDuration); + void waitForChatToFinish(int vocFile, int16 chatDuration, const char *str, uint8 charNum); + + // -> initialization + int initCharacterChat(int8 charNum); + void backupChatPartnerAnimFrame(int8 charNum); + void restoreChatPartnerAnimFrame(int8 charNum); + int8 getChatPartnerNum(); + + // -> deinitialization + void endCharacterChat(int8 charNum, int16 arg_4); + + // graphics + // -> misc + int findDuplicateItemShape(int shape); + void updateKyragemFading(); + + // -> interface + void loadMainScreen(int page = 3); + void redrawInventory(int page); +public: + void drawSentenceCommand(const char *sentence, int unk1); + void updateSentenceCommand(const char *str1, const char *str2, int unk1); + void updateTextFade(); + +protected: + // -> amulet + void drawJewelPress(int jewel, int drawSpecial); + void drawJewelsFadeOutStart(); + void drawJewelsFadeOutEnd(int jewel); + + // -> shape handling + void setupShapes123(const Shape *shapeTable, int endShape, int flags); + void freeShapes123(); + + // misc (TODO) + void startup(); + void mainLoop(); + + int checkForNPCScriptRun(int xpos, int ypos); + void runNpcScript(int func); + + void loadMouseShapes(); + void loadCharacterShapes(); + void loadSpecialEffectShapes(); + void loadItems(); + void loadButtonShapes(); + void initMainButtonList(); + void setCharactersInDefaultScene(); + void setupPanPages(); + void freePanPages(); + void closeFinalWsa(); + + //void setTimer19(); + void setupTimers(); + void timerUpdateHeadAnims(int timerNum); + void timerSetFlags1(int timerNum); + void timerSetFlags2(int timerNum); + void timerSetFlags3(int timerNum); + void timerCheckAnimFlag1(int timerNum); + void timerCheckAnimFlag2(int timerNum); + void checkAmuletAnimFlags(); + void timerRedrawAmulet(int timerNum); + void timerFadeText(int timerNum); + void updateAnimFlag1(int timerNum); + void updateAnimFlag2(int timerNum); + void drawAmulet(); + void setTextFadeTimerCountdown(int16 countdown); + void setWalkspeed(uint8 newSpeed); + + int buttonInventoryCallback(Button *caller); + int buttonAmuletCallback(Button *caller); + + bool _skipIntroFlag; + bool _abortIntroFlag; + bool _menuDirectlyToLoad; + bool _abortWalkFlag; + bool _abortWalkFlag2; + bool _mousePressFlag; + uint8 *_itemBkgBackUp[2]; + uint8 *_shapes[373]; + int8 _itemInHand; + int _mouseState; + bool _handleInput; + bool _changedScene; + int _unkScreenVar1, _unkScreenVar2, _unkScreenVar3; + int _beadStateVar; + int _unkAmuletVar; + + int _malcolmFlag; + int _endSequenceSkipFlag; + int _endSequenceNeedLoading; + int _unkEndSeqVar2; + uint8 *_endSequenceBackUpRect; + int _unkEndSeqVar4; + int _unkEndSeqVar5; + int _lastDisplayedPanPage; + uint8 *_panPagesTable[20]; + Movie *_finalA, *_finalB, *_finalC; + + Movie *_movieObjects[10]; + + uint16 _entranceMouseCursorTracks[8]; + uint16 _walkBlockNorth; + uint16 _walkBlockEast; + uint16 _walkBlockSouth; + uint16 _walkBlockWest; + + int32 _scaleMode; + int16 _scaleTable[145]; + + Rect _noDropRects[11]; + + int8 _birthstoneGemTable[4]; + int8 _idolGemsTable[3]; + + int8 _marbleVaseItem; + int8 _foyerItemTable[3]; + + int8 _cauldronState; + int8 _crystalState[2]; + + uint16 _brandonStatusBit; + uint8 _brandonStatusBit0x02Flag; + uint8 _brandonStatusBit0x20Flag; + uint8 _brandonPoisonFlagsGFX[256]; + uint8 _deathHandler; + int16 _brandonInvFlag; + uint8 _poisonDeathCounter; + int _brandonPosX; + int _brandonPosY; + + uint16 _currentChatPartnerBackupFrame; + uint16 _currentCharAnimFrame; + + int8 *_sceneAnimTable[50]; + + Item _itemTable[145]; + int _lastProcessedItem; + int _lastProcessedItemHeight; + + int16 *_exitListPtr; + int16 _exitList[11]; + SceneExits _sceneExits; + uint16 _currentRoom; + int _scenePhasingFlag; + + int _sceneChangeState; + int _loopFlag2; + + int _pathfinderFlag; + int _pathfinderFlag2; + int _lastFindWayRet; + int *_movFacingTable; + + int8 _talkingCharNum; + int8 _charSayUnk2; + int8 _charSayUnk3; + int8 _currHeadShape; + uint8 _currSentenceColor[3]; + int8 _startSentencePalIndex; + bool _fadeText; + + uint8 _configTextspeed; + + Animator_LoK *_animator; + SeqPlayer *_seq; + Sprites *_sprites; + Screen_LoK *_screen; + + EMCState _scriptMain; + + EMCState _npcScript; + EMCData _npcScriptData; + + EMCState _scriptClick; + EMCData _scriptClickData; + + Character *_characterList; + Character *_currentCharacter; + + Button *_buttonList; + GUI_LoK *_gui; + + struct KyragemState { + uint16 nextOperation; + uint16 rOffset; + uint16 gOffset; + uint16 bOffset; + uint32 timerCount; + } _kyragemFadingState; + + static const int8 _dosTrackMap[]; + static const int _dosTrackMapSize; + + // TODO: get rid of all variables having pointers to the static resources if possible + // i.e. let them directly use the _staticres functions + void initStaticResource(); + + const uint8 *_seq_Forest; + const uint8 *_seq_KallakWriting; + const uint8 *_seq_KyrandiaLogo; + const uint8 *_seq_KallakMalcolm; + const uint8 *_seq_MalcolmTree; + const uint8 *_seq_WestwoodLogo; + const uint8 *_seq_Demo1; + const uint8 *_seq_Demo2; + const uint8 *_seq_Demo3; + const uint8 *_seq_Demo4; + const uint8 *_seq_Reunion; + + const char * const*_seq_WSATable; + const char * const*_seq_CPSTable; + const char * const*_seq_COLTable; + const char * const*_seq_textsTable; + + int _seq_WSATable_Size; + int _seq_CPSTable_Size; + int _seq_COLTable_Size; + int _seq_textsTable_Size; + + const char * const*_itemList; + const char * const*_takenList; + const char * const*_placedList; + const char * const*_droppedList; + const char * const*_noDropList; + const char * const*_putDownFirst; + const char * const*_waitForAmulet; + const char * const*_blackJewel; + const char * const*_poisonGone; + const char * const*_healingTip; + const char * const*_thePoison; + const char * const*_fluteString; + const char * const*_wispJewelStrings; + const char * const*_magicJewelString; + const char * const*_flaskFull; + const char * const*_fullFlask; + const char * const*_veryClever; + const char * const*_homeString; + const char * const*_newGameString; + + int _itemList_Size; + int _takenList_Size; + int _placedList_Size; + int _droppedList_Size; + int _noDropList_Size; + int _putDownFirst_Size; + int _waitForAmulet_Size; + int _blackJewel_Size; + int _poisonGone_Size; + int _healingTip_Size; + int _thePoison_Size; + int _fluteString_Size; + int _wispJewelStrings_Size; + int _magicJewelString_Size; + int _flaskFull_Size; + int _fullFlask_Size; + int _veryClever_Size; + int _homeString_Size; + int _newGameString_Size; + + const char * const*_characterImageTable; + int _characterImageTableSize; + + const char * const*_guiStrings; + int _guiStringsSize; + + const char * const*_configStrings; + int _configStringsSize; + + Shape *_defaultShapeTable; + int _defaultShapeTableSize; + + const Shape *_healingShapeTable; + int _healingShapeTableSize; + const Shape *_healingShape2Table; + int _healingShape2TableSize; + + const Shape *_posionDeathShapeTable; + int _posionDeathShapeTableSize; + + const Shape *_fluteAnimShapeTable; + int _fluteAnimShapeTableSize; + + const Shape *_winterScrollTable; + int _winterScrollTableSize; + const Shape *_winterScroll1Table; + int _winterScroll1TableSize; + const Shape *_winterScroll2Table; + int _winterScroll2TableSize; + + const Shape *_drinkAnimationTable; + int _drinkAnimationTableSize; + + const Shape *_brandonToWispTable; + int _brandonToWispTableSize; + + const Shape *_magicAnimationTable; + int _magicAnimationTableSize; + + const Shape *_brandonStoneTable; + int _brandonStoneTableSize; + + Room *_roomTable; + int _roomTableSize; + const char * const*_roomFilenameTable; + int _roomFilenameTableSize; + + const uint8 *_amuleteAnim; + + const uint8 * const*_specialPalettes; + + const char *const *_soundFiles; + int _soundFilesSize; + const char *const *_soundFilesIntro; + int _soundFilesIntroSize; + const int32 *_cdaTrackTable; + int _cdaTrackTableSize; + const AudioDataStruct * _soundData; + + static const int8 _charXPosTable[]; + static const int8 _charYPosTable[]; + + // positions of the inventory + static const uint16 _itemPosX[]; + static const uint8 _itemPosY[]; + + void setupButtonData(); + Button *_buttonData; + Button **_buttonDataListPtr; + + static const uint8 _magicMouseItemStartFrame[]; + static const uint8 _magicMouseItemEndFrame[]; + static const uint8 _magicMouseItemStartFrame2[]; + static const uint8 _magicMouseItemEndFrame2[]; + + static const uint16 _amuletX[]; + static const uint16 _amuletY[]; + static const uint16 _amuletX2[]; + static const uint16 _amuletY2[]; +protected: + void setupOpcodeTable(); + + // Opcodes + int o1_magicInMouseItem(EMCState *script); + int o1_characterSays(EMCState *script); + int o1_pauseTicks(EMCState *script); + int o1_drawSceneAnimShape(EMCState *script); + int o1_queryGameFlag(EMCState *script); + int o1_setGameFlag(EMCState *script); + int o1_resetGameFlag(EMCState *script); + int o1_runNPCScript(EMCState *script); + int o1_setSpecialExitList(EMCState *script); + int o1_blockInWalkableRegion(EMCState *script); + int o1_blockOutWalkableRegion(EMCState *script); + int o1_walkPlayerToPoint(EMCState *script); + int o1_dropItemInScene(EMCState *script); + int o1_drawAnimShapeIntoScene(EMCState *script); + int o1_createMouseItem(EMCState *script); + int o1_savePageToDisk(EMCState *script); + int o1_sceneAnimOn(EMCState *script); + int o1_sceneAnimOff(EMCState *script); + int o1_getElapsedSeconds(EMCState *script); + int o1_mouseIsPointer(EMCState *script); + int o1_destroyMouseItem(EMCState *script); + int o1_runSceneAnimUntilDone(EMCState *script); + int o1_fadeSpecialPalette(EMCState *script); + int o1_playAdlibSound(EMCState *script); + int o1_playAdlibScore(EMCState *script); + int o1_phaseInSameScene(EMCState *script); + int o1_setScenePhasingFlag(EMCState *script); + int o1_resetScenePhasingFlag(EMCState *script); + int o1_queryScenePhasingFlag(EMCState *script); + int o1_sceneToDirection(EMCState *script); + int o1_setBirthstoneGem(EMCState *script); + int o1_placeItemInGenericMapScene(EMCState *script); + int o1_setBrandonStatusBit(EMCState *script); + int o1_pauseSeconds(EMCState *script); + int o1_getCharactersLocation(EMCState *script); + int o1_runNPCSubscript(EMCState *script); + int o1_magicOutMouseItem(EMCState *script); + int o1_internalAnimOn(EMCState *script); + int o1_forceBrandonToNormal(EMCState *script); + int o1_poisonDeathNow(EMCState *script); + int o1_setScaleMode(EMCState *script); + int o1_openWSAFile(EMCState *script); + int o1_closeWSAFile(EMCState *script); + int o1_runWSAFromBeginningToEnd(EMCState *script); + int o1_displayWSAFrame(EMCState *script); + int o1_enterNewScene(EMCState *script); + int o1_setSpecialEnterXAndY(EMCState *script); + int o1_runWSAFrames(EMCState *script); + int o1_popBrandonIntoScene(EMCState *script); + int o1_restoreAllObjectBackgrounds(EMCState *script); + int o1_setCustomPaletteRange(EMCState *script); + int o1_loadPageFromDisk(EMCState *script); + int o1_customPrintTalkString(EMCState *script); + int o1_restoreCustomPrintBackground(EMCState *script); + int o1_hideMouse(EMCState *script); + int o1_showMouse(EMCState *script); + int o1_getCharacterX(EMCState *script); + int o1_getCharacterY(EMCState *script); + int o1_changeCharactersFacing(EMCState *script); + int o1_copyWSARegion(EMCState *script); + int o1_printText(EMCState *script); + int o1_random(EMCState *script); + int o1_loadSoundFile(EMCState *script); + int o1_displayWSAFrameOnHidPage(EMCState *script); + int o1_displayWSASequentialFrames(EMCState *script); + int o1_drawCharacterStanding(EMCState *script); + int o1_internalAnimOff(EMCState *script); + int o1_changeCharactersXAndY(EMCState *script); + int o1_clearSceneAnimatorBeacon(EMCState *script); + int o1_querySceneAnimatorBeacon(EMCState *script); + int o1_refreshSceneAnimator(EMCState *script); + int o1_placeItemInOffScene(EMCState *script); + int o1_wipeDownMouseItem(EMCState *script); + int o1_placeCharacterInOtherScene(EMCState *script); + int o1_getKey(EMCState *script); + int o1_specificItemInInventory(EMCState *script); + int o1_popMobileNPCIntoScene(EMCState *script); + int o1_mobileCharacterInScene(EMCState *script); + int o1_hideMobileCharacter(EMCState *script); + int o1_unhideMobileCharacter(EMCState *script); + int o1_setCharactersLocation(EMCState *script); + int o1_walkCharacterToPoint(EMCState *script); + int o1_specialEventDisplayBrynnsNote(EMCState *script); + int o1_specialEventRemoveBrynnsNote(EMCState *script); + int o1_setLogicPage(EMCState *script); + int o1_fatPrint(EMCState *script); + int o1_preserveAllObjectBackgrounds(EMCState *script); + int o1_updateSceneAnimations(EMCState *script); + int o1_sceneAnimationActive(EMCState *script); + int o1_setCharactersMovementDelay(EMCState *script); + int o1_getCharactersFacing(EMCState *script); + int o1_bkgdScrollSceneAndMasksRight(EMCState *script); + int o1_dispelMagicAnimation(EMCState *script); + int o1_findBrightestFireberry(EMCState *script); + int o1_setFireberryGlowPalette(EMCState *script); + int o1_setDeathHandlerFlag(EMCState *script); + int o1_drinkPotionAnimation(EMCState *script); + int o1_makeAmuletAppear(EMCState *script); + int o1_drawItemShapeIntoScene(EMCState *script); + int o1_setCharactersCurrentFrame(EMCState *script); + int o1_waitForConfirmationMouseClick(EMCState *script); + int o1_pageFlip(EMCState *script); + int o1_setSceneFile(EMCState *script); + int o1_getItemInMarbleVase(EMCState *script); + int o1_setItemInMarbleVase(EMCState *script); + int o1_addItemToInventory(EMCState *script); + int o1_intPrint(EMCState *script); + int o1_shakeScreen(EMCState *script); + int o1_createAmuletJewel(EMCState *script); + int o1_setSceneAnimCurrXY(EMCState *script); + int o1_poisonBrandonAndRemaps(EMCState *script); + int o1_fillFlaskWithWater(EMCState *script); + int o1_getCharactersMovementDelay(EMCState *script); + int o1_getBirthstoneGem(EMCState *script); + int o1_queryBrandonStatusBit(EMCState *script); + int o1_playFluteAnimation(EMCState *script); + int o1_playWinterScrollSequence(EMCState *script); + int o1_getIdolGem(EMCState *script); + int o1_setIdolGem(EMCState *script); + int o1_totalItemsInScene(EMCState *script); + int o1_restoreBrandonsMovementDelay(EMCState *script); + int o1_setMousePos(EMCState *script); + int o1_getMouseState(EMCState *script); + int o1_setEntranceMouseCursorTrack(EMCState *script); + int o1_itemAppearsOnGround(EMCState *script); + int o1_setNoDrawShapesFlag(EMCState *script); + int o1_fadeEntirePalette(EMCState *script); + int o1_itemOnGroundHere(EMCState *script); + int o1_queryCauldronState(EMCState *script); + int o1_setCauldronState(EMCState *script); + int o1_queryCrystalState(EMCState *script); + int o1_setCrystalState(EMCState *script); + int o1_setPaletteRange(EMCState *script); + int o1_shrinkBrandonDown(EMCState *script); + int o1_growBrandonUp(EMCState *script); + int o1_setBrandonScaleXAndY(EMCState *script); + int o1_resetScaleMode(EMCState *script); + int o1_getScaleDepthTableValue(EMCState *script); + int o1_setScaleDepthTableValue(EMCState *script); + int o1_message(EMCState *script); + int o1_checkClickOnNPC(EMCState *script); + int o1_getFoyerItem(EMCState *script); + int o1_setFoyerItem(EMCState *script); + int o1_setNoItemDropRegion(EMCState *script); + int o1_walkMalcolmOn(EMCState *script); + int o1_passiveProtection(EMCState *script); + int o1_setPlayingLoop(EMCState *script); + int o1_brandonToStoneSequence(EMCState *script); + int o1_brandonHealingSequence(EMCState *script); + int o1_protectCommandLine(EMCState *script); + int o1_pauseMusicSeconds(EMCState *script); + int o1_resetMaskRegion(EMCState *script); + int o1_setPaletteChangeFlag(EMCState *script); + int o1_fillRect(EMCState *script); + int o1_dummy(EMCState *script); + int o1_vocUnload(EMCState *script); + int o1_vocLoad(EMCState *script); +}; + +} // end of namespace Kyra + +#endif + diff --git a/engines/kyra/kyra_mr.cpp b/engines/kyra/kyra_mr.cpp index 2168000dc9..6eca24fe98 100644 --- a/engines/kyra/kyra_mr.cpp +++ b/engines/kyra/kyra_mr.cpp @@ -325,7 +325,7 @@ int KyraEngine_MR::go() { } void KyraEngine_MR::initMainMenu() { - _menuAnim = new WSAMovieV2(this, _screen); + _menuAnim = new WSAMovie_v2(this, _screen); _menuAnim->open("REVENGE.WSA", 1, _screen->getPalette(0)); _menuAnim->setX(0); _menuAnim->setY(0); @@ -550,11 +550,11 @@ void KyraEngine_MR::initMouseShapes() { void KyraEngine_MR::startup() { debugC(9, kDebugLevelMain, "KyraEngine_MR::startup()"); - _album.wsa = new WSAMovieV2(this, _screen); + _album.wsa = new WSAMovie_v2(this, _screen); assert(_album.wsa); - _album.leftPage.wsa = new WSAMovieV2(this, _screen); + _album.leftPage.wsa = new WSAMovie_v2(this, _screen); assert(_album.leftPage.wsa); - _album.rightPage.wsa = new WSAMovieV2(this, _screen); + _album.rightPage.wsa = new WSAMovie_v2(this, _screen); assert(_album.rightPage.wsa); musicUpdate(0); @@ -607,7 +607,7 @@ void KyraEngine_MR::startup() { for (int i = 0; i < 16; ++i) { _sceneAnims[i].flags = 0; - _sceneAnimMovie[i] = new WSAMovieV2(this, _screen); + _sceneAnimMovie[i] = new WSAMovie_v2(this, _screen); assert(_sceneAnimMovie[i]); } @@ -664,7 +664,7 @@ void KyraEngine_MR::startup() { musicUpdate(0); runStartupScript(1, 0); _res->exists("MOODOMTR.WSA", true); - _invWsa = new WSAMovieV2(this, _screen); + _invWsa = new WSAMovie_v2(this, _screen); assert(_invWsa); _invWsa->open("MOODOMTR.WSA", 1, 0); _invWsaFrame = 6; diff --git a/engines/kyra/kyra_mr.h b/engines/kyra/kyra_mr.h index a50fbfd440..4e28d6a5c0 100644 --- a/engines/kyra/kyra_mr.h +++ b/engines/kyra/kyra_mr.h @@ -39,7 +39,7 @@ namespace Kyra { class SoundDigital; class Screen_MR; class MainMenu; -class WSAMovieV2; +class WSAMovie_v2; class TextDisplayer_MR; struct Button; @@ -157,7 +157,7 @@ private: void initMainMenu(); void uninitMainMenu(); - WSAMovieV2 *_menuAnim; + WSAMovie_v2 *_menuAnim; // timer void setupTimers(); @@ -262,7 +262,7 @@ private: void clearInventorySlot(int slot, int page); void drawInventorySlot(int page, int item, int slot); - WSAMovieV2 *_invWsa; + WSAMovie_v2 *_invWsa; int _invWsaFrame; // localization @@ -535,11 +535,11 @@ private: struct Album { uint8 *backUpPage; uint8 *file; - WSAMovieV2 *wsa; + WSAMovie_v2 *wsa; uint8 *backUpRect; struct PageMovie { - WSAMovieV2 *wsa; + WSAMovie_v2 *wsa; int curFrame; int maxFrame; uint32 timer; diff --git a/engines/kyra/kyra_v1.cpp b/engines/kyra/kyra_v1.cpp deleted file mode 100644 index 2504719ef5..0000000000 --- a/engines/kyra/kyra_v1.cpp +++ /dev/null @@ -1,1044 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include "kyra/kyra_v1.h" - -#include "common/file.h" -#include "common/events.h" -#include "common/system.h" -#include "common/savefile.h" - -#include "gui/message.h" - -#include "kyra/resource.h" -#include "kyra/screen.h" -#include "kyra/script.h" -#include "kyra/seqplayer.h" -#include "kyra/sound.h" -#include "kyra/sprites.h" -#include "kyra/wsamovie.h" -#include "kyra/animator_v1.h" -#include "kyra/text.h" -#include "kyra/debugger.h" -#include "kyra/timer.h" - -namespace Kyra { - -KyraEngine_v1::KyraEngine_v1(OSystem *system, const GameFlags &flags) - : KyraEngine(system, flags) { - _skipFlag = false; - - _seq_Forest = _seq_KallakWriting = _seq_KyrandiaLogo = _seq_KallakMalcolm = - _seq_MalcolmTree = _seq_WestwoodLogo = _seq_Demo1 = _seq_Demo2 = _seq_Demo3 = - _seq_Demo4 = 0; - - _seq_WSATable = _seq_CPSTable = _seq_COLTable = _seq_textsTable = 0; - _seq_WSATable_Size = _seq_CPSTable_Size = _seq_COLTable_Size = _seq_textsTable_Size = 0; - - _roomFilenameTable = _characterImageTable = 0; - _roomFilenameTableSize = _characterImageTableSize = 0; - _itemList = _takenList = _placedList = _droppedList = _noDropList = 0; - _itemList_Size = _takenList_Size = _placedList_Size = _droppedList_Size = _noDropList_Size = 0; - _putDownFirst = _waitForAmulet = _blackJewel = _poisonGone = _healingTip = 0; - _putDownFirst_Size = _waitForAmulet_Size = _blackJewel_Size = _poisonGone_Size = _healingTip_Size = 0; - _thePoison = _fluteString = _wispJewelStrings = _magicJewelString = _flaskFull = _fullFlask = 0; - _thePoison_Size = _fluteString_Size = _wispJewelStrings_Size = 0; - _magicJewelString_Size = _flaskFull_Size = _fullFlask_Size = 0; - - _defaultShapeTable = 0; - _healingShapeTable = _healingShape2Table = 0; - _defaultShapeTableSize = _healingShapeTableSize = _healingShape2TableSize = 0; - _posionDeathShapeTable = _fluteAnimShapeTable = 0; - _posionDeathShapeTableSize = _fluteAnimShapeTableSize = 0; - _winterScrollTable = _winterScroll1Table = _winterScroll2Table = 0; - _winterScrollTableSize = _winterScroll1TableSize = _winterScroll2TableSize = 0; - _drinkAnimationTable = _brandonToWispTable = _magicAnimationTable = _brandonStoneTable = 0; - _drinkAnimationTableSize = _brandonToWispTableSize = _magicAnimationTableSize = _brandonStoneTableSize = 0; - memset(&_specialPalettes, 0, sizeof(_specialPalettes)); - _sprites = 0; - _animator = 0; - _seq = 0; - _characterList = 0; - _movFacingTable = 0; - _buttonData = 0; - _buttonDataListPtr = 0; - memset(_shapes, 0, sizeof(_shapes)); - memset(_movieObjects, 0, sizeof(_movieObjects)); - _finalA = _finalB = _finalC = 0; - _endSequenceBackUpRect = 0; - memset(_panPagesTable, 0, sizeof(_panPagesTable)); - memset(_sceneAnimTable, 0, sizeof(_sceneAnimTable)); - _currHeadShape = 0; - - memset(&_itemBkgBackUp, 0, sizeof(_itemBkgBackUp)); -} - -KyraEngine_v1::~KyraEngine_v1() { - for (int i = 0; i < ARRAYSIZE(_movieObjects); ++i) { - if (_movieObjects[i]) - _movieObjects[i]->close(); - delete _movieObjects[i]; - _movieObjects[i] = 0; - } - - closeFinalWsa(); - if (_emc) { - _emc->unload(&_npcScriptData); - _emc->unload(&_scriptClickData); - } - - Common::clearAllSpecialDebugLevels(); - - delete _screen; - delete _sprites; - delete _animator; - delete _seq; - - delete[] _characterList; - - delete[] _movFacingTable; - - delete[] _gui->_scrollUpButton.data0ShapePtr; - delete[] _gui->_scrollUpButton.data1ShapePtr; - delete[] _gui->_scrollUpButton.data2ShapePtr; - delete[] _gui->_scrollDownButton.data0ShapePtr; - delete[] _gui->_scrollDownButton.data1ShapePtr; - delete[] _gui->_scrollDownButton.data2ShapePtr; - - delete[] _buttonData; - delete[] _buttonDataListPtr; - - delete _gui; - - delete[] _itemBkgBackUp[0]; - delete[] _itemBkgBackUp[1]; - - for (int i = 0; i < ARRAYSIZE(_shapes); ++i) { - if (_shapes[i] != 0) { - delete[] _shapes[i]; - for (int i2 = 0; i2 < ARRAYSIZE(_shapes); i2++) { - if (_shapes[i2] == _shapes[i] && i2 != i) { - _shapes[i2] = 0; - } - } - _shapes[i] = 0; - } - } - - for (int i = 0; i < ARRAYSIZE(_sceneAnimTable); ++i) - delete[] _sceneAnimTable[i]; -} - -int KyraEngine_v1::init() { - _screen = new Screen_v1(this, _system); - assert(_screen); - _screen->setResolution(); - - KyraEngine::init(); - - _sprites = new Sprites(this, _system); - assert(_sprites); - _seq = new SeqPlayer(this, _system); - assert(_seq); - _animator = new Animator_v1(this, _system); - assert(_animator); - _animator->init(5, 11, 12); - assert(*_animator); - _text = new TextDisplayer(this, screen()); - assert(_text); - _gui = new GUI_v1(this, _screen); - assert(_gui); - - initStaticResource(); - - _sound->setSoundList(&_soundData[kMusicIntro]); - - _trackMap = _dosTrackMap; - _trackMapSize = _dosTrackMapSize; - - if (!_sound->init()) - error("Couldn't init sound"); - - _sound->loadSoundFile(0); - - setupButtonData(); - - _paletteChanged = 1; - _currentCharacter = 0; - _characterList = new Character[11]; - assert(_characterList); - memset(_characterList, 0, sizeof(Character)*11); - - for (int i = 0; i < 11; ++i) - memset(_characterList[i].inventoryItems, 0xFF, sizeof(_characterList[i].inventoryItems)); - - _characterList[0].sceneId = 5; - _characterList[0].height = 48; - _characterList[0].facing = 3; - _characterList[0].currentAnimFrame = 7; - - memset(&_npcScriptData, 0, sizeof(EMCData)); - memset(&_scriptClickData, 0, sizeof(EMCData)); - - memset(&_npcScript, 0, sizeof(EMCState)); - memset(&_scriptMain, 0, sizeof(EMCState)); - memset(&_scriptClick, 0, sizeof(EMCState)); - - _debugger = new Debugger_v1(this); - assert(_debugger); - memset(_shapes, 0, sizeof(_shapes)); - - for (int i = 0; i < ARRAYSIZE(_movieObjects); ++i) - _movieObjects[i] = createWSAMovie(); - - memset(_flagsTable, 0, sizeof(_flagsTable)); - - _abortWalkFlag = false; - _abortWalkFlag2 = false; - _talkingCharNum = -1; - _charSayUnk3 = -1; - memset(_currSentenceColor, 0, 3); - _startSentencePalIndex = -1; - _fadeText = false; - - _cauldronState = 0; - _crystalState[0] = _crystalState[1] = -1; - - _brandonStatusBit = 0; - _brandonStatusBit0x02Flag = _brandonStatusBit0x20Flag = 10; - _brandonPosX = _brandonPosY = -1; - _deathHandler = 0xFF; - _poisonDeathCounter = 0; - - memset(_itemTable, 0, sizeof(_itemTable)); - memset(_exitList, 0xFFFF, sizeof(_exitList)); - _exitListPtr = 0; - _pathfinderFlag = _pathfinderFlag2 = 0; - _lastFindWayRet = 0; - _sceneChangeState = _loopFlag2 = 0; - - _movFacingTable = new int[150]; - assert(_movFacingTable); - _movFacingTable[0] = 8; - - _skipFlag = false; - - _marbleVaseItem = -1; - memset(_foyerItemTable, -1, sizeof(_foyerItemTable)); - _mouseState = _itemInHand = -1; - _handleInput = false; - - _currentRoom = 0xFFFF; - _scenePhasingFlag = 0; - _lastProcessedItem = 0; - _lastProcessedItemHeight = 16; - - _unkScreenVar1 = 1; - _unkScreenVar2 = 0; - _unkScreenVar3 = 0; - _unkAmuletVar = 0; - - _endSequenceNeedLoading = 1; - _malcolmFlag = 0; - _beadStateVar = 0; - _endSequenceSkipFlag = 0; - _unkEndSeqVar2 = 0; - _endSequenceBackUpRect = 0; - _unkEndSeqVar4 = 0; - _unkEndSeqVar5 = 0; - _lastDisplayedPanPage = 0; - memset(_panPagesTable, 0, sizeof(_panPagesTable)); - _finalA = _finalB = _finalC = 0; - memset(&_kyragemFadingState, 0, sizeof(_kyragemFadingState)); - _kyragemFadingState.gOffset = 0x13; - _kyragemFadingState.bOffset = 0x13; - - _mousePressFlag = false; - - _menuDirectlyToLoad = false; - - _lastMusicCommand = 0; - - return 0; -} - -int KyraEngine_v1::go() { - if (_res->getFileSize("6.FNT")) - _screen->loadFont(Screen::FID_6_FNT, "6.FNT"); - _screen->loadFont(Screen::FID_8_FNT, "8FAT.FNT"); - _screen->setScreenDim(0); - - _abortIntroFlag = false; - - if (_flags.isDemo) { - seq_demo(); - } else { - setGameFlag(0xF3); - setGameFlag(0xFD); - if (_gameToLoad == -1) { - setGameFlag(0xEF); - seq_intro(); - if (_quitFlag) - return 0; - if (_skipIntroFlag && _abortIntroFlag) - resetGameFlag(0xEF); - } - startup(); - resetGameFlag(0xEF); - mainLoop(); - } - return 0; -} - - -void KyraEngine_v1::startup() { - debugC(9, kDebugLevelMain, "KyraEngine_v1::startup()"); - static const uint8 colorMap[] = { 0, 0, 0, 0, 12, 12, 12, 0, 0, 0, 0, 0 }; - _screen->setTextColorMap(colorMap); - _sound->setSoundList(&_soundData[kMusicIngame]); - _sound->loadSoundFile(0); -// _screen->setFont(Screen::FID_6_FNT); - _screen->setAnimBlockPtr(3750); - memset(_sceneAnimTable, 0, sizeof(_sceneAnimTable)); - loadMouseShapes(); - _currentCharacter = &_characterList[0]; - for (int i = 1; i < 5; ++i) - _animator->setCharacterDefaultFrame(i); - for (int i = 5; i <= 10; ++i) - setCharactersPositions(i); - _animator->setCharactersHeight(); - resetBrandonPoisonFlags(); - _screen->_curPage = 0; - // XXX - for (int i = 0; i < 12; ++i) { - int size = _screen->getRectSize(3, 24); - _shapes[361+i] = new byte[size]; - } - - _itemBkgBackUp[0] = new uint8[_screen->getRectSize(3, 24)]; - memset(_itemBkgBackUp[0], 0, _screen->getRectSize(3, 24)); - _itemBkgBackUp[1] = new uint8[_screen->getRectSize(4, 32)]; - memset(_itemBkgBackUp[1], 0, _screen->getRectSize(4, 32)); - - for (int i = 0; i < _roomTableSize; ++i) { - for (int item = 0; item < 12; ++item) { - _roomTable[i].itemsTable[item] = 0xFF; - _roomTable[i].itemsXPos[item] = 0xFFFF; - _roomTable[i].itemsYPos[item] = 0xFF; - _roomTable[i].needInit[item] = 0; - } - } - - loadCharacterShapes(); - loadSpecialEffectShapes(); - loadItems(); - loadButtonShapes(); - initMainButtonList(); - loadMainScreen(); - _screen->loadPalette("PALETTE.COL", _screen->_currentPalette); - - // XXX - _animator->initAnimStateList(); - setCharactersInDefaultScene(); - - if (!_emc->load("_STARTUP.EMC", &_npcScriptData, &_opcodes)) - error("Could not load \"_STARTUP.EMC\" script"); - _emc->init(&_scriptMain, &_npcScriptData); - - if (!_emc->start(&_scriptMain, 0)) - error("Could not start script function 0 of script \"_STARTUP.EMC\""); - - while (_emc->isValid(&_scriptMain)) - _emc->run(&_scriptMain); - - _emc->unload(&_npcScriptData); - - if (!_emc->load("_NPC.EMC", &_npcScriptData, &_opcodes)) - error("Could not load \"_NPC.EMC\" script"); - - snd_playTheme(1, -1); - if (_gameToLoad == -1) { - enterNewScene(_currentCharacter->sceneId, _currentCharacter->facing, 0, 0, 1); - if (_abortIntroFlag && _skipIntroFlag) { - _menuDirectlyToLoad = true; - _screen->setMouseCursor(1, 1, _shapes[0]); - _screen->showMouse(); - _gui->buttonMenuCallback(0); - _menuDirectlyToLoad = false; - } else - saveGame(getSavegameFilename(0), "New game"); - } else { - _screen->setFont(Screen::FID_8_FNT); - loadGame(getSavegameFilename(_gameToLoad)); - _gameToLoad = -1; - } -} - -void KyraEngine_v1::mainLoop() { - debugC(9, kDebugLevelMain, "KyraEngine_v1::mainLoop()"); - - while (!_quitFlag) { - int32 frameTime = (int32)_system->getMillis(); - _skipFlag = false; - - if (_currentCharacter->sceneId == 210) { - updateKyragemFading(); - if (seq_playEnd() && _deathHandler != 8) - break; - } - - if (_deathHandler != 0xFF) { - snd_playWanderScoreViaMap(0, 1); - snd_playSoundEffect(49); - _screen->hideMouse(); - _screen->setMouseCursor(1, 1, _shapes[0]); - destroyMouseItem(); - _screen->showMouse(); - _gui->buttonMenuCallback(0); - _deathHandler = 0xFF; - } - - if ((_brandonStatusBit & 2) && _brandonStatusBit0x02Flag) - _animator->animRefreshNPC(0); - - if ((_brandonStatusBit & 0x20) && _brandonStatusBit0x20Flag) { - _animator->animRefreshNPC(0); - _brandonStatusBit0x20Flag = 0; - } - - _screen->showMouse(); - - _gui->processButtonList(_buttonList, 0, 0); - updateMousePointer(); - _timer->update(); - updateTextFade(); - - _handleInput = true; - delay((frameTime + _gameSpeed) - _system->getMillis(), true, true); - _handleInput = false; - - _sound->process(); - } -} - -void KyraEngine_v1::delayUntil(uint32 timestamp, bool updateTimers, bool update, bool isMainLoop) { - while (_system->getMillis() < timestamp && !_quitFlag) { - if (updateTimers) - _timer->update(); - - if (timestamp - _system->getMillis() >= 10) - delay(10, update, isMainLoop); - } -} - -void KyraEngine_v1::delay(uint32 amount, bool update, bool isMainLoop) { - Common::Event event; - - uint32 start = _system->getMillis(); - do { - while (_eventMan->pollEvent(event)) { - switch (event.type) { - case Common::EVENT_KEYDOWN: - if (event.kbd.keycode >= '1' && event.kbd.keycode <= '9' && - (event.kbd.flags == Common::KBD_CTRL || event.kbd.flags == Common::KBD_ALT) && isMainLoop) { - const char *saveLoadSlot = getSavegameFilename(9 - (event.kbd.keycode - '0') + 990); - - if (event.kbd.flags == Common::KBD_CTRL) - loadGame(saveLoadSlot); - else { - char savegameName[14]; - sprintf(savegameName, "Quicksave %d", event.kbd.keycode - '0'); - saveGame(saveLoadSlot, savegameName); - } - } else if (event.kbd.flags == Common::KBD_CTRL) { - if (event.kbd.keycode == 'd') - _debugger->attach(); - else if (event.kbd.keycode == 'q') - _quitFlag = true; - } else if (event.kbd.keycode == '.') { - _skipFlag = true; - } else if (event.kbd.keycode == Common::KEYCODE_RETURN || event.kbd.keycode == Common::KEYCODE_SPACE || event.kbd.keycode == Common::KEYCODE_ESCAPE) { - _abortIntroFlag = true; - _skipFlag = true; - } - - break; - case Common::EVENT_MOUSEMOVE: - _animator->_updateScreen = true; - break; - case Common::EVENT_QUIT: - quitGame(); - break; - case Common::EVENT_LBUTTONDOWN: - _mousePressFlag = true; - break; - case Common::EVENT_LBUTTONUP: - _mousePressFlag = false; - - if (_abortWalkFlag2) - _abortWalkFlag = true; - - if (_handleInput) { - _handleInput = false; - processInput(); - _handleInput = true; - } else - _skipFlag = true; - - break; - default: - break; - } - } - - if (_debugger->isAttached()) - _debugger->onFrame(); - - if (update) { - _sprites->updateSceneAnims(); - _animator->updateAllObjectShapes(); - updateTextFade(); - updateMousePointer(); - } - - if (_currentCharacter && _currentCharacter->sceneId == 210 && update) - updateKyragemFading(); - - if (_skipFlag && !_abortIntroFlag && !queryGameFlag(0xFE)) - _skipFlag = false; - - if (amount > 0 && !_skipFlag && !_quitFlag) - _system->delayMillis(10); - - if (_skipFlag) - _sound->voiceStop(); - } while (!_skipFlag && _system->getMillis() < start + amount && !_quitFlag); -} - -void KyraEngine_v1::waitForEvent() { - bool finished = false; - Common::Event event; - - while (!finished && !_quitFlag) { - while (_eventMan->pollEvent(event)) { - switch (event.type) { - case Common::EVENT_KEYDOWN: - finished = true; - break; - case Common::EVENT_QUIT: - quitGame(); - break; - case Common::EVENT_LBUTTONDOWN: - finished = true; - _skipFlag = true; - break; - default: - break; - } - } - - if (_debugger->isAttached()) - _debugger->onFrame(); - - _system->delayMillis(10); - } -} - -void KyraEngine_v1::delayWithTicks(int ticks) { - uint32 nextTime = _system->getMillis() + ticks * _tickLength; - - while (_system->getMillis() < nextTime) { - _sprites->updateSceneAnims(); - _animator->updateAllObjectShapes(); - - if (_currentCharacter->sceneId == 210) { - updateKyragemFading(); - seq_playEnd(); - } - - if (_skipFlag) - break; - - if (nextTime - _system->getMillis() >= 10) - delay(10); - } -} - -#pragma mark - -#pragma mark - Animation/shape specific code -#pragma mark - - -void KyraEngine_v1::setupShapes123(const Shape *shapeTable, int endShape, int flags) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::setupShapes123(%p, %d, %d)", (const void *)shapeTable, endShape, flags); - - for (int i = 123; i <= 172; ++i) - _shapes[i] = 0; - - uint8 curImage = 0xFF; - int curPageBackUp = _screen->_curPage; - _screen->_curPage = 8; // we are using page 8 here in the original page 2 was backuped and then used for this stuff - int shapeFlags = 2; - if (flags) - shapeFlags = 3; - for (int i = 123; i < 123+endShape; ++i) { - uint8 newImage = shapeTable[i-123].imageIndex; - if (newImage != curImage && newImage != 0xFF) { - assert(_characterImageTable); - _screen->loadBitmap(_characterImageTable[newImage], 8, 8, 0); - curImage = newImage; - } - _shapes[i] = _screen->encodeShape(shapeTable[i-123].x<<3, shapeTable[i-123].y, shapeTable[i-123].w<<3, shapeTable[i-123].h, shapeFlags); - assert(i-7 < _defaultShapeTableSize); - _defaultShapeTable[i-7].xOffset = shapeTable[i-123].xOffset; - _defaultShapeTable[i-7].yOffset = shapeTable[i-123].yOffset; - _defaultShapeTable[i-7].w = shapeTable[i-123].w; - _defaultShapeTable[i-7].h = shapeTable[i-123].h; - } - _screen->_curPage = curPageBackUp; -} - -void KyraEngine_v1::freeShapes123() { - debugC(9, kDebugLevelMain, "KyraEngine_v1::freeShapes123()"); - - for (int i = 123; i <= 172; ++i) { - delete[] _shapes[i]; - _shapes[i] = 0; - } -} - -#pragma mark - -#pragma mark - Misc stuff -#pragma mark - - -Movie *KyraEngine_v1::createWSAMovie() { - if (_flags.platform == Common::kPlatformAmiga) - return new WSAMovieAmiga(this); - - return new WSAMovieV1(this); -} - -void KyraEngine_v1::setBrandonPoisonFlags(int reset) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::setBrandonPoisonFlags(%d)", reset); - _brandonStatusBit |= 1; - - if (reset) - _poisonDeathCounter = 0; - - for (int i = 0; i < 0x100; ++i) - _brandonPoisonFlagsGFX[i] = i; - - _brandonPoisonFlagsGFX[0x99] = 0x34; - _brandonPoisonFlagsGFX[0x9A] = 0x35; - _brandonPoisonFlagsGFX[0x9B] = 0x37; - _brandonPoisonFlagsGFX[0x9C] = 0x38; - _brandonPoisonFlagsGFX[0x9D] = 0x2B; -} - -void KyraEngine_v1::resetBrandonPoisonFlags() { - debugC(9, kDebugLevelMain, "KyraEngine_v1::resetBrandonPoisonFlags()"); - _brandonStatusBit = 0; - - for (int i = 0; i < 0x100; ++i) - _brandonPoisonFlagsGFX[i] = i; -} - -#pragma mark - -#pragma mark - Input -#pragma mark - - -void KyraEngine_v1::processInput() { - Common::Point mouse = getMousePos(); - int xpos = mouse.x; - int ypos = mouse.y; - - debugC(9, kDebugLevelMain, "KyraEngine_v1::processInput(%d, %d)", xpos, ypos); - _abortWalkFlag2 = false; - - if (processInputHelper(xpos, ypos)) - return; - - uint8 item = findItemAtPos(xpos, ypos); - if (item == 0xFF) { - _changedScene = false; - int handled = clickEventHandler(xpos, ypos); - if (_changedScene || handled) - return; - } - - // XXX _deathHandler specific - if (ypos <= 158) { - uint16 exit = 0xFFFF; - if (xpos < 12) { - exit = _walkBlockWest; - } else if (xpos >= 308) { - exit = _walkBlockEast; - } else if (ypos >= 136) { - exit = _walkBlockSouth; - } else if (ypos < 12) { - exit = _walkBlockNorth; - } - - if (exit != 0xFFFF) { - _abortWalkFlag2 = true; - handleSceneChange(xpos, ypos, 1, 1); - _abortWalkFlag2 = false; - return; - } else { - int script = checkForNPCScriptRun(xpos, ypos); - if (script >= 0) { - runNpcScript(script); - return; - } - if (_itemInHand != -1) { - if (ypos < 155) { - if (hasClickedOnExit(xpos, ypos)) { - _abortWalkFlag2 = true; - handleSceneChange(xpos, ypos, 1, 1); - _abortWalkFlag2 = false; - return; - } - dropItem(0, _itemInHand, xpos, ypos, 1); - } - } else { - if (ypos <= 155) { - _abortWalkFlag2 = true; - handleSceneChange(xpos, ypos, 1, 1); - _abortWalkFlag2 = false; - } - } - } - } -} - -int KyraEngine_v1::processInputHelper(int xpos, int ypos) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::processInputHelper(%d, %d)", xpos, ypos); - uint8 item = findItemAtPos(xpos, ypos); - if (item != 0xFF) { - if (_itemInHand == -1) { - _screen->hideMouse(); - _animator->animRemoveGameItem(item); - snd_playSoundEffect(53); - assert(_currentCharacter->sceneId < _roomTableSize); - Room *currentRoom = &_roomTable[_currentCharacter->sceneId]; - int item2 = currentRoom->itemsTable[item]; - currentRoom->itemsTable[item] = 0xFF; - setMouseItem(item2); - assert(_itemList && _takenList); - updateSentenceCommand(_itemList[item2], _takenList[0], 179); - _itemInHand = item2; - _screen->showMouse(); - clickEventHandler2(); - return 1; - } else { - exchangeItemWithMouseItem(_currentCharacter->sceneId, item); - return 1; - } - } - return 0; -} - -int KyraEngine_v1::clickEventHandler(int xpos, int ypos) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::clickEventHandler(%d, %d)", xpos, ypos); - _emc->init(&_scriptClick, &_scriptClickData); - _scriptClick.regs[1] = xpos; - _scriptClick.regs[2] = ypos; - _scriptClick.regs[3] = 0; - _scriptClick.regs[4] = _itemInHand; - _emc->start(&_scriptClick, 1); - - while (_emc->isValid(&_scriptClick)) - _emc->run(&_scriptClick); - - return _scriptClick.regs[3]; -} - -void KyraEngine_v1::updateMousePointer(bool forceUpdate) { - int shape = 0; - - int newMouseState = 0; - int newX = 0; - int newY = 0; - Common::Point mouse = getMousePos(); - if (mouse.y <= 158) { - if (mouse.x >= 12) { - if (mouse.x >= 308) { - if (_walkBlockEast == 0xFFFF) { - newMouseState = -2; - } else { - newMouseState = -5; - shape = 3; - newX = 7; - newY = 5; - } - } else if (mouse.y >= 136) { - if (_walkBlockSouth == 0xFFFF) { - newMouseState = -2; - } else { - newMouseState = -4; - shape = 4; - newX = 5; - newY = 7; - } - } else if (mouse.y < 12) { - if (_walkBlockNorth == 0xFFFF) { - newMouseState = -2; - } else { - newMouseState = -6; - shape = 2; - newX = 5; - newY = 1; - } - } - } else { - if (_walkBlockWest == 0xFFFF) { - newMouseState = -2; - } else { - newMouseState = -3; - newX = 1; - newY = shape = 5; - } - } - } - - if (mouse.x >= _entranceMouseCursorTracks[0] && mouse.y >= _entranceMouseCursorTracks[1] - && mouse.x <= _entranceMouseCursorTracks[2] && mouse.y <= _entranceMouseCursorTracks[3]) { - switch (_entranceMouseCursorTracks[4]) { - case 0: - newMouseState = -6; - shape = 2; - newX = 5; - newY = 1; - break; - - case 2: - newMouseState = -5; - shape = 3; - newX = 7; - newY = 5; - break; - - case 4: - newMouseState = -4; - shape = 4; - newX = 5; - newY = 7; - break; - - case 6: - newMouseState = -3; - shape = 5; - newX = 1; - newY = 5; - break; - - default: - break; - } - } - - if (newMouseState == -2) { - shape = 6; - newX = 4; - newY = 4; - } - - if ((newMouseState && _mouseState != newMouseState) || (newMouseState && forceUpdate)) { - _mouseState = newMouseState; - _screen->hideMouse(); - _screen->setMouseCursor(newX, newY, _shapes[shape]); - _screen->showMouse(); - } - - if (!newMouseState) { - if (_mouseState != _itemInHand || forceUpdate) { - if (mouse.y > 158 || (mouse.x >= 12 && mouse.x < 308 && mouse.y < 136 && mouse.y >= 12) || forceUpdate) { - _mouseState = _itemInHand; - _screen->hideMouse(); - if (_itemInHand == -1) - _screen->setMouseCursor(1, 1, _shapes[0]); - else - _screen->setMouseCursor(8, 15, _shapes[216+_itemInHand]); - _screen->showMouse(); - } - } - } -} - -bool KyraEngine_v1::hasClickedOnExit(int xpos, int ypos) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::hasClickedOnExit(%d, %d)", xpos, ypos); - if (xpos < 16 || xpos >= 304) - return true; - - if (ypos < 8) - return true; - - if (ypos < 136 || ypos > 155) - return false; - - return true; -} - -void KyraEngine_v1::clickEventHandler2() { - debugC(9, kDebugLevelMain, "KyraEngine_v1::clickEventHandler2()"); - - Common::Point mouse = getMousePos(); - - _emc->init(&_scriptClick, &_scriptClickData); - _scriptClick.regs[0] = _currentCharacter->sceneId; - _scriptClick.regs[1] = mouse.x; - _scriptClick.regs[2] = mouse.y; - _scriptClick.regs[4] = _itemInHand; - _emc->start(&_scriptClick, 6); - - while (_emc->isValid(&_scriptClick)) - _emc->run(&_scriptClick); -} - -int KyraEngine_v1::checkForNPCScriptRun(int xpos, int ypos) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::checkForNPCScriptRun(%d, %d)", xpos, ypos); - int returnValue = -1; - const Character *currentChar = _currentCharacter; - int charLeft = 0, charRight = 0, charTop = 0, charBottom = 0; - - int scaleFactor = _scaleTable[currentChar->y1]; - int addX = (((scaleFactor*8)*3)>>8)>>1; - int addY = ((scaleFactor*3)<<4)>>8; - - charLeft = currentChar->x1 - addX; - charRight = currentChar->x1 + addX; - charTop = currentChar->y1 - addY; - charBottom = currentChar->y1; - - if (xpos >= charLeft && charRight >= xpos && charTop <= ypos && charBottom >= ypos) - return 0; - - if (xpos > 304 || xpos < 16) - return -1; - - for (int i = 1; i < 5; ++i) { - currentChar = &_characterList[i]; - - if (currentChar->sceneId != _currentCharacter->sceneId) - continue; - - charLeft = currentChar->x1 - 12; - charRight = currentChar->x1 + 11; - charTop = currentChar->y1 - 48; - // if (!i) - // charBottom = currentChar->y2 - 16; - // else - charBottom = currentChar->y1; - - if (xpos < charLeft || xpos > charRight || ypos < charTop || charBottom < ypos) - continue; - - if (returnValue != -1) { - if (currentChar->y1 >= _characterList[returnValue].y1) - returnValue = i; - } else { - returnValue = i; - } - } - - return returnValue; -} - -void KyraEngine_v1::runNpcScript(int func) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::runNpcScript(%d)", func); - _emc->init(&_npcScript, &_npcScriptData); - _emc->start(&_npcScript, func); - _npcScript.regs[0] = _currentCharacter->sceneId; - _npcScript.regs[4] = _itemInHand; - _npcScript.regs[5] = func; - - while (_emc->isValid(&_npcScript)) - _emc->run(&_npcScript); -} - -void KyraEngine_v1::checkAmuletAnimFlags() { - debugC(9, kDebugLevelMain, "KyraEngine_v1::checkSpecialAnimFlags()"); - - if (_brandonStatusBit & 2) { - seq_makeBrandonNormal2(); - _timer->setCountdown(19, 300); - } - - if (_brandonStatusBit & 0x20) { - seq_makeBrandonNormal(); - _timer->setCountdown(19, 300); - } -} - -#pragma mark - - -void KyraEngine_v1::registerDefaultSettings() { - KyraEngine::registerDefaultSettings(); - - // Most settings already have sensible defaults. This one, however, is - // specific to the Kyra engine. - ConfMan.registerDefault("walkspeed", 2); -} - -void KyraEngine_v1::readSettings() { - int talkspeed = ConfMan.getInt("talkspeed"); - - // The default talk speed is 60. This should be mapped to "Normal". - - if (talkspeed == 0) - _configTextspeed = 3; // Clickable - if (talkspeed <= 50) - _configTextspeed = 0; // Slow - else if (talkspeed <= 150) - _configTextspeed = 1; // Normal - else - _configTextspeed = 2; // Fast - - KyraEngine::readSettings(); -} - -void KyraEngine_v1::writeSettings() { - int talkspeed; - - switch (_configTextspeed) { - case 0: // Slow - talkspeed = 1; - break; - case 1: // Normal - talkspeed = 60; - break; - case 2: // Fast - talkspeed = 255; - break; - default: // Clickable - talkspeed = 0; - break; - } - - ConfMan.setInt("talkspeed", talkspeed); - - KyraEngine::writeSettings(); -} - -} // end of namespace Kyra diff --git a/engines/kyra/kyra_v1.h b/engines/kyra/kyra_v1.h deleted file mode 100644 index 801d3b9189..0000000000 --- a/engines/kyra/kyra_v1.h +++ /dev/null @@ -1,819 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#ifndef KYRA_KYRA_V1_H -#define KYRA_KYRA_V1_H - -#include "kyra/kyra.h" -#include "kyra/script.h" -#include "kyra/screen_v1.h" -#include "kyra/gui_v1.h" - -namespace Kyra { - -class Movie; -class SoundDigital; -class SeqPlayer; -class Sprites; -class Animator_v1; -class TextDisplayer; -class KyraEngine_v1; - -struct Character { - uint16 sceneId; - uint8 height; - uint8 facing; - uint16 currentAnimFrame; - uint8 inventoryItems[10]; - int16 x1, y1, x2, y2; -}; - -struct Shape { - uint8 imageIndex; - int8 xOffset, yOffset; - uint8 x, y, w, h; -}; - -struct Room { - uint8 nameIndex; - uint16 northExit; - uint16 eastExit; - uint16 southExit; - uint16 westExit; - uint8 itemsTable[12]; - uint16 itemsXPos[12]; - uint8 itemsYPos[12]; - uint8 needInit[12]; -}; - -struct Item { - uint8 unk1; - uint8 height; - uint8 unk2; - uint8 unk3; -}; - -struct SeqLoop { - const uint8 *ptr; - uint16 count; -}; - -struct SceneExits { - uint16 northXPos; - uint8 northYPos; - uint16 eastXPos; - uint8 eastYPos; - uint16 southXPos; - uint8 southYPos; - uint16 westXPos; - uint8 westYPos; -}; - -struct BeadState { - int16 x; - int16 y; - int16 width; - int16 height; - int16 dstX; - int16 dstY; - int16 width2; - int16 unk8; - int16 unk9; - int16 tableIndex; -}; - -class KyraEngine_v1 : public KyraEngine { - friend class MusicPlayer; - friend class Debugger_v1; - friend class Animator_v1; - friend class GUI_v1; -public: - KyraEngine_v1(OSystem *system, const GameFlags &flags); - ~KyraEngine_v1(); - - Screen *screen() { return _screen; } - Animator_v1 *animator() { return _animator; } - virtual Movie *createWSAMovie(); - - uint8 **shapes() { return _shapes; } - Character *currentCharacter() { return _currentCharacter; } - Character *characterList() { return _characterList; } - uint16 brandonStatus() { return _brandonStatusBit; } - - // TODO: remove me with workaround in animator.cpp l209 - uint16 getScene() { return _currentRoom; } - - int _paletteChanged; - int16 _northExitHeight; - - typedef void (KyraEngine_v1::*IntroProc)(); - - // static data access - const char * const*seqWSATable() { return _seq_WSATable; } - const char * const*seqCPSTable() { return _seq_CPSTable; } - const char * const*seqCOLTable() { return _seq_COLTable; } - const char * const*seqTextsTable() { return _seq_textsTable; } - - const uint8 * const*palTable1() { return &_specialPalettes[0]; } - const uint8 * const*palTable2() { return &_specialPalettes[29]; } - -protected: - virtual int go(); - virtual int init(); - -public: - // sequences - // -> misc - bool seq_skipSequence() const; -protected: - // -> demo - void seq_demo(); - - // -> intro - void seq_intro(); - void seq_introLogos(); - void seq_introStory(); - void seq_introMalcolmTree(); - void seq_introKallakWriting(); - void seq_introKallakMalcolm(); - - // -> ingame animations - void seq_createAmuletJewel(int jewel, int page, int noSound, int drawOnly); - void seq_brandonHealing(); - void seq_brandonHealing2(); - void seq_poisonDeathNow(int now); - void seq_poisonDeathNowAnim(); - void seq_playFluteAnimation(); - void seq_winterScroll1(); - void seq_winterScroll2(); - void seq_makeBrandonInv(); - void seq_makeBrandonNormal(); - void seq_makeBrandonNormal2(); - void seq_makeBrandonWisp(); - void seq_dispelMagicAnimation(); - void seq_fillFlaskWithWater(int item, int type); - void seq_playDrinkPotionAnim(int item, int unk2, int flags); - void seq_brandonToStone(); - - // -> end fight - int seq_playEnd(); - void seq_playEnding(); - - int handleMalcolmFlag(); - int handleBeadState(); - void initBeadState(int x, int y, int x2, int y2, int unk1, BeadState *ptr); - int processBead(int x, int y, int &x2, int &y2, BeadState *ptr); - - // -> credits - void seq_playCredits(); - -public: - // delay - void delayUntil(uint32 timestamp, bool updateGameTimers = false, bool update = false, bool isMainLoop = false); - void delay(uint32 millis, bool update = false, bool isMainLoop = false); - void delayWithTicks(int ticks); - void waitForEvent(); - - // TODO - void registerDefaultSettings(); - void readSettings(); - void writeSettings(); - - void snd_playSoundEffect(int track, int volume=0xFF); - void snd_playWanderScoreViaMap(int command, int restart); - virtual void snd_playVoiceFile(int id); - void snd_voiceWaitForFinish(bool ingame = true); - -protected: - void saveGame(const char *fileName, const char *saveName); - void loadGame(const char *fileName); - -protected: - // input - void processInput(); - int processInputHelper(int xpos, int ypos); - int clickEventHandler(int xpos, int ypos); - void clickEventHandler2(); - void updateMousePointer(bool forceUpdate = false); - bool hasClickedOnExit(int xpos, int ypos); - - bool _skipFlag; - bool skipFlag() const { return _skipFlag; } - void resetSkipFlag(bool removeEvent = true) { _skipFlag = false; } - - // scene - // -> init - void loadSceneMsc(); - void startSceneScript(int brandonAlive); - void setupSceneItems(); - void initSceneData(int facing, int unk1, int brandonAlive); - void initSceneObjectList(int brandonAlive); - void initSceneScreen(int brandonAlive); - void setupSceneResource(int sceneId); - - // -> process - void enterNewScene(int sceneId, int facing, int unk1, int unk2, int brandonAlive); - int handleSceneChange(int xpos, int ypos, int unk1, int frameReset); - int processSceneChange(int *table, int unk1, int frameReset); - int changeScene(int facing); - - // -> modification - void transcendScenes(int roomIndex, int roomName); - void setSceneFile(int roomIndex, int roomName); - - // -> pathfinder - int findWay(int x, int y, int toX, int toY, int *moveTable, int moveTableSize); - bool lineIsPassable(int x, int y); - - // -> item handling - // --> misc - void addItemToRoom(uint16 sceneId, uint8 item, int itemIndex, int x, int y); - - // --> drop handling - void itemDropDown(int x, int y, int destX, int destY, byte freeItem, int item); - int processItemDrop(uint16 sceneId, uint8 item, int x, int y, int unk1, int unk2); - void dropItem(int unk1, int item, int x, int y, int unk2); - - // --> dropped item handling - int countItemsInScene(uint16 sceneId); - void exchangeItemWithMouseItem(uint16 sceneId, int itemIndex); - byte findFreeItemInScene(int scene); - byte findItemAtPos(int x, int y); - - // --> drop area handling - void addToNoDropRects(int x, int y, int w, int h); - void clearNoDropRects(); - int isDropable(int x, int y); - int checkNoDropRects(int x, int y); - - // --> player items handling - void updatePlayerItemsForScene(); - - // --> item GFX handling - void backUpItemRect0(int xpos, int ypos); - void restoreItemRect0(int xpos, int ypos); - void backUpItemRect1(int xpos, int ypos); - void restoreItemRect1(int xpos, int ypos); - - // items - // -> misc - void placeItemInGenericMapScene(int item, int index); - - // -> mouse item - void createMouseItem(int item); - void destroyMouseItem(); - void setMouseItem(int item); - - // -> graphics effects - void wipeDownMouseItem(int xpos, int ypos); - void itemSpecialFX(int x, int y, int item); - void itemSpecialFX1(int x, int y, int item); - void itemSpecialFX2(int x, int y, int item); - void magicOutMouseItem(int animIndex, int itemPos); - void magicInMouseItem(int animIndex, int item, int itemPos); - void specialMouseItemFX(int shape, int x, int y, int animIndex, int tableIndex, int loopStart, int maxLoops); - void processSpecialMouseItemFX(int shape, int x, int y, int tableValue, int loopStart, int maxLoops); - - // character - // -> movement - void moveCharacterToPos(int character, int facing, int xpos, int ypos); - void setCharacterPositionWithUpdate(int character); - int setCharacterPosition(int character, int *facingTable); - void setCharacterPositionHelper(int character, int *facingTable); - void setCharactersPositions(int character); - - // -> brandon - void setBrandonPoisonFlags(int reset); - void resetBrandonPoisonFlags(); - - // chat - // -> process - void characterSays(int vocFile, const char *chatStr, int8 charNum, int8 chatDuration); - void waitForChatToFinish(int vocFile, int16 chatDuration, const char *str, uint8 charNum); - - // -> initialization - int initCharacterChat(int8 charNum); - void backupChatPartnerAnimFrame(int8 charNum); - void restoreChatPartnerAnimFrame(int8 charNum); - int8 getChatPartnerNum(); - - // -> deinitialization - void endCharacterChat(int8 charNum, int16 arg_4); - - // graphics - // -> misc - int findDuplicateItemShape(int shape); - void updateKyragemFading(); - - // -> interface - void loadMainScreen(int page = 3); - void redrawInventory(int page); -public: - void drawSentenceCommand(const char *sentence, int unk1); - void updateSentenceCommand(const char *str1, const char *str2, int unk1); - void updateTextFade(); - -protected: - // -> amulet - void drawJewelPress(int jewel, int drawSpecial); - void drawJewelsFadeOutStart(); - void drawJewelsFadeOutEnd(int jewel); - - // -> shape handling - void setupShapes123(const Shape *shapeTable, int endShape, int flags); - void freeShapes123(); - - // misc (TODO) - void startup(); - void mainLoop(); - - int checkForNPCScriptRun(int xpos, int ypos); - void runNpcScript(int func); - - void loadMouseShapes(); - void loadCharacterShapes(); - void loadSpecialEffectShapes(); - void loadItems(); - void loadButtonShapes(); - void initMainButtonList(); - void setCharactersInDefaultScene(); - void setupPanPages(); - void freePanPages(); - void closeFinalWsa(); - - //void setTimer19(); - void setupTimers(); - void timerUpdateHeadAnims(int timerNum); - void timerSetFlags1(int timerNum); - void timerSetFlags2(int timerNum); - void timerSetFlags3(int timerNum); - void timerCheckAnimFlag1(int timerNum); - void timerCheckAnimFlag2(int timerNum); - void checkAmuletAnimFlags(); - void timerRedrawAmulet(int timerNum); - void timerFadeText(int timerNum); - void updateAnimFlag1(int timerNum); - void updateAnimFlag2(int timerNum); - void drawAmulet(); - void setTextFadeTimerCountdown(int16 countdown); - void setWalkspeed(uint8 newSpeed); - - int buttonInventoryCallback(Button *caller); - int buttonAmuletCallback(Button *caller); - - bool _skipIntroFlag; - bool _abortIntroFlag; - bool _menuDirectlyToLoad; - bool _abortWalkFlag; - bool _abortWalkFlag2; - bool _mousePressFlag; - uint8 *_itemBkgBackUp[2]; - uint8 *_shapes[373]; - int8 _itemInHand; - int _mouseState; - bool _handleInput; - bool _changedScene; - int _unkScreenVar1, _unkScreenVar2, _unkScreenVar3; - int _beadStateVar; - int _unkAmuletVar; - - int _malcolmFlag; - int _endSequenceSkipFlag; - int _endSequenceNeedLoading; - int _unkEndSeqVar2; - uint8 *_endSequenceBackUpRect; - int _unkEndSeqVar4; - int _unkEndSeqVar5; - int _lastDisplayedPanPage; - uint8 *_panPagesTable[20]; - Movie *_finalA, *_finalB, *_finalC; - - Movie *_movieObjects[10]; - - uint16 _entranceMouseCursorTracks[8]; - uint16 _walkBlockNorth; - uint16 _walkBlockEast; - uint16 _walkBlockSouth; - uint16 _walkBlockWest; - - int32 _scaleMode; - int16 _scaleTable[145]; - - Rect _noDropRects[11]; - - int8 _birthstoneGemTable[4]; - int8 _idolGemsTable[3]; - - int8 _marbleVaseItem; - int8 _foyerItemTable[3]; - - int8 _cauldronState; - int8 _crystalState[2]; - - uint16 _brandonStatusBit; - uint8 _brandonStatusBit0x02Flag; - uint8 _brandonStatusBit0x20Flag; - uint8 _brandonPoisonFlagsGFX[256]; - uint8 _deathHandler; - int16 _brandonInvFlag; - uint8 _poisonDeathCounter; - int _brandonPosX; - int _brandonPosY; - - uint16 _currentChatPartnerBackupFrame; - uint16 _currentCharAnimFrame; - - int8 *_sceneAnimTable[50]; - - Item _itemTable[145]; - int _lastProcessedItem; - int _lastProcessedItemHeight; - - int16 *_exitListPtr; - int16 _exitList[11]; - SceneExits _sceneExits; - uint16 _currentRoom; - int _scenePhasingFlag; - - int _sceneChangeState; - int _loopFlag2; - - int _pathfinderFlag; - int _pathfinderFlag2; - int _lastFindWayRet; - int *_movFacingTable; - - int8 _talkingCharNum; - int8 _charSayUnk2; - int8 _charSayUnk3; - int8 _currHeadShape; - uint8 _currSentenceColor[3]; - int8 _startSentencePalIndex; - bool _fadeText; - - uint8 _configTextspeed; - - Animator_v1 *_animator; - SeqPlayer *_seq; - Sprites *_sprites; - Screen_v1 *_screen; - - EMCState _scriptMain; - - EMCState _npcScript; - EMCData _npcScriptData; - - EMCState _scriptClick; - EMCData _scriptClickData; - - Character *_characterList; - Character *_currentCharacter; - - Button *_buttonList; - GUI_v1 *_gui; - - struct KyragemState { - uint16 nextOperation; - uint16 rOffset; - uint16 gOffset; - uint16 bOffset; - uint32 timerCount; - } _kyragemFadingState; - - static const int8 _dosTrackMap[]; - static const int _dosTrackMapSize; - - // TODO: get rid of all variables having pointers to the static resources if possible - // i.e. let them directly use the _staticres functions - void initStaticResource(); - - const uint8 *_seq_Forest; - const uint8 *_seq_KallakWriting; - const uint8 *_seq_KyrandiaLogo; - const uint8 *_seq_KallakMalcolm; - const uint8 *_seq_MalcolmTree; - const uint8 *_seq_WestwoodLogo; - const uint8 *_seq_Demo1; - const uint8 *_seq_Demo2; - const uint8 *_seq_Demo3; - const uint8 *_seq_Demo4; - const uint8 *_seq_Reunion; - - const char * const*_seq_WSATable; - const char * const*_seq_CPSTable; - const char * const*_seq_COLTable; - const char * const*_seq_textsTable; - - int _seq_WSATable_Size; - int _seq_CPSTable_Size; - int _seq_COLTable_Size; - int _seq_textsTable_Size; - - const char * const*_itemList; - const char * const*_takenList; - const char * const*_placedList; - const char * const*_droppedList; - const char * const*_noDropList; - const char * const*_putDownFirst; - const char * const*_waitForAmulet; - const char * const*_blackJewel; - const char * const*_poisonGone; - const char * const*_healingTip; - const char * const*_thePoison; - const char * const*_fluteString; - const char * const*_wispJewelStrings; - const char * const*_magicJewelString; - const char * const*_flaskFull; - const char * const*_fullFlask; - const char * const*_veryClever; - const char * const*_homeString; - const char * const*_newGameString; - - int _itemList_Size; - int _takenList_Size; - int _placedList_Size; - int _droppedList_Size; - int _noDropList_Size; - int _putDownFirst_Size; - int _waitForAmulet_Size; - int _blackJewel_Size; - int _poisonGone_Size; - int _healingTip_Size; - int _thePoison_Size; - int _fluteString_Size; - int _wispJewelStrings_Size; - int _magicJewelString_Size; - int _flaskFull_Size; - int _fullFlask_Size; - int _veryClever_Size; - int _homeString_Size; - int _newGameString_Size; - - const char * const*_characterImageTable; - int _characterImageTableSize; - - const char * const*_guiStrings; - int _guiStringsSize; - - const char * const*_configStrings; - int _configStringsSize; - - Shape *_defaultShapeTable; - int _defaultShapeTableSize; - - const Shape *_healingShapeTable; - int _healingShapeTableSize; - const Shape *_healingShape2Table; - int _healingShape2TableSize; - - const Shape *_posionDeathShapeTable; - int _posionDeathShapeTableSize; - - const Shape *_fluteAnimShapeTable; - int _fluteAnimShapeTableSize; - - const Shape *_winterScrollTable; - int _winterScrollTableSize; - const Shape *_winterScroll1Table; - int _winterScroll1TableSize; - const Shape *_winterScroll2Table; - int _winterScroll2TableSize; - - const Shape *_drinkAnimationTable; - int _drinkAnimationTableSize; - - const Shape *_brandonToWispTable; - int _brandonToWispTableSize; - - const Shape *_magicAnimationTable; - int _magicAnimationTableSize; - - const Shape *_brandonStoneTable; - int _brandonStoneTableSize; - - Room *_roomTable; - int _roomTableSize; - const char * const*_roomFilenameTable; - int _roomFilenameTableSize; - - const uint8 *_amuleteAnim; - - const uint8 * const*_specialPalettes; - - const char *const *_soundFiles; - int _soundFilesSize; - const char *const *_soundFilesIntro; - int _soundFilesIntroSize; - const int32 *_cdaTrackTable; - int _cdaTrackTableSize; - const AudioDataStruct * _soundData; - - static const int8 _charXPosTable[]; - static const int8 _charYPosTable[]; - - // positions of the inventory - static const uint16 _itemPosX[]; - static const uint8 _itemPosY[]; - - void setupButtonData(); - Button *_buttonData; - Button **_buttonDataListPtr; - - static const uint8 _magicMouseItemStartFrame[]; - static const uint8 _magicMouseItemEndFrame[]; - static const uint8 _magicMouseItemStartFrame2[]; - static const uint8 _magicMouseItemEndFrame2[]; - - static const uint16 _amuletX[]; - static const uint16 _amuletY[]; - static const uint16 _amuletX2[]; - static const uint16 _amuletY2[]; -protected: - void setupOpcodeTable(); - - // Opcodes - int o1_magicInMouseItem(EMCState *script); - int o1_characterSays(EMCState *script); - int o1_pauseTicks(EMCState *script); - int o1_drawSceneAnimShape(EMCState *script); - int o1_queryGameFlag(EMCState *script); - int o1_setGameFlag(EMCState *script); - int o1_resetGameFlag(EMCState *script); - int o1_runNPCScript(EMCState *script); - int o1_setSpecialExitList(EMCState *script); - int o1_blockInWalkableRegion(EMCState *script); - int o1_blockOutWalkableRegion(EMCState *script); - int o1_walkPlayerToPoint(EMCState *script); - int o1_dropItemInScene(EMCState *script); - int o1_drawAnimShapeIntoScene(EMCState *script); - int o1_createMouseItem(EMCState *script); - int o1_savePageToDisk(EMCState *script); - int o1_sceneAnimOn(EMCState *script); - int o1_sceneAnimOff(EMCState *script); - int o1_getElapsedSeconds(EMCState *script); - int o1_mouseIsPointer(EMCState *script); - int o1_destroyMouseItem(EMCState *script); - int o1_runSceneAnimUntilDone(EMCState *script); - int o1_fadeSpecialPalette(EMCState *script); - int o1_playAdlibSound(EMCState *script); - int o1_playAdlibScore(EMCState *script); - int o1_phaseInSameScene(EMCState *script); - int o1_setScenePhasingFlag(EMCState *script); - int o1_resetScenePhasingFlag(EMCState *script); - int o1_queryScenePhasingFlag(EMCState *script); - int o1_sceneToDirection(EMCState *script); - int o1_setBirthstoneGem(EMCState *script); - int o1_placeItemInGenericMapScene(EMCState *script); - int o1_setBrandonStatusBit(EMCState *script); - int o1_pauseSeconds(EMCState *script); - int o1_getCharactersLocation(EMCState *script); - int o1_runNPCSubscript(EMCState *script); - int o1_magicOutMouseItem(EMCState *script); - int o1_internalAnimOn(EMCState *script); - int o1_forceBrandonToNormal(EMCState *script); - int o1_poisonDeathNow(EMCState *script); - int o1_setScaleMode(EMCState *script); - int o1_openWSAFile(EMCState *script); - int o1_closeWSAFile(EMCState *script); - int o1_runWSAFromBeginningToEnd(EMCState *script); - int o1_displayWSAFrame(EMCState *script); - int o1_enterNewScene(EMCState *script); - int o1_setSpecialEnterXAndY(EMCState *script); - int o1_runWSAFrames(EMCState *script); - int o1_popBrandonIntoScene(EMCState *script); - int o1_restoreAllObjectBackgrounds(EMCState *script); - int o1_setCustomPaletteRange(EMCState *script); - int o1_loadPageFromDisk(EMCState *script); - int o1_customPrintTalkString(EMCState *script); - int o1_restoreCustomPrintBackground(EMCState *script); - int o1_hideMouse(EMCState *script); - int o1_showMouse(EMCState *script); - int o1_getCharacterX(EMCState *script); - int o1_getCharacterY(EMCState *script); - int o1_changeCharactersFacing(EMCState *script); - int o1_copyWSARegion(EMCState *script); - int o1_printText(EMCState *script); - int o1_random(EMCState *script); - int o1_loadSoundFile(EMCState *script); - int o1_displayWSAFrameOnHidPage(EMCState *script); - int o1_displayWSASequentialFrames(EMCState *script); - int o1_drawCharacterStanding(EMCState *script); - int o1_internalAnimOff(EMCState *script); - int o1_changeCharactersXAndY(EMCState *script); - int o1_clearSceneAnimatorBeacon(EMCState *script); - int o1_querySceneAnimatorBeacon(EMCState *script); - int o1_refreshSceneAnimator(EMCState *script); - int o1_placeItemInOffScene(EMCState *script); - int o1_wipeDownMouseItem(EMCState *script); - int o1_placeCharacterInOtherScene(EMCState *script); - int o1_getKey(EMCState *script); - int o1_specificItemInInventory(EMCState *script); - int o1_popMobileNPCIntoScene(EMCState *script); - int o1_mobileCharacterInScene(EMCState *script); - int o1_hideMobileCharacter(EMCState *script); - int o1_unhideMobileCharacter(EMCState *script); - int o1_setCharactersLocation(EMCState *script); - int o1_walkCharacterToPoint(EMCState *script); - int o1_specialEventDisplayBrynnsNote(EMCState *script); - int o1_specialEventRemoveBrynnsNote(EMCState *script); - int o1_setLogicPage(EMCState *script); - int o1_fatPrint(EMCState *script); - int o1_preserveAllObjectBackgrounds(EMCState *script); - int o1_updateSceneAnimations(EMCState *script); - int o1_sceneAnimationActive(EMCState *script); - int o1_setCharactersMovementDelay(EMCState *script); - int o1_getCharactersFacing(EMCState *script); - int o1_bkgdScrollSceneAndMasksRight(EMCState *script); - int o1_dispelMagicAnimation(EMCState *script); - int o1_findBrightestFireberry(EMCState *script); - int o1_setFireberryGlowPalette(EMCState *script); - int o1_setDeathHandlerFlag(EMCState *script); - int o1_drinkPotionAnimation(EMCState *script); - int o1_makeAmuletAppear(EMCState *script); - int o1_drawItemShapeIntoScene(EMCState *script); - int o1_setCharactersCurrentFrame(EMCState *script); - int o1_waitForConfirmationMouseClick(EMCState *script); - int o1_pageFlip(EMCState *script); - int o1_setSceneFile(EMCState *script); - int o1_getItemInMarbleVase(EMCState *script); - int o1_setItemInMarbleVase(EMCState *script); - int o1_addItemToInventory(EMCState *script); - int o1_intPrint(EMCState *script); - int o1_shakeScreen(EMCState *script); - int o1_createAmuletJewel(EMCState *script); - int o1_setSceneAnimCurrXY(EMCState *script); - int o1_poisonBrandonAndRemaps(EMCState *script); - int o1_fillFlaskWithWater(EMCState *script); - int o1_getCharactersMovementDelay(EMCState *script); - int o1_getBirthstoneGem(EMCState *script); - int o1_queryBrandonStatusBit(EMCState *script); - int o1_playFluteAnimation(EMCState *script); - int o1_playWinterScrollSequence(EMCState *script); - int o1_getIdolGem(EMCState *script); - int o1_setIdolGem(EMCState *script); - int o1_totalItemsInScene(EMCState *script); - int o1_restoreBrandonsMovementDelay(EMCState *script); - int o1_setMousePos(EMCState *script); - int o1_getMouseState(EMCState *script); - int o1_setEntranceMouseCursorTrack(EMCState *script); - int o1_itemAppearsOnGround(EMCState *script); - int o1_setNoDrawShapesFlag(EMCState *script); - int o1_fadeEntirePalette(EMCState *script); - int o1_itemOnGroundHere(EMCState *script); - int o1_queryCauldronState(EMCState *script); - int o1_setCauldronState(EMCState *script); - int o1_queryCrystalState(EMCState *script); - int o1_setCrystalState(EMCState *script); - int o1_setPaletteRange(EMCState *script); - int o1_shrinkBrandonDown(EMCState *script); - int o1_growBrandonUp(EMCState *script); - int o1_setBrandonScaleXAndY(EMCState *script); - int o1_resetScaleMode(EMCState *script); - int o1_getScaleDepthTableValue(EMCState *script); - int o1_setScaleDepthTableValue(EMCState *script); - int o1_message(EMCState *script); - int o1_checkClickOnNPC(EMCState *script); - int o1_getFoyerItem(EMCState *script); - int o1_setFoyerItem(EMCState *script); - int o1_setNoItemDropRegion(EMCState *script); - int o1_walkMalcolmOn(EMCState *script); - int o1_passiveProtection(EMCState *script); - int o1_setPlayingLoop(EMCState *script); - int o1_brandonToStoneSequence(EMCState *script); - int o1_brandonHealingSequence(EMCState *script); - int o1_protectCommandLine(EMCState *script); - int o1_pauseMusicSeconds(EMCState *script); - int o1_resetMaskRegion(EMCState *script); - int o1_setPaletteChangeFlag(EMCState *script); - int o1_fillRect(EMCState *script); - int o1_dummy(EMCState *script); - int o1_vocUnload(EMCState *script); - int o1_vocLoad(EMCState *script); -}; - -} // end of namespace Kyra - -#endif - diff --git a/engines/kyra/kyra_v2.h b/engines/kyra/kyra_v2.h index 3b7aac91ba..484e044ac7 100644 --- a/engines/kyra/kyra_v2.h +++ b/engines/kyra/kyra_v2.h @@ -230,7 +230,7 @@ protected: }; SceneAnim _sceneAnims[16]; - WSAMovieV2 *_sceneAnimMovie[16]; + WSAMovie_v2 *_sceneAnimMovie[16]; void freeSceneAnims(); diff --git a/engines/kyra/module.mk b/engines/kyra/module.mk index aec2778def..2a0e2adf41 100644 --- a/engines/kyra/module.mk +++ b/engines/kyra/module.mk @@ -1,49 +1,49 @@ MODULE := engines/kyra MODULE_OBJS := \ - animator_v1.o \ + animator_lok.o \ animator_v2.o \ animator_hof.o \ animator_mr.o \ debugger.o \ detection.o \ gui.o \ - gui_v1.o \ + gui_lok.o \ gui_v2.o \ gui_hof.o \ gui_mr.o \ - items_v1.o \ + items_lok.o \ items_v2.o \ items_hof.o \ items_mr.o \ kyra.o \ - kyra_v1.o \ + kyra_lok.o \ kyra_v2.o \ kyra_hof.o \ kyra_mr.o \ resource.o \ saveload.o \ - saveload_v1.o \ + saveload_lok.o \ saveload_hof.o \ saveload_mr.o \ scene.o \ - scene_v1.o \ + scene_lok.o \ scene_v2.o \ scene_hof.o \ scene_mr.o \ screen.o \ - screen_v1.o \ + screen_lok.o \ screen_v2.o \ screen_hof.o \ screen_mr.o \ - script_v1.o \ + script_lok.o \ script_v2.o \ script_hof.o \ script_mr.o \ script.o \ script_tim.o \ seqplayer.o \ - sequences_v1.o \ + sequences_lok.o \ sequences_v2.o \ sequences_hof.o \ sequences_mr.o \ @@ -51,15 +51,15 @@ MODULE_OBJS := \ sound_digital.o \ sound_towns.o \ sound.o \ - sound_v1.o \ + sound_lok.o \ sprites.o \ staticres.o \ text.o \ - text_v1.o \ + text_lok.o \ text_hof.o \ text_mr.o \ timer.o \ - timer_v1.o \ + timer_lok.o \ timer_hof.o \ timer_mr.o \ vqa.o \ diff --git a/engines/kyra/saveload_lok.cpp b/engines/kyra/saveload_lok.cpp new file mode 100644 index 0000000000..6f1fc484fd --- /dev/null +++ b/engines/kyra/saveload_lok.cpp @@ -0,0 +1,300 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "common/endian.h" +#include "common/savefile.h" +#include "common/system.h" + +#include "kyra/kyra_lok.h" +#include "kyra/animator_lok.h" +#include "kyra/screen.h" +#include "kyra/resource.h" +#include "kyra/sound.h" +#include "kyra/timer.h" + +namespace Kyra { +void KyraEngine_LoK::loadGame(const char *fileName) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::loadGame('%s')", fileName); + + SaveHeader header; + Common::InSaveFile *in = openSaveForReading(fileName, header); + if (!in) { + warning("Can't open file '%s', game not loadable", fileName); + return; + } + + if (header.originalSave) { + // no support for original savefile in Kyrandia 1 (yet) + delete in; + return; + } + + snd_playSoundEffect(0x0A); + snd_playWanderScoreViaMap(0, 1); + + // unload the current voice file should fix some problems with voices + if (_currentRoom != 0xFFFF && _flags.isTalkie) { + char file[32]; + assert(_currentRoom < _roomTableSize); + int tableId = _roomTable[_currentRoom].nameIndex; + assert(tableId < _roomFilenameTableSize); + strcpy(file, _roomFilenameTable[tableId]); + strcat(file, ".VRM"); + _res->unloadPakFile(file); + } + + int brandonX = 0, brandonY = 0; + for (int i = 0; i < 11; i++) { + _characterList[i].sceneId = in->readUint16BE(); + _characterList[i].height = in->readByte(); + _characterList[i].facing = in->readByte(); + _characterList[i].currentAnimFrame = in->readUint16BE(); + //_characterList[i].unk6 = in->readUint32BE(); + in->read(_characterList[i].inventoryItems, 10); + _characterList[i].x1 = in->readSint16BE(); + _characterList[i].y1 = in->readSint16BE(); + _characterList[i].x2 = in->readSint16BE(); + _characterList[i].y2 = in->readSint16BE(); + if (i == 0) { + brandonX = _characterList[i].x1; + brandonY = _characterList[i].y1; + } + //_characterList[i].field_20 = in->readUint16BE(); + //_characterList[i].field_23 = in->readUint16BE(); + } + + _marbleVaseItem = in->readSint16BE(); + _itemInHand = in->readByte(); + + for (int i = 0; i < 4; ++i) + _birthstoneGemTable[i] = in->readByte(); + for (int i = 0; i < 3; ++i) + _idolGemsTable[i] = in->readByte(); + for (int i = 0; i < 3; ++i) + _foyerItemTable[i] = in->readByte(); + _cauldronState = in->readByte(); + for (int i = 0; i < 2; ++i) + _crystalState[i] = in->readByte(); + + _brandonStatusBit = in->readUint16BE(); + _brandonStatusBit0x02Flag = in->readByte(); + _brandonStatusBit0x20Flag = in->readByte(); + in->read(_brandonPoisonFlagsGFX, 256); + _brandonInvFlag = in->readSint16BE(); + _poisonDeathCounter = in->readByte(); + _animator->_brandonDrawFrame = in->readUint16BE(); + + _timer->loadDataFromFile(*in, header.version); + + memset(_flagsTable, 0, sizeof(_flagsTable)); + uint32 flagsSize = in->readUint32BE(); + assert(flagsSize <= sizeof(_flagsTable)); + in->read(_flagsTable, flagsSize); + + for (int i = 0; i < _roomTableSize; ++i) { + for (int item = 0; item < 12; ++item) { + _roomTable[i].itemsTable[item] = 0xFF; + _roomTable[i].itemsXPos[item] = 0xFFFF; + _roomTable[i].itemsYPos[item] = 0xFF; + _roomTable[i].needInit[item] = 0; + } + } + + uint16 sceneId = 0; + + while (true) { + sceneId = in->readUint16BE(); + if (sceneId == 0xFFFF) + break; + assert(sceneId < _roomTableSize); + _roomTable[sceneId].nameIndex = in->readByte(); + + for (int i = 0; i < 12; i++) { + _roomTable[sceneId].itemsTable[i] = in->readByte(); + _roomTable[sceneId].itemsXPos[i] = in->readUint16BE(); + _roomTable[sceneId].itemsYPos[i] = in->readUint16BE(); + _roomTable[sceneId].needInit[i] = in->readByte(); + } + } + if (header.version >= 3) { + _lastMusicCommand = in->readSint16BE(); + if (_lastMusicCommand != -1) + snd_playWanderScoreViaMap(_lastMusicCommand, 1); + } + + // Version 4 stored settings in the savegame. As of version 5, they are + // handled by the config manager. + + if (header.version == 4) { + in->readByte(); // Text speed + in->readByte(); // Walk speed + in->readByte(); // Music + in->readByte(); // Sound + in->readByte(); // Voice + } + + if (header.version >= 7) { + _curSfxFile = in->readByte(); + + // In the first version when this entry was introduced, + // it wasn't made sure that _curSfxFile was initialized + // so if it's out of bounds we just set it to 0. + if (_flags.platform == Common::kPlatformFMTowns || _flags.platform == Common::kPlatformPC98) { + if (_curSfxFile >= _soundData->_fileListLen || _curSfxFile < 0) + _curSfxFile = 0; + _sound->loadSoundFile(_curSfxFile); + } + } + + _screen->_disableScreen = true; + loadMainScreen(8); + + if (queryGameFlag(0x2D)) { + _screen->loadBitmap("AMULET3.CPS", 10, 10, 0); + if (!queryGameFlag(0xF1)) { + for (int i = 0x55; i <= 0x5A; ++i) { + if (queryGameFlag(i)) + seq_createAmuletJewel(i-0x55, 10, 1, 1); + } + } + _screen->copyRegion(0, 0, 0, 0, 320, 200, 10, 8); + _screen->copyRegion(0, 0, 0, 0, 320, 200, 8, 0); + } + + createMouseItem(_itemInHand); + _animator->setBrandonAnimSeqSize(3, 48); + redrawInventory(0); + _animator->_noDrawShapesFlag = 1; + enterNewScene(_currentCharacter->sceneId, _currentCharacter->facing, 0, 0, 1); + _animator->_noDrawShapesFlag = 0; + + _currentCharacter->x1 = brandonX; + _currentCharacter->y1 = brandonY; + _animator->animRefreshNPC(0); + _animator->restoreAllObjectBackgrounds(); + _animator->preserveAnyChangedBackgrounds(); + _animator->prepDrawAllObjects(); + _animator->copyChangedObjectsForward(0); + _screen->copyRegion(8, 8, 8, 8, 304, 128, 2, 0); + _screen->_disableScreen = false; + _screen->updateScreen(); + + _abortWalkFlag = true; + _abortWalkFlag2 = false; + _mousePressFlag = false; + setMousePos(brandonX, brandonY); + + if (in->ioFailed()) + error("Load failed ('%s', '%s').", fileName, header.description.c_str()); + else + debugC(1, kDebugLevelMain, "Loaded savegame '%s.'", header.description.c_str()); + + // We didn't explicitly set the walk speed, but it's saved as part of + // the _timers array, so we need to re-sync it with _configWalkspeed. + setWalkspeed(_configWalkspeed); + + delete in; +} + +void KyraEngine_LoK::saveGame(const char *fileName, const char *saveName) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::saveGame('%s', '%s')", fileName, saveName); + + if (_quitFlag) + return; + + Common::OutSaveFile *out = openSaveForWriting(fileName, saveName); + if (!out) + return; + + for (int i = 0; i < 11; i++) { + out->writeUint16BE(_characterList[i].sceneId); + out->writeByte(_characterList[i].height); + out->writeByte(_characterList[i].facing); + out->writeUint16BE(_characterList[i].currentAnimFrame); + //out->writeUint32BE(_characterList[i].unk6); + out->write(_characterList[i].inventoryItems, 10); + out->writeSint16BE(_characterList[i].x1); + out->writeSint16BE(_characterList[i].y1); + out->writeSint16BE(_characterList[i].x2); + out->writeSint16BE(_characterList[i].y2); + //out->writeUint16BE(_characterList[i].field_20); + //out->writeUint16BE(_characterList[i].field_23); + } + + out->writeSint16BE(_marbleVaseItem); + out->writeByte(_itemInHand); + + for (int i = 0; i < 4; ++i) + out->writeByte(_birthstoneGemTable[i]); + for (int i = 0; i < 3; ++i) + out->writeByte(_idolGemsTable[i]); + for (int i = 0; i < 3; ++i) + out->writeByte(_foyerItemTable[i]); + out->writeByte(_cauldronState); + for (int i = 0; i < 2; ++i) + out->writeByte(_crystalState[i]); + + out->writeUint16BE(_brandonStatusBit); + out->writeByte(_brandonStatusBit0x02Flag); + out->writeByte(_brandonStatusBit0x20Flag); + out->write(_brandonPoisonFlagsGFX, 256); + out->writeSint16BE(_brandonInvFlag); + out->writeByte(_poisonDeathCounter); + out->writeUint16BE(_animator->_brandonDrawFrame); + + _timer->saveDataToFile(*out); + + out->writeUint32BE(sizeof(_flagsTable)); + out->write(_flagsTable, sizeof(_flagsTable)); + + for (uint16 i = 0; i < _roomTableSize; i++) { + out->writeUint16BE(i); + out->writeByte(_roomTable[i].nameIndex); + for (int a = 0; a < 12; a++) { + out->writeByte(_roomTable[i].itemsTable[a]); + out->writeUint16BE(_roomTable[i].itemsXPos[a]); + out->writeUint16BE(_roomTable[i].itemsYPos[a]); + out->writeByte(_roomTable[i].needInit[a]); + } + } + // room table terminator + out->writeUint16BE(0xFFFF); + + out->writeSint16BE(_lastMusicCommand); + + out->writeByte(_curSfxFile); + + out->finalize(); + + // check for errors + if (out->ioFailed()) + warning("Can't write file '%s'. (Disk full?)", fileName); + else + debugC(1, kDebugLevelMain, "Saved game '%s.'", saveName); + + delete out; +} +} // end of namespace Kyra + diff --git a/engines/kyra/saveload_v1.cpp b/engines/kyra/saveload_v1.cpp deleted file mode 100644 index 7e871876a0..0000000000 --- a/engines/kyra/saveload_v1.cpp +++ /dev/null @@ -1,300 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include "common/endian.h" -#include "common/savefile.h" -#include "common/system.h" - -#include "kyra/kyra_v1.h" -#include "kyra/animator_v1.h" -#include "kyra/screen.h" -#include "kyra/resource.h" -#include "kyra/sound.h" -#include "kyra/timer.h" - -namespace Kyra { -void KyraEngine_v1::loadGame(const char *fileName) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::loadGame('%s')", fileName); - - SaveHeader header; - Common::InSaveFile *in = openSaveForReading(fileName, header); - if (!in) { - warning("Can't open file '%s', game not loadable", fileName); - return; - } - - if (header.originalSave) { - // no support for original savefile in Kyrandia 1 (yet) - delete in; - return; - } - - snd_playSoundEffect(0x0A); - snd_playWanderScoreViaMap(0, 1); - - // unload the current voice file should fix some problems with voices - if (_currentRoom != 0xFFFF && _flags.isTalkie) { - char file[32]; - assert(_currentRoom < _roomTableSize); - int tableId = _roomTable[_currentRoom].nameIndex; - assert(tableId < _roomFilenameTableSize); - strcpy(file, _roomFilenameTable[tableId]); - strcat(file, ".VRM"); - _res->unloadPakFile(file); - } - - int brandonX = 0, brandonY = 0; - for (int i = 0; i < 11; i++) { - _characterList[i].sceneId = in->readUint16BE(); - _characterList[i].height = in->readByte(); - _characterList[i].facing = in->readByte(); - _characterList[i].currentAnimFrame = in->readUint16BE(); - //_characterList[i].unk6 = in->readUint32BE(); - in->read(_characterList[i].inventoryItems, 10); - _characterList[i].x1 = in->readSint16BE(); - _characterList[i].y1 = in->readSint16BE(); - _characterList[i].x2 = in->readSint16BE(); - _characterList[i].y2 = in->readSint16BE(); - if (i == 0) { - brandonX = _characterList[i].x1; - brandonY = _characterList[i].y1; - } - //_characterList[i].field_20 = in->readUint16BE(); - //_characterList[i].field_23 = in->readUint16BE(); - } - - _marbleVaseItem = in->readSint16BE(); - _itemInHand = in->readByte(); - - for (int i = 0; i < 4; ++i) - _birthstoneGemTable[i] = in->readByte(); - for (int i = 0; i < 3; ++i) - _idolGemsTable[i] = in->readByte(); - for (int i = 0; i < 3; ++i) - _foyerItemTable[i] = in->readByte(); - _cauldronState = in->readByte(); - for (int i = 0; i < 2; ++i) - _crystalState[i] = in->readByte(); - - _brandonStatusBit = in->readUint16BE(); - _brandonStatusBit0x02Flag = in->readByte(); - _brandonStatusBit0x20Flag = in->readByte(); - in->read(_brandonPoisonFlagsGFX, 256); - _brandonInvFlag = in->readSint16BE(); - _poisonDeathCounter = in->readByte(); - _animator->_brandonDrawFrame = in->readUint16BE(); - - _timer->loadDataFromFile(*in, header.version); - - memset(_flagsTable, 0, sizeof(_flagsTable)); - uint32 flagsSize = in->readUint32BE(); - assert(flagsSize <= sizeof(_flagsTable)); - in->read(_flagsTable, flagsSize); - - for (int i = 0; i < _roomTableSize; ++i) { - for (int item = 0; item < 12; ++item) { - _roomTable[i].itemsTable[item] = 0xFF; - _roomTable[i].itemsXPos[item] = 0xFFFF; - _roomTable[i].itemsYPos[item] = 0xFF; - _roomTable[i].needInit[item] = 0; - } - } - - uint16 sceneId = 0; - - while (true) { - sceneId = in->readUint16BE(); - if (sceneId == 0xFFFF) - break; - assert(sceneId < _roomTableSize); - _roomTable[sceneId].nameIndex = in->readByte(); - - for (int i = 0; i < 12; i++) { - _roomTable[sceneId].itemsTable[i] = in->readByte(); - _roomTable[sceneId].itemsXPos[i] = in->readUint16BE(); - _roomTable[sceneId].itemsYPos[i] = in->readUint16BE(); - _roomTable[sceneId].needInit[i] = in->readByte(); - } - } - if (header.version >= 3) { - _lastMusicCommand = in->readSint16BE(); - if (_lastMusicCommand != -1) - snd_playWanderScoreViaMap(_lastMusicCommand, 1); - } - - // Version 4 stored settings in the savegame. As of version 5, they are - // handled by the config manager. - - if (header.version == 4) { - in->readByte(); // Text speed - in->readByte(); // Walk speed - in->readByte(); // Music - in->readByte(); // Sound - in->readByte(); // Voice - } - - if (header.version >= 7) { - _curSfxFile = in->readByte(); - - // In the first version when this entry was introduced, - // it wasn't made sure that _curSfxFile was initialized - // so if it's out of bounds we just set it to 0. - if (_flags.platform == Common::kPlatformFMTowns || _flags.platform == Common::kPlatformPC98) { - if (_curSfxFile >= _soundData->_fileListLen || _curSfxFile < 0) - _curSfxFile = 0; - _sound->loadSoundFile(_curSfxFile); - } - } - - _screen->_disableScreen = true; - loadMainScreen(8); - - if (queryGameFlag(0x2D)) { - _screen->loadBitmap("AMULET3.CPS", 10, 10, 0); - if (!queryGameFlag(0xF1)) { - for (int i = 0x55; i <= 0x5A; ++i) { - if (queryGameFlag(i)) - seq_createAmuletJewel(i-0x55, 10, 1, 1); - } - } - _screen->copyRegion(0, 0, 0, 0, 320, 200, 10, 8); - _screen->copyRegion(0, 0, 0, 0, 320, 200, 8, 0); - } - - createMouseItem(_itemInHand); - _animator->setBrandonAnimSeqSize(3, 48); - redrawInventory(0); - _animator->_noDrawShapesFlag = 1; - enterNewScene(_currentCharacter->sceneId, _currentCharacter->facing, 0, 0, 1); - _animator->_noDrawShapesFlag = 0; - - _currentCharacter->x1 = brandonX; - _currentCharacter->y1 = brandonY; - _animator->animRefreshNPC(0); - _animator->restoreAllObjectBackgrounds(); - _animator->preserveAnyChangedBackgrounds(); - _animator->prepDrawAllObjects(); - _animator->copyChangedObjectsForward(0); - _screen->copyRegion(8, 8, 8, 8, 304, 128, 2, 0); - _screen->_disableScreen = false; - _screen->updateScreen(); - - _abortWalkFlag = true; - _abortWalkFlag2 = false; - _mousePressFlag = false; - setMousePos(brandonX, brandonY); - - if (in->ioFailed()) - error("Load failed ('%s', '%s').", fileName, header.description.c_str()); - else - debugC(1, kDebugLevelMain, "Loaded savegame '%s.'", header.description.c_str()); - - // We didn't explicitly set the walk speed, but it's saved as part of - // the _timers array, so we need to re-sync it with _configWalkspeed. - setWalkspeed(_configWalkspeed); - - delete in; -} - -void KyraEngine_v1::saveGame(const char *fileName, const char *saveName) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::saveGame('%s', '%s')", fileName, saveName); - - if (_quitFlag) - return; - - Common::OutSaveFile *out = openSaveForWriting(fileName, saveName); - if (!out) - return; - - for (int i = 0; i < 11; i++) { - out->writeUint16BE(_characterList[i].sceneId); - out->writeByte(_characterList[i].height); - out->writeByte(_characterList[i].facing); - out->writeUint16BE(_characterList[i].currentAnimFrame); - //out->writeUint32BE(_characterList[i].unk6); - out->write(_characterList[i].inventoryItems, 10); - out->writeSint16BE(_characterList[i].x1); - out->writeSint16BE(_characterList[i].y1); - out->writeSint16BE(_characterList[i].x2); - out->writeSint16BE(_characterList[i].y2); - //out->writeUint16BE(_characterList[i].field_20); - //out->writeUint16BE(_characterList[i].field_23); - } - - out->writeSint16BE(_marbleVaseItem); - out->writeByte(_itemInHand); - - for (int i = 0; i < 4; ++i) - out->writeByte(_birthstoneGemTable[i]); - for (int i = 0; i < 3; ++i) - out->writeByte(_idolGemsTable[i]); - for (int i = 0; i < 3; ++i) - out->writeByte(_foyerItemTable[i]); - out->writeByte(_cauldronState); - for (int i = 0; i < 2; ++i) - out->writeByte(_crystalState[i]); - - out->writeUint16BE(_brandonStatusBit); - out->writeByte(_brandonStatusBit0x02Flag); - out->writeByte(_brandonStatusBit0x20Flag); - out->write(_brandonPoisonFlagsGFX, 256); - out->writeSint16BE(_brandonInvFlag); - out->writeByte(_poisonDeathCounter); - out->writeUint16BE(_animator->_brandonDrawFrame); - - _timer->saveDataToFile(*out); - - out->writeUint32BE(sizeof(_flagsTable)); - out->write(_flagsTable, sizeof(_flagsTable)); - - for (uint16 i = 0; i < _roomTableSize; i++) { - out->writeUint16BE(i); - out->writeByte(_roomTable[i].nameIndex); - for (int a = 0; a < 12; a++) { - out->writeByte(_roomTable[i].itemsTable[a]); - out->writeUint16BE(_roomTable[i].itemsXPos[a]); - out->writeUint16BE(_roomTable[i].itemsYPos[a]); - out->writeByte(_roomTable[i].needInit[a]); - } - } - // room table terminator - out->writeUint16BE(0xFFFF); - - out->writeSint16BE(_lastMusicCommand); - - out->writeByte(_curSfxFile); - - out->finalize(); - - // check for errors - if (out->ioFailed()) - warning("Can't write file '%s'. (Disk full?)", fileName); - else - debugC(1, kDebugLevelMain, "Saved game '%s.'", saveName); - - delete out; -} -} // end of namespace Kyra - diff --git a/engines/kyra/scene_hof.cpp b/engines/kyra/scene_hof.cpp index b072a76e66..1882386b03 100644 --- a/engines/kyra/scene_hof.cpp +++ b/engines/kyra/scene_hof.cpp @@ -98,7 +98,7 @@ void KyraEngine_HoF::enterNewScene(uint16 newScene, int facing, int unk1, int un _emc->run(&_sceneScriptState); } - Common::for_each(_wsaSlots, _wsaSlots+ARRAYSIZE(_wsaSlots), Common::mem_fun(&WSAMovieV2::close)); + Common::for_each(_wsaSlots, _wsaSlots+ARRAYSIZE(_wsaSlots), Common::mem_fun(&WSAMovie_v2::close)); _specialExitCount = 0; memset(_specialExitTable, -1, sizeof(_specialExitTable)); diff --git a/engines/kyra/scene_lok.cpp b/engines/kyra/scene_lok.cpp new file mode 100644 index 0000000000..36535eba60 --- /dev/null +++ b/engines/kyra/scene_lok.cpp @@ -0,0 +1,1284 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "kyra/kyra_lok.h" +#include "kyra/seqplayer.h" +#include "kyra/screen.h" +#include "kyra/resource.h" +#include "kyra/sound.h" +#include "kyra/sprites.h" +#include "kyra/wsamovie.h" +#include "kyra/animator_lok.h" +#include "kyra/text.h" +#include "kyra/script.h" +#include "kyra/timer.h" + +#include "common/system.h" +#include "common/savefile.h" + +namespace Kyra { + +void KyraEngine_LoK::enterNewScene(int sceneId, int facing, int unk1, int unk2, int brandonAlive) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::enterNewScene(%d, %d, %d, %d, %d)", sceneId, facing, unk1, unk2, brandonAlive); + int unkVar1 = 1; + _screen->hideMouse(); + _handleInput = false; + _abortWalkFlag = false; + _abortWalkFlag2 = false; + + if (_flags.platform == Common::kPlatformFMTowns || _flags.platform == Common::kPlatformPC98) { + int newSfxFile = -1; + if (_currentCharacter->sceneId == 7 && sceneId == 24) + newSfxFile = 2; + else if (_currentCharacter->sceneId == 25 && sceneId == 109) + newSfxFile = 3; + else if (_currentCharacter->sceneId == 120 && sceneId == 37) + newSfxFile = 4; + else if (_currentCharacter->sceneId == 52 && sceneId == 199) + newSfxFile = 5; + else if (_currentCharacter->sceneId == 37 && sceneId == 120) + newSfxFile = 3; + else if (_currentCharacter->sceneId == 109 && sceneId == 25) + newSfxFile = 2; + else if (_currentCharacter->sceneId == 24 && sceneId == 7) + newSfxFile = 1; + + if (newSfxFile != -1) { + _curSfxFile = newSfxFile; + _sound->loadSoundFile(_curSfxFile); + } + } + + switch (_currentCharacter->sceneId) { + case 1: + if (sceneId == 0) { + moveCharacterToPos(0, 0, _currentCharacter->x1, 84); + unkVar1 = 0; + } + break; + + case 3: + if (sceneId == 2) { + moveCharacterToPos(0, 6, 155, _currentCharacter->y1); + unkVar1 = 0; + } + break; + + case 26: + if (sceneId == 27) { + moveCharacterToPos(0, 6, 155, _currentCharacter->y1); + unkVar1 = 0; + } + break; + + case 44: + if (sceneId == 45) { + moveCharacterToPos(0, 2, 192, _currentCharacter->y1); + unkVar1 = 0; + } + break; + + default: + break; + } + + if (unkVar1 && unk1) { + int xpos = _currentCharacter->x1; + int ypos = _currentCharacter->y1; + switch (facing) { + case 0: + ypos = _currentCharacter->y1 - 6; + break; + + case 2: + xpos = 336; + break; + + case 4: + ypos = 143; + break; + + case 6: + xpos = -16; + break; + + default: + break; + } + + moveCharacterToPos(0, facing, xpos, ypos); + } + + for (int i = 0; i < ARRAYSIZE(_movieObjects); ++i) + _movieObjects[i]->close(); + + if (!brandonAlive) { + _emc->init(&_scriptClick, &_scriptClickData); + _emc->start(&_scriptClick, 5); + while (_emc->isValid(&_scriptClick)) + _emc->run(&_scriptClick); + } + + memset(_entranceMouseCursorTracks, 0xFFFF, sizeof(uint16)*4); + _currentCharacter->sceneId = sceneId; + + assert(sceneId < _roomTableSize); + assert(_roomTable[sceneId].nameIndex < _roomFilenameTableSize); + + Room *currentRoom = &_roomTable[sceneId]; + + setupSceneResource(sceneId); + + _currentRoom = sceneId; + + int tableId = _roomTable[sceneId].nameIndex; + char fileNameBuffer[32]; + strcpy(fileNameBuffer, _roomFilenameTable[tableId]); + strcat(fileNameBuffer, ".DAT"); + _sprites->loadDat(fileNameBuffer, _sceneExits); + _sprites->setupSceneAnims(); + _emc->unload(&_scriptClickData); + loadSceneMsc(); + + _walkBlockNorth = currentRoom->northExit; + _walkBlockEast = currentRoom->eastExit; + _walkBlockSouth = currentRoom->southExit; + _walkBlockWest = currentRoom->westExit; + + if (_walkBlockNorth == 0xFFFF) + _screen->blockOutRegion(0, 0, 320, (_northExitHeight & 0xFF)+3); + if (_walkBlockEast == 0xFFFF) + _screen->blockOutRegion(312, 0, 8, 139); + if (_walkBlockSouth == 0xFFFF) + _screen->blockOutRegion(0, 135, 320, 8); + if (_walkBlockWest == 0xFFFF) + _screen->blockOutRegion(0, 0, 8, 139); + + if (!brandonAlive) + updatePlayerItemsForScene(); + + startSceneScript(brandonAlive); + setupSceneItems(); + + initSceneData(facing, unk2, brandonAlive); + + _loopFlag2 = 0; + _screen->showMouse(); + if (!brandonAlive) + seq_poisonDeathNow(0); + updateMousePointer(true); + _changedScene = true; +} + +void KyraEngine_LoK::transcendScenes(int roomIndex, int roomName) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::transcendScenes(%d, %d)", roomIndex, roomName); + assert(roomIndex < _roomTableSize); + + if (_flags.isTalkie) { + char file[32]; + assert(roomIndex < _roomTableSize); + int tableId = _roomTable[roomIndex].nameIndex; + assert(tableId < _roomFilenameTableSize); + strcpy(file, _roomFilenameTable[tableId]); + strcat(file, ".VRM"); + _res->unloadPakFile(file); + } + + _roomTable[roomIndex].nameIndex = roomName; + _unkScreenVar2 = 1; + _unkScreenVar3 = 1; + _unkScreenVar1 = 0; + _brandonPosX = _currentCharacter->x1; + _brandonPosY = _currentCharacter->y1; + enterNewScene(roomIndex, _currentCharacter->facing, 0, 0, 0); + _unkScreenVar1 = 1; + _unkScreenVar2 = 0; + _unkScreenVar3 = 0; +} + +void KyraEngine_LoK::setSceneFile(int roomIndex, int roomName) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::setSceneFile(%d, %d)", roomIndex, roomName); + assert(roomIndex < _roomTableSize); + _roomTable[roomIndex].nameIndex = roomName; +} + +void KyraEngine_LoK::moveCharacterToPos(int character, int facing, int xpos, int ypos) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::moveCharacterToPos(%d, %d, %d, %d)", character, facing, xpos, ypos); + Character *ch = &_characterList[character]; + ch->facing = facing; + _screen->hideMouse(); + xpos = (int16)(xpos & 0xFFFC); + ypos = (int16)(ypos & 0xFFFE); + _timer->disable(19); + _timer->disable(14); + _timer->disable(18); + uint32 nextFrame = 0; + + switch (facing) { + case 0: + while (ypos < ch->y1) { + nextFrame = _timer->getDelay(5 + character) * _tickLength + _system->getMillis(); + setCharacterPositionWithUpdate(character); + delayUntil(nextFrame, true); + } + break; + + case 2: + while (ch->x1 < xpos) { + nextFrame = _timer->getDelay(5 + character) * _tickLength + _system->getMillis(); + setCharacterPositionWithUpdate(character); + delayUntil(nextFrame, true); + } + break; + + case 4: + while (ypos > ch->y1) { + nextFrame = _timer->getDelay(5 + character) * _tickLength + _system->getMillis(); + setCharacterPositionWithUpdate(character); + delayUntil(nextFrame, true); + } + break; + + case 6: + while (ch->x1 > xpos) { + nextFrame = _timer->getDelay(5 + character) * _tickLength + _system->getMillis(); + setCharacterPositionWithUpdate(character); + delayUntil(nextFrame, true); + } + break; + + default: + break; + } + + _timer->enable(19); + _timer->enable(14); + _timer->enable(18); + _screen->showMouse(); +} + +void KyraEngine_LoK::setCharacterPositionWithUpdate(int character) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::setCharacterPositionWithUpdate(%d)", character); + setCharacterPosition(character, 0); + _sprites->updateSceneAnims(); + _timer->update(); + _animator->updateAllObjectShapes(); + updateTextFade(); + + if (_currentCharacter->sceneId == 210) + updateKyragemFading(); +} + +int KyraEngine_LoK::setCharacterPosition(int character, int *facingTable) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::setCharacterPosition(%d, %p)", character, (const void *)facingTable); + + if (character == 0) { + _currentCharacter->x1 += _charXPosTable[_currentCharacter->facing]; + _currentCharacter->y1 += _charYPosTable[_currentCharacter->facing]; + setCharacterPositionHelper(0, facingTable); + return 1; + } else { + _characterList[character].x1 += _charXPosTable[_characterList[character].facing]; + _characterList[character].y1 += _charYPosTable[_characterList[character].facing]; + if (_characterList[character].sceneId == _currentCharacter->sceneId) + setCharacterPositionHelper(character, 0); + } + return 0; +} + +void KyraEngine_LoK::setCharacterPositionHelper(int character, int *facingTable) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::setCharacterPositionHelper(%d, %p)", character, (const void *)facingTable); + Character *ch = &_characterList[character]; + ++ch->currentAnimFrame; + int facing = ch->facing; + if (facingTable) { + if (*facingTable != *(facingTable - 1)) { + if (*(facingTable - 1) == *(facingTable + 1)) { + facing = getOppositeFacingDirection(*(facingTable - 1)); + *facingTable = *(facingTable - 1); + } + } + } + + static uint8 facingIsZero[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + static uint8 facingIsFour[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + + if (facing == 0) { + ++facingIsZero[character]; + } else { + bool resetTables = false; + if (facing != 7) { + if (facing - 1 != 0) { + if (facing != 4) { + if (facing == 3 || facing == 5) { + if (facingIsFour[character] > 2) + facing = 4; + resetTables = true; + } + } else { + ++facingIsFour[character]; + } + } else { + if (facingIsZero[character] > 2) + facing = 0; + resetTables = true; + } + } else { + if (facingIsZero[character] > 2) + facing = 0; + resetTables = true; + } + + if (resetTables) { + facingIsZero[character] = 0; + facingIsFour[character] = 0; + } + } + + static const uint16 maxAnimationFrame[] = { + 0x000F, 0x0031, 0x0055, 0x0000, 0x0000, 0x0000, + 0x0008, 0x002A, 0x004E, 0x0000, 0x0000, 0x0000, + 0x0022, 0x0046, 0x006A, 0x0000, 0x0000, 0x0000, + 0x001D, 0x0041, 0x0065, 0x0000, 0x0000, 0x0000, + 0x001F, 0x0043, 0x0067, 0x0000, 0x0000, 0x0000, + 0x0028, 0x004C, 0x0070, 0x0000, 0x0000, 0x0000, + 0x0023, 0x0047, 0x006B, 0x0000, 0x0000, 0x0000 + }; + + if (facing == 0) { + if (maxAnimationFrame[36+character] > ch->currentAnimFrame) + ch->currentAnimFrame = maxAnimationFrame[36+character]; + if (maxAnimationFrame[30+character] < ch->currentAnimFrame) + ch->currentAnimFrame = maxAnimationFrame[36+character]; + } else if (facing == 4) { + if (maxAnimationFrame[18+character] > ch->currentAnimFrame) + ch->currentAnimFrame = maxAnimationFrame[18+character]; + if (maxAnimationFrame[12+character] < ch->currentAnimFrame) + ch->currentAnimFrame = maxAnimationFrame[18+character]; + } else { + if (maxAnimationFrame[18+character] < ch->currentAnimFrame) + ch->currentAnimFrame = maxAnimationFrame[30+character]; + if (maxAnimationFrame[character] == ch->currentAnimFrame) + ch->currentAnimFrame = maxAnimationFrame[6+character]; + if (maxAnimationFrame[character] < ch->currentAnimFrame) + ch->currentAnimFrame = maxAnimationFrame[6+character]+2; + } + + if (character == 0 && (_brandonStatusBit & 0x10)) + ch->currentAnimFrame = 88; + + _animator->animRefreshNPC(character); +} + +void KyraEngine_LoK::loadSceneMsc() { + assert(_currentCharacter->sceneId < _roomTableSize); + int tableId = _roomTable[_currentCharacter->sceneId].nameIndex; + assert(tableId < _roomFilenameTableSize); + char fileNameBuffer[32]; + strcpy(fileNameBuffer, _roomFilenameTable[tableId]); + strcat(fileNameBuffer, ".MSC"); + _screen->fillRect(0, 0, 319, 199, 0, 5); + _res->exists(fileNameBuffer, true); + _screen->loadBitmap(fileNameBuffer, 3, 5, 0); +} + +void KyraEngine_LoK::startSceneScript(int brandonAlive) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::startSceneScript(%d)", brandonAlive); + assert(_currentCharacter->sceneId < _roomTableSize); + int tableId = _roomTable[_currentCharacter->sceneId].nameIndex; + assert(tableId < _roomFilenameTableSize); + char fileNameBuffer[32]; + strcpy(fileNameBuffer, _roomFilenameTable[tableId]); + strcat(fileNameBuffer, ".CPS"); + _screen->clearPage(3); + _res->exists(fileNameBuffer, true); + // FIXME: check this hack for amiga version + _screen->loadBitmap(fileNameBuffer, 3, 3, (_flags.platform == Common::kPlatformAmiga ? _screen->getPalette(0) : 0)); + _sprites->loadSceneShapes(); + _exitListPtr = 0; + + _scaleMode = 1; + for (int i = 0; i < 145; ++i) + _scaleTable[i] = 256; + + clearNoDropRects(); + _emc->init(&_scriptClick, &_scriptClickData); + strcpy(fileNameBuffer, _roomFilenameTable[tableId]); + strcat(fileNameBuffer, ".EMC"); + _res->exists(fileNameBuffer, true); + _emc->unload(&_scriptClickData); + _emc->load(fileNameBuffer, &_scriptClickData, &_opcodes); + _emc->start(&_scriptClick, 0); + _scriptClick.regs[0] = _currentCharacter->sceneId; + _scriptClick.regs[7] = brandonAlive; + + while (_emc->isValid(&_scriptClick)) + _emc->run(&_scriptClick); +} + +void KyraEngine_LoK::initSceneData(int facing, int unk1, int brandonAlive) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::initSceneData(%d, %d, %d)", facing, unk1, brandonAlive); + + int16 xpos2 = 0; + int setFacing = 1; + + int16 xpos = 0, ypos = 0; + + if (_brandonPosX == -1 && _brandonPosY == -1) { + switch (facing + 1) { + case 0: + xpos = ypos = -1; + break; + + case 1: case 2: case 8: + xpos = _sceneExits.southXPos; + ypos = _sceneExits.southYPos; + break; + + case 3: + xpos = _sceneExits.westXPos; + ypos = _sceneExits.westYPos; + break; + + case 4: case 5: case 6: + xpos = _sceneExits.northXPos; + ypos = _sceneExits.northYPos; + break; + + case 7: + xpos = _sceneExits.eastXPos; + ypos = _sceneExits.eastYPos; + break; + + default: + break; + } + + if ((uint8)(_northExitHeight & 0xFF) + 2 >= ypos) + ypos = (_northExitHeight & 0xFF) + 4; + if (xpos >= 308) + xpos = 304; + if ((uint8)(_northExitHeight >> 8) - 2 <= ypos) + ypos = (_northExitHeight >> 8) - 4; + if (xpos <= 12) + xpos = 16; + } + + if (_brandonPosX > -1) + xpos = _brandonPosX; + if (_brandonPosY > -1) + ypos = _brandonPosY; + + int16 ypos2 = 0; + if (_brandonPosX > -1 && _brandonPosY > -1) { + switch (_currentCharacter->sceneId) { + case 1: + _currentCharacter->x1 = xpos; + _currentCharacter->x2 = xpos; + _currentCharacter->y1 = ypos; + _currentCharacter->y2 = ypos; + facing = 4; + xpos2 = 192; + ypos2 = 104; + setFacing = 0; + unk1 = 1; + break; + + case 3: + _currentCharacter->x1 = xpos; + _currentCharacter->x2 = xpos; + _currentCharacter->y1 = ypos; + _currentCharacter->y2 = ypos; + facing = 2; + xpos2 = 204; + ypos2 = 94; + setFacing = 0; + unk1 = 1; + break; + + case 26: + _currentCharacter->x1 = xpos; + _currentCharacter->x2 = xpos; + _currentCharacter->y1 = ypos; + _currentCharacter->y2 = ypos; + facing = 2; + xpos2 = 192; + ypos2 = 128; + setFacing = 0; + unk1 = 1; + break; + + case 44: + _currentCharacter->x1 = xpos; + _currentCharacter->x2 = xpos; + _currentCharacter->y1 = ypos; + _currentCharacter->y2 = ypos; + facing = 6; + xpos2 = 156; + ypos2 = 96; + setFacing = 0; + unk1 = 1; + break; + + case 37: + _currentCharacter->x1 = xpos; + _currentCharacter->x2 = xpos; + _currentCharacter->y1 = ypos; + _currentCharacter->y2 = ypos; + facing = 2; + xpos2 = 148; + ypos2 = 114; + setFacing = 0; + unk1 = 1; + break; + + default: + break; + } + } + + _brandonPosX = _brandonPosY = -1; + + if (unk1 && setFacing) { + ypos2 = ypos; + xpos2 = xpos; + switch (facing) { + case 0: + ypos = 142; + break; + + case 2: + xpos = -16; + break; + + case 4: + ypos = (uint8)(_northExitHeight & 0xFF) - 4; + break; + + case 6: + xpos = 336; + break; + + default: + break; + } + } + + xpos2 = (int16)(xpos2 & 0xFFFC); + ypos2 = (int16)(ypos2 & 0xFFFE); + xpos = (int16)(xpos & 0xFFFC); + ypos = (int16)(ypos & 0xFFFE); + _currentCharacter->facing = facing; + _currentCharacter->x1 = xpos; + _currentCharacter->x2 = xpos; + _currentCharacter->y1 = ypos; + _currentCharacter->y2 = ypos; + + initSceneObjectList(brandonAlive); + + if (unk1 && brandonAlive == 0) + moveCharacterToPos(0, facing, xpos2, ypos2); + + _scriptClick.regs[4] = _itemInHand; + _scriptClick.regs[7] = brandonAlive; + _emc->start(&_scriptClick, 3); + while (_emc->isValid(&_scriptClick)) + _emc->run(&_scriptClick); +} + +void KyraEngine_LoK::initSceneObjectList(int brandonAlive) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::initSceneObjectList(%d)", brandonAlive); + for (int i = 0; i < 28; ++i) + _animator->actors()[i].active = 0; + + int startAnimFrame = 0; + + Animator_LoK::AnimObject *curAnimState = _animator->actors(); + curAnimState->active = 1; + curAnimState->drawY = _currentCharacter->y1; + curAnimState->sceneAnimPtr = _shapes[_currentCharacter->currentAnimFrame]; + curAnimState->animFrameNumber = _currentCharacter->currentAnimFrame; + startAnimFrame = _currentCharacter->currentAnimFrame-7; + int xOffset = _defaultShapeTable[startAnimFrame].xOffset; + int yOffset = _defaultShapeTable[startAnimFrame].yOffset; + + if (_scaleMode) { + curAnimState->x1 = _currentCharacter->x1; + curAnimState->y1 = _currentCharacter->y1; + + _animator->_brandonScaleX = _scaleTable[_currentCharacter->y1]; + _animator->_brandonScaleY = _scaleTable[_currentCharacter->y1]; + + curAnimState->x1 += (_animator->_brandonScaleX * xOffset) >> 8; + curAnimState->y1 += (_animator->_brandonScaleY * yOffset) >> 8; + } else { + curAnimState->x1 = _currentCharacter->x1 + xOffset; + curAnimState->y1 = _currentCharacter->y1 + yOffset; + } + + curAnimState->x2 = curAnimState->x1; + curAnimState->y2 = curAnimState->y1; + curAnimState->refreshFlag = 1; + curAnimState->bkgdChangeFlag = 1; + _animator->clearQueue(); + _animator->addObjectToQueue(curAnimState); + + int listAdded = 0; + int addedObjects = 1; + + for (int i = 1; i < 5; ++i) { + Character *ch = &_characterList[i]; + curAnimState = &_animator->actors()[addedObjects]; + if (ch->sceneId != _currentCharacter->sceneId) { + curAnimState->active = 0; + curAnimState->refreshFlag = 0; + curAnimState->bkgdChangeFlag = 0; + ++addedObjects; + continue; + } + + curAnimState->drawY = ch->y1; + curAnimState->sceneAnimPtr = _shapes[ch->currentAnimFrame]; + curAnimState->animFrameNumber = ch->currentAnimFrame; + startAnimFrame = ch->currentAnimFrame-7; + xOffset = _defaultShapeTable[startAnimFrame].xOffset; + yOffset = _defaultShapeTable[startAnimFrame].yOffset; + if (_scaleMode) { + curAnimState->x1 = ch->x1; + curAnimState->y1 = ch->y1; + + _animator->_brandonScaleX = _scaleTable[ch->y1]; + _animator->_brandonScaleY = _scaleTable[ch->y1]; + + curAnimState->x1 += (_animator->_brandonScaleX * xOffset) >> 8; + curAnimState->y1 += (_animator->_brandonScaleY * yOffset) >> 8; + } else { + curAnimState->x1 = ch->x1 + xOffset; + curAnimState->y1 = ch->y1 + yOffset; + } + curAnimState->x2 = curAnimState->x1; + curAnimState->y2 = curAnimState->y1; + curAnimState->active = 1; + curAnimState->refreshFlag = 1; + curAnimState->bkgdChangeFlag = 1; + + if (ch->facing >= 1 && ch->facing <= 3) + curAnimState->flags |= 1; + else if (ch->facing >= 5 && ch->facing <= 7) + curAnimState->flags &= 0xFFFFFFFE; + + _animator->addObjectToQueue(curAnimState); + + ++addedObjects; + ++listAdded; + if (listAdded < 2) + i = 5; + } + + for (int i = 0; i < 11; ++i) { + curAnimState = &_animator->sprites()[i]; + + if (_sprites->_anims[i].play) { + curAnimState->active = 1; + curAnimState->refreshFlag = 1; + curAnimState->bkgdChangeFlag = 1; + } else { + curAnimState->active = 0; + curAnimState->refreshFlag = 0; + curAnimState->bkgdChangeFlag = 0; + } + curAnimState->height = _sprites->_anims[i].height; + curAnimState->height2 = _sprites->_anims[i].height2; + curAnimState->width = _sprites->_anims[i].width + 1; + curAnimState->width2 = _sprites->_anims[i].width2; + curAnimState->drawY = _sprites->_anims[i].drawY; + curAnimState->x1 = curAnimState->x2 = _sprites->_anims[i].x; + curAnimState->y1 = curAnimState->y2 = _sprites->_anims[i].y; + curAnimState->background = _sprites->_anims[i].background; + curAnimState->sceneAnimPtr = _sprites->_sceneShapes[_sprites->_anims[i].sprite]; + + curAnimState->disable = _sprites->_anims[i].disable; + + if (_sprites->_anims[i].unk2) + curAnimState->flags = 0x800; + else + curAnimState->flags = 0; + + if (_sprites->_anims[i].flipX) + curAnimState->flags |= 0x1; + + _animator->addObjectToQueue(curAnimState); + } + + for (int i = 0; i < 12; ++i) { + curAnimState = &_animator->items()[i]; + Room *curRoom = &_roomTable[_currentCharacter->sceneId]; + byte curItem = curRoom->itemsTable[i]; + if (curItem != 0xFF) { + curAnimState->drawY = curRoom->itemsYPos[i]; + curAnimState->sceneAnimPtr = _shapes[216+curItem]; + curAnimState->animFrameNumber = (int16)0xFFFF; + curAnimState->y1 = curRoom->itemsYPos[i]; + curAnimState->x1 = curRoom->itemsXPos[i]; + + curAnimState->x1 -= (_animator->fetchAnimWidth(curAnimState->sceneAnimPtr, _scaleTable[curAnimState->drawY])) >> 1; + curAnimState->y1 -= _animator->fetchAnimHeight(curAnimState->sceneAnimPtr, _scaleTable[curAnimState->drawY]); + + curAnimState->x2 = curAnimState->x1; + curAnimState->y2 = curAnimState->y1; + + curAnimState->active = 1; + curAnimState->refreshFlag = 1; + curAnimState->bkgdChangeFlag = 1; + + _animator->addObjectToQueue(curAnimState); + } else { + curAnimState->active = 0; + curAnimState->refreshFlag = 0; + curAnimState->bkgdChangeFlag = 0; + } + } + + _animator->preserveAnyChangedBackgrounds(); + curAnimState = _animator->actors(); + curAnimState->bkgdChangeFlag = 1; + curAnimState->refreshFlag = 1; + for (int i = 1; i < 28; ++i) { + curAnimState = &_animator->objects()[i]; + if (curAnimState->active) { + curAnimState->bkgdChangeFlag = 1; + curAnimState->refreshFlag = 1; + } + } + _animator->restoreAllObjectBackgrounds(); + _animator->preserveAnyChangedBackgrounds(); + _animator->prepDrawAllObjects(); + initSceneScreen(brandonAlive); + _animator->copyChangedObjectsForward(0); +} + +void KyraEngine_LoK::initSceneScreen(int brandonAlive) { + if (_flags.platform == Common::kPlatformAmiga) { + if (_unkScreenVar1 && !queryGameFlag(0xF0)) { + memset(_screen->getPalette(2), 0, 32*3); + if (_currentCharacter->sceneId != 117 || !queryGameFlag(0xB3)) + _screen->setScreenPalette(_screen->getPalette(2)); + } + + if (_unkScreenVar2 == 1) + _screen->shuffleScreen(8, 8, 304, 128, 2, 0, _unkScreenVar3, false); + else + _screen->copyRegion(8, 8, 8, 8, 304, 128, 2, 0); + + if (_unkScreenVar1 && !queryGameFlag(0xA0)) { + if (_currentCharacter->sceneId == 45 && _paletteChanged) + memcpy(_screen->getPalette(0) + 12*3, _screen->getPalette(4) + 12*3, 2); + + if (_currentCharacter->sceneId >= 229 && _currentCharacter->sceneId <= 245 && (_brandonStatusBit & 1)) + memcpy(_screen->getPalette(0), _screen->getPalette(0) + 320*3, 64); + + _screen->setScreenPalette(_screen->getPalette(0)); + } + } else { + if (_unkScreenVar1 && !queryGameFlag(0xA0)) { + for (int i = 0; i < 60; ++i) { + uint16 col = _screen->getPalette(0)[684+i]; + col += _screen->getPalette(1)[684+i] << 1; + col >>= 2; + _screen->getPalette(0)[684+i] = col; + } + _screen->setScreenPalette(_screen->getPalette(0)); + } + + if (_unkScreenVar2 == 1) + _screen->shuffleScreen(8, 8, 304, 128, 2, 0, _unkScreenVar3, false); + else + _screen->copyRegion(8, 8, 8, 8, 304, 128, 2, 0); + + if (_unkScreenVar1 && _paletteChanged) { + if (!queryGameFlag(0xA0)) { + memcpy(_screen->getPalette(0) + 684, _screen->getPalette(1) + 684, 60); + _screen->setScreenPalette(_screen->getPalette(0)); + } else { + memset(_screen->getPalette(0), 0, 768); + } + } + } + + if (!_emc->start(&_scriptClick, 2)) + error("Could not start script function 2 of scene script"); + + _scriptClick.regs[7] = brandonAlive; + + while (_emc->isValid(&_scriptClick)) + _emc->run(&_scriptClick); + + setTextFadeTimerCountdown(-1); + if (_currentCharacter->sceneId == 210) { + if (_itemInHand != -1) + magicOutMouseItem(2, -1); + + _screen->hideMouse(); + for (int i = 0; i < 10; ++i) { + if (_currentCharacter->inventoryItems[i] != 0xFF) + magicOutMouseItem(2, i); + } + _screen->showMouse(); + } +} + +int KyraEngine_LoK::handleSceneChange(int xpos, int ypos, int unk1, int frameReset) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::handleSceneChange(%d, %d, %d, %d)", xpos, ypos, unk1, frameReset); + if (queryGameFlag(0xEF)) + unk1 = 0; + + int sceneId = _currentCharacter->sceneId; + _pathfinderFlag = 0; + + if (xpos < 12) { + if (_roomTable[sceneId].westExit != 0xFFFF) { + xpos = 12; + ypos = _sceneExits.westYPos; + _pathfinderFlag = 7; + } + } else if (xpos >= 308) { + if (_roomTable[sceneId].eastExit != 0xFFFF) { + xpos = 307; + ypos = _sceneExits.eastYPos; + _pathfinderFlag = 13; + } + } + + if (ypos <= (_northExitHeight&0xFF)+2) { + if (_roomTable[sceneId].northExit != 0xFFFF) { + xpos = _sceneExits.northXPos; + ypos = _northExitHeight & 0xFF; + _pathfinderFlag = 14; + } + } else if (ypos >= 136) { + if (_roomTable[sceneId].southExit != 0xFFFF) { + xpos = _sceneExits.southXPos; + ypos = 136; + _pathfinderFlag = 11; + } + } + + int temp = xpos - _currentCharacter->x1; + if (ABS(temp) < 4) { + temp = ypos - _currentCharacter->y1; + if (ABS(temp) < 2) + return 0; + } + + int x = (int16)(_currentCharacter->x1 & 0xFFFC); + int y = (int16)(_currentCharacter->y1 & 0xFFFE); + xpos = (int16)(xpos & 0xFFFC); + ypos = (int16)(ypos & 0xFFFE); + + int ret = findWay(x, y, xpos, ypos, _movFacingTable, 150); + _pathfinderFlag = 0; + + if (ret >= _lastFindWayRet) + _lastFindWayRet = ret; + + if (ret == 0x7D00 || ret == 0) + return 0; + + return processSceneChange(_movFacingTable, unk1, frameReset); +} + +int KyraEngine_LoK::processSceneChange(int *table, int unk1, int frameReset) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::processSceneChange(%p, %d, %d)", (const void *)table, unk1, frameReset); + if (queryGameFlag(0xEF)) + unk1 = 0; + + int *tableStart = table; + _sceneChangeState = 0; + _loopFlag2 = 0; + bool running = true; + int returnValue = 0; + uint32 nextFrame = 0; + _abortWalkFlag = false; + _mousePressFlag = false; + + while (running) { + if (_abortWalkFlag) { + *table = 8; + _currentCharacter->currentAnimFrame = 7; + _animator->animRefreshNPC(0); + _animator->updateAllObjectShapes(); + processInput(); + return 0; + } + bool forceContinue = false; + switch (*table) { + case 0: case 1: case 2: + case 3: case 4: case 5: + case 6: case 7: + _currentCharacter->facing = getOppositeFacingDirection(*table); + break; + + case 8: + forceContinue = true; + running = false; + break; + + default: + ++table; + forceContinue = true; + break; + } + + returnValue = changeScene(_currentCharacter->facing); + if (returnValue) { + running = false; + _abortWalkFlag = false; + } + + if (unk1) { + if (_mousePressFlag) { + running = false; + _sceneChangeState = 1; + } + } + + if (forceContinue || !running) + continue; + + int temp = 0; + if (table == tableStart || table[1] == 8) + temp = setCharacterPosition(0, 0); + else + temp = setCharacterPosition(0, table); + + if (temp) + ++table; + + nextFrame = _timer->getDelay(5) * _tickLength + _system->getMillis(); + while (_system->getMillis() < nextFrame) { + _timer->update(); + + if (_currentCharacter->sceneId == 210) { + updateKyragemFading(); + if (seq_playEnd() || _beadStateVar == 4 || _beadStateVar == 5) { + *table = 8; + running = false; + break; + } + } + + if ((nextFrame - _system->getMillis()) >= 10) + delay(10, true); + } + } + + if (frameReset && !(_brandonStatusBit & 2)) + _currentCharacter->currentAnimFrame = 7; + + _animator->animRefreshNPC(0); + _animator->updateAllObjectShapes(); + return returnValue; +} + +int KyraEngine_LoK::changeScene(int facing) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::changeScene(%d)", facing); + if (queryGameFlag(0xEF)) { + if (_currentCharacter->sceneId == 5) + return 0; + } + + int xpos = _charXPosTable[facing] + _currentCharacter->x1; + int ypos = _charYPosTable[facing] + _currentCharacter->y1; + + if (xpos >= 12 && xpos <= 308) { + if (!lineIsPassable(xpos, ypos)) + return false; + } + + if (_exitListPtr) { + int16 *ptr = _exitListPtr; + // this loop should be only entered one time, seems to be some hack in the original + while (true) { + if (*ptr == -1) + break; + + if (*ptr > _currentCharacter->x1 || _currentCharacter->y1 < ptr[1] || _currentCharacter->x1 > ptr[2] || _currentCharacter->y1 > ptr[3]) { + ptr += 10; + break; + } + + _brandonPosX = ptr[6]; + _brandonPosY = ptr[7]; + uint16 sceneId = ptr[5]; + facing = ptr[4]; + int unk1 = ptr[8]; + int unk2 = ptr[9]; + + if (sceneId == 0xFFFF) { + switch (facing) { + case 0: + sceneId = _roomTable[_currentCharacter->sceneId].northExit; + break; + + case 2: + sceneId = _roomTable[_currentCharacter->sceneId].eastExit; + break; + + case 4: + sceneId = _roomTable[_currentCharacter->sceneId].southExit; + break; + + case 6: + sceneId = _roomTable[_currentCharacter->sceneId].westExit; + break; + + default: + break; + } + } + + _currentCharacter->facing = facing; + _animator->animRefreshNPC(0); + _animator->updateAllObjectShapes(); + enterNewScene(sceneId, facing, unk1, unk2, 0); + resetGameFlag(0xEE); + return 1; + } + } + + int returnValue = 0; + facing = 0; + + if ((_northExitHeight & 0xFF) + 2 >= ypos || (_northExitHeight & 0xFF) + 2 >= _currentCharacter->y1) { + facing = 0; + returnValue = 1; + } + + if (xpos >= 308 || (_currentCharacter->x1 + 4) >= 308) { + facing = 2; + returnValue = 1; + } + + if (((_northExitHeight >> 8) & 0xFF) - 2 < ypos || ((_northExitHeight >> 8) & 0xFF) - 2 < _currentCharacter->y1) { + facing = 4; + returnValue = 1; + } + + if (xpos <= 12 || _currentCharacter->y1 <= 12) { + facing = 6; + returnValue = 1; + } + + if (!returnValue) + return 0; + + uint16 sceneId = 0xFFFF; + switch (facing) { + case 0: + sceneId = _roomTable[_currentCharacter->sceneId].northExit; + break; + + case 2: + sceneId = _roomTable[_currentCharacter->sceneId].eastExit; + break; + + case 4: + sceneId = _roomTable[_currentCharacter->sceneId].southExit; + break; + + default: + sceneId = _roomTable[_currentCharacter->sceneId].westExit; + break; + } + + if (sceneId == 0xFFFF) + return 0; + + enterNewScene(sceneId, facing, 1, 1, 0); + return returnValue; +} + +void KyraEngine_LoK::setCharactersInDefaultScene() { + static const uint32 defaultSceneTable[][4] = { + { 0xFFFF, 0x0004, 0x0003, 0xFFFF }, + { 0xFFFF, 0x0022, 0xFFFF, 0x0000 }, + { 0xFFFF, 0x001D, 0x0021, 0xFFFF }, + { 0xFFFF, 0x0000, 0x0000, 0xFFFF } + }; + + for (int i = 1; i < 5; ++i) { + Character *cur = &_characterList[i]; + //cur->field_20 = 0; + + const uint32 *curTable = defaultSceneTable[i-1]; + cur->sceneId = curTable[0]; + + if (cur->sceneId == _currentCharacter->sceneId) + //++cur->field_20; + cur->sceneId = curTable[1/*cur->field_20*/]; + + //cur->field_23 = curTable[cur->field_20+1]; + } +} + +void KyraEngine_LoK::setCharactersPositions(int character) { + static uint16 initXPosTable[] = { + 0x3200, 0x0024, 0x2230, 0x2F00, 0x0020, 0x002B, + 0x00CA, 0x00F0, 0x0082, 0x00A2, 0x0042 + }; + static uint8 initYPosTable[] = { + 0x00, 0xA2, 0x00, 0x42, 0x00, + 0x67, 0x67, 0x60, 0x5A, 0x71, + 0x76 + }; + + assert(character < ARRAYSIZE(initXPosTable)); + Character *edit = &_characterList[character]; + edit->x1 = edit->x2 = initXPosTable[character]; + edit->y1 = edit->y2 = initYPosTable[character]; +} + +#pragma mark - +#pragma mark - Pathfinder +#pragma mark - + +int KyraEngine_LoK::findWay(int x, int y, int toX, int toY, int *moveTable, int moveTableSize) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::findWay(%d, %d, %d, %d, %p, %d)", x, y, toX, toY, (const void *)moveTable, moveTableSize); + int ret = KyraEngine::findWay(x, y, toX, toY, moveTable, moveTableSize); + if (ret == 0x7D00) + return 0; + return getMoveTableSize(moveTable); +} + +bool KyraEngine_LoK::lineIsPassable(int x, int y) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::lineIsPassable(%d, %d)", x, y); + if (queryGameFlag(0xEF)) { + if (_currentCharacter->sceneId == 5) + return true; + } + + if (_pathfinderFlag & 2) { + if (x >= 312) + return false; + } + + if (_pathfinderFlag & 4) { + if (y >= 136) + return false; + } + + if (_pathfinderFlag & 8) { + if (x < 8) + return false; + } + + if (_pathfinderFlag2) { + if (x <= 8 || x >= 312) + return true; + if (y < (_northExitHeight & 0xFF) || y > 135) + return true; + } + + if (y > 137) + return false; + + if (y < 0) + y = 0; + + int ypos = 8; + if (_scaleMode) { + ypos = (_scaleTable[y] >> 5) + 1; + if (8 < ypos) + ypos = 8; + } + + x -= (ypos >> 1); + + int xpos = x; + int xtemp = xpos + ypos - 1; + if (x < 0) + xpos = 0; + + if (xtemp > 319) + xtemp = 319; + + for (; xpos < xtemp; ++xpos) { + if (!_screen->getShapeFlag1(xpos, y)) + return false; + } + return true; +} + +#pragma mark - + +void KyraEngine_LoK::setupSceneResource(int sceneId) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::setupSceneResource(%d)", sceneId); + if (!_flags.isTalkie) + return; + + if (_currentRoom != 0xFFFF) { + assert(_currentRoom < _roomTableSize); + int tableId = _roomTable[_currentRoom].nameIndex; + assert(tableId < _roomFilenameTableSize); + + // unload our old room + char file[64]; + strcpy(file, _roomFilenameTable[tableId]); + strcat(file, ".VRM"); + _res->unloadPakFile(file); + + strcpy(file, _roomFilenameTable[tableId]); + strcat(file, ".PAK"); + _res->unloadPakFile(file); + + strcpy(file, _roomFilenameTable[tableId]); + strcat(file, ".APK"); + _res->unloadPakFile(file); + } + + assert(sceneId < _roomTableSize); + int tableId = _roomTable[sceneId].nameIndex; + assert(tableId < _roomFilenameTableSize); + + // load our new room + char file[64]; + strcpy(file, _roomFilenameTable[tableId]); + strcat(file, ".VRM"); + if (_res->exists(file)) + _res->loadPakFile(file); + + strcpy(file, _roomFilenameTable[tableId]); + strcat(file, ".PAK"); + if (_res->exists(file)) + _res->loadPakFile(file); + + strcpy(file, _roomFilenameTable[tableId]); + strcat(file, ".APK"); + if (_res->exists(file)) + _res->loadPakFile(file); +} + +} // end of namespace Kyra + diff --git a/engines/kyra/scene_v1.cpp b/engines/kyra/scene_v1.cpp deleted file mode 100644 index c5d1de82a9..0000000000 --- a/engines/kyra/scene_v1.cpp +++ /dev/null @@ -1,1284 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include "kyra/kyra_v1.h" -#include "kyra/seqplayer.h" -#include "kyra/screen.h" -#include "kyra/resource.h" -#include "kyra/sound.h" -#include "kyra/sprites.h" -#include "kyra/wsamovie.h" -#include "kyra/animator_v1.h" -#include "kyra/text.h" -#include "kyra/script.h" -#include "kyra/timer.h" - -#include "common/system.h" -#include "common/savefile.h" - -namespace Kyra { - -void KyraEngine_v1::enterNewScene(int sceneId, int facing, int unk1, int unk2, int brandonAlive) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::enterNewScene(%d, %d, %d, %d, %d)", sceneId, facing, unk1, unk2, brandonAlive); - int unkVar1 = 1; - _screen->hideMouse(); - _handleInput = false; - _abortWalkFlag = false; - _abortWalkFlag2 = false; - - if (_flags.platform == Common::kPlatformFMTowns || _flags.platform == Common::kPlatformPC98) { - int newSfxFile = -1; - if (_currentCharacter->sceneId == 7 && sceneId == 24) - newSfxFile = 2; - else if (_currentCharacter->sceneId == 25 && sceneId == 109) - newSfxFile = 3; - else if (_currentCharacter->sceneId == 120 && sceneId == 37) - newSfxFile = 4; - else if (_currentCharacter->sceneId == 52 && sceneId == 199) - newSfxFile = 5; - else if (_currentCharacter->sceneId == 37 && sceneId == 120) - newSfxFile = 3; - else if (_currentCharacter->sceneId == 109 && sceneId == 25) - newSfxFile = 2; - else if (_currentCharacter->sceneId == 24 && sceneId == 7) - newSfxFile = 1; - - if (newSfxFile != -1) { - _curSfxFile = newSfxFile; - _sound->loadSoundFile(_curSfxFile); - } - } - - switch (_currentCharacter->sceneId) { - case 1: - if (sceneId == 0) { - moveCharacterToPos(0, 0, _currentCharacter->x1, 84); - unkVar1 = 0; - } - break; - - case 3: - if (sceneId == 2) { - moveCharacterToPos(0, 6, 155, _currentCharacter->y1); - unkVar1 = 0; - } - break; - - case 26: - if (sceneId == 27) { - moveCharacterToPos(0, 6, 155, _currentCharacter->y1); - unkVar1 = 0; - } - break; - - case 44: - if (sceneId == 45) { - moveCharacterToPos(0, 2, 192, _currentCharacter->y1); - unkVar1 = 0; - } - break; - - default: - break; - } - - if (unkVar1 && unk1) { - int xpos = _currentCharacter->x1; - int ypos = _currentCharacter->y1; - switch (facing) { - case 0: - ypos = _currentCharacter->y1 - 6; - break; - - case 2: - xpos = 336; - break; - - case 4: - ypos = 143; - break; - - case 6: - xpos = -16; - break; - - default: - break; - } - - moveCharacterToPos(0, facing, xpos, ypos); - } - - for (int i = 0; i < ARRAYSIZE(_movieObjects); ++i) - _movieObjects[i]->close(); - - if (!brandonAlive) { - _emc->init(&_scriptClick, &_scriptClickData); - _emc->start(&_scriptClick, 5); - while (_emc->isValid(&_scriptClick)) - _emc->run(&_scriptClick); - } - - memset(_entranceMouseCursorTracks, 0xFFFF, sizeof(uint16)*4); - _currentCharacter->sceneId = sceneId; - - assert(sceneId < _roomTableSize); - assert(_roomTable[sceneId].nameIndex < _roomFilenameTableSize); - - Room *currentRoom = &_roomTable[sceneId]; - - setupSceneResource(sceneId); - - _currentRoom = sceneId; - - int tableId = _roomTable[sceneId].nameIndex; - char fileNameBuffer[32]; - strcpy(fileNameBuffer, _roomFilenameTable[tableId]); - strcat(fileNameBuffer, ".DAT"); - _sprites->loadDat(fileNameBuffer, _sceneExits); - _sprites->setupSceneAnims(); - _emc->unload(&_scriptClickData); - loadSceneMsc(); - - _walkBlockNorth = currentRoom->northExit; - _walkBlockEast = currentRoom->eastExit; - _walkBlockSouth = currentRoom->southExit; - _walkBlockWest = currentRoom->westExit; - - if (_walkBlockNorth == 0xFFFF) - _screen->blockOutRegion(0, 0, 320, (_northExitHeight & 0xFF)+3); - if (_walkBlockEast == 0xFFFF) - _screen->blockOutRegion(312, 0, 8, 139); - if (_walkBlockSouth == 0xFFFF) - _screen->blockOutRegion(0, 135, 320, 8); - if (_walkBlockWest == 0xFFFF) - _screen->blockOutRegion(0, 0, 8, 139); - - if (!brandonAlive) - updatePlayerItemsForScene(); - - startSceneScript(brandonAlive); - setupSceneItems(); - - initSceneData(facing, unk2, brandonAlive); - - _loopFlag2 = 0; - _screen->showMouse(); - if (!brandonAlive) - seq_poisonDeathNow(0); - updateMousePointer(true); - _changedScene = true; -} - -void KyraEngine_v1::transcendScenes(int roomIndex, int roomName) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::transcendScenes(%d, %d)", roomIndex, roomName); - assert(roomIndex < _roomTableSize); - - if (_flags.isTalkie) { - char file[32]; - assert(roomIndex < _roomTableSize); - int tableId = _roomTable[roomIndex].nameIndex; - assert(tableId < _roomFilenameTableSize); - strcpy(file, _roomFilenameTable[tableId]); - strcat(file, ".VRM"); - _res->unloadPakFile(file); - } - - _roomTable[roomIndex].nameIndex = roomName; - _unkScreenVar2 = 1; - _unkScreenVar3 = 1; - _unkScreenVar1 = 0; - _brandonPosX = _currentCharacter->x1; - _brandonPosY = _currentCharacter->y1; - enterNewScene(roomIndex, _currentCharacter->facing, 0, 0, 0); - _unkScreenVar1 = 1; - _unkScreenVar2 = 0; - _unkScreenVar3 = 0; -} - -void KyraEngine_v1::setSceneFile(int roomIndex, int roomName) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::setSceneFile(%d, %d)", roomIndex, roomName); - assert(roomIndex < _roomTableSize); - _roomTable[roomIndex].nameIndex = roomName; -} - -void KyraEngine_v1::moveCharacterToPos(int character, int facing, int xpos, int ypos) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::moveCharacterToPos(%d, %d, %d, %d)", character, facing, xpos, ypos); - Character *ch = &_characterList[character]; - ch->facing = facing; - _screen->hideMouse(); - xpos = (int16)(xpos & 0xFFFC); - ypos = (int16)(ypos & 0xFFFE); - _timer->disable(19); - _timer->disable(14); - _timer->disable(18); - uint32 nextFrame = 0; - - switch (facing) { - case 0: - while (ypos < ch->y1) { - nextFrame = _timer->getDelay(5 + character) * _tickLength + _system->getMillis(); - setCharacterPositionWithUpdate(character); - delayUntil(nextFrame, true); - } - break; - - case 2: - while (ch->x1 < xpos) { - nextFrame = _timer->getDelay(5 + character) * _tickLength + _system->getMillis(); - setCharacterPositionWithUpdate(character); - delayUntil(nextFrame, true); - } - break; - - case 4: - while (ypos > ch->y1) { - nextFrame = _timer->getDelay(5 + character) * _tickLength + _system->getMillis(); - setCharacterPositionWithUpdate(character); - delayUntil(nextFrame, true); - } - break; - - case 6: - while (ch->x1 > xpos) { - nextFrame = _timer->getDelay(5 + character) * _tickLength + _system->getMillis(); - setCharacterPositionWithUpdate(character); - delayUntil(nextFrame, true); - } - break; - - default: - break; - } - - _timer->enable(19); - _timer->enable(14); - _timer->enable(18); - _screen->showMouse(); -} - -void KyraEngine_v1::setCharacterPositionWithUpdate(int character) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::setCharacterPositionWithUpdate(%d)", character); - setCharacterPosition(character, 0); - _sprites->updateSceneAnims(); - _timer->update(); - _animator->updateAllObjectShapes(); - updateTextFade(); - - if (_currentCharacter->sceneId == 210) - updateKyragemFading(); -} - -int KyraEngine_v1::setCharacterPosition(int character, int *facingTable) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::setCharacterPosition(%d, %p)", character, (const void *)facingTable); - - if (character == 0) { - _currentCharacter->x1 += _charXPosTable[_currentCharacter->facing]; - _currentCharacter->y1 += _charYPosTable[_currentCharacter->facing]; - setCharacterPositionHelper(0, facingTable); - return 1; - } else { - _characterList[character].x1 += _charXPosTable[_characterList[character].facing]; - _characterList[character].y1 += _charYPosTable[_characterList[character].facing]; - if (_characterList[character].sceneId == _currentCharacter->sceneId) - setCharacterPositionHelper(character, 0); - } - return 0; -} - -void KyraEngine_v1::setCharacterPositionHelper(int character, int *facingTable) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::setCharacterPositionHelper(%d, %p)", character, (const void *)facingTable); - Character *ch = &_characterList[character]; - ++ch->currentAnimFrame; - int facing = ch->facing; - if (facingTable) { - if (*facingTable != *(facingTable - 1)) { - if (*(facingTable - 1) == *(facingTable + 1)) { - facing = getOppositeFacingDirection(*(facingTable - 1)); - *facingTable = *(facingTable - 1); - } - } - } - - static uint8 facingIsZero[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; - static uint8 facingIsFour[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; - - if (facing == 0) { - ++facingIsZero[character]; - } else { - bool resetTables = false; - if (facing != 7) { - if (facing - 1 != 0) { - if (facing != 4) { - if (facing == 3 || facing == 5) { - if (facingIsFour[character] > 2) - facing = 4; - resetTables = true; - } - } else { - ++facingIsFour[character]; - } - } else { - if (facingIsZero[character] > 2) - facing = 0; - resetTables = true; - } - } else { - if (facingIsZero[character] > 2) - facing = 0; - resetTables = true; - } - - if (resetTables) { - facingIsZero[character] = 0; - facingIsFour[character] = 0; - } - } - - static const uint16 maxAnimationFrame[] = { - 0x000F, 0x0031, 0x0055, 0x0000, 0x0000, 0x0000, - 0x0008, 0x002A, 0x004E, 0x0000, 0x0000, 0x0000, - 0x0022, 0x0046, 0x006A, 0x0000, 0x0000, 0x0000, - 0x001D, 0x0041, 0x0065, 0x0000, 0x0000, 0x0000, - 0x001F, 0x0043, 0x0067, 0x0000, 0x0000, 0x0000, - 0x0028, 0x004C, 0x0070, 0x0000, 0x0000, 0x0000, - 0x0023, 0x0047, 0x006B, 0x0000, 0x0000, 0x0000 - }; - - if (facing == 0) { - if (maxAnimationFrame[36+character] > ch->currentAnimFrame) - ch->currentAnimFrame = maxAnimationFrame[36+character]; - if (maxAnimationFrame[30+character] < ch->currentAnimFrame) - ch->currentAnimFrame = maxAnimationFrame[36+character]; - } else if (facing == 4) { - if (maxAnimationFrame[18+character] > ch->currentAnimFrame) - ch->currentAnimFrame = maxAnimationFrame[18+character]; - if (maxAnimationFrame[12+character] < ch->currentAnimFrame) - ch->currentAnimFrame = maxAnimationFrame[18+character]; - } else { - if (maxAnimationFrame[18+character] < ch->currentAnimFrame) - ch->currentAnimFrame = maxAnimationFrame[30+character]; - if (maxAnimationFrame[character] == ch->currentAnimFrame) - ch->currentAnimFrame = maxAnimationFrame[6+character]; - if (maxAnimationFrame[character] < ch->currentAnimFrame) - ch->currentAnimFrame = maxAnimationFrame[6+character]+2; - } - - if (character == 0 && (_brandonStatusBit & 0x10)) - ch->currentAnimFrame = 88; - - _animator->animRefreshNPC(character); -} - -void KyraEngine_v1::loadSceneMsc() { - assert(_currentCharacter->sceneId < _roomTableSize); - int tableId = _roomTable[_currentCharacter->sceneId].nameIndex; - assert(tableId < _roomFilenameTableSize); - char fileNameBuffer[32]; - strcpy(fileNameBuffer, _roomFilenameTable[tableId]); - strcat(fileNameBuffer, ".MSC"); - _screen->fillRect(0, 0, 319, 199, 0, 5); - _res->exists(fileNameBuffer, true); - _screen->loadBitmap(fileNameBuffer, 3, 5, 0); -} - -void KyraEngine_v1::startSceneScript(int brandonAlive) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::startSceneScript(%d)", brandonAlive); - assert(_currentCharacter->sceneId < _roomTableSize); - int tableId = _roomTable[_currentCharacter->sceneId].nameIndex; - assert(tableId < _roomFilenameTableSize); - char fileNameBuffer[32]; - strcpy(fileNameBuffer, _roomFilenameTable[tableId]); - strcat(fileNameBuffer, ".CPS"); - _screen->clearPage(3); - _res->exists(fileNameBuffer, true); - // FIXME: check this hack for amiga version - _screen->loadBitmap(fileNameBuffer, 3, 3, (_flags.platform == Common::kPlatformAmiga ? _screen->getPalette(0) : 0)); - _sprites->loadSceneShapes(); - _exitListPtr = 0; - - _scaleMode = 1; - for (int i = 0; i < 145; ++i) - _scaleTable[i] = 256; - - clearNoDropRects(); - _emc->init(&_scriptClick, &_scriptClickData); - strcpy(fileNameBuffer, _roomFilenameTable[tableId]); - strcat(fileNameBuffer, ".EMC"); - _res->exists(fileNameBuffer, true); - _emc->unload(&_scriptClickData); - _emc->load(fileNameBuffer, &_scriptClickData, &_opcodes); - _emc->start(&_scriptClick, 0); - _scriptClick.regs[0] = _currentCharacter->sceneId; - _scriptClick.regs[7] = brandonAlive; - - while (_emc->isValid(&_scriptClick)) - _emc->run(&_scriptClick); -} - -void KyraEngine_v1::initSceneData(int facing, int unk1, int brandonAlive) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::initSceneData(%d, %d, %d)", facing, unk1, brandonAlive); - - int16 xpos2 = 0; - int setFacing = 1; - - int16 xpos = 0, ypos = 0; - - if (_brandonPosX == -1 && _brandonPosY == -1) { - switch (facing + 1) { - case 0: - xpos = ypos = -1; - break; - - case 1: case 2: case 8: - xpos = _sceneExits.southXPos; - ypos = _sceneExits.southYPos; - break; - - case 3: - xpos = _sceneExits.westXPos; - ypos = _sceneExits.westYPos; - break; - - case 4: case 5: case 6: - xpos = _sceneExits.northXPos; - ypos = _sceneExits.northYPos; - break; - - case 7: - xpos = _sceneExits.eastXPos; - ypos = _sceneExits.eastYPos; - break; - - default: - break; - } - - if ((uint8)(_northExitHeight & 0xFF) + 2 >= ypos) - ypos = (_northExitHeight & 0xFF) + 4; - if (xpos >= 308) - xpos = 304; - if ((uint8)(_northExitHeight >> 8) - 2 <= ypos) - ypos = (_northExitHeight >> 8) - 4; - if (xpos <= 12) - xpos = 16; - } - - if (_brandonPosX > -1) - xpos = _brandonPosX; - if (_brandonPosY > -1) - ypos = _brandonPosY; - - int16 ypos2 = 0; - if (_brandonPosX > -1 && _brandonPosY > -1) { - switch (_currentCharacter->sceneId) { - case 1: - _currentCharacter->x1 = xpos; - _currentCharacter->x2 = xpos; - _currentCharacter->y1 = ypos; - _currentCharacter->y2 = ypos; - facing = 4; - xpos2 = 192; - ypos2 = 104; - setFacing = 0; - unk1 = 1; - break; - - case 3: - _currentCharacter->x1 = xpos; - _currentCharacter->x2 = xpos; - _currentCharacter->y1 = ypos; - _currentCharacter->y2 = ypos; - facing = 2; - xpos2 = 204; - ypos2 = 94; - setFacing = 0; - unk1 = 1; - break; - - case 26: - _currentCharacter->x1 = xpos; - _currentCharacter->x2 = xpos; - _currentCharacter->y1 = ypos; - _currentCharacter->y2 = ypos; - facing = 2; - xpos2 = 192; - ypos2 = 128; - setFacing = 0; - unk1 = 1; - break; - - case 44: - _currentCharacter->x1 = xpos; - _currentCharacter->x2 = xpos; - _currentCharacter->y1 = ypos; - _currentCharacter->y2 = ypos; - facing = 6; - xpos2 = 156; - ypos2 = 96; - setFacing = 0; - unk1 = 1; - break; - - case 37: - _currentCharacter->x1 = xpos; - _currentCharacter->x2 = xpos; - _currentCharacter->y1 = ypos; - _currentCharacter->y2 = ypos; - facing = 2; - xpos2 = 148; - ypos2 = 114; - setFacing = 0; - unk1 = 1; - break; - - default: - break; - } - } - - _brandonPosX = _brandonPosY = -1; - - if (unk1 && setFacing) { - ypos2 = ypos; - xpos2 = xpos; - switch (facing) { - case 0: - ypos = 142; - break; - - case 2: - xpos = -16; - break; - - case 4: - ypos = (uint8)(_northExitHeight & 0xFF) - 4; - break; - - case 6: - xpos = 336; - break; - - default: - break; - } - } - - xpos2 = (int16)(xpos2 & 0xFFFC); - ypos2 = (int16)(ypos2 & 0xFFFE); - xpos = (int16)(xpos & 0xFFFC); - ypos = (int16)(ypos & 0xFFFE); - _currentCharacter->facing = facing; - _currentCharacter->x1 = xpos; - _currentCharacter->x2 = xpos; - _currentCharacter->y1 = ypos; - _currentCharacter->y2 = ypos; - - initSceneObjectList(brandonAlive); - - if (unk1 && brandonAlive == 0) - moveCharacterToPos(0, facing, xpos2, ypos2); - - _scriptClick.regs[4] = _itemInHand; - _scriptClick.regs[7] = brandonAlive; - _emc->start(&_scriptClick, 3); - while (_emc->isValid(&_scriptClick)) - _emc->run(&_scriptClick); -} - -void KyraEngine_v1::initSceneObjectList(int brandonAlive) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::initSceneObjectList(%d)", brandonAlive); - for (int i = 0; i < 28; ++i) - _animator->actors()[i].active = 0; - - int startAnimFrame = 0; - - Animator_v1::AnimObject *curAnimState = _animator->actors(); - curAnimState->active = 1; - curAnimState->drawY = _currentCharacter->y1; - curAnimState->sceneAnimPtr = _shapes[_currentCharacter->currentAnimFrame]; - curAnimState->animFrameNumber = _currentCharacter->currentAnimFrame; - startAnimFrame = _currentCharacter->currentAnimFrame-7; - int xOffset = _defaultShapeTable[startAnimFrame].xOffset; - int yOffset = _defaultShapeTable[startAnimFrame].yOffset; - - if (_scaleMode) { - curAnimState->x1 = _currentCharacter->x1; - curAnimState->y1 = _currentCharacter->y1; - - _animator->_brandonScaleX = _scaleTable[_currentCharacter->y1]; - _animator->_brandonScaleY = _scaleTable[_currentCharacter->y1]; - - curAnimState->x1 += (_animator->_brandonScaleX * xOffset) >> 8; - curAnimState->y1 += (_animator->_brandonScaleY * yOffset) >> 8; - } else { - curAnimState->x1 = _currentCharacter->x1 + xOffset; - curAnimState->y1 = _currentCharacter->y1 + yOffset; - } - - curAnimState->x2 = curAnimState->x1; - curAnimState->y2 = curAnimState->y1; - curAnimState->refreshFlag = 1; - curAnimState->bkgdChangeFlag = 1; - _animator->clearQueue(); - _animator->addObjectToQueue(curAnimState); - - int listAdded = 0; - int addedObjects = 1; - - for (int i = 1; i < 5; ++i) { - Character *ch = &_characterList[i]; - curAnimState = &_animator->actors()[addedObjects]; - if (ch->sceneId != _currentCharacter->sceneId) { - curAnimState->active = 0; - curAnimState->refreshFlag = 0; - curAnimState->bkgdChangeFlag = 0; - ++addedObjects; - continue; - } - - curAnimState->drawY = ch->y1; - curAnimState->sceneAnimPtr = _shapes[ch->currentAnimFrame]; - curAnimState->animFrameNumber = ch->currentAnimFrame; - startAnimFrame = ch->currentAnimFrame-7; - xOffset = _defaultShapeTable[startAnimFrame].xOffset; - yOffset = _defaultShapeTable[startAnimFrame].yOffset; - if (_scaleMode) { - curAnimState->x1 = ch->x1; - curAnimState->y1 = ch->y1; - - _animator->_brandonScaleX = _scaleTable[ch->y1]; - _animator->_brandonScaleY = _scaleTable[ch->y1]; - - curAnimState->x1 += (_animator->_brandonScaleX * xOffset) >> 8; - curAnimState->y1 += (_animator->_brandonScaleY * yOffset) >> 8; - } else { - curAnimState->x1 = ch->x1 + xOffset; - curAnimState->y1 = ch->y1 + yOffset; - } - curAnimState->x2 = curAnimState->x1; - curAnimState->y2 = curAnimState->y1; - curAnimState->active = 1; - curAnimState->refreshFlag = 1; - curAnimState->bkgdChangeFlag = 1; - - if (ch->facing >= 1 && ch->facing <= 3) - curAnimState->flags |= 1; - else if (ch->facing >= 5 && ch->facing <= 7) - curAnimState->flags &= 0xFFFFFFFE; - - _animator->addObjectToQueue(curAnimState); - - ++addedObjects; - ++listAdded; - if (listAdded < 2) - i = 5; - } - - for (int i = 0; i < 11; ++i) { - curAnimState = &_animator->sprites()[i]; - - if (_sprites->_anims[i].play) { - curAnimState->active = 1; - curAnimState->refreshFlag = 1; - curAnimState->bkgdChangeFlag = 1; - } else { - curAnimState->active = 0; - curAnimState->refreshFlag = 0; - curAnimState->bkgdChangeFlag = 0; - } - curAnimState->height = _sprites->_anims[i].height; - curAnimState->height2 = _sprites->_anims[i].height2; - curAnimState->width = _sprites->_anims[i].width + 1; - curAnimState->width2 = _sprites->_anims[i].width2; - curAnimState->drawY = _sprites->_anims[i].drawY; - curAnimState->x1 = curAnimState->x2 = _sprites->_anims[i].x; - curAnimState->y1 = curAnimState->y2 = _sprites->_anims[i].y; - curAnimState->background = _sprites->_anims[i].background; - curAnimState->sceneAnimPtr = _sprites->_sceneShapes[_sprites->_anims[i].sprite]; - - curAnimState->disable = _sprites->_anims[i].disable; - - if (_sprites->_anims[i].unk2) - curAnimState->flags = 0x800; - else - curAnimState->flags = 0; - - if (_sprites->_anims[i].flipX) - curAnimState->flags |= 0x1; - - _animator->addObjectToQueue(curAnimState); - } - - for (int i = 0; i < 12; ++i) { - curAnimState = &_animator->items()[i]; - Room *curRoom = &_roomTable[_currentCharacter->sceneId]; - byte curItem = curRoom->itemsTable[i]; - if (curItem != 0xFF) { - curAnimState->drawY = curRoom->itemsYPos[i]; - curAnimState->sceneAnimPtr = _shapes[216+curItem]; - curAnimState->animFrameNumber = (int16)0xFFFF; - curAnimState->y1 = curRoom->itemsYPos[i]; - curAnimState->x1 = curRoom->itemsXPos[i]; - - curAnimState->x1 -= (_animator->fetchAnimWidth(curAnimState->sceneAnimPtr, _scaleTable[curAnimState->drawY])) >> 1; - curAnimState->y1 -= _animator->fetchAnimHeight(curAnimState->sceneAnimPtr, _scaleTable[curAnimState->drawY]); - - curAnimState->x2 = curAnimState->x1; - curAnimState->y2 = curAnimState->y1; - - curAnimState->active = 1; - curAnimState->refreshFlag = 1; - curAnimState->bkgdChangeFlag = 1; - - _animator->addObjectToQueue(curAnimState); - } else { - curAnimState->active = 0; - curAnimState->refreshFlag = 0; - curAnimState->bkgdChangeFlag = 0; - } - } - - _animator->preserveAnyChangedBackgrounds(); - curAnimState = _animator->actors(); - curAnimState->bkgdChangeFlag = 1; - curAnimState->refreshFlag = 1; - for (int i = 1; i < 28; ++i) { - curAnimState = &_animator->objects()[i]; - if (curAnimState->active) { - curAnimState->bkgdChangeFlag = 1; - curAnimState->refreshFlag = 1; - } - } - _animator->restoreAllObjectBackgrounds(); - _animator->preserveAnyChangedBackgrounds(); - _animator->prepDrawAllObjects(); - initSceneScreen(brandonAlive); - _animator->copyChangedObjectsForward(0); -} - -void KyraEngine_v1::initSceneScreen(int brandonAlive) { - if (_flags.platform == Common::kPlatformAmiga) { - if (_unkScreenVar1 && !queryGameFlag(0xF0)) { - memset(_screen->getPalette(2), 0, 32*3); - if (_currentCharacter->sceneId != 117 || !queryGameFlag(0xB3)) - _screen->setScreenPalette(_screen->getPalette(2)); - } - - if (_unkScreenVar2 == 1) - _screen->shuffleScreen(8, 8, 304, 128, 2, 0, _unkScreenVar3, false); - else - _screen->copyRegion(8, 8, 8, 8, 304, 128, 2, 0); - - if (_unkScreenVar1 && !queryGameFlag(0xA0)) { - if (_currentCharacter->sceneId == 45 && _paletteChanged) - memcpy(_screen->getPalette(0) + 12*3, _screen->getPalette(4) + 12*3, 2); - - if (_currentCharacter->sceneId >= 229 && _currentCharacter->sceneId <= 245 && (_brandonStatusBit & 1)) - memcpy(_screen->getPalette(0), _screen->getPalette(0) + 320*3, 64); - - _screen->setScreenPalette(_screen->getPalette(0)); - } - } else { - if (_unkScreenVar1 && !queryGameFlag(0xA0)) { - for (int i = 0; i < 60; ++i) { - uint16 col = _screen->getPalette(0)[684+i]; - col += _screen->getPalette(1)[684+i] << 1; - col >>= 2; - _screen->getPalette(0)[684+i] = col; - } - _screen->setScreenPalette(_screen->getPalette(0)); - } - - if (_unkScreenVar2 == 1) - _screen->shuffleScreen(8, 8, 304, 128, 2, 0, _unkScreenVar3, false); - else - _screen->copyRegion(8, 8, 8, 8, 304, 128, 2, 0); - - if (_unkScreenVar1 && _paletteChanged) { - if (!queryGameFlag(0xA0)) { - memcpy(_screen->getPalette(0) + 684, _screen->getPalette(1) + 684, 60); - _screen->setScreenPalette(_screen->getPalette(0)); - } else { - memset(_screen->getPalette(0), 0, 768); - } - } - } - - if (!_emc->start(&_scriptClick, 2)) - error("Could not start script function 2 of scene script"); - - _scriptClick.regs[7] = brandonAlive; - - while (_emc->isValid(&_scriptClick)) - _emc->run(&_scriptClick); - - setTextFadeTimerCountdown(-1); - if (_currentCharacter->sceneId == 210) { - if (_itemInHand != -1) - magicOutMouseItem(2, -1); - - _screen->hideMouse(); - for (int i = 0; i < 10; ++i) { - if (_currentCharacter->inventoryItems[i] != 0xFF) - magicOutMouseItem(2, i); - } - _screen->showMouse(); - } -} - -int KyraEngine_v1::handleSceneChange(int xpos, int ypos, int unk1, int frameReset) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::handleSceneChange(%d, %d, %d, %d)", xpos, ypos, unk1, frameReset); - if (queryGameFlag(0xEF)) - unk1 = 0; - - int sceneId = _currentCharacter->sceneId; - _pathfinderFlag = 0; - - if (xpos < 12) { - if (_roomTable[sceneId].westExit != 0xFFFF) { - xpos = 12; - ypos = _sceneExits.westYPos; - _pathfinderFlag = 7; - } - } else if (xpos >= 308) { - if (_roomTable[sceneId].eastExit != 0xFFFF) { - xpos = 307; - ypos = _sceneExits.eastYPos; - _pathfinderFlag = 13; - } - } - - if (ypos <= (_northExitHeight&0xFF)+2) { - if (_roomTable[sceneId].northExit != 0xFFFF) { - xpos = _sceneExits.northXPos; - ypos = _northExitHeight & 0xFF; - _pathfinderFlag = 14; - } - } else if (ypos >= 136) { - if (_roomTable[sceneId].southExit != 0xFFFF) { - xpos = _sceneExits.southXPos; - ypos = 136; - _pathfinderFlag = 11; - } - } - - int temp = xpos - _currentCharacter->x1; - if (ABS(temp) < 4) { - temp = ypos - _currentCharacter->y1; - if (ABS(temp) < 2) - return 0; - } - - int x = (int16)(_currentCharacter->x1 & 0xFFFC); - int y = (int16)(_currentCharacter->y1 & 0xFFFE); - xpos = (int16)(xpos & 0xFFFC); - ypos = (int16)(ypos & 0xFFFE); - - int ret = findWay(x, y, xpos, ypos, _movFacingTable, 150); - _pathfinderFlag = 0; - - if (ret >= _lastFindWayRet) - _lastFindWayRet = ret; - - if (ret == 0x7D00 || ret == 0) - return 0; - - return processSceneChange(_movFacingTable, unk1, frameReset); -} - -int KyraEngine_v1::processSceneChange(int *table, int unk1, int frameReset) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::processSceneChange(%p, %d, %d)", (const void *)table, unk1, frameReset); - if (queryGameFlag(0xEF)) - unk1 = 0; - - int *tableStart = table; - _sceneChangeState = 0; - _loopFlag2 = 0; - bool running = true; - int returnValue = 0; - uint32 nextFrame = 0; - _abortWalkFlag = false; - _mousePressFlag = false; - - while (running) { - if (_abortWalkFlag) { - *table = 8; - _currentCharacter->currentAnimFrame = 7; - _animator->animRefreshNPC(0); - _animator->updateAllObjectShapes(); - processInput(); - return 0; - } - bool forceContinue = false; - switch (*table) { - case 0: case 1: case 2: - case 3: case 4: case 5: - case 6: case 7: - _currentCharacter->facing = getOppositeFacingDirection(*table); - break; - - case 8: - forceContinue = true; - running = false; - break; - - default: - ++table; - forceContinue = true; - break; - } - - returnValue = changeScene(_currentCharacter->facing); - if (returnValue) { - running = false; - _abortWalkFlag = false; - } - - if (unk1) { - if (_mousePressFlag) { - running = false; - _sceneChangeState = 1; - } - } - - if (forceContinue || !running) - continue; - - int temp = 0; - if (table == tableStart || table[1] == 8) - temp = setCharacterPosition(0, 0); - else - temp = setCharacterPosition(0, table); - - if (temp) - ++table; - - nextFrame = _timer->getDelay(5) * _tickLength + _system->getMillis(); - while (_system->getMillis() < nextFrame) { - _timer->update(); - - if (_currentCharacter->sceneId == 210) { - updateKyragemFading(); - if (seq_playEnd() || _beadStateVar == 4 || _beadStateVar == 5) { - *table = 8; - running = false; - break; - } - } - - if ((nextFrame - _system->getMillis()) >= 10) - delay(10, true); - } - } - - if (frameReset && !(_brandonStatusBit & 2)) - _currentCharacter->currentAnimFrame = 7; - - _animator->animRefreshNPC(0); - _animator->updateAllObjectShapes(); - return returnValue; -} - -int KyraEngine_v1::changeScene(int facing) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::changeScene(%d)", facing); - if (queryGameFlag(0xEF)) { - if (_currentCharacter->sceneId == 5) - return 0; - } - - int xpos = _charXPosTable[facing] + _currentCharacter->x1; - int ypos = _charYPosTable[facing] + _currentCharacter->y1; - - if (xpos >= 12 && xpos <= 308) { - if (!lineIsPassable(xpos, ypos)) - return false; - } - - if (_exitListPtr) { - int16 *ptr = _exitListPtr; - // this loop should be only entered one time, seems to be some hack in the original - while (true) { - if (*ptr == -1) - break; - - if (*ptr > _currentCharacter->x1 || _currentCharacter->y1 < ptr[1] || _currentCharacter->x1 > ptr[2] || _currentCharacter->y1 > ptr[3]) { - ptr += 10; - break; - } - - _brandonPosX = ptr[6]; - _brandonPosY = ptr[7]; - uint16 sceneId = ptr[5]; - facing = ptr[4]; - int unk1 = ptr[8]; - int unk2 = ptr[9]; - - if (sceneId == 0xFFFF) { - switch (facing) { - case 0: - sceneId = _roomTable[_currentCharacter->sceneId].northExit; - break; - - case 2: - sceneId = _roomTable[_currentCharacter->sceneId].eastExit; - break; - - case 4: - sceneId = _roomTable[_currentCharacter->sceneId].southExit; - break; - - case 6: - sceneId = _roomTable[_currentCharacter->sceneId].westExit; - break; - - default: - break; - } - } - - _currentCharacter->facing = facing; - _animator->animRefreshNPC(0); - _animator->updateAllObjectShapes(); - enterNewScene(sceneId, facing, unk1, unk2, 0); - resetGameFlag(0xEE); - return 1; - } - } - - int returnValue = 0; - facing = 0; - - if ((_northExitHeight & 0xFF) + 2 >= ypos || (_northExitHeight & 0xFF) + 2 >= _currentCharacter->y1) { - facing = 0; - returnValue = 1; - } - - if (xpos >= 308 || (_currentCharacter->x1 + 4) >= 308) { - facing = 2; - returnValue = 1; - } - - if (((_northExitHeight >> 8) & 0xFF) - 2 < ypos || ((_northExitHeight >> 8) & 0xFF) - 2 < _currentCharacter->y1) { - facing = 4; - returnValue = 1; - } - - if (xpos <= 12 || _currentCharacter->y1 <= 12) { - facing = 6; - returnValue = 1; - } - - if (!returnValue) - return 0; - - uint16 sceneId = 0xFFFF; - switch (facing) { - case 0: - sceneId = _roomTable[_currentCharacter->sceneId].northExit; - break; - - case 2: - sceneId = _roomTable[_currentCharacter->sceneId].eastExit; - break; - - case 4: - sceneId = _roomTable[_currentCharacter->sceneId].southExit; - break; - - default: - sceneId = _roomTable[_currentCharacter->sceneId].westExit; - break; - } - - if (sceneId == 0xFFFF) - return 0; - - enterNewScene(sceneId, facing, 1, 1, 0); - return returnValue; -} - -void KyraEngine_v1::setCharactersInDefaultScene() { - static const uint32 defaultSceneTable[][4] = { - { 0xFFFF, 0x0004, 0x0003, 0xFFFF }, - { 0xFFFF, 0x0022, 0xFFFF, 0x0000 }, - { 0xFFFF, 0x001D, 0x0021, 0xFFFF }, - { 0xFFFF, 0x0000, 0x0000, 0xFFFF } - }; - - for (int i = 1; i < 5; ++i) { - Character *cur = &_characterList[i]; - //cur->field_20 = 0; - - const uint32 *curTable = defaultSceneTable[i-1]; - cur->sceneId = curTable[0]; - - if (cur->sceneId == _currentCharacter->sceneId) - //++cur->field_20; - cur->sceneId = curTable[1/*cur->field_20*/]; - - //cur->field_23 = curTable[cur->field_20+1]; - } -} - -void KyraEngine_v1::setCharactersPositions(int character) { - static uint16 initXPosTable[] = { - 0x3200, 0x0024, 0x2230, 0x2F00, 0x0020, 0x002B, - 0x00CA, 0x00F0, 0x0082, 0x00A2, 0x0042 - }; - static uint8 initYPosTable[] = { - 0x00, 0xA2, 0x00, 0x42, 0x00, - 0x67, 0x67, 0x60, 0x5A, 0x71, - 0x76 - }; - - assert(character < ARRAYSIZE(initXPosTable)); - Character *edit = &_characterList[character]; - edit->x1 = edit->x2 = initXPosTable[character]; - edit->y1 = edit->y2 = initYPosTable[character]; -} - -#pragma mark - -#pragma mark - Pathfinder -#pragma mark - - -int KyraEngine_v1::findWay(int x, int y, int toX, int toY, int *moveTable, int moveTableSize) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::findWay(%d, %d, %d, %d, %p, %d)", x, y, toX, toY, (const void *)moveTable, moveTableSize); - int ret = KyraEngine::findWay(x, y, toX, toY, moveTable, moveTableSize); - if (ret == 0x7D00) - return 0; - return getMoveTableSize(moveTable); -} - -bool KyraEngine_v1::lineIsPassable(int x, int y) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::lineIsPassable(%d, %d)", x, y); - if (queryGameFlag(0xEF)) { - if (_currentCharacter->sceneId == 5) - return true; - } - - if (_pathfinderFlag & 2) { - if (x >= 312) - return false; - } - - if (_pathfinderFlag & 4) { - if (y >= 136) - return false; - } - - if (_pathfinderFlag & 8) { - if (x < 8) - return false; - } - - if (_pathfinderFlag2) { - if (x <= 8 || x >= 312) - return true; - if (y < (_northExitHeight & 0xFF) || y > 135) - return true; - } - - if (y > 137) - return false; - - if (y < 0) - y = 0; - - int ypos = 8; - if (_scaleMode) { - ypos = (_scaleTable[y] >> 5) + 1; - if (8 < ypos) - ypos = 8; - } - - x -= (ypos >> 1); - - int xpos = x; - int xtemp = xpos + ypos - 1; - if (x < 0) - xpos = 0; - - if (xtemp > 319) - xtemp = 319; - - for (; xpos < xtemp; ++xpos) { - if (!_screen->getShapeFlag1(xpos, y)) - return false; - } - return true; -} - -#pragma mark - - -void KyraEngine_v1::setupSceneResource(int sceneId) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::setupSceneResource(%d)", sceneId); - if (!_flags.isTalkie) - return; - - if (_currentRoom != 0xFFFF) { - assert(_currentRoom < _roomTableSize); - int tableId = _roomTable[_currentRoom].nameIndex; - assert(tableId < _roomFilenameTableSize); - - // unload our old room - char file[64]; - strcpy(file, _roomFilenameTable[tableId]); - strcat(file, ".VRM"); - _res->unloadPakFile(file); - - strcpy(file, _roomFilenameTable[tableId]); - strcat(file, ".PAK"); - _res->unloadPakFile(file); - - strcpy(file, _roomFilenameTable[tableId]); - strcat(file, ".APK"); - _res->unloadPakFile(file); - } - - assert(sceneId < _roomTableSize); - int tableId = _roomTable[sceneId].nameIndex; - assert(tableId < _roomFilenameTableSize); - - // load our new room - char file[64]; - strcpy(file, _roomFilenameTable[tableId]); - strcat(file, ".VRM"); - if (_res->exists(file)) - _res->loadPakFile(file); - - strcpy(file, _roomFilenameTable[tableId]); - strcat(file, ".PAK"); - if (_res->exists(file)) - _res->loadPakFile(file); - - strcpy(file, _roomFilenameTable[tableId]); - strcat(file, ".APK"); - if (_res->exists(file)) - _res->loadPakFile(file); -} - -} // end of namespace Kyra - diff --git a/engines/kyra/screen_lok.cpp b/engines/kyra/screen_lok.cpp new file mode 100644 index 0000000000..011c90dde9 --- /dev/null +++ b/engines/kyra/screen_lok.cpp @@ -0,0 +1,243 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "kyra/kyra_lok.h" +#include "kyra/screen_lok.h" + +namespace Kyra { + +#define BITBLIT_RECTS 10 + +Screen_LoK::Screen_LoK(KyraEngine_LoK *vm, OSystem *system) + : Screen(vm, system) { + _vm = vm; +} + +Screen_LoK::~Screen_LoK() { + delete[] _bitBlitRects; + + for (int i = 0; i < ARRAYSIZE(_saveLoadPage); ++i) { + delete[] _saveLoadPage[i]; + _saveLoadPage[i] = 0; + } + + for (int i = 0; i < ARRAYSIZE(_saveLoadPageOvl); ++i) { + delete[] _saveLoadPageOvl[i]; + _saveLoadPageOvl[i] = 0; + } + + delete[] _unkPtr1; + delete[] _unkPtr2; +} + +bool Screen_LoK::init() { + if (!Screen::init()) + return false; + + _bitBlitRects = new Rect[BITBLIT_RECTS]; + assert(_bitBlitRects); + memset(_bitBlitRects, 0, sizeof(Rect)*BITBLIT_RECTS); + _bitBlitNum = 0; + memset(_saveLoadPage, 0, sizeof(_saveLoadPage)); + memset(_saveLoadPageOvl, 0, sizeof(_saveLoadPageOvl)); + + _unkPtr1 = new uint8[getRectSize(1, 144)]; + assert(_unkPtr1); + memset(_unkPtr1, 0, getRectSize(1, 144)); + _unkPtr2 = new uint8[getRectSize(1, 144)]; + assert(_unkPtr2); + memset(_unkPtr2, 0, getRectSize(1, 144)); + + return true; +} + +void Screen_LoK::setScreenDim(int dim) { + debugC(9, kDebugLevelScreen, "Screen_LoK::setScreenDim(%d)", dim); + assert(dim < _screenDimTableCount); + _curDim = &_screenDimTable[dim]; +} + +const ScreenDim *Screen_LoK::getScreenDim(int dim) { + debugC(9, kDebugLevelScreen, "Screen_LoK::getScreenDim(%d)", dim); + assert(dim < _screenDimTableCount); + return &_screenDimTable[dim]; +} + +void Screen_LoK::fadeSpecialPalette(int palIndex, int startIndex, int size, int fadeTime) { + debugC(9, kDebugLevelScreen, "Screen_LoK::fadeSpecialPalette(%d, %d, %d, %d)", palIndex, startIndex, size, fadeTime); + + assert(_vm->palTable1()[palIndex]); + assert(_currentPalette); + uint8 tempPal[768]; + memcpy(tempPal, _currentPalette, 768); + memcpy(&tempPal[startIndex*3], _vm->palTable1()[palIndex], size*3); + fadePalette(tempPal, fadeTime*18); + memcpy(&_currentPalette[startIndex*3], &tempPal[startIndex*3], size*3); + setScreenPalette(_currentPalette); + _system->updateScreen(); +} + +void Screen_LoK::addBitBlitRect(int x, int y, int w, int h) { + debugC(9, kDebugLevelScreen, "Screen_LoK::addBitBlitRects(%d, %d, %d, %d)", x, y, w, h); + if (_bitBlitNum >= BITBLIT_RECTS) + error("too many bit blit rects"); + + _bitBlitRects[_bitBlitNum].x = x; + _bitBlitRects[_bitBlitNum].y = y; + _bitBlitRects[_bitBlitNum].x2 = w; + _bitBlitRects[_bitBlitNum].y2 = h; + ++_bitBlitNum; +} + +void Screen_LoK::bitBlitRects() { + debugC(9, kDebugLevelScreen, "Screen_LoK::bitBlitRects()"); + Rect *cur = _bitBlitRects; + while (_bitBlitNum) { + _bitBlitNum--; + copyRegion(cur->x, cur->y, cur->x, cur->y, cur->x2, cur->y2, 2, 0); + ++cur; + } +} + +void Screen_LoK::savePageToDisk(const char *file, int page) { + debugC(9, kDebugLevelScreen, "Screen_LoK::savePageToDisk('%s', %d)", file, page); + if (!_saveLoadPage[page/2]) { + _saveLoadPage[page/2] = new uint8[SCREEN_W * SCREEN_H]; + assert(_saveLoadPage[page/2]); + } + memcpy(_saveLoadPage[page/2], getPagePtr(page), SCREEN_W * SCREEN_H); + + if (_useOverlays) { + if (!_saveLoadPageOvl[page/2]) { + _saveLoadPageOvl[page/2] = new uint8[SCREEN_OVL_SJIS_SIZE]; + assert(_saveLoadPageOvl[page/2]); + } + + uint8 *srcPage = getOverlayPtr(page); + if (!srcPage) { + warning("trying to save unsupported overlay page %d", page); + return; + } + + memcpy(_saveLoadPageOvl[page/2], srcPage, SCREEN_OVL_SJIS_SIZE); + } +} + +void Screen_LoK::loadPageFromDisk(const char *file, int page) { + debugC(9, kDebugLevelScreen, "Screen_LoK::loadPageFromDisk('%s', %d)", file, page); + copyBlockToPage(page, 0, 0, SCREEN_W, SCREEN_H, _saveLoadPage[page/2]); + delete[] _saveLoadPage[page/2]; + + if (_saveLoadPageOvl[page/2]) { + uint8 *dstPage = getOverlayPtr(page); + if (!dstPage) { + warning("trying to restore unsupported overlay page %d", page); + return; + } + + memcpy(dstPage, _saveLoadPageOvl[page/2], SCREEN_OVL_SJIS_SIZE); + delete[] _saveLoadPageOvl[page/2]; + _saveLoadPageOvl[page/2] = 0; + } _saveLoadPage[page/2] = 0; +} + +void Screen_LoK::deletePageFromDisk(int page) { + debugC(9, kDebugLevelScreen, "Screen_LoK::deletePageFromDisk(%d)", page); + delete[] _saveLoadPage[page/2]; + _saveLoadPage[page/2] = 0; + + if (_saveLoadPageOvl[page/2]) { + delete[] _saveLoadPageOvl[page/2]; + _saveLoadPageOvl[page/2] = 0; + } +} + +void Screen_LoK::copyBackgroundBlock(int x, int page, int flag) { + debugC(9, kDebugLevelScreen, "Screen_LoK::copyBackgroundBlock(%d, %d, %d)", x, page, flag); + + if (x < 1) + return; + + int height = 128; + if (flag) + height += 8; + if (!(x & 1)) + ++x; + if (x == 19) + x = 17; + + uint8 *ptr1 = _unkPtr1; + uint8 *ptr2 = _unkPtr2; + int oldVideoPage = _curPage; + _curPage = page; + + int curX = x; + hideMouse(); + copyRegionToBuffer(_curPage, 8, 8, 8, height, ptr2); + for (int i = 0; i < 19; ++i) { + int tempX = curX + 1; + copyRegionToBuffer(_curPage, tempX<<3, 8, 8, height, ptr1); + copyBlockToPage(_curPage, tempX<<3, 8, 8, height, ptr2); + int newXPos = curX + x; + if (newXPos > 37) + newXPos = newXPos % 38; + + tempX = newXPos + 1; + copyRegionToBuffer(_curPage, tempX<<3, 8, 8, height, ptr2); + copyBlockToPage(_curPage, tempX<<3, 8, 8, height, ptr1); + curX += x*2; + if (curX > 37) { + curX = curX % 38; + } + } + showMouse(); + _curPage = oldVideoPage; +} + +void Screen_LoK::copyBackgroundBlock2(int x) { + debugC(9, kDebugLevelScreen, "Screen_LoK::copyBackgroundBlock2(%d)", x); + copyBackgroundBlock(x, 4, 1); +} + +void Screen_LoK::setTextColorMap(const uint8 *cmap) { + debugC(9, kDebugLevelScreen, "Screen_LoK::setTextColorMap(%p)", (const void *)cmap); + setTextColor(cmap, 0, 11); +} + +int Screen_LoK::getRectSize(int x, int y) { + if (x < 1) + x = 1; + else if (x > 40) + x = 40; + + if (y < 1) + y = 1; + else if (y > 200) + y = 200; + + return ((x*y) << 3); +} + +} // end of namespace Kyra diff --git a/engines/kyra/screen_lok.h b/engines/kyra/screen_lok.h new file mode 100644 index 0000000000..74df23a543 --- /dev/null +++ b/engines/kyra/screen_lok.h @@ -0,0 +1,77 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#ifndef KYRA_SCREEN_LOK_H +#define KYRA_SCREEN_LOK_H + +#include "kyra/screen.h" + +namespace Kyra { + +class KyraEngine_LoK; + +class Screen_LoK : public Screen { +public: + Screen_LoK(KyraEngine_LoK *vm, OSystem *system); + virtual ~Screen_LoK(); + + bool init(); + + int getRectSize(int w, int h); + + void setScreenDim(int dim); + const ScreenDim *getScreenDim(int dim); + + void setTextColorMap(const uint8 *cmap); + + void fadeSpecialPalette(int palIndex, int startIndex, int size, int fadeTime); + + void savePageToDisk(const char *file, int page); + void loadPageFromDisk(const char *file, int page); + void deletePageFromDisk(int page); + + void copyBackgroundBlock(int x, int page, int flag); + void copyBackgroundBlock2(int x); + + void addBitBlitRect(int x, int y, int w, int h); + void bitBlitRects(); + +protected: + KyraEngine_LoK *_vm; + + static const ScreenDim _screenDimTable[]; + static const int _screenDimTableCount; + + Rect *_bitBlitRects; + int _bitBlitNum; + uint8 *_unkPtr1, *_unkPtr2; + + uint8 *_saveLoadPage[8]; + uint8 *_saveLoadPageOvl[8]; +}; + +} // end of namespace Kyra + +#endif diff --git a/engines/kyra/screen_v1.cpp b/engines/kyra/screen_v1.cpp deleted file mode 100644 index 7af01358e5..0000000000 --- a/engines/kyra/screen_v1.cpp +++ /dev/null @@ -1,243 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include "kyra/kyra_v1.h" -#include "kyra/screen_v1.h" - -namespace Kyra { - -#define BITBLIT_RECTS 10 - -Screen_v1::Screen_v1(KyraEngine_v1 *vm, OSystem *system) - : Screen(vm, system) { - _vm = vm; -} - -Screen_v1::~Screen_v1() { - delete[] _bitBlitRects; - - for (int i = 0; i < ARRAYSIZE(_saveLoadPage); ++i) { - delete[] _saveLoadPage[i]; - _saveLoadPage[i] = 0; - } - - for (int i = 0; i < ARRAYSIZE(_saveLoadPageOvl); ++i) { - delete[] _saveLoadPageOvl[i]; - _saveLoadPageOvl[i] = 0; - } - - delete[] _unkPtr1; - delete[] _unkPtr2; -} - -bool Screen_v1::init() { - if (!Screen::init()) - return false; - - _bitBlitRects = new Rect[BITBLIT_RECTS]; - assert(_bitBlitRects); - memset(_bitBlitRects, 0, sizeof(Rect)*BITBLIT_RECTS); - _bitBlitNum = 0; - memset(_saveLoadPage, 0, sizeof(_saveLoadPage)); - memset(_saveLoadPageOvl, 0, sizeof(_saveLoadPageOvl)); - - _unkPtr1 = new uint8[getRectSize(1, 144)]; - assert(_unkPtr1); - memset(_unkPtr1, 0, getRectSize(1, 144)); - _unkPtr2 = new uint8[getRectSize(1, 144)]; - assert(_unkPtr2); - memset(_unkPtr2, 0, getRectSize(1, 144)); - - return true; -} - -void Screen_v1::setScreenDim(int dim) { - debugC(9, kDebugLevelScreen, "Screen_v1::setScreenDim(%d)", dim); - assert(dim < _screenDimTableCount); - _curDim = &_screenDimTable[dim]; -} - -const ScreenDim *Screen_v1::getScreenDim(int dim) { - debugC(9, kDebugLevelScreen, "Screen_v1::getScreenDim(%d)", dim); - assert(dim < _screenDimTableCount); - return &_screenDimTable[dim]; -} - -void Screen_v1::fadeSpecialPalette(int palIndex, int startIndex, int size, int fadeTime) { - debugC(9, kDebugLevelScreen, "Screen_v1::fadeSpecialPalette(%d, %d, %d, %d)", palIndex, startIndex, size, fadeTime); - - assert(_vm->palTable1()[palIndex]); - assert(_currentPalette); - uint8 tempPal[768]; - memcpy(tempPal, _currentPalette, 768); - memcpy(&tempPal[startIndex*3], _vm->palTable1()[palIndex], size*3); - fadePalette(tempPal, fadeTime*18); - memcpy(&_currentPalette[startIndex*3], &tempPal[startIndex*3], size*3); - setScreenPalette(_currentPalette); - _system->updateScreen(); -} - -void Screen_v1::addBitBlitRect(int x, int y, int w, int h) { - debugC(9, kDebugLevelScreen, "Screen_v1::addBitBlitRects(%d, %d, %d, %d)", x, y, w, h); - if (_bitBlitNum >= BITBLIT_RECTS) - error("too many bit blit rects"); - - _bitBlitRects[_bitBlitNum].x = x; - _bitBlitRects[_bitBlitNum].y = y; - _bitBlitRects[_bitBlitNum].x2 = w; - _bitBlitRects[_bitBlitNum].y2 = h; - ++_bitBlitNum; -} - -void Screen_v1::bitBlitRects() { - debugC(9, kDebugLevelScreen, "Screen_v1::bitBlitRects()"); - Rect *cur = _bitBlitRects; - while (_bitBlitNum) { - _bitBlitNum--; - copyRegion(cur->x, cur->y, cur->x, cur->y, cur->x2, cur->y2, 2, 0); - ++cur; - } -} - -void Screen_v1::savePageToDisk(const char *file, int page) { - debugC(9, kDebugLevelScreen, "Screen_v1::savePageToDisk('%s', %d)", file, page); - if (!_saveLoadPage[page/2]) { - _saveLoadPage[page/2] = new uint8[SCREEN_W * SCREEN_H]; - assert(_saveLoadPage[page/2]); - } - memcpy(_saveLoadPage[page/2], getPagePtr(page), SCREEN_W * SCREEN_H); - - if (_useOverlays) { - if (!_saveLoadPageOvl[page/2]) { - _saveLoadPageOvl[page/2] = new uint8[SCREEN_OVL_SJIS_SIZE]; - assert(_saveLoadPageOvl[page/2]); - } - - uint8 *srcPage = getOverlayPtr(page); - if (!srcPage) { - warning("trying to save unsupported overlay page %d", page); - return; - } - - memcpy(_saveLoadPageOvl[page/2], srcPage, SCREEN_OVL_SJIS_SIZE); - } -} - -void Screen_v1::loadPageFromDisk(const char *file, int page) { - debugC(9, kDebugLevelScreen, "Screen_v1::loadPageFromDisk('%s', %d)", file, page); - copyBlockToPage(page, 0, 0, SCREEN_W, SCREEN_H, _saveLoadPage[page/2]); - delete[] _saveLoadPage[page/2]; - - if (_saveLoadPageOvl[page/2]) { - uint8 *dstPage = getOverlayPtr(page); - if (!dstPage) { - warning("trying to restore unsupported overlay page %d", page); - return; - } - - memcpy(dstPage, _saveLoadPageOvl[page/2], SCREEN_OVL_SJIS_SIZE); - delete[] _saveLoadPageOvl[page/2]; - _saveLoadPageOvl[page/2] = 0; - } _saveLoadPage[page/2] = 0; -} - -void Screen_v1::deletePageFromDisk(int page) { - debugC(9, kDebugLevelScreen, "Screen_v1::deletePageFromDisk(%d)", page); - delete[] _saveLoadPage[page/2]; - _saveLoadPage[page/2] = 0; - - if (_saveLoadPageOvl[page/2]) { - delete[] _saveLoadPageOvl[page/2]; - _saveLoadPageOvl[page/2] = 0; - } -} - -void Screen_v1::copyBackgroundBlock(int x, int page, int flag) { - debugC(9, kDebugLevelScreen, "Screen_v1::copyBackgroundBlock(%d, %d, %d)", x, page, flag); - - if (x < 1) - return; - - int height = 128; - if (flag) - height += 8; - if (!(x & 1)) - ++x; - if (x == 19) - x = 17; - - uint8 *ptr1 = _unkPtr1; - uint8 *ptr2 = _unkPtr2; - int oldVideoPage = _curPage; - _curPage = page; - - int curX = x; - hideMouse(); - copyRegionToBuffer(_curPage, 8, 8, 8, height, ptr2); - for (int i = 0; i < 19; ++i) { - int tempX = curX + 1; - copyRegionToBuffer(_curPage, tempX<<3, 8, 8, height, ptr1); - copyBlockToPage(_curPage, tempX<<3, 8, 8, height, ptr2); - int newXPos = curX + x; - if (newXPos > 37) - newXPos = newXPos % 38; - - tempX = newXPos + 1; - copyRegionToBuffer(_curPage, tempX<<3, 8, 8, height, ptr2); - copyBlockToPage(_curPage, tempX<<3, 8, 8, height, ptr1); - curX += x*2; - if (curX > 37) { - curX = curX % 38; - } - } - showMouse(); - _curPage = oldVideoPage; -} - -void Screen_v1::copyBackgroundBlock2(int x) { - debugC(9, kDebugLevelScreen, "Screen_v1::copyBackgroundBlock2(%d)", x); - copyBackgroundBlock(x, 4, 1); -} - -void Screen_v1::setTextColorMap(const uint8 *cmap) { - debugC(9, kDebugLevelScreen, "Screen_v1::setTextColorMap(%p)", (const void *)cmap); - setTextColor(cmap, 0, 11); -} - -int Screen_v1::getRectSize(int x, int y) { - if (x < 1) - x = 1; - else if (x > 40) - x = 40; - - if (y < 1) - y = 1; - else if (y > 200) - y = 200; - - return ((x*y) << 3); -} - -} // end of namespace Kyra diff --git a/engines/kyra/screen_v1.h b/engines/kyra/screen_v1.h deleted file mode 100644 index 10219ae6b5..0000000000 --- a/engines/kyra/screen_v1.h +++ /dev/null @@ -1,77 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#ifndef KYRA_SCREEN_V1_H -#define KYRA_SCREEN_V1_H - -#include "kyra/screen.h" - -namespace Kyra { - -class KyraEngine_v1; - -class Screen_v1 : public Screen { -public: - Screen_v1(KyraEngine_v1 *vm, OSystem *system); - virtual ~Screen_v1(); - - bool init(); - - int getRectSize(int w, int h); - - void setScreenDim(int dim); - const ScreenDim *getScreenDim(int dim); - - void setTextColorMap(const uint8 *cmap); - - void fadeSpecialPalette(int palIndex, int startIndex, int size, int fadeTime); - - void savePageToDisk(const char *file, int page); - void loadPageFromDisk(const char *file, int page); - void deletePageFromDisk(int page); - - void copyBackgroundBlock(int x, int page, int flag); - void copyBackgroundBlock2(int x); - - void addBitBlitRect(int x, int y, int w, int h); - void bitBlitRects(); - -protected: - KyraEngine_v1 *_vm; - - static const ScreenDim _screenDimTable[]; - static const int _screenDimTableCount; - - Rect *_bitBlitRects; - int _bitBlitNum; - uint8 *_unkPtr1, *_unkPtr2; - - uint8 *_saveLoadPage[8]; - uint8 *_saveLoadPageOvl[8]; -}; - -} // end of namespace Kyra - -#endif diff --git a/engines/kyra/script_lok.cpp b/engines/kyra/script_lok.cpp new file mode 100644 index 0000000000..3f578d9e0f --- /dev/null +++ b/engines/kyra/script_lok.cpp @@ -0,0 +1,2031 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + + +#include "common/endian.h" +#include "common/system.h" + +#include "kyra/kyra_lok.h" +#include "kyra/script.h" +#include "kyra/screen.h" +#include "kyra/sprites.h" +#include "kyra/wsamovie.h" +#include "kyra/animator_lok.h" +#include "kyra/text.h" +#include "kyra/timer.h" + +namespace Kyra { +int KyraEngine_LoK::o1_magicInMouseItem(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_magicInMouseItem(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + magicInMouseItem(stackPos(0), stackPos(1), -1); + return 0; +} + +int KyraEngine_LoK::o1_characterSays(EMCState *script) { + _skipFlag = false; + if (_flags.isTalkie) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_characterSays(%p) (%d, '%s', %d, %d)", (const void *)script, stackPos(0), stackPosString(1), stackPos(2), stackPos(3)); + characterSays(stackPos(0), stackPosString(1), stackPos(2), stackPos(3)); + } else { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_characterSays(%p) ('%s', %d, %d)", (const void *)script, stackPosString(0), stackPos(1), stackPos(2)); + const char *string = stackPosString(0); + + if ((_flags.platform == Common::kPlatformFMTowns || _flags.platform == Common::kPlatformPC98) && _flags.lang == Common::JA_JPN) { + static const uint8 townsString1[] = { + 0x83, 0x75, 0x83, 0x89, 0x83, 0x93, 0x83, 0x83, 0x93, 0x81, + 0x41, 0x82, 0xDC, 0x82, 0xBD, 0x97, 0x88, 0x82, 0xBD, 0x82, + 0xCC, 0x82, 0xA9, 0x81, 0x48, 0x00, 0x00, 0x00 + }; + static const uint8 townsString2[] = { + 0x83, 0x75, 0x83, 0x89, 0x83, 0x93, 0x83, 0x5C, 0x83, 0x93, + 0x81, 0x41, 0x82, 0xDC, 0x82, 0xBD, 0x97, 0x88, 0x82, 0xBD, + 0x82, 0xCC, 0x82, 0xA9, 0x81, 0x48, 0x00, 0x00 + }; + + if (strncmp((const char *)townsString1, string, sizeof(townsString1)) == 0) + string = (const char *)townsString2; + } + + characterSays(-1, string, stackPos(1), stackPos(2)); + } + + return 0; +} + +int KyraEngine_LoK::o1_pauseTicks(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_pauseTicks(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + if (stackPos(1)) { + warning("STUB: special o1_pauseTicks"); + // delete this after correct implementing + delayWithTicks(stackPos(0)); + } else { + delayWithTicks(stackPos(0)); + } + return 0; +} + +int KyraEngine_LoK::o1_drawSceneAnimShape(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_drawSceneAnimShape(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); + _screen->drawShape(stackPos(4), _sprites->_sceneShapes[stackPos(0)], stackPos(1), stackPos(2), 0, (stackPos(3) != 0) ? 1 : 0); + return 0; +} + +int KyraEngine_LoK::o1_queryGameFlag(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_queryGameFlag(%p) (0x%X)", (const void *)script, stackPos(0)); + return queryGameFlag(stackPos(0)); +} + +int KyraEngine_LoK::o1_setGameFlag(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_setGameFlag(%p) (0x%X)", (const void *)script, stackPos(0)); + return setGameFlag(stackPos(0)); +} + +int KyraEngine_LoK::o1_resetGameFlag(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_resetGameFlag(%p) (0x%X)", (const void *)script, stackPos(0)); + return resetGameFlag(stackPos(0)); +} + +int KyraEngine_LoK::o1_runNPCScript(EMCState *script) { + warning("STUB: o1_runNPCScript"); + return 0; +} + +int KyraEngine_LoK::o1_setSpecialExitList(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_setSpecialExitList(%p) (%d, %d, %d, %d, %d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7), stackPos(8), stackPos(9)); + + for (int i = 0; i < 10; ++i) + _exitList[i] = stackPos(i); + _exitListPtr = _exitList; + + return 0; +} + +int KyraEngine_LoK::o1_blockInWalkableRegion(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_blockInWalkableRegion(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); + _screen->blockInRegion(stackPos(0), stackPos(1), stackPos(2)-stackPos(0)+1, stackPos(3)-stackPos(1)+1); + return 0; +} + +int KyraEngine_LoK::o1_blockOutWalkableRegion(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_blockOutWalkableRegion(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); + _screen->blockOutRegion(stackPos(0), stackPos(1), stackPos(2)-stackPos(0)+1, stackPos(3)-stackPos(1)+1); + return 0; +} + +int KyraEngine_LoK::o1_walkPlayerToPoint(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_walkPlayerToPoint(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); + + int normalTimers = stackPos(2); + if (!normalTimers) { + _timer->disable(19); + _timer->disable(14); + _timer->disable(18); + } + + int reinitScript = handleSceneChange(stackPos(0), stackPos(1), stackPos(2), stackPos(3)); + + if (!normalTimers) { + _timer->enable(19); + _timer->enable(14); + _timer->enable(18); + } + + if (reinitScript) + _emc->init(script, script->dataPtr); + + if (_sceneChangeState) { + _sceneChangeState = 0; + return 1; + } + return 0; +} + +int KyraEngine_LoK::o1_dropItemInScene(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_dropItemInScene(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); + int item = stackPos(0); + int xpos = stackPos(1); + int ypos = stackPos(2); + + byte freeItem = findFreeItemInScene(_currentCharacter->sceneId); + if (freeItem != 0xFF) { + int sceneId = _currentCharacter->sceneId; + Room *room = &_roomTable[sceneId]; + room->itemsXPos[freeItem] = xpos; + room->itemsYPos[freeItem] = ypos; + room->itemsTable[freeItem] = item; + + _animator->animAddGameItem(freeItem, sceneId); + _animator->updateAllObjectShapes(); + } else { + if (item == 43) + placeItemInGenericMapScene(item, 0); + else + placeItemInGenericMapScene(item, 1); + } + return 0; +} + +int KyraEngine_LoK::o1_drawAnimShapeIntoScene(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_drawAnimShapeIntoScene(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); + _screen->hideMouse(); + _animator->restoreAllObjectBackgrounds(); + int shape = stackPos(0); + int xpos = stackPos(1); + int ypos = stackPos(2); + int flags = (stackPos(3) != 0) ? 1 : 0; + _screen->drawShape(2, _sprites->_sceneShapes[shape], xpos, ypos, 0, flags); + _screen->drawShape(0, _sprites->_sceneShapes[shape], xpos, ypos, 0, flags); + _animator->flagAllObjectsForBkgdChange(); + _animator->preserveAnyChangedBackgrounds(); + _animator->flagAllObjectsForRefresh(); + _animator->updateAllObjectShapes(); + _screen->showMouse(); + return 0; +} + +int KyraEngine_LoK::o1_createMouseItem(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_createMouseItem(%p) (%d)", (const void *)script, stackPos(0)); + createMouseItem(stackPos(0)); + return 0; +} + +int KyraEngine_LoK::o1_savePageToDisk(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_savePageToDisk(%p) ('%s', %d)", (const void *)script, stackPosString(0), stackPos(1)); + _screen->savePageToDisk(stackPosString(0), stackPos(1)); + return 0; +} + +int KyraEngine_LoK::o1_sceneAnimOn(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_sceneAnimOn(%p) (%d)", (const void *)script, stackPos(0)); + _sprites->_anims[stackPos(0)].play = true; + return 0; +} + +int KyraEngine_LoK::o1_sceneAnimOff(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_sceneAnimOff(%p) (%d)", (const void *)script, stackPos(0)); + _sprites->_anims[stackPos(0)].play = false; + return 0; +} + +int KyraEngine_LoK::o1_getElapsedSeconds(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_getElapsedSeconds(%p) ()", (const void *)script); + return _system->getMillis() / 1000; +} + +int KyraEngine_LoK::o1_mouseIsPointer(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_mouseIsPointer(%p) ()", (const void *)script); + if (_itemInHand == -1) + return 1; + return 0; +} + +int KyraEngine_LoK::o1_destroyMouseItem(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_destroyMouseItem(%p) ()", (const void *)script); + destroyMouseItem(); + return 0; +} + +int KyraEngine_LoK::o1_runSceneAnimUntilDone(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_runSceneAnimUntilDone(%p) (%d)", (const void *)script, stackPos(0)); + _screen->hideMouse(); + _animator->restoreAllObjectBackgrounds(); + _sprites->_anims[stackPos(0)].play = true; + _animator->sprites()[stackPos(0)].active = 1; + _animator->flagAllObjectsForBkgdChange(); + _animator->preserveAnyChangedBackgrounds(); + while (_sprites->_anims[stackPos(0)].play) { + _sprites->updateSceneAnims(); + _animator->updateAllObjectShapes(); + delay(10); + } + _animator->restoreAllObjectBackgrounds(); + _screen->showMouse(); + return 0; +} + +int KyraEngine_LoK::o1_fadeSpecialPalette(EMCState *script) { + if (_flags.platform == Common::kPlatformAmiga) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_fadeSpecialPalette(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); + if (_currentCharacter->sceneId != 45) { + if (stackPos(0) == 13) { + memcpy(_screen->getPalette(0), _screen->getPalette(0) + 384*3, 32*3); + _screen->setScreenPalette(_screen->getPalette(0)); + } + } else { + warning("KyraEngine_LoK::o1_fadeSpecialPalette not implemented"); + } + } else { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_fadeSpecialPalette(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); + _screen->fadeSpecialPalette(stackPos(0), stackPos(1), stackPos(2), stackPos(3)); + } + return 0; +} + +int KyraEngine_LoK::o1_playAdlibSound(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_playAdlibSound(%p) (%d)", (const void *)script, stackPos(0)); + snd_playSoundEffect(stackPos(0)); + return 0; +} + +int KyraEngine_LoK::o1_playAdlibScore(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_playAdlibScore(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + snd_playWanderScoreViaMap(stackPos(0), stackPos(1)); + return 0; +} + +int KyraEngine_LoK::o1_phaseInSameScene(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_phaseInSameScene(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + transcendScenes(stackPos(0), stackPos(1)); + return 0; +} + +int KyraEngine_LoK::o1_setScenePhasingFlag(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_setScenePhasingFlag(%p) ()", (const void *)script); + _scenePhasingFlag = 1; + return 1; +} + +int KyraEngine_LoK::o1_resetScenePhasingFlag(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_resetScenePhasingFlag(%p) ()", (const void *)script); + _scenePhasingFlag = 0; + return 0; +} + +int KyraEngine_LoK::o1_queryScenePhasingFlag(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_queryScenePhasingFlag(%p) ()", (const void *)script); + return _scenePhasingFlag; +} + +int KyraEngine_LoK::o1_sceneToDirection(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_sceneToDirection(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + assert(stackPos(0) < _roomTableSize); + Room *curRoom = &_roomTable[stackPos(0)]; + uint16 returnValue = 0xFFFF; + switch (stackPos(1)) { + case 0: + returnValue = curRoom->northExit; + break; + + case 2: + returnValue = curRoom->eastExit; + break; + + case 4: + returnValue = curRoom->southExit; + break; + + case 6: + returnValue = curRoom->westExit; + break; + + default: + break; + } + if (returnValue == 0xFFFF) + return -1; + return returnValue; +} + +int KyraEngine_LoK::o1_setBirthstoneGem(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_setBirthstoneGem(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + int index = stackPos(0); + if (index < 4 && index >= 0) { + _birthstoneGemTable[index] = stackPos(1); + return 1; + } + return 0; +} + +int KyraEngine_LoK::o1_placeItemInGenericMapScene(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_placeItemInGenericMapScene(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + placeItemInGenericMapScene(stackPos(0), stackPos(1)); + return 0; +} + +int KyraEngine_LoK::o1_setBrandonStatusBit(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_setBrandonStatusBit(%p) (%d)", (const void *)script, stackPos(0)); + _brandonStatusBit |= stackPos(0); + return 0; +} + +int KyraEngine_LoK::o1_pauseSeconds(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_pauseSeconds(%p) (%d)", (const void *)script, stackPos(0)); + if (stackPos(0) > 0 && !_skipFlag) + delay(stackPos(0)*1000, true); + _skipFlag = false; + return 0; +} + +int KyraEngine_LoK::o1_getCharactersLocation(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_getCharactersLocation(%p) (%d)", (const void *)script, stackPos(0)); + return _characterList[stackPos(0)].sceneId; +} + +int KyraEngine_LoK::o1_runNPCSubscript(EMCState *script) { + warning("STUB: o1_runNPCSubscript"); + return 0; +} + +int KyraEngine_LoK::o1_magicOutMouseItem(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_magicOutMouseItem(%p) (%d)", (const void *)script, stackPos(0)); + magicOutMouseItem(stackPos(0), -1); + return 0; +} + +int KyraEngine_LoK::o1_internalAnimOn(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_internalAnimOn(%p) (%d)", (const void *)script, stackPos(0)); + _animator->sprites()[stackPos(0)].active = 1; + return 0; +} + +int KyraEngine_LoK::o1_forceBrandonToNormal(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_forceBrandonToNormal(%p) ()", (const void *)script); + checkAmuletAnimFlags(); + return 0; +} + +int KyraEngine_LoK::o1_poisonDeathNow(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_poisonDeathNow(%p) ()", (const void *)script); + seq_poisonDeathNow(1); + return 0; +} + +int KyraEngine_LoK::o1_setScaleMode(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_setScaleMode(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); + int len = stackPos(0); + int setValue1 = stackPos(1); + int start2 = stackPos(2); + int setValue2 = stackPos(3); + for (int i = 0; i < len; ++i) + _scaleTable[i] = setValue1; + int temp = setValue2 - setValue1; + int temp2 = start2 - len; + for (int i = len, offset = 0; i < start2; ++i, ++offset) + _scaleTable[i] = (offset * temp) / temp2 + setValue1; + for (int i = start2; i < 145; ++i) + _scaleTable[i] = setValue2; + _scaleMode = 1; + return _scaleMode; +} + +int KyraEngine_LoK::o1_openWSAFile(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_openWSAFile(%p) ('%s', %d, %d, %d)", (const void *)script, stackPosString(0), stackPos(1), stackPos(2), stackPos(3)); + + const char *filename = stackPosString(0); + int wsaIndex = stackPos(1); + + _movieObjects[wsaIndex]->open(filename, (stackPos(3) != 0) ? 1 : 0, 0); + assert(_movieObjects[wsaIndex]->opened()); + + return 0; +} + +int KyraEngine_LoK::o1_closeWSAFile(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_closeWSAFile(%p) (%d)", (const void *)script, stackPos(0)); + + int wsaIndex = stackPos(0); + if (_movieObjects[wsaIndex]) + _movieObjects[wsaIndex]->close(); + + return 0; +} + +int KyraEngine_LoK::o1_runWSAFromBeginningToEnd(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_runWSAFromBeginningToEnd(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); + + _screen->hideMouse(); + + bool running = true; + + int xpos = stackPos(0); + int ypos = stackPos(1); + int waitTime = stackPos(2); + int wsaIndex = stackPos(3); + int worldUpdate = stackPos(4); + int wsaFrame = 0; + + _movieObjects[wsaIndex]->setX(xpos); + _movieObjects[wsaIndex]->setY(ypos); + _movieObjects[wsaIndex]->setDrawPage(0); + while (running) { + _movieObjects[wsaIndex]->displayFrame(wsaFrame++); + _animator->_updateScreen = true; + if (wsaFrame >= _movieObjects[wsaIndex]->frames()) + running = false; + + uint32 continueTime = waitTime * _tickLength + _system->getMillis(); + while (_system->getMillis() < continueTime) { + if (worldUpdate) { + _sprites->updateSceneAnims(); + _animator->updateAllObjectShapes(); + } else { + _screen->updateScreen(); + } + if (continueTime - _system->getMillis() >= 10) + delay(10); + } + } + + _screen->showMouse(); + + return 0; +} + +int KyraEngine_LoK::o1_displayWSAFrame(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_displayWSAFrame(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); + int frame = stackPos(0); + int xpos = stackPos(1); + int ypos = stackPos(2); + int waitTime = stackPos(3); + int wsaIndex = stackPos(4); + _screen->hideMouse(); + _movieObjects[wsaIndex]->setX(xpos); + _movieObjects[wsaIndex]->setY(ypos); + _movieObjects[wsaIndex]->setDrawPage(0); + _movieObjects[wsaIndex]->displayFrame(frame); + _animator->_updateScreen = true; + uint32 continueTime = waitTime * _tickLength + _system->getMillis(); + while (_system->getMillis() < continueTime) { + _sprites->updateSceneAnims(); + _animator->updateAllObjectShapes(); + if (_skipFlag) + break; + + if (continueTime - _system->getMillis() >= 10) + delay(10); + } + _screen->showMouse(); + return 0; +} + +int KyraEngine_LoK::o1_enterNewScene(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_enterNewScene(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); + enterNewScene(stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); + return 0; +} + +int KyraEngine_LoK::o1_setSpecialEnterXAndY(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_setSpecialEnterXAndY(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + _brandonPosX = stackPos(0); + _brandonPosY = stackPos(1); + if (_brandonPosX + 1 == 0 && _brandonPosY + 1 == 0) + _currentCharacter->currentAnimFrame = 88; + return 0; +} + +int KyraEngine_LoK::o1_runWSAFrames(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_runWSAFrames(%p) (%d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5)); + int xpos = stackPos(0); + int ypos = stackPos(1); + int delayTime = stackPos(2); + int startFrame = stackPos(3); + int endFrame = stackPos(4); + int wsaIndex = stackPos(5); + _screen->hideMouse(); + _movieObjects[wsaIndex]->setX(xpos); + _movieObjects[wsaIndex]->setY(ypos); + _movieObjects[wsaIndex]->setDrawPage(0); + for (; startFrame <= endFrame; ++startFrame) { + uint32 nextRun = _system->getMillis() + delayTime * _tickLength; + _movieObjects[wsaIndex]->displayFrame(startFrame); + _animator->_updateScreen = true; + while (_system->getMillis() < nextRun) { + _sprites->updateSceneAnims(); + _animator->updateAllObjectShapes(); + if (nextRun - _system->getMillis() >= 10) + delay(10); + } + } + _screen->showMouse(); + return 0; +} + +int KyraEngine_LoK::o1_popBrandonIntoScene(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_popBrandonIntoScene(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); + int changeScaleMode = stackPos(3); + int xpos = (int16)(stackPos(0) & 0xFFFC); + int ypos = (int16)(stackPos(1) & 0xFFFE); + int facing = stackPos(2); + _currentCharacter->x1 = _currentCharacter->x2 = xpos; + _currentCharacter->y1 = _currentCharacter->y2 = ypos; + _currentCharacter->facing = facing; + _currentCharacter->currentAnimFrame = 7; + int xOffset = _defaultShapeTable[0].xOffset; + int yOffset = _defaultShapeTable[0].yOffset; + int width = _defaultShapeTable[0].w << 3; + int height = _defaultShapeTable[0].h; + Animator_LoK::AnimObject *curAnim = _animator->actors(); + + if (changeScaleMode) { + curAnim->x1 = _currentCharacter->x1; + curAnim->y1 = _currentCharacter->y1; + _animator->_brandonScaleY = _scaleTable[_currentCharacter->y1]; + _animator->_brandonScaleX = _animator->_brandonScaleY; + + int animWidth = _animator->fetchAnimWidth(curAnim->sceneAnimPtr, _animator->_brandonScaleX) >> 1; + int animHeight = _animator->fetchAnimHeight(curAnim->sceneAnimPtr, _animator->_brandonScaleY); + + animWidth = (xOffset * animWidth) / width; + animHeight = (yOffset * animHeight) / height; + + curAnim->x2 = curAnim->x1 += animWidth; + curAnim->y2 = curAnim->y1 += animHeight; + } else { + curAnim->x2 = curAnim->x1 = _currentCharacter->x1 + xOffset; + curAnim->y2 = curAnim->y1 = _currentCharacter->y1 + yOffset; + } + + int scaleModeBackup = _scaleMode; + if (changeScaleMode) + _scaleMode = 1; + + _animator->animRefreshNPC(0); + _animator->preserveAllBackgrounds(); + _animator->prepDrawAllObjects(); + _animator->copyChangedObjectsForward(0); + + _scaleMode = scaleModeBackup; + + return 0; +} + +int KyraEngine_LoK::o1_restoreAllObjectBackgrounds(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_restoreAllObjectBackgrounds(%p) (%d)", (const void *)script, stackPos(0)); + int disable = stackPos(0); + int activeBackup = 0; + if (disable) { + activeBackup = _animator->actors()->active; + _animator->actors()->active = 0; + } + _animator->restoreAllObjectBackgrounds(); + if (disable) + _animator->actors()->active = activeBackup; + return 0; +} + +int KyraEngine_LoK::o1_setCustomPaletteRange(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_setCustomPaletteRange(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); + memcpy(_screen->getPalette(1) + stackPos(1)*3, _specialPalettes[stackPos(0)], stackPos(2)*3); + return 0; +} + +int KyraEngine_LoK::o1_loadPageFromDisk(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_loadPageFromDisk(%p) ('%s', %d)", (const void *)script, stackPosString(0), stackPos(1)); + _screen->loadPageFromDisk(stackPosString(0), stackPos(1)); + _animator->_updateScreen = true; + return 0; +} + +int KyraEngine_LoK::o1_customPrintTalkString(EMCState *script) { + if (_flags.isTalkie) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_customPrintTalkString(%p) (%d, '%s', %d, %d, %d)", (const void *)script, stackPos(0), stackPosString(1), stackPos(2), stackPos(3), stackPos(4) & 0xFF); + + if (speechEnabled()) { + snd_voiceWaitForFinish(); + snd_playVoiceFile(stackPos(0)); + } + + _skipFlag = false; + if (textEnabled()) + _text->printTalkTextMessage(stackPosString(1), stackPos(2), stackPos(3), stackPos(4) & 0xFF, 0, 2); + } else { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_customPrintTalkString(%p) ('%s', %d, %d, %d)", (const void *)script, stackPosString(0), stackPos(1), stackPos(2), stackPos(3) & 0xFF); + _skipFlag = false; + _text->printTalkTextMessage(stackPosString(0), stackPos(1), stackPos(2), stackPos(3) & 0xFF, 0, 2); + } + _screen->updateScreen(); + return 0; +} + +int KyraEngine_LoK::o1_restoreCustomPrintBackground(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_restoreCustomPrintBackground(%p) ()", (const void *)script); + _text->restoreTalkTextMessageBkgd(2, 0); + return 0; +} + +int KyraEngine_LoK::o1_hideMouse(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_hideMouse(%p) ()", (const void *)script); + _screen->hideMouse(); + return 0; +} + +int KyraEngine_LoK::o1_showMouse(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_showMouse(%p) ()", (const void *)script); + _screen->showMouse(); + return 0; +} + +int KyraEngine_LoK::o1_getCharacterX(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_getCharacterX(%p) (%d)", (const void *)script, stackPos(0)); + return _characterList[stackPos(0)].x1; +} + +int KyraEngine_LoK::o1_getCharacterY(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_getCharacterY(%p) (%d)", (const void *)script, stackPos(0)); + return _characterList[stackPos(0)].y1; +} + +int KyraEngine_LoK::o1_changeCharactersFacing(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_changeCharactersFacing(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); + int character = stackPos(0); + int facing = stackPos(1); + int newAnimFrame = stackPos(2); + + _animator->restoreAllObjectBackgrounds(); + if (newAnimFrame != -1) + _characterList[character].currentAnimFrame = newAnimFrame; + _characterList[character].facing = facing; + _animator->animRefreshNPC(character); + _animator->preserveAllBackgrounds(); + _animator->prepDrawAllObjects(); + _animator->copyChangedObjectsForward(0); + + return 0; +} + +int KyraEngine_LoK::o1_copyWSARegion(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_copyWSARegion(%p) (%d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5)); + int xpos = stackPos(0); + int ypos = stackPos(1); + int width = stackPos(2); + int height = stackPos(3); + int srcPage = stackPos(4); + int dstPage = stackPos(5); + _screen->copyRegion(xpos, ypos, xpos, ypos, width, height, srcPage, dstPage); + _animator->_updateScreen = true; + return 0; +} + +int KyraEngine_LoK::o1_printText(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_printText(%p) ('%s', %d, %d, 0x%X, 0x%X)", (const void *)script, stackPosString(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); + if (_flags.lang == Common::JA_JPN && stackPos(3) == 7) + _screen->printText(stackPosString(0), stackPos(1), stackPos(2), 0, 0x80); + else + _screen->printText(stackPosString(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); + _screen->updateScreen(); + return 0; +} + +int KyraEngine_LoK::o1_random(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_random(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + assert(stackPos(0) < stackPos(1)); + return _rnd.getRandomNumberRng(stackPos(0), stackPos(1)); +} + +int KyraEngine_LoK::o1_loadSoundFile(EMCState *script) { + warning("STUB: o1_loadSoundFile"); + return 0; +} + +int KyraEngine_LoK::o1_displayWSAFrameOnHidPage(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_displayWSAFrameOnHidPage(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); + int frame = stackPos(0); + int xpos = stackPos(1); + int ypos = stackPos(2); + int waitTime = stackPos(3); + int wsaIndex = stackPos(4); + + _screen->hideMouse(); + uint32 continueTime = waitTime * _tickLength + _system->getMillis(); + _movieObjects[wsaIndex]->setX(xpos); + _movieObjects[wsaIndex]->setY(ypos); + _movieObjects[wsaIndex]->setDrawPage(2); + _movieObjects[wsaIndex]->displayFrame(frame); + _animator->_updateScreen = true; + while (_system->getMillis() < continueTime) { + _sprites->updateSceneAnims(); + _animator->updateAllObjectShapes(); + if (_skipFlag) + break; + + if (continueTime - _system->getMillis() >= 10) + delay(10); + } + _screen->showMouse(); + + return 0; +} + +int KyraEngine_LoK::o1_displayWSASequentialFrames(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_displayWSASequentialFrames(%p) (%d, %d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6)); + int startFrame = stackPos(0); + int endFrame = stackPos(1); + int xpos = stackPos(2); + int ypos = stackPos(3); + int waitTime = stackPos(4); + int wsaIndex = stackPos(5); + int maxTime = stackPos(6); + if (maxTime - 1 <= 0) + maxTime = 1; + + _movieObjects[wsaIndex]->setX(xpos); + _movieObjects[wsaIndex]->setY(ypos); + _movieObjects[wsaIndex]->setDrawPage(0); + + // Workaround for bug #1498221 "KYRA1: Glitches when meeting Zanthia" + // the original didn't do a forced screen update after displaying a wsa frame + // while we have to do it, which make brandon disappear for a short moment, + // what shouldn't happen. So we're not updating the screen for this special + // case too. + if (startFrame == 18 && endFrame == 18 && _currentRoom == 45) { + _movieObjects[wsaIndex]->displayFrame(18); + delay(waitTime * _tickLength); + return 0; + } + + int curTime = 0; + _screen->hideMouse(); + while (curTime < maxTime) { + if (endFrame >= startFrame) { + int frame = startFrame; + while (endFrame >= frame) { + uint32 continueTime = waitTime * _tickLength + _system->getMillis(); + _movieObjects[wsaIndex]->displayFrame(frame); + _animator->_updateScreen = true; + while (_system->getMillis() < continueTime) { + _sprites->updateSceneAnims(); + _animator->updateAllObjectShapes(); + if (_skipFlag) + break; + + if (continueTime - _system->getMillis() >= 10) + delay(10); + } + ++frame; + } + } else { + int frame = startFrame; + while (endFrame <= frame) { + uint32 continueTime = waitTime * _tickLength + _system->getMillis(); + _movieObjects[wsaIndex]->displayFrame(frame); + _animator->_updateScreen = true; + while (_system->getMillis() < continueTime) { + _sprites->updateSceneAnims(); + _animator->updateAllObjectShapes(); + if (_skipFlag) + break; + + if (continueTime - _system->getMillis() >= 10) + delay(10); + } + --frame; + } + } + + if (_skipFlag) + break; + else + ++curTime; + } + _screen->showMouse(); + + return 0; +} + +int KyraEngine_LoK::o1_drawCharacterStanding(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_drawCharacterStanding(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); + int character = stackPos(0); + int animFrame = stackPos(1); + int newFacing = stackPos(2); + int updateShapes = stackPos(3); + _characterList[character].currentAnimFrame = animFrame; + if (newFacing != -1) + _characterList[character].facing = newFacing; + _animator->animRefreshNPC(character); + if (updateShapes) + _animator->updateAllObjectShapes(); + return 0; +} + +int KyraEngine_LoK::o1_internalAnimOff(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_internalAnimOff(%p) (%d)", (const void *)script, stackPos(0)); + _animator->sprites()[stackPos(0)].active = 0; + return 0; +} + +int KyraEngine_LoK::o1_changeCharactersXAndY(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_changeCharactersXAndY(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); + Character *ch = &_characterList[stackPos(0)]; + int16 x = stackPos(1); + int16 y = stackPos(2); + if (x != -1 && y != -1) { + x &= 0xFFFC; + y &= 0xFFFE; + } + _animator->restoreAllObjectBackgrounds(); + ch->x1 = ch->x2 = x; + ch->y1 = ch->y2 = y; + _animator->preserveAllBackgrounds(); + return 0; +} + +int KyraEngine_LoK::o1_clearSceneAnimatorBeacon(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_clearSceneAnimatorBeacon(%p) ()", (const void *)script); + _sprites->_sceneAnimatorBeaconFlag = 0; + return 0; +} + +int KyraEngine_LoK::o1_querySceneAnimatorBeacon(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_querySceneAnimatorBeacon(%p) ()", (const void *)script); + return _sprites->_sceneAnimatorBeaconFlag; +} + +int KyraEngine_LoK::o1_refreshSceneAnimator(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_refreshSceneAnimator(%p) ()", (const void *)script); + _sprites->updateSceneAnims(); + _animator->updateAllObjectShapes(); + return 0; +} + +int KyraEngine_LoK::o1_placeItemInOffScene(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_placeItemInOffScene(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); + int item = stackPos(0); + int xpos = stackPos(1); + int ypos = stackPos(2); + int sceneId = stackPos(3); + + byte freeItem = findFreeItemInScene(sceneId); + if (freeItem != 0xFF) { + assert(sceneId < _roomTableSize); + Room *room = &_roomTable[sceneId]; + + room->itemsTable[freeItem] = item; + room->itemsXPos[freeItem] = xpos; + room->itemsYPos[freeItem] = ypos; + } + return 0; +} + +int KyraEngine_LoK::o1_wipeDownMouseItem(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_wipeDownMouseItem(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); + _screen->hideMouse(); + wipeDownMouseItem(stackPos(1), stackPos(2)); + destroyMouseItem(); + _screen->showMouse(); + return 0; +} + +int KyraEngine_LoK::o1_placeCharacterInOtherScene(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_placeCharacterInOtherScene(%p) (%d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5)); + int id = stackPos(0); + int sceneId = stackPos(1); + int xpos = (int16)(stackPos(2) & 0xFFFC); + int ypos = (int16)(stackPos(3) & 0xFFFE); + int facing = stackPos(4); + int animFrame = stackPos(5); + + _characterList[id].sceneId = sceneId; + _characterList[id].x1 = _characterList[id].x2 = xpos; + _characterList[id].y1 = _characterList[id].y2 = ypos; + _characterList[id].facing = facing; + _characterList[id].currentAnimFrame = animFrame; + return 0; +} + +int KyraEngine_LoK::o1_getKey(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_getKey(%p) ()", (const void *)script); + waitForEvent(); + return 0; +} + +int KyraEngine_LoK::o1_specificItemInInventory(EMCState *script) { + warning("STUB: o1_specificItemInInventory"); + return 0; +} + +int KyraEngine_LoK::o1_popMobileNPCIntoScene(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_popMobileNPCIntoScene(%p) (%d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), (int16)(stackPos(4) & 0xFFFC), (int8)(stackPos(5) & 0xFE)); + int character = stackPos(0); + int sceneId = stackPos(1); + int animFrame = stackPos(2); + int facing = stackPos(3); + int16 xpos = (int16)(stackPos(4) & 0xFFFC); + int8 ypos = (int16)(stackPos(5) & 0xFFFE); + Character *curChar = &_characterList[character]; + + curChar->sceneId = sceneId; + curChar->currentAnimFrame = animFrame; + curChar->facing = facing; + curChar->x1 = curChar->x2 = xpos; + curChar->y1 = curChar->y2 = ypos; + + _animator->animAddNPC(character); + _animator->updateAllObjectShapes(); + return 0; +} + +int KyraEngine_LoK::o1_mobileCharacterInScene(EMCState *script) { + warning("STUB: o1_mobileCharacterInScene"); + return 0; +} + +int KyraEngine_LoK::o1_hideMobileCharacter(EMCState *script) { + warning("STUB: o1_hideMobileCharacter"); + return 0; +} + +int KyraEngine_LoK::o1_unhideMobileCharacter(EMCState *script) { + warning("STUB: o1_unhideMobileCharacter"); + return 0; +} + +int KyraEngine_LoK::o1_setCharactersLocation(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_setCharactersLocation(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + Character *ch = &_characterList[stackPos(0)]; + Animator_LoK::AnimObject *animObj = &_animator->actors()[stackPos(0)]; + int newScene = stackPos(1); + if (_currentCharacter->sceneId == ch->sceneId) { + if (_currentCharacter->sceneId != newScene) + animObj->active = 0; + } else if (_currentCharacter->sceneId == newScene) { + if (_currentCharacter->sceneId != ch->sceneId) + animObj->active = 1; + } + + ch->sceneId = stackPos(1); + return 0; +} + +int KyraEngine_LoK::o1_walkCharacterToPoint(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_walkCharacterToPoint(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); + int character = stackPos(0); + int toX = stackPos(1); + int toY = stackPos(2); + _pathfinderFlag2 = 1; + uint32 nextFrame; + int findWayReturn = findWay(_characterList[character].x1, _characterList[character].y1, toX, toY, _movFacingTable, 150); + _pathfinderFlag2 = 0; + + if (_lastFindWayRet < findWayReturn) + _lastFindWayRet = findWayReturn; + if (findWayReturn == 0x7D00 || findWayReturn == 0) + return 0; + + int *curPos = _movFacingTable; + bool running = true; + while (running) { + bool forceContinue = false; + switch (*curPos) { + case 0: + _characterList[character].facing = 2; + break; + + case 1: + _characterList[character].facing = 1; + break; + + case 2: + _characterList[character].facing = 0; + break; + + case 3: + _characterList[character].facing = 7; + break; + + case 4: + _characterList[character].facing = 6; + break; + + case 5: + _characterList[character].facing = 5; + break; + + case 6: + _characterList[character].facing = 4; + break; + + case 7: + _characterList[character].facing = 3; + break; + + case 8: + running = 0; + break; + + default: + ++curPos; + forceContinue = true; + break; + } + + if (forceContinue || !running) + continue; + + setCharacterPosition(character, 0); + ++curPos; + + nextFrame = _timer->getDelay(5 + character) * _tickLength + _system->getMillis(); + while (_system->getMillis() < nextFrame) { + _sprites->updateSceneAnims(); + updateMousePointer(); + _timer->update(); + _animator->updateAllObjectShapes(); + updateTextFade(); + if ((nextFrame - _system->getMillis()) >= 10) + delay(10); + } + } + return 0; +} + +int KyraEngine_LoK::o1_specialEventDisplayBrynnsNote(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_specialEventDisplayBrynnsNote(%p) ()", (const void *)script); + _screen->hideMouse(); + _screen->savePageToDisk("HIDPAGE.TMP", 2); + _screen->savePageToDisk("SEENPAGE.TMP", 0); + if (_flags.isTalkie) { + if (_flags.lang == Common::EN_ANY || _flags.lang == Common::IT_ITA) + _screen->loadBitmap("NOTEENG.CPS", 3, 3, 0); + else if (_flags.lang == Common::FR_FRA) + _screen->loadBitmap("NOTEFRE.CPS", 3, 3, 0); + else if (_flags.lang == Common::DE_DEU) + _screen->loadBitmap("NOTEGER.CPS", 3, 3, 0); + } else { + _screen->loadBitmap("NOTE.CPS", 3, 3, 0); + } + _screen->copyRegion(63, 8, 63, 8, 194, 128, 2, 0); + _screen->updateScreen(); + _screen->showMouse(); + _screen->setFont(Screen::FID_6_FNT); + return 0; +} + +int KyraEngine_LoK::o1_specialEventRemoveBrynnsNote(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_specialEventRemoveBrynnsNote(%p) ()", (const void *)script); + _screen->hideMouse(); + _screen->loadPageFromDisk("SEENPAGE.TMP", 0); + _screen->loadPageFromDisk("HIDPAGE.TMP", 2); + _screen->updateScreen(); + _screen->showMouse(); + _screen->setFont(Screen::FID_8_FNT); + return 0; +} + +int KyraEngine_LoK::o1_setLogicPage(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_setLogicPage(%p) (%d)", (const void *)script, stackPos(0)); + _screen->_curPage = stackPos(0); + return stackPos(0); +} + +int KyraEngine_LoK::o1_fatPrint(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_fatPrint(%p) ('%s', %d, %d, %d, %d, %d)", (const void *)script, stackPosString(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5)); + + // Workaround for bug #1582672 ("KYRA1: Text crippled and drawn wrong") + // I'm not sure how the original handles this, since it seems to call + // printText also, maybe it fails somewhere inside... + // TODO: fix the reason for this workaround + if (_currentRoom == 117) + return 0; + _text->printText(stackPosString(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5)); + return 0; +} + +int KyraEngine_LoK::o1_preserveAllObjectBackgrounds(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_preserveAllObjectBackgrounds(%p) ()", (const void *)script); + _animator->preserveAllBackgrounds(); + return 0; +} + +int KyraEngine_LoK::o1_updateSceneAnimations(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_updateSceneAnimations(%p) (%d)", (const void *)script, stackPos(0)); + int times = stackPos(0); + while (times--) { + _sprites->updateSceneAnims(); + _animator->updateAllObjectShapes(); + } + return 0; +} + +int KyraEngine_LoK::o1_sceneAnimationActive(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_sceneAnimationActive(%p) (%d)", (const void *)script, stackPos(0)); + return _sprites->_anims[stackPos(0)].play; +} + +int KyraEngine_LoK::o1_setCharactersMovementDelay(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_setCharactersMovementDelay(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + _timer->setDelay(stackPos(0)+5, stackPos(1)); + return 0; +} + +int KyraEngine_LoK::o1_getCharactersFacing(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_getCharactersFacing(%p) (%d)", (const void *)script, stackPos(0)); + return _characterList[stackPos(0)].facing; +} + +int KyraEngine_LoK::o1_bkgdScrollSceneAndMasksRight(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_bkgdScrollSceneAndMasksRight(%p) (%d)", (const void *)script, stackPos(0)); + _screen->copyBackgroundBlock(stackPos(0), 2, 0); + _screen->copyBackgroundBlock2(stackPos(0)); + // update the whole screen + _screen->copyRegion(7, 7, 7, 7, 305, 129, 3, 0); + // Don't do a screen update here, see bug #1910180 "KYRA1: Screen 'flash'" + // it would cause to draw the screen with a wrong palette and thus look + // strange for the user. Since this opcode should be just called on scene + // initialization anyway, there should be no problem with not updating the + // screen right now. + return 0; +} + +int KyraEngine_LoK::o1_dispelMagicAnimation(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_dispelMagicAnimation(%p) ()", (const void *)script); + seq_dispelMagicAnimation(); + return 0; +} + +int KyraEngine_LoK::o1_findBrightestFireberry(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_findBrightestFireberry(%p) ()", (const void *)script); + if (_currentCharacter->sceneId >= 187 && _currentCharacter->sceneId <= 198) + return 29; + + if (_currentCharacter->sceneId == 133 || _currentCharacter->sceneId == 137 || + _currentCharacter->sceneId == 165 || _currentCharacter->sceneId == 173) + return 29; + + if (_itemInHand == 28) + return 28; + + int brightestFireberry = 107; + if (_itemInHand >= 29 && _itemInHand <= 33) + brightestFireberry = _itemInHand; + for (int i = 0; i < 10; ++i) { + uint8 item = _currentCharacter->inventoryItems[i]; + if (item == 0xFF) + continue; + if (item == 28) + return 28; + if (item >= 29 && item <= 33) { + if (item < brightestFireberry) + brightestFireberry = item; + } + } + assert(_currentCharacter->sceneId < _roomTableSize); + Room *curRoom = &_roomTable[_currentCharacter->sceneId]; + for (int i = 0; i < 12; ++i) { + uint8 item = curRoom->itemsTable[i]; + if (item == 0xFF) + continue; + if (item == 28) + return 28; + if (item >= 29 && item <= 33) { + if (item < brightestFireberry) + brightestFireberry = item; + } + } + if (brightestFireberry == 107) + return -1; + return brightestFireberry; +} + +int KyraEngine_LoK::o1_setFireberryGlowPalette(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_setFireberryGlowPalette(%p) (%d)", (const void *)script, stackPos(0)); + int palIndex = 0; + switch (stackPos(0)) { + case 0x1E: + palIndex = 9; + break; + + case 0x1F: + palIndex = 10; + break; + + case 0x20: + palIndex = 11; + break; + + case 0x21: + case -1: + palIndex = 12; + break; + + default: + palIndex = 8; + break; + } + if (_brandonStatusBit & 2) { + if (_currentCharacter->sceneId != 133 && _currentCharacter->sceneId != 137 && + _currentCharacter->sceneId != 165 && _currentCharacter->sceneId != 173 && + (_currentCharacter->sceneId < 187 || _currentCharacter->sceneId > 198)) { + palIndex = 14; + } + } + const uint8 *palette = _specialPalettes[palIndex]; + memcpy(_screen->getPalette(1) + 684, palette, 44); + return 0; +} + +int KyraEngine_LoK::o1_setDeathHandlerFlag(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_setDeathHandlerFlag(%p) (%d)", (const void *)script, stackPos(0)); + _deathHandler = stackPos(0); + return 0; +} + +int KyraEngine_LoK::o1_drinkPotionAnimation(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_drinkPotionAnimation(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); + seq_playDrinkPotionAnim(stackPos(0), stackPos(1), stackPos(2)); + return 0; +} + +int KyraEngine_LoK::o1_makeAmuletAppear(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_makeAmuletAppear(%p) ()", (const void *)script); + WSAMovie_v1 amulet(this); + amulet.open("AMULET.WSA", 1, 0); + amulet.setX(224); + amulet.setY(152); + amulet.setDrawPage(0); + if (amulet.opened()) { + assert(_amuleteAnim); + _screen->hideMouse(); + snd_playSoundEffect(0x70); + uint32 nextTime = 0; + for (int i = 0; _amuleteAnim[i] != 0xFF; ++i) { + nextTime = _system->getMillis() + 5 * _tickLength; + + uint8 code = _amuleteAnim[i]; + if (code == 3 || code == 7) + snd_playSoundEffect(0x71); + + if (code == 5) + snd_playSoundEffect(0x72); + + if (code == 14) + snd_playSoundEffect(0x73); + + amulet.displayFrame(code); + _animator->_updateScreen = true; + + while (_system->getMillis() < nextTime) { + _sprites->updateSceneAnims(); + _animator->updateAllObjectShapes(); + if (nextTime - _system->getMillis() >= 10) + delay(10); + } + } + _screen->showMouse(); + } + setGameFlag(0x2D); + return 0; +} + +int KyraEngine_LoK::o1_drawItemShapeIntoScene(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_drawItemShapeIntoScene(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); + int item = stackPos(0); + int x = stackPos(1); + int y = stackPos(2); + int flags = stackPos(3); + int onlyHidPage = stackPos(4); + + if (flags) + flags = 1; + + if (onlyHidPage) { + _screen->drawShape(2, _shapes[216+item], x, y, 0, flags); + } else { + _screen->hideMouse(); + _animator->restoreAllObjectBackgrounds(); + _screen->drawShape(2, _shapes[216+item], x, y, 0, flags); + _screen->drawShape(0, _shapes[216+item], x, y, 0, flags); + _animator->flagAllObjectsForBkgdChange(); + _animator->preserveAnyChangedBackgrounds(); + _animator->flagAllObjectsForRefresh(); + _animator->updateAllObjectShapes(); + _screen->showMouse(); + } + return 0; +} + +int KyraEngine_LoK::o1_setCharactersCurrentFrame(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_setCharactersCurrentFrame(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + _characterList[stackPos(0)].currentAnimFrame = stackPos(1); + return 0; +} + +int KyraEngine_LoK::o1_waitForConfirmationMouseClick(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_waitForConfirmationMouseClick(%p) ()", (const void *)script); + // if (mouseEnabled) { + while (!_mousePressFlag) { + updateMousePointer(); + _sprites->updateSceneAnims(); + _animator->updateAllObjectShapes(); + delay(10); + } + + while (_mousePressFlag) { + updateMousePointer(); + _sprites->updateSceneAnims(); + _animator->updateAllObjectShapes(); + delay(10); + } + // } + _gui->processButtonList(_buttonList, 0, 0); + _skipFlag = false; + Common::Point mouse = getMousePos(); + script->regs[1] = mouse.x; + script->regs[2] = mouse.y; + return 0; +} + +int KyraEngine_LoK::o1_pageFlip(EMCState *script) { + warning("STUB: o1_pageFlip"); + return 0; +} + +int KyraEngine_LoK::o1_setSceneFile(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_setSceneFile(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + setSceneFile(stackPos(0), stackPos(1)); + return 0; +} + +int KyraEngine_LoK::o1_getItemInMarbleVase(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_getItemInMarbleVase(%p) ()", (const void *)script); + return _marbleVaseItem; +} + +int KyraEngine_LoK::o1_setItemInMarbleVase(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_setItemInMarbleVase(%p) (%d)", (const void *)script, stackPos(0)); + _marbleVaseItem = stackPos(0); + return 0; +} + +int KyraEngine_LoK::o1_addItemToInventory(EMCState *script) { + warning("STUB: o1_addItemToInventory"); + return 0; +} + +int KyraEngine_LoK::o1_intPrint(EMCState *script) { + warning("STUB: o1_intPrint"); + return 0; +} + +int KyraEngine_LoK::o1_shakeScreen(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_shakeScreen(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + int waitTicks = stackPos(1); + int times = stackPos(0); + + for (int i = 0; i < times; ++i) { + _screen->shakeScreen(1); + delay(waitTicks * _tickLength); + } + + return 0; +} + +int KyraEngine_LoK::o1_createAmuletJewel(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_createAmuletJewel(%p) (%d)", (const void *)script, stackPos(0)); + seq_createAmuletJewel(stackPos(0), 0, 0, 0); + return 0; +} + +int KyraEngine_LoK::o1_setSceneAnimCurrXY(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_setSceneAnimCurrXY(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); + _sprites->_anims[stackPos(0)].x = stackPos(1); + _sprites->_anims[stackPos(0)].y = stackPos(2); + return 0; +} + +int KyraEngine_LoK::o1_poisonBrandonAndRemaps(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_poisonBrandonAndRemaps(%p) ()", (const void *)script); + setBrandonPoisonFlags(1); + return 0; +} + +int KyraEngine_LoK::o1_fillFlaskWithWater(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_fillFlaskWithWater(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + seq_fillFlaskWithWater(stackPos(0), stackPos(1)); + return 0; +} + +int KyraEngine_LoK::o1_getCharactersMovementDelay(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_getCharactersMovementDelay(%p) (%d)", (const void *)script, stackPos(0)); + return _timer->getDelay(stackPos(0)+5); +} + +int KyraEngine_LoK::o1_getBirthstoneGem(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_getBirthstoneGem(%p) (%d)", (const void *)script, stackPos(0)); + if (stackPos(0) < 4) + return _birthstoneGemTable[stackPos(0)]; + return 0; +} + +int KyraEngine_LoK::o1_queryBrandonStatusBit(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_queryBrandonStatusBit(%p) (%d)", (const void *)script, stackPos(0)); + if (_brandonStatusBit & stackPos(0)) + return 1; + return 0; +} + +int KyraEngine_LoK::o1_playFluteAnimation(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_playFluteAnimation(%p) ()", (const void *)script); + seq_playFluteAnimation(); + return 0; +} + +int KyraEngine_LoK::o1_playWinterScrollSequence(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_playWinterScrollSequence(%p) (%d)", (const void *)script, stackPos(0)); + if (!stackPos(0)) + seq_winterScroll2(); + else + seq_winterScroll1(); + return 0; +} + +int KyraEngine_LoK::o1_getIdolGem(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_getIdolGem(%p) (%d)", (const void *)script, stackPos(0)); + return _idolGemsTable[stackPos(0)]; +} + +int KyraEngine_LoK::o1_setIdolGem(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_setIdolGem(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + _idolGemsTable[stackPos(0)] = stackPos(1); + return 0; +} + +int KyraEngine_LoK::o1_totalItemsInScene(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_totalItemsInScene(%p) (%d)", (const void *)script, stackPos(0)); + return countItemsInScene(stackPos(0)); +} + +int KyraEngine_LoK::o1_restoreBrandonsMovementDelay(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_restoreBrandonsMovementDelay(%p) ()", (const void *)script); + setWalkspeed(_configWalkspeed); + return 0; +} + +int KyraEngine_LoK::o1_setMousePos(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_setMousePos(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + _system->warpMouse(stackPos(0), stackPos(1)); + return 0; +} + +int KyraEngine_LoK::o1_getMouseState(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_getMouseState(%p) ()", (const void *)script); + return _mouseState; +} + +int KyraEngine_LoK::o1_setEntranceMouseCursorTrack(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_setEntranceMouseCursorTrack(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); + _entranceMouseCursorTracks[0] = stackPos(0); + _entranceMouseCursorTracks[1] = stackPos(1); + _entranceMouseCursorTracks[2] = stackPos(0) + stackPos(2) - 1; + _entranceMouseCursorTracks[3] = stackPos(1) + stackPos(3) - 1; + _entranceMouseCursorTracks[4] = stackPos(4); + return 0; +} + +int KyraEngine_LoK::o1_itemAppearsOnGround(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_itemAppearsOnGround(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); + processItemDrop(_currentCharacter->sceneId, stackPos(0), stackPos(1), stackPos(2), 2, 0); + return 0; +} + +int KyraEngine_LoK::o1_setNoDrawShapesFlag(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_setNoDrawShapesFlag(%p) (%d)", (const void *)script, stackPos(0)); + _animator->_noDrawShapesFlag = stackPos(0); + return 0; +} + +int KyraEngine_LoK::o1_fadeEntirePalette(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_fadeEntirePalette(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + int cmd = stackPos(0); + uint8 *fadePal = 0; + + if (_flags.platform == Common::kPlatformAmiga) { + if (cmd == 0) { + fadePal = _screen->getPalette(2); + memset(fadePal, 0, 32*3); + memcpy(_screen->getPalette(4), _screen->getPalette(0), 32*3); + } else if (cmd == 1) { + fadePal = _screen->getPalette(0); + memcpy(_screen->getPalette(0), _screen->getPalette(4), 32*3); + } else if (cmd == 2) { + fadePal = _screen->getPalette(0); + memset(_screen->getPalette(2), 0, 32*3); + } + } else { + if (cmd == 0) { + fadePal = _screen->getPalette(2); + uint8 *screenPal = _screen->getPalette(0); + uint8 *backUpPal = _screen->getPalette(3); + + memcpy(backUpPal, screenPal, sizeof(uint8)*768); + memset(fadePal, 0, sizeof(uint8)*768); + } else if (cmd == 1) { + //fadePal = _screen->getPalette(3); + warning("unimplemented o1_fadeEntirePalette function"); + return 0; + } else if (cmd == 2) { + memset(_screen->getPalette(2), 0, 768); + memcpy(_screen->getPalette(0), _screen->getPalette(1), 768); + fadePal = _screen->getPalette(0); + } + } + + _screen->fadePalette(fadePal, stackPos(1)); + return 0; +} + +int KyraEngine_LoK::o1_itemOnGroundHere(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_itemOnGroundHere(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + assert(stackPos(0) < _roomTableSize); + Room *curRoom = &_roomTable[stackPos(0)]; + for (int i = 0; i < 12; ++i) { + if (curRoom->itemsTable[i] == stackPos(1)) + return 1; + } + return 0; +} + +int KyraEngine_LoK::o1_queryCauldronState(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_queryCauldronState(%p) ()", (const void *)script); + return _cauldronState; +} + +int KyraEngine_LoK::o1_setCauldronState(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_setCauldronState(%p) (%d)", (const void *)script, stackPos(0)); + _cauldronState = stackPos(0); + return _cauldronState; +} + +int KyraEngine_LoK::o1_queryCrystalState(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_queryCrystalState(%p) (%d)", (const void *)script, stackPos(0)); + if (!stackPos(0)) + return _crystalState[0]; + else if (stackPos(0) == 1) + return _crystalState[1]; + return -1; +} + +int KyraEngine_LoK::o1_setCrystalState(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_setCrystalState(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + if (!stackPos(0)) + _crystalState[0] = stackPos(1); + else if (stackPos(0) == 1) + _crystalState[1] = stackPos(1); + return stackPos(1); +} + +int KyraEngine_LoK::o1_setPaletteRange(EMCState *script) { + warning("STUB: o1_setPaletteRange"); + return 0; +} + +int KyraEngine_LoK::o1_shrinkBrandonDown(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_shrinkBrandonDown(%p) (%d)", (const void *)script, stackPos(0)); + int delayTime = stackPos(0); + checkAmuletAnimFlags(); + int scaleValue = _scaleTable[_currentCharacter->y1]; + int scale = 0; + + if (_scaleMode) + scale = scaleValue; + else + scale = 256; + + int scaleModeBackUp = _scaleMode; + _scaleMode = 1; + int scaleEnd = scale >> 1; + for (; scaleEnd <= scale; --scale) { + _scaleTable[_currentCharacter->y1] = scale; + _animator->animRefreshNPC(0); + delayWithTicks(1); + } + delayWithTicks(delayTime); // XXX + _scaleTable[_currentCharacter->y1] = scaleValue; + _scaleMode = scaleModeBackUp; + return 0; +} + +int KyraEngine_LoK::o1_growBrandonUp(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_growBrandonUp(%p) ()", (const void *)script); + int scaleValue = _scaleTable[_currentCharacter->y1]; + int scale = 0; + if (_scaleMode) + scale = scaleValue; + else + scale = 256; + + int scaleModeBackUp = _scaleMode; + _scaleMode = 1; + for (int curScale = scale >> 1; curScale <= scale; ++curScale) { + _scaleTable[_currentCharacter->y1] = curScale; + _animator->animRefreshNPC(0); + delayWithTicks(1); + } + _scaleTable[_currentCharacter->y1] = scaleValue; + _scaleMode = scaleModeBackUp; + return 0; +} + +int KyraEngine_LoK::o1_setBrandonScaleXAndY(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_setBrandonScaleXAndY(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + _animator->_brandonScaleX = stackPos(0); + _animator->_brandonScaleY = stackPos(1); + return 0; +} + +int KyraEngine_LoK::o1_resetScaleMode(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_resetScaleMode(%p) ()", (const void *)script); + _scaleMode = 0; + return 0; +} + +int KyraEngine_LoK::o1_getScaleDepthTableValue(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_getScaleDepthTableValue(%p) (%d)", (const void *)script, stackPos(0)); + assert(stackPos(0) < ARRAYSIZE(_scaleTable)); + return _scaleTable[stackPos(0)]; +} + +int KyraEngine_LoK::o1_setScaleDepthTableValue(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_setScaleDepthTableValue(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + assert(stackPos(0) < ARRAYSIZE(_scaleTable)); + _scaleTable[stackPos(0)] = stackPos(1); + return stackPos(1); +} + +int KyraEngine_LoK::o1_message(EMCState *script) { + if (_flags.isTalkie) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_message(%p) (%d, '%s', %d)", (const void *)script, stackPos(0), stackPosString(1), stackPos(2)); + drawSentenceCommand(stackPosString(1), stackPos(2)); + } else { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_message(%p) ('%s', %d)", (const void *)script, stackPosString(0), stackPos(1)); + drawSentenceCommand(stackPosString(0), stackPos(1)); + } + + return 0; +} + +int KyraEngine_LoK::o1_checkClickOnNPC(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_checkClickOnNPC(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + return checkForNPCScriptRun(stackPos(0), stackPos(1)); +} + +int KyraEngine_LoK::o1_getFoyerItem(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_getFoyerItem(%p) (%d)", (const void *)script, stackPos(0)); + assert(stackPos(0) < ARRAYSIZE(_foyerItemTable)); + return _foyerItemTable[stackPos(0)]; +} + +int KyraEngine_LoK::o1_setFoyerItem(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_setFoyerItem(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + assert(stackPos(0) < ARRAYSIZE(_foyerItemTable)); + _foyerItemTable[stackPos(0)] = stackPos(1); + return stackPos(1); +} + +int KyraEngine_LoK::o1_setNoItemDropRegion(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_setNoItemDropRegion(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); + addToNoDropRects(stackPos(0), stackPos(1), stackPos(2), stackPos(3)); + return 0; +} + +int KyraEngine_LoK::o1_walkMalcolmOn(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_walkMalcolmOn(%p) ()", (const void *)script); + if (!_malcolmFlag) + _malcolmFlag = 1; + return 0; +} + +int KyraEngine_LoK::o1_passiveProtection(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_passiveProtection(%p) ()", (const void *)script); + return 1; +} + +int KyraEngine_LoK::o1_setPlayingLoop(EMCState *script) { + warning("STUB: o1_setPlayingLoop"); + return 0; +} + +int KyraEngine_LoK::o1_brandonToStoneSequence(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_brandonToStoneSequence(%p) ()", (const void *)script); + seq_brandonToStone(); + return 0; +} + +int KyraEngine_LoK::o1_brandonHealingSequence(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_brandonHealingSequence(%p) ()", (const void *)script); + seq_brandonHealing(); + return 0; +} + +int KyraEngine_LoK::o1_protectCommandLine(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_protectCommandLine(%p) (%d)", (const void *)script, stackPos(0)); + return stackPos(0); +} + +int KyraEngine_LoK::o1_pauseMusicSeconds(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_pauseMusicSeconds(%p) ()", (const void *)script); + // if music disabled + // return + o1_pauseSeconds(script); + return 0; +} + +int KyraEngine_LoK::o1_resetMaskRegion(EMCState *script) { + warning("STUB: o1_resetMaskRegion"); + return 0; +} + +int KyraEngine_LoK::o1_setPaletteChangeFlag(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_setPaletteChangeFlag(%p) (%d)", (const void *)script, stackPos(0)); + _paletteChanged = stackPos(0); + return _paletteChanged; +} + +int KyraEngine_LoK::o1_fillRect(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_fillRect(%p) (%d, %d, %d, %d, %d, 0x%X)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5)); + int videoPageBackup = _screen->_curPage; + _screen->_curPage = stackPos(0); + _screen->fillRect(stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5)); + _screen->_curPage = videoPageBackup; + return 0; +} + +int KyraEngine_LoK::o1_vocUnload(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_vocUnload(%p) ()", (const void *)script); + // this should unload all voc files (not needed) + return 0; +} + +int KyraEngine_LoK::o1_vocLoad(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_vocLoad(%p) (%d)", (const void *)script, stackPos(0)); + // this should load the specified voc file (not needed) + return 0; +} + +int KyraEngine_LoK::o1_dummy(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_dummy(%p) ()", (const void *)script); + return 0; +} + +#pragma mark - + +typedef Common::Functor1Mem OpcodeV1; +#define SetOpcodeTable(x) table = &x; +#define Opcode(x) table->push_back(new OpcodeV1(this, &KyraEngine_LoK::x)) +void KyraEngine_LoK::setupOpcodeTable() { + Common::Array *table = 0; + + SetOpcodeTable(_opcodes); + // 0x00 + Opcode(o1_magicInMouseItem); + Opcode(o1_characterSays); + Opcode(o1_pauseTicks); + Opcode(o1_drawSceneAnimShape); + // 0x04 + Opcode(o1_queryGameFlag); + Opcode(o1_setGameFlag); + Opcode(o1_resetGameFlag); + Opcode(o1_runNPCScript); + // 0x08 + Opcode(o1_setSpecialExitList); + Opcode(o1_blockInWalkableRegion); + Opcode(o1_blockOutWalkableRegion); + Opcode(o1_walkPlayerToPoint); + // 0x0c + Opcode(o1_dropItemInScene); + Opcode(o1_drawAnimShapeIntoScene); + Opcode(o1_createMouseItem); + Opcode(o1_savePageToDisk); + // 0x10 + Opcode(o1_sceneAnimOn); + Opcode(o1_sceneAnimOff); + Opcode(o1_getElapsedSeconds); + Opcode(o1_mouseIsPointer); + // 0x14 + Opcode(o1_destroyMouseItem); + Opcode(o1_runSceneAnimUntilDone); + Opcode(o1_fadeSpecialPalette); + Opcode(o1_playAdlibSound); + // 0x18 + Opcode(o1_playAdlibScore); + Opcode(o1_phaseInSameScene); + Opcode(o1_setScenePhasingFlag); + Opcode(o1_resetScenePhasingFlag); + // 0x1c + Opcode(o1_queryScenePhasingFlag); + Opcode(o1_sceneToDirection); + Opcode(o1_setBirthstoneGem); + Opcode(o1_placeItemInGenericMapScene); + // 0x20 + Opcode(o1_setBrandonStatusBit); + Opcode(o1_pauseSeconds); + Opcode(o1_getCharactersLocation); + Opcode(o1_runNPCSubscript); + // 0x24 + Opcode(o1_magicOutMouseItem); + Opcode(o1_internalAnimOn); + Opcode(o1_forceBrandonToNormal); + Opcode(o1_poisonDeathNow); + // 0x28 + Opcode(o1_setScaleMode); + Opcode(o1_openWSAFile); + Opcode(o1_closeWSAFile); + Opcode(o1_runWSAFromBeginningToEnd); + // 0x2c + Opcode(o1_displayWSAFrame); + Opcode(o1_enterNewScene); + Opcode(o1_setSpecialEnterXAndY); + Opcode(o1_runWSAFrames); + // 0x30 + Opcode(o1_popBrandonIntoScene); + Opcode(o1_restoreAllObjectBackgrounds); + Opcode(o1_setCustomPaletteRange); + Opcode(o1_loadPageFromDisk); + // 0x34 + Opcode(o1_customPrintTalkString); + Opcode(o1_restoreCustomPrintBackground); + Opcode(o1_hideMouse); + Opcode(o1_showMouse); + // 0x38 + Opcode(o1_getCharacterX); + Opcode(o1_getCharacterY); + Opcode(o1_changeCharactersFacing); + Opcode(o1_copyWSARegion); + // 0x3c + Opcode(o1_printText); + Opcode(o1_random); + Opcode(o1_loadSoundFile); + Opcode(o1_displayWSAFrameOnHidPage); + // 0x40 + Opcode(o1_displayWSASequentialFrames); + Opcode(o1_drawCharacterStanding); + Opcode(o1_internalAnimOff); + Opcode(o1_changeCharactersXAndY); + // 0x44 + Opcode(o1_clearSceneAnimatorBeacon); + Opcode(o1_querySceneAnimatorBeacon); + Opcode(o1_refreshSceneAnimator); + Opcode(o1_placeItemInOffScene); + // 0x48 + Opcode(o1_wipeDownMouseItem); + Opcode(o1_placeCharacterInOtherScene); + Opcode(o1_getKey); + Opcode(o1_specificItemInInventory); + // 0x4c + Opcode(o1_popMobileNPCIntoScene); + Opcode(o1_mobileCharacterInScene); + Opcode(o1_hideMobileCharacter); + Opcode(o1_unhideMobileCharacter); + // 0x50 + Opcode(o1_setCharactersLocation); + Opcode(o1_walkCharacterToPoint); + Opcode(o1_specialEventDisplayBrynnsNote); + Opcode(o1_specialEventRemoveBrynnsNote); + // 0x54 + Opcode(o1_setLogicPage); + Opcode(o1_fatPrint); + Opcode(o1_preserveAllObjectBackgrounds); + Opcode(o1_updateSceneAnimations); + // 0x58 + Opcode(o1_sceneAnimationActive); + Opcode(o1_setCharactersMovementDelay); + Opcode(o1_getCharactersFacing); + Opcode(o1_bkgdScrollSceneAndMasksRight); + // 0x5c + Opcode(o1_dispelMagicAnimation); + Opcode(o1_findBrightestFireberry); + Opcode(o1_setFireberryGlowPalette); + Opcode(o1_setDeathHandlerFlag); + // 0x60 + Opcode(o1_drinkPotionAnimation); + Opcode(o1_makeAmuletAppear); + Opcode(o1_drawItemShapeIntoScene); + Opcode(o1_setCharactersCurrentFrame); + // 0x64 + Opcode(o1_waitForConfirmationMouseClick); + Opcode(o1_pageFlip); + Opcode(o1_setSceneFile); + Opcode(o1_getItemInMarbleVase); + // 0x68 + Opcode(o1_setItemInMarbleVase); + Opcode(o1_addItemToInventory); + Opcode(o1_intPrint); + Opcode(o1_shakeScreen); + // 0x6c + Opcode(o1_createAmuletJewel); + Opcode(o1_setSceneAnimCurrXY); + Opcode(o1_poisonBrandonAndRemaps); + Opcode(o1_fillFlaskWithWater); + // 0x70 + Opcode(o1_getCharactersMovementDelay); + Opcode(o1_getBirthstoneGem); + Opcode(o1_queryBrandonStatusBit); + Opcode(o1_playFluteAnimation); + // 0x74 + Opcode(o1_playWinterScrollSequence); + Opcode(o1_getIdolGem); + Opcode(o1_setIdolGem); + Opcode(o1_totalItemsInScene); + // 0x78 + Opcode(o1_restoreBrandonsMovementDelay); + Opcode(o1_setMousePos); + Opcode(o1_getMouseState); + Opcode(o1_setEntranceMouseCursorTrack); + // 0x7c + Opcode(o1_itemAppearsOnGround); + Opcode(o1_setNoDrawShapesFlag); + Opcode(o1_fadeEntirePalette); + Opcode(o1_itemOnGroundHere); + // 0x80 + Opcode(o1_queryCauldronState); + Opcode(o1_setCauldronState); + Opcode(o1_queryCrystalState); + Opcode(o1_setCrystalState); + // 0x84 + Opcode(o1_setPaletteRange); + Opcode(o1_shrinkBrandonDown); + Opcode(o1_growBrandonUp); + Opcode(o1_setBrandonScaleXAndY); + // 0x88 + Opcode(o1_resetScaleMode); + Opcode(o1_getScaleDepthTableValue); + Opcode(o1_setScaleDepthTableValue); + Opcode(o1_message); + // 0x8c + Opcode(o1_checkClickOnNPC); + Opcode(o1_getFoyerItem); + Opcode(o1_setFoyerItem); + Opcode(o1_setNoItemDropRegion); + // 0x90 + Opcode(o1_walkMalcolmOn); + Opcode(o1_passiveProtection); + Opcode(o1_setPlayingLoop); + Opcode(o1_brandonToStoneSequence); + // 0x94 + Opcode(o1_brandonHealingSequence); + Opcode(o1_protectCommandLine); + Opcode(o1_pauseMusicSeconds); + Opcode(o1_resetMaskRegion); + // 0x98 + Opcode(o1_setPaletteChangeFlag); + Opcode(o1_fillRect); + Opcode(o1_vocUnload); + Opcode(o1_vocLoad); + // 0x9c + Opcode(o1_dummy); +} +#undef Opcode + +} // end of namespace Kyra + diff --git a/engines/kyra/script_v1.cpp b/engines/kyra/script_v1.cpp deleted file mode 100644 index 6eb02c7511..0000000000 --- a/engines/kyra/script_v1.cpp +++ /dev/null @@ -1,2031 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - - -#include "common/endian.h" -#include "common/system.h" - -#include "kyra/kyra_v1.h" -#include "kyra/script.h" -#include "kyra/screen.h" -#include "kyra/sprites.h" -#include "kyra/wsamovie.h" -#include "kyra/animator_v1.h" -#include "kyra/text.h" -#include "kyra/timer.h" - -namespace Kyra { -int KyraEngine_v1::o1_magicInMouseItem(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_magicInMouseItem(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - magicInMouseItem(stackPos(0), stackPos(1), -1); - return 0; -} - -int KyraEngine_v1::o1_characterSays(EMCState *script) { - _skipFlag = false; - if (_flags.isTalkie) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_characterSays(%p) (%d, '%s', %d, %d)", (const void *)script, stackPos(0), stackPosString(1), stackPos(2), stackPos(3)); - characterSays(stackPos(0), stackPosString(1), stackPos(2), stackPos(3)); - } else { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_characterSays(%p) ('%s', %d, %d)", (const void *)script, stackPosString(0), stackPos(1), stackPos(2)); - const char *string = stackPosString(0); - - if ((_flags.platform == Common::kPlatformFMTowns || _flags.platform == Common::kPlatformPC98) && _flags.lang == Common::JA_JPN) { - static const uint8 townsString1[] = { - 0x83, 0x75, 0x83, 0x89, 0x83, 0x93, 0x83, 0x83, 0x93, 0x81, - 0x41, 0x82, 0xDC, 0x82, 0xBD, 0x97, 0x88, 0x82, 0xBD, 0x82, - 0xCC, 0x82, 0xA9, 0x81, 0x48, 0x00, 0x00, 0x00 - }; - static const uint8 townsString2[] = { - 0x83, 0x75, 0x83, 0x89, 0x83, 0x93, 0x83, 0x5C, 0x83, 0x93, - 0x81, 0x41, 0x82, 0xDC, 0x82, 0xBD, 0x97, 0x88, 0x82, 0xBD, - 0x82, 0xCC, 0x82, 0xA9, 0x81, 0x48, 0x00, 0x00 - }; - - if (strncmp((const char *)townsString1, string, sizeof(townsString1)) == 0) - string = (const char *)townsString2; - } - - characterSays(-1, string, stackPos(1), stackPos(2)); - } - - return 0; -} - -int KyraEngine_v1::o1_pauseTicks(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_pauseTicks(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - if (stackPos(1)) { - warning("STUB: special o1_pauseTicks"); - // delete this after correct implementing - delayWithTicks(stackPos(0)); - } else { - delayWithTicks(stackPos(0)); - } - return 0; -} - -int KyraEngine_v1::o1_drawSceneAnimShape(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_drawSceneAnimShape(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); - _screen->drawShape(stackPos(4), _sprites->_sceneShapes[stackPos(0)], stackPos(1), stackPos(2), 0, (stackPos(3) != 0) ? 1 : 0); - return 0; -} - -int KyraEngine_v1::o1_queryGameFlag(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_queryGameFlag(%p) (0x%X)", (const void *)script, stackPos(0)); - return queryGameFlag(stackPos(0)); -} - -int KyraEngine_v1::o1_setGameFlag(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setGameFlag(%p) (0x%X)", (const void *)script, stackPos(0)); - return setGameFlag(stackPos(0)); -} - -int KyraEngine_v1::o1_resetGameFlag(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_resetGameFlag(%p) (0x%X)", (const void *)script, stackPos(0)); - return resetGameFlag(stackPos(0)); -} - -int KyraEngine_v1::o1_runNPCScript(EMCState *script) { - warning("STUB: o1_runNPCScript"); - return 0; -} - -int KyraEngine_v1::o1_setSpecialExitList(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setSpecialExitList(%p) (%d, %d, %d, %d, %d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7), stackPos(8), stackPos(9)); - - for (int i = 0; i < 10; ++i) - _exitList[i] = stackPos(i); - _exitListPtr = _exitList; - - return 0; -} - -int KyraEngine_v1::o1_blockInWalkableRegion(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_blockInWalkableRegion(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); - _screen->blockInRegion(stackPos(0), stackPos(1), stackPos(2)-stackPos(0)+1, stackPos(3)-stackPos(1)+1); - return 0; -} - -int KyraEngine_v1::o1_blockOutWalkableRegion(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_blockOutWalkableRegion(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); - _screen->blockOutRegion(stackPos(0), stackPos(1), stackPos(2)-stackPos(0)+1, stackPos(3)-stackPos(1)+1); - return 0; -} - -int KyraEngine_v1::o1_walkPlayerToPoint(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_walkPlayerToPoint(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); - - int normalTimers = stackPos(2); - if (!normalTimers) { - _timer->disable(19); - _timer->disable(14); - _timer->disable(18); - } - - int reinitScript = handleSceneChange(stackPos(0), stackPos(1), stackPos(2), stackPos(3)); - - if (!normalTimers) { - _timer->enable(19); - _timer->enable(14); - _timer->enable(18); - } - - if (reinitScript) - _emc->init(script, script->dataPtr); - - if (_sceneChangeState) { - _sceneChangeState = 0; - return 1; - } - return 0; -} - -int KyraEngine_v1::o1_dropItemInScene(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_dropItemInScene(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); - int item = stackPos(0); - int xpos = stackPos(1); - int ypos = stackPos(2); - - byte freeItem = findFreeItemInScene(_currentCharacter->sceneId); - if (freeItem != 0xFF) { - int sceneId = _currentCharacter->sceneId; - Room *room = &_roomTable[sceneId]; - room->itemsXPos[freeItem] = xpos; - room->itemsYPos[freeItem] = ypos; - room->itemsTable[freeItem] = item; - - _animator->animAddGameItem(freeItem, sceneId); - _animator->updateAllObjectShapes(); - } else { - if (item == 43) - placeItemInGenericMapScene(item, 0); - else - placeItemInGenericMapScene(item, 1); - } - return 0; -} - -int KyraEngine_v1::o1_drawAnimShapeIntoScene(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_drawAnimShapeIntoScene(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); - _screen->hideMouse(); - _animator->restoreAllObjectBackgrounds(); - int shape = stackPos(0); - int xpos = stackPos(1); - int ypos = stackPos(2); - int flags = (stackPos(3) != 0) ? 1 : 0; - _screen->drawShape(2, _sprites->_sceneShapes[shape], xpos, ypos, 0, flags); - _screen->drawShape(0, _sprites->_sceneShapes[shape], xpos, ypos, 0, flags); - _animator->flagAllObjectsForBkgdChange(); - _animator->preserveAnyChangedBackgrounds(); - _animator->flagAllObjectsForRefresh(); - _animator->updateAllObjectShapes(); - _screen->showMouse(); - return 0; -} - -int KyraEngine_v1::o1_createMouseItem(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_createMouseItem(%p) (%d)", (const void *)script, stackPos(0)); - createMouseItem(stackPos(0)); - return 0; -} - -int KyraEngine_v1::o1_savePageToDisk(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_savePageToDisk(%p) ('%s', %d)", (const void *)script, stackPosString(0), stackPos(1)); - _screen->savePageToDisk(stackPosString(0), stackPos(1)); - return 0; -} - -int KyraEngine_v1::o1_sceneAnimOn(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_sceneAnimOn(%p) (%d)", (const void *)script, stackPos(0)); - _sprites->_anims[stackPos(0)].play = true; - return 0; -} - -int KyraEngine_v1::o1_sceneAnimOff(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_sceneAnimOff(%p) (%d)", (const void *)script, stackPos(0)); - _sprites->_anims[stackPos(0)].play = false; - return 0; -} - -int KyraEngine_v1::o1_getElapsedSeconds(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_getElapsedSeconds(%p) ()", (const void *)script); - return _system->getMillis() / 1000; -} - -int KyraEngine_v1::o1_mouseIsPointer(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_mouseIsPointer(%p) ()", (const void *)script); - if (_itemInHand == -1) - return 1; - return 0; -} - -int KyraEngine_v1::o1_destroyMouseItem(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_destroyMouseItem(%p) ()", (const void *)script); - destroyMouseItem(); - return 0; -} - -int KyraEngine_v1::o1_runSceneAnimUntilDone(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_runSceneAnimUntilDone(%p) (%d)", (const void *)script, stackPos(0)); - _screen->hideMouse(); - _animator->restoreAllObjectBackgrounds(); - _sprites->_anims[stackPos(0)].play = true; - _animator->sprites()[stackPos(0)].active = 1; - _animator->flagAllObjectsForBkgdChange(); - _animator->preserveAnyChangedBackgrounds(); - while (_sprites->_anims[stackPos(0)].play) { - _sprites->updateSceneAnims(); - _animator->updateAllObjectShapes(); - delay(10); - } - _animator->restoreAllObjectBackgrounds(); - _screen->showMouse(); - return 0; -} - -int KyraEngine_v1::o1_fadeSpecialPalette(EMCState *script) { - if (_flags.platform == Common::kPlatformAmiga) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_fadeSpecialPalette(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); - if (_currentCharacter->sceneId != 45) { - if (stackPos(0) == 13) { - memcpy(_screen->getPalette(0), _screen->getPalette(0) + 384*3, 32*3); - _screen->setScreenPalette(_screen->getPalette(0)); - } - } else { - warning("KyraEngine_v1::o1_fadeSpecialPalette not implemented"); - } - } else { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_fadeSpecialPalette(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); - _screen->fadeSpecialPalette(stackPos(0), stackPos(1), stackPos(2), stackPos(3)); - } - return 0; -} - -int KyraEngine_v1::o1_playAdlibSound(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_playAdlibSound(%p) (%d)", (const void *)script, stackPos(0)); - snd_playSoundEffect(stackPos(0)); - return 0; -} - -int KyraEngine_v1::o1_playAdlibScore(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_playAdlibScore(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - snd_playWanderScoreViaMap(stackPos(0), stackPos(1)); - return 0; -} - -int KyraEngine_v1::o1_phaseInSameScene(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_phaseInSameScene(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - transcendScenes(stackPos(0), stackPos(1)); - return 0; -} - -int KyraEngine_v1::o1_setScenePhasingFlag(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setScenePhasingFlag(%p) ()", (const void *)script); - _scenePhasingFlag = 1; - return 1; -} - -int KyraEngine_v1::o1_resetScenePhasingFlag(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_resetScenePhasingFlag(%p) ()", (const void *)script); - _scenePhasingFlag = 0; - return 0; -} - -int KyraEngine_v1::o1_queryScenePhasingFlag(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_queryScenePhasingFlag(%p) ()", (const void *)script); - return _scenePhasingFlag; -} - -int KyraEngine_v1::o1_sceneToDirection(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_sceneToDirection(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - assert(stackPos(0) < _roomTableSize); - Room *curRoom = &_roomTable[stackPos(0)]; - uint16 returnValue = 0xFFFF; - switch (stackPos(1)) { - case 0: - returnValue = curRoom->northExit; - break; - - case 2: - returnValue = curRoom->eastExit; - break; - - case 4: - returnValue = curRoom->southExit; - break; - - case 6: - returnValue = curRoom->westExit; - break; - - default: - break; - } - if (returnValue == 0xFFFF) - return -1; - return returnValue; -} - -int KyraEngine_v1::o1_setBirthstoneGem(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setBirthstoneGem(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - int index = stackPos(0); - if (index < 4 && index >= 0) { - _birthstoneGemTable[index] = stackPos(1); - return 1; - } - return 0; -} - -int KyraEngine_v1::o1_placeItemInGenericMapScene(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_placeItemInGenericMapScene(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - placeItemInGenericMapScene(stackPos(0), stackPos(1)); - return 0; -} - -int KyraEngine_v1::o1_setBrandonStatusBit(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setBrandonStatusBit(%p) (%d)", (const void *)script, stackPos(0)); - _brandonStatusBit |= stackPos(0); - return 0; -} - -int KyraEngine_v1::o1_pauseSeconds(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_pauseSeconds(%p) (%d)", (const void *)script, stackPos(0)); - if (stackPos(0) > 0 && !_skipFlag) - delay(stackPos(0)*1000, true); - _skipFlag = false; - return 0; -} - -int KyraEngine_v1::o1_getCharactersLocation(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_getCharactersLocation(%p) (%d)", (const void *)script, stackPos(0)); - return _characterList[stackPos(0)].sceneId; -} - -int KyraEngine_v1::o1_runNPCSubscript(EMCState *script) { - warning("STUB: o1_runNPCSubscript"); - return 0; -} - -int KyraEngine_v1::o1_magicOutMouseItem(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_magicOutMouseItem(%p) (%d)", (const void *)script, stackPos(0)); - magicOutMouseItem(stackPos(0), -1); - return 0; -} - -int KyraEngine_v1::o1_internalAnimOn(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_internalAnimOn(%p) (%d)", (const void *)script, stackPos(0)); - _animator->sprites()[stackPos(0)].active = 1; - return 0; -} - -int KyraEngine_v1::o1_forceBrandonToNormal(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_forceBrandonToNormal(%p) ()", (const void *)script); - checkAmuletAnimFlags(); - return 0; -} - -int KyraEngine_v1::o1_poisonDeathNow(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_poisonDeathNow(%p) ()", (const void *)script); - seq_poisonDeathNow(1); - return 0; -} - -int KyraEngine_v1::o1_setScaleMode(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setScaleMode(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); - int len = stackPos(0); - int setValue1 = stackPos(1); - int start2 = stackPos(2); - int setValue2 = stackPos(3); - for (int i = 0; i < len; ++i) - _scaleTable[i] = setValue1; - int temp = setValue2 - setValue1; - int temp2 = start2 - len; - for (int i = len, offset = 0; i < start2; ++i, ++offset) - _scaleTable[i] = (offset * temp) / temp2 + setValue1; - for (int i = start2; i < 145; ++i) - _scaleTable[i] = setValue2; - _scaleMode = 1; - return _scaleMode; -} - -int KyraEngine_v1::o1_openWSAFile(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_openWSAFile(%p) ('%s', %d, %d, %d)", (const void *)script, stackPosString(0), stackPos(1), stackPos(2), stackPos(3)); - - const char *filename = stackPosString(0); - int wsaIndex = stackPos(1); - - _movieObjects[wsaIndex]->open(filename, (stackPos(3) != 0) ? 1 : 0, 0); - assert(_movieObjects[wsaIndex]->opened()); - - return 0; -} - -int KyraEngine_v1::o1_closeWSAFile(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_closeWSAFile(%p) (%d)", (const void *)script, stackPos(0)); - - int wsaIndex = stackPos(0); - if (_movieObjects[wsaIndex]) - _movieObjects[wsaIndex]->close(); - - return 0; -} - -int KyraEngine_v1::o1_runWSAFromBeginningToEnd(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_runWSAFromBeginningToEnd(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); - - _screen->hideMouse(); - - bool running = true; - - int xpos = stackPos(0); - int ypos = stackPos(1); - int waitTime = stackPos(2); - int wsaIndex = stackPos(3); - int worldUpdate = stackPos(4); - int wsaFrame = 0; - - _movieObjects[wsaIndex]->setX(xpos); - _movieObjects[wsaIndex]->setY(ypos); - _movieObjects[wsaIndex]->setDrawPage(0); - while (running) { - _movieObjects[wsaIndex]->displayFrame(wsaFrame++); - _animator->_updateScreen = true; - if (wsaFrame >= _movieObjects[wsaIndex]->frames()) - running = false; - - uint32 continueTime = waitTime * _tickLength + _system->getMillis(); - while (_system->getMillis() < continueTime) { - if (worldUpdate) { - _sprites->updateSceneAnims(); - _animator->updateAllObjectShapes(); - } else { - _screen->updateScreen(); - } - if (continueTime - _system->getMillis() >= 10) - delay(10); - } - } - - _screen->showMouse(); - - return 0; -} - -int KyraEngine_v1::o1_displayWSAFrame(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_displayWSAFrame(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); - int frame = stackPos(0); - int xpos = stackPos(1); - int ypos = stackPos(2); - int waitTime = stackPos(3); - int wsaIndex = stackPos(4); - _screen->hideMouse(); - _movieObjects[wsaIndex]->setX(xpos); - _movieObjects[wsaIndex]->setY(ypos); - _movieObjects[wsaIndex]->setDrawPage(0); - _movieObjects[wsaIndex]->displayFrame(frame); - _animator->_updateScreen = true; - uint32 continueTime = waitTime * _tickLength + _system->getMillis(); - while (_system->getMillis() < continueTime) { - _sprites->updateSceneAnims(); - _animator->updateAllObjectShapes(); - if (_skipFlag) - break; - - if (continueTime - _system->getMillis() >= 10) - delay(10); - } - _screen->showMouse(); - return 0; -} - -int KyraEngine_v1::o1_enterNewScene(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_enterNewScene(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); - enterNewScene(stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); - return 0; -} - -int KyraEngine_v1::o1_setSpecialEnterXAndY(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setSpecialEnterXAndY(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - _brandonPosX = stackPos(0); - _brandonPosY = stackPos(1); - if (_brandonPosX + 1 == 0 && _brandonPosY + 1 == 0) - _currentCharacter->currentAnimFrame = 88; - return 0; -} - -int KyraEngine_v1::o1_runWSAFrames(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_runWSAFrames(%p) (%d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5)); - int xpos = stackPos(0); - int ypos = stackPos(1); - int delayTime = stackPos(2); - int startFrame = stackPos(3); - int endFrame = stackPos(4); - int wsaIndex = stackPos(5); - _screen->hideMouse(); - _movieObjects[wsaIndex]->setX(xpos); - _movieObjects[wsaIndex]->setY(ypos); - _movieObjects[wsaIndex]->setDrawPage(0); - for (; startFrame <= endFrame; ++startFrame) { - uint32 nextRun = _system->getMillis() + delayTime * _tickLength; - _movieObjects[wsaIndex]->displayFrame(startFrame); - _animator->_updateScreen = true; - while (_system->getMillis() < nextRun) { - _sprites->updateSceneAnims(); - _animator->updateAllObjectShapes(); - if (nextRun - _system->getMillis() >= 10) - delay(10); - } - } - _screen->showMouse(); - return 0; -} - -int KyraEngine_v1::o1_popBrandonIntoScene(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_popBrandonIntoScene(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); - int changeScaleMode = stackPos(3); - int xpos = (int16)(stackPos(0) & 0xFFFC); - int ypos = (int16)(stackPos(1) & 0xFFFE); - int facing = stackPos(2); - _currentCharacter->x1 = _currentCharacter->x2 = xpos; - _currentCharacter->y1 = _currentCharacter->y2 = ypos; - _currentCharacter->facing = facing; - _currentCharacter->currentAnimFrame = 7; - int xOffset = _defaultShapeTable[0].xOffset; - int yOffset = _defaultShapeTable[0].yOffset; - int width = _defaultShapeTable[0].w << 3; - int height = _defaultShapeTable[0].h; - Animator_v1::AnimObject *curAnim = _animator->actors(); - - if (changeScaleMode) { - curAnim->x1 = _currentCharacter->x1; - curAnim->y1 = _currentCharacter->y1; - _animator->_brandonScaleY = _scaleTable[_currentCharacter->y1]; - _animator->_brandonScaleX = _animator->_brandonScaleY; - - int animWidth = _animator->fetchAnimWidth(curAnim->sceneAnimPtr, _animator->_brandonScaleX) >> 1; - int animHeight = _animator->fetchAnimHeight(curAnim->sceneAnimPtr, _animator->_brandonScaleY); - - animWidth = (xOffset * animWidth) / width; - animHeight = (yOffset * animHeight) / height; - - curAnim->x2 = curAnim->x1 += animWidth; - curAnim->y2 = curAnim->y1 += animHeight; - } else { - curAnim->x2 = curAnim->x1 = _currentCharacter->x1 + xOffset; - curAnim->y2 = curAnim->y1 = _currentCharacter->y1 + yOffset; - } - - int scaleModeBackup = _scaleMode; - if (changeScaleMode) - _scaleMode = 1; - - _animator->animRefreshNPC(0); - _animator->preserveAllBackgrounds(); - _animator->prepDrawAllObjects(); - _animator->copyChangedObjectsForward(0); - - _scaleMode = scaleModeBackup; - - return 0; -} - -int KyraEngine_v1::o1_restoreAllObjectBackgrounds(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_restoreAllObjectBackgrounds(%p) (%d)", (const void *)script, stackPos(0)); - int disable = stackPos(0); - int activeBackup = 0; - if (disable) { - activeBackup = _animator->actors()->active; - _animator->actors()->active = 0; - } - _animator->restoreAllObjectBackgrounds(); - if (disable) - _animator->actors()->active = activeBackup; - return 0; -} - -int KyraEngine_v1::o1_setCustomPaletteRange(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setCustomPaletteRange(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); - memcpy(_screen->getPalette(1) + stackPos(1)*3, _specialPalettes[stackPos(0)], stackPos(2)*3); - return 0; -} - -int KyraEngine_v1::o1_loadPageFromDisk(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_loadPageFromDisk(%p) ('%s', %d)", (const void *)script, stackPosString(0), stackPos(1)); - _screen->loadPageFromDisk(stackPosString(0), stackPos(1)); - _animator->_updateScreen = true; - return 0; -} - -int KyraEngine_v1::o1_customPrintTalkString(EMCState *script) { - if (_flags.isTalkie) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_customPrintTalkString(%p) (%d, '%s', %d, %d, %d)", (const void *)script, stackPos(0), stackPosString(1), stackPos(2), stackPos(3), stackPos(4) & 0xFF); - - if (speechEnabled()) { - snd_voiceWaitForFinish(); - snd_playVoiceFile(stackPos(0)); - } - - _skipFlag = false; - if (textEnabled()) - _text->printTalkTextMessage(stackPosString(1), stackPos(2), stackPos(3), stackPos(4) & 0xFF, 0, 2); - } else { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_customPrintTalkString(%p) ('%s', %d, %d, %d)", (const void *)script, stackPosString(0), stackPos(1), stackPos(2), stackPos(3) & 0xFF); - _skipFlag = false; - _text->printTalkTextMessage(stackPosString(0), stackPos(1), stackPos(2), stackPos(3) & 0xFF, 0, 2); - } - _screen->updateScreen(); - return 0; -} - -int KyraEngine_v1::o1_restoreCustomPrintBackground(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_restoreCustomPrintBackground(%p) ()", (const void *)script); - _text->restoreTalkTextMessageBkgd(2, 0); - return 0; -} - -int KyraEngine_v1::o1_hideMouse(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_hideMouse(%p) ()", (const void *)script); - _screen->hideMouse(); - return 0; -} - -int KyraEngine_v1::o1_showMouse(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_showMouse(%p) ()", (const void *)script); - _screen->showMouse(); - return 0; -} - -int KyraEngine_v1::o1_getCharacterX(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_getCharacterX(%p) (%d)", (const void *)script, stackPos(0)); - return _characterList[stackPos(0)].x1; -} - -int KyraEngine_v1::o1_getCharacterY(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_getCharacterY(%p) (%d)", (const void *)script, stackPos(0)); - return _characterList[stackPos(0)].y1; -} - -int KyraEngine_v1::o1_changeCharactersFacing(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_changeCharactersFacing(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); - int character = stackPos(0); - int facing = stackPos(1); - int newAnimFrame = stackPos(2); - - _animator->restoreAllObjectBackgrounds(); - if (newAnimFrame != -1) - _characterList[character].currentAnimFrame = newAnimFrame; - _characterList[character].facing = facing; - _animator->animRefreshNPC(character); - _animator->preserveAllBackgrounds(); - _animator->prepDrawAllObjects(); - _animator->copyChangedObjectsForward(0); - - return 0; -} - -int KyraEngine_v1::o1_copyWSARegion(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_copyWSARegion(%p) (%d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5)); - int xpos = stackPos(0); - int ypos = stackPos(1); - int width = stackPos(2); - int height = stackPos(3); - int srcPage = stackPos(4); - int dstPage = stackPos(5); - _screen->copyRegion(xpos, ypos, xpos, ypos, width, height, srcPage, dstPage); - _animator->_updateScreen = true; - return 0; -} - -int KyraEngine_v1::o1_printText(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_printText(%p) ('%s', %d, %d, 0x%X, 0x%X)", (const void *)script, stackPosString(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); - if (_flags.lang == Common::JA_JPN && stackPos(3) == 7) - _screen->printText(stackPosString(0), stackPos(1), stackPos(2), 0, 0x80); - else - _screen->printText(stackPosString(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); - _screen->updateScreen(); - return 0; -} - -int KyraEngine_v1::o1_random(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_random(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - assert(stackPos(0) < stackPos(1)); - return _rnd.getRandomNumberRng(stackPos(0), stackPos(1)); -} - -int KyraEngine_v1::o1_loadSoundFile(EMCState *script) { - warning("STUB: o1_loadSoundFile"); - return 0; -} - -int KyraEngine_v1::o1_displayWSAFrameOnHidPage(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_displayWSAFrameOnHidPage(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); - int frame = stackPos(0); - int xpos = stackPos(1); - int ypos = stackPos(2); - int waitTime = stackPos(3); - int wsaIndex = stackPos(4); - - _screen->hideMouse(); - uint32 continueTime = waitTime * _tickLength + _system->getMillis(); - _movieObjects[wsaIndex]->setX(xpos); - _movieObjects[wsaIndex]->setY(ypos); - _movieObjects[wsaIndex]->setDrawPage(2); - _movieObjects[wsaIndex]->displayFrame(frame); - _animator->_updateScreen = true; - while (_system->getMillis() < continueTime) { - _sprites->updateSceneAnims(); - _animator->updateAllObjectShapes(); - if (_skipFlag) - break; - - if (continueTime - _system->getMillis() >= 10) - delay(10); - } - _screen->showMouse(); - - return 0; -} - -int KyraEngine_v1::o1_displayWSASequentialFrames(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_displayWSASequentialFrames(%p) (%d, %d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6)); - int startFrame = stackPos(0); - int endFrame = stackPos(1); - int xpos = stackPos(2); - int ypos = stackPos(3); - int waitTime = stackPos(4); - int wsaIndex = stackPos(5); - int maxTime = stackPos(6); - if (maxTime - 1 <= 0) - maxTime = 1; - - _movieObjects[wsaIndex]->setX(xpos); - _movieObjects[wsaIndex]->setY(ypos); - _movieObjects[wsaIndex]->setDrawPage(0); - - // Workaround for bug #1498221 "KYRA1: Glitches when meeting Zanthia" - // the original didn't do a forced screen update after displaying a wsa frame - // while we have to do it, which make brandon disappear for a short moment, - // what shouldn't happen. So we're not updating the screen for this special - // case too. - if (startFrame == 18 && endFrame == 18 && _currentRoom == 45) { - _movieObjects[wsaIndex]->displayFrame(18); - delay(waitTime * _tickLength); - return 0; - } - - int curTime = 0; - _screen->hideMouse(); - while (curTime < maxTime) { - if (endFrame >= startFrame) { - int frame = startFrame; - while (endFrame >= frame) { - uint32 continueTime = waitTime * _tickLength + _system->getMillis(); - _movieObjects[wsaIndex]->displayFrame(frame); - _animator->_updateScreen = true; - while (_system->getMillis() < continueTime) { - _sprites->updateSceneAnims(); - _animator->updateAllObjectShapes(); - if (_skipFlag) - break; - - if (continueTime - _system->getMillis() >= 10) - delay(10); - } - ++frame; - } - } else { - int frame = startFrame; - while (endFrame <= frame) { - uint32 continueTime = waitTime * _tickLength + _system->getMillis(); - _movieObjects[wsaIndex]->displayFrame(frame); - _animator->_updateScreen = true; - while (_system->getMillis() < continueTime) { - _sprites->updateSceneAnims(); - _animator->updateAllObjectShapes(); - if (_skipFlag) - break; - - if (continueTime - _system->getMillis() >= 10) - delay(10); - } - --frame; - } - } - - if (_skipFlag) - break; - else - ++curTime; - } - _screen->showMouse(); - - return 0; -} - -int KyraEngine_v1::o1_drawCharacterStanding(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_drawCharacterStanding(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); - int character = stackPos(0); - int animFrame = stackPos(1); - int newFacing = stackPos(2); - int updateShapes = stackPos(3); - _characterList[character].currentAnimFrame = animFrame; - if (newFacing != -1) - _characterList[character].facing = newFacing; - _animator->animRefreshNPC(character); - if (updateShapes) - _animator->updateAllObjectShapes(); - return 0; -} - -int KyraEngine_v1::o1_internalAnimOff(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_internalAnimOff(%p) (%d)", (const void *)script, stackPos(0)); - _animator->sprites()[stackPos(0)].active = 0; - return 0; -} - -int KyraEngine_v1::o1_changeCharactersXAndY(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_changeCharactersXAndY(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); - Character *ch = &_characterList[stackPos(0)]; - int16 x = stackPos(1); - int16 y = stackPos(2); - if (x != -1 && y != -1) { - x &= 0xFFFC; - y &= 0xFFFE; - } - _animator->restoreAllObjectBackgrounds(); - ch->x1 = ch->x2 = x; - ch->y1 = ch->y2 = y; - _animator->preserveAllBackgrounds(); - return 0; -} - -int KyraEngine_v1::o1_clearSceneAnimatorBeacon(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_clearSceneAnimatorBeacon(%p) ()", (const void *)script); - _sprites->_sceneAnimatorBeaconFlag = 0; - return 0; -} - -int KyraEngine_v1::o1_querySceneAnimatorBeacon(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_querySceneAnimatorBeacon(%p) ()", (const void *)script); - return _sprites->_sceneAnimatorBeaconFlag; -} - -int KyraEngine_v1::o1_refreshSceneAnimator(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_refreshSceneAnimator(%p) ()", (const void *)script); - _sprites->updateSceneAnims(); - _animator->updateAllObjectShapes(); - return 0; -} - -int KyraEngine_v1::o1_placeItemInOffScene(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_placeItemInOffScene(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); - int item = stackPos(0); - int xpos = stackPos(1); - int ypos = stackPos(2); - int sceneId = stackPos(3); - - byte freeItem = findFreeItemInScene(sceneId); - if (freeItem != 0xFF) { - assert(sceneId < _roomTableSize); - Room *room = &_roomTable[sceneId]; - - room->itemsTable[freeItem] = item; - room->itemsXPos[freeItem] = xpos; - room->itemsYPos[freeItem] = ypos; - } - return 0; -} - -int KyraEngine_v1::o1_wipeDownMouseItem(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_wipeDownMouseItem(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); - _screen->hideMouse(); - wipeDownMouseItem(stackPos(1), stackPos(2)); - destroyMouseItem(); - _screen->showMouse(); - return 0; -} - -int KyraEngine_v1::o1_placeCharacterInOtherScene(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_placeCharacterInOtherScene(%p) (%d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5)); - int id = stackPos(0); - int sceneId = stackPos(1); - int xpos = (int16)(stackPos(2) & 0xFFFC); - int ypos = (int16)(stackPos(3) & 0xFFFE); - int facing = stackPos(4); - int animFrame = stackPos(5); - - _characterList[id].sceneId = sceneId; - _characterList[id].x1 = _characterList[id].x2 = xpos; - _characterList[id].y1 = _characterList[id].y2 = ypos; - _characterList[id].facing = facing; - _characterList[id].currentAnimFrame = animFrame; - return 0; -} - -int KyraEngine_v1::o1_getKey(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_getKey(%p) ()", (const void *)script); - waitForEvent(); - return 0; -} - -int KyraEngine_v1::o1_specificItemInInventory(EMCState *script) { - warning("STUB: o1_specificItemInInventory"); - return 0; -} - -int KyraEngine_v1::o1_popMobileNPCIntoScene(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_popMobileNPCIntoScene(%p) (%d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), (int16)(stackPos(4) & 0xFFFC), (int8)(stackPos(5) & 0xFE)); - int character = stackPos(0); - int sceneId = stackPos(1); - int animFrame = stackPos(2); - int facing = stackPos(3); - int16 xpos = (int16)(stackPos(4) & 0xFFFC); - int8 ypos = (int16)(stackPos(5) & 0xFFFE); - Character *curChar = &_characterList[character]; - - curChar->sceneId = sceneId; - curChar->currentAnimFrame = animFrame; - curChar->facing = facing; - curChar->x1 = curChar->x2 = xpos; - curChar->y1 = curChar->y2 = ypos; - - _animator->animAddNPC(character); - _animator->updateAllObjectShapes(); - return 0; -} - -int KyraEngine_v1::o1_mobileCharacterInScene(EMCState *script) { - warning("STUB: o1_mobileCharacterInScene"); - return 0; -} - -int KyraEngine_v1::o1_hideMobileCharacter(EMCState *script) { - warning("STUB: o1_hideMobileCharacter"); - return 0; -} - -int KyraEngine_v1::o1_unhideMobileCharacter(EMCState *script) { - warning("STUB: o1_unhideMobileCharacter"); - return 0; -} - -int KyraEngine_v1::o1_setCharactersLocation(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setCharactersLocation(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - Character *ch = &_characterList[stackPos(0)]; - Animator_v1::AnimObject *animObj = &_animator->actors()[stackPos(0)]; - int newScene = stackPos(1); - if (_currentCharacter->sceneId == ch->sceneId) { - if (_currentCharacter->sceneId != newScene) - animObj->active = 0; - } else if (_currentCharacter->sceneId == newScene) { - if (_currentCharacter->sceneId != ch->sceneId) - animObj->active = 1; - } - - ch->sceneId = stackPos(1); - return 0; -} - -int KyraEngine_v1::o1_walkCharacterToPoint(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_walkCharacterToPoint(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); - int character = stackPos(0); - int toX = stackPos(1); - int toY = stackPos(2); - _pathfinderFlag2 = 1; - uint32 nextFrame; - int findWayReturn = findWay(_characterList[character].x1, _characterList[character].y1, toX, toY, _movFacingTable, 150); - _pathfinderFlag2 = 0; - - if (_lastFindWayRet < findWayReturn) - _lastFindWayRet = findWayReturn; - if (findWayReturn == 0x7D00 || findWayReturn == 0) - return 0; - - int *curPos = _movFacingTable; - bool running = true; - while (running) { - bool forceContinue = false; - switch (*curPos) { - case 0: - _characterList[character].facing = 2; - break; - - case 1: - _characterList[character].facing = 1; - break; - - case 2: - _characterList[character].facing = 0; - break; - - case 3: - _characterList[character].facing = 7; - break; - - case 4: - _characterList[character].facing = 6; - break; - - case 5: - _characterList[character].facing = 5; - break; - - case 6: - _characterList[character].facing = 4; - break; - - case 7: - _characterList[character].facing = 3; - break; - - case 8: - running = 0; - break; - - default: - ++curPos; - forceContinue = true; - break; - } - - if (forceContinue || !running) - continue; - - setCharacterPosition(character, 0); - ++curPos; - - nextFrame = _timer->getDelay(5 + character) * _tickLength + _system->getMillis(); - while (_system->getMillis() < nextFrame) { - _sprites->updateSceneAnims(); - updateMousePointer(); - _timer->update(); - _animator->updateAllObjectShapes(); - updateTextFade(); - if ((nextFrame - _system->getMillis()) >= 10) - delay(10); - } - } - return 0; -} - -int KyraEngine_v1::o1_specialEventDisplayBrynnsNote(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_specialEventDisplayBrynnsNote(%p) ()", (const void *)script); - _screen->hideMouse(); - _screen->savePageToDisk("HIDPAGE.TMP", 2); - _screen->savePageToDisk("SEENPAGE.TMP", 0); - if (_flags.isTalkie) { - if (_flags.lang == Common::EN_ANY || _flags.lang == Common::IT_ITA) - _screen->loadBitmap("NOTEENG.CPS", 3, 3, 0); - else if (_flags.lang == Common::FR_FRA) - _screen->loadBitmap("NOTEFRE.CPS", 3, 3, 0); - else if (_flags.lang == Common::DE_DEU) - _screen->loadBitmap("NOTEGER.CPS", 3, 3, 0); - } else { - _screen->loadBitmap("NOTE.CPS", 3, 3, 0); - } - _screen->copyRegion(63, 8, 63, 8, 194, 128, 2, 0); - _screen->updateScreen(); - _screen->showMouse(); - _screen->setFont(Screen::FID_6_FNT); - return 0; -} - -int KyraEngine_v1::o1_specialEventRemoveBrynnsNote(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_specialEventRemoveBrynnsNote(%p) ()", (const void *)script); - _screen->hideMouse(); - _screen->loadPageFromDisk("SEENPAGE.TMP", 0); - _screen->loadPageFromDisk("HIDPAGE.TMP", 2); - _screen->updateScreen(); - _screen->showMouse(); - _screen->setFont(Screen::FID_8_FNT); - return 0; -} - -int KyraEngine_v1::o1_setLogicPage(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setLogicPage(%p) (%d)", (const void *)script, stackPos(0)); - _screen->_curPage = stackPos(0); - return stackPos(0); -} - -int KyraEngine_v1::o1_fatPrint(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_fatPrint(%p) ('%s', %d, %d, %d, %d, %d)", (const void *)script, stackPosString(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5)); - - // Workaround for bug #1582672 ("KYRA1: Text crippled and drawn wrong") - // I'm not sure how the original handles this, since it seems to call - // printText also, maybe it fails somewhere inside... - // TODO: fix the reason for this workaround - if (_currentRoom == 117) - return 0; - _text->printText(stackPosString(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5)); - return 0; -} - -int KyraEngine_v1::o1_preserveAllObjectBackgrounds(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_preserveAllObjectBackgrounds(%p) ()", (const void *)script); - _animator->preserveAllBackgrounds(); - return 0; -} - -int KyraEngine_v1::o1_updateSceneAnimations(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_updateSceneAnimations(%p) (%d)", (const void *)script, stackPos(0)); - int times = stackPos(0); - while (times--) { - _sprites->updateSceneAnims(); - _animator->updateAllObjectShapes(); - } - return 0; -} - -int KyraEngine_v1::o1_sceneAnimationActive(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_sceneAnimationActive(%p) (%d)", (const void *)script, stackPos(0)); - return _sprites->_anims[stackPos(0)].play; -} - -int KyraEngine_v1::o1_setCharactersMovementDelay(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setCharactersMovementDelay(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - _timer->setDelay(stackPos(0)+5, stackPos(1)); - return 0; -} - -int KyraEngine_v1::o1_getCharactersFacing(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_getCharactersFacing(%p) (%d)", (const void *)script, stackPos(0)); - return _characterList[stackPos(0)].facing; -} - -int KyraEngine_v1::o1_bkgdScrollSceneAndMasksRight(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_bkgdScrollSceneAndMasksRight(%p) (%d)", (const void *)script, stackPos(0)); - _screen->copyBackgroundBlock(stackPos(0), 2, 0); - _screen->copyBackgroundBlock2(stackPos(0)); - // update the whole screen - _screen->copyRegion(7, 7, 7, 7, 305, 129, 3, 0); - // Don't do a screen update here, see bug #1910180 "KYRA1: Screen 'flash'" - // it would cause to draw the screen with a wrong palette and thus look - // strange for the user. Since this opcode should be just called on scene - // initialization anyway, there should be no problem with not updating the - // screen right now. - return 0; -} - -int KyraEngine_v1::o1_dispelMagicAnimation(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_dispelMagicAnimation(%p) ()", (const void *)script); - seq_dispelMagicAnimation(); - return 0; -} - -int KyraEngine_v1::o1_findBrightestFireberry(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_findBrightestFireberry(%p) ()", (const void *)script); - if (_currentCharacter->sceneId >= 187 && _currentCharacter->sceneId <= 198) - return 29; - - if (_currentCharacter->sceneId == 133 || _currentCharacter->sceneId == 137 || - _currentCharacter->sceneId == 165 || _currentCharacter->sceneId == 173) - return 29; - - if (_itemInHand == 28) - return 28; - - int brightestFireberry = 107; - if (_itemInHand >= 29 && _itemInHand <= 33) - brightestFireberry = _itemInHand; - for (int i = 0; i < 10; ++i) { - uint8 item = _currentCharacter->inventoryItems[i]; - if (item == 0xFF) - continue; - if (item == 28) - return 28; - if (item >= 29 && item <= 33) { - if (item < brightestFireberry) - brightestFireberry = item; - } - } - assert(_currentCharacter->sceneId < _roomTableSize); - Room *curRoom = &_roomTable[_currentCharacter->sceneId]; - for (int i = 0; i < 12; ++i) { - uint8 item = curRoom->itemsTable[i]; - if (item == 0xFF) - continue; - if (item == 28) - return 28; - if (item >= 29 && item <= 33) { - if (item < brightestFireberry) - brightestFireberry = item; - } - } - if (brightestFireberry == 107) - return -1; - return brightestFireberry; -} - -int KyraEngine_v1::o1_setFireberryGlowPalette(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setFireberryGlowPalette(%p) (%d)", (const void *)script, stackPos(0)); - int palIndex = 0; - switch (stackPos(0)) { - case 0x1E: - palIndex = 9; - break; - - case 0x1F: - palIndex = 10; - break; - - case 0x20: - palIndex = 11; - break; - - case 0x21: - case -1: - palIndex = 12; - break; - - default: - palIndex = 8; - break; - } - if (_brandonStatusBit & 2) { - if (_currentCharacter->sceneId != 133 && _currentCharacter->sceneId != 137 && - _currentCharacter->sceneId != 165 && _currentCharacter->sceneId != 173 && - (_currentCharacter->sceneId < 187 || _currentCharacter->sceneId > 198)) { - palIndex = 14; - } - } - const uint8 *palette = _specialPalettes[palIndex]; - memcpy(_screen->getPalette(1) + 684, palette, 44); - return 0; -} - -int KyraEngine_v1::o1_setDeathHandlerFlag(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setDeathHandlerFlag(%p) (%d)", (const void *)script, stackPos(0)); - _deathHandler = stackPos(0); - return 0; -} - -int KyraEngine_v1::o1_drinkPotionAnimation(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_drinkPotionAnimation(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); - seq_playDrinkPotionAnim(stackPos(0), stackPos(1), stackPos(2)); - return 0; -} - -int KyraEngine_v1::o1_makeAmuletAppear(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_makeAmuletAppear(%p) ()", (const void *)script); - WSAMovieV1 amulet(this); - amulet.open("AMULET.WSA", 1, 0); - amulet.setX(224); - amulet.setY(152); - amulet.setDrawPage(0); - if (amulet.opened()) { - assert(_amuleteAnim); - _screen->hideMouse(); - snd_playSoundEffect(0x70); - uint32 nextTime = 0; - for (int i = 0; _amuleteAnim[i] != 0xFF; ++i) { - nextTime = _system->getMillis() + 5 * _tickLength; - - uint8 code = _amuleteAnim[i]; - if (code == 3 || code == 7) - snd_playSoundEffect(0x71); - - if (code == 5) - snd_playSoundEffect(0x72); - - if (code == 14) - snd_playSoundEffect(0x73); - - amulet.displayFrame(code); - _animator->_updateScreen = true; - - while (_system->getMillis() < nextTime) { - _sprites->updateSceneAnims(); - _animator->updateAllObjectShapes(); - if (nextTime - _system->getMillis() >= 10) - delay(10); - } - } - _screen->showMouse(); - } - setGameFlag(0x2D); - return 0; -} - -int KyraEngine_v1::o1_drawItemShapeIntoScene(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_drawItemShapeIntoScene(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); - int item = stackPos(0); - int x = stackPos(1); - int y = stackPos(2); - int flags = stackPos(3); - int onlyHidPage = stackPos(4); - - if (flags) - flags = 1; - - if (onlyHidPage) { - _screen->drawShape(2, _shapes[216+item], x, y, 0, flags); - } else { - _screen->hideMouse(); - _animator->restoreAllObjectBackgrounds(); - _screen->drawShape(2, _shapes[216+item], x, y, 0, flags); - _screen->drawShape(0, _shapes[216+item], x, y, 0, flags); - _animator->flagAllObjectsForBkgdChange(); - _animator->preserveAnyChangedBackgrounds(); - _animator->flagAllObjectsForRefresh(); - _animator->updateAllObjectShapes(); - _screen->showMouse(); - } - return 0; -} - -int KyraEngine_v1::o1_setCharactersCurrentFrame(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setCharactersCurrentFrame(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - _characterList[stackPos(0)].currentAnimFrame = stackPos(1); - return 0; -} - -int KyraEngine_v1::o1_waitForConfirmationMouseClick(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_waitForConfirmationMouseClick(%p) ()", (const void *)script); - // if (mouseEnabled) { - while (!_mousePressFlag) { - updateMousePointer(); - _sprites->updateSceneAnims(); - _animator->updateAllObjectShapes(); - delay(10); - } - - while (_mousePressFlag) { - updateMousePointer(); - _sprites->updateSceneAnims(); - _animator->updateAllObjectShapes(); - delay(10); - } - // } - _gui->processButtonList(_buttonList, 0, 0); - _skipFlag = false; - Common::Point mouse = getMousePos(); - script->regs[1] = mouse.x; - script->regs[2] = mouse.y; - return 0; -} - -int KyraEngine_v1::o1_pageFlip(EMCState *script) { - warning("STUB: o1_pageFlip"); - return 0; -} - -int KyraEngine_v1::o1_setSceneFile(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setSceneFile(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - setSceneFile(stackPos(0), stackPos(1)); - return 0; -} - -int KyraEngine_v1::o1_getItemInMarbleVase(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_getItemInMarbleVase(%p) ()", (const void *)script); - return _marbleVaseItem; -} - -int KyraEngine_v1::o1_setItemInMarbleVase(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setItemInMarbleVase(%p) (%d)", (const void *)script, stackPos(0)); - _marbleVaseItem = stackPos(0); - return 0; -} - -int KyraEngine_v1::o1_addItemToInventory(EMCState *script) { - warning("STUB: o1_addItemToInventory"); - return 0; -} - -int KyraEngine_v1::o1_intPrint(EMCState *script) { - warning("STUB: o1_intPrint"); - return 0; -} - -int KyraEngine_v1::o1_shakeScreen(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_shakeScreen(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - int waitTicks = stackPos(1); - int times = stackPos(0); - - for (int i = 0; i < times; ++i) { - _screen->shakeScreen(1); - delay(waitTicks * _tickLength); - } - - return 0; -} - -int KyraEngine_v1::o1_createAmuletJewel(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_createAmuletJewel(%p) (%d)", (const void *)script, stackPos(0)); - seq_createAmuletJewel(stackPos(0), 0, 0, 0); - return 0; -} - -int KyraEngine_v1::o1_setSceneAnimCurrXY(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setSceneAnimCurrXY(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); - _sprites->_anims[stackPos(0)].x = stackPos(1); - _sprites->_anims[stackPos(0)].y = stackPos(2); - return 0; -} - -int KyraEngine_v1::o1_poisonBrandonAndRemaps(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_poisonBrandonAndRemaps(%p) ()", (const void *)script); - setBrandonPoisonFlags(1); - return 0; -} - -int KyraEngine_v1::o1_fillFlaskWithWater(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_fillFlaskWithWater(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - seq_fillFlaskWithWater(stackPos(0), stackPos(1)); - return 0; -} - -int KyraEngine_v1::o1_getCharactersMovementDelay(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_getCharactersMovementDelay(%p) (%d)", (const void *)script, stackPos(0)); - return _timer->getDelay(stackPos(0)+5); -} - -int KyraEngine_v1::o1_getBirthstoneGem(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_getBirthstoneGem(%p) (%d)", (const void *)script, stackPos(0)); - if (stackPos(0) < 4) - return _birthstoneGemTable[stackPos(0)]; - return 0; -} - -int KyraEngine_v1::o1_queryBrandonStatusBit(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_queryBrandonStatusBit(%p) (%d)", (const void *)script, stackPos(0)); - if (_brandonStatusBit & stackPos(0)) - return 1; - return 0; -} - -int KyraEngine_v1::o1_playFluteAnimation(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_playFluteAnimation(%p) ()", (const void *)script); - seq_playFluteAnimation(); - return 0; -} - -int KyraEngine_v1::o1_playWinterScrollSequence(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_playWinterScrollSequence(%p) (%d)", (const void *)script, stackPos(0)); - if (!stackPos(0)) - seq_winterScroll2(); - else - seq_winterScroll1(); - return 0; -} - -int KyraEngine_v1::o1_getIdolGem(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_getIdolGem(%p) (%d)", (const void *)script, stackPos(0)); - return _idolGemsTable[stackPos(0)]; -} - -int KyraEngine_v1::o1_setIdolGem(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setIdolGem(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - _idolGemsTable[stackPos(0)] = stackPos(1); - return 0; -} - -int KyraEngine_v1::o1_totalItemsInScene(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_totalItemsInScene(%p) (%d)", (const void *)script, stackPos(0)); - return countItemsInScene(stackPos(0)); -} - -int KyraEngine_v1::o1_restoreBrandonsMovementDelay(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_restoreBrandonsMovementDelay(%p) ()", (const void *)script); - setWalkspeed(_configWalkspeed); - return 0; -} - -int KyraEngine_v1::o1_setMousePos(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setMousePos(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - _system->warpMouse(stackPos(0), stackPos(1)); - return 0; -} - -int KyraEngine_v1::o1_getMouseState(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_getMouseState(%p) ()", (const void *)script); - return _mouseState; -} - -int KyraEngine_v1::o1_setEntranceMouseCursorTrack(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setEntranceMouseCursorTrack(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); - _entranceMouseCursorTracks[0] = stackPos(0); - _entranceMouseCursorTracks[1] = stackPos(1); - _entranceMouseCursorTracks[2] = stackPos(0) + stackPos(2) - 1; - _entranceMouseCursorTracks[3] = stackPos(1) + stackPos(3) - 1; - _entranceMouseCursorTracks[4] = stackPos(4); - return 0; -} - -int KyraEngine_v1::o1_itemAppearsOnGround(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_itemAppearsOnGround(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); - processItemDrop(_currentCharacter->sceneId, stackPos(0), stackPos(1), stackPos(2), 2, 0); - return 0; -} - -int KyraEngine_v1::o1_setNoDrawShapesFlag(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setNoDrawShapesFlag(%p) (%d)", (const void *)script, stackPos(0)); - _animator->_noDrawShapesFlag = stackPos(0); - return 0; -} - -int KyraEngine_v1::o1_fadeEntirePalette(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_fadeEntirePalette(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - int cmd = stackPos(0); - uint8 *fadePal = 0; - - if (_flags.platform == Common::kPlatformAmiga) { - if (cmd == 0) { - fadePal = _screen->getPalette(2); - memset(fadePal, 0, 32*3); - memcpy(_screen->getPalette(4), _screen->getPalette(0), 32*3); - } else if (cmd == 1) { - fadePal = _screen->getPalette(0); - memcpy(_screen->getPalette(0), _screen->getPalette(4), 32*3); - } else if (cmd == 2) { - fadePal = _screen->getPalette(0); - memset(_screen->getPalette(2), 0, 32*3); - } - } else { - if (cmd == 0) { - fadePal = _screen->getPalette(2); - uint8 *screenPal = _screen->getPalette(0); - uint8 *backUpPal = _screen->getPalette(3); - - memcpy(backUpPal, screenPal, sizeof(uint8)*768); - memset(fadePal, 0, sizeof(uint8)*768); - } else if (cmd == 1) { - //fadePal = _screen->getPalette(3); - warning("unimplemented o1_fadeEntirePalette function"); - return 0; - } else if (cmd == 2) { - memset(_screen->getPalette(2), 0, 768); - memcpy(_screen->getPalette(0), _screen->getPalette(1), 768); - fadePal = _screen->getPalette(0); - } - } - - _screen->fadePalette(fadePal, stackPos(1)); - return 0; -} - -int KyraEngine_v1::o1_itemOnGroundHere(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_itemOnGroundHere(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - assert(stackPos(0) < _roomTableSize); - Room *curRoom = &_roomTable[stackPos(0)]; - for (int i = 0; i < 12; ++i) { - if (curRoom->itemsTable[i] == stackPos(1)) - return 1; - } - return 0; -} - -int KyraEngine_v1::o1_queryCauldronState(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_queryCauldronState(%p) ()", (const void *)script); - return _cauldronState; -} - -int KyraEngine_v1::o1_setCauldronState(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setCauldronState(%p) (%d)", (const void *)script, stackPos(0)); - _cauldronState = stackPos(0); - return _cauldronState; -} - -int KyraEngine_v1::o1_queryCrystalState(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_queryCrystalState(%p) (%d)", (const void *)script, stackPos(0)); - if (!stackPos(0)) - return _crystalState[0]; - else if (stackPos(0) == 1) - return _crystalState[1]; - return -1; -} - -int KyraEngine_v1::o1_setCrystalState(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setCrystalState(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - if (!stackPos(0)) - _crystalState[0] = stackPos(1); - else if (stackPos(0) == 1) - _crystalState[1] = stackPos(1); - return stackPos(1); -} - -int KyraEngine_v1::o1_setPaletteRange(EMCState *script) { - warning("STUB: o1_setPaletteRange"); - return 0; -} - -int KyraEngine_v1::o1_shrinkBrandonDown(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_shrinkBrandonDown(%p) (%d)", (const void *)script, stackPos(0)); - int delayTime = stackPos(0); - checkAmuletAnimFlags(); - int scaleValue = _scaleTable[_currentCharacter->y1]; - int scale = 0; - - if (_scaleMode) - scale = scaleValue; - else - scale = 256; - - int scaleModeBackUp = _scaleMode; - _scaleMode = 1; - int scaleEnd = scale >> 1; - for (; scaleEnd <= scale; --scale) { - _scaleTable[_currentCharacter->y1] = scale; - _animator->animRefreshNPC(0); - delayWithTicks(1); - } - delayWithTicks(delayTime); // XXX - _scaleTable[_currentCharacter->y1] = scaleValue; - _scaleMode = scaleModeBackUp; - return 0; -} - -int KyraEngine_v1::o1_growBrandonUp(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_growBrandonUp(%p) ()", (const void *)script); - int scaleValue = _scaleTable[_currentCharacter->y1]; - int scale = 0; - if (_scaleMode) - scale = scaleValue; - else - scale = 256; - - int scaleModeBackUp = _scaleMode; - _scaleMode = 1; - for (int curScale = scale >> 1; curScale <= scale; ++curScale) { - _scaleTable[_currentCharacter->y1] = curScale; - _animator->animRefreshNPC(0); - delayWithTicks(1); - } - _scaleTable[_currentCharacter->y1] = scaleValue; - _scaleMode = scaleModeBackUp; - return 0; -} - -int KyraEngine_v1::o1_setBrandonScaleXAndY(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setBrandonScaleXAndY(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - _animator->_brandonScaleX = stackPos(0); - _animator->_brandonScaleY = stackPos(1); - return 0; -} - -int KyraEngine_v1::o1_resetScaleMode(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_resetScaleMode(%p) ()", (const void *)script); - _scaleMode = 0; - return 0; -} - -int KyraEngine_v1::o1_getScaleDepthTableValue(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_getScaleDepthTableValue(%p) (%d)", (const void *)script, stackPos(0)); - assert(stackPos(0) < ARRAYSIZE(_scaleTable)); - return _scaleTable[stackPos(0)]; -} - -int KyraEngine_v1::o1_setScaleDepthTableValue(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setScaleDepthTableValue(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - assert(stackPos(0) < ARRAYSIZE(_scaleTable)); - _scaleTable[stackPos(0)] = stackPos(1); - return stackPos(1); -} - -int KyraEngine_v1::o1_message(EMCState *script) { - if (_flags.isTalkie) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_message(%p) (%d, '%s', %d)", (const void *)script, stackPos(0), stackPosString(1), stackPos(2)); - drawSentenceCommand(stackPosString(1), stackPos(2)); - } else { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_message(%p) ('%s', %d)", (const void *)script, stackPosString(0), stackPos(1)); - drawSentenceCommand(stackPosString(0), stackPos(1)); - } - - return 0; -} - -int KyraEngine_v1::o1_checkClickOnNPC(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_checkClickOnNPC(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - return checkForNPCScriptRun(stackPos(0), stackPos(1)); -} - -int KyraEngine_v1::o1_getFoyerItem(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_getFoyerItem(%p) (%d)", (const void *)script, stackPos(0)); - assert(stackPos(0) < ARRAYSIZE(_foyerItemTable)); - return _foyerItemTable[stackPos(0)]; -} - -int KyraEngine_v1::o1_setFoyerItem(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setFoyerItem(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - assert(stackPos(0) < ARRAYSIZE(_foyerItemTable)); - _foyerItemTable[stackPos(0)] = stackPos(1); - return stackPos(1); -} - -int KyraEngine_v1::o1_setNoItemDropRegion(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setNoItemDropRegion(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); - addToNoDropRects(stackPos(0), stackPos(1), stackPos(2), stackPos(3)); - return 0; -} - -int KyraEngine_v1::o1_walkMalcolmOn(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_walkMalcolmOn(%p) ()", (const void *)script); - if (!_malcolmFlag) - _malcolmFlag = 1; - return 0; -} - -int KyraEngine_v1::o1_passiveProtection(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_passiveProtection(%p) ()", (const void *)script); - return 1; -} - -int KyraEngine_v1::o1_setPlayingLoop(EMCState *script) { - warning("STUB: o1_setPlayingLoop"); - return 0; -} - -int KyraEngine_v1::o1_brandonToStoneSequence(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_brandonToStoneSequence(%p) ()", (const void *)script); - seq_brandonToStone(); - return 0; -} - -int KyraEngine_v1::o1_brandonHealingSequence(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_brandonHealingSequence(%p) ()", (const void *)script); - seq_brandonHealing(); - return 0; -} - -int KyraEngine_v1::o1_protectCommandLine(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_protectCommandLine(%p) (%d)", (const void *)script, stackPos(0)); - return stackPos(0); -} - -int KyraEngine_v1::o1_pauseMusicSeconds(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_pauseMusicSeconds(%p) ()", (const void *)script); - // if music disabled - // return - o1_pauseSeconds(script); - return 0; -} - -int KyraEngine_v1::o1_resetMaskRegion(EMCState *script) { - warning("STUB: o1_resetMaskRegion"); - return 0; -} - -int KyraEngine_v1::o1_setPaletteChangeFlag(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setPaletteChangeFlag(%p) (%d)", (const void *)script, stackPos(0)); - _paletteChanged = stackPos(0); - return _paletteChanged; -} - -int KyraEngine_v1::o1_fillRect(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_fillRect(%p) (%d, %d, %d, %d, %d, 0x%X)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5)); - int videoPageBackup = _screen->_curPage; - _screen->_curPage = stackPos(0); - _screen->fillRect(stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5)); - _screen->_curPage = videoPageBackup; - return 0; -} - -int KyraEngine_v1::o1_vocUnload(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_vocUnload(%p) ()", (const void *)script); - // this should unload all voc files (not needed) - return 0; -} - -int KyraEngine_v1::o1_vocLoad(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_vocLoad(%p) (%d)", (const void *)script, stackPos(0)); - // this should load the specified voc file (not needed) - return 0; -} - -int KyraEngine_v1::o1_dummy(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_dummy(%p) ()", (const void *)script); - return 0; -} - -#pragma mark - - -typedef Common::Functor1Mem OpcodeV1; -#define SetOpcodeTable(x) table = &x; -#define Opcode(x) table->push_back(new OpcodeV1(this, &KyraEngine_v1::x)) -void KyraEngine_v1::setupOpcodeTable() { - Common::Array *table = 0; - - SetOpcodeTable(_opcodes); - // 0x00 - Opcode(o1_magicInMouseItem); - Opcode(o1_characterSays); - Opcode(o1_pauseTicks); - Opcode(o1_drawSceneAnimShape); - // 0x04 - Opcode(o1_queryGameFlag); - Opcode(o1_setGameFlag); - Opcode(o1_resetGameFlag); - Opcode(o1_runNPCScript); - // 0x08 - Opcode(o1_setSpecialExitList); - Opcode(o1_blockInWalkableRegion); - Opcode(o1_blockOutWalkableRegion); - Opcode(o1_walkPlayerToPoint); - // 0x0c - Opcode(o1_dropItemInScene); - Opcode(o1_drawAnimShapeIntoScene); - Opcode(o1_createMouseItem); - Opcode(o1_savePageToDisk); - // 0x10 - Opcode(o1_sceneAnimOn); - Opcode(o1_sceneAnimOff); - Opcode(o1_getElapsedSeconds); - Opcode(o1_mouseIsPointer); - // 0x14 - Opcode(o1_destroyMouseItem); - Opcode(o1_runSceneAnimUntilDone); - Opcode(o1_fadeSpecialPalette); - Opcode(o1_playAdlibSound); - // 0x18 - Opcode(o1_playAdlibScore); - Opcode(o1_phaseInSameScene); - Opcode(o1_setScenePhasingFlag); - Opcode(o1_resetScenePhasingFlag); - // 0x1c - Opcode(o1_queryScenePhasingFlag); - Opcode(o1_sceneToDirection); - Opcode(o1_setBirthstoneGem); - Opcode(o1_placeItemInGenericMapScene); - // 0x20 - Opcode(o1_setBrandonStatusBit); - Opcode(o1_pauseSeconds); - Opcode(o1_getCharactersLocation); - Opcode(o1_runNPCSubscript); - // 0x24 - Opcode(o1_magicOutMouseItem); - Opcode(o1_internalAnimOn); - Opcode(o1_forceBrandonToNormal); - Opcode(o1_poisonDeathNow); - // 0x28 - Opcode(o1_setScaleMode); - Opcode(o1_openWSAFile); - Opcode(o1_closeWSAFile); - Opcode(o1_runWSAFromBeginningToEnd); - // 0x2c - Opcode(o1_displayWSAFrame); - Opcode(o1_enterNewScene); - Opcode(o1_setSpecialEnterXAndY); - Opcode(o1_runWSAFrames); - // 0x30 - Opcode(o1_popBrandonIntoScene); - Opcode(o1_restoreAllObjectBackgrounds); - Opcode(o1_setCustomPaletteRange); - Opcode(o1_loadPageFromDisk); - // 0x34 - Opcode(o1_customPrintTalkString); - Opcode(o1_restoreCustomPrintBackground); - Opcode(o1_hideMouse); - Opcode(o1_showMouse); - // 0x38 - Opcode(o1_getCharacterX); - Opcode(o1_getCharacterY); - Opcode(o1_changeCharactersFacing); - Opcode(o1_copyWSARegion); - // 0x3c - Opcode(o1_printText); - Opcode(o1_random); - Opcode(o1_loadSoundFile); - Opcode(o1_displayWSAFrameOnHidPage); - // 0x40 - Opcode(o1_displayWSASequentialFrames); - Opcode(o1_drawCharacterStanding); - Opcode(o1_internalAnimOff); - Opcode(o1_changeCharactersXAndY); - // 0x44 - Opcode(o1_clearSceneAnimatorBeacon); - Opcode(o1_querySceneAnimatorBeacon); - Opcode(o1_refreshSceneAnimator); - Opcode(o1_placeItemInOffScene); - // 0x48 - Opcode(o1_wipeDownMouseItem); - Opcode(o1_placeCharacterInOtherScene); - Opcode(o1_getKey); - Opcode(o1_specificItemInInventory); - // 0x4c - Opcode(o1_popMobileNPCIntoScene); - Opcode(o1_mobileCharacterInScene); - Opcode(o1_hideMobileCharacter); - Opcode(o1_unhideMobileCharacter); - // 0x50 - Opcode(o1_setCharactersLocation); - Opcode(o1_walkCharacterToPoint); - Opcode(o1_specialEventDisplayBrynnsNote); - Opcode(o1_specialEventRemoveBrynnsNote); - // 0x54 - Opcode(o1_setLogicPage); - Opcode(o1_fatPrint); - Opcode(o1_preserveAllObjectBackgrounds); - Opcode(o1_updateSceneAnimations); - // 0x58 - Opcode(o1_sceneAnimationActive); - Opcode(o1_setCharactersMovementDelay); - Opcode(o1_getCharactersFacing); - Opcode(o1_bkgdScrollSceneAndMasksRight); - // 0x5c - Opcode(o1_dispelMagicAnimation); - Opcode(o1_findBrightestFireberry); - Opcode(o1_setFireberryGlowPalette); - Opcode(o1_setDeathHandlerFlag); - // 0x60 - Opcode(o1_drinkPotionAnimation); - Opcode(o1_makeAmuletAppear); - Opcode(o1_drawItemShapeIntoScene); - Opcode(o1_setCharactersCurrentFrame); - // 0x64 - Opcode(o1_waitForConfirmationMouseClick); - Opcode(o1_pageFlip); - Opcode(o1_setSceneFile); - Opcode(o1_getItemInMarbleVase); - // 0x68 - Opcode(o1_setItemInMarbleVase); - Opcode(o1_addItemToInventory); - Opcode(o1_intPrint); - Opcode(o1_shakeScreen); - // 0x6c - Opcode(o1_createAmuletJewel); - Opcode(o1_setSceneAnimCurrXY); - Opcode(o1_poisonBrandonAndRemaps); - Opcode(o1_fillFlaskWithWater); - // 0x70 - Opcode(o1_getCharactersMovementDelay); - Opcode(o1_getBirthstoneGem); - Opcode(o1_queryBrandonStatusBit); - Opcode(o1_playFluteAnimation); - // 0x74 - Opcode(o1_playWinterScrollSequence); - Opcode(o1_getIdolGem); - Opcode(o1_setIdolGem); - Opcode(o1_totalItemsInScene); - // 0x78 - Opcode(o1_restoreBrandonsMovementDelay); - Opcode(o1_setMousePos); - Opcode(o1_getMouseState); - Opcode(o1_setEntranceMouseCursorTrack); - // 0x7c - Opcode(o1_itemAppearsOnGround); - Opcode(o1_setNoDrawShapesFlag); - Opcode(o1_fadeEntirePalette); - Opcode(o1_itemOnGroundHere); - // 0x80 - Opcode(o1_queryCauldronState); - Opcode(o1_setCauldronState); - Opcode(o1_queryCrystalState); - Opcode(o1_setCrystalState); - // 0x84 - Opcode(o1_setPaletteRange); - Opcode(o1_shrinkBrandonDown); - Opcode(o1_growBrandonUp); - Opcode(o1_setBrandonScaleXAndY); - // 0x88 - Opcode(o1_resetScaleMode); - Opcode(o1_getScaleDepthTableValue); - Opcode(o1_setScaleDepthTableValue); - Opcode(o1_message); - // 0x8c - Opcode(o1_checkClickOnNPC); - Opcode(o1_getFoyerItem); - Opcode(o1_setFoyerItem); - Opcode(o1_setNoItemDropRegion); - // 0x90 - Opcode(o1_walkMalcolmOn); - Opcode(o1_passiveProtection); - Opcode(o1_setPlayingLoop); - Opcode(o1_brandonToStoneSequence); - // 0x94 - Opcode(o1_brandonHealingSequence); - Opcode(o1_protectCommandLine); - Opcode(o1_pauseMusicSeconds); - Opcode(o1_resetMaskRegion); - // 0x98 - Opcode(o1_setPaletteChangeFlag); - Opcode(o1_fillRect); - Opcode(o1_vocUnload); - Opcode(o1_vocLoad); - // 0x9c - Opcode(o1_dummy); -} -#undef Opcode - -} // end of namespace Kyra - diff --git a/engines/kyra/seqplayer.cpp b/engines/kyra/seqplayer.cpp index 9a670ce85f..73d69ef10c 100644 --- a/engines/kyra/seqplayer.cpp +++ b/engines/kyra/seqplayer.cpp @@ -40,7 +40,7 @@ namespace Kyra { -SeqPlayer::SeqPlayer(KyraEngine_v1 *vm, OSystem *system) { +SeqPlayer::SeqPlayer(KyraEngine_LoK *vm, OSystem *system) { _vm = vm; _system = system; diff --git a/engines/kyra/seqplayer.h b/engines/kyra/seqplayer.h index ce7f4648df..7e1b06d955 100644 --- a/engines/kyra/seqplayer.h +++ b/engines/kyra/seqplayer.h @@ -26,13 +26,13 @@ #ifndef KYRA_SEQPLAYER_H #define KYRA_SEQPLAYER_H -#include "kyra/kyra_v1.h" +#include "kyra/kyra_lok.h" namespace Kyra { class SeqPlayer { public: - SeqPlayer(KyraEngine_v1 *vm, OSystem *system); + SeqPlayer(KyraEngine_LoK *vm, OSystem *system); ~SeqPlayer(); void setCopyViewOffs(bool offs) { @@ -46,7 +46,7 @@ public: uint8 *setPanPages(int pageNum, int shape); protected: - KyraEngine_v1 *_vm; + KyraEngine_LoK *_vm; OSystem *_system; Screen *_screen; Sound *_sound; diff --git a/engines/kyra/sequences_hof.cpp b/engines/kyra/sequences_hof.cpp index bed94b2ae0..fc0959f444 100644 --- a/engines/kyra/sequences_hof.cpp +++ b/engines/kyra/sequences_hof.cpp @@ -333,7 +333,7 @@ void KyraEngine_HoF::seq_playSequences(int startSeq, int endSeq) { seq_uninit(); } -int KyraEngine_HoF::seq_introWestwood(WSAMovieV2 *wsaObj, int x, int y, int frm) { +int KyraEngine_HoF::seq_introWestwood(WSAMovie_v2 *wsaObj, int x, int y, int frm) { debugC(9, kDebugLevelMain, "KyraEngine_HoF::seq_introWestwood(%p, %i, %i, %i)", (const void*)wsaObj, x, y, frm); if (frm == -2) { @@ -346,7 +346,7 @@ int KyraEngine_HoF::seq_introWestwood(WSAMovieV2 *wsaObj, int x, int y, int frm) return 0; } -int KyraEngine_HoF::seq_introTitle(WSAMovieV2 *wsaObj, int x, int y, int frm) { +int KyraEngine_HoF::seq_introTitle(WSAMovie_v2 *wsaObj, int x, int y, int frm) { debugC(9, kDebugLevelMain, "KyraEngine_HoF::seq_introTitle(%p, %i, %i, %i)", (const void*)wsaObj, x, y, frm); if (frm == 1) { @@ -368,7 +368,7 @@ int KyraEngine_HoF::seq_introTitle(WSAMovieV2 *wsaObj, int x, int y, int frm) { return 0; } -int KyraEngine_HoF::seq_introOverview(WSAMovieV2 *wsaObj, int x, int y, int frm) { +int KyraEngine_HoF::seq_introOverview(WSAMovie_v2 *wsaObj, int x, int y, int frm) { debugC(9, kDebugLevelMain, "KyraEngine_HoF::seq_introOverview(%p, %i, %i, %i)", (const void*)wsaObj, x, y, frm); uint8 *tmpPal = &(_screen->getPalette(3)[0x101]); @@ -468,7 +468,7 @@ int KyraEngine_HoF::seq_introOverview(WSAMovieV2 *wsaObj, int x, int y, int frm) return 0; } -int KyraEngine_HoF::seq_introLibrary(WSAMovieV2 *wsaObj, int x, int y, int frm) { +int KyraEngine_HoF::seq_introLibrary(WSAMovie_v2 *wsaObj, int x, int y, int frm) { debugC(9, kDebugLevelMain, "KyraEngine_HoF::seq_introLibrary(%p, %i, %i, %i)", (const void*)wsaObj, x, y, frm); switch (_seqFrameCounter) { @@ -544,7 +544,7 @@ int KyraEngine_HoF::seq_introLibrary(WSAMovieV2 *wsaObj, int x, int y, int frm) } -int KyraEngine_HoF::seq_introHand(WSAMovieV2 *wsaObj, int x, int y, int frm) { +int KyraEngine_HoF::seq_introHand(WSAMovie_v2 *wsaObj, int x, int y, int frm) { debugC(9, kDebugLevelMain, "KyraEngine_HoF::seq_introHand(%p, %i, %i, %i)", (const void*)wsaObj, x, y, frm); switch (_seqFrameCounter) { @@ -628,7 +628,7 @@ int KyraEngine_HoF::seq_introHand(WSAMovieV2 *wsaObj, int x, int y, int frm) { return 0; } -int KyraEngine_HoF::seq_introPoint(WSAMovieV2 *wsaObj, int x, int y, int frm) { +int KyraEngine_HoF::seq_introPoint(WSAMovie_v2 *wsaObj, int x, int y, int frm) { if (frm == -2) { seq_waitForTextsTimeout(); _seqEndTime = 0; @@ -661,7 +661,7 @@ int KyraEngine_HoF::seq_introPoint(WSAMovieV2 *wsaObj, int x, int y, int frm) { return 0; } -int KyraEngine_HoF::seq_introZanfaun(WSAMovieV2 *wsaObj, int x, int y, int frm) { +int KyraEngine_HoF::seq_introZanfaun(WSAMovie_v2 *wsaObj, int x, int y, int frm) { if (frm == -2) { seq_waitForTextsTimeout(); _seqEndTime = 0; @@ -750,7 +750,7 @@ int KyraEngine_HoF::seq_introZanfaun(WSAMovieV2 *wsaObj, int x, int y, int frm) return 0; } -int KyraEngine_HoF::seq_introOver1(WSAMovieV2 *wsaObj, int x, int y, int frm) { +int KyraEngine_HoF::seq_introOver1(WSAMovie_v2 *wsaObj, int x, int y, int frm) { if (frm == 2) seq_waitForTextsTimeout(); else if (frm == 3) @@ -759,13 +759,13 @@ int KyraEngine_HoF::seq_introOver1(WSAMovieV2 *wsaObj, int x, int y, int frm) { } -int KyraEngine_HoF::seq_introOver2(WSAMovieV2 *wsaObj, int x, int y, int frm) { +int KyraEngine_HoF::seq_introOver2(WSAMovie_v2 *wsaObj, int x, int y, int frm) { if (frm == 1) seq_playTalkText(12); return frm; } -int KyraEngine_HoF::seq_introForest(WSAMovieV2 *wsaObj, int x, int y, int frm) { +int KyraEngine_HoF::seq_introForest(WSAMovie_v2 *wsaObj, int x, int y, int frm) { if (frm == 11) seq_waitForTextsTimeout(); else if (frm == 12) @@ -774,7 +774,7 @@ int KyraEngine_HoF::seq_introForest(WSAMovieV2 *wsaObj, int x, int y, int frm) { return frm; } -int KyraEngine_HoF::seq_introDragon(WSAMovieV2 *wsaObj, int x, int y, int frm) { +int KyraEngine_HoF::seq_introDragon(WSAMovie_v2 *wsaObj, int x, int y, int frm) { if (frm == 11) seq_waitForTextsTimeout(); else if (frm == 3) @@ -782,17 +782,17 @@ int KyraEngine_HoF::seq_introDragon(WSAMovieV2 *wsaObj, int x, int y, int frm) { return frm; } -int KyraEngine_HoF::seq_introDarm(WSAMovieV2 *wsaObj, int x, int y, int frm) { +int KyraEngine_HoF::seq_introDarm(WSAMovie_v2 *wsaObj, int x, int y, int frm) { //NULLSUB (at least in fm-towns version) return frm; } -int KyraEngine_HoF::seq_introLibrary2(WSAMovieV2 *wsaObj, int x, int y, int frm) { +int KyraEngine_HoF::seq_introLibrary2(WSAMovie_v2 *wsaObj, int x, int y, int frm) { //NULLSUB (at least in fm-towns version) return frm; } -int KyraEngine_HoF::seq_introMarco(WSAMovieV2 *wsaObj, int x, int y, int frm) { +int KyraEngine_HoF::seq_introMarco(WSAMovie_v2 *wsaObj, int x, int y, int frm) { if (frm == 36) { seq_waitForTextsTimeout(); _seqEndTime = 0; @@ -800,34 +800,34 @@ int KyraEngine_HoF::seq_introMarco(WSAMovieV2 *wsaObj, int x, int y, int frm) { return frm; } -int KyraEngine_HoF::seq_introHand1a(WSAMovieV2 *wsaObj, int x, int y, int frm) { +int KyraEngine_HoF::seq_introHand1a(WSAMovie_v2 *wsaObj, int x, int y, int frm) { //NULLSUB (at least in fm-towns version) return frm; } -int KyraEngine_HoF::seq_introHand1b(WSAMovieV2 *wsaObj, int x, int y, int frm) { +int KyraEngine_HoF::seq_introHand1b(WSAMovie_v2 *wsaObj, int x, int y, int frm) { if (frm == 15) frm = 12; return frm; } -int KyraEngine_HoF::seq_introHand1c(WSAMovieV2 *wsaObj, int x, int y, int frm) { +int KyraEngine_HoF::seq_introHand1c(WSAMovie_v2 *wsaObj, int x, int y, int frm) { if (frm == 8) frm = 4; return frm; } -int KyraEngine_HoF::seq_introHand2(WSAMovieV2 *wsaObj, int x, int y, int frm) { +int KyraEngine_HoF::seq_introHand2(WSAMovie_v2 *wsaObj, int x, int y, int frm) { //NULLSUB (at least in fm-towns version) return frm; } -int KyraEngine_HoF::seq_introHand3(WSAMovieV2 *wsaObj, int x, int y, int frm) { +int KyraEngine_HoF::seq_introHand3(WSAMovie_v2 *wsaObj, int x, int y, int frm) { //NULLSUB (at least in fm-towns version) return frm; } -int KyraEngine_HoF::seq_finaleFunters(WSAMovieV2 *wsaObj, int x, int y, int frm) { +int KyraEngine_HoF::seq_finaleFunters(WSAMovie_v2 *wsaObj, int x, int y, int frm) { uint32 endtime = 0; int chatX = 0; int chatY = 0; @@ -911,7 +911,7 @@ int KyraEngine_HoF::seq_finaleFunters(WSAMovieV2 *wsaObj, int x, int y, int frm) return 0; } -int KyraEngine_HoF::seq_finaleFerb(WSAMovieV2 *wsaObj, int x, int y, int frm) { +int KyraEngine_HoF::seq_finaleFerb(WSAMovie_v2 *wsaObj, int x, int y, int frm) { uint32 endtime = 0; int chatX = 0; int chatY = 0; @@ -995,7 +995,7 @@ int KyraEngine_HoF::seq_finaleFerb(WSAMovieV2 *wsaObj, int x, int y, int frm) { return 0; } -int KyraEngine_HoF::seq_finaleFish(WSAMovieV2 *wsaObj, int x, int y, int frm) { +int KyraEngine_HoF::seq_finaleFish(WSAMovie_v2 *wsaObj, int x, int y, int frm) { uint32 endtime = 0; int chatX = 0; int chatY = 0; @@ -1072,7 +1072,7 @@ int KyraEngine_HoF::seq_finaleFish(WSAMovieV2 *wsaObj, int x, int y, int frm) { return 0; } -int KyraEngine_HoF::seq_finaleFheep(WSAMovieV2 *wsaObj, int x, int y, int frm) { +int KyraEngine_HoF::seq_finaleFheep(WSAMovie_v2 *wsaObj, int x, int y, int frm) { uint32 endtime = 0; int chatX = 0; int chatY = 0; @@ -1154,7 +1154,7 @@ int KyraEngine_HoF::seq_finaleFheep(WSAMovieV2 *wsaObj, int x, int y, int frm) { return 0; } -int KyraEngine_HoF::seq_finaleFarmer(WSAMovieV2 *wsaObj, int x, int y, int frm) { +int KyraEngine_HoF::seq_finaleFarmer(WSAMovie_v2 *wsaObj, int x, int y, int frm) { uint32 endtime = 0; int chatX = 0; int chatY = 0; @@ -1224,7 +1224,7 @@ int KyraEngine_HoF::seq_finaleFarmer(WSAMovieV2 *wsaObj, int x, int y, int frm) return 0; } -int KyraEngine_HoF::seq_finaleFuards(WSAMovieV2 *wsaObj, int x, int y, int frm) { +int KyraEngine_HoF::seq_finaleFuards(WSAMovie_v2 *wsaObj, int x, int y, int frm) { uint32 endtime = 0; int chatX = 0; int chatY = 0; @@ -1324,7 +1324,7 @@ int KyraEngine_HoF::seq_finaleFuards(WSAMovieV2 *wsaObj, int x, int y, int frm) return 0; } -int KyraEngine_HoF::seq_finaleFirates(WSAMovieV2 *wsaObj, int x, int y, int frm) { +int KyraEngine_HoF::seq_finaleFirates(WSAMovie_v2 *wsaObj, int x, int y, int frm) { uint32 endtime = 0; int chatX = 0; int chatY = 0; @@ -1416,7 +1416,7 @@ int KyraEngine_HoF::seq_finaleFirates(WSAMovieV2 *wsaObj, int x, int y, int frm) return 0; } -int KyraEngine_HoF::seq_finaleFrash(WSAMovieV2 *wsaObj, int x, int y, int frm) { +int KyraEngine_HoF::seq_finaleFrash(WSAMovie_v2 *wsaObj, int x, int y, int frm) { int tmp = 0; switch (frm) { @@ -1544,7 +1544,7 @@ void KyraEngine_HoF::seq_finaleActorScreen() { _sound->loadSoundFile(0); } -int KyraEngine_HoF::seq_finaleFiggle(WSAMovieV2 *wsaObj, int x, int y, int frm) { +int KyraEngine_HoF::seq_finaleFiggle(WSAMovie_v2 *wsaObj, int x, int y, int frm) { if (_seqFrameCounter == 10) _seqEndTime = 0; if (_seqFrameCounter == 10 || _seqFrameCounter == 5 || _seqFrameCounter == 7) @@ -1554,18 +1554,18 @@ int KyraEngine_HoF::seq_finaleFiggle(WSAMovieV2 *wsaObj, int x, int y, int frm) return frm; } -int KyraEngine_HoF::seq_demoVirgin(WSAMovieV2 *wsaObj, int x, int y, int frm) { +int KyraEngine_HoF::seq_demoVirgin(WSAMovie_v2 *wsaObj, int x, int y, int frm) { if (!frm) delay(50 * _tickLength); return 0; } -int KyraEngine_HoF::seq_demoWestwood(WSAMovieV2 *wsaObj, int x, int y, int frm) { +int KyraEngine_HoF::seq_demoWestwood(WSAMovie_v2 *wsaObj, int x, int y, int frm) { if (!frm) _sound->playTrack(2); return 0; } -int KyraEngine_HoF::seq_demoTitle(WSAMovieV2 *wsaObj, int x, int y, int frm) { +int KyraEngine_HoF::seq_demoTitle(WSAMovie_v2 *wsaObj, int x, int y, int frm) { if (!frm) { _sound->playTrack(3); } else if (frm == 25) { @@ -1576,7 +1576,7 @@ int KyraEngine_HoF::seq_demoTitle(WSAMovieV2 *wsaObj, int x, int y, int frm) { return 0; } -int KyraEngine_HoF::seq_demoHill(WSAMovieV2 *wsaObj, int x, int y, int frm) { +int KyraEngine_HoF::seq_demoHill(WSAMovie_v2 *wsaObj, int x, int y, int frm) { if (!frm) { _sound->playTrack(4); } else if (frm == 25) { @@ -1596,7 +1596,7 @@ int KyraEngine_HoF::seq_demoHill(WSAMovieV2 *wsaObj, int x, int y, int frm) { return 0; } -int KyraEngine_HoF::seq_demoOuthome(WSAMovieV2 *wsaObj, int x, int y, int frm) { +int KyraEngine_HoF::seq_demoOuthome(WSAMovie_v2 *wsaObj, int x, int y, int frm) { switch (frm) { case 12: seq_playTalkText(4); @@ -1637,7 +1637,7 @@ int KyraEngine_HoF::seq_demoOuthome(WSAMovieV2 *wsaObj, int x, int y, int frm) { return 0; } -int KyraEngine_HoF::seq_demoWharf(WSAMovieV2 *wsaObj, int x, int y, int frm) { +int KyraEngine_HoF::seq_demoWharf(WSAMovie_v2 *wsaObj, int x, int y, int frm) { if (!_seqFrameCounter) seq_loadNestedSequence(0, kSequenceDemoWharf2); @@ -1678,7 +1678,7 @@ int KyraEngine_HoF::seq_demoWharf(WSAMovieV2 *wsaObj, int x, int y, int frm) { return 0; } -int KyraEngine_HoF::seq_demoDinob(WSAMovieV2 *wsaObj, int x, int y, int frm) { +int KyraEngine_HoF::seq_demoDinob(WSAMovie_v2 *wsaObj, int x, int y, int frm) { if (frm == 0) { if (!(_seqFrameCounter/8)) { seq_loadNestedSequence(0, kSequenceDemoDinob2); @@ -1699,7 +1699,7 @@ int KyraEngine_HoF::seq_demoDinob(WSAMovieV2 *wsaObj, int x, int y, int frm) { return 0; } -int KyraEngine_HoF::seq_demoFisher(WSAMovieV2 *wsaObj, int x, int y, int frm) { +int KyraEngine_HoF::seq_demoFisher(WSAMovie_v2 *wsaObj, int x, int y, int frm) { if (((_system->getMillis() - _seqStartTime) / (5 * _tickLength)) > 0) { _seqStartTime = _system->getMillis(); if (!_seqFrameCounter) { @@ -1741,14 +1741,14 @@ int KyraEngine_HoF::seq_demoFisher(WSAMovieV2 *wsaObj, int x, int y, int frm) { return 0; } -int KyraEngine_HoF::seq_demoWharf2(WSAMovieV2 *wsaObj, int x, int y, int frm) { +int KyraEngine_HoF::seq_demoWharf2(WSAMovie_v2 *wsaObj, int x, int y, int frm) { if (frm == 69) _seqWsaCurrentFrame = 8; return frm; } -int KyraEngine_HoF::seq_demoDinob2(WSAMovieV2 *wsaObj, int x, int y, int frm) { +int KyraEngine_HoF::seq_demoDinob2(WSAMovie_v2 *wsaObj, int x, int y, int frm) { switch (frm) { case 19: seq_playTalkText(13); @@ -1778,17 +1778,17 @@ int KyraEngine_HoF::seq_demoDinob2(WSAMovieV2 *wsaObj, int x, int y, int frm) { return frm; } -int KyraEngine_HoF::seq_demoWater(WSAMovieV2 *wsaObj, int x, int y, int frm) { +int KyraEngine_HoF::seq_demoWater(WSAMovie_v2 *wsaObj, int x, int y, int frm) { if (frm == 1) seq_playTalkText(11); return frm; } -int KyraEngine_HoF::seq_demoBail(WSAMovieV2 *wsaObj, int x, int y, int frm) { +int KyraEngine_HoF::seq_demoBail(WSAMovie_v2 *wsaObj, int x, int y, int frm) { return frm; } -int KyraEngine_HoF::seq_demoDig(WSAMovieV2 *wsaObj, int x, int y, int frm) { +int KyraEngine_HoF::seq_demoDig(WSAMovie_v2 *wsaObj, int x, int y, int frm) { return frm; } @@ -2048,7 +2048,7 @@ void KyraEngine_HoF::seq_loadNestedSequence(int wsaNum, int seqNum) { NestedSequence s = _sequences->seqn[seqNum]; if (!_activeWSA[wsaNum].movie) { - _activeWSA[wsaNum].movie = new WSAMovieV2(this, _screen); + _activeWSA[wsaNum].movie = new WSAMovie_v2(this, _screen); assert(_activeWSA[wsaNum].movie); } @@ -2328,7 +2328,7 @@ void KyraEngine_HoF::seq_printCreditsString(uint16 strIndex, int x, int y, const _seqTextColor[0] = seqTextColor0; } -void KyraEngine_HoF::seq_playWsaSyncDialogue(uint16 strIndex, uint16 vocIndex, int textColor, int x, int y, int width, WSAMovieV2 *wsa, int firstframe, int lastframe, int wsaXpos, int wsaYpos) { +void KyraEngine_HoF::seq_playWsaSyncDialogue(uint16 strIndex, uint16 vocIndex, int textColor, int x, int y, int width, WSAMovie_v2 *wsa, int firstframe, int lastframe, int wsaXpos, int wsaYpos) { int dur = int(strlen(_sequenceStrings[strIndex])) * (_flags.isTalkie ? 7 : 15); int entry = textEnabled() ? seq_setTextEntry(strIndex, x, y, dur, width) : strIndex; _activeText[entry].textcolor = textColor; @@ -2574,7 +2574,7 @@ void KyraEngine_HoF::seq_scrollPage() { } void KyraEngine_HoF::seq_showStarcraftLogo() { - WSAMovieV2 *ci = new WSAMovieV2(this, _screen); + WSAMovie_v2 *ci = new WSAMovie_v2(this, _screen); assert(ci); _screen->clearPage(2); _res->loadPakFile("INTROGEN.PAK"); @@ -2616,7 +2616,7 @@ void KyraEngine_HoF::seq_showStarcraftLogo() { void KyraEngine_HoF::seq_init() { _seqProcessedString = new char[200]; - _seqWsa = new WSAMovieV2(this, _screen); + _seqWsa = new WSAMovie_v2(this, _screen); _activeWSA = new ActiveWSA[8]; _activeText = new ActiveText[10]; diff --git a/engines/kyra/sequences_lok.cpp b/engines/kyra/sequences_lok.cpp new file mode 100644 index 0000000000..904eae9d48 --- /dev/null +++ b/engines/kyra/sequences_lok.cpp @@ -0,0 +1,1884 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "kyra/kyra_lok.h" +#include "kyra/seqplayer.h" +#include "kyra/screen_lok.h" +#include "kyra/resource.h" +#include "kyra/sound.h" +#include "kyra/sprites.h" +#include "kyra/wsamovie.h" +#include "kyra/animator_lok.h" +#include "kyra/text.h" +#include "kyra/timer.h" + +#include "common/events.h" +#include "common/system.h" +#include "common/savefile.h" + +namespace Kyra { + +void KyraEngine_LoK::seq_demo() { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::seq_demo()"); + + snd_playTheme(0, 2); + + _screen->loadBitmap("START.CPS", 7, 7, _screen->_currentPalette); + _screen->copyRegion(0, 0, 0, 0, 320, 200, 6, 0, Screen::CR_NO_P_CHECK); + _screen->updateScreen(); + _screen->fadeFromBlack(); + delay(60 * _tickLength); + _screen->fadeToBlack(); + + _screen->clearPage(0); + _screen->loadBitmap("TOP.CPS", 7, 7, NULL); + _screen->loadBitmap("BOTTOM.CPS", 5, 5, _screen->_currentPalette); + _screen->copyRegion(0, 91, 0, 8, 320, 103, 6, 0); + _screen->copyRegion(0, 0, 0, 111, 320, 64, 6, 0); + _screen->updateScreen(); + _screen->fadeFromBlack(); + + _seq->playSequence(_seq_WestwoodLogo, true); + delay(60 * _tickLength); + _seq->playSequence(_seq_KyrandiaLogo, true); + + _screen->fadeToBlack(); + _screen->clearPage(2); + _screen->clearPage(0); + + _seq->playSequence(_seq_Demo1, true); + + _screen->clearPage(0); + _seq->playSequence(_seq_Demo2, true); + + _screen->clearPage(0); + _seq->playSequence(_seq_Demo3, true); + + _screen->clearPage(0); + _seq->playSequence(_seq_Demo4, true); + + _screen->clearPage(0); + _screen->loadBitmap("FINAL.CPS", 7, 7, _screen->_currentPalette); + _screen->_curPage = 0; + _screen->copyRegion(0, 0, 0, 0, 320, 200, 6, 0); + _screen->updateScreen(); + _screen->fadeFromBlack(); + delay(60 * _tickLength); + _screen->fadeToBlack(); + _sound->haltTrack(); +} + +void KyraEngine_LoK::seq_intro() { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::seq_intro()"); + + if (_flags.isTalkie) + _res->loadPakFile("INTRO.VRM"); + + static const IntroProc introProcTable[] = { + &KyraEngine_LoK::seq_introLogos, + &KyraEngine_LoK::seq_introStory, + &KyraEngine_LoK::seq_introMalcolmTree, + &KyraEngine_LoK::seq_introKallakWriting, + &KyraEngine_LoK::seq_introKallakMalcolm + }; + + Common::InSaveFile *in; + if ((in = _saveFileMan->openForLoading(getSavegameFilename(0)))) { + delete in; + _skipIntroFlag = true; + } else + _skipIntroFlag = false; + + _seq->setCopyViewOffs(true); + _screen->setFont(Screen::FID_8_FNT); + if (_flags.platform != Common::kPlatformFMTowns && _flags.platform != Common::kPlatformPC98) + snd_playTheme(0, 2); + _text->setTalkCoords(144); + + for (int i = 0; i < ARRAYSIZE(introProcTable) && !seq_skipSequence(); ++i) + (this->*introProcTable[i])(); + + _text->setTalkCoords(136); + delay(30 * _tickLength); + _seq->setCopyViewOffs(false); + _sound->haltTrack(); + _sound->voiceStop(); + + if (_flags.isTalkie) + _res->unloadPakFile("INTRO.VRM"); +} + +void KyraEngine_LoK::seq_introLogos() { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::seq_introLogos()"); + + if (_flags.platform == Common::kPlatformFMTowns || _flags.platform == Common::kPlatformPC98) { + _screen->loadBitmap("LOGO.CPS", 3, 3, _screen->_currentPalette); + _screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0); + _screen->updateScreen(); + _screen->fadeFromBlack(); + delay(90 * _tickLength); + _screen->fadeToBlack(); + if (!_abortIntroFlag) + snd_playWanderScoreViaMap(57, 0); + } + + _screen->clearPage(0); + + if (_flags.platform == Common::kPlatformAmiga) { + _screen->loadPalette("INTRO.PAL", _screen->_currentPalette); + _screen->loadBitmap("BOTTOM.CPS", 3, 5, 0); + _screen->loadBitmap("TOP.CPS", 3, 3, 0); + _screen->copyRegion(0, 0, 0, 111, 320, 64, 2, 0); + _screen->copyRegion(0, 91, 0, 8, 320, 109, 2, 0); + _screen->copyRegion(0, 0, 0, 0, 320, 190, 0, 2); + } else { + _screen->loadBitmap("TOP.CPS", 7, 7, 0); + _screen->loadBitmap("BOTTOM.CPS", 5, 5, _screen->_currentPalette); + _screen->copyRegion(0, 91, 0, 8, 320, 103, 6, 0); + _screen->copyRegion(0, 0, 0, 111, 320, 64, 6, 0); + } + + _screen->_curPage = 0; + _screen->updateScreen(); + _screen->fadeFromBlack(); + + if (_seq->playSequence(_seq_WestwoodLogo, _skipFlag) || _quitFlag) { + _screen->fadeToBlack(); + _screen->clearPage(0); + return; + } + delay(60 * _tickLength); + + if (_flags.platform == Common::kPlatformAmiga) { + memcpy(_screen->_currentPalette, _screen->_currentPalette + 3*32, 3*32); + _screen->setScreenPalette(_screen->_currentPalette); + } + + if ((_seq->playSequence(_seq_KyrandiaLogo, _skipFlag) && !seq_skipSequence()) || _quitFlag) { + _screen->fadeToBlack(); + _screen->clearPage(0); + return; + } + _screen->fillRect(0, 179, 319, 199, 0); + + if (_quitFlag) + return; + + if (_flags.platform == Common::kPlatformAmiga) { + memcpy(_screen->_currentPalette, _screen->_currentPalette + 3*64, 3*32); + _screen->fadeToBlack(); + _screen->copyRegion(0, 0, 0, 0, 320, 200, 4, 0); + _screen->fadeFromBlack(); + } else { + _screen->copyRegion(0, 91, 0, 8, 320, 104, 6, 2); + _screen->copyRegion(0, 0, 0, 112, 320, 64, 6, 2); + + uint32 start = _system->getMillis(); + bool doneFlag = false; + int oldDistance = 0; + + do { + uint32 now = _system->getMillis(); + + // The smallest y2 we ever draw the screen for is 65. + int distance = (now - start) / _tickLength; + if (distance > 112) { + distance = 112; + doneFlag = true; + } + + if (distance > oldDistance) { + int y1 = 8 + distance; + int h1 = 168 - distance; + int y2 = 176 - distance; + int h2 = distance; + + _screen->copyRegion(0, y1, 0, 8, 320, h1, 2, 0); + if (h2 > 0) + _screen->copyRegion(0, 64, 0, y2, 320, h2, 4, 0); + _screen->updateScreen(); + } + + oldDistance = distance; + delay(10); + } while (!doneFlag && !_quitFlag && !_abortIntroFlag); + } + + if (_quitFlag) + return; + + _seq->playSequence(_seq_Forest, true); +} + +void KyraEngine_LoK::seq_introStory() { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::seq_introStory()"); + _screen->clearPage(3); + _screen->clearPage(0); + + // HACK: The Italian fan translation uses an special text screen here + // so we show it even when text is disabled + if (!textEnabled() && speechEnabled() && _flags.lang != Common::IT_ITA) + return; + + if (_flags.lang == Common::EN_ANY && !_flags.isTalkie && (_flags.platform == Common::kPlatformPC || _flags.platform == Common::kPlatformAmiga)) + _screen->loadBitmap("TEXT.CPS", 3, 3, _screen->_currentPalette); + else if (_flags.lang == Common::EN_ANY || _flags.lang == Common::JA_JPN) + _screen->loadBitmap("TEXT_ENG.CPS", 3, 3, _screen->_currentPalette); + else if (_flags.lang == Common::DE_DEU) + _screen->loadBitmap("TEXT_GER.CPS", 3, 3, _screen->_currentPalette); + else if (_flags.lang == Common::FR_FRA) + _screen->loadBitmap("TEXT_FRE.CPS", 3, 3, _screen->_currentPalette); + else if (_flags.lang == Common::ES_ESP) + _screen->loadBitmap("TEXT_SPA.CPS", 3, 3, _screen->_currentPalette); + else if (_flags.lang == Common::IT_ITA && !_flags.isTalkie) + _screen->loadBitmap("TEXT_ITA.CPS", 3, 3, _screen->_currentPalette); + else if (_flags.lang == Common::IT_ITA && _flags.isTalkie) + _screen->loadBitmap("TEXT_ENG.CPS", 3, 3, _screen->_currentPalette); + else + warning("no story graphics file found"); + _screen->setScreenPalette(_screen->_currentPalette); + _screen->copyRegion(0, 0, 0, 0, 320, 200, 3, 0); + + if (_flags.lang == Common::JA_JPN) { + const int x1 = (Screen::SCREEN_W - _screen->getTextWidth(_seq_textsTable[18])) / 2; + const int x2 = (Screen::SCREEN_W - _screen->getTextWidth(_seq_textsTable[19])) / 2; + const int y1 = 175; + const int y2 = 184; + + uint8 colorMap[] = { 0, 15, 12, 12 }; + _screen->setTextColor(colorMap, 0, 3); + + _screen->printText(_seq_textsTable[18], x1, y1, 5, 8); + _screen->printText(_seq_textsTable[19], x2, y2, 5, 8); + } + + _screen->updateScreen(); + //debugC(0, kDebugLevelMain, "skipFlag %i, %i", _skipFlag, _tickLength); + delay(360 * _tickLength); +} + +void KyraEngine_LoK::seq_introMalcolmTree() { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::seq_introMalcolmTree()"); + _screen->_curPage = 0; + _screen->clearPage(3); + _seq->playSequence(_seq_MalcolmTree, true); +} + +void KyraEngine_LoK::seq_introKallakWriting() { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::seq_introKallakWriting()"); + _seq->makeHandShapes(); + _screen->setAnimBlockPtr(5060); + _screen->_charWidth = -2; + _screen->clearPage(3); + _seq->playSequence(_seq_KallakWriting, true); +} + +void KyraEngine_LoK::seq_introKallakMalcolm() { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::seq_introKallakMalcolm()"); + _screen->clearPage(3); + _seq->playSequence(_seq_KallakMalcolm, true); +} + +void KyraEngine_LoK::seq_createAmuletJewel(int jewel, int page, int noSound, int drawOnly) { + debugC(9, kDebugLevelMain, "seq_createAmuletJewel(%d, %d, %d, %d)", jewel, page, noSound, drawOnly); + static const uint16 specialJewelTable[] = { + 0x167, 0x162, 0x15D, 0x158, 0x153, 0xFFFF + }; + static const uint16 specialJewelTable1[] = { + 0x14F, 0x154, 0x159, 0x15E, 0x163, 0xFFFF + }; + static const uint16 specialJewelTable2[] = { + 0x150, 0x155, 0x15A, 0x15F, 0x164, 0xFFFF + }; + static const uint16 specialJewelTable3[] = { + 0x151, 0x156, 0x15B, 0x160, 0x165, 0xFFFF + }; + static const uint16 specialJewelTable4[] = { + 0x152, 0x157, 0x15C, 0x161, 0x166, 0xFFFF + }; + if (!noSound) + snd_playSoundEffect(0x5F); + _screen->hideMouse(); + if (!drawOnly) { + for (int i = 0; specialJewelTable[i] != 0xFFFF; ++i) { + _screen->drawShape(page, _shapes[specialJewelTable[i]], _amuletX2[jewel], _amuletY2[jewel], 0, 0); + _screen->updateScreen(); + delayWithTicks(3); + } + + const uint16 *opcodes = 0; + switch (jewel - 1) { + case 0: + opcodes = specialJewelTable1; + break; + + case 1: + opcodes = specialJewelTable2; + break; + + case 2: + opcodes = specialJewelTable3; + break; + + case 3: + opcodes = specialJewelTable4; + break; + } + + if (opcodes) { + for (int i = 0; opcodes[i] != 0xFFFF; ++i) { + _screen->drawShape(page, _shapes[opcodes[i]], _amuletX2[jewel], _amuletY2[jewel], 0, 0); + _screen->updateScreen(); + delayWithTicks(3); + } + } + } + _screen->drawShape(page, _shapes[323+jewel], _amuletX2[jewel], _amuletY2[jewel], 0, 0); + _screen->updateScreen(); + _screen->showMouse(); + setGameFlag(0x55+jewel); +} + +void KyraEngine_LoK::seq_brandonHealing() { + debugC(9, kDebugLevelMain, "seq_brandonHealing()"); + if (!(_deathHandler & 8)) + return; + if (_currentCharacter->sceneId == 210) { + if (_beadStateVar == 4 || _beadStateVar == 6) + return; + } + _screen->hideMouse(); + checkAmuletAnimFlags(); + assert(_healingShapeTable); + setupShapes123(_healingShapeTable, 22, 0); + _animator->setBrandonAnimSeqSize(3, 48); + snd_playSoundEffect(0x53); + for (int i = 123; i <= 144; ++i) { + _currentCharacter->currentAnimFrame = i; + _animator->animRefreshNPC(0); + delayWithTicks(8); + } + for (int i = 125; i >= 123; --i) { + _currentCharacter->currentAnimFrame = i; + _animator->animRefreshNPC(0); + delayWithTicks(8); + } + _animator->resetBrandonAnimSeqSize(); + _currentCharacter->currentAnimFrame = 7; + _animator->animRefreshNPC(0); + freeShapes123(); + _screen->showMouse(); +} + +void KyraEngine_LoK::seq_brandonHealing2() { + debugC(9, kDebugLevelMain, "seq_brandonHealing2()"); + _screen->hideMouse(); + checkAmuletAnimFlags(); + assert(_healingShape2Table); + setupShapes123(_healingShape2Table, 30, 0); + resetBrandonPoisonFlags(); + _animator->setBrandonAnimSeqSize(3, 48); + snd_playSoundEffect(0x50); + for (int i = 123; i <= 152; ++i) { + _currentCharacter->currentAnimFrame = i; + _animator->animRefreshNPC(0); + delayWithTicks(8); + } + _animator->resetBrandonAnimSeqSize(); + _currentCharacter->currentAnimFrame = 7; + _animator->animRefreshNPC(0); + freeShapes123(); + _screen->showMouse(); + assert(_poisonGone); + characterSays(2010, _poisonGone[0], 0, -2); + characterSays(2011, _poisonGone[1], 0, -2); +} + +void KyraEngine_LoK::seq_poisonDeathNow(int now) { + debugC(9, kDebugLevelMain, "seq_poisonDeathNow(%d)", now); + if (!(_brandonStatusBit & 1)) + return; + ++_poisonDeathCounter; + if (now) + _poisonDeathCounter = 2; + if (_poisonDeathCounter >= 2) { + snd_playWanderScoreViaMap(1, 1); + assert(_thePoison); + characterSays(7000, _thePoison[0], 0, -2); + characterSays(7001, _thePoison[1], 0, -2); + seq_poisonDeathNowAnim(); + _deathHandler = 3; + } else { + assert(_thePoison); + characterSays(7002, _thePoison[2], 0, -2); + characterSays(7004, _thePoison[3], 0, -2); + } +} + +void KyraEngine_LoK::seq_poisonDeathNowAnim() { + debugC(9, kDebugLevelMain, "seq_poisonDeathNowAnim()"); + _screen->hideMouse(); + checkAmuletAnimFlags(); + assert(_posionDeathShapeTable); + setupShapes123(_posionDeathShapeTable, 20, 0); + _animator->setBrandonAnimSeqSize(8, 48); + + _currentCharacter->currentAnimFrame = 124; + _animator->animRefreshNPC(0); + delayWithTicks(30); + + _currentCharacter->currentAnimFrame = 123; + _animator->animRefreshNPC(0); + delayWithTicks(30); + + for (int i = 125; i <= 139; ++i) { + _currentCharacter->currentAnimFrame = i; + _animator->animRefreshNPC(0); + delayWithTicks(8); + } + + delayWithTicks(60); + + for (int i = 140; i <= 142; ++i) { + _currentCharacter->currentAnimFrame = i; + _animator->animRefreshNPC(0); + delayWithTicks(8); + } + + delayWithTicks(60); + + _animator->resetBrandonAnimSeqSize(); + freeShapes123(); + _animator->restoreAllObjectBackgrounds(); + _currentCharacter->x1 = _currentCharacter->x2 = -1; + _currentCharacter->y1 = _currentCharacter->y2 = -1; + _animator->preserveAllBackgrounds(); + _screen->showMouse(); +} + +void KyraEngine_LoK::seq_playFluteAnimation() { + debugC(9, kDebugLevelMain, "seq_playFluteAnimation()"); + _screen->hideMouse(); + checkAmuletAnimFlags(); + setupShapes123(_fluteAnimShapeTable, 36, 0); + _animator->setBrandonAnimSeqSize(3, 75); + for (int i = 123; i <= 130; ++i) { + _currentCharacter->currentAnimFrame = i; + _animator->animRefreshNPC(0); + delayWithTicks(2); + } + + int delayTime = 0, soundType = 0; + if (queryGameFlag(0x85)) { + snd_playSoundEffect(0x63); + delayTime = 9; + soundType = 3; + } else if (!queryGameFlag(0x86)) { + snd_playSoundEffect(0x61); + delayTime = 2; + soundType = 1; + setGameFlag(0x86); + } else { + snd_playSoundEffect(0x62); + delayTime = 2; + soundType = 2; + } + + for (int i = 131; i <= 158; ++i) { + _currentCharacter->currentAnimFrame = i; + _animator->animRefreshNPC(0); + delayWithTicks(delayTime); + } + + for (int i = 126; i >= 123; --i) { + _currentCharacter->currentAnimFrame = i; + _animator->animRefreshNPC(0); + delayWithTicks(delayTime); + } + _animator->resetBrandonAnimSeqSize(); + _currentCharacter->currentAnimFrame = 7; + _animator->animRefreshNPC(0); + freeShapes123(); + _screen->showMouse(); + + if (soundType == 1) { + assert(_fluteString); + characterSays(1000, _fluteString[0], 0, -2); + } else if (soundType == 2) { + assert(_fluteString); + characterSays(1001, _fluteString[1], 0, -2); + } +} + +void KyraEngine_LoK::seq_winterScroll1() { + debugC(9, kDebugLevelMain, "seq_winterScroll1()"); + _screen->hideMouse(); + checkAmuletAnimFlags(); + assert(_winterScrollTable); + assert(_winterScroll1Table); + assert(_winterScroll2Table); + setupShapes123(_winterScrollTable, 7, 0); + _animator->setBrandonAnimSeqSize(5, 66); + + for (int i = 123; i <= 129; ++i) { + _currentCharacter->currentAnimFrame = i; + _animator->animRefreshNPC(0); + delayWithTicks(8); + } + + freeShapes123(); + snd_playSoundEffect(0x20); + + uint8 numFrames, midpoint; + if (_flags.isTalkie) { + numFrames = 18; + midpoint = 136; + } else { + numFrames = 35; + midpoint = 147; + } + setupShapes123(_winterScroll1Table, numFrames, 0); + for (int i = 123; i < midpoint; ++i) { + _currentCharacter->currentAnimFrame = i; + _animator->animRefreshNPC(0); + delayWithTicks(8); + } + + if (_currentCharacter->sceneId == 41 && !queryGameFlag(0xA2)) { + snd_playSoundEffect(0x20); + _sprites->_anims[0].play = false; + _animator->sprites()[0].active = 0; + _sprites->_anims[1].play = true; + _animator->sprites()[1].active = 1; + setGameFlag(0xA2); + } + + for (int i = midpoint; i < 123 + numFrames; ++i) { + _currentCharacter->currentAnimFrame = i; + _animator->animRefreshNPC(0); + delayWithTicks(8); + } + + if (_currentCharacter->sceneId == 117 && !queryGameFlag(0xB3)) { + for (int i = 0; i <= 7; ++i) { + _sprites->_anims[i].play = false; + _animator->sprites()[i].active = 0; + } + uint8 tmpPal[768]; + memcpy(tmpPal, _screen->_currentPalette, 768); + memcpy(&tmpPal[684], palTable2()[0], 60); + _screen->fadePalette(tmpPal, 72); + memcpy(&_screen->_currentPalette[684], palTable2()[0], 60); + _screen->setScreenPalette(_screen->_currentPalette); + setGameFlag(0xB3); + } else { + delayWithTicks(120); + } + + freeShapes123(); + setupShapes123(_winterScroll2Table, 4, 0); + + for (int i = 123; i <= 126; ++i) { + _currentCharacter->currentAnimFrame = i; + _animator->animRefreshNPC(0); + delayWithTicks(8); + } + + _animator->resetBrandonAnimSeqSize(); + _currentCharacter->currentAnimFrame = 7; + _animator->animRefreshNPC(0); + freeShapes123(); + _screen->showMouse(); +} + +void KyraEngine_LoK::seq_winterScroll2() { + debugC(9, kDebugLevelMain, "seq_winterScroll2()"); + _screen->hideMouse(); + checkAmuletAnimFlags(); + assert(_winterScrollTable); + setupShapes123(_winterScrollTable, 7, 0); + _animator->setBrandonAnimSeqSize(5, 66); + + for (int i = 123; i <= 128; ++i) { + _currentCharacter->currentAnimFrame = i; + _animator->animRefreshNPC(0); + delayWithTicks(8); + } + + delayWithTicks(120); + + for (int i = 127; i >= 123; --i) { + _currentCharacter->currentAnimFrame = i; + _animator->animRefreshNPC(0); + delayWithTicks(8); + } + + _animator->resetBrandonAnimSeqSize(); + _currentCharacter->currentAnimFrame = 7; + _animator->animRefreshNPC(0); + freeShapes123(); + _screen->showMouse(); +} + +void KyraEngine_LoK::seq_makeBrandonInv() { + debugC(9, kDebugLevelMain, "seq_makeBrandonInv()"); + if (_deathHandler == 8) + return; + + if (_currentCharacter->sceneId == 210) { + if (_beadStateVar == 4 || _beadStateVar == 6) + return; + } + + _screen->hideMouse(); + checkAmuletAnimFlags(); + _brandonStatusBit |= 0x20; + _timer->setCountdown(18, 2700); + _brandonStatusBit |= 0x40; + snd_playSoundEffect(0x77); + _brandonInvFlag = 0; + while (_brandonInvFlag <= 0x100) { + _animator->animRefreshNPC(0); + delayWithTicks(10); + _brandonInvFlag += 0x10; + } + _brandonStatusBit &= 0xFFBF; + _screen->showMouse(); +} + +void KyraEngine_LoK::seq_makeBrandonNormal() { + debugC(9, kDebugLevelMain, "seq_makeBrandonNormal()"); + _screen->hideMouse(); + _brandonStatusBit |= 0x40; + snd_playSoundEffect(0x77); + _brandonInvFlag = 0x100; + while (_brandonInvFlag >= 0) { + _animator->animRefreshNPC(0); + delayWithTicks(10); + _brandonInvFlag -= 0x10; + } + _brandonInvFlag = 0; + _brandonStatusBit &= 0xFF9F; + _screen->showMouse(); +} + +void KyraEngine_LoK::seq_makeBrandonNormal2() { + debugC(9, kDebugLevelMain, "seq_makeBrandonNormal2()"); + _screen->hideMouse(); + assert(_brandonToWispTable); + setupShapes123(_brandonToWispTable, 26, 0); + _animator->setBrandonAnimSeqSize(5, 48); + _brandonStatusBit &= 0xFFFD; + snd_playSoundEffect(0x6C); + for (int i = 138; i >= 123; --i) { + _currentCharacter->currentAnimFrame = i; + _animator->animRefreshNPC(0); + delayWithTicks(8); + } + _animator->setBrandonAnimSeqSize(4, 48); + _currentCharacter->currentAnimFrame = 7; + _animator->animRefreshNPC(0); + + if (_currentCharacter->sceneId >= 229 && _currentCharacter->sceneId <= 245) + _screen->fadeSpecialPalette(31, 234, 13, 4); + else if (_currentCharacter->sceneId >= 118 && _currentCharacter->sceneId <= 186) + _screen->fadeSpecialPalette(14, 228, 15, 4); + + freeShapes123(); + _screen->showMouse(); +} + +void KyraEngine_LoK::seq_makeBrandonWisp() { + debugC(9, kDebugLevelMain, "seq_makeBrandonWisp()"); + if (_deathHandler == 8) + return; + + if (_currentCharacter->sceneId == 210) { + if (_beadStateVar == 4 || _beadStateVar == 6) + return; + } + _screen->hideMouse(); + checkAmuletAnimFlags(); + assert(_brandonToWispTable); + setupShapes123(_brandonToWispTable, 26, 0); + _animator->setBrandonAnimSeqSize(5, 48); + snd_playSoundEffect(0x6C); + for (int i = 123; i <= 138; ++i) { + _currentCharacter->currentAnimFrame = i; + _animator->animRefreshNPC(0); + delayWithTicks(8); + } + _brandonStatusBit |= 2; + + if (_currentCharacter->sceneId >= 109 && _currentCharacter->sceneId <= 198) + _timer->setCountdown(14, 18000); + else + _timer->setCountdown(14, 7200); + + _animator->_brandonDrawFrame = 113; + _brandonStatusBit0x02Flag = 1; + _currentCharacter->currentAnimFrame = 113; + _animator->animRefreshNPC(0); + _animator->updateAllObjectShapes(); + + if (_currentCharacter->sceneId >= 229 && _currentCharacter->sceneId <= 245) + _screen->fadeSpecialPalette(30, 234, 13, 4); + else if (_currentCharacter->sceneId >= 118 && _currentCharacter->sceneId <= 186) + _screen->fadeSpecialPalette(14, 228, 15, 4); + + freeShapes123(); + _screen->showMouse(); +} + +void KyraEngine_LoK::seq_dispelMagicAnimation() { + debugC(9, kDebugLevelMain, "seq_dispelMagicAnimation()"); + if (_deathHandler == 8) + return; + if (_currentCharacter->sceneId == 210) { + if (_beadStateVar == 4 || _beadStateVar == 6) + return; + } + _screen->hideMouse(); + if (_currentCharacter->sceneId == 210 && _currentCharacter->sceneId < 160) + _currentCharacter->facing = 3; + if (_malcolmFlag == 7 && _beadStateVar == 3) { + _beadStateVar = 6; + _unkEndSeqVar5 = 2; + _malcolmFlag = 10; + } + checkAmuletAnimFlags(); + setGameFlag(0xEE); + assert(_magicAnimationTable); + setupShapes123(_magicAnimationTable, 5, 0); + _animator->setBrandonAnimSeqSize(8, 49); + snd_playSoundEffect(0x15); + for (int i = 123; i <= 127; ++i) { + _currentCharacter->currentAnimFrame = i; + _animator->animRefreshNPC(0); + delayWithTicks(8); + } + + delayWithTicks(120); + + for (int i = 127; i >= 123; --i) { + _currentCharacter->currentAnimFrame = i; + _animator->animRefreshNPC(0); + delayWithTicks(10); + } + _animator->resetBrandonAnimSeqSize(); + _currentCharacter->currentAnimFrame = 7; + _animator->animRefreshNPC(0); + freeShapes123(); + _screen->showMouse(); +} + +void KyraEngine_LoK::seq_fillFlaskWithWater(int item, int type) { + debugC(9, kDebugLevelMain, "seq_fillFlaskWithWater(%d, %d)", item, type); + int newItem = -1; + static const uint8 flaskTable1[] = { 0x46, 0x48, 0x4A, 0x4C }; + static const uint8 flaskTable2[] = { 0x47, 0x49, 0x4B, 0x4D }; + + if (item >= 60 && item <= 77) { + assert(_flaskFull); + characterSays(8006, _flaskFull[0], 0, -2); + } else if (item == 78) { + assert(type >= 0 && type < ARRAYSIZE(flaskTable1)); + newItem = flaskTable1[type]; + } else if (item == 79) { + assert(type >= 0 && type < ARRAYSIZE(flaskTable2)); + newItem = flaskTable2[type]; + } + + if (newItem == -1) + return; + + _screen->hideMouse(); + setMouseItem(newItem); + _screen->showMouse(); + _itemInHand = newItem; + assert(_fullFlask); + assert(type < _fullFlask_Size && type >= 0); + static const uint16 voiceEntries[] = { + 0x1F40, 0x1F41, 0x1F42, 0x1F45 + }; + assert(type < ARRAYSIZE(voiceEntries)); + characterSays(voiceEntries[type], _fullFlask[type], 0, -2); +} + +void KyraEngine_LoK::seq_playDrinkPotionAnim(int item, int unk2, int flags) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::seq_playDrinkPotionAnim(%d, %d, %d)", item, unk2, flags); + uint8 red, green, blue; + + switch (item) { + case 60: + case 61: + red = 63; + green = blue = 6; + break; + case 62: + case 63: + red = green = 0; + blue = 67; + break; + case 64: + case 65: + red = 84; + green = 78; + blue = 14; + break; + case 66: + red = blue = 0; + green = 48; + break; + case 67: + red = 100; + green = 48; + blue = 23; + break; + case 68: + red = 73; + green = 0; + blue = 89; + break; + case 69: + red = green = 73; + blue = 86; + break; + default: + red = 33; + green = 66; + blue = 100; + break; + } + red = (uint8)((double)red * 0.63); + green = (uint8)((double)green * 0.63); + blue = (uint8)((double)blue * 0.63); + + _screen->setPaletteIndex(0xFE, red, green, blue); + + _screen->hideMouse(); + checkAmuletAnimFlags(); + _currentCharacter->facing = 5; + _animator->animRefreshNPC(0); + assert(_drinkAnimationTable); + setupShapes123(_drinkAnimationTable, 9, flags); + _animator->setBrandonAnimSeqSize(5, 54); + + for (int i = 123; i <= 131; ++i) { + _currentCharacter->currentAnimFrame = i; + _animator->animRefreshNPC(0); + delayWithTicks(5); + } + snd_playSoundEffect(0x34); + for (int i = 0; i < 2; ++i) { + _currentCharacter->currentAnimFrame = 130; + _animator->animRefreshNPC(0); + delayWithTicks(7); + _currentCharacter->currentAnimFrame = 131; + _animator->animRefreshNPC(0); + delayWithTicks(7); + } + + if (unk2) { + // XXX + } + + for (int i = 131; i >= 123; --i) { + _currentCharacter->currentAnimFrame = i; + _animator->animRefreshNPC(0); + delayWithTicks(5); + } + + _animator->resetBrandonAnimSeqSize(); + _currentCharacter->currentAnimFrame = 7; + _animator->animRefreshNPC(0); + freeShapes123(); + _screen->setPaletteIndex(0xFE, 30, 30, 30); + _screen->showMouse(); +} + +int KyraEngine_LoK::seq_playEnd() { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::seq_playEnd()"); + if (_endSequenceSkipFlag) + return 0; + + if (_deathHandler == 8) + return 0; + + _screen->_curPage = 2; + if (_endSequenceNeedLoading) { + snd_playWanderScoreViaMap(50, 1); + setupPanPages(); + _finalA = new WSAMovie_v1(this); + assert(_finalA); + _finalA->open("finala.wsa", 1, 0); + _finalB = new WSAMovie_v1(this); + assert(_finalB); + _finalB->open("finalb.wsa", 1, 0); + _finalC = new WSAMovie_v1(this); + assert(_finalC); + _endSequenceNeedLoading = 0; + _finalC->open("finalc.wsa", 1, 0); + _screen->_curPage = 0; + _beadStateVar = 0; + _malcolmFlag = 0; + _unkEndSeqVar2 = _system->getMillis() + 600 * _tickLength; + _screen->copyRegion(312, 0, 312, 0, 8, 136, 0, 2); + } + + // TODO: better handling. This timer shouldn't count when the menu is open or something. + if (_unkEndSeqVar2 != -1) { + if (_system->getMillis() > (uint32)_unkEndSeqVar2) { + _unkEndSeqVar2 = -1; + if (!_malcolmFlag) + _malcolmFlag = 1; + } + } + + if (handleMalcolmFlag()) { + _beadStateVar = 0; + _malcolmFlag = 12; + handleMalcolmFlag(); + handleBeadState(); + closeFinalWsa(); + if (_deathHandler == 8) { + _screen->_curPage = 0; + checkAmuletAnimFlags(); + seq_brandonToStone(); + delay(60 * _tickLength); + return 1; + } else { + _endSequenceSkipFlag = 1; + if (_text->printed()) + _text->restoreTalkTextMessageBkgd(2, 0); + _screen->_curPage = 0; + _screen->hideMouse(); + _screen->fadeSpecialPalette(32, 228, 20, 60); + delay(60 * _tickLength); + _screen->loadBitmap("GEMHEAL.CPS", 3, 3, _screen->_currentPalette); + _screen->setScreenPalette(_screen->_currentPalette); + _screen->shuffleScreen(8, 8, 304, 128, 2, 0, 1, 0); + uint32 nextTime = _system->getMillis() + 120 * _tickLength; + _finalA = new WSAMovie_v1(this); + assert(_finalA); + _finalA->open("finald.wsa", 1, 0); + _finalA->setX(8); _finalA->setY(8); + _finalA->setDrawPage(0); + delayUntil(nextTime); + snd_playSoundEffect(0x40); + for (int i = 0; i < 22; ++i) { + delayUntil(nextTime); + if (i == 4) + snd_playSoundEffect(0x3E); + else if (i == 20) + snd_playSoundEffect(0x0E); + nextTime = _system->getMillis() + 8 * _tickLength; + _finalA->displayFrame(i); + _screen->updateScreen(); + } + delete _finalA; + _finalA = 0; + seq_playEnding(); + return 1; + } + } else { + handleBeadState(); + _screen->bitBlitRects(); + _screen->updateScreen(); + _screen->_curPage = 0; + } + return 0; +} + +void KyraEngine_LoK::seq_brandonToStone() { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::seq_brandonToStone()"); + _screen->hideMouse(); + assert(_brandonStoneTable); + setupShapes123(_brandonStoneTable, 14, 0); + _animator->setBrandonAnimSeqSize(5, 51); + for (int i = 123; i <= 136; ++i) { + _currentCharacter->currentAnimFrame = i; + _animator->animRefreshNPC(0); + delayWithTicks(8); + } + _animator->resetBrandonAnimSeqSize(); + freeShapes123(); + _screen->showMouse(); +} + +void KyraEngine_LoK::seq_playEnding() { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::seq_playEnding()"); + if (_quitFlag) + return; + _screen->hideMouse(); + _screen->_curPage = 0; + _screen->fadeToBlack(); + _screen->loadBitmap("REUNION.CPS", 3, 3, _screen->_currentPalette); + _screen->copyRegion(8, 8, 8, 8, 304, 128, 2, 0); + _screen->_curPage = 0; + // XXX + assert(_homeString); + drawSentenceCommand(_homeString[0], 179); + + memset(_screen->getPalette(2), 0, sizeof(uint8)*768); + _screen->setScreenPalette(_screen->getPalette(2)); + + _seq->playSequence(_seq_Reunion, false); + _screen->fadeToBlack(); + + _screen->showMouse(); + seq_playCredits(); +} + +void KyraEngine_LoK::seq_playCredits() { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::seq_playCredits()"); + static const uint8 colorMap[] = { 0, 0, 0xC, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + static const char stringTerms[] = { 0x5, 0xd, 0x0}; + static const int numStrings = 250; + + struct { + int16 x, y; + uint8 code; + uint8 unk1; + Screen::FontId font; + uint8 *str; + } strings[numStrings]; + + memset(strings, 0, sizeof(strings)); + + _screen->hideMouse(); + if (!_flags.isTalkie) { + _screen->loadFont(Screen::FID_CRED6_FNT, "CREDIT6.FNT"); + _screen->loadFont(Screen::FID_CRED8_FNT, "CREDIT8.FNT"); + } else + _screen->setFont(Screen::FID_8_FNT); + + _screen->loadBitmap("CHALET.CPS", 4, 4, _screen->_currentPalette); + + _screen->setCurPage(0); + _screen->clearCurPage(); + _screen->setTextColorMap(colorMap); + _screen->_charWidth = -1; + + // we only need this for the fm-towns version + if (_flags.platform == Common::kPlatformFMTowns || _flags.platform == Common::kPlatformPC98) + snd_playWanderScoreViaMap(53, 1); + + uint8 *buffer = 0; + uint32 size = 0; + + if (_flags.platform == Common::kPlatformFMTowns || _flags.platform == Common::kPlatformPC98) { + int sizeTmp = 0; + const uint8 *bufferTmp = _staticres->loadRawData(kCreditsStrings, sizeTmp); + buffer = new uint8[sizeTmp]; + assert(buffer); + memcpy(buffer, bufferTmp, sizeTmp); + size = sizeTmp; + _staticres->unloadId(kCreditsStrings); + } else { + buffer = _res->fileData("CREDITS.TXT", &size); + assert(buffer); + } + + uint8 *nextString = buffer; + uint8 *currentString = buffer; + int currentY = 200; + + for (int i = 0; i < numStrings; i++) { + if (*nextString == 0) + break; + + currentString = nextString; + nextString = (uint8 *)strpbrk((const char *)currentString, stringTerms); + if (!nextString) + nextString = (uint8 *)strchr((const char *)currentString, 0); + + strings[i].code = nextString[0]; + *nextString = 0; + if (strings[i].code != 0) + nextString++; + + if (*currentString == 3 || *currentString == 4) { + strings[i].unk1 = *currentString; + currentString++; + } + + if (*currentString == 1) { + currentString++; + if (!_flags.isTalkie) + _screen->setFont(Screen::FID_CRED6_FNT); + } else { + if (*currentString == 2) + currentString++; + if (!_flags.isTalkie) + _screen->setFont(Screen::FID_CRED8_FNT); + } + strings[i].font = _screen->_currentFont; + + if (strings[i].unk1 == 3) + strings[i].x = 157 - _screen->getTextWidth((const char *)currentString); + else if (strings[i].unk1 == 4) + strings[i].x = 161; + else + strings[i].x = (320 - _screen->getTextWidth((const char *)currentString)) / 2 + 1; + + strings[i].y = currentY; + if (strings[i].code != 5) + currentY += 10; + + strings[i].str = currentString; + } + + _screen->setCurPage(2); + + memset(_screen->getPalette(2), 0, sizeof(uint8)*768); + _screen->setScreenPalette(_screen->getPalette(2)); + _screen->copyRegion(8, 32, 8, 32, 312, 128, 4, 0, Screen::CR_NO_P_CHECK); + _screen->fadePalette(_screen->_currentPalette, 0x5A); + + Common::Event event; + bool finished = false; + int bottom = 201; + while (!finished) { + uint32 startLoop = _system->getMillis(); + if (bottom > 175) { + _screen->copyRegion(8, 32, 8, 32, 312, 128, 4, 2, Screen::CR_NO_P_CHECK); + bottom = 0; + + for (int i = 0; i < numStrings; i++) { + if (strings[i].y < 200 && strings[i].y > 0) { + if (strings[i].font != _screen->_currentFont) + _screen->setFont(strings[i].font); + _screen->printText((const char *)strings[i].str, strings[i].x, strings[i].y, 15, 0); + } + strings[i].y--; + if (strings[i].y > bottom) + bottom = strings[i].y; + } + _screen->copyRegion(8, 32, 8, 32, 312, 128, 2, 0, Screen::CR_NO_P_CHECK); + _screen->updateScreen(); + } + + while (_eventMan->pollEvent(event)) { + switch (event.type) { + case Common::EVENT_KEYDOWN: + finished = true; + break; + case Common::EVENT_QUIT: + quitGame(); + finished = true; + break; + default: + break; + } + } + + uint32 now = _system->getMillis(); + uint32 nextLoop = startLoop + _tickLength * 5; + + if (nextLoop > now) + _system->delayMillis(nextLoop - now); + } + + delete[] buffer; + + _screen->fadeToBlack(); + _screen->clearCurPage(); + _screen->showMouse(); +} + +bool KyraEngine_LoK::seq_skipSequence() const { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::seq_skipSequence()"); + return _quitFlag || _abortIntroFlag; +} + +int KyraEngine_LoK::handleMalcolmFlag() { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::handleMalcolmFlag()"); + static uint16 frame = 0; + static uint32 timer1 = 0; + static uint32 timer2 = 0; + + switch (_malcolmFlag) { + case 1: + frame = 0; + _malcolmFlag = 2; + timer2 = 0; + + // Fall through to the next case + + case 2: + if (_system->getMillis() >= timer2) { + _finalA->setX(8); + _finalA->setY(46); + _finalA->setDrawPage(0); + _finalA->displayFrame(frame); + _screen->updateScreen(); + timer2 = _system->getMillis() + 8 * _tickLength; + ++frame; + if (frame > 13) { + _malcolmFlag = 3; + timer1 = _system->getMillis() + 180 * _tickLength; + } + } + break; + + case 3: + if (_system->getMillis() < timer1) { + if (_system->getMillis() >= timer2) { + frame = _rnd.getRandomNumberRng(14, 17); + _finalA->setX(8); + _finalA->setY(46); + _finalA->setDrawPage(0); + _finalA->displayFrame(frame); + _screen->updateScreen(); + timer2 = _system->getMillis() + 8 * _tickLength; + } + } else { + _malcolmFlag = 4; + frame = 18; + } + break; + + case 4: + if (_system->getMillis() >= timer2) { + _finalA->setX(8); + _finalA->setY(46); + _finalA->setDrawPage(0); + _finalA->displayFrame(frame); + _screen->updateScreen(); + timer2 = _system->getMillis() + 8 * _tickLength; + ++frame; + if (frame > 25) { + frame = 26; + _malcolmFlag = 5; + _beadStateVar = 1; + } + } + break; + + case 5: + if (_system->getMillis() >= timer2) { + _finalA->setX(8); + _finalA->setY(46); + _finalA->setDrawPage(0); + _finalA->displayFrame(frame); + _screen->updateScreen(); + timer2 = _system->getMillis() + 8 * _tickLength; + ++frame; + if (frame > 31) { + frame = 32; + _malcolmFlag = 6; + } + } + break; + + case 6: + if (_unkEndSeqVar4) { + if (frame <= 33 && _system->getMillis() >= timer2) { + _finalA->setX(8); + _finalA->setY(46); + _finalA->setDrawPage(0); + _finalA->displayFrame(frame); + _screen->updateScreen(); + timer2 = _system->getMillis() + 8 * _tickLength; + ++frame; + if (frame > 33) { + _malcolmFlag = 7; + frame = 32; + _unkEndSeqVar5 = 0; + } + } + } + break; + + case 7: + if (_unkEndSeqVar5 == 1) { + _malcolmFlag = 8; + frame = 34; + } else if (_unkEndSeqVar5 == 2) { + _malcolmFlag = 3; + timer1 = _system->getMillis() + 180 * _tickLength; + } + break; + + case 8: + if (_system->getMillis() >= timer2) { + _finalA->setX(8); + _finalA->setY(46); + _finalA->setDrawPage(0); + _finalA->displayFrame(frame); + _screen->updateScreen(); + timer2 = _system->getMillis() + 8 * _tickLength; + ++frame; + if (frame > 37) { + _malcolmFlag = 0; + _deathHandler = 8; + return 1; + } + } + break; + + case 9: + snd_playSoundEffect(12); + snd_playSoundEffect(12); + _finalC->setX(16); + _finalC->setY(50); + _finalC->setDrawPage(0); + for (int i = 0; i < 18; ++i) { + timer2 = _system->getMillis() + 4 * _tickLength; + _finalC->displayFrame(i); + _screen->updateScreen(); + delayUntil(timer2); + } + snd_playWanderScoreViaMap(51, 1); + delay(60 * _tickLength); + _malcolmFlag = 0; + return 1; + + case 10: + if (!_beadStateVar) { + handleBeadState(); + _screen->bitBlitRects(); + assert(_veryClever); + _text->printTalkTextMessage(_veryClever[0], 60, 31, 5, 0, 2); + timer2 = _system->getMillis() + 180 * _tickLength; + _malcolmFlag = 11; + } + break; + + case 11: + if (_system->getMillis() >= timer2) { + _text->restoreTalkTextMessageBkgd(2, 0); + _malcolmFlag = 3; + timer1 = _system->getMillis() + 180 * _tickLength; + } + break; + + default: + break; + } + + return 0; +} + +int KyraEngine_LoK::handleBeadState() { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::handleBeadState()"); + static uint32 timer1 = 0; + static uint32 timer2 = 0; + static BeadState beadState1 = { -1, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + static BeadState beadState2 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + + static const int table1[] = { + -1, -2, -4, -5, -6, -7, -6, -5, + -4, -2, -1, 0, 1, 2, 4, 5, + 6, 7, 6, 5, 4, 2, 1, 0, 0 + }; + static const int table2[] = { + 0, 0, 1, 1, 2, 2, 3, 3, + 4, 4, 5, 5, 5, 5, 4, 4, + 3, 3, 2, 2, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + + switch (_beadStateVar) { + case 0: + if (beadState1.x != -1 && _endSequenceBackUpRect) { + _screen->copyFromCurPageBlock(beadState1.x >> 3, beadState1.y, beadState1.width, beadState1.height, _endSequenceBackUpRect); + _screen->addBitBlitRect(beadState1.x, beadState1.y, beadState1.width2, beadState1.height); + } + + beadState1.x = -1; + beadState1.tableIndex = 0; + timer1 = 0; + timer2 = 0; + _lastDisplayedPanPage = 0; + return 1; + + case 1: + if (beadState1.x != -1) { + if (_endSequenceBackUpRect) { + _screen->copyFromCurPageBlock(beadState1.x >> 3, beadState1.y, beadState1.width, beadState1.height, _endSequenceBackUpRect); + _screen->addBitBlitRect(beadState1.x, beadState1.y, beadState1.width2, beadState1.height); + } + beadState1.x = -1; + beadState1.tableIndex = 0; + } + _beadStateVar = 2; + break; + + case 2: + if (_system->getMillis() >= timer1) { + int x = 0, y = 0; + timer1 = _system->getMillis() + 4 * _tickLength; + if (beadState1.x == -1) { + assert(_panPagesTable); + beadState1.width2 = _animator->fetchAnimWidth(_panPagesTable[19], 256); + beadState1.width = ((beadState1.width2 + 7) >> 3) + 1; + beadState1.height = _animator->fetchAnimHeight(_panPagesTable[19], 256); + if (!_endSequenceBackUpRect) { + _endSequenceBackUpRect = new uint8[(beadState1.width * beadState1.height) << 3]; + assert(_endSequenceBackUpRect); + memset(_endSequenceBackUpRect, 0, ((beadState1.width * beadState1.height) << 3) * sizeof(uint8)); + } + x = beadState1.x = 60; + y = beadState1.y = 40; + initBeadState(x, y, x, 25, 8, &beadState2); + } else { + if (processBead(beadState1.x, beadState1.y, x, y, &beadState2)) { + _beadStateVar = 3; + timer2 = _system->getMillis() + 240 * _tickLength; + _unkEndSeqVar4 = 0; + beadState1.dstX = beadState1.x; + beadState1.dstY = beadState1.y; + return 0; + } else { + _screen->copyFromCurPageBlock(beadState1.x >> 3, beadState1.y, beadState1.width, beadState1.height, _endSequenceBackUpRect); + _screen->addBitBlitRect(beadState1.x, beadState1.y, beadState1.width2, beadState1.height); + beadState1.x = x; + beadState1.y = y; + } + } + + _screen->copyCurPageBlock(x >> 3, y, beadState1.width, beadState1.height, _endSequenceBackUpRect); + _screen->drawShape(2, _panPagesTable[_lastDisplayedPanPage++], x, y, 0, 0); + + if (_lastDisplayedPanPage > 17) + _lastDisplayedPanPage = 0; + + _screen->addBitBlitRect(x, y, beadState1.width2, beadState1.height); + } + break; + + case 3: + if (_system->getMillis() >= timer1) { + timer1 = _system->getMillis() + 4 * _tickLength; + _screen->copyFromCurPageBlock(beadState1.x >> 3, beadState1.y, beadState1.width, beadState1.height, _endSequenceBackUpRect); + _screen->addBitBlitRect(beadState1.x, beadState1.y, beadState1.width2, beadState1.height); + + beadState1.x = beadState1.dstX + table1[beadState1.tableIndex]; + beadState1.y = beadState1.dstY + table2[beadState1.tableIndex]; + _screen->copyCurPageBlock(beadState1.x >> 3, beadState1.y, beadState1.width, beadState1.height, _endSequenceBackUpRect); + + _screen->drawShape(2, _panPagesTable[_lastDisplayedPanPage++], beadState1.x, beadState1.y, 0, 0); + if (_lastDisplayedPanPage >= 17) + _lastDisplayedPanPage = 0; + + _screen->addBitBlitRect(beadState1.x, beadState1.y, beadState1.width2, beadState1.height); + + ++beadState1.tableIndex; + if (beadState1.tableIndex > 24) + beadState1.tableIndex = 0; + _unkEndSeqVar4 = 1; + if (_system->getMillis() > timer2 && _malcolmFlag == 7 && !_unkAmuletVar && !_text->printed()) { + snd_playSoundEffect(0x0B); + if (_currentCharacter->x1 > 233 && _currentCharacter->x1 < 305 && _currentCharacter->y1 > 85 && _currentCharacter->y1 < 105 && + (_brandonStatusBit & 0x20)) { + beadState1.unk8 = 290; + beadState1.unk9 = 40; + _beadStateVar = 5; + } else { + _beadStateVar = 4; + beadState1.unk8 = _currentCharacter->x1 - 4; + beadState1.unk9 = _currentCharacter->y1 - 30; + } + + if (_text->printed()) + _text->restoreTalkTextMessageBkgd(2, 0); + + initBeadState(beadState1.x, beadState1.y, beadState1.unk8, beadState1.unk9, 12, &beadState2); + _lastDisplayedPanPage = 18; + } + } + break; + + case 4: + if (_system->getMillis() >= timer1) { + int x = 0, y = 0; + timer1 = _system->getMillis() + _tickLength; + if (processBead(beadState1.x, beadState1.y, x, y, &beadState2)) { + if (_brandonStatusBit & 20) { + _unkEndSeqVar5 = 2; + _beadStateVar = 6; + } else { + snd_playWanderScoreViaMap(52, 1); + snd_playSoundEffect(0x0C); + _unkEndSeqVar5 = 1; + _beadStateVar = 0; + } + } else { + _screen->copyFromCurPageBlock(beadState1.x >> 3, beadState1.y, beadState1.width, beadState1.height, _endSequenceBackUpRect); + _screen->addBitBlitRect(beadState1.x, beadState1.y, beadState1.width2, beadState1.height); + beadState1.x = x; + beadState1.y = y; + _screen->copyCurPageBlock(beadState1.x >> 3, beadState1.y, beadState1.width, beadState1.height, _endSequenceBackUpRect); + _screen->drawShape(2, _panPagesTable[_lastDisplayedPanPage++], x, y, 0, 0); + if (_lastDisplayedPanPage > 17) { + _lastDisplayedPanPage = 0; + } + _screen->addBitBlitRect(beadState1.x, beadState1.y, beadState1.width2, beadState1.height); + } + } + break; + + case 5: + if (_system->getMillis() >= timer1) { + timer1 = _system->getMillis() + _tickLength; + int x = 0, y = 0; + if (processBead(beadState1.x, beadState1.y, x, y, &beadState2)) { + if (beadState2.dstX == 290) { + _screen->copyFromCurPageBlock(beadState1.x >> 3, beadState1.y, beadState1.width, beadState1.height, _endSequenceBackUpRect); + uint32 nextRun = 0; + _finalB->setX(224); + _finalB->setY(8); + _finalB->setDrawPage(0); + for (int i = 0; i < 8; ++i) { + nextRun = _system->getMillis() + _tickLength; + _finalB->displayFrame(i); + _screen->updateScreen(); + delayUntil(nextRun); + } + snd_playSoundEffect(0x0D); + for (int i = 7; i >= 0; --i) { + nextRun = _system->getMillis() + _tickLength; + _finalB->displayFrame(i); + _screen->updateScreen(); + delayUntil(nextRun); + } + initBeadState(beadState1.x, beadState1.y, 63, 60, 12, &beadState2); + } else { + _screen->copyFromCurPageBlock(beadState1.x >> 3, beadState1.y, beadState1.width, beadState1.height, _endSequenceBackUpRect); + _screen->addBitBlitRect(beadState1.x, beadState1.y, beadState1.width2, beadState1.height); + beadState1.x = -1; + beadState1.tableIndex = 0; + _beadStateVar = 0; + _malcolmFlag = 9; + } + } else { + _screen->copyFromCurPageBlock(beadState1.x >> 3, beadState1.y, beadState1.width, beadState1.height, _endSequenceBackUpRect); + _screen->addBitBlitRect(beadState1.x, beadState1.y, beadState1.width2, beadState1.height); + beadState1.x = x; + beadState1.y = y; + _screen->copyCurPageBlock(beadState1.x >> 3, beadState1.y, beadState1.width, beadState1.height, _endSequenceBackUpRect); + _screen->drawShape(2, _panPagesTable[_lastDisplayedPanPage++], x, y, 0, 0); + if (_lastDisplayedPanPage > 17) + _lastDisplayedPanPage = 0; + _screen->addBitBlitRect(beadState1.x, beadState1.y, beadState1.width2, beadState1.height); + } + } + break; + + case 6: + _screen->drawShape(2, _panPagesTable[19], beadState1.x, beadState1.y, 0, 0); + _screen->addBitBlitRect(beadState1.x, beadState1.y, beadState1.width2, beadState1.height); + _beadStateVar = 0; + break; + + default: + break; + } + return 0; +} + +void KyraEngine_LoK::initBeadState(int x, int y, int x2, int y2, int unk, BeadState *ptr) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::initBeadState(%d, %d, %d, %d, %d, %p)", x, y, x2, y2, unk, (const void *)ptr); + ptr->unk9 = unk; + int xDiff = x2 - x; + int yDiff = y2 - y; + int unk1 = 0, unk2 = 0; + if (xDiff > 0) + unk1 = 1; + else if (xDiff == 0) + unk1 = 0; + else + unk1 = -1; + + + if (yDiff > 0) + unk2 = 1; + else if (yDiff == 0) + unk2 = 0; + else + unk2 = -1; + + xDiff = ABS(xDiff); + yDiff = ABS(yDiff); + + ptr->y = 0; + ptr->x = 0; + ptr->width = xDiff; + ptr->height = yDiff; + ptr->dstX = x2; + ptr->dstY = y2; + ptr->width2 = unk1; + ptr->unk8 = unk2; +} + +int KyraEngine_LoK::processBead(int x, int y, int &x2, int &y2, BeadState *ptr) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::processBead(%d, %d, %p, %p, %p)", x, y, (const void *)&x2, (const void *)&y2, (const void *)ptr); + if (x == ptr->dstX && y == ptr->dstY) + return 1; + + int xPos = x, yPos = y; + if (ptr->width >= ptr->height) { + for (int i = 0; i < ptr->unk9; ++i) { + ptr->y += ptr->height; + if (ptr->y >= ptr->width) { + ptr->y -= ptr->width; + yPos += ptr->unk8; + } + xPos += ptr->width2; + } + } else { + for (int i = 0; i < ptr->unk9; ++i) { + ptr->x += ptr->width; + if (ptr->x >= ptr->height) { + ptr->x -= ptr->height; + xPos += ptr->width2; + } + yPos += ptr->unk8; + } + } + + int temp = ABS(x - ptr->dstX); + if (ptr->unk9 > temp) + xPos = ptr->dstX; + temp = ABS(y - ptr->dstY); + if (ptr->unk9 > temp) + yPos = ptr->dstY; + x2 = xPos; + y2 = yPos; + return 0; +} + +void KyraEngine_LoK::setupPanPages() { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::setupPanPages()"); + _screen->savePageToDisk("BKGD.PG", 2); + _screen->loadBitmap("BEAD.CPS", 3, 3, 0); + if (_flags.platform == Common::kPlatformMacintosh || _flags.platform == Common::kPlatformAmiga) { + int pageBackUp = _screen->_curPage; + _screen->_curPage = 2; + + delete[] _panPagesTable[19]; + _panPagesTable[19] = _screen->encodeShape(0, 0, 16, 9, 0); + assert(_panPagesTable[19]); + + int curX = 16; + for (int i = 0; i < 19; ++i) { + delete[] _panPagesTable[i]; + _panPagesTable[i] = _screen->encodeShape(curX, 0, 8, 5, 0); + assert(_panPagesTable[i]); + curX += 8; + } + + _screen->_curPage = pageBackUp; + } else { + for (int i = 0; i <= 19; ++i) { + delete[] _panPagesTable[i]; + _panPagesTable[i] = _seq->setPanPages(3, i); + assert(_panPagesTable[i]); + } + } + _screen->loadPageFromDisk("BKGD.PG", 2); +} + +void KyraEngine_LoK::freePanPages() { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::freePanPages()"); + delete _endSequenceBackUpRect; + _endSequenceBackUpRect = 0; + for (int i = 0; i <= 19; ++i) { + delete[] _panPagesTable[i]; + _panPagesTable[i] = 0; + } +} + +void KyraEngine_LoK::closeFinalWsa() { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::closeFinalWsa()"); + delete _finalA; + _finalA = 0; + delete _finalB; + _finalB = 0; + delete _finalC; + _finalC = 0; + freePanPages(); + _endSequenceNeedLoading = 1; +} + +void KyraEngine_LoK::updateKyragemFading() { + static const uint8 kyraGemPalette[0x28] = { + 0x3F, 0x3B, 0x38, 0x34, 0x32, 0x2F, 0x2C, 0x29, 0x25, 0x22, + 0x1F, 0x1C, 0x19, 0x16, 0x12, 0x0F, 0x0C, 0x0A, 0x06, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + if (_system->getMillis() < _kyragemFadingState.timerCount) + return; + + _kyragemFadingState.timerCount = _system->getMillis() + 4 * _tickLength; + int palPos = 684; + for (int i = 0; i < 20; ++i) { + _screen->_currentPalette[palPos++] = kyraGemPalette[i + _kyragemFadingState.rOffset]; + _screen->_currentPalette[palPos++] = kyraGemPalette[i + _kyragemFadingState.gOffset]; + _screen->_currentPalette[palPos++] = kyraGemPalette[i + _kyragemFadingState.bOffset]; + } + _screen->setScreenPalette(_screen->_currentPalette); + _animator->_updateScreen = true; + switch (_kyragemFadingState.nextOperation) { + case 0: + --_kyragemFadingState.bOffset; + if (_kyragemFadingState.bOffset >= 1) + return; + _kyragemFadingState.nextOperation = 1; + break; + + case 1: + ++_kyragemFadingState.rOffset; + if (_kyragemFadingState.rOffset < 19) + return; + _kyragemFadingState.nextOperation = 2; + break; + + case 2: + --_kyragemFadingState.gOffset; + if (_kyragemFadingState.gOffset >= 1) + return; + _kyragemFadingState.nextOperation = 3; + break; + + case 3: + ++_kyragemFadingState.bOffset; + if (_kyragemFadingState.bOffset < 19) + return; + _kyragemFadingState.nextOperation = 4; + break; + + case 4: + --_kyragemFadingState.rOffset; + if (_kyragemFadingState.rOffset >= 1) + return; + _kyragemFadingState.nextOperation = 5; + break; + + case 5: + ++_kyragemFadingState.gOffset; + if (_kyragemFadingState.gOffset < 19) + return; + _kyragemFadingState.nextOperation = 0; + break; + + default: + break; + } + + _kyragemFadingState.timerCount = _system->getMillis() + 120 * _tickLength; +} + +void KyraEngine_LoK::drawJewelPress(int jewel, int drawSpecial) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::drawJewelPress(%d, %d)", jewel, drawSpecial); + _screen->hideMouse(); + int shape = 0; + + if (drawSpecial) + shape = 0x14E; + else + shape = jewel + 0x149; + + snd_playSoundEffect(0x45); + _screen->drawShape(0, _shapes[shape], _amuletX2[jewel], _amuletY2[jewel], 0, 0); + _screen->updateScreen(); + delayWithTicks(2); + + if (drawSpecial) + shape = 0x148; + else + shape = jewel + 0x143; + + _screen->drawShape(0, _shapes[shape], _amuletX2[jewel], _amuletY2[jewel], 0, 0); + _screen->updateScreen(); + _screen->showMouse(); +} + +void KyraEngine_LoK::drawJewelsFadeOutStart() { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::drawJewelsFadeOutStart()"); + static const uint16 jewelTable1[] = { 0x164, 0x15F, 0x15A, 0x155, 0x150, 0xFFFF }; + static const uint16 jewelTable2[] = { 0x163, 0x15E, 0x159, 0x154, 0x14F, 0xFFFF }; + static const uint16 jewelTable3[] = { 0x166, 0x160, 0x15C, 0x157, 0x152, 0xFFFF }; + static const uint16 jewelTable4[] = { 0x165, 0x161, 0x15B, 0x156, 0x151, 0xFFFF }; + for (int i = 0; jewelTable1[i] != 0xFFFF; ++i) { + if (queryGameFlag(0x57)) + _screen->drawShape(0, _shapes[jewelTable1[i]], _amuletX2[2], _amuletY2[2], 0, 0); + if (queryGameFlag(0x59)) + _screen->drawShape(0, _shapes[jewelTable3[i]], _amuletX2[4], _amuletY2[4], 0, 0); + if (queryGameFlag(0x56)) + _screen->drawShape(0, _shapes[jewelTable2[i]], _amuletX2[1], _amuletY2[1], 0, 0); + if (queryGameFlag(0x58)) + _screen->drawShape(0, _shapes[jewelTable4[i]], _amuletX2[3], _amuletY2[3], 0, 0); + _screen->updateScreen(); + delayWithTicks(3); + } +} + +void KyraEngine_LoK::drawJewelsFadeOutEnd(int jewel) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::drawJewelsFadeOutEnd(%d)", jewel); + static const uint16 jewelTable[] = { 0x153, 0x158, 0x15D, 0x162, 0x148, 0xFFFF }; + int newDelay = 0; + + switch (jewel - 1) { + case 2: + if (_currentCharacter->sceneId >= 109 && _currentCharacter->sceneId <= 198) + newDelay = 18900; + else + newDelay = 8100; + break; + + default: + newDelay = 3600; + break; + } + + setGameFlag(0xF1); + _timer->setCountdown(19, newDelay); + _screen->hideMouse(); + for (int i = 0; jewelTable[i] != 0xFFFF; ++i) { + uint16 shape = jewelTable[i]; + if (queryGameFlag(0x57)) + _screen->drawShape(0, _shapes[shape], _amuletX2[2], _amuletY2[2], 0, 0); + if (queryGameFlag(0x59)) + _screen->drawShape(0, _shapes[shape], _amuletX2[4], _amuletY2[4], 0, 0); + if (queryGameFlag(0x56)) + _screen->drawShape(0, _shapes[shape], _amuletX2[1], _amuletY2[1], 0, 0); + if (queryGameFlag(0x58)) + _screen->drawShape(0, _shapes[shape], _amuletX2[3], _amuletY2[3], 0, 0); + + _screen->updateScreen(); + delayWithTicks(3); + } + _screen->showMouse(); +} + +} // end of namespace Kyra + diff --git a/engines/kyra/sequences_v1.cpp b/engines/kyra/sequences_v1.cpp deleted file mode 100644 index 607def3583..0000000000 --- a/engines/kyra/sequences_v1.cpp +++ /dev/null @@ -1,1884 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include "kyra/kyra.h" -#include "kyra/seqplayer.h" -#include "kyra/screen_v1.h" -#include "kyra/resource.h" -#include "kyra/sound.h" -#include "kyra/sprites.h" -#include "kyra/wsamovie.h" -#include "kyra/animator_v1.h" -#include "kyra/text.h" -#include "kyra/timer.h" - -#include "common/events.h" -#include "common/system.h" -#include "common/savefile.h" - -namespace Kyra { - -void KyraEngine_v1::seq_demo() { - debugC(9, kDebugLevelMain, "KyraEngine_v1::seq_demo()"); - - snd_playTheme(0, 2); - - _screen->loadBitmap("START.CPS", 7, 7, _screen->_currentPalette); - _screen->copyRegion(0, 0, 0, 0, 320, 200, 6, 0, Screen::CR_NO_P_CHECK); - _screen->updateScreen(); - _screen->fadeFromBlack(); - delay(60 * _tickLength); - _screen->fadeToBlack(); - - _screen->clearPage(0); - _screen->loadBitmap("TOP.CPS", 7, 7, NULL); - _screen->loadBitmap("BOTTOM.CPS", 5, 5, _screen->_currentPalette); - _screen->copyRegion(0, 91, 0, 8, 320, 103, 6, 0); - _screen->copyRegion(0, 0, 0, 111, 320, 64, 6, 0); - _screen->updateScreen(); - _screen->fadeFromBlack(); - - _seq->playSequence(_seq_WestwoodLogo, true); - delay(60 * _tickLength); - _seq->playSequence(_seq_KyrandiaLogo, true); - - _screen->fadeToBlack(); - _screen->clearPage(2); - _screen->clearPage(0); - - _seq->playSequence(_seq_Demo1, true); - - _screen->clearPage(0); - _seq->playSequence(_seq_Demo2, true); - - _screen->clearPage(0); - _seq->playSequence(_seq_Demo3, true); - - _screen->clearPage(0); - _seq->playSequence(_seq_Demo4, true); - - _screen->clearPage(0); - _screen->loadBitmap("FINAL.CPS", 7, 7, _screen->_currentPalette); - _screen->_curPage = 0; - _screen->copyRegion(0, 0, 0, 0, 320, 200, 6, 0); - _screen->updateScreen(); - _screen->fadeFromBlack(); - delay(60 * _tickLength); - _screen->fadeToBlack(); - _sound->haltTrack(); -} - -void KyraEngine_v1::seq_intro() { - debugC(9, kDebugLevelMain, "KyraEngine_v1::seq_intro()"); - - if (_flags.isTalkie) - _res->loadPakFile("INTRO.VRM"); - - static const IntroProc introProcTable[] = { - &KyraEngine_v1::seq_introLogos, - &KyraEngine_v1::seq_introStory, - &KyraEngine_v1::seq_introMalcolmTree, - &KyraEngine_v1::seq_introKallakWriting, - &KyraEngine_v1::seq_introKallakMalcolm - }; - - Common::InSaveFile *in; - if ((in = _saveFileMan->openForLoading(getSavegameFilename(0)))) { - delete in; - _skipIntroFlag = true; - } else - _skipIntroFlag = false; - - _seq->setCopyViewOffs(true); - _screen->setFont(Screen::FID_8_FNT); - if (_flags.platform != Common::kPlatformFMTowns && _flags.platform != Common::kPlatformPC98) - snd_playTheme(0, 2); - _text->setTalkCoords(144); - - for (int i = 0; i < ARRAYSIZE(introProcTable) && !seq_skipSequence(); ++i) - (this->*introProcTable[i])(); - - _text->setTalkCoords(136); - delay(30 * _tickLength); - _seq->setCopyViewOffs(false); - _sound->haltTrack(); - _sound->voiceStop(); - - if (_flags.isTalkie) - _res->unloadPakFile("INTRO.VRM"); -} - -void KyraEngine_v1::seq_introLogos() { - debugC(9, kDebugLevelMain, "KyraEngine_v1::seq_introLogos()"); - - if (_flags.platform == Common::kPlatformFMTowns || _flags.platform == Common::kPlatformPC98) { - _screen->loadBitmap("LOGO.CPS", 3, 3, _screen->_currentPalette); - _screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0); - _screen->updateScreen(); - _screen->fadeFromBlack(); - delay(90 * _tickLength); - _screen->fadeToBlack(); - if (!_abortIntroFlag) - snd_playWanderScoreViaMap(57, 0); - } - - _screen->clearPage(0); - - if (_flags.platform == Common::kPlatformAmiga) { - _screen->loadPalette("INTRO.PAL", _screen->_currentPalette); - _screen->loadBitmap("BOTTOM.CPS", 3, 5, 0); - _screen->loadBitmap("TOP.CPS", 3, 3, 0); - _screen->copyRegion(0, 0, 0, 111, 320, 64, 2, 0); - _screen->copyRegion(0, 91, 0, 8, 320, 109, 2, 0); - _screen->copyRegion(0, 0, 0, 0, 320, 190, 0, 2); - } else { - _screen->loadBitmap("TOP.CPS", 7, 7, 0); - _screen->loadBitmap("BOTTOM.CPS", 5, 5, _screen->_currentPalette); - _screen->copyRegion(0, 91, 0, 8, 320, 103, 6, 0); - _screen->copyRegion(0, 0, 0, 111, 320, 64, 6, 0); - } - - _screen->_curPage = 0; - _screen->updateScreen(); - _screen->fadeFromBlack(); - - if (_seq->playSequence(_seq_WestwoodLogo, _skipFlag) || _quitFlag) { - _screen->fadeToBlack(); - _screen->clearPage(0); - return; - } - delay(60 * _tickLength); - - if (_flags.platform == Common::kPlatformAmiga) { - memcpy(_screen->_currentPalette, _screen->_currentPalette + 3*32, 3*32); - _screen->setScreenPalette(_screen->_currentPalette); - } - - if ((_seq->playSequence(_seq_KyrandiaLogo, _skipFlag) && !seq_skipSequence()) || _quitFlag) { - _screen->fadeToBlack(); - _screen->clearPage(0); - return; - } - _screen->fillRect(0, 179, 319, 199, 0); - - if (_quitFlag) - return; - - if (_flags.platform == Common::kPlatformAmiga) { - memcpy(_screen->_currentPalette, _screen->_currentPalette + 3*64, 3*32); - _screen->fadeToBlack(); - _screen->copyRegion(0, 0, 0, 0, 320, 200, 4, 0); - _screen->fadeFromBlack(); - } else { - _screen->copyRegion(0, 91, 0, 8, 320, 104, 6, 2); - _screen->copyRegion(0, 0, 0, 112, 320, 64, 6, 2); - - uint32 start = _system->getMillis(); - bool doneFlag = false; - int oldDistance = 0; - - do { - uint32 now = _system->getMillis(); - - // The smallest y2 we ever draw the screen for is 65. - int distance = (now - start) / _tickLength; - if (distance > 112) { - distance = 112; - doneFlag = true; - } - - if (distance > oldDistance) { - int y1 = 8 + distance; - int h1 = 168 - distance; - int y2 = 176 - distance; - int h2 = distance; - - _screen->copyRegion(0, y1, 0, 8, 320, h1, 2, 0); - if (h2 > 0) - _screen->copyRegion(0, 64, 0, y2, 320, h2, 4, 0); - _screen->updateScreen(); - } - - oldDistance = distance; - delay(10); - } while (!doneFlag && !_quitFlag && !_abortIntroFlag); - } - - if (_quitFlag) - return; - - _seq->playSequence(_seq_Forest, true); -} - -void KyraEngine_v1::seq_introStory() { - debugC(9, kDebugLevelMain, "KyraEngine_v1::seq_introStory()"); - _screen->clearPage(3); - _screen->clearPage(0); - - // HACK: The Italian fan translation uses an special text screen here - // so we show it even when text is disabled - if (!textEnabled() && speechEnabled() && _flags.lang != Common::IT_ITA) - return; - - if (_flags.lang == Common::EN_ANY && !_flags.isTalkie && (_flags.platform == Common::kPlatformPC || _flags.platform == Common::kPlatformAmiga)) - _screen->loadBitmap("TEXT.CPS", 3, 3, _screen->_currentPalette); - else if (_flags.lang == Common::EN_ANY || _flags.lang == Common::JA_JPN) - _screen->loadBitmap("TEXT_ENG.CPS", 3, 3, _screen->_currentPalette); - else if (_flags.lang == Common::DE_DEU) - _screen->loadBitmap("TEXT_GER.CPS", 3, 3, _screen->_currentPalette); - else if (_flags.lang == Common::FR_FRA) - _screen->loadBitmap("TEXT_FRE.CPS", 3, 3, _screen->_currentPalette); - else if (_flags.lang == Common::ES_ESP) - _screen->loadBitmap("TEXT_SPA.CPS", 3, 3, _screen->_currentPalette); - else if (_flags.lang == Common::IT_ITA && !_flags.isTalkie) - _screen->loadBitmap("TEXT_ITA.CPS", 3, 3, _screen->_currentPalette); - else if (_flags.lang == Common::IT_ITA && _flags.isTalkie) - _screen->loadBitmap("TEXT_ENG.CPS", 3, 3, _screen->_currentPalette); - else - warning("no story graphics file found"); - _screen->setScreenPalette(_screen->_currentPalette); - _screen->copyRegion(0, 0, 0, 0, 320, 200, 3, 0); - - if (_flags.lang == Common::JA_JPN) { - const int x1 = (Screen::SCREEN_W - _screen->getTextWidth(_seq_textsTable[18])) / 2; - const int x2 = (Screen::SCREEN_W - _screen->getTextWidth(_seq_textsTable[19])) / 2; - const int y1 = 175; - const int y2 = 184; - - uint8 colorMap[] = { 0, 15, 12, 12 }; - _screen->setTextColor(colorMap, 0, 3); - - _screen->printText(_seq_textsTable[18], x1, y1, 5, 8); - _screen->printText(_seq_textsTable[19], x2, y2, 5, 8); - } - - _screen->updateScreen(); - //debugC(0, kDebugLevelMain, "skipFlag %i, %i", _skipFlag, _tickLength); - delay(360 * _tickLength); -} - -void KyraEngine_v1::seq_introMalcolmTree() { - debugC(9, kDebugLevelMain, "KyraEngine_v1::seq_introMalcolmTree()"); - _screen->_curPage = 0; - _screen->clearPage(3); - _seq->playSequence(_seq_MalcolmTree, true); -} - -void KyraEngine_v1::seq_introKallakWriting() { - debugC(9, kDebugLevelMain, "KyraEngine_v1::seq_introKallakWriting()"); - _seq->makeHandShapes(); - _screen->setAnimBlockPtr(5060); - _screen->_charWidth = -2; - _screen->clearPage(3); - _seq->playSequence(_seq_KallakWriting, true); -} - -void KyraEngine_v1::seq_introKallakMalcolm() { - debugC(9, kDebugLevelMain, "KyraEngine_v1::seq_introKallakMalcolm()"); - _screen->clearPage(3); - _seq->playSequence(_seq_KallakMalcolm, true); -} - -void KyraEngine_v1::seq_createAmuletJewel(int jewel, int page, int noSound, int drawOnly) { - debugC(9, kDebugLevelMain, "seq_createAmuletJewel(%d, %d, %d, %d)", jewel, page, noSound, drawOnly); - static const uint16 specialJewelTable[] = { - 0x167, 0x162, 0x15D, 0x158, 0x153, 0xFFFF - }; - static const uint16 specialJewelTable1[] = { - 0x14F, 0x154, 0x159, 0x15E, 0x163, 0xFFFF - }; - static const uint16 specialJewelTable2[] = { - 0x150, 0x155, 0x15A, 0x15F, 0x164, 0xFFFF - }; - static const uint16 specialJewelTable3[] = { - 0x151, 0x156, 0x15B, 0x160, 0x165, 0xFFFF - }; - static const uint16 specialJewelTable4[] = { - 0x152, 0x157, 0x15C, 0x161, 0x166, 0xFFFF - }; - if (!noSound) - snd_playSoundEffect(0x5F); - _screen->hideMouse(); - if (!drawOnly) { - for (int i = 0; specialJewelTable[i] != 0xFFFF; ++i) { - _screen->drawShape(page, _shapes[specialJewelTable[i]], _amuletX2[jewel], _amuletY2[jewel], 0, 0); - _screen->updateScreen(); - delayWithTicks(3); - } - - const uint16 *opcodes = 0; - switch (jewel - 1) { - case 0: - opcodes = specialJewelTable1; - break; - - case 1: - opcodes = specialJewelTable2; - break; - - case 2: - opcodes = specialJewelTable3; - break; - - case 3: - opcodes = specialJewelTable4; - break; - } - - if (opcodes) { - for (int i = 0; opcodes[i] != 0xFFFF; ++i) { - _screen->drawShape(page, _shapes[opcodes[i]], _amuletX2[jewel], _amuletY2[jewel], 0, 0); - _screen->updateScreen(); - delayWithTicks(3); - } - } - } - _screen->drawShape(page, _shapes[323+jewel], _amuletX2[jewel], _amuletY2[jewel], 0, 0); - _screen->updateScreen(); - _screen->showMouse(); - setGameFlag(0x55+jewel); -} - -void KyraEngine_v1::seq_brandonHealing() { - debugC(9, kDebugLevelMain, "seq_brandonHealing()"); - if (!(_deathHandler & 8)) - return; - if (_currentCharacter->sceneId == 210) { - if (_beadStateVar == 4 || _beadStateVar == 6) - return; - } - _screen->hideMouse(); - checkAmuletAnimFlags(); - assert(_healingShapeTable); - setupShapes123(_healingShapeTable, 22, 0); - _animator->setBrandonAnimSeqSize(3, 48); - snd_playSoundEffect(0x53); - for (int i = 123; i <= 144; ++i) { - _currentCharacter->currentAnimFrame = i; - _animator->animRefreshNPC(0); - delayWithTicks(8); - } - for (int i = 125; i >= 123; --i) { - _currentCharacter->currentAnimFrame = i; - _animator->animRefreshNPC(0); - delayWithTicks(8); - } - _animator->resetBrandonAnimSeqSize(); - _currentCharacter->currentAnimFrame = 7; - _animator->animRefreshNPC(0); - freeShapes123(); - _screen->showMouse(); -} - -void KyraEngine_v1::seq_brandonHealing2() { - debugC(9, kDebugLevelMain, "seq_brandonHealing2()"); - _screen->hideMouse(); - checkAmuletAnimFlags(); - assert(_healingShape2Table); - setupShapes123(_healingShape2Table, 30, 0); - resetBrandonPoisonFlags(); - _animator->setBrandonAnimSeqSize(3, 48); - snd_playSoundEffect(0x50); - for (int i = 123; i <= 152; ++i) { - _currentCharacter->currentAnimFrame = i; - _animator->animRefreshNPC(0); - delayWithTicks(8); - } - _animator->resetBrandonAnimSeqSize(); - _currentCharacter->currentAnimFrame = 7; - _animator->animRefreshNPC(0); - freeShapes123(); - _screen->showMouse(); - assert(_poisonGone); - characterSays(2010, _poisonGone[0], 0, -2); - characterSays(2011, _poisonGone[1], 0, -2); -} - -void KyraEngine_v1::seq_poisonDeathNow(int now) { - debugC(9, kDebugLevelMain, "seq_poisonDeathNow(%d)", now); - if (!(_brandonStatusBit & 1)) - return; - ++_poisonDeathCounter; - if (now) - _poisonDeathCounter = 2; - if (_poisonDeathCounter >= 2) { - snd_playWanderScoreViaMap(1, 1); - assert(_thePoison); - characterSays(7000, _thePoison[0], 0, -2); - characterSays(7001, _thePoison[1], 0, -2); - seq_poisonDeathNowAnim(); - _deathHandler = 3; - } else { - assert(_thePoison); - characterSays(7002, _thePoison[2], 0, -2); - characterSays(7004, _thePoison[3], 0, -2); - } -} - -void KyraEngine_v1::seq_poisonDeathNowAnim() { - debugC(9, kDebugLevelMain, "seq_poisonDeathNowAnim()"); - _screen->hideMouse(); - checkAmuletAnimFlags(); - assert(_posionDeathShapeTable); - setupShapes123(_posionDeathShapeTable, 20, 0); - _animator->setBrandonAnimSeqSize(8, 48); - - _currentCharacter->currentAnimFrame = 124; - _animator->animRefreshNPC(0); - delayWithTicks(30); - - _currentCharacter->currentAnimFrame = 123; - _animator->animRefreshNPC(0); - delayWithTicks(30); - - for (int i = 125; i <= 139; ++i) { - _currentCharacter->currentAnimFrame = i; - _animator->animRefreshNPC(0); - delayWithTicks(8); - } - - delayWithTicks(60); - - for (int i = 140; i <= 142; ++i) { - _currentCharacter->currentAnimFrame = i; - _animator->animRefreshNPC(0); - delayWithTicks(8); - } - - delayWithTicks(60); - - _animator->resetBrandonAnimSeqSize(); - freeShapes123(); - _animator->restoreAllObjectBackgrounds(); - _currentCharacter->x1 = _currentCharacter->x2 = -1; - _currentCharacter->y1 = _currentCharacter->y2 = -1; - _animator->preserveAllBackgrounds(); - _screen->showMouse(); -} - -void KyraEngine_v1::seq_playFluteAnimation() { - debugC(9, kDebugLevelMain, "seq_playFluteAnimation()"); - _screen->hideMouse(); - checkAmuletAnimFlags(); - setupShapes123(_fluteAnimShapeTable, 36, 0); - _animator->setBrandonAnimSeqSize(3, 75); - for (int i = 123; i <= 130; ++i) { - _currentCharacter->currentAnimFrame = i; - _animator->animRefreshNPC(0); - delayWithTicks(2); - } - - int delayTime = 0, soundType = 0; - if (queryGameFlag(0x85)) { - snd_playSoundEffect(0x63); - delayTime = 9; - soundType = 3; - } else if (!queryGameFlag(0x86)) { - snd_playSoundEffect(0x61); - delayTime = 2; - soundType = 1; - setGameFlag(0x86); - } else { - snd_playSoundEffect(0x62); - delayTime = 2; - soundType = 2; - } - - for (int i = 131; i <= 158; ++i) { - _currentCharacter->currentAnimFrame = i; - _animator->animRefreshNPC(0); - delayWithTicks(delayTime); - } - - for (int i = 126; i >= 123; --i) { - _currentCharacter->currentAnimFrame = i; - _animator->animRefreshNPC(0); - delayWithTicks(delayTime); - } - _animator->resetBrandonAnimSeqSize(); - _currentCharacter->currentAnimFrame = 7; - _animator->animRefreshNPC(0); - freeShapes123(); - _screen->showMouse(); - - if (soundType == 1) { - assert(_fluteString); - characterSays(1000, _fluteString[0], 0, -2); - } else if (soundType == 2) { - assert(_fluteString); - characterSays(1001, _fluteString[1], 0, -2); - } -} - -void KyraEngine_v1::seq_winterScroll1() { - debugC(9, kDebugLevelMain, "seq_winterScroll1()"); - _screen->hideMouse(); - checkAmuletAnimFlags(); - assert(_winterScrollTable); - assert(_winterScroll1Table); - assert(_winterScroll2Table); - setupShapes123(_winterScrollTable, 7, 0); - _animator->setBrandonAnimSeqSize(5, 66); - - for (int i = 123; i <= 129; ++i) { - _currentCharacter->currentAnimFrame = i; - _animator->animRefreshNPC(0); - delayWithTicks(8); - } - - freeShapes123(); - snd_playSoundEffect(0x20); - - uint8 numFrames, midpoint; - if (_flags.isTalkie) { - numFrames = 18; - midpoint = 136; - } else { - numFrames = 35; - midpoint = 147; - } - setupShapes123(_winterScroll1Table, numFrames, 0); - for (int i = 123; i < midpoint; ++i) { - _currentCharacter->currentAnimFrame = i; - _animator->animRefreshNPC(0); - delayWithTicks(8); - } - - if (_currentCharacter->sceneId == 41 && !queryGameFlag(0xA2)) { - snd_playSoundEffect(0x20); - _sprites->_anims[0].play = false; - _animator->sprites()[0].active = 0; - _sprites->_anims[1].play = true; - _animator->sprites()[1].active = 1; - setGameFlag(0xA2); - } - - for (int i = midpoint; i < 123 + numFrames; ++i) { - _currentCharacter->currentAnimFrame = i; - _animator->animRefreshNPC(0); - delayWithTicks(8); - } - - if (_currentCharacter->sceneId == 117 && !queryGameFlag(0xB3)) { - for (int i = 0; i <= 7; ++i) { - _sprites->_anims[i].play = false; - _animator->sprites()[i].active = 0; - } - uint8 tmpPal[768]; - memcpy(tmpPal, _screen->_currentPalette, 768); - memcpy(&tmpPal[684], palTable2()[0], 60); - _screen->fadePalette(tmpPal, 72); - memcpy(&_screen->_currentPalette[684], palTable2()[0], 60); - _screen->setScreenPalette(_screen->_currentPalette); - setGameFlag(0xB3); - } else { - delayWithTicks(120); - } - - freeShapes123(); - setupShapes123(_winterScroll2Table, 4, 0); - - for (int i = 123; i <= 126; ++i) { - _currentCharacter->currentAnimFrame = i; - _animator->animRefreshNPC(0); - delayWithTicks(8); - } - - _animator->resetBrandonAnimSeqSize(); - _currentCharacter->currentAnimFrame = 7; - _animator->animRefreshNPC(0); - freeShapes123(); - _screen->showMouse(); -} - -void KyraEngine_v1::seq_winterScroll2() { - debugC(9, kDebugLevelMain, "seq_winterScroll2()"); - _screen->hideMouse(); - checkAmuletAnimFlags(); - assert(_winterScrollTable); - setupShapes123(_winterScrollTable, 7, 0); - _animator->setBrandonAnimSeqSize(5, 66); - - for (int i = 123; i <= 128; ++i) { - _currentCharacter->currentAnimFrame = i; - _animator->animRefreshNPC(0); - delayWithTicks(8); - } - - delayWithTicks(120); - - for (int i = 127; i >= 123; --i) { - _currentCharacter->currentAnimFrame = i; - _animator->animRefreshNPC(0); - delayWithTicks(8); - } - - _animator->resetBrandonAnimSeqSize(); - _currentCharacter->currentAnimFrame = 7; - _animator->animRefreshNPC(0); - freeShapes123(); - _screen->showMouse(); -} - -void KyraEngine_v1::seq_makeBrandonInv() { - debugC(9, kDebugLevelMain, "seq_makeBrandonInv()"); - if (_deathHandler == 8) - return; - - if (_currentCharacter->sceneId == 210) { - if (_beadStateVar == 4 || _beadStateVar == 6) - return; - } - - _screen->hideMouse(); - checkAmuletAnimFlags(); - _brandonStatusBit |= 0x20; - _timer->setCountdown(18, 2700); - _brandonStatusBit |= 0x40; - snd_playSoundEffect(0x77); - _brandonInvFlag = 0; - while (_brandonInvFlag <= 0x100) { - _animator->animRefreshNPC(0); - delayWithTicks(10); - _brandonInvFlag += 0x10; - } - _brandonStatusBit &= 0xFFBF; - _screen->showMouse(); -} - -void KyraEngine_v1::seq_makeBrandonNormal() { - debugC(9, kDebugLevelMain, "seq_makeBrandonNormal()"); - _screen->hideMouse(); - _brandonStatusBit |= 0x40; - snd_playSoundEffect(0x77); - _brandonInvFlag = 0x100; - while (_brandonInvFlag >= 0) { - _animator->animRefreshNPC(0); - delayWithTicks(10); - _brandonInvFlag -= 0x10; - } - _brandonInvFlag = 0; - _brandonStatusBit &= 0xFF9F; - _screen->showMouse(); -} - -void KyraEngine_v1::seq_makeBrandonNormal2() { - debugC(9, kDebugLevelMain, "seq_makeBrandonNormal2()"); - _screen->hideMouse(); - assert(_brandonToWispTable); - setupShapes123(_brandonToWispTable, 26, 0); - _animator->setBrandonAnimSeqSize(5, 48); - _brandonStatusBit &= 0xFFFD; - snd_playSoundEffect(0x6C); - for (int i = 138; i >= 123; --i) { - _currentCharacter->currentAnimFrame = i; - _animator->animRefreshNPC(0); - delayWithTicks(8); - } - _animator->setBrandonAnimSeqSize(4, 48); - _currentCharacter->currentAnimFrame = 7; - _animator->animRefreshNPC(0); - - if (_currentCharacter->sceneId >= 229 && _currentCharacter->sceneId <= 245) - _screen->fadeSpecialPalette(31, 234, 13, 4); - else if (_currentCharacter->sceneId >= 118 && _currentCharacter->sceneId <= 186) - _screen->fadeSpecialPalette(14, 228, 15, 4); - - freeShapes123(); - _screen->showMouse(); -} - -void KyraEngine_v1::seq_makeBrandonWisp() { - debugC(9, kDebugLevelMain, "seq_makeBrandonWisp()"); - if (_deathHandler == 8) - return; - - if (_currentCharacter->sceneId == 210) { - if (_beadStateVar == 4 || _beadStateVar == 6) - return; - } - _screen->hideMouse(); - checkAmuletAnimFlags(); - assert(_brandonToWispTable); - setupShapes123(_brandonToWispTable, 26, 0); - _animator->setBrandonAnimSeqSize(5, 48); - snd_playSoundEffect(0x6C); - for (int i = 123; i <= 138; ++i) { - _currentCharacter->currentAnimFrame = i; - _animator->animRefreshNPC(0); - delayWithTicks(8); - } - _brandonStatusBit |= 2; - - if (_currentCharacter->sceneId >= 109 && _currentCharacter->sceneId <= 198) - _timer->setCountdown(14, 18000); - else - _timer->setCountdown(14, 7200); - - _animator->_brandonDrawFrame = 113; - _brandonStatusBit0x02Flag = 1; - _currentCharacter->currentAnimFrame = 113; - _animator->animRefreshNPC(0); - _animator->updateAllObjectShapes(); - - if (_currentCharacter->sceneId >= 229 && _currentCharacter->sceneId <= 245) - _screen->fadeSpecialPalette(30, 234, 13, 4); - else if (_currentCharacter->sceneId >= 118 && _currentCharacter->sceneId <= 186) - _screen->fadeSpecialPalette(14, 228, 15, 4); - - freeShapes123(); - _screen->showMouse(); -} - -void KyraEngine_v1::seq_dispelMagicAnimation() { - debugC(9, kDebugLevelMain, "seq_dispelMagicAnimation()"); - if (_deathHandler == 8) - return; - if (_currentCharacter->sceneId == 210) { - if (_beadStateVar == 4 || _beadStateVar == 6) - return; - } - _screen->hideMouse(); - if (_currentCharacter->sceneId == 210 && _currentCharacter->sceneId < 160) - _currentCharacter->facing = 3; - if (_malcolmFlag == 7 && _beadStateVar == 3) { - _beadStateVar = 6; - _unkEndSeqVar5 = 2; - _malcolmFlag = 10; - } - checkAmuletAnimFlags(); - setGameFlag(0xEE); - assert(_magicAnimationTable); - setupShapes123(_magicAnimationTable, 5, 0); - _animator->setBrandonAnimSeqSize(8, 49); - snd_playSoundEffect(0x15); - for (int i = 123; i <= 127; ++i) { - _currentCharacter->currentAnimFrame = i; - _animator->animRefreshNPC(0); - delayWithTicks(8); - } - - delayWithTicks(120); - - for (int i = 127; i >= 123; --i) { - _currentCharacter->currentAnimFrame = i; - _animator->animRefreshNPC(0); - delayWithTicks(10); - } - _animator->resetBrandonAnimSeqSize(); - _currentCharacter->currentAnimFrame = 7; - _animator->animRefreshNPC(0); - freeShapes123(); - _screen->showMouse(); -} - -void KyraEngine_v1::seq_fillFlaskWithWater(int item, int type) { - debugC(9, kDebugLevelMain, "seq_fillFlaskWithWater(%d, %d)", item, type); - int newItem = -1; - static const uint8 flaskTable1[] = { 0x46, 0x48, 0x4A, 0x4C }; - static const uint8 flaskTable2[] = { 0x47, 0x49, 0x4B, 0x4D }; - - if (item >= 60 && item <= 77) { - assert(_flaskFull); - characterSays(8006, _flaskFull[0], 0, -2); - } else if (item == 78) { - assert(type >= 0 && type < ARRAYSIZE(flaskTable1)); - newItem = flaskTable1[type]; - } else if (item == 79) { - assert(type >= 0 && type < ARRAYSIZE(flaskTable2)); - newItem = flaskTable2[type]; - } - - if (newItem == -1) - return; - - _screen->hideMouse(); - setMouseItem(newItem); - _screen->showMouse(); - _itemInHand = newItem; - assert(_fullFlask); - assert(type < _fullFlask_Size && type >= 0); - static const uint16 voiceEntries[] = { - 0x1F40, 0x1F41, 0x1F42, 0x1F45 - }; - assert(type < ARRAYSIZE(voiceEntries)); - characterSays(voiceEntries[type], _fullFlask[type], 0, -2); -} - -void KyraEngine_v1::seq_playDrinkPotionAnim(int item, int unk2, int flags) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::seq_playDrinkPotionAnim(%d, %d, %d)", item, unk2, flags); - uint8 red, green, blue; - - switch (item) { - case 60: - case 61: - red = 63; - green = blue = 6; - break; - case 62: - case 63: - red = green = 0; - blue = 67; - break; - case 64: - case 65: - red = 84; - green = 78; - blue = 14; - break; - case 66: - red = blue = 0; - green = 48; - break; - case 67: - red = 100; - green = 48; - blue = 23; - break; - case 68: - red = 73; - green = 0; - blue = 89; - break; - case 69: - red = green = 73; - blue = 86; - break; - default: - red = 33; - green = 66; - blue = 100; - break; - } - red = (uint8)((double)red * 0.63); - green = (uint8)((double)green * 0.63); - blue = (uint8)((double)blue * 0.63); - - _screen->setPaletteIndex(0xFE, red, green, blue); - - _screen->hideMouse(); - checkAmuletAnimFlags(); - _currentCharacter->facing = 5; - _animator->animRefreshNPC(0); - assert(_drinkAnimationTable); - setupShapes123(_drinkAnimationTable, 9, flags); - _animator->setBrandonAnimSeqSize(5, 54); - - for (int i = 123; i <= 131; ++i) { - _currentCharacter->currentAnimFrame = i; - _animator->animRefreshNPC(0); - delayWithTicks(5); - } - snd_playSoundEffect(0x34); - for (int i = 0; i < 2; ++i) { - _currentCharacter->currentAnimFrame = 130; - _animator->animRefreshNPC(0); - delayWithTicks(7); - _currentCharacter->currentAnimFrame = 131; - _animator->animRefreshNPC(0); - delayWithTicks(7); - } - - if (unk2) { - // XXX - } - - for (int i = 131; i >= 123; --i) { - _currentCharacter->currentAnimFrame = i; - _animator->animRefreshNPC(0); - delayWithTicks(5); - } - - _animator->resetBrandonAnimSeqSize(); - _currentCharacter->currentAnimFrame = 7; - _animator->animRefreshNPC(0); - freeShapes123(); - _screen->setPaletteIndex(0xFE, 30, 30, 30); - _screen->showMouse(); -} - -int KyraEngine_v1::seq_playEnd() { - debugC(9, kDebugLevelMain, "KyraEngine_v1::seq_playEnd()"); - if (_endSequenceSkipFlag) - return 0; - - if (_deathHandler == 8) - return 0; - - _screen->_curPage = 2; - if (_endSequenceNeedLoading) { - snd_playWanderScoreViaMap(50, 1); - setupPanPages(); - _finalA = new WSAMovieV1(this); - assert(_finalA); - _finalA->open("finala.wsa", 1, 0); - _finalB = new WSAMovieV1(this); - assert(_finalB); - _finalB->open("finalb.wsa", 1, 0); - _finalC = new WSAMovieV1(this); - assert(_finalC); - _endSequenceNeedLoading = 0; - _finalC->open("finalc.wsa", 1, 0); - _screen->_curPage = 0; - _beadStateVar = 0; - _malcolmFlag = 0; - _unkEndSeqVar2 = _system->getMillis() + 600 * _tickLength; - _screen->copyRegion(312, 0, 312, 0, 8, 136, 0, 2); - } - - // TODO: better handling. This timer shouldn't count when the menu is open or something. - if (_unkEndSeqVar2 != -1) { - if (_system->getMillis() > (uint32)_unkEndSeqVar2) { - _unkEndSeqVar2 = -1; - if (!_malcolmFlag) - _malcolmFlag = 1; - } - } - - if (handleMalcolmFlag()) { - _beadStateVar = 0; - _malcolmFlag = 12; - handleMalcolmFlag(); - handleBeadState(); - closeFinalWsa(); - if (_deathHandler == 8) { - _screen->_curPage = 0; - checkAmuletAnimFlags(); - seq_brandonToStone(); - delay(60 * _tickLength); - return 1; - } else { - _endSequenceSkipFlag = 1; - if (_text->printed()) - _text->restoreTalkTextMessageBkgd(2, 0); - _screen->_curPage = 0; - _screen->hideMouse(); - _screen->fadeSpecialPalette(32, 228, 20, 60); - delay(60 * _tickLength); - _screen->loadBitmap("GEMHEAL.CPS", 3, 3, _screen->_currentPalette); - _screen->setScreenPalette(_screen->_currentPalette); - _screen->shuffleScreen(8, 8, 304, 128, 2, 0, 1, 0); - uint32 nextTime = _system->getMillis() + 120 * _tickLength; - _finalA = new WSAMovieV1(this); - assert(_finalA); - _finalA->open("finald.wsa", 1, 0); - _finalA->setX(8); _finalA->setY(8); - _finalA->setDrawPage(0); - delayUntil(nextTime); - snd_playSoundEffect(0x40); - for (int i = 0; i < 22; ++i) { - delayUntil(nextTime); - if (i == 4) - snd_playSoundEffect(0x3E); - else if (i == 20) - snd_playSoundEffect(0x0E); - nextTime = _system->getMillis() + 8 * _tickLength; - _finalA->displayFrame(i); - _screen->updateScreen(); - } - delete _finalA; - _finalA = 0; - seq_playEnding(); - return 1; - } - } else { - handleBeadState(); - _screen->bitBlitRects(); - _screen->updateScreen(); - _screen->_curPage = 0; - } - return 0; -} - -void KyraEngine_v1::seq_brandonToStone() { - debugC(9, kDebugLevelMain, "KyraEngine_v1::seq_brandonToStone()"); - _screen->hideMouse(); - assert(_brandonStoneTable); - setupShapes123(_brandonStoneTable, 14, 0); - _animator->setBrandonAnimSeqSize(5, 51); - for (int i = 123; i <= 136; ++i) { - _currentCharacter->currentAnimFrame = i; - _animator->animRefreshNPC(0); - delayWithTicks(8); - } - _animator->resetBrandonAnimSeqSize(); - freeShapes123(); - _screen->showMouse(); -} - -void KyraEngine_v1::seq_playEnding() { - debugC(9, kDebugLevelMain, "KyraEngine_v1::seq_playEnding()"); - if (_quitFlag) - return; - _screen->hideMouse(); - _screen->_curPage = 0; - _screen->fadeToBlack(); - _screen->loadBitmap("REUNION.CPS", 3, 3, _screen->_currentPalette); - _screen->copyRegion(8, 8, 8, 8, 304, 128, 2, 0); - _screen->_curPage = 0; - // XXX - assert(_homeString); - drawSentenceCommand(_homeString[0], 179); - - memset(_screen->getPalette(2), 0, sizeof(uint8)*768); - _screen->setScreenPalette(_screen->getPalette(2)); - - _seq->playSequence(_seq_Reunion, false); - _screen->fadeToBlack(); - - _screen->showMouse(); - seq_playCredits(); -} - -void KyraEngine_v1::seq_playCredits() { - debugC(9, kDebugLevelMain, "KyraEngine_v1::seq_playCredits()"); - static const uint8 colorMap[] = { 0, 0, 0xC, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - static const char stringTerms[] = { 0x5, 0xd, 0x0}; - static const int numStrings = 250; - - struct { - int16 x, y; - uint8 code; - uint8 unk1; - Screen::FontId font; - uint8 *str; - } strings[numStrings]; - - memset(strings, 0, sizeof(strings)); - - _screen->hideMouse(); - if (!_flags.isTalkie) { - _screen->loadFont(Screen::FID_CRED6_FNT, "CREDIT6.FNT"); - _screen->loadFont(Screen::FID_CRED8_FNT, "CREDIT8.FNT"); - } else - _screen->setFont(Screen::FID_8_FNT); - - _screen->loadBitmap("CHALET.CPS", 4, 4, _screen->_currentPalette); - - _screen->setCurPage(0); - _screen->clearCurPage(); - _screen->setTextColorMap(colorMap); - _screen->_charWidth = -1; - - // we only need this for the fm-towns version - if (_flags.platform == Common::kPlatformFMTowns || _flags.platform == Common::kPlatformPC98) - snd_playWanderScoreViaMap(53, 1); - - uint8 *buffer = 0; - uint32 size = 0; - - if (_flags.platform == Common::kPlatformFMTowns || _flags.platform == Common::kPlatformPC98) { - int sizeTmp = 0; - const uint8 *bufferTmp = _staticres->loadRawData(kCreditsStrings, sizeTmp); - buffer = new uint8[sizeTmp]; - assert(buffer); - memcpy(buffer, bufferTmp, sizeTmp); - size = sizeTmp; - _staticres->unloadId(kCreditsStrings); - } else { - buffer = _res->fileData("CREDITS.TXT", &size); - assert(buffer); - } - - uint8 *nextString = buffer; - uint8 *currentString = buffer; - int currentY = 200; - - for (int i = 0; i < numStrings; i++) { - if (*nextString == 0) - break; - - currentString = nextString; - nextString = (uint8 *)strpbrk((const char *)currentString, stringTerms); - if (!nextString) - nextString = (uint8 *)strchr((const char *)currentString, 0); - - strings[i].code = nextString[0]; - *nextString = 0; - if (strings[i].code != 0) - nextString++; - - if (*currentString == 3 || *currentString == 4) { - strings[i].unk1 = *currentString; - currentString++; - } - - if (*currentString == 1) { - currentString++; - if (!_flags.isTalkie) - _screen->setFont(Screen::FID_CRED6_FNT); - } else { - if (*currentString == 2) - currentString++; - if (!_flags.isTalkie) - _screen->setFont(Screen::FID_CRED8_FNT); - } - strings[i].font = _screen->_currentFont; - - if (strings[i].unk1 == 3) - strings[i].x = 157 - _screen->getTextWidth((const char *)currentString); - else if (strings[i].unk1 == 4) - strings[i].x = 161; - else - strings[i].x = (320 - _screen->getTextWidth((const char *)currentString)) / 2 + 1; - - strings[i].y = currentY; - if (strings[i].code != 5) - currentY += 10; - - strings[i].str = currentString; - } - - _screen->setCurPage(2); - - memset(_screen->getPalette(2), 0, sizeof(uint8)*768); - _screen->setScreenPalette(_screen->getPalette(2)); - _screen->copyRegion(8, 32, 8, 32, 312, 128, 4, 0, Screen::CR_NO_P_CHECK); - _screen->fadePalette(_screen->_currentPalette, 0x5A); - - Common::Event event; - bool finished = false; - int bottom = 201; - while (!finished) { - uint32 startLoop = _system->getMillis(); - if (bottom > 175) { - _screen->copyRegion(8, 32, 8, 32, 312, 128, 4, 2, Screen::CR_NO_P_CHECK); - bottom = 0; - - for (int i = 0; i < numStrings; i++) { - if (strings[i].y < 200 && strings[i].y > 0) { - if (strings[i].font != _screen->_currentFont) - _screen->setFont(strings[i].font); - _screen->printText((const char *)strings[i].str, strings[i].x, strings[i].y, 15, 0); - } - strings[i].y--; - if (strings[i].y > bottom) - bottom = strings[i].y; - } - _screen->copyRegion(8, 32, 8, 32, 312, 128, 2, 0, Screen::CR_NO_P_CHECK); - _screen->updateScreen(); - } - - while (_eventMan->pollEvent(event)) { - switch (event.type) { - case Common::EVENT_KEYDOWN: - finished = true; - break; - case Common::EVENT_QUIT: - quitGame(); - finished = true; - break; - default: - break; - } - } - - uint32 now = _system->getMillis(); - uint32 nextLoop = startLoop + _tickLength * 5; - - if (nextLoop > now) - _system->delayMillis(nextLoop - now); - } - - delete[] buffer; - - _screen->fadeToBlack(); - _screen->clearCurPage(); - _screen->showMouse(); -} - -bool KyraEngine_v1::seq_skipSequence() const { - debugC(9, kDebugLevelMain, "KyraEngine_v1::seq_skipSequence()"); - return _quitFlag || _abortIntroFlag; -} - -int KyraEngine_v1::handleMalcolmFlag() { - debugC(9, kDebugLevelMain, "KyraEngine_v1::handleMalcolmFlag()"); - static uint16 frame = 0; - static uint32 timer1 = 0; - static uint32 timer2 = 0; - - switch (_malcolmFlag) { - case 1: - frame = 0; - _malcolmFlag = 2; - timer2 = 0; - - // Fall through to the next case - - case 2: - if (_system->getMillis() >= timer2) { - _finalA->setX(8); - _finalA->setY(46); - _finalA->setDrawPage(0); - _finalA->displayFrame(frame); - _screen->updateScreen(); - timer2 = _system->getMillis() + 8 * _tickLength; - ++frame; - if (frame > 13) { - _malcolmFlag = 3; - timer1 = _system->getMillis() + 180 * _tickLength; - } - } - break; - - case 3: - if (_system->getMillis() < timer1) { - if (_system->getMillis() >= timer2) { - frame = _rnd.getRandomNumberRng(14, 17); - _finalA->setX(8); - _finalA->setY(46); - _finalA->setDrawPage(0); - _finalA->displayFrame(frame); - _screen->updateScreen(); - timer2 = _system->getMillis() + 8 * _tickLength; - } - } else { - _malcolmFlag = 4; - frame = 18; - } - break; - - case 4: - if (_system->getMillis() >= timer2) { - _finalA->setX(8); - _finalA->setY(46); - _finalA->setDrawPage(0); - _finalA->displayFrame(frame); - _screen->updateScreen(); - timer2 = _system->getMillis() + 8 * _tickLength; - ++frame; - if (frame > 25) { - frame = 26; - _malcolmFlag = 5; - _beadStateVar = 1; - } - } - break; - - case 5: - if (_system->getMillis() >= timer2) { - _finalA->setX(8); - _finalA->setY(46); - _finalA->setDrawPage(0); - _finalA->displayFrame(frame); - _screen->updateScreen(); - timer2 = _system->getMillis() + 8 * _tickLength; - ++frame; - if (frame > 31) { - frame = 32; - _malcolmFlag = 6; - } - } - break; - - case 6: - if (_unkEndSeqVar4) { - if (frame <= 33 && _system->getMillis() >= timer2) { - _finalA->setX(8); - _finalA->setY(46); - _finalA->setDrawPage(0); - _finalA->displayFrame(frame); - _screen->updateScreen(); - timer2 = _system->getMillis() + 8 * _tickLength; - ++frame; - if (frame > 33) { - _malcolmFlag = 7; - frame = 32; - _unkEndSeqVar5 = 0; - } - } - } - break; - - case 7: - if (_unkEndSeqVar5 == 1) { - _malcolmFlag = 8; - frame = 34; - } else if (_unkEndSeqVar5 == 2) { - _malcolmFlag = 3; - timer1 = _system->getMillis() + 180 * _tickLength; - } - break; - - case 8: - if (_system->getMillis() >= timer2) { - _finalA->setX(8); - _finalA->setY(46); - _finalA->setDrawPage(0); - _finalA->displayFrame(frame); - _screen->updateScreen(); - timer2 = _system->getMillis() + 8 * _tickLength; - ++frame; - if (frame > 37) { - _malcolmFlag = 0; - _deathHandler = 8; - return 1; - } - } - break; - - case 9: - snd_playSoundEffect(12); - snd_playSoundEffect(12); - _finalC->setX(16); - _finalC->setY(50); - _finalC->setDrawPage(0); - for (int i = 0; i < 18; ++i) { - timer2 = _system->getMillis() + 4 * _tickLength; - _finalC->displayFrame(i); - _screen->updateScreen(); - delayUntil(timer2); - } - snd_playWanderScoreViaMap(51, 1); - delay(60 * _tickLength); - _malcolmFlag = 0; - return 1; - - case 10: - if (!_beadStateVar) { - handleBeadState(); - _screen->bitBlitRects(); - assert(_veryClever); - _text->printTalkTextMessage(_veryClever[0], 60, 31, 5, 0, 2); - timer2 = _system->getMillis() + 180 * _tickLength; - _malcolmFlag = 11; - } - break; - - case 11: - if (_system->getMillis() >= timer2) { - _text->restoreTalkTextMessageBkgd(2, 0); - _malcolmFlag = 3; - timer1 = _system->getMillis() + 180 * _tickLength; - } - break; - - default: - break; - } - - return 0; -} - -int KyraEngine_v1::handleBeadState() { - debugC(9, kDebugLevelMain, "KyraEngine_v1::handleBeadState()"); - static uint32 timer1 = 0; - static uint32 timer2 = 0; - static BeadState beadState1 = { -1, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - static BeadState beadState2 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - - static const int table1[] = { - -1, -2, -4, -5, -6, -7, -6, -5, - -4, -2, -1, 0, 1, 2, 4, 5, - 6, 7, 6, 5, 4, 2, 1, 0, 0 - }; - static const int table2[] = { - 0, 0, 1, 1, 2, 2, 3, 3, - 4, 4, 5, 5, 5, 5, 4, 4, - 3, 3, 2, 2, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0 - }; - - switch (_beadStateVar) { - case 0: - if (beadState1.x != -1 && _endSequenceBackUpRect) { - _screen->copyFromCurPageBlock(beadState1.x >> 3, beadState1.y, beadState1.width, beadState1.height, _endSequenceBackUpRect); - _screen->addBitBlitRect(beadState1.x, beadState1.y, beadState1.width2, beadState1.height); - } - - beadState1.x = -1; - beadState1.tableIndex = 0; - timer1 = 0; - timer2 = 0; - _lastDisplayedPanPage = 0; - return 1; - - case 1: - if (beadState1.x != -1) { - if (_endSequenceBackUpRect) { - _screen->copyFromCurPageBlock(beadState1.x >> 3, beadState1.y, beadState1.width, beadState1.height, _endSequenceBackUpRect); - _screen->addBitBlitRect(beadState1.x, beadState1.y, beadState1.width2, beadState1.height); - } - beadState1.x = -1; - beadState1.tableIndex = 0; - } - _beadStateVar = 2; - break; - - case 2: - if (_system->getMillis() >= timer1) { - int x = 0, y = 0; - timer1 = _system->getMillis() + 4 * _tickLength; - if (beadState1.x == -1) { - assert(_panPagesTable); - beadState1.width2 = _animator->fetchAnimWidth(_panPagesTable[19], 256); - beadState1.width = ((beadState1.width2 + 7) >> 3) + 1; - beadState1.height = _animator->fetchAnimHeight(_panPagesTable[19], 256); - if (!_endSequenceBackUpRect) { - _endSequenceBackUpRect = new uint8[(beadState1.width * beadState1.height) << 3]; - assert(_endSequenceBackUpRect); - memset(_endSequenceBackUpRect, 0, ((beadState1.width * beadState1.height) << 3) * sizeof(uint8)); - } - x = beadState1.x = 60; - y = beadState1.y = 40; - initBeadState(x, y, x, 25, 8, &beadState2); - } else { - if (processBead(beadState1.x, beadState1.y, x, y, &beadState2)) { - _beadStateVar = 3; - timer2 = _system->getMillis() + 240 * _tickLength; - _unkEndSeqVar4 = 0; - beadState1.dstX = beadState1.x; - beadState1.dstY = beadState1.y; - return 0; - } else { - _screen->copyFromCurPageBlock(beadState1.x >> 3, beadState1.y, beadState1.width, beadState1.height, _endSequenceBackUpRect); - _screen->addBitBlitRect(beadState1.x, beadState1.y, beadState1.width2, beadState1.height); - beadState1.x = x; - beadState1.y = y; - } - } - - _screen->copyCurPageBlock(x >> 3, y, beadState1.width, beadState1.height, _endSequenceBackUpRect); - _screen->drawShape(2, _panPagesTable[_lastDisplayedPanPage++], x, y, 0, 0); - - if (_lastDisplayedPanPage > 17) - _lastDisplayedPanPage = 0; - - _screen->addBitBlitRect(x, y, beadState1.width2, beadState1.height); - } - break; - - case 3: - if (_system->getMillis() >= timer1) { - timer1 = _system->getMillis() + 4 * _tickLength; - _screen->copyFromCurPageBlock(beadState1.x >> 3, beadState1.y, beadState1.width, beadState1.height, _endSequenceBackUpRect); - _screen->addBitBlitRect(beadState1.x, beadState1.y, beadState1.width2, beadState1.height); - - beadState1.x = beadState1.dstX + table1[beadState1.tableIndex]; - beadState1.y = beadState1.dstY + table2[beadState1.tableIndex]; - _screen->copyCurPageBlock(beadState1.x >> 3, beadState1.y, beadState1.width, beadState1.height, _endSequenceBackUpRect); - - _screen->drawShape(2, _panPagesTable[_lastDisplayedPanPage++], beadState1.x, beadState1.y, 0, 0); - if (_lastDisplayedPanPage >= 17) - _lastDisplayedPanPage = 0; - - _screen->addBitBlitRect(beadState1.x, beadState1.y, beadState1.width2, beadState1.height); - - ++beadState1.tableIndex; - if (beadState1.tableIndex > 24) - beadState1.tableIndex = 0; - _unkEndSeqVar4 = 1; - if (_system->getMillis() > timer2 && _malcolmFlag == 7 && !_unkAmuletVar && !_text->printed()) { - snd_playSoundEffect(0x0B); - if (_currentCharacter->x1 > 233 && _currentCharacter->x1 < 305 && _currentCharacter->y1 > 85 && _currentCharacter->y1 < 105 && - (_brandonStatusBit & 0x20)) { - beadState1.unk8 = 290; - beadState1.unk9 = 40; - _beadStateVar = 5; - } else { - _beadStateVar = 4; - beadState1.unk8 = _currentCharacter->x1 - 4; - beadState1.unk9 = _currentCharacter->y1 - 30; - } - - if (_text->printed()) - _text->restoreTalkTextMessageBkgd(2, 0); - - initBeadState(beadState1.x, beadState1.y, beadState1.unk8, beadState1.unk9, 12, &beadState2); - _lastDisplayedPanPage = 18; - } - } - break; - - case 4: - if (_system->getMillis() >= timer1) { - int x = 0, y = 0; - timer1 = _system->getMillis() + _tickLength; - if (processBead(beadState1.x, beadState1.y, x, y, &beadState2)) { - if (_brandonStatusBit & 20) { - _unkEndSeqVar5 = 2; - _beadStateVar = 6; - } else { - snd_playWanderScoreViaMap(52, 1); - snd_playSoundEffect(0x0C); - _unkEndSeqVar5 = 1; - _beadStateVar = 0; - } - } else { - _screen->copyFromCurPageBlock(beadState1.x >> 3, beadState1.y, beadState1.width, beadState1.height, _endSequenceBackUpRect); - _screen->addBitBlitRect(beadState1.x, beadState1.y, beadState1.width2, beadState1.height); - beadState1.x = x; - beadState1.y = y; - _screen->copyCurPageBlock(beadState1.x >> 3, beadState1.y, beadState1.width, beadState1.height, _endSequenceBackUpRect); - _screen->drawShape(2, _panPagesTable[_lastDisplayedPanPage++], x, y, 0, 0); - if (_lastDisplayedPanPage > 17) { - _lastDisplayedPanPage = 0; - } - _screen->addBitBlitRect(beadState1.x, beadState1.y, beadState1.width2, beadState1.height); - } - } - break; - - case 5: - if (_system->getMillis() >= timer1) { - timer1 = _system->getMillis() + _tickLength; - int x = 0, y = 0; - if (processBead(beadState1.x, beadState1.y, x, y, &beadState2)) { - if (beadState2.dstX == 290) { - _screen->copyFromCurPageBlock(beadState1.x >> 3, beadState1.y, beadState1.width, beadState1.height, _endSequenceBackUpRect); - uint32 nextRun = 0; - _finalB->setX(224); - _finalB->setY(8); - _finalB->setDrawPage(0); - for (int i = 0; i < 8; ++i) { - nextRun = _system->getMillis() + _tickLength; - _finalB->displayFrame(i); - _screen->updateScreen(); - delayUntil(nextRun); - } - snd_playSoundEffect(0x0D); - for (int i = 7; i >= 0; --i) { - nextRun = _system->getMillis() + _tickLength; - _finalB->displayFrame(i); - _screen->updateScreen(); - delayUntil(nextRun); - } - initBeadState(beadState1.x, beadState1.y, 63, 60, 12, &beadState2); - } else { - _screen->copyFromCurPageBlock(beadState1.x >> 3, beadState1.y, beadState1.width, beadState1.height, _endSequenceBackUpRect); - _screen->addBitBlitRect(beadState1.x, beadState1.y, beadState1.width2, beadState1.height); - beadState1.x = -1; - beadState1.tableIndex = 0; - _beadStateVar = 0; - _malcolmFlag = 9; - } - } else { - _screen->copyFromCurPageBlock(beadState1.x >> 3, beadState1.y, beadState1.width, beadState1.height, _endSequenceBackUpRect); - _screen->addBitBlitRect(beadState1.x, beadState1.y, beadState1.width2, beadState1.height); - beadState1.x = x; - beadState1.y = y; - _screen->copyCurPageBlock(beadState1.x >> 3, beadState1.y, beadState1.width, beadState1.height, _endSequenceBackUpRect); - _screen->drawShape(2, _panPagesTable[_lastDisplayedPanPage++], x, y, 0, 0); - if (_lastDisplayedPanPage > 17) - _lastDisplayedPanPage = 0; - _screen->addBitBlitRect(beadState1.x, beadState1.y, beadState1.width2, beadState1.height); - } - } - break; - - case 6: - _screen->drawShape(2, _panPagesTable[19], beadState1.x, beadState1.y, 0, 0); - _screen->addBitBlitRect(beadState1.x, beadState1.y, beadState1.width2, beadState1.height); - _beadStateVar = 0; - break; - - default: - break; - } - return 0; -} - -void KyraEngine_v1::initBeadState(int x, int y, int x2, int y2, int unk, BeadState *ptr) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::initBeadState(%d, %d, %d, %d, %d, %p)", x, y, x2, y2, unk, (const void *)ptr); - ptr->unk9 = unk; - int xDiff = x2 - x; - int yDiff = y2 - y; - int unk1 = 0, unk2 = 0; - if (xDiff > 0) - unk1 = 1; - else if (xDiff == 0) - unk1 = 0; - else - unk1 = -1; - - - if (yDiff > 0) - unk2 = 1; - else if (yDiff == 0) - unk2 = 0; - else - unk2 = -1; - - xDiff = ABS(xDiff); - yDiff = ABS(yDiff); - - ptr->y = 0; - ptr->x = 0; - ptr->width = xDiff; - ptr->height = yDiff; - ptr->dstX = x2; - ptr->dstY = y2; - ptr->width2 = unk1; - ptr->unk8 = unk2; -} - -int KyraEngine_v1::processBead(int x, int y, int &x2, int &y2, BeadState *ptr) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::processBead(%d, %d, %p, %p, %p)", x, y, (const void *)&x2, (const void *)&y2, (const void *)ptr); - if (x == ptr->dstX && y == ptr->dstY) - return 1; - - int xPos = x, yPos = y; - if (ptr->width >= ptr->height) { - for (int i = 0; i < ptr->unk9; ++i) { - ptr->y += ptr->height; - if (ptr->y >= ptr->width) { - ptr->y -= ptr->width; - yPos += ptr->unk8; - } - xPos += ptr->width2; - } - } else { - for (int i = 0; i < ptr->unk9; ++i) { - ptr->x += ptr->width; - if (ptr->x >= ptr->height) { - ptr->x -= ptr->height; - xPos += ptr->width2; - } - yPos += ptr->unk8; - } - } - - int temp = ABS(x - ptr->dstX); - if (ptr->unk9 > temp) - xPos = ptr->dstX; - temp = ABS(y - ptr->dstY); - if (ptr->unk9 > temp) - yPos = ptr->dstY; - x2 = xPos; - y2 = yPos; - return 0; -} - -void KyraEngine_v1::setupPanPages() { - debugC(9, kDebugLevelMain, "KyraEngine_v1::setupPanPages()"); - _screen->savePageToDisk("BKGD.PG", 2); - _screen->loadBitmap("BEAD.CPS", 3, 3, 0); - if (_flags.platform == Common::kPlatformMacintosh || _flags.platform == Common::kPlatformAmiga) { - int pageBackUp = _screen->_curPage; - _screen->_curPage = 2; - - delete[] _panPagesTable[19]; - _panPagesTable[19] = _screen->encodeShape(0, 0, 16, 9, 0); - assert(_panPagesTable[19]); - - int curX = 16; - for (int i = 0; i < 19; ++i) { - delete[] _panPagesTable[i]; - _panPagesTable[i] = _screen->encodeShape(curX, 0, 8, 5, 0); - assert(_panPagesTable[i]); - curX += 8; - } - - _screen->_curPage = pageBackUp; - } else { - for (int i = 0; i <= 19; ++i) { - delete[] _panPagesTable[i]; - _panPagesTable[i] = _seq->setPanPages(3, i); - assert(_panPagesTable[i]); - } - } - _screen->loadPageFromDisk("BKGD.PG", 2); -} - -void KyraEngine_v1::freePanPages() { - debugC(9, kDebugLevelMain, "KyraEngine_v1::freePanPages()"); - delete _endSequenceBackUpRect; - _endSequenceBackUpRect = 0; - for (int i = 0; i <= 19; ++i) { - delete[] _panPagesTable[i]; - _panPagesTable[i] = 0; - } -} - -void KyraEngine_v1::closeFinalWsa() { - debugC(9, kDebugLevelMain, "KyraEngine_v1::closeFinalWsa()"); - delete _finalA; - _finalA = 0; - delete _finalB; - _finalB = 0; - delete _finalC; - _finalC = 0; - freePanPages(); - _endSequenceNeedLoading = 1; -} - -void KyraEngine_v1::updateKyragemFading() { - static const uint8 kyraGemPalette[0x28] = { - 0x3F, 0x3B, 0x38, 0x34, 0x32, 0x2F, 0x2C, 0x29, 0x25, 0x22, - 0x1F, 0x1C, 0x19, 0x16, 0x12, 0x0F, 0x0C, 0x0A, 0x06, 0x03, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; - - if (_system->getMillis() < _kyragemFadingState.timerCount) - return; - - _kyragemFadingState.timerCount = _system->getMillis() + 4 * _tickLength; - int palPos = 684; - for (int i = 0; i < 20; ++i) { - _screen->_currentPalette[palPos++] = kyraGemPalette[i + _kyragemFadingState.rOffset]; - _screen->_currentPalette[palPos++] = kyraGemPalette[i + _kyragemFadingState.gOffset]; - _screen->_currentPalette[palPos++] = kyraGemPalette[i + _kyragemFadingState.bOffset]; - } - _screen->setScreenPalette(_screen->_currentPalette); - _animator->_updateScreen = true; - switch (_kyragemFadingState.nextOperation) { - case 0: - --_kyragemFadingState.bOffset; - if (_kyragemFadingState.bOffset >= 1) - return; - _kyragemFadingState.nextOperation = 1; - break; - - case 1: - ++_kyragemFadingState.rOffset; - if (_kyragemFadingState.rOffset < 19) - return; - _kyragemFadingState.nextOperation = 2; - break; - - case 2: - --_kyragemFadingState.gOffset; - if (_kyragemFadingState.gOffset >= 1) - return; - _kyragemFadingState.nextOperation = 3; - break; - - case 3: - ++_kyragemFadingState.bOffset; - if (_kyragemFadingState.bOffset < 19) - return; - _kyragemFadingState.nextOperation = 4; - break; - - case 4: - --_kyragemFadingState.rOffset; - if (_kyragemFadingState.rOffset >= 1) - return; - _kyragemFadingState.nextOperation = 5; - break; - - case 5: - ++_kyragemFadingState.gOffset; - if (_kyragemFadingState.gOffset < 19) - return; - _kyragemFadingState.nextOperation = 0; - break; - - default: - break; - } - - _kyragemFadingState.timerCount = _system->getMillis() + 120 * _tickLength; -} - -void KyraEngine_v1::drawJewelPress(int jewel, int drawSpecial) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::drawJewelPress(%d, %d)", jewel, drawSpecial); - _screen->hideMouse(); - int shape = 0; - - if (drawSpecial) - shape = 0x14E; - else - shape = jewel + 0x149; - - snd_playSoundEffect(0x45); - _screen->drawShape(0, _shapes[shape], _amuletX2[jewel], _amuletY2[jewel], 0, 0); - _screen->updateScreen(); - delayWithTicks(2); - - if (drawSpecial) - shape = 0x148; - else - shape = jewel + 0x143; - - _screen->drawShape(0, _shapes[shape], _amuletX2[jewel], _amuletY2[jewel], 0, 0); - _screen->updateScreen(); - _screen->showMouse(); -} - -void KyraEngine_v1::drawJewelsFadeOutStart() { - debugC(9, kDebugLevelMain, "KyraEngine_v1::drawJewelsFadeOutStart()"); - static const uint16 jewelTable1[] = { 0x164, 0x15F, 0x15A, 0x155, 0x150, 0xFFFF }; - static const uint16 jewelTable2[] = { 0x163, 0x15E, 0x159, 0x154, 0x14F, 0xFFFF }; - static const uint16 jewelTable3[] = { 0x166, 0x160, 0x15C, 0x157, 0x152, 0xFFFF }; - static const uint16 jewelTable4[] = { 0x165, 0x161, 0x15B, 0x156, 0x151, 0xFFFF }; - for (int i = 0; jewelTable1[i] != 0xFFFF; ++i) { - if (queryGameFlag(0x57)) - _screen->drawShape(0, _shapes[jewelTable1[i]], _amuletX2[2], _amuletY2[2], 0, 0); - if (queryGameFlag(0x59)) - _screen->drawShape(0, _shapes[jewelTable3[i]], _amuletX2[4], _amuletY2[4], 0, 0); - if (queryGameFlag(0x56)) - _screen->drawShape(0, _shapes[jewelTable2[i]], _amuletX2[1], _amuletY2[1], 0, 0); - if (queryGameFlag(0x58)) - _screen->drawShape(0, _shapes[jewelTable4[i]], _amuletX2[3], _amuletY2[3], 0, 0); - _screen->updateScreen(); - delayWithTicks(3); - } -} - -void KyraEngine_v1::drawJewelsFadeOutEnd(int jewel) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::drawJewelsFadeOutEnd(%d)", jewel); - static const uint16 jewelTable[] = { 0x153, 0x158, 0x15D, 0x162, 0x148, 0xFFFF }; - int newDelay = 0; - - switch (jewel - 1) { - case 2: - if (_currentCharacter->sceneId >= 109 && _currentCharacter->sceneId <= 198) - newDelay = 18900; - else - newDelay = 8100; - break; - - default: - newDelay = 3600; - break; - } - - setGameFlag(0xF1); - _timer->setCountdown(19, newDelay); - _screen->hideMouse(); - for (int i = 0; jewelTable[i] != 0xFFFF; ++i) { - uint16 shape = jewelTable[i]; - if (queryGameFlag(0x57)) - _screen->drawShape(0, _shapes[shape], _amuletX2[2], _amuletY2[2], 0, 0); - if (queryGameFlag(0x59)) - _screen->drawShape(0, _shapes[shape], _amuletX2[4], _amuletY2[4], 0, 0); - if (queryGameFlag(0x56)) - _screen->drawShape(0, _shapes[shape], _amuletX2[1], _amuletY2[1], 0, 0); - if (queryGameFlag(0x58)) - _screen->drawShape(0, _shapes[shape], _amuletX2[3], _amuletY2[3], 0, 0); - - _screen->updateScreen(); - delayWithTicks(3); - } - _screen->showMouse(); -} - -} // end of namespace Kyra - diff --git a/engines/kyra/sound_lok.cpp b/engines/kyra/sound_lok.cpp new file mode 100644 index 0000000000..398ac085c4 --- /dev/null +++ b/engines/kyra/sound_lok.cpp @@ -0,0 +1,83 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "kyra/sound.h" +#include "kyra/kyra_lok.h" + +namespace Kyra { + +void KyraEngine_LoK::snd_playSoundEffect(int track, int volume) { + debugC(9, kDebugLevelMain | kDebugLevelSound, "KyraEngine_LoK::snd_playSoundEffect(%d, %d)", track, volume); + if ((_flags.platform == Common::kPlatformFMTowns || _flags.platform == Common::kPlatformPC98) && track == 49) { + snd_playWanderScoreViaMap(56, 1); + return; + } + + KyraEngine::snd_playSoundEffect(track); +} + +void KyraEngine_LoK::snd_playWanderScoreViaMap(int command, int restart) { + debugC(9, kDebugLevelMain | kDebugLevelSound, "KyraEngine_LoK::snd_playWanderScoreViaMap(%d, %d)", command, restart); + if (restart) + _lastMusicCommand = -1; + + if (_flags.platform == Common::kPlatformFMTowns || _flags.platform == Common::kPlatformPC98) { + if (command == 1) { + _sound->beginFadeOut(); + } else if (command >= 35 && command <= 38) { + snd_playSoundEffect(command-20); + } else if (command >= 2) { + if (_lastMusicCommand != command) { + // the original does -2 here we handle this inside _sound->playTrack() + _sound->playTrack(command); + } + } else { + _sound->haltTrack(); + } + } else { + KyraEngine::snd_playWanderScoreViaMap(command, restart); + } +} + +void KyraEngine_LoK::snd_playVoiceFile(int id) { + debugC(9, kDebugLevelMain | kDebugLevelSound, "KyraEngine_LoK::snd_playVoiceFile(%d)", id); + char vocFile[9]; + assert(id >= 0 && id < 9999); + sprintf(vocFile, "%03d", id); + _speechFile = vocFile; + _sound->voicePlay(vocFile); +} + +void KyraEngine_LoK::snd_voiceWaitForFinish(bool ingame) { + debugC(9, kDebugLevelMain | kDebugLevelSound, "KyraEngine_LoK::snd_voiceWaitForFinish(%d)", ingame); + while (_sound->voiceIsPlaying() && !_skipFlag) { + if (ingame) + delay(10, true); + else + _system->delayMillis(10); + } +} + +} // end of namespace Kyra diff --git a/engines/kyra/sound_v1.cpp b/engines/kyra/sound_v1.cpp deleted file mode 100644 index 8293eb7508..0000000000 --- a/engines/kyra/sound_v1.cpp +++ /dev/null @@ -1,83 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include "kyra/sound.h" -#include "kyra/kyra_v1.h" - -namespace Kyra { - -void KyraEngine_v1::snd_playSoundEffect(int track, int volume) { - debugC(9, kDebugLevelMain | kDebugLevelSound, "KyraEngine_v1::snd_playSoundEffect(%d, %d)", track, volume); - if ((_flags.platform == Common::kPlatformFMTowns || _flags.platform == Common::kPlatformPC98) && track == 49) { - snd_playWanderScoreViaMap(56, 1); - return; - } - - KyraEngine::snd_playSoundEffect(track); -} - -void KyraEngine_v1::snd_playWanderScoreViaMap(int command, int restart) { - debugC(9, kDebugLevelMain | kDebugLevelSound, "KyraEngine_v1::snd_playWanderScoreViaMap(%d, %d)", command, restart); - if (restart) - _lastMusicCommand = -1; - - if (_flags.platform == Common::kPlatformFMTowns || _flags.platform == Common::kPlatformPC98) { - if (command == 1) { - _sound->beginFadeOut(); - } else if (command >= 35 && command <= 38) { - snd_playSoundEffect(command-20); - } else if (command >= 2) { - if (_lastMusicCommand != command) { - // the original does -2 here we handle this inside _sound->playTrack() - _sound->playTrack(command); - } - } else { - _sound->haltTrack(); - } - } else { - KyraEngine::snd_playWanderScoreViaMap(command, restart); - } -} - -void KyraEngine_v1::snd_playVoiceFile(int id) { - debugC(9, kDebugLevelMain | kDebugLevelSound, "KyraEngine_v1::snd_playVoiceFile(%d)", id); - char vocFile[9]; - assert(id >= 0 && id < 9999); - sprintf(vocFile, "%03d", id); - _speechFile = vocFile; - _sound->voicePlay(vocFile); -} - -void KyraEngine_v1::snd_voiceWaitForFinish(bool ingame) { - debugC(9, kDebugLevelMain | kDebugLevelSound, "KyraEngine_v1::snd_voiceWaitForFinish(%d)", ingame); - while (_sound->voiceIsPlaying() && !_skipFlag) { - if (ingame) - delay(10, true); - else - _system->delayMillis(10); - } -} - -} // end of namespace Kyra diff --git a/engines/kyra/sprites.cpp b/engines/kyra/sprites.cpp index 0ba9f456bf..34c2986f25 100644 --- a/engines/kyra/sprites.cpp +++ b/engines/kyra/sprites.cpp @@ -30,14 +30,14 @@ #include "common/system.h" #include "common/events.h" #include "kyra/screen.h" -#include "kyra/kyra_v1.h" +#include "kyra/kyra_lok.h" #include "kyra/sprites.h" #include "kyra/resource.h" -#include "kyra/animator_v1.h" +#include "kyra/animator_lok.h" namespace Kyra { -Sprites::Sprites(KyraEngine_v1 *vm, OSystem *system) { +Sprites::Sprites(KyraEngine_LoK *vm, OSystem *system) { _vm = vm; _res = vm->resource(); _screen = vm->screen(); @@ -554,7 +554,7 @@ void Sprites::loadSceneShapes() { void Sprites::refreshSceneAnimObject(uint8 animNum, uint8 shapeNum, uint16 x, uint16 y, bool flipX, bool unkFlag) { debugC(9, kDebugLevelSprites, "Sprites::refreshSceneAnimObject(%i, %i, %i, %i, %i, %i", animNum, shapeNum, x, y, flipX, unkFlag); - Animator_v1::AnimObject &anim = _vm->animator()->sprites()[animNum]; + Animator_LoK::AnimObject &anim = _vm->animator()->sprites()[animNum]; anim.refreshFlag = 1; anim.bkgdChangeFlag = 1; diff --git a/engines/kyra/sprites.h b/engines/kyra/sprites.h index 3304458fda..212bfc7428 100644 --- a/engines/kyra/sprites.h +++ b/engines/kyra/sprites.h @@ -26,7 +26,7 @@ #ifndef KYRA_SPRITES_H #define KYRA_SPRITES_H -#include "kyra/kyra_v1.h" +#include "kyra/kyra_lok.h" namespace Kyra { @@ -63,11 +63,11 @@ struct Anim { bool disable; }; -class KyraEngine_v1; +class KyraEngine_LoK; class Sprites { public: - Sprites(KyraEngine_v1 *vm, OSystem *system); + Sprites(KyraEngine_LoK *vm, OSystem *system); ~Sprites(); void updateSceneAnims(); @@ -86,7 +86,7 @@ public: protected: void freeSceneShapes(); - KyraEngine_v1 *_vm; + KyraEngine_LoK *_vm; Resource *_res; OSystem *_system; Screen *_screen; diff --git a/engines/kyra/staticres.cpp b/engines/kyra/staticres.cpp index b81a5838ce..dbe181b84f 100644 --- a/engines/kyra/staticres.cpp +++ b/engines/kyra/staticres.cpp @@ -27,16 +27,16 @@ #include "common/endian.h" #include "common/md5.h" #include "kyra/kyra.h" -#include "kyra/kyra_v1.h" +#include "kyra/kyra_lok.h" #include "kyra/kyra_v2.h" #include "kyra/kyra_hof.h" #include "kyra/kyra_mr.h" #include "kyra/screen.h" -#include "kyra/screen_v1.h" +#include "kyra/screen_lok.h" #include "kyra/screen_hof.h" #include "kyra/screen_mr.h" #include "kyra/resource.h" -#include "kyra/gui_v1.h" +#include "kyra/gui_lok.h" #include "kyra/gui_hof.h" #include "kyra/gui_mr.h" @@ -932,7 +932,7 @@ uint8 *StaticResource::getFile(const char *name, int &size) { #pragma mark - -void KyraEngine_v1::initStaticResource() { +void KyraEngine_LoK::initStaticResource() { int temp = 0; _seq_Forest = _staticres->loadRawData(kForestSeq, temp); _seq_KallakWriting = _staticres->loadRawData(kKallakWritingSeq, temp); @@ -1041,7 +1041,7 @@ void KyraEngine_v1::initStaticResource() { _soundData = (_flags.platform == Common::kPlatformPC) ? soundData_PC : soundData_TOWNS; } -void KyraEngine_v1::loadMouseShapes() { +void KyraEngine_LoK::loadMouseShapes() { _screen->loadBitmap("MOUSE.CPS", 3, 3, 0); _screen->_curPage = 2; _shapes[0] = _screen->encodeShape(0, 0, 8, 10, 0); @@ -1057,7 +1057,7 @@ void KyraEngine_v1::loadMouseShapes() { _screen->setShapePages(5, 3); } -void KyraEngine_v1::loadCharacterShapes() { +void KyraEngine_LoK::loadCharacterShapes() { int curImage = 0xFF; int videoPage = _screen->_curPage; _screen->_curPage = 2; @@ -1078,7 +1078,7 @@ void KyraEngine_v1::loadCharacterShapes() { _screen->_curPage = videoPage; } -void KyraEngine_v1::loadSpecialEffectShapes() { +void KyraEngine_LoK::loadSpecialEffectShapes() { _screen->loadBitmap("EFFECTS.CPS", 3, 3, 0); _screen->_curPage = 2; @@ -1096,7 +1096,7 @@ void KyraEngine_v1::loadSpecialEffectShapes() { _shapes[currShape] = _screen->encodeShape((currShape-201) * 16, 106, 16, 16, 1); } -void KyraEngine_v1::loadItems() { +void KyraEngine_LoK::loadItems() { int shape; _screen->loadBitmap("JEWELS3.CPS", 3, 3, 0); @@ -1150,7 +1150,7 @@ void KyraEngine_v1::loadItems() { delete[] fileData; } -void KyraEngine_v1::loadButtonShapes() { +void KyraEngine_LoK::loadButtonShapes() { _screen->loadBitmap("BUTTONS2.CPS", 3, 3, 0); _screen->_curPage = 2; _gui->_scrollUpButton.data0ShapePtr = _screen->encodeShape(0, 0, 24, 14, 1); @@ -1162,7 +1162,7 @@ void KyraEngine_v1::loadButtonShapes() { _screen->_curPage = 0; } -void KyraEngine_v1::loadMainScreen(int page) { +void KyraEngine_LoK::loadMainScreen(int page) { _screen->clearPage(page); if (_flags.lang == Common::EN_ANY && !_flags.isTalkie && (_flags.platform == Common::kPlatformPC || _flags.platform == Common::kPlatformAmiga)) @@ -1296,7 +1296,7 @@ void KyraEngine_HoF::initStaticResource() { _callbackN = (_flags.isDemo && !_flags.isTalkie) ? hofDemoNestedSequenceCallbacks : hofNestedSequenceCallbacks; } -const ScreenDim Screen_v1::_screenDimTable[] = { +const ScreenDim Screen_LoK::_screenDimTable[] = { { 0x00, 0x00, 0x28, 0xC8, 0x0F, 0x0C, 0x00, 0x00 }, { 0x08, 0x48, 0x18, 0x38, 0x0F, 0x0C, 0x00, 0x00 }, { 0x01, 0x08, 0x26, 0x80, 0x0F, 0x0C, 0x00, 0x00 }, @@ -1310,7 +1310,7 @@ const ScreenDim Screen_v1::_screenDimTable[] = { { 0x03, 0x28, 0x22, 0x46, 0x0F, 0x0D, 0x00, 0x00 } }; -const int Screen_v1::_screenDimTableCount = ARRAYSIZE(Screen_v1::_screenDimTable); +const int Screen_LoK::_screenDimTableCount = ARRAYSIZE(Screen_LoK::_screenDimTable); const ScreenDim Screen_HoF::_screenDimTable[] = { { 0x00, 0x00, 0x28, 0xC8, 0xC7, 0xCF, 0x00, 0x00 }, @@ -1346,23 +1346,23 @@ const int8 KyraEngine::_addYPosTable[] = { 0, -2, -2, -2, 0, 2, 2, 2 }; -const int8 KyraEngine_v1::_charXPosTable[] = { +const int8 KyraEngine_LoK::_charXPosTable[] = { 0, 4, 4, 4, 0, -4, -4, -4 }; -const int8 KyraEngine_v1::_charYPosTable[] = { +const int8 KyraEngine_LoK::_charYPosTable[] = { -2, -2, 0, 2, 2, 2, 0, -2 }; -const uint16 KyraEngine_v1::_itemPosX[] = { +const uint16 KyraEngine_LoK::_itemPosX[] = { 95, 115, 135, 155, 175, 95, 115, 135, 155, 175 }; -const uint8 KyraEngine_v1::_itemPosY[] = { +const uint8 KyraEngine_LoK::_itemPosY[] = { 160, 160, 160, 160, 160, 181, 181, 181, 181, 181 }; -void GUI_v1::initStaticResource() { +void GUI_LoK::initStaticResource() { GUI_V1_BUTTON(_scrollUpButton, 0x12, 1, 1, 1, 0x483, 0, 0, 0, 0x18, 0x0f, 0); GUI_V1_BUTTON(_scrollDownButton, 0x13, 1, 1, 1, 0x483, 0, 0, 0, 0x18, 0x0f, 0); @@ -1377,9 +1377,9 @@ void GUI_v1::initStaticResource() { _menu = new Menu[6]; assert(_menu); - Button::Callback quitPlayingFunctor = BUTTON_FUNCTOR(GUI_v1, this, &GUI_v1::quitPlaying); - Button::Callback loadGameMenuFunctor = BUTTON_FUNCTOR(GUI_v1, this, &GUI_v1::loadGameMenu); - Button::Callback cancelSubMenuFunctor = BUTTON_FUNCTOR(GUI_v1, this, &GUI_v1::cancelSubMenu); + Button::Callback quitPlayingFunctor = BUTTON_FUNCTOR(GUI_LoK, this, &GUI_LoK::quitPlaying); + Button::Callback loadGameMenuFunctor = BUTTON_FUNCTOR(GUI_LoK, this, &GUI_LoK::loadGameMenu); + Button::Callback cancelSubMenuFunctor = BUTTON_FUNCTOR(GUI_LoK, this, &GUI_LoK::cancelSubMenu); GUI_V1_MENU(_menu[0], -1, -1, 0x100, 0x8B, 248, 249, 250, 0, 251, -1, 8, 0, 5, -1, -1, -1, -1); GUI_V1_MENU_ITEM(_menu[0].item[0], 1, 0, 0, 0, -1, -1, 0x1E, 0xDC, 0x0F, 252, 253, -1, 0, 248, 249, 250, -1, 0, 0, 0, 0, 0); @@ -1388,16 +1388,16 @@ void GUI_v1::initStaticResource() { GUI_V1_MENU_ITEM(_menu[0].item[3], 1, 0, 0, 0, -1, -1, 0x51, 0xDC, 0x0F, 252, 253, -1, 0, 248, 249, 250, -1, 0, 0, 0, 0, 0); GUI_V1_MENU_ITEM(_menu[0].item[4], 1, 0, 0, 0, -1, 0, 0x6E, 0xDC, 0x0F, 252, 253, -1, 255, 248, 249, 250, -1, 0, 0, 0, 0, 0); _menu[0].item[0].callback = loadGameMenuFunctor; - _menu[0].item[1].callback = BUTTON_FUNCTOR(GUI_v1, this, &GUI_v1::saveGameMenu); - _menu[0].item[2].callback = BUTTON_FUNCTOR(GUI_v1, this, &GUI_v1::gameControlsMenu); + _menu[0].item[1].callback = BUTTON_FUNCTOR(GUI_LoK, this, &GUI_LoK::saveGameMenu); + _menu[0].item[2].callback = BUTTON_FUNCTOR(GUI_LoK, this, &GUI_LoK::gameControlsMenu); _menu[0].item[3].callback = quitPlayingFunctor; - _menu[0].item[4].callback = BUTTON_FUNCTOR(GUI_v1, this, &GUI_v1::resumeGame); + _menu[0].item[4].callback = BUTTON_FUNCTOR(GUI_LoK, this, &GUI_LoK::resumeGame); GUI_V1_MENU(_menu[1], -1, -1, 0x140, 0x38, 248, 249, 250, 0, 254,-1, 8, 0, 2, -1, -1, -1, -1); GUI_V1_MENU_ITEM(_menu[1].item[0], 1, 0, 0, 0, 0x18, 0, 0x1E, 0x48, 0x0F, 252, 253, -1, 255, 248, 249, 250, -1, 0, 0, 0, 0, 0); GUI_V1_MENU_ITEM(_menu[1].item[1], 1, 0, 0, 0, 0xD8, 0, 0x1E, 0x48, 0x0F, 252, 253, -1, 255, 248, 249, 250, -1, 0, 0, 0, 0, 0); - _menu[1].item[0].callback = BUTTON_FUNCTOR(GUI_v1, this, &GUI_v1::quitConfirmYes); - _menu[1].item[1].callback = BUTTON_FUNCTOR(GUI_v1, this, &GUI_v1::quitConfirmNo); + _menu[1].item[0].callback = BUTTON_FUNCTOR(GUI_LoK, this, &GUI_LoK::quitConfirmYes); + _menu[1].item[1].callback = BUTTON_FUNCTOR(GUI_LoK, this, &GUI_LoK::quitConfirmNo); GUI_V1_MENU(_menu[2], -1, -1, 0x120, 0xA0, 248, 249, 250, 0, 251, -1, 8, 0, 6, 132, 22, 132, 124); GUI_V1_MENU_ITEM(_menu[2].item[0], 1, 0, 0, 0, -1, 255, 0x27, 0x100, 0x0F, 252, 253, 5, 0, 248, 249, 250, -1, 0, 0, 0, 0, 0); @@ -1411,7 +1411,7 @@ void GUI_v1::initStaticResource() { GUI_V1_MENU(_menu[3], -1, -1, 288, 67, 248, 249, 250, 0, 251, -1, 8, 0, 2, -1, -1, -1, -1); GUI_V1_MENU_ITEM(_menu[3].item[0], 1, 0, 0, 0, 24, 0, 44, 85, 15, 252, 253, -1, 255, 248, 249, 250, -1, 0, 0, 0, 0, 0); GUI_V1_MENU_ITEM(_menu[3].item[1], 1, 0, 0, 0, 179, 0, 44, 85, 15, 252, 253, -1, 255, 248, 249, 250, -1, 0, 0, 0, 0, 0); - _menu[3].item[0].callback = BUTTON_FUNCTOR(GUI_v1, this, &GUI_v1::savegameConfirm); + _menu[3].item[0].callback = BUTTON_FUNCTOR(GUI_LoK, this, &GUI_LoK::savegameConfirm); _menu[3].item[1].callback = cancelSubMenuFunctor; GUI_V1_MENU(_menu[4], -1, -1, 0xD0, 0x4C, 248, 249, 250, 0, 251, -1, 8, 0, 2, -1, -1, -1, -1); @@ -1427,14 +1427,14 @@ void GUI_v1::initStaticResource() { GUI_V1_MENU_ITEM(_menu[5].item[3], 1, 0, 0, 0, 0xA5, 0, 0x51, 0x80, 0x0F, 252, 253, 5, 0, 248, 249, 250, -1, 0, 0x10, 0x53, 0, 0); GUI_V1_MENU_ITEM(_menu[5].item[4], 1, 0, 0, 0, 0xA5, 0, 0x62, 0x80, 0x0F, 252, 253, 5, 0, 248, 249, 250, -1, 0, 0x10, 0x65, 0, 0); GUI_V1_MENU_ITEM(_menu[5].item[5], 1, 0, 0, 0, -1, 0, 0x7F, 0x6C, 0x0F, 252, 253, -1, 255, 248, 249, 250, -1, -0, 0, 0, 0, 0); - _menu[5].item[0].callback = BUTTON_FUNCTOR(GUI_v1, this, &GUI_v1::controlsChangeMusic); - _menu[5].item[1].callback = BUTTON_FUNCTOR(GUI_v1, this, &GUI_v1::controlsChangeSounds); - _menu[5].item[2].callback = BUTTON_FUNCTOR(GUI_v1, this, &GUI_v1::controlsChangeWalk); - _menu[5].item[4].callback = BUTTON_FUNCTOR(GUI_v1, this, &GUI_v1::controlsChangeText); - _menu[5].item[5].callback = BUTTON_FUNCTOR(GUI_v1, this, &GUI_v1::controlsApply); + _menu[5].item[0].callback = BUTTON_FUNCTOR(GUI_LoK, this, &GUI_LoK::controlsChangeMusic); + _menu[5].item[1].callback = BUTTON_FUNCTOR(GUI_LoK, this, &GUI_LoK::controlsChangeSounds); + _menu[5].item[2].callback = BUTTON_FUNCTOR(GUI_LoK, this, &GUI_LoK::controlsChangeWalk); + _menu[5].item[4].callback = BUTTON_FUNCTOR(GUI_LoK, this, &GUI_LoK::controlsChangeText); + _menu[5].item[5].callback = BUTTON_FUNCTOR(GUI_LoK, this, &GUI_LoK::controlsApply); } -void KyraEngine_v1::setupButtonData() { +void KyraEngine_LoK::setupButtonData() { delete[] _buttonData; delete[] _buttonDataListPtr; @@ -1444,9 +1444,9 @@ void KyraEngine_v1::setupButtonData() { assert(_buttonDataListPtr); GUI_V1_BUTTON(_buttonData[1], 0x01, 1, 1, 1, 0x0487, 0, 0x009, 0xA4, 0x36, 0x1E, 0); - _buttonData[1].buttonCallback = BUTTON_FUNCTOR(GUI_v1, _gui, &GUI_v1::buttonMenuCallback); + _buttonData[1].buttonCallback = BUTTON_FUNCTOR(GUI_LoK, _gui, &GUI_LoK::buttonMenuCallback); - Button::Callback inventoryFunctor = BUTTON_FUNCTOR(KyraEngine_v1, this, &KyraEngine_v1::buttonInventoryCallback); + Button::Callback inventoryFunctor = BUTTON_FUNCTOR(KyraEngine_LoK, this, &KyraEngine_LoK::buttonInventoryCallback); for (int i = 2; i <= 10; ++i) _buttonData[i].buttonCallback = inventoryFunctor; _buttonData[0].buttonCallback = inventoryFunctor; @@ -1461,7 +1461,7 @@ void KyraEngine_v1::setupButtonData() { GUI_V1_BUTTON(_buttonData[9], 0x0A, 0, 0, 0, 0x0400, 0, 0x099, 0xB3, 0x13, 0x14, 0); GUI_V1_BUTTON(_buttonData[10], 0x0B, 0, 0, 0, 0x0400, 0, 0x0AD, 0xB3, 0x13, 0x14, 0); - Button::Callback amuletFunctor = BUTTON_FUNCTOR(KyraEngine_v1, this, &KyraEngine_v1::buttonAmuletCallback); + Button::Callback amuletFunctor = BUTTON_FUNCTOR(KyraEngine_LoK, this, &KyraEngine_LoK::buttonAmuletCallback); GUI_V1_BUTTON(_buttonData[11], 0x15, 1, 1, 1, 0x0487, 0, 0x0FD, 0x9C, 0x1A, 0x12, 0); GUI_V1_BUTTON(_buttonData[12], 0x16, 1, 1, 1, 0x0487, 0, 0x0E7, 0xAA, 0x1A, 0x12, 0); GUI_V1_BUTTON(_buttonData[13], 0x17, 1, 1, 1, 0x0487, 0, 0x0FD, 0xB5, 0x1A, 0x12, 0); @@ -1474,29 +1474,29 @@ void KyraEngine_v1::setupButtonData() { _buttonDataListPtr[14] = 0; } -const uint8 KyraEngine_v1::_magicMouseItemStartFrame[] = { +const uint8 KyraEngine_LoK::_magicMouseItemStartFrame[] = { 0xAD, 0xB7, 0xBE, 0x00 }; -const uint8 KyraEngine_v1::_magicMouseItemEndFrame[] = { +const uint8 KyraEngine_LoK::_magicMouseItemEndFrame[] = { 0xB1, 0xB9, 0xC2, 0x00 }; -const uint8 KyraEngine_v1::_magicMouseItemStartFrame2[] = { +const uint8 KyraEngine_LoK::_magicMouseItemStartFrame2[] = { 0xB2, 0xBA, 0xC3, 0x00 }; -const uint8 KyraEngine_v1::_magicMouseItemEndFrame2[] = { +const uint8 KyraEngine_LoK::_magicMouseItemEndFrame2[] = { 0xB6, 0xBD, 0xC8, 0x00 }; -const uint16 KyraEngine_v1::_amuletX[] = { 231, 275, 253, 253 }; -const uint16 KyraEngine_v1::_amuletY[] = { 170, 170, 159, 181 }; +const uint16 KyraEngine_LoK::_amuletX[] = { 231, 275, 253, 253 }; +const uint16 KyraEngine_LoK::_amuletY[] = { 170, 170, 159, 181 }; -const uint16 KyraEngine_v1::_amuletX2[] = { 0x000, 0x0FD, 0x0E7, 0x0FD, 0x113, 0x000 }; -const uint16 KyraEngine_v1::_amuletY2[] = { 0x000, 0x09F, 0x0AA, 0x0B5, 0x0AA, 0x000 }; +const uint16 KyraEngine_LoK::_amuletX2[] = { 0x000, 0x0FD, 0x0E7, 0x0FD, 0x113, 0x000 }; +const uint16 KyraEngine_LoK::_amuletY2[] = { 0x000, 0x09F, 0x0AA, 0x0B5, 0x0AA, 0x000 }; -const int8 KyraEngine_v1::_dosTrackMap[] = { +const int8 KyraEngine_LoK::_dosTrackMap[] = { -1, 0, -1, 1, 0, 3, 0, 2, 0, 4, 1, 2, 1, 3, 1, 4, 1, 92, 1, 6, 1, 7, 2, 2, @@ -1513,7 +1513,7 @@ const int8 KyraEngine_v1::_dosTrackMap[] = { 8, 4, 8, 5, 6, 11, 5, 11 }; -const int KyraEngine_v1::_dosTrackMapSize = ARRAYSIZE(KyraEngine_v1::_dosTrackMap); +const int KyraEngine_LoK::_dosTrackMapSize = ARRAYSIZE(KyraEngine_LoK::_dosTrackMap); // kyra engine v2 static data diff --git a/engines/kyra/text_lok.cpp b/engines/kyra/text_lok.cpp new file mode 100644 index 0000000000..ccca079e32 --- /dev/null +++ b/engines/kyra/text_lok.cpp @@ -0,0 +1,399 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "kyra/kyra_lok.h" +#include "kyra/screen_lok.h" +#include "kyra/text.h" +#include "kyra/animator_lok.h" +#include "kyra/sprites.h" +#include "kyra/timer.h" + +namespace Kyra { + +void KyraEngine_LoK::waitForChatToFinish(int vocFile, int16 chatDuration, const char *chatStr, uint8 charNum) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::waitForChatToFinish(%i, %s, %i)", chatDuration, chatStr, charNum); + bool hasUpdatedNPCs = false; + bool runLoop = true; + bool drawText = textEnabled(); + uint8 currPage; + Common::Event event; + + //while (towns_isEscKeyPressed() ) + //towns_getKey(); + + uint32 timeToEnd = strlen(chatStr) * 8 * _tickLength + _system->getMillis(); + + if (_configVoice == 0 && chatDuration != -1) { + switch (_configTextspeed) { + case 0: + chatDuration *= 2; + break; + case 2: + chatDuration /= 4; + break; + case 3: + chatDuration = -1; + break; + } + } + + if (chatDuration != -1) + chatDuration *= _tickLength; + + if (vocFile != -1) { + snd_voiceWaitForFinish(); + snd_playVoiceFile(vocFile); + } + + _timer->disable(14); + _timer->disable(18); + _timer->disable(19); + + uint32 timeAtStart = _system->getMillis(); + uint32 loopStart; + while (runLoop) { + loopStart = _system->getMillis(); + if (_currentCharacter->sceneId == 210) + if (seq_playEnd()) + break; + + if (_system->getMillis() > timeToEnd && !hasUpdatedNPCs) { + hasUpdatedNPCs = true; + _timer->disable(15); + _currHeadShape = 4; + _animator->animRefreshNPC(0); + _animator->animRefreshNPC(_talkingCharNum); + + if (_charSayUnk2 != -1) { + _animator->sprites()[_charSayUnk2].active = 0; + _sprites->_anims[_charSayUnk2].play = false; + _charSayUnk2 = -1; + } + } + + _timer->update(); + _sprites->updateSceneAnims(); + _animator->restoreAllObjectBackgrounds(); + _animator->preserveAnyChangedBackgrounds(); + _animator->prepDrawAllObjects(); + + if (drawText) { + currPage = _screen->_curPage; + _screen->_curPage = 2; + _text->printCharacterText(chatStr, charNum, _characterList[charNum].x1); + _animator->_updateScreen = true; + _screen->_curPage = currPage; + } + + _animator->copyChangedObjectsForward(0); + updateTextFade(); + + if (((chatDuration < (int16)(_system->getMillis() - timeAtStart)) && chatDuration != -1 && drawText) || (!drawText && !snd_voiceIsPlaying())) + break; + + uint32 nextTime = loopStart + _tickLength; + + while (_system->getMillis() < nextTime) { + while (_eventMan->pollEvent(event)) { + switch (event.type) { + case Common::EVENT_KEYDOWN: + if (event.kbd.keycode == '.') + _skipFlag = true; + break; + case Common::EVENT_QUIT: + quitGame(); + runLoop = false; + break; + case Common::EVENT_LBUTTONDOWN: + runLoop = false; + break; + default: + break; + } + } + + if (nextTime - _system->getMillis() >= 10) { + _system->delayMillis(10); + _system->updateScreen(); + } + } + + if (_skipFlag) + runLoop = false; + } + + if (_skipFlag) + snd_stopVoice(); + + _timer->enable(14); + _timer->enable(15); + _timer->enable(18); + _timer->enable(19); + //clearKyrandiaButtonIO(); +} + +void KyraEngine_LoK::endCharacterChat(int8 charNum, int16 convoInitialized) { + _charSayUnk3 = -1; + + if (charNum > 4 && charNum < 11) { + //TODO: weird _game_inventory stuff here + //warning("STUB: endCharacterChat() for high charnums"); + } + + if (convoInitialized != 0) { + _talkingCharNum = -1; + if (_currentCharacter->currentAnimFrame != 88) + _currentCharacter->currentAnimFrame = 7; + _animator->animRefreshNPC(0); + _animator->updateAllObjectShapes(); + } +} + +void KyraEngine_LoK::restoreChatPartnerAnimFrame(int8 charNum) { + _talkingCharNum = -1; + + if (charNum > 0 && charNum < 5) { + _characterList[charNum].currentAnimFrame = _currentChatPartnerBackupFrame; + _animator->animRefreshNPC(charNum); + } + + if (_currentCharacter->currentAnimFrame != 88) + _currentCharacter->currentAnimFrame = 7; + + _animator->animRefreshNPC(0); + _animator->updateAllObjectShapes(); +} + +void KyraEngine_LoK::backupChatPartnerAnimFrame(int8 charNum) { + _talkingCharNum = 0; + + if (charNum < 5 && charNum > 0) + _currentChatPartnerBackupFrame = _characterList[charNum].currentAnimFrame; + + if (_currentCharacter->currentAnimFrame != 88) { + _currentCharacter->currentAnimFrame = 16; + if (_scaleMode != 0) + _currentCharacter->currentAnimFrame = 7; + } + + _animator->animRefreshNPC(0); + _animator->updateAllObjectShapes(); +} + +int8 KyraEngine_LoK::getChatPartnerNum() { + uint8 sceneTable[] = {0x2, 0x5, 0x2D, 0x7, 0x1B, 0x8, 0x22, 0x9, 0x30, 0x0A}; + int pos = 0; + int partner = -1; + + for (int i = 1; i < 6; i++) { + if (_currentCharacter->sceneId == sceneTable[pos]) { + partner = sceneTable[pos+1]; + break; + } + pos += 2; + } + + for (int i = 1; i < 5; i++) { + if (_characterList[i].sceneId == _currentCharacter->sceneId) { + partner = i; + break; + } + } + return partner; +} + +int KyraEngine_LoK::initCharacterChat(int8 charNum) { + int returnValue = 0; + + if (_talkingCharNum == -1) { + returnValue = 1; + _talkingCharNum = 0; + + if (_currentCharacter->currentAnimFrame != 88) { + _currentCharacter->currentAnimFrame = 16; + if (_scaleMode != 0) + _currentCharacter->currentAnimFrame = 7; + } + + _animator->animRefreshNPC(0); + _animator->updateAllObjectShapes(); + } + + _charSayUnk2 = -1; + _animator->flagAllObjectsForBkgdChange(); + _animator->restoreAllObjectBackgrounds(); + + if (charNum > 4 && charNum < 11) { + // TODO: Fill in weird _game_inventory stuff here + //warning("STUB: initCharacterChat() for high charnums"); + } + + _animator->flagAllObjectsForRefresh(); + _animator->flagAllObjectsForBkgdChange(); + _animator->preserveAnyChangedBackgrounds(); + _charSayUnk3 = charNum; + + return returnValue; +} + +void KyraEngine_LoK::characterSays(int vocFile, const char *chatStr, int8 charNum, int8 chatDuration) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::characterSays('%s', %i, %d)", chatStr, charNum, chatDuration); + uint8 startAnimFrames[] = { 0x10, 0x32, 0x56, 0x0, 0x0, 0x0 }; + + uint16 chatTicks; + int16 convoInitialized; + int8 chatPartnerNum; + + if (_currentCharacter->sceneId == 210) + return; + + convoInitialized = initCharacterChat(charNum); + chatPartnerNum = getChatPartnerNum(); + + if (chatPartnerNum >= 0 && chatPartnerNum < 5) + backupChatPartnerAnimFrame(chatPartnerNum); + + if (charNum < 5) { + _characterList[charNum].currentAnimFrame = startAnimFrames[charNum]; + _charSayUnk3 = charNum; + _talkingCharNum = charNum; + _animator->animRefreshNPC(charNum); + } + + char *processedString = _text->preprocessString(chatStr); + int lineNum = _text->buildMessageSubstrings(processedString); + + int16 yPos = _characterList[charNum].y1; + yPos -= ((_scaleTable[yPos] * _characterList[charNum].height) >> 8); + yPos -= 8; + yPos -= lineNum * 10; + + if (yPos < 11) + yPos = 11; + + if (yPos > 100) + yPos = 100; + + _text->_talkMessageY = yPos; + _text->_talkMessageH = lineNum * 10; + + if (textEnabled()) { + _animator->restoreAllObjectBackgrounds(); + + _screen->copyRegion(12, _text->_talkMessageY, 12, 136, 296, _text->_talkMessageH, 2, 2); + _screen->hideMouse(); + + _text->printCharacterText(processedString, charNum, _characterList[charNum].x1); + _screen->showMouse(); + } + + if (chatDuration == -2) + chatTicks = strlen(processedString) * 9; + else + chatTicks = chatDuration; + + if (!speechEnabled()) + vocFile = -1; + waitForChatToFinish(vocFile, chatTicks, chatStr, charNum); + + if (textEnabled()) { + _animator->restoreAllObjectBackgrounds(); + + _screen->copyRegion(12, 136, 12, _text->_talkMessageY, 296, _text->_talkMessageH, 2, 2); + _animator->preserveAllBackgrounds(); + _animator->prepDrawAllObjects(); + _screen->hideMouse(); + + _screen->copyRegion(12, _text->_talkMessageY, 12, _text->_talkMessageY, 296, _text->_talkMessageH, 2, 0); + _screen->showMouse(); + _animator->flagAllObjectsForRefresh(); + _animator->copyChangedObjectsForward(0); + } + + if (chatPartnerNum != -1 && chatPartnerNum < 5) + restoreChatPartnerAnimFrame(chatPartnerNum); + + endCharacterChat(charNum, convoInitialized); +} + +void KyraEngine_LoK::drawSentenceCommand(const char *sentence, int color) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::drawSentenceCommand('%s', %i)", sentence, color); + _screen->hideMouse(); + _screen->fillRect(8, 143, 311, 152, 12); + + if (_startSentencePalIndex != color || _fadeText != false) { + _currSentenceColor[0] = _screen->_currentPalette[765] = _screen->_currentPalette[color*3]; + _currSentenceColor[1] = _screen->_currentPalette[766] = _screen->_currentPalette[color*3+1]; + _currSentenceColor[2] = _screen->_currentPalette[767] = _screen->_currentPalette[color*3+2]; + + _screen->setScreenPalette(_screen->_currentPalette); + _startSentencePalIndex = 0; + } + + _text->printText(sentence, 8, 143, 0xFF, 12, 0); + _screen->showMouse(); + setTextFadeTimerCountdown(15); + _fadeText = false; +} + +void KyraEngine_LoK::updateSentenceCommand(const char *str1, const char *str2, int color) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::updateSentenceCommand('%s', '%s', %i)", str1, str2, color); + char sentenceCommand[500]; + strncpy(sentenceCommand, str1, 500); + if (str2) + strncat(sentenceCommand, str2, 500 - strlen(sentenceCommand)); + + drawSentenceCommand(sentenceCommand, color); + _screen->updateScreen(); +} + +void KyraEngine_LoK::updateTextFade() { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::updateTextFade()"); + if (!_fadeText) + return; + + bool finished = false; + for (int i = 0; i < 3; i++) { + if (_currSentenceColor[i] > 4) + _currSentenceColor[i] -= 4; + else + if (_currSentenceColor[i]) { + _currSentenceColor[i] = 0; + finished = true; + } + } + + _screen->_currentPalette[765] = _currSentenceColor[0]; + _screen->_currentPalette[766] = _currSentenceColor[1]; + _screen->_currentPalette[767] = _currSentenceColor[2]; + _screen->setScreenPalette(_screen->_currentPalette); + + if (finished) { + _fadeText = false; + _startSentencePalIndex = -1; + } +} + +} // end of namespace Kyra diff --git a/engines/kyra/text_v1.cpp b/engines/kyra/text_v1.cpp deleted file mode 100644 index 5534992c6a..0000000000 --- a/engines/kyra/text_v1.cpp +++ /dev/null @@ -1,399 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include "kyra/kyra_v1.h" -#include "kyra/screen_v1.h" -#include "kyra/text.h" -#include "kyra/animator_v1.h" -#include "kyra/sprites.h" -#include "kyra/timer.h" - -namespace Kyra { - -void KyraEngine_v1::waitForChatToFinish(int vocFile, int16 chatDuration, const char *chatStr, uint8 charNum) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::waitForChatToFinish(%i, %s, %i)", chatDuration, chatStr, charNum); - bool hasUpdatedNPCs = false; - bool runLoop = true; - bool drawText = textEnabled(); - uint8 currPage; - Common::Event event; - - //while (towns_isEscKeyPressed() ) - //towns_getKey(); - - uint32 timeToEnd = strlen(chatStr) * 8 * _tickLength + _system->getMillis(); - - if (_configVoice == 0 && chatDuration != -1) { - switch (_configTextspeed) { - case 0: - chatDuration *= 2; - break; - case 2: - chatDuration /= 4; - break; - case 3: - chatDuration = -1; - break; - } - } - - if (chatDuration != -1) - chatDuration *= _tickLength; - - if (vocFile != -1) { - snd_voiceWaitForFinish(); - snd_playVoiceFile(vocFile); - } - - _timer->disable(14); - _timer->disable(18); - _timer->disable(19); - - uint32 timeAtStart = _system->getMillis(); - uint32 loopStart; - while (runLoop) { - loopStart = _system->getMillis(); - if (_currentCharacter->sceneId == 210) - if (seq_playEnd()) - break; - - if (_system->getMillis() > timeToEnd && !hasUpdatedNPCs) { - hasUpdatedNPCs = true; - _timer->disable(15); - _currHeadShape = 4; - _animator->animRefreshNPC(0); - _animator->animRefreshNPC(_talkingCharNum); - - if (_charSayUnk2 != -1) { - _animator->sprites()[_charSayUnk2].active = 0; - _sprites->_anims[_charSayUnk2].play = false; - _charSayUnk2 = -1; - } - } - - _timer->update(); - _sprites->updateSceneAnims(); - _animator->restoreAllObjectBackgrounds(); - _animator->preserveAnyChangedBackgrounds(); - _animator->prepDrawAllObjects(); - - if (drawText) { - currPage = _screen->_curPage; - _screen->_curPage = 2; - _text->printCharacterText(chatStr, charNum, _characterList[charNum].x1); - _animator->_updateScreen = true; - _screen->_curPage = currPage; - } - - _animator->copyChangedObjectsForward(0); - updateTextFade(); - - if (((chatDuration < (int16)(_system->getMillis() - timeAtStart)) && chatDuration != -1 && drawText) || (!drawText && !snd_voiceIsPlaying())) - break; - - uint32 nextTime = loopStart + _tickLength; - - while (_system->getMillis() < nextTime) { - while (_eventMan->pollEvent(event)) { - switch (event.type) { - case Common::EVENT_KEYDOWN: - if (event.kbd.keycode == '.') - _skipFlag = true; - break; - case Common::EVENT_QUIT: - quitGame(); - runLoop = false; - break; - case Common::EVENT_LBUTTONDOWN: - runLoop = false; - break; - default: - break; - } - } - - if (nextTime - _system->getMillis() >= 10) { - _system->delayMillis(10); - _system->updateScreen(); - } - } - - if (_skipFlag) - runLoop = false; - } - - if (_skipFlag) - snd_stopVoice(); - - _timer->enable(14); - _timer->enable(15); - _timer->enable(18); - _timer->enable(19); - //clearKyrandiaButtonIO(); -} - -void KyraEngine_v1::endCharacterChat(int8 charNum, int16 convoInitialized) { - _charSayUnk3 = -1; - - if (charNum > 4 && charNum < 11) { - //TODO: weird _game_inventory stuff here - //warning("STUB: endCharacterChat() for high charnums"); - } - - if (convoInitialized != 0) { - _talkingCharNum = -1; - if (_currentCharacter->currentAnimFrame != 88) - _currentCharacter->currentAnimFrame = 7; - _animator->animRefreshNPC(0); - _animator->updateAllObjectShapes(); - } -} - -void KyraEngine_v1::restoreChatPartnerAnimFrame(int8 charNum) { - _talkingCharNum = -1; - - if (charNum > 0 && charNum < 5) { - _characterList[charNum].currentAnimFrame = _currentChatPartnerBackupFrame; - _animator->animRefreshNPC(charNum); - } - - if (_currentCharacter->currentAnimFrame != 88) - _currentCharacter->currentAnimFrame = 7; - - _animator->animRefreshNPC(0); - _animator->updateAllObjectShapes(); -} - -void KyraEngine_v1::backupChatPartnerAnimFrame(int8 charNum) { - _talkingCharNum = 0; - - if (charNum < 5 && charNum > 0) - _currentChatPartnerBackupFrame = _characterList[charNum].currentAnimFrame; - - if (_currentCharacter->currentAnimFrame != 88) { - _currentCharacter->currentAnimFrame = 16; - if (_scaleMode != 0) - _currentCharacter->currentAnimFrame = 7; - } - - _animator->animRefreshNPC(0); - _animator->updateAllObjectShapes(); -} - -int8 KyraEngine_v1::getChatPartnerNum() { - uint8 sceneTable[] = {0x2, 0x5, 0x2D, 0x7, 0x1B, 0x8, 0x22, 0x9, 0x30, 0x0A}; - int pos = 0; - int partner = -1; - - for (int i = 1; i < 6; i++) { - if (_currentCharacter->sceneId == sceneTable[pos]) { - partner = sceneTable[pos+1]; - break; - } - pos += 2; - } - - for (int i = 1; i < 5; i++) { - if (_characterList[i].sceneId == _currentCharacter->sceneId) { - partner = i; - break; - } - } - return partner; -} - -int KyraEngine_v1::initCharacterChat(int8 charNum) { - int returnValue = 0; - - if (_talkingCharNum == -1) { - returnValue = 1; - _talkingCharNum = 0; - - if (_currentCharacter->currentAnimFrame != 88) { - _currentCharacter->currentAnimFrame = 16; - if (_scaleMode != 0) - _currentCharacter->currentAnimFrame = 7; - } - - _animator->animRefreshNPC(0); - _animator->updateAllObjectShapes(); - } - - _charSayUnk2 = -1; - _animator->flagAllObjectsForBkgdChange(); - _animator->restoreAllObjectBackgrounds(); - - if (charNum > 4 && charNum < 11) { - // TODO: Fill in weird _game_inventory stuff here - //warning("STUB: initCharacterChat() for high charnums"); - } - - _animator->flagAllObjectsForRefresh(); - _animator->flagAllObjectsForBkgdChange(); - _animator->preserveAnyChangedBackgrounds(); - _charSayUnk3 = charNum; - - return returnValue; -} - -void KyraEngine_v1::characterSays(int vocFile, const char *chatStr, int8 charNum, int8 chatDuration) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::characterSays('%s', %i, %d)", chatStr, charNum, chatDuration); - uint8 startAnimFrames[] = { 0x10, 0x32, 0x56, 0x0, 0x0, 0x0 }; - - uint16 chatTicks; - int16 convoInitialized; - int8 chatPartnerNum; - - if (_currentCharacter->sceneId == 210) - return; - - convoInitialized = initCharacterChat(charNum); - chatPartnerNum = getChatPartnerNum(); - - if (chatPartnerNum >= 0 && chatPartnerNum < 5) - backupChatPartnerAnimFrame(chatPartnerNum); - - if (charNum < 5) { - _characterList[charNum].currentAnimFrame = startAnimFrames[charNum]; - _charSayUnk3 = charNum; - _talkingCharNum = charNum; - _animator->animRefreshNPC(charNum); - } - - char *processedString = _text->preprocessString(chatStr); - int lineNum = _text->buildMessageSubstrings(processedString); - - int16 yPos = _characterList[charNum].y1; - yPos -= ((_scaleTable[yPos] * _characterList[charNum].height) >> 8); - yPos -= 8; - yPos -= lineNum * 10; - - if (yPos < 11) - yPos = 11; - - if (yPos > 100) - yPos = 100; - - _text->_talkMessageY = yPos; - _text->_talkMessageH = lineNum * 10; - - if (textEnabled()) { - _animator->restoreAllObjectBackgrounds(); - - _screen->copyRegion(12, _text->_talkMessageY, 12, 136, 296, _text->_talkMessageH, 2, 2); - _screen->hideMouse(); - - _text->printCharacterText(processedString, charNum, _characterList[charNum].x1); - _screen->showMouse(); - } - - if (chatDuration == -2) - chatTicks = strlen(processedString) * 9; - else - chatTicks = chatDuration; - - if (!speechEnabled()) - vocFile = -1; - waitForChatToFinish(vocFile, chatTicks, chatStr, charNum); - - if (textEnabled()) { - _animator->restoreAllObjectBackgrounds(); - - _screen->copyRegion(12, 136, 12, _text->_talkMessageY, 296, _text->_talkMessageH, 2, 2); - _animator->preserveAllBackgrounds(); - _animator->prepDrawAllObjects(); - _screen->hideMouse(); - - _screen->copyRegion(12, _text->_talkMessageY, 12, _text->_talkMessageY, 296, _text->_talkMessageH, 2, 0); - _screen->showMouse(); - _animator->flagAllObjectsForRefresh(); - _animator->copyChangedObjectsForward(0); - } - - if (chatPartnerNum != -1 && chatPartnerNum < 5) - restoreChatPartnerAnimFrame(chatPartnerNum); - - endCharacterChat(charNum, convoInitialized); -} - -void KyraEngine_v1::drawSentenceCommand(const char *sentence, int color) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::drawSentenceCommand('%s', %i)", sentence, color); - _screen->hideMouse(); - _screen->fillRect(8, 143, 311, 152, 12); - - if (_startSentencePalIndex != color || _fadeText != false) { - _currSentenceColor[0] = _screen->_currentPalette[765] = _screen->_currentPalette[color*3]; - _currSentenceColor[1] = _screen->_currentPalette[766] = _screen->_currentPalette[color*3+1]; - _currSentenceColor[2] = _screen->_currentPalette[767] = _screen->_currentPalette[color*3+2]; - - _screen->setScreenPalette(_screen->_currentPalette); - _startSentencePalIndex = 0; - } - - _text->printText(sentence, 8, 143, 0xFF, 12, 0); - _screen->showMouse(); - setTextFadeTimerCountdown(15); - _fadeText = false; -} - -void KyraEngine_v1::updateSentenceCommand(const char *str1, const char *str2, int color) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::updateSentenceCommand('%s', '%s', %i)", str1, str2, color); - char sentenceCommand[500]; - strncpy(sentenceCommand, str1, 500); - if (str2) - strncat(sentenceCommand, str2, 500 - strlen(sentenceCommand)); - - drawSentenceCommand(sentenceCommand, color); - _screen->updateScreen(); -} - -void KyraEngine_v1::updateTextFade() { - debugC(9, kDebugLevelMain, "KyraEngine_v1::updateTextFade()"); - if (!_fadeText) - return; - - bool finished = false; - for (int i = 0; i < 3; i++) { - if (_currSentenceColor[i] > 4) - _currSentenceColor[i] -= 4; - else - if (_currSentenceColor[i]) { - _currSentenceColor[i] = 0; - finished = true; - } - } - - _screen->_currentPalette[765] = _currSentenceColor[0]; - _screen->_currentPalette[766] = _currSentenceColor[1]; - _screen->_currentPalette[767] = _currSentenceColor[2]; - _screen->setScreenPalette(_screen->_currentPalette); - - if (finished) { - _fadeText = false; - _startSentencePalIndex = -1; - } -} - -} // end of namespace Kyra diff --git a/engines/kyra/timer_lok.cpp b/engines/kyra/timer_lok.cpp new file mode 100644 index 0000000000..91081a36b3 --- /dev/null +++ b/engines/kyra/timer_lok.cpp @@ -0,0 +1,180 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "kyra/kyra.h" +#include "kyra/kyra_lok.h" +#include "kyra/screen.h" +#include "kyra/animator_lok.h" +#include "kyra/timer.h" + +#include "common/system.h" + +namespace Kyra { + +#define TimerV1(x) new Common::Functor1Mem(this, &KyraEngine_LoK::x) + +void KyraEngine_LoK::setupTimers() { + debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_LoK::setupTimers()"); + + for (int i = 0; i <= 4; ++i) + _timer->addTimer(i, 0, -1, 1); + + _timer->addTimer(5, 0, 5, 1); + _timer->addTimer(6, 0, 7, 1); + _timer->addTimer(7, 0, 8, 1); + _timer->addTimer(8, 0, 9, 1); + _timer->addTimer(9, 0, 7, 1); + + for (int i = 10; i <= 13; ++i) + _timer->addTimer(i, 0, 420, 1); + + _timer->addTimer(14, TimerV1(timerCheckAnimFlag2), 600, 1); + _timer->addTimer(15, TimerV1(timerUpdateHeadAnims), 11, 1); + _timer->addTimer(16, TimerV1(timerSetFlags1), 7200, 1); + _timer->addTimer(17, 0 /*sub_15120*/, 7200, 1); + _timer->addTimer(18, TimerV1(timerCheckAnimFlag1), 600, 1); + _timer->addTimer(19, TimerV1(timerRedrawAmulet), 600, 1); + + _timer->addTimer(20, 0, 7200, 1); + _timer->addTimer(21, 0/*sub_1517C*/, 18000, 1); + _timer->addTimer(22, 0, 7200, 1); + + for (int i = 23; i <= 27; ++i) + _timer->addTimer(i, 0, 10800, 1); + + _timer->addTimer(28, 0, 21600, 1); + _timer->addTimer(29, 0, 7200, 1); + _timer->addTimer(30, 0, 10800, 1); + + _timer->addTimer(31, TimerV1(timerFadeText), -1, 1); + _timer->addTimer(32, TimerV1(updateAnimFlag1), 9, 1); + _timer->addTimer(33, TimerV1(updateAnimFlag2), 3, 1); +} + +void KyraEngine_LoK::timerUpdateHeadAnims(int timerNum) { + debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_LoK::timerUpdateHeadAnims(%i)", timerNum); + static int8 currentFrame = 0; + static const int8 frameTable[] = {4, 5, 4, 5, 4, 5, 0, 1, 4, 5, + 4, 4, 6, 4, 8, 1, 9, 4, -1}; + + if (_talkingCharNum < 0) + return; + + _currHeadShape = frameTable[currentFrame]; + currentFrame++; + + if (frameTable[currentFrame] == -1) + currentFrame = 0; + + _animator->animRefreshNPC(0); + _animator->animRefreshNPC(_talkingCharNum); +} + +void KyraEngine_LoK::timerSetFlags1(int timerNum) { + debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_LoK::timerSetFlags(%i)", timerNum); + if (_currentCharacter->sceneId == 0x1C) + return; + + int rndNr = _rnd.getRandomNumberRng(0, 3); + + for (int i = 0; i < 4; i++) { + if (!queryGameFlag(rndNr + 17)) { + setGameFlag(rndNr + 17); + break; + } else { + rndNr++; + if (rndNr > 3) + rndNr = 0; + } + } +} + +void KyraEngine_LoK::timerFadeText(int timerNum) { + debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_LoK::timerFadeText(%i)", timerNum); + _fadeText = true; +} + +void KyraEngine_LoK::updateAnimFlag1(int timerNum) { + debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_LoK::updateAnimFlag1(%d)", timerNum); + if (_brandonStatusBit & 2) { + _brandonStatusBit0x02Flag = 1; + } +} + +void KyraEngine_LoK::updateAnimFlag2(int timerNum) { + debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_LoK::updateAnimFlag2(%d)", timerNum); + if (_brandonStatusBit & 0x20) { + _brandonStatusBit0x20Flag = 1; + } +} + +void KyraEngine_LoK::setTextFadeTimerCountdown(int16 countdown) { + debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_LoK::setTextFadeTimerCountdown(%i)", countdown); + if (countdown == -1) + countdown = 32000; + + _timer->setCountdown(31, countdown*60); +} + +void KyraEngine_LoK::timerSetFlags2(int timerNum) { + debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_LoK::timerSetFlags2(%i)", timerNum); + if (!((uint32*)(_flagsTable+0x2D))[timerNum]) + ((uint32*)(_flagsTable+0x2D))[timerNum] = 1; +} + +void KyraEngine_LoK::timerCheckAnimFlag1(int timerNum) { + debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_LoK::timerCheckAnimFlag1(%i)", timerNum); + if (_brandonStatusBit & 0x20) { + checkAmuletAnimFlags(); + _timer->setCountdown(18, -1); + } +} + +void KyraEngine_LoK::timerCheckAnimFlag2(int timerNum) { + debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_LoK::timerCheckAnimFlag2(%i)", timerNum); + if (_brandonStatusBit & 0x2) { + checkAmuletAnimFlags(); + _timer->setCountdown(14, -1); + } +} + +void KyraEngine_LoK::timerRedrawAmulet(int timerNum) { + debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_LoK::timerRedrawAmulet(%i)", timerNum); + if (queryGameFlag(0xF1)) { + drawAmulet(); + _timer->setCountdown(19, -1); + } +} + +void KyraEngine_LoK::setWalkspeed(uint8 newSpeed) { + debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_LoK::setWalkspeed(%i)", newSpeed); + static const uint8 speeds[] = { 11, 9, 6, 5, 3 }; + + assert(newSpeed < ARRAYSIZE(speeds)); + _timer->setDelay(5, speeds[newSpeed]); +} + +} // end of namespace Kyra + diff --git a/engines/kyra/timer_v1.cpp b/engines/kyra/timer_v1.cpp deleted file mode 100644 index f5e7c52ba1..0000000000 --- a/engines/kyra/timer_v1.cpp +++ /dev/null @@ -1,180 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include "kyra/kyra.h" -#include "kyra/kyra_v1.h" -#include "kyra/screen.h" -#include "kyra/animator_v1.h" -#include "kyra/timer.h" - -#include "common/system.h" - -namespace Kyra { - -#define TimerV1(x) new Common::Functor1Mem(this, &KyraEngine_v1::x) - -void KyraEngine_v1::setupTimers() { - debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v1::setupTimers()"); - - for (int i = 0; i <= 4; ++i) - _timer->addTimer(i, 0, -1, 1); - - _timer->addTimer(5, 0, 5, 1); - _timer->addTimer(6, 0, 7, 1); - _timer->addTimer(7, 0, 8, 1); - _timer->addTimer(8, 0, 9, 1); - _timer->addTimer(9, 0, 7, 1); - - for (int i = 10; i <= 13; ++i) - _timer->addTimer(i, 0, 420, 1); - - _timer->addTimer(14, TimerV1(timerCheckAnimFlag2), 600, 1); - _timer->addTimer(15, TimerV1(timerUpdateHeadAnims), 11, 1); - _timer->addTimer(16, TimerV1(timerSetFlags1), 7200, 1); - _timer->addTimer(17, 0 /*sub_15120*/, 7200, 1); - _timer->addTimer(18, TimerV1(timerCheckAnimFlag1), 600, 1); - _timer->addTimer(19, TimerV1(timerRedrawAmulet), 600, 1); - - _timer->addTimer(20, 0, 7200, 1); - _timer->addTimer(21, 0/*sub_1517C*/, 18000, 1); - _timer->addTimer(22, 0, 7200, 1); - - for (int i = 23; i <= 27; ++i) - _timer->addTimer(i, 0, 10800, 1); - - _timer->addTimer(28, 0, 21600, 1); - _timer->addTimer(29, 0, 7200, 1); - _timer->addTimer(30, 0, 10800, 1); - - _timer->addTimer(31, TimerV1(timerFadeText), -1, 1); - _timer->addTimer(32, TimerV1(updateAnimFlag1), 9, 1); - _timer->addTimer(33, TimerV1(updateAnimFlag2), 3, 1); -} - -void KyraEngine_v1::timerUpdateHeadAnims(int timerNum) { - debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v1::timerUpdateHeadAnims(%i)", timerNum); - static int8 currentFrame = 0; - static const int8 frameTable[] = {4, 5, 4, 5, 4, 5, 0, 1, 4, 5, - 4, 4, 6, 4, 8, 1, 9, 4, -1}; - - if (_talkingCharNum < 0) - return; - - _currHeadShape = frameTable[currentFrame]; - currentFrame++; - - if (frameTable[currentFrame] == -1) - currentFrame = 0; - - _animator->animRefreshNPC(0); - _animator->animRefreshNPC(_talkingCharNum); -} - -void KyraEngine_v1::timerSetFlags1(int timerNum) { - debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v1::timerSetFlags(%i)", timerNum); - if (_currentCharacter->sceneId == 0x1C) - return; - - int rndNr = _rnd.getRandomNumberRng(0, 3); - - for (int i = 0; i < 4; i++) { - if (!queryGameFlag(rndNr + 17)) { - setGameFlag(rndNr + 17); - break; - } else { - rndNr++; - if (rndNr > 3) - rndNr = 0; - } - } -} - -void KyraEngine_v1::timerFadeText(int timerNum) { - debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v1::timerFadeText(%i)", timerNum); - _fadeText = true; -} - -void KyraEngine_v1::updateAnimFlag1(int timerNum) { - debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v1::updateAnimFlag1(%d)", timerNum); - if (_brandonStatusBit & 2) { - _brandonStatusBit0x02Flag = 1; - } -} - -void KyraEngine_v1::updateAnimFlag2(int timerNum) { - debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v1::updateAnimFlag2(%d)", timerNum); - if (_brandonStatusBit & 0x20) { - _brandonStatusBit0x20Flag = 1; - } -} - -void KyraEngine_v1::setTextFadeTimerCountdown(int16 countdown) { - debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v1::setTextFadeTimerCountdown(%i)", countdown); - if (countdown == -1) - countdown = 32000; - - _timer->setCountdown(31, countdown*60); -} - -void KyraEngine_v1::timerSetFlags2(int timerNum) { - debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v1::timerSetFlags2(%i)", timerNum); - if (!((uint32*)(_flagsTable+0x2D))[timerNum]) - ((uint32*)(_flagsTable+0x2D))[timerNum] = 1; -} - -void KyraEngine_v1::timerCheckAnimFlag1(int timerNum) { - debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v1::timerCheckAnimFlag1(%i)", timerNum); - if (_brandonStatusBit & 0x20) { - checkAmuletAnimFlags(); - _timer->setCountdown(18, -1); - } -} - -void KyraEngine_v1::timerCheckAnimFlag2(int timerNum) { - debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v1::timerCheckAnimFlag2(%i)", timerNum); - if (_brandonStatusBit & 0x2) { - checkAmuletAnimFlags(); - _timer->setCountdown(14, -1); - } -} - -void KyraEngine_v1::timerRedrawAmulet(int timerNum) { - debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v1::timerRedrawAmulet(%i)", timerNum); - if (queryGameFlag(0xF1)) { - drawAmulet(); - _timer->setCountdown(19, -1); - } -} - -void KyraEngine_v1::setWalkspeed(uint8 newSpeed) { - debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v1::setWalkspeed(%i)", newSpeed); - static const uint8 speeds[] = { 11, 9, 6, 5, 3 }; - - assert(newSpeed < ARRAYSIZE(speeds)); - _timer->setDelay(5, speeds[newSpeed]); -} - -} // end of namespace Kyra - diff --git a/engines/kyra/wsamovie.cpp b/engines/kyra/wsamovie.cpp index 5190f24ad6..42159478dd 100644 --- a/engines/kyra/wsamovie.cpp +++ b/engines/kyra/wsamovie.cpp @@ -35,11 +35,11 @@ #include "kyra/resource.h" namespace Kyra { -WSAMovieV1::WSAMovieV1(KyraEngine *vm) : Movie(vm) {} -WSAMovieV1::~WSAMovieV1() { close(); } +WSAMovie_v1::WSAMovie_v1(KyraEngine *vm) : Movie(vm) {} +WSAMovie_v1::~WSAMovie_v1() { close(); } -int WSAMovieV1::open(const char *filename, int offscreenDecode, uint8 *palBuf) { - debugC(9, kDebugLevelMovie, "WSAMovieV1::open('%s', %d, %p)", filename, offscreenDecode, (const void *)palBuf); +int WSAMovie_v1::open(const char *filename, int offscreenDecode, uint8 *palBuf) { + debugC(9, kDebugLevelMovie, "WSAMovie_v1::open('%s', %d, %p)", filename, offscreenDecode, (const void *)palBuf); close(); uint32 flags = 0; @@ -123,8 +123,8 @@ int WSAMovieV1::open(const char *filename, int offscreenDecode, uint8 *palBuf) { return _numFrames; } -void WSAMovieV1::close() { - debugC(9, kDebugLevelMovie, "WSAMovieV1::close()"); +void WSAMovie_v1::close() { + debugC(9, kDebugLevelMovie, "WSAMovie_v1::close()"); if (_opened) { delete[] _deltaBuffer; delete[] _offscreenBuffer; @@ -134,8 +134,8 @@ void WSAMovieV1::close() { } } -void WSAMovieV1::displayFrame(int frameNum, ...) { - debugC(9, kDebugLevelMovie, "WSAMovieV1::displayFrame(%d, ...)", frameNum); +void WSAMovie_v1::displayFrame(int frameNum, ...) { + debugC(9, kDebugLevelMovie, "WSAMovie_v1::displayFrame(%d, ...)", frameNum); if (frameNum >= _numFrames || !_opened) return; @@ -198,8 +198,8 @@ void WSAMovieV1::displayFrame(int frameNum, ...) { _vm->screen()->copyBlockToPage(_drawPage, _x, _y, _width, _height, _offscreenBuffer); } -void WSAMovieV1::processFrame(int frameNum, uint8 *dst) { - debugC(9, kDebugLevelMovie, "WSAMovieV1::processFrame(%d, %p)", frameNum, (const void *)dst); +void WSAMovie_v1::processFrame(int frameNum, uint8 *dst) { + debugC(9, kDebugLevelMovie, "WSAMovie_v1::processFrame(%d, %p)", frameNum, (const void *)dst); if (!_opened) return; assert(frameNum <= _numFrames); @@ -213,11 +213,11 @@ void WSAMovieV1::processFrame(int frameNum, uint8 *dst) { #pragma mark - -WSAMovieAmiga::WSAMovieAmiga(KyraEngine *vm) : WSAMovieV1(vm), _buffer(0) {} +WSAMovieAmiga::WSAMovieAmiga(KyraEngine *vm) : WSAMovie_v1(vm), _buffer(0) {} int WSAMovieAmiga::open(const char *filename, int offscreenDecode, uint8 *palBuf) { debugC(9, kDebugLevelMovie, "WSAMovieAmiga::open('%s', %d, %p)", filename, offscreenDecode, (const void *)palBuf); - int res = WSAMovieV1::open(filename, offscreenDecode, palBuf); + int res = WSAMovie_v1::open(filename, offscreenDecode, palBuf); if (!res) return 0; @@ -233,7 +233,7 @@ void WSAMovieAmiga::close() { delete[] _buffer; _buffer = 0; } - WSAMovieV1::close(); + WSAMovie_v1::close(); } void WSAMovieAmiga::displayFrame(int frameNum, ...) { @@ -342,10 +342,10 @@ void WSAMovieAmiga::processFrame(int frameNum, uint8 *dst) { #pragma mark - -WSAMovieV2::WSAMovieV2(KyraEngine *vm, Screen_v2 *screen) : WSAMovieV1(vm), _screen(screen), _xAdd(0), _yAdd(0) {} +WSAMovie_v2::WSAMovie_v2(KyraEngine *vm, Screen_v2 *screen) : WSAMovie_v1(vm), _screen(screen), _xAdd(0), _yAdd(0) {} -int WSAMovieV2::open(const char *filename, int unk1, uint8 *palBuf) { - debugC(9, kDebugLevelMovie, "WSAMovieV2::open('%s', %d, %p)", filename, unk1, (const void *)palBuf); +int WSAMovie_v2::open(const char *filename, int unk1, uint8 *palBuf) { + debugC(9, kDebugLevelMovie, "WSAMovie_v2::open('%s', %d, %p)", filename, unk1, (const void *)palBuf); close(); uint32 flags = 0; @@ -429,8 +429,8 @@ int WSAMovieV2::open(const char *filename, int unk1, uint8 *palBuf) { return _numFrames; } -void WSAMovieV2::displayFrame(int frameNum, ...) { - debugC(9, kDebugLevelMovie, "WSAMovieV2::displayFrame(%d, ...)", frameNum); +void WSAMovie_v2::displayFrame(int frameNum, ...) { + debugC(9, kDebugLevelMovie, "WSAMovie_v2::displayFrame(%d, ...)", frameNum); if (frameNum >= _numFrames || frameNum < 0 || !_opened) return; diff --git a/engines/kyra/wsamovie.h b/engines/kyra/wsamovie.h index d1f3465c07..cc3a188eea 100644 --- a/engines/kyra/wsamovie.h +++ b/engines/kyra/wsamovie.h @@ -60,10 +60,10 @@ protected: int _drawPage; }; -class WSAMovieV1 : public Movie { +class WSAMovie_v1 : public Movie { public: - WSAMovieV1(KyraEngine *vm); - virtual ~WSAMovieV1(); + WSAMovie_v1(KyraEngine *vm); + virtual ~WSAMovie_v1(); virtual int open(const char *filename, int offscreen, uint8 *palette); virtual void close(); @@ -94,7 +94,7 @@ protected: uint8 *_frameData; }; -class WSAMovieAmiga : public WSAMovieV1 { +class WSAMovieAmiga : public WSAMovie_v1 { public: WSAMovieAmiga(KyraEngine *vm); int open(const char *filename, int offscreen, uint8 *palette); @@ -107,9 +107,9 @@ private: uint8 *_buffer; }; -class WSAMovieV2 : public WSAMovieV1 { +class WSAMovie_v2 : public WSAMovie_v1 { public: - WSAMovieV2(KyraEngine *vm, Screen_v2 *scren); + WSAMovie_v2(KyraEngine *vm, Screen_v2 *scren); int open(const char *filename, int unk1, uint8 *palette); -- cgit v1.2.3