From 4b5f3266cffa778b52f51a5a8cc39b16bac89584 Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Fri, 2 May 2008 14:46:30 +0000 Subject: Started to refactor kyra2/kyra3 code to a common base. (regressions possible, compiling currently broken) svn-id: r31817 --- engines/kyra/animator_hof.cpp | 391 ++++++ engines/kyra/animator_mr.cpp | 483 +++++++ engines/kyra/animator_v2.cpp | 490 ------- engines/kyra/animator_v3.cpp | 584 --------- engines/kyra/debugger.cpp | 19 +- engines/kyra/debugger.h | 12 +- engines/kyra/detection.cpp | 8 +- engines/kyra/gui_v2.cpp | 63 +- engines/kyra/gui_v2.h | 8 +- engines/kyra/gui_v3.cpp | 85 +- engines/kyra/gui_v3.h | 12 +- engines/kyra/items_hof.cpp | 511 ++++++++ engines/kyra/items_mr.cpp | 644 ++++++++++ engines/kyra/items_v2.cpp | 511 -------- engines/kyra/items_v3.cpp | 644 ---------- engines/kyra/kyra_hof.cpp | 2242 ++++++++++++++++++++++++++++++++ engines/kyra/kyra_mr.cpp | 1563 ++++++++++++++++++++++ engines/kyra/kyra_mr.h | 733 +++++++++++ engines/kyra/kyra_v2.cpp | 2330 --------------------------------- engines/kyra/kyra_v2.h | 1166 ----------------- engines/kyra/kyra_v3.cpp | 1651 ------------------------ engines/kyra/kyra_v3.h | 833 ------------ engines/kyra/module.mk | 36 +- engines/kyra/resource.h | 2 +- engines/kyra/saveload_hof.cpp | 333 +++++ engines/kyra/saveload_mr.cpp | 262 ++++ engines/kyra/saveload_v2.cpp | 333 ----- engines/kyra/saveload_v3.cpp | 262 ---- engines/kyra/scene_hof.cpp | 777 +++++++++++ engines/kyra/scene_mr.cpp | 864 +++++++++++++ engines/kyra/scene_v2.cpp | 959 -------------- engines/kyra/scene_v3.cpp | 918 ------------- engines/kyra/screen.cpp | 300 ----- engines/kyra/screen.h | 35 - engines/kyra/screen_hof.cpp | 279 ++++ engines/kyra/screen_hof.h | 63 + engines/kyra/screen_mr.cpp | 138 ++ engines/kyra/screen_mr.h | 57 + engines/kyra/screen_v2.cpp | 279 ---- engines/kyra/screen_v2.h | 62 - engines/kyra/screen_v3.cpp | 138 -- engines/kyra/screen_v3.h | 57 - engines/kyra/script_hof.cpp | 2131 ++++++++++++++++++++++++++++++ engines/kyra/script_mr.cpp | 1686 ++++++++++++++++++++++++ engines/kyra/script_v2.cpp | 2134 ------------------------------ engines/kyra/script_v3.cpp | 1687 ------------------------ engines/kyra/sequences_hof.cpp | 2782 ++++++++++++++++++++++++++++++++++++++++ engines/kyra/sequences_mr.cpp | 354 +++++ engines/kyra/sequences_v2.cpp | 2781 --------------------------------------- engines/kyra/sequences_v3.cpp | 354 ----- engines/kyra/staticres.cpp | 182 +-- engines/kyra/text_hof.cpp | 690 ++++++++++ engines/kyra/text_hof.h | 56 + engines/kyra/text_mr.cpp | 817 ++++++++++++ engines/kyra/text_mr.h | 55 + engines/kyra/text_v2.cpp | 690 ---------- engines/kyra/text_v2.h | 56 - engines/kyra/text_v3.cpp | 817 ------------ engines/kyra/text_v3.h | 55 - engines/kyra/timer_hof.cpp | 121 ++ engines/kyra/timer_mr.cpp | 93 ++ engines/kyra/timer_v2.cpp | 121 -- engines/kyra/timer_v3.cpp | 93 -- engines/kyra/wsamovie.cpp | 3 +- engines/kyra/wsamovie.h | 8 +- 65 files changed, 18347 insertions(+), 20556 deletions(-) create mode 100644 engines/kyra/animator_hof.cpp create mode 100644 engines/kyra/animator_mr.cpp delete mode 100644 engines/kyra/animator_v2.cpp delete mode 100644 engines/kyra/animator_v3.cpp create mode 100644 engines/kyra/items_hof.cpp create mode 100644 engines/kyra/items_mr.cpp delete mode 100644 engines/kyra/items_v2.cpp delete mode 100644 engines/kyra/items_v3.cpp create mode 100644 engines/kyra/kyra_hof.cpp create mode 100644 engines/kyra/kyra_mr.cpp create mode 100644 engines/kyra/kyra_mr.h delete mode 100644 engines/kyra/kyra_v2.cpp delete mode 100644 engines/kyra/kyra_v2.h delete mode 100644 engines/kyra/kyra_v3.cpp delete mode 100644 engines/kyra/kyra_v3.h create mode 100644 engines/kyra/saveload_hof.cpp create mode 100644 engines/kyra/saveload_mr.cpp delete mode 100644 engines/kyra/saveload_v2.cpp delete mode 100644 engines/kyra/saveload_v3.cpp create mode 100644 engines/kyra/scene_hof.cpp create mode 100644 engines/kyra/scene_mr.cpp delete mode 100644 engines/kyra/scene_v2.cpp delete mode 100644 engines/kyra/scene_v3.cpp create mode 100644 engines/kyra/screen_hof.cpp create mode 100644 engines/kyra/screen_hof.h create mode 100644 engines/kyra/screen_mr.cpp create mode 100644 engines/kyra/screen_mr.h delete mode 100644 engines/kyra/screen_v2.cpp delete mode 100644 engines/kyra/screen_v2.h delete mode 100644 engines/kyra/screen_v3.cpp delete mode 100644 engines/kyra/screen_v3.h create mode 100644 engines/kyra/script_hof.cpp create mode 100644 engines/kyra/script_mr.cpp delete mode 100644 engines/kyra/script_v2.cpp delete mode 100644 engines/kyra/script_v3.cpp create mode 100644 engines/kyra/sequences_hof.cpp create mode 100644 engines/kyra/sequences_mr.cpp delete mode 100644 engines/kyra/sequences_v2.cpp delete mode 100644 engines/kyra/sequences_v3.cpp create mode 100644 engines/kyra/text_hof.cpp create mode 100644 engines/kyra/text_hof.h create mode 100644 engines/kyra/text_mr.cpp create mode 100644 engines/kyra/text_mr.h delete mode 100644 engines/kyra/text_v2.cpp delete mode 100644 engines/kyra/text_v2.h delete mode 100644 engines/kyra/text_v3.cpp delete mode 100644 engines/kyra/text_v3.h create mode 100644 engines/kyra/timer_hof.cpp create mode 100644 engines/kyra/timer_mr.cpp delete mode 100644 engines/kyra/timer_v2.cpp delete mode 100644 engines/kyra/timer_v3.cpp (limited to 'engines') diff --git a/engines/kyra/animator_hof.cpp b/engines/kyra/animator_hof.cpp new file mode 100644 index 0000000000..4667f11498 --- /dev/null +++ b/engines/kyra/animator_hof.cpp @@ -0,0 +1,391 @@ +/* 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_hof.h" +#include "kyra/wsamovie.h" + +#include "common/endian.h" + +namespace Kyra { + +void KyraEngine_HoF::restorePage3() { + debugC(9, kDebugLevelAnimator, "KyraEngine_HoF::restorePage3()"); + screen()->copyBlockToPage(2, 0, 0, 320, 144, _gamePlayBuffer); +} + +void KyraEngine_HoF::clearAnimObjects() { + debugC(9, kDebugLevelAnimator, "KyraEngine_HoF::clearAnimObjects()"); + memset(_animObjects, 0, sizeof(_animObjects)); + + _animObjects[0].index = 0; + _animObjects[0].type = 0; + _animObjects[0].enabled = 1; + _animObjects[0].flags = 0x800; + _animObjects[0].width = 32; + _animObjects[0].height = 49; + _animObjects[0].width2 = 4; + _animObjects[0].height2 = 10; + + for (int i = 1; i < 11; ++i) { + _animObjects[i].index = i; + _animObjects[i].type = 2; + } + + for (int i = 11; i <= 40; ++i) { + _animObjects[i].index = i; + _animObjects[i].type = 1; + _animObjects[i].flags = 0x800; + _animObjects[i].width = 16; + _animObjects[i].height = 16; + } +} + +void KyraEngine_HoF::drawAnimObjects() { + debugC(9, kDebugLevelAnimator, "KyraEngine_HoF::drawAnimObjects()"); + for (AnimObj *curObject = _animList; curObject; curObject = curObject->nextObject) { + if (!curObject->enabled) + continue; + + int x = curObject->xPos2 - (_screen->getScreenDim(2)->sx << 3); + int y = curObject->yPos2 - _screen->getScreenDim(2)->sy; + int layer = 7; + + if (curObject->flags & 0x800) { + if (curObject->animFlags) + layer = 0; + else + layer = getDrawLayer(curObject->xPos1, curObject->yPos1); + } + curObject->flags |= 0x800; + + if (curObject->index) + drawSceneAnimObject(curObject, x, y, layer); + else + drawCharacterAnimObject(curObject, x, y, layer); + } +} + +void KyraEngine_HoF::refreshAnimObjects(int force) { + debugC(9, kDebugLevelAnimator, "KyraEngine_HoF::refreshAnimObjects(%d)", force); + for (AnimObj *curObject = _animList; curObject; curObject = curObject->nextObject) { + if (!curObject->enabled) + continue; + if (!curObject->needRefresh && !force) + continue; + + int x = curObject->xPos2 - curObject->width2; + if (x < 0) + x = 0; + if (x >= 320) + x = 319; + int y = curObject->yPos2 - curObject->height2; + if (y < 0) + y = 0; + if (y >= 143) + y = 142; + + int width = curObject->width + curObject->width2 + 8; + int height = curObject->height + curObject->height2*2; + if (width + x > 320) + width -= width + x - 322; + if (height + y > 143) + height -= height + y - 144; + + _screen->hideMouse(); + _screen->copyRegion(x, y, x, y, width, height, 2, 0, Screen::CR_NO_P_CHECK); + _screen->showMouse(); + + curObject->needRefresh = false; + } +} + +void KyraEngine_HoF::updateItemAnimations() { + debugC(9, kDebugLevelAnimator, "KyraEngine_HoF::updateItemAnimations()"); + bool nextFrame = false; + + if (_itemAnimData[0].itemIndex == -1 || _inventorySaved) + return; + + const ItemAnimData_v2 *s = &_itemAnimData[_nextAnimItem]; + ActiveItemAnim *a = &_activeItemAnim[_nextAnimItem]; + + if (++_nextAnimItem == 14) { + _nextAnimItem = 0; + return; + } + + uint32 ctime = _system->getMillis(); + if (ctime < a->nextFrame) + return; + + uint16 shpIdx = s->frames[a->currentFrame].index + 64; + if ((s->itemIndex == _handItemSet || s->itemIndex == _itemInHand) && (!_mouseState && _screen->isMouseVisible())) { + nextFrame = true; + _screen->setMouseCursor(8, 15, getShapePtr(shpIdx)); + } + + for (int i = 0; i < 10; i++) { + if (s->itemIndex == _mainCharacter.inventory[i]) { + nextFrame = true; + _screen->drawShape(2, getShapePtr(240 + i), 304, 184, 0, 0); + _screen->drawShape(2, getShapePtr(shpIdx), 304, 184, 0, 0); + _screen->copyRegion(304, 184, _inventoryX[i], _inventoryY[i], 16, 16, 2, 0); + } + } + + _screen->updateScreen(); + + for (int i = 11; i < 40; i++) { + AnimObj *animObject = &_animObjects[i]; + if (animObject->shapeIndex2 == s->itemIndex + 64) { + if (s->itemIndex == 121) { + int f = findItem(_mainCharacter.sceneId, 121); + int nx = _itemList[f].x - 4; + if (nx > 12) { + if (lineIsPassable(nx, _itemList[f].y)) { + animObject->xPos2 -= 4; + _itemList[f].x -= 4; + } + } + } + animObject->shapePtr = getShapePtr(shpIdx); + animObject->shapeIndex1 = shpIdx; + animObject->needRefresh = 1; + nextFrame = true; + } + } + + if (nextFrame) { + a->nextFrame = _system->getMillis() + (s->frames[a->currentFrame].delay * _tickLength); + a->currentFrame = ++a->currentFrame % s->numFrames; + } +} + +void KyraEngine_HoF::updateCharFacing() { + debugC(9, kDebugLevelAnimator, "KyraEngine_HoF::updateCharFacing()"); + if (_mainCharacter.x1 > _mouseX) + _mainCharacter.facing = 5; + else + _mainCharacter.facing = 3; + + _mainCharacter.animFrame = _characterFrameTable[_mainCharacter.facing]; + updateCharacterAnim(0); + refreshAnimObjectsIfNeed(); +} + +void KyraEngine_HoF::updateCharacterAnim(int) { + debugC(9, kDebugLevelAnimator, "KyraEngine_HoF::updateCharacterAnim(-)"); + Character *c = &_mainCharacter; + AnimObj *animState = _animObjects; + + animState->needRefresh = 1; + animState->specialRefresh = 1; + + if (c->facing >= 1 && c->facing <= 3) + animState->flags |= 1; + else if (c->facing >= 5 && c->facing <= 7) + animState->flags &= ~1; + + animState->xPos2 = animState->xPos1 = c->x1; + animState->yPos2 = animState->yPos1 = c->y1; + animState->shapePtr = getShapePtr(c->animFrame); + animState->shapeIndex1 = animState->shapeIndex2 = c->animFrame; + + int xAdd = _shapeDescTable[c->animFrame-9].xAdd; + int yAdd = _shapeDescTable[c->animFrame-9].yAdd; + + _charScaleX = _charScaleY = getScale(c->x1, c->y1); + + animState->xPos2 += (xAdd * _charScaleX) >> 8; + animState->yPos2 += (yAdd * _charScaleY) >> 8; + animState->width2 = 8; + animState->height2 = 10; + + _animList = deleteAnimListEntry(_animList, animState); + if (_animList) + _animList = addToAnimListSorted(_animList, animState); + else + _animList = initAnimList(_animList, animState); + + updateCharPal(1); +} + +void KyraEngine_HoF::updateSceneAnim(int anim, int newFrame) { + debugC(9, kDebugLevelAnimator, "KyraEngine_HoF::updateSceneAnim(%d, %d)", anim, newFrame); + AnimObj *animObject = &_animObjects[1+anim]; + if (!animObject->enabled) + return; + + animObject->needRefresh = 1; + animObject->specialRefresh = 1; + animObject->flags = 0; + + if (_sceneAnims[anim].flags & 2) + animObject->flags |= 0x800; + else + animObject->flags &= ~0x800; + + if (_sceneAnims[anim].flags & 4) + animObject->flags |= 1; + else + animObject->flags &= ~1; + + if (_sceneAnims[anim].flags & 0x20) { + animObject->shapePtr = _sceneShapeTable[newFrame]; + animObject->shapeIndex2 = 0xFFFF; + animObject->shapeIndex3 = 0xFFFF; + animObject->animNum = 0xFFFF; + } else { + animObject->shapePtr = 0; + animObject->shapeIndex3 = newFrame; + animObject->animNum = anim; + } + + animObject->xPos1 = _sceneAnims[anim].x; + animObject->yPos1 = _sceneAnims[anim].y; + animObject->xPos2 = _sceneAnims[anim].x2; + animObject->yPos2 = _sceneAnims[anim].y2; + + if (_sceneAnims[anim].flags & 2) { + _animList = deleteAnimListEntry(_animList, animObject); + if (!_animList) + _animList = initAnimList(_animList, animObject); + else + _animList = addToAnimListSorted(_animList, animObject); + } +} + +void KyraEngine_HoF::drawSceneAnimObject(AnimObj *obj, int x, int y, int layer) { + debugC(9, kDebugLevelAnimator, "KyraEngine_HoF::drawSceneAnimObject(%p, %d, %d, %d)", (const void*)obj, x, y, layer); + if (obj->type == 1) { + if (obj->shapeIndex1 == 0xFFFF) + return; + int scale = getScale(obj->xPos1, obj->yPos1); + _screen->drawShape(2, getShapePtr(obj->shapeIndex1), x, y, 2, obj->flags | 4, layer, scale, scale); + return; + } + + if (obj->shapePtr) { + _screen->drawShape(2, obj->shapePtr, x, y, 2, obj->flags, layer); + } else { + if (obj->shapeIndex3 == 0xFFFF || obj->animNum == 0xFFFF) + return; + + int flags = 0x4000; + if (obj->flags & 0x800) + flags |= 0x8000; + + if (_sceneAnims[obj->animNum].wsaFlag) { + x = y = 0; + } else { + x = obj->xPos2; + y = obj->yPos2; + } + + _sceneAnimMovie[obj->animNum]->setX(x); + _sceneAnimMovie[obj->animNum]->setY(y); + _sceneAnimMovie[obj->animNum]->setDrawPage(2); + _sceneAnimMovie[obj->animNum]->displayFrame(obj->shapeIndex3, int(flags | layer), 0, 0); + } +} + +void KyraEngine_HoF::drawCharacterAnimObject(AnimObj *obj, int x, int y, int layer) { + debugC(9, kDebugLevelAnimator, "KyraEngine_HoF::drawCharacterAnimObject(%p, %d, %d, %d)", (const void*)obj, x, y, layer); + if (_drawNoShapeFlag || obj->shapeIndex1 == 0xFFFF) + return; + _screen->drawShape(2, getShapePtr(obj->shapeIndex1), x, y, 2, obj->flags | 4, layer, _charScaleX, _charScaleY); +} + +void KyraEngine_HoF::addItemToAnimList(int item) { + debugC(9, kDebugLevelAnimator, "KyraEngine_HoF::addItemToAnimList(%d)", item); + restorePage3(); + + AnimObj *animObj = &_animObjects[11+item]; + + animObj->enabled = 1; + animObj->needRefresh = 1; + animObj->specialRefresh = 1; + + int itemId = _itemList[item].id; + + animObj->xPos2 = animObj->xPos1 = _itemList[item].x; + animObj->yPos2 = animObj->yPos1 = _itemList[item].y; + + animObj->shapePtr = getShapePtr(64+itemId); + animObj->shapeIndex2 = animObj->shapeIndex1 = 64+itemId; + + int scaleY, scaleX; + scaleY = scaleX = getScale(animObj->xPos1, animObj->yPos1); + + uint8 *shapePtr = getShapePtr(64+itemId); + animObj->xPos3 = (animObj->xPos2 -= (_screen->getShapeScaledWidth(shapePtr, scaleX) >> 1)); + animObj->yPos3 = (animObj->yPos2 -= _screen->getShapeScaledHeight(shapePtr, scaleY)); + + animObj->width2 = animObj->height2 = 0; + + _animList = addToAnimListSorted(_animList, animObj); + animObj->needRefresh = 1; + animObj->specialRefresh = 1; +} + +void KyraEngine_HoF::deleteItemAnimEntry(int item) { + debugC(9, kDebugLevelAnimator, "KyraEngine_HoF::deleteItemAnimEntry(%d)", item); + AnimObj *animObj = &_animObjects[11+item]; + + restorePage3(); + + animObj->shapePtr = 0; + animObj->shapeIndex1 = 0xFFFF; + animObj->shapeIndex2 = 0xFFFF; + animObj->needRefresh = 1; + animObj->specialRefresh = 1; + + refreshAnimObjectsIfNeed(); + + animObj->enabled = 0; + _animList = deleteAnimListEntry(_animList, animObj); +} + +void KyraEngine_HoF::setCharacterAnimDim(int w, int h) { + debugC(9, kDebugLevelAnimator, "KyraEngine_HoF::setCharacterAnimDim(%d, %d)", w, h); + restorePage3(); + + _animObj0Width = _animObjects[0].width; + _animObj0Height = _animObjects[0].height; + + _animObjects[0].width = w; + _animObjects[0].height = h; +} + +void KyraEngine_HoF::resetCharacterAnimDim() { + debugC(9, kDebugLevelAnimator, "KyraEngine_HoF::resetCharacterAnimDim()"); + restorePage3(); + + _animObjects[0].width = _animObj0Width; + _animObjects[0].height = _animObj0Height; +} + +} // end of namespace Kyra + diff --git a/engines/kyra/animator_mr.cpp b/engines/kyra/animator_mr.cpp new file mode 100644 index 0000000000..8cf99c0290 --- /dev/null +++ b/engines/kyra/animator_mr.cpp @@ -0,0 +1,483 @@ +/* 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_mr.h" +#include "kyra/resource.h" +#include "kyra/wsamovie.h" + +namespace Kyra { + +void KyraEngine_MR::restorePage3() { + debugC(9, kDebugLevelAnimator, "KyraEngine_MR::restorePage3()"); + screen()->copyBlockToPage(2, 0, 0, 320, 200, _gamePlayBuffer); +} + +void KyraEngine_MR::clearAnimObjects() { + debugC(9, kDebugLevelAnimator, "KyraEngine_MR::clearAnimObjects()"); + + for (int i = 0; i < 67; ++i) + _animObjects[i].enabled = false; + + _animObjects[0].index = 0; + _animObjects[0].type = 0; + _animObjects[0].enabled = true; + _animObjects[0].specialRefresh = 1; + _animObjects[0].flags = 0x800; + _animObjects[0].width = 57; + _animObjects[0].height = 91; + _animObjects[0].width2 = 4; + _animObjects[0].height2 = 10; + + for (int i = 1; i < 17; ++i) { + _animObjects[i].index = i; + _animObjects[i].type = 2; + _animObjects[i].flags = 0; + _animObjects[i].enabled = false; + _animObjects[i].needRefresh = 0; + _animObjects[i].specialRefresh = 1; + } + + for (int i = 17; i <= 66; ++i) { + _animObjects[i].index = i; + _animObjects[i].type = 1; + _animObjects[i].specialRefresh = 1; + _animObjects[i].flags = 0x800; + _animObjects[i].width = 24; + _animObjects[i].height = 20; + _animObjects[i].width2 = 0; + _animObjects[i].height2 = 0; + } +} + +void KyraEngine_MR::animSetupPaletteEntry(AnimObj *anim) { + debugC(9, kDebugLevelAnimator, "KyraEngine_MR::animSetupPaletteEntry(%p)", (const void*)anim); + int layer = _screen->getLayer(anim->xPos1, anim->yPos1) - 1; + int16 count = 0; + for (int i = 0; i < 3; ++i) + count += _sceneDatPalette[layer*3+i]; + count /= 3; + count *= -1; + count = MAX(0, MIN(count, 10)); + anim->palette = count / 3; +} + +void KyraEngine_MR::drawAnimObjects() { + debugC(9, kDebugLevelAnimator, "KyraEngine_MR::drawAnimObjects()"); + for (AnimObj *curObject = _animList; curObject; curObject = curObject->nextObject) { + if (!curObject->enabled) + continue; + + int x = curObject->xPos2 - (_screen->getScreenDim(2)->sx << 3); + int y = curObject->yPos2 - _screen->getScreenDim(2)->sy; + int layer = 7; + + if (curObject->flags & 0x800) { + if (!curObject->specialRefresh) + layer = 0; + else + layer = getDrawLayer(curObject->xPos1, curObject->yPos1); + } + + if (curObject->index) + drawSceneAnimObject(curObject, x, y, layer); + else + drawCharacterAnimObject(curObject, x, y, layer); + } +} + +void KyraEngine_MR::drawSceneAnimObject(AnimObj *obj, int x, int y, int layer) { + debugC(9, kDebugLevelAnimator, "KyraEngine_MR::drawSceneAnimObject(%p, %d, %d, %d)", (const void*)obj, x, y, layer); + if (obj->type == 1) { + if (obj->shapeIndex1 == 0xFFFF) + return; + int scale = getScale(obj->xPos1, obj->yPos1); + _screen->drawShape(2, getShapePtr(obj->shapeIndex1), x, y, 2, obj->flags | 0x104, _paletteOverlay, obj->palette, layer, scale, scale); + } else { + if (obj->shapePtr) { + _screen->drawShape(2, obj->shapePtr, x, y, 2, obj->flags, 7); + } else { + if (obj->shapeIndex3 == 0xFFFF || obj->animNum == 0xFFFF) + return; + uint16 flags = 0x4000; + if (obj->flags & 0x800) + flags |= 0x8000; + x = obj->xPos2 - _sceneAnimMovie[obj->animNum]->xAdd(); + y = obj->yPos2 - _sceneAnimMovie[obj->animNum]->yAdd(); + _sceneAnimMovie[obj->animNum]->setDrawPage(2); + _sceneAnimMovie[obj->animNum]->setX(x); + _sceneAnimMovie[obj->animNum]->setY(y); + _sceneAnimMovie[obj->animNum]->displayFrame(obj->shapeIndex3, flags | layer); + } + } +} + +void KyraEngine_MR::drawCharacterAnimObject(AnimObj *obj, int x, int y, int layer) { + debugC(9, kDebugLevelAnimator, "KyraEngine_MR::drawCharacterAnimObject(%p, %d, %d, %d)", (const void*)obj, x, y, layer); + if (_drawNoShapeFlag) + return; + + if (_mainCharacter.animFrame < 9) + _mainCharacter.animFrame = 87; + + if (obj->shapeIndex1 == 0xFFFF || _mainCharacter.animFrame == 87) + return; + + _screen->drawShape(2, getShapePtr(421), _mainCharacter.x3, _mainCharacter.y3, 2, obj->flags | 0x304, _paletteOverlay, 3, layer, _charScale, _charScale); + uint8 *shape = getShapePtr(_mainCharacter.animFrame); + if (shape) + _screen->drawShape(2, shape, x, y, 2, obj->flags | 4, layer, _charScale, _charScale); +} + +void KyraEngine_MR::refreshAnimObjects(int force) { + debugC(9, kDebugLevelAnimator, "KyraEngine_MR::refreshAnimObjects(%d)", force); + for (AnimObj *curObject = _animList; curObject; curObject = curObject->nextObject) { + if (!curObject->enabled) + continue; + if (!curObject->needRefresh && !force) + continue; + + const int scale = (curObject->index == 0) ? _charScale : 0; + + int x = curObject->xPos2 - curObject->width2; + if (scale) + x -= (0x100 - scale) >> 4; + + if (x < 0) + x = 0; + if (x >= 320) + x = 319; + + int y = curObject->yPos2 - curObject->height2; + if (scale) + y -= (0x100 - scale) >> 3; + if (y < 0) + y = 0; + if (y >= 187) + y = 186; + + int width = curObject->width + curObject->width2 + 8; + int height = curObject->height + curObject->height2*2; + if (width + x > 320) + width -= width + x - 322; + + const int maxY = _inventoryState ? 143 : 187; + if (height + y > maxY) + height -= height + y - (maxY + 1); + + if (height > 0) { + _screen->hideMouse(); + _screen->copyRegion(x, y, x, y, width, height, 2, 0, Screen::CR_NO_P_CHECK); + _screen->showMouse(); + } + + curObject->needRefresh = false; + } +} + +void KyraEngine_MR::updateCharacterAnim(int charId) { + debugC(9, kDebugLevelAnimator, "KyraEngine_MR::updateCharacterAnim(%d)", charId); + + AnimObj *obj = &_animObjects[0]; + obj->needRefresh = true; + obj->flags &= ~1; + obj->xPos1 = _mainCharacter.x1; + obj->yPos1 = _mainCharacter.y1; + obj->shapePtr = getShapePtr(_mainCharacter.animFrame); + obj->shapeIndex1 = obj->shapeIndex2 = _mainCharacter.animFrame; + + int shapeOffsetX = 0, shapeOffsetY = 0; + if (_mainCharacter.animFrame >= 50 && _mainCharacter.animFrame <= 87) { + shapeOffsetX = _malcolmShapeXOffset; + shapeOffsetY = _malcolmShapeYOffset; + } else { + shapeOffsetX = _newShapeXAdd; + shapeOffsetY = _newShapeYAdd; + } + + obj->xPos2 = _mainCharacter.x1; + obj->yPos2 = _mainCharacter.y1; + _charScale = getScale(_mainCharacter.x1, _mainCharacter.y1); + obj->xPos2 += (shapeOffsetX * _charScale) >> 8; + obj->yPos2 += (shapeOffsetY * _charScale) >> 8; + _mainCharacter.x3 = _mainCharacter.x1 - (_charScale >> 4) - 1; + _mainCharacter.y3 = _mainCharacter.y1 - (_charScale >> 6) - 1; + if (_charBackUpWidth2 == -1) { + obj->width2 = 4; + obj->height2 = 10; + } + + for (int i = 1; i <= 16; ++i) { + if (_animObjects[i].enabled && _animObjects[i].specialRefresh) + _animObjects[i].needRefresh = true; + } + + _animList = deleteAnimListEntry(_animList, obj); + if (_animList) + _animList = addToAnimListSorted(_animList, obj); + else + _animList = initAnimList(_animList, obj); + + if (!_loadingState) + updateCharPal(1); +} + +void KyraEngine_MR::updateSceneAnim(int anim, int newFrame) { + debugC(9, kDebugLevelAnimator, "KyraEngine_MR::updateSceneAnim(%d, %d)", anim, newFrame); + AnimObj *animObject = &_animObjects[1+anim]; + if (!animObject->enabled) + return; + + animObject->needRefresh = true; + + if (_sceneAnims[anim].flags & 2) + animObject->flags |= 1; + else + animObject->flags &= ~1; + + if (_sceneAnims[anim].flags & 4) { + animObject->shapePtr = _sceneShapes[newFrame]; + animObject->shapeIndex2 = 0xFFFF; + animObject->shapeIndex3 = 0xFFFF; + animObject->animNum = 0xFFFF; + } else { + animObject->shapePtr = 0; + animObject->shapeIndex3 = newFrame; + animObject->animNum = anim; + } + + animObject->xPos1 = _sceneAnims[anim].x; + animObject->yPos1 = _sceneAnims[anim].y; + animObject->xPos2 = _sceneAnims[anim].x2; + animObject->yPos2 = _sceneAnims[anim].y2; + + if (_sceneAnims[anim].flags & 0x20) { + _animList = deleteAnimListEntry(_animList, animObject); + if (!_animList) + _animList = initAnimList(_animList, animObject); + else + _animList = addToAnimListSorted(_animList, animObject); + } +} + +void KyraEngine_MR::setupSceneAnimObject(int animId, uint16 flags, int x, int y, int x2, int y2, int w, + int h, int unk10, int specialSize, int unk14, int shape, const char *filename) { + debugC(9, kDebugLevelAnimator, "KyraEngine_MR::setupSceneAnimObject(%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, '%s')", + animId, flags, x, y, x2, y2, w, h, unk10, specialSize, unk14, shape, filename); + restorePage3(); + SceneAnim &anim = _sceneAnims[animId]; + anim.flags = flags; + anim.x = x; + anim.y = y; + anim.x2 = x2; + anim.y2 = y2; + anim.width = w; + anim.height = h; + anim.specialSize = specialSize; + anim.shapeIndex = shape; + if (filename) + strcpy(anim.filename, filename); + + if (flags & 8) { + _sceneAnimMovie[animId]->open(filename, 1, 0); + musicUpdate(0); + if (_sceneAnimMovie[animId]->opened()) { + anim.wsaFlag = 1; + if (x2 == -1) + x2 = _sceneAnimMovie[animId]->xAdd(); + if (y2 == -1) + y2 = _sceneAnimMovie[animId]->yAdd(); + if (w == -1) + w = _sceneAnimMovie[animId]->width(); + if (h == -1) + h = _sceneAnimMovie[animId]->height(); + if (x == -1) + x = (w >> 1) + x2; + if (y == -1) + y = y2 + h - 1; + + anim.x = x; + anim.y = y; + anim.x2 = x2; + anim.y2 = y2; + anim.width = w; + anim.height = h; + } + } + + AnimObj *obj = &_animObjects[1+animId]; + obj->enabled = true; + obj->needRefresh = true; + + obj->specialRefresh = (anim.flags & 0x20) ? 1 : 0; + obj->flags = (anim.flags & 0x10) ? 0x800 : 0; + if (anim.flags & 2) + obj->flags |= 1; + + obj->xPos1 = anim.x; + obj->yPos1 = anim.y; + + if ((anim.flags & 4) && anim.shapeIndex != -1) + obj->shapePtr = _sceneShapes[anim.shapeIndex]; + else + obj->shapePtr = 0; + + if (anim.flags & 8) { + obj->shapeIndex3 = anim.shapeIndex; + obj->animNum = animId; + } else { + obj->shapeIndex3 = 0xFFFF; + obj->animNum = 0xFFFF; + } + + obj->xPos3 = obj->xPos2 = anim.x2; + obj->yPos3 = obj->yPos2 = anim.y2; + obj->width = anim.width; + obj->height = anim.height; + obj->width2 = obj->height2 = anim.specialSize; + + if (_animList) + _animList = addToAnimListSorted(_animList, obj); + else + _animList = initAnimList(_animList, obj); +} + +void KyraEngine_MR::removeSceneAnimObject(int anim, int refresh) { + debugC(9, kDebugLevelAnimator, "KyraEngine_MR::removeSceneAnimObject(%d, %d)", anim, refresh); + AnimObj *obj = &_animObjects[anim+1]; + restorePage3(); + obj->shapeIndex3 = 0xFFFF; + obj->animNum = 0xFFFF; + obj->needRefresh = true; + + if (refresh) + refreshAnimObjectsIfNeed(); + + obj->enabled = false; + _animList = deleteAnimListEntry(_animList, obj); + _sceneAnimMovie[anim]->close(); +} + +void KyraEngine_MR::setCharacterAnimDim(int w, int h) { + debugC(9, kDebugLevelAnimator, "KyraEngine_MR::setCharacterAnimDim(%d, %d)", w, h); + restorePage3(); + _charBackUpWidth = _animObjects[0].width; + _charBackUpWidth2 = _animObjects[0].width2; + _charBackUpHeight = _animObjects[0].height; + _charBackUpHeight2 = _animObjects[0].height2; + + _animObjects[0].width2 = (w - _charBackUpWidth) / 2; + _animObjects[0].height2 = h - _charBackUpHeight; + _animObjects[0].width = w; + _animObjects[0].height = h; +} + +void KyraEngine_MR::resetCharacterAnimDim() { + debugC(9, kDebugLevelAnimator, "KyraEngine_MR::resetCharacterAnimDim()"); + restorePage3(); + _animObjects[0].width2 = _charBackUpWidth2; + _animObjects[0].height2 = _charBackUpHeight2; + _animObjects[0].width = _charBackUpWidth; + _animObjects[0].height = _charBackUpHeight; + _charBackUpWidth2 = _charBackUpHeight2 = -1; + _charBackUpWidth = _charBackUpHeight = -1; +} + +void KyraEngine_MR::showIdleAnim() { + debugC(9, kDebugLevelMain | kDebugLevelAnimator, "KyraEngine_MR::showIdleAnim()"); + + if (_mainCharacter.sceneId == 20 || _mainCharacter.sceneId == 21 + || _mainCharacter.sceneId == 12 || _mainCharacter.sceneId == 11) + return; + + if (_mainCharacter.animFrame == 87) + return; + + if (!_nextIdleType && !talkObjectsInCurScene()) { + malcolmRandomChat(); + } else { + static const char *facingTable[] = { + "A", "R", "R", "FR", "FX", "FL", "L", "L" + }; + + char filename[14]; + snprintf(filename, 14, "MI0%s%.02d.EMC", facingTable[_mainCharacter.facing], _malcolmShapes); + + if (_res->exists(filename)) + runTemporaryScript(filename, 1, 1, 1, 1); + } + + _nextIdleType = !_nextIdleType; +} + +void KyraEngine_MR::addItemToAnimList(int item) { + debugC(9, kDebugLevelAnimator, "KyraEngine_MR::addItemToAnimList(%d)", item); + restorePage3(); + + AnimObj *animObj = &_animObjects[17+item]; + + animObj->enabled = 1; + animObj->needRefresh = 1; + + int itemId = _itemList[item].id; + + animObj->xPos2 = animObj->xPos1 = _itemList[item].x; + animObj->yPos2 = animObj->yPos1 = _itemList[item].y; + + animObj->shapePtr = getShapePtr(248+itemId); + animSetupPaletteEntry(animObj); + animObj->shapeIndex2 = animObj->shapeIndex1 = 248+itemId; + + int scaleY, scaleX; + scaleY = scaleX = getScale(animObj->xPos1, animObj->yPos1); + + uint8 *shapePtr = getShapePtr(248+itemId); + animObj->xPos3 = (animObj->xPos2 -= (_screen->getShapeScaledWidth(shapePtr, scaleX) >> 1)); + animObj->yPos3 = (animObj->yPos2 -= _screen->getShapeScaledHeight(shapePtr, scaleY)); + + animObj->width2 = animObj->height2 = 0; + + _animList = addToAnimListSorted(_animList, animObj); + animObj->needRefresh = 1; +} + +void KyraEngine_MR::deleteItemAnimEntry(int item) { + debugC(9, kDebugLevelAnimator, "KyraEngine_MR::deleteItemAnimEntry(%d)", item); + AnimObj *animObj = &_animObjects[17+item]; + + restorePage3(); + + animObj->shapePtr = 0; + animObj->shapeIndex1 = 0xFFFF; + animObj->shapeIndex2 = 0xFFFF; + animObj->needRefresh = 1; + + refreshAnimObjectsIfNeed(); + + animObj->enabled = 0; + _animList = deleteAnimListEntry(_animList, animObj); +} + +} // end of namespace Kyra + diff --git a/engines/kyra/animator_v2.cpp b/engines/kyra/animator_v2.cpp deleted file mode 100644 index 8efbdbe747..0000000000 --- a/engines/kyra/animator_v2.cpp +++ /dev/null @@ -1,490 +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_v2.h" -#include "kyra/wsamovie.h" - -#include "common/endian.h" - -namespace Kyra { - -void KyraEngine_v2::clearAnimObjects() { - debugC(9, kDebugLevelAnimator, "KyraEngine_v2::clearAnimObjects()"); - memset(_animObjects, 0, sizeof(_animObjects)); - - _animObjects[0].index = 0; - _animObjects[0].type = 0; - _animObjects[0].enabled = 1; - _animObjects[0].flags = 0x800; - _animObjects[0].width = 32; - _animObjects[0].height = 49; - _animObjects[0].width2 = 4; - _animObjects[0].height2 = 10; - - for (int i = 1; i < 11; ++i) { - _animObjects[i].index = i; - _animObjects[i].type = 2; - } - - for (int i = 11; i <= 40; ++i) { - _animObjects[i].index = i; - _animObjects[i].type = 1; - _animObjects[i].flags = 0x800; - _animObjects[i].width = 16; - _animObjects[i].height = 16; - } -} - -KyraEngine_v2::AnimObj *KyraEngine_v2::initAnimList(AnimObj *list, AnimObj *entry) { - debugC(9, kDebugLevelAnimator, "KyraEngine_v2::initAnimList(%p, %p)", (const void*)list, (const void*)entry); - entry->nextObject = list; - return entry; -} - -KyraEngine_v2::AnimObj *KyraEngine_v2::addToAnimListSorted(AnimObj *list, AnimObj *add) { - debugC(9, kDebugLevelAnimator, "KyraEngine_v2::addToAnimListSorted(%p, %p)", (const void*)list, (const void*)add); - add->nextObject = 0; - - if (!list) - return add; - - if (add->yPos1 <= list->yPos1) { - add->nextObject = list; - return add; - } - - AnimObj *cur = list; - AnimObj *prev = list; - while (add->yPos1 > cur->yPos1) { - AnimObj *temp = cur->nextObject; - if (!temp) - break; - prev = cur; - cur = temp; - } - - if (add->yPos1 <= cur->yPos1) { - prev->nextObject = add; - add->nextObject = cur; - } else { - cur->nextObject = add; - add->nextObject = 0; - } - return list; -} - -KyraEngine_v2::AnimObj *KyraEngine_v2::deleteAnimListEntry(AnimObj *list, AnimObj *entry) { - debugC(9, kDebugLevelAnimator, "KyraEngine_v2::addToAnimListSorted(%p, %p)", (const void*)list, (const void*)entry); - if (!list) - return 0; - - AnimObj *old = 0; - AnimObj *cur = list; - - while (true) { - if (cur == entry) - break; - if (!cur->nextObject) - break; - old = cur; - cur = cur->nextObject; - } - - if (cur != entry) - return list; - - if (cur == list) { - if (!cur->nextObject) - return 0; - cur = cur->nextObject; - return cur; - } - - if (!cur->nextObject) { - if (!old) - return 0; - old->nextObject = 0; - return list; - } - - if (cur != entry) - return list; - - old->nextObject = entry->nextObject; - return list; -} - -void KyraEngine_v2::drawAnimObjects() { - debugC(9, kDebugLevelAnimator, "KyraEngine_v2::drawAnimObjects()"); - for (AnimObj *curObject = _animList; curObject; curObject = curObject->nextObject) { - if (!curObject->enabled) - continue; - - int x = curObject->xPos2 - (_screen->getScreenDim(2)->sx << 3); - int y = curObject->yPos2 - _screen->getScreenDim(2)->sy; - int layer = 7; - - if (curObject->flags & 0x800) { - if (curObject->animFlags) - layer = 0; - else - layer = getDrawLayer(curObject->xPos1, curObject->yPos1); - } - curObject->flags |= 0x800; - - if (curObject->index) - drawSceneAnimObject(curObject, x, y, layer); - else - drawCharacterAnimObject(curObject, x, y, layer); - } -} - -void KyraEngine_v2::refreshAnimObjects(int force) { - debugC(9, kDebugLevelAnimator, "KyraEngine_v2::refreshAnimObjects(%d)", force); - for (AnimObj *curObject = _animList; curObject; curObject = curObject->nextObject) { - if (!curObject->enabled) - continue; - if (!curObject->needRefresh && !force) - continue; - - int x = curObject->xPos2 - curObject->width2; - if (x < 0) - x = 0; - if (x >= 320) - x = 319; - int y = curObject->yPos2 - curObject->height2; - if (y < 0) - y = 0; - if (y >= 143) - y = 142; - - int width = curObject->width + curObject->width2 + 8; - int height = curObject->height + curObject->height2*2; - if (width + x > 320) - width -= width + x - 322; - if (height + y > 143) - height -= height + y - 144; - - _screen->hideMouse(); - _screen->copyRegion(x, y, x, y, width, height, 2, 0, Screen::CR_NO_P_CHECK); - _screen->showMouse(); - - curObject->needRefresh = false; - } -} - -void KyraEngine_v2::refreshAnimObjectsIfNeed() { - debugC(9, kDebugLevelAnimator, "KyraEngine_v2::refreshAnimObjectsIfNeed()"); - for (AnimObj *curEntry = _animList; curEntry; curEntry = curEntry->nextObject) { - if (curEntry->enabled && curEntry->needRefresh) { - restorePage3(); - drawAnimObjects(); - refreshAnimObjects(0); - _screen->updateScreen(); - return; - } - } -} - -void KyraEngine_v2::updateItemAnimations() { - debugC(9, kDebugLevelAnimator, "KyraEngine_v2::updateItemAnimations()"); - bool nextFrame = false; - - if (_itemAnimData[0].itemIndex == -1 || _inventorySaved) - return; - - const ItemAnimData_v2 *s = &_itemAnimData[_nextAnimItem]; - ActiveItemAnim *a = &_activeItemAnim[_nextAnimItem]; - - if (++_nextAnimItem == 14) { - _nextAnimItem = 0; - return; - } - - uint32 ctime = _system->getMillis(); - if (ctime < a->nextFrame) - return; - - uint16 shpIdx = s->frames[a->currentFrame].index + 64; - if ((s->itemIndex == _handItemSet || s->itemIndex == _itemInHand) && (!_mouseState && _screen->isMouseVisible())) { - nextFrame = true; - _screen->setMouseCursor(8, 15, getShapePtr(shpIdx)); - } - - for (int i = 0; i < 10; i++) { - if (s->itemIndex == _mainCharacter.inventory[i]) { - nextFrame = true; - _screen->drawShape(2, _defaultShapeTable[240 + i], 304, 184, 0, 0); - _screen->drawShape(2, getShapePtr(shpIdx), 304, 184, 0, 0); - _screen->copyRegion(304, 184, _inventoryX[i], _inventoryY[i], 16, 16, 2, 0); - } - } - - _screen->updateScreen(); - - for (int i = 11; i < 40; i++) { - AnimObj *animObject = &_animObjects[i]; - if (animObject->shapeIndex2 == s->itemIndex + 64) { - if (s->itemIndex == 121) { - int f = findItem(_mainCharacter.sceneId, 121); - int nx = _itemList[f].x - 4; - if (nx > 12) { - if (lineIsPassable(nx, _itemList[f].y)) { - animObject->xPos2 -= 4; - _itemList[f].x -= 4; - } - } - } - animObject->shapePtr = _defaultShapeTable[shpIdx]; - animObject->shapeIndex1 = shpIdx; - animObject->needRefresh = 1; - nextFrame = true; - } - } - - if (nextFrame) { - a->nextFrame = _system->getMillis() + (s->frames[a->currentFrame].delay * _tickLength); - a->currentFrame = ++a->currentFrame % s->numFrames; - } -} - -void KyraEngine_v2::flagAnimObjsForRefresh() { - debugC(9, kDebugLevelAnimator, "KyraEngine_v2::flagAnimObjsForRefresh()"); - for (AnimObj *curEntry = _animList; curEntry; curEntry = curEntry->nextObject) - curEntry->needRefresh = 1; -} - -void KyraEngine_v2::flagAnimObjsUnk8() { - debugC(9, kDebugLevelAnimator, "KyraEngine_v2::flagAnimObjsUnk8()"); - for (AnimObj *curEntry = _animList; curEntry; curEntry = curEntry->nextObject) - curEntry->unk8 = 1; -} - -void KyraEngine_v2::updateCharFacing() { - debugC(9, kDebugLevelAnimator, "KyraEngine_v2::updateCharFacing()"); - if (_mainCharacter.x1 > _mouseX) - _mainCharacter.facing = 5; - else - _mainCharacter.facing = 3; - - _mainCharacter.animFrame = _characterFrameTable[_mainCharacter.facing]; - updateCharacterAnim(0); - refreshAnimObjectsIfNeed(); -} - -void KyraEngine_v2::updateCharacterAnim(int) { - debugC(9, kDebugLevelAnimator, "KyraEngine_v2::updateCharacterAnim(-)"); - Character *c = &_mainCharacter; - AnimObj *animState = _animObjects; - - animState->needRefresh = 1; - animState->unk8 = 1; - - if (c->facing >= 1 && c->facing <= 3) - animState->flags |= 1; - else if (c->facing >= 5 && c->facing <= 7) - animState->flags &= ~1; - - animState->xPos2 = animState->xPos1 = c->x1; - animState->yPos2 = animState->yPos1 = c->y1; - animState->shapePtr = _defaultShapeTable[c->animFrame]; - animState->shapeIndex1 = animState->shapeIndex2 = c->animFrame; - - int xAdd = _shapeDescTable[c->animFrame-9].xAdd; - int yAdd = _shapeDescTable[c->animFrame-9].yAdd; - - _charScaleX = _charScaleY = getScale(c->x1, c->y1); - - animState->xPos2 += (xAdd * _charScaleX) >> 8; - animState->yPos2 += (yAdd * _charScaleY) >> 8; - animState->width2 = 8; - animState->height2 = 10; - - _animList = deleteAnimListEntry(_animList, animState); - if (_animList) - _animList = addToAnimListSorted(_animList, animState); - else - _animList = initAnimList(_animList, animState); - - updateCharPal(1); -} - -void KyraEngine_v2::updateSceneAnim(int anim, int newFrame) { - debugC(9, kDebugLevelAnimator, "KyraEngine_v2::updateSceneAnim(%d, %d)", anim, newFrame); - AnimObj *animObject = &_animObjects[1+anim]; - if (!animObject->enabled) - return; - - animObject->needRefresh = 1; - animObject->unk8 = 1; - animObject->flags = 0; - - if (_sceneAnims[anim].flags & 2) - animObject->flags |= 0x800; - else - animObject->flags &= ~0x800; - - if (_sceneAnims[anim].flags & 4) - animObject->flags |= 1; - else - animObject->flags &= ~1; - - if (_sceneAnims[anim].flags & 0x20) { - animObject->shapePtr = _sceneShapeTable[newFrame]; - animObject->shapeIndex2 = 0xFFFF; - animObject->shapeIndex3 = 0xFFFF; - animObject->animNum = 0xFFFF; - } else { - animObject->shapePtr = 0; - animObject->shapeIndex3 = newFrame; - animObject->animNum = anim; - } - - animObject->xPos1 = _sceneAnims[anim].x; - animObject->yPos1 = _sceneAnims[anim].y; - animObject->xPos2 = _sceneAnims[anim].x2; - animObject->yPos2 = _sceneAnims[anim].y2; - - if (_sceneAnims[anim].flags & 2) { - _animList = deleteAnimListEntry(_animList, animObject); - if (!_animList) - _animList = initAnimList(_animList, animObject); - else - _animList = addToAnimListSorted(_animList, animObject); - } -} - -void KyraEngine_v2::drawSceneAnimObject(AnimObj *obj, int x, int y, int layer) { - debugC(9, kDebugLevelAnimator, "KyraEngine_v2::drawSceneAnimObject(%p, %d, %d, %d)", (const void*)obj, x, y, layer); - if (obj->type == 1) { - if (obj->shapeIndex1 == 0xFFFF) - return; - int scale = getScale(obj->xPos1, obj->yPos1); - _screen->drawShape(2, getShapePtr(obj->shapeIndex1), x, y, 2, obj->flags | 4, layer, scale, scale); - return; - } - - if (obj->shapePtr) { - _screen->drawShape(2, obj->shapePtr, x, y, 2, obj->flags, layer); - } else { - if (obj->shapeIndex3 == 0xFFFF || obj->animNum == 0xFFFF) - return; - - int flags = 0x4000; - if (obj->flags & 0x800) - flags |= 0x8000; - - if (_sceneAnims[obj->animNum].wsaFlag) { - x = y = 0; - } else { - x = obj->xPos2; - y = obj->yPos2; - } - - _sceneAnimMovie[obj->animNum]->setX(x); - _sceneAnimMovie[obj->animNum]->setY(y); - _sceneAnimMovie[obj->animNum]->setDrawPage(2); - _sceneAnimMovie[obj->animNum]->displayFrame(obj->shapeIndex3, int(flags | layer), 0, 0); - } -} - -void KyraEngine_v2::drawCharacterAnimObject(AnimObj *obj, int x, int y, int layer) { - debugC(9, kDebugLevelAnimator, "KyraEngine_v2::drawCharacterAnimObject(%p, %d, %d, %d)", (const void*)obj, x, y, layer); - if (_drawNoShapeFlag || obj->shapeIndex1 == 0xFFFF) - return; - _screen->drawShape(2, getShapePtr(obj->shapeIndex1), x, y, 2, obj->flags | 4, layer, _charScaleX, _charScaleY); -} - -void KyraEngine_v2::addItemToAnimList(int item) { - debugC(9, kDebugLevelAnimator, "KyraEngine_v2::addItemToAnimList(%d)", item); - restorePage3(); - - AnimObj *animObj = &_animObjects[11+item]; - - animObj->enabled = 1; - animObj->needRefresh = 1; - animObj->unk8 = 1; - - int itemId = _itemList[item].id; - - animObj->xPos2 = animObj->xPos1 = _itemList[item].x; - animObj->yPos2 = animObj->yPos1 = _itemList[item].y; - - animObj->shapePtr = _defaultShapeTable[64+itemId]; - animObj->shapeIndex2 = animObj->shapeIndex1 = 64+itemId; - - int scaleY, scaleX; - scaleY = scaleX = getScale(animObj->xPos1, animObj->yPos1); - - uint8 *shapePtr = getShapePtr(64+itemId); - animObj->xPos3 = (animObj->xPos2 -= (_screen->getShapeScaledWidth(shapePtr, scaleX) >> 1)); - animObj->yPos3 = (animObj->yPos2 -= _screen->getShapeScaledHeight(shapePtr, scaleY)); - - animObj->width2 = animObj->height2 = 0; - - _animList = addToAnimListSorted(_animList, animObj); - animObj->needRefresh = 1; - animObj->unk8 = 1; -} - -void KyraEngine_v2::deleteItemAnimEntry(int item) { - debugC(9, kDebugLevelAnimator, "KyraEngine_v2::deleteItemAnimEntry(%d)", item); - AnimObj *animObj = &_animObjects[11+item]; - - restorePage3(); - - animObj->shapePtr = 0; - animObj->shapeIndex1 = 0xFFFF; - animObj->shapeIndex2 = 0xFFFF; - animObj->needRefresh = 1; - animObj->unk8 = 1; - - refreshAnimObjectsIfNeed(); - - animObj->enabled = 0; - _animList = deleteAnimListEntry(_animList, animObj); -} - -void KyraEngine_v2::setCharacterAnimDim(int w, int h) { - debugC(9, kDebugLevelAnimator, "KyraEngine_v2::setCharacterAnimDim(%d, %d)", w, h); - restorePage3(); - - _animObj0Width = _animObjects[0].width; - _animObj0Height = _animObjects[0].height; - - _animObjects[0].width = w; - _animObjects[0].height = h; -} - -void KyraEngine_v2::resetCharacterAnimDim() { - debugC(9, kDebugLevelAnimator, "KyraEngine_v2::resetCharacterAnimDim()"); - restorePage3(); - - _animObjects[0].width = _animObj0Width; - _animObjects[0].height = _animObj0Height; -} - -} // end of namespace Kyra - diff --git a/engines/kyra/animator_v3.cpp b/engines/kyra/animator_v3.cpp deleted file mode 100644 index 07a3713908..0000000000 --- a/engines/kyra/animator_v3.cpp +++ /dev/null @@ -1,584 +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_v3.h" -#include "kyra/wsamovie.h" - -namespace Kyra { - -void KyraEngine_v3::clearAnimObjects() { - debugC(9, kDebugLevelAnimator, "KyraEngine_v3::clearAnimObjects()"); - - for (int i = 0; i < 67; ++i) - _animObjects[i].enabled = false; - - _animObjects[0].index = 0; - _animObjects[0].type = 0; - _animObjects[0].enabled = true; - _animObjects[0].unk8 = 1; - _animObjects[0].flags = 0x800; - _animObjects[0].width = 57; - _animObjects[0].height = 91; - _animObjects[0].width2 = 4; - _animObjects[0].height2 = 10; - - for (int i = 1; i < 17; ++i) { - _animObjects[i].index = i; - _animObjects[i].type = 2; - _animObjects[i].flags = 0; - _animObjects[i].enabled = false; - _animObjects[i].needRefresh = 0; - _animObjects[i].unk8 = 1; - } - - for (int i = 17; i <= 66; ++i) { - _animObjects[i].index = i; - _animObjects[i].type = 1; - _animObjects[i].unk8 = 1; - _animObjects[i].flags = 0x800; - _animObjects[i].width = 24; - _animObjects[i].height = 20; - _animObjects[i].width2 = 0; - _animObjects[i].height2 = 0; - } -} - -KyraEngine_v3::AnimObj *KyraEngine_v3::initAnimList(AnimObj *list, AnimObj *entry) { - debugC(9, kDebugLevelAnimator, "KyraEngine_v3::initAnimList(%p, %p)", (const void*)list, (const void*)entry); - entry->nextObject = list; - return entry; -} - -KyraEngine_v3::AnimObj *KyraEngine_v3::addToAnimListSorted(AnimObj *list, AnimObj *add) { - debugC(9, kDebugLevelAnimator, "KyraEngine_v3::addToAnimListSorted(%p, %p)", (const void*)list, (const void*)add); - add->nextObject = 0; - - if (!list) - return add; - - if (add->yPos1 <= list->yPos1) { - add->nextObject = list; - return add; - } - - AnimObj *cur = list; - AnimObj *prev = list; - while (add->yPos1 > cur->yPos1) { - AnimObj *temp = cur->nextObject; - if (!temp) - break; - prev = cur; - cur = temp; - } - - if (add->yPos1 <= cur->yPos1) { - prev->nextObject = add; - add->nextObject = cur; - } else { - cur->nextObject = add; - add->nextObject = 0; - } - return list; -} - -KyraEngine_v3::AnimObj *KyraEngine_v3::deleteAnimListEntry(AnimObj *list, AnimObj *entry) { - debugC(9, kDebugLevelAnimator, "KyraEngine_v3::addToAnimListSorted(%p, %p)", (const void*)list, (const void*)entry); - if (!list) - return 0; - - AnimObj *old = 0; - AnimObj *cur = list; - - while (true) { - if (cur == entry) - break; - if (!cur->nextObject) - break; - old = cur; - cur = cur->nextObject; - } - - if (cur != entry) - return list; - - if (cur == list) { - if (!cur->nextObject) - return 0; - cur = cur->nextObject; - return cur; - } - - if (!cur->nextObject) { - if (!old) - return 0; - old->nextObject = 0; - return list; - } - - if (cur != entry) - return list; - - old->nextObject = entry->nextObject; - return list; -} - -void KyraEngine_v3::animSetupPaletteEntry(AnimObj *anim) { - debugC(9, kDebugLevelAnimator, "KyraEngine_v3::animSetupPaletteEntry(%p)", (const void*)anim); - int layer = _screen->getLayer(anim->xPos1, anim->yPos1) - 1; - int16 count = 0; - for (int i = 0; i < 3; ++i) - count += _sceneDatPalette[layer*3+i]; - count /= 3; - count *= -1; - count = MAX(0, MIN(count, 10)); - anim->palette = count / 3; -} - -void KyraEngine_v3::restorePage3() { - debugC(9, kDebugLevelAnimator, "KyraEngine_v3::restorePage3()"); - musicUpdate(0); - _screen->copyBlockToPage(3, 0, 0, 320, 200, _gamePlayBuffer); - musicUpdate(0); -} - -void KyraEngine_v3::drawAnimObjects() { - debugC(9, kDebugLevelAnimator, "KyraEngine_v3::drawAnimObjects()"); - for (AnimObj *curObject = _animList; curObject; curObject = curObject->nextObject) { - if (!curObject->enabled) - continue; - - int x = curObject->xPos2 - (_screen->getScreenDim(2)->sx << 3); - int y = curObject->yPos2 - _screen->getScreenDim(2)->sy; - int layer = 7; - - if (curObject->flags & 0x800) { - if (!curObject->unk8) - layer = 0; - else - layer = getDrawLayer(curObject->xPos1, curObject->yPos1); - } - - if (curObject->index) - drawSceneAnimObject(curObject, x, y, layer); - else - drawCharacterAnimObject(curObject, x, y, layer); - } -} - -void KyraEngine_v3::drawSceneAnimObject(AnimObj *obj, int x, int y, int layer) { - debugC(9, kDebugLevelAnimator, "KyraEngine_v3::drawSceneAnimObject(%p, %d, %d, %d)", (const void*)obj, x, y, layer); - if (obj->type == 1) { - if (obj->shapeIndex == 0xFFFF) - return; - int scale = getScale(obj->xPos1, obj->yPos1); - _screen->drawShape(2, getShapePtr(obj->shapeIndex), x, y, 2, obj->flags | 0x104, _paletteOverlay, obj->palette, layer, scale, scale); - } else { - if (obj->shapePtr) { - _screen->drawShape(2, obj->shapePtr, x, y, 2, obj->flags, 7); - } else { - if (obj->shapeIndex3 == 0xFFFF || obj->animNum == 0xFFFF) - return; - uint16 flags = 0x4000; - if (obj->flags & 0x800) - flags |= 0x8000; - x = obj->xPos2 - _sceneAnimMovie[obj->animNum]->xAdd(); - y = obj->yPos2 - _sceneAnimMovie[obj->animNum]->yAdd(); - _sceneAnimMovie[obj->animNum]->setDrawPage(2); - _sceneAnimMovie[obj->animNum]->setX(x); - _sceneAnimMovie[obj->animNum]->setY(y); - _sceneAnimMovie[obj->animNum]->displayFrame(obj->shapeIndex3, flags | layer); - } - } -} - -void KyraEngine_v3::drawCharacterAnimObject(AnimObj *obj, int x, int y, int layer) { - debugC(9, kDebugLevelAnimator, "KyraEngine_v3::drawCharacterAnimObject(%p, %d, %d, %d)", (const void*)obj, x, y, layer); - if (_drawNoShapeFlag) - return; - - if (_mainCharacter.animFrame < 9) - _mainCharacter.animFrame = 87; - - if (obj->shapeIndex == 0xFFFF || _mainCharacter.animFrame == 87) - return; - - _screen->drawShape(2, getShapePtr(421), _mainCharacter.x3, _mainCharacter.y3, 2, obj->flags | 0x304, _paletteOverlay, 3, layer, _charScale, _charScale); - uint8 *shape = getShapePtr(_mainCharacter.animFrame); - if (shape) - _screen->drawShape(2, shape, x, y, 2, obj->flags | 4, layer, _charScale, _charScale); -} - -void KyraEngine_v3::refreshAnimObjects(int force) { - debugC(9, kDebugLevelAnimator, "KyraEngine_v3::refreshAnimObjects(%d)", force); - for (AnimObj *curObject = _animList; curObject; curObject = curObject->nextObject) { - if (!curObject->enabled) - continue; - if (!curObject->needRefresh && !force) - continue; - - const int scale = (curObject->index == 0) ? _charScale : 0; - - int x = curObject->xPos2 - curObject->width2; - if (scale) - x -= (0x100 - scale) >> 4; - - if (x < 0) - x = 0; - if (x >= 320) - x = 319; - - int y = curObject->yPos2 - curObject->height2; - if (scale) - y -= (0x100 - scale) >> 3; - if (y < 0) - y = 0; - if (y >= 187) - y = 186; - - int width = curObject->width + curObject->width2 + 8; - int height = curObject->height + curObject->height2*2; - if (width + x > 320) - width -= width + x - 322; - - const int maxY = _inventoryState ? 143 : 187; - if (height + y > maxY) - height -= height + y - (maxY + 1); - - if (height > 0) { - _screen->hideMouse(); - _screen->copyRegion(x, y, x, y, width, height, 2, 0, Screen::CR_NO_P_CHECK); - _screen->showMouse(); - } - - curObject->needRefresh = false; - } -} - -void KyraEngine_v3::refreshAnimObjectsIfNeed() { - debugC(9, kDebugLevelAnimator, "KyraEngine_v3::refreshAnimObjectsIfNeed()"); - for (AnimObj *curEntry = _animList; curEntry; curEntry = curEntry->nextObject) { - if (curEntry->enabled && curEntry->needRefresh) { - restorePage3(); - drawAnimObjects(); - refreshAnimObjects(0); - _screen->updateScreen(); - return; - } - } -} - -void KyraEngine_v3::flagAnimObjsForRefresh() { - debugC(9, kDebugLevelAnimator, "KyraEngine_v3::flagAnimObjsForRefresh()"); - for (AnimObj *curEntry = _animList; curEntry; curEntry = curEntry->nextObject) - curEntry->needRefresh = true; -} - -void KyraEngine_v3::updateCharacterAnim(int charId) { - debugC(9, kDebugLevelAnimator, "KyraEngine_v3::updateCharacterAnim(%d)", charId); - - AnimObj *obj = &_animObjects[0]; - obj->needRefresh = true; - obj->flags &= ~1; - obj->xPos1 = _mainCharacter.x1; - obj->yPos1 = _mainCharacter.y1; - obj->shapePtr = getShapePtr(_mainCharacter.animFrame); - obj->shapeIndex = obj->shapeIndex2 = _mainCharacter.animFrame; - - int shapeOffsetX = 0, shapeOffsetY = 0; - if (_mainCharacter.animFrame >= 50 && _mainCharacter.animFrame <= 87) { - shapeOffsetX = _malcolmShapeXOffset; - shapeOffsetY = _malcolmShapeYOffset; - } else { - shapeOffsetX = _newShapeXAdd; - shapeOffsetY = _newShapeYAdd; - } - - obj->xPos2 = _mainCharacter.x1; - obj->yPos2 = _mainCharacter.y1; - _charScale = getScale(_mainCharacter.x1, _mainCharacter.y1); - obj->xPos2 += (shapeOffsetX * _charScale) >> 8; - obj->yPos2 += (shapeOffsetY * _charScale) >> 8; - _mainCharacter.x3 = _mainCharacter.x1 - (_charScale >> 4) - 1; - _mainCharacter.y3 = _mainCharacter.y1 - (_charScale >> 6) - 1; - if (_charBackUpWidth2 == -1) { - obj->width2 = 4; - obj->height2 = 10; - } - - for (int i = 1; i <= 16; ++i) { - if (_animObjects[i].enabled && _animObjects[i].unk8) - _animObjects[i].needRefresh = true; - } - - _animList = deleteAnimListEntry(_animList, obj); - if (_animList) - _animList = addToAnimListSorted(_animList, obj); - else - _animList = initAnimList(_animList, obj); - - if (!_loadingState) - updateCharPal(1); -} - -void KyraEngine_v3::updateSceneAnim(int anim, int newFrame) { - debugC(9, kDebugLevelAnimator, "KyraEngine_v3::updateSceneAnim(%d, %d)", anim, newFrame); - AnimObj *animObject = &_animObjects[1+anim]; - if (!animObject->enabled) - return; - - animObject->needRefresh = true; - - if (_sceneAnims[anim].flags & 2) - animObject->flags |= 1; - else - animObject->flags &= ~1; - - if (_sceneAnims[anim].flags & 4) { - animObject->shapePtr = _sceneShapes[newFrame]; - animObject->shapeIndex2 = 0xFFFF; - animObject->shapeIndex3 = 0xFFFF; - animObject->animNum = 0xFFFF; - } else { - animObject->shapePtr = 0; - animObject->shapeIndex3 = newFrame; - animObject->animNum = anim; - } - - animObject->xPos1 = _sceneAnims[anim].x; - animObject->yPos1 = _sceneAnims[anim].y; - animObject->xPos2 = _sceneAnims[anim].x2; - animObject->yPos2 = _sceneAnims[anim].y2; - - if (_sceneAnims[anim].flags & 0x20) { - _animList = deleteAnimListEntry(_animList, animObject); - if (!_animList) - _animList = initAnimList(_animList, animObject); - else - _animList = addToAnimListSorted(_animList, animObject); - } -} - -void KyraEngine_v3::setupSceneAnimObject(int animId, uint16 flags, int x, int y, int x2, int y2, int w, - int h, int unk10, int specialSize, int unk14, int shape, const char *filename) { - debugC(9, kDebugLevelAnimator, "KyraEngine_v3::setupSceneAnimObject(%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, '%s')", - animId, flags, x, y, x2, y2, w, h, unk10, specialSize, unk14, shape, filename); - restorePage3(); - SceneAnim &anim = _sceneAnims[animId]; - anim.flags = flags; - anim.x = x; - anim.y = y; - anim.x2 = x2; - anim.y2 = y2; - anim.width = w; - anim.height = h; - anim.unk10 = unk10; - anim.specialSize = specialSize; - anim.unk14 = unk14; - anim.shapeIndex = shape; - if (filename) - strcpy(anim.filename, filename); - - if (flags & 8) { - _sceneAnimMovie[animId]->open(filename, 1, 0); - musicUpdate(0); - if (_sceneAnimMovie[animId]->opened()) { - anim.wsaFlag = 1; - if (x2 == -1) - x2 = _sceneAnimMovie[animId]->xAdd(); - if (y2 == -1) - y2 = _sceneAnimMovie[animId]->yAdd(); - if (w == -1) - w = _sceneAnimMovie[animId]->width(); - if (h == -1) - h = _sceneAnimMovie[animId]->height(); - if (x == -1) - x = (w >> 1) + x2; - if (y == -1) - y = y2 + h - 1; - - anim.x = x; - anim.y = y; - anim.x2 = x2; - anim.y2 = y2; - anim.width = w; - anim.height = h; - } - } - - AnimObj *obj = &_animObjects[1+animId]; - obj->enabled = true; - obj->needRefresh = true; - - obj->unk8 = (anim.flags & 0x20) ? 1 : 0; - obj->flags = (anim.flags & 0x10) ? 0x800 : 0; - if (anim.flags & 2) - obj->flags |= 1; - - obj->xPos1 = anim.x; - obj->yPos1 = anim.y; - - if ((anim.flags & 4) && anim.shapeIndex != 0xFFFF) - obj->shapePtr = _sceneShapes[anim.shapeIndex]; - else - obj->shapePtr = 0; - - if (anim.flags & 8) { - obj->shapeIndex3 = anim.shapeIndex; - obj->animNum = animId; - } else { - obj->shapeIndex3 = 0xFFFF; - obj->animNum = 0xFFFF; - } - - obj->xPos3 = obj->xPos2 = anim.x2; - obj->yPos3 = obj->yPos2 = anim.y2; - obj->width = anim.width; - obj->height = anim.height; - obj->width2 = obj->height2 = anim.specialSize; - - if (_animList) - _animList = addToAnimListSorted(_animList, obj); - else - _animList = initAnimList(_animList, obj); -} - -void KyraEngine_v3::removeSceneAnimObject(int anim, int refresh) { - debugC(9, kDebugLevelAnimator, "KyraEngine_v3::removeSceneAnimObject(%d, %d)", anim, refresh); - AnimObj *obj = &_animObjects[anim+1]; - restorePage3(); - obj->shapeIndex3 = 0xFFFF; - obj->animNum = 0xFFFF; - obj->needRefresh = true; - - if (refresh) - refreshAnimObjectsIfNeed(); - - obj->enabled = false; - _animList = deleteAnimListEntry(_animList, obj); - _sceneAnimMovie[anim]->close(); -} - -void KyraEngine_v3::setCharacterAnimDim(int w, int h) { - debugC(9, kDebugLevelAnimator, "KyraEngine_v3::setCharacterAnimDim(%d, %d)", w, h); - restorePage3(); - _charBackUpWidth = _animObjects[0].width; - _charBackUpWidth2 = _animObjects[0].width2; - _charBackUpHeight = _animObjects[0].height; - _charBackUpHeight2 = _animObjects[0].height2; - - _animObjects[0].width2 = (w - _charBackUpWidth) / 2; - _animObjects[0].height2 = h - _charBackUpHeight; - _animObjects[0].width = w; - _animObjects[0].height = h; -} - -void KyraEngine_v3::resetCharacterAnimDim() { - debugC(9, kDebugLevelAnimator, "KyraEngine_v3::resetCharacterAnimDim()"); - restorePage3(); - _animObjects[0].width2 = _charBackUpWidth2; - _animObjects[0].height2 = _charBackUpHeight2; - _animObjects[0].width = _charBackUpWidth; - _animObjects[0].height = _charBackUpHeight; - _charBackUpWidth2 = _charBackUpHeight2 = -1; - _charBackUpWidth = _charBackUpHeight = -1; -} - -void KyraEngine_v3::showIdleAnim() { - debugC(9, kDebugLevelMain | kDebugLevelAnimator, "KyraEngine_v3::showIdleAnim()"); - - if (_mainCharacter.sceneId == 20 || _mainCharacter.sceneId == 21 - || _mainCharacter.sceneId == 12 || _mainCharacter.sceneId == 11) - return; - - if (_mainCharacter.animFrame == 87) - return; - - if (!_nextIdleType && !talkObjectsInCurScene()) { - malcolmRandomChat(); - } else { - static const char *facingTable[] = { - "A", "R", "R", "FR", "FX", "FL", "L", "L" - }; - - char filename[14]; - snprintf(filename, 14, "MI0%s%.02d.EMC", facingTable[_mainCharacter.facing], _malcolmShapes); - - if (_res->exists(filename)) - runTemporaryScript(filename, 1, 1, 1, 1); - } - - _nextIdleType = !_nextIdleType; -} - -void KyraEngine_v3::addItemToAnimList(int item) { - debugC(9, kDebugLevelAnimator, "KyraEngine_v3::addItemToAnimList(%d)", item); - restorePage3(); - - AnimObj *animObj = &_animObjects[17+item]; - - animObj->enabled = 1; - animObj->needRefresh = 1; - - int itemId = _itemList[item].id; - - animObj->xPos2 = animObj->xPos1 = _itemList[item].x; - animObj->yPos2 = animObj->yPos1 = _itemList[item].y; - - animObj->shapePtr = getShapePtr(248+itemId); - animSetupPaletteEntry(animObj); - animObj->shapeIndex2 = animObj->shapeIndex = 248+itemId; - - int scaleY, scaleX; - scaleY = scaleX = getScale(animObj->xPos1, animObj->yPos1); - - uint8 *shapePtr = getShapePtr(248+itemId); - animObj->xPos3 = (animObj->xPos2 -= (_screen->getShapeScaledWidth(shapePtr, scaleX) >> 1)); - animObj->yPos3 = (animObj->yPos2 -= _screen->getShapeScaledHeight(shapePtr, scaleY)); - - animObj->width2 = animObj->height2 = 0; - - _animList = addToAnimListSorted(_animList, animObj); - animObj->needRefresh = 1; -} - -void KyraEngine_v3::deleteItemAnimEntry(int item) { - debugC(9, kDebugLevelAnimator, "KyraEngine_v3::deleteItemAnimEntry(%d)", item); - AnimObj *animObj = &_animObjects[17+item]; - - restorePage3(); - - animObj->shapePtr = 0; - animObj->shapeIndex = 0xFFFF; - animObj->shapeIndex2 = 0xFFFF; - animObj->needRefresh = 1; - - refreshAnimObjectsIfNeed(); - - animObj->enabled = 0; - _animList = deleteAnimListEntry(_animList, animObj); -} - -} // end of namespace Kyra - diff --git a/engines/kyra/debugger.cpp b/engines/kyra/debugger.cpp index b59e7e9c84..82f6dd30fb 100644 --- a/engines/kyra/debugger.cpp +++ b/engines/kyra/debugger.cpp @@ -28,8 +28,8 @@ #include "common/system.h" #include "kyra/debugger.h" #include "kyra/kyra_v1.h" -#include "kyra/kyra_v2.h" -#include "kyra/kyra_v3.h" +#include "kyra/kyra_hof.h" +#include "kyra/kyra_mr.h" #include "kyra/screen.h" #include "kyra/timer.h" #include "kyra/resource.h" @@ -283,7 +283,7 @@ bool Debugger_v1::cmd_listBirthstones(int argc, const char **argv) { #pragma mark - -Debugger_v2::Debugger_v2(KyraEngine_v2 *vm) : Debugger(vm), _vm(vm) { +Debugger_v2::Debugger_v2(KyraEngine_HoF *vm) : Debugger(vm), _vm(vm) { DCmd_Register("character_info", WRAP_METHOD(Debugger_v2, cmd_characterInfo)); DCmd_Register("enter", WRAP_METHOD(Debugger_v2, cmd_enterScene)); DCmd_Register("rooms", WRAP_METHOD(Debugger_v2, cmd_listScenes)); // for consistency with kyra_v1 @@ -322,7 +322,8 @@ bool Debugger_v2::cmd_enterScene(int argc, const char **argv) { _vm->_mainCharacter.facing = direction; _vm->enterNewScene(scene, _vm->_mainCharacter.facing, 0, 0, 1); - _vm->_screen->_mouseLockCount = 0; + while (!_vm->_screen->isMouseVisible()) + _vm->_screen->showMouse(); _detach_now = true; return false; @@ -335,8 +336,8 @@ bool Debugger_v2::cmd_enterScene(int argc, const char **argv) { bool Debugger_v2::cmd_listScenes(int argc, const char **argv) { int shown = 1; for (int i = 0; i < _vm->_sceneListSize; ++i) { - if (_vm->_sceneList[i].filename[0]) { - DebugPrintf("%-2i: %-10s", i, _vm->_sceneList[i].filename); + if (_vm->_sceneList[i].filename1[0]) { + DebugPrintf("%-2i: %-10s", i, _vm->_sceneList[i].filename1); if (!(shown % 5)) DebugPrintf("\n"); ++shown; @@ -348,7 +349,7 @@ bool Debugger_v2::cmd_listScenes(int argc, const char **argv) { } bool Debugger_v2::cmd_sceneInfo(int argc, const char **argv) { - DebugPrintf("Current scene: %d '%s'\n", _vm->_currentScene, _vm->_sceneList[_vm->_currentScene].filename); + DebugPrintf("Current scene: %d '%s'\n", _vm->_currentScene, _vm->_sceneList[_vm->_currentScene].filename1); DebugPrintf("\n"); DebugPrintf("Exit information:\n"); DebugPrintf("Exit1: leads to %d, position %dx%d\n", int16(_vm->_sceneExit1), _vm->_sceneEnterX1, _vm->_sceneEnterY1); @@ -371,7 +372,7 @@ bool Debugger_v2::cmd_sceneInfo(int argc, const char **argv) { } bool Debugger_v2::cmd_characterInfo(int argc, const char **argv) { - DebugPrintf("Main character is in scene: %d '%s'\n", _vm->_mainCharacter.sceneId, _vm->_sceneList[_vm->_mainCharacter.sceneId].filename); + DebugPrintf("Main character is in scene: %d '%s'\n", _vm->_mainCharacter.sceneId, _vm->_sceneList[_vm->_mainCharacter.sceneId].filename1); DebugPrintf("Position: %dx%d\n", _vm->_mainCharacter.x1, _vm->_mainCharacter.y1); DebugPrintf("Facing: %d\n", _vm->_mainCharacter.facing); DebugPrintf("Inventory:\n"); @@ -452,7 +453,7 @@ bool Debugger_v2::cmd_passcodes(int argc, const char **argv) { return true; } -Debugger_v3::Debugger_v3(KyraEngine_v3 *vm) : Debugger(vm), _vm(vm) { +Debugger_v3::Debugger_v3(KyraEngine_MR *vm) : Debugger(vm), _vm(vm) { DCmd_Register("give", WRAP_METHOD(Debugger_v3, cmd_giveItem)); DCmd_Register("enter", WRAP_METHOD(Debugger_v3, cmd_enterScene)); DCmd_Register("rooms", WRAP_METHOD(Debugger_v3, cmd_listScenes)); // for consistency with kyra_v1 diff --git a/engines/kyra/debugger.h b/engines/kyra/debugger.h index 85c4902e42..be6725de89 100644 --- a/engines/kyra/debugger.h +++ b/engines/kyra/debugger.h @@ -32,8 +32,8 @@ namespace Kyra { class KyraEngine; class KyraEngine_v1; -class KyraEngine_v2; -class KyraEngine_v3; +class KyraEngine_HoF; +class KyraEngine_MR; class Debugger : public ::GUI::Debugger { public: @@ -73,11 +73,11 @@ protected: class Debugger_v2 : public Debugger { public: - Debugger_v2(KyraEngine_v2 *vm); + Debugger_v2(KyraEngine_HoF *vm); virtual ~Debugger_v2() {} protected: - KyraEngine_v2 *_vm; + KyraEngine_HoF *_vm; bool cmd_enterScene(int argc, const char **argv); bool cmd_listScenes(int argc, const char **argv); @@ -90,11 +90,11 @@ protected: class Debugger_v3 : public Debugger { public: - Debugger_v3(KyraEngine_v3 *vm); + Debugger_v3(KyraEngine_MR *vm); virtual ~Debugger_v3() {} protected: - KyraEngine_v3 *_vm; + KyraEngine_MR *_vm; bool cmd_giveItem(int argc, const char **argv); bool cmd_enterScene(int argc, const char **argv); diff --git a/engines/kyra/detection.cpp b/engines/kyra/detection.cpp index 53d26becb2..30b0a17d4d 100644 --- a/engines/kyra/detection.cpp +++ b/engines/kyra/detection.cpp @@ -24,8 +24,8 @@ #include "kyra/kyra.h" #include "kyra/kyra_v1.h" -#include "kyra/kyra_v2.h" -#include "kyra/kyra_v3.h" +#include "kyra/kyra_hof.h" +#include "kyra/kyra_mr.h" #include "common/config-manager.h" #include "common/advancedDetector.h" @@ -509,10 +509,10 @@ bool KyraMetaEngine::createInstance(OSystem *syst, Engine **engine, const Common *engine = new Kyra::KyraEngine_v1(syst, flags); break; case Kyra::GI_KYRA2: - *engine = new Kyra::KyraEngine_v2(syst, flags); + *engine = new Kyra::KyraEngine_HoF(syst, flags); break; case Kyra::GI_KYRA3: - *engine = new Kyra::KyraEngine_v3(syst, flags); + *engine = new Kyra::KyraEngine_MR(syst, flags); break; default: res = false; diff --git a/engines/kyra/gui_v2.cpp b/engines/kyra/gui_v2.cpp index 2e16de5112..aadb35d62d 100644 --- a/engines/kyra/gui_v2.cpp +++ b/engines/kyra/gui_v2.cpp @@ -24,17 +24,18 @@ */ #include "kyra/kyra.h" -#include "kyra/kyra_v2.h" +#include "kyra/kyra_hof.h" #include "kyra/screen.h" #include "kyra/wsamovie.h" #include "kyra/timer.h" #include "kyra/sound.h" +#include "kyra/resource.h" #include "common/savefile.h" namespace Kyra { -void KyraEngine_v2::loadButtonShapes() { +void KyraEngine_HoF::loadButtonShapes() { const uint8 *src = _screen->getCPagePtr(3); _screen->loadBitmap("_BUTTONS.CSH", 3, 3, 0); @@ -55,7 +56,7 @@ void KyraEngine_v2::loadButtonShapes() { _buttonShapes[18] = _screen->makeShapeCopy(src, 18); } -void KyraEngine_v2::setupLangButtonShapes() { +void KyraEngine_HoF::setupLangButtonShapes() { switch (_lang) { case 0: _inventoryButtons[0].data0ShapePtr = _buttonShapes[6]; @@ -79,7 +80,7 @@ void KyraEngine_v2::setupLangButtonShapes() { } } -GUI_v2::GUI_v2(KyraEngine_v2 *vm) : GUI(vm), _vm(vm), _screen(vm->screen_v2()) { +GUI_v2::GUI_v2(KyraEngine_HoF *vm) : GUI(vm), _vm(vm), _screen(vm->screen_v2()) { _backUpButtonList = _unknownButtonList = 0; initStaticData(); _currentMenu = 0; @@ -443,7 +444,7 @@ const char *GUI_v2::getMenuItemLabel(const MenuItem &menuItem) { #pragma mark - -int KyraEngine_v2::buttonInventory(Button *button) { +int KyraEngine_HoF::buttonInventory(Button *button) { if (!_screen->isMouseVisible()) return 0; @@ -494,7 +495,7 @@ int KyraEngine_v2::buttonInventory(Button *button) { return 0; } -int KyraEngine_v2::scrollInventory(Button *button) { +int KyraEngine_HoF::scrollInventory(Button *button) { uint16 *src = _mainCharacter.inventory; uint16 *dst = &_mainCharacter.inventory[10]; uint16 temp[5]; @@ -512,7 +513,7 @@ int KyraEngine_v2::scrollInventory(Button *button) { return 0; } -int KyraEngine_v2::getInventoryItemSlot(uint16 item) { +int KyraEngine_HoF::getInventoryItemSlot(uint16 item) { for (int i = 0; i < 20; ++i) { if (_mainCharacter.inventory[i] == item) return i; @@ -520,7 +521,7 @@ int KyraEngine_v2::getInventoryItemSlot(uint16 item) { return -1; } -int KyraEngine_v2::findFreeVisibleInventorySlot() { +int KyraEngine_HoF::findFreeVisibleInventorySlot() { for (int i = 0; i < 10; ++i) { if (_mainCharacter.inventory[i] == 0xFFFF) return i; @@ -528,7 +529,7 @@ int KyraEngine_v2::findFreeVisibleInventorySlot() { return -1; } -void KyraEngine_v2::removeItemFromInventory(int slot) { +void KyraEngine_HoF::removeItemFromInventory(int slot) { _mainCharacter.inventory[slot] = 0xFFFF; if (slot < 10) { _screen->hideMouse(); @@ -537,7 +538,7 @@ void KyraEngine_v2::removeItemFromInventory(int slot) { } } -bool KyraEngine_v2::checkInventoryItemExchange(uint16 handItem, int slot) { +bool KyraEngine_HoF::checkInventoryItemExchange(uint16 handItem, int slot) { bool removeItem = false; uint16 newItem = 0xFFFF; @@ -573,17 +574,17 @@ bool KyraEngine_v2::checkInventoryItemExchange(uint16 handItem, int slot) { return false; } -void KyraEngine_v2::drawInventoryShape(int page, uint16 item, int slot) { +void KyraEngine_HoF::drawInventoryShape(int page, uint16 item, int slot) { _screen->drawShape(page, getShapePtr(item+64), _inventoryX[slot], _inventoryY[slot], 0, 0); _screen->updateScreen(); } -void KyraEngine_v2::clearInventorySlot(int slot, int page) { - _screen->drawShape(page, _defaultShapeTable[240+slot], _inventoryX[slot], _inventoryY[slot], 0, 0); +void KyraEngine_HoF::clearInventorySlot(int slot, int page) { + _screen->drawShape(page, getShapePtr(240+slot), _inventoryX[slot], _inventoryY[slot], 0, 0); _screen->updateScreen(); } -void KyraEngine_v2::redrawInventory(int page) { +void KyraEngine_HoF::redrawInventory(int page) { int pageBackUp = _screen->_curPage; _screen->_curPage = page; @@ -602,7 +603,7 @@ void KyraEngine_v2::redrawInventory(int page) { _screen->_curPage = pageBackUp; } -void KyraEngine_v2::scrollInventoryWheel() { +void KyraEngine_HoF::scrollInventoryWheel() { WSAMovieV2 movie(this, _screen); movie.open("INVWHEEL.WSA", 0, 0); int frames = movie.opened() ? movie.frames() : 6; @@ -648,7 +649,7 @@ void KyraEngine_v2::scrollInventoryWheel() { // spellbook specific code -int KyraEngine_v2::bookButton(Button *button) { +int KyraEngine_HoF::bookButton(Button *button) { if (!queryGameFlag(1)) { objectChat(getTableString(0xEB, _cCodeBuffer, 1), 0, 0x83, 0xEB); return 0; @@ -739,7 +740,7 @@ int KyraEngine_v2::bookButton(Button *button) { return 0; } -void KyraEngine_v2::loadBookBkgd() { +void KyraEngine_HoF::loadBookBkgd() { char filename[16]; if (_flags.isTalkie) @@ -783,7 +784,7 @@ void KyraEngine_v2::loadBookBkgd() { _screen->loadBitmap(filename, 3, 3, 0); } -void KyraEngine_v2::showBookPage() { +void KyraEngine_HoF::showBookPage() { char filename[16]; sprintf(filename, "PAGE%.01X.", _bookCurPage); @@ -811,19 +812,19 @@ void KyraEngine_v2::showBookPage() { _screen->showMouse(); } -void KyraEngine_v2::bookLoop() { +void KyraEngine_HoF::bookLoop() { Button bookButtons[5]; GUI_V2_BUTTON(bookButtons[0], 0x24, 0, 0, 1, 1, 1, 0x4487, 0, 0x82, 0xBE, 0x0A, 0x0A, 0xC7, 0xCF, 0xC7, 0xCF, 0xC7, 0xCF, 0); - bookButtons[0].buttonCallback = BUTTON_FUNCTOR(KyraEngine_v2, this, &KyraEngine_v2::bookPrevPage); + bookButtons[0].buttonCallback = BUTTON_FUNCTOR(KyraEngine_HoF, this, &KyraEngine_HoF::bookPrevPage); GUI_V2_BUTTON(bookButtons[1], 0x25, 0, 0, 1, 1, 1, 0x4487, 0, 0xB1, 0xBE, 0x0A, 0x0A, 0xC7, 0xCF, 0xC7, 0xCF, 0xC7, 0xCF, 0); - bookButtons[1].buttonCallback = BUTTON_FUNCTOR(KyraEngine_v2, this, &KyraEngine_v2::bookNextPage); + bookButtons[1].buttonCallback = BUTTON_FUNCTOR(KyraEngine_HoF, this, &KyraEngine_HoF::bookNextPage); GUI_V2_BUTTON(bookButtons[2], 0x26, 0, 0, 1, 1, 1, 0x4487, 0, 0x8F, 0xBE, 0x21, 0x0A, 0xC7, 0xCF, 0xC7, 0xCF, 0xC7, 0xCF, 0); - bookButtons[2].buttonCallback = BUTTON_FUNCTOR(KyraEngine_v2, this, &KyraEngine_v2::bookClose); + bookButtons[2].buttonCallback = BUTTON_FUNCTOR(KyraEngine_HoF, this, &KyraEngine_HoF::bookClose); GUI_V2_BUTTON(bookButtons[3], 0x27, 0, 0, 1, 1, 1, 0x4487, 0, 0x08, 0x08, 0x90, 0xB4, 0xC7, 0xCF, 0xC7, 0xCF, 0xC7, 0xCF, 0); - bookButtons[3].buttonCallback = BUTTON_FUNCTOR(KyraEngine_v2, this, &KyraEngine_v2::bookPrevPage); + bookButtons[3].buttonCallback = BUTTON_FUNCTOR(KyraEngine_HoF, this, &KyraEngine_HoF::bookPrevPage); GUI_V2_BUTTON(bookButtons[4], 0x28, 0, 0, 1, 1, 1, 0x4487, 0, 0xAA, 0x08, 0x8E, 0xB4, 0xC7, 0xCF, 0xC7, 0xCF, 0xC7, 0xCF, 0); - bookButtons[4].buttonCallback = BUTTON_FUNCTOR(KyraEngine_v2, this, &KyraEngine_v2::bookNextPage); + bookButtons[4].buttonCallback = BUTTON_FUNCTOR(KyraEngine_HoF, this, &KyraEngine_HoF::bookNextPage); Button *buttonList = 0; @@ -851,7 +852,7 @@ void KyraEngine_v2::bookLoop() { _screen->clearPage(2); } -void KyraEngine_v2::bookDecodeText(uint8 *str) { +void KyraEngine_HoF::bookDecodeText(uint8 *str) { uint8 *dst = str, *op = str; while (*op != 0x1A) { while (*op != 0x1A && *op != 0x0D) @@ -866,7 +867,7 @@ void KyraEngine_v2::bookDecodeText(uint8 *str) { *dst = 0; } -void KyraEngine_v2::bookPrintText(int dstPage, const uint8 *str, int x, int y, uint8 color) { +void KyraEngine_HoF::bookPrintText(int dstPage, const uint8 *str, int x, int y, uint8 color) { int curPageBackUp = _screen->_curPage; _screen->_curPage = dstPage; @@ -883,24 +884,24 @@ void KyraEngine_v2::bookPrintText(int dstPage, const uint8 *str, int x, int y, u _screen->_curPage = curPageBackUp; } -int KyraEngine_v2::bookPrevPage(Button *button) { +int KyraEngine_HoF::bookPrevPage(Button *button) { _bookNewPage = MAX(_bookCurPage-2, 0); return 0; } -int KyraEngine_v2::bookNextPage(Button *button) { +int KyraEngine_HoF::bookNextPage(Button *button) { _bookNewPage = MIN(_bookCurPage+2, _bookMaxPage); return 0; } -int KyraEngine_v2::bookClose(Button *button) { +int KyraEngine_HoF::bookClose(Button *button) { _bookShown = false; return 0; } // cauldron specific code -int KyraEngine_v2::cauldronClearButton(Button *button) { +int KyraEngine_HoF::cauldronClearButton(Button *button) { if (!queryGameFlag(2)) { updateCharFacing(); objectChat(getTableString(0xF0, _cCodeBuffer, 1), 0, 0x83, 0xF0); @@ -926,7 +927,7 @@ int KyraEngine_v2::cauldronClearButton(Button *button) { return 0; } -int KyraEngine_v2::cauldronButton(Button *button) { +int KyraEngine_HoF::cauldronButton(Button *button) { if (!queryGameFlag(2)) { objectChat(getTableString(0xF0, _cCodeBuffer, 1), 0, 0x83, 0xF0); return 0; diff --git a/engines/kyra/gui_v2.h b/engines/kyra/gui_v2.h index b5a25d29bf..5f03da9ada 100644 --- a/engines/kyra/gui_v2.h +++ b/engines/kyra/gui_v2.h @@ -91,13 +91,13 @@ namespace Kyra { -class KyraEngine_v2; +class KyraEngine_HoF; class Screen_v2; class GUI_v2 : public GUI { -friend class KyraEngine_v2; +friend class KyraEngine_HoF; public: - GUI_v2(KyraEngine_v2 *engine); + GUI_v2(KyraEngine_HoF *engine); Button *addButtonToList(Button *list, Button *newButton); @@ -145,7 +145,7 @@ private: void resetState(int item); - KyraEngine_v2 *_vm; + KyraEngine_HoF *_vm; Screen_v2 *_screen; bool _buttonListChanged; diff --git a/engines/kyra/gui_v3.cpp b/engines/kyra/gui_v3.cpp index 0c9a2ef9f1..3a701caf91 100644 --- a/engines/kyra/gui_v3.cpp +++ b/engines/kyra/gui_v3.cpp @@ -24,14 +24,15 @@ */ #include "kyra/gui_v3.h" -#include "kyra/kyra_v3.h" -#include "kyra/text_v3.h" +#include "kyra/kyra_mr.h" +#include "kyra/text_mr.h" #include "kyra/wsamovie.h" +#include "kyra/resource.h" namespace Kyra { -void KyraEngine_v3::showMessage(const char *string, uint8 c0, uint8 c1) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::showMessage('%s', %d, %d)", string, c0, c1); +void KyraEngine_MR::showMessage(const char *string, uint8 c0, uint8 c1) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::showMessage('%s', %d, %d)", string, c0, c1); _shownMessage = string; _screen->hideMouse(); @@ -51,13 +52,13 @@ void KyraEngine_v3::showMessage(const char *string, uint8 c0, uint8 c1) { _screen->showMouse(); } -void KyraEngine_v3::showMessageFromCCode(int string, uint8 c0, int) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::showMessageFromCCode(%d, %d, -)", string, c0); +void KyraEngine_MR::showMessageFromCCode(int string, uint8 c0, int) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::showMessageFromCCode(%d, %d, -)", string, c0); showMessage((const char*)getTableEntry(_cCodeFile, string), c0, 0xF0); } -void KyraEngine_v3::updateItemCommand(int item, int str, uint8 c0) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::updateItemCommand(%d, %d, %d)", item, str, c0); +void KyraEngine_MR::updateItemCommand(int item, int str, uint8 c0) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::updateItemCommand(%d, %d, %d)", item, str, c0); char buffer[100]; char *src = (char*)getTableEntry(_itemFile, item); @@ -74,30 +75,30 @@ void KyraEngine_v3::updateItemCommand(int item, int str, uint8 c0) { showMessage(buffer, c0, 0xF0); } -void KyraEngine_v3::updateCommandLine() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::updateCommandLine()"); +void KyraEngine_MR::updateCommandLine() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::updateCommandLine()"); if (_restoreCommandLine) { restoreCommandLine(); _restoreCommandLine = false; } } -void KyraEngine_v3::restoreCommandLine() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::restoreCommandLine()"); +void KyraEngine_MR::restoreCommandLine() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::restoreCommandLine()"); int y = _inventoryState ? 144 : 188; _screen->copyBlockToPage(0, 0, y, 320, 12, _interfaceCommandLine); } -void KyraEngine_v3::updateCLState() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::updateCLState()"); +void KyraEngine_MR::updateCLState() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::updateCLState()"); if (_inventoryState) _commandLineY = 145; else _commandLineY = 189; } -void KyraEngine_v3::showInventory() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::showInventory()"); +void KyraEngine_MR::showInventory() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::showInventory()"); if (!_screen->isMouseVisible()) return; if (queryGameFlag(3)) @@ -175,8 +176,8 @@ void KyraEngine_v3::showInventory() { _screen->showMouse(); } -void KyraEngine_v3::hideInventory() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::hideInventory()"); +void KyraEngine_MR::hideInventory() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::hideInventory()"); if (queryGameFlag(3)) return; @@ -239,8 +240,8 @@ void KyraEngine_v3::hideInventory() { _screen->showMouse(); } -void KyraEngine_v3::drawMalcolmsMoodText() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::drawMalcolmsMoodText()"); +void KyraEngine_MR::drawMalcolmsMoodText() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::drawMalcolmsMoodText()"); static const int stringId[] = { 0x32, 0x37, 0x3C }; if (queryGameFlag(0x219)) @@ -274,8 +275,8 @@ void KyraEngine_v3::drawMalcolmsMoodText() { _screen->_curPage = pageBackUp; } -void KyraEngine_v3::drawMalcolmsMoodPointer(int frame, int page) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::drawMalcolmsMoodPointer(%d, %d)", frame, page); +void KyraEngine_MR::drawMalcolmsMoodPointer(int frame, int page) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::drawMalcolmsMoodPointer(%d, %d)", frame, page); static const uint8 stateTable[] = { 1, 6, 11 }; @@ -301,8 +302,8 @@ void KyraEngine_v3::drawMalcolmsMoodPointer(int frame, int page) { _invWsaFrame = frame; } -void KyraEngine_v3::drawJestersStaff(int type, int page) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::drawJestersStaff(%d, %d)", type, page); +void KyraEngine_MR::drawJestersStaff(int type, int page) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::drawJestersStaff(%d, %d)", type, page); int y = 155; if (page == 30) { page = 2; @@ -313,8 +314,8 @@ void KyraEngine_v3::drawJestersStaff(int type, int page) { _screen->drawShape(page, getShapePtr(shape), 217, y, 0, 0); } -void KyraEngine_v3::drawScore(int page, int x, int y) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::drawScore(%d, %d, %d)", page, x, y); +void KyraEngine_MR::drawScore(int page, int x, int y) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::drawScore(%d, %d, %d)", page, x, y); if (page == 30) { page = 2; y -= 144; @@ -331,8 +332,8 @@ void KyraEngine_v3::drawScore(int page, int x, int y) { _screen->drawShape(page, getShapePtr(shape3+433), x, y, 0, 0); } -void KyraEngine_v3::drawScoreCounting(int oldScore, int newScore, int drawOld, const int x) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::drawScoreCounting(%d, %d, %d, %d)", oldScore, newScore, drawOld, x); +void KyraEngine_MR::drawScoreCounting(int oldScore, int newScore, int drawOld, const int x) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::drawScoreCounting(%d, %d, %d, %d)", oldScore, newScore, drawOld, x); int y = 189; if (_inventoryState) y -= 44; @@ -366,8 +367,8 @@ void KyraEngine_v3::drawScoreCounting(int oldScore, int newScore, int drawOld, c _screen->drawShape(0, getShapePtr(new001+433), x + 16, y, 0, 0); } -int KyraEngine_v3::getScoreX(const char *str) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::getScoreX('%s')", str); +int KyraEngine_MR::getScoreX(const char *str) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::getScoreX('%s')", str); Screen::FontId oldFont = _screen->setFont(Screen::FID_8_FNT); _screen->_charWidth = -2; @@ -379,8 +380,8 @@ int KyraEngine_v3::getScoreX(const char *str) { return x; } -void KyraEngine_v3::redrawInventory(int page) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::redrawInventory(%d)", page); +void KyraEngine_MR::redrawInventory(int page) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::redrawInventory(%d)", page); int yOffset = 0; if (page == 30) { @@ -407,8 +408,8 @@ void KyraEngine_v3::redrawInventory(int page) { _screen->updateScreen(); } -void KyraEngine_v3::clearInventorySlot(int slot, int page) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::clearInventorySlot(%d, %d)", slot, page); +void KyraEngine_MR::clearInventorySlot(int slot, int page) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::clearInventorySlot(%d, %d)", slot, page); int yOffset = 0; if (page == 30) { page = 2; @@ -418,8 +419,8 @@ void KyraEngine_v3::clearInventorySlot(int slot, int page) { _screen->drawShape(page, getShapePtr(slot+422), _inventoryX[slot], _inventoryY[slot] + yOffset, 0, 0); } -void KyraEngine_v3::drawInventorySlot(int page, int item, int slot) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::drawInventorySlot(%d, %d, %d)", page, item, slot); +void KyraEngine_MR::drawInventorySlot(int page, int item, int slot) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::drawInventorySlot(%d, %d, %d)", page, item, slot); int yOffset = 0; if (page == 30) { page = 2; @@ -429,8 +430,8 @@ void KyraEngine_v3::drawInventorySlot(int page, int item, int slot) { _screen->drawShape(page, getShapePtr(item+248), _inventoryX[slot], _inventoryY[slot] + yOffset, 0, 0); } -int KyraEngine_v3::buttonInventory(Button *button) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::buttonInventory(%p)", (const void*)button); +int KyraEngine_MR::buttonInventory(Button *button) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::buttonInventory(%p)", (const void*)button); setNextIdleAnimTimer(); if (!_enableInventory || !_inventoryState || !_screen->isMouseVisible()) return 0; @@ -483,7 +484,7 @@ int KyraEngine_v3::buttonInventory(Button *button) { return 0; } -int KyraEngine_v3::buttonMoodChange(Button *button) { +int KyraEngine_MR::buttonMoodChange(Button *button) { if (queryGameFlag(0x219)) { snd_playSoundEffect(0x0D, 0xC8); return 0; @@ -550,7 +551,7 @@ int KyraEngine_v3::buttonMoodChange(Button *button) { return 0; } -int KyraEngine_v3::buttonShowScore(Button *button) { +int KyraEngine_MR::buttonShowScore(Button *button) { strcpy(_stringBuffer, (const char*)getTableEntry(_cCodeFile, 18)); char *buffer = _stringBuffer; @@ -573,7 +574,7 @@ int KyraEngine_v3::buttonShowScore(Button *button) { return 0; } -int KyraEngine_v3::buttonJesterStaff(Button *button) { +int KyraEngine_MR::buttonJesterStaff(Button *button) { makeCharFacingMouse(); if (_itemInHand == 27) { _screen->hideMouse(); @@ -606,7 +607,7 @@ int KyraEngine_v3::buttonJesterStaff(Button *button) { #pragma mark - -GUI_v3::GUI_v3(KyraEngine_v3 *vm) : GUI(vm), _vm(vm), _screen(vm->_screen) { +GUI_v3::GUI_v3(KyraEngine_MR *vm) : GUI(vm), _vm(vm), _screen(vm->_screen) { _backUpButtonList = _unknownButtonList = 0; _buttonListChanged = false; } diff --git a/engines/kyra/gui_v3.h b/engines/kyra/gui_v3.h index acf3d948f8..b6c7953dff 100644 --- a/engines/kyra/gui_v3.h +++ b/engines/kyra/gui_v3.h @@ -53,13 +53,13 @@ namespace Kyra { button.data2Val3 = s; \ button.flags2 = t; -class KyraEngine_v3; -class Screen_v3; +class KyraEngine_MR; +class Screen_MR; class GUI_v3 : public GUI { -friend class KyraEngine_v3; +friend class KyraEngine_MR; public: - GUI_v3(KyraEngine_v3 *engine); + GUI_v3(KyraEngine_MR *engine); Button *addButtonToList(Button *list, Button *newButton); @@ -84,8 +84,8 @@ private: uint8 defaultColor1() const { return 0xCF; } uint8 defaultColor2() const { return 0xF8; } - KyraEngine_v3 *_vm; - Screen_v3 *_screen; + KyraEngine_MR *_vm; + Screen_MR *_screen; bool _buttonListChanged; Button *_backUpButtonList; diff --git a/engines/kyra/items_hof.cpp b/engines/kyra/items_hof.cpp new file mode 100644 index 0000000000..c20ce5bbb1 --- /dev/null +++ b/engines/kyra/items_hof.cpp @@ -0,0 +1,511 @@ +/* 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_hof.h" + +namespace Kyra { + +int KyraEngine_HoF::findFreeItem() { + debugC(9, kDebugLevelMain, "KyraEngine_HoF::findFreeItem()"); + for (int i = 0; i < 30; ++i) { + if (_itemList[i].id == 0xFFFF) + return i; + } + return -1; +} + +int KyraEngine_HoF::countAllItems() { + debugC(9, kDebugLevelMain, "KyraEngine_HoF::countAllItems()"); + int num = 0; + for (int i = 0; i < 30; ++i) { + if (_itemList[i].id != 0xFFFF) + ++num; + } + return num; +} + +int KyraEngine_HoF::findItem(uint16 sceneId, uint16 id) { + debugC(9, kDebugLevelMain, "KyraEngine_HoF::findItem(%u, %u)", sceneId, id); + for (int i = 0; i < 30; ++i) { + if (_itemList[i].id == id && _itemList[i].sceneId == sceneId) + return i; + } + return -1; +} + +int KyraEngine_HoF::checkItemCollision(int x, int y) { + debugC(9, kDebugLevelMain, "KyraEngine_HoF::checkItemCollision(%d, %d)", x, y); + int itemPos = -1, yPos = -1; + + for (int i = 0; i < 30; ++i) { + const Item &curItem = _itemList[i]; + + if (curItem.id == 0xFFFF || curItem.sceneId != _mainCharacter.sceneId) + continue; + + int itemX1 = curItem.x - 8 - 3; + int itemX2 = curItem.x + 7 + 3; + + if (x < itemX1 || x > itemX2) + continue; + + int itemY1 = curItem.y - _itemHtDat[curItem.id] - 3; + int itemY2 = curItem.y + 3; + + if (y < itemY1 || y > itemY2) + continue; + + if (curItem.y >= yPos) { + itemPos = i; + yPos = curItem.y; + } + } + + return itemPos; +} + +void KyraEngine_HoF::resetItemList() { + debugC(9, kDebugLevelMain, "KyraEngine_HoF::resetItemList()"); + for (int i = 0; i < 30; ++i) { + _itemList[i].id = 0xFFFF; + _itemList[i].sceneId = 0xFFFF; + _itemList[i].x = 0; + _itemList[i].y = 0; + _itemList[i].unk7 = 0; + } +} + +void KyraEngine_HoF::updateWaterFlasks() { + debugC(9, kDebugLevelMain, "KyraEngine_HoF::updateWaterFlasks()"); + for (int i = 22; i < 24; i++) { + if (_itemInHand == i) + setHandItem(i - 1); + + for (int ii = 0; ii < 20; ii++) { + if (_mainCharacter.inventory[ii] == i) { + _mainCharacter.inventory[ii]--; + if (ii < 10) { + clearInventorySlot(ii, 0); + _screen->drawShape(0, getShapePtr(i + 63), _inventoryX[ii], _inventoryY[ii], 0, 0); + } + } + } + + for (int ii = 0; ii < 30; ii++) { + if (_itemList[ii].id == i) + _itemList[ii].id--; + } + } +} + +bool KyraEngine_HoF::dropItem(int unk1, uint16 item, int x, int y, int unk2) { + debugC(9, kDebugLevelMain, "KyraEngine_HoF::dropItem(%d, %u, %d, %d, %d)", unk1, item, x, y, unk2); + if (_handItemSet <= -1) + return false; + + bool success = processItemDrop(_mainCharacter.sceneId, item, x, y, unk1, unk2); + if (!success) { + snd_playSoundEffect(0x0d); + if (countAllItems() >= 30) + showMessageFromCCode(5, 0x84, 0); + } + + return success; +} + +bool KyraEngine_HoF::processItemDrop(uint16 sceneId, uint16 item, int x, int y, int unk1, int unk2) { + debugC(9, kDebugLevelMain, "KyraEngine_HoF::processItemDrop(%u, %u, %d, %d, %d, %d)", sceneId, item, x, y, unk1, unk2); + int itemPos = checkItemCollision(x, y); + + if (unk1) + itemPos = -1; + + if (itemPos >= 0) { + exchangeMouseItem(itemPos); + return false; + } + + int freeItemSlot = -1; + + if (unk1 != 3) { + for (int i = 0; i < 30; ++i) { + if (_itemList[i].id == 0xFFFF) { + freeItemSlot = i; + break; + } + } + } + + if (freeItemSlot == -1) + return false; + + if (sceneId != _mainCharacter.sceneId) { + _itemList[freeItemSlot].x = x; + _itemList[freeItemSlot].y = y; + _itemList[freeItemSlot].id = item; + _itemList[freeItemSlot].unk7 = 1; + _itemList[freeItemSlot].sceneId = sceneId; + return true; + } + + int itemHeight = _itemHtDat[item]; + + // no idea why it's '&&' here and not single checks for x and y + if (x == -1 && y == -1) { + x = _rnd.getRandomNumberRng(0x10, 0x130); + y = _rnd.getRandomNumberRng(0x10, 0x87); + } + + int posX = x, posY = y; + int itemX = -1, itemY = -1; + bool needRepositioning = true; + + while (needRepositioning) { + if ((_screen->getDrawLayer(posX, posY) <= 1 && _screen->getDrawLayer2(posX, posY, itemHeight) <= 1 && isDropable(posX, posY)) || posY == 136) { + int posX2 = posX, posX3 = posX; + bool repositioning = true; + + while (repositioning) { + if (isDropable(posX3, posY) && _screen->getDrawLayer(posX3, posY) < 7 && checkItemCollision(posX3, posY) == -1) { + itemX = posX3; + itemY = posY; + needRepositioning = false; + repositioning = false; + } + + if (isDropable(posX2, posY) && _screen->getDrawLayer(posX2, posY) < 7 && checkItemCollision(posX2, posY) == -1) { + itemX = posX2; + itemY = posY; + needRepositioning = false; + repositioning = false; + } + + if (repositioning) { + posX3 = MAX(posX3 - 2, 16); + posX2 = MIN(posX2 + 2, 304); + + if (posX3 <= 16 && posX2 >= 304) + repositioning = false; + } + } + } + + if (posY == 136) + needRepositioning = false; + else + posY = MIN(posY + 2, 136); + } + + if (itemX == -1 || itemY == -1) + return false; + + if (unk1 == 3) { + _itemList[freeItemSlot].x = itemX; + _itemList[freeItemSlot].y = itemY; + return true; + } else if (unk1 == 2) { + itemDropDown(x, y, itemX, itemY, freeItemSlot, item); + } + + if (!unk1) + removeHandItem(); + + itemDropDown(x, y, itemX, itemY, freeItemSlot, item); + + if (!unk1 && unk2) { + int itemStr = 3; + if (_lang == 1) + itemStr = getItemCommandStringDrop(item); + updateCommandLineEx(item+54, itemStr, 0xD6); + } + + return true; +} + +void KyraEngine_HoF::itemDropDown(int startX, int startY, int dstX, int dstY, int itemSlot, uint16 item) { + debugC(9, kDebugLevelMain, "KyraEngine_HoF::itemDropDown(%d, %d, %d, %d, %d, %u)", startX, startY, dstX, dstY, itemSlot, item); + uint8 *itemShape = getShapePtr(item + 64); + + if (startX == dstX && startY == dstY) { + if (_layerFlagTable[_screen->getLayer(dstX, dstY)] && item != 13) { + updateCharFacing(); + snd_playSoundEffect(0x2d); + removeHandItem(); + objectChat(getTableString(0xFF, _cCodeBuffer, 1), 0, 0x83, 0xFF); + } else { + _itemList[itemSlot].x = dstX; + _itemList[itemSlot].y = dstY; + _itemList[itemSlot].id = item; + _itemList[itemSlot].sceneId = _mainCharacter.sceneId; + snd_playSoundEffect(0x0c); + addItemToAnimList(itemSlot); + } + } else { + _screen->hideMouse(); + + if (startY <= dstY) { + int speed = 2; + int curY = startY; + int curX = startX - 8; + + backUpGfxRect24x24(curX, curY-16); + while (curY < dstY) { + restoreGfxRect24x24(curX, curY-16); + + curY = MIN(curY + speed, dstY); + ++speed; + + backUpGfxRect24x24(curX, curY-16); + uint32 endDelay = _system->getMillis() + _tickLength; + + _screen->drawShape(0, itemShape, curX, curY-16, 0, 0); + _screen->updateScreen(); + + // XXX: original doesn't update game state while delaying + // our implementation *could* do it, so maybe check this again + delayUntil(endDelay); + } + + if (dstX != dstY || (dstY - startY > 16)) { + snd_playSoundEffect(0x69); + speed = MAX(speed, 6); + int speedX = ((dstX - startX) << 4) / speed; + int origSpeed = speed; + speed >>= 1; + + if (dstY - startY <= 8) + speed >>= 1; + + speed = -speed; + + curX = startX << 4; + + int x = 0, y = 0; + while (--origSpeed) { + x = (curX >> 4) - 8; + y = curY - 16; + + restoreGfxRect24x24(x, y); + curY = MIN(curY + speed, dstY); + curX += speedX; + ++speed; + + x = (curX >> 4) - 8; + y = curY - 16; + backUpGfxRect24x24(x, y); + + uint16 endDelay = _system->getMillis() + _tickLength; + _screen->drawShape(0, itemShape, x, y, 0, 0); + _screen->updateScreen(); + + // XXX: original doesn't update game state while delaying + // our implementation *could* do it, so maybe check this again + delayUntil(endDelay); + } + + restoreGfxRect24x24(x, y); + } else { + restoreGfxRect24x24(curX, curY-16); + } + } + + if (_layerFlagTable[_screen->getLayer(dstX, dstY)] && item != 13) { + updateCharFacing(); + snd_playSoundEffect(0x2d); + removeHandItem(); + _screen->showMouse(); + objectChat(getTableString(0xFF, _cCodeBuffer, 1), 0, 0x83, 0xFF); + } else { + _itemList[itemSlot].x = dstX; + _itemList[itemSlot].y = dstY; + _itemList[itemSlot].id = item; + _itemList[itemSlot].sceneId = _mainCharacter.sceneId; + snd_playSoundEffect(0x0c); + addItemToAnimList(itemSlot); + _screen->showMouse(); + } + } +} + +void KyraEngine_HoF::exchangeMouseItem(int itemPos) { + debugC(9, kDebugLevelMain, "KyraEngine_HoF::exchangeMouseItem(%d)", itemPos); + _screen->hideMouse(); + + deleteItemAnimEntry(itemPos); + + int itemId = _itemList[itemPos].id; + _itemList[itemPos].id = _itemInHand; + _itemInHand = itemId; + + addItemToAnimList(itemPos); + snd_playSoundEffect(0x0b); + setMouseCursor(_itemInHand); + int str2 = 7; + + if (_lang == 1) + str2 = getItemCommandStringPickUp(itemId); + + updateCommandLineEx(itemId + 54, str2, 0xD6); + _screen->showMouse(); + + runSceneScript6(); +} + +bool KyraEngine_HoF::pickUpItem(int x, int y) { + debugC(9, kDebugLevelMain, "KyraEngine_HoF::pickUpItem(%d, %d)", x, y); + int itemPos = checkItemCollision(x, y); + + if (itemPos <= -1) + return false; + + if (_itemInHand >= 0) { + exchangeMouseItem(itemPos); + } else { + _screen->hideMouse(); + deleteItemAnimEntry(itemPos); + int itemId = _itemList[itemPos].id; + _itemList[itemPos].id = 0xFFFF; + snd_playSoundEffect(0x0b); + setMouseCursor(itemId); + int str2 = 7; + + if (_lang == 1) + str2 = getItemCommandStringPickUp(itemId); + + updateCommandLineEx(itemId + 54, str2, 0xD6); + _itemInHand = itemId; + _screen->showMouse(); + + runSceneScript6(); + } + + return true; +} + +bool KyraEngine_HoF::isDropable(int x, int y) { + debugC(9, kDebugLevelMain, "KyraEngine_HoF::isDropable(%d, %d)", x, y); + if (x < 14 || x > 304 || y < 14 || y > 136) + return false; + + x -= 8; + y -= 1; + + for (int xpos = x; xpos < x + 16; ++xpos) { + if (_screen->getShapeFlag1(xpos, y) == 0) + return false; + } + + return true; +} + +int KyraEngine_HoF::getItemCommandStringDrop(uint16 item) { + debugC(9, kDebugLevelMain, "KyraEngine_HoF::getItemCommandStringDrop(%u)", item); + assert(item < _itemStringMapSize); + int stringId = _itemStringMap[item]; + + static const int dropStringIds[] = { + 0x2D, 0x103, 0x003, 0x106 + }; + assert(stringId < ARRAYSIZE(dropStringIds)); + + return dropStringIds[stringId]; +} + +int KyraEngine_HoF::getItemCommandStringPickUp(uint16 item) { + debugC(9, kDebugLevelMain, "KyraEngine_HoF::getItemCommandStringPickUp(%u)", item); + assert(item < _itemStringMapSize); + int stringId = _itemStringMap[item]; + + static const int pickUpStringIds[] = { + 0x02B, 0x102, 0x007, 0x105 + }; + assert(stringId < ARRAYSIZE(pickUpStringIds)); + + return pickUpStringIds[stringId]; +} + +int KyraEngine_HoF::getItemCommandStringInv(uint16 item) { + debugC(9, kDebugLevelMain, "KyraEngine_HoF::getItemCommandStringInv(%u)", item); + assert(item < _itemStringMapSize); + int stringId = _itemStringMap[item]; + + static const int pickUpStringIds[] = { + 0x02C, 0x104, 0x008, 0x107 + }; + assert(stringId < ARRAYSIZE(pickUpStringIds)); + + return pickUpStringIds[stringId]; +} + +void KyraEngine_HoF::setMouseCursor(uint16 item) { + debugC(9, kDebugLevelMain, "KyraEngine_HoF::setMouseCursor(%u)", item); + int shape = 0; + int hotX = 1; + int hotY = 1; + + if (item != 0xFFFF) { + hotX = 8; + hotY = 15; + shape = item+64; + } + + _screen->setMouseCursor(hotX, hotY, getShapePtr(shape)); +} + +void KyraEngine_HoF::setHandItem(uint16 item) { + debugC(9, kDebugLevelMain, "KyraEngine_HoF::setHandItem(%u)", item); + _screen->hideMouse(); + + if (item == 0xFFFF) { + removeHandItem(); + } else { + setMouseCursor(item); + _itemInHand = item; + } + + _screen->showMouse(); +} + +void KyraEngine_HoF::removeHandItem() { + debugC(9, kDebugLevelMain, "KyraEngine_HoF::removeHandItem()"); + _screen->hideMouse(); + _screen->setMouseCursor(0, 0, getShapePtr(0)); + _itemInHand = -1; + _handItemSet = -1; + _screen->showMouse(); +} + +bool KyraEngine_HoF::itemIsFlask(int item) { + debugC(9, kDebugLevelMain, "KyraEngine_HoF::itemIsFlask(%d)", item); + for (int i = 0; _flaskTable[i] != -1; ++i) { + if (_flaskTable[i] == item) + return true; + } + + return false; +} + +} // end of namespace Kyra + diff --git a/engines/kyra/items_mr.cpp b/engines/kyra/items_mr.cpp new file mode 100644 index 0000000000..609d87881e --- /dev/null +++ b/engines/kyra/items_mr.cpp @@ -0,0 +1,644 @@ +/* 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_mr.h" +#include "kyra/timer.h" + +namespace Kyra { + +void KyraEngine_MR::resetItem(int index) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::resetItem(%d)", index); + _itemList[index].id = 0xFFFF; + _itemList[index].sceneId = 0xFFFF; + _itemList[index].x = 0; + _itemList[index].y = 0; + _itemList[index].unk8 = 0; +} + +void KyraEngine_MR::resetItemList() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::resetItemList()"); + for (int i = 0; i < 50; ++i) + resetItem(i); +} + +void KyraEngine_MR::removeTrashItems() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::removeTrashItems()"); + for (int i = 0; _trashItemList[i] != 0xFF; ++i) { + for (int item = findItem(_trashItemList[i]); item != -1; item = findItem(_trashItemList[i])) { + if (_itemList[item].sceneId != _mainCharacter.sceneId) + resetItem(item); + else + break; + } + } +} + +int KyraEngine_MR::findFreeItem() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::findFreeItem()"); + for (int i = 0; i < 50; ++i) { + if (_itemList[i].id == 0xFFFF) + return i; + } + return -1; +} + +int KyraEngine_MR::findFreeInventorySlot() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::findFreeInventorySlot()"); + for (int i = 0; i < 10; ++i) { + if (_mainCharacter.inventory[i] == 0xFFFF) + return i; + } + return -1; +} + +int KyraEngine_MR::findItem(uint16 sceneId, uint16 id) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::findItem(%u, %u)", sceneId, id); + for (int i = 0; i < 50; ++i) { + if (_itemList[i].id == id && _itemList[i].sceneId == sceneId) + return i; + } + return -1; +} + +int KyraEngine_MR::findItem(uint16 item) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::findItem(%u)", item); + for (int i = 0; i < 50; ++i) { + if (_itemList[i].id == item) + return i; + } + return -1; +} + +int KyraEngine_MR::countAllItems() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::countAllItems()"); + int count = 0; + + for (int i = 0; i < 50; ++i) { + if (_itemList[i].id != 0xFFFF) + ++count; + } + + return count; +} + +int KyraEngine_MR::checkItemCollision(int x, int y) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::checkItemCollision(%d, %d)", x, y); + int itemIndex = -1; + int maxItemY = -1; + + for (int i = 0; i < 50; ++i) { + if (_itemList[i].id == 0xFFFF || _itemList[i].sceneId != _mainCharacter.sceneId) + continue; + + const int x1 = _itemList[i].x - 11; + const int x2 = _itemList[i].x + 10; + + if (x < x1 || x > x2) + continue; + + const int y1 = _itemList[i].y - _itemBuffer1[_itemList[i].id] - 3; + const int y2 = _itemList[i].y + 3; + + if (y < y1 || y > y2) + continue; + + if (_itemList[i].y >= maxItemY) { + itemIndex = i; + maxItemY = _itemList[i].y; + } + } + + return itemIndex; +} + +void KyraEngine_MR::setMouseCursor(uint16 item) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::setMouseCursor(%u)", item); + int shape = 0; + int hotX = 1; + int hotY = 1; + + if (item != 0xFFFF) { + hotX = 12; + hotY = 19; + shape = item+248; + } + + if ((int16)item != _itemInHand) + _screen->setMouseCursor(hotX, hotY, getShapePtr(shape)); +} + +void KyraEngine_MR::setItemMouseCursor() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::setItemMouseCursor()"); + _handItemSet = _itemInHand; + if (_itemInHand == -1) + _screen->setMouseCursor(0, 0, _gameShapes[0]); + else + _screen->setMouseCursor(12, 19, _gameShapes[_itemInHand+248]); +} + +void KyraEngine_MR::setHandItem(uint16 item) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::setHandItem(%u)", item); + _screen->hideMouse(); + + if (item == 0xFFFF) { + removeHandItem(); + } else { + setMouseCursor(item); + _itemInHand = item; + } + + _screen->showMouse(); +} + +void KyraEngine_MR::removeHandItem() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::removeHandItem()"); + _screen->hideMouse(); + _screen->setMouseCursor(0, 0, _gameShapes[0]); + _itemInHand = -1; + _handItemSet = -1; + _screen->showMouse(); +} + +bool KyraEngine_MR::dropItem(int unk1, uint16 item, int x, int y, int unk2) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::dropItem(%d, %d, %d, %d, %d)", unk1, item, x, y, unk2); + + if (_handItemSet <= -1) + return false; + + if (processItemDrop(_mainCharacter.sceneId, item, x, y, unk1, unk2)) + return true; + + snd_playSoundEffect(13, 200); + + if (countAllItems() >= 50) { + removeTrashItems(); + if (processItemDrop(_mainCharacter.sceneId, item, x, y, unk1, unk2)) + return true; + + if (countAllItems() >= 50) + showMessageFromCCode(14, 0xB3, 0); + } + + if (!_chatText) + snd_playSoundEffect(13, 200); + return false; +} + +bool KyraEngine_MR::processItemDrop(uint16 sceneId, uint16 item, int x, int y, int unk1, int unk2) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::processItemDrop(%d, %d, %d, %d, %d, %d)", sceneId, item, x, y, unk1, unk2); + + int itemPos = checkItemCollision(x, y); + + if (unk1) + itemPos = -1; + + if (itemPos >= 0) { + exchangeMouseItem(itemPos, 1); + return true; + } + + int freeItemSlot = -1; + + if (unk2 != 3) { + for (int i = 0; i < 50; ++i) { + if (_itemList[i].id == 0xFFFF) { + freeItemSlot = i; + break; + } + } + } + + if (freeItemSlot < 0) + return false; + + if (_mainCharacter.sceneId != sceneId) { + _itemList[freeItemSlot].x = x; + _itemList[freeItemSlot].y = y; + _itemList[freeItemSlot].id = item; + _itemList[freeItemSlot].unk8 = 1; + _itemList[freeItemSlot].sceneId = sceneId; + return true; + } + + int itemHeight = _itemBuffer1[item]; + + // no idea why it's '&&' here and not single checks for x and y + if (x == -1 && y == -1) { + x = _rnd.getRandomNumberRng(0x18, 0x128); + y = _rnd.getRandomNumberRng(0x14, 0x87); + } + + int posX = x, posY = y; + int itemX = -1, itemY = -1; + bool needRepositioning = true; + + while (needRepositioning) { + if ((_screen->getDrawLayer(posX, posY) <= 1 && _screen->getDrawLayer2(posX, posY, itemHeight) <= 1 && isDropable(posX, posY)) || posY == 187) { + int posX2 = posX, posX3 = posX; + bool repositioning = true; + + while (repositioning) { + if (isDropable(posX3, posY) && _screen->getDrawLayer2(posX3, posY, itemHeight) < 7 && checkItemCollision(posX3, posY) == -1) { + itemX = posX3; + itemY = posY; + needRepositioning = false; + repositioning = false; + } + + if (isDropable(posX2, posY) && _screen->getDrawLayer2(posX2, posY, itemHeight) < 7 && checkItemCollision(posX2, posY) == -1) { + itemX = posX2; + itemY = posY; + needRepositioning = false; + repositioning = false; + } + + if (repositioning) { + posX3 = MAX(posX3 - 2, 24); + posX2 = MIN(posX2 + 2, 296); + + if (posX3 <= 24 && posX2 >= 296) + repositioning = false; + } + } + } + + if (posY == 187) + needRepositioning = false; + else + posY = MIN(posY + 2, 187); + } + + if (itemX == -1 || itemY == -1) + return false; + + if (unk1 == 3) { + _itemList[freeItemSlot].x = itemX; + _itemList[freeItemSlot].y = itemY; + return true; + } else if (unk1 == 2) { + itemDropDown(x, y, itemX, itemY, freeItemSlot, item, 0); + } + + itemDropDown(x, y, itemX, itemY, freeItemSlot, item, (unk1 == 0) ? 1 : 0); + + if (!unk1 && unk2) { + int itemStr = 1; + if (_lang == 1) + itemStr = getItemCommandStringDrop(item); + updateItemCommand(item, itemStr, 0xFF); + } + + return true; +} + +void KyraEngine_MR::itemDropDown(int startX, int startY, int dstX, int dstY, int itemSlot, uint16 item, int remove) { + debugC(9, kDebugLevelMain, "KyraEngine_v2::itemDropDown(%d, %d, %d, %d, %d, %u, %d)", startX, startY, dstX, dstY, itemSlot, item, remove); + if (startX == dstX && startY == dstY) { + _itemList[itemSlot].x = dstX; + _itemList[itemSlot].y = dstY; + _itemList[itemSlot].id = item; + _itemList[itemSlot].sceneId = _mainCharacter.sceneId; + snd_playSoundEffect(0x0C, 0xC8); + addItemToAnimList(itemSlot); + } else { + uint8 *itemShape = getShapePtr(item + 248); + _screen->hideMouse(); + + if (startY <= dstY) { + int speed = 2; + int curY = startY; + int curX = startX - 12; + + backUpGfxRect32x32(curX, curY-16); + while (curY < dstY) { + restoreGfxRect32x32(curX, curY-16); + + curY = MIN(curY + speed, dstY); + ++speed; + + backUpGfxRect32x32(curX, curY-16); + uint32 endDelay = _system->getMillis() + _tickLength; + + _screen->drawShape(0, itemShape, curX, curY-16, 0, 0); + _screen->updateScreen(); + + delayUntil(endDelay); + } + restoreGfxRect32x32(curX, curY-16); + + if (dstX != dstY || (dstY - startY > 16)) { + snd_playSoundEffect(0x11, 0xC8); + speed = MAX(speed, 6); + int speedX = ((dstX - startX) << 4) / speed; + int origSpeed = speed; + speed >>= 1; + + if (dstY - startY <= 8) + speed >>= 1; + + speed = -speed; + + curX = startX << 4; + + int x = 0, y = 0; + while (--origSpeed) { + curY = MIN(curY + speed, dstY); + curX += speedX; + ++speed; + + x = (curX >> 4) - 8; + y = curY - 16; + backUpGfxRect32x32(x, y); + + uint16 endDelay = _system->getMillis() + _tickLength; + _screen->drawShape(0, itemShape, x, y, 0, 0); + _screen->updateScreen(); + + restoreGfxRect32x32(x, y); + + delayUntil(endDelay); + } + + restoreGfxRect32x32(x, y); + } + } + + _itemList[itemSlot].x = dstX; + _itemList[itemSlot].y = dstY; + _itemList[itemSlot].id = item; + _itemList[itemSlot].sceneId = _mainCharacter.sceneId; + snd_playSoundEffect(0x0C, 0xC8); + addItemToAnimList(itemSlot); + _screen->showMouse(); + } + + if (remove) + removeHandItem(); +} + +void KyraEngine_MR::exchangeMouseItem(int itemPos, int runScript) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::exchangeMouseItem(%d, %d)", itemPos, runScript); + + if (itemListMagic(_itemInHand, itemPos)) + return; + + if (_itemInHand == 43) { + removeHandItem(); + return; + } + + _screen->hideMouse(); + deleteItemAnimEntry(itemPos); + + int itemId = _itemList[itemPos].id; + _itemList[itemPos].id = _itemInHand; + _itemInHand = itemId; + + addItemToAnimList(itemPos); + snd_playSoundEffect(0x0B, 0xC8); + setMouseCursor(_itemInHand); + int str2 = 0; + + if (_lang == 1) + str2 = getItemCommandStringPickUp(itemId); + + updateItemCommand(itemId, str2, 0xFF); + _screen->showMouse(); + + if (runScript) + runSceneScript6(); +} + +bool KyraEngine_MR::pickUpItem(int x, int y, int runScript) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::pickUpItem(%d, %d, %d)", x, y, runScript); + int itemPos = checkItemCollision(x, y); + + if (itemPos <= -1) + return false; + + if (_itemInHand >= 0) { + exchangeMouseItem(itemPos, runScript); + } else { + _screen->hideMouse(); + deleteItemAnimEntry(itemPos); + int itemId = _itemList[itemPos].id; + _itemList[itemPos].id = 0xFFFF; + snd_playSoundEffect(0x0B, 0xC8); + setMouseCursor(itemId); + int itemString = 0; + + if (_lang == 1) + itemString = getItemCommandStringPickUp(itemId); + + updateItemCommand(itemId, itemString, 0xFF); + _itemInHand = itemId; + _screen->showMouse(); + + if (runScript) + runSceneScript6(); + } + + return true; +} + +bool KyraEngine_MR::isDropable(int x, int y) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::isDropable(%d, %d)", x, y); + if (y < 14 || y > 187) + return false; + + x -= 12; + + for (int xpos = x; xpos < x + 24; ++xpos) { + if (_screen->getShapeFlag1(xpos, y) == 0) + return false; + } + + return true; +} + +bool KyraEngine_MR::itemListMagic(int handItem, int itemSlot) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::itemListMagic(%d, %d)", handItem, itemSlot); + + uint16 item = _itemList[itemSlot].id; + if (_currentChapter == 1 && handItem == 3 && item == 3 && queryGameFlag(0x76)) { + eelScript(); + return true; + } else if ((handItem == 6 || handItem == 7) && item == 2) { + int animObjIndex = -1; + for (int i = 17; i <= 66; ++i) { + if (_animObjects[i].shapeIndex2 == 250) + animObjIndex = i; + } + + assert(animObjIndex != -1); + + _screen->hideMouse(); + snd_playSoundEffect(0x93, 0xC8); + for (int i = 109; i <= 141; ++i) { + _animObjects[animObjIndex].shapeIndex1 = i+248; + _animObjects[animObjIndex].needRefresh = true; + delay(1*_tickLength, true); + } + + deleteItemAnimEntry(itemSlot); + _itemList[itemSlot].id = 0xFFFF; + _screen->showMouse(); + return true; + } + + if (_mainCharacter.sceneId == 51 && queryGameFlag(0x19B) && !queryGameFlag(0x19C) + && ((item == 63 && handItem == 56) || (item == 56 && handItem == 63))) { + + if (queryGameFlag(0x1AC)) { + setGameFlag(0x19C); + setGameFlag(0x1AD); + } else { + setGameFlag(0x1AE); + } + + _timer->setCountdown(12, 1); + _timer->enable(12); + } + + for (int i = 0; _itemMagicTable[i] != 0xFF; i += 4) { + if (_itemMagicTable[i+0] != handItem || _itemMagicTable[i+1] != item) + continue; + + uint8 resItem = _itemMagicTable[i+2]; + uint8 newItem = _itemMagicTable[i+3]; + + snd_playSoundEffect(0x0F, 0xC8); + + _itemList[itemSlot].id = (resItem == 0xFF) ? 0xFFFF : resItem; + + _screen->hideMouse(); + deleteItemAnimEntry(itemSlot); + addItemToAnimList(itemSlot); + + if (newItem == 0xFE) + removeHandItem(); + else if (newItem != 0xFF) + setHandItem(newItem); + _screen->showMouse(); + + if (_lang != 1) + updateItemCommand(resItem, 3, 0xFF); + + // Unlike the original we give points for when combining with scene items + if (resItem == 7) { + updateScore(35, 100); + delay(60*_tickLength, true); + } + + return true; + } + + return false; +} + +bool KyraEngine_MR::itemInventoryMagic(int handItem, int invSlot) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::itemInventoryMagic(%d, %d)", handItem, invSlot); + + uint16 item = _mainCharacter.inventory[invSlot]; + if (_currentChapter == 1 && handItem == 3 && item == 3 && queryGameFlag(0x76)) { + eelScript(); + return true; + } else if ((handItem == 6 || handItem == 7) && item == 2) { + _screen->hideMouse(); + snd_playSoundEffect(0x93, 0xC8); + for (int i = 109; i <= 141; ++i) { + _mainCharacter.inventory[invSlot] = i; + _screen->drawShape(2, getShapePtr(invSlot+422), 0, 144, 0, 0); + _screen->drawShape(2, getShapePtr(i+248), 0, 144, 0, 0); + _screen->copyRegion(0, 144, _inventoryX[invSlot], _inventoryY[invSlot], 24, 20, 2, 0, Screen::CR_NO_P_CHECK); + _screen->updateScreen(); + delay(1*_tickLength, true); + } + + _mainCharacter.inventory[invSlot] = 0xFFFF; + clearInventorySlot(invSlot, 0); + _screen->showMouse(); + return true; + } + + for (int i = 0; _itemMagicTable[i] != 0xFF; i += 4) { + if (_itemMagicTable[i+0] != handItem || _itemMagicTable[i+1] != item) + continue; + + uint8 resItem = _itemMagicTable[i+2]; + uint8 newItem = _itemMagicTable[i+3]; + + snd_playSoundEffect(0x0F, 0xC8); + + _mainCharacter.inventory[invSlot] = (resItem == 0xFF) ? 0xFFFF : resItem; + + _screen->hideMouse(); + clearInventorySlot(invSlot, 0); + drawInventorySlot(0, resItem, invSlot); + + if (newItem == 0xFE) + removeHandItem(); + else if (newItem != 0xFF) + setHandItem(newItem); + _screen->showMouse(); + + if (_lang != 1) + updateItemCommand(resItem, 3, 0xFF); + + // Unlike the original we give points for every language + if (resItem == 7) { + updateScore(35, 100); + delay(60*_tickLength, true); + } + + return true; + } + + return false; +} + +int KyraEngine_MR::getItemCommandStringDrop(uint16 item) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::getItemCommandStringDrop(%u)", item); + assert(item < _itemStringMapSize); + int stringId = _itemStringMap[item]; + return _itemStringDrop[stringId]; +} + +int KyraEngine_MR::getItemCommandStringPickUp(uint16 item) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::getItemCommandStringPickUp(%u)", item); + assert(item < _itemStringMapSize); + int stringId = _itemStringMap[item]; + return _itemStringPickUp[stringId]; +} + +int KyraEngine_MR::getItemCommandStringInv(uint16 item) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::getItemCommandStringInv(%u)", item); + assert(item < _itemStringMapSize); + int stringId = _itemStringMap[item]; + return _itemStringInv[stringId]; +} + +} // end of namespace Kyra + diff --git a/engines/kyra/items_v2.cpp b/engines/kyra/items_v2.cpp deleted file mode 100644 index ee010b62e6..0000000000 --- a/engines/kyra/items_v2.cpp +++ /dev/null @@ -1,511 +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_v2.h" - -namespace Kyra { - -int KyraEngine_v2::findFreeItem() { - debugC(9, kDebugLevelMain, "KyraEngine_v2::findFreeItem()"); - for (int i = 0; i < 30; ++i) { - if (_itemList[i].id == 0xFFFF) - return i; - } - return -1; -} - -int KyraEngine_v2::countAllItems() { - debugC(9, kDebugLevelMain, "KyraEngine_v2::countAllItems()"); - int num = 0; - for (int i = 0; i < 30; ++i) { - if (_itemList[i].id != 0xFFFF) - ++num; - } - return num; -} - -int KyraEngine_v2::findItem(uint16 sceneId, uint16 id) { - debugC(9, kDebugLevelMain, "KyraEngine_v2::findItem(%u, %u)", sceneId, id); - for (int i = 0; i < 30; ++i) { - if (_itemList[i].id == id && _itemList[i].sceneId == sceneId) - return i; - } - return -1; -} - -int KyraEngine_v2::checkItemCollision(int x, int y) { - debugC(9, kDebugLevelMain, "KyraEngine_v2::checkItemCollision(%d, %d)", x, y); - int itemPos = -1, yPos = -1; - - for (int i = 0; i < 30; ++i) { - const Item &curItem = _itemList[i]; - - if (curItem.id == 0xFFFF || curItem.sceneId != _mainCharacter.sceneId) - continue; - - int itemX1 = curItem.x - 8 - 3; - int itemX2 = curItem.x + 7 + 3; - - if (x < itemX1 || x > itemX2) - continue; - - int itemY1 = curItem.y - _itemHtDat[curItem.id] - 3; - int itemY2 = curItem.y + 3; - - if (y < itemY1 || y > itemY2) - continue; - - if (curItem.y >= yPos) { - itemPos = i; - yPos = curItem.y; - } - } - - return itemPos; -} - -void KyraEngine_v2::resetItemList() { - debugC(9, kDebugLevelMain, "KyraEngine_v2::resetItemList()"); - for (int i = 0; i < 30; ++i) { - _itemList[i].id = 0xFFFF; - _itemList[i].sceneId = 0xFFFF; - _itemList[i].x = 0; - _itemList[i].y = 0; - _itemList[i].unk7 = 0; - } -} - -void KyraEngine_v2::updateWaterFlasks() { - debugC(9, kDebugLevelMain, "KyraEngine_v2::updateWaterFlasks()"); - for (int i = 22; i < 24; i++) { - if (_itemInHand == i) - setHandItem(i - 1); - - for (int ii = 0; ii < 20; ii++) { - if (_mainCharacter.inventory[ii] == i) { - _mainCharacter.inventory[ii]--; - if (ii < 10) { - clearInventorySlot(ii, 0); - _screen->drawShape(0, getShapePtr(i + 63), _inventoryX[ii], _inventoryY[ii], 0, 0); - } - } - } - - for (int ii = 0; ii < 30; ii++) { - if (_itemList[ii].id == i) - _itemList[ii].id--; - } - } -} - -bool KyraEngine_v2::dropItem(int unk1, uint16 item, int x, int y, int unk2) { - debugC(9, kDebugLevelMain, "KyraEngine_v2::dropItem(%d, %u, %d, %d, %d)", unk1, item, x, y, unk2); - if (_handItemSet <= -1) - return false; - - bool success = processItemDrop(_mainCharacter.sceneId, item, x, y, unk1, unk2); - if (!success) { - snd_playSoundEffect(0x0d); - if (countAllItems() >= 30) - showMessageFromCCode(5, 0x84, 0); - } - - return success; -} - -bool KyraEngine_v2::processItemDrop(uint16 sceneId, uint16 item, int x, int y, int unk1, int unk2) { - debugC(9, kDebugLevelMain, "KyraEngine_v2::processItemDrop(%u, %u, %d, %d, %d, %d)", sceneId, item, x, y, unk1, unk2); - int itemPos = checkItemCollision(x, y); - - if (unk1) - itemPos = -1; - - if (itemPos >= 0) { - exchangeMouseItem(itemPos); - return false; - } - - int freeItemSlot = -1; - - if (unk1 != 3) { - for (int i = 0; i < 30; ++i) { - if (_itemList[i].id == 0xFFFF) { - freeItemSlot = i; - break; - } - } - } - - if (freeItemSlot == -1) - return false; - - if (sceneId != _mainCharacter.sceneId) { - _itemList[freeItemSlot].x = x; - _itemList[freeItemSlot].y = y; - _itemList[freeItemSlot].id = item; - _itemList[freeItemSlot].unk7 = 1; - _itemList[freeItemSlot].sceneId = sceneId; - return true; - } - - int itemHeight = _itemHtDat[item]; - - // no idea why it's '&&' here and not single checks for x and y - if (x == -1 && y == -1) { - x = _rnd.getRandomNumberRng(0x10, 0x130); - y = _rnd.getRandomNumberRng(0x10, 0x87); - } - - int posX = x, posY = y; - int itemX = -1, itemY = -1; - bool needRepositioning = true; - - while (needRepositioning) { - if ((_screen->getDrawLayer(posX, posY) <= 1 && _screen->getDrawLayer2(posX, posY, itemHeight) <= 1 && isDropable(posX, posY)) || posY == 136) { - int posX2 = posX, posX3 = posX; - bool repositioning = true; - - while (repositioning) { - if (isDropable(posX3, posY) && _screen->getDrawLayer(posX3, posY) < 7 && checkItemCollision(posX3, posY) == -1) { - itemX = posX3; - itemY = posY; - needRepositioning = false; - repositioning = false; - } - - if (isDropable(posX2, posY) && _screen->getDrawLayer(posX2, posY) < 7 && checkItemCollision(posX2, posY) == -1) { - itemX = posX2; - itemY = posY; - needRepositioning = false; - repositioning = false; - } - - if (repositioning) { - posX3 = MAX(posX3 - 2, 16); - posX2 = MIN(posX2 + 2, 304); - - if (posX3 <= 16 && posX2 >= 304) - repositioning = false; - } - } - } - - if (posY == 136) - needRepositioning = false; - else - posY = MIN(posY + 2, 136); - } - - if (itemX == -1 || itemY == -1) - return false; - - if (unk1 == 3) { - _itemList[freeItemSlot].x = itemX; - _itemList[freeItemSlot].y = itemY; - return true; - } else if (unk1 == 2) { - itemDropDown(x, y, itemX, itemY, freeItemSlot, item); - } - - if (!unk1) - removeHandItem(); - - itemDropDown(x, y, itemX, itemY, freeItemSlot, item); - - if (!unk1 && unk2) { - int itemStr = 3; - if (_lang == 1) - itemStr = getItemCommandStringDrop(item); - updateCommandLineEx(item+54, itemStr, 0xD6); - } - - return true; -} - -void KyraEngine_v2::itemDropDown(int startX, int startY, int dstX, int dstY, int itemSlot, uint16 item) { - debugC(9, kDebugLevelMain, "KyraEngine_v2::itemDropDown(%d, %d, %d, %d, %d, %u)", startX, startY, dstX, dstY, itemSlot, item); - uint8 *itemShape = getShapePtr(item + 64); - - if (startX == dstX && startY == dstY) { - if (_layerFlagTable[_screen->getLayer(dstX, dstY)] && item != 13) { - updateCharFacing(); - snd_playSoundEffect(0x2d); - removeHandItem(); - objectChat(getTableString(0xFF, _cCodeBuffer, 1), 0, 0x83, 0xFF); - } else { - _itemList[itemSlot].x = dstX; - _itemList[itemSlot].y = dstY; - _itemList[itemSlot].id = item; - _itemList[itemSlot].sceneId = _mainCharacter.sceneId; - snd_playSoundEffect(0x0c); - addItemToAnimList(itemSlot); - } - } else { - _screen->hideMouse(); - - if (startY <= dstY) { - int speed = 2; - int curY = startY; - int curX = startX - 8; - - backUpGfxRect24x24(curX, curY-16); - while (curY < dstY) { - restoreGfxRect24x24(curX, curY-16); - - curY = MIN(curY + speed, dstY); - ++speed; - - backUpGfxRect24x24(curX, curY-16); - uint32 endDelay = _system->getMillis() + _tickLength; - - _screen->drawShape(0, itemShape, curX, curY-16, 0, 0); - _screen->updateScreen(); - - // XXX: original doesn't update game state while delaying - // our implementation *could* do it, so maybe check this again - delayUntil(endDelay); - } - - if (dstX != dstY || (dstY - startY > 16)) { - snd_playSoundEffect(0x69); - speed = MAX(speed, 6); - int speedX = ((dstX - startX) << 4) / speed; - int origSpeed = speed; - speed >>= 1; - - if (dstY - startY <= 8) - speed >>= 1; - - speed = -speed; - - curX = startX << 4; - - int x = 0, y = 0; - while (--origSpeed) { - x = (curX >> 4) - 8; - y = curY - 16; - - restoreGfxRect24x24(x, y); - curY = MIN(curY + speed, dstY); - curX += speedX; - ++speed; - - x = (curX >> 4) - 8; - y = curY - 16; - backUpGfxRect24x24(x, y); - - uint16 endDelay = _system->getMillis() + _tickLength; - _screen->drawShape(0, itemShape, x, y, 0, 0); - _screen->updateScreen(); - - // XXX: original doesn't update game state while delaying - // our implementation *could* do it, so maybe check this again - delayUntil(endDelay); - } - - restoreGfxRect24x24(x, y); - } else { - restoreGfxRect24x24(curX, curY-16); - } - } - - if (_layerFlagTable[_screen->getLayer(dstX, dstY)] && item != 13) { - updateCharFacing(); - snd_playSoundEffect(0x2d); - removeHandItem(); - _screen->showMouse(); - objectChat(getTableString(0xFF, _cCodeBuffer, 1), 0, 0x83, 0xFF); - } else { - _itemList[itemSlot].x = dstX; - _itemList[itemSlot].y = dstY; - _itemList[itemSlot].id = item; - _itemList[itemSlot].sceneId = _mainCharacter.sceneId; - snd_playSoundEffect(0x0c); - addItemToAnimList(itemSlot); - _screen->showMouse(); - } - } -} - -void KyraEngine_v2::exchangeMouseItem(int itemPos) { - debugC(9, kDebugLevelMain, "KyraEngine_v2::exchangeMouseItem(%d)", itemPos); - _screen->hideMouse(); - - deleteItemAnimEntry(itemPos); - - int itemId = _itemList[itemPos].id; - _itemList[itemPos].id = _itemInHand; - _itemInHand = itemId; - - addItemToAnimList(itemPos); - snd_playSoundEffect(0x0b); - setMouseCursor(_itemInHand); - int str2 = 7; - - if (_lang == 1) - str2 = getItemCommandStringPickUp(itemId); - - updateCommandLineEx(itemId + 54, str2, 0xD6); - _screen->showMouse(); - - runSceneScript6(); -} - -bool KyraEngine_v2::pickUpItem(int x, int y) { - debugC(9, kDebugLevelMain, "KyraEngine_v2::pickUpItem(%d, %d)", x, y); - int itemPos = checkItemCollision(x, y); - - if (itemPos <= -1) - return false; - - if (_itemInHand >= 0) { - exchangeMouseItem(itemPos); - } else { - _screen->hideMouse(); - deleteItemAnimEntry(itemPos); - int itemId = _itemList[itemPos].id; - _itemList[itemPos].id = 0xFFFF; - snd_playSoundEffect(0x0b); - setMouseCursor(itemId); - int str2 = 7; - - if (_lang == 1) - str2 = getItemCommandStringPickUp(itemId); - - updateCommandLineEx(itemId + 54, str2, 0xD6); - _itemInHand = itemId; - _screen->showMouse(); - - runSceneScript6(); - } - - return true; -} - -bool KyraEngine_v2::isDropable(int x, int y) { - debugC(9, kDebugLevelMain, "KyraEngine_v2::isDropable(%d, %d)", x, y); - if (x < 14 || x > 304 || y < 14 || y > 136) - return false; - - x -= 8; - y -= 1; - - for (int xpos = x; xpos < x + 16; ++xpos) { - if (_screen->getShapeFlag1(xpos, y) == 0) - return false; - } - - return true; -} - -int KyraEngine_v2::getItemCommandStringDrop(uint16 item) { - debugC(9, kDebugLevelMain, "KyraEngine_v2::getItemCommandStringDrop(%u)", item); - assert(item < _itemStringMapSize); - int stringId = _itemStringMap[item]; - - static const int dropStringIds[] = { - 0x2D, 0x103, 0x003, 0x106 - }; - assert(stringId < ARRAYSIZE(dropStringIds)); - - return dropStringIds[stringId]; -} - -int KyraEngine_v2::getItemCommandStringPickUp(uint16 item) { - debugC(9, kDebugLevelMain, "KyraEngine_v2::getItemCommandStringPickUp(%u)", item); - assert(item < _itemStringMapSize); - int stringId = _itemStringMap[item]; - - static const int pickUpStringIds[] = { - 0x02B, 0x102, 0x007, 0x105 - }; - assert(stringId < ARRAYSIZE(pickUpStringIds)); - - return pickUpStringIds[stringId]; -} - -int KyraEngine_v2::getItemCommandStringInv(uint16 item) { - debugC(9, kDebugLevelMain, "KyraEngine_v2::getItemCommandStringInv(%u)", item); - assert(item < _itemStringMapSize); - int stringId = _itemStringMap[item]; - - static const int pickUpStringIds[] = { - 0x02C, 0x104, 0x008, 0x107 - }; - assert(stringId < ARRAYSIZE(pickUpStringIds)); - - return pickUpStringIds[stringId]; -} - -void KyraEngine_v2::setMouseCursor(uint16 item) { - debugC(9, kDebugLevelMain, "KyraEngine_v2::setMouseCursor(%u)", item); - int shape = 0; - int hotX = 1; - int hotY = 1; - - if (item != 0xFFFF) { - hotX = 8; - hotY = 15; - shape = item+64; - } - - _screen->setMouseCursor(hotX, hotY, getShapePtr(shape)); -} - -void KyraEngine_v2::setHandItem(uint16 item) { - debugC(9, kDebugLevelMain, "KyraEngine_v2::setHandItem(%u)", item); - _screen->hideMouse(); - - if (item == 0xFFFF) { - removeHandItem(); - } else { - setMouseCursor(item); - _itemInHand = item; - } - - _screen->showMouse(); -} - -void KyraEngine_v2::removeHandItem() { - debugC(9, kDebugLevelMain, "KyraEngine_v2::removeHandItem()"); - _screen->hideMouse(); - _screen->setMouseCursor(0, 0, _defaultShapeTable[0]); - _itemInHand = -1; - _handItemSet = -1; - _screen->showMouse(); -} - -bool KyraEngine_v2::itemIsFlask(int item) { - debugC(9, kDebugLevelMain, "KyraEngine_v2::itemIsFlask(%d)", item); - for (int i = 0; _flaskTable[i] != -1; ++i) { - if (_flaskTable[i] == item) - return true; - } - - return false; -} - -} // end of namespace Kyra - diff --git a/engines/kyra/items_v3.cpp b/engines/kyra/items_v3.cpp deleted file mode 100644 index d428debda6..0000000000 --- a/engines/kyra/items_v3.cpp +++ /dev/null @@ -1,644 +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_v3.h" -#include "kyra/timer.h" - -namespace Kyra { - -void KyraEngine_v3::resetItem(int index) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::resetItem(%d)", index); - _itemList[index].id = 0xFFFF; - _itemList[index].sceneId = 0xFFFF; - _itemList[index].x = 0; - _itemList[index].y = 0; - _itemList[index].unk8 = 0; -} - -void KyraEngine_v3::resetItemList() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::resetItemList()"); - for (int i = 0; i < 50; ++i) - resetItem(i); -} - -void KyraEngine_v3::removeTrashItems() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::removeTrashItems()"); - for (int i = 0; _trashItemList[i] != 0xFF; ++i) { - for (int item = findItem(_trashItemList[i]); item != -1; item = findItem(_trashItemList[i])) { - if (_itemList[item].sceneId != _mainCharacter.sceneId) - resetItem(item); - else - break; - } - } -} - -int KyraEngine_v3::findFreeItem() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::findFreeItem()"); - for (int i = 0; i < 50; ++i) { - if (_itemList[i].id == 0xFFFF) - return i; - } - return -1; -} - -int KyraEngine_v3::findFreeInventorySlot() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::findFreeInventorySlot()"); - for (int i = 0; i < 10; ++i) { - if (_mainCharacter.inventory[i] == 0xFFFF) - return i; - } - return -1; -} - -int KyraEngine_v3::findItem(uint16 sceneId, uint16 id) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::findItem(%u, %u)", sceneId, id); - for (int i = 0; i < 50; ++i) { - if (_itemList[i].id == id && _itemList[i].sceneId == sceneId) - return i; - } - return -1; -} - -int KyraEngine_v3::findItem(uint16 item) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::findItem(%u)", item); - for (int i = 0; i < 50; ++i) { - if (_itemList[i].id == item) - return i; - } - return -1; -} - -int KyraEngine_v3::countAllItems() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::countAllItems()"); - int count = 0; - - for (int i = 0; i < 50; ++i) { - if (_itemList[i].id != 0xFFFF) - ++count; - } - - return count; -} - -int KyraEngine_v3::checkItemCollision(int x, int y) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::checkItemCollision(%d, %d)", x, y); - int itemIndex = -1; - int maxItemY = -1; - - for (int i = 0; i < 50; ++i) { - if (_itemList[i].id == 0xFFFF || _itemList[i].sceneId != _mainCharacter.sceneId) - continue; - - const int x1 = _itemList[i].x - 11; - const int x2 = _itemList[i].x + 10; - - if (x < x1 || x > x2) - continue; - - const int y1 = _itemList[i].y - _itemBuffer1[_itemList[i].id] - 3; - const int y2 = _itemList[i].y + 3; - - if (y < y1 || y > y2) - continue; - - if (_itemList[i].y >= maxItemY) { - itemIndex = i; - maxItemY = _itemList[i].y; - } - } - - return itemIndex; -} - -void KyraEngine_v3::setMouseCursor(uint16 item) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::setMouseCursor(%u)", item); - int shape = 0; - int hotX = 1; - int hotY = 1; - - if (item != 0xFFFF) { - hotX = 12; - hotY = 19; - shape = item+248; - } - - if ((int16)item != _itemInHand) - _screen->setMouseCursor(hotX, hotY, getShapePtr(shape)); -} - -void KyraEngine_v3::setItemMouseCursor() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::setItemMouseCursor()"); - _handItemSet = _itemInHand; - if (_itemInHand == -1) - _screen->setMouseCursor(0, 0, _gameShapes[0]); - else - _screen->setMouseCursor(12, 19, _gameShapes[_itemInHand+248]); -} - -void KyraEngine_v3::setHandItem(uint16 item) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::setHandItem(%u)", item); - _screen->hideMouse(); - - if (item == 0xFFFF) { - removeHandItem(); - } else { - setMouseCursor(item); - _itemInHand = item; - } - - _screen->showMouse(); -} - -void KyraEngine_v3::removeHandItem() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::removeHandItem()"); - _screen->hideMouse(); - _screen->setMouseCursor(0, 0, _gameShapes[0]); - _itemInHand = -1; - _handItemSet = -1; - _screen->showMouse(); -} - -bool KyraEngine_v3::dropItem(int unk1, uint16 item, int x, int y, int unk2) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::dropItem(%d, %d, %d, %d, %d)", unk1, item, x, y, unk2); - - if (_handItemSet <= -1) - return false; - - if (processItemDrop(_mainCharacter.sceneId, item, x, y, unk1, unk2)) - return true; - - snd_playSoundEffect(13, 200); - - if (countAllItems() >= 50) { - removeTrashItems(); - if (processItemDrop(_mainCharacter.sceneId, item, x, y, unk1, unk2)) - return true; - - if (countAllItems() >= 50) - showMessageFromCCode(14, 0xB3, 0); - } - - if (!_chatText) - snd_playSoundEffect(13, 200); - return false; -} - -bool KyraEngine_v3::processItemDrop(uint16 sceneId, uint16 item, int x, int y, int unk1, int unk2) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::processItemDrop(%d, %d, %d, %d, %d, %d)", sceneId, item, x, y, unk1, unk2); - - int itemPos = checkItemCollision(x, y); - - if (unk1) - itemPos = -1; - - if (itemPos >= 0) { - exchangeMouseItem(itemPos, 1); - return true; - } - - int freeItemSlot = -1; - - if (unk2 != 3) { - for (int i = 0; i < 50; ++i) { - if (_itemList[i].id == 0xFFFF) { - freeItemSlot = i; - break; - } - } - } - - if (freeItemSlot < 0) - return false; - - if (_mainCharacter.sceneId != sceneId) { - _itemList[freeItemSlot].x = x; - _itemList[freeItemSlot].y = y; - _itemList[freeItemSlot].id = item; - _itemList[freeItemSlot].unk8 = 1; - _itemList[freeItemSlot].sceneId = sceneId; - return true; - } - - int itemHeight = _itemBuffer1[item]; - - // no idea why it's '&&' here and not single checks for x and y - if (x == -1 && y == -1) { - x = _rnd.getRandomNumberRng(0x18, 0x128); - y = _rnd.getRandomNumberRng(0x14, 0x87); - } - - int posX = x, posY = y; - int itemX = -1, itemY = -1; - bool needRepositioning = true; - - while (needRepositioning) { - if ((_screen->getDrawLayer(posX, posY) <= 1 && _screen->getDrawLayer2(posX, posY, itemHeight) <= 1 && isDropable(posX, posY)) || posY == 187) { - int posX2 = posX, posX3 = posX; - bool repositioning = true; - - while (repositioning) { - if (isDropable(posX3, posY) && _screen->getDrawLayer2(posX3, posY, itemHeight) < 7 && checkItemCollision(posX3, posY) == -1) { - itemX = posX3; - itemY = posY; - needRepositioning = false; - repositioning = false; - } - - if (isDropable(posX2, posY) && _screen->getDrawLayer2(posX2, posY, itemHeight) < 7 && checkItemCollision(posX2, posY) == -1) { - itemX = posX2; - itemY = posY; - needRepositioning = false; - repositioning = false; - } - - if (repositioning) { - posX3 = MAX(posX3 - 2, 24); - posX2 = MIN(posX2 + 2, 296); - - if (posX3 <= 24 && posX2 >= 296) - repositioning = false; - } - } - } - - if (posY == 187) - needRepositioning = false; - else - posY = MIN(posY + 2, 187); - } - - if (itemX == -1 || itemY == -1) - return false; - - if (unk1 == 3) { - _itemList[freeItemSlot].x = itemX; - _itemList[freeItemSlot].y = itemY; - return true; - } else if (unk1 == 2) { - itemDropDown(x, y, itemX, itemY, freeItemSlot, item, 0); - } - - itemDropDown(x, y, itemX, itemY, freeItemSlot, item, (unk1 == 0) ? 1 : 0); - - if (!unk1 && unk2) { - int itemStr = 1; - if (_lang == 1) - itemStr = getItemCommandStringDrop(item); - updateItemCommand(item, itemStr, 0xFF); - } - - return true; -} - -void KyraEngine_v3::itemDropDown(int startX, int startY, int dstX, int dstY, int itemSlot, uint16 item, int remove) { - debugC(9, kDebugLevelMain, "KyraEngine_v2::itemDropDown(%d, %d, %d, %d, %d, %u, %d)", startX, startY, dstX, dstY, itemSlot, item, remove); - if (startX == dstX && startY == dstY) { - _itemList[itemSlot].x = dstX; - _itemList[itemSlot].y = dstY; - _itemList[itemSlot].id = item; - _itemList[itemSlot].sceneId = _mainCharacter.sceneId; - snd_playSoundEffect(0x0C, 0xC8); - addItemToAnimList(itemSlot); - } else { - uint8 *itemShape = getShapePtr(item + 248); - _screen->hideMouse(); - - if (startY <= dstY) { - int speed = 2; - int curY = startY; - int curX = startX - 12; - - backUpGfxRect32x32(curX, curY-16); - while (curY < dstY) { - restoreGfxRect32x32(curX, curY-16); - - curY = MIN(curY + speed, dstY); - ++speed; - - backUpGfxRect32x32(curX, curY-16); - uint32 endDelay = _system->getMillis() + _tickLength; - - _screen->drawShape(0, itemShape, curX, curY-16, 0, 0); - _screen->updateScreen(); - - delayUntil(endDelay); - } - restoreGfxRect32x32(curX, curY-16); - - if (dstX != dstY || (dstY - startY > 16)) { - snd_playSoundEffect(0x11, 0xC8); - speed = MAX(speed, 6); - int speedX = ((dstX - startX) << 4) / speed; - int origSpeed = speed; - speed >>= 1; - - if (dstY - startY <= 8) - speed >>= 1; - - speed = -speed; - - curX = startX << 4; - - int x = 0, y = 0; - while (--origSpeed) { - curY = MIN(curY + speed, dstY); - curX += speedX; - ++speed; - - x = (curX >> 4) - 8; - y = curY - 16; - backUpGfxRect32x32(x, y); - - uint16 endDelay = _system->getMillis() + _tickLength; - _screen->drawShape(0, itemShape, x, y, 0, 0); - _screen->updateScreen(); - - restoreGfxRect32x32(x, y); - - delayUntil(endDelay); - } - - restoreGfxRect32x32(x, y); - } - } - - _itemList[itemSlot].x = dstX; - _itemList[itemSlot].y = dstY; - _itemList[itemSlot].id = item; - _itemList[itemSlot].sceneId = _mainCharacter.sceneId; - snd_playSoundEffect(0x0C, 0xC8); - addItemToAnimList(itemSlot); - _screen->showMouse(); - } - - if (remove) - removeHandItem(); -} - -void KyraEngine_v3::exchangeMouseItem(int itemPos, int runScript) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::exchangeMouseItem(%d, %d)", itemPos, runScript); - - if (itemListMagic(_itemInHand, itemPos)) - return; - - if (_itemInHand == 43) { - removeHandItem(); - return; - } - - _screen->hideMouse(); - deleteItemAnimEntry(itemPos); - - int itemId = _itemList[itemPos].id; - _itemList[itemPos].id = _itemInHand; - _itemInHand = itemId; - - addItemToAnimList(itemPos); - snd_playSoundEffect(0x0B, 0xC8); - setMouseCursor(_itemInHand); - int str2 = 0; - - if (_lang == 1) - str2 = getItemCommandStringPickUp(itemId); - - updateItemCommand(itemId, str2, 0xFF); - _screen->showMouse(); - - if (runScript) - runSceneScript6(); -} - -bool KyraEngine_v3::pickUpItem(int x, int y, int runScript) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::pickUpItem(%d, %d, %d)", x, y, runScript); - int itemPos = checkItemCollision(x, y); - - if (itemPos <= -1) - return false; - - if (_itemInHand >= 0) { - exchangeMouseItem(itemPos, runScript); - } else { - _screen->hideMouse(); - deleteItemAnimEntry(itemPos); - int itemId = _itemList[itemPos].id; - _itemList[itemPos].id = 0xFFFF; - snd_playSoundEffect(0x0B, 0xC8); - setMouseCursor(itemId); - int itemString = 0; - - if (_lang == 1) - itemString = getItemCommandStringPickUp(itemId); - - updateItemCommand(itemId, itemString, 0xFF); - _itemInHand = itemId; - _screen->showMouse(); - - if (runScript) - runSceneScript6(); - } - - return true; -} - -bool KyraEngine_v3::isDropable(int x, int y) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::isDropable(%d, %d)", x, y); - if (y < 14 || y > 187) - return false; - - x -= 12; - - for (int xpos = x; xpos < x + 24; ++xpos) { - if (_screen->getShapeFlag1(xpos, y) == 0) - return false; - } - - return true; -} - -bool KyraEngine_v3::itemListMagic(int handItem, int itemSlot) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::itemListMagic(%d, %d)", handItem, itemSlot); - - uint16 item = _itemList[itemSlot].id; - if (_currentChapter == 1 && handItem == 3 && item == 3 && queryGameFlag(0x76)) { - eelScript(); - return true; - } else if ((handItem == 6 || handItem == 7) && item == 2) { - int animObjIndex = -1; - for (int i = 17; i <= 66; ++i) { - if (_animObjects[i].shapeIndex2 == 250) - animObjIndex = i; - } - - assert(animObjIndex != -1); - - _screen->hideMouse(); - snd_playSoundEffect(0x93, 0xC8); - for (int i = 109; i <= 141; ++i) { - _animObjects[animObjIndex].shapeIndex = i+248; - _animObjects[animObjIndex].needRefresh = true; - delay(1*_tickLength, true); - } - - deleteItemAnimEntry(itemSlot); - _itemList[itemSlot].id = 0xFFFF; - _screen->showMouse(); - return true; - } - - if (_mainCharacter.sceneId == 51 && queryGameFlag(0x19B) && !queryGameFlag(0x19C) - && ((item == 63 && handItem == 56) || (item == 56 && handItem == 63))) { - - if (queryGameFlag(0x1AC)) { - setGameFlag(0x19C); - setGameFlag(0x1AD); - } else { - setGameFlag(0x1AE); - } - - _timer->setCountdown(12, 1); - _timer->enable(12); - } - - for (int i = 0; _itemMagicTable[i] != 0xFF; i += 4) { - if (_itemMagicTable[i+0] != handItem || _itemMagicTable[i+1] != item) - continue; - - uint8 resItem = _itemMagicTable[i+2]; - uint8 newItem = _itemMagicTable[i+3]; - - snd_playSoundEffect(0x0F, 0xC8); - - _itemList[itemSlot].id = (resItem == 0xFF) ? 0xFFFF : resItem; - - _screen->hideMouse(); - deleteItemAnimEntry(itemSlot); - addItemToAnimList(itemSlot); - - if (newItem == 0xFE) - removeHandItem(); - else if (newItem != 0xFF) - setHandItem(newItem); - _screen->showMouse(); - - if (_lang != 1) - updateItemCommand(resItem, 3, 0xFF); - - // Unlike the original we give points for when combining with scene items - if (resItem == 7) { - updateScore(35, 100); - delay(60*_tickLength, true); - } - - return true; - } - - return false; -} - -bool KyraEngine_v3::itemInventoryMagic(int handItem, int invSlot) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::itemInventoryMagic(%d, %d)", handItem, invSlot); - - uint16 item = _mainCharacter.inventory[invSlot]; - if (_currentChapter == 1 && handItem == 3 && item == 3 && queryGameFlag(0x76)) { - eelScript(); - return true; - } else if ((handItem == 6 || handItem == 7) && item == 2) { - _screen->hideMouse(); - snd_playSoundEffect(0x93, 0xC8); - for (int i = 109; i <= 141; ++i) { - _mainCharacter.inventory[invSlot] = i; - _screen->drawShape(2, getShapePtr(invSlot+422), 0, 144, 0, 0); - _screen->drawShape(2, getShapePtr(i+248), 0, 144, 0, 0); - _screen->copyRegion(0, 144, _inventoryX[invSlot], _inventoryY[invSlot], 24, 20, 2, 0, Screen::CR_NO_P_CHECK); - _screen->updateScreen(); - delay(1*_tickLength, true); - } - - _mainCharacter.inventory[invSlot] = 0xFFFF; - clearInventorySlot(invSlot, 0); - _screen->showMouse(); - return true; - } - - for (int i = 0; _itemMagicTable[i] != 0xFF; i += 4) { - if (_itemMagicTable[i+0] != handItem || _itemMagicTable[i+1] != item) - continue; - - uint8 resItem = _itemMagicTable[i+2]; - uint8 newItem = _itemMagicTable[i+3]; - - snd_playSoundEffect(0x0F, 0xC8); - - _mainCharacter.inventory[invSlot] = (resItem == 0xFF) ? 0xFFFF : resItem; - - _screen->hideMouse(); - clearInventorySlot(invSlot, 0); - drawInventorySlot(0, resItem, invSlot); - - if (newItem == 0xFE) - removeHandItem(); - else if (newItem != 0xFF) - setHandItem(newItem); - _screen->showMouse(); - - if (_lang != 1) - updateItemCommand(resItem, 3, 0xFF); - - // Unlike the original we give points for every language - if (resItem == 7) { - updateScore(35, 100); - delay(60*_tickLength, true); - } - - return true; - } - - return false; -} - -int KyraEngine_v3::getItemCommandStringDrop(uint16 item) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::getItemCommandStringDrop(%u)", item); - assert(item < _itemStringMapSize); - int stringId = _itemStringMap[item]; - return _itemStringDrop[stringId]; -} - -int KyraEngine_v3::getItemCommandStringPickUp(uint16 item) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::getItemCommandStringPickUp(%u)", item); - assert(item < _itemStringMapSize); - int stringId = _itemStringMap[item]; - return _itemStringPickUp[stringId]; -} - -int KyraEngine_v3::getItemCommandStringInv(uint16 item) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::getItemCommandStringInv(%u)", item); - assert(item < _itemStringMapSize); - int stringId = _itemStringMap[item]; - return _itemStringInv[stringId]; -} - -} // end of namespace Kyra - diff --git a/engines/kyra/kyra_hof.cpp b/engines/kyra/kyra_hof.cpp new file mode 100644 index 0000000000..e4b7d2b528 --- /dev/null +++ b/engines/kyra/kyra_hof.cpp @@ -0,0 +1,2242 @@ +/* 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_hof.h" +#include "kyra/screen.h" +#include "kyra/resource.h" +#include "kyra/wsamovie.h" +#include "kyra/sound.h" +#include "kyra/script.h" +#include "kyra/script_tim.h" +#include "kyra/text_hof.h" +#include "kyra/timer.h" +#include "kyra/debugger.h" + +#include "common/system.h" +#include "common/config-manager.h" + +namespace Kyra { + +KyraEngine_HoF::KyraEngine_HoF(OSystem *system, const GameFlags &flags) : KyraEngine_v2(system, flags), _updateFunctor(this, &KyraEngine_HoF::update) { + _mouseSHPBuf = 0; + _debugger = 0; + _screen = 0; + _text = 0; + + _seqProcessedString = 0; + _activeWSA = 0; + _activeText = 0; + _seqWsa = 0; + _sequences = 0; + _sequenceSoundList = 0; + + _showCredits = false; + + _gamePlayBuffer = 0; + _cCodeBuffer = _optionsBuffer = _chapterBuffer = 0; + + _overwriteSceneFacing = false; + _mainCharX = _mainCharY = -1; + _drawNoShapeFlag = false; + _charPalEntry = 0; + _itemInHand = -1; + _unkSceneScreenFlag1 = false; + _noScriptEnter = true; + _currentChapter = 0; + _newChapterFile = 1; + _oldTalkFile = -1; + _currentTalkFile = 0; + _lastSfxTrack = -1; + _handItemSet = -1; + memset(_animObjects, 0, sizeof(_animObjects)); + _unkHandleSceneChangeFlag = false; + _pathfinderFlag = 0; + _mouseX = _mouseY = 0; + _newShapeCount = 0; + _newShapeFiledata = 0; + + _vocHigh = -1; + _chatVocHigh = -1; + _chatVocLow = -1; + _chatText = 0; + _chatObject = -1; + _lastIdleScript = -1; + + _currentTalkSections.STATim = 0; + _currentTalkSections.TLKTim = 0; + _currentTalkSections.ENDTim = 0; + + memset(&_invWsa, 0, sizeof(_invWsa)); + _itemAnimData = 0; + _demoAnimData = 0; + _nextAnimItem = 0; + + for (int i = 0; i < 15; i++) + memset(&_activeItemAnim[i], 0, sizeof(ActiveItemAnim)); + + _colorCodeFlag1 = 0; + _colorCodeFlag2 = -1; + _scriptCountDown = 0; + _dbgPass = 0; + + _gamePlayBuffer = 0; + _unkBuf500Bytes = 0; + _screenBuffer = 0; + _inventorySaved = false; + _unkBuf200kByte = 0; + memset(&_sceneShapeTable, 0, sizeof(_sceneShapeTable)); + memset(&_sceneScriptData, 0, sizeof(_sceneScriptData)); + + _talkObjectList = 0; + _shapeDescTable = 0; + _gfxBackUpRect = 0; + _sceneList = 0; + memset(&_sceneAnimMovie, 0, sizeof(_sceneAnimMovie)); + memset(&_wsaSlots, 0, sizeof(_wsaSlots)); + memset(&_buttonShapes, 0, sizeof(_buttonShapes)); + + _configTextspeed = 50; + + _inventoryButtons = _buttonList = 0; + + _dlgBuffer = 0; + _conversationState = new int8*[19]; + for (int i = 0; i < 19; i++) + _conversationState[i] = new int8[14]; + _npcTalkChpIndex = _npcTalkDlgIndex = -1; + _mainCharacter.dlgIndex = 0; + setNewDlgIndex(-1); + + _deathHandler = -1; + + _bookMaxPage = 6; + _bookCurPage = 0; + _bookNewPage = 0; + _bookBkgd = 0; + + _cauldronState = 0; + _cauldronUseCount = 0; + memset(_cauldronStateTables, 0, sizeof(_cauldronStateTables)); + + _menuDirectlyToLoad = false; + _menu = 0; +} + +KyraEngine_HoF::~KyraEngine_HoF() { + cleanup(); + seq_uninit(); + + delete [] _mouseSHPBuf; + delete _screen; + delete _text; + delete _gui; + delete _tim; + _text = 0; + delete _debugger; + delete _invWsa.wsa; + + if (_sequenceSoundList) { + for (int i = 0; i < _sequenceSoundListSize; i++) { + if (_sequenceSoundList[i]) + delete [] _sequenceSoundList[i]; + } + delete [] _sequenceSoundList; + _sequenceSoundList = NULL; + } + + if (_dlgBuffer) + delete [] _dlgBuffer; + for (int i = 0; i < 19; i++) + delete [] _conversationState[i]; + delete [] _conversationState; + + for (Common::Array::iterator i = _opcodesTemporary.begin(); i != _opcodesTemporary.end(); ++i) + delete *i; + _opcodesTemporary.clear(); + + for (Common::Array::iterator i = _timOpcodes.begin(); i != _timOpcodes.end(); ++i) + delete *i; + _timOpcodes.clear(); +} + +int KyraEngine_HoF::init() { + _screen = new Screen_HoF(this, _system); + assert(_screen); + _screen->setResolution(); + + KyraEngine::init(); + initStaticResource(); + + _debugger = new Debugger_v2(this); + assert(_debugger); + _text = new TextDisplayer_v2(this, _screen); + assert(_text); + _gui = new GUI_v2(this); + assert(_gui); + _tim = new TIMInterpreter(this, _system); + assert(_tim); + + if (_flags.isDemo && !_flags.isTalkie) { + _screen->loadFont(_screen->FID_8_FNT, "FONT9P.FNT"); + } else { + _screen->loadFont(_screen->FID_6_FNT, "6.FNT"); + _screen->loadFont(_screen->FID_8_FNT, "8FAT.FNT"); + _screen->loadFont(_screen->FID_BOOKFONT_FNT, "BOOKFONT.FNT"); + } + _screen->loadFont(_screen->FID_GOLDFONT_FNT, "GOLDFONT.FNT"); + + _screen->setAnimBlockPtr(3504); + _screen->setScreenDim(0); + + if (!_sound->init()) + error("Couldn't init sound"); + + _abortIntroFlag = false; + + if (_sequenceStrings) { + for (int i = 0; i < 33; i++) + _sequenceStringsDuration[i] = (int) strlen(_sequenceStrings[i]) * 8; + } + + // No mouse display in demo + if (_flags.isDemo && !_flags.isTalkie) + return 0; + + _mouseSHPBuf = _res->fileData("PWGMOUSE.SHP", 0); + assert(_mouseSHPBuf); + + for (int i = 0; i < 2; i++) + addShapeToPool(_screen->getPtrToShape(_mouseSHPBuf, i), i); + + _screen->setMouseCursor(0, 0, getShapePtr(0)); + return 0; +} + +int KyraEngine_HoF::go() { + if (_gameToLoad == -1) { + if (_flags.platform == Common::kPlatformFMTowns || _flags.platform == Common::kPlatformPC98) + seq_showStarcraftLogo(); + + if (_flags.isDemo && !_flags.isTalkie) { + seq_playSequences(kSequenceDemoVirgin, kSequenceDemoFisher); + _menuChoice = 4; + } else { + seq_playSequences(kSequenceVirgin, kSequenceZanfaun); + } + } else { + _menuChoice = 1; + } + + _res->unloadAllPakFiles(); + + if (_menuChoice != 4) { + // load just the pak files needed for ingame + _res->loadPakFile(StaticResource::staticDataFilename()); + if (_flags.platform == Common::kPlatformPC && _flags.isTalkie) + _res->loadFileList("FILEDATA.FDT"); + else + _res->loadFileList(_ingamePakList, _ingamePakListSize); + } + + _menuDirectlyToLoad = (_menuChoice == 3) ? true : false; + + if (_menuChoice & 1) { + startup(); + if (!quit()) + runLoop(); + cleanup(); + + if (_showCredits) + seq_playSequences(kSequenceFunters, kSequenceFrash); + } + + return 0; +} + +void KyraEngine_HoF::startup() { + _sound->setSoundList(&_soundData[kMusicIngame]); + // The track map is exactly the same + // for FM-TOWNS and DOS + _trackMap = _dosTrackMap; + _trackMapSize = _dosTrackMapSize; + + _screen->_curPage = 0; + delete [] _mouseSHPBuf; + _mouseSHPBuf = 0; + + memset(_sceneShapeTable, 0, sizeof(_sceneShapeTable)); + _gamePlayBuffer = new uint8[46080]; + _unkBuf500Bytes = new uint8[500]; + + loadMouseShapes(); + loadItemShapes(); + + _screen->setMouseCursor(0, 0, getShapePtr(0)); + + _screenBuffer = new uint8[64000]; + _unkBuf200kByte = new uint8[200000]; + + loadChapterBuffer(_newChapterFile); + + loadCCodeBuffer("C_CODE.XXX"); + + if (_flags.isTalkie) { + loadOptionsBuffer("OPTIONS.XXX"); + + showMessageFromCCode(265, 150, 0); + _screen->updateScreen(); + openTalkFile(0); + _currentTalkFile = 1; + openTalkFile(1); + } else { + _optionsBuffer = _cCodeBuffer; + } + + showMessage(0, 207); + + _screen->setShapePages(5, 3); + + memset(&_mainCharacter, 0, sizeof(_mainCharacter)); + _mainCharacter.height = 0x30; + _mainCharacter.facing = 4; + _mainCharacter.animFrame = 0x12; + memset(_mainCharacter.inventory, -1, sizeof(_mainCharacter.inventory)); + + memset(_sceneAnims, 0, sizeof(_sceneAnims)); + for (int i = 0; i < ARRAYSIZE(_sceneAnimMovie); ++i) + _sceneAnimMovie[i] = new WSAMovieV2(this, _screen); + memset(_wsaSlots, 0, sizeof(_wsaSlots)); + for (int i = 0; i < ARRAYSIZE(_wsaSlots); ++i) + _wsaSlots[i] = new WSAMovieV2(this, _screen); + + _screen->_curPage = 0; + + _talkObjectList = new TalkObject[72]; + memset(_talkObjectList, 0, sizeof(TalkObject)*72); + _shapeDescTable = new ShapeDesc[55]; + memset(_shapeDescTable, 0, sizeof(ShapeDesc)*55); + + for (int i = 9; i <= 32; ++i) { + _shapeDescTable[i-9].width = 30; + _shapeDescTable[i-9].height = 55; + _shapeDescTable[i-9].xAdd = -15; + _shapeDescTable[i-9].yAdd = -50; + } + + for (int i = 19; i <= 24; ++i) { + _shapeDescTable[i-9].width = 53; + _shapeDescTable[i-9].yAdd = -51; + } + + _gfxBackUpRect = new uint8[_screen->getRectSize(32, 32)]; + _itemList = new Item[30]; + memset(_itemList, 0, sizeof(Item)*30); + loadButtonShapes(); + resetItemList(); + _loadedZTable = 1; + loadZShapes(_loadedZTable); + initInventoryButtonList(); + setupLangButtonShapes(); + loadInventoryShapes(); + + _res->loadFileToBuf("PALETTE.COL", _screen->_currentPalette, 0x300); + _screen->loadBitmap("_PLAYFLD.CPS", 3, 3, 0); + _screen->copyPage(3, 0); + _screen->showMouse(); + _screen->hideMouse(); + + clearAnimObjects(); + + for (int i = 0; i < 19; ++i) + memset(_conversationState[i], -1, sizeof(int8)*14); + clearCauldronTable(); + memset(_inputColorCode, -1, sizeof(_inputColorCode)); + memset(_newSceneDlgState, 0, sizeof(_newSceneDlgState)); + memset(_hiddenItems, -1, sizeof(_hiddenItems)); + for (int i = 0; i < 23; ++i) + resetCauldronStateTable(i); + + _sceneList = new SceneDesc[86]; + memset(_sceneList, 0, sizeof(SceneDesc)*86); + _sceneListSize = 86; + runStartScript(1, 0); + loadNPCScript(); + + if (_gameToLoad == -1) { + snd_playWanderScoreViaMap(52, 1); + enterNewScene(_mainCharacter.sceneId, _mainCharacter.facing, 0, 0, 1); + saveGame(getSavegameFilename(0), "New Game"); + } else { + loadGame(getSavegameFilename(_gameToLoad)); + } + + _screen->showMouse(); + + if (_menuDirectlyToLoad) + (*_inventoryButtons[0].buttonCallback)(&_inventoryButtons[0]); + + setNextIdleAnimTimer(); + //XXX + setWalkspeed(_configWalkspeed); +} + +void KyraEngine_HoF::runLoop() { + _screen->updateScreen(); + + _quitFlag = false; + _runFlag = true; + while (!_quitFlag && _runFlag) { + if (_deathHandler >= 0) { + removeHandItem(); + delay(5); + _drawNoShapeFlag = 0; + _gui->optionsButton(0); + _deathHandler = -1; + } + + if (_system->getMillis() > _nextIdleAnim) + showIdleAnim(); + + if (queryGameFlag(0x159)) { + dinoRide(); + resetGameFlag(0x159); + } + + if (queryGameFlag(0x124) && !queryGameFlag(0x125)) { + _mainCharacter.animFrame = 32; + enterNewScene(39, -1, 0, 0, 0); + } + + if (queryGameFlag(0xD8)) { + resetGameFlag(0xD8); + if (_mainCharacter.sceneId == 34) { + if (queryGameFlag(0xD1)) { + initTalkObject(28); + npcChatSequence(getTableString(0xFA, _cCodeBuffer, 1), 28, 0x83, 0xFA); + deinitTalkObject(28); + enterNewScene(35, 4, 0, 0, 0); + } else if (queryGameFlag(0xD0)) { + initTalkObject(29); + npcChatSequence(getTableString(0xFB, _cCodeBuffer, 1), 29, 0x83, 0xFB); + deinitTalkObject(29); + enterNewScene(33, 6, 0, 0, 0); + } + } + } + + int inputFlag = checkInput(_buttonList, true); + removeInputTop(); + + update(); + + if (inputFlag == 198 || inputFlag == 199) { + _unk3 = _handItemSet; + handleInput(_mouseX, _mouseY); + } + + //if (queryGameFlag(0x1EE) && inputFlag) + // sub_13B19(inputFlag); + + _system->delayMillis(10); + } +} + +void KyraEngine_HoF::handleInput(int x, int y) { + setNextIdleAnimTimer(); + if (_unk5) { + _unk5 = 0; + return; + } + + if (!_screen->isMouseVisible()) + return; + + if (_unk3 == -2) { + snd_playSoundEffect(13); + return; + } + + setNextIdleAnimTimer(); + + if (x <= 6 || x >= 312 || y <= 6 || y >= 135) { + bool exitOk = false; + assert(_unk3 + 6 >= 0); + switch (_unk3 + 6) { + case 0: + if (_sceneExit1 != 0xFFFF) + exitOk = true; + break; + + case 1: + if (_sceneExit2 != 0xFFFF) + exitOk = true; + break; + + case 2: + if (_sceneExit3 != 0xFFFF) + exitOk = true; + break; + + case 3: + if (_sceneExit4 != 0xFFFF) + exitOk = true; + break; + + default: + break; + } + + if (exitOk) { + inputSceneChange(x, y, 1, 1); + return; + } + } + + if (checkCharCollision(x, y) >= 0 && _unk3 >= -1) { + runSceneScript2(); + return; + } else if (pickUpItem(x, y)) { + return; + } else { + int skipHandling = 0; + + if (checkItemCollision(x, y) == -1) { + resetGameFlag(0x1EF); + skipHandling = handleInputUnkSub(x, y) ? 1 : 0; + + if (queryGameFlag(0x1EF)) { + resetGameFlag(0x1EF); + return; + } + + if (_unk5) { + _unk5 = 0; + return; + } + } + + if (_deathHandler > -1) + skipHandling = 1; + + if (skipHandling) + return; + + if (checkCharCollision(x, y) >= 0) { + runSceneScript2(); + return; + } + + if (_itemInHand >= 0) { + if (y > 136) + return; + + dropItem(0, _itemInHand, x, y, 1); + } else { + if (_unk3 == -2 || y > 135) + return; + + if (!_unk5) { + inputSceneChange(x, y, 1, 1); + return; + } + + _unk5 = 0; + } + } +} + +bool KyraEngine_HoF::handleInputUnkSub(int x, int y) { + if (y > 143 || _deathHandler > -1 || queryGameFlag(0x164)) + return false; + + if (_handItemSet <= -3 && findItem(_mainCharacter.sceneId, 13) >= 0) { + updateCharFacing(); + objectChat(getTableString(0xFC, _cCodeBuffer, 1), 0, 0x83, 0xFC); + return true; + } else { + _emc->init(&_sceneScriptState, &_sceneScriptData); + + _sceneScriptState.regs[1] = x; + _sceneScriptState.regs[2] = y; + _sceneScriptState.regs[3] = 0; + _sceneScriptState.regs[4] = _itemInHand; + + _emc->start(&_sceneScriptState, 1); + + while (_emc->isValid(&_sceneScriptState)) + _emc->run(&_sceneScriptState); + + //XXXsys_unkKeyboad (flush? wait? whatever...) + + if (queryGameFlag(0x1ED)) { + _sound->beginFadeOut(); + _screen->fadeToBlack(); + _showCredits = true; + _runFlag = false; + } + + return _sceneScriptState.regs[3] != 0; + } +} + +void KyraEngine_HoF::update() { + updateInput(); + + refreshAnimObjectsIfNeed(); + updateMouse(); + updateSpecialSceneScripts(); + _timer->update(); + updateItemAnimations(); + updateInvWsa(); + fadeMessagePalette(); + _screen->updateScreen(); +} + +void KyraEngine_HoF::updateWithText() { + updateInput(); + + updateMouse(); + fadeMessagePalette(); + updateSpecialSceneScripts(); + _timer->update(); + updateItemAnimations(); + updateInvWsa(); + restorePage3(); + drawAnimObjects(); + + if (textEnabled() && _chatText) { + int pageBackUp = _screen->_curPage; + _screen->_curPage = 2; + objectChatPrintText(_chatText, _chatObject); + _screen->_curPage = pageBackUp; + } + + refreshAnimObjects(0); + _screen->updateScreen(); +} + +void KyraEngine_HoF::updateMouse() { + int shapeIndex = 0; + int type = 0; + int xOffset = 0, yOffset = 0; + Common::Point mouse = getMousePos(); + + if (mouse.y <= 145) { + if (mouse.x <= 6) { + if (_sceneExit4 != 0xFFFF) { + type = -3; + shapeIndex = 4; + xOffset = 1; + yOffset = 5; + } else { + type = -2; + } + } else if (mouse.x >= 312) { + if (_sceneExit2 != 0xFFFF) { + type = -5; + shapeIndex = 2; + xOffset = 7; + yOffset = 5; + } else { + type = -2; + } + } else if (mouse.y >= 135) { + if (_sceneExit3 != 0xFFFF) { + type = -4; + shapeIndex = 3; + xOffset = 5; + yOffset = 10; + } else { + type = -2; + } + } else if (mouse.y <= 6) { + if (_sceneExit1 != 0xFFFF) { + type = -6; + shapeIndex = 1; + xOffset = 5; + yOffset = 1; + } else { + type = -2; + } + } + } + + for (int i = 0; i < _specialExitCount; ++i) { + if (checkSpecialSceneExit(i, mouse.x, mouse.y)) { + switch (_specialExitTable[20+i]) { + case 0: + type = -6; + shapeIndex = 1; + xOffset = 5; + yOffset = 1; + break; + + case 2: + type = -5; + shapeIndex = 2; + xOffset = 7; + yOffset = 5; + break; + + case 4: + type = -4; + shapeIndex = 3; + xOffset = 5; + yOffset = 7; + break; + + case 6: + type = -3; + shapeIndex = 4; + xOffset = 1; + yOffset = 5; + break; + + default: + break; + } + } + } + + if (type == -2) { + shapeIndex = 5; + xOffset = 5; + yOffset = 9; + } + + if (type != 0 && _handItemSet != type && _screen->isMouseVisible()) { + _mouseState = _handItemSet = type; + _screen->hideMouse(); + _screen->setMouseCursor(xOffset, yOffset, getShapePtr(shapeIndex)); + _screen->showMouse(); + } + + if (type == 0 && _handItemSet != _itemInHand && _screen->isMouseVisible()) { + if ((mouse.y > 145) || (mouse.x > 6 && mouse.x < 312 && mouse.y > 6 && mouse.y < 135)) { + _mouseState = 0; + _handItemSet = _itemInHand; + _screen->hideMouse(); + if (_itemInHand == -1) + _screen->setMouseCursor(0, 0, getShapePtr(0)); + else + _screen->setMouseCursor(8, 15, getShapePtr(_itemInHand+64)); + _screen->showMouse(); + } + } +} + +int KyraEngine_HoF::checkInput(Button *buttonList, bool mainLoop) { + updateInput(); + + int keys = 0; + + while (_eventList.size()) { + Common::Event event = *_eventList.begin(); + bool breakLoop = false; + + 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) && mainLoop) { + const char *saveLoadSlot = getSavegameFilename(9 - (event.kbd.keycode - '0') + 990); + + if (event.kbd.flags == Common::KBD_CTRL) { + loadGame(saveLoadSlot); + _eventList.clear(); + breakLoop = true; + } 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(); + } + break; + + case Common::EVENT_MOUSEMOVE: { + Common::Point pos = getMousePos(); + _mouseX = pos.x; + _mouseY = pos.y; + _screen->updateScreen(); + } break; + + case Common::EVENT_LBUTTONDOWN: + case Common::EVENT_LBUTTONUP: { + Common::Point pos = getMousePos(); + _mouseX = pos.x; + _mouseY = pos.y; + keys = event.type == Common::EVENT_LBUTTONDOWN ? 199 : (200 | 0x800); + breakLoop = true; + } break; + + default: + break; + } + + if (_debugger->isAttached()) + _debugger->onFrame(); + + if (breakLoop) + break; + + _eventList.erase(_eventList.begin()); + } + + return _gui->processButtonList(buttonList, keys | 0x8000); +} + +void KyraEngine_HoF::delay(uint32 amount, bool updateGame, bool isMainLoop) { + uint32 start = _system->getMillis(); + do { + if (updateGame) { + if (_chatText) + updateWithText(); + else + update(); + } else { + updateInput(); + } + + if (amount > 0) + _system->delayMillis(amount > 10 ? 10 : amount); + } while (!skipFlag() && _system->getMillis() < start + amount && !_quitFlag); +} + +void KyraEngine_HoF::cleanup() { + delete [] _inventoryButtons; _inventoryButtons = 0; + + delete [] _gamePlayBuffer; _gamePlayBuffer = 0; + delete [] _unkBuf500Bytes; _unkBuf500Bytes = 0; + delete [] _screenBuffer; _screenBuffer = 0; + delete [] _unkBuf200kByte; _unkBuf200kByte = 0; + + resetNewShapes(_newShapeCount, _newShapeFiledata); + _newShapeFiledata = 0; + _newShapeCount = 0; + + freeSceneShapePtrs(); + + if (_optionsBuffer != _cCodeBuffer) + delete [] _optionsBuffer; + _optionsBuffer = 0; + delete [] _cCodeBuffer; _cCodeBuffer = 0; + delete [] _chapterBuffer; _chapterBuffer = 0; + + delete [] _talkObjectList; _talkObjectList = 0; + delete [] _shapeDescTable; _shapeDescTable = 0; + + delete [] _gfxBackUpRect; _gfxBackUpRect = 0; + + delete [] _sceneList; _sceneList = 0; + + for (int i = 0; i < ARRAYSIZE(_sceneAnimMovie); ++i) { + delete _sceneAnimMovie[i]; + _sceneAnimMovie[i] = 0; + } + for (int i = 0; i < ARRAYSIZE(_wsaSlots); ++i) { + delete _wsaSlots[i]; + _wsaSlots[i] = 0; + } + for (int i = 0; i < ARRAYSIZE(_buttonShapes); ++i) { + delete [] _buttonShapes[i]; + _buttonShapes[i] = 0; + } +} + +#pragma mark - Localization + +void KyraEngine_HoF::loadCCodeBuffer(const char *file) { + char tempString[13]; + strcpy(tempString, file); + changeFileExtension(tempString); + + delete [] _cCodeBuffer; + _cCodeBuffer = _res->fileData(tempString, 0); +} + +void KyraEngine_HoF::loadOptionsBuffer(const char *file) { + char tempString[13]; + strcpy(tempString, file); + changeFileExtension(tempString); + + delete [] _optionsBuffer; + _optionsBuffer = _res->fileData(tempString, 0); +} + +void KyraEngine_HoF::loadChapterBuffer(int chapter) { + char tempString[14]; + + static const char *chapterFilenames[] = { + "CH1.XXX", "CH2.XXX", "CH3.XXX", "CH4.XXX", "CH5.XXX" + }; + + assert(chapter >= 1 && chapter <= ARRAYSIZE(chapterFilenames)); + strcpy(tempString, chapterFilenames[chapter-1]); + changeFileExtension(tempString); + + delete [] _chapterBuffer; + _chapterBuffer = _res->fileData(tempString, 0); + _currentChapter = chapter; +} + +void KyraEngine_HoF::changeFileExtension(char *buffer) { + while (*buffer != '.') + ++buffer; + + ++buffer; + strcpy(buffer, _languageExtension[_lang]); +} + +uint8 *KyraEngine_HoF::getTableEntry(uint8 *buffer, int id) { + return buffer + READ_LE_UINT16(buffer + (id<<1)); +} + +char *KyraEngine_HoF::getTableString(int id, uint8 *buffer, int decode) { + char *string = (char*)getTableEntry(buffer, id); + + if (decode && _flags.lang != Common::JA_JPN) { + decodeString1(string, _internStringBuf); + decodeString2(_internStringBuf, _internStringBuf); + string = _internStringBuf; + } + + return string; +} + +const char *KyraEngine_HoF::getChapterString(int id) { + if (_currentChapter != _newChapterFile) + loadChapterBuffer(_newChapterFile); + + return getTableString(id, _chapterBuffer, 1); +} + +int KyraEngine_HoF::decodeString1(const char *src, char *dst) { + static const uint8 decodeTable1[] = { + 0x20, 0x65, 0x74, 0x61, 0x69, 0x6E, 0x6F, 0x73, 0x72, 0x6C, 0x68, + 0x63, 0x64, 0x75, 0x70, 0x6D + }; + + static const uint8 decodeTable2[] = { + 0x74, 0x61, 0x73, 0x69, 0x6F, 0x20, 0x77, 0x62, 0x20, 0x72, 0x6E, + 0x73, 0x64, 0x61, 0x6C, 0x6D, 0x68, 0x20, 0x69, 0x65, 0x6F, 0x72, + 0x61, 0x73, 0x6E, 0x72, 0x74, 0x6C, 0x63, 0x20, 0x73, 0x79, 0x6E, + 0x73, 0x74, 0x63, 0x6C, 0x6F, 0x65, 0x72, 0x20, 0x64, 0x74, 0x67, + 0x65, 0x73, 0x69, 0x6F, 0x6E, 0x72, 0x20, 0x75, 0x66, 0x6D, 0x73, + 0x77, 0x20, 0x74, 0x65, 0x70, 0x2E, 0x69, 0x63, 0x61, 0x65, 0x20, + 0x6F, 0x69, 0x61, 0x64, 0x75, 0x72, 0x20, 0x6C, 0x61, 0x65, 0x69, + 0x79, 0x6F, 0x64, 0x65, 0x69, 0x61, 0x20, 0x6F, 0x74, 0x72, 0x75, + 0x65, 0x74, 0x6F, 0x61, 0x6B, 0x68, 0x6C, 0x72, 0x20, 0x65, 0x69, + 0x75, 0x2C, 0x2E, 0x6F, 0x61, 0x6E, 0x73, 0x72, 0x63, 0x74, 0x6C, + 0x61, 0x69, 0x6C, 0x65, 0x6F, 0x69, 0x72, 0x61, 0x74, 0x70, 0x65, + 0x61, 0x6F, 0x69, 0x70, 0x20, 0x62, 0x6D + }; + + int size = 0; + uint cChar = 0; + while ((cChar = *src++) != 0) { + if (cChar & 0x80) { + cChar &= 0x7F; + int index = (cChar & 0x78) >> 3; + *dst++ = decodeTable1[index]; + ++size; + assert(cChar < sizeof(decodeTable2)); + cChar = decodeTable2[cChar]; + } + + *dst++ = cChar; + ++size; + } + + *dst++ = 0; + return size; +} + +void KyraEngine_HoF::decodeString2(const char *src, char *dst) { + if (!src || !dst) + return; + + char out = 0; + while ((out = *src) != 0) { + if (*src == 0x1B) { + ++src; + out = *src + 0x7F; + } + *dst++ = out; + ++src; + } + + *dst = 0; +} + +#pragma mark - + +void KyraEngine_HoF::showMessageFromCCode(int id, int16 palIndex, int) { + const char *string = getTableString(id, _cCodeBuffer, 1); + showMessage(string, palIndex); +} + +void KyraEngine_HoF::showMessage(const char *string, int16 palIndex) { + _shownMessage = string; + _screen->hideMouse(); + _screen->fillRect(0, 190, 319, 199, 0xCF); + + if (string) { + if (palIndex != -1 || _fadeMessagePalette) { + palIndex *= 3; + memcpy(_messagePal, _screen->_currentPalette + palIndex, 3); + memmove(_screen->_currentPalette + 765, _screen->_currentPalette + palIndex, 3); + _screen->setScreenPalette(_screen->_currentPalette); + } + + int x = _text->getCenterStringX(string, 0, 320); + _text->printText(string, x, 190, 255, 207, 0); + + setTimer1DelaySecs(7); + } + + _fadeMessagePalette = false; + _screen->showMouse(); +} + +void KyraEngine_HoF::showChapterMessage(int id, int16 palIndex) { + showMessage(getChapterString(id), palIndex); +} + +void KyraEngine_HoF::updateCommandLineEx(int str1, int str2, int16 palIndex) { + char buffer[0x51]; + char *src = buffer; + + strcpy(src, getTableString(str1, _cCodeBuffer, 1)); + + if (_flags.lang != Common::JA_JPN) { + while (*src != 0x20) + ++src; + ++src; + *src = toupper(*src); + } + + strcpy((char*)_unkBuf500Bytes, src); + + if (str2 > 0) { + if (_flags.lang != Common::JA_JPN) + strcat((char*)_unkBuf500Bytes, " "); + strcat((char*)_unkBuf500Bytes, getTableString(str2, _cCodeBuffer, 1)); + } + + showMessage((char*)_unkBuf500Bytes, palIndex); +} + +void KyraEngine_HoF::fadeMessagePalette() { + if (!_fadeMessagePalette) + return; + + bool updatePalette = false; + for (int i = 0; i < 3; ++i) { + if (_messagePal[i] >= 4) { + _messagePal[i] -= 4; + updatePalette = true; + } else if (_messagePal[i] != 0) { + _messagePal[i] = 0; + updatePalette = true; + } + } + + if (updatePalette) { + memcpy(_screen->getPalette(0) + 765, _messagePal, 3); + _screen->setScreenPalette(_screen->getPalette(0)); + } else { + _fadeMessagePalette = false; + } +} + +#pragma mark - + +void KyraEngine_HoF::loadMouseShapes() { + _screen->loadBitmap("_MOUSE.CSH", 3, 3, 0); + + for (int i = 0; i <= 8; ++i) + addShapeToPool(_screen->makeShapeCopy(_screen->getCPagePtr(3), i), i); +} + +void KyraEngine_HoF::loadItemShapes() { + _screen->loadBitmap("_ITEMS.CSH", 3, 3, 0); + + for (int i = 64; i <= 239; ++i) + addShapeToPool(_screen->getCPagePtr(3), i, i-64); + + _res->loadFileToBuf("_ITEMHT.DAT", _itemHtDat, sizeof(_itemHtDat)); + assert(_res->getFileSize("_ITEMHT.DAT") == sizeof(_itemHtDat)); + + _screen->_curPage = 0; +} + +void KyraEngine_HoF::loadZShapes(int shapes) { + char file[10]; + strcpy(file, "_ZX.SHP"); + + _loadedZTable = shapes; + file[2] = '0' + shapes; + + uint8 *data = _res->fileData(file, 0); + for (int i = 9; i <= 32; ++i) + addShapeToPool(data, i, i-9); + delete [] data; + + _loadedZTable = shapes; +} + +void KyraEngine_HoF::loadInventoryShapes() { + int curPageBackUp = _screen->_curPage; + _screen->_curPage = 2; + + _screen->loadBitmap("_PLAYALL.CPS", 3, 3, 0); + + for (int i = 0; i < 10; ++i) + addShapeToPool(_screen->encodeShape(_inventoryX[i], _inventoryY[i], 16, 16, 0), 240+i); + + _screen->_curPage = curPageBackUp; +} + +void KyraEngine_HoF::runStartScript(int script, int unk1) { + char filename[14]; + strcpy(filename, "_START0X.EMC"); + filename[7] = script + '0'; + + EMCData scriptData; + EMCState scriptState; + memset(&scriptData, 0, sizeof(EMCData)); + memset(&scriptState, 0, sizeof(EMCState)); + + _emc->load(filename, &scriptData, &_opcodes); + _emc->init(&scriptState, &scriptData); + scriptState.regs[6] = unk1; + _emc->start(&scriptState, 0); + while (_emc->isValid(&scriptState)) + _emc->run(&scriptState); + _emc->unload(&scriptData); +} + +void KyraEngine_HoF::loadNPCScript() { + char filename[12]; + strcpy(filename, "_NPC.EMC"); + + if (_flags.platform != Common::kPlatformPC || _flags.isTalkie) { + switch (_lang) { + case 0: + filename[5] = 'E'; + break; + + case 1: + filename[5] = 'F'; + break; + + case 2: + filename[5] = 'G'; + break; + + case 3: + filename[5] = 'J'; + break; + + default: + break; + }; + } + + _emc->load(filename, &_npcScriptData, &_opcodes); +} + +void KyraEngine_HoF::runTemporaryScript(const char *filename, int allowSkip, int resetChar, int newShapes, int shapeUnload) { + memset(&_temporaryScriptData, 0, sizeof(_temporaryScriptData)); + memset(&_temporaryScriptState, 0, sizeof(_temporaryScriptState)); + + if (!_emc->load(filename, &_temporaryScriptData, &_opcodesTemporary)) + error("Couldn't load temporary script '%s'", filename); + + _emc->init(&_temporaryScriptState, &_temporaryScriptData); + _emc->start(&_temporaryScriptState, 0); + + _newShapeFlag = -1; + + if (_newShapeFiledata && newShapes) { + resetNewShapes(_newShapeCount, _newShapeFiledata); + _newShapeFiledata = 0; + _newShapeCount = 0; + } + + while (_emc->isValid(&_temporaryScriptState)) + _emc->run(&_temporaryScriptState); + + uint8 *fileData = 0; + + if (newShapes) + _newShapeFiledata = _res->fileData(_newShapeFilename, 0); + + fileData = _newShapeFiledata; + + if (!fileData) { + _emc->unload(&_temporaryScriptData); + return; + } + + if (newShapes) + _newShapeCount = initNewShapes(fileData); + + processNewShapes(allowSkip, resetChar); + + if (shapeUnload) { + resetNewShapes(_newShapeCount, fileData); + _newShapeCount = 0; + _newShapeFiledata = 0; + } + + _emc->unload(&_temporaryScriptData); +} + +#pragma mark - + +void KyraEngine_HoF::resetScaleTable() { + Common::set_to(_scaleTable, _scaleTable + ARRAYSIZE(_scaleTable), 0x100); +} + +void KyraEngine_HoF::setScaleTableItem(int item, int data) { + if (item >= 1 || item <= 15) + _scaleTable[item-1] = (data << 8) / 100; +} + +int KyraEngine_HoF::getScale(int x, int y) { + return _scaleTable[_screen->getLayer(x, y) - 1]; +} + +void KyraEngine_HoF::setDrawLayerTableEntry(int entry, int data) { + if (entry >= 1 || entry <= 15) + _drawLayerTable[entry-1] = data; +} + +int KyraEngine_HoF::getDrawLayer(int x, int y) { + int layer = _screen->getLayer(x, y); + layer = _drawLayerTable[layer-1]; + if (layer < 0) + layer = 0; + else if (layer >= 7) + layer = 6; + return layer; +} + +void KyraEngine_HoF::backUpPage0() { + if (_screenBuffer) { + _screen->hideMouse(); + memcpy(_screenBuffer, _screen->getCPagePtr(0), 64000); + _screen->showMouse(); + } +} + +void KyraEngine_HoF::restorePage0() { + restorePage3(); + if (_screenBuffer) + _screen->copyBlockToPage(0, 0, 0, 320, 200, _screenBuffer); +} + +void KyraEngine_HoF::updateCharPal(int unk1) { + static bool unkVar1 = false; + + if (!_useCharPal) + return; + + int layer = _screen->getLayer(_mainCharacter.x1, _mainCharacter.y1); + int palEntry = _charPalTable[layer]; + + if (palEntry != _charPalEntry && unk1) { + const uint8 *src = &_scenePal[(palEntry << 4) * 3]; + uint8 *ptr = _screen->getPalette(0) + 336; + for (int i = 0; i < 48; ++i) { + *ptr -= (*ptr - *src) >> 1; + ++ptr; + ++src; + } + _screen->setScreenPalette(_screen->getPalette(0)); + unkVar1 = true; + _charPalEntry = palEntry; + } else if (unkVar1 || !unk1) { + memcpy(_screen->getPalette(0) + 336, &_scenePal[(palEntry << 4) * 3], 48); + _screen->setScreenPalette(_screen->getPalette(0)); + unkVar1 = false; + } +} + +void KyraEngine_HoF::setCharPalEntry(int entry, int value) { + if (entry > 15 || entry < 1) + entry = 1; + if (value > 8 || value < 0) + value = 0; + _charPalTable[entry] = value; + _useCharPal = 1; + _charPalEntry = 0; +} + +int KyraEngine_HoF::inputSceneChange(int x, int y, int unk1, int unk2) { + bool refreshNPC = false; + uint16 curScene = _mainCharacter.sceneId; + _pathfinderFlag = 15; + + if (!_unkHandleSceneChangeFlag) { + if (_unk3 == -3) { + if (_sceneList[curScene].exit4 != 0xFFFF) { + x = 4; + y = _sceneEnterY4; + _pathfinderFlag = 7; + } + } else if (_unk3 == -5) { + if (_sceneList[curScene].exit2 != 0xFFFF) { + x = 316; + y = _sceneEnterY2; + _pathfinderFlag = 7; + } + } else if (_unk3 == -6) { + if (_sceneList[curScene].exit1 != 0xFFFF) { + x = _sceneEnterX1; + y = _sceneEnterY1 - 2; + _pathfinderFlag = 14; + } + } else if (_unk3 == -4) { + if (_sceneList[curScene].exit3 != 0xFFFF) { + x = _sceneEnterX3; + y = 147; + _pathfinderFlag = 11; + } + } + } + + int strId = 0; + int vocH = _flags.isTalkie ? 131 : -1; + + if (_pathfinderFlag) { + if (findItem(curScene, 13) >= 0 && _unk3 <= -3) { + strId = 252; + } else if (_itemInHand == 72) { + strId = 257; + } else if (findItem(curScene, 72) >= 0 && _unk3 <= -3) { + strId = 256; + } else if (getInventoryItemSlot(72) != -1 && _unk3 <= -3) { + strId = 257; + } + } + + if (strId) { + updateCharFacing(); + objectChat(getTableString(strId, _cCodeBuffer, 1), 0, vocH, strId); + _pathfinderFlag = 0; + return 0; + } + + if (ABS(_mainCharacter.x1 - x) < 4 && ABS(_mainCharacter.y1 - y) < 2) { + _pathfinderFlag = 0; + return 0; + } + + int curX = _mainCharacter.x1 & ~3; + int curY = _mainCharacter.y1 & ~1; + int dstX = x & ~3; + int dstY = y & ~1; + + int wayLength = findWay(curX, curY, dstX, dstY, _movFacingTable, 600); + _pathfinderFlag = 0; + _timer->disable(5); + + if (wayLength != 0 && wayLength != 0x7D00) + refreshNPC = (trySceneChange(_movFacingTable, unk1, unk2) != 0); + + int charLayer = _screen->getLayer(_mainCharacter.x1, _mainCharacter.y1); + if (_layerFlagTable[charLayer] != 0 && !queryGameFlag(0x163)) { + if (queryGameFlag(0x164)) { + _screen->hideMouse(); + _timer->disable(5); + runTemporaryScript("_ZANBURN.EMC", 0, 1, 1, 0); + _deathHandler = 7; + snd_playWanderScoreViaMap(0x53, 1); + } else { + objectChat(getTableString(0xFD, _cCodeBuffer, 1), 0, 0x83, 0xFD); + setGameFlag(0x164); + _timer->enable(5); + _timer->setCountdown(5, 120); + } + } else if (queryGameFlag(0x164)) { + objectChat(getTableString(0xFE, _cCodeBuffer, 1), 0, 0x83, 0xFE); + resetGameFlag(0x164); + _timer->disable(5); + } + + if (refreshNPC) + enterNewSceneUnk2(0); + + _pathfinderFlag = 0; + return refreshNPC; +} + +void KyraEngine_HoF::moveCharacter(int facing, int x, int y) { + _mainCharacter.facing = facing; + x &= ~3; + y &= ~1; + + _screen->hideMouse(); + switch (facing) { + case 0: + while (y < _mainCharacter.y1) + updateCharPosWithUpdate(); + break; + + case 2: + while (_mainCharacter.x1 < x) + updateCharPosWithUpdate(); + break; + + case 4: + while (y > _mainCharacter.y1) + updateCharPosWithUpdate(); + break; + + case 6: + while (_mainCharacter.x1 > x) + updateCharPosWithUpdate(); + break; + + default: + break; + } + + _screen->showMouse(); +} + +int KyraEngine_HoF::updateCharPos(int *table) { + static uint32 nextUpdate = 0; + static const int updateX[] = { 0, 4, 4, 4, 0, -4, -4, -4 }; + static const int updateY[] = { -2, -2, 0, 2, 2, 2, 0, -2 }; + + if (_system->getMillis() < nextUpdate) + return 0; + + int facing = _mainCharacter.facing; + _mainCharacter.x1 += updateX[facing]; + _mainCharacter.y1 += updateY[facing]; + updateCharAnimFrame(0, table); + nextUpdate = _system->getMillis() + _timer->getDelay(0) * _tickLength; + return 1; +} + +void KyraEngine_HoF::updateCharPosWithUpdate() { + updateCharPos(0); + update(); +} + +void KyraEngine_HoF::updateCharAnimFrame(int charId, int *table) { + static int unkTable1[] = { 0, 0 }; + static const int unkTable2[] = { 17, 0 }; + static const int unkTable3[] = { 10, 0 }; + static const int unkTable4[] = { 24, 0 }; + static const int unkTable5[] = { 19, 0 }; + static const int unkTable6[] = { 21, 0 }; + static const int unkTable7[] = { 31, 0 }; + static const int unkTable8[] = { 26, 0 }; + + Character *character = &_mainCharacter; + ++character->animFrame; + + int facing = character->facing; + + if (table) { + if (table[0] != table[-1] && table[-1] == table[1]) { + facing = getOppositeFacingDirection(table[-1]); + table[0] = table[-1]; + } + } + + if (!facing) { + ++unkTable1[charId]; + } else if (facing == 4) { + ++unkTable1[charId+1]; + } else if (facing == 7 || facing == 1 || facing == 5 || facing == 3) { + if (facing == 7 || facing == 1) { + if (unkTable1[charId] > 2) + facing = 0; + } else { + if (unkTable1[charId+1] > 2) + facing = 4; + } + + unkTable1[charId] = 0; + unkTable1[charId+1] = 0; + } + + if (facing == 0) { + if (character->animFrame < unkTable8[charId]) + character->animFrame = unkTable8[charId]; + + if (character->animFrame > unkTable7[charId]) + character->animFrame = unkTable8[charId]; + } else if (facing == 4) { + if (character->animFrame < unkTable5[charId]) + character->animFrame = unkTable5[charId]; + + if (character->animFrame > unkTable4[charId]) + character->animFrame = unkTable5[charId]; + } else { + if (character->animFrame > unkTable5[charId]) + character->animFrame = unkTable6[charId]; + + if (character->animFrame == unkTable2[charId]) + character->animFrame = unkTable3[charId]; + + if (character->animFrame > unkTable2[charId]) + character->animFrame = unkTable3[charId] + 2; + } + + updateCharacterAnim(charId); +} + +int KyraEngine_HoF::checkCharCollision(int x, int y) { + int scale1 = 0, scale2 = 0, scale3 = 0; + int x1 = 0, x2 = 0, y1 = 0, y2 = 0; + scale1 = getScale(_mainCharacter.x1, _mainCharacter.y1); + scale2 = (scale1 * 24) >> 8; + scale3 = (scale1 * 48) >> 8; + + x1 = _mainCharacter.x1 - (scale2 >> 1); + x2 = _mainCharacter.x1 + (scale2 >> 1); + y1 = _mainCharacter.y1 - scale3; + y2 = _mainCharacter.y1; + + if (x >= x1 && x <= x2 && y >= y1 && y <= y2) + return 0; + + return -1; +} + +int KyraEngine_HoF::initNewShapes(uint8 *filedata) { + const int lastEntry = MIN(_newShapeLastEntry, 31); + for (int i = 0; i < lastEntry; ++i) { + addShapeToPool(filedata, i+33, i); + ShapeDesc *desc = &_shapeDescTable[24+i]; + desc->xAdd = _newShapeXAdd; + desc->yAdd = _newShapeYAdd; + desc->width = _newShapeWidth; + desc->height = _newShapeHeight; + } + return lastEntry; +} + +void KyraEngine_HoF::processNewShapes(int allowSkip, int resetChar) { + setCharacterAnimDim(_newShapeWidth, _newShapeHeight); + + _emc->init(&_temporaryScriptState, &_temporaryScriptData); + _emc->start(&_temporaryScriptState, 1); + + resetSkipFlag(); + + while (_emc->isValid(&_temporaryScriptState)) { + _temporaryScriptExecBit = false; + while (_emc->isValid(&_temporaryScriptState) && !_temporaryScriptExecBit) + _emc->run(&_temporaryScriptState); + + if (_newShapeAnimFrame < 0) + continue; + + _mainCharacter.animFrame = _newShapeAnimFrame + 33; + updateCharacterAnim(0); + if (_chatText) + updateWithText(); + else + update(); + + uint32 delayEnd = _system->getMillis() + _newShapeDelay * _tickLength; + + while ((!skipFlag() || !allowSkip) && _system->getMillis() < delayEnd) { + if (_chatText) + updateWithText(); + else + update(); + + delay(10); + } + + if (skipFlag()) + resetSkipFlag(); + } + + if (resetChar) { + if (_newShapeFlag >= 0) { + _mainCharacter.animFrame = _newShapeFlag + 33; + updateCharacterAnim(0); + if (_chatText) + updateWithText(); + else + update(); + } + + _mainCharacter.animFrame = _characterFrameTable[_mainCharacter.facing]; + updateCharacterAnim(0); + } + + _newShapeFlag = -1; + resetCharacterAnimDim(); +} + +void KyraEngine_HoF::resetNewShapes(int count, uint8 *filedata) { + for (int i = 0; i < count; ++i) + remShapeFromPool(i+33); + delete [] filedata; + setNextIdleAnimTimer(); +} + +void KyraEngine_HoF::setNextIdleAnimTimer() { + _nextIdleAnim = _system->getMillis() + _rnd.getRandomNumberRng(10, 15) * 60 * _tickLength; +} + +void KyraEngine_HoF::showIdleAnim() { + static const uint8 scriptMinTable[] = { + 0x00, 0x05, 0x07, 0x08, 0x00, 0x09, 0x0A, 0x0B, 0xFF, 0x00 + }; + + static const uint8 scriptMaxTable[] = { + 0x04, 0x06, 0x07, 0x08, 0x04, 0x09, 0x0A, 0x0B, 0xFF, 0x00 + }; + + if (queryGameFlag(0x159) && _flags.isTalkie) + return; + + static bool scriptAnimation = false; + if (!scriptAnimation && _flags.isTalkie) { + scriptAnimation = true; + zanthRandomIdleChat(); + } else { + scriptAnimation = false; + if (_loadedZTable > 8) + return; + + int scriptMin = scriptMinTable[_loadedZTable-1]; + int scriptMax = scriptMaxTable[_loadedZTable-1]; + int script = 0; + + if (scriptMin < scriptMax) { + do { + script = _rnd.getRandomNumberRng(scriptMin, scriptMax); + } while (script == _lastIdleScript); + } else { + script = scriptMin; + } + + runIdleScript(script); + _lastIdleScript = script; + } +} + +void KyraEngine_HoF::runIdleScript(int script) { + if (script < 0 || script >= 12) + script = 0; + + if (_mainCharacter.animFrame != 18) { + setNextIdleAnimTimer(); + } else { + // FIXME: move this to staticres.cpp? + static const char *idleScriptFiles[] = { + "_IDLHAIR.EMC", "_IDLDUST.EMC", "_IDLLEAN.EMC", "_IDLDIRT.EMC", "_IDLTOSS.EMC", "_IDLNOSE.EMC", + "_IDLBRSH.EMC", "_Z3IDLE.EMC", "_Z4IDLE.EMC", "_Z6IDLE.EMC", "_Z7IDLE.EMC", "_Z8IDLE.EMC" + }; + + runTemporaryScript(idleScriptFiles[script], 1, 1, 1, 1); + } +} + +#pragma mark - + +void KyraEngine_HoF::backUpGfxRect24x24(int x, int y) { + _screen->copyRegionToBuffer(_screen->_curPage, x, y, 24, 24, _gfxBackUpRect); +} + +void KyraEngine_HoF::restoreGfxRect24x24(int x, int y) { + _screen->copyBlockToPage(_screen->_curPage, x, y, 24, 24, _gfxBackUpRect); +} + +void KyraEngine_HoF::backUpGfxRect32x32(int x, int y) { + _screen->copyRegionToBuffer(_screen->_curPage, x, y, 32, 32, _gfxBackUpRect); +} + +void KyraEngine_HoF::restoreGfxRect32x32(int x, int y) { + _screen->copyBlockToPage(_screen->_curPage, x, y, 32, 32, _gfxBackUpRect); +} + +#pragma mark - + +void KyraEngine_HoF::openTalkFile(int newFile) { + debugC(9, kDebugLevelMain | kDebugLevelSound, "KyraEngine_HoF::openTalkFile(%d)", newFile); + char talkFilename[16]; + + if (_oldTalkFile > 0) { + sprintf(talkFilename, "CH%dVOC.TLK", _oldTalkFile); + _res->unloadPakFile(talkFilename); + _oldTalkFile = -1; + } + + if (newFile == 0) { + strcpy(talkFilename, "ANYTALK.TLK"); + _res->loadPakFile(talkFilename); + } else { + sprintf(talkFilename, "CH%dVOC.TLK", newFile); + _res->loadPakFile(talkFilename); + } + + _oldTalkFile = newFile; +} + +void KyraEngine_HoF::snd_playVoiceFile(int id) { + debugC(9, kDebugLevelMain | kDebugLevelSound, "KyraEngine_HoF::snd_playVoiceFile(%d)", id); + char vocFile[9]; + assert(id >= 0 && id <= 9999999); + sprintf(vocFile, "%07d", id); + if (_sound->voiceFileIsPresent(vocFile)) { + snd_stopVoice(); + + while (!_sound->voicePlay(vocFile)) { + updateWithText(); + _system->delayMillis(10); + } + + _speechFile = vocFile; + } +} + +void KyraEngine_HoF::snd_loadSoundFile(int id) { + debugC(9, kDebugLevelMain | kDebugLevelSound, "KyraEngine_HoF::snd_loadSoundFile(%d)", id); + if (id < 0 || !_trackMap) + return; + + assert(id < _trackMapSize); + int file = _trackMap[id*2]; + _curSfxFile = _curMusicTheme = file; + _sound->loadSoundFile(file); +} + +void KyraEngine_HoF::playVoice(int high, int low) { + debugC(9, kDebugLevelMain | kDebugLevelSound, "KyraEngine_HoF::playVoice(%d, %d)", high, low); + if (!_flags.isTalkie) + return; + int vocFile = high * 10000 + low * 10; + snd_playVoiceFile(vocFile); +} + +void KyraEngine_HoF::snd_playSoundEffect(int track, int volume) { + debugC(9, kDebugLevelMain | kDebugLevelSound, "KyraEngine_HoF::snd_playSoundEffect(%d, %d)", track, volume); + + if (_flags.platform == Common::kPlatformFMTowns || _flags.platform == Common::kPlatformPC98) { + if (track == 10) + track = _lastSfxTrack; + + if (track == 10 || track == -1) + return; + + _lastSfxTrack = track; + } + + int16 vocIndex = (int16)READ_LE_UINT16(&_ingameSoundIndex[track * 2]); + if (vocIndex != -1) + _sound->voicePlay(_ingameSoundList[vocIndex], true); + else if (_flags.platform == Common::kPlatformPC) + // TODO ?? Maybe there is a way to let users select whether they want + // voc, midi or adl sfx (even though it makes no sense to choose anything but voc). + KyraEngine::snd_playSoundEffect(track); +} + +#pragma mark - + +void KyraEngine_HoF::loadInvWsa(const char *filename, int run, int delayTime, int page, int sfx, int sFrame, int flags) { + int wsaFlags = 1; + if (flags) + wsaFlags |= 2; + + if (!_invWsa.wsa) + _invWsa.wsa = new WSAMovieV2(this, _screen); + + if (!_invWsa.wsa->open(filename, wsaFlags, 0)) + error("Couldn't open inventory WSA file '%s'", filename); + + _invWsa.curFrame = 0; + _invWsa.lastFrame = _invWsa.wsa->frames(); + + _invWsa.x = _invWsa.wsa->xAdd(); + _invWsa.y = _invWsa.wsa->yAdd(); + _invWsa.w = _invWsa.wsa->width(); + _invWsa.h = _invWsa.wsa->height(); + _invWsa.x2 = _invWsa.x + _invWsa.w - 1; + _invWsa.y2 = _invWsa.y + _invWsa.h - 1; + + _invWsa.delay = delayTime; + _invWsa.page = page; + _invWsa.sfx = sfx; + + _invWsa.specialFrame = sFrame; + + if (_invWsa.page) + _screen->copyRegion(_invWsa.x, _invWsa.y, _invWsa.x, _invWsa.y, _invWsa.w, _invWsa.h, 0, _invWsa.page, Screen::CR_NO_P_CHECK); + + _invWsa.running = true; + _invWsa.timer = _system->getMillis(); + + if (run) { + while (_invWsa.running && !skipFlag() && !_quitFlag) { + update(); + _system->delayMillis(10); + } + + if (skipFlag()) { + resetSkipFlag(); + displayInvWsaLastFrame(); + } + } +} + +void KyraEngine_HoF::closeInvWsa() { + _invWsa.wsa->close(); + delete _invWsa.wsa; + _invWsa.wsa = 0; + _invWsa.running = false; +} + +void KyraEngine_HoF::updateInvWsa() { + if (!_invWsa.running || !_invWsa.wsa) + return; + + if (_invWsa.timer > _system->getMillis()) + return; + + _invWsa.wsa->setX(0); + _invWsa.wsa->setY(0); + _invWsa.wsa->setDrawPage(_invWsa.page); + _invWsa.wsa->displayFrame(_invWsa.curFrame, 0, 0, 0); + + if (_invWsa.page) + _screen->copyRegion(_invWsa.x, _invWsa.y, _invWsa.x, _invWsa.y, _invWsa.w, _invWsa.h, _invWsa.page, 0, Screen::CR_NO_P_CHECK); + + _invWsa.timer = _system->getMillis() + _invWsa.delay * _tickLength; + + ++_invWsa.curFrame; + if (_invWsa.curFrame >= _invWsa.lastFrame) + displayInvWsaLastFrame(); + + if (_invWsa.curFrame == _invWsa.specialFrame) + snd_playSoundEffect(_invWsa.sfx); + + if (_invWsa.sfx == -2) { + switch (_invWsa.curFrame) { + case 9: case 27: case 40: + snd_playSoundEffect(0x39); + break; + + case 18: case 34: case 44: + snd_playSoundEffect(0x33); + break; + + case 48: + snd_playSoundEffect(0x38); + break; + + default: + break; + } + } +} + +void KyraEngine_HoF::displayInvWsaLastFrame() { + if (!_invWsa.wsa) + return; + + _invWsa.wsa->setX(0); + _invWsa.wsa->setY(0); + _invWsa.wsa->setDrawPage(_invWsa.page); + _invWsa.wsa->displayFrame(_invWsa.lastFrame-1, 0, 0, 0); + + if (_invWsa.page) + _screen->copyRegion(_invWsa.x, _invWsa.y, _invWsa.x, _invWsa.y, _invWsa.w, _invWsa.h, _invWsa.page, 0, Screen::CR_NO_P_CHECK); + + closeInvWsa(); + + int32 countdown = _rnd.getRandomNumberRng(45, 80); + _timer->setCountdown(2, countdown * 60); +} + +#pragma mark - + +void KyraEngine_HoF::setCauldronState(uint8 state, bool paletteFade) { + memcpy(_screen->getPalette(2), _screen->getPalette(0), 768); + Common::SeekableReadStream *file = _res->getFileStream("_POTIONS.PAL"); + if (!file) + error("Couldn't load cauldron palette"); + file->seek(state*18, SEEK_SET); + file->read(_screen->getPalette(2)+723, 18); + delete file; + file = 0; + + if (paletteFade) { + snd_playSoundEffect((state == 0) ? 0x6B : 0x66); + _screen->fadePalette(_screen->getPalette(2), 0x4B, &_updateFunctor); + } else { + _screen->setScreenPalette(_screen->getPalette(2)); + _screen->updateScreen(); + } + + memcpy(_screen->getPalette(0)+723, _screen->getPalette(2)+723, 18); + _cauldronState = state; + _cauldronUseCount = 0; + //if (state == 5) + // sub_27149(); +} + +void KyraEngine_HoF::clearCauldronTable() { + Common::set_to(_cauldronTable, _cauldronTable+ARRAYSIZE(_cauldronTable), -1); +} + +void KyraEngine_HoF::addFrontCauldronTable(int item) { + for (int i = 23; i >= 0; --i) + _cauldronTable[i+1] = _cauldronTable[i]; + _cauldronTable[0] = item; +} + +void KyraEngine_HoF::cauldronItemAnim(int item) { + const int x = 282; + const int y = 135; + const int mouseDstX = (x + 7) & (~1); + const int mouseDstY = (y + 15) & (~1); + int mouseX = _mouseX & (~1); + int mouseY = _mouseY & (~1); + + while (mouseY != mouseDstY) { + if (mouseY < mouseDstY) + mouseY += 2; + else if (mouseY > mouseDstY) + mouseY -= 2; + uint32 waitEnd = _system->getMillis() + _tickLength; + setMousePos(mouseX, mouseY); + _system->updateScreen(); + delayUntil(waitEnd); + } + + while (mouseX != mouseDstX) { + if (mouseX < mouseDstX) + mouseX += 2; + else if (mouseX > mouseDstX) + mouseX -= 2; + uint32 waitEnd = _system->getMillis() + _tickLength; + setMousePos(mouseX, mouseY); + _system->updateScreen(); + delayUntil(waitEnd); + } + + if (itemIsFlask(item)) { + setHandItem(19); + delayUntil(_system->getMillis()+_tickLength*30); + setHandItem(18); + } else { + _screen->hideMouse(); + backUpGfxRect32x32(x, y); + uint8 *shape = getShapePtr(item+64); + + int curY = y; + for (int i = 0; i < 12; i += 2, curY += 2) { + restoreGfxRect32x32(x, y); + uint32 waitEnd = _system->getMillis() + _tickLength; + _screen->drawShape(0, shape, x, curY, 0, 0); + _screen->updateScreen(); + delayUntil(waitEnd); + } + + snd_playSoundEffect(0x17); + + for (int i = 16; i > 0; i -= 2, curY += 2) { + _screen->setNewShapeHeight(shape, i); + restoreGfxRect32x32(x, y); + uint32 waitEnd = _system->getMillis() + _tickLength; + _screen->drawShape(0, shape, x, curY, 0, 0); + _screen->updateScreen(); + delayUntil(waitEnd); + } + + restoreGfxRect32x32(x, y); + _screen->resetShapeHeight(shape); + removeHandItem(); + _screen->showMouse(); + } +} + +bool KyraEngine_HoF::updateCauldron() { + for (int i = 0; i < 23; ++i) { + const int16 *curStateTable = _cauldronStateTables[i]; + if (*curStateTable == -2) + continue; + + int cauldronState = i; + int16 cauldronTable[25]; + memcpy(cauldronTable, _cauldronTable, sizeof(cauldronTable)); + + while (*curStateTable != -2) { + int stateValue = *curStateTable++; + int j = 0; + for (; j < 25; ++j) { + int val = cauldronTable[j]; + + switch (val) { + case 68: + val = 70; + break; + + case 133: + case 167: + val = 119; + break; + + case 130: + case 143: + case 100: + val = 12; + break; + + case 132: + case 65: + case 69: + case 74: + val = 137; + break; + + case 157: + val = 134; + break; + + default: + break; + } + + if (val == stateValue) { + cauldronTable[j] = -1; + j = 26; + } + } + + if (j == 25) + cauldronState = -1; + } + + if (cauldronState >= 0) { + showMessage(0, 0xCF); + setCauldronState(cauldronState, true); + if (cauldronState == 7) + objectChat(getTableString(0xF2, _cCodeBuffer, 1), 0, 0x83, 0xF2); + clearCauldronTable(); + return true; + } + } + + return false; +} + +void KyraEngine_HoF::cauldronRndPaletteFade() { + showMessage(0, 0xCF); + int index = _rnd.getRandomNumberRng(0x0F, 0x16); + Common::SeekableReadStream *file = _res->getFileStream("_POTIONS.PAL"); + if (!file) + error("Couldn't load cauldron palette"); + file->seek(index*18, SEEK_SET); + file->read(_screen->getPalette(0)+723, 18); + snd_playSoundEffect(0x6A); + _screen->fadePalette(_screen->getPalette(0), 0x1E, &_updateFunctor); + file->seek(0, SEEK_SET); + file->read(_screen->getPalette(0)+723, 18); + delete file; + _screen->fadePalette(_screen->getPalette(0), 0x1E, &_updateFunctor); +} + +void KyraEngine_HoF::resetCauldronStateTable(int idx) { + for (int i = 0; i < 7; ++i) + _cauldronStateTables[idx][i] = -2; +} + +bool KyraEngine_HoF::addToCauldronStateTable(int data, int idx) { + for (int i = 0; i < 7; ++i) { + if (_cauldronStateTables[idx][i] == -2) { + _cauldronStateTables[idx][i] = data; + return true; + } + } + return false; +} + +void KyraEngine_HoF::listItemsInCauldron() { + int itemsInCauldron = 0; + for (int i = 0; i < 25; ++i) { + if (_cauldronTable[i] != -1) + ++itemsInCauldron; + else + break; + } + + if (!itemsInCauldron) { + if (!_cauldronState) + objectChat(getTableString(0xF4, _cCodeBuffer, 1), 0, 0x83, 0xF4); + else + objectChat(getTableString(0xF3, _cCodeBuffer, 1), 0, 0x83, 0xF3); + } else { + objectChat(getTableString(0xF7, _cCodeBuffer, 1), 0, 0x83, 0xF7); + + char buffer[80]; + for (int i = 0; i < itemsInCauldron-1; ++i) { + char *str = buffer; + strcpy(str, getTableString(_cauldronTable[i]+54, _cCodeBuffer, 1)); + if (_lang == 1) { + if (*str == 37) + str += 2; + } + strcpy((char*)_unkBuf500Bytes, "..."); + strcat((char*)_unkBuf500Bytes, str); + strcat((char*)_unkBuf500Bytes, "..."); + objectChat((const char*)_unkBuf500Bytes, 0, 0x83, _cauldronTable[i]+54); + } + + char *str = buffer; + strcpy(str, getTableString(_cauldronTable[itemsInCauldron-1]+54, _cCodeBuffer, 1)); + if (_lang == 1) { + if (*str == 37) + str += 2; + } + strcpy((char*)_unkBuf500Bytes, "..."); + strcat((char*)_unkBuf500Bytes, str); + strcat((char*)_unkBuf500Bytes, "."); + objectChat((const char*)_unkBuf500Bytes, 0, 0x83, _cauldronTable[itemsInCauldron-1]+54); + } +} + +#pragma mark - + +void KyraEngine_HoF::dinoRide() { + _mainCharX = _mainCharY = -1; + + setGameFlag(0x15A); + enterNewScene(41, -1, 0, 0, 0); + resetGameFlag(0x15A); + + setGameFlag(0x15B); + enterNewScene(39, -1, 0, 0, 0); + resetGameFlag(0x15B); + + setGameFlag(0x16F); + + setGameFlag(0x15C); + enterNewScene(42, -1, 0, 0, 0); + resetGameFlag(0x15C); + + setGameFlag(0x15D); + enterNewScene(39, -1, 0, 0, 0); + resetGameFlag(0x15D); + + setGameFlag(0x15E); + enterNewScene(40, -1, 0, 0, 0); + resetGameFlag(0x15E); + + _mainCharX = 262; + _mainCharY = 28; + _mainCharacter.facing = 5; + _mainCharacter.animFrame = _characterFrameTable[5]; + enterNewScene(39, 4, 0, 0, 0); + setHandItem(0x61); + _screen->showMouse(); + resetGameFlag(0x159); +} + +#pragma mark - + +void KyraEngine_HoF::playTim(const char *filename) { + TIM *tim = _tim->load(filename, &_timOpcodes); + if (!tim) + return; + + _tim->resetFinishedFlag(); + while (!_quitFlag && !_tim->finished()) { + _tim->exec(tim, 0); + if (_chatText) + updateWithText(); + else + update(); + delay(10); + } + + _tim->unload(tim); +} + +#pragma mark - + +void KyraEngine_HoF::registerDefaultSettings() { + KyraEngine::registerDefaultSettings(); + + // Most settings already have sensible defaults. This one, however, is + // specific to the Kyra engine. + ConfMan.registerDefault("walkspeed", 5); +} + +void KyraEngine_HoF::writeSettings() { + ConfMan.setInt("talkspeed", ((_configTextspeed-2) * 255) / 95); + + switch (_lang) { + case 1: + _flags.lang = Common::FR_FRA; + break; + + case 2: + _flags.lang = Common::DE_DEU; + break; + + case 3: + _flags.lang = Common::JA_JPN; + break; + + case 0: + default: + _flags.lang = Common::EN_ANY; + break; + } + + ConfMan.set("language", Common::getLanguageCode(_flags.lang)); + + KyraEngine::writeSettings(); +} + +void KyraEngine_HoF::readSettings() { + int talkspeed = ConfMan.getInt("talkspeed"); + _configTextspeed = (talkspeed*95)/255 + 2; + KyraEngine::readSettings(); +} + +} // end of namespace Kyra + + + + diff --git a/engines/kyra/kyra_mr.cpp b/engines/kyra/kyra_mr.cpp new file mode 100644 index 0000000000..a3295f3f38 --- /dev/null +++ b/engines/kyra/kyra_mr.cpp @@ -0,0 +1,1563 @@ +/* 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_mr.h" +#include "kyra/screen_mr.h" +#include "kyra/wsamovie.h" +#include "kyra/sound.h" +#include "kyra/text_mr.h" +#include "kyra/vqa.h" +#include "kyra/gui.h" +#include "kyra/timer.h" +#include "kyra/debugger.h" +#include "kyra/gui_v3.h" +#include "kyra/resource.h" + +#include "common/system.h" +#include "common/config-manager.h" + +namespace Kyra { +KyraEngine_MR::KyraEngine_MR(OSystem *system, const GameFlags &flags) : KyraEngine_v2(system, flags) { + _soundDigital = 0; + _musicSoundChannel = -1; + _menuAudioFile = "TITLE1.AUD"; + _lastMusicCommand = -1; + _itemBuffer1 = _itemBuffer2 = 0; + _scoreFile = 0; + _cCodeFile = 0; + _scenesFile = 0; + _itemFile = 0; + _gamePlayBuffer = 0; + _interface = _interfaceCommandLine = 0; + _costPalBuffer = 0; + _animObjects = 0; + memset(_sceneShapes, 0, sizeof(_sceneShapes)); + memset(_sceneAnimMovie, 0, sizeof(_sceneAnimMovie)); + _gfxBackUpRect = 0; + _itemList = 0; + _malcolmShapes = 0; + _paletteOverlay = 0; + _sceneList = 0; + memset(&_mainCharacter, 0, sizeof(_mainCharacter)); + _mainCharacter.sceneId = 9; + _mainCharacter.height = 0x4C; + _mainCharacter.facing = 5; + _mainCharacter.animFrame = 0x57; + _mainCharacter.walkspeed = 5; + memset(_mainCharacter.inventory, -1, sizeof(_mainCharacter.inventory)); + _text = 0; + _commandLineY = 189; + _inventoryState = false; + memset(&_sceneScriptState, 0, sizeof(_sceneScriptState)); + memset(&_sceneScriptData, 0, sizeof(_sceneScriptData)); + _updateCharPosNextUpdate = 0; + memset(_characterAnimTable, 0, sizeof(_characterAnimTable)); + _overwriteSceneFacing = false; + _maskPageMinY = _maskPageMaxY = 0; + _sceneStrings = 0; + _enterNewSceneLock = 0; + _mainCharX = _mainCharY = -1; + _animList = 0; + _drawNoShapeFlag = false; + _wsaPlayingVQA = false; + _lastCharPalLayer = -1; + _charPalUpdate = false; + _runFlag = false; + _unk5 = 0; + _unkSceneScreenFlag1 = false; + _noScriptEnter = true; + _itemInHand = _handItemSet = -1; + _unk3 = -1; + _unk4 = 0; + _loadingState = false; + _noStartupChat = false; + _pathfinderFlag = 0; + _talkObjectList = 0; + _chatText = 0; + _chatObject = -1; + memset(&_chatScriptState, 0, sizeof(_chatScriptState)); + memset(&_chatScriptData, 0, sizeof(_chatScriptData)); + _voiceSoundChannel = -1; + _charBackUpWidth2 = _charBackUpHeight2 = -1; + _charBackUpWidth = _charBackUpHeight = -1; + _useActorBuffer = false; + _curStudioSFX = 283; + _badConscienceShown = false; + _currentChapter = 1; + _deathHandler = -1; + _unkHandleSceneChangeFlag = false; + memset(_sceneShapeDescs, 0, sizeof(_sceneShapeDescs)); + _cnvFile = _dlgBuffer = 0; + _curDlgChapter = _curDlgIndex = _curDlgLang = -1; + _isStartupDialog = 0; + _stringBuffer = 0; + _dialogSceneAnim = _dialogSceneScript = -1; + memset(&_dialogScriptData, 0, sizeof(_dialogScriptData)); + memset(&_dialogScriptState, 0, sizeof(_dialogScriptState)); + _dialogScriptFuncStart = _dialogScriptFuncProc = _dialogScriptFuncEnd = 0; + _malcolmsMood = 1; + _nextIdleAnim = 0; + _nextIdleType = false; + _newShapeFlag = -1; + _newShapeFiledata = 0; + _inventoryScrollSpeed = -1; + _invWsa = 0; + _invWsaFrame = -1; + _score = 0; + memset(_scoreFlagTable, 0, sizeof(_scoreFlagTable)); + _debugger = 0; + _mainButtonData = 0; + _mainButtonList = 0; + _mainButtonListInitialized = false; + _enableInventory = true; + _goodConscienceShown = false; + _goodConscienceAnim = -1; + _goodConsciencePosition = false; + _showOutro = false; +} + +KyraEngine_MR::~KyraEngine_MR() { + delete _screen; + delete _soundDigital; + + delete [] _itemBuffer1; + delete [] _itemBuffer2; + delete [] _scoreFile; + delete [] _cCodeFile; + delete [] _scenesFile; + delete [] _itemFile; + delete [] _gamePlayBuffer; + delete [] _interface; + delete [] _interfaceCommandLine; + delete [] _costPalBuffer; + delete [] _animObjects; + + for (uint i = 0; i < ARRAYSIZE(_sceneShapes); ++i) + delete [] _sceneShapes[i]; + + for (uint i = 0; i < ARRAYSIZE(_sceneAnimMovie); ++i) + delete _sceneAnimMovie[i]; + + delete [] _gfxBackUpRect; + delete [] _itemList; + delete [] _paletteOverlay; + delete [] _sceneList; + + for (ShapeMap::iterator i = _gameShapes.begin(); i != _gameShapes.end(); ++i) { + delete [] i->_value; + i->_value = 0; + } + _gameShapes.clear(); + + _emc->unload(&_sceneScriptData); + + delete [] _sceneStrings; + delete [] _talkObjectList; + + for (Common::Array::iterator i = _opcodesTemporary.begin(); i != _opcodesTemporary.end(); ++i) + delete *i; + _opcodesTemporary.clear(); + + for (Common::Array::iterator i = _opcodesDialog.begin(); i != _opcodesDialog.end(); ++i) + delete *i; + _opcodesDialog.clear(); + + delete _cnvFile; + delete _dlgBuffer; + delete [] _stringBuffer; + delete [] _newShapeFiledata; + delete _invWsa; + delete _debugger; + delete [] _mainButtonData; + delete _gui; +} + +int KyraEngine_MR::init() { + _screen = new Screen_MR(this, _system); + assert(_screen); + _screen->setResolution(); + + KyraEngine::init(); + + _debugger = new Debugger_v3(this); + assert(_debugger); + + _soundDigital = new SoundDigital(this, _mixer); + assert(_soundDigital); + if (!_soundDigital->init()) + error("_soundDigital->init() failed"); + KyraEngine::_text = _text = new TextDisplayer_MR(this, _screen); + assert(_text); + _gui = new GUI_v3(this); + assert(_gui); + + _screen->loadFont(Screen::FID_6_FNT, "6.FNT"); + _screen->loadFont(Screen::FID_8_FNT, "8FAT.FNT"); + _screen->loadFont(Screen::FID_BOOKFONT_FNT, "BOOKFONT.FNT"); + _screen->setFont(Screen::FID_6_FNT); + _screen->setAnimBlockPtr(3500); + _screen->setScreenDim(0); + + _res->loadFileToBuf("PALETTE.COL", _screen->getPalette(0), 768); + _screen->setScreenPalette(_screen->getPalette(0)); + + return 0; +} + +int KyraEngine_MR::go() { + bool running = true; + preinit(); + _screen->hideMouse(); + initMainMenu(); + + _screen->clearPage(0); + _screen->clearPage(2); + + while (running && !_quitFlag) { + _screen->_curPage = 0; + _screen->clearPage(0); + + _screen->setScreenPalette(_screen->getPalette(0)); + + // XXX + playMenuAudioFile(); + + for (int i = 0; i < 64 && !_quitFlag; ++i) { + uint32 nextRun = _system->getMillis() + 3 * _tickLength; + _menuAnim->displayFrame(i, 0); + _screen->updateScreen(); + delayUntil(nextRun); + } + + for (int i = 64; i > 29 && !_quitFlag; --i) { + uint32 nextRun = _system->getMillis() + 3 * _tickLength; + _menuAnim->displayFrame(i, 0); + _screen->updateScreen(); + delayUntil(nextRun); + } + + switch (_menu->handle(3)) { + case 0: + uninitMainMenu(); + + fadeOutMusic(60); + _screen->fadeToBlack(); + _musicSoundChannel = -1; + startup(); + runLoop(); + running = false; + break; + + case 1: + playVQA("K3INTRO"); + _wsaPlayingVQA = false; + _screen->hideMouse(); + break; + + case 2: + //uninitMainMenu(); + //show load dialog + //running = false; + break; + + case 3: + default: + fadeOutMusic(60); + _screen->fadeToBlack(); + uninitMainMenu(); + quitGame(); + running = false; + break; + } + } + + if (_showOutro) + playVQA("CREDITS"); + + return 0; +} + +void KyraEngine_MR::initMainMenu() { + _menuAnim = new WSAMovieV2(this, _screen); + _menuAnim->open("REVENGE.WSA", 1, _screen->getPalette(0)); + _menuAnim->setX(0); + _menuAnim->setY(0); + _menuAnim->setDrawPage(0); + memset(_screen->getPalette(0), 0, 3); + + _menu = new MainMenu(this); + MainMenu::StaticData data = { + { _mainMenuStrings[_lang*4+0], _mainMenuStrings[_lang*4+1], _mainMenuStrings[_lang*4+2], _mainMenuStrings[_lang*4+3] }, + { 0x01, 0x04, 0x0C, 0x04, 0x00, 0x80, 0xFF, 0x00, 0x01, 0x02, 0x03 }, + { 0x16, 0x19, 0x1A, 0x16 }, + 0x80, 0xFF + }; + + MainMenu::Animation anim; + anim.anim = _menuAnim; + anim.startFrame = 29; + anim.endFrame = 63; + anim.delay = 2; + + _menu->init(data, anim); +} + +void KyraEngine_MR::uninitMainMenu() { + delete _menuAnim; + _menuAnim = 0; + delete _menu; + _menu = 0; +} + +void KyraEngine_MR::playVQA(const char *name) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::playVQA('%s')", name); + + VQAMovie vqa(this, _system); + + char filename[20]; + int size = 0; // TODO: Movie size is 0, 1 or 2. + + snprintf(filename, sizeof(filename), "%s%d.VQA", name, size); + + if (vqa.open(filename)) { + _soundDigital->stopAllSounds(); + + _screen->hideMouse(); + memcpy(_screen->getPalette(1), _screen->getPalette(0), 768); + fadeOutMusic(60); + _screen->fadeToBlack(); + _screen->clearPage(0); + + vqa.setDrawPage(0); + vqa.play(); + vqa.close(); + + _soundDigital->stopAllSounds(); + _screen->showMouse(); + + uint8 pal[768]; + // Taken from original, it used '1' here too + memset(pal, 1, sizeof(pal)); + _screen->setScreenPalette(pal); + _screen->clearPage(0); + memcpy(_screen->getPalette(0), _screen->getPalette(1), 768); + _wsaPlayingVQA = true; + } +} + +#pragma mark - + +void KyraEngine_MR::playMenuAudioFile() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::playMenuAudioFile()"); + if (_soundDigital->isPlaying(_musicSoundChannel)) + return; + + _musicSoundChannel = _soundDigital->playSound(_menuAudioFile, 0xFF, Audio::Mixer::kMusicSoundType); +} + +void KyraEngine_MR::snd_playWanderScoreViaMap(int track, int force) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::snd_playWanderScoreViaMap(%d, %d)", track, force); + + // XXX byte_3C87C compare + + if (_musicSoundChannel != -1 && !_soundDigital->isPlaying(_musicSoundChannel)) + force = 1; + else if (_musicSoundChannel == -1) + force = 1; + + if (track == _lastMusicCommand && !force) + return; + + stopMusicTrack(); + + if (_musicSoundChannel == -1) { + assert(track < _soundListSize && track >= 0); + + _musicSoundChannel = _soundDigital->playSound(_soundList[track], 0xFF, Audio::Mixer::kMusicSoundType); + } + + _lastMusicCommand = track; +} + +void KyraEngine_MR::stopMusicTrack() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::stopMusicTrack()"); + + if (_musicSoundChannel != -1 && _soundDigital->isPlaying(_musicSoundChannel)) + _soundDigital->stopSound(_musicSoundChannel); + + _lastMusicCommand = -1; + _musicSoundChannel = -1; +} + +int KyraEngine_MR::musicUpdate(int forceRestart) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::musicUpdate(%d)", forceRestart); + + static uint32 mTimer = 0; + static uint16 lock = 0; + + if (ABS(_system->getMillis() - mTimer) > (int)(0x0F * _tickLength)) + mTimer = _system->getMillis(); + + if (_system->getMillis() < mTimer && !forceRestart) + return 1; + + if (!lock) { + lock = 1; + if (_musicSoundChannel >= 0) { + if (!_soundDigital->isPlaying(_musicSoundChannel)) { + if (_lastMusicCommand != -1) + snd_playWanderScoreViaMap(_lastMusicCommand, 1); + } + } + lock = 0; + mTimer = _system->getMillis() + 0x0F * _tickLength; + } + + return 1; +} + +void KyraEngine_MR::fadeOutMusic(int ticks) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::fadeOutMusic(%d)", ticks); + if (_musicSoundChannel >= 0) { + _fadeOutMusicChannel = _musicSoundChannel; + _soundDigital->beginFadeOut(_musicSoundChannel, ticks); + _lastMusicCommand = -1; + } +} + +void KyraEngine_MR::snd_playSoundEffect(int item, int volume) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::snd_playSoundEffect(%d, %d)", item, volume); + if (_sfxFileMap[item*2+0] != 0xFF) { + char filename[16]; + snprintf(filename, 16, "%s.AUD", _sfxFileList[_sfxFileMap[item*2+0]]); + uint8 priority = _sfxFileMap[item*2+1]; + + _soundDigital->playSound(filename, priority, Audio::Mixer::kSFXSoundType, volume); + } +} + +void KyraEngine_MR::playVoice(int high, int low) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::playVoice(%d, %d)", high, low); + snd_playVoiceFile(high * 1000 + low); +} + +void KyraEngine_MR::snd_playVoiceFile(int file) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::snd_playVoiceFile(%d)", file); + char filename[16]; + snprintf(filename, 16, "%u.AUD", (uint)file); + + _voiceSoundChannel = _soundDigital->playSound(filename, 0xFE, Audio::Mixer::kSpeechSoundType, 255); +} + +bool KyraEngine_MR::snd_voiceIsPlaying() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::snd_voiceIsPlaying()"); + return _soundDigital->isPlaying(_voiceSoundChannel); +} + +void KyraEngine_MR::snd_stopVoice() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::snd_stopVoice()"); + if (_voiceSoundChannel != -1) + _soundDigital->stopSound(_voiceSoundChannel); +} + +void KyraEngine_MR::playStudioSFX(const char *str) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::playStudioSFX('%s')", str); + if (_rnd.getRandomNumberRng(1, 2) != 2) + return; + + const int strSize = strlen(str) - 1; + if (str[strSize] != '?' && str[strSize] != '!') + return; + + snd_playSoundEffect(_curStudioSFX++, 128); + + if (_curStudioSFX > 291) + _curStudioSFX = 283; +} + +#pragma mark - + +void KyraEngine_MR::preinit() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::preinit()"); + + _itemBuffer1 = new int8[72]; + _itemBuffer2 = new int8[144]; + initMouseShapes(); + initItems(); + + _screen->setMouseCursor(0, 0, _gameShapes[0]); +} + +void KyraEngine_MR::initMouseShapes() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::initMouseShapes()"); + uint8 *data = _res->fileData("MOUSE.SHP", 0); + assert(data); + for (int i = 0; i <= 6; ++i) + _gameShapes[i] = _screen->makeShapeCopy(data, i); + delete [] data; +} + +void KyraEngine_MR::startup() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::startup()"); + musicUpdate(0); + + memset(_flagsTable, 0, sizeof(_flagsTable)); + + _gamePlayBuffer = new uint8[64000]; + musicUpdate(0); + musicUpdate(0); + + _interface = new uint8[17920]; + _interfaceCommandLine = new uint8[3840]; + + _screen->setFont(Screen::FID_6_FNT); + + _stringBuffer = new char[500]; + //XXX + musicUpdate(0); + _costPalBuffer = new uint8[864]; + //XXX + _animObjects = new AnimObj[67]; + + musicUpdate(0); + + memset(_sceneShapes, 0, sizeof(_sceneShapes)); + _screenBuffer = new uint8[64000]; + + musicUpdate(0); + musicUpdate(0); + + if (!loadLanguageFile("ITEMS.", _itemFile)) + error("Couldn't load ITEMS"); + if (!loadLanguageFile("SCORE.", _scoreFile)) + error("Couldn't load SCORE"); + if (!loadLanguageFile("C_CODE.", _cCodeFile)) + error("Couldn't load C_CODE"); + if (!loadLanguageFile("SCENES.", _scenesFile)) + error("Couldn't load SCENES"); + + //XXX + + if ((_actorFileSize = loadLanguageFile("_ACTOR.", _actorFile)) == 0) + error("couldn't load _ACTOR"); + + musicUpdate(0); + //XXX + musicUpdate(0); + openTalkFile(0); + musicUpdate(0); + _currentTalkFile = 0; + openTalkFile(1); + //XXX + loadCostPal(); + musicUpdate(0); + + for (int i = 0; i < 16; ++i) { + _sceneAnims[i].flags = 0; + _sceneAnimMovie[i] = new WSAMovieV2(this, _screen); + assert(_sceneAnimMovie[i]); + } + + _screen->_curPage = 0; + + _talkObjectList = new TalkObject[88]; + memset(_talkObjectList, 0, sizeof(TalkObject)*88); + for (int i = 0; i < 88; ++i) + _talkObjectList[i].sceneId = 0xFF; + + musicUpdate(0); + updateMalcolmShapes(); + _gfxBackUpRect = new uint8[_screen->getRectSize(32, 32)]; + _itemList = new Item[50]; + resetItemList(); + + loadShadowShape(); + //loadButtonShapes(); + musicUpdate(0); + loadExtrasShapes(); + musicUpdate(0); + loadMalcolmShapes(_malcolmShapes); + musicUpdate(0); + initMainButtonList(true); + loadInterfaceShapes(); + + musicUpdate(0); + _res->loadFileToBuf("PALETTE.COL", _screen->getPalette(0), 768); + _paletteOverlay = new uint8[256]; + _screen->generateOverlay(_screen->getPalette(0), _paletteOverlay, 0xF0, 0x19); + + loadInterface(); + musicUpdate(0); + + clearAnimObjects(); + + _scoreMax = 0; + for (int i = 0; i < _scoreTableSize; ++i) { + if (_scoreTable[i] > 0) + _scoreMax += _scoreTable[i]; + } + + musicUpdate(0); + memset(_hiddenItems, -1, sizeof(_hiddenItems)); + + memset(_newSceneDlgState, 0, sizeof(_newSceneDlgState)); + memset(_conversationState, -1, sizeof(_conversationState)); + + _sceneList = new SceneDesc[98]; + assert(_sceneList); + memset(_sceneList, 0, sizeof(SceneDesc)*98); + _sceneListSize = 98; + + musicUpdate(0); + runStartupScript(1, 0); + _res->exists("MOODOMTR.WSA", true); + _invWsa = new WSAMovieV2(this, _screen); + assert(_invWsa); + _invWsa->open("MOODOMTR.WSA", 1, 0); + _invWsaFrame = 6; + _soundDigital->beginFadeOut(_musicSoundChannel, 60); + delayWithTicks(60); + enterNewScene(_mainCharacter.sceneId, _mainCharacter.facing, 0, 0, 1); + _screen->updateScreen(); + musicUpdate(0); + _screen->showMouse(); + //XXX +} + +void KyraEngine_MR::loadCostPal() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::loadCostPal()"); + _costPalBuffer = _res->fileData("_COSTPAL.DAT", 0); +} + +void KyraEngine_MR::loadShadowShape() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::loadShadowShape()"); + _screen->loadBitmap("SHADOW.CSH", 3, 3, 0); + addShapeToPool(_screen->getCPagePtr(3), 421, 0); +} + +void KyraEngine_MR::loadExtrasShapes() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::loadExtrasShapes()"); + _screen->loadBitmap("EXTRAS.CSH", 3, 3, 0); + for (int i = 0; i < 20; ++i) + addShapeToPool(_screen->getCPagePtr(3), i+433, i); + addShapeToPool(_screen->getCPagePtr(3), 453, 20); + addShapeToPool(_screen->getCPagePtr(3), 454, 21); +} + +void KyraEngine_MR::loadInterfaceShapes() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::loadInterfaceShapes()"); + _screen->loadBitmap("INTRFACE.CSH", 3, 3, 0); + for (int i = 422; i <= 432; ++i) + addShapeToPool(_screen->getCPagePtr(3), i, i-422); +} + +void KyraEngine_MR::loadInterface() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::loadInterface()"); + _screen->loadBitmap("INTRFACE.CPS", 3, 3, 0); + memcpy(_interface, _screen->getCPagePtr(3), 17920); + memcpy(_interfaceCommandLine, _screen->getCPagePtr(3), 3840); +} + +void KyraEngine_MR::initItems() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::initItems()"); + + _screen->loadBitmap("ITEMS.CSH", 3, 3, 0); + + for (int i = 248; i <= 319; ++i) + addShapeToPool(_screen->getCPagePtr(3), i, i-248); + + _screen->loadBitmap("ITEMS2.CSH", 3, 3, 0); + + for (int i = 320; i <= 397; ++i) + addShapeToPool(_screen->getCPagePtr(3), i, i-320); + + uint32 size = 0; + uint8 *itemsDat = _res->fileData("_ITEMS.DAT", &size); + + assert(size >= 72+144); + + memcpy(_itemBuffer1, itemsDat , 72); + memcpy(_itemBuffer2, itemsDat+72, 144); + + delete [] itemsDat; + + _screen->_curPage = 0; +} + +void KyraEngine_MR::runStartupScript(int script, int unk1) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::runStartupScript(%d, %d)", script, unk1); + EMCState state; + EMCData data; + memset(&state, 0, sizeof(state)); + memset(&data, 0, sizeof(data)); + char filename[13]; + strcpy(filename, "_START0X.EMC"); + filename[7] = (script % 10) + '0'; + + _emc->load(filename, &data, &_opcodes); + _emc->init(&state, &data); + _emc->start(&state, 0); + state.regs[6] = unk1; + + while (_emc->isValid(&state)) + _emc->run(&state); + + _emc->unload(&data); +} + +void KyraEngine_MR::openTalkFile(int file) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::openTalkFile(%d)", file); + char talkFilename[16]; + + if (file == 0) { + strcpy(talkFilename, "ANYTALK.TLK"); + } else { + if (_currentTalkFile > 0) { + sprintf(talkFilename, "CH%dTALK.TLK", _currentTalkFile); + _res->unloadPakFile(talkFilename); + } + sprintf(talkFilename, "CH%dTALK.TLK", file); + } + + _currentTalkFile = file; + _res->loadPakFile(talkFilename); +} + +#pragma mark - + +void KyraEngine_MR::loadMalcolmShapes(int newShapes) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::loadMalcolmShapes(%d)", newShapes); + static const uint8 numberOffset[] = { 3, 3, 4, 4, 3, 3 }; + static const uint8 startShape[] = { 0x32, 0x58, 0x78, 0x98, 0xB8, 0xD8 }; + static const uint8 endShape[] = { 0x57, 0x77, 0x97, 0xB7, 0xD7, 0xF7 }; + static const char * const filenames[] = { + "MSW##.SHP", + "MTA##.SHP", + "MTFL##.SHP", + "MTFR##.SHP", + "MTL##.SHP", + "MTR##.SHP" + }; + + for (int i = 50; i <= 247; ++i) { + if (i == 87) + continue; + + ShapeMap::iterator iter = _gameShapes.find(i); + if (iter != _gameShapes.end()) { + delete iter->_value; + iter->_value = 0; + } + } + + const char lowNum = (newShapes % 10) + '0'; + const char highNum = (newShapes / 10) + '0'; + + for (int i = 0; i < 6; ++i) { + char filename[16]; + strcpy(filename, filenames[i]); + filename[numberOffset[i]+0] = highNum; + filename[numberOffset[i]+1] = lowNum; + _res->exists(filename, true); + _res->loadFileToBuf(filename, _screenBuffer, 64000); + for (int j = startShape[i]; j <= endShape[i]; ++j) { + if (j == 87) + continue; + addShapeToPool(_screenBuffer, j, j-startShape[i]); + } + } + + _malcolmShapes = newShapes; + updateMalcolmShapes(); +} + +void KyraEngine_MR::updateMalcolmShapes() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::updateMalcolmShapes()"); + assert(_malcolmShapes >= 0 && _malcolmShapes < _shapeDescsSize); + _malcolmShapeXOffset = _shapeDescs[_malcolmShapes].xOffset; + _malcolmShapeYOffset = _shapeDescs[_malcolmShapes].yOffset; + _animObjects[0].width = _shapeDescs[_malcolmShapes].width; + _animObjects[0].height = _shapeDescs[_malcolmShapes].height; +} + +#pragma mark - + +void KyraEngine_MR::moveCharacter(int facing, int x, int y) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::moveCharacter(%d, %d, %d)", facing, x, y); + x &= ~3; + y &= ~1; + _mainCharacter.facing = facing; + + _screen->hideMouse(); + switch (facing) { + case 0: + while (_mainCharacter.y1 > y) + updateCharPosWithUpdate(); + break; + + case 2: + while (_mainCharacter.x1 < x) + updateCharPosWithUpdate(); + break; + + case 4: + while (_mainCharacter.y1 < y) + updateCharPosWithUpdate(); + break; + + case 6: + while (_mainCharacter.x1 > x) + updateCharPosWithUpdate(); + break; + + default: + break; + } + _screen->showMouse(); +} + +void KyraEngine_MR::updateCharPosWithUpdate() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::updateCharPosWithUpdate()"); + updateCharPos(0, 0); + update(); +} + +int KyraEngine_MR::updateCharPos(int *table, int force) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::updateCharPos(%p, %d)", (const void*)table, force); + if (_updateCharPosNextUpdate > _system->getMillis() && !force) + return 0; + _mainCharacter.x1 += _updateCharPosXTable[_mainCharacter.facing]; + _mainCharacter.y1 += _updateCharPosYTable[_mainCharacter.facing]; + updateCharAnimFrame(0, table); + _updateCharPosNextUpdate = _system->getMillis() + _mainCharacter.walkspeed * _tickLength; + return 1; +} + +void KyraEngine_MR::updateCharAnimFrame(int character, int *table) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::updateCharPos(%d, %p)", character, (const void*)table); + ++_mainCharacter.animFrame; + int facing = _mainCharacter.facing; + + if (table) { + if (table[0] != table[-1] && table[1] == table[-1]) { + facing = getOppositeFacingDirection(table[-1]); + table[0] = table[-1]; + } + } + + if (facing) { + if (facing == 7 || facing == 1) { + if (_characterAnimTable[0] > 2) + facing = 0; + memset(_characterAnimTable, 0, sizeof(_characterAnimTable)); + } else if (facing == 4) { + ++_characterAnimTable[1]; + } else if (facing == 5 || facing == 3) { + if (_characterAnimTable[1] > 2) + facing = 4; + memset(_characterAnimTable, 0, sizeof(_characterAnimTable)); + } + } else { + ++_characterAnimTable[0]; + } + + switch (facing) { + case 0: + if (_mainCharacter.animFrame < 79 || _mainCharacter.animFrame > 86) + _mainCharacter.animFrame = 79; + break; + + case 1: case 2: case 3: + if (_mainCharacter.animFrame < 71 || _mainCharacter.animFrame > 78) + _mainCharacter.animFrame = 71; + break; + + case 4: + if (_mainCharacter.animFrame < 55 || _mainCharacter.animFrame > 62) + _mainCharacter.animFrame = 55; + break; + + case 5: case 6: case 7: + if (_mainCharacter.animFrame < 63 || _mainCharacter.animFrame > 70) + _mainCharacter.animFrame = 63; + break; + + default: + break; + } + + updateCharacterAnim(0); +} + +void KyraEngine_MR::updateCharPal(int unk1) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::updateCharPal(%d)", unk1); + int layer = _screen->getLayer(_mainCharacter.x1, _mainCharacter.y1) - 1; + const uint8 *src = _costPalBuffer + _malcolmShapes * 72; + uint8 *dst = _screen->getPalette(0) + 432; + const int8 *sceneDatPal = &_sceneDatPalette[layer * 3]; + + if (layer != _lastCharPalLayer && unk1) { + for (int i = 0, j = 0; i < 72; ++i) { + uint8 col = *dst; + int8 addCol = *src + *sceneDatPal; + addCol = MAX(0, MIN(addCol, 63)); + addCol = (col - addCol) >> 1; + *dst -= addCol; + ++dst; + ++src; + ++sceneDatPal; + ++j; + if (j > 3) { + sceneDatPal = &_sceneDatPalette[layer * 3]; + j = 0; + } + } + _charPalUpdate = true; + _screen->setScreenPalette(_screen->getPalette(0)); + _lastCharPalLayer = layer; + } else if (_charPalUpdate || !unk1) { + memcpy(dst, src, 72); + + for (int i = 0, j = 0; i < 72; ++i) { + uint8 col = *dst + *sceneDatPal; + *dst = MAX(0, MIN(col, 63)); + ++dst; + ++sceneDatPal; + ++j; + if (j >= 3) { + sceneDatPal = &_sceneDatPalette[layer * 3]; + j = 0; + } + } + + _screen->setScreenPalette(_screen->getPalette(0)); + _charPalUpdate = false; + } +} + +bool KyraEngine_MR::checkCharCollision(int x, int y) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::checkCharCollision(%d, %d)", x, y); + + int scale = getScale(_mainCharacter.x1, _mainCharacter.y1); + int width = (scale * 37) >> 8; + int height = (scale * 76) >> 8; + + int x1 = _mainCharacter.x1 - width/2; + int x2 = _mainCharacter.x1 + width/2; + int y1 = _mainCharacter.y1 - height; + int y2 = _mainCharacter.y1; + + if (x >= x1 && x <= x2 && y >= y1 && y <= y2) + return true; + return false; +} + +#pragma mark - + +void KyraEngine_MR::runLoop() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::runLoop()"); + + _runFlag = true; + while (_runFlag && !_quitFlag) { + if (_deathHandler >= 0) { + // TODO: add menu etc. + loadGame(getSavegameFilename(999)); + } + + if (_system->getMillis() >= _nextIdleAnim) + showIdleAnim(); + + int inputFlag = checkInput(_mainButtonList, true); + removeInputTop(); + + update(); + _timer->update(); + + if (inputFlag == 198 || inputFlag == 199) { + _unk3 = _handItemSet; + Common::Point mouse = getMousePos(); + handleInput(mouse.x, mouse.y); + } + + _system->delayMillis(10); + } +} + +void KyraEngine_MR::handleInput(int x, int y) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::handleInput(%d, %d)", x, y); + if (_inventoryState) + return; + setNextIdleAnimTimer(); + + if (_unk5) { + _unk5 = 0; + return; + } + + if (!_screen->isMouseVisible()) + return; + + if (_unk3 == -3) { + snd_playSoundEffect(0x0D, 0x80); + return; + } + + setNextIdleAnimTimer(); + + int skip = 0; + + if (checkCharCollision(x, y) && _unk3 >= -1 && runSceneScript2()) { + return; + } else if (_itemInHand != 27 && pickUpItem(x, y, 1)) { + return; + } else if (checkItemCollision(x, y) == -1) { + resetGameFlag(1); + skip = runSceneScript1(x, y); + + if (queryGameFlag(1)) { + resetGameFlag(1); + return; + } else if (_unk5) { + _unk5 = 0; + return; + } + } + + if (_deathHandler >= 0) + skip = 1; + + if (skip) + return; + + if (checkCharCollision(x, y)) { + if (runSceneScript2()) + return; + } else if (_itemInHand >= 0 && _unk3 >= 0) { + if (_itemInHand == 27) { + makeCharFacingMouse(); + } else if (y <= 187) { + if (_itemInHand == 43) + removeHandItem(); + else + dropItem(0, _itemInHand, x, y, 1); + } + return; + } else if (_unk3 == -3) { + return; + } else { + if (y > 187 && _unk3 > -4) + return; + if (_unk5) { + _unk5 = 0; + return; + } + } + + inputSceneChange(x, y, 1, 1); +} + +int KyraEngine_MR::inputSceneChange(int x, int y, int unk1, int unk2) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::inputSceneChange(%d, %d, %d, %d)", x, y, unk1, unk2); + uint16 curScene = _mainCharacter.sceneId; + _pathfinderFlag = 15; + + if (!_unkHandleSceneChangeFlag) { + if (_unk3 == -4) { + if (_sceneList[curScene].exit4 != 0xFFFF) { + x = 4; + y = _sceneEnterY4; + _pathfinderFlag = 7; + } + } else if (_unk3 == -6) { + if (_sceneList[curScene].exit2 != 0xFFFF) { + x = 316; + y = _sceneEnterY2; + _pathfinderFlag = 7; + } + } else if (_unk3 == -7) { + if (_sceneList[curScene].exit1 != 0xFFFF) { + x = _sceneEnterX1; + y = _sceneEnterY1 - 2; + _pathfinderFlag = 14; + } + } else if (_unk3 == -5) { + if (_sceneList[curScene].exit3 != 0xFFFF) { + x = _sceneEnterX3; + y = 191; + _pathfinderFlag = 11; + } + } + } + + if (ABS(_mainCharacter.x1 - x) < 4 && ABS(_mainCharacter.y1 - y) < 2) { + _pathfinderFlag = 0; + return 0; + } + + int x1 = _mainCharacter.x1 & (~3); + int y1 = _mainCharacter.y1 & (~1); + x &= ~3; + y &= ~1; + + int size = findWay(x1, y1, x, y, _movFacingTable, 600); + _pathfinderFlag = 0; + + if (!size || size == 0x7D00) + return 0; + + return trySceneChange(_movFacingTable, unk1, unk2); +} + +void KyraEngine_MR::update() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::update()"); + updateInput(); + + musicUpdate(0); + refreshAnimObjectsIfNeed(); + musicUpdate(0); + updateMouse(); + updateSpecialSceneScripts(); + updateCommandLine(); + //XXX + musicUpdate(0); + + _screen->updateScreen(); +} + +void KyraEngine_MR::updateWithText() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::update()"); + updateInput(); + + musicUpdate(0); + updateMouse(); + //XXX + updateSpecialSceneScripts(); + updateCommandLine(); + musicUpdate(0); + + restorePage3(); + drawAnimObjects(); + if (textEnabled() && _chatText) { + int curPage = _screen->_curPage; + _screen->_curPage = 2; + objectChatPrintText(_chatText, _chatObject); + _screen->_curPage = curPage; + } + refreshAnimObjects(0); + + _screen->updateScreen(); +} + +void KyraEngine_MR::updateMouse() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::updateMouse()"); + int shape = 0, offsetX = 0, offsetY = 0; + Common::Point mouse = getMousePos(); + bool hasItemCollision = checkItemCollision(mouse.x, mouse.y) != -1; + + if (mouse.y > 187) { + bool setItemCursor = false; + if (_handItemSet == -6) { + if (mouse.x < 311) + setItemCursor = true; + } else if (_handItemSet == -5) { + if (mouse.x < _sceneMinX || mouse.x > _sceneMaxX) + setItemCursor = true; + } else if (_handItemSet == -4) { + if (mouse.x > 8) + setItemCursor = true; + } + + if (setItemCursor) { + setItemMouseCursor(); + return; + } + } + + if (_inventoryState) { + if (mouse.y >= 144) + return; + hideInventory(); + } + + if (hasItemCollision && _handItemSet < -1 && _itemInHand < 0) { + _handItemSet = -1; + _itemInHand = -1; + _screen->setMouseCursor(0, 0, _gameShapes[0]); + } + + int type = 0; + if (mouse.y <= 199) { + if (mouse.x <= 8) { + if (_sceneExit4 != 0xFFFF) { + type = -4; + shape = 4; + offsetX = 0; + offsetY = 0; + } + } else if (mouse.x >= 311) { + if (_sceneExit2 != 0xFFFF) { + type = -6; + shape = 2; + offsetX = 13; + offsetY = 8; + } + } else if (mouse.y >= 171) { + if (_sceneExit3 != 0xFFFF) { + if (mouse.x >= _sceneMinX && mouse.x <= _sceneMaxX) { + type = -5; + shape = 3; + offsetX = 8; + offsetY = 13; + } + } + } else if (mouse.y <= 8) { + if (_sceneExit1 != 0xFFFF) { + type = -7; + shape = 1; + offsetX = 8; + offsetY = 0; + } + } + } + + for (int i = 0; i < _specialExitCount; ++i) { + if (checkSpecialSceneExit(i, mouse.x, mouse.y)) { + switch (_specialExitTable[20+i]) { + case 0: + type = -7; + shape = 1; + offsetX = 8; + offsetY = 0; + break; + + case 2: + type = -6; + shape = 2; + offsetX = 13; + offsetY = 8; + break; + + case 4: + type = -5; + shape = 3; + offsetX = 8; + offsetY = 13; + break; + + case 6: + type = -4; + shape = 4; + offsetX = 0; + offsetY = 8; + break; + + default: + break; + } + } + } + + if (type != 0 && type != _handItemSet && !hasItemCollision) { + _handItemSet = type; + _screen->setMouseCursor(offsetX, offsetY, _gameShapes[shape]); + } else if (type == 0 && _handItemSet != _itemInHand && mouse.x > 8 && mouse.x < 311 && mouse.y < 171 && mouse.y > 8) { + setItemMouseCursor(); + } else if (mouse.y > 187 && _handItemSet > -4 && type == 0 && !_inventoryState) { + showInventory(); + } +} + +void KyraEngine_MR::delay(uint32 millis, bool doUpdate, bool isMainLoop) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::delay(%d, %d, %d)", millis, doUpdate, isMainLoop); + uint32 endTime = _system->getMillis() + millis; + while (endTime > _system->getMillis()) { + if (doUpdate) { + //XXX + update(); + } + + _system->delayMillis(10); + } +} + +#pragma mark - + +int KyraEngine_MR::checkInput(Button *buttonList, bool mainLoop) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::checkInput(%p, %d)", (const void*)buttonList, mainLoop); + updateInput(); + + int keys = 0; + + while (_eventList.size()) { + Common::Event event = *_eventList.begin(); + bool breakLoop = false; + + 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) && mainLoop) { + const char *saveLoadSlot = getSavegameFilename(9 - (event.kbd.keycode - '0') + 990); + + if (event.kbd.flags == Common::KBD_CTRL) { + loadGame(saveLoadSlot); + _eventList.clear(); + breakLoop = true; + } 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(); + } + break; + + case Common::EVENT_MOUSEMOVE: { + Common::Point pos = getMousePos(); + _mouseX = pos.x; + _mouseY = pos.y; + _screen->updateScreen(); + } break; + + case Common::EVENT_LBUTTONDOWN: + case Common::EVENT_LBUTTONUP: { + Common::Point pos = getMousePos(); + _mouseX = pos.x; + _mouseY = pos.y; + keys = event.type == Common::EVENT_LBUTTONDOWN ? 199 : (200 | 0x800); + breakLoop = true; + } break; + + default: + break; + } + + if (_debugger->isAttached()) + _debugger->onFrame(); + + if (breakLoop) + break; + + _eventList.erase(_eventList.begin()); + } + + return _gui->processButtonList(buttonList, keys | 0x8000); +} + +void KyraEngine_MR::makeCharFacingMouse() { + debugC(9, kDebugLevelAnimator, "KyraEngine_MR::makeCharFacingMouse()"); + if (_mainCharacter.x1 > _mouseX) + _mainCharacter.facing = 5; + else + _mainCharacter.facing = 3; + _mainCharacter.animFrame = _characterFrameTable[_mainCharacter.facing]; + updateCharacterAnim(0); + refreshAnimObjectsIfNeed(); +} + +#pragma mark - + +int KyraEngine_MR::getDrawLayer(int x, int y) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::getDrawLayer(%d, %d)", x, y); + int layer = _screen->getLayer(x, y) - 1; + layer = _sceneDatLayerTable[layer]; + return MAX(0, MIN(layer, 6)); +} + +int KyraEngine_MR::getScale(int x, int y) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::getScale(%d, %d)", x, y); + return _scaleTable[_screen->getLayer(x, y) - 1]; +} + +#pragma mark - + +void KyraEngine_MR::backUpGfxRect32x32(int x, int y) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::backUpGfxRect32x32(%d, %d)", x, y); + _screen->copyRegionToBuffer(_screen->_curPage, x, y, 32, 32, _gfxBackUpRect); +} + +void KyraEngine_MR::restoreGfxRect32x32(int x, int y) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::restoreGfxRect32x32(%d, %d)", x, y); + _screen->copyBlockToPage(_screen->_curPage, x, y, 32, 32, _gfxBackUpRect); +} + +#pragma mark - + +char *KyraEngine_MR::appendLanguage(char *buf, int lang, int bufSize) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::appendLanguage([%p|'%s'], %d, %d)", (const void*)buf, buf, lang, bufSize); + assert(lang < _languageExtensionSize); + + int size = strlen(buf) + strlen(_languageExtension[lang]); + + if (size > bufSize) { + warning("buffer too small to append language extension"); + return 0; + } + + char *temp = buf + strlen(buf); + bufSize -= strlen(buf); + + strncat(temp, _languageExtension[lang], bufSize); + + return buf; +} + +int KyraEngine_MR::loadLanguageFile(const char *file, uint8 *&buffer) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::loadLanguageFile('%s', %p)", file, (const void*)buffer); + + uint32 size = 0; + char nBuf[32]; + strncpy(nBuf, file, 32); + buffer = _res->fileData(appendLanguage(nBuf, _lang, sizeof(nBuf)), &size); + + return buffer ? size : 0 ; +} + +uint8 *KyraEngine_MR::getTableEntry(uint8 *buffer, int id) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::getTableEntry(%p, %d)", (const void*)buffer, id); + uint16 tableEntries = READ_LE_UINT16(buffer); + const uint16 *indexTable = (const uint16*)(buffer + 2); + const uint16 *offsetTable = indexTable + tableEntries; + + int num = 0; + while (id != READ_LE_UINT16(indexTable)) { + ++indexTable; + ++num; + } + + return buffer + READ_LE_UINT16(offsetTable + num); +} + +void KyraEngine_MR::getTableEntry(Common::SeekableReadStream *stream, int id, char *dst) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::getTableEntry(%p, %d, %p)", (const void*)stream, id, (const void*)dst); + stream->seek(0, SEEK_SET); + uint16 tableEntries = stream->readUint16LE(); + + int num = 0; + while (id != stream->readUint16LE()) + ++num; + + stream->seek(2+tableEntries*2+num*2, SEEK_SET); + stream->seek(stream->readUint16LE(), SEEK_SET); + char c = 0; + while ((c = stream->readByte()) != 0) + *dst++ = c; + *dst = 0; +} + +#pragma mark - + +bool KyraEngine_MR::talkObjectsInCurScene() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::talkObjectsInCurScene()"); + + for (int i = 0; i < 88; ++i) { + if (_talkObjectList[i].sceneId == _mainCharacter.sceneId) + return true; + } + + return false; +} + +#pragma mark - + +bool KyraEngine_MR::updateScore(int scoreId, int strId) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::updateScore(%d, %d)", scoreId, strId); + + int scoreIndex = (scoreId >> 3); + int scoreBit = scoreId & 7; + if ((_scoreFlagTable[scoreIndex] & (1 << scoreBit)) != 0) + return false; + + setNextIdleAnimTimer(); + _scoreFlagTable[scoreIndex] |= (1 << scoreBit); + + _screen->hideMouse(); + strcpy(_stringBuffer, (const char*)getTableEntry(_scoreFile, strId)); + strcat(_stringBuffer, ": "); + + assert(scoreId < _scoreTableSize); + + int count = _scoreTable[scoreId]; + if (count > 0) + scoreIncrease(count, _stringBuffer); + + _screen->showMouse(); + setNextIdleAnimTimer(); + return true; +} + +void KyraEngine_MR::scoreIncrease(int count, const char *str) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::scoreIncrease(%d, '%s')", count, str); + int drawOld = 1; + _screen->hideMouse(); + + showMessage(str, 0xFF, 0xF0); + const int x = getScoreX(str); + + for (int i = 0; i < count; ++i) { + int oldScore = _score; + int newScore = ++_score; + + if (newScore > _scoreMax) { + _score = _scoreMax; + break; + } + + drawScoreCounting(oldScore, newScore, drawOld, x); + if (_inventoryState) + drawScore(0, 215, 191); + _screen->updateScreen(); + delay(20, true); + + snd_playSoundEffect(0x0E, 0xC8); + drawOld = 0; + } + + _screen->showMouse(); +} + +#pragma mark - + +void KyraEngine_MR::changeChapter(int newChapter, int sceneId, int malcolmShapes, int facing) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::changeChapter(%d, %d, %d, %d)", newChapter, sceneId, malcolmShapes, facing); + resetItemList(); + + _currentChapter = newChapter; + runStartupScript(newChapter, 0); + _mainCharacter.dlgIndex = 0; + + _malcolmsMood = 1; + memset(_newSceneDlgState, 0, sizeof(_newSceneDlgState)); + + if (malcolmShapes >= 0) + loadMalcolmShapes(malcolmShapes); + + enterNewScene(sceneId, facing, 0, 0, 0); +} + +} // end of namespace Kyra + diff --git a/engines/kyra/kyra_mr.h b/engines/kyra/kyra_mr.h new file mode 100644 index 0000000000..e166998bc8 --- /dev/null +++ b/engines/kyra/kyra_mr.h @@ -0,0 +1,733 @@ +/* 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_V3_H +#define KYRA_KYRA_V3_H + +#include "kyra/kyra_v2.h" +#include "kyra/screen_mr.h" +#include "kyra/script.h" + +#include "common/hashmap.h" +#include "common/list.h" + +namespace Kyra { + +class SoundDigital; +class Screen_MR; +class MainMenu; +class WSAMovieV2; +class TextDisplayer_MR; +class Debugger_v3; +class GUI_v3; +struct Button; + +class KyraEngine_MR : public KyraEngine_v2 { +friend class Debugger_v3; +friend class TextDisplayer_MR; +friend class GUI_v3; +public: + KyraEngine_MR(OSystem *system, const GameFlags &flags); + ~KyraEngine_MR(); + + Screen *screen() { return _screen; } + Screen_v2 *screen_v2() const { return _screen; } + SoundDigital *soundDigital() { return _soundDigital; } + int language() const { return _lang; } + + int go(); + + void playVQA(const char *name); + +protected: + // KyraEngine_v2 API + int getFirstSpecialSceneScript() const { return 9; } + + // -- + Screen_MR *_screen; + SoundDigital *_soundDigital; + + int init(); + + void preinit(); + void startup(); + void runStartupScript(int script, int unk1); + + void setupOpcodeTable(); + + // run + bool _showOutro; + bool _runFlag; + int _deathHandler; + + void runLoop(); + void handleInput(int x, int y); + bool _unkHandleSceneChangeFlag; + int inputSceneChange(int x, int y, int unk1, int unk2); + + void update(); + void updateWithText(); + void updateMouse(); + + void delay(uint32 millis, bool update = false, bool isMainLoop = false); + + // - Input + int checkInput(Button *buttonList, bool mainLoop = false); + + // sound specific +private: + void playMenuAudioFile(); + + int _musicSoundChannel; + int _fadeOutMusicChannel; + const char *_menuAudioFile; + + static const char *_soundList[]; + static const int _soundListSize; + + void snd_playWanderScoreViaMap(int track, int force); + void stopMusicTrack(); + + int musicUpdate(int forceRestart); + void fadeOutMusic(int ticks); + + void snd_playSoundEffect(int item, int volume); + + static const uint8 _sfxFileMap[]; + static const int _sfxFileMapSize; + static const char *_sfxFileList[]; + static const int _sfxFileListSize; + + int _voiceSoundChannel; + + void playVoice(int high, int low); + void snd_playVoiceFile(int file); + bool snd_voiceIsPlaying(); + void snd_stopVoice(); + + int _curStudioSFX; + void playStudioSFX(const char *str); + + // gui + GUI_v3 *_gui; + + Button *_mainButtonData; + Button *_mainButtonList; + bool _mainButtonListInitialized; + void initMainButtonList(bool disable); + + bool _enableInventory; + int buttonInventory(Button *button); + int buttonMoodChange(Button *button); + int buttonShowScore(Button *button); + int buttonJesterStaff(Button *button); + + // -> main menu + void initMainMenu(); + void uninitMainMenu(); + + WSAMovieV2 *_menuAnim; + + // timer + void setupTimers(); + + void setWalkspeed(uint8); + void setCommandLineRestoreTimer(int secs); + + void timerRestoreCommandLine(int arg); + void timerRunSceneScript7(int arg); + void timerFleaDeath(int arg); + + uint32 _nextIdleAnim; + void setNextIdleAnimTimer(); + + // pathfinder + bool lineIsPassable(int x, int y); + +private: + // main menu + static const char *_mainMenuStrings[]; + + // animator + uint8 *_gamePlayBuffer; + void restorePage3(); + + AnimObj *_animObjects; + + void clearAnimObjects(); + + void animSetupPaletteEntry(AnimObj *anim); + + void drawAnimObjects(); + void drawSceneAnimObject(AnimObj *obj, int x, int y, int drawLayer); + void drawCharacterAnimObject(AnimObj *obj, int x, int y, int drawLayer); + + void refreshAnimObjects(int force); + + bool _loadingState; + void updateCharacterAnim(int charId); + + void updateSceneAnim(int anim, int newFrame); + void setupSceneAnimObject(int anim, uint16 flags, int x, int y, int x2, int y2, int w, int h, int unk10, int specialSize, int unk14, int shape, const char *filename); + void removeSceneAnimObject(int anim, int refresh); + + int _charBackUpWidth2, _charBackUpHeight2; + int _charBackUpWidth, _charBackUpHeight; + + void setCharacterAnimDim(int w, int h); + void resetCharacterAnimDim(); + + bool _nextIdleType; + void showIdleAnim(); + + void addItemToAnimList(int item); + void deleteItemAnimEntry(int item); + + // interface + uint8 *_interface; + uint8 *_interfaceCommandLine; + + void loadInterfaceShapes(); + void loadInterface(); + + void showMessage(const char *string, uint8 c0, uint8 c1); + void showMessageFromCCode(int string, uint8 c0, int); + void updateItemCommand(int item, int str, uint8 c0); + + void updateCommandLine(); + void restoreCommandLine(); + void updateCLState(); + + int _commandLineY; + const char *_shownMessage; + bool _restoreCommandLine; + bool _inventoryState; + int _inventoryScrollSpeed; + + void showInventory(); + void hideInventory(); + + void drawMalcolmsMoodText(); + void drawMalcolmsMoodPointer(int frame, int page); + void drawJestersStaff(int type, int page); + + void drawScore(int page, int x, int y); + void drawScoreCounting(int oldScore, int newScore, int drawOld, const int x); + int getScoreX(const char *str); + + static const uint8 _inventoryX[]; + static const uint8 _inventoryY[]; + void redrawInventory(int page); + void clearInventorySlot(int slot, int page); + void drawInventorySlot(int page, int item, int slot); + + WSAMovieV2 *_invWsa; + int _invWsaFrame; + + // localization + uint8 *_scoreFile; + uint8 *_cCodeFile; + uint8 *_scenesFile; + uint8 *_itemFile; + uint8 *_actorFile; + uint32 _actorFileSize; + uint8 *_sceneStrings; + + uint8 *getTableEntry(uint8 *buffer, int id); + void getTableEntry(Common::SeekableReadStream *stream, int id, char *dst); + + // items + int8 *_itemBuffer1; + int8 *_itemBuffer2; + struct Item { + uint16 id; + uint16 sceneId; + int16 x, y; + uint16 unk8; + }; + + Item *_itemList; + uint16 _hiddenItems[100]; + + void resetItem(int index); + void resetItemList(); + static const uint8 _trashItemList[]; + void removeTrashItems(); + + int findFreeItem(); + int findItem(uint16 item, uint16 scene); + int findItem(uint16 item); + + int countAllItems(); + + void initItems(); + + int checkItemCollision(int x, int y); + + bool dropItem(int unk1, uint16 item, int x, int y, int unk2); + bool processItemDrop(uint16 sceneId, uint16 item, int x, int y, int unk1, int unk2); + void itemDropDown(int startX, int startY, int dstX, int dstY, int itemSlot, uint16 item, int remove); + void exchangeMouseItem(int itemPos, int runScript); + bool pickUpItem(int x, int y, int runScript); + + bool isDropable(int x, int y); + + static const uint8 _itemMagicTable[]; + bool itemListMagic(int handItem, int itemSlot); + bool itemInventoryMagic(int handItem, int invSlot); + + static const uint8 _itemStringMap[]; + static const uint _itemStringMapSize; + static const uint8 _itemStringPickUp[]; + static const uint8 _itemStringDrop[]; + static const uint8 _itemStringInv[]; + + int getItemCommandStringPickUp(uint16 item); + int getItemCommandStringDrop(uint16 item); + int getItemCommandStringInv(uint16 item); + + // -> hand item + void setMouseCursor(uint16 item); + + void setHandItem(uint16 item); + void removeHandItem(); + void setItemMouseCursor(); + + int _itemInHand; + int _handItemSet; + + // shapes + void initMouseShapes(); + + int _malcolmShapes; + void loadMalcolmShapes(int newShapes); + void updateMalcolmShapes(); + + int _malcolmShapeXOffset, _malcolmShapeYOffset; + + struct ShapeDesc { + uint8 width, height; + int8 xOffset, yOffset; + }; + static const ShapeDesc _shapeDescs[]; + static const int _shapeDescsSize; + + // scene animation + uint8 *_sceneShapes[20]; + + void freeSceneShapes(); + + // voice + int _currentTalkFile; + void openTalkFile(int file); + + // scene + bool _noScriptEnter; + void enterNewScene(uint16 scene, int facing, int unk1, int unk2, int unk3); + void enterNewSceneUnk1(int facing, int unk1, int unk2); + void enterNewSceneUnk2(int unk1); + int _enterNewSceneLock; + + void unloadScene(); + + void loadScenePal(); + void loadSceneMsc(); + void initSceneScript(int unk1); + void initSceneAnims(int unk1); + void initSceneScreen(int unk1); + + int runSceneScript1(int x, int y); + int runSceneScript2(); + bool _noStartupChat; + void runSceneScript4(int unk1); + void runSceneScript6(); + void runSceneScript8(); + + int _sceneMinX, _sceneMaxX; + int _maskPageMinY, _maskPageMaxY; + + EMCState _sceneScriptState; + EMCData _sceneScriptData; + + int trySceneChange(int *moveTable, int unk1, int unk2); + int checkSceneChange(); + + int8 _sceneDatPalette[45]; + int8 _sceneDatLayerTable[15]; + struct SceneShapeDesc { + // the original saves those variables, we don't, since + // they are just needed on scene load + /*int x, y; + int w, h;*/ + int drawX, drawY; + }; + SceneShapeDesc _sceneShapeDescs[20]; + + int getDrawLayer(int x, int y); + + int getScale(int x, int y); + int _scaleTable[15]; + + bool _unkSceneScreenFlag1; + + // character + struct Character { + uint16 sceneId; + uint16 dlgIndex; + uint8 height; + uint8 facing; + uint16 animFrame; + //uint8 unk8, unk9; + byte walkspeed; + uint16 inventory[10]; + int16 x1, y1; + int16 x2, y2; + int16 x3, y3; + }; + + Character _mainCharacter; + int _mainCharX, _mainCharY; + int _charScale; + + void moveCharacter(int facing, int x, int y); + + void updateCharPosWithUpdate(); + int updateCharPos(int *table, int force); + + uint32 _updateCharPosNextUpdate; + static const int8 _updateCharPosXTable[]; + static const int8 _updateCharPosYTable[]; + + void updateCharAnimFrame(int character, int *table); + int8 _characterAnimTable[2]; + static const uint8 _characterFrameTable[]; + + bool _overwriteSceneFacing; + + void updateCharPal(int unk1); + int _lastCharPalLayer; + bool _charPalUpdate; + + bool checkCharCollision(int x, int y); + + int _malcolmsMood; + + void makeCharFacingMouse(); + + int findFreeInventorySlot(); + + // talk object + struct TalkObject { + char filename[13]; + int8 sceneAnim; + int8 sceneScript; + int16 x, y; + uint8 color; + uint8 sceneId; + }; + + TalkObject *_talkObjectList; + + bool talkObjectsInCurScene(); + + // chat + int _vocHigh; + + const char *_chatText; + int _chatObject; + uint32 _chatEndTime; + int _chatVocHigh, _chatVocLow; + + EMCData _chatScriptData; + EMCState _chatScriptState; + + int chatGetType(const char *text); + int chatCalcDuration(const char *text); + + void objectChat(const char *text, int object, int vocHigh, int vocLow); + void objectChatInit(const char *text, int object, int vocHigh, int vocLow); + void objectChatPrintText(const char *text, int object); + void objectChatProcess(const char *script); + void objectChatWaitToFinish(); + + void badConscienceChat(const char *str, int vocHigh, int vocLow); + void badConscienceChatWaitToFinish(); + + void goodConscienceChat(const char *str, int vocHigh, int vocLow); + void goodConscienceChatWaitToFinish(); + + void malcolmSceneStartupChat(); + + byte _newSceneDlgState[40]; + int8 _conversationState[30][30]; + bool _chatAltFlag; + void setDlgIndex(uint16 index); + void updateDlgIndex(); + + Common::SeekableReadStream *_cnvFile; + Common::SeekableReadStream *_dlgBuffer; + int _curDlgChapter, _curDlgIndex, _curDlgLang; + void updateDlgBuffer(); + void loadDlgHeader(int &vocHighBase, int &vocHighIndex, int &index1, int &index2); + + static const uint8 _vocHighTable[]; + bool _isStartupDialog; + void processDialog(int vocHighIndex, int vocHighBase, int funcNum); + + EMCData _dialogScriptData; + EMCState _dialogScriptState; + int _dialogSceneAnim; + int _dialogSceneScript; + int _dialogScriptFuncStart, _dialogScriptFuncProc, _dialogScriptFuncEnd; + + void dialogStartScript(int object, int funcNum); + void dialogEndScript(int object); + + void npcChatSequence(const char *str, int object, int vocHigh, int vocLow); + + Common::Array _opcodesDialog; + + int o3d_updateAnim(EMCState *script); + int o3d_delay(EMCState *script); + + void malcolmRandomChat(); + void runDialog(int dlgIndex, int funcNum); + + // conscience + bool _badConscienceShown; + int _badConscienceAnim; + bool _badConsciencePosition; + + static const uint8 _badConscienceFrameTable[]; + + void showBadConscience(); + void hideBadConscience(); + + bool _goodConscienceShown; + int _goodConscienceAnim; + bool _goodConsciencePosition; + + static const uint8 _goodConscienceFrameTable[]; + + void showGoodConscience(); + void hideGoodConscience(); + + // special script code + bool _temporaryScriptExecBit; + bool _useFrameTable; + + Common::Array _opcodesTemporary; + + int o3t_defineNewShapes(EMCState *script); + int o3t_setCurrentFrame(EMCState *script); + int o3t_setNewShapeFlag(EMCState *script); + + EMCData _temporaryScriptData; + EMCState _temporaryScriptState; + + void runTemporaryScript(const char *filename, int allowSkip, int resetChar, int newShapes, int shapeUnload); + + // special shape code + char _newShapeFilename[13]; + int _newShapeLastEntry; + int _newShapeWidth, _newShapeHeight; + int _newShapeXAdd, _newShapeYAdd; + + int _newShapeAnimFrame; + int _newShapeDelay; + + int _newShapeFlag; + uint8 *_newShapeFiledata; + int _newShapeCount; + + int initNewShapes(uint8 *filedata); + void processNewShapes(int allowSkip, int resetChar); + void resetNewShapes(int count, uint8 *filedata); + + // unk + uint8 *_costPalBuffer; + uint8 *_screenBuffer; + uint8 *_paletteOverlay; + bool _useActorBuffer; + + int _currentChapter; + void changeChapter(int newChapter, int sceneId, int malcolmShapes, int facing); + + static const uint8 _chapterLowestScene[]; + + int _unk3, _unk4, _unk5; + + void loadCostPal(); + void loadShadowShape(); + void loadExtrasShapes(); + + uint8 *_gfxBackUpRect; + void backUpGfxRect32x32(int x, int y); + void restoreGfxRect32x32(int x, int y); + + char *_stringBuffer; + + int _score; + int _scoreMax; + + static const int8 _scoreTable[]; + static const int _scoreTableSize; + int8 _scoreFlagTable[26]; + bool updateScore(int scoreId, int strId); + void scoreIncrease(int count, const char *str); + + void eelScript(); + + // save/load + void saveGame(const char *fileName, const char *saveName); + void loadGame(const char *fileName); + + // opcodes + int o3_getMalcolmShapes(EMCState *script); + int o3_setCharacterPos(EMCState *script); + int o3_defineObject(EMCState *script); + int o3_refreshCharacter(EMCState *script); + int o3_getCharacterX(EMCState *script); + int o3_getCharacterY(EMCState *script); + int o3_getCharacterFacing(EMCState *script); + int o3_getCharacterScene(EMCState *script); + int o3_getMalcolmsMood(EMCState *script); + int o3_getCharacterFrameFromFacing(EMCState *script); + int o3_setCharacterFacingOverwrite(EMCState *script); + int o3_trySceneChange(EMCState *script); + int o3_moveCharacter(EMCState *script); + int o3_setCharacterFacing(EMCState *script); + int o3_showSceneFileMessage(EMCState *script); + int o3_setCharacterAnimFrameFromFacing(EMCState *script); + int o3_showBadConscience(EMCState *script); + int o3_hideBadConscience(EMCState *script); + int o3_setInventorySlot(EMCState *script); + int o3_getInventorySlot(EMCState *script); + int o3_addItemToInventory(EMCState *script); + int o3_addItemToCurScene(EMCState *script); + int o3_objectChat(EMCState *script); + int o3_checkForItem(EMCState *script); + int o3_resetInventory(EMCState *script); + int o3_defineItem(EMCState *script); + int o3_removeInventoryItemInstances(EMCState *script); + int o3_countInventoryItemInstances(EMCState *script); + int o3_npcChatSequence(EMCState *script); + int o3_queryGameFlag(EMCState *script); + int o3_resetGameFlag(EMCState *script); + int o3_setGameFlag(EMCState *script); + int o3_setHandItem(EMCState *script); + int o3_removeHandItem(EMCState *script); + int o3_handItemSet(EMCState *script); + int o3_hideMouse(EMCState *script); + int o3_addSpecialExit(EMCState *script); + int o3_setMousePos(EMCState *script); + int o3_showMouse(EMCState *script); + int o3_badConscienceChat(EMCState *script); + int o3_wipeDownMouseItem(EMCState *script); + int o3_setMalcolmsMood(EMCState *script); + int o3_delay(EMCState *script); + int o3_updateScore(EMCState *script); + int o3_makeSecondChanceSave(EMCState *script); + int o3_setSceneFilename(EMCState *script); + int o3_removeItemsFromScene(EMCState *script); + int o3_disguiseMalcolm(EMCState *script); + int o3_drawSceneShape(EMCState *script); + int o3_drawSceneShapeOnPage(EMCState *script); + int o3_checkInRect(EMCState *script); + int o3_updateConversations(EMCState *script); + int o3_setSceneDim(EMCState *script); + int o3_update(EMCState *script); + int o3_setSceneAnimPosAndFrame(EMCState *script); + int o3_removeItemInstances(EMCState *script); + int o3_disableInventory(EMCState *script); + int o3_enableInventory(EMCState *script); + int o3_enterNewScene(EMCState *script); + int o3_switchScene(EMCState *script); + int o3_getShapeFlag1(EMCState *script); + int o3_setMalcolmPos(EMCState *script); + int o3_stopMusic(EMCState *script); + int o3_playWanderScoreViaMap(EMCState *script); + int o3_playSoundEffect(EMCState *script); + int o3_getScore(EMCState *script); + int o3_blockOutRegion(EMCState *script); + int o3_showSceneStringsMessage(EMCState *script); + int o3_getRand(EMCState *script); + int o3_setDeathHandler(EMCState *script); + int o3_showGoodConscience(EMCState *script); + int o3_goodConscienceChat(EMCState *script); + int o3_hideGoodConscience(EMCState *script); + int o3_waitForConfirmationClick(EMCState *script); + int o3_defineRoomEntrance(EMCState *script); + int o3_runTemporaryScript(EMCState *script); + int o3_setSpecialSceneScriptRunTime(EMCState *script); + int o3_defineSceneAnim(EMCState *script); + int o3_updateSceneAnim(EMCState *script); + int o3_runActorScript(EMCState *script); + int o3_runDialog(EMCState *script); + int o3_malcolmRandomChat(EMCState *script); + int o3_setDlgIndex(EMCState *script); + int o3_getDlgIndex(EMCState *script); + int o3_defineScene(EMCState *script); + int o3_setConversationState(EMCState *script); + int o3_getConversationState(EMCState *script); + int o3_changeChapter(EMCState *script); + int o3_countItemInstances(EMCState *script); + int o3_dialogStartScript(EMCState *script); + int o3_dialogEndScript(EMCState *script); + int o3_setSpecialSceneScriptState(EMCState *script); + int o3_clearSpecialSceneScriptState(EMCState *script); + int o3_querySpecialSceneScriptState(EMCState *script); + int o3_setHiddenItemsEntry(EMCState *script); + int o3_getHiddenItemsEntry(EMCState *script); + int o3_customChat(EMCState *script); + int o3_customChatFinish(EMCState *script); + int o3_setupSceneAnimObject(EMCState *script); + int o3_removeSceneAnimObject(EMCState *script); + int o3_disableTimer(EMCState *script); + int o3_enableTimer(EMCState *script); + int o3_setTimerCountdown(EMCState *script); + int o3_setVocHigh(EMCState *script); + int o3_getVocHigh(EMCState *script); + int o3_dummy(EMCState *script); + + // misc + TextDisplayer_MR *_text; + Debugger_v3 *_debugger; + bool _wsaPlayingVQA; + + // resource specific +private: + static const char *_languageExtension[]; + static const int _languageExtensionSize; + + char *appendLanguage(char *buf, int lang, int bufSize); + + int loadLanguageFile(const char *file, uint8 *&buffer); +}; + +} // end of namespace Kyra + +#endif + diff --git a/engines/kyra/kyra_v2.cpp b/engines/kyra/kyra_v2.cpp deleted file mode 100644 index 8d4a64e1a7..0000000000 --- a/engines/kyra/kyra_v2.cpp +++ /dev/null @@ -1,2330 +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_v2.h" -#include "kyra/screen.h" -#include "kyra/resource.h" -#include "kyra/wsamovie.h" -#include "kyra/sound.h" -#include "kyra/script.h" -#include "kyra/script_tim.h" -#include "kyra/text_v2.h" -#include "kyra/timer.h" -#include "kyra/debugger.h" - -#include "common/system.h" -#include "common/config-manager.h" - -namespace Kyra { - -KyraEngine_v2::KyraEngine_v2(OSystem *system, const GameFlags &flags) : KyraEngine(system, flags), _updateFunctor(this, &KyraEngine_v2::update) { - memset(_defaultShapeTable, 0, sizeof(_defaultShapeTable)); - _mouseSHPBuf = 0; - _debugger = 0; - _screen = 0; - _text = 0; - - _seqProcessedString = 0; - _activeWSA = 0; - _activeText = 0; - _seqWsa = 0; - _sequences = 0; - _sequenceSoundList = 0; - - _showCredits = false; - - _gamePlayBuffer = 0; - _cCodeBuffer = _optionsBuffer = _chapterBuffer = 0; - - _overwriteSceneFacing = false; - _mainCharX = _mainCharY = -1; - _drawNoShapeFlag = false; - _charPalEntry = 0; - _itemInHand = -1; - _unkSceneScreenFlag1 = false; - _noScriptEnter = true; - _currentChapter = 0; - _newChapterFile = 1; - _oldTalkFile = -1; - _currentTalkFile = 0; - _lastSfxTrack = -1; - _handItemSet = -1; - _lastProcessedSceneScript = 0; - _specialSceneScriptRunFlag = false; - memset(_animObjects, 0, sizeof(_animObjects)); - _unkHandleSceneChangeFlag = false; - _pathfinderFlag = 0; - _mouseX = _mouseY = 0; - _newShapeCount = 0; - _newShapeFiledata = 0; - - _vocHigh = -1; - _chatVocHigh = -1; - _chatVocLow = -1; - _chatText = 0; - _chatObject = -1; - _lastIdleScript = -1; - - _currentTalkSections.STATim = 0; - _currentTalkSections.TLKTim = 0; - _currentTalkSections.ENDTim = 0; - - memset(&_invWsa, 0, sizeof(_invWsa)); - _itemAnimData = 0; - _demoAnimData = 0; - _nextAnimItem = 0; - - for (int i = 0; i < 15; i++) - memset(&_activeItemAnim[i], 0, sizeof(ActiveItemAnim)); - - _colorCodeFlag1 = 0; - _colorCodeFlag2 = -1; - _scriptCountDown = 0; - _dbgPass = 0; - - _gamePlayBuffer = 0; - _unkBuf500Bytes = 0; - _screenBuffer = 0; - _inventorySaved = false; - _unkBuf200kByte = 0; - memset(&_defaultShapeTable, 0, sizeof(_defaultShapeTable)); - memset(&_sceneShapeTable, 0, sizeof(_sceneShapeTable)); - memset(&_sceneScriptData, 0, sizeof(_sceneScriptData)); - - _talkObjectList = 0; - _shapeDescTable = 0; - _gfxBackUpRect = 0; - _sceneList = 0; - memset(&_sceneAnimMovie, 0, sizeof(_sceneAnimMovie)); - memset(&_wsaSlots, 0, sizeof(_wsaSlots)); - memset(&_buttonShapes, 0, sizeof(_buttonShapes)); - - _configTextspeed = 50; - - _inventoryButtons = _buttonList = 0; - - _dlgBuffer = 0; - _conversationState = new int8*[19]; - for (int i = 0; i < 19; i++) - _conversationState[i] = new int8[14]; - _npcTalkChpIndex = _npcTalkDlgIndex = -1; - _mainCharacter.dlgIndex = 0; - setNewDlgIndex(-1); - - _deathHandler = -1; - - _bookMaxPage = 6; - _bookCurPage = 0; - _bookNewPage = 0; - _bookBkgd = 0; - - _cauldronState = 0; - _cauldronUseCount = 0; - memset(_cauldronStateTables, 0, sizeof(_cauldronStateTables)); - - _menuDirectlyToLoad = false; - _menu = 0; -} - -KyraEngine_v2::~KyraEngine_v2() { - cleanup(); - seq_uninit(); - - delete [] _mouseSHPBuf; - delete _screen; - delete _text; - delete _gui; - delete _tim; - _text = 0; - delete _debugger; - delete _invWsa.wsa; - - if (_sequenceSoundList) { - for (int i = 0; i < _sequenceSoundListSize; i++) { - if (_sequenceSoundList[i]) - delete [] _sequenceSoundList[i]; - } - delete [] _sequenceSoundList; - _sequenceSoundList = NULL; - } - - if (_dlgBuffer) - delete [] _dlgBuffer; - for (int i = 0; i < 19; i++) - delete [] _conversationState[i]; - delete [] _conversationState; - - for (Common::Array::iterator i = _opcodesTemporary.begin(); i != _opcodesTemporary.end(); ++i) - delete *i; - _opcodesTemporary.clear(); - - for (Common::Array::iterator i = _timOpcodes.begin(); i != _timOpcodes.end(); ++i) - delete *i; - _timOpcodes.clear(); -} - -int KyraEngine_v2::init() { - _screen = new Screen_v2(this, _system); - assert(_screen); - _screen->setResolution(); - - KyraEngine::init(); - initStaticResource(); - - _debugger = new Debugger_v2(this); - assert(_debugger); - _text = new TextDisplayer_v2(this, _screen); - assert(_text); - _gui = new GUI_v2(this); - assert(_gui); - _tim = new TIMInterpreter(this, _system); - assert(_tim); - - if (_flags.isDemo && !_flags.isTalkie) { - _screen->loadFont(_screen->FID_8_FNT, "FONT9P.FNT"); - } else { - _screen->loadFont(_screen->FID_6_FNT, "6.FNT"); - _screen->loadFont(_screen->FID_8_FNT, "8FAT.FNT"); - _screen->loadFont(_screen->FID_BOOKFONT_FNT, "BOOKFONT.FNT"); - } - _screen->loadFont(_screen->FID_GOLDFONT_FNT, "GOLDFONT.FNT"); - - _screen->setAnimBlockPtr(3504); - _screen->setScreenDim(0); - - if (!_sound->init()) - error("Couldn't init sound"); - - _abortIntroFlag = false; - - if (_sequenceStrings) { - for (int i = 0; i < 33; i++) - _sequenceStringsDuration[i] = (int) strlen(_sequenceStrings[i]) * 8; - } - - // No mouse display in demo - if (_flags.isDemo && !_flags.isTalkie) - return 0; - - _mouseSHPBuf = _res->fileData("PWGMOUSE.SHP", 0); - assert(_mouseSHPBuf); - - for (int i = 0; i < 2; i++) { - _defaultShapeTable[i] = _screen->getPtrToShape(_mouseSHPBuf, i); - assert(_defaultShapeTable[i]); - } - - _screen->setMouseCursor(0, 0, _defaultShapeTable[0]); - return 0; -} - -int KyraEngine_v2::go() { - if (_gameToLoad == -1) { - if (_flags.platform == Common::kPlatformFMTowns || _flags.platform == Common::kPlatformPC98) - seq_showStarcraftLogo(); - - if (_flags.isDemo && !_flags.isTalkie) { - seq_playSequences(kSequenceDemoVirgin, kSequenceDemoFisher); - _menuChoice = 4; - } else { - seq_playSequences(kSequenceVirgin, kSequenceZanfaun); - } - } else { - _menuChoice = 1; - } - - _res->unloadAllPakFiles(); - - if (_menuChoice != 4) { - // load just the pak files needed for ingame - _res->loadPakFile(StaticResource::staticDataFilename()); - if (_flags.platform == Common::kPlatformPC && _flags.isTalkie) - _res->loadFileList("FILEDATA.FDT"); - else - _res->loadFileList(_ingamePakList, _ingamePakListSize); - } - - _menuDirectlyToLoad = (_menuChoice == 3) ? true : false; - - if (_menuChoice & 1) { - startup(); - if (!quit()) - runLoop(); - cleanup(); - - if (_showCredits) - seq_playSequences(kSequenceFunters, kSequenceFrash); - } - - return 0; -} - -void KyraEngine_v2::startup() { - _sound->setSoundList(&_soundData[kMusicIngame]); - // The track map is exactly the same - // for FM-TOWNS and DOS - _trackMap = _dosTrackMap; - _trackMapSize = _dosTrackMapSize; - - _screen->_curPage = 0; - delete [] _mouseSHPBuf; - _mouseSHPBuf = 0; - - memset(_defaultShapeTable, 0, sizeof(_defaultShapeTable)); - memset(_sceneShapeTable, 0, sizeof(_sceneShapeTable)); - _gamePlayBuffer = new uint8[46080]; - _unkBuf500Bytes = new uint8[500]; - - loadMouseShapes(); - loadItemShapes(); - - _screen->setMouseCursor(0, 0, getShapePtr(0)); - - _screenBuffer = new uint8[64000]; - _unkBuf200kByte = new uint8[200000]; - - loadChapterBuffer(_newChapterFile); - - loadCCodeBuffer("C_CODE.XXX"); - - if (_flags.isTalkie) { - loadOptionsBuffer("OPTIONS.XXX"); - - showMessageFromCCode(265, 150, 0); - _screen->updateScreen(); - openTalkFile(0); - _currentTalkFile = 1; - openTalkFile(1); - } else { - _optionsBuffer = _cCodeBuffer; - } - - showMessage(0, 207); - - _screen->setShapePages(5, 3); - - memset(&_mainCharacter, 0, sizeof(_mainCharacter)); - _mainCharacter.height = 0x30; - _mainCharacter.facing = 4; - _mainCharacter.animFrame = 0x12; - memset(_mainCharacter.inventory, -1, sizeof(_mainCharacter.inventory)); - - memset(_sceneAnims, 0, sizeof(_sceneAnims)); - for (int i = 0; i < ARRAYSIZE(_sceneAnimMovie); ++i) - _sceneAnimMovie[i] = new WSAMovieV2(this, _screen); - memset(_wsaSlots, 0, sizeof(_wsaSlots)); - for (int i = 0; i < ARRAYSIZE(_wsaSlots); ++i) - _wsaSlots[i] = new WSAMovieV2(this, _screen); - - _screen->_curPage = 0; - - _talkObjectList = new TalkObject[72]; - memset(_talkObjectList, 0, sizeof(TalkObject)*72); - _shapeDescTable = new ShapeDesc[55]; - memset(_shapeDescTable, 0, sizeof(ShapeDesc)*55); - - for (int i = 9; i <= 32; ++i) { - _shapeDescTable[i-9].width = 30; - _shapeDescTable[i-9].height = 55; - _shapeDescTable[i-9].xAdd = -15; - _shapeDescTable[i-9].yAdd = -50; - } - - for (int i = 19; i <= 24; ++i) { - _shapeDescTable[i-9].width = 53; - _shapeDescTable[i-9].yAdd = -51; - } - - _gfxBackUpRect = new uint8[_screen->getRectSize(32, 32)]; - _itemList = new Item[30]; - memset(_itemList, 0, sizeof(Item)*30); - loadButtonShapes(); - resetItemList(); - _loadedZTable = 1; - loadZShapes(_loadedZTable); - initInventoryButtonList(); - setupLangButtonShapes(); - loadInventoryShapes(); - - _res->loadFileToBuf("PALETTE.COL", _screen->_currentPalette, 0x300); - _screen->loadBitmap("_PLAYFLD.CPS", 3, 3, 0); - _screen->copyPage(3, 0); - _screen->showMouse(); - _screen->hideMouse(); - - clearAnimObjects(); - - for (int i = 0; i < 19; ++i) - memset(_conversationState[i], -1, sizeof(int8)*14); - clearCauldronTable(); - memset(_inputColorCode, -1, sizeof(_inputColorCode)); - memset(_newSceneDlgState, 0, sizeof(_newSceneDlgState)); - memset(_hiddenItems, -1, sizeof(_hiddenItems)); - for (int i = 0; i < 23; ++i) - resetCauldronStateTable(i); - - _sceneList = new SceneDesc[86]; - memset(_sceneList, 0, sizeof(SceneDesc)*86); - _sceneListSize = 86; - runStartScript(1, 0); - loadNPCScript(); - - if (_gameToLoad == -1) { - snd_playWanderScoreViaMap(52, 1); - enterNewScene(_mainCharacter.sceneId, _mainCharacter.facing, 0, 0, 1); - saveGame(getSavegameFilename(0), "New Game"); - } else { - loadGame(getSavegameFilename(_gameToLoad)); - } - - _screen->showMouse(); - - if (_menuDirectlyToLoad) - (*_inventoryButtons[0].buttonCallback)(&_inventoryButtons[0]); - - setNextIdleAnimTimer(); - //XXX - setWalkspeed(_configWalkspeed); -} - -void KyraEngine_v2::runLoop() { - _screen->updateScreen(); - - _quitFlag = false; - _runFlag = true; - while (!_quitFlag && _runFlag) { - if (_deathHandler >= 0) { - removeHandItem(); - delay(5); - _drawNoShapeFlag = 0; - _gui->optionsButton(0); - _deathHandler = -1; - } - - if (_system->getMillis() > _nextIdleAnim) - showIdleAnim(); - - if (queryGameFlag(0x159)) { - dinoRide(); - resetGameFlag(0x159); - } - - if (queryGameFlag(0x124) && !queryGameFlag(0x125)) { - _mainCharacter.animFrame = 32; - enterNewScene(39, -1, 0, 0, 0); - } - - if (queryGameFlag(0xD8)) { - resetGameFlag(0xD8); - if (_mainCharacter.sceneId == 34) { - if (queryGameFlag(0xD1)) { - initTalkObject(28); - npcChatSequence(getTableString(0xFA, _cCodeBuffer, 1), 28, 0x83, 0xFA); - deinitTalkObject(28); - enterNewScene(35, 4, 0, 0, 0); - } else if (queryGameFlag(0xD0)) { - initTalkObject(29); - npcChatSequence(getTableString(0xFB, _cCodeBuffer, 1), 29, 0x83, 0xFB); - deinitTalkObject(29); - enterNewScene(33, 6, 0, 0, 0); - } - } - } - - int inputFlag = checkInput(_buttonList, true); - removeInputTop(); - - update(); - - if (inputFlag == 198 || inputFlag == 199) { - _unk3 = _handItemSet; - handleInput(_mouseX, _mouseY); - } - - //if (queryGameFlag(0x1EE) && inputFlag) - // sub_13B19(inputFlag); - - _system->delayMillis(10); - } -} - -void KyraEngine_v2::handleInput(int x, int y) { - setNextIdleAnimTimer(); - if (_unk5) { - _unk5 = 0; - return; - } - - if (!_screen->isMouseVisible()) - return; - - if (_unk3 == -2) { - snd_playSoundEffect(13); - return; - } - - setNextIdleAnimTimer(); - - if (x <= 6 || x >= 312 || y <= 6 || y >= 135) { - bool exitOk = false; - assert(_unk3 + 6 >= 0); - switch (_unk3 + 6) { - case 0: - if (_sceneExit1 != 0xFFFF) - exitOk = true; - break; - - case 1: - if (_sceneExit2 != 0xFFFF) - exitOk = true; - break; - - case 2: - if (_sceneExit3 != 0xFFFF) - exitOk = true; - break; - - case 3: - if (_sceneExit4 != 0xFFFF) - exitOk = true; - break; - - default: - break; - } - - if (exitOk) { - inputSceneChange(x, y, 1, 1); - return; - } - } - - if (checkCharCollision(x, y) >= 0 && _unk3 >= -1) { - runSceneScript2(); - return; - } else if (pickUpItem(x, y)) { - return; - } else { - int skipHandling = 0; - - if (checkItemCollision(x, y) == -1) { - resetGameFlag(0x1EF); - skipHandling = handleInputUnkSub(x, y) ? 1 : 0; - - if (queryGameFlag(0x1EF)) { - resetGameFlag(0x1EF); - return; - } - - if (_unk5) { - _unk5 = 0; - return; - } - } - - if (_deathHandler > -1) - skipHandling = 1; - - if (skipHandling) - return; - - if (checkCharCollision(x, y) >= 0) { - runSceneScript2(); - return; - } - - if (_itemInHand >= 0) { - if (y > 136) - return; - - dropItem(0, _itemInHand, x, y, 1); - } else { - if (_unk3 == -2 || y > 135) - return; - - if (!_unk5) { - inputSceneChange(x, y, 1, 1); - return; - } - - _unk5 = 0; - } - } -} - -bool KyraEngine_v2::handleInputUnkSub(int x, int y) { - if (y > 143 || _deathHandler > -1 || queryGameFlag(0x164)) - return false; - - if (_handItemSet <= -3 && findItem(_mainCharacter.sceneId, 13) >= 0) { - updateCharFacing(); - objectChat(getTableString(0xFC, _cCodeBuffer, 1), 0, 0x83, 0xFC); - return true; - } else { - _emc->init(&_sceneScriptState, &_sceneScriptData); - - _sceneScriptState.regs[1] = x; - _sceneScriptState.regs[2] = y; - _sceneScriptState.regs[3] = 0; - _sceneScriptState.regs[4] = _itemInHand; - - _emc->start(&_sceneScriptState, 1); - - while (_emc->isValid(&_sceneScriptState)) - _emc->run(&_sceneScriptState); - - //XXXsys_unkKeyboad (flush? wait? whatever...) - - if (queryGameFlag(0x1ED)) { - _sound->beginFadeOut(); - _screen->fadeToBlack(); - _showCredits = true; - _runFlag = false; - } - - return _sceneScriptState.regs[3] != 0; - } -} - -void KyraEngine_v2::update() { - updateInput(); - - refreshAnimObjectsIfNeed(); - updateMouse(); - updateSpecialSceneScripts(); - _timer->update(); - updateItemAnimations(); - updateInvWsa(); - fadeMessagePalette(); - _screen->updateScreen(); -} - -void KyraEngine_v2::updateWithText() { - updateInput(); - - updateMouse(); - fadeMessagePalette(); - updateSpecialSceneScripts(); - _timer->update(); - updateItemAnimations(); - updateInvWsa(); - restorePage3(); - drawAnimObjects(); - - if (textEnabled() && _chatText) { - int pageBackUp = _screen->_curPage; - _screen->_curPage = 2; - objectChatPrintText(_chatText, _chatObject); - _screen->_curPage = pageBackUp; - } - - refreshAnimObjects(0); - _screen->updateScreen(); -} - -void KyraEngine_v2::updateMouse() { - int shapeIndex = 0; - int type = 0; - int xOffset = 0, yOffset = 0; - Common::Point mouse = getMousePos(); - - if (mouse.y <= 145) { - if (mouse.x <= 6) { - if (_sceneExit4 != 0xFFFF) { - type = -3; - shapeIndex = 4; - xOffset = 1; - yOffset = 5; - } else { - type = -2; - } - } else if (mouse.x >= 312) { - if (_sceneExit2 != 0xFFFF) { - type = -5; - shapeIndex = 2; - xOffset = 7; - yOffset = 5; - } else { - type = -2; - } - } else if (mouse.y >= 135) { - if (_sceneExit3 != 0xFFFF) { - type = -4; - shapeIndex = 3; - xOffset = 5; - yOffset = 10; - } else { - type = -2; - } - } else if (mouse.y <= 6) { - if (_sceneExit1 != 0xFFFF) { - type = -6; - shapeIndex = 1; - xOffset = 5; - yOffset = 1; - } else { - type = -2; - } - } - } - - for (int i = 0; i < _specialExitCount; ++i) { - if (checkSpecialSceneExit(i, mouse.x, mouse.y)) { - switch (_specialExitTable[20+i]) { - case 0: - type = -6; - shapeIndex = 1; - xOffset = 5; - yOffset = 1; - break; - - case 2: - type = -5; - shapeIndex = 2; - xOffset = 7; - yOffset = 5; - break; - - case 4: - type = -4; - shapeIndex = 3; - xOffset = 5; - yOffset = 7; - break; - - case 6: - type = -3; - shapeIndex = 4; - xOffset = 1; - yOffset = 5; - break; - - default: - break; - } - } - } - - if (type == -2) { - shapeIndex = 5; - xOffset = 5; - yOffset = 9; - } - - if (type != 0 && _handItemSet != type && _screen->isMouseVisible()) { - _mouseState = _handItemSet = type; - _screen->hideMouse(); - _screen->setMouseCursor(xOffset, yOffset, getShapePtr(shapeIndex)); - _screen->showMouse(); - } - - if (type == 0 && _handItemSet != _itemInHand && _screen->isMouseVisible()) { - if ((mouse.y > 145) || (mouse.x > 6 && mouse.x < 312 && mouse.y > 6 && mouse.y < 135)) { - _mouseState = 0; - _handItemSet = _itemInHand; - _screen->hideMouse(); - if (_itemInHand == -1) - _screen->setMouseCursor(0, 0, getShapePtr(0)); - else - _screen->setMouseCursor(8, 15, getShapePtr(_itemInHand+64)); - _screen->showMouse(); - } - } -} - -void KyraEngine_v2::updateInput() { - Common::Event event; - - while (_eventMan->pollEvent(event)) { - switch (event.type) { - case Common::EVENT_QUIT: - _quitFlag = true; - break; - - case Common::EVENT_KEYDOWN: - if (event.kbd.keycode == '.' || event.kbd.keycode == Common::KEYCODE_ESCAPE) - _eventList.push_back(Event(event, true)); - else if (event.kbd.keycode == 'q' && event.kbd.flags == Common::KBD_CTRL) - _quitFlag = true; - else - _eventList.push_back(event); - break; - - case Common::EVENT_LBUTTONDOWN: - _eventList.push_back(Event(event, true)); - break; - - case Common::EVENT_LBUTTONUP: - case Common::EVENT_MOUSEMOVE: - _eventList.push_back(event); - break; - - default: - break; - } - } -} - -int KyraEngine_v2::checkInput(Button *buttonList, bool mainLoop) { - updateInput(); - - int keys = 0; - - while (_eventList.size()) { - Common::Event event = *_eventList.begin(); - bool breakLoop = false; - - 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) && mainLoop) { - const char *saveLoadSlot = getSavegameFilename(9 - (event.kbd.keycode - '0') + 990); - - if (event.kbd.flags == Common::KBD_CTRL) { - loadGame(saveLoadSlot); - _eventList.clear(); - breakLoop = true; - } 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(); - } - break; - - case Common::EVENT_MOUSEMOVE: { - Common::Point pos = getMousePos(); - _mouseX = pos.x; - _mouseY = pos.y; - _screen->updateScreen(); - } break; - - case Common::EVENT_LBUTTONDOWN: - case Common::EVENT_LBUTTONUP: { - Common::Point pos = getMousePos(); - _mouseX = pos.x; - _mouseY = pos.y; - keys = event.type == Common::EVENT_LBUTTONDOWN ? 199 : (200 | 0x800); - breakLoop = true; - } break; - - default: - break; - } - - if (_debugger->isAttached()) - _debugger->onFrame(); - - if (breakLoop) - break; - - _eventList.erase(_eventList.begin()); - } - - return _gui->processButtonList(buttonList, keys | 0x8000); -} - -void KyraEngine_v2::removeInputTop() { - if (!_eventList.empty()) - _eventList.erase(_eventList.begin()); -} - -bool KyraEngine_v2::skipFlag() const { - for (Common::List::const_iterator i = _eventList.begin(); i != _eventList.end(); ++i) { - if (i->causedSkip) - return true; - } - return false; -} - -void KyraEngine_v2::resetSkipFlag(bool removeEvent) { - for (Common::List::iterator i = _eventList.begin(); i != _eventList.end(); ++i) { - if (i->causedSkip) { - if (removeEvent) - _eventList.erase(i); - else - i->causedSkip = false; - return; - } - } -} - -void KyraEngine_v2::delay(uint32 amount, bool updateGame, bool isMainLoop) { - uint32 start = _system->getMillis(); - do { - if (updateGame) { - if (_chatText) - updateWithText(); - else - update(); - } else { - updateInput(); - } - - if (amount > 0) - _system->delayMillis(amount > 10 ? 10 : amount); - } while (!skipFlag() && _system->getMillis() < start + amount && !_quitFlag); -} - -void KyraEngine_v2::cleanup() { - delete [] _inventoryButtons; _inventoryButtons = 0; - - delete [] _gamePlayBuffer; _gamePlayBuffer = 0; - delete [] _unkBuf500Bytes; _unkBuf500Bytes = 0; - delete [] _screenBuffer; _screenBuffer = 0; - delete [] _unkBuf200kByte; _unkBuf200kByte = 0; - - resetNewShapes(_newShapeCount, _newShapeFiledata); - _newShapeFiledata = 0; - _newShapeCount = 0; - - for (int i = 0; i < ARRAYSIZE(_defaultShapeTable); ++i) { - delete [] _defaultShapeTable[i]; - _defaultShapeTable[i] = 0; - } - freeSceneShapePtrs(); - - if (_optionsBuffer != _cCodeBuffer) - delete [] _optionsBuffer; - _optionsBuffer = 0; - delete [] _cCodeBuffer; _cCodeBuffer = 0; - delete [] _chapterBuffer; _chapterBuffer = 0; - - delete [] _talkObjectList; _talkObjectList = 0; - delete [] _shapeDescTable; _shapeDescTable = 0; - - delete [] _gfxBackUpRect; _gfxBackUpRect = 0; - - delete [] _sceneList; _sceneList = 0; - - for (int i = 0; i < ARRAYSIZE(_sceneAnimMovie); ++i) { - delete _sceneAnimMovie[i]; - _sceneAnimMovie[i] = 0; - } - for (int i = 0; i < ARRAYSIZE(_wsaSlots); ++i) { - delete _wsaSlots[i]; - _wsaSlots[i] = 0; - } - for (int i = 0; i < ARRAYSIZE(_buttonShapes); ++i) { - delete [] _buttonShapes[i]; - _buttonShapes[i] = 0; - } -} - -#pragma mark - Localization - -void KyraEngine_v2::loadCCodeBuffer(const char *file) { - char tempString[13]; - strcpy(tempString, file); - changeFileExtension(tempString); - - delete [] _cCodeBuffer; - _cCodeBuffer = _res->fileData(tempString, 0); -} - -void KyraEngine_v2::loadOptionsBuffer(const char *file) { - char tempString[13]; - strcpy(tempString, file); - changeFileExtension(tempString); - - delete [] _optionsBuffer; - _optionsBuffer = _res->fileData(tempString, 0); -} - -void KyraEngine_v2::loadChapterBuffer(int chapter) { - char tempString[14]; - - static const char *chapterFilenames[] = { - "CH1.XXX", "CH2.XXX", "CH3.XXX", "CH4.XXX", "CH5.XXX" - }; - - assert(chapter >= 1 && chapter <= ARRAYSIZE(chapterFilenames)); - strcpy(tempString, chapterFilenames[chapter-1]); - changeFileExtension(tempString); - - delete [] _chapterBuffer; - _chapterBuffer = _res->fileData(tempString, 0); - _currentChapter = chapter; -} - -void KyraEngine_v2::changeFileExtension(char *buffer) { - while (*buffer != '.') - ++buffer; - - ++buffer; - strcpy(buffer, _languageExtension[_lang]); -} - -uint8 *KyraEngine_v2::getTableEntry(uint8 *buffer, int id) { - return buffer + READ_LE_UINT16(buffer + (id<<1)); -} - -char *KyraEngine_v2::getTableString(int id, uint8 *buffer, int decode) { - char *string = (char*)getTableEntry(buffer, id); - - if (decode && _flags.lang != Common::JA_JPN) { - decodeString1(string, _internStringBuf); - decodeString2(_internStringBuf, _internStringBuf); - string = _internStringBuf; - } - - return string; -} - -const char *KyraEngine_v2::getChapterString(int id) { - if (_currentChapter != _newChapterFile) - loadChapterBuffer(_newChapterFile); - - return getTableString(id, _chapterBuffer, 1); -} - -int KyraEngine_v2::decodeString1(const char *src, char *dst) { - static const uint8 decodeTable1[] = { - 0x20, 0x65, 0x74, 0x61, 0x69, 0x6E, 0x6F, 0x73, 0x72, 0x6C, 0x68, - 0x63, 0x64, 0x75, 0x70, 0x6D - }; - - static const uint8 decodeTable2[] = { - 0x74, 0x61, 0x73, 0x69, 0x6F, 0x20, 0x77, 0x62, 0x20, 0x72, 0x6E, - 0x73, 0x64, 0x61, 0x6C, 0x6D, 0x68, 0x20, 0x69, 0x65, 0x6F, 0x72, - 0x61, 0x73, 0x6E, 0x72, 0x74, 0x6C, 0x63, 0x20, 0x73, 0x79, 0x6E, - 0x73, 0x74, 0x63, 0x6C, 0x6F, 0x65, 0x72, 0x20, 0x64, 0x74, 0x67, - 0x65, 0x73, 0x69, 0x6F, 0x6E, 0x72, 0x20, 0x75, 0x66, 0x6D, 0x73, - 0x77, 0x20, 0x74, 0x65, 0x70, 0x2E, 0x69, 0x63, 0x61, 0x65, 0x20, - 0x6F, 0x69, 0x61, 0x64, 0x75, 0x72, 0x20, 0x6C, 0x61, 0x65, 0x69, - 0x79, 0x6F, 0x64, 0x65, 0x69, 0x61, 0x20, 0x6F, 0x74, 0x72, 0x75, - 0x65, 0x74, 0x6F, 0x61, 0x6B, 0x68, 0x6C, 0x72, 0x20, 0x65, 0x69, - 0x75, 0x2C, 0x2E, 0x6F, 0x61, 0x6E, 0x73, 0x72, 0x63, 0x74, 0x6C, - 0x61, 0x69, 0x6C, 0x65, 0x6F, 0x69, 0x72, 0x61, 0x74, 0x70, 0x65, - 0x61, 0x6F, 0x69, 0x70, 0x20, 0x62, 0x6D - }; - - int size = 0; - uint cChar = 0; - while ((cChar = *src++) != 0) { - if (cChar & 0x80) { - cChar &= 0x7F; - int index = (cChar & 0x78) >> 3; - *dst++ = decodeTable1[index]; - ++size; - assert(cChar < sizeof(decodeTable2)); - cChar = decodeTable2[cChar]; - } - - *dst++ = cChar; - ++size; - } - - *dst++ = 0; - return size; -} - -void KyraEngine_v2::decodeString2(const char *src, char *dst) { - if (!src || !dst) - return; - - char out = 0; - while ((out = *src) != 0) { - if (*src == 0x1B) { - ++src; - out = *src + 0x7F; - } - *dst++ = out; - ++src; - } - - *dst = 0; -} - -#pragma mark - - -void KyraEngine_v2::showMessageFromCCode(int id, int16 palIndex, int) { - const char *string = getTableString(id, _cCodeBuffer, 1); - showMessage(string, palIndex); -} - -void KyraEngine_v2::showMessage(const char *string, int16 palIndex) { - _shownMessage = string; - _screen->hideMouse(); - _screen->fillRect(0, 190, 319, 199, 0xCF); - - if (string) { - if (palIndex != -1 || _fadeMessagePalette) { - palIndex *= 3; - memcpy(_messagePal, _screen->_currentPalette + palIndex, 3); - memmove(_screen->_currentPalette + 765, _screen->_currentPalette + palIndex, 3); - _screen->setScreenPalette(_screen->_currentPalette); - } - - int x = _text->getCenterStringX(string, 0, 320); - _text->printText(string, x, 190, 255, 207, 0); - - setTimer1DelaySecs(7); - } - - _fadeMessagePalette = false; - _screen->showMouse(); -} - -void KyraEngine_v2::showChapterMessage(int id, int16 palIndex) { - showMessage(getChapterString(id), palIndex); -} - -void KyraEngine_v2::updateCommandLineEx(int str1, int str2, int16 palIndex) { - char buffer[0x51]; - char *src = buffer; - - strcpy(src, getTableString(str1, _cCodeBuffer, 1)); - - if (_flags.lang != Common::JA_JPN) { - while (*src != 0x20) - ++src; - ++src; - *src = toupper(*src); - } - - strcpy((char*)_unkBuf500Bytes, src); - - if (str2 > 0) { - if (_flags.lang != Common::JA_JPN) - strcat((char*)_unkBuf500Bytes, " "); - strcat((char*)_unkBuf500Bytes, getTableString(str2, _cCodeBuffer, 1)); - } - - showMessage((char*)_unkBuf500Bytes, palIndex); -} - -void KyraEngine_v2::fadeMessagePalette() { - if (!_fadeMessagePalette) - return; - - bool updatePalette = false; - for (int i = 0; i < 3; ++i) { - if (_messagePal[i] >= 4) { - _messagePal[i] -= 4; - updatePalette = true; - } else if (_messagePal[i] != 0) { - _messagePal[i] = 0; - updatePalette = true; - } - } - - if (updatePalette) { - memcpy(_screen->getPalette(0) + 765, _messagePal, 3); - _screen->setScreenPalette(_screen->getPalette(0)); - } else { - _fadeMessagePalette = false; - } -} - -#pragma mark - - -void KyraEngine_v2::loadMouseShapes() { - _screen->loadBitmap("_MOUSE.CSH", 3, 3, 0); - - for (int i = 0; i <= 8; ++i) { - _defaultShapeTable[i] = _screen->makeShapeCopy(_screen->getCPagePtr(3), i); - assert(_defaultShapeTable[i]); - } -} - -void KyraEngine_v2::loadItemShapes() { - _screen->loadBitmap("_ITEMS.CSH", 3, 3, 0); - - for (int i = 64; i <= 239; ++i) { - _defaultShapeTable[i] = _screen->makeShapeCopy(_screen->getCPagePtr(3), i-64); - assert(_defaultShapeTable[i]); - } - - _res->loadFileToBuf("_ITEMHT.DAT", _itemHtDat, sizeof(_itemHtDat)); - assert(_res->getFileSize("_ITEMHT.DAT") == sizeof(_itemHtDat)); - - _screen->_curPage = 0; -} - -void KyraEngine_v2::loadZShapes(int shapes) { - char file[10]; - strcpy(file, "_ZX.SHP"); - - _loadedZTable = shapes; - file[2] = '0' + shapes; - - uint8 *data = _res->fileData(file, 0); - for (int i = 9; i <= 32; ++i) { - delete [] _defaultShapeTable[i]; - _defaultShapeTable[i] = _screen->makeShapeCopy(data, i-9); - assert(_defaultShapeTable[i]); - } - delete [] data; - - _loadedZTable = shapes; -} - -void KyraEngine_v2::loadInventoryShapes() { - int curPageBackUp = _screen->_curPage; - _screen->_curPage = 2; - - _screen->loadBitmap("_PLAYALL.CPS", 3, 3, 0); - - for (int i = 0; i < 10; ++i) { - _defaultShapeTable[240+i] = _screen->encodeShape(_inventoryX[i], _inventoryY[i], 16, 16, 0); - assert(_defaultShapeTable[240+i]); - } - - _screen->_curPage = curPageBackUp; -} - -void KyraEngine_v2::runStartScript(int script, int unk1) { - char filename[14]; - strcpy(filename, "_START0X.EMC"); - filename[7] = script + '0'; - - EMCData scriptData; - EMCState scriptState; - memset(&scriptData, 0, sizeof(EMCData)); - memset(&scriptState, 0, sizeof(EMCState)); - - _emc->load(filename, &scriptData, &_opcodes); - _emc->init(&scriptState, &scriptData); - scriptState.regs[6] = unk1; - _emc->start(&scriptState, 0); - while (_emc->isValid(&scriptState)) - _emc->run(&scriptState); - _emc->unload(&scriptData); -} - -void KyraEngine_v2::loadNPCScript() { - char filename[12]; - strcpy(filename, "_NPC.EMC"); - - if (_flags.platform != Common::kPlatformPC || _flags.isTalkie) { - switch (_lang) { - case 0: - filename[5] = 'E'; - break; - - case 1: - filename[5] = 'F'; - break; - - case 2: - filename[5] = 'G'; - break; - - case 3: - filename[5] = 'J'; - break; - - default: - break; - }; - } - - _emc->load(filename, &_npcScriptData, &_opcodes); -} - -void KyraEngine_v2::runTemporaryScript(const char *filename, int allowSkip, int resetChar, int newShapes, int shapeUnload) { - memset(&_temporaryScriptData, 0, sizeof(_temporaryScriptData)); - memset(&_temporaryScriptState, 0, sizeof(_temporaryScriptState)); - - if (!_emc->load(filename, &_temporaryScriptData, &_opcodesTemporary)) - error("Couldn't load temporary script '%s'", filename); - - _emc->init(&_temporaryScriptState, &_temporaryScriptData); - _emc->start(&_temporaryScriptState, 0); - - _newShapeFlag = -1; - - if (_newShapeFiledata && newShapes) { - resetNewShapes(_newShapeCount, _newShapeFiledata); - _newShapeFiledata = 0; - _newShapeCount = 0; - } - - while (_emc->isValid(&_temporaryScriptState)) - _emc->run(&_temporaryScriptState); - - uint8 *fileData = 0; - - if (newShapes) - _newShapeFiledata = _res->fileData(_newShapeFilename, 0); - - fileData = _newShapeFiledata; - - if (!fileData) { - _emc->unload(&_temporaryScriptData); - return; - } - - if (newShapes) - _newShapeCount = initNewShapes(fileData); - - processNewShapes(allowSkip, resetChar); - - if (shapeUnload) { - resetNewShapes(_newShapeCount, fileData); - _newShapeCount = 0; - _newShapeFiledata = 0; - } - - _emc->unload(&_temporaryScriptData); -} - -#pragma mark - - -void KyraEngine_v2::resetScaleTable() { - Common::set_to(_scaleTable, _scaleTable + ARRAYSIZE(_scaleTable), 0x100); -} - -void KyraEngine_v2::setScaleTableItem(int item, int data) { - if (item >= 1 || item <= 15) - _scaleTable[item-1] = (data << 8) / 100; -} - -int KyraEngine_v2::getScale(int x, int y) { - return _scaleTable[_screen->getLayer(x, y) - 1]; -} - -void KyraEngine_v2::setDrawLayerTableEntry(int entry, int data) { - if (entry >= 1 || entry <= 15) - _drawLayerTable[entry-1] = data; -} - -int KyraEngine_v2::getDrawLayer(int x, int y) { - int layer = _screen->getLayer(x, y); - layer = _drawLayerTable[layer-1]; - if (layer < 0) - layer = 0; - else if (layer >= 7) - layer = 6; - return layer; -} - -void KyraEngine_v2::restorePage3() { - _screen->copyBlockToPage(2, 0, 0, 320, 144, _gamePlayBuffer); -} - -void KyraEngine_v2::backUpPage0() { - if (_screenBuffer) { - _screen->hideMouse(); - memcpy(_screenBuffer, _screen->getCPagePtr(0), 64000); - _screen->showMouse(); - } -} - -void KyraEngine_v2::restorePage0() { - restorePage3(); - if (_screenBuffer) - _screen->copyBlockToPage(0, 0, 0, 320, 200, _screenBuffer); -} - -void KyraEngine_v2::updateCharPal(int unk1) { - static bool unkVar1 = false; - - if (!_useCharPal) - return; - - int layer = _screen->getLayer(_mainCharacter.x1, _mainCharacter.y1); - int palEntry = _charPalTable[layer]; - - if (palEntry != _charPalEntry && unk1) { - const uint8 *src = &_scenePal[(palEntry << 4) * 3]; - uint8 *ptr = _screen->getPalette(0) + 336; - for (int i = 0; i < 48; ++i) { - *ptr -= (*ptr - *src) >> 1; - ++ptr; - ++src; - } - _screen->setScreenPalette(_screen->getPalette(0)); - unkVar1 = true; - _charPalEntry = palEntry; - } else if (unkVar1 || !unk1) { - memcpy(_screen->getPalette(0) + 336, &_scenePal[(palEntry << 4) * 3], 48); - _screen->setScreenPalette(_screen->getPalette(0)); - unkVar1 = false; - } -} - -void KyraEngine_v2::setCharPalEntry(int entry, int value) { - if (entry > 15 || entry < 1) - entry = 1; - if (value > 8 || value < 0) - value = 0; - _charPalTable[entry] = value; - _useCharPal = 1; - _charPalEntry = 0; -} - -int KyraEngine_v2::inputSceneChange(int x, int y, int unk1, int unk2) { - bool refreshNPC = false; - uint16 curScene = _mainCharacter.sceneId; - _pathfinderFlag = 15; - - if (!_unkHandleSceneChangeFlag) { - if (_unk3 == -3) { - if (_sceneList[curScene].exit4 != 0xFFFF) { - x = 4; - y = _sceneEnterY4; - _pathfinderFlag = 7; - } - } else if (_unk3 == -5) { - if (_sceneList[curScene].exit2 != 0xFFFF) { - x = 316; - y = _sceneEnterY2; - _pathfinderFlag = 7; - } - } else if (_unk3 == -6) { - if (_sceneList[curScene].exit1 != 0xFFFF) { - x = _sceneEnterX1; - y = _sceneEnterY1 - 2; - _pathfinderFlag = 14; - } - } else if (_unk3 == -4) { - if (_sceneList[curScene].exit3 != 0xFFFF) { - x = _sceneEnterX3; - y = 147; - _pathfinderFlag = 11; - } - } - } - - int strId = 0; - int vocH = _flags.isTalkie ? 131 : -1; - - if (_pathfinderFlag) { - if (findItem(curScene, 13) >= 0 && _unk3 <= -3) { - strId = 252; - } else if (_itemInHand == 72) { - strId = 257; - } else if (findItem(curScene, 72) >= 0 && _unk3 <= -3) { - strId = 256; - } else if (getInventoryItemSlot(72) != -1 && _unk3 <= -3) { - strId = 257; - } - } - - if (strId) { - updateCharFacing(); - objectChat(getTableString(strId, _cCodeBuffer, 1), 0, vocH, strId); - _pathfinderFlag = 0; - return 0; - } - - if (ABS(_mainCharacter.x1 - x) < 4 && ABS(_mainCharacter.y1 - y) < 2) { - _pathfinderFlag = 0; - return 0; - } - - int curX = _mainCharacter.x1 & ~3; - int curY = _mainCharacter.y1 & ~1; - int dstX = x & ~3; - int dstY = y & ~1; - - int wayLength = findWay(curX, curY, dstX, dstY, _movFacingTable, 600); - _pathfinderFlag = 0; - _timer->disable(5); - - if (wayLength != 0 && wayLength != 0x7D00) - refreshNPC = (trySceneChange(_movFacingTable, unk1, unk2) != 0); - - int charLayer = _screen->getLayer(_mainCharacter.x1, _mainCharacter.y1); - if (_layerFlagTable[charLayer] != 0 && !queryGameFlag(0x163)) { - if (queryGameFlag(0x164)) { - _screen->hideMouse(); - _timer->disable(5); - runTemporaryScript("_ZANBURN.EMC", 0, 1, 1, 0); - _deathHandler = 7; - snd_playWanderScoreViaMap(0x53, 1); - } else { - objectChat(getTableString(0xFD, _cCodeBuffer, 1), 0, 0x83, 0xFD); - setGameFlag(0x164); - _timer->enable(5); - _timer->setCountdown(5, 120); - } - } else if (queryGameFlag(0x164)) { - objectChat(getTableString(0xFE, _cCodeBuffer, 1), 0, 0x83, 0xFE); - resetGameFlag(0x164); - _timer->disable(5); - } - - if (refreshNPC) - enterNewSceneUnk2(0); - - _pathfinderFlag = 0; - return refreshNPC; -} - -bool KyraEngine_v2::checkSpecialSceneExit(int num, int x, int y) { - if (_specialExitTable[0+num] > x || _specialExitTable[5+num] > y || - _specialExitTable[10+num] < x || _specialExitTable[15+num] < y) - return 0; - return 1; -} - -void KyraEngine_v2::moveCharacter(int facing, int x, int y) { - _mainCharacter.facing = facing; - x &= ~3; - y &= ~1; - - _screen->hideMouse(); - switch (facing) { - case 0: - while (y < _mainCharacter.y1) - updateCharPosWithUpdate(); - break; - - case 2: - while (_mainCharacter.x1 < x) - updateCharPosWithUpdate(); - break; - - case 4: - while (y > _mainCharacter.y1) - updateCharPosWithUpdate(); - break; - - case 6: - while (_mainCharacter.x1 > x) - updateCharPosWithUpdate(); - break; - - default: - break; - } - - _screen->showMouse(); -} - -int KyraEngine_v2::updateCharPos(int *table) { - static uint32 nextUpdate = 0; - static const int updateX[] = { 0, 4, 4, 4, 0, -4, -4, -4 }; - static const int updateY[] = { -2, -2, 0, 2, 2, 2, 0, -2 }; - - if (_system->getMillis() < nextUpdate) - return 0; - - int facing = _mainCharacter.facing; - _mainCharacter.x1 += updateX[facing]; - _mainCharacter.y1 += updateY[facing]; - updateCharAnimFrame(0, table); - nextUpdate = _system->getMillis() + _timer->getDelay(0) * _tickLength; - return 1; -} - -void KyraEngine_v2::updateCharPosWithUpdate() { - updateCharPos(0); - update(); -} - -void KyraEngine_v2::updateCharAnimFrame(int charId, int *table) { - static int unkTable1[] = { 0, 0 }; - static const int unkTable2[] = { 17, 0 }; - static const int unkTable3[] = { 10, 0 }; - static const int unkTable4[] = { 24, 0 }; - static const int unkTable5[] = { 19, 0 }; - static const int unkTable6[] = { 21, 0 }; - static const int unkTable7[] = { 31, 0 }; - static const int unkTable8[] = { 26, 0 }; - - Character *character = &_mainCharacter; - ++character->animFrame; - - int facing = character->facing; - - if (table) { - if (table[0] != table[-1] && table[-1] == table[1]) { - facing = getOppositeFacingDirection(table[-1]); - table[0] = table[-1]; - } - } - - if (!facing) { - ++unkTable1[charId]; - } else if (facing == 4) { - ++unkTable1[charId+1]; - } else if (facing == 7 || facing == 1 || facing == 5 || facing == 3) { - if (facing == 7 || facing == 1) { - if (unkTable1[charId] > 2) - facing = 0; - } else { - if (unkTable1[charId+1] > 2) - facing = 4; - } - - unkTable1[charId] = 0; - unkTable1[charId+1] = 0; - } - - if (facing == 0) { - if (character->animFrame < unkTable8[charId]) - character->animFrame = unkTable8[charId]; - - if (character->animFrame > unkTable7[charId]) - character->animFrame = unkTable8[charId]; - } else if (facing == 4) { - if (character->animFrame < unkTable5[charId]) - character->animFrame = unkTable5[charId]; - - if (character->animFrame > unkTable4[charId]) - character->animFrame = unkTable5[charId]; - } else { - if (character->animFrame > unkTable5[charId]) - character->animFrame = unkTable6[charId]; - - if (character->animFrame == unkTable2[charId]) - character->animFrame = unkTable3[charId]; - - if (character->animFrame > unkTable2[charId]) - character->animFrame = unkTable3[charId] + 2; - } - - updateCharacterAnim(charId); -} - -int KyraEngine_v2::checkCharCollision(int x, int y) { - int scale1 = 0, scale2 = 0, scale3 = 0; - int x1 = 0, x2 = 0, y1 = 0, y2 = 0; - scale1 = getScale(_mainCharacter.x1, _mainCharacter.y1); - scale2 = (scale1 * 24) >> 8; - scale3 = (scale1 * 48) >> 8; - - x1 = _mainCharacter.x1 - (scale2 >> 1); - x2 = _mainCharacter.x1 + (scale2 >> 1); - y1 = _mainCharacter.y1 - scale3; - y2 = _mainCharacter.y1; - - if (x >= x1 && x <= x2 && y >= y1 && y <= y2) - return 0; - - return -1; -} - -int KyraEngine_v2::initNewShapes(uint8 *filedata) { - const int lastEntry = MIN(_newShapeLastEntry, 31); - for (int i = 0; i < lastEntry; ++i) { - _defaultShapeTable[33+i] = _screen->getPtrToShape(filedata, i); - ShapeDesc *desc = &_shapeDescTable[24+i]; - desc->xAdd = _newShapeXAdd; - desc->yAdd = _newShapeYAdd; - desc->width = _newShapeWidth; - desc->height = _newShapeHeight; - } - return lastEntry; -} - -void KyraEngine_v2::processNewShapes(int allowSkip, int resetChar) { - setCharacterAnimDim(_newShapeWidth, _newShapeHeight); - - _emc->init(&_temporaryScriptState, &_temporaryScriptData); - _emc->start(&_temporaryScriptState, 1); - - resetSkipFlag(); - - while (_emc->isValid(&_temporaryScriptState)) { - _temporaryScriptExecBit = false; - while (_emc->isValid(&_temporaryScriptState) && !_temporaryScriptExecBit) - _emc->run(&_temporaryScriptState); - - if (_newShapeAnimFrame < 0) - continue; - - _mainCharacter.animFrame = _newShapeAnimFrame + 33; - updateCharacterAnim(0); - if (_chatText) - updateWithText(); - else - update(); - - uint32 delayEnd = _system->getMillis() + _newShapeDelay * _tickLength; - - while ((!skipFlag() || !allowSkip) && _system->getMillis() < delayEnd) { - if (_chatText) - updateWithText(); - else - update(); - - delay(10); - } - - if (skipFlag()) - resetSkipFlag(); - } - - if (resetChar) { - if (_newShapeFlag >= 0) { - _mainCharacter.animFrame = _newShapeFlag + 33; - updateCharacterAnim(0); - if (_chatText) - updateWithText(); - else - update(); - } - - _mainCharacter.animFrame = _characterFrameTable[_mainCharacter.facing]; - updateCharacterAnim(0); - } - - _newShapeFlag = -1; - resetCharacterAnimDim(); -} - -void KyraEngine_v2::resetNewShapes(int count, uint8 *filedata) { - Common::set_to(_defaultShapeTable+33, _defaultShapeTable+33+count, (uint8*)0); - delete [] filedata; - setNextIdleAnimTimer(); -} - -void KyraEngine_v2::setNextIdleAnimTimer() { - _nextIdleAnim = _system->getMillis() + _rnd.getRandomNumberRng(10, 15) * 60 * _tickLength; -} - -void KyraEngine_v2::showIdleAnim() { - static const uint8 scriptMinTable[] = { - 0x00, 0x05, 0x07, 0x08, 0x00, 0x09, 0x0A, 0x0B, 0xFF, 0x00 - }; - - static const uint8 scriptMaxTable[] = { - 0x04, 0x06, 0x07, 0x08, 0x04, 0x09, 0x0A, 0x0B, 0xFF, 0x00 - }; - - if (queryGameFlag(0x159) && _flags.isTalkie) - return; - - static bool scriptAnimation = false; - if (!scriptAnimation && _flags.isTalkie) { - scriptAnimation = true; - zanthRandomIdleChat(); - } else { - scriptAnimation = false; - if (_loadedZTable > 8) - return; - - int scriptMin = scriptMinTable[_loadedZTable-1]; - int scriptMax = scriptMaxTable[_loadedZTable-1]; - int script = 0; - - if (scriptMin < scriptMax) { - do { - script = _rnd.getRandomNumberRng(scriptMin, scriptMax); - } while (script == _lastIdleScript); - } else { - script = scriptMin; - } - - runIdleScript(script); - _lastIdleScript = script; - } -} - -void KyraEngine_v2::runIdleScript(int script) { - if (script < 0 || script >= 12) - script = 0; - - if (_mainCharacter.animFrame != 18) { - setNextIdleAnimTimer(); - } else { - // FIXME: move this to staticres.cpp? - static const char *idleScriptFiles[] = { - "_IDLHAIR.EMC", "_IDLDUST.EMC", "_IDLLEAN.EMC", "_IDLDIRT.EMC", "_IDLTOSS.EMC", "_IDLNOSE.EMC", - "_IDLBRSH.EMC", "_Z3IDLE.EMC", "_Z4IDLE.EMC", "_Z6IDLE.EMC", "_Z7IDLE.EMC", "_Z8IDLE.EMC" - }; - - runTemporaryScript(idleScriptFiles[script], 1, 1, 1, 1); - } -} - -#pragma mark - - -void KyraEngine_v2::backUpGfxRect24x24(int x, int y) { - _screen->copyRegionToBuffer(_screen->_curPage, x, y, 24, 24, _gfxBackUpRect); -} - -void KyraEngine_v2::restoreGfxRect24x24(int x, int y) { - _screen->copyBlockToPage(_screen->_curPage, x, y, 24, 24, _gfxBackUpRect); -} - -void KyraEngine_v2::backUpGfxRect32x32(int x, int y) { - _screen->copyRegionToBuffer(_screen->_curPage, x, y, 32, 32, _gfxBackUpRect); -} - -void KyraEngine_v2::restoreGfxRect32x32(int x, int y) { - _screen->copyBlockToPage(_screen->_curPage, x, y, 32, 32, _gfxBackUpRect); -} - -#pragma mark - - -void KyraEngine_v2::openTalkFile(int newFile) { - debugC(9, kDebugLevelMain | kDebugLevelSound, "KyraEngine_v2::openTalkFile(%d)", newFile); - char talkFilename[16]; - - if (_oldTalkFile > 0) { - sprintf(talkFilename, "CH%dVOC.TLK", _oldTalkFile); - _res->unloadPakFile(talkFilename); - _oldTalkFile = -1; - } - - if (newFile == 0) { - strcpy(talkFilename, "ANYTALK.TLK"); - _res->loadPakFile(talkFilename); - } else { - sprintf(talkFilename, "CH%dVOC.TLK", newFile); - _res->loadPakFile(talkFilename); - } - - _oldTalkFile = newFile; -} - -void KyraEngine_v2::snd_playVoiceFile(int id) { - debugC(9, kDebugLevelMain | kDebugLevelSound, "KyraEngine_v2::snd_playVoiceFile(%d)", id); - char vocFile[9]; - assert(id >= 0 && id <= 9999999); - sprintf(vocFile, "%07d", id); - if (_sound->voiceFileIsPresent(vocFile)) { - snd_stopVoice(); - - while (!_sound->voicePlay(vocFile)) { - updateWithText(); - _system->delayMillis(10); - } - - _speechFile = vocFile; - } -} - -void KyraEngine_v2::snd_loadSoundFile(int id) { - debugC(9, kDebugLevelMain | kDebugLevelSound, "KyraEngine_v2::snd_loadSoundFile(%d)", id); - if (id < 0 || !_trackMap) - return; - - assert(id < _trackMapSize); - int file = _trackMap[id*2]; - _curSfxFile = _curMusicTheme = file; - _sound->loadSoundFile(file); -} - -void KyraEngine_v2::playVoice(int high, int low) { - debugC(9, kDebugLevelMain | kDebugLevelSound, "KyraEngine_v2::playVoice(%d, %d)", high, low); - if (!_flags.isTalkie) - return; - int vocFile = high * 10000 + low * 10; - snd_playVoiceFile(vocFile); -} - -void KyraEngine_v2::snd_playSoundEffect(int track, int volume) { - debugC(9, kDebugLevelMain | kDebugLevelSound, "KyraEngine_v2::snd_playSoundEffect(%d, %d)", track, volume); - - if (_flags.platform == Common::kPlatformFMTowns || _flags.platform == Common::kPlatformPC98) { - if (track == 10) - track = _lastSfxTrack; - - if (track == 10 || track == -1) - return; - - _lastSfxTrack = track; - } - - int16 vocIndex = (int16)READ_LE_UINT16(&_ingameSoundIndex[track * 2]); - if (vocIndex != -1) - _sound->voicePlay(_ingameSoundList[vocIndex], true); - else if (_flags.platform == Common::kPlatformPC) - // TODO ?? Maybe there is a way to let users select whether they want - // voc, midi or adl sfx (even though it makes no sense to choose anything but voc). - KyraEngine::snd_playSoundEffect(track); -} - -#pragma mark - - -void KyraEngine_v2::loadInvWsa(const char *filename, int run, int delayTime, int page, int sfx, int sFrame, int flags) { - int wsaFlags = 1; - if (flags) - wsaFlags |= 2; - - if (!_invWsa.wsa) - _invWsa.wsa = new WSAMovieV2(this, _screen); - - if (!_invWsa.wsa->open(filename, wsaFlags, 0)) - error("Couldn't open inventory WSA file '%s'", filename); - - _invWsa.curFrame = 0; - _invWsa.lastFrame = _invWsa.wsa->frames(); - - _invWsa.x = _invWsa.wsa->xAdd(); - _invWsa.y = _invWsa.wsa->yAdd(); - _invWsa.w = _invWsa.wsa->width(); - _invWsa.h = _invWsa.wsa->height(); - _invWsa.x2 = _invWsa.x + _invWsa.w - 1; - _invWsa.y2 = _invWsa.y + _invWsa.h - 1; - - _invWsa.delay = delayTime; - _invWsa.page = page; - _invWsa.sfx = sfx; - - _invWsa.specialFrame = sFrame; - - if (_invWsa.page) - _screen->copyRegion(_invWsa.x, _invWsa.y, _invWsa.x, _invWsa.y, _invWsa.w, _invWsa.h, 0, _invWsa.page, Screen::CR_NO_P_CHECK); - - _invWsa.running = true; - _invWsa.timer = _system->getMillis(); - - if (run) { - while (_invWsa.running && !skipFlag() && !_quitFlag) { - update(); - _system->delayMillis(10); - } - - if (skipFlag()) { - resetSkipFlag(); - displayInvWsaLastFrame(); - } - } -} - -void KyraEngine_v2::closeInvWsa() { - _invWsa.wsa->close(); - delete _invWsa.wsa; - _invWsa.wsa = 0; - _invWsa.running = false; -} - -void KyraEngine_v2::updateInvWsa() { - if (!_invWsa.running || !_invWsa.wsa) - return; - - if (_invWsa.timer > _system->getMillis()) - return; - - _invWsa.wsa->setX(0); - _invWsa.wsa->setY(0); - _invWsa.wsa->setDrawPage(_invWsa.page); - _invWsa.wsa->displayFrame(_invWsa.curFrame, 0, 0, 0); - - if (_invWsa.page) - _screen->copyRegion(_invWsa.x, _invWsa.y, _invWsa.x, _invWsa.y, _invWsa.w, _invWsa.h, _invWsa.page, 0, Screen::CR_NO_P_CHECK); - - _invWsa.timer = _system->getMillis() + _invWsa.delay * _tickLength; - - ++_invWsa.curFrame; - if (_invWsa.curFrame >= _invWsa.lastFrame) - displayInvWsaLastFrame(); - - if (_invWsa.curFrame == _invWsa.specialFrame) - snd_playSoundEffect(_invWsa.sfx); - - if (_invWsa.sfx == -2) { - switch (_invWsa.curFrame) { - case 9: case 27: case 40: - snd_playSoundEffect(0x39); - break; - - case 18: case 34: case 44: - snd_playSoundEffect(0x33); - break; - - case 48: - snd_playSoundEffect(0x38); - break; - - default: - break; - } - } -} - -void KyraEngine_v2::displayInvWsaLastFrame() { - if (!_invWsa.wsa) - return; - - _invWsa.wsa->setX(0); - _invWsa.wsa->setY(0); - _invWsa.wsa->setDrawPage(_invWsa.page); - _invWsa.wsa->displayFrame(_invWsa.lastFrame-1, 0, 0, 0); - - if (_invWsa.page) - _screen->copyRegion(_invWsa.x, _invWsa.y, _invWsa.x, _invWsa.y, _invWsa.w, _invWsa.h, _invWsa.page, 0, Screen::CR_NO_P_CHECK); - - closeInvWsa(); - - int32 countdown = _rnd.getRandomNumberRng(45, 80); - _timer->setCountdown(2, countdown * 60); -} - -#pragma mark - - -void KyraEngine_v2::setCauldronState(uint8 state, bool paletteFade) { - memcpy(_screen->getPalette(2), _screen->getPalette(0), 768); - Common::SeekableReadStream *file = _res->getFileStream("_POTIONS.PAL"); - if (!file) - error("Couldn't load cauldron palette"); - file->seek(state*18, SEEK_SET); - file->read(_screen->getPalette(2)+723, 18); - delete file; - file = 0; - - if (paletteFade) { - snd_playSoundEffect((state == 0) ? 0x6B : 0x66); - _screen->fadePalette(_screen->getPalette(2), 0x4B, &_updateFunctor); - } else { - _screen->setScreenPalette(_screen->getPalette(2)); - _screen->updateScreen(); - } - - memcpy(_screen->getPalette(0)+723, _screen->getPalette(2)+723, 18); - _cauldronState = state; - _cauldronUseCount = 0; - //if (state == 5) - // sub_27149(); -} - -void KyraEngine_v2::clearCauldronTable() { - Common::set_to(_cauldronTable, _cauldronTable+ARRAYSIZE(_cauldronTable), -1); -} - -void KyraEngine_v2::addFrontCauldronTable(int item) { - for (int i = 23; i >= 0; --i) - _cauldronTable[i+1] = _cauldronTable[i]; - _cauldronTable[0] = item; -} - -void KyraEngine_v2::cauldronItemAnim(int item) { - const int x = 282; - const int y = 135; - const int mouseDstX = (x + 7) & (~1); - const int mouseDstY = (y + 15) & (~1); - int mouseX = _mouseX & (~1); - int mouseY = _mouseY & (~1); - - while (mouseY != mouseDstY) { - if (mouseY < mouseDstY) - mouseY += 2; - else if (mouseY > mouseDstY) - mouseY -= 2; - uint32 waitEnd = _system->getMillis() + _tickLength; - setMousePos(mouseX, mouseY); - _system->updateScreen(); - delayUntil(waitEnd); - } - - while (mouseX != mouseDstX) { - if (mouseX < mouseDstX) - mouseX += 2; - else if (mouseX > mouseDstX) - mouseX -= 2; - uint32 waitEnd = _system->getMillis() + _tickLength; - setMousePos(mouseX, mouseY); - _system->updateScreen(); - delayUntil(waitEnd); - } - - if (itemIsFlask(item)) { - setHandItem(19); - delayUntil(_system->getMillis()+_tickLength*30); - setHandItem(18); - } else { - _screen->hideMouse(); - backUpGfxRect32x32(x, y); - uint8 *shape = getShapePtr(item+64); - - int curY = y; - for (int i = 0; i < 12; i += 2, curY += 2) { - restoreGfxRect32x32(x, y); - uint32 waitEnd = _system->getMillis() + _tickLength; - _screen->drawShape(0, shape, x, curY, 0, 0); - _screen->updateScreen(); - delayUntil(waitEnd); - } - - snd_playSoundEffect(0x17); - - for (int i = 16; i > 0; i -= 2, curY += 2) { - _screen->setNewShapeHeight(shape, i); - restoreGfxRect32x32(x, y); - uint32 waitEnd = _system->getMillis() + _tickLength; - _screen->drawShape(0, shape, x, curY, 0, 0); - _screen->updateScreen(); - delayUntil(waitEnd); - } - - restoreGfxRect32x32(x, y); - _screen->resetShapeHeight(shape); - removeHandItem(); - _screen->showMouse(); - } -} - -bool KyraEngine_v2::updateCauldron() { - for (int i = 0; i < 23; ++i) { - const int16 *curStateTable = _cauldronStateTables[i]; - if (*curStateTable == -2) - continue; - - int cauldronState = i; - int16 cauldronTable[25]; - memcpy(cauldronTable, _cauldronTable, sizeof(cauldronTable)); - - while (*curStateTable != -2) { - int stateValue = *curStateTable++; - int j = 0; - for (; j < 25; ++j) { - int val = cauldronTable[j]; - - switch (val) { - case 68: - val = 70; - break; - - case 133: - case 167: - val = 119; - break; - - case 130: - case 143: - case 100: - val = 12; - break; - - case 132: - case 65: - case 69: - case 74: - val = 137; - break; - - case 157: - val = 134; - break; - - default: - break; - } - - if (val == stateValue) { - cauldronTable[j] = -1; - j = 26; - } - } - - if (j == 25) - cauldronState = -1; - } - - if (cauldronState >= 0) { - showMessage(0, 0xCF); - setCauldronState(cauldronState, true); - if (cauldronState == 7) - objectChat(getTableString(0xF2, _cCodeBuffer, 1), 0, 0x83, 0xF2); - clearCauldronTable(); - return true; - } - } - - return false; -} - -void KyraEngine_v2::cauldronRndPaletteFade() { - showMessage(0, 0xCF); - int index = _rnd.getRandomNumberRng(0x0F, 0x16); - Common::SeekableReadStream *file = _res->getFileStream("_POTIONS.PAL"); - if (!file) - error("Couldn't load cauldron palette"); - file->seek(index*18, SEEK_SET); - file->read(_screen->getPalette(0)+723, 18); - snd_playSoundEffect(0x6A); - _screen->fadePalette(_screen->getPalette(0), 0x1E, &_updateFunctor); - file->seek(0, SEEK_SET); - file->read(_screen->getPalette(0)+723, 18); - delete file; - _screen->fadePalette(_screen->getPalette(0), 0x1E, &_updateFunctor); -} - -void KyraEngine_v2::resetCauldronStateTable(int idx) { - for (int i = 0; i < 7; ++i) - _cauldronStateTables[idx][i] = -2; -} - -bool KyraEngine_v2::addToCauldronStateTable(int data, int idx) { - for (int i = 0; i < 7; ++i) { - if (_cauldronStateTables[idx][i] == -2) { - _cauldronStateTables[idx][i] = data; - return true; - } - } - return false; -} - -void KyraEngine_v2::listItemsInCauldron() { - int itemsInCauldron = 0; - for (int i = 0; i < 25; ++i) { - if (_cauldronTable[i] != -1) - ++itemsInCauldron; - else - break; - } - - if (!itemsInCauldron) { - if (!_cauldronState) - objectChat(getTableString(0xF4, _cCodeBuffer, 1), 0, 0x83, 0xF4); - else - objectChat(getTableString(0xF3, _cCodeBuffer, 1), 0, 0x83, 0xF3); - } else { - objectChat(getTableString(0xF7, _cCodeBuffer, 1), 0, 0x83, 0xF7); - - char buffer[80]; - for (int i = 0; i < itemsInCauldron-1; ++i) { - char *str = buffer; - strcpy(str, getTableString(_cauldronTable[i]+54, _cCodeBuffer, 1)); - if (_lang == 1) { - if (*str == 37) - str += 2; - } - strcpy((char*)_unkBuf500Bytes, "..."); - strcat((char*)_unkBuf500Bytes, str); - strcat((char*)_unkBuf500Bytes, "..."); - objectChat((const char*)_unkBuf500Bytes, 0, 0x83, _cauldronTable[i]+54); - } - - char *str = buffer; - strcpy(str, getTableString(_cauldronTable[itemsInCauldron-1]+54, _cCodeBuffer, 1)); - if (_lang == 1) { - if (*str == 37) - str += 2; - } - strcpy((char*)_unkBuf500Bytes, "..."); - strcat((char*)_unkBuf500Bytes, str); - strcat((char*)_unkBuf500Bytes, "."); - objectChat((const char*)_unkBuf500Bytes, 0, 0x83, _cauldronTable[itemsInCauldron-1]+54); - } -} - -#pragma mark - - -void KyraEngine_v2::dinoRide() { - _mainCharX = _mainCharY = -1; - - setGameFlag(0x15A); - enterNewScene(41, -1, 0, 0, 0); - resetGameFlag(0x15A); - - setGameFlag(0x15B); - enterNewScene(39, -1, 0, 0, 0); - resetGameFlag(0x15B); - - setGameFlag(0x16F); - - setGameFlag(0x15C); - enterNewScene(42, -1, 0, 0, 0); - resetGameFlag(0x15C); - - setGameFlag(0x15D); - enterNewScene(39, -1, 0, 0, 0); - resetGameFlag(0x15D); - - setGameFlag(0x15E); - enterNewScene(40, -1, 0, 0, 0); - resetGameFlag(0x15E); - - _mainCharX = 262; - _mainCharY = 28; - _mainCharacter.facing = 5; - _mainCharacter.animFrame = _characterFrameTable[5]; - enterNewScene(39, 4, 0, 0, 0); - setHandItem(0x61); - _screen->showMouse(); - resetGameFlag(0x159); -} - -#pragma mark - - -void KyraEngine_v2::playTim(const char *filename) { - TIM *tim = _tim->load(filename, &_timOpcodes); - if (!tim) - return; - - _tim->resetFinishedFlag(); - while (!_quitFlag && !_tim->finished()) { - _tim->exec(tim, 0); - if (_chatText) - updateWithText(); - else - update(); - delay(10); - } - - _tim->unload(tim); -} - -#pragma mark - - -void KyraEngine_v2::registerDefaultSettings() { - KyraEngine::registerDefaultSettings(); - - // Most settings already have sensible defaults. This one, however, is - // specific to the Kyra engine. - ConfMan.registerDefault("walkspeed", 5); -} - -void KyraEngine_v2::writeSettings() { - ConfMan.setInt("talkspeed", ((_configTextspeed-2) * 255) / 95); - - switch (_lang) { - case 1: - _flags.lang = Common::FR_FRA; - break; - - case 2: - _flags.lang = Common::DE_DEU; - break; - - case 3: - _flags.lang = Common::JA_JPN; - break; - - case 0: - default: - _flags.lang = Common::EN_ANY; - break; - } - - ConfMan.set("language", Common::getLanguageCode(_flags.lang)); - - KyraEngine::writeSettings(); -} - -void KyraEngine_v2::readSettings() { - int talkspeed = ConfMan.getInt("talkspeed"); - _configTextspeed = (talkspeed*95)/255 + 2; - KyraEngine::readSettings(); -} - -} // end of namespace Kyra - - - - diff --git a/engines/kyra/kyra_v2.h b/engines/kyra/kyra_v2.h deleted file mode 100644 index 7cd1f609dd..0000000000 --- a/engines/kyra/kyra_v2.h +++ /dev/null @@ -1,1166 +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_V2_H -#define KYRA_KYRA_V2_H - -#include "kyra/kyra.h" -#include "kyra/script.h" -#include "kyra/script_tim.h" -#include "kyra/screen_v2.h" -#include "kyra/text_v2.h" -#include "kyra/gui_v2.h" - -#include "common/list.h" -#include "common/func.h" - -namespace Kyra { - -enum kSequences { - kSequenceVirgin = 0, - kSequenceWestwood, - kSequenceTitle, - kSequenceOverview, - kSequenceLibrary, - kSequenceHand, - kSequencePoint, - kSequenceZanfaun, - - kSequenceFunters, - kSequenceFerb, - kSequenceFish, - kSequenceFheep, - kSequenceFarmer, - kSequenceFuards, - kSequenceFirates, - kSequenceFrash, - - kSequenceArraySize -}; - -enum kNestedSequences { - kSequenceFiggle = 0, - kSequenceOver1, - kSequenceOver2, - kSequenceForest, - kSequenceDragon, - kSequenceDarm, - kSequenceLibrary2, - kSequenceLibrary3, - kSequenceMarco, - kSequenceHand1a, - kSequenceHand1b, - kSequenceHand1c, - kSequenceHand2, - kSequenceHand3, - kSequenceHand4 -}; - -enum kSequencesDemo { - kSequenceDemoVirgin = 0, - kSequenceDemoWestwood, - kSequenceDemoTitle, - kSequenceDemoHill, - kSequenceDemoOuthome, - kSequenceDemoWharf, - kSequenceDemoDinob, - kSequenceDemoFisher -}; - -enum kNestedSequencesDemo { - kSequenceDemoWharf2 = 0, - kSequenceDemoDinob2, - kSequenceDemoWater, - kSequenceDemoBail, - kSequenceDemoDig -}; - -class WSAMovieV2; -class KyraEngine_v2; -class TextDisplayer_v2; -class Debugger_v2; - -struct TIM; - -typedef int (KyraEngine_v2::*SeqProc)(WSAMovieV2*, int, int, int); - -struct FrameControl { - uint16 index; - uint16 delay; -}; - -struct ActiveWSA { - int16 flags; - WSAMovieV2 *movie; - uint16 startFrame; - uint16 endFrame; - uint16 frameDelay; - SeqProc callback; - uint32 nextFrame; - uint16 currentFrame; - uint16 lastFrame; - uint16 x; - uint16 y; - const FrameControl *control; - uint16 startupCommand; - uint16 finalCommand; -}; - -struct ActiveText { - uint16 strIndex; - uint16 x; - uint16 y; - int duration; - uint16 width; - uint32 startTime; - int16 textcolor; -}; - -struct Sequence { - uint16 flags; - const char * wsaFile; - const char * cpsFile; - uint8 startupCommand; - uint8 finalCommand; - int16 stringIndex1; - int16 stringIndex2; - uint16 startFrame; - uint16 numFrames; - uint16 frameDelay; - uint16 xPos; - uint16 yPos; - uint16 duration; -}; - -struct NestedSequence { - uint16 flags; - const char * wsaFile; - uint16 startframe; - uint16 endFrame; - uint16 frameDelay; - uint16 x; - uint16 y; - const FrameControl *wsaControl; - uint16 startupCommand; - uint16 finalCommand; -}; - -struct HofSeqData { - const Sequence *seq; - int numSeq; - const NestedSequence *seqn; - int numSeqn; -}; - -struct ItemAnimData_v1 { - int16 itemIndex; - uint16 y; - const uint16 *frames; -}; - -struct ItemAnimData_v2 { - int16 itemIndex; - uint8 numFrames; - const FrameControl *frames; -}; - -struct ActiveItemAnim { - uint16 currentFrame; - uint32 nextFrame; -}; - -class KyraEngine_v2 : public KyraEngine { -friend class Debugger_v2; -friend class TextDisplayer_v2; -friend class GUI_v2; -public: - KyraEngine_v2(OSystem *system, const GameFlags &flags); - ~KyraEngine_v2(); - - virtual Screen *screen() { return _screen; } - Screen_v2 *screen_v2() { return _screen; } - virtual TextDisplayer *text() { return _text; } - int language() const { return _lang; } -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); - - void seq_sequenceCommand(int command); - void seq_loadNestedSequence(int wsaNum, int seqNum); - void seq_nestedSequenceFrame(int command, int wsaNum); - void seq_animatedSubFrame(int srcPage, int dstPage, int delaytime, - int steps, int x, int y, int w, int h, int openClose, int directionFlags); - bool seq_processNextSubFrame(int wsaNum); - void seq_resetActiveWSA(int wsaNum); - void seq_unloadWSA(int wsaNum); - void seq_processWSAs(); - void seq_cmpFadeFrame(const char *cmpFile); - void seq_playTalkText(uint8 chatNum); - void seq_resetAllTextEntries(); - uint32 seq_activeTextsTimeLeft(); - void seq_waitForTextsTimeout(); - int seq_setTextEntry(uint16 strIndex, uint16 posX, uint16 posY, int duration, uint16 width); - void seq_processText(); - 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); - 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(); - void seq_showStarcraftLogo(); - - void seq_init(); - void seq_uninit(); - - int init(); - int go(); - - Screen_v2 *_screen; - TextDisplayer_v2 *_text; - Debugger_v2 *_debugger; - TIMInterpreter *_tim; - - uint8 *_mouseSHPBuf; - - static const int8 _dosTrackMap[]; - static const int _dosTrackMapSize; - - const AudioDataStruct *_soundData; - -protected: - // game initialization - void startup(); - void runLoop(); - void cleanup(); - - void registerDefaultSettings(); - void writeSettings(); - void readSettings(); - uint8 _configTextspeed; - - // 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(); - - void setupTimers(); - void setupOpcodeTable(); - - void loadMouseShapes(); - void loadItemShapes(); - - // run - MainMenu *_menu; - - bool _runFlag; - bool _showCredits; - - void update(); - void updateWithText(); - - Common::Functor0Mem _updateFunctor; - - void updateMouse(); - - void dinoRide(); - - int checkInput(Button *buttonList, bool mainLoop = false); - void removeInputTop(); - void handleInput(int x, int y); - bool handleInputUnkSub(int x, int y); - - int inputSceneChange(int x, int y, int unk1, int unk2); - - // - Input - void updateInput(); - - int _mouseX, _mouseY; - int _mouseState; - - struct Event { - Common::Event event; - bool causedSkip; - - Event() : event(), causedSkip(false) {} - Event(Common::Event e) : event(e), causedSkip(false) {} - Event(Common::Event e, bool skip) : event(e), causedSkip(skip) {} - - operator Common::Event() const { return event; } - }; - Common::List _eventList; - - bool skipFlag() const; - void resetSkipFlag(bool removeEvent = true); - - // gfx/animation specific - uint8 *_gamePlayBuffer; - void restorePage3(); - - uint8 *_screenBuffer; - bool _inventorySaved; - void backUpPage0(); - void restorePage0(); - - uint8 *_gfxBackUpRect; - - void backUpGfxRect24x24(int x, int y); - void restoreGfxRect24x24(int x, int y); - void backUpGfxRect32x32(int x, int y); - void restoreGfxRect32x32(int x, int y); - - uint8 *getShapePtr(int index) { return _defaultShapeTable[index]; } - uint8 *_defaultShapeTable[250]; - uint8 *_sceneShapeTable[50]; - - WSAMovieV2 *_wsaSlots[10]; - - void freeSceneShapePtrs(); - - struct ShapeDesc { - uint8 unk0, unk1, unk2, unk3, unk4; - uint16 width, height; - int16 xAdd, yAdd; - }; - - ShapeDesc *_shapeDescTable; - - struct SceneAnim { - uint16 flags; - int16 x, y; - int16 x2, y2; - int16 width, height; - uint16 unkE; - uint16 specialSize; - uint16 unk12; - int16 shapeIndex; - uint16 wsaFlag; - char filename[14]; - }; - - SceneAnim _sceneAnims[10]; - WSAMovieV2 *_sceneAnimMovie[10]; - bool _specialSceneScriptState[10]; - bool _specialSceneScriptStateBackup[10]; - EMCState _sceneSpecialScripts[10]; - uint32 _sceneSpecialScriptsTimer[10]; - int _lastProcessedSceneScript; - bool _specialSceneScriptRunFlag; - - void updateSpecialSceneScripts(); - void freeSceneAnims(); - - int _loadedZTable; - void loadZShapes(int shapes); - void loadInventoryShapes(); - - void resetScaleTable(); - void setScaleTableItem(int item, int data); - int getScale(int x, int y); - uint16 _scaleTable[15]; - - void setDrawLayerTableEntry(int entry, int data); - int getDrawLayer(int x, int y); - int _drawLayerTable[15]; - - int _layerFlagTable[16]; // seems to indicate layers where items get destroyed when dropped to (TODO: check this!) - - char _newShapeFilename[13]; - int _newShapeLastEntry; - int _newShapeWidth, _newShapeHeight; - int _newShapeXAdd, _newShapeYAdd; - int _newShapeFlag; - uint8 *_newShapeFiledata; - int _newShapeCount; - int _newShapeAnimFrame; - int _newShapeDelay; - - int initNewShapes(uint8 *filedata); - void processNewShapes(int allowSkip, int resetChar); - void resetNewShapes(int count, uint8 *filedata); - - // animator - struct AnimObj { - uint16 index; - uint16 type; - uint16 enabled; - uint16 needRefresh; - uint16 unk8; - uint16 animFlags; - uint16 flags; - int16 xPos1, yPos1; - uint8 *shapePtr; - uint16 shapeIndex1; - uint16 animNum; - uint16 shapeIndex3; - uint16 shapeIndex2; - uint16 unk1E; - uint8 unk20; - uint8 unk21; - uint8 unk22; - uint8 unk23; - int16 xPos2, yPos2; - int16 xPos3, yPos3; - int16 width, height; - int16 width2, height2; - AnimObj *nextObject; - }; - - AnimObj _animObjects[42]; - void clearAnimObjects(); - - AnimObj *_animList; - bool _drawNoShapeFlag; - AnimObj *initAnimList(AnimObj *list, AnimObj *entry); - AnimObj *addToAnimListSorted(AnimObj *list, AnimObj *entry); - AnimObj *deleteAnimListEntry(AnimObj *list, AnimObj *entry); - - void drawAnimObjects(); - void drawSceneAnimObject(AnimObj *obj, int x, int y, int drawLayer); - void drawCharacterAnimObject(AnimObj *obj, int x, int y, int drawLayer); - - void refreshAnimObjects(int force); - void refreshAnimObjectsIfNeed(); - void updateItemAnimations(); - - void flagAnimObjsUnk8(); - void flagAnimObjsForRefresh(); - - void updateCharFacing(); - void updateCharacterAnim(int); - void updateSceneAnim(int anim, int newFrame); - - void addItemToAnimList(int item); - void deleteItemAnimEntry(int item); - - int _animObj0Width, _animObj0Height; - void setCharacterAnimDim(int w, int h); - void resetCharacterAnimDim(); - - // scene - struct SceneDesc { - char filename[10]; - uint16 exit1, exit2, exit3, exit4; - uint8 flags; - uint8 sound; - }; - - SceneDesc *_sceneList; - int _sceneListSize; - uint16 _currentScene; - - const char *_sceneCommentString; - uint16 _sceneExit1, _sceneExit2, _sceneExit3, _sceneExit4; - int _sceneEnterX1, _sceneEnterY1, _sceneEnterX2, _sceneEnterY2, - _sceneEnterX3, _sceneEnterY3, _sceneEnterX4, _sceneEnterY4; - int _specialExitCount; - uint16 _specialExitTable[25]; - bool checkSpecialSceneExit(int num, int x, int y); - uint8 _scenePal[688]; - bool _overwriteSceneFacing; - - void enterNewScene(uint16 newScene, int facing, int unk1, int unk2, int unk3); - void enterNewSceneUnk1(int facing, int unk1, int unk2); - void enterNewSceneUnk2(int unk1); - void unloadScene(); - - void loadScenePal(); - void loadSceneMsc(); - - void fadeScenePal(int srcIndex, int delay); - - void startSceneScript(int unk1); - void runSceneScript2(); - void runSceneScript4(int unk1); - void runSceneScript6(); - void runSceneScript7(); - - void initSceneAnims(int unk1); - void initSceneScreen(int unk1); - - int trySceneChange(int *moveTable, int unk1, int updateChar); - int checkSceneChange(); - - // pathfinder - int _movFacingTable[600]; - int findWay(int curX, int curY, int dstX, int dstY, int *moveTable, int moveTableSize); - bool lineIsPassable(int x, int y); - bool directLinePassable(int x, int y, int toX, int toY); - - int pathfinderInitPositionTable(int *moveTable); - int pathfinderAddToPositionTable(int index, int v1, int v2); - int pathfinderInitPositionIndexTable(int tableLen, int x, int y); - int pathfinderAddToPositionIndexTable(int index, int v); - void pathfinderFinializePath(int *moveTable, int unk1, int x, int y, int moveTableSize); - - int _pathfinderPositionTable[400]; - int _pathfinderPositionIndexTable[200]; - - // item - uint8 _itemHtDat[176]; - - struct Item { - uint16 id; - uint16 sceneId; - int16 x; - uint8 y; - uint16 unk7; - }; - Item *_itemList; - - uint16 _hiddenItems[20]; - - int findFreeItem(); - int countAllItems(); - int findItem(uint16 sceneId, uint16 id); - int checkItemCollision(int x, int y); - void resetItemList(); - void updateWaterFlasks(); - - int _itemInHand; - int _handItemSet; - - bool dropItem(int unk1, uint16 item, int x, int y, int unk2); - bool processItemDrop(uint16 sceneId, uint16 item, int x, int y, int unk1, int unk2); - void itemDropDown(int startX, int startY, int dstX, int dstY, int itemSlot, uint16 item); - void exchangeMouseItem(int itemPos); - bool pickUpItem(int x, int y); - - bool isDropable(int x, int y); - - static const byte _itemStringMap[]; - static const int _itemStringMapSize; - - void setMouseCursor(uint16 item); - void setHandItem(uint16 item); - void removeHandItem(); - - static const int16 _flaskTable[]; - bool itemIsFlask(int item); - - // inventory - static const int _inventoryX[]; - static const int _inventoryY[]; - static const uint16 _itemMagicTable[]; - - int getInventoryItemSlot(uint16 item); - void removeItemFromInventory(int slot); - bool checkInventoryItemExchange(uint16 item, int slot); - void drawInventoryShape(int page, uint16 item, int slot); - void clearInventorySlot(int slot, int page); - void redrawInventory(int page); - void scrollInventoryWheel(); - int findFreeVisibleInventorySlot(); - - ActiveItemAnim _activeItemAnim[15]; - int _nextAnimItem; - - // gui - bool _menuDirectlyToLoad; - GUI_v2 *_gui; - - void loadButtonShapes(); - void setupLangButtonShapes(); - uint8 *_buttonShapes[19]; - - void initInventoryButtonList(); - Button *_inventoryButtons; - Button *_buttonList; - - int scrollInventory(Button *button); - int buttonInventory(Button *button); - int bookButton(Button *button); - int cauldronButton(Button *button); - int cauldronClearButton(Button *button); - - // book - static const int _bookPageYOffset[]; - static const byte _bookTextColorMap[]; - - int _bookMaxPage; - int _bookNewPage; - int _bookCurPage; - int _bookBkgd; - bool _bookShown; - - void loadBookBkgd(); - void showBookPage(); - void bookLoop(); - - void bookDecodeText(uint8 *text); - void bookPrintText(int dstPage, const uint8 *text, int x, int y, uint8 color); - - int bookPrevPage(Button *button); - int bookNextPage(Button *button); - int bookClose(Button *button); - - // cauldron - uint8 _cauldronState; - int16 _cauldronUseCount; - int16 _cauldronTable[25]; - int16 _cauldronStateTables[23][7]; - - static const int16 _cauldronProtectedItems[]; - static const int16 _cauldronBowlTable[]; - static const int16 _cauldronMagicTable[]; - static const int16 _cauldronMagicTableScene77[]; - static const uint8 _cauldronStateTable[]; - - void resetCauldronStateTable(int idx); - bool addToCauldronStateTable(int data, int idx); - - void setCauldronState(uint8 state, bool paletteFade); - void clearCauldronTable(); - void addFrontCauldronTable(int item); - void cauldronItemAnim(int item); - void cauldronRndPaletteFade(); - bool updateCauldron(); - void listItemsInCauldron(); - - // localization - void loadCCodeBuffer(const char *file); - void loadOptionsBuffer(const char *file); - void loadChapterBuffer(int chapter); - uint8 *_optionsBuffer; - uint8 *_cCodeBuffer; - - uint8 *_chapterBuffer; - int _currentChapter; - int _newChapterFile; - - uint8 *getTableEntry(uint8 *buffer, int id); - char *getTableString(int id, uint8 *buffer, int decode); - const char *getChapterString(int id); - int decodeString1(const char *src, char *dst); - void decodeString2(const char *src, char *dst); - - void changeFileExtension(char *buffer); - - // - Just used in French version - int getItemCommandStringDrop(uint16 item); - int getItemCommandStringPickUp(uint16 item); - int getItemCommandStringInv(uint16 item); - // - - - char _internStringBuf[200]; - static const char *_languageExtension[]; - static const char *_scriptLangExt[]; - - // character - struct Character { - uint16 sceneId; - uint16 dlgIndex; - uint8 height; - uint8 facing; - uint16 animFrame; - uint8 unk8; - uint8 unk9; - uint8 unkA; - uint16 inventory[20]; - int16 x1, y1; - int16 x2, y2; - }; - - int8 _deathHandler; - Character _mainCharacter; - bool _useCharPal; - int _charPalEntry; - uint8 _charPalTable[16]; - void updateCharPal(int unk1); - void setCharPalEntry(int entry, int value); - - void moveCharacter(int facing, int x, int y); - int updateCharPos(int *table); - void updateCharPosWithUpdate(); - void updateCharAnimFrame(int num, int *table); - - int checkCharCollision(int x, int y); - - int _mainCharX, _mainCharY; - int _charScaleX, _charScaleY; - - static const int _characterFrameTable[]; - - // text - void showMessageFromCCode(int id, int16 palIndex, int); - void showMessage(const char *string, int16 palIndex); - void showChapterMessage(int id, int16 palIndex); - - void updateCommandLineEx(int str1, int str2, int16 palIndex); - - const char *_shownMessage; - - byte _messagePal[3]; - bool _fadeMessagePalette; - void fadeMessagePalette(); - - // chat - int _vocHigh; - - const char *_chatText; - int _chatObject; - bool _chatIsNote; - uint32 _chatEndTime; - int _chatVocHigh, _chatVocLow; - - EMCData _chatScriptData; - EMCState _chatScriptState; - - int chatGetType(const char *text); - int chatCalcDuration(const char *text); - - void objectChat(const char *text, int object, int vocHigh = -1, int vocLow = -1); - void objectChatInit(const char *text, int object, int vocHigh = -1, int vocLow = -1); - void objectChatPrintText(const char *text, int object); - void objectChatProcess(const char *script); - void objectChatWaitToFinish(); - - void startDialogue(int dlgIndex); - - void zanthSceneStartupChat(); - void zanthRandomIdleChat(); - void updateDlgBuffer(); - void loadDlgHeader(int &csEntry, int &vocH, int &scIndex1, int &scIndex2); - void processDialogue(int dlgOffset, int vocH = 0, int csEntry = 0); - void npcChatSequence(const char *str, int objectId, int vocHigh = -1, int vocLow = -1); - void setNewDlgIndex(int dlgIndex); - - int _npcTalkChpIndex; - int _npcTalkDlgIndex; - uint8 _newSceneDlgState[32]; - int8 **_conversationState; - uint8 *_dlgBuffer; - - // Talk object handling - void initTalkObject(int index); - void deinitTalkObject(int index); - - struct TalkObject { - char filename[13]; - int8 scriptId; - int16 x, y; - int8 color; - }; - TalkObject *_talkObjectList; - - struct TalkSections { - TIM *STATim; - TIM *TLKTim; - TIM *ENDTim; - }; - TalkSections _currentTalkSections; - - char _TLKFilename[13]; - - // tim - void playTim(const char *filename); - - int t2_initChat(const TIM *tim, const uint16 *param); - int t2_updateSceneAnim(const TIM *tim, const uint16 *param); - int t2_resetChat(const TIM *tim, const uint16 *param); - int t2_playSoundEffect(const TIM *tim, const uint16 *param); - - Common::Array _timOpcodes; - - // sound - int _oldTalkFile; - int _currentTalkFile; - void openTalkFile(int newFile); - int _lastSfxTrack; - - virtual void snd_playVoiceFile(int id); - void snd_loadSoundFile(int id); - - void playVoice(int high, int low); - void snd_playSoundEffect(int track, int volume=0xFF); - - // timer - void timerFadeOutMessage(int); - void timerCauldronAnimation(int); - void timerFunc4(int); - void timerFunc5(int); - void timerBurnZanthia(int); - - void setTimer1DelaySecs(int secs); - - uint32 _nextIdleAnim; - int _lastIdleScript; - - void setNextIdleAnimTimer(); - void showIdleAnim(); - void runIdleScript(int script); - - void setWalkspeed(uint8 speed); - - // delay - void delay(uint32 millis, bool updateGame = false, bool isMainLoop = false); - - // ingame static sequence handling - void seq_makeBookOrCauldronAppear(int type); - void seq_makeBookAppear(); - - struct InventoryWsa { - int x, y, x2, y2, w, h; - int page; - int curFrame, lastFrame, specialFrame; - int sfx; - int delay; - bool running; - uint32 timer; - WSAMovieV2 *wsa; - } _invWsa; - - // TODO: move inside KyraEngine_v2::InventoryWsa? - void loadInvWsa(const char *filename, int run, int delay, int page, int sfx, int sFrame, int flags); - void closeInvWsa(); - - void updateInvWsa(); - void displayInvWsaLastFrame(); - - // opcodes - int o2_setCharacterFacingRefresh(EMCState *script); - int o2_setCharacterPos(EMCState *script); - int o2_defineObject(EMCState *script); - int o2_refreshCharacter(EMCState *script); - int o2_getCharacterX(EMCState *script); - int o2_getCharacterY(EMCState *script); - int o2_getCharacterFacing(EMCState *script); - int o2_getCharacterScene(EMCState *script); - int o2_setSceneComment(EMCState *script); - int o2_setCharacterAnimFrame(EMCState *script); - int o2_setCharacterFacing(EMCState *script); - int o2_trySceneChange(EMCState *script); - int o2_moveCharacter(EMCState *script); - int o2_customCharacterChat(EMCState *script); - int o2_soundFadeOut(EMCState *script); - int o2_showChapterMessage(EMCState *script); - int o2_restoreTalkTextMessageBkgd(EMCState *script); - int o2_wsaClose(EMCState *script); - int o2_meanWhileScene(EMCState *script); - int o2_backUpScreen(EMCState *script); - int o2_restoreScreen(EMCState *script); - int o2_displayWsaFrame(EMCState *script); - int o2_displayWsaSequentialFramesLooping(EMCState *script); - int o2_wsaOpen(EMCState *script); - int o2_displayWsaSequentialFrames(EMCState *script); - int o2_displayWsaSequence(EMCState *script); - int o2_addItemToInventory(EMCState *script); - int o2_drawShape(EMCState *script); - int o2_addItemToCurScene(EMCState *script); - int o2_checkForItem(EMCState *script); - int o2_loadSoundFile(EMCState *script); - int o2_removeItemSlotFromInventory(EMCState *script); - int o2_defineItem(EMCState *script); - int o2_removeItemFromInventory(EMCState *script); - int o2_countItemInInventory(EMCState *script); - int o2_countItemsInScene(EMCState *script); - int o2_queryGameFlag(EMCState *script); - int o2_resetGameFlag(EMCState *script); - int o2_setGameFlag(EMCState *script); - int o2_setHandItem(EMCState *script); - int o2_removeHandItem(EMCState *script); - int o2_handItemSet(EMCState *script); - int o2_hideMouse(EMCState *script); - int o2_addSpecialExit(EMCState *script); - int o2_setMousePos(EMCState *script); - int o2_showMouse(EMCState *script); - int o2_wipeDownMouseItem(EMCState *script); - int o2_getElapsedSecs(EMCState *script); - int o2_getTimerDelay(EMCState *script); - //int o2_playSoundEffect(EMCState *script); - int o2_delaySecs(EMCState *script); - int o2_delay(EMCState *script); - int o2_setTimerDelay(EMCState *script); - int o2_setScaleTableItem(EMCState *script); - int o2_setDrawLayerTableItem(EMCState *script); - int o2_setCharPalEntry(EMCState *script); - int o2_loadZShapes(EMCState *script); - int o2_drawSceneShape(EMCState *script); - int o2_drawSceneShapeOnPage(EMCState *script); - int o2_disableAnimObject(EMCState *script); - int o2_enableAnimObject(EMCState *script); - int o2_loadPalette384(EMCState *script); - int o2_setPalette384(EMCState *script); - int o2_restoreBackBuffer(EMCState *script); - int o2_backUpInventoryGfx(EMCState *script); - int o2_disableSceneAnim(EMCState *script); - int o2_enableSceneAnim(EMCState *script); - int o2_restoreInventoryGfx(EMCState *script); - int o2_setSceneAnimPos2(EMCState *script); - int o2_update(EMCState *script); - int o2_fadeScenePal(EMCState *script); - int o2_enterNewSceneEx(EMCState *script); - int o2_switchScene(EMCState *script); - int o2_getShapeFlag1(EMCState *script); - int o2_setPathfinderFlag(EMCState *script); - int o2_getSceneExitToFacing(EMCState *script); - int o2_setLayerFlag(EMCState *script); - int o2_setZanthiaPos(EMCState *script); - int o2_loadMusicTrack(EMCState *script); - int o2_playWanderScoreViaMap(EMCState *script); - int o2_playSoundEffect(EMCState *script); - int o2_setSceneAnimPos(EMCState *script); - int o2_blockInRegion(EMCState *script); - int o2_blockOutRegion(EMCState *script); - int o2_setCauldronState(EMCState *script); - int o2_showItemString(EMCState *script); - int o2_getRand(EMCState *script); - int o2_isAnySoundPlaying(EMCState *script); - int o2_setDeathHandlerFlag(EMCState *script); - int o2_setDrawNoShapeFlag(EMCState *script); - int o2_setRunFlag(EMCState *script); - int o2_showLetter(EMCState *script); - int o2_fillRect(EMCState *script); - int o2_waitForConfirmationClick(EMCState *script); - int o2_encodeShape(EMCState *script); - int o2_defineRoomEntrance(EMCState *script); - int o2_runTemporaryScript(EMCState *script); - int o2_setSpecialSceneScriptRunTime(EMCState *script); - int o2_defineSceneAnim(EMCState *script); - int o2_updateSceneAnim(EMCState *script); - int o2_addToSceneAnimPosAndUpdate(EMCState *script); - int o2_useItemOnMainChar(EMCState *script); - int o2_startDialogue(EMCState *script); - int o2_zanthRandomChat(EMCState *script); - int o2_setupDialogue(EMCState *script); - int o2_getDlgIndex(EMCState *script); - int o2_defineRoom(EMCState *script); - int o2_addCauldronStateTableEntry(EMCState *script); - int o2_setCountDown(EMCState *script); - int o2_getCountDown(EMCState *script); - int o2_pressColorKey(EMCState *script); - int o2_objectChat(EMCState *script); - int o2_chapterChange(EMCState *script); - int o2_getColorCodeFlag1(EMCState *script); - int o2_setColorCodeFlag1(EMCState *script); - int o2_getColorCodeFlag2(EMCState *script); - int o2_setColorCodeFlag2(EMCState *script); - int o2_getColorCodeValue(EMCState *script); - int o2_setColorCodeValue(EMCState *script); - int o2_countItemInstances(EMCState *script); - int o2_removeItemFromScene(EMCState *script); - int o2_initObject(EMCState *script); - int o2_npcChat(EMCState *script); - int o2_deinitObject(EMCState *script); - int o2_playTimSequence(EMCState *script); - int o2_makeBookOrCauldronAppear(EMCState *script); - int o2_setSpecialSceneScriptState(EMCState *script); - int o2_clearSpecialSceneScriptState(EMCState *script); - int o2_querySpecialSceneScriptState(EMCState *script); - int o2_resetInputColorCode(EMCState *script); - int o2_setHiddenItemsEntry(EMCState *script); - int o2_getHiddenItemsEntry(EMCState *script); - int o2_mushroomEffect(EMCState *script); - int o2_customChat(EMCState *script); - int o2_customChatFinish(EMCState *script); - int o2_setupSceneAnimation(EMCState *script); - int o2_stopSceneAnimation(EMCState *script); - int o2_disableTimer(EMCState *script); - int o2_enableTimer(EMCState *script); - int o2_setTimerCountdown(EMCState *script); - int o2_processPaletteIndex(EMCState *script); - int o2_updateTwoSceneAnims(EMCState *script); - int o2_getRainbowRoomData(EMCState *script); - int o2_drawSceneShapeEx(EMCState *script); - int o2_getBoolFromStack(EMCState *script); - int o2_getSfxDriver(EMCState *script); - int o2_getVocSupport(EMCState *script); - int o2_getMusicDriver(EMCState *script); - int o2_setVocHigh(EMCState *script); - int o2_getVocHigh(EMCState *script); - int o2_zanthiaChat(EMCState *script); - int o2_isVoiceEnabled(EMCState *script); - int o2_isVoicePlaying(EMCState *script); - int o2_stopVoicePlaying(EMCState *script); - int o2_getGameLanguage(EMCState *script); - int o2_demoFinale(EMCState *script); - int o2_dummy(EMCState *script); - - // opcodes temporary - // TODO: rename it from temporary to something more appropriate - int o2t_defineNewShapes(EMCState *script); - int o2t_setCurrentFrame(EMCState *script); - int o2t_playSoundEffect(EMCState *script); - int o2t_fadeScenePal(EMCState *script); - int o2t_setShapeFlag(EMCState *script); - - // script - void runStartScript(int script, int unk1); - void loadNPCScript(); - - bool _noScriptEnter; - - EMCData _npcScriptData; - - EMCData _sceneScriptData; - EMCState _sceneScriptState; - - EMCData _temporaryScriptData; - EMCState _temporaryScriptState; - bool _temporaryScriptExecBit; - Common::Array _opcodesTemporary; - - void runTemporaryScript(const char *filename, int allowSkip, int resetChar, int newShapes, int shapeUnload); - - // pathfinder - int _pathfinderFlag; - - uint8 *_unkBuf500Bytes; - uint8 *_unkBuf200kByte; - bool _chatAltFlag; - int _unk3, _unk4, _unk5; - bool _unkSceneScreenFlag1; - bool _unkHandleSceneChangeFlag; - - // sequence player - ActiveWSA *_activeWSA; - ActiveText *_activeText; - - const char *const *_sequencePakList; - int _sequencePakListSize; - const char *const *_ingamePakList; - int _ingamePakListSize; - - const char *const *_musicFileListIntro; - int _musicFileListIntroSize; - const char *const *_musicFileListFinale; - int _musicFileListFinaleSize; - const char *const *_musicFileListIngame; - int _musicFileListIngameSize; - const uint8 *_cdaTrackTableIntro; - int _cdaTrackTableIntroSize; - const uint8 *_cdaTrackTableIngame; - int _cdaTrackTableIngameSize; - const uint8 *_cdaTrackTableFinale; - int _cdaTrackTableFinaleSize; - const char *const *_sequenceSoundList; - int _sequenceSoundListSize; - const char *const *_ingameSoundList; - int _ingameSoundListSize; - const uint16 *_ingameSoundIndex; - int _ingameSoundIndexSize; - const char *const *_sequenceStrings; - int _sequenceStringsSize; - const uint16 *_ingameTalkObjIndex; - int _ingameTalkObjIndexSize; - const char *const *_ingameTimJpStr; - int _ingameTimJpStrSize; - const HofSeqData *_sequences; - const ItemAnimData_v2 *_itemAnimData; - int _itemAnimDataSize; - const ItemAnimData_v1 *_demoAnimData; - int _demoAnimSize; - - int _sequenceStringsDuration[33]; - - static const uint8 _seqTextColorPresets[]; - char *_seqProcessedString; - WSAMovieV2 *_seqWsa; - - bool _abortIntroFlag; - int _menuChoice; - - uint32 _seqFrameDelay; - uint32 _seqStartTime; - uint32 _seqEndTime; - int _seqFrameCounter; - int _seqScrollTextCounter; - int _seqWsaCurrentFrame; - bool _seqSpecialFlag; - bool _seqSubframePlaying; - uint8 _seqTextColor[2]; - uint8 _seqTextColorMap[16]; - - const SeqProc *_callbackS; - const SeqProc *_callbackN; - - static const uint8 _rainbowRoomData[]; - - // color code related vars - int _colorCodeFlag1; - int _colorCodeFlag2; - uint8 _presetColorCode[7]; - uint8 _inputColorCode[7]; - uint32 _scriptCountDown; - int _dbgPass; - - // save/load specific - void saveGame(const char *fileName, const char *saveName); - void loadGame(const char *fileName); -}; - -} // end of namespace Kyra - -#endif - - - - diff --git a/engines/kyra/kyra_v3.cpp b/engines/kyra/kyra_v3.cpp deleted file mode 100644 index fd0b5b9e93..0000000000 --- a/engines/kyra/kyra_v3.cpp +++ /dev/null @@ -1,1651 +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_v3.h" -#include "kyra/screen_v3.h" -#include "kyra/wsamovie.h" -#include "kyra/sound.h" -#include "kyra/text_v3.h" -#include "kyra/vqa.h" -#include "kyra/gui.h" -#include "kyra/timer.h" -#include "kyra/debugger.h" -#include "kyra/gui_v3.h" - -#include "common/system.h" -#include "common/config-manager.h" - -namespace Kyra { -KyraEngine_v3::KyraEngine_v3(OSystem *system, const GameFlags &flags) : KyraEngine(system, flags) { - _soundDigital = 0; - _musicSoundChannel = -1; - _menuAudioFile = "TITLE1.AUD"; - _lastMusicCommand = -1; - _itemBuffer1 = _itemBuffer2 = 0; - _scoreFile = 0; - _cCodeFile = 0; - _scenesFile = 0; - _itemFile = 0; - _gamePlayBuffer = 0; - _interface = _interfaceCommandLine = 0; - _costPalBuffer = 0; - _animObjects = 0; - _sceneAnims = 0; - memset(_sceneShapes, 0, sizeof(_sceneShapes)); - memset(_sceneAnimMovie, 0, sizeof(_sceneAnimMovie)); - _gfxBackUpRect = 0; - _itemList = 0; - _malcolmShapes = 0; - _paletteOverlay = 0; - _sceneList = 0; - memset(&_mainCharacter, 0, sizeof(_mainCharacter)); - _mainCharacter.sceneId = 9; - _mainCharacter.height = 0x4C; - _mainCharacter.facing = 5; - _mainCharacter.animFrame = 0x57; - _mainCharacter.walkspeed = 5; - memset(_mainCharacter.inventory, -1, sizeof(_mainCharacter.inventory)); - _text = 0; - _commandLineY = 189; - _inventoryState = false; - memset(&_sceneScriptState, 0, sizeof(_sceneScriptState)); - memset(&_sceneScriptData, 0, sizeof(_sceneScriptData)); - _updateCharPosNextUpdate = 0; - memset(_characterAnimTable, 0, sizeof(_characterAnimTable)); - _overwriteSceneFacing = false; - _maskPageMinY = _maskPageMaxY = 0; - _sceneStrings = 0; - _enterNewSceneLock = 0; - _mainCharX = _mainCharY = -1; - _animList = 0; - _drawNoShapeFlag = false; - _wsaPlayingVQA = false; - _lastCharPalLayer = -1; - _charPalUpdate = false; - _runFlag = false; - _unk5 = 0; - _unkSceneScreenFlag1 = false; - _noScriptEnter = true; - _itemInHand = _handItemSet = -1; - _unk3 = -1; - _unk4 = 0; - _loadingState = false; - _noStartupChat = false; - _lastProcessedSceneScript = 0; - _specialSceneScriptRunFlag = false; - _pathfinderFlag = 0; - _talkObjectList = 0; - _chatText = 0; - _chatObject = -1; - memset(&_chatScriptState, 0, sizeof(_chatScriptState)); - memset(&_chatScriptData, 0, sizeof(_chatScriptData)); - _voiceSoundChannel = -1; - _charBackUpWidth2 = _charBackUpHeight2 = -1; - _charBackUpWidth = _charBackUpHeight = -1; - _useActorBuffer = false; - _curStudioSFX = 283; - _badConscienceShown = false; - _currentChapter = 1; - _deathHandler = -1; - _moveFacingTable = 0; - _unkHandleSceneChangeFlag = false; - memset(_sceneShapeDescs, 0, sizeof(_sceneShapeDescs)); - _cnvFile = _dlgBuffer = 0; - _curDlgChapter = _curDlgIndex = _curDlgLang = -1; - _isStartupDialog = 0; - _stringBuffer = 0; - _dialogSceneAnim = _dialogSceneScript = -1; - memset(&_dialogScriptData, 0, sizeof(_dialogScriptData)); - memset(&_dialogScriptState, 0, sizeof(_dialogScriptState)); - _dialogScriptFuncStart = _dialogScriptFuncProc = _dialogScriptFuncEnd = 0; - _malcolmsMood = 1; - _nextIdleAnim = 0; - _nextIdleType = false; - _newShapeFlag = -1; - _newShapeFiledata = 0; - _inventoryScrollSpeed = -1; - _invWsa = 0; - _invWsaFrame = -1; - _score = 0; - memset(_scoreFlagTable, 0, sizeof(_scoreFlagTable)); - _debugger = 0; - _mainButtonData = 0; - _mainButtonList = 0; - _mainButtonListInitialized = false; - _enableInventory = true; - _goodConscienceShown = false; - _goodConscienceAnim = -1; - _goodConsciencePosition = false; - _showOutro = false; -} - -KyraEngine_v3::~KyraEngine_v3() { - delete _screen; - delete _soundDigital; - - delete [] _itemBuffer1; - delete [] _itemBuffer2; - delete [] _scoreFile; - delete [] _cCodeFile; - delete [] _scenesFile; - delete [] _itemFile; - delete [] _gamePlayBuffer; - delete [] _interface; - delete [] _interfaceCommandLine; - delete [] _costPalBuffer; - delete [] _animObjects; - delete [] _sceneAnims; - - for (uint i = 0; i < ARRAYSIZE(_sceneShapes); ++i) - delete [] _sceneShapes[i]; - - for (uint i = 0; i < ARRAYSIZE(_sceneAnimMovie); ++i) - delete _sceneAnimMovie[i]; - - delete [] _gfxBackUpRect; - delete [] _itemList; - delete [] _paletteOverlay; - delete [] _sceneList; - - for (ShapeMap::iterator i = _gameShapes.begin(); i != _gameShapes.end(); ++i) { - delete [] i->_value; - i->_value = 0; - } - _gameShapes.clear(); - - _emc->unload(&_sceneScriptData); - - delete [] _sceneStrings; - delete [] _talkObjectList; - delete [] _moveFacingTable; - - for (Common::Array::iterator i = _opcodesTemporary.begin(); i != _opcodesTemporary.end(); ++i) - delete *i; - _opcodesTemporary.clear(); - - for (Common::Array::iterator i = _opcodesDialog.begin(); i != _opcodesDialog.end(); ++i) - delete *i; - _opcodesDialog.clear(); - - delete _cnvFile; - delete _dlgBuffer; - delete [] _stringBuffer; - delete [] _newShapeFiledata; - delete _invWsa; - delete _debugger; - delete [] _mainButtonData; - delete _gui; -} - -int KyraEngine_v3::init() { - _screen = new Screen_v3(this, _system); - assert(_screen); - _screen->setResolution(); - - KyraEngine::init(); - - _debugger = new Debugger_v3(this); - assert(_debugger); - - _soundDigital = new SoundDigital(this, _mixer); - assert(_soundDigital); - if (!_soundDigital->init()) - error("_soundDigital->init() failed"); - KyraEngine::_text = _text = new TextDisplayer_v3(this, _screen); - assert(_text); - _gui = new GUI_v3(this); - assert(_gui); - - _screen->loadFont(Screen::FID_6_FNT, "6.FNT"); - _screen->loadFont(Screen::FID_8_FNT, "8FAT.FNT"); - _screen->loadFont(Screen::FID_BOOKFONT_FNT, "BOOKFONT.FNT"); - _screen->setFont(Screen::FID_6_FNT); - _screen->setAnimBlockPtr(3500); - _screen->setScreenDim(0); - - _res->loadFileToBuf("PALETTE.COL", _screen->getPalette(0), 768); - _screen->setScreenPalette(_screen->getPalette(0)); - - return 0; -} - -int KyraEngine_v3::go() { - bool running = true; - preinit(); - _screen->hideMouse(); - initMainMenu(); - - _screen->clearPage(0); - _screen->clearPage(2); - - while (running && !_quitFlag) { - _screen->_curPage = 0; - _screen->clearPage(0); - - _screen->setScreenPalette(_screen->getPalette(0)); - - // XXX - playMenuAudioFile(); - - for (int i = 0; i < 64 && !_quitFlag; ++i) { - uint32 nextRun = _system->getMillis() + 3 * _tickLength; - _menuAnim->displayFrame(i, 0); - _screen->updateScreen(); - delayUntil(nextRun); - } - - for (int i = 64; i > 29 && !_quitFlag; --i) { - uint32 nextRun = _system->getMillis() + 3 * _tickLength; - _menuAnim->displayFrame(i, 0); - _screen->updateScreen(); - delayUntil(nextRun); - } - - switch (_menu->handle(3)) { - case 0: - uninitMainMenu(); - - fadeOutMusic(60); - _screen->fadeToBlack(); - _musicSoundChannel = -1; - startup(); - runLoop(); - running = false; - break; - - case 1: - playVQA("K3INTRO"); - _wsaPlayingVQA = false; - _screen->hideMouse(); - break; - - case 2: - //uninitMainMenu(); - //show load dialog - //running = false; - break; - - case 3: - default: - fadeOutMusic(60); - _screen->fadeToBlack(); - uninitMainMenu(); - quitGame(); - running = false; - break; - } - } - - if (_showOutro) - playVQA("CREDITS"); - - return 0; -} - -void KyraEngine_v3::initMainMenu() { - _menuAnim = new WSAMovieV2(this, _screen); - _menuAnim->open("REVENGE.WSA", 1, _screen->getPalette(0)); - _menuAnim->setX(0); - _menuAnim->setY(0); - _menuAnim->setDrawPage(0); - memset(_screen->getPalette(0), 0, 3); - - _menu = new MainMenu(this); - MainMenu::StaticData data = { - { _mainMenuStrings[_lang*4+0], _mainMenuStrings[_lang*4+1], _mainMenuStrings[_lang*4+2], _mainMenuStrings[_lang*4+3] }, - { 0x01, 0x04, 0x0C, 0x04, 0x00, 0x80, 0xFF, 0x00, 0x01, 0x02, 0x03 }, - { 0x16, 0x19, 0x1A, 0x16 }, - 0x80, 0xFF - }; - - MainMenu::Animation anim; - anim.anim = _menuAnim; - anim.startFrame = 29; - anim.endFrame = 63; - anim.delay = 2; - - _menu->init(data, anim); -} - -void KyraEngine_v3::uninitMainMenu() { - delete _menuAnim; - _menuAnim = 0; - delete _menu; - _menu = 0; -} - -void KyraEngine_v3::playVQA(const char *name) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::playVQA('%s')", name); - - VQAMovie vqa(this, _system); - - char filename[20]; - int size = 0; // TODO: Movie size is 0, 1 or 2. - - snprintf(filename, sizeof(filename), "%s%d.VQA", name, size); - - if (vqa.open(filename)) { - _soundDigital->stopAllSounds(); - - _screen->hideMouse(); - memcpy(_screen->getPalette(1), _screen->getPalette(0), 768); - fadeOutMusic(60); - _screen->fadeToBlack(); - _screen->clearPage(0); - - vqa.setDrawPage(0); - vqa.play(); - vqa.close(); - - _soundDigital->stopAllSounds(); - _screen->showMouse(); - - uint8 pal[768]; - // Taken from original, it used '1' here too - memset(pal, 1, sizeof(pal)); - _screen->setScreenPalette(pal); - _screen->clearPage(0); - memcpy(_screen->getPalette(0), _screen->getPalette(1), 768); - _wsaPlayingVQA = true; - } -} - -#pragma mark - - -void KyraEngine_v3::playMenuAudioFile() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::playMenuAudioFile()"); - if (_soundDigital->isPlaying(_musicSoundChannel)) - return; - - _musicSoundChannel = _soundDigital->playSound(_menuAudioFile, 0xFF, Audio::Mixer::kMusicSoundType); -} - -void KyraEngine_v3::snd_playWanderScoreViaMap(int track, int force) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::snd_playWanderScoreViaMap(%d, %d)", track, force); - - // XXX byte_3C87C compare - - if (_musicSoundChannel != -1 && !_soundDigital->isPlaying(_musicSoundChannel)) - force = 1; - else if (_musicSoundChannel == -1) - force = 1; - - if (track == _lastMusicCommand && !force) - return; - - stopMusicTrack(); - - if (_musicSoundChannel == -1) { - assert(track < _soundListSize && track >= 0); - - _musicSoundChannel = _soundDigital->playSound(_soundList[track], 0xFF, Audio::Mixer::kMusicSoundType); - } - - _lastMusicCommand = track; -} - -void KyraEngine_v3::stopMusicTrack() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::stopMusicTrack()"); - - if (_musicSoundChannel != -1 && _soundDigital->isPlaying(_musicSoundChannel)) - _soundDigital->stopSound(_musicSoundChannel); - - _lastMusicCommand = -1; - _musicSoundChannel = -1; -} - -int KyraEngine_v3::musicUpdate(int forceRestart) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::musicUpdate(%d)", forceRestart); - - static uint32 mTimer = 0; - static uint16 lock = 0; - - if (ABS(_system->getMillis() - mTimer) > (int)(0x0F * _tickLength)) - mTimer = _system->getMillis(); - - if (_system->getMillis() < mTimer && !forceRestart) - return 1; - - if (!lock) { - lock = 1; - if (_musicSoundChannel >= 0) { - if (!_soundDigital->isPlaying(_musicSoundChannel)) { - if (_lastMusicCommand != -1) - snd_playWanderScoreViaMap(_lastMusicCommand, 1); - } - } - lock = 0; - mTimer = _system->getMillis() + 0x0F * _tickLength; - } - - return 1; -} - -void KyraEngine_v3::fadeOutMusic(int ticks) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::fadeOutMusic(%d)", ticks); - if (_musicSoundChannel >= 0) { - _fadeOutMusicChannel = _musicSoundChannel; - _soundDigital->beginFadeOut(_musicSoundChannel, ticks); - _lastMusicCommand = -1; - } -} - -void KyraEngine_v3::snd_playSoundEffect(int item, int volume) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::snd_playSoundEffect(%d, %d)", item, volume); - if (_sfxFileMap[item*2+0] != 0xFF) { - char filename[16]; - snprintf(filename, 16, "%s.AUD", _sfxFileList[_sfxFileMap[item*2+0]]); - uint8 priority = _sfxFileMap[item*2+1]; - - _soundDigital->playSound(filename, priority, Audio::Mixer::kSFXSoundType, volume); - } -} - -void KyraEngine_v3::playVoice(int high, int low) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::playVoice(%d, %d)", high, low); - snd_playVoiceFile(high * 1000 + low); -} - -void KyraEngine_v3::snd_playVoiceFile(int file) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::snd_playVoiceFile(%d)", file); - char filename[16]; - snprintf(filename, 16, "%u.AUD", (uint)file); - - _voiceSoundChannel = _soundDigital->playSound(filename, 0xFE, Audio::Mixer::kSpeechSoundType, 255); -} - -bool KyraEngine_v3::snd_voiceIsPlaying() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::snd_voiceIsPlaying()"); - return _soundDigital->isPlaying(_voiceSoundChannel); -} - -void KyraEngine_v3::snd_stopVoice() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::snd_stopVoice()"); - if (_voiceSoundChannel != -1) - _soundDigital->stopSound(_voiceSoundChannel); -} - -void KyraEngine_v3::playStudioSFX(const char *str) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::playStudioSFX('%s')", str); - if (_rnd.getRandomNumberRng(1, 2) != 2) - return; - - const int strSize = strlen(str) - 1; - if (str[strSize] != '?' && str[strSize] != '!') - return; - - snd_playSoundEffect(_curStudioSFX++, 128); - - if (_curStudioSFX > 291) - _curStudioSFX = 283; -} - -#pragma mark - - -void KyraEngine_v3::preinit() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::preinit()"); - - _itemBuffer1 = new int8[72]; - _itemBuffer2 = new int8[144]; - initMouseShapes(); - initItems(); - - _screen->setMouseCursor(0, 0, _gameShapes[0]); -} - -void KyraEngine_v3::initMouseShapes() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::initMouseShapes()"); - uint8 *data = _res->fileData("MOUSE.SHP", 0); - assert(data); - for (int i = 0; i <= 6; ++i) - _gameShapes[i] = _screen->makeShapeCopy(data, i); - delete [] data; -} - -void KyraEngine_v3::startup() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::startup()"); - musicUpdate(0); - - memset(_flagsTable, 0, sizeof(_flagsTable)); - - _gamePlayBuffer = new uint8[64000]; - musicUpdate(0); - musicUpdate(0); - - _interface = new uint8[17920]; - _interfaceCommandLine = new uint8[3840]; - - _screen->setFont(Screen::FID_6_FNT); - - _stringBuffer = new char[500]; - //XXX - musicUpdate(0); - _moveFacingTable = new int[600]; - _costPalBuffer = new uint8[864]; - //XXX - _animObjects = new AnimObj[67]; - _sceneAnims = new SceneAnim[16]; - - musicUpdate(0); - - memset(_sceneShapes, 0, sizeof(_sceneShapes)); - _screenBuffer = new uint8[64000]; - - musicUpdate(0); - musicUpdate(0); - - if (!loadLanguageFile("ITEMS.", _itemFile)) - error("Couldn't load ITEMS"); - if (!loadLanguageFile("SCORE.", _scoreFile)) - error("Couldn't load SCORE"); - if (!loadLanguageFile("C_CODE.", _cCodeFile)) - error("Couldn't load C_CODE"); - if (!loadLanguageFile("SCENES.", _scenesFile)) - error("Couldn't load SCENES"); - - //XXX - - if ((_actorFileSize = loadLanguageFile("_ACTOR.", _actorFile)) == 0) - error("couldn't load _ACTOR"); - - musicUpdate(0); - //XXX - musicUpdate(0); - openTalkFile(0); - musicUpdate(0); - _currentTalkFile = 0; - openTalkFile(1); - //XXX - loadCostPal(); - musicUpdate(0); - - for (int i = 0; i < 16; ++i) { - _sceneAnims[i].flags = 0; - _sceneAnimMovie[i] = new WSAMovieV2(this, _screen); - assert(_sceneAnimMovie[i]); - } - - _screen->_curPage = 0; - - _talkObjectList = new TalkObject[88]; - memset(_talkObjectList, 0, sizeof(TalkObject)*88); - for (int i = 0; i < 88; ++i) - _talkObjectList[i].sceneId = 0xFF; - - musicUpdate(0); - updateMalcolmShapes(); - _gfxBackUpRect = new uint8[_screen->getRectSize(32, 32)]; - _itemList = new Item[50]; - resetItemList(); - - loadShadowShape(); - //loadButtonShapes(); - musicUpdate(0); - loadExtrasShapes(); - musicUpdate(0); - loadMalcolmShapes(_malcolmShapes); - musicUpdate(0); - initMainButtonList(true); - loadInterfaceShapes(); - - musicUpdate(0); - _res->loadFileToBuf("PALETTE.COL", _screen->getPalette(0), 768); - _paletteOverlay = new uint8[256]; - _screen->generateOverlay(_screen->getPalette(0), _paletteOverlay, 0xF0, 0x19); - - loadInterface(); - musicUpdate(0); - - clearAnimObjects(); - - _scoreMax = 0; - for (int i = 0; i < _scoreTableSize; ++i) { - if (_scoreTable[i] > 0) - _scoreMax += _scoreTable[i]; - } - - musicUpdate(0); - memset(_hiddenItems, -1, sizeof(_hiddenItems)); - - memset(_newSceneDlgState, 0, sizeof(_newSceneDlgState)); - memset(_conversationState, -1, sizeof(_conversationState)); - - _sceneList = new SceneDesc[98]; - assert(_sceneList); - memset(_sceneList, 0, sizeof(SceneDesc)*98); - _sceneListSize = 98; - - musicUpdate(0); - runStartupScript(1, 0); - _res->exists("MOODOMTR.WSA", true); - _invWsa = new WSAMovieV2(this, _screen); - assert(_invWsa); - _invWsa->open("MOODOMTR.WSA", 1, 0); - _invWsaFrame = 6; - _soundDigital->beginFadeOut(_musicSoundChannel, 60); - delayWithTicks(60); - enterNewScene(_mainCharacter.sceneId, _mainCharacter.facing, 0, 0, 1); - _screen->updateScreen(); - musicUpdate(0); - _screen->showMouse(); - //XXX -} - -void KyraEngine_v3::loadCostPal() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::loadCostPal()"); - _costPalBuffer = _res->fileData("_COSTPAL.DAT", 0); -} - -void KyraEngine_v3::loadShadowShape() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::loadShadowShape()"); - _screen->loadBitmap("SHADOW.CSH", 3, 3, 0); - addShapeToPool(_screen->getCPagePtr(3), 421, 0); -} - -void KyraEngine_v3::loadExtrasShapes() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::loadExtrasShapes()"); - _screen->loadBitmap("EXTRAS.CSH", 3, 3, 0); - for (int i = 0; i < 20; ++i) - addShapeToPool(_screen->getCPagePtr(3), i+433, i); - addShapeToPool(_screen->getCPagePtr(3), 453, 20); - addShapeToPool(_screen->getCPagePtr(3), 454, 21); -} - -void KyraEngine_v3::loadInterfaceShapes() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::loadInterfaceShapes()"); - _screen->loadBitmap("INTRFACE.CSH", 3, 3, 0); - for (int i = 422; i <= 432; ++i) - addShapeToPool(_screen->getCPagePtr(3), i, i-422); -} - -void KyraEngine_v3::loadInterface() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::loadInterface()"); - _screen->loadBitmap("INTRFACE.CPS", 3, 3, 0); - memcpy(_interface, _screen->getCPagePtr(3), 17920); - memcpy(_interfaceCommandLine, _screen->getCPagePtr(3), 3840); -} - -void KyraEngine_v3::initItems() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::initItems()"); - - _screen->loadBitmap("ITEMS.CSH", 3, 3, 0); - - for (int i = 248; i <= 319; ++i) - addShapeToPool(_screen->getCPagePtr(3), i, i-248); - - _screen->loadBitmap("ITEMS2.CSH", 3, 3, 0); - - for (int i = 320; i <= 397; ++i) - addShapeToPool(_screen->getCPagePtr(3), i, i-320); - - uint32 size = 0; - uint8 *itemsDat = _res->fileData("_ITEMS.DAT", &size); - - assert(size >= 72+144); - - memcpy(_itemBuffer1, itemsDat , 72); - memcpy(_itemBuffer2, itemsDat+72, 144); - - delete [] itemsDat; - - _screen->_curPage = 0; -} - -void KyraEngine_v3::runStartupScript(int script, int unk1) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::runStartupScript(%d, %d)", script, unk1); - EMCState state; - EMCData data; - memset(&state, 0, sizeof(state)); - memset(&data, 0, sizeof(data)); - char filename[13]; - strcpy(filename, "_START0X.EMC"); - filename[7] = (script % 10) + '0'; - - _emc->load(filename, &data, &_opcodes); - _emc->init(&state, &data); - _emc->start(&state, 0); - state.regs[6] = unk1; - - while (_emc->isValid(&state)) - _emc->run(&state); - - _emc->unload(&data); -} - -void KyraEngine_v3::openTalkFile(int file) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::openTalkFile(%d)", file); - char talkFilename[16]; - - if (file == 0) { - strcpy(talkFilename, "ANYTALK.TLK"); - } else { - if (_currentTalkFile > 0) { - sprintf(talkFilename, "CH%dTALK.TLK", _currentTalkFile); - _res->unloadPakFile(talkFilename); - } - sprintf(talkFilename, "CH%dTALK.TLK", file); - } - - _currentTalkFile = file; - _res->loadPakFile(talkFilename); -} - -#pragma mark - - -void KyraEngine_v3::addShapeToPool(const uint8 *data, int realIndex, int shape) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::addShapeToPool(%p, %d, %d)", data, realIndex, shape); - ShapeMap::iterator iter = _gameShapes.find(realIndex); - if (iter != _gameShapes.end()) { - delete [] iter->_value; - iter->_value = 0; - } - _gameShapes[realIndex] = _screen->makeShapeCopy(data, shape); - assert(_gameShapes[realIndex]); -} - -uint8 *KyraEngine_v3::getShapePtr(int shape) const { - debugC(9, kDebugLevelMain, "KyraEngine_v3::getShapePtr(%d)", shape); - ShapeMap::iterator iter = _gameShapes.find(shape); - if (iter == _gameShapes.end()) - return 0; - return iter->_value; -} - -void KyraEngine_v3::loadMalcolmShapes(int newShapes) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::loadMalcolmShapes(%d)", newShapes); - static const uint8 numberOffset[] = { 3, 3, 4, 4, 3, 3 }; - static const uint8 startShape[] = { 0x32, 0x58, 0x78, 0x98, 0xB8, 0xD8 }; - static const uint8 endShape[] = { 0x57, 0x77, 0x97, 0xB7, 0xD7, 0xF7 }; - static const char * const filenames[] = { - "MSW##.SHP", - "MTA##.SHP", - "MTFL##.SHP", - "MTFR##.SHP", - "MTL##.SHP", - "MTR##.SHP" - }; - - for (int i = 50; i <= 247; ++i) { - if (i == 87) - continue; - - ShapeMap::iterator iter = _gameShapes.find(i); - if (iter != _gameShapes.end()) { - delete iter->_value; - iter->_value = 0; - } - } - - const char lowNum = (newShapes % 10) + '0'; - const char highNum = (newShapes / 10) + '0'; - - for (int i = 0; i < 6; ++i) { - char filename[16]; - strcpy(filename, filenames[i]); - filename[numberOffset[i]+0] = highNum; - filename[numberOffset[i]+1] = lowNum; - _res->exists(filename, true); - _res->loadFileToBuf(filename, _screenBuffer, 64000); - for (int j = startShape[i]; j <= endShape[i]; ++j) { - if (j == 87) - continue; - addShapeToPool(_screenBuffer, j, j-startShape[i]); - } - } - - _malcolmShapes = newShapes; - updateMalcolmShapes(); -} - -void KyraEngine_v3::updateMalcolmShapes() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::updateMalcolmShapes()"); - assert(_malcolmShapes >= 0 && _malcolmShapes < _shapeDescsSize); - _malcolmShapeXOffset = _shapeDescs[_malcolmShapes].xOffset; - _malcolmShapeYOffset = _shapeDescs[_malcolmShapes].yOffset; - _animObjects[0].width = _shapeDescs[_malcolmShapes].width; - _animObjects[0].height = _shapeDescs[_malcolmShapes].height; -} - -#pragma mark - - -void KyraEngine_v3::moveCharacter(int facing, int x, int y) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::moveCharacter(%d, %d, %d)", facing, x, y); - x &= ~3; - y &= ~1; - _mainCharacter.facing = facing; - - _screen->hideMouse(); - switch (facing) { - case 0: - while (_mainCharacter.y1 > y) - updateCharPosWithUpdate(); - break; - - case 2: - while (_mainCharacter.x1 < x) - updateCharPosWithUpdate(); - break; - - case 4: - while (_mainCharacter.y1 < y) - updateCharPosWithUpdate(); - break; - - case 6: - while (_mainCharacter.x1 > x) - updateCharPosWithUpdate(); - break; - - default: - break; - } - _screen->showMouse(); -} - -void KyraEngine_v3::updateCharPosWithUpdate() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::updateCharPosWithUpdate()"); - updateCharPos(0, 0); - update(); -} - -int KyraEngine_v3::updateCharPos(int *table, int force) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::updateCharPos(%p, %d)", (const void*)table, force); - if (_updateCharPosNextUpdate > _system->getMillis() && !force) - return 0; - _mainCharacter.x1 += _updateCharPosXTable[_mainCharacter.facing]; - _mainCharacter.y1 += _updateCharPosYTable[_mainCharacter.facing]; - updateCharAnimFrame(0, table); - _updateCharPosNextUpdate = _system->getMillis() + _mainCharacter.walkspeed * _tickLength; - return 1; -} - -void KyraEngine_v3::updateCharAnimFrame(int character, int *table) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::updateCharPos(%d, %p)", character, (const void*)table); - ++_mainCharacter.animFrame; - int facing = _mainCharacter.facing; - - if (table) { - if (table[0] != table[-1] && table[1] == table[-1]) { - facing = getOppositeFacingDirection(table[-1]); - table[0] = table[-1]; - } - } - - if (facing) { - if (facing == 7 || facing == 1) { - if (_characterAnimTable[0] > 2) - facing = 0; - memset(_characterAnimTable, 0, sizeof(_characterAnimTable)); - } else if (facing == 4) { - ++_characterAnimTable[1]; - } else if (facing == 5 || facing == 3) { - if (_characterAnimTable[1] > 2) - facing = 4; - memset(_characterAnimTable, 0, sizeof(_characterAnimTable)); - } - } else { - ++_characterAnimTable[0]; - } - - switch (facing) { - case 0: - if (_mainCharacter.animFrame < 79 || _mainCharacter.animFrame > 86) - _mainCharacter.animFrame = 79; - break; - - case 1: case 2: case 3: - if (_mainCharacter.animFrame < 71 || _mainCharacter.animFrame > 78) - _mainCharacter.animFrame = 71; - break; - - case 4: - if (_mainCharacter.animFrame < 55 || _mainCharacter.animFrame > 62) - _mainCharacter.animFrame = 55; - break; - - case 5: case 6: case 7: - if (_mainCharacter.animFrame < 63 || _mainCharacter.animFrame > 70) - _mainCharacter.animFrame = 63; - break; - - default: - break; - } - - updateCharacterAnim(0); -} - -void KyraEngine_v3::updateCharPal(int unk1) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::updateCharPal(%d)", unk1); - int layer = _screen->getLayer(_mainCharacter.x1, _mainCharacter.y1) - 1; - const uint8 *src = _costPalBuffer + _malcolmShapes * 72; - uint8 *dst = _screen->getPalette(0) + 432; - const int8 *sceneDatPal = &_sceneDatPalette[layer * 3]; - - if (layer != _lastCharPalLayer && unk1) { - for (int i = 0, j = 0; i < 72; ++i) { - uint8 col = *dst; - int8 addCol = *src + *sceneDatPal; - addCol = MAX(0, MIN(addCol, 63)); - addCol = (col - addCol) >> 1; - *dst -= addCol; - ++dst; - ++src; - ++sceneDatPal; - ++j; - if (j > 3) { - sceneDatPal = &_sceneDatPalette[layer * 3]; - j = 0; - } - } - _charPalUpdate = true; - _screen->setScreenPalette(_screen->getPalette(0)); - _lastCharPalLayer = layer; - } else if (_charPalUpdate || !unk1) { - memcpy(dst, src, 72); - - for (int i = 0, j = 0; i < 72; ++i) { - uint8 col = *dst + *sceneDatPal; - *dst = MAX(0, MIN(col, 63)); - ++dst; - ++sceneDatPal; - ++j; - if (j >= 3) { - sceneDatPal = &_sceneDatPalette[layer * 3]; - j = 0; - } - } - - _screen->setScreenPalette(_screen->getPalette(0)); - _charPalUpdate = false; - } -} - -bool KyraEngine_v3::checkCharCollision(int x, int y) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::checkCharCollision(%d, %d)", x, y); - - int scale = getScale(_mainCharacter.x1, _mainCharacter.y1); - int width = (scale * 37) >> 8; - int height = (scale * 76) >> 8; - - int x1 = _mainCharacter.x1 - width/2; - int x2 = _mainCharacter.x1 + width/2; - int y1 = _mainCharacter.y1 - height; - int y2 = _mainCharacter.y1; - - if (x >= x1 && x <= x2 && y >= y1 && y <= y2) - return true; - return false; -} - -#pragma mark - - -void KyraEngine_v3::runLoop() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::runLoop()"); - - _runFlag = true; - while (_runFlag && !_quitFlag) { - if (_deathHandler >= 0) { - // TODO: add menu etc. - loadGame(getSavegameFilename(999)); - } - - if (_system->getMillis() >= _nextIdleAnim) - showIdleAnim(); - - int inputFlag = checkInput(_mainButtonList, true); - removeInputTop(); - - update(); - _timer->update(); - - if (inputFlag == 198 || inputFlag == 199) { - _unk3 = _handItemSet; - Common::Point mouse = getMousePos(); - handleInput(mouse.x, mouse.y); - } - - _system->delayMillis(10); - } -} - -void KyraEngine_v3::handleInput(int x, int y) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::handleInput(%d, %d)", x, y); - if (_inventoryState) - return; - setNextIdleAnimTimer(); - - if (_unk5) { - _unk5 = 0; - return; - } - - if (!_screen->isMouseVisible()) - return; - - if (_unk3 == -3) { - snd_playSoundEffect(0x0D, 0x80); - return; - } - - setNextIdleAnimTimer(); - - int skip = 0; - - if (checkCharCollision(x, y) && _unk3 >= -1 && runSceneScript2()) { - return; - } else if (_itemInHand != 27 && pickUpItem(x, y, 1)) { - return; - } else if (checkItemCollision(x, y) == -1) { - resetGameFlag(1); - skip = runSceneScript1(x, y); - - if (queryGameFlag(1)) { - resetGameFlag(1); - return; - } else if (_unk5) { - _unk5 = 0; - return; - } - } - - if (_deathHandler >= 0) - skip = 1; - - if (skip) - return; - - if (checkCharCollision(x, y)) { - if (runSceneScript2()) - return; - } else if (_itemInHand >= 0 && _unk3 >= 0) { - if (_itemInHand == 27) { - makeCharFacingMouse(); - } else if (y <= 187) { - if (_itemInHand == 43) - removeHandItem(); - else - dropItem(0, _itemInHand, x, y, 1); - } - return; - } else if (_unk3 == -3) { - return; - } else { - if (y > 187 && _unk3 > -4) - return; - if (_unk5) { - _unk5 = 0; - return; - } - } - - inputSceneChange(x, y, 1, 1); -} - -int KyraEngine_v3::inputSceneChange(int x, int y, int unk1, int unk2) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::inputSceneChange(%d, %d, %d, %d)", x, y, unk1, unk2); - uint16 curScene = _mainCharacter.sceneId; - _pathfinderFlag = 15; - - if (!_unkHandleSceneChangeFlag) { - if (_unk3 == -4) { - if (_sceneList[curScene].exit4 != 0xFFFF) { - x = 4; - y = _sceneEnterY4; - _pathfinderFlag = 7; - } - } else if (_unk3 == -6) { - if (_sceneList[curScene].exit2 != 0xFFFF) { - x = 316; - y = _sceneEnterY2; - _pathfinderFlag = 7; - } - } else if (_unk3 == -7) { - if (_sceneList[curScene].exit1 != 0xFFFF) { - x = _sceneEnterX1; - y = _sceneEnterY1 - 2; - _pathfinderFlag = 14; - } - } else if (_unk3 == -5) { - if (_sceneList[curScene].exit3 != 0xFFFF) { - x = _sceneEnterX3; - y = 191; - _pathfinderFlag = 11; - } - } - } - - if (ABS(_mainCharacter.x1 - x) < 4 && ABS(_mainCharacter.y1 - y) < 2) { - _pathfinderFlag = 0; - return 0; - } - - int x1 = _mainCharacter.x1 & (~3); - int y1 = _mainCharacter.y1 & (~1); - x &= ~3; - y &= ~1; - - int size = findWay(x1, y1, x, y, _moveFacingTable, 600); - _pathfinderFlag = 0; - - if (!size || size == 0x7D00) - return 0; - - return trySceneChange(_moveFacingTable, unk1, unk2); -} - -void KyraEngine_v3::update() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::update()"); - updateInput(); - - musicUpdate(0); - refreshAnimObjectsIfNeed(); - musicUpdate(0); - updateMouse(); - updateSpecialSceneScripts(); - updateCommandLine(); - //XXX - musicUpdate(0); - - _screen->updateScreen(); -} - -void KyraEngine_v3::updateWithText() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::update()"); - updateInput(); - - musicUpdate(0); - updateMouse(); - //XXX - updateSpecialSceneScripts(); - updateCommandLine(); - musicUpdate(0); - - restorePage3(); - drawAnimObjects(); - if (textEnabled() && _chatText) { - int curPage = _screen->_curPage; - _screen->_curPage = 2; - objectChatPrintText(_chatText, _chatObject); - _screen->_curPage = curPage; - } - refreshAnimObjects(0); - - _screen->updateScreen(); -} - -void KyraEngine_v3::updateMouse() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::updateMouse()"); - int shape = 0, offsetX = 0, offsetY = 0; - Common::Point mouse = getMousePos(); - bool hasItemCollision = checkItemCollision(mouse.x, mouse.y) != -1; - - if (mouse.y > 187) { - bool setItemCursor = false; - if (_handItemSet == -6) { - if (mouse.x < 311) - setItemCursor = true; - } else if (_handItemSet == -5) { - if (mouse.x < _sceneMinX || mouse.x > _sceneMaxX) - setItemCursor = true; - } else if (_handItemSet == -4) { - if (mouse.x > 8) - setItemCursor = true; - } - - if (setItemCursor) { - setItemMouseCursor(); - return; - } - } - - if (_inventoryState) { - if (mouse.y >= 144) - return; - hideInventory(); - } - - if (hasItemCollision && _handItemSet < -1 && _itemInHand < 0) { - _handItemSet = -1; - _itemInHand = -1; - _screen->setMouseCursor(0, 0, _gameShapes[0]); - } - - int type = 0; - if (mouse.y <= 199) { - if (mouse.x <= 8) { - if (_sceneExit4 != 0xFFFF) { - type = -4; - shape = 4; - offsetX = 0; - offsetY = 0; - } - } else if (mouse.x >= 311) { - if (_sceneExit2 != 0xFFFF) { - type = -6; - shape = 2; - offsetX = 13; - offsetY = 8; - } - } else if (mouse.y >= 171) { - if (_sceneExit3 != 0xFFFF) { - if (mouse.x >= _sceneMinX && mouse.x <= _sceneMaxX) { - type = -5; - shape = 3; - offsetX = 8; - offsetY = 13; - } - } - } else if (mouse.y <= 8) { - if (_sceneExit1 != 0xFFFF) { - type = -7; - shape = 1; - offsetX = 8; - offsetY = 0; - } - } - } - - for (int i = 0; i < _specialExitCount; ++i) { - if (checkSpecialSceneExit(i, mouse.x, mouse.y)) { - switch (_specialExitTable[20+i]) { - case 0: - type = -7; - shape = 1; - offsetX = 8; - offsetY = 0; - break; - - case 2: - type = -6; - shape = 2; - offsetX = 13; - offsetY = 8; - break; - - case 4: - type = -5; - shape = 3; - offsetX = 8; - offsetY = 13; - break; - - case 6: - type = -4; - shape = 4; - offsetX = 0; - offsetY = 8; - break; - - default: - break; - } - } - } - - if (type != 0 && type != _handItemSet && !hasItemCollision) { - _handItemSet = type; - _screen->setMouseCursor(offsetX, offsetY, _gameShapes[shape]); - } else if (type == 0 && _handItemSet != _itemInHand && mouse.x > 8 && mouse.x < 311 && mouse.y < 171 && mouse.y > 8) { - setItemMouseCursor(); - } else if (mouse.y > 187 && _handItemSet > -4 && type == 0 && !_inventoryState) { - showInventory(); - } -} - -void KyraEngine_v3::delay(uint32 millis, bool doUpdate, bool isMainLoop) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::delay(%d, %d, %d)", millis, doUpdate, isMainLoop); - uint32 endTime = _system->getMillis() + millis; - while (endTime > _system->getMillis()) { - if (doUpdate) { - //XXX - update(); - } - - _system->delayMillis(10); - } -} - -#pragma mark - - -void KyraEngine_v3::updateInput() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::updateInput()"); - Common::Event event; - - while (_eventMan->pollEvent(event)) { - switch (event.type) { - case Common::EVENT_QUIT: - _quitFlag = true; - break; - - case Common::EVENT_KEYDOWN: - if (event.kbd.keycode == '.' || event.kbd.keycode == Common::KEYCODE_ESCAPE) - _eventList.push_back(Event(event, true)); - else if (event.kbd.keycode == 'q' && event.kbd.flags == Common::KBD_CTRL) - _quitFlag = true; - else - _eventList.push_back(event); - break; - - case Common::EVENT_LBUTTONDOWN: - _eventList.push_back(Event(event, true)); - break; - - case Common::EVENT_LBUTTONUP: - case Common::EVENT_MOUSEMOVE: - _eventList.push_back(event); - break; - - default: - break; - } - } -} - -int KyraEngine_v3::checkInput(Button *buttonList, bool mainLoop) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::checkInput(%p, %d)", (const void*)buttonList, mainLoop); - updateInput(); - - int keys = 0; - - while (_eventList.size()) { - Common::Event event = *_eventList.begin(); - bool breakLoop = false; - - 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) && mainLoop) { - const char *saveLoadSlot = getSavegameFilename(9 - (event.kbd.keycode - '0') + 990); - - if (event.kbd.flags == Common::KBD_CTRL) { - loadGame(saveLoadSlot); - _eventList.clear(); - breakLoop = true; - } 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(); - } - break; - - case Common::EVENT_MOUSEMOVE: { - Common::Point pos = getMousePos(); - _mouseX = pos.x; - _mouseY = pos.y; - _screen->updateScreen(); - } break; - - case Common::EVENT_LBUTTONDOWN: - case Common::EVENT_LBUTTONUP: { - Common::Point pos = getMousePos(); - _mouseX = pos.x; - _mouseY = pos.y; - keys = event.type == Common::EVENT_LBUTTONDOWN ? 199 : (200 | 0x800); - breakLoop = true; - } break; - - default: - break; - } - - if (_debugger->isAttached()) - _debugger->onFrame(); - - if (breakLoop) - break; - - _eventList.erase(_eventList.begin()); - } - - return _gui->processButtonList(buttonList, keys | 0x8000); -} - -void KyraEngine_v3::removeInputTop() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::removeInputTop()"); - if (!_eventList.empty()) - _eventList.erase(_eventList.begin()); -} - -bool KyraEngine_v3::skipFlag() const { - debugC(9, kDebugLevelMain, "KyraEngine_v3::skipFlag()"); - for (Common::List::const_iterator i = _eventList.begin(); i != _eventList.end(); ++i) { - if (i->causedSkip) - return true; - } - return false; -} - -void KyraEngine_v3::resetSkipFlag(bool removeEvent) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::resetSkipFlag(%d)", removeEvent); - for (Common::List::iterator i = _eventList.begin(); i != _eventList.end(); ++i) { - if (i->causedSkip) { - if (removeEvent) - _eventList.erase(i); - else - i->causedSkip = false; - return; - } - } -} - -void KyraEngine_v3::makeCharFacingMouse() { - debugC(9, kDebugLevelAnimator, "KyraEngine_v3::makeCharFacingMouse()"); - if (_mainCharacter.x1 > _mouseX) - _mainCharacter.facing = 5; - else - _mainCharacter.facing = 3; - _mainCharacter.animFrame = _characterFrameTable[_mainCharacter.facing]; - updateCharacterAnim(0); - refreshAnimObjectsIfNeed(); -} - -#pragma mark - - -int KyraEngine_v3::getDrawLayer(int x, int y) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::getDrawLayer(%d, %d)", x, y); - int layer = _screen->getLayer(x, y) - 1; - layer = _sceneDatLayerTable[layer]; - return MAX(0, MIN(layer, 6)); -} - -int KyraEngine_v3::getScale(int x, int y) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::getScale(%d, %d)", x, y); - return _scaleTable[_screen->getLayer(x, y) - 1]; -} - -#pragma mark - - -void KyraEngine_v3::backUpGfxRect32x32(int x, int y) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::backUpGfxRect32x32(%d, %d)", x, y); - _screen->copyRegionToBuffer(_screen->_curPage, x, y, 32, 32, _gfxBackUpRect); -} - -void KyraEngine_v3::restoreGfxRect32x32(int x, int y) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::restoreGfxRect32x32(%d, %d)", x, y); - _screen->copyBlockToPage(_screen->_curPage, x, y, 32, 32, _gfxBackUpRect); -} - -#pragma mark - - -char *KyraEngine_v3::appendLanguage(char *buf, int lang, int bufSize) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::appendLanguage([%p|'%s'], %d, %d)", (const void*)buf, buf, lang, bufSize); - assert(lang < _languageExtensionSize); - - int size = strlen(buf) + strlen(_languageExtension[lang]); - - if (size > bufSize) { - warning("buffer too small to append language extension"); - return 0; - } - - char *temp = buf + strlen(buf); - bufSize -= strlen(buf); - - strncat(temp, _languageExtension[lang], bufSize); - - return buf; -} - -int KyraEngine_v3::loadLanguageFile(const char *file, uint8 *&buffer) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::loadLanguageFile('%s', %p)", file, (const void*)buffer); - - uint32 size = 0; - char nBuf[32]; - strncpy(nBuf, file, 32); - buffer = _res->fileData(appendLanguage(nBuf, _lang, sizeof(nBuf)), &size); - - return buffer ? size : 0 ; -} - -uint8 *KyraEngine_v3::getTableEntry(uint8 *buffer, int id) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::getTableEntry(%p, %d)", (const void*)buffer, id); - uint16 tableEntries = READ_LE_UINT16(buffer); - const uint16 *indexTable = (const uint16*)(buffer + 2); - const uint16 *offsetTable = indexTable + tableEntries; - - int num = 0; - while (id != READ_LE_UINT16(indexTable)) { - ++indexTable; - ++num; - } - - return buffer + READ_LE_UINT16(offsetTable + num); -} - -void KyraEngine_v3::getTableEntry(Common::SeekableReadStream *stream, int id, char *dst) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::getTableEntry(%p, %d, %p)", (const void*)stream, id, (const void*)dst); - stream->seek(0, SEEK_SET); - uint16 tableEntries = stream->readUint16LE(); - - int num = 0; - while (id != stream->readUint16LE()) - ++num; - - stream->seek(2+tableEntries*2+num*2, SEEK_SET); - stream->seek(stream->readUint16LE(), SEEK_SET); - char c = 0; - while ((c = stream->readByte()) != 0) - *dst++ = c; - *dst = 0; -} - -#pragma mark - - -bool KyraEngine_v3::talkObjectsInCurScene() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::talkObjectsInCurScene()"); - - for (int i = 0; i < 88; ++i) { - if (_talkObjectList[i].sceneId == _mainCharacter.sceneId) - return true; - } - - return false; -} - -#pragma mark - - -bool KyraEngine_v3::updateScore(int scoreId, int strId) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::updateScore(%d, %d)", scoreId, strId); - - int scoreIndex = (scoreId >> 3); - int scoreBit = scoreId & 7; - if ((_scoreFlagTable[scoreIndex] & (1 << scoreBit)) != 0) - return false; - - setNextIdleAnimTimer(); - _scoreFlagTable[scoreIndex] |= (1 << scoreBit); - - _screen->hideMouse(); - strcpy(_stringBuffer, (const char*)getTableEntry(_scoreFile, strId)); - strcat(_stringBuffer, ": "); - - assert(scoreId < _scoreTableSize); - - int count = _scoreTable[scoreId]; - if (count > 0) - scoreIncrease(count, _stringBuffer); - - _screen->showMouse(); - setNextIdleAnimTimer(); - return true; -} - -void KyraEngine_v3::scoreIncrease(int count, const char *str) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::scoreIncrease(%d, '%s')", count, str); - int drawOld = 1; - _screen->hideMouse(); - - showMessage(str, 0xFF, 0xF0); - const int x = getScoreX(str); - - for (int i = 0; i < count; ++i) { - int oldScore = _score; - int newScore = ++_score; - - if (newScore > _scoreMax) { - _score = _scoreMax; - break; - } - - drawScoreCounting(oldScore, newScore, drawOld, x); - if (_inventoryState) - drawScore(0, 215, 191); - _screen->updateScreen(); - delay(20, true); - - snd_playSoundEffect(0x0E, 0xC8); - drawOld = 0; - } - - _screen->showMouse(); -} - -#pragma mark - - -void KyraEngine_v3::changeChapter(int newChapter, int sceneId, int malcolmShapes, int facing) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::changeChapter(%d, %d, %d, %d)", newChapter, sceneId, malcolmShapes, facing); - resetItemList(); - - _currentChapter = newChapter; - runStartupScript(newChapter, 0); - _mainCharacter.dlgIndex = 0; - - _malcolmsMood = 1; - memset(_newSceneDlgState, 0, sizeof(_newSceneDlgState)); - - if (malcolmShapes >= 0) - loadMalcolmShapes(malcolmShapes); - - enterNewScene(sceneId, facing, 0, 0, 0); -} - -} // end of namespace Kyra - diff --git a/engines/kyra/kyra_v3.h b/engines/kyra/kyra_v3.h deleted file mode 100644 index c666f25eba..0000000000 --- a/engines/kyra/kyra_v3.h +++ /dev/null @@ -1,833 +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_V3_H -#define KYRA_KYRA_V3_H - -#include "kyra/kyra.h" -#include "kyra/screen_v3.h" -#include "kyra/script.h" - -#include "common/hashmap.h" -#include "common/list.h" - -namespace Kyra { - -class SoundDigital; -class Screen_v3; -class MainMenu; -class WSAMovieV2; -class TextDisplayer_v3; -class Debugger_v3; -class GUI_v3; -struct Button; - -class KyraEngine_v3 : public KyraEngine { -friend class Debugger_v3; -friend class TextDisplayer_v3; -friend class GUI_v3; -public: - KyraEngine_v3(OSystem *system, const GameFlags &flags); - ~KyraEngine_v3(); - - Screen *screen() { return _screen; } - SoundDigital *soundDigital() { return _soundDigital; } - int language() const { return _lang; } - - int go(); - - void playVQA(const char *name); - -private: - Screen_v3 *_screen; - SoundDigital *_soundDigital; - - int init(); - - void preinit(); - void startup(); - void runStartupScript(int script, int unk1); - - void setupOpcodeTable(); - - // run - bool _showOutro; - bool _runFlag; - int _deathHandler; - - void runLoop(); - void handleInput(int x, int y); - bool _unkHandleSceneChangeFlag; - int inputSceneChange(int x, int y, int unk1, int unk2); - - void update(); - void updateWithText(); - void updateMouse(); - - void delay(uint32 millis, bool update = false, bool isMainLoop = false); - - // - Input - void updateInput(); - int checkInput(Button *buttonList, bool mainLoop = false); - void removeInputTop(); - - int _mouseX, _mouseY; - int _mouseState; - - struct Event { - Common::Event event; - bool causedSkip; - - Event() : event(), causedSkip(false) {} - Event(Common::Event e) : event(e), causedSkip(false) {} - Event(Common::Event e, bool skip) : event(e), causedSkip(skip) {} - - operator Common::Event() const { return event; } - }; - Common::List _eventList; - - bool skipFlag() const; - void resetSkipFlag(bool removeEvent = true); - - // sound specific -private: - void playMenuAudioFile(); - - int _musicSoundChannel; - int _fadeOutMusicChannel; - const char *_menuAudioFile; - - static const char *_soundList[]; - static const int _soundListSize; - - void snd_playWanderScoreViaMap(int track, int force); - void stopMusicTrack(); - - int musicUpdate(int forceRestart); - void fadeOutMusic(int ticks); - - void snd_playSoundEffect(int item, int volume); - - static const uint8 _sfxFileMap[]; - static const int _sfxFileMapSize; - static const char *_sfxFileList[]; - static const int _sfxFileListSize; - - int _voiceSoundChannel; - - void playVoice(int high, int low); - void snd_playVoiceFile(int file); - bool snd_voiceIsPlaying(); - void snd_stopVoice(); - - int _curStudioSFX; - void playStudioSFX(const char *str); - - // gui - GUI_v3 *_gui; - - Button *_mainButtonData; - Button *_mainButtonList; - bool _mainButtonListInitialized; - void initMainButtonList(bool disable); - - bool _enableInventory; - int buttonInventory(Button *button); - int buttonMoodChange(Button *button); - int buttonShowScore(Button *button); - int buttonJesterStaff(Button *button); - - // -> main menu - void initMainMenu(); - void uninitMainMenu(); - - WSAMovieV2 *_menuAnim; - MainMenu *_menu; - - // timer - void setupTimers(); - - void setWalkspeed(uint8); - void setCommandLineRestoreTimer(int secs); - - void timerRestoreCommandLine(int arg); - void timerRunSceneScript7(int arg); - void timerFleaDeath(int arg); - - uint32 _nextIdleAnim; - void setNextIdleAnimTimer(); - - // pathfinder - int *_moveFacingTable; - int _pathfinderFlag; - - int findWay(int x1, int y1, int x2, int y2, int *moveTable, int moveTableSize); - bool lineIsPassable(int x, int y); - -private: - // main menu - static const char *_mainMenuStrings[]; - - // animator - struct AnimObj { - uint16 index; - uint16 type; - bool enabled; - bool needRefresh; - uint16 unk8; - uint16 flags; - int16 xPos1, yPos1; - uint8 *shapePtr; - uint16 shapeIndex; - uint16 animNum; - uint16 shapeIndex3; - uint16 shapeIndex2; - int16 xPos2, yPos2; - int16 xPos3, yPos3; - int16 width, height; - int16 width2, height2; - uint16 palette; - AnimObj *nextObject; - }; - - AnimObj *_animObjects; - uint8 *_gamePlayBuffer; - - void clearAnimObjects(); - - AnimObj *_animList; - bool _drawNoShapeFlag; - AnimObj *initAnimList(AnimObj *list, AnimObj *entry); - AnimObj *addToAnimListSorted(AnimObj *list, AnimObj *entry); - AnimObj *deleteAnimListEntry(AnimObj *list, AnimObj *entry); - - void animSetupPaletteEntry(AnimObj *anim); - - void restorePage3(); - - void drawAnimObjects(); - void drawSceneAnimObject(AnimObj *obj, int x, int y, int drawLayer); - void drawCharacterAnimObject(AnimObj *obj, int x, int y, int drawLayer); - - void refreshAnimObjects(int force); - void refreshAnimObjectsIfNeed(); - - void flagAnimObjsForRefresh(); - - bool _loadingState; - void updateCharacterAnim(int charId); - - void updateSceneAnim(int anim, int newFrame); - void setupSceneAnimObject(int anim, uint16 flags, int x, int y, int x2, int y2, int w, int h, int unk10, int specialSize, int unk14, int shape, const char *filename); - void removeSceneAnimObject(int anim, int refresh); - - int _charBackUpWidth2, _charBackUpHeight2; - int _charBackUpWidth, _charBackUpHeight; - - void setCharacterAnimDim(int w, int h); - void resetCharacterAnimDim(); - - bool _nextIdleType; - void showIdleAnim(); - - void addItemToAnimList(int item); - void deleteItemAnimEntry(int item); - - // interface - uint8 *_interface; - uint8 *_interfaceCommandLine; - - void loadInterfaceShapes(); - void loadInterface(); - - void showMessage(const char *string, uint8 c0, uint8 c1); - void showMessageFromCCode(int string, uint8 c0, int); - void updateItemCommand(int item, int str, uint8 c0); - - void updateCommandLine(); - void restoreCommandLine(); - void updateCLState(); - - int _commandLineY; - const char *_shownMessage; - bool _restoreCommandLine; - bool _inventoryState; - int _inventoryScrollSpeed; - - void showInventory(); - void hideInventory(); - - void drawMalcolmsMoodText(); - void drawMalcolmsMoodPointer(int frame, int page); - void drawJestersStaff(int type, int page); - - void drawScore(int page, int x, int y); - void drawScoreCounting(int oldScore, int newScore, int drawOld, const int x); - int getScoreX(const char *str); - - static const uint8 _inventoryX[]; - static const uint8 _inventoryY[]; - void redrawInventory(int page); - void clearInventorySlot(int slot, int page); - void drawInventorySlot(int page, int item, int slot); - - WSAMovieV2 *_invWsa; - int _invWsaFrame; - - // localization - uint8 *_scoreFile; - uint8 *_cCodeFile; - uint8 *_scenesFile; - uint8 *_itemFile; - uint8 *_actorFile; - uint32 _actorFileSize; - uint8 *_sceneStrings; - - uint8 *getTableEntry(uint8 *buffer, int id); - void getTableEntry(Common::SeekableReadStream *stream, int id, char *dst); - - // items - int8 *_itemBuffer1; - int8 *_itemBuffer2; - struct Item { - uint16 id; - uint16 sceneId; - int16 x, y; - uint16 unk8; - }; - - Item *_itemList; - uint16 _hiddenItems[100]; - - void resetItem(int index); - void resetItemList(); - static const uint8 _trashItemList[]; - void removeTrashItems(); - - int findFreeItem(); - int findItem(uint16 item, uint16 scene); - int findItem(uint16 item); - - int countAllItems(); - - void initItems(); - - int checkItemCollision(int x, int y); - - bool dropItem(int unk1, uint16 item, int x, int y, int unk2); - bool processItemDrop(uint16 sceneId, uint16 item, int x, int y, int unk1, int unk2); - void itemDropDown(int startX, int startY, int dstX, int dstY, int itemSlot, uint16 item, int remove); - void exchangeMouseItem(int itemPos, int runScript); - bool pickUpItem(int x, int y, int runScript); - - bool isDropable(int x, int y); - - static const uint8 _itemMagicTable[]; - bool itemListMagic(int handItem, int itemSlot); - bool itemInventoryMagic(int handItem, int invSlot); - - static const uint8 _itemStringMap[]; - static const uint _itemStringMapSize; - static const uint8 _itemStringPickUp[]; - static const uint8 _itemStringDrop[]; - static const uint8 _itemStringInv[]; - - int getItemCommandStringPickUp(uint16 item); - int getItemCommandStringDrop(uint16 item); - int getItemCommandStringInv(uint16 item); - - // -> hand item - void setMouseCursor(uint16 item); - - void setHandItem(uint16 item); - void removeHandItem(); - void setItemMouseCursor(); - - int _itemInHand; - int _handItemSet; - - // shapes - typedef Common::HashMap ShapeMap; - ShapeMap _gameShapes; - - void addShapeToPool(const uint8 *data, int realIndex, int shape); - uint8 *getShapePtr(int shape) const; - - void initMouseShapes(); - - int _malcolmShapes; - void loadMalcolmShapes(int newShapes); - void updateMalcolmShapes(); - - int _malcolmShapeXOffset, _malcolmShapeYOffset; - - struct ShapeDesc { - uint8 width, height; - int8 xOffset, yOffset; - }; - static const ShapeDesc _shapeDescs[]; - static const int _shapeDescsSize; - - // scene animation - struct SceneAnim { - uint16 flags; - int16 x, y; - int16 x2, y2; - int16 width, height; - uint16 unk10; - uint16 specialSize; - uint16 unk14; - uint16 shapeIndex; - uint16 wsaFlag; - char filename[13]; - }; - - SceneAnim *_sceneAnims; - WSAMovieV2 *_sceneAnimMovie[16]; - uint8 *_sceneShapes[20]; - - void freeSceneShapes(); - void freeSceneAnims(); - - // voice - int _currentTalkFile; - void openTalkFile(int file); - - // scene - struct SceneDesc { - char filename1[10]; - char filename2[10]; - uint16 exit1, exit2, exit3, exit4; - uint8 flags, sound; - }; - - SceneDesc *_sceneList; - int _sceneListSize; - uint16 _sceneExit1, _sceneExit2, _sceneExit3, _sceneExit4; - int _sceneEnterX1, _sceneEnterY1; - int _sceneEnterX2, _sceneEnterY2; - int _sceneEnterX3, _sceneEnterY3; - int _sceneEnterX4, _sceneEnterY4; - - int _specialExitCount; - uint16 _specialExitTable[25]; - bool checkSpecialSceneExit(int index, int x, int y); - - bool _noScriptEnter; - void enterNewScene(uint16 scene, int facing, int unk1, int unk2, int unk3); - void enterNewSceneUnk1(int facing, int unk1, int unk2); - void enterNewSceneUnk2(int unk1); - int _enterNewSceneLock; - - void unloadScene(); - - void loadScenePal(); - void loadSceneMsc(); - void initSceneScript(int unk1); - void initSceneAnims(int unk1); - void initSceneScreen(int unk1); - - int runSceneScript1(int x, int y); - int runSceneScript2(); - bool _noStartupChat; - void runSceneScript4(int unk1); - void runSceneScript6(); - void runSceneScript8(); - - int _sceneMinX, _sceneMaxX; - int _maskPageMinY, _maskPageMaxY; - - EMCState _sceneScriptState; - EMCData _sceneScriptData; - - bool _specialSceneScriptState[10]; - bool _specialSceneScriptStateBackup[10]; - EMCState _sceneSpecialScripts[10]; - uint32 _sceneSpecialScriptsTimer[10]; - int _lastProcessedSceneScript; - bool _specialSceneScriptRunFlag; - - void updateSpecialSceneScripts(); - - int trySceneChange(int *moveTable, int unk1, int unk2); - int checkSceneChange(); - - int8 _sceneDatPalette[45]; - int8 _sceneDatLayerTable[15]; - struct SceneShapeDesc { - // the original saves those variables, we don't, since - // they are just needed on scene load - /*int x, y; - int w, h;*/ - int drawX, drawY; - }; - SceneShapeDesc _sceneShapeDescs[20]; - - int getDrawLayer(int x, int y); - - int getScale(int x, int y); - int _scaleTable[15]; - - bool _unkSceneScreenFlag1; - - // character - struct Character { - uint16 sceneId; - uint16 dlgIndex; - uint8 height; - uint8 facing; - uint16 animFrame; - //uint8 unk8, unk9; - byte walkspeed; - uint16 inventory[10]; - int16 x1, y1; - int16 x2, y2; - int16 x3, y3; - }; - - Character _mainCharacter; - int _mainCharX, _mainCharY; - int _charScale; - - void moveCharacter(int facing, int x, int y); - - void updateCharPosWithUpdate(); - int updateCharPos(int *table, int force); - - uint32 _updateCharPosNextUpdate; - static const int8 _updateCharPosXTable[]; - static const int8 _updateCharPosYTable[]; - - void updateCharAnimFrame(int character, int *table); - int8 _characterAnimTable[2]; - static const uint8 _characterFrameTable[]; - - bool _overwriteSceneFacing; - - void updateCharPal(int unk1); - int _lastCharPalLayer; - bool _charPalUpdate; - - bool checkCharCollision(int x, int y); - - int _malcolmsMood; - - void makeCharFacingMouse(); - - int findFreeInventorySlot(); - - // talk object - struct TalkObject { - char filename[13]; - int8 sceneAnim; - int8 sceneScript; - int16 x, y; - uint8 color; - uint8 sceneId; - }; - - TalkObject *_talkObjectList; - - bool talkObjectsInCurScene(); - - // chat - int _vocHigh; - - const char *_chatText; - int _chatObject; - uint32 _chatEndTime; - int _chatVocHigh, _chatVocLow; - - EMCData _chatScriptData; - EMCState _chatScriptState; - - int chatGetType(const char *text); - int chatCalcDuration(const char *text); - - void objectChat(const char *text, int object, int vocHigh, int vocLow); - void objectChatInit(const char *text, int object, int vocHigh, int vocLow); - void objectChatPrintText(const char *text, int object); - void objectChatProcess(const char *script); - void objectChatWaitToFinish(); - - void badConscienceChat(const char *str, int vocHigh, int vocLow); - void badConscienceChatWaitToFinish(); - - void goodConscienceChat(const char *str, int vocHigh, int vocLow); - void goodConscienceChatWaitToFinish(); - - void malcolmSceneStartupChat(); - - byte _newSceneDlgState[40]; - int8 _conversationState[30][30]; - bool _chatAltFlag; - void setDlgIndex(uint16 index); - void updateDlgIndex(); - - Common::SeekableReadStream *_cnvFile; - Common::SeekableReadStream *_dlgBuffer; - int _curDlgChapter, _curDlgIndex, _curDlgLang; - void updateDlgBuffer(); - void loadDlgHeader(int &vocHighBase, int &vocHighIndex, int &index1, int &index2); - - static const uint8 _vocHighTable[]; - bool _isStartupDialog; - void processDialog(int vocHighIndex, int vocHighBase, int funcNum); - - EMCData _dialogScriptData; - EMCState _dialogScriptState; - int _dialogSceneAnim; - int _dialogSceneScript; - int _dialogScriptFuncStart, _dialogScriptFuncProc, _dialogScriptFuncEnd; - - void dialogStartScript(int object, int funcNum); - void dialogEndScript(int object); - - void npcChatSequence(const char *str, int object, int vocHigh, int vocLow); - - Common::Array _opcodesDialog; - - int o3d_updateAnim(EMCState *script); - int o3d_delay(EMCState *script); - - void malcolmRandomChat(); - void runDialog(int dlgIndex, int funcNum); - - // conscience - bool _badConscienceShown; - int _badConscienceAnim; - bool _badConsciencePosition; - - static const uint8 _badConscienceFrameTable[]; - - void showBadConscience(); - void hideBadConscience(); - - bool _goodConscienceShown; - int _goodConscienceAnim; - bool _goodConsciencePosition; - - static const uint8 _goodConscienceFrameTable[]; - - void showGoodConscience(); - void hideGoodConscience(); - - // special script code - bool _temporaryScriptExecBit; - bool _useFrameTable; - - Common::Array _opcodesTemporary; - - int o3t_defineNewShapes(EMCState *script); - int o3t_setCurrentFrame(EMCState *script); - int o3t_setNewShapeFlag(EMCState *script); - - EMCData _temporaryScriptData; - EMCState _temporaryScriptState; - - void runTemporaryScript(const char *filename, int allowSkip, int resetChar, int newShapes, int shapeUnload); - - // special shape code - char _newShapeFilename[13]; - int _newShapeLastEntry; - int _newShapeWidth, _newShapeHeight; - int _newShapeXAdd, _newShapeYAdd; - - int _newShapeAnimFrame; - int _newShapeDelay; - - int _newShapeFlag; - uint8 *_newShapeFiledata; - int _newShapeCount; - - int initNewShapes(uint8 *filedata); - void processNewShapes(int allowSkip, int resetChar); - void resetNewShapes(int count, uint8 *filedata); - - // unk - uint8 *_costPalBuffer; - uint8 *_screenBuffer; - uint8 *_paletteOverlay; - bool _useActorBuffer; - - int _currentChapter; - void changeChapter(int newChapter, int sceneId, int malcolmShapes, int facing); - - static const uint8 _chapterLowestScene[]; - - int _unk3, _unk4, _unk5; - - void loadCostPal(); - void loadShadowShape(); - void loadExtrasShapes(); - - uint8 *_gfxBackUpRect; - void backUpGfxRect32x32(int x, int y); - void restoreGfxRect32x32(int x, int y); - - char *_stringBuffer; - - int _score; - int _scoreMax; - - static const int8 _scoreTable[]; - static const int _scoreTableSize; - int8 _scoreFlagTable[26]; - bool updateScore(int scoreId, int strId); - void scoreIncrease(int count, const char *str); - - void eelScript(); - - // save/load - void saveGame(const char *fileName, const char *saveName); - void loadGame(const char *fileName); - - // opcodes - int o3_getMalcolmShapes(EMCState *script); - int o3_setCharacterPos(EMCState *script); - int o3_defineObject(EMCState *script); - int o3_refreshCharacter(EMCState *script); - int o3_getCharacterX(EMCState *script); - int o3_getCharacterY(EMCState *script); - int o3_getCharacterFacing(EMCState *script); - int o3_getCharacterScene(EMCState *script); - int o3_getMalcolmsMood(EMCState *script); - int o3_getCharacterFrameFromFacing(EMCState *script); - int o3_setCharacterFacingOverwrite(EMCState *script); - int o3_trySceneChange(EMCState *script); - int o3_moveCharacter(EMCState *script); - int o3_setCharacterFacing(EMCState *script); - int o3_showSceneFileMessage(EMCState *script); - int o3_setCharacterAnimFrameFromFacing(EMCState *script); - int o3_showBadConscience(EMCState *script); - int o3_hideBadConscience(EMCState *script); - int o3_setInventorySlot(EMCState *script); - int o3_getInventorySlot(EMCState *script); - int o3_addItemToInventory(EMCState *script); - int o3_addItemToCurScene(EMCState *script); - int o3_objectChat(EMCState *script); - int o3_checkForItem(EMCState *script); - int o3_resetInventory(EMCState *script); - int o3_defineItem(EMCState *script); - int o3_removeInventoryItemInstances(EMCState *script); - int o3_countInventoryItemInstances(EMCState *script); - int o3_npcChatSequence(EMCState *script); - int o3_queryGameFlag(EMCState *script); - int o3_resetGameFlag(EMCState *script); - int o3_setGameFlag(EMCState *script); - int o3_setHandItem(EMCState *script); - int o3_removeHandItem(EMCState *script); - int o3_handItemSet(EMCState *script); - int o3_hideMouse(EMCState *script); - int o3_addSpecialExit(EMCState *script); - int o3_setMousePos(EMCState *script); - int o3_showMouse(EMCState *script); - int o3_badConscienceChat(EMCState *script); - int o3_wipeDownMouseItem(EMCState *script); - int o3_setMalcolmsMood(EMCState *script); - int o3_delay(EMCState *script); - int o3_updateScore(EMCState *script); - int o3_makeSecondChanceSave(EMCState *script); - int o3_setSceneFilename(EMCState *script); - int o3_removeItemsFromScene(EMCState *script); - int o3_disguiseMalcolm(EMCState *script); - int o3_drawSceneShape(EMCState *script); - int o3_drawSceneShapeOnPage(EMCState *script); - int o3_checkInRect(EMCState *script); - int o3_updateConversations(EMCState *script); - int o3_setSceneDim(EMCState *script); - int o3_update(EMCState *script); - int o3_setSceneAnimPosAndFrame(EMCState *script); - int o3_removeItemInstances(EMCState *script); - int o3_disableInventory(EMCState *script); - int o3_enableInventory(EMCState *script); - int o3_enterNewScene(EMCState *script); - int o3_switchScene(EMCState *script); - int o3_getShapeFlag1(EMCState *script); - int o3_setMalcolmPos(EMCState *script); - int o3_stopMusic(EMCState *script); - int o3_playWanderScoreViaMap(EMCState *script); - int o3_playSoundEffect(EMCState *script); - int o3_getScore(EMCState *script); - int o3_blockOutRegion(EMCState *script); - int o3_showSceneStringsMessage(EMCState *script); - int o3_getRand(EMCState *script); - int o3_setDeathHandler(EMCState *script); - int o3_showGoodConscience(EMCState *script); - int o3_goodConscienceChat(EMCState *script); - int o3_hideGoodConscience(EMCState *script); - int o3_waitForConfirmationClick(EMCState *script); - int o3_defineRoomEntrance(EMCState *script); - int o3_runTemporaryScript(EMCState *script); - int o3_setSpecialSceneScriptRunTime(EMCState *script); - int o3_defineSceneAnim(EMCState *script); - int o3_updateSceneAnim(EMCState *script); - int o3_runActorScript(EMCState *script); - int o3_runDialog(EMCState *script); - int o3_malcolmRandomChat(EMCState *script); - int o3_setDlgIndex(EMCState *script); - int o3_getDlgIndex(EMCState *script); - int o3_defineScene(EMCState *script); - int o3_setConversationState(EMCState *script); - int o3_getConversationState(EMCState *script); - int o3_changeChapter(EMCState *script); - int o3_countItemInstances(EMCState *script); - int o3_dialogStartScript(EMCState *script); - int o3_dialogEndScript(EMCState *script); - int o3_setSpecialSceneScriptState(EMCState *script); - int o3_clearSpecialSceneScriptState(EMCState *script); - int o3_querySpecialSceneScriptState(EMCState *script); - int o3_setHiddenItemsEntry(EMCState *script); - int o3_getHiddenItemsEntry(EMCState *script); - int o3_customChat(EMCState *script); - int o3_customChatFinish(EMCState *script); - int o3_setupSceneAnimObject(EMCState *script); - int o3_removeSceneAnimObject(EMCState *script); - int o3_disableTimer(EMCState *script); - int o3_enableTimer(EMCState *script); - int o3_setTimerCountdown(EMCState *script); - int o3_setVocHigh(EMCState *script); - int o3_getVocHigh(EMCState *script); - int o3_dummy(EMCState *script); - - // misc - TextDisplayer_v3 *_text; - Debugger_v3 *_debugger; - bool _wsaPlayingVQA; - - // resource specific -private: - static const char *_languageExtension[]; - static const int _languageExtensionSize; - - char *appendLanguage(char *buf, int lang, int bufSize); - - int loadLanguageFile(const char *file, uint8 *&buffer); -}; - -} // end of namespace Kyra - -#endif - diff --git a/engines/kyra/module.mk b/engines/kyra/module.mk index d53479b133..a45891de46 100644 --- a/engines/kyra/module.mk +++ b/engines/kyra/module.mk @@ -3,7 +3,8 @@ MODULE := engines/kyra MODULE_OBJS := \ animator_v1.o \ animator_v2.o \ - animator_v3.o \ + animator_hof.o \ + animator_mr.o \ debugger.o \ detection.o \ gui.o \ @@ -11,34 +12,37 @@ MODULE_OBJS := \ gui_v2.o \ gui_v3.o \ items_v1.o \ - items_v2.o \ - items_v3.o \ + items_hof.o \ + items_mr.o \ kyra.o \ kyra_v1.o \ kyra_v2.o \ - kyra_v3.o \ + kyra_hof.o \ + kyra_mr.o \ resource.o \ saveload.o \ saveload_v1.o \ - saveload_v2.o \ - saveload_v3.o \ + saveload_hof.o \ + saveload_mr.o \ scene.o \ scene_v1.o \ scene_v2.o \ - scene_v3.o \ + scene_hof.o \ + scene_mr.o \ screen.o \ screen_v1.o \ screen_v2.o \ - screen_v3.o \ + screen_hof.o \ + screen_mr.o \ script_v1.o \ - script_v2.o \ - script_v3.o \ + script_hof.o \ + script_mr.o \ script.o \ script_tim.o \ seqplayer.o \ sequences_v1.o \ - sequences_v2.o \ - sequences_v3.o \ + sequences_hof.o \ + sequences_mr.o \ sound_adlib.o \ sound_digital.o \ sound_towns.o \ @@ -48,12 +52,12 @@ MODULE_OBJS := \ staticres.o \ text.o \ text_v1.o \ - text_v2.o \ - text_v3.o \ + text_hof.o \ + text_mr.o \ timer.o \ timer_v1.o \ - timer_v2.o \ - timer_v3.o \ + timer_hof.o \ + timer_mr.o \ vqa.o \ wsamovie.o diff --git a/engines/kyra/resource.h b/engines/kyra/resource.h index 7a6bdbd73e..f414cacee8 100644 --- a/engines/kyra/resource.h +++ b/engines/kyra/resource.h @@ -37,7 +37,7 @@ #include "common/ptr.h" #include "kyra/kyra.h" -#include "kyra/kyra_v2.h" +#include "kyra/kyra_hof.h" namespace Kyra { diff --git a/engines/kyra/saveload_hof.cpp b/engines/kyra/saveload_hof.cpp new file mode 100644 index 0000000000..00a54ea916 --- /dev/null +++ b/engines/kyra/saveload_hof.cpp @@ -0,0 +1,333 @@ +/* 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_v2.h" +#include "kyra/screen_v2.h" +#include "kyra/resource.h" +#include "kyra/sound.h" +#include "kyra/timer.h" + +namespace Kyra { + +void KyraEngine_HoF::saveGame(const char *fileName, const char *saveName) { + debugC(9, kDebugLevelMain, "KyraEngine_HoF::saveGame('%s', '%s')", fileName, saveName); + + Common::OutSaveFile *out = openSaveForWriting(fileName, saveName); + if (!out) { + warning("Can't open file '%s', game not loadable", fileName); + return; + } + + _timer->saveDataToFile(*out); + + out->writeUint32BE(sizeof(_flagsTable)); + out->write(_flagsTable, sizeof(_flagsTable)); + + // usually we have to save the flag set by opcode 10 here + //out->writeUint16BE(word_2AB05); + out->writeSint16BE(_lastMusicCommand); + out->writeByte(_newChapterFile); + out->writeByte(_loadedZTable); + out->writeByte(_cauldronState); + out->writeByte(_colorCodeFlag1); + out->writeByte(_colorCodeFlag2); + out->writeByte(_bookCurPage); + out->writeByte(_bookMaxPage); + for (int i = 0; i < 7; ++i) + out->writeByte(_presetColorCode[i]); + for (int i = 0; i < 7; ++i) + out->writeByte(_inputColorCode[i]); + for (int i = 0; i < 25; ++i) + out->writeSint16BE(_cauldronTable[i]); + for (int i = 0; i < 20; ++i) + out->writeUint16BE(_hiddenItems[i]); + for (int i = 0; i < 19; ++i) + out->write(_conversationState[i], 14); + out->write(_newSceneDlgState, 32); + out->writeSint16BE(_cauldronUseCount); + + out->writeUint16BE(_mainCharacter.sceneId); + out->writeUint16BE(_mainCharacter.dlgIndex); + out->writeByte(_mainCharacter.height); + out->writeByte(_mainCharacter.facing); + out->writeUint16BE(_mainCharacter.animFrame); + out->writeByte(_mainCharacter.unk8); + out->writeByte(_mainCharacter.unk9); + out->writeByte(_mainCharacter.unkA); + for (int i = 0; i < 20; ++i) + out->writeUint16BE(_mainCharacter.inventory[i]); + out->writeSint16BE(_mainCharacter.x1); + out->writeSint16BE(_mainCharacter.y1); + out->writeSint16BE(_mainCharacter.x2); + out->writeSint16BE(_mainCharacter.y2); + + for (int i = 0; i < 30; ++i) { + out->writeUint16BE(_itemList[i].id); + out->writeUint16BE(_itemList[i].sceneId); + out->writeSint16BE(_itemList[i].x); + out->writeByte(_itemList[i].y); + out->writeUint16BE(_itemList[i].unk7); + } + + for (int i = 0; i < 72; ++i) { + out->write(_talkObjectList[i].filename, 13); + out->writeByte(_talkObjectList[i].scriptId); + out->writeSint16BE(_talkObjectList[i].x); + out->writeSint16BE(_talkObjectList[i].y); + out->writeByte(_talkObjectList[i].color); + } + + for (int i = 0; i < 86; ++i) { + out->write(_sceneList[i].filename1, 10); + out->writeUint16BE(_sceneList[i].exit1); + out->writeUint16BE(_sceneList[i].exit2); + out->writeUint16BE(_sceneList[i].exit3); + out->writeUint16BE(_sceneList[i].exit4); + out->writeByte(_sceneList[i].flags); + out->writeByte(_sceneList[i].sound); + } + + out->writeSint16BE(_itemInHand); + out->writeUint16BE(_sceneExit1); + out->writeUint16BE(_sceneExit2); + out->writeUint16BE(_sceneExit3); + out->writeUint16BE(_sceneExit4); + + 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; +} + +void KyraEngine_HoF::loadGame(const char *fileName) { + debugC(9, kDebugLevelMain, "KyraEngine_HoF::loadGame('%s')", fileName); + + SaveHeader header; + Common::InSaveFile *saveFile = openSaveForReading(fileName, header); + if (!saveFile) { + showMessageFromCCode(0x35, 0x84, 0); + snd_playSoundEffect(0x0D); + return; + } + + if (header.originalSave) + warning("Trying to load savegame from original interpreter, while this is possible, it is not officially supported"); + + bool setFlag1EE = (queryGameFlag(0x1EE) != 0); + + _deathHandler = -1; + if (!_unkSceneScreenFlag1) { + _sound->beginFadeOut(); + _system->delayMillis(5 * _tickLength); + _lastMusicCommand = -1; + } + + int loadedZTable = _loadedZTable; + + Common::SeekableSubReadStreamEndian in(saveFile, saveFile->pos(), saveFile->size(), !header.originalSave, true); + + _screen->hideMouse(); + + if (!header.originalSave) { + _timer->loadDataFromFile(in, header.version); + + uint32 flagsSize = in.readUint32BE(); + assert(flagsSize <= sizeof(_flagsTable)); + in.read(_flagsTable, flagsSize); + } + + // usually we have to save the flag set by opcode 10 here + //word_2AB05 = in.readUint16(); + if (header.originalSave) + in.readUint16(); + _lastMusicCommand = in.readSint16(); + _newChapterFile = in.readByte(); + _loadedZTable = in.readByte(); + _cauldronState = in.readByte(); + _colorCodeFlag1 = in.readByte(); + _colorCodeFlag2 = in.readByte(); + _bookCurPage = in.readByte(); + _bookMaxPage = in.readByte(); + for (int i = 0; i < 7; ++i) + _presetColorCode[i] = in.readByte(); + for (int i = 0; i < 7; ++i) + _inputColorCode[i] = in.readByte(); + for (int i = 0; i < 25; ++i) + _cauldronTable[i] = in.readSint16(); + for (int i = 0; i < 20; ++i) + _hiddenItems[i] = in.readUint16(); + + if (header.originalSave) { + assert(sizeof(_flagsTable) >= 0x41); + in.read(_flagsTable, 0x41); + } + + for (int i = 0; i < 19; ++i) + in.read(_conversationState[i], 14); + + if (!header.originalSave) { + in.read(_newSceneDlgState, 32); + } else { + for (int i = 0; i < 31; ++i) + _newSceneDlgState[i] = in.readUint16(); + } + + _cauldronUseCount = in.readSint16(); + + if (header.originalSave) + in.seek(6, SEEK_CUR); + + _mainCharacter.sceneId = in.readUint16(); + _mainCharacter.dlgIndex = in.readUint16(); + _mainCharacter.height = in.readByte(); + _mainCharacter.facing = in.readByte(); + _mainCharacter.animFrame = in.readUint16(); + _mainCharacter.unk8 = in.readByte(); + _mainCharacter.unk9 = in.readByte(); + _mainCharacter.unkA = in.readByte(); + for (int i = 0; i < 20; ++i) + _mainCharacter.inventory[i] = in.readUint16(); + _mainCharacter.x1 = in.readSint16(); + _mainCharacter.y1 = in.readSint16(); + _mainCharacter.x2 = in.readSint16(); + _mainCharacter.y2 = in.readSint16(); + + for (int i = 0; i < 30; ++i) { + _itemList[i].id = in.readUint16(); + _itemList[i].sceneId = in.readUint16(); + _itemList[i].x = in.readSint16(); + _itemList[i].y = in.readByte(); + _itemList[i].unk7 = in.readUint16(); + } + + for (int i = 0; i < 72; ++i) { + in.read(_talkObjectList[i].filename, 13); + _talkObjectList[i].scriptId = in.readByte(); + _talkObjectList[i].x = in.readSint16(); + _talkObjectList[i].y = in.readSint16(); + _talkObjectList[i].color = in.readByte(); + } + + for (int i = 0; i < 86; ++i) { + if (!header.originalSave) { + in.read(_sceneList[i].filename1, 10); + } else { + in.read(_sceneList[i].filename1, 9); + _sceneList[i].filename1[9] = 0; + } + + _sceneList[i].exit1 = in.readUint16(); + _sceneList[i].exit2 = in.readUint16(); + _sceneList[i].exit3 = in.readUint16(); + _sceneList[i].exit4 = in.readUint16(); + _sceneList[i].flags = in.readByte(); + _sceneList[i].sound = in.readByte(); + } + + _itemInHand = in.readSint16(); + + if (header.originalSave) { + uint32 currentTime = _system->getMillis(); + + for (int i = 0; i < 6; ++i) + _timer->setDelay(i, in.readSint32LE()); + + for (int i = 0; i < 6; ++i) { + if (in.readUint16LE()) + _timer->enable(i); + else + _timer->disable(i); + } + + for (int i = 0; i < 6; ++i) + _timer->setNextRun(i, currentTime + (in.readUint32LE() * _tickLength)); + + _timer->resetNextRun(); + } + + _sceneExit1 = in.readUint16(); + _sceneExit2 = in.readUint16(); + _sceneExit3 = in.readUint16(); + _sceneExit4 = in.readUint16(); + + if (saveFile->ioFailed()) + error("Load failed ('%s', '%s').", fileName, header.description.c_str()); + else + debugC(1, kDebugLevelMain, "Loaded savegame '%s.'", header.description.c_str()); + + if (loadedZTable != _loadedZTable) + loadZShapes(_loadedZTable); + + _screen->loadBitmap("_PLAYFLD.CPS", 3, 3, 0); + if (!queryGameFlag(1)) + _screen->copyRegion(0xCE, 0x90, 0xCE, 0x90, 0x2C, 0x2C, 2, 0, Screen::CR_NO_P_CHECK); + if (!queryGameFlag(2)) + _screen->copyRegion(0xFA, 0x90, 0xFA, 0x90, 0x46, 0x2C, 2, 0, Screen::CR_NO_P_CHECK); + _screen->loadBitmap("_PLAYALL.CPS", 3, 3, 0); + if (queryGameFlag(1)) + _screen->copyRegion(0xCE, 0x90, 0xCE, 0x90, 0x2C, 0x2C, 2, 0, Screen::CR_NO_P_CHECK); + if (queryGameFlag(2)) + _screen->copyRegion(0xFA, 0x90, 0xFA, 0x90, 0x46, 0x2C, 2, 0, Screen::CR_NO_P_CHECK); + + redrawInventory(0); + int cauldronUseCount = _cauldronUseCount; + setCauldronState(_cauldronState, 0); + _cauldronUseCount = cauldronUseCount; + _mainCharX = _mainCharacter.x2 = _mainCharacter.x1; + _mainCharY = _mainCharacter.y2 = _mainCharacter.y1; + _mainCharacter.facing = 4; + + enterNewScene(_mainCharacter.sceneId, _mainCharacter.facing, 0, 0, 1); + setHandItem(_itemInHand); + + if (_lastMusicCommand >= 0 && !_unkSceneScreenFlag1) + snd_playWanderScoreViaMap(_lastMusicCommand, 1); + + while (!_screen->isMouseVisible()) + _screen->showMouse(); + + setTimer1DelaySecs(7); + _shownMessage = " "; + _fadeMessagePalette = false; + + if (setFlag1EE) + setGameFlag(0x1EE); + + // 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); +} + +} // end of namespace Kyra + diff --git a/engines/kyra/saveload_mr.cpp b/engines/kyra/saveload_mr.cpp new file mode 100644 index 0000000000..cab86c3cfe --- /dev/null +++ b/engines/kyra/saveload_mr.cpp @@ -0,0 +1,262 @@ +/* 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_mr.h" +#include "kyra/timer.h" + +namespace Kyra { + +void KyraEngine_MR::saveGame(const char *fileName, const char *saveName) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::saveGame('%s', '%s')", fileName, saveName); + + Common::OutSaveFile *out = openSaveForWriting(fileName, saveName); + if (!out) { + warning("Can't open file '%s', game not loadable", fileName); + return; + } + + _timer->saveDataToFile(*out); + + out->writeUint32BE(sizeof(_flagsTable)); + out->write(_flagsTable, sizeof(_flagsTable)); + + out->writeSint16BE(_lastMusicCommand); + out->writeByte(_currentChapter); + out->writeByte(_malcolmShapes); + //XXX + out->writeSint16BE(_score); + out->writeSint16BE(_scoreMax); + out->writeByte(_malcolmsMood); + out->write(_conversationState, sizeof(_conversationState)); + out->write(_newSceneDlgState, sizeof(_newSceneDlgState)); + for (int i = 0; i < 100; ++i) + out->writeUint16BE(_hiddenItems[i]); + out->write(_scoreFlagTable, sizeof(_scoreFlagTable)); + + out->writeUint16BE(_mainCharacter.sceneId); + out->writeUint16BE(_mainCharacter.dlgIndex); + out->writeByte(_mainCharacter.height); + out->writeByte(_mainCharacter.facing); + out->writeUint16BE(_mainCharacter.animFrame); + out->writeByte(_mainCharacter.walkspeed); + for (int i = 0; i < 10; ++i) + out->writeUint16BE(_mainCharacter.inventory[i]); + out->writeSint16BE(_mainCharacter.x1); + out->writeSint16BE(_mainCharacter.y1); + out->writeSint16BE(_mainCharacter.x2); + out->writeSint16BE(_mainCharacter.y2); + out->writeSint16BE(_mainCharacter.x3); + out->writeSint16BE(_mainCharacter.y3); + + for (int i = 0; i < 50; ++i) { + out->writeUint16BE(_itemList[i].id); + out->writeUint16BE(_itemList[i].sceneId); + out->writeSint16BE(_itemList[i].x); + out->writeSint16BE(_itemList[i].y); + out->writeUint16BE(_itemList[i].unk8); + } + + for (int i = 0; i < 88; ++i) { + out->write(_talkObjectList[i].filename, 13); + out->writeByte(_talkObjectList[i].sceneAnim); + out->writeByte(_talkObjectList[i].sceneScript); + out->writeSint16BE(_talkObjectList[i].x); + out->writeSint16BE(_talkObjectList[i].y); + out->writeByte(_talkObjectList[i].color); + } + + for (int i = 0; i < 98; ++i) { + out->write(_sceneList[i].filename1, 10); + out->write(_sceneList[i].filename2, 10); + out->writeUint16BE(_sceneList[i].exit1); + out->writeUint16BE(_sceneList[i].exit2); + out->writeUint16BE(_sceneList[i].exit3); + out->writeUint16BE(_sceneList[i].exit4); + out->writeByte(_sceneList[i].flags); + out->writeByte(_sceneList[i].sound); + } + + out->writeSint16BE(_itemInHand); + out->writeUint16BE(_sceneExit1); + out->writeUint16BE(_sceneExit2); + out->writeUint16BE(_sceneExit3); + out->writeUint16BE(_sceneExit4); + + 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; +} + +void KyraEngine_MR::loadGame(const char *fileName) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::loadGame('%s')", fileName); + + SaveHeader header; + Common::InSaveFile *saveFile = openSaveForReading(fileName, header); + if (!saveFile) { + showMessageFromCCode(17, 0xB3, 0); + snd_playSoundEffect(0x0D, 0xC8); + return; + } + + if (_inventoryState) { + updateCharacterAnim(0); + restorePage3(); + drawAnimObjects(); + _inventoryState = true; + refreshAnimObjects(0); + hideInventory(); + } + + _deathHandler = -1; + if (!_unkSceneScreenFlag1) + _lastMusicCommand = -1; + + int curShapes = _malcolmShapes; + + Common::SeekableSubReadStreamEndian in(saveFile, saveFile->pos(), saveFile->size(), !header.originalSave, true); + + _screen->hideMouse(); + + _timer->loadDataFromFile(in, header.version); + + uint32 flagsSize = in.readUint32BE(); + assert(flagsSize <= sizeof(_flagsTable)); + in.read(_flagsTable, flagsSize); + + // usually we have to save the flag set by opcode 10 here + _lastMusicCommand = in.readSint16(); + _currentChapter = in.readByte(); + _malcolmShapes = in.readByte(); + //XXX + _score = in.readSint16(); + _scoreMax = in.readSint16(); + _malcolmsMood = in.readByte(); + in.read(_conversationState, sizeof(_conversationState)); + in.read(_newSceneDlgState, sizeof(_newSceneDlgState)); + for (int i = 0; i < 100; ++i) + _hiddenItems[i] = in.readUint16(); + in.read(_scoreFlagTable, sizeof(_scoreFlagTable)); + + _mainCharacter.sceneId = in.readUint16(); + _mainCharacter.dlgIndex = in.readUint16(); + _mainCharacter.height = in.readByte(); + _mainCharacter.facing = in.readByte(); + _mainCharacter.animFrame = in.readUint16(); + _mainCharacter.walkspeed = in.readByte(); + for (int i = 0; i < 10; ++i) + _mainCharacter.inventory[i] = in.readUint16(); + _mainCharacter.x1 = in.readSint16(); + _mainCharacter.y1 = in.readSint16(); + _mainCharacter.x2 = in.readSint16(); + _mainCharacter.y2 = in.readSint16(); + _mainCharacter.x3 = in.readSint16(); + _mainCharacter.y3 = in.readSint16(); + + for (int i = 0; i < 50; ++i) { + _itemList[i].id = in.readUint16(); + _itemList[i].sceneId = in.readUint16(); + _itemList[i].x = in.readSint16(); + _itemList[i].y = in.readSint16(); + _itemList[i].unk8 = in.readUint16(); + } + + for (int i = 0; i < 88; ++i) { + in.read(_talkObjectList[i].filename, 13); + _talkObjectList[i].sceneAnim = in.readByte(); + _talkObjectList[i].sceneScript = in.readByte(); + _talkObjectList[i].x = in.readSint16(); + _talkObjectList[i].y = in.readSint16(); + _talkObjectList[i].color = in.readByte(); + } + + for (int i = 0; i < 98; ++i) { + in.read(_sceneList[i].filename1, 10); + in.read(_sceneList[i].filename2, 10); + _sceneList[i].exit1 = in.readUint16(); + _sceneList[i].exit2 = in.readUint16(); + _sceneList[i].exit3 = in.readUint16(); + _sceneList[i].exit4 = in.readUint16(); + _sceneList[i].flags = in.readByte(); + _sceneList[i].sound = in.readByte(); + } + + _itemInHand = in.readSint16(); + _sceneExit1 = in.readUint16(); + _sceneExit2 = in.readUint16(); + _sceneExit3 = in.readUint16(); + _sceneExit4 = in.readUint16(); + + if (saveFile->ioFailed()) + error("Load failed ('%s', '%s').", fileName, header.description.c_str()); + else + debugC(1, kDebugLevelMain, "Loaded savegame '%s.'", header.description.c_str()); + + _loadingState = true; + updateCharacterAnim(0); + _loadingState = false; + + if (curShapes != _malcolmShapes) + loadMalcolmShapes(_malcolmShapes); + + _mainCharX = _mainCharacter.x2 = _mainCharacter.x1; + _mainCharY = _mainCharacter.y2 = _mainCharacter.y1; + _mainCharacter.facing = 4; + _badConscienceShown = false; + _badConsciencePosition = false; + _goodConscienceShown = false; + _goodConsciencePosition = false; + + enterNewScene(_mainCharacter.sceneId, _mainCharacter.facing, 0, 0, 1); + setHandItem(_itemInHand); + + if (_lastMusicCommand >= 0 && !_unkSceneScreenFlag1) + snd_playWanderScoreViaMap(_lastMusicCommand, 1); + else if (_lastMusicCommand == -1) + snd_playWanderScoreViaMap(28, 1); + + while (!_screen->isMouseVisible()) + _screen->showMouse(); + + setCommandLineRestoreTimer(7); + _shownMessage = " "; + _restoreCommandLine = false; + + // 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); +} + +} // end of namespace Kyra + diff --git a/engines/kyra/saveload_v2.cpp b/engines/kyra/saveload_v2.cpp deleted file mode 100644 index 94824c9895..0000000000 --- a/engines/kyra/saveload_v2.cpp +++ /dev/null @@ -1,333 +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_v2.h" -#include "kyra/screen_v2.h" -#include "kyra/resource.h" -#include "kyra/sound.h" -#include "kyra/timer.h" - -namespace Kyra { - -void KyraEngine_v2::saveGame(const char *fileName, const char *saveName) { - debugC(9, kDebugLevelMain, "KyraEngine_v2::saveGame('%s', '%s')", fileName, saveName); - - Common::OutSaveFile *out = openSaveForWriting(fileName, saveName); - if (!out) { - warning("Can't open file '%s', game not loadable", fileName); - return; - } - - _timer->saveDataToFile(*out); - - out->writeUint32BE(sizeof(_flagsTable)); - out->write(_flagsTable, sizeof(_flagsTable)); - - // usually we have to save the flag set by opcode 10 here - //out->writeUint16BE(word_2AB05); - out->writeSint16BE(_lastMusicCommand); - out->writeByte(_newChapterFile); - out->writeByte(_loadedZTable); - out->writeByte(_cauldronState); - out->writeByte(_colorCodeFlag1); - out->writeByte(_colorCodeFlag2); - out->writeByte(_bookCurPage); - out->writeByte(_bookMaxPage); - for (int i = 0; i < 7; ++i) - out->writeByte(_presetColorCode[i]); - for (int i = 0; i < 7; ++i) - out->writeByte(_inputColorCode[i]); - for (int i = 0; i < 25; ++i) - out->writeSint16BE(_cauldronTable[i]); - for (int i = 0; i < 20; ++i) - out->writeUint16BE(_hiddenItems[i]); - for (int i = 0; i < 19; ++i) - out->write(_conversationState[i], 14); - out->write(_newSceneDlgState, 32); - out->writeSint16BE(_cauldronUseCount); - - out->writeUint16BE(_mainCharacter.sceneId); - out->writeUint16BE(_mainCharacter.dlgIndex); - out->writeByte(_mainCharacter.height); - out->writeByte(_mainCharacter.facing); - out->writeUint16BE(_mainCharacter.animFrame); - out->writeByte(_mainCharacter.unk8); - out->writeByte(_mainCharacter.unk9); - out->writeByte(_mainCharacter.unkA); - for (int i = 0; i < 20; ++i) - out->writeUint16BE(_mainCharacter.inventory[i]); - out->writeSint16BE(_mainCharacter.x1); - out->writeSint16BE(_mainCharacter.y1); - out->writeSint16BE(_mainCharacter.x2); - out->writeSint16BE(_mainCharacter.y2); - - for (int i = 0; i < 30; ++i) { - out->writeUint16BE(_itemList[i].id); - out->writeUint16BE(_itemList[i].sceneId); - out->writeSint16BE(_itemList[i].x); - out->writeByte(_itemList[i].y); - out->writeUint16BE(_itemList[i].unk7); - } - - for (int i = 0; i < 72; ++i) { - out->write(_talkObjectList[i].filename, 13); - out->writeByte(_talkObjectList[i].scriptId); - out->writeSint16BE(_talkObjectList[i].x); - out->writeSint16BE(_talkObjectList[i].y); - out->writeByte(_talkObjectList[i].color); - } - - for (int i = 0; i < 86; ++i) { - out->write(_sceneList[i].filename, 10); - out->writeUint16BE(_sceneList[i].exit1); - out->writeUint16BE(_sceneList[i].exit2); - out->writeUint16BE(_sceneList[i].exit3); - out->writeUint16BE(_sceneList[i].exit4); - out->writeByte(_sceneList[i].flags); - out->writeByte(_sceneList[i].sound); - } - - out->writeSint16BE(_itemInHand); - out->writeUint16BE(_sceneExit1); - out->writeUint16BE(_sceneExit2); - out->writeUint16BE(_sceneExit3); - out->writeUint16BE(_sceneExit4); - - 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; -} - -void KyraEngine_v2::loadGame(const char *fileName) { - debugC(9, kDebugLevelMain, "KyraEngine_v2::loadGame('%s')", fileName); - - SaveHeader header; - Common::InSaveFile *saveFile = openSaveForReading(fileName, header); - if (!saveFile) { - showMessageFromCCode(0x35, 0x84, 0); - snd_playSoundEffect(0x0D); - return; - } - - if (header.originalSave) - warning("Trying to load savegame from original interpreter, while this is possible, it is not officially supported"); - - bool setFlag1EE = (queryGameFlag(0x1EE) != 0); - - _deathHandler = -1; - if (!_unkSceneScreenFlag1) { - _sound->beginFadeOut(); - _system->delayMillis(5 * _tickLength); - _lastMusicCommand = -1; - } - - int loadedZTable = _loadedZTable; - - Common::SeekableSubReadStreamEndian in(saveFile, saveFile->pos(), saveFile->size(), !header.originalSave, true); - - _screen->hideMouse(); - - if (!header.originalSave) { - _timer->loadDataFromFile(in, header.version); - - uint32 flagsSize = in.readUint32BE(); - assert(flagsSize <= sizeof(_flagsTable)); - in.read(_flagsTable, flagsSize); - } - - // usually we have to save the flag set by opcode 10 here - //word_2AB05 = in.readUint16(); - if (header.originalSave) - in.readUint16(); - _lastMusicCommand = in.readSint16(); - _newChapterFile = in.readByte(); - _loadedZTable = in.readByte(); - _cauldronState = in.readByte(); - _colorCodeFlag1 = in.readByte(); - _colorCodeFlag2 = in.readByte(); - _bookCurPage = in.readByte(); - _bookMaxPage = in.readByte(); - for (int i = 0; i < 7; ++i) - _presetColorCode[i] = in.readByte(); - for (int i = 0; i < 7; ++i) - _inputColorCode[i] = in.readByte(); - for (int i = 0; i < 25; ++i) - _cauldronTable[i] = in.readSint16(); - for (int i = 0; i < 20; ++i) - _hiddenItems[i] = in.readUint16(); - - if (header.originalSave) { - assert(sizeof(_flagsTable) >= 0x41); - in.read(_flagsTable, 0x41); - } - - for (int i = 0; i < 19; ++i) - in.read(_conversationState[i], 14); - - if (!header.originalSave) { - in.read(_newSceneDlgState, 32); - } else { - for (int i = 0; i < 31; ++i) - _newSceneDlgState[i] = in.readUint16(); - } - - _cauldronUseCount = in.readSint16(); - - if (header.originalSave) - in.seek(6, SEEK_CUR); - - _mainCharacter.sceneId = in.readUint16(); - _mainCharacter.dlgIndex = in.readUint16(); - _mainCharacter.height = in.readByte(); - _mainCharacter.facing = in.readByte(); - _mainCharacter.animFrame = in.readUint16(); - _mainCharacter.unk8 = in.readByte(); - _mainCharacter.unk9 = in.readByte(); - _mainCharacter.unkA = in.readByte(); - for (int i = 0; i < 20; ++i) - _mainCharacter.inventory[i] = in.readUint16(); - _mainCharacter.x1 = in.readSint16(); - _mainCharacter.y1 = in.readSint16(); - _mainCharacter.x2 = in.readSint16(); - _mainCharacter.y2 = in.readSint16(); - - for (int i = 0; i < 30; ++i) { - _itemList[i].id = in.readUint16(); - _itemList[i].sceneId = in.readUint16(); - _itemList[i].x = in.readSint16(); - _itemList[i].y = in.readByte(); - _itemList[i].unk7 = in.readUint16(); - } - - for (int i = 0; i < 72; ++i) { - in.read(_talkObjectList[i].filename, 13); - _talkObjectList[i].scriptId = in.readByte(); - _talkObjectList[i].x = in.readSint16(); - _talkObjectList[i].y = in.readSint16(); - _talkObjectList[i].color = in.readByte(); - } - - for (int i = 0; i < 86; ++i) { - if (!header.originalSave) { - in.read(_sceneList[i].filename, 10); - } else { - in.read(_sceneList[i].filename, 9); - _sceneList[i].filename[9] = 0; - } - - _sceneList[i].exit1 = in.readUint16(); - _sceneList[i].exit2 = in.readUint16(); - _sceneList[i].exit3 = in.readUint16(); - _sceneList[i].exit4 = in.readUint16(); - _sceneList[i].flags = in.readByte(); - _sceneList[i].sound = in.readByte(); - } - - _itemInHand = in.readSint16(); - - if (header.originalSave) { - uint32 currentTime = _system->getMillis(); - - for (int i = 0; i < 6; ++i) - _timer->setDelay(i, in.readSint32LE()); - - for (int i = 0; i < 6; ++i) { - if (in.readUint16LE()) - _timer->enable(i); - else - _timer->disable(i); - } - - for (int i = 0; i < 6; ++i) - _timer->setNextRun(i, currentTime + (in.readUint32LE() * _tickLength)); - - _timer->resetNextRun(); - } - - _sceneExit1 = in.readUint16(); - _sceneExit2 = in.readUint16(); - _sceneExit3 = in.readUint16(); - _sceneExit4 = in.readUint16(); - - if (saveFile->ioFailed()) - error("Load failed ('%s', '%s').", fileName, header.description.c_str()); - else - debugC(1, kDebugLevelMain, "Loaded savegame '%s.'", header.description.c_str()); - - if (loadedZTable != _loadedZTable) - loadZShapes(_loadedZTable); - - _screen->loadBitmap("_PLAYFLD.CPS", 3, 3, 0); - if (!queryGameFlag(1)) - _screen->copyRegion(0xCE, 0x90, 0xCE, 0x90, 0x2C, 0x2C, 2, 0, Screen::CR_NO_P_CHECK); - if (!queryGameFlag(2)) - _screen->copyRegion(0xFA, 0x90, 0xFA, 0x90, 0x46, 0x2C, 2, 0, Screen::CR_NO_P_CHECK); - _screen->loadBitmap("_PLAYALL.CPS", 3, 3, 0); - if (queryGameFlag(1)) - _screen->copyRegion(0xCE, 0x90, 0xCE, 0x90, 0x2C, 0x2C, 2, 0, Screen::CR_NO_P_CHECK); - if (queryGameFlag(2)) - _screen->copyRegion(0xFA, 0x90, 0xFA, 0x90, 0x46, 0x2C, 2, 0, Screen::CR_NO_P_CHECK); - - redrawInventory(0); - int cauldronUseCount = _cauldronUseCount; - setCauldronState(_cauldronState, 0); - _cauldronUseCount = cauldronUseCount; - _mainCharX = _mainCharacter.x2 = _mainCharacter.x1; - _mainCharY = _mainCharacter.y2 = _mainCharacter.y1; - _mainCharacter.facing = 4; - - enterNewScene(_mainCharacter.sceneId, _mainCharacter.facing, 0, 0, 1); - setHandItem(_itemInHand); - - if (_lastMusicCommand >= 0 && !_unkSceneScreenFlag1) - snd_playWanderScoreViaMap(_lastMusicCommand, 1); - - while (!_screen->isMouseVisible()) - _screen->showMouse(); - - setTimer1DelaySecs(7); - _shownMessage = " "; - _fadeMessagePalette = false; - - if (setFlag1EE) - setGameFlag(0x1EE); - - // 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); -} - -} // end of namespace Kyra - diff --git a/engines/kyra/saveload_v3.cpp b/engines/kyra/saveload_v3.cpp deleted file mode 100644 index 4d975c2a67..0000000000 --- a/engines/kyra/saveload_v3.cpp +++ /dev/null @@ -1,262 +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_v3.h" -#include "kyra/timer.h" - -namespace Kyra { - -void KyraEngine_v3::saveGame(const char *fileName, const char *saveName) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::saveGame('%s', '%s')", fileName, saveName); - - Common::OutSaveFile *out = openSaveForWriting(fileName, saveName); - if (!out) { - warning("Can't open file '%s', game not loadable", fileName); - return; - } - - _timer->saveDataToFile(*out); - - out->writeUint32BE(sizeof(_flagsTable)); - out->write(_flagsTable, sizeof(_flagsTable)); - - out->writeSint16BE(_lastMusicCommand); - out->writeByte(_currentChapter); - out->writeByte(_malcolmShapes); - //XXX - out->writeSint16BE(_score); - out->writeSint16BE(_scoreMax); - out->writeByte(_malcolmsMood); - out->write(_conversationState, sizeof(_conversationState)); - out->write(_newSceneDlgState, sizeof(_newSceneDlgState)); - for (int i = 0; i < 100; ++i) - out->writeUint16BE(_hiddenItems[i]); - out->write(_scoreFlagTable, sizeof(_scoreFlagTable)); - - out->writeUint16BE(_mainCharacter.sceneId); - out->writeUint16BE(_mainCharacter.dlgIndex); - out->writeByte(_mainCharacter.height); - out->writeByte(_mainCharacter.facing); - out->writeUint16BE(_mainCharacter.animFrame); - out->writeByte(_mainCharacter.walkspeed); - for (int i = 0; i < 10; ++i) - out->writeUint16BE(_mainCharacter.inventory[i]); - out->writeSint16BE(_mainCharacter.x1); - out->writeSint16BE(_mainCharacter.y1); - out->writeSint16BE(_mainCharacter.x2); - out->writeSint16BE(_mainCharacter.y2); - out->writeSint16BE(_mainCharacter.x3); - out->writeSint16BE(_mainCharacter.y3); - - for (int i = 0; i < 50; ++i) { - out->writeUint16BE(_itemList[i].id); - out->writeUint16BE(_itemList[i].sceneId); - out->writeSint16BE(_itemList[i].x); - out->writeSint16BE(_itemList[i].y); - out->writeUint16BE(_itemList[i].unk8); - } - - for (int i = 0; i < 88; ++i) { - out->write(_talkObjectList[i].filename, 13); - out->writeByte(_talkObjectList[i].sceneAnim); - out->writeByte(_talkObjectList[i].sceneScript); - out->writeSint16BE(_talkObjectList[i].x); - out->writeSint16BE(_talkObjectList[i].y); - out->writeByte(_talkObjectList[i].color); - } - - for (int i = 0; i < 98; ++i) { - out->write(_sceneList[i].filename1, 10); - out->write(_sceneList[i].filename2, 10); - out->writeUint16BE(_sceneList[i].exit1); - out->writeUint16BE(_sceneList[i].exit2); - out->writeUint16BE(_sceneList[i].exit3); - out->writeUint16BE(_sceneList[i].exit4); - out->writeByte(_sceneList[i].flags); - out->writeByte(_sceneList[i].sound); - } - - out->writeSint16BE(_itemInHand); - out->writeUint16BE(_sceneExit1); - out->writeUint16BE(_sceneExit2); - out->writeUint16BE(_sceneExit3); - out->writeUint16BE(_sceneExit4); - - 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; -} - -void KyraEngine_v3::loadGame(const char *fileName) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::loadGame('%s')", fileName); - - SaveHeader header; - Common::InSaveFile *saveFile = openSaveForReading(fileName, header); - if (!saveFile) { - showMessageFromCCode(17, 0xB3, 0); - snd_playSoundEffect(0x0D, 0xC8); - return; - } - - if (_inventoryState) { - updateCharacterAnim(0); - restorePage3(); - drawAnimObjects(); - _inventoryState = true; - refreshAnimObjects(0); - hideInventory(); - } - - _deathHandler = -1; - if (!_unkSceneScreenFlag1) - _lastMusicCommand = -1; - - int curShapes = _malcolmShapes; - - Common::SeekableSubReadStreamEndian in(saveFile, saveFile->pos(), saveFile->size(), !header.originalSave, true); - - _screen->hideMouse(); - - _timer->loadDataFromFile(in, header.version); - - uint32 flagsSize = in.readUint32BE(); - assert(flagsSize <= sizeof(_flagsTable)); - in.read(_flagsTable, flagsSize); - - // usually we have to save the flag set by opcode 10 here - _lastMusicCommand = in.readSint16(); - _currentChapter = in.readByte(); - _malcolmShapes = in.readByte(); - //XXX - _score = in.readSint16(); - _scoreMax = in.readSint16(); - _malcolmsMood = in.readByte(); - in.read(_conversationState, sizeof(_conversationState)); - in.read(_newSceneDlgState, sizeof(_newSceneDlgState)); - for (int i = 0; i < 100; ++i) - _hiddenItems[i] = in.readUint16(); - in.read(_scoreFlagTable, sizeof(_scoreFlagTable)); - - _mainCharacter.sceneId = in.readUint16(); - _mainCharacter.dlgIndex = in.readUint16(); - _mainCharacter.height = in.readByte(); - _mainCharacter.facing = in.readByte(); - _mainCharacter.animFrame = in.readUint16(); - _mainCharacter.walkspeed = in.readByte(); - for (int i = 0; i < 10; ++i) - _mainCharacter.inventory[i] = in.readUint16(); - _mainCharacter.x1 = in.readSint16(); - _mainCharacter.y1 = in.readSint16(); - _mainCharacter.x2 = in.readSint16(); - _mainCharacter.y2 = in.readSint16(); - _mainCharacter.x3 = in.readSint16(); - _mainCharacter.y3 = in.readSint16(); - - for (int i = 0; i < 50; ++i) { - _itemList[i].id = in.readUint16(); - _itemList[i].sceneId = in.readUint16(); - _itemList[i].x = in.readSint16(); - _itemList[i].y = in.readSint16(); - _itemList[i].unk8 = in.readUint16(); - } - - for (int i = 0; i < 88; ++i) { - in.read(_talkObjectList[i].filename, 13); - _talkObjectList[i].sceneAnim = in.readByte(); - _talkObjectList[i].sceneScript = in.readByte(); - _talkObjectList[i].x = in.readSint16(); - _talkObjectList[i].y = in.readSint16(); - _talkObjectList[i].color = in.readByte(); - } - - for (int i = 0; i < 98; ++i) { - in.read(_sceneList[i].filename1, 10); - in.read(_sceneList[i].filename2, 10); - _sceneList[i].exit1 = in.readUint16(); - _sceneList[i].exit2 = in.readUint16(); - _sceneList[i].exit3 = in.readUint16(); - _sceneList[i].exit4 = in.readUint16(); - _sceneList[i].flags = in.readByte(); - _sceneList[i].sound = in.readByte(); - } - - _itemInHand = in.readSint16(); - _sceneExit1 = in.readUint16(); - _sceneExit2 = in.readUint16(); - _sceneExit3 = in.readUint16(); - _sceneExit4 = in.readUint16(); - - if (saveFile->ioFailed()) - error("Load failed ('%s', '%s').", fileName, header.description.c_str()); - else - debugC(1, kDebugLevelMain, "Loaded savegame '%s.'", header.description.c_str()); - - _loadingState = true; - updateCharacterAnim(0); - _loadingState = false; - - if (curShapes != _malcolmShapes) - loadMalcolmShapes(_malcolmShapes); - - _mainCharX = _mainCharacter.x2 = _mainCharacter.x1; - _mainCharY = _mainCharacter.y2 = _mainCharacter.y1; - _mainCharacter.facing = 4; - _badConscienceShown = false; - _badConsciencePosition = false; - _goodConscienceShown = false; - _goodConsciencePosition = false; - - enterNewScene(_mainCharacter.sceneId, _mainCharacter.facing, 0, 0, 1); - setHandItem(_itemInHand); - - if (_lastMusicCommand >= 0 && !_unkSceneScreenFlag1) - snd_playWanderScoreViaMap(_lastMusicCommand, 1); - else if (_lastMusicCommand == -1) - snd_playWanderScoreViaMap(28, 1); - - while (!_screen->isMouseVisible()) - _screen->showMouse(); - - setCommandLineRestoreTimer(7); - _shownMessage = " "; - _restoreCommandLine = false; - - // 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); -} - -} // end of namespace Kyra - diff --git a/engines/kyra/scene_hof.cpp b/engines/kyra/scene_hof.cpp new file mode 100644 index 0000000000..216c453b4b --- /dev/null +++ b/engines/kyra/scene_hof.cpp @@ -0,0 +1,777 @@ +/* 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_hof.h" +#include "kyra/screen_v2.h" +#include "kyra/sound.h" +#include "kyra/wsamovie.h" +#include "kyra/resource.h" + +#include "common/func.h" + +namespace Kyra { + +void KyraEngine_HoF::enterNewScene(uint16 newScene, int facing, int unk1, int unk2, int unk3) { + debugC(9, kDebugLevelMain, "KyraEngine_HoF::enterNewScene(%d, %d, %d, %d, %d)", newScene, facing, unk1, unk2, unk3); + if (_newChapterFile != _currentTalkFile) { + _currentTalkFile = _newChapterFile; + if (_flags.isTalkie) { + showMessageFromCCode(265, 150, 0); + _screen->updateScreen(); + openTalkFile(_currentTalkFile); + } + showMessage(0, 207); + _screen->updateScreen(); + } + + _screen->hideMouse(); + + if (!unk3) { + updateWaterFlasks(); + displayInvWsaLastFrame(); + } + + if (unk1) { + int x = _mainCharacter.x1; + int y = _mainCharacter.y1; + + switch (facing) { + case 0: + y -= 6; + break; + + case 2: + x = 335; + break; + + case 4: + y = 147; + break; + + case 6: + x = -16; + break; + + default: + break; + } + + moveCharacter(facing, x, y); + } + + bool newSoundFile = false; + uint32 waitTime = 0; + if (_sceneList[newScene].sound != _lastMusicCommand) { + newSoundFile = true; + waitTime = _system->getMillis() + 1000; + _sound->beginFadeOut(); + } + + _chatAltFlag = false; + + if (!unk3) { + _emc->init(&_sceneScriptState, &_sceneScriptData); + _emc->start(&_sceneScriptState, 5); + while (_emc->isValid(&_sceneScriptState)) + _emc->run(&_sceneScriptState); + } + + Common::for_each(_wsaSlots, _wsaSlots+ARRAYSIZE(_wsaSlots), Common::mem_fun(&WSAMovieV2::close)); + _specialExitCount = 0; + memset(_specialExitTable, -1, sizeof(_specialExitTable)); + + _mainCharacter.sceneId = newScene; + _sceneList[newScene].flags &= ~1; + loadScenePal(); + unloadScene(); + loadSceneMsc(); + + SceneDesc &scene = _sceneList[newScene]; + _sceneExit1 = scene.exit1; + _sceneExit2 = scene.exit2; + _sceneExit3 = scene.exit3; + _sceneExit4 = scene.exit4; + + if (newSoundFile) { + if (_sound->getMusicType() == Sound::kAdlib) { + while (_sound->isPlaying()) + _system->delayMillis(10); + } else { + while (waitTime > _system->getMillis()) + _system->delayMillis(10); + } + snd_loadSoundFile(_sceneList[newScene].sound); + } + + startSceneScript(unk3); + + if (_overwriteSceneFacing) { + facing = _mainCharacter.facing; + _overwriteSceneFacing = false; + } + + enterNewSceneUnk1(facing, unk2, unk3); + + setTimer1DelaySecs(-1); + _sceneScriptState.regs[3] = 1; + enterNewSceneUnk2(unk3); + _screen->showMouse(); + _unk5 = 0; + setNextIdleAnimTimer(); + + _currentScene = newScene; +} + +void KyraEngine_HoF::enterNewSceneUnk1(int facing, int unk1, int unk2) { + debugC(9, kDebugLevelMain, "KyraEngine_HoF::enterNewSceneUnk1(%d, %d, %d)", facing, unk1, unk2); + int x = 0, y = 0; + int x2 = 0, y2 = 0; + bool needProc = true; + + if (_mainCharX == -1 && _mainCharY == -1) { + switch (facing+1) { + case 1: case 2: case 8: + x2 = _sceneEnterX3; + y2 = _sceneEnterY3; + break; + + case 3: + x2 = _sceneEnterX4; + y2 = _sceneEnterY4; + break; + + case 4: case 5: case 6: + x2 = _sceneEnterX1; + y2 = _sceneEnterY1; + break; + + case 7: + x2 = _sceneEnterX2; + y2 = _sceneEnterY2; + break; + + default: + x2 = y2 = -1; + break; + } + + if (x2 >= 316) + x2 = 312; + if (y2 >= 141) + y2 = 139; + if (x2 <= 4) + x2 = 8; + } + + if (_mainCharX >= 0) { + x = x2 = _mainCharX; + needProc = false; + } + + if (_mainCharY >= 0) { + y = y2 = _mainCharY; + needProc = false; + } + + _mainCharX = _mainCharY = -1; + + if (unk1 && needProc) { + x = x2; + y = y2; + + switch (facing) { + case 0: + y2 = 147; + break; + + case 2: + x2 = -16; + break; + + case 4: + y2 = y - 4; + break; + + case 6: + x2 = 335; + break; + + default: + break; + } + } + + x2 &= ~3; + x &= ~3; + y2 &= ~1; + y &= ~1; + + _mainCharacter.facing = facing; + _mainCharacter.x1 = _mainCharacter.x2 = x2; + _mainCharacter.y1 = _mainCharacter.y2 = y2; + initSceneAnims(unk2); + + if (!unk2) + snd_playWanderScoreViaMap(_sceneList[_mainCharacter.sceneId].sound, 0); + + if (unk1 && !unk2 && _mainCharacter.animFrame != 32) + moveCharacter(facing, x, y); +} + +void KyraEngine_HoF::enterNewSceneUnk2(int unk1) { + debugC(9, kDebugLevelMain, "KyraEngine_HoF::enterNewSceneUnk2(%d)", unk1); + _unk3 = -1; + + if (_flags.isTalkie) { + if (_mainCharX == -1 && _mainCharY == -1 && _mainCharacter.sceneId != 61 && + !queryGameFlag(0x1F1) && !queryGameFlag(0x192) && !queryGameFlag(0x193) && + _mainCharacter.sceneId != 70 && !queryGameFlag(0x159) && _mainCharacter.sceneId != 37) { + _mainCharacter.animFrame = _characterFrameTable[_mainCharacter.facing]; + updateCharacterAnim(0); + refreshAnimObjectsIfNeed(); + } + } else if (_mainCharX != -1 && _mainCharY != -1) { + if (_characterFrameTable[_mainCharacter.facing] == 25) + _mainCharacter.facing = 5; + _mainCharacter.animFrame = _characterFrameTable[_mainCharacter.facing]; + updateCharacterAnim(0); + refreshAnimObjectsIfNeed(); + } + + if (!unk1) { + runSceneScript4(0); + zanthSceneStartupChat(); + } + + _unk4 = 0; + _unk3 = -1; +} + +int KyraEngine_HoF::trySceneChange(int *moveTable, int unk1, int updateChar) { + debugC(9, kDebugLevelMain, "KyraEngine_HoF::trySceneChange(%p, %d, %d)", (const void*)moveTable, unk1, updateChar); + bool running = true; + bool unkFlag = false; + int8 updateType = -1; + int changedScene = 0; + const int *moveTableStart = moveTable; + _unk4 = 0; + while (running && !_quitFlag) { + if (*moveTable >= 0 && *moveTable <= 7) { + _mainCharacter.facing = getOppositeFacingDirection(*moveTable); + unkFlag = true; + } else { + if (*moveTable == 8) { + running = false; + } else { + ++moveTable; + unkFlag = false; + } + } + + if (checkSceneChange()) { + running = false; + changedScene = 1; + } + + if (unk1) { + if (skipFlag()) { + resetSkipFlag(false); + running = false; + _unk4 = 1; + } + } + + if (!unkFlag || !running) + continue; + + int ret = 0; + if (moveTable == moveTableStart || moveTable[1] == 8) + ret = updateCharPos(0); + else + ret = updateCharPos(moveTable); + + if (ret) + ++moveTable; + + ++updateType; + if (!updateType) { + update(); + } else if (updateType == 1) { + refreshAnimObjectsIfNeed(); + updateType = -1; + } + } + + if (updateChar) + _mainCharacter.animFrame = _characterFrameTable[_mainCharacter.facing]; + + updateCharacterAnim(0); + refreshAnimObjectsIfNeed(); + + if (!changedScene && !_unk4) { + //XXX + } + return changedScene; +} + +int KyraEngine_HoF::checkSceneChange() { + debugC(9, kDebugLevelMain, "KyraEngine_HoF::checkSceneChange()"); + SceneDesc &curScene = _sceneList[_mainCharacter.sceneId]; + int charX = _mainCharacter.x1, charY = _mainCharacter.y1; + int facing = 0; + int process = 0; + + if (_screen->getLayer(charX, charY) == 1 && _unk3 == -6) { + facing = 0; + process = 1; + } else if (charX >= 316 && _unk3 == -5) { + facing = 2; + process = 1; + } else if (charY >= 142 && _unk3 == -4) { + facing = 4; + process = 1; + } else if (charX <= 4 && _unk3 == -3) { + facing = 6; + process = 1; + } + + if (!process) + return 0; + + uint16 newScene = 0xFFFF; + switch (facing) { + case 0: + newScene = curScene.exit1; + break; + + case 2: + newScene = curScene.exit2; + break; + + case 4: + newScene = curScene.exit3; + break; + + case 6: + newScene = curScene.exit4; + break; + + default: + newScene = _mainCharacter.sceneId; + break; + } + + if (newScene == 0xFFFF) + return 0; + + enterNewScene(newScene, facing, 1, 1, 0); + return 1; +} + +void KyraEngine_HoF::unloadScene() { + debugC(9, kDebugLevelMain, "KyraEngine_HoF::unloadScene()"); + _emc->unload(&_sceneScriptData); + freeSceneShapePtrs(); + freeSceneAnims(); +} + +void KyraEngine_HoF::loadScenePal() { + debugC(9, kDebugLevelMain, "KyraEngine_HoF::loadScenePal()"); + uint16 sceneId = _mainCharacter.sceneId; + memcpy(_screen->getPalette(1), _screen->getPalette(0), 768); + + char filename[14]; + strcpy(filename, _sceneList[sceneId].filename1); + strcat(filename, ".COL"); + _screen->loadBitmap(filename, 3, 3, 0); + memcpy(_screen->getPalette(1), _screen->getCPagePtr(3), 384); + memset(_screen->getPalette(1), 0, 3); + memcpy(_scenePal, _screen->getCPagePtr(3)+336, 432); +} + +void KyraEngine_HoF::loadSceneMsc() { + debugC(9, kDebugLevelMain, "KyraEngine_HoF::loadSceneMsc()"); + uint16 sceneId = _mainCharacter.sceneId; + char filename[14]; + strcpy(filename, _sceneList[sceneId].filename1); + strcat(filename, ".MSC"); + _screen->loadBitmap(filename, 3, 5, 0); +} + +void KyraEngine_HoF::startSceneScript(int unk1) { + debugC(9, kDebugLevelMain, "KyraEngine_HoF::startSceneScript(%d)", unk1); + uint16 sceneId = _mainCharacter.sceneId; + char filename[14]; + + strcpy(filename, _sceneList[sceneId].filename1); + if (sceneId == 68 && (queryGameFlag(0x1BC) || queryGameFlag(0x1BD))) + strcpy(filename, "DOORX"); + strcat(filename, ".CPS"); + + _screen->loadBitmap(filename, 3, 3, 0); + resetScaleTable(); + _useCharPal = false; + memset(_charPalTable, 0, sizeof(_charPalTable)); + memset(_layerFlagTable, 0, sizeof(_layerFlagTable)); + memset(_specialSceneScriptState, 0, sizeof(_specialSceneScriptState)); + + _sceneEnterX1 = 160; + _sceneEnterY1 = 0; + _sceneEnterX2 = 296; + _sceneEnterY2 = 72; + _sceneEnterX3 = 160; + _sceneEnterY3 = 128; + _sceneEnterX4 = 24; + _sceneEnterY4 = 72; + + _sceneCommentString = "Undefined scene comment string!"; + _emc->init(&_sceneScriptState, &_sceneScriptData); + + strcpy(filename, _sceneList[sceneId].filename1); + strcat(filename, "."); + strcat(filename, _scriptLangExt[(_flags.platform == Common::kPlatformPC && !_flags.isTalkie) ? 0 : _lang]); + + _res->exists(filename, true); + _emc->load(filename, &_sceneScriptData, &_opcodes); + runSceneScript7(); + + _emc->start(&_sceneScriptState, 0); + _sceneScriptState.regs[0] = sceneId; + _sceneScriptState.regs[5] = unk1; + while (_emc->isValid(&_sceneScriptState)) + _emc->run(&_sceneScriptState); + + memcpy(_gamePlayBuffer, _screen->getCPagePtr(3), 46080); + + for (int i = 0; i < 10; ++i) { + _emc->init(&_sceneSpecialScripts[i], &_sceneScriptData); + _emc->start(&_sceneSpecialScripts[i], i+8); + _sceneSpecialScriptsTimer[i] = 0; + } + + _sceneEnterX1 &= ~3; + _sceneEnterX2 &= ~3; + _sceneEnterX3 &= ~3; + _sceneEnterX4 &= ~3; + _sceneEnterY1 &= ~1; + _sceneEnterY2 &= ~1; + _sceneEnterY3 &= ~1; + _sceneEnterY4 &= ~1; +} + +void KyraEngine_HoF::runSceneScript2() { + debugC(9, kDebugLevelMain, "KyraEngine_HoF::runSceneScript2()"); + _emc->init(&_sceneScriptState, &_sceneScriptData); + _sceneScriptState.regs[4] = _itemInHand; + _emc->start(&_sceneScriptState, 2); + + while (_emc->isValid(&_sceneScriptState)) + _emc->run(&_sceneScriptState); +} + +void KyraEngine_HoF::runSceneScript4(int unk1) { + debugC(9, kDebugLevelMain, "KyraEngine_HoF::runSceneScript4(%d)", unk1); + _sceneScriptState.regs[4] = _itemInHand; + _sceneScriptState.regs[5] = unk1; + + _emc->start(&_sceneScriptState, 4); + while (_emc->isValid(&_sceneScriptState)) + _emc->run(&_sceneScriptState); +} + +void KyraEngine_HoF::runSceneScript6() { + debugC(9, kDebugLevelMain, "KyraEngine_HoF::runSceneScript6()"); + _emc->init(&_sceneScriptState, &_sceneScriptData); + + _sceneScriptState.regs[0] = _mainCharacter.sceneId; + _sceneScriptState.regs[1] = _mouseX; + _sceneScriptState.regs[2] = _mouseY; + _sceneScriptState.regs[4] = _itemInHand; + + _emc->start(&_sceneScriptState, 6); + while (_emc->isValid(&_sceneScriptState)) + _emc->run(&_sceneScriptState); +} + +void KyraEngine_HoF::runSceneScript7() { + debugC(9, kDebugLevelMain, "KyraEngine_HoF::runSceneScript7()"); + int oldPage = _screen->_curPage; + _screen->_curPage = 2; + + _emc->start(&_sceneScriptState, 7); + while (_emc->isValid(&_sceneScriptState)) + _emc->run(&_sceneScriptState); + + _screen->_curPage = oldPage; +} + +void KyraEngine_HoF::initSceneAnims(int unk1) { + debugC(9, kDebugLevelMain, "KyraEngine_HoF::initSceneAnims(%d)", unk1); + for (int i = 0; i < ARRAYSIZE(_animObjects); ++i) + _animObjects[i].enabled = 0; + + bool animInit = false; + + AnimObj *animState = &_animObjects[0]; + + if (_mainCharacter.animFrame != 32) + _mainCharacter.animFrame = _characterFrameTable[_mainCharacter.facing]; + + animState->enabled = 1; + animState->xPos1 = _mainCharacter.x1; + animState->yPos1 = _mainCharacter.y1; + animState->shapePtr = getShapePtr(_mainCharacter.animFrame); + animState->shapeIndex1 = animState->shapeIndex2 = _mainCharacter.animFrame; + + int frame = _mainCharacter.animFrame - 9; + int shapeX = _shapeDescTable[frame].xAdd; + int shapeY = _shapeDescTable[frame].yAdd; + + animState->xPos2 = _mainCharacter.x1; + animState->yPos2 = _mainCharacter.y1; + + _charScaleX = _charScaleY = getScale(_mainCharacter.x1, _mainCharacter.y1); + + int shapeXScaled = (shapeX * _charScaleX) >> 8; + int shapeYScaled = (shapeY * _charScaleY) >> 8; + + animState->xPos2 += shapeXScaled; + animState->yPos2 += shapeYScaled; + animState->xPos3 = animState->xPos2; + animState->yPos3 = animState->yPos2; + animState->needRefresh = 1; + animState->specialRefresh = 1; + + _animList = 0; + + AnimObj *charAnimState = animState; + + for (int i = 0; i < 10; ++i) { + animState = &_animObjects[i+1]; + animState->enabled = 0; + animState->needRefresh = 0; + animState->specialRefresh = 0; + + if (_sceneAnims[i].flags & 1) { + animState->enabled = 1; + animState->needRefresh = 1; + animState->specialRefresh = 1; + } + + animState->animFlags = _sceneAnims[i].flags & 8; + + if (_sceneAnims[i].flags & 2) + animState->flags = 0x800; + else + animState->flags = 0; + + if (_sceneAnims[i].flags & 4) + animState->flags |= 1; + + animState->xPos1 = _sceneAnims[i].x; + animState->yPos1 = _sceneAnims[i].y; + + if (_sceneAnims[i].flags & 0x20) + animState->shapePtr = _sceneShapeTable[_sceneAnims[i].shapeIndex]; + else + animState->shapePtr = 0; + + if (_sceneAnims[i].flags & 0x40) { + animState->shapeIndex3 = _sceneAnims[i].shapeIndex; + animState->animNum = i; + } else { + animState->shapeIndex3 = 0xFFFF; + animState->animNum = 0xFFFF; + } + + animState->shapeIndex2 = 0xFFFF; + + animState->xPos3 = animState->xPos2 = _sceneAnims[i].x2; + animState->yPos3 = animState->yPos2 = _sceneAnims[i].y2; + animState->width = _sceneAnims[i].width; + animState->height = _sceneAnims[i].height; + animState->width2 = animState->height2 = _sceneAnims[i].specialSize; + + if (_sceneAnims[i].flags & 1) { + if (animInit) { + _animList = addToAnimListSorted(_animList, animState); + } else { + _animList = initAnimList(_animList, animState); + animInit = true; + } + } + } + + if (animInit) { + _animList = addToAnimListSorted(_animList, charAnimState); + } else { + _animList = initAnimList(_animList, charAnimState); + animInit = true; + } + + for (int i = 0; i < 30; ++i) { + animState = &_animObjects[i+11]; + + uint16 shapeIndex = _itemList[i].id; + if (shapeIndex == 0xFFFF || _itemList[i].sceneId != _mainCharacter.sceneId) { + animState->enabled = 0; + animState->needRefresh = 0; + animState->specialRefresh = 0; + } else { + animState->xPos1 = _itemList[i].x; + animState->yPos1 = _itemList[i].y; + animState->shapePtr = getShapePtr(64+shapeIndex); + animState->shapeIndex1 = animState->shapeIndex2 = shapeIndex+64; + + animState->xPos2 = _itemList[i].x; + animState->yPos2 = _itemList[i].y; + int objectScale = getScale(animState->xPos2, animState->yPos2); + + const uint8 *shape = getShapePtr(animState->shapeIndex1); + animState->xPos2 -= (_screen->getShapeScaledWidth(shape, objectScale) >> 1); + animState->yPos2 -= (_screen->getShapeScaledHeight(shape, objectScale) >> 1); + animState->xPos3 = animState->xPos2; + animState->yPos3 = animState->yPos2; + + animState->enabled = 1; + animState->needRefresh = 1; + animState->specialRefresh = 1; + + if (animInit) { + _animList = addToAnimListSorted(_animList, animState); + } else { + _animList = initAnimList(_animList, animState); + animInit = true; + } + } + } + + _animObjects[0].specialRefresh = 1; + _animObjects[0].needRefresh = 1; + + for (int i = 1; i < 41; ++i) { + if (_animObjects[i].enabled) { + _animObjects[i].needRefresh = 1; + _animObjects[i].specialRefresh = 1; + } + } + + restorePage3(); + drawAnimObjects(); + _screen->hideMouse(); + initSceneScreen(unk1); + _screen->showMouse(); + refreshAnimObjects(0); +} + +void KyraEngine_HoF::initSceneScreen(int unk1) { + debugC(9, kDebugLevelMain, "KyraEngine_HoF::initSceneScreen(%d)", unk1); + if (_unkSceneScreenFlag1) { + _screen->copyRegion(0, 0, 0, 0, 320, 144, 2, 0, Screen::CR_NO_P_CHECK); + return; + } + + if (_noScriptEnter) { + memset(_screen->getPalette(0), 0, 384); + _screen->setScreenPalette(_screen->getPalette(0)); + } + + _screen->copyRegion(0, 0, 0, 0, 320, 144, 2, 0, Screen::CR_NO_P_CHECK); + + if (_noScriptEnter) { + _screen->setScreenPalette(_screen->getPalette(1)); + memcpy(_screen->getPalette(0), _screen->getPalette(1), 384); + } + + updateCharPal(0); + + _emc->start(&_sceneScriptState, 3); + _sceneScriptState.regs[5] = unk1; + while (_emc->isValid(&_sceneScriptState)) + _emc->run(&_sceneScriptState); +} + +void KyraEngine_HoF::freeSceneShapePtrs() { + debugC(9, kDebugLevelMain, "KyraEngine_HoF::freeSceneShapePtrs()"); + for (int i = 0; i < ARRAYSIZE(_sceneShapeTable); ++i) + delete [] _sceneShapeTable[i]; + memset(_sceneShapeTable, 0, sizeof(_sceneShapeTable)); +} + +void KyraEngine_HoF::fadeScenePal(int srcIndex, int delayTime) { + debugC(9, kDebugLevelMain, "KyraEngine_HoF::fadeScenePal(%d, %d)", srcIndex, delayTime); + uint8 *dst = _screen->getPalette(0) + 336; + const uint8 *src = _scenePal + (srcIndex << 4)*3; + memcpy(dst, src, 48); + + _screen->fadePalette(_screen->getPalette(0), delayTime, &_updateFunctor); +} + +#pragma mark - +#pragma mark - Pathfinder +#pragma mark - + +bool KyraEngine_HoF::lineIsPassable(int x, int y) { + debugC(9, kDebugLevelMain, "KyraEngine_HoF::lineIsPassable(%d, %d)", x, y); + static int unkTable[] = { 1, 1, 1, 1, 1, 2, 4, 6, 8 }; + + if (_pathfinderFlag & 2) { + if (x >= 320) + return false; + } + + if (_pathfinderFlag & 4) { + if (y >= 144) + return false; + } + + if (_pathfinderFlag & 8) { + if (x < 0) + return false; + } + + if (y > 143) + return false; + + int unk1 = unkTable[getScale(x, y) >> 5]; + + if (y < 0) + y = 0; + x -= unk1 >> 1; + if (x < 0) + x = 0; + int x2 = x + unk1; + if (x2 > 320) + x2 = 320; + + for (;x < x2; ++x) + if (!_screen->getShapeFlag1(x, y)) + return false; + + return true; +} + +} // end of namespace Kyra + diff --git a/engines/kyra/scene_mr.cpp b/engines/kyra/scene_mr.cpp new file mode 100644 index 0000000000..c5a1c28ce2 --- /dev/null +++ b/engines/kyra/scene_mr.cpp @@ -0,0 +1,864 @@ +/* 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_mr.h" +#include "kyra/screen_mr.h" +#include "kyra/wsamovie.h" +#include "kyra/sound.h" +#include "kyra/resource.h" + +namespace Kyra { + +void KyraEngine_MR::enterNewScene(uint16 sceneId, int facing, int unk1, int unk2, int unk3) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::enterNewScene('%d, %d, %d, %d, %d)", sceneId, facing, unk1, unk2, unk3); + ++_enterNewSceneLock; + _screen->hideMouse(); + + showMessage(0, 0xF0, 0xF0); + if (_inventoryState) { + hideInventory(); + musicUpdate(0); + } + + musicUpdate(0); + if (_currentChapter != _currentTalkFile) { + _currentTalkFile = _currentChapter; + openTalkFile(_currentTalkFile); + } + musicUpdate(0); + + if (!unk3) { + //XXX + musicUpdate(0); + } + + if (unk1) { + int x = _mainCharacter.x1; + int y = _mainCharacter.y1; + + switch (facing) { + case 0: + y -= 6; + break; + + case 2: + x = 343; + break; + + case 4: + y = 191; + break; + + case 6: + x = -24; + break; + } + + musicUpdate(0); + moveCharacter(facing, x, y); + } + + musicUpdate(0); + uint32 waitUntilTimer = 0; + bool newSoundFile = false; + if (_lastMusicCommand != _sceneList[sceneId].sound) { + fadeOutMusic(60); + waitUntilTimer = _system->getMillis() + 60 * _tickLength; + newSoundFile = true; + } + + //XXX + + if (!unk3) { + _emc->init(&_sceneScriptState, &_sceneScriptData); + _emc->start(&_sceneScriptState, 5); + while (_emc->isValid(&_sceneScriptState)) { + _emc->run(&_sceneScriptState); + musicUpdate(0); + } + } + + musicUpdate(0); + + _specialExitCount = 0; + Common::set_to(_specialExitTable, _specialExitTable+ARRAYSIZE(_specialExitTable), 0xFFFF); + + musicUpdate(0); + + _mainCharacter.sceneId = sceneId; + _sceneList[sceneId].flags &= ~1; + musicUpdate(0); + unloadScene(); + musicUpdate(0); + + for (int i = 0; i < 4; ++i) { + if (i != _musicSoundChannel && i != _fadeOutMusicChannel) + _soundDigital->stopSound(i); + } + _fadeOutMusicChannel = -1; + musicUpdate(0); + loadScenePal(); + musicUpdate(0); + + if (queryGameFlag(0x1D9)) { + char filename[20]; + if (queryGameFlag(0x20D)) { + resetGameFlag(0x20D); + strcpy(filename, "COW1_"); + } else if (queryGameFlag(0x20E)) { + resetGameFlag(0x20E); + strcpy(filename, "COW2_"); + } else if (queryGameFlag(0x20F)) { + resetGameFlag(0x20F); + strcpy(filename, "COW3_"); + } else if (queryGameFlag(0x20C)) { + resetGameFlag(0x20C); + strcpy(filename, "BOAT"); + } else if (queryGameFlag(0x210)) { + resetGameFlag(0x210); + strcpy(filename, "JUNG"); + } + + playVQA(filename); + + resetGameFlag(0x1D9); + } + + musicUpdate(0); + loadSceneMsc(); + musicUpdate(0); + _sceneExit1 = _sceneList[sceneId].exit1; + _sceneExit2 = _sceneList[sceneId].exit2; + _sceneExit3 = _sceneList[sceneId].exit3; + _sceneExit4 = _sceneList[sceneId].exit4; + + while (_system->getMillis() < waitUntilTimer) + _system->delayMillis(10); + + musicUpdate(0); + initSceneScript(unk3); + musicUpdate(0); + + if (_overwriteSceneFacing) { + facing = _mainCharacter.facing; + _overwriteSceneFacing = false; + } + + enterNewSceneUnk1(facing, unk2, unk3); + musicUpdate(0); + setCommandLineRestoreTimer(-1); + _sceneScriptState.regs[3] = 1; + enterNewSceneUnk2(unk3); + if (queryGameFlag(0)) { + _showOutro = true; + _runFlag = false; + } else { + if (!--_enterNewSceneLock) + _unk5 = 0; + + setNextIdleAnimTimer(); + + if (_itemInHand < 0) { + _itemInHand = -1; + _handItemSet = -1; + _screen->setMouseCursor(0, 0, _gameShapes[0]); + } + + Common::Point pos = getMousePos(); + if (pos.y > 187) + setMousePos(pos.x, 179); + } + _screen->showMouse(); +} + +void KyraEngine_MR::enterNewSceneUnk1(int facing, int unk1, int unk2) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::enterNewSceneUnk1(%d, %d, %d)", facing, unk1, unk2); + int x = 0, y = 0; + int x2 = 0, y2 = 0; + bool needProc = true; + + if (_mainCharX == -1 && _mainCharY == -1) { + switch (facing+1) { + case 1: case 2: case 8: + x2 = _sceneEnterX3; + y2 = _sceneEnterY3; + break; + + case 3: + x2 = _sceneEnterX4; + y2 = _sceneEnterY4; + break; + + case 4: case 5: case 6: + x2 = _sceneEnterX1; + y2 = _sceneEnterY1; + break; + + case 7: + x2 = _sceneEnterX2; + y2 = _sceneEnterY2; + break; + + default: + x2 = y2 = -1; + break; + } + + if (x2 >= 316) + x2 = 312; + if (y2 >= 185) + y2 = 183; + if (x2 <= 4) + x2 = 8; + } + + if (_mainCharX >= 0) { + x = x2 = _mainCharX; + needProc = false; + } + + if (_mainCharY >= 0) { + y = y2 = _mainCharY; + needProc = false; + } + + _mainCharX = _mainCharY = -1; + + if (unk1 && needProc) { + x = x2; + y = y2; + + switch (facing) { + case 0: + y2 = 191; + break; + + case 2: + x2 = -24; + break; + + case 4: + y2 = y - 4; + break; + + case 6: + x2 = 343; + break; + + default: + break; + } + } + + x2 &= ~3; + x &= ~3; + y2 &= ~1; + y &= ~1; + + _mainCharacter.facing = facing; + _mainCharacter.x1 = _mainCharacter.x2 = x2; + _mainCharacter.y1 = _mainCharacter.y2 = y2; + initSceneAnims(unk2); + + if (_mainCharacter.sceneId == 9 && !_soundDigital->isPlaying(_musicSoundChannel)) + snd_playWanderScoreViaMap(_sceneList[_mainCharacter.sceneId].sound, 0); + if (!unk2) + snd_playWanderScoreViaMap(_sceneList[_mainCharacter.sceneId].sound, 0); + + if (unk1 && !unk2 && _mainCharacter.animFrame != 87) + moveCharacter(facing, x, y); +} + +void KyraEngine_MR::enterNewSceneUnk2(int unk1) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::enterNewSceneUnk2(%d)", unk1); + _unk3 = -1; + if (_mainCharX == -1 && _mainCharY == -1 && !unk1) { + _mainCharacter.animFrame = _characterFrameTable[_mainCharacter.facing]; + updateCharacterAnim(0); + refreshAnimObjectsIfNeed(); + } + + if (!unk1) { + runSceneScript4(0); + malcolmSceneStartupChat(); + } + + _unk4 = 0; + _unk3 = -1; +} + +void KyraEngine_MR::unloadScene() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::unloadScene()"); + delete [] _sceneStrings; + _sceneStrings = 0; + musicUpdate(0); + _emc->unload(&_sceneScriptData); + musicUpdate(0); + freeSceneShapes(); + musicUpdate(0); + freeSceneAnims(); + musicUpdate(0); +} + +void KyraEngine_MR::freeSceneShapes() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::freeSceneShapes()"); + for (uint i = 0; i < ARRAYSIZE(_sceneShapes); ++i) { + delete [] _sceneShapes[i]; + _sceneShapes[i] = 0; + } +} + +void KyraEngine_MR::loadScenePal() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::loadScenePal()"); + char filename[16]; + memcpy(_screen->getPalette(2), _screen->getPalette(0), 768); + strcpy(filename, _sceneList[_mainCharacter.sceneId].filename1); + strcat(filename, ".COL"); + + _screen->loadBitmap(filename, 3, 3, 0); + memcpy(_screen->getPalette(2), _screen->getCPagePtr(3), 432); + memset(_screen->getPalette(2), 0, 3); + + for (int i = 144; i <= 167; ++i) { + uint8 *palette = _screen->getPalette(2) + i * 3; + palette[0] = palette[2] = 63; + palette[1] = 0; + } + + _screen->generateOverlay(_screen->getPalette(2), _paletteOverlay, 0xF0, 0x19); + + uint8 *palette = _screen->getPalette(2) + 432; + const uint8 *costPal = _costPalBuffer + _malcolmShapes * 72; + memcpy(palette, costPal, 24*3); +} + +void KyraEngine_MR::loadSceneMsc() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::loadSceneMsc()"); + char filename[16]; + strcpy(filename, _sceneList[_mainCharacter.sceneId].filename1); + strcat(filename, ".MSC"); + + _res->exists(filename, true); + Common::SeekableReadStream *stream = _res->getFileStream(filename); + assert(stream); + int16 minY = 0, height = 0; + minY = stream->readSint16LE(); + height = stream->readSint16LE(); + delete stream; + stream = 0; + musicUpdate(0); + _maskPageMinY = minY; + _maskPageMaxY = minY + height - 1; + + _screen->setShapePages(5, 3, _maskPageMinY, _maskPageMaxY); + + musicUpdate(0); + _screen->loadBitmap(filename, 5, 5, 0, true); + + // HACK + uint8 data[320*200]; + _screen->copyRegionToBuffer(5, 0, 0, 320, 200, data); + _screen->clearPage(5); + _screen->copyBlockToPage(5, 0, _maskPageMinY, 320, height, data); + + musicUpdate(0); +} + +void KyraEngine_MR::initSceneScript(int unk1) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::initSceneScript(%d)", unk1); + const SceneDesc &scene = _sceneList[_mainCharacter.sceneId]; + musicUpdate(0); + + char filename[16]; + strcpy(filename, scene.filename1); + strcat(filename, ".DAT"); + + _res->exists(filename, true); + Common::SeekableReadStream *stream = _res->getFileStream(filename); + assert(stream); + stream->seek(2, SEEK_CUR); + + byte scaleTable[15]; + stream->read(scaleTable, 15); + stream->read(_sceneDatPalette, 45); + stream->read(_sceneDatLayerTable, 15); + int16 shapesCount = stream->readSint16LE(); + + for (int i = 0; i < 15; ++i) + _scaleTable[i] = (uint16(scaleTable[i]) << 8) / 100; + + if (shapesCount > 0) { + strcpy(filename, scene.filename1); + strcat(filename, "9.CPS"); + musicUpdate(0); + _screen->loadBitmap(filename, 3, 3, 0); + int pageBackUp = _screen->_curPage; + _screen->_curPage = 2; + for (int i = 0; i < shapesCount; ++i) { + int16 x = stream->readSint16LE(); + int16 y = stream->readSint16LE(); + int16 w = stream->readSint16LE(); + int16 h = stream->readSint16LE(); + _sceneShapeDescs[i].drawX = stream->readSint16LE(); + _sceneShapeDescs[i].drawY = stream->readSint16LE(); + _sceneShapes[i] = _screen->encodeShape(x, y, w, h, 0); + assert(_sceneShapes[i]); + musicUpdate(0); + } + _screen->_curPage = pageBackUp; + musicUpdate(0); + } + musicUpdate(0); + + strcpy(filename, scene.filename1); + strcat(filename, ".CPS"); + _screen->loadBitmap(filename, 3, 3, 0); + musicUpdate(0); + + Common::set_to(_specialSceneScriptState, _specialSceneScriptState+ARRAYSIZE(_specialSceneScriptState), false); + _sceneEnterX1 = 160; + _sceneEnterY1 = 0; + _sceneEnterX2 = 296; + _sceneEnterY2 = 93; + _sceneEnterX3 = 160; + _sceneEnterY3 = 171; + _sceneEnterX4 = 24; + _sceneEnterY4 = 93; + _sceneMinX = 0; + _sceneMaxX = 319; + + _emc->init(&_sceneScriptState, &_sceneScriptData); + strcpy(filename, scene.filename2); + strcat(filename, ".EMC"); + musicUpdate(0); + _res->exists(filename, true); + _emc->load(filename, &_sceneScriptData, &_opcodes); + + strcpy(filename, scene.filename2); + strcat(filename, "."); + loadLanguageFile(filename, _sceneStrings); + musicUpdate(0); + + runSceneScript8(); + _emc->start(&_sceneScriptState, 0); + _sceneScriptState.regs[0] = _mainCharacter.sceneId; + _sceneScriptState.regs[5] = unk1; + while (_emc->isValid(&_sceneScriptState)) + _emc->run(&_sceneScriptState); + + _screen->copyRegionToBuffer(3, 0, 0, 320, 200, _gamePlayBuffer); + musicUpdate(0); + + for (int i = 0; i < 10; ++i) { + _emc->init(&_sceneSpecialScripts[i], &_sceneScriptData); + _emc->start(&_sceneSpecialScripts[i], i+9); + musicUpdate(0); + _sceneSpecialScriptsTimer[i] = 0; + } + + _sceneEnterX1 &= ~3; + _sceneEnterY1 &= ~1; + _sceneEnterX2 &= ~3; + _sceneEnterY2 &= ~1; + _sceneEnterX3 &= ~3; + _sceneEnterY3 &= ~1; + _sceneEnterX4 &= ~3; + _sceneEnterY4 &= ~1; + musicUpdate(0); +} + +void KyraEngine_MR::initSceneAnims(int unk1) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::initSceneAnims(%d)", unk1); + for (int i = 0; i < 67; ++i) + _animObjects[i].enabled = false; + + AnimObj *obj = &_animObjects[0]; + + if (_mainCharacter.animFrame != 87 && !unk1) + _mainCharacter.animFrame = _characterFrameTable[_mainCharacter.facing]; + + obj->enabled = true; + obj->xPos1 = _mainCharacter.x1; + obj->yPos1 = _mainCharacter.y1; + obj->shapePtr = getShapePtr(_mainCharacter.animFrame); + obj->shapeIndex2 = obj->shapeIndex1 = _mainCharacter.animFrame; + obj->xPos2 = _mainCharacter.x1; + obj->yPos2 = _mainCharacter.y1; + _charScale = getScale(_mainCharacter.x1, _mainCharacter.y1); + obj->xPos3 = obj->xPos2 += (_malcolmShapeXOffset * _charScale) >> 8; + obj->yPos3 = obj->yPos2 += (_malcolmShapeYOffset * _charScale) >> 8; + _mainCharacter.x3 = _mainCharacter.x1 - (_charScale >> 4) - 1; + _mainCharacter.y3 = _mainCharacter.y1 - (_charScale >> 6) - 1; + obj->needRefresh = true; + _animList = 0; + + for (int i = 0; i < 16; ++i) { + const SceneAnim &anim = _sceneAnims[i]; + obj = &_animObjects[i+1]; + obj->enabled = false; + obj->needRefresh = false; + + if (anim.flags & 1) { + obj->enabled = true; + obj->needRefresh = true; + } + + obj->specialRefresh = (anim.flags & 0x20) ? 1 : 0; + obj->flags = (anim.flags & 0x10) ? 0x800 : 0; + if (anim.flags & 2) + obj->flags |= 1; + + obj->xPos1 = anim.x; + obj->yPos1 = anim.y; + + if ((anim.flags & 4) && anim.shapeIndex != -1) + obj->shapePtr = _sceneShapes[anim.shapeIndex]; + else + obj->shapePtr = 0; + + if (anim.flags & 8) { + obj->shapeIndex3 = anim.shapeIndex; + obj->animNum = i; + } else { + obj->shapeIndex3 = 0xFFFF; + obj->animNum = 0xFFFF; + } + + obj->xPos3 = obj->xPos2 = anim.x2; + obj->yPos3 = obj->yPos2 = anim.y2; + obj->width = anim.width; + obj->height = anim.height; + obj->width2 = obj->height2 = anim.specialSize; + + if (anim.flags & 1) { + if (_animList) + _animList = addToAnimListSorted(_animList, obj); + else + _animList = initAnimList(_animList, obj); + } + } + + if (_animList) + _animList = addToAnimListSorted(_animList, &_animObjects[0]); + else + _animList = initAnimList(_animList, &_animObjects[0]); + + for (int i = 0; i < 50; ++i) { + obj = &_animObjects[i+17]; + const Item &item = _itemList[i]; + if (item.id != 0xFFFF && item.sceneId == _mainCharacter.sceneId) { + obj->xPos1 = item.x; + obj->yPos1 = item.y; + animSetupPaletteEntry(obj); + obj->shapePtr = 0; + obj->shapeIndex1 = obj->shapeIndex2 = item.id + 248; + obj->xPos2 = item.x; + obj->yPos2 = item.y; + + int scale = getScale(obj->xPos1, obj->yPos1); + const uint8 *shape = getShapePtr(obj->shapeIndex1); + obj->xPos3 = obj->xPos2 -= (_screen->getShapeScaledWidth(shape, scale) >> 1); + obj->yPos3 = obj->yPos2 -= _screen->getShapeScaledHeight(shape, scale) - 1; + obj->enabled = true; + obj->needRefresh = true; + + if (_animList) + _animList = addToAnimListSorted(_animList, obj); + else + _animList = initAnimList(_animList, obj); + } else { + obj->enabled = false; + obj->needRefresh = false; + } + } + + for (int i = 0; i < 67; ++i) + _animObjects[i].needRefresh = _animObjects[i].enabled; + + restorePage3(); + drawAnimObjects(); + _screen->hideMouse(); + initSceneScreen(unk1); + _screen->showMouse(); + refreshAnimObjects(0); +} + +void KyraEngine_MR::initSceneScreen(int unk1) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::initSceneScreen(%d)", unk1); + _screen->copyBlockToPage(2, 0, 188, 320, 12, _interfaceCommandLine); + + if (_unkSceneScreenFlag1) { + _screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0, Screen::CR_NO_P_CHECK); + return; + } + + if (_noScriptEnter) { + memset(_screen->getPalette(0), 0, 432); + if (!_wsaPlayingVQA) + _screen->setScreenPalette(_screen->getPalette(0)); + } + + _screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0, Screen::CR_NO_P_CHECK); + + if (_noScriptEnter) { + if (!_wsaPlayingVQA) + _screen->setScreenPalette(_screen->getPalette(2)); + memcpy(_screen->getPalette(0), _screen->getPalette(2), 432); + if (_wsaPlayingVQA) { + _screen->fadeFromBlack(0x3C); + _wsaPlayingVQA = false; + } + } + + updateCharPal(0); + + if (1/*!_menuDirectlyToLoad*/) { + _emc->start(&_sceneScriptState, 3); + _sceneScriptState.regs[5] = unk1; + + while (_emc->isValid(&_sceneScriptState)) + _emc->run(&_sceneScriptState); + } +} + +int KyraEngine_MR::trySceneChange(int *moveTable, int unk1, int updateChar) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::trySceneChange(%p, %d, %d)", (const void*)moveTable, unk1, updateChar); + bool running = true; + bool unkFlag = false; + int changedScene = 0; + const int *moveTableStart = moveTable; + _unk4 = 0; + + while (running && !_quitFlag) { + if (*moveTable >= 0 && *moveTable <= 7) { + _mainCharacter.facing = getOppositeFacingDirection(*moveTable); + unkFlag = true; + } else { + if (*moveTable == 8) { + running = false; + } else { + ++moveTable; + unkFlag = false; + } + } + + if (checkSceneChange()) { + running = false; + changedScene = 1; + } + + if (unk1) { + if (skipFlag()) { + resetSkipFlag(false); + running = false; + _unk4 = 1; + } + } + + if (!unkFlag || !running) + continue; + + int ret = 0; + if (moveTable == moveTableStart || moveTable[1] == 8) + ret = updateCharPos(0, 0); + else + ret = updateCharPos(moveTable, 0); + + if (ret) + ++moveTable; + + update(); + } + + if (updateChar) + _mainCharacter.animFrame = _characterFrameTable[_mainCharacter.facing]; + + updateCharacterAnim(0); + refreshAnimObjectsIfNeed(); + + return changedScene; +} + +int KyraEngine_MR::checkSceneChange() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::checkSceneChange()"); + const SceneDesc &curScene = _sceneList[_mainCharacter.sceneId]; + int charX = _mainCharacter.x1, charY = _mainCharacter.y1; + int facing = 0; + int process = 0; + + if (_screen->getLayer(charX, charY) == 1 && _unk3 == -7) { + facing = 0; + process = 1; + } else if (charX >= 316 && _unk3 == -6) { + facing = 2; + process = 1; + } else if (charY >= 186 && _unk3 == -5) { + facing = 4; + process = 1; + } else if (charX <= 4 && _unk3 == -4) { + facing = 6; + process = 1; + } + + if (!process) + return 0; + + uint16 newScene = 0xFFFF; + switch (facing) { + case 0: + newScene = curScene.exit1; + break; + + case 2: + newScene = curScene.exit2; + break; + + case 4: + newScene = curScene.exit3; + break; + + case 6: + newScene = curScene.exit4; + break; + + default: + newScene = _mainCharacter.sceneId; + break; + } + + if (newScene == 0xFFFF) + return 0; + + enterNewScene(newScene, facing, 1, 1, 0); + return 1; +} +int KyraEngine_MR::runSceneScript1(int x, int y) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::runSceneScript1(%d, %d)", x, y); + if (y > 187 && _unk3 > -4) + return 0; + if (_deathHandler >= 0) + return 0; + + _emc->init(&_sceneScriptState, &_sceneScriptData); + _sceneScriptState.regs[1] = x; + _sceneScriptState.regs[2] = y; + _sceneScriptState.regs[3] = 0; + _sceneScriptState.regs[4] = _itemInHand; + + _emc->start(&_sceneScriptState, 1); + while (_emc->isValid(&_sceneScriptState)) + _emc->run(&_sceneScriptState); + + return _sceneScriptState.regs[3]; +} + +int KyraEngine_MR::runSceneScript2() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::runSceneScript2()"); + _sceneScriptState.regs[1] = _mouseX; + _sceneScriptState.regs[2] = _mouseY; + _sceneScriptState.regs[3] = 0; + _sceneScriptState.regs[4] = _itemInHand; + + _emc->start(&_sceneScriptState, 2); + while (_emc->isValid(&_sceneScriptState)) + _emc->run(&_sceneScriptState); + + return _sceneScriptState.regs[3]; +} + +void KyraEngine_MR::runSceneScript4(int unk1) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::runSceneScript4(%d)", unk1); + _sceneScriptState.regs[4] = _itemInHand; + _sceneScriptState.regs[5] = unk1; + _sceneScriptState.regs[3] = 0; + _noStartupChat = false; + + _emc->start(&_sceneScriptState, 4); + while (_emc->isValid(&_sceneScriptState)) + _emc->run(&_sceneScriptState); + + if (_sceneScriptState.regs[3]) + _noStartupChat = true; +} + +void KyraEngine_MR::runSceneScript6() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::runSceneScript6()"); + _emc->init(&_sceneScriptState, &_sceneScriptData); + + _sceneScriptState.regs[0] = _mainCharacter.sceneId; + _sceneScriptState.regs[1] = _mouseX; + _sceneScriptState.regs[2] = _mouseY; + _sceneScriptState.regs[3] = _itemInHand; + + _emc->start(&_sceneScriptState, 6); + while (_emc->isValid(&_sceneScriptState)) + _emc->run(&_sceneScriptState); +} + +void KyraEngine_MR::runSceneScript8() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::runSceneScript8()"); + _emc->start(&_sceneScriptState, 8); + while (_emc->isValid(&_sceneScriptState)) { + musicUpdate(0); + _emc->run(&_sceneScriptState); + } +} + +bool KyraEngine_MR::lineIsPassable(int x, int y) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::lineIsPassable(%d, %d)", x, y); + static const uint8 widthTable[] = { 1, 1, 1, 1, 1, 2, 4, 6, 8 }; + + if ((_pathfinderFlag & 2) && x >= 320) + return false; + if ((_pathfinderFlag & 4) && y >= 188) + return false; + if ((_pathfinderFlag & 8) && x < 0) + return false; + if (y > 187) + return false; + + uint width = widthTable[getScale(x, y) >> 5]; + + if (y < 0) + y = 0; + x -= width >> 1; + if (x < 0) + x = 0; + int x2 = x + width; + if (x2 > 320) + x2 = 320; + + for (; x < x2; ++x) { + if (y < _maskPageMinY || y > _maskPageMaxY) + return false; + + if (!_screen->getShapeFlag1(x, y)) + return false; + } + + return true; +} + +} // end of namespace Kyra diff --git a/engines/kyra/scene_v2.cpp b/engines/kyra/scene_v2.cpp deleted file mode 100644 index f46d993719..0000000000 --- a/engines/kyra/scene_v2.cpp +++ /dev/null @@ -1,959 +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_v2.h" -#include "kyra/screen_v2.h" -#include "kyra/sound.h" -#include "kyra/wsamovie.h" - -#include "common/func.h" - -namespace Kyra { - -void KyraEngine_v2::enterNewScene(uint16 newScene, int facing, int unk1, int unk2, int unk3) { - debugC(9, kDebugLevelMain, "KyraEngine_v2::enterNewScene(%d, %d, %d, %d, %d)", newScene, facing, unk1, unk2, unk3); - if (_newChapterFile != _currentTalkFile) { - _currentTalkFile = _newChapterFile; - if (_flags.isTalkie) { - showMessageFromCCode(265, 150, 0); - _screen->updateScreen(); - openTalkFile(_currentTalkFile); - } - showMessage(0, 207); - _screen->updateScreen(); - } - - _screen->hideMouse(); - - if (!unk3) { - updateWaterFlasks(); - displayInvWsaLastFrame(); - } - - if (unk1) { - int x = _mainCharacter.x1; - int y = _mainCharacter.y1; - - switch (facing) { - case 0: - y -= 6; - break; - - case 2: - x = 335; - break; - - case 4: - y = 147; - break; - - case 6: - x = -16; - break; - - default: - break; - } - - moveCharacter(facing, x, y); - } - - bool newSoundFile = false; - uint32 waitTime = 0; - if (_sceneList[newScene].sound != _lastMusicCommand) { - newSoundFile = true; - waitTime = _system->getMillis() + 1000; - _sound->beginFadeOut(); - } - - _chatAltFlag = false; - - if (!unk3) { - _emc->init(&_sceneScriptState, &_sceneScriptData); - _emc->start(&_sceneScriptState, 5); - while (_emc->isValid(&_sceneScriptState)) - _emc->run(&_sceneScriptState); - } - - Common::for_each(_wsaSlots, _wsaSlots+ARRAYSIZE(_wsaSlots), Common::mem_fun(&WSAMovieV2::close)); - _specialExitCount = 0; - memset(_specialExitTable, -1, sizeof(_specialExitTable)); - - _mainCharacter.sceneId = newScene; - _sceneList[newScene].flags &= ~1; - loadScenePal(); - unloadScene(); - loadSceneMsc(); - - SceneDesc &scene = _sceneList[newScene]; - _sceneExit1 = scene.exit1; - _sceneExit2 = scene.exit2; - _sceneExit3 = scene.exit3; - _sceneExit4 = scene.exit4; - - if (newSoundFile) { - if (_sound->getMusicType() == Sound::kAdlib) { - while (_sound->isPlaying()) - _system->delayMillis(10); - } else { - while (waitTime > _system->getMillis()) - _system->delayMillis(10); - } - snd_loadSoundFile(_sceneList[newScene].sound); - } - - startSceneScript(unk3); - - if (_overwriteSceneFacing) { - facing = _mainCharacter.facing; - _overwriteSceneFacing = false; - } - - enterNewSceneUnk1(facing, unk2, unk3); - - setTimer1DelaySecs(-1); - _sceneScriptState.regs[3] = 1; - enterNewSceneUnk2(unk3); - _screen->showMouse(); - _unk5 = 0; - setNextIdleAnimTimer(); - - _currentScene = newScene; -} - -void KyraEngine_v2::enterNewSceneUnk1(int facing, int unk1, int unk2) { - debugC(9, kDebugLevelMain, "KyraEngine_v2::enterNewSceneUnk1(%d, %d, %d)", facing, unk1, unk2); - int x = 0, y = 0; - int x2 = 0, y2 = 0; - bool needProc = true; - - if (_mainCharX == -1 && _mainCharY == -1) { - switch (facing+1) { - case 1: case 2: case 8: - x2 = _sceneEnterX3; - y2 = _sceneEnterY3; - break; - - case 3: - x2 = _sceneEnterX4; - y2 = _sceneEnterY4; - break; - - case 4: case 5: case 6: - x2 = _sceneEnterX1; - y2 = _sceneEnterY1; - break; - - case 7: - x2 = _sceneEnterX2; - y2 = _sceneEnterY2; - break; - - default: - x2 = y2 = -1; - break; - } - - if (x2 >= 316) - x2 = 312; - if (y2 >= 141) - y2 = 139; - if (x2 <= 4) - x2 = 8; - } - - if (_mainCharX >= 0) { - x = x2 = _mainCharX; - needProc = false; - } - - if (_mainCharY >= 0) { - y = y2 = _mainCharY; - needProc = false; - } - - _mainCharX = _mainCharY = -1; - - if (unk1 && needProc) { - x = x2; - y = y2; - - switch (facing) { - case 0: - y2 = 147; - break; - - case 2: - x2 = -16; - break; - - case 4: - y2 = y - 4; - break; - - case 6: - x2 = 335; - break; - - default: - break; - } - } - - x2 &= ~3; - x &= ~3; - y2 &= ~1; - y &= ~1; - - _mainCharacter.facing = facing; - _mainCharacter.x1 = _mainCharacter.x2 = x2; - _mainCharacter.y1 = _mainCharacter.y2 = y2; - initSceneAnims(unk2); - - if (!unk2) - snd_playWanderScoreViaMap(_sceneList[_mainCharacter.sceneId].sound, 0); - - if (unk1 && !unk2 && _mainCharacter.animFrame != 32) - moveCharacter(facing, x, y); -} - -void KyraEngine_v2::enterNewSceneUnk2(int unk1) { - debugC(9, kDebugLevelMain, "KyraEngine_v2::enterNewSceneUnk2(%d)", unk1); - _unk3 = -1; - - if (_flags.isTalkie) { - if (_mainCharX == -1 && _mainCharY == -1 && _mainCharacter.sceneId != 61 && - !queryGameFlag(0x1F1) && !queryGameFlag(0x192) && !queryGameFlag(0x193) && - _mainCharacter.sceneId != 70 && !queryGameFlag(0x159) && _mainCharacter.sceneId != 37) { - _mainCharacter.animFrame = _characterFrameTable[_mainCharacter.facing]; - updateCharacterAnim(0); - refreshAnimObjectsIfNeed(); - } - } else if (_mainCharX != -1 && _mainCharY != -1) { - if (_characterFrameTable[_mainCharacter.facing] == 25) - _mainCharacter.facing = 5; - _mainCharacter.animFrame = _characterFrameTable[_mainCharacter.facing]; - updateCharacterAnim(0); - refreshAnimObjectsIfNeed(); - } - - if (!unk1) { - runSceneScript4(0); - zanthSceneStartupChat(); - } - - _unk4 = 0; - _unk3 = -1; -} - -int KyraEngine_v2::trySceneChange(int *moveTable, int unk1, int updateChar) { - debugC(9, kDebugLevelMain, "KyraEngine_v2::trySceneChange(%p, %d, %d)", (const void*)moveTable, unk1, updateChar); - bool running = true; - bool unkFlag = false; - int8 updateType = -1; - int changedScene = 0; - const int *moveTableStart = moveTable; - _unk4 = 0; - while (running && !_quitFlag) { - if (*moveTable >= 0 && *moveTable <= 7) { - _mainCharacter.facing = getOppositeFacingDirection(*moveTable); - unkFlag = true; - } else { - if (*moveTable == 8) { - running = false; - } else { - ++moveTable; - unkFlag = false; - } - } - - if (checkSceneChange()) { - running = false; - changedScene = 1; - } - - if (unk1) { - if (skipFlag()) { - resetSkipFlag(false); - running = false; - _unk4 = 1; - } - } - - if (!unkFlag || !running) - continue; - - int ret = 0; - if (moveTable == moveTableStart || moveTable[1] == 8) - ret = updateCharPos(0); - else - ret = updateCharPos(moveTable); - - if (ret) - ++moveTable; - - ++updateType; - if (!updateType) { - update(); - } else if (updateType == 1) { - refreshAnimObjectsIfNeed(); - updateType = -1; - } - } - - if (updateChar) - _mainCharacter.animFrame = _characterFrameTable[_mainCharacter.facing]; - - updateCharacterAnim(0); - refreshAnimObjectsIfNeed(); - - if (!changedScene && !_unk4) { - //XXX - } - return changedScene; -} - -int KyraEngine_v2::checkSceneChange() { - debugC(9, kDebugLevelMain, "KyraEngine_v2::checkSceneChange()"); - SceneDesc &curScene = _sceneList[_mainCharacter.sceneId]; - int charX = _mainCharacter.x1, charY = _mainCharacter.y1; - int facing = 0; - int process = 0; - - if (_screen->getLayer(charX, charY) == 1 && _unk3 == -6) { - facing = 0; - process = 1; - } else if (charX >= 316 && _unk3 == -5) { - facing = 2; - process = 1; - } else if (charY >= 142 && _unk3 == -4) { - facing = 4; - process = 1; - } else if (charX <= 4 && _unk3 == -3) { - facing = 6; - process = 1; - } - - if (!process) - return 0; - - uint16 newScene = 0xFFFF; - switch (facing) { - case 0: - newScene = curScene.exit1; - break; - - case 2: - newScene = curScene.exit2; - break; - - case 4: - newScene = curScene.exit3; - break; - - case 6: - newScene = curScene.exit4; - break; - - default: - newScene = _mainCharacter.sceneId; - break; - } - - if (newScene == 0xFFFF) - return 0; - - enterNewScene(newScene, facing, 1, 1, 0); - return 1; -} - -void KyraEngine_v2::unloadScene() { - debugC(9, kDebugLevelMain, "KyraEngine_v2::unloadScene()"); - _emc->unload(&_sceneScriptData); - freeSceneShapePtrs(); - freeSceneAnims(); -} - -void KyraEngine_v2::loadScenePal() { - debugC(9, kDebugLevelMain, "KyraEngine_v2::loadScenePal()"); - uint16 sceneId = _mainCharacter.sceneId; - memcpy(_screen->getPalette(1), _screen->getPalette(0), 768); - - char filename[14]; - strcpy(filename, _sceneList[sceneId].filename); - strcat(filename, ".COL"); - _screen->loadBitmap(filename, 3, 3, 0); - memcpy(_screen->getPalette(1), _screen->getCPagePtr(3), 384); - memset(_screen->getPalette(1), 0, 3); - memcpy(_scenePal, _screen->getCPagePtr(3)+336, 432); -} - -void KyraEngine_v2::loadSceneMsc() { - debugC(9, kDebugLevelMain, "KyraEngine_v2::loadSceneMsc()"); - uint16 sceneId = _mainCharacter.sceneId; - char filename[14]; - strcpy(filename, _sceneList[sceneId].filename); - strcat(filename, ".MSC"); - _screen->loadBitmap(filename, 3, 5, 0); -} - -void KyraEngine_v2::startSceneScript(int unk1) { - debugC(9, kDebugLevelMain, "KyraEngine_v2::startSceneScript(%d)", unk1); - uint16 sceneId = _mainCharacter.sceneId; - char filename[14]; - - strcpy(filename, _sceneList[sceneId].filename); - if (sceneId == 68 && (queryGameFlag(0x1BC) || queryGameFlag(0x1BD))) - strcpy(filename, "DOORX"); - strcat(filename, ".CPS"); - - _screen->loadBitmap(filename, 3, 3, 0); - resetScaleTable(); - _useCharPal = false; - memset(_charPalTable, 0, sizeof(_charPalTable)); - memset(_layerFlagTable, 0, sizeof(_layerFlagTable)); - memset(_specialSceneScriptState, 0, sizeof(_specialSceneScriptState)); - - _sceneEnterX1 = 160; - _sceneEnterY1 = 0; - _sceneEnterX2 = 296; - _sceneEnterY2 = 72; - _sceneEnterX3 = 160; - _sceneEnterY3 = 128; - _sceneEnterX4 = 24; - _sceneEnterY4 = 72; - - _sceneCommentString = "Undefined scene comment string!"; - _emc->init(&_sceneScriptState, &_sceneScriptData); - - strcpy(filename, _sceneList[sceneId].filename); - strcat(filename, "."); - strcat(filename, _scriptLangExt[(_flags.platform == Common::kPlatformPC && !_flags.isTalkie) ? 0 : _lang]); - - _res->exists(filename, true); - _emc->load(filename, &_sceneScriptData, &_opcodes); - runSceneScript7(); - - _emc->start(&_sceneScriptState, 0); - _sceneScriptState.regs[0] = sceneId; - _sceneScriptState.regs[5] = unk1; - while (_emc->isValid(&_sceneScriptState)) - _emc->run(&_sceneScriptState); - - memcpy(_gamePlayBuffer, _screen->getCPagePtr(3), 46080); - - for (int i = 0; i < 10; ++i) { - _emc->init(&_sceneSpecialScripts[i], &_sceneScriptData); - _emc->start(&_sceneSpecialScripts[i], i+8); - _sceneSpecialScriptsTimer[i] = 0; - } - - _sceneEnterX1 &= ~3; - _sceneEnterX2 &= ~3; - _sceneEnterX3 &= ~3; - _sceneEnterX4 &= ~3; - _sceneEnterY1 &= ~1; - _sceneEnterY2 &= ~1; - _sceneEnterY3 &= ~1; - _sceneEnterY4 &= ~1; -} - -void KyraEngine_v2::runSceneScript2() { - debugC(9, kDebugLevelMain, "KyraEngine_v2::runSceneScript2()"); - _emc->init(&_sceneScriptState, &_sceneScriptData); - _sceneScriptState.regs[4] = _itemInHand; - _emc->start(&_sceneScriptState, 2); - - while (_emc->isValid(&_sceneScriptState)) - _emc->run(&_sceneScriptState); -} - -void KyraEngine_v2::runSceneScript4(int unk1) { - debugC(9, kDebugLevelMain, "KyraEngine_v2::runSceneScript4(%d)", unk1); - _sceneScriptState.regs[4] = _itemInHand; - _sceneScriptState.regs[5] = unk1; - - _emc->start(&_sceneScriptState, 4); - while (_emc->isValid(&_sceneScriptState)) - _emc->run(&_sceneScriptState); -} - -void KyraEngine_v2::runSceneScript6() { - debugC(9, kDebugLevelMain, "KyraEngine_v2::runSceneScript6()"); - _emc->init(&_sceneScriptState, &_sceneScriptData); - - _sceneScriptState.regs[0] = _mainCharacter.sceneId; - _sceneScriptState.regs[1] = _mouseX; - _sceneScriptState.regs[2] = _mouseY; - _sceneScriptState.regs[4] = _itemInHand; - - _emc->start(&_sceneScriptState, 6); - while (_emc->isValid(&_sceneScriptState)) - _emc->run(&_sceneScriptState); -} - -void KyraEngine_v2::runSceneScript7() { - debugC(9, kDebugLevelMain, "KyraEngine_v2::runSceneScript7()"); - int oldPage = _screen->_curPage; - _screen->_curPage = 2; - - _emc->start(&_sceneScriptState, 7); - while (_emc->isValid(&_sceneScriptState)) - _emc->run(&_sceneScriptState); - - _screen->_curPage = oldPage; -} - -void KyraEngine_v2::initSceneAnims(int unk1) { - debugC(9, kDebugLevelMain, "KyraEngine_v2::initSceneAnims(%d)", unk1); - for (int i = 0; i < ARRAYSIZE(_animObjects); ++i) - _animObjects[i].enabled = 0; - - bool animInit = false; - - AnimObj *animState = &_animObjects[0]; - - if (_mainCharacter.animFrame != 32) - _mainCharacter.animFrame = _characterFrameTable[_mainCharacter.facing]; - - animState->enabled = 1; - animState->xPos1 = _mainCharacter.x1; - animState->yPos1 = _mainCharacter.y1; - animState->shapePtr = _defaultShapeTable[_mainCharacter.animFrame]; - animState->shapeIndex1 = animState->shapeIndex2 = _mainCharacter.animFrame; - - int frame = _mainCharacter.animFrame - 9; - int shapeX = _shapeDescTable[frame].xAdd; - int shapeY = _shapeDescTable[frame].yAdd; - - animState->xPos2 = _mainCharacter.x1; - animState->yPos2 = _mainCharacter.y1; - - _charScaleX = _charScaleY = getScale(_mainCharacter.x1, _mainCharacter.y1); - - int shapeXScaled = (shapeX * _charScaleX) >> 8; - int shapeYScaled = (shapeY * _charScaleY) >> 8; - - animState->xPos2 += shapeXScaled; - animState->yPos2 += shapeYScaled; - animState->xPos3 = animState->xPos2; - animState->yPos3 = animState->yPos2; - animState->needRefresh = 1; - animState->unk8 = 1; - - _animList = 0; - - AnimObj *charAnimState = animState; - - for (int i = 0; i < 10; ++i) { - animState = &_animObjects[i+1]; - animState->enabled = 0; - animState->needRefresh = 0; - animState->unk8 = 0; - - if (_sceneAnims[i].flags & 1) { - animState->enabled = 1; - animState->needRefresh = 1; - animState->unk8 = 1; - } - - animState->animFlags = _sceneAnims[i].flags & 8; - - if (_sceneAnims[i].flags & 2) - animState->flags = 0x800; - else - animState->flags = 0; - - if (_sceneAnims[i].flags & 4) - animState->flags |= 1; - - animState->xPos1 = _sceneAnims[i].x; - animState->yPos1 = _sceneAnims[i].y; - - if (_sceneAnims[i].flags & 0x20) - animState->shapePtr = _sceneShapeTable[_sceneAnims[i].shapeIndex]; - else - animState->shapePtr = 0; - - if (_sceneAnims[i].flags & 0x40) { - animState->shapeIndex3 = _sceneAnims[i].shapeIndex; - animState->animNum = i; - } else { - animState->shapeIndex3 = 0xFFFF; - animState->animNum = 0xFFFF; - } - - animState->shapeIndex2 = 0xFFFF; - - animState->xPos3 = animState->xPos2 = _sceneAnims[i].x2; - animState->yPos3 = animState->yPos2 = _sceneAnims[i].y2; - animState->width = _sceneAnims[i].width; - animState->height = _sceneAnims[i].height; - animState->width2 = animState->height2 = _sceneAnims[i].specialSize; - - if (_sceneAnims[i].flags & 1) { - if (animInit) { - _animList = addToAnimListSorted(_animList, animState); - } else { - _animList = initAnimList(_animList, animState); - animInit = true; - } - } - } - - if (animInit) { - _animList = addToAnimListSorted(_animList, charAnimState); - } else { - _animList = initAnimList(_animList, charAnimState); - animInit = true; - } - - for (int i = 0; i < 30; ++i) { - animState = &_animObjects[i+11]; - - uint16 shapeIndex = _itemList[i].id; - if (shapeIndex == 0xFFFF || _itemList[i].sceneId != _mainCharacter.sceneId) { - animState->enabled = 0; - animState->needRefresh = 0; - animState->unk8 = 0; - } else { - animState->xPos1 = _itemList[i].x; - animState->yPos1 = _itemList[i].y; - animState->shapePtr = _defaultShapeTable[64+shapeIndex]; - animState->shapeIndex1 = animState->shapeIndex2 = shapeIndex+64; - - animState->xPos2 = _itemList[i].x; - animState->yPos2 = _itemList[i].y; - int objectScale = getScale(animState->xPos2, animState->yPos2); - - const uint8 *shape = getShapePtr(animState->shapeIndex1); - animState->xPos2 -= (_screen->getShapeScaledWidth(shape, objectScale) >> 1); - animState->yPos2 -= (_screen->getShapeScaledHeight(shape, objectScale) >> 1); - animState->xPos3 = animState->xPos2; - animState->yPos3 = animState->yPos2; - - animState->enabled = 1; - animState->needRefresh = 1; - animState->unk8 = 1; - - if (animInit) { - _animList = addToAnimListSorted(_animList, animState); - } else { - _animList = initAnimList(_animList, animState); - animInit = true; - } - } - } - - _animObjects[0].unk8 = 1; - _animObjects[0].needRefresh = 1; - - for (int i = 1; i < 41; ++i) { - if (_animObjects[i].enabled) { - _animObjects[i].needRefresh = 1; - _animObjects[i].unk8 = 1; - } - } - - restorePage3(); - drawAnimObjects(); - _screen->hideMouse(); - initSceneScreen(unk1); - _screen->showMouse(); - refreshAnimObjects(0); -} - -void KyraEngine_v2::initSceneScreen(int unk1) { - debugC(9, kDebugLevelMain, "KyraEngine_v2::initSceneScreen(%d)", unk1); - if (_unkSceneScreenFlag1) { - _screen->copyRegion(0, 0, 0, 0, 320, 144, 2, 0, Screen::CR_NO_P_CHECK); - return; - } - - if (_noScriptEnter) { - memset(_screen->getPalette(0), 0, 384); - _screen->setScreenPalette(_screen->getPalette(0)); - } - - _screen->copyRegion(0, 0, 0, 0, 320, 144, 2, 0, Screen::CR_NO_P_CHECK); - - if (_noScriptEnter) { - _screen->setScreenPalette(_screen->getPalette(1)); - memcpy(_screen->getPalette(0), _screen->getPalette(1), 384); - } - - updateCharPal(0); - - _emc->start(&_sceneScriptState, 3); - _sceneScriptState.regs[5] = unk1; - while (_emc->isValid(&_sceneScriptState)) - _emc->run(&_sceneScriptState); -} - -void KyraEngine_v2::updateSpecialSceneScripts() { - debugC(9, kDebugLevelMain, "KyraEngine_v2::updateSpecialSceneScripts()"); - uint32 nextTime = _system->getMillis() + _tickLength; - const int startScript = _lastProcessedSceneScript; - - while (_system->getMillis() <= nextTime) { - if (_sceneSpecialScriptsTimer[_lastProcessedSceneScript] <= _system->getMillis() && - !_specialSceneScriptState[_lastProcessedSceneScript]) { - _specialSceneScriptRunFlag = true; - - while (_specialSceneScriptRunFlag && _sceneSpecialScriptsTimer[_lastProcessedSceneScript] <= _system->getMillis()) { - if (!_emc->run(&_sceneSpecialScripts[_lastProcessedSceneScript])) - _specialSceneScriptRunFlag = false; - } - } - - if (!_emc->isValid(&_sceneSpecialScripts[_lastProcessedSceneScript])) { - _emc->start(&_sceneSpecialScripts[_lastProcessedSceneScript], 8+_lastProcessedSceneScript); - _specialSceneScriptRunFlag = false; - } - - ++_lastProcessedSceneScript; - if (_lastProcessedSceneScript >= 10) - _lastProcessedSceneScript = 0; - - if (_lastProcessedSceneScript == startScript) - return; - } -} - -void KyraEngine_v2::freeSceneShapePtrs() { - debugC(9, kDebugLevelMain, "KyraEngine_v2::freeSceneShapePtrs()"); - for (int i = 0; i < ARRAYSIZE(_sceneShapeTable); ++i) - delete [] _sceneShapeTable[i]; - memset(_sceneShapeTable, 0, sizeof(_sceneShapeTable)); -} - -void KyraEngine_v2::freeSceneAnims() { - debugC(9, kDebugLevelMain, "KyraEngine_v2::freeSceneAnims()"); - for (int i = 0; i < ARRAYSIZE(_sceneAnims); ++i) - _sceneAnims[i].flags = 0; - Common::for_each(_sceneAnimMovie, _sceneAnimMovie+ARRAYSIZE(_sceneAnimMovie), Common::mem_fun(&WSAMovieV2::close)); -} - -void KyraEngine_v2::fadeScenePal(int srcIndex, int delayTime) { - debugC(9, kDebugLevelMain, "KyraEngine_v2::fadeScenePal(%d, %d)", srcIndex, delayTime); - uint8 *dst = _screen->getPalette(0) + 336; - const uint8 *src = _scenePal + (srcIndex << 4)*3; - memcpy(dst, src, 48); - - _screen->fadePalette(_screen->getPalette(0), delayTime, &_updateFunctor); -} - -#pragma mark - -#pragma mark - Pathfinder -#pragma mark - - -int KyraEngine_v2::findWay(int x, int y, int toX, int toY, int *moveTable, int moveTableSize) { - debugC(9, kDebugLevelMain, "KyraEngine_v2::findWay(%d, %d, %d, %d, %p, %d)", x, y, toX, toY, (const void *)moveTable, moveTableSize); - x &= ~3; toX &= ~3; - y &= ~1; toY &= ~1; - int size = KyraEngine::findWay(x, y, toX, toY, moveTable, moveTableSize); - static bool usePostProcess = false; - if (size && !usePostProcess) { - usePostProcess = true; - int temp = pathfinderInitPositionTable(moveTable); - temp = pathfinderInitPositionIndexTable(temp, x, y); - pathfinderFinializePath(moveTable, temp, x, y, moveTableSize); - usePostProcess = false; - } - return usePostProcess ? size : getMoveTableSize(moveTable); -} - -bool KyraEngine_v2::lineIsPassable(int x, int y) { - debugC(9, kDebugLevelMain, "KyraEngine_v2::lineIsPassable(%d, %d)", x, y); - static int unkTable[] = { 1, 1, 1, 1, 1, 2, 4, 6, 8 }; - - if (_pathfinderFlag & 2) { - if (x >= 320) - return false; - } - - if (_pathfinderFlag & 4) { - if (y >= 144) - return false; - } - - if (_pathfinderFlag & 8) { - if (x < 0) - return false; - } - - if (y > 143) - return false; - - int unk1 = unkTable[getScale(x, y) >> 5]; - - if (y < 0) - y = 0; - x -= unk1 >> 1; - if (x < 0) - x = 0; - int x2 = x + unk1; - if (x2 > 320) - x2 = 320; - - for (;x < x2; ++x) - if (!_screen->getShapeFlag1(x, y)) - return false; - - return true; -} - -bool KyraEngine_v2::directLinePassable(int x, int y, int toX, int toY) { - debugC(9, kDebugLevelMain, "KyraEngine_v2::directLinePassable(%d, %d, %d, %d)", x, y, toX, toY); - while (x != toX && y != toY) { - int facing = getFacingFromPointToPoint(x, y, toX, toY); - x += _addXPosTable[facing]; - y += _addYPosTable[facing]; - if (!_screen->getShapeFlag1(x, y)) - return false; - } - return true; -} - -int KyraEngine_v2::pathfinderInitPositionTable(int *moveTable) { - debugC(9, kDebugLevelMain, "KyraEngine_v2::pathfinderInitPositionTable(%p)", (const void*)moveTable); - bool breakLoop = false; - int *moveTableCur = moveTable; - int oldEntry = *moveTableCur, curEntry = *moveTableCur; - int oldX = 0, newX = 0, oldY = 0, newY = 0; - int lastEntry = 0; - lastEntry = pathfinderAddToPositionTable(lastEntry, 0, 0); - - while (*moveTableCur != 8) { - oldEntry = curEntry; - - while (true) { - curEntry = *moveTableCur; - if (curEntry >= 0 && curEntry <= 7) - break; - - if (curEntry == 8) { - breakLoop = true; - break; - } else { - ++moveTableCur; - } - } - - if (breakLoop) - break; - - oldX = newX; - oldY = newY; - - newX += _addXPosTable[curEntry]; - newY += _addYPosTable[curEntry]; - - int temp = ABS(curEntry - oldEntry); - if (temp > 4) { - temp = 8 - temp; - } - - if (temp > 1 || oldEntry != curEntry) - lastEntry = pathfinderAddToPositionTable(lastEntry, oldX, oldY); - - ++moveTableCur; - } - - lastEntry = pathfinderAddToPositionTable(lastEntry, newX, newY); - _pathfinderPositionTable[lastEntry*2+0] = -1; - _pathfinderPositionTable[lastEntry*2+1] = -1; - return lastEntry; -} - -int KyraEngine_v2::pathfinderAddToPositionTable(int index, int v1, int v2) { - debugC(9, kDebugLevelMain, "KyraEngine_v2::pathfinderAddToPositionTable(%d, %d, %d)", index, v1, v2); - _pathfinderPositionTable[index<<1] = v1; - _pathfinderPositionTable[(index<<1)+1] = v2; - ++index; - if (index >= 199) - --index; - return index; -} - -int KyraEngine_v2::pathfinderInitPositionIndexTable(int tableLen, int x, int y) { - debugC(9, kDebugLevelMain, "KyraEngine_v2::pathfinderInitPositionIndexTable(%d, %d, %d)", tableLen, x, y); - int x1 = 0, y1 = 0; - int x2 = 0, y2 = 0; - int lastEntry = 0; - int index2 = tableLen-1, index1 = 0; - while (index2 > index1) { - x1 = _pathfinderPositionTable[index1*2+0] + x; - y1 = _pathfinderPositionTable[index1*2+1] + y; - x2 = _pathfinderPositionTable[index2*2+0] + x; - y2 = _pathfinderPositionTable[index2*2+1] + y; - - if (directLinePassable(x1, y1, x2, y2)) { - lastEntry = pathfinderAddToPositionIndexTable(lastEntry, index2); - if (tableLen-1 == index2) - break; - index1 = index2; - index2 = tableLen-1; - } else if (index1+1 == index2) { - lastEntry = pathfinderAddToPositionIndexTable(lastEntry, index2); - index1 = index2; - index2 = tableLen-1; - } else { - --index2; - } - } - return lastEntry; -} - -int KyraEngine_v2::pathfinderAddToPositionIndexTable(int index, int v) { - debugC(9, kDebugLevelMain, "KyraEngine_v2::pathfinderAddToPositionIndexTable(%d, %d)", index, v); - _pathfinderPositionIndexTable[index] = v; - ++index; - if (index >= 199) - --index; - return index; -} - -void KyraEngine_v2::pathfinderFinializePath(int *moveTable, int tableLen, int x, int y, int moveTableSize) { - debugC(9, kDebugLevelMain, "KyraEngine_v2::pathfinderFinializePath(%p, %d, %d, %d, %d)", (void *)moveTable, tableLen, x, y, moveTableSize); - int x1 = 0, y1 = 0; - int x2 = 0, y2 = 0; - int index1 = 0, index2 = 0; - int sizeLeft = moveTableSize; - for (int i = 0; i < tableLen; ++i) { - index2 = _pathfinderPositionIndexTable[i]; - x1 = _pathfinderPositionTable[index1*2+0] + x; - y1 = _pathfinderPositionTable[index1*2+1] + y; - x2 = _pathfinderPositionTable[index2*2+0] + x; - y2 = _pathfinderPositionTable[index2*2+1] + y; - - int wayLen = findWay(x1, y1, x2, y2, moveTable, sizeLeft); - moveTable += wayLen; - sizeLeft -= wayLen; // unlike the original we want to be sure that the size left is correct - index1 = index2; - } -} - -} // end of namespace Kyra diff --git a/engines/kyra/scene_v3.cpp b/engines/kyra/scene_v3.cpp deleted file mode 100644 index b74e9da22e..0000000000 --- a/engines/kyra/scene_v3.cpp +++ /dev/null @@ -1,918 +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_v3.h" -#include "kyra/screen_v3.h" -#include "kyra/wsamovie.h" -#include "kyra/sound.h" - -namespace Kyra { - -void KyraEngine_v3::enterNewScene(uint16 sceneId, int facing, int unk1, int unk2, int unk3) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::enterNewScene('%d, %d, %d, %d, %d)", sceneId, facing, unk1, unk2, unk3); - ++_enterNewSceneLock; - _screen->hideMouse(); - - showMessage(0, 0xF0, 0xF0); - if (_inventoryState) { - hideInventory(); - musicUpdate(0); - } - - musicUpdate(0); - if (_currentChapter != _currentTalkFile) { - _currentTalkFile = _currentChapter; - openTalkFile(_currentTalkFile); - } - musicUpdate(0); - - if (!unk3) { - //XXX - musicUpdate(0); - } - - if (unk1) { - int x = _mainCharacter.x1; - int y = _mainCharacter.y1; - - switch (facing) { - case 0: - y -= 6; - break; - - case 2: - x = 343; - break; - - case 4: - y = 191; - break; - - case 6: - x = -24; - break; - } - - musicUpdate(0); - moveCharacter(facing, x, y); - } - - musicUpdate(0); - uint32 waitUntilTimer = 0; - bool newSoundFile = false; - if (_lastMusicCommand != _sceneList[sceneId].sound) { - fadeOutMusic(60); - waitUntilTimer = _system->getMillis() + 60 * _tickLength; - newSoundFile = true; - } - - //XXX - - if (!unk3) { - _emc->init(&_sceneScriptState, &_sceneScriptData); - _emc->start(&_sceneScriptState, 5); - while (_emc->isValid(&_sceneScriptState)) { - _emc->run(&_sceneScriptState); - musicUpdate(0); - } - } - - musicUpdate(0); - - _specialExitCount = 0; - Common::set_to(_specialExitTable, _specialExitTable+ARRAYSIZE(_specialExitTable), 0xFFFF); - - musicUpdate(0); - - _mainCharacter.sceneId = sceneId; - _sceneList[sceneId].flags &= ~1; - musicUpdate(0); - unloadScene(); - musicUpdate(0); - - for (int i = 0; i < 4; ++i) { - if (i != _musicSoundChannel && i != _fadeOutMusicChannel) - _soundDigital->stopSound(i); - } - _fadeOutMusicChannel = -1; - musicUpdate(0); - loadScenePal(); - musicUpdate(0); - - if (queryGameFlag(0x1D9)) { - char filename[20]; - if (queryGameFlag(0x20D)) { - resetGameFlag(0x20D); - strcpy(filename, "COW1_"); - } else if (queryGameFlag(0x20E)) { - resetGameFlag(0x20E); - strcpy(filename, "COW2_"); - } else if (queryGameFlag(0x20F)) { - resetGameFlag(0x20F); - strcpy(filename, "COW3_"); - } else if (queryGameFlag(0x20C)) { - resetGameFlag(0x20C); - strcpy(filename, "BOAT"); - } else if (queryGameFlag(0x210)) { - resetGameFlag(0x210); - strcpy(filename, "JUNG"); - } - - playVQA(filename); - - resetGameFlag(0x1D9); - } - - musicUpdate(0); - loadSceneMsc(); - musicUpdate(0); - _sceneExit1 = _sceneList[sceneId].exit1; - _sceneExit2 = _sceneList[sceneId].exit2; - _sceneExit3 = _sceneList[sceneId].exit3; - _sceneExit4 = _sceneList[sceneId].exit4; - - while (_system->getMillis() < waitUntilTimer) - _system->delayMillis(10); - - musicUpdate(0); - initSceneScript(unk3); - musicUpdate(0); - - if (_overwriteSceneFacing) { - facing = _mainCharacter.facing; - _overwriteSceneFacing = false; - } - - enterNewSceneUnk1(facing, unk2, unk3); - musicUpdate(0); - setCommandLineRestoreTimer(-1); - _sceneScriptState.regs[3] = 1; - enterNewSceneUnk2(unk3); - if (queryGameFlag(0)) { - _showOutro = true; - _runFlag = false; - } else { - if (!--_enterNewSceneLock) - _unk5 = 0; - - setNextIdleAnimTimer(); - - if (_itemInHand < 0) { - _itemInHand = -1; - _handItemSet = -1; - _screen->setMouseCursor(0, 0, _gameShapes[0]); - } - - Common::Point pos = getMousePos(); - if (pos.y > 187) - setMousePos(pos.x, 179); - } - _screen->showMouse(); -} - -void KyraEngine_v3::enterNewSceneUnk1(int facing, int unk1, int unk2) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::enterNewSceneUnk1(%d, %d, %d)", facing, unk1, unk2); - int x = 0, y = 0; - int x2 = 0, y2 = 0; - bool needProc = true; - - if (_mainCharX == -1 && _mainCharY == -1) { - switch (facing+1) { - case 1: case 2: case 8: - x2 = _sceneEnterX3; - y2 = _sceneEnterY3; - break; - - case 3: - x2 = _sceneEnterX4; - y2 = _sceneEnterY4; - break; - - case 4: case 5: case 6: - x2 = _sceneEnterX1; - y2 = _sceneEnterY1; - break; - - case 7: - x2 = _sceneEnterX2; - y2 = _sceneEnterY2; - break; - - default: - x2 = y2 = -1; - break; - } - - if (x2 >= 316) - x2 = 312; - if (y2 >= 185) - y2 = 183; - if (x2 <= 4) - x2 = 8; - } - - if (_mainCharX >= 0) { - x = x2 = _mainCharX; - needProc = false; - } - - if (_mainCharY >= 0) { - y = y2 = _mainCharY; - needProc = false; - } - - _mainCharX = _mainCharY = -1; - - if (unk1 && needProc) { - x = x2; - y = y2; - - switch (facing) { - case 0: - y2 = 191; - break; - - case 2: - x2 = -24; - break; - - case 4: - y2 = y - 4; - break; - - case 6: - x2 = 343; - break; - - default: - break; - } - } - - x2 &= ~3; - x &= ~3; - y2 &= ~1; - y &= ~1; - - _mainCharacter.facing = facing; - _mainCharacter.x1 = _mainCharacter.x2 = x2; - _mainCharacter.y1 = _mainCharacter.y2 = y2; - initSceneAnims(unk2); - - if (_mainCharacter.sceneId == 9 && !_soundDigital->isPlaying(_musicSoundChannel)) - snd_playWanderScoreViaMap(_sceneList[_mainCharacter.sceneId].sound, 0); - if (!unk2) - snd_playWanderScoreViaMap(_sceneList[_mainCharacter.sceneId].sound, 0); - - if (unk1 && !unk2 && _mainCharacter.animFrame != 87) - moveCharacter(facing, x, y); -} - -void KyraEngine_v3::enterNewSceneUnk2(int unk1) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::enterNewSceneUnk2(%d)", unk1); - _unk3 = -1; - if (_mainCharX == -1 && _mainCharY == -1 && !unk1) { - _mainCharacter.animFrame = _characterFrameTable[_mainCharacter.facing]; - updateCharacterAnim(0); - refreshAnimObjectsIfNeed(); - } - - if (!unk1) { - runSceneScript4(0); - malcolmSceneStartupChat(); - } - - _unk4 = 0; - _unk3 = -1; -} - -void KyraEngine_v3::unloadScene() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::unloadScene()"); - delete [] _sceneStrings; - _sceneStrings = 0; - musicUpdate(0); - _emc->unload(&_sceneScriptData); - musicUpdate(0); - freeSceneShapes(); - musicUpdate(0); - freeSceneAnims(); - musicUpdate(0); -} - -void KyraEngine_v3::freeSceneShapes() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::freeSceneShapes()"); - for (uint i = 0; i < ARRAYSIZE(_sceneShapes); ++i) { - delete [] _sceneShapes[i]; - _sceneShapes[i] = 0; - } -} - -void KyraEngine_v3::freeSceneAnims() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::freeSceneAnims()"); - for (int i = 0; i < 16; ++i) { - _sceneAnims[i].flags = 0; - _sceneAnimMovie[i]->close(); - } -} - -void KyraEngine_v3::loadScenePal() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::loadScenePal()"); - char filename[16]; - memcpy(_screen->getPalette(2), _screen->getPalette(0), 768); - strcpy(filename, _sceneList[_mainCharacter.sceneId].filename1); - strcat(filename, ".COL"); - - _screen->loadBitmap(filename, 3, 3, 0); - memcpy(_screen->getPalette(2), _screen->getCPagePtr(3), 432); - memset(_screen->getPalette(2), 0, 3); - - for (int i = 144; i <= 167; ++i) { - uint8 *palette = _screen->getPalette(2) + i * 3; - palette[0] = palette[2] = 63; - palette[1] = 0; - } - - _screen->generateOverlay(_screen->getPalette(2), _paletteOverlay, 0xF0, 0x19); - - uint8 *palette = _screen->getPalette(2) + 432; - const uint8 *costPal = _costPalBuffer + _malcolmShapes * 72; - memcpy(palette, costPal, 24*3); -} - -void KyraEngine_v3::loadSceneMsc() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::loadSceneMsc()"); - char filename[16]; - strcpy(filename, _sceneList[_mainCharacter.sceneId].filename1); - strcat(filename, ".MSC"); - - _res->exists(filename, true); - Common::SeekableReadStream *stream = _res->getFileStream(filename); - assert(stream); - int16 minY = 0, height = 0; - minY = stream->readSint16LE(); - height = stream->readSint16LE(); - delete stream; - stream = 0; - musicUpdate(0); - _maskPageMinY = minY; - _maskPageMaxY = minY + height - 1; - - _screen->setShapePages(5, 3, _maskPageMinY, _maskPageMaxY); - - musicUpdate(0); - _screen->loadBitmap(filename, 5, 5, 0, true); - - // HACK - uint8 data[320*200]; - _screen->copyRegionToBuffer(5, 0, 0, 320, 200, data); - _screen->clearPage(5); - _screen->copyBlockToPage(5, 0, _maskPageMinY, 320, height, data); - - musicUpdate(0); -} - -void KyraEngine_v3::initSceneScript(int unk1) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::initSceneScript(%d)", unk1); - const SceneDesc &scene = _sceneList[_mainCharacter.sceneId]; - musicUpdate(0); - - char filename[16]; - strcpy(filename, scene.filename1); - strcat(filename, ".DAT"); - - _res->exists(filename, true); - Common::SeekableReadStream *stream = _res->getFileStream(filename); - assert(stream); - stream->seek(2, SEEK_CUR); - - byte scaleTable[15]; - stream->read(scaleTable, 15); - stream->read(_sceneDatPalette, 45); - stream->read(_sceneDatLayerTable, 15); - int16 shapesCount = stream->readSint16LE(); - - for (int i = 0; i < 15; ++i) - _scaleTable[i] = (uint16(scaleTable[i]) << 8) / 100; - - if (shapesCount > 0) { - strcpy(filename, scene.filename1); - strcat(filename, "9.CPS"); - musicUpdate(0); - _screen->loadBitmap(filename, 3, 3, 0); - int pageBackUp = _screen->_curPage; - _screen->_curPage = 2; - for (int i = 0; i < shapesCount; ++i) { - int16 x = stream->readSint16LE(); - int16 y = stream->readSint16LE(); - int16 w = stream->readSint16LE(); - int16 h = stream->readSint16LE(); - _sceneShapeDescs[i].drawX = stream->readSint16LE(); - _sceneShapeDescs[i].drawY = stream->readSint16LE(); - _sceneShapes[i] = _screen->encodeShape(x, y, w, h, 0); - assert(_sceneShapes[i]); - musicUpdate(0); - } - _screen->_curPage = pageBackUp; - musicUpdate(0); - } - musicUpdate(0); - - strcpy(filename, scene.filename1); - strcat(filename, ".CPS"); - _screen->loadBitmap(filename, 3, 3, 0); - musicUpdate(0); - - Common::set_to(_specialSceneScriptState, _specialSceneScriptState+ARRAYSIZE(_specialSceneScriptState), false); - _sceneEnterX1 = 160; - _sceneEnterY1 = 0; - _sceneEnterX2 = 296; - _sceneEnterY2 = 93; - _sceneEnterX3 = 160; - _sceneEnterY3 = 171; - _sceneEnterX4 = 24; - _sceneEnterY4 = 93; - _sceneMinX = 0; - _sceneMaxX = 319; - - _emc->init(&_sceneScriptState, &_sceneScriptData); - strcpy(filename, scene.filename2); - strcat(filename, ".EMC"); - musicUpdate(0); - _res->exists(filename, true); - _emc->load(filename, &_sceneScriptData, &_opcodes); - - strcpy(filename, scene.filename2); - strcat(filename, "."); - loadLanguageFile(filename, _sceneStrings); - musicUpdate(0); - - runSceneScript8(); - _emc->start(&_sceneScriptState, 0); - _sceneScriptState.regs[0] = _mainCharacter.sceneId; - _sceneScriptState.regs[5] = unk1; - while (_emc->isValid(&_sceneScriptState)) - _emc->run(&_sceneScriptState); - - _screen->copyRegionToBuffer(3, 0, 0, 320, 200, _gamePlayBuffer); - musicUpdate(0); - - for (int i = 0; i < 10; ++i) { - _emc->init(&_sceneSpecialScripts[i], &_sceneScriptData); - _emc->start(&_sceneSpecialScripts[i], i+9); - musicUpdate(0); - _sceneSpecialScriptsTimer[i] = 0; - } - - _sceneEnterX1 &= ~3; - _sceneEnterY1 &= ~1; - _sceneEnterX2 &= ~3; - _sceneEnterY2 &= ~1; - _sceneEnterX3 &= ~3; - _sceneEnterY3 &= ~1; - _sceneEnterX4 &= ~3; - _sceneEnterY4 &= ~1; - musicUpdate(0); -} - -void KyraEngine_v3::initSceneAnims(int unk1) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::initSceneAnims(%d)", unk1); - for (int i = 0; i < 67; ++i) - _animObjects[i].enabled = false; - - AnimObj *obj = &_animObjects[0]; - - if (_mainCharacter.animFrame != 87 && !unk1) - _mainCharacter.animFrame = _characterFrameTable[_mainCharacter.facing]; - - obj->enabled = true; - obj->xPos1 = _mainCharacter.x1; - obj->yPos1 = _mainCharacter.y1; - obj->shapePtr = getShapePtr(_mainCharacter.animFrame); - obj->shapeIndex2 = obj->shapeIndex = _mainCharacter.animFrame; - obj->xPos2 = _mainCharacter.x1; - obj->yPos2 = _mainCharacter.y1; - _charScale = getScale(_mainCharacter.x1, _mainCharacter.y1); - obj->xPos3 = obj->xPos2 += (_malcolmShapeXOffset * _charScale) >> 8; - obj->yPos3 = obj->yPos2 += (_malcolmShapeYOffset * _charScale) >> 8; - _mainCharacter.x3 = _mainCharacter.x1 - (_charScale >> 4) - 1; - _mainCharacter.y3 = _mainCharacter.y1 - (_charScale >> 6) - 1; - obj->needRefresh = true; - _animList = 0; - - for (int i = 0; i < 16; ++i) { - const SceneAnim &anim = _sceneAnims[i]; - obj = &_animObjects[i+1]; - obj->enabled = false; - obj->needRefresh = false; - - if (anim.flags & 1) { - obj->enabled = true; - obj->needRefresh = true; - } - - obj->unk8 = (anim.flags & 0x20) ? 1 : 0; - obj->flags = (anim.flags & 0x10) ? 0x800 : 0; - if (anim.flags & 2) - obj->flags |= 1; - - obj->xPos1 = anim.x; - obj->yPos1 = anim.y; - - if ((anim.flags & 4) && anim.shapeIndex != 0xFFFF) - obj->shapePtr = _sceneShapes[anim.shapeIndex]; - else - obj->shapePtr = 0; - - if (anim.flags & 8) { - obj->shapeIndex3 = anim.shapeIndex; - obj->animNum = i; - } else { - obj->shapeIndex3 = 0xFFFF; - obj->animNum = 0xFFFF; - } - - obj->xPos3 = obj->xPos2 = anim.x2; - obj->yPos3 = obj->yPos2 = anim.y2; - obj->width = anim.width; - obj->height = anim.height; - obj->width2 = obj->height2 = anim.specialSize; - - if (anim.flags & 1) { - if (_animList) - _animList = addToAnimListSorted(_animList, obj); - else - _animList = initAnimList(_animList, obj); - } - } - - if (_animList) - _animList = addToAnimListSorted(_animList, &_animObjects[0]); - else - _animList = initAnimList(_animList, &_animObjects[0]); - - for (int i = 0; i < 50; ++i) { - obj = &_animObjects[i+17]; - const Item &item = _itemList[i]; - if (item.id != 0xFFFF && item.sceneId == _mainCharacter.sceneId) { - obj->xPos1 = item.x; - obj->yPos1 = item.y; - animSetupPaletteEntry(obj); - obj->shapePtr = 0; - obj->shapeIndex = obj->shapeIndex2 = item.id + 248; - obj->xPos2 = item.x; - obj->yPos2 = item.y; - - int scale = getScale(obj->xPos1, obj->yPos1); - const uint8 *shape = getShapePtr(obj->shapeIndex); - obj->xPos3 = obj->xPos2 -= (_screen->getShapeScaledWidth(shape, scale) >> 1); - obj->yPos3 = obj->yPos2 -= _screen->getShapeScaledHeight(shape, scale) - 1; - obj->enabled = true; - obj->needRefresh = true; - - if (_animList) - _animList = addToAnimListSorted(_animList, obj); - else - _animList = initAnimList(_animList, obj); - } else { - obj->enabled = false; - obj->needRefresh = false; - } - } - - for (int i = 0; i < 67; ++i) - _animObjects[i].needRefresh = _animObjects[i].enabled; - - restorePage3(); - drawAnimObjects(); - _screen->hideMouse(); - initSceneScreen(unk1); - _screen->showMouse(); - refreshAnimObjects(0); -} - -void KyraEngine_v3::initSceneScreen(int unk1) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::initSceneScreen(%d)", unk1); - _screen->copyBlockToPage(2, 0, 188, 320, 12, _interfaceCommandLine); - - if (_unkSceneScreenFlag1) { - _screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0, Screen::CR_NO_P_CHECK); - return; - } - - if (_noScriptEnter) { - memset(_screen->getPalette(0), 0, 432); - if (!_wsaPlayingVQA) - _screen->setScreenPalette(_screen->getPalette(0)); - } - - _screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0, Screen::CR_NO_P_CHECK); - - if (_noScriptEnter) { - if (!_wsaPlayingVQA) - _screen->setScreenPalette(_screen->getPalette(2)); - memcpy(_screen->getPalette(0), _screen->getPalette(2), 432); - if (_wsaPlayingVQA) { - _screen->fadeFromBlack(0x3C); - _wsaPlayingVQA = false; - } - } - - updateCharPal(0); - - if (1/*!_menuDirectlyToLoad*/) { - _emc->start(&_sceneScriptState, 3); - _sceneScriptState.regs[5] = unk1; - - while (_emc->isValid(&_sceneScriptState)) - _emc->run(&_sceneScriptState); - } -} - -void KyraEngine_v3::updateSpecialSceneScripts() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::updateSpecialSceneScripts()"); - uint32 nextTime = _system->getMillis() + _tickLength; - const int startScript = _lastProcessedSceneScript; - - while (_system->getMillis() <= nextTime) { - if (_sceneSpecialScriptsTimer[_lastProcessedSceneScript] <= _system->getMillis() && - !_specialSceneScriptState[_lastProcessedSceneScript]) { - _specialSceneScriptRunFlag = true; - - while (_specialSceneScriptRunFlag && _sceneSpecialScriptsTimer[_lastProcessedSceneScript] <= _system->getMillis()) { - if (!_emc->run(&_sceneSpecialScripts[_lastProcessedSceneScript])) - _specialSceneScriptRunFlag = false; - } - } - - if (!_emc->isValid(&_sceneSpecialScripts[_lastProcessedSceneScript])) { - _emc->start(&_sceneSpecialScripts[_lastProcessedSceneScript], 9+_lastProcessedSceneScript); - _specialSceneScriptRunFlag = false; - } - - ++_lastProcessedSceneScript; - if (_lastProcessedSceneScript >= 10) - _lastProcessedSceneScript = 0; - - if (_lastProcessedSceneScript == startScript) - return; - } -} - -int KyraEngine_v3::trySceneChange(int *moveTable, int unk1, int updateChar) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::trySceneChange(%p, %d, %d)", (const void*)moveTable, unk1, updateChar); - bool running = true; - bool unkFlag = false; - int changedScene = 0; - const int *moveTableStart = moveTable; - _unk4 = 0; - - while (running && !_quitFlag) { - if (*moveTable >= 0 && *moveTable <= 7) { - _mainCharacter.facing = getOppositeFacingDirection(*moveTable); - unkFlag = true; - } else { - if (*moveTable == 8) { - running = false; - } else { - ++moveTable; - unkFlag = false; - } - } - - if (checkSceneChange()) { - running = false; - changedScene = 1; - } - - if (unk1) { - if (skipFlag()) { - resetSkipFlag(false); - running = false; - _unk4 = 1; - } - } - - if (!unkFlag || !running) - continue; - - int ret = 0; - if (moveTable == moveTableStart || moveTable[1] == 8) - ret = updateCharPos(0, 0); - else - ret = updateCharPos(moveTable, 0); - - if (ret) - ++moveTable; - - update(); - } - - if (updateChar) - _mainCharacter.animFrame = _characterFrameTable[_mainCharacter.facing]; - - updateCharacterAnim(0); - refreshAnimObjectsIfNeed(); - - return changedScene; -} - -int KyraEngine_v3::checkSceneChange() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::checkSceneChange()"); - const SceneDesc &curScene = _sceneList[_mainCharacter.sceneId]; - int charX = _mainCharacter.x1, charY = _mainCharacter.y1; - int facing = 0; - int process = 0; - - if (_screen->getLayer(charX, charY) == 1 && _unk3 == -7) { - facing = 0; - process = 1; - } else if (charX >= 316 && _unk3 == -6) { - facing = 2; - process = 1; - } else if (charY >= 186 && _unk3 == -5) { - facing = 4; - process = 1; - } else if (charX <= 4 && _unk3 == -4) { - facing = 6; - process = 1; - } - - if (!process) - return 0; - - uint16 newScene = 0xFFFF; - switch (facing) { - case 0: - newScene = curScene.exit1; - break; - - case 2: - newScene = curScene.exit2; - break; - - case 4: - newScene = curScene.exit3; - break; - - case 6: - newScene = curScene.exit4; - break; - - default: - newScene = _mainCharacter.sceneId; - break; - } - - if (newScene == 0xFFFF) - return 0; - - enterNewScene(newScene, facing, 1, 1, 0); - return 1; -} -int KyraEngine_v3::runSceneScript1(int x, int y) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::runSceneScript1(%d, %d)", x, y); - if (y > 187 && _unk3 > -4) - return 0; - if (_deathHandler >= 0) - return 0; - - _emc->init(&_sceneScriptState, &_sceneScriptData); - _sceneScriptState.regs[1] = x; - _sceneScriptState.regs[2] = y; - _sceneScriptState.regs[3] = 0; - _sceneScriptState.regs[4] = _itemInHand; - - _emc->start(&_sceneScriptState, 1); - while (_emc->isValid(&_sceneScriptState)) - _emc->run(&_sceneScriptState); - - return _sceneScriptState.regs[3]; -} - -int KyraEngine_v3::runSceneScript2() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::runSceneScript2()"); - _sceneScriptState.regs[1] = _mouseX; - _sceneScriptState.regs[2] = _mouseY; - _sceneScriptState.regs[3] = 0; - _sceneScriptState.regs[4] = _itemInHand; - - _emc->start(&_sceneScriptState, 2); - while (_emc->isValid(&_sceneScriptState)) - _emc->run(&_sceneScriptState); - - return _sceneScriptState.regs[3]; -} - -void KyraEngine_v3::runSceneScript4(int unk1) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::runSceneScript4(%d)", unk1); - _sceneScriptState.regs[4] = _itemInHand; - _sceneScriptState.regs[5] = unk1; - _sceneScriptState.regs[3] = 0; - _noStartupChat = false; - - _emc->start(&_sceneScriptState, 4); - while (_emc->isValid(&_sceneScriptState)) - _emc->run(&_sceneScriptState); - - if (_sceneScriptState.regs[3]) - _noStartupChat = true; -} - -void KyraEngine_v3::runSceneScript6() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::runSceneScript6()"); - _emc->init(&_sceneScriptState, &_sceneScriptData); - - _sceneScriptState.regs[0] = _mainCharacter.sceneId; - _sceneScriptState.regs[1] = _mouseX; - _sceneScriptState.regs[2] = _mouseY; - _sceneScriptState.regs[3] = _itemInHand; - - _emc->start(&_sceneScriptState, 6); - while (_emc->isValid(&_sceneScriptState)) - _emc->run(&_sceneScriptState); -} - -void KyraEngine_v3::runSceneScript8() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::runSceneScript8()"); - _emc->start(&_sceneScriptState, 8); - while (_emc->isValid(&_sceneScriptState)) { - musicUpdate(0); - _emc->run(&_sceneScriptState); - } -} - -bool KyraEngine_v3::checkSpecialSceneExit(int index, int x, int y) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::checkSpecialSceneExit(%d, %d, %d)", index, x, y); - if (_specialExitTable[index] < x && _specialExitTable[5+index] < y && - _specialExitTable[10+index] > x && _specialExitTable[15+index] > y) - return true; - - return false; -} - -int KyraEngine_v3::findWay(int x, int y, int toX, int toY, int *moveTable, int moveTableSize) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::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_v3::lineIsPassable(int x, int y) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::lineIsPassable(%d, %d)", x, y); - static const uint8 widthTable[] = { 1, 1, 1, 1, 1, 2, 4, 6, 8 }; - - if ((_pathfinderFlag & 2) && x >= 320) - return false; - if ((_pathfinderFlag & 4) && y >= 188) - return false; - if ((_pathfinderFlag & 8) && x < 0) - return false; - if (y > 187) - return false; - - uint width = widthTable[getScale(x, y) >> 5]; - - if (y < 0) - y = 0; - x -= width >> 1; - if (x < 0) - x = 0; - int x2 = x + width; - if (x2 > 320) - x2 = 320; - - for (; x < x2; ++x) { - if (y < _maskPageMinY || y > _maskPageMaxY) - return false; - - if (!_screen->getShapeFlag1(x, y)) - return false; - } - - return true; -} - -} // end of namespace Kyra diff --git a/engines/kyra/screen.cpp b/engines/kyra/screen.cpp index de0c079293..298483465e 100644 --- a/engines/kyra/screen.cpp +++ b/engines/kyra/screen.cpp @@ -3112,305 +3112,5 @@ void Screen::drawCharSJIS(uint16 c, int x, int y) { #pragma mark - -uint8 *ScreenEx::generateOverlay(const uint8 *palette, uint8 *buffer, int startColor, uint16 factor) { - if (!palette || !buffer) - return buffer; - - factor = MIN(255, factor); - factor >>= 1; - factor &= 0xFF; - - const byte col1 = palette[startColor * 3 + 0]; - const byte col2 = palette[startColor * 3 + 1]; - const byte col3 = palette[startColor * 3 + 2]; - - uint8 *dst = buffer; - *dst++ = 0; - - for (int i = 1; i != 255; ++i) { - uint8 processedPalette[3]; - const uint8 *src = palette + i*3; - byte col; - - col = *src++; - col -= ((((col - col1) * factor) << 1) >> 8) & 0xFF; - processedPalette[0] = col; - - col = *src++; - col -= ((((col - col2) * factor) << 1) >> 8) & 0xFF; - processedPalette[1] = col; - - col = *src++; - col -= ((((col - col3) * factor) << 1) >> 8) & 0xFF; - processedPalette[2] = col; - - *dst++ = findLeastDifferentColor(processedPalette, palette+3, 255)+1; - } - - return buffer; -} - -void ScreenEx::applyOverlay(int x, int y, int w, int h, int pageNum, const uint8 *overlay) { - if (pageNum == 0 || pageNum == 1) - addDirtyRect(x, y, w, h); - - uint8 *dst = getPagePtr(pageNum) + y * 320 + x; - while (h--) { - for (int wi = 0; wi < w; ++wi) { - uint8 index = *dst; - *dst++ = overlay[index]; - } - dst += 320 - w; - } -} - -int ScreenEx::findLeastDifferentColor(const uint8 *paletteEntry, const uint8 *palette, uint16 numColors) { - int m = 0x7fff; - int r = 0x101; - - for (int i = 0; i < numColors; i++) { - int v = paletteEntry[0] - *palette++; - int c = v * v; - v = paletteEntry[1] - *palette++; - c += (v * v); - v = paletteEntry[2] - *palette++; - c += (v * v); - - if (c <= m) { - m = c; - r = i; - } - } - - return r; -} - -void ScreenEx::copyWsaRect(int x, int y, int w, int h, int dimState, int plotFunc, const uint8 *src, - int unk1, const uint8 *unkPtr1, const uint8 *unkPtr2) { - uint8 *dstPtr = getPagePtr(_curPage); - uint8 *origDst = dstPtr; - - const ScreenDim *dim = getScreenDim(dimState); - int dimX1 = dim->sx << 3; - int dimX2 = dim->w << 3; - dimX2 += dimX1; - - int dimY1 = dim->sy; - int dimY2 = dim->h; - dimY2 += dimY1; - - int temp = y - dimY1; - if (temp < 0) { - if ((temp += h) <= 0) - return; - else { - SWAP(temp, h); - y += temp - h; - src += (temp - h) * w; - } - } - - temp = dimY2 - y; - if (temp <= 0) - return; - - if (temp < h) - h = temp; - - int srcOffset = 0; - temp = x - dimX1; - if (temp < 0) { - temp = -temp; - srcOffset = temp; - x += temp; - w -= temp; - } - - int srcAdd = 0; - - temp = dimX2 - x; - if (temp <= 0) - return; - - if (temp < w) { - SWAP(w, temp); - temp -= w; - srcAdd = temp; - } - - dstPtr += y * SCREEN_W + x; - uint8 *dst = dstPtr; - - if (_curPage == 0 || _curPage == 1) - addDirtyRect(x, y, w, h); - - clearOverlayRect(_curPage, x, y, w, h); - - temp = h; - int curY = y; - while (h--) { - src += srcOffset; - ++curY; - int cW = w; - - switch (plotFunc) { - case 0: - memcpy(dst, src, cW); - dst += cW; src += cW; - break; - - case 1: - while (cW--) { - uint8 d = *src++; - uint8 t = unkPtr1[d]; - if (t != 0xFF) - d = unkPtr2[*dst + (t << 8)]; - *dst++ = d; - } - break; - - case 4: - while (cW--) { - uint8 d = *src++; - if (d) - *dst = d; - ++dst; - } - break; - - case 5: - while (cW--) { - uint8 d = *src++; - if (d) { - uint8 t = unkPtr1[d]; - if (t != 0xFF) - d = unkPtr2[*dst + (t << 8)]; - *dst = d; - } - ++dst; - } - break; - - case 8: - case 9: - while (cW--) { - uint8 d = *src++; - uint8 t = _shapePages[0][dst - origDst] & 7; - if (unk1 < t && (curY > _maskMinY && curY < _maskMaxY)) - d = _shapePages[1][dst - origDst]; - *dst++ = d; - } - break; - - case 12: - case 13: - while (cW--) { - uint8 d = *src++; - if (d) { - uint8 t = _shapePages[0][dst - origDst] & 7; - if (unk1 < t && (curY > _maskMinY && curY < _maskMaxY)) - d = _shapePages[1][dst - origDst]; - *dst++ = d; - } else { - d = _shapePages[1][dst - origDst]; - *dst++ = d; - } - } - break; - - default: - break; - } - - dst = (dstPtr += SCREEN_W); - src += srcAdd; - } -} - -const uint8 *ScreenEx::getPtrToShape(const uint8 *shpFile, int shape) { - debugC(9, kDebugLevelScreen, "ScreenEx::getPtrToShape(%p, %d)", (const void *)shpFile, shape); - uint16 shapes = READ_LE_UINT16(shpFile); - - if (shapes <= shape) - return 0; - - uint32 offset = READ_LE_UINT32(shpFile + (shape << 2) + 2); - - return shpFile + offset + 2; -} - -uint8 *ScreenEx::getPtrToShape(uint8 *shpFile, int shape) { - debugC(9, kDebugLevelScreen, "ScreenEx::getPtrToShape(%p, %d)", (void *)shpFile, shape); - uint16 shapes = READ_LE_UINT16(shpFile); - - if (shapes <= shape) - return 0; - - uint32 offset = READ_LE_UINT32(shpFile + (shape << 2) + 2); - - return shpFile + offset + 2; -} - -int ScreenEx::getShapeScaledWidth(const uint8 *shpFile, int scale) { - int width = READ_LE_UINT16(shpFile+3); - return (width * scale) >> 8; -} - -int ScreenEx::getShapeScaledHeight(const uint8 *shpFile, int scale) { - int height = shpFile[2]; - return (height * scale) >> 8; -} - -uint16 ScreenEx::getShapeSize(const uint8 *shp) { - debugC(9, kDebugLevelScreen, "ScreenEx::getShapeSize(%p)", (const void *)shp); - - return READ_LE_UINT16(shp+6); -} - -uint8 *ScreenEx::makeShapeCopy(const uint8 *src, int index) { - debugC(9, kDebugLevelScreen, "ScreenEx::makeShapeCopy(%p, %d)", (const void *)src, index); - - const uint8 *shape = getPtrToShape(src, index); - int size = getShapeSize(shape); - - uint8 *copy = new uint8[size]; - assert(copy); - memcpy(copy, shape, size); - - return copy; -} - -int ScreenEx::getLayer(int x, int y) { - if (x < 0) - x = 0; - else if (x >= 320) - x = 319; - if (y < 0) - y = 0; - else if (y >= 144) - y = 143; - - uint8 pixel = *(getCPagePtr(5) + y * 320 + x); - pixel &= 0x7F; - pixel >>= 3; - - if (pixel < 1) - pixel = 1; - else if (pixel > 15) - pixel = 15; - return pixel; -} - -int ScreenEx::getRectSize(int w, int h) { - if (w > 320 || h > 200) - return 0; - return w*h; -} - -void ScreenEx::setTextColorMap(const uint8 *cmap) { - debugC(9, kDebugLevelScreen, "ScreenEx::setTextColorMap(%p)", (const void *)cmap); - setTextColor(cmap, 0, 15); -} - } // End of namespace Kyra diff --git a/engines/kyra/screen.h b/engines/kyra/screen.h index 5e806b36fc..bf23747daf 100644 --- a/engines/kyra/screen.h +++ b/engines/kyra/screen.h @@ -358,41 +358,6 @@ protected: bool _debugEnabled; }; -class ScreenEx : public Screen { -public: - ScreenEx(KyraEngine *vm, OSystem *system) : Screen(vm, system) {} - - // screen page handling - void copyWsaRect(int x, int y, int w, int h, int dimState, int plotFunc, const uint8 *src, - int unk1, const uint8 *unkPtr1, const uint8 *unkPtr2); - - // palette handling - uint8 *generateOverlay(const uint8 *palette, uint8 *buffer, int color, uint16 factor); - void applyOverlay(int x, int y, int w, int h, int pageNum, const uint8 *overlay); - int findLeastDifferentColor(const uint8 *paletteEntry, const uint8 *palette, uint16 numColors); - - // shape handling - uint8 *getPtrToShape(uint8 *shpFile, int shape); - const uint8 *getPtrToShape(const uint8 *shpFile, int shape); - - int getShapeScaledWidth(const uint8 *shpFile, int scale); - int getShapeScaledHeight(const uint8 *shpFile, int scale); - - uint16 getShapeSize(const uint8 *shp); - - uint8 *makeShapeCopy(const uint8 *src, int index); - - // rect handling - int getRectSize(int w, int h); - - // text display - void setTextColorMap(const uint8 *cmap); - - // layer handling - virtual int getLayer(int x, int y); -protected: -}; - } // End of namespace Kyra #endif diff --git a/engines/kyra/screen_hof.cpp b/engines/kyra/screen_hof.cpp new file mode 100644 index 0000000000..9192626159 --- /dev/null +++ b/engines/kyra/screen_hof.cpp @@ -0,0 +1,279 @@ +/* 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_hof.h" +#include "kyra/screen_hof.h" + +namespace Kyra { + +Screen_HoF::Screen_HoF(KyraEngine_HoF *vm, OSystem *system) + : Screen_v2(vm, system) { + _vm = vm; + _wsaFrameAnimBuffer = new uint8[1024]; +} + +Screen_HoF::~Screen_HoF() { + delete [] _wsaFrameAnimBuffer; +} + +void Screen_HoF::setScreenDim(int dim) { + debugC(9, kDebugLevelScreen, "Screen_HoF::setScreenDim(%d)", dim); + assert(dim < _screenDimTableCount); + _curDim = &_screenDimTable[dim]; +} + +const ScreenDim *Screen_HoF::getScreenDim(int dim) { + debugC(9, kDebugLevelScreen, "Screen_HoF::getScreenDim(%d)", dim); + assert(dim < _screenDimTableCount); + return &_screenDimTable[dim]; +} + +void Screen_HoF::generateGrayOverlay(const uint8 *srcPal, uint8 *grayOverlay, int factor, int addR, int addG, int addB, int lastColor, bool flag) { + uint8 tmpPal[768]; + + for (int i = 0; i != lastColor; i++) { + if (flag) { + int v = ((((srcPal[3 * i] & 0x3f) + (srcPal[3 * i + 1] & 0x3f) + + (srcPal[3 * i + 2] & 0x3f)) / 3) * factor) / 0x40; + tmpPal[3 * i] = tmpPal[3 * i + 1] = tmpPal[3 * i + 2] = v & 0xff; + } else { + int v = (((srcPal[3 * i] & 0x3f) * factor) / 0x40) + addR; + tmpPal[3 * i] = (v > 0x3f) ? 0x3f : v & 0xff; + v = (((srcPal[3 * i + 1] & 0x3f) * factor) / 0x40) + addG; + tmpPal[3 * i + 1] = (v > 0x3f) ? 0x3f : v & 0xff; + v = (((srcPal[3 * i + 2] & 0x3f) * factor) / 0x40) + addB; + tmpPal[3 * i + 2] = (v > 0x3f) ? 0x3f : v & 0xff; + } + } + + for (int i = 0; i < lastColor; i++) + grayOverlay[i] = findLeastDifferentColor(tmpPal + 3 * i, srcPal, lastColor); +} + +void Screen_HoF::wsaFrameAnimationStep(int x1, int y1, int x2, int y2, + int w1, int h1, int w2, int h2, int srcPage, int dstPage, int dim) { + + if (!(w1 || h1 || w2 || h2)) + return; + + ScreenDim cdm = _screenDimTable[dim]; + cdm.sx <<= 3; + cdm.w <<= 3; + + int na = 0, nb = 0, nc = w2; + + if (!calcBounds(cdm.w, cdm.h, x2, y2, w2, h2, na, nb, nc)) + return; + + const uint8 *src = getPagePtr(srcPage) + y1 * 320; + uint8 *dst = getPagePtr(dstPage) + (y2 + cdm.sy) * 320; + + int u = -1; + + do { + int t = (nb * h1) / h2; + if (t != u) { + u = t; + const uint8 *s = src + (x1 + t) * 320; + uint8 *dt = (uint8*) _wsaFrameAnimBuffer; + + t = w2 - w1; + if (!t) { + memcpy(dt, s, w2); + } else if (t > 0) { + if (w1 == 1) { + memset(dt, *s, w2); + } else { + t = ((((((w2 - w1 + 1) & 0xffff) << 8) / w1) + 0x100) & 0xffff) << 8; + int bp = 0; + for (int i = 0; i < w1; i++) { + int cnt = (t >> 16); + bp += (t & 0xffff); + if (bp > 0xffff) { + bp -= 0xffff; + cnt++; + } + memset(dt, *s++, cnt); + dt += cnt; + } + } + } else { + if (w2 == 1) { + *dt = *s; + } else { + t = (((((w1 - w2) & 0xffff) << 8) / w2) & 0xffff) << 8; + int bp = 0; + for (int i = 0; i < w2; i++) { + *dt++ = *s++; + bp += (t & 0xffff); + if (bp > 0xffff) { + bp -= 0xffff; + s++; + } + s += (t >> 16); + } + } + } + } + memcpy(dst + x2 + cdm.sx, _wsaFrameAnimBuffer + na, w2); + dst += 320; + } while (++nb < h2); +} + +void Screen_HoF::cmpFadeFrameStep(int srcPage, int srcW, int srcH, int srcX, int srcY, int dstPage, int dstW, + int dstH, int dstX, int dstY, int cmpW, int cmpH, int cmpPage) { + + if (!(cmpW || cmpH )) + return; + + int r1, r2, r3, r4, r5, r6; + + int X1 = srcX; + int Y1 = srcY; + int W1 = cmpW; + int H1 = cmpH; + + if (!calcBounds(srcW, srcH, X1, Y1, W1, H1, r1, r2, r3)) + return; + + int X2 = dstX; + int Y2 = dstY; + int W2 = W1; + int H2 = H1; + + if (!calcBounds(dstW, dstH, X2, Y2, W2, H2, r4, r5, r6)) + return; + + const uint8 *src = getPagePtr(srcPage) + srcW * (Y1 + r5); + uint8 *dst = getPagePtr(dstPage) + dstW * (Y2 + r2); + const uint8 *cmp = getPagePtr(cmpPage); + + while (H2--) { + const uint8 *s = src + r4 + X1; + uint8 *d = dst + r1 + X2; + + for (int i = 0; i < W2; i++) { + int ix = (*s++ << 8) + *d; + *d++ = cmp[ix]; + } + + src += W1; + dst += W2; + } +} + +void Screen_HoF::copyPageMemory(int srcPage, int srcPos, int dstPage, int dstPos, int numBytes) { + const uint8 *src = getPagePtr(srcPage) + srcPos; + uint8 *dst = getPagePtr(dstPage) + dstPos; + memcpy(dst, src, numBytes); +} + + +void Screen_HoF::copyRegionEx(int srcPage, int srcW, int srcH, int dstPage, int dstX,int dstY, int dstW, int dstH, const ScreenDim *dim, bool flag) { + int x0 = dim->sx << 3; + int y0 = dim->sy; + int w0 = dim->w << 3; + int h0 = dim->h; + + int x1 = dstX; + int y1 = dstY; + int w1 = dstW; + int h1 = dstH; + + int x2, y2, w2; + + calcBounds(w0, h0, x1, y1, w1, h1, x2, y2, w2); + + const uint8 *src = getPagePtr(srcPage) + (320 * srcH) + srcW; + uint8 *dst = getPagePtr(dstPage) + 320 * (y0 + y1); + + for (int y = 0; y < h1; y++) { + const uint8 *s = src + x2; + uint8 *d = dst + x0 + x1; + + if (flag) + d += (h1 >> 1); + + for (int x = 0; x < w1; x++) { + if (*s) + *d = *s; + s++; + d++; + } + dst += 320; + src += 320; + } +} + +bool Screen_HoF::calcBounds(int w0, int h0, int &x1, int &y1, int &w1, int &h1, int &x2, int &y2, int &w2) { + x2 = 0; + y2 = 0; + w2 = w1; + + int t = x1 + w1; + if (t < 1) { + w1 = h1 = -1; + } else { + if (t <= x1) { + x2 = w1 - t; + w1 = t; + x1 = 0; + } + t = w0 - x1; + if (t < 1) { + w1 = h1 = -1; + } else { + if (t <= w1) { + w1 = t; + } + w2 -= w1; + t = h1 + y1; + if (t < 1) { + w1 = h1 = -1; + } else { + if (t <= y1) { + y2 = h1 - t; + h1 = t; + y1 = 0; + } + t = h0 - y1; + if (t < 1) { + w1 = h1 = -1; + } else { + if (t <= h1) { + h1 = t; + } + } + } + } + } + + return (w1 == -1) ? false : true; +} + +} // end of namespace Kyra + diff --git a/engines/kyra/screen_hof.h b/engines/kyra/screen_hof.h new file mode 100644 index 0000000000..a6df749538 --- /dev/null +++ b/engines/kyra/screen_hof.h @@ -0,0 +1,63 @@ +/* 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_HOF_H +#define KYRA_SCREEN_HOF_H + +#include "kyra/screen_v2.h" + +namespace Kyra { + +class KyraEngine_HoF; + +class Screen_HoF : public Screen_v2 { +friend class Debugger_v2; +public: + Screen_HoF(KyraEngine_HoF *vm, OSystem *system); + ~Screen_HoF(); + + void setScreenDim(int dim); + const ScreenDim *getScreenDim(int dim); + + // sequence player + void generateGrayOverlay(const uint8 *srcPal, uint8 *grayOverlay, int factor, int addR, int addG, int addB, int lastColor, bool flag); + bool calcBounds(int w0, int h0, int &x1, int &y1, int &w1, int &h1, int &x2, int &y2, int &w2); + void wsaFrameAnimationStep(int x1, int y1, int x2, int y2, int w1, int h1, int w2, int h2, int srcPage, int dstPage, int dim); + void cmpFadeFrameStep(int srcPage, int srcW, int srcH, int srcX, int srcY, int dstPage, int dstW, int dstH, int dstX, int dstY, int cmpW, int cmpH, int cmpPage); + void copyPageMemory(int srcPage, int srcPos, int dstPage, int dstPos, int numBytes); + void copyRegionEx(int srcPage, int srcW, int srcH, int dstPage, int dstX,int dstY, int dstW, int dstH, const ScreenDim *d, bool flag = false); +private: + KyraEngine_HoF *_vm; + + static const ScreenDim _screenDimTable[]; + static const int _screenDimTableCount; + + uint8 *_wsaFrameAnimBuffer; +}; + +} // End of namespace Kyra + +#endif + diff --git a/engines/kyra/screen_mr.cpp b/engines/kyra/screen_mr.cpp new file mode 100644 index 0000000000..0fcfe00879 --- /dev/null +++ b/engines/kyra/screen_mr.cpp @@ -0,0 +1,138 @@ +/* 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/screen_mr.h" + +#include "kyra/kyra_mr.h" + +namespace Kyra { + +Screen_MR::Screen_MR(KyraEngine_MR *vm, OSystem *system) : Screen_v2(vm, system) { +} + +Screen_MR::~Screen_MR() { +} + +void Screen_MR::setScreenDim(int dim) { + debugC(9, kDebugLevelScreen, "Screen_MR::setScreenDim(%d)", dim); + assert(dim < _screenDimTableCount); + _curDim = &_screenDimTable[dim]; +} + +const ScreenDim *Screen_MR::getScreenDim(int dim) { + debugC(9, kDebugLevelScreen, "Screen_MR::getScreenDim(%d)", dim); + assert(dim < _screenDimTableCount); + return &_screenDimTable[dim]; +} + +int Screen_MR::getLayer(int x, int y) { + debugC(9, kDebugLevelScreen, "Screen_MR::getLayer(%d, %d)", x, y); + if (x < 0) + x = 0; + else if (x >= 320) + x = 319; + if (y < 0) + y = 0; + else if (y >= 188) + y = 187; + + if (y < _maskMinY || y > _maskMaxY) + return 15; + + uint8 pixel = *(getCPagePtr(5) + y * 320 + x); + pixel &= 0x7F; + pixel >>= 3; + + if (pixel < 1) + pixel = 1; + else if (pixel > 15) + pixel = 15; + return pixel; +} + +byte Screen_MR::getShapeFlag1(int x, int y) { + debugC(9, kDebugLevelScreen, "Screen_MR::getShapeFlag1(%d, %d)", x, y); + if (y < _maskMinY || y > _maskMaxY) + return 0; + + uint8 color = _shapePages[0][y * SCREEN_W + x]; + color &= 0x80; + color ^= 0x80; + + if (color & 0x80) + return 1; + return 0; +} + +byte Screen_MR::getShapeFlag2(int x, int y) { + debugC(9, kDebugLevelScreen, "Screen_MR::getShapeFlag2(%d, %d)", x, y); + if (y < _maskMinY || y > _maskMaxY) + return 0; + + uint8 color = _shapePages[0][y * SCREEN_W + x]; + color &= 0x7F; + color &= 0x87; + return color; +} + +int Screen_MR::getDrawLayer(int x, int y) { + debugC(9, kDebugLevelScreen, "Screen_MR::getDrawLayer(%d, %d)", x, y); + int xpos = x - 8; + int ypos = y; + int layer = 1; + + for (int curX = xpos; curX < xpos + 24; ++curX) { + int tempLayer = getShapeFlag2(curX, ypos); + + if (layer < tempLayer) + layer = tempLayer; + + if (layer >= 7) + return 7; + } + return layer; +} + +int Screen_MR::getDrawLayer2(int x, int y, int height) { + debugC(9, kDebugLevelScreen, "Screen_MR::getDrawLayer2(%d, %d, %d)", x, y, height); + int xpos = x - 8; + int ypos = y; + int layer = 1; + + for (int useX = xpos; useX < xpos + 24; ++useX) { + for (int useY = ypos - height; useY < ypos; ++useY) { + int tempLayer = getShapeFlag2(useX, useY); + + if (tempLayer > layer) + layer = tempLayer; + + if (tempLayer >= 7) + return 7; + } + } + return layer; +} + +} // end of namespace Kyra diff --git a/engines/kyra/screen_mr.h b/engines/kyra/screen_mr.h new file mode 100644 index 0000000000..fe3ae2a930 --- /dev/null +++ b/engines/kyra/screen_mr.h @@ -0,0 +1,57 @@ +/* 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_MR_H +#define KYRA_SCREEN_MR_H + +#include "kyra/screen_v2.h" + +namespace Kyra { + +class KyraEngine_MR; + +class Screen_MR : public Screen_v2 { +public: + Screen_MR(KyraEngine_MR *vm, OSystem *system); + ~Screen_MR(); + + void setScreenDim(int dim); + const ScreenDim *getScreenDim(int dim); + + int getLayer(int x, int y); + + byte getShapeFlag1(int x, int y); + byte getShapeFlag2(int x, int y); + + int getDrawLayer(int x, int y); + int getDrawLayer2(int x, int y, int height); +private: + static const ScreenDim _screenDimTable[]; + static const int _screenDimTableCount; +}; + +} // end of namespace Kyra + +#endif diff --git a/engines/kyra/screen_v2.cpp b/engines/kyra/screen_v2.cpp deleted file mode 100644 index f3eb840ca2..0000000000 --- a/engines/kyra/screen_v2.cpp +++ /dev/null @@ -1,279 +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_v2.h" -#include "kyra/screen_v2.h" - -namespace Kyra { - -Screen_v2::Screen_v2(KyraEngine_v2 *vm, OSystem *system) - : ScreenEx(vm, system) { - _vm = vm; - _wsaFrameAnimBuffer = new uint8[1024]; -} - -Screen_v2::~Screen_v2() { - delete [] _wsaFrameAnimBuffer; -} - -void Screen_v2::setScreenDim(int dim) { - debugC(9, kDebugLevelScreen, "Screen_v2::setScreenDim(%d)", dim); - assert(dim < _screenDimTableCount); - _curDim = &_screenDimTable[dim]; -} - -const ScreenDim *Screen_v2::getScreenDim(int dim) { - debugC(9, kDebugLevelScreen, "Screen_v2::getScreenDim(%d)", dim); - assert(dim < _screenDimTableCount); - return &_screenDimTable[dim]; -} - -void Screen_v2::generateGrayOverlay(const uint8 *srcPal, uint8 *grayOverlay, int factor, int addR, int addG, int addB, int lastColor, bool flag) { - uint8 tmpPal[768]; - - for (int i = 0; i != lastColor; i++) { - if (flag) { - int v = ((((srcPal[3 * i] & 0x3f) + (srcPal[3 * i + 1] & 0x3f) - + (srcPal[3 * i + 2] & 0x3f)) / 3) * factor) / 0x40; - tmpPal[3 * i] = tmpPal[3 * i + 1] = tmpPal[3 * i + 2] = v & 0xff; - } else { - int v = (((srcPal[3 * i] & 0x3f) * factor) / 0x40) + addR; - tmpPal[3 * i] = (v > 0x3f) ? 0x3f : v & 0xff; - v = (((srcPal[3 * i + 1] & 0x3f) * factor) / 0x40) + addG; - tmpPal[3 * i + 1] = (v > 0x3f) ? 0x3f : v & 0xff; - v = (((srcPal[3 * i + 2] & 0x3f) * factor) / 0x40) + addB; - tmpPal[3 * i + 2] = (v > 0x3f) ? 0x3f : v & 0xff; - } - } - - for (int i = 0; i < lastColor; i++) - grayOverlay[i] = findLeastDifferentColor(tmpPal + 3 * i, srcPal, lastColor); -} - -void Screen_v2::wsaFrameAnimationStep(int x1, int y1, int x2, int y2, - int w1, int h1, int w2, int h2, int srcPage, int dstPage, int dim) { - - if (!(w1 || h1 || w2 || h2)) - return; - - ScreenDim cdm = _screenDimTable[dim]; - cdm.sx <<= 3; - cdm.w <<= 3; - - int na = 0, nb = 0, nc = w2; - - if (!calcBounds(cdm.w, cdm.h, x2, y2, w2, h2, na, nb, nc)) - return; - - const uint8 *src = getPagePtr(srcPage) + y1 * 320; - uint8 *dst = getPagePtr(dstPage) + (y2 + cdm.sy) * 320; - - int u = -1; - - do { - int t = (nb * h1) / h2; - if (t != u) { - u = t; - const uint8 *s = src + (x1 + t) * 320; - uint8 *dt = (uint8*) _wsaFrameAnimBuffer; - - t = w2 - w1; - if (!t) { - memcpy(dt, s, w2); - } else if (t > 0) { - if (w1 == 1) { - memset(dt, *s, w2); - } else { - t = ((((((w2 - w1 + 1) & 0xffff) << 8) / w1) + 0x100) & 0xffff) << 8; - int bp = 0; - for (int i = 0; i < w1; i++) { - int cnt = (t >> 16); - bp += (t & 0xffff); - if (bp > 0xffff) { - bp -= 0xffff; - cnt++; - } - memset(dt, *s++, cnt); - dt += cnt; - } - } - } else { - if (w2 == 1) { - *dt = *s; - } else { - t = (((((w1 - w2) & 0xffff) << 8) / w2) & 0xffff) << 8; - int bp = 0; - for (int i = 0; i < w2; i++) { - *dt++ = *s++; - bp += (t & 0xffff); - if (bp > 0xffff) { - bp -= 0xffff; - s++; - } - s += (t >> 16); - } - } - } - } - memcpy(dst + x2 + cdm.sx, _wsaFrameAnimBuffer + na, w2); - dst += 320; - } while (++nb < h2); -} - -void Screen_v2::cmpFadeFrameStep(int srcPage, int srcW, int srcH, int srcX, int srcY, int dstPage, int dstW, - int dstH, int dstX, int dstY, int cmpW, int cmpH, int cmpPage) { - - if (!(cmpW || cmpH )) - return; - - int r1, r2, r3, r4, r5, r6; - - int X1 = srcX; - int Y1 = srcY; - int W1 = cmpW; - int H1 = cmpH; - - if (!calcBounds(srcW, srcH, X1, Y1, W1, H1, r1, r2, r3)) - return; - - int X2 = dstX; - int Y2 = dstY; - int W2 = W1; - int H2 = H1; - - if (!calcBounds(dstW, dstH, X2, Y2, W2, H2, r4, r5, r6)) - return; - - const uint8 *src = getPagePtr(srcPage) + srcW * (Y1 + r5); - uint8 *dst = getPagePtr(dstPage) + dstW * (Y2 + r2); - const uint8 *cmp = getPagePtr(cmpPage); - - while (H2--) { - const uint8 *s = src + r4 + X1; - uint8 *d = dst + r1 + X2; - - for (int i = 0; i < W2; i++) { - int ix = (*s++ << 8) + *d; - *d++ = cmp[ix]; - } - - src += W1; - dst += W2; - } -} - -void Screen_v2::copyPageMemory(int srcPage, int srcPos, int dstPage, int dstPos, int numBytes) { - const uint8 *src = getPagePtr(srcPage) + srcPos; - uint8 *dst = getPagePtr(dstPage) + dstPos; - memcpy(dst, src, numBytes); -} - - -void Screen_v2::copyRegionEx(int srcPage, int srcW, int srcH, int dstPage, int dstX,int dstY, int dstW, int dstH, const ScreenDim *dim, bool flag) { - int x0 = dim->sx << 3; - int y0 = dim->sy; - int w0 = dim->w << 3; - int h0 = dim->h; - - int x1 = dstX; - int y1 = dstY; - int w1 = dstW; - int h1 = dstH; - - int x2, y2, w2; - - calcBounds(w0, h0, x1, y1, w1, h1, x2, y2, w2); - - const uint8 *src = getPagePtr(srcPage) + (320 * srcH) + srcW; - uint8 *dst = getPagePtr(dstPage) + 320 * (y0 + y1); - - for (int y = 0; y < h1; y++) { - const uint8 *s = src + x2; - uint8 *d = dst + x0 + x1; - - if (flag) - d += (h1 >> 1); - - for (int x = 0; x < w1; x++) { - if (*s) - *d = *s; - s++; - d++; - } - dst += 320; - src += 320; - } -} - -bool Screen_v2::calcBounds(int w0, int h0, int &x1, int &y1, int &w1, int &h1, int &x2, int &y2, int &w2) { - x2 = 0; - y2 = 0; - w2 = w1; - - int t = x1 + w1; - if (t < 1) { - w1 = h1 = -1; - } else { - if (t <= x1) { - x2 = w1 - t; - w1 = t; - x1 = 0; - } - t = w0 - x1; - if (t < 1) { - w1 = h1 = -1; - } else { - if (t <= w1) { - w1 = t; - } - w2 -= w1; - t = h1 + y1; - if (t < 1) { - w1 = h1 = -1; - } else { - if (t <= y1) { - y2 = h1 - t; - h1 = t; - y1 = 0; - } - t = h0 - y1; - if (t < 1) { - w1 = h1 = -1; - } else { - if (t <= h1) { - h1 = t; - } - } - } - } - } - - return (w1 == -1) ? false : true; -} - -} // end of namespace Kyra - diff --git a/engines/kyra/screen_v2.h b/engines/kyra/screen_v2.h deleted file mode 100644 index 665f71ace4..0000000000 --- a/engines/kyra/screen_v2.h +++ /dev/null @@ -1,62 +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_V2_H -#define KYRA_SCREEN_V2_H - -#include "kyra/screen.h" - -namespace Kyra { - -class KyraEngine_v2; - -class Screen_v2 : public ScreenEx { -friend class Debugger_v2; -public: - Screen_v2(KyraEngine_v2 *vm, OSystem *system); - virtual ~Screen_v2(); - - virtual void setScreenDim(int dim); - virtual const ScreenDim *getScreenDim(int dim); - - // sequence player - void generateGrayOverlay(const uint8 *srcPal, uint8 *grayOverlay, int factor, int addR, int addG, int addB, int lastColor, bool flag); - bool calcBounds(int w0, int h0, int &x1, int &y1, int &w1, int &h1, int &x2, int &y2, int &w2); - void wsaFrameAnimationStep(int x1, int y1, int x2, int y2, int w1, int h1, int w2, int h2, int srcPage, int dstPage, int dim); - void cmpFadeFrameStep(int srcPage, int srcW, int srcH, int srcX, int srcY, int dstPage, int dstW, int dstH, int dstX, int dstY, int cmpW, int cmpH, int cmpPage); - void copyPageMemory(int srcPage, int srcPos, int dstPage, int dstPos, int numBytes); - void copyRegionEx(int srcPage, int srcW, int srcH, int dstPage, int dstX,int dstY, int dstW, int dstH, const ScreenDim *d, bool flag = false); -private: - KyraEngine_v2 *_vm; - - static const ScreenDim _screenDimTable[]; - static const int _screenDimTableCount; - - uint8 *_wsaFrameAnimBuffer; -}; - -} // End of namespace Kyra - -#endif diff --git a/engines/kyra/screen_v3.cpp b/engines/kyra/screen_v3.cpp deleted file mode 100644 index 938307b774..0000000000 --- a/engines/kyra/screen_v3.cpp +++ /dev/null @@ -1,138 +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/screen_v3.h" - -#include "kyra/kyra_v3.h" - -namespace Kyra { - -Screen_v3::Screen_v3(KyraEngine_v3 *vm, OSystem *system) : ScreenEx(vm, system) { -} - -Screen_v3::~Screen_v3() { -} - -void Screen_v3::setScreenDim(int dim) { - debugC(9, kDebugLevelScreen, "Screen_v3::setScreenDim(%d)", dim); - assert(dim < _screenDimTableCount); - _curDim = &_screenDimTable[dim]; -} - -const ScreenDim *Screen_v3::getScreenDim(int dim) { - debugC(9, kDebugLevelScreen, "Screen_v3::getScreenDim(%d)", dim); - assert(dim < _screenDimTableCount); - return &_screenDimTable[dim]; -} - -int Screen_v3::getLayer(int x, int y) { - debugC(9, kDebugLevelScreen, "Screen_v3::getLayer(%d, %d)", x, y); - if (x < 0) - x = 0; - else if (x >= 320) - x = 319; - if (y < 0) - y = 0; - else if (y >= 188) - y = 187; - - if (y < _maskMinY || y > _maskMaxY) - return 15; - - uint8 pixel = *(getCPagePtr(5) + y * 320 + x); - pixel &= 0x7F; - pixel >>= 3; - - if (pixel < 1) - pixel = 1; - else if (pixel > 15) - pixel = 15; - return pixel; -} - -byte Screen_v3::getShapeFlag1(int x, int y) { - debugC(9, kDebugLevelScreen, "Screen_v3::getShapeFlag1(%d, %d)", x, y); - if (y < _maskMinY || y > _maskMaxY) - return 0; - - uint8 color = _shapePages[0][y * SCREEN_W + x]; - color &= 0x80; - color ^= 0x80; - - if (color & 0x80) - return 1; - return 0; -} - -byte Screen_v3::getShapeFlag2(int x, int y) { - debugC(9, kDebugLevelScreen, "Screen_v3::getShapeFlag2(%d, %d)", x, y); - if (y < _maskMinY || y > _maskMaxY) - return 0; - - uint8 color = _shapePages[0][y * SCREEN_W + x]; - color &= 0x7F; - color &= 0x87; - return color; -} - -int Screen_v3::getDrawLayer(int x, int y) { - debugC(9, kDebugLevelScreen, "Screen_v3::getDrawLayer(%d, %d)", x, y); - int xpos = x - 8; - int ypos = y; - int layer = 1; - - for (int curX = xpos; curX < xpos + 24; ++curX) { - int tempLayer = getShapeFlag2(curX, ypos); - - if (layer < tempLayer) - layer = tempLayer; - - if (layer >= 7) - return 7; - } - return layer; -} - -int Screen_v3::getDrawLayer2(int x, int y, int height) { - debugC(9, kDebugLevelScreen, "Screen_v3::getDrawLayer2(%d, %d, %d)", x, y, height); - int xpos = x - 8; - int ypos = y; - int layer = 1; - - for (int useX = xpos; useX < xpos + 24; ++useX) { - for (int useY = ypos - height; useY < ypos; ++useY) { - int tempLayer = getShapeFlag2(useX, useY); - - if (tempLayer > layer) - layer = tempLayer; - - if (tempLayer >= 7) - return 7; - } - } - return layer; -} - -} // end of namespace Kyra diff --git a/engines/kyra/screen_v3.h b/engines/kyra/screen_v3.h deleted file mode 100644 index dc49268ad6..0000000000 --- a/engines/kyra/screen_v3.h +++ /dev/null @@ -1,57 +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_V3_H -#define KYRA_SCREEN_V3_H - -#include "kyra/screen.h" - -namespace Kyra { - -class KyraEngine_v3; - -class Screen_v3 : public ScreenEx { -public: - Screen_v3(KyraEngine_v3 *vm, OSystem *system); - virtual ~Screen_v3(); - - virtual void setScreenDim(int dim); - virtual const ScreenDim *getScreenDim(int dim); - - int getLayer(int x, int y); - - byte getShapeFlag1(int x, int y); - byte getShapeFlag2(int x, int y); - - int getDrawLayer(int x, int y); - int getDrawLayer2(int x, int y, int height); -private: - static const ScreenDim _screenDimTable[]; - static const int _screenDimTableCount; -}; - -} // end of namespace Kyra - -#endif diff --git a/engines/kyra/script_hof.cpp b/engines/kyra/script_hof.cpp new file mode 100644 index 0000000000..25c1499df6 --- /dev/null +++ b/engines/kyra/script_hof.cpp @@ -0,0 +1,2131 @@ +/* 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_hof.h" +#include "kyra/text_hof.h" +#include "kyra/wsamovie.h" +#include "kyra/sound.h" +#include "kyra/timer.h" +#include "kyra/script_tim.h" +#include "kyra/resource.h" + +#include "common/endian.h" + +namespace Kyra { + +int KyraEngine_HoF::o2_setCharacterFacingRefresh(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_setCharacterFacingRefresh(%p) (-, %d, %d)", (const void *)script, stackPos(1), stackPos(2)); + int animFrame = stackPos(2); + if (animFrame >= 0) + _mainCharacter.animFrame = animFrame; + _mainCharacter.facing = stackPos(1); + updateCharacterAnim(0); + refreshAnimObjectsIfNeed(); + return 0; +} + +int KyraEngine_HoF::o2_setCharacterPos(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_setCharacterFacingRefresh(%p) (-, %d, %d)", (const void *)script, stackPos(1), stackPos(2)); + int x = stackPos(1); + int y = stackPos(2); + + if (x != -1 && y != -1) { + x &= ~3; + y &= ~1; + } + + restorePage3(); + _mainCharacter.x2 = _mainCharacter.x1 = x; + _mainCharacter.y2 = _mainCharacter.y1 = y; + return 0; +} + +int KyraEngine_HoF::o2_defineObject(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_defineObject(%p) (%d, '%s', %d, %d, %d, %d)", (const void *)script, + stackPos(0), stackPosString(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5)); + TalkObject *object = &_talkObjectList[stackPos(0)]; + strcpy(object->filename, stackPosString(1)); + object->scriptId = stackPos(2); + object->x = stackPos(3); + object->y = stackPos(4); + object->color = stackPos(5); + return 0; +} + +int KyraEngine_HoF::o2_refreshCharacter(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_refreshCharacter(%p) (-, %d, %d, %d)", (const void *)script, stackPos(1), stackPos(2), stackPos(3)); + int unk = stackPos(1); + int facing = stackPos(2); + int refresh = stackPos(3); + if (facing >= 0) + _mainCharacter.facing = facing; + if (unk >= 0 && unk != 32) + _mainCharacter.animFrame = _characterFrameTable[_mainCharacter.facing]; + updateCharacterAnim(0); + if (refresh) + refreshAnimObjectsIfNeed(); + return 0; +} + +int KyraEngine_HoF::o2_getCharacterX(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_getCharacterX(%p) ()", (const void *)script); + return _mainCharacter.x1; +} + +int KyraEngine_HoF::o2_getCharacterY(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_getCharacterY(%p) ()", (const void *)script); + return _mainCharacter.y1; +} + +int KyraEngine_HoF::o2_getCharacterFacing(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_getCharacterFacing(%p) ()", (const void *)script); + return _mainCharacter.facing; +} + +int KyraEngine_HoF::o2_getCharacterScene(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_getCharacterScene(%p) ()", (const void *)script); + return _mainCharacter.sceneId; +} + +int KyraEngine_HoF::o2_setSceneComment(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_setSceneComment(%p) ('%s')", (const void *)script, stackPosString(0)); + _sceneCommentString = stackPosString(0); + return 0; +} + +int KyraEngine_HoF::o2_setCharacterAnimFrame(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_setCharacterAnimFrame(%p) (-, %d, %d)", (const void *)script, stackPos(1), stackPos(2)); + int animFrame = stackPos(1); + int updateAnim = stackPos(2); + + _mainCharacter.animFrame = animFrame; + if (updateAnim) + updateCharacterAnim(0); + + return 0; +} + +int KyraEngine_HoF::o2_setCharacterFacing(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_setCharacterFacing(%p) (%d)", (const void *)script, stackPos(0)); + _mainCharacter.facing = stackPos(0); + _overwriteSceneFacing = 1; + return 0; +} + +int KyraEngine_HoF::o2_trySceneChange(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_trySceneChange(%p) (%d, %d, %d, %d)", (const void *)script, + stackPos(0), stackPos(1), stackPos(2), stackPos(3)); + + _unkHandleSceneChangeFlag = 1; + int success = inputSceneChange(stackPos(0), stackPos(1), stackPos(2), stackPos(3)); + _unkHandleSceneChangeFlag = 0; + + if (success) { + _emc->init(script, script->dataPtr); + _unk4 = 0; + _unk3 = -1; + _unk5 = 1; + return 0; + } else { + return (_unk4 != 0) ? 1 : 0; + } +} + +int KyraEngine_HoF::o2_moveCharacter(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_moveCharacter(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); + moveCharacter(stackPos(0), stackPos(1), stackPos(2)); + return 0; +} + +int KyraEngine_HoF::o2_customCharacterChat(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_customCharacterChat(%p) ('%s', %d, %d, %d, %d)", (const void *)script, stackPosString(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); + playVoice(_vocHigh, stackPos(4)); + _text->printCustomCharacterText(stackPosString(0), stackPos(1), stackPos(2), stackPos(3), 0, 2); + return 0; +} + +int KyraEngine_HoF::o2_soundFadeOut(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_soundFadeOut(%p) ()", (const void *)script); + _sound->beginFadeOut(); + return 0; +} + +int KyraEngine_HoF::o2_showChapterMessage(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_showChapterMessage(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + showChapterMessage(stackPos(0), stackPos(1)); + return 0; +} + +int KyraEngine_HoF::o2_restoreTalkTextMessageBkgd(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_restoreTalkTextMessageBkgd(%p) ()", (const void *)script); + _text->restoreTalkTextMessageBkgd(2, 0); + return 0; +} + +int KyraEngine_HoF::o2_wsaClose(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_wsaClose(%p) (%d)", (const void *)script, stackPos(0)); + assert(stackPos(0) >= 0 && stackPos(0) < ARRAYSIZE(_wsaSlots)); + _wsaSlots[stackPos(0)]->close(); + return 0; +} + +int KyraEngine_HoF::o2_meanWhileScene(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_meanWhileScene(%p) (%d)", (const void *)script, stackPos(0)); + static const uint8 jpSubtitle[] = { 0x88, 0xEA, 0x95, 0xFB, 0x81, 0x45, 0x81, 0x45, 0x81, 0x45 }; + const char *cpsfile = stackPosString(0); + const char *palfile = stackPosString(1); + + _screen->loadBitmap(cpsfile, 3, 3, 0); + memcpy(_screen->getPalette(2), _screen->_currentPalette, 768); + _screen->loadPalette(palfile, _screen->getPalette(2)); + _screen->fillRect(0, 0, 319, 199, 207); + _screen->setScreenPalette(_screen->getPalette(2)); + _screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0); + if (!scumm_stricmp(cpsfile, "_MEANWIL.CPS") && _flags.lang == Common::JA_JPN) { + Screen::FontId o = _screen->setFont(Screen::FID_6_FNT); + _screen->printText((const char*)jpSubtitle, 140, 176, 255, 132); + _screen->setFont(o); + } + _screen->updateScreen(); + return 0; +} + +int KyraEngine_HoF::o2_backUpScreen(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_backUpScreen(%p) (%d)", (const void *)script, stackPos(0)); + _screen->copyRegionToBuffer(stackPos(0), 0, 0, 320, 144, _screenBuffer); + return 0; +} + +int KyraEngine_HoF::o2_restoreScreen(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_restoreScreen(%p) (%d)", (const void *)script, stackPos(0)); + _screen->copyBlockToPage(stackPos(0), 0, 0, 320, 144, _screenBuffer); + return 0; +} + +int KyraEngine_HoF::o2_displayWsaFrame(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_displayWsaFrame(%p) (%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)); + int frame = stackPos(0); + int x = stackPos(1); + int y = stackPos(2); + int waitTime = stackPos(3); + int slot = stackPos(4); + int copyParam = stackPos(5); + int doUpdate = stackPos(6); + int dstPage = stackPos(7); + int backUp = stackPos(8); + + _screen->hideMouse(); + uint32 endTime = _system->getMillis() + waitTime * _tickLength; + _wsaSlots[slot]->setX(x); + _wsaSlots[slot]->setY(y); + _wsaSlots[slot]->setDrawPage(dstPage); + _wsaSlots[slot]->displayFrame(frame, copyParam | 0xC000, 0, 0); + _screen->updateScreen(); + + if (backUp) + memcpy(_gamePlayBuffer, _screen->getCPagePtr(3), 46080); + + while (_system->getMillis() < endTime) { + if (doUpdate) + update(); + + if (endTime - _system->getMillis() >= 10) + delay(10); + } + _screen->showMouse(); + return 0; +} + +int KyraEngine_HoF::o2_displayWsaSequentialFramesLooping(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_displayWsaSequentialFramesLooping(%p) (%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)); + int startFrame = stackPos(0); + int endFrame = stackPos(1); + int x = stackPos(2); + int y = stackPos(3); + int waitTime = stackPos(4); + int slot = stackPos(5); + int maxTimes = stackPos(6); + int copyFlags = stackPos(7); + + if (maxTimes > 1) + maxTimes = 1; + + _wsaSlots[slot]->setX(x); + _wsaSlots[slot]->setY(y); + _wsaSlots[slot]->setDrawPage(0); + + _screen->hideMouse(); + int curTime = 0; + while (curTime < maxTimes) { + if (startFrame < endFrame) { + for (int i = startFrame; i <= endFrame; ++i) { + uint32 endTime = _system->getMillis() + waitTime * _tickLength; + _wsaSlots[slot]->displayFrame(i, 0xC000 | copyFlags, 0, 0); + + if (!skipFlag()) { + _screen->updateScreen(); + + do { + update(); + + if (endTime - _system->getMillis() >= 10) + delay(10); + } while (_system->getMillis() < endTime); + } + } + } else { + for (int i = startFrame; i >= endFrame; --i) { + uint32 endTime = _system->getMillis() + waitTime * _tickLength; + _wsaSlots[slot]->displayFrame(i, 0xC000 | copyFlags, 0, 0); + + if (!skipFlag()) { + _screen->updateScreen(); + + do { + update(); + + if (endTime - _system->getMillis() >= 10 && !skipFlag()) + delay(10); + } while (_system->getMillis() < endTime && !skipFlag()); + } + } + } + + ++curTime; + } + resetSkipFlag(); + _screen->showMouse(); + return 0; +} + +int KyraEngine_HoF::o2_wsaOpen(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_wsaOpen(%p) ('%s', %d)", (const void *)script, stackPosString(0), stackPos(1)); + assert(stackPos(1) >= 0 && stackPos(1) < ARRAYSIZE(_wsaSlots)); + _wsaSlots[stackPos(1)]->open(stackPosString(0), 1, 0); + return 0; +} + +int KyraEngine_HoF::o2_displayWsaSequentialFrames(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_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)); + + uint16 frameDelay = stackPos(2) * _tickLength; + uint16 currentFrame = stackPos(3); + uint16 lastFrame = stackPos(4); + uint16 index = stackPos(5); + uint16 copyParam = stackPos(6) | 0xc000; + + _wsaSlots[index]->setX(stackPos(0)); + _wsaSlots[index]->setY(stackPos(1)); + _wsaSlots[index]->setDrawPage(0); + + _screen->hideMouse(); + + while (currentFrame <= lastFrame) { + uint32 endTime = _system->getMillis() + frameDelay; + _wsaSlots[index]->displayFrame(currentFrame++, copyParam, 0, 0); + if (!skipFlag()) { + _screen->updateScreen(); + delayUntil(endTime); + } + } + + resetSkipFlag(); + _screen->showMouse(); + + return 0; +} + +int KyraEngine_HoF::o2_displayWsaSequence(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_displayWsaSequence(%p) (%d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5)); + + const int frameDelay = stackPos(2) * _tickLength; + const int index = stackPos(3); + const bool doUpdate = (stackPos(4) != 0); + const uint16 copyParam = stackPos(5) | 0xc000; + + _wsaSlots[index]->setX(stackPos(0)); + _wsaSlots[index]->setY(stackPos(1)); + _wsaSlots[index]->setDrawPage(0); + + _screen->hideMouse(); + + int currentFrame = 0; + const int lastFrame = _wsaSlots[index]->frames(); + + while (currentFrame <= lastFrame) { + uint32 endTime = _system->getMillis() + frameDelay; + _wsaSlots[index]->displayFrame(currentFrame++, copyParam, 0, 0); + if (!skipFlag()) { + if (doUpdate) + update(); + _screen->updateScreen(); + delayUntil(endTime); + } + } + + resetSkipFlag(); + _screen->showMouse(); + + return 0; +} + +int KyraEngine_HoF::o2_addItemToInventory(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_addItemToInventory(%p) (%d, -, %d)", (const void *)script, stackPos(0), stackPos(2)); + int slot = findFreeVisibleInventorySlot(); + if (slot != -1) { + _mainCharacter.inventory[slot] = stackPos(0); + if (stackPos(2)) + redrawInventory(0); + } + return slot; +} + +int KyraEngine_HoF::o2_drawShape(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_drawShape(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); + + uint8 *shp = getShapePtr(stackPos(0) + 64); + int x = stackPos(1); + int y = stackPos(2); + uint8 dsFlag = stackPos(3) & 0xff; + uint8 modeFlag = stackPos(4) & 0xff; + + if (modeFlag) { + _screen->drawShape(2, shp, x, y, 2, dsFlag ? 1 : 0); + } else { + _screen->hideMouse(); + restorePage3(); + _screen->drawShape(2, shp, x, y, 2, dsFlag ? 1 : 0); + memcpy(_gamePlayBuffer, _screen->getCPagePtr(3), 46080); + _screen->drawShape(0, shp, x, y, 2, dsFlag ? 1 : 0); + + flagAnimObjsForRefresh(); + flagAnimObjsSpecialRefresh(); + refreshAnimObjectsIfNeed(); + _screen->showMouse(); + } + + return 0; +} + +int KyraEngine_HoF::o2_addItemToCurScene(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_addItemToCurScene(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); + const int16 id = stackPos(0); + int x = stackPos(1); + int y = stackPos(2); + + int freeItem = findFreeItem(); + x = MAX(14, x); + x = MIN(304, x); + y = MAX(14, y); + y = MIN(136, y); + if (freeItem >= 0) { + _itemList[freeItem].id = id; + _itemList[freeItem].x = x; + _itemList[freeItem].y = y; + _itemList[freeItem].sceneId = _mainCharacter.sceneId; + addItemToAnimList(freeItem); + refreshAnimObjectsIfNeed(); + } + return 0; +} + +int KyraEngine_HoF::o2_checkForItem(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_checkForItem(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + return findItem(stackPos(0), stackPos(1)) == -1 ? 0 : 1; +} + +int KyraEngine_HoF::o2_loadSoundFile(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_loadSoundFile(%p) (%d)", (const void *)script, stackPos(0)); + if (_sound->hasSoundFile(stackPos(0))) + snd_playTheme(stackPos(0), -1); + return 0; +} + +int KyraEngine_HoF::o2_removeItemSlotFromInventory(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_removeItemSlotFromInventory(%p) (%d)", (const void *)script, stackPos(0)); + removeItemFromInventory(stackPos(0)); + return 0; +} + +int KyraEngine_HoF::o2_defineItem(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_defineItem(%p) (%d, %d, %d, %d)", (const void *)script, + stackPos(0), stackPos(1), stackPos(2), stackPos(3)); + int freeItem = findFreeItem(); + + if (freeItem >= 0) { + _itemList[freeItem].id = stackPos(0); + _itemList[freeItem].x = stackPos(1); + _itemList[freeItem].y = stackPos(2); + _itemList[freeItem].sceneId = stackPos(3); + } + + return freeItem; +} + +int KyraEngine_HoF::o2_removeItemFromInventory(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_removeItemFromInventory(%p) (%d)", (const void *)script, stackPos(0)); + uint16 item = stackPos(0); + int slot = -1; + while ((slot = getInventoryItemSlot(item)) != -1) + removeItemFromInventory(slot); + return 0; +} + +int KyraEngine_HoF::o2_countItemInInventory(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_countItemInInventory(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + uint16 item = stackPos(1); + int count = 0; + + for (int i = 0; i < 20; ++i) { + if (_mainCharacter.inventory[i] == item) + ++count; + } + + if ((stackPos(0) == 0) && _itemInHand == int16(item)) + ++count; + + return count; +} + +int KyraEngine_HoF::o2_countItemsInScene(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_countItemsInScene(%p) (%d)", (const void *)script, stackPos(0)); + int count = 0; + for (int i = 0; i < 30; ++i) { + if (_itemList[i].sceneId == stackPos(0) && _itemList[i].id != 0xFFFF) + ++count; + } + return count; +} + +int KyraEngine_HoF::o2_queryGameFlag(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_queryGameFlag(%p) (%d)", (const void *)script, stackPos(0)); + return queryGameFlag(stackPos(0)); +} + +int KyraEngine_HoF::o2_resetGameFlag(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_resetGameFlag(%p) (%d)", (const void *)script, stackPos(0)); + return resetGameFlag(stackPos(0)); +} + +int KyraEngine_HoF::o2_setGameFlag(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_setGameFlag(%p) (%d)", (const void *)script, stackPos(0)); + return setGameFlag(stackPos(0)); +} + +int KyraEngine_HoF::o2_setHandItem(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_setHandItem(%p) (%d)", (const void *)script, stackPos(0)); + setHandItem(stackPos(0)); + return 0; +} + +int KyraEngine_HoF::o2_removeHandItem(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_removeHandItem(%p) ()", (const void *)script); + removeHandItem(); + return 0; +} + +int KyraEngine_HoF::o2_handItemSet(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_handItemSet(%p) ()", (const void *)script); + return _handItemSet; +} + +int KyraEngine_HoF::o2_hideMouse(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_hideMouse(%p) ()", (const void *)script); + _screen->hideMouse(); + return 0; +} + +int KyraEngine_HoF::o2_addSpecialExit(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_addSpecialExit(%p) (%d, %d, %d, %d, %d)", (const void *)script, + stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); + if (_specialExitCount < 5) { + _specialExitTable[_specialExitCount+0] = stackPos(0); + _specialExitTable[_specialExitCount+5] = stackPos(1); + _specialExitTable[_specialExitCount+10] = stackPos(2) + stackPos(0) - 1; + _specialExitTable[_specialExitCount+15] = stackPos(3) + stackPos(1) - 1; + _specialExitTable[_specialExitCount+20] = stackPos(4); + ++_specialExitCount; + } + return 0; +} + +int KyraEngine_HoF::o2_setMousePos(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_setMousePos(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + setMousePos(stackPos(0), stackPos(1)); + return 0; +} + +int KyraEngine_HoF::o2_showMouse(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_showMouse(%p) ()", (const void *)script); + _screen->showMouse(); + return 0; +} + +int KyraEngine_HoF::o2_wipeDownMouseItem(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_wipeDownMouseItem(%p) (-, %d, %d)", (const void *)script, stackPos(1), stackPos(2)); + _screen->hideMouse(); + const int x = stackPos(1) - 8; + const int y = stackPos(2) - 15; + + if (_itemInHand >= 0) { + backUpGfxRect32x32(x, y); + uint8 *shape = getShapePtr(_itemInHand+64); + for (int curY = y, height = 16; height > 0; height -= 2, curY += 2) { + restoreGfxRect32x32(x, y); + _screen->setNewShapeHeight(shape, height); + uint32 waitTime = _system->getMillis() + _tickLength; + _screen->drawShape(0, shape, x, curY, 0, 0); + _screen->updateScreen(); + delayUntil(waitTime); + } + restoreGfxRect32x32(x, y); + _screen->resetShapeHeight(shape); + } + + _screen->showMouse(); + removeHandItem(); + + return 0; +} + +int KyraEngine_HoF::o2_getElapsedSecs(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_getElapsedSecs(%p) ()", (const void *)script); + return _system->getMillis() / 1000; +} + +int KyraEngine_HoF::o2_getTimerDelay(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_getTimerDelay(%p) (%d)", (const void *)script, stackPos(0)); + return _timer->getDelay(stackPos(0)); +} + +int KyraEngine_HoF::o2_delaySecs(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_delaySecs(%p) (%d)", (const void *)script, stackPos(0)); + delay(stackPos(0) * 1000, true); + return 0; +} + +int KyraEngine_HoF::o2_delay(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_delay(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + if (stackPos(1)) { + uint32 maxWaitTime = _system->getMillis() + stackPos(0) * _tickLength; + while (_system->getMillis() < maxWaitTime) { + int inputFlag = checkInput(0); + removeInputTop(); + + if (inputFlag == 198 || inputFlag == 199) + return 1; + + if (_chatText) + updateWithText(); + else + update(); + _system->delayMillis(10); + } + } else { + delay(stackPos(0) * _tickLength, true); + } + return 0; +} + +int KyraEngine_HoF::o2_setTimerDelay(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_setTimerDelay(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + _timer->setDelay(stackPos(0), stackPos(1)); + return 0; +} + +int KyraEngine_HoF::o2_setScaleTableItem(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_setScaleTableItem(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + setScaleTableItem(stackPos(0), stackPos(1)); + return 0; +} + +int KyraEngine_HoF::o2_setDrawLayerTableItem(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_setDrawLayerTableItem(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + setDrawLayerTableEntry(stackPos(0), stackPos(1)); + return 0; +} + +int KyraEngine_HoF::o2_setCharPalEntry(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_setCharPalEntry(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + setCharPalEntry(stackPos(0), stackPos(1)); + return 0; +} + +int KyraEngine_HoF::o2_loadZShapes(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_loadZShapes(%p) (%d)", (const void *)script, stackPos(0)); + loadZShapes(stackPos(0)); + return 0; +} + +int KyraEngine_HoF::o2_drawSceneShape(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_drawSceneShape(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), + stackPos(2), stackPos(3)); + + int shape = stackPos(0); + int x = stackPos(1); + int y = stackPos(2); + int flag = (stackPos(3) != 0) ? 1 : 0; + + _screen->hideMouse(); + restorePage3(); + + _screen->drawShape(2, _sceneShapeTable[shape], x, y, 2, flag); + + memcpy(_gamePlayBuffer, _screen->getCPagePtr(3), 46080); + + _screen->drawShape(0, _sceneShapeTable[shape], x, y, 2, flag); + + flagAnimObjsSpecialRefresh(); + flagAnimObjsForRefresh(); + refreshAnimObjectsIfNeed(); + _screen->showMouse(); + return 0; +} + +int KyraEngine_HoF::o2_drawSceneShapeOnPage(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_drawSceneShapeOnPage(%p) (%d, %d, %d, %d, %d)", (const void *)script, + stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); + int shape = stackPos(0); + int x = stackPos(1); + int y = stackPos(2); + int flag = stackPos(3); + int drawPage = stackPos(4); + + _screen->drawShape(drawPage, _sceneShapeTable[shape], x, y, 2, flag ? 1 : 0); + return 0; +} + +int KyraEngine_HoF::o2_disableAnimObject(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_disableAnimObject(%p) (%d)", (const void *)script, stackPos(0)); + _animObjects[stackPos(0)+1].enabled = false; + return 0; +} + +int KyraEngine_HoF::o2_enableAnimObject(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_enableAnimObject(%p) (%d)", (const void *)script, stackPos(0)); + _animObjects[stackPos(0)+1].enabled = true; + return 0; +} + +int KyraEngine_HoF::o2_loadPalette384(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_loadPalette384(%p) ('%s')", (const void *)script, stackPosString(0)); + memcpy(_screen->getPalette(1), _screen->getPalette(0), 768); + _res->loadFileToBuf(stackPosString(0), _screen->getPalette(1), 384); + return 0; +} + +int KyraEngine_HoF::o2_setPalette384(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_setPalette384(%p) ()", (const void *)script); + memcpy(_screen->getPalette(0), _screen->getPalette(1), 384); + _screen->setScreenPalette(_screen->getPalette(0)); + return 0; +} + +int KyraEngine_HoF::o2_restoreBackBuffer(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_restoreBackBuffer(%p) (%d)", (const void *)script, stackPos(0)); + int disable = stackPos(0); + int oldState = 0; + + if (disable) { + oldState = _animObjects[0].enabled; + _animObjects[0].enabled = 0; + } + + restorePage3(); + + if (disable) + _animObjects[0].enabled = oldState; + + return 0; +} + +int KyraEngine_HoF::o2_backUpInventoryGfx(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_backUpInventoryGfx(%p) ()", (const void *)script); + _screen->copyRegionToBuffer(1, 0, 144, 320, 56, _screenBuffer); + _inventorySaved = true; + return 0; +} + +int KyraEngine_HoF::o2_disableSceneAnim(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_disableSceneAnim(%p) (%d)", (const void *)script, stackPos(0)); + _sceneAnims[stackPos(0)].flags &= ~1; + return 0; +} + +int KyraEngine_HoF::o2_enableSceneAnim(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_enableSceneAnim(%p) (%d)", (const void *)script, stackPos(0)); + _sceneAnims[stackPos(0)].flags |= 1; + return 0; +} + +int KyraEngine_HoF::o2_restoreInventoryGfx(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_restoreInventoryGfx(%p) ()", (const void *)script); + _screen->copyBlockToPage(1, 0, 144, 320, 56, _screenBuffer); + _inventorySaved = false; + return 0; +} + +int KyraEngine_HoF::o2_setSceneAnimPos2(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_setSceneAnimPos2(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); + _sceneAnims[stackPos(0)].x2 = stackPos(1); + _sceneAnims[stackPos(0)].y2 = stackPos(2); + return 0; +} + +int KyraEngine_HoF::o2_update(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_update(%p) (%d)", (const void *)script, stackPos(0)); + + int times = stackPos(0); + while (times--) { + if (_chatText) + updateWithText(); + else + update(); + } + + return 0; +} + +int KyraEngine_HoF::o2_fadeScenePal(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_fadeScenePal(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + fadeScenePal(stackPos(0), stackPos(1)); + return 0; +} + +int KyraEngine_HoF::o2_enterNewSceneEx(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_enterNewSceneEx(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), + stackPos(1), stackPos(2), stackPos(3), stackPos(4)); + + int skipNpcScript = stackPos(3); + enterNewScene(stackPos(0), stackPos(1), stackPos(2), skipNpcScript, stackPos(4)); + + if (!skipNpcScript) + runSceneScript4(0); + + _unk5 = 1; + + if (_mainCharX == -1 || _mainCharY == -1) { + _mainCharacter.animFrame = _characterFrameTable[_mainCharacter.facing]; + updateCharacterAnim(0); + } + + return 0; +} + +int KyraEngine_HoF::o2_switchScene(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_switchScene(%p) (%d)", (const void *)script, stackPos(0)); + setGameFlag(0x1EF); + _mainCharX = _mainCharacter.x1; + _mainCharY = _mainCharacter.y1; + _noScriptEnter = 0; + enterNewScene(stackPos(0), _mainCharacter.facing, 0, 0, 0); + _noScriptEnter = 1; + return 0; +} + +int KyraEngine_HoF::o2_getShapeFlag1(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_getShapeFlag1(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + return _screen->getShapeFlag1(stackPos(0), stackPos(1)); +} + +int KyraEngine_HoF::o2_setPathfinderFlag(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_setPathfinderFlag(%p) (%d)", (const void *)script, stackPos(0)); + _pathfinderFlag = stackPos(0); + return 0; +} + +int KyraEngine_HoF::o2_getSceneExitToFacing(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_getSceneExitToFacing(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + const int scene = stackPos(0); + const int facing = stackPos(1); + + if (facing == 0) + return (int16)_sceneList[scene].exit1; + else if (facing == 2) + return (int16)_sceneList[scene].exit2; + else if (facing == 4) + return (int16)_sceneList[scene].exit3; + else if (facing == 6) + return (int16)_sceneList[scene].exit4; + return -1; +} + +int KyraEngine_HoF::o2_setLayerFlag(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_setLayerFlag(%p) (%d)", (const void *)script, stackPos(0)); + int layer = stackPos(0); + if (layer >= 1 && layer <= 16) + _layerFlagTable[layer] = 1; + return 0; +} + +int KyraEngine_HoF::o2_setZanthiaPos(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_setZanthiaPos(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + _mainCharX = stackPos(0); + _mainCharY = stackPos(1); + + if (_mainCharX == -1 && _mainCharY == -1) + _mainCharacter.animFrame = 32; + else + _mainCharacter.animFrame = _characterFrameTable[_mainCharacter.facing]; + + return 0; +} + +int KyraEngine_HoF::o2_loadMusicTrack(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_loadMusicTrack(%p) (%d)", (const void *)script, stackPos(0)); + snd_loadSoundFile(stackPos(0)); + return 0; +} + +int KyraEngine_HoF::o2_playWanderScoreViaMap(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_playWanderScoreViaMap(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + snd_playWanderScoreViaMap(stackPos(0), stackPos(1)); + return 0; +} + +int KyraEngine_HoF::o2_playSoundEffect(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_playSoundEffect(%p) (%d)", (const void *)script, stackPos(0)); + snd_playSoundEffect(stackPos(0)); + return 0; +} + +int KyraEngine_HoF::o2_setSceneAnimPos(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_setSceneAnimPos(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); + _sceneAnims[stackPos(0)].x = stackPos(1); + _sceneAnims[stackPos(0)].y = stackPos(2); + return 0; +} + +int KyraEngine_HoF::o2_blockInRegion(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_blockInRegion(%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_HoF::o2_blockOutRegion(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_blockOutRegion(%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_HoF::o2_setCauldronState(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_setCauldronState(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + setCauldronState(stackPos(0), stackPos(1) != 0); + clearCauldronTable(); + return 0; +} + +int KyraEngine_HoF::o2_showItemString(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_showItemString(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + const int item = stackPos(0); + + int string = 0; + if (stackPos(1) == 1) { + if (_lang == 1) + string = getItemCommandStringPickUp(item); + else + string = 7; + } else { + if (_lang == 1) + string = getItemCommandStringInv(item); + else + string = 8; + } + + updateCommandLineEx(item+54, string, 0xD6); + return 0; +} + +int KyraEngine_HoF::o2_getRand(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_getRand(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + assert(stackPos(0) < stackPos(1)); + return _rnd.getRandomNumberRng(stackPos(0), stackPos(1)); +} + +int KyraEngine_HoF::o2_isAnySoundPlaying(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_isAnySoundPlaying(%p) ()", (const void *)script); + return _sound->voiceIsPlaying(); +} + +int KyraEngine_HoF::o2_setDeathHandlerFlag(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_setDeathHandlerFlag(%p) (%d)", (const void *)script, stackPos(0)); + _deathHandler = stackPos(0); + return 0; +} + +int KyraEngine_HoF::o2_setDrawNoShapeFlag(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_setDrawNoShapeFlag(%p) (%d)", (const void *)script, stackPos(0)); + _drawNoShapeFlag = (stackPos(0) != 0); + return 0; +} + +int KyraEngine_HoF::o2_setRunFlag(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_setRunFlag(%p) (%d)", (const void *)script, stackPos(0)); + // this is usually just _runFlag, but since this is just used when the game should play the credits + // we handle it a bit different :-) + _showCredits = true; + _runFlag = false; + return 0; +} + +int KyraEngine_HoF::o2_showLetter(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_showLetter(%p) (%d)", (const void *)script, stackPos(0)); + const int letter = stackPos(0); + char filename[16]; + + _screen->hideMouse(); + + showMessage(0, 0xCF); + displayInvWsaLastFrame(); + backUpPage0(); + + memcpy(_screen->getPalette(2), _screen->getPalette(0), 768); + + _screen->clearPage(3); + _screen->loadBitmap("_NOTE.CPS", 3, 3, 0); + + sprintf(filename, "_NTEPAL%.1d.COL", letter+1); + _res->loadFileToBuf(filename, _screen->getPalette(0), 768); + + _screen->fadeToBlack(0x14); + + sprintf(filename, "LETTER%.1d.", letter); + strcat(filename, _languageExtension[_lang]); + + uint8 *letterBuffer = _res->fileData(filename, 0); + if (letterBuffer) { + bookDecodeText(letterBuffer); + bookPrintText(2, letterBuffer, 0xC, 0xA, 0x20); + } + + _screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0, Screen::CR_NO_P_CHECK); + _screen->fadePalette(_screen->getPalette(0), 0x14); + _screen->setMouseCursor(0, 0, getShapePtr(0)); + setMousePos(280, 160); + + _screen->showMouse(); + + bool running = true; + while (running) { + int inputFlag = checkInput(0); + removeInputTop(); + + if (inputFlag == 198 || inputFlag == 199) + running = false; + + _screen->updateScreen(); + _system->delayMillis(10); + } + + _screen->hideMouse(); + _screen->fadeToBlack(0x14); + restorePage0(); + memcpy(_screen->getPalette(0), _screen->getPalette(2), 768); + _screen->fadePalette(_screen->getPalette(0), 0x14); + setHandItem(_itemInHand); + _screen->showMouse(); + + return 0; +} + +int KyraEngine_HoF::o2_fillRect(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_fillRect(%p) (%d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5)); + _screen->fillRect(stackPos(1), stackPos(2), stackPos(1)+stackPos(3), stackPos(2)+stackPos(4), stackPos(5), stackPos(0)); + return 0; +} + +int KyraEngine_HoF::o2_waitForConfirmationClick(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_waitForConfirmationClick(%p) (%d)", (const void *)script, stackPos(0)); + resetSkipFlag(); + uint32 maxWaitTime = _system->getMillis() + stackPos(0) * _tickLength; + + while (_system->getMillis() < maxWaitTime) { + int inputFlag = checkInput(0); + removeInputTop(); + + if (inputFlag == 198 || inputFlag == 199) { + _sceneScriptState.regs[1] = _mouseX; + _sceneScriptState.regs[2] = _mouseY; + return 0; + } + + update(); + _system->delayMillis(10); + } + + _sceneScriptState.regs[1] = _mouseX; + _sceneScriptState.regs[2] = _mouseY; + return 1; +} + +int KyraEngine_HoF::o2_encodeShape(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_encodeShape(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), + stackPos(2), stackPos(3), stackPos(4)); + _sceneShapeTable[stackPos(0)] = _screen->encodeShape(stackPos(1), stackPos(2), stackPos(3), stackPos(4), 2); + return 0; +} + +int KyraEngine_HoF::o2_defineRoomEntrance(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_defineRoomEntrance(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); + switch (stackPos(0)) { + case 0: + _sceneEnterX1 = stackPos(1); + _sceneEnterY1 = stackPos(2); + break; + + case 1: + _sceneEnterX2 = stackPos(1); + _sceneEnterY2 = stackPos(2); + break; + + case 2: + _sceneEnterX3 = stackPos(1); + _sceneEnterY3 = stackPos(2); + break; + + case 3: + _sceneEnterX4 = stackPos(1); + _sceneEnterY4 = stackPos(2); + break; + + default: + break; + } + return 0; +} + +int KyraEngine_HoF::o2_runTemporaryScript(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_runTemporaryScript(%p) ('%s', %d, %d, %d)", (const void *)script, stackPosString(0), stackPos(1), + stackPos(2), stackPos(3)); + + runTemporaryScript(stackPosString(0), stackPos(3), stackPos(2) ? 1 : 0, stackPos(1), stackPos(2)); + return 0; +} + +int KyraEngine_HoF::o2_setSpecialSceneScriptRunTime(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_setSpecialSceneScriptRunTime(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + assert(stackPos(0) >= 0 && stackPos(0) < 10); + _sceneSpecialScriptsTimer[stackPos(0)] = _system->getMillis() + stackPos(1) * _tickLength; + return 0; +} + +int KyraEngine_HoF::o2_defineSceneAnim(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_defineSceneAnim(%p) (%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, '%s')", (const void *)script, + stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7), stackPos(8), + stackPos(9), stackPos(10), stackPos(11), stackPosString(12)); + int animId = stackPos(0); + SceneAnim &anim = _sceneAnims[animId]; + anim.flags = stackPos(1); + anim.x = stackPos(2); + anim.y = stackPos(3); + anim.x2 = stackPos(4); + anim.y2 = stackPos(5); + anim.width = stackPos(6); + anim.height = stackPos(7); + anim.specialSize = stackPos(9); + anim.shapeIndex = stackPos(11); + if (stackPosString(12) != 0) + strcpy(anim.filename, stackPosString(12)); + + if (anim.flags & 0x40) { + if (!_sceneAnimMovie[animId]->open(anim.filename, 1, 0)) + error("couldn't load '%s'", anim.filename); + + if (_sceneAnimMovie[animId]->xAdd() || _sceneAnimMovie[animId]->yAdd()) + anim.wsaFlag = 1; + else + anim.wsaFlag = 0; + } + + return 0; +} + +int KyraEngine_HoF::o2_updateSceneAnim(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_updateSceneAnim(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + updateSceneAnim(stackPos(0), stackPos(1)); + + // HACK: Some animations are really too fast because of missing delay times. + // Notice that the delay time is purely subjective set here, it could look + // slower or maybe faster in the original, but at least this looks OK for + // Raziel^. + // + // We know currently of some different animations where this happens. + // - Where Marco is dangling from the flesh-eating plant (see bug #1923638 "HoF: Marco missing animation frames"). + // - After giving the ticket to the captain. He would move very fast (barely noticeable) onto the ship + // without this delay. + // - The scene after giving the sandwitch to the guards in the city. (see bug #1926838 "HoF: Animation plays too fast") + // This scene script calls o2_delay though, but since this updates the scene animation scripts again there is no delay + // for the animation. + if ((stackPos(0) == 2 && _mainCharacter.sceneId == 3) || (stackPos(0) == 3 && _mainCharacter.sceneId == 33) || + ((stackPos(0) == 1 || stackPos(0) == 2) && _mainCharacter.sceneId == 19)) + _sceneSpecialScriptsTimer[_lastProcessedSceneScript] = _system->getMillis() + _tickLength * 6; + + _specialSceneScriptRunFlag = false; + return 0; +} + +int KyraEngine_HoF::o2_addToSceneAnimPosAndUpdate(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_addToSceneAnimPosAndUpdate(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); + const int anim = stackPos(0); + _sceneAnims[anim].x2 += stackPos(1); + _sceneAnims[anim].y2 += stackPos(2); + if (_sceneAnims[anim].flags & 2) { + _sceneAnims[anim].x += stackPos(1); + _sceneAnims[anim].y += stackPos(2); + } + updateSceneAnim(anim, stackPos(3)); + _specialSceneScriptRunFlag = false; + return 0; +} + +int KyraEngine_HoF::o2_useItemOnMainChar(EMCState *script) { + EMCState tmpScript; + _emc->init(&tmpScript, &_npcScriptData); + _emc->start(&tmpScript, 0); + tmpScript.regs[4] = _itemInHand; + tmpScript.regs[0] = _mainCharacter.sceneId; + + int oldVocH = _vocHigh; + _vocHigh = 0x5a; + + while(_emc->isValid(&tmpScript)) + _emc->run(&tmpScript); + + _vocHigh = oldVocH; + + return 0; +} + +int KyraEngine_HoF::o2_startDialogue(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_startDialogue(%p) (%d)", (const void *)script, stackPos(0)); + startDialogue(stackPos(0)); + return 0; +} + +int KyraEngine_HoF::o2_zanthRandomChat(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_zanthRandomChat(%p)", (const void *)script); + zanthRandomIdleChat(); + return 0; +} + +int KyraEngine_HoF::o2_setupDialogue(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_setupDialogue(%p) (%d)", (const void *)script, stackPos(0)); + setNewDlgIndex(stackPos(0)); + return 0; +} + +int KyraEngine_HoF::o2_getDlgIndex(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_setNewDlgIndex(%p) (%d)", (const void *)script, stackPos(0)); + return _mainCharacter.dlgIndex; +} + +int KyraEngine_HoF::o2_defineRoom(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_defineRoom(%p) (%d, '%s', %d, %d, %d, %d, %d, %d)", (const void *)script, + stackPos(0), stackPosString(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7)); + SceneDesc *scene = &_sceneList[stackPos(0)]; + strcpy(scene->filename1, stackPosString(1)); + scene->exit1 = stackPos(2); + scene->exit2 = stackPos(3); + scene->exit3 = stackPos(4); + scene->exit4 = stackPos(5); + scene->flags = stackPos(6); + scene->sound = stackPos(7); + + if (_mainCharacter.sceneId == stackPos(0)) { + _sceneExit1 = scene->exit1; + _sceneExit2 = scene->exit2; + _sceneExit3 = scene->exit3; + _sceneExit4 = scene->exit4; + } + + return 0; +} + +int KyraEngine_HoF::o2_addCauldronStateTableEntry(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_addCauldronStateTableEntry(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + return addToCauldronStateTable(stackPos(0), stackPos(1)) ? 1 : 0; +} + +int KyraEngine_HoF::o2_setCountDown(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_setCountDown(%p) (%d)", (const void *)script, stackPos(0)); + _scriptCountDown = _system->getMillis() + stackPos(0) * _tickLength; + return 0; +} + +int KyraEngine_HoF::o2_getCountDown(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_getCountDown(%p)", (const void *)script); + uint32 time = _system->getMillis(); + return (time > _scriptCountDown) ? 0 : (_scriptCountDown - time) / _tickLength; +} + +int KyraEngine_HoF::o2_pressColorKey(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_pressColorKey(%p) (%d)", (const void *)script, stackPos(0)); + for (int i = 6; i; i--) + _inputColorCode[i] = _inputColorCode[i - 1]; + _inputColorCode[0] = stackPos(0) & 0xff; + for (int i = 0; i < 7; i++) { + if (_presetColorCode[i] != _inputColorCode[6 - i]) + return _dbgPass; + } + return 1; +} + +int KyraEngine_HoF::o2_objectChat(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_objectChat(%p) ('%s', %d)", (const void *)script, stackPosString(0), stackPos(1)); + if (_flags.isTalkie) + warning("Unexpected call: o2_objectChat(%p) ('%s', %d)", (const void *)script, stackPosString(0), stackPos(1)); + else + objectChat(stackPosString(0), stackPos(1)); + return 0; +} + +int KyraEngine_HoF::o2_chapterChange(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_chapterChange(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + const int chapter = stackPos(0); + const int scene = stackPos(1); + + resetItemList(); + + _newChapterFile = chapter; + runStartScript(chapter, 0); + + _mainCharacter.dlgIndex = 0; + memset(_newSceneDlgState, 0, 32); + + static const int zShapeList[] = { 1, 2, 2, 2, 4 }; + assert(chapter > 1 && chapter <= ARRAYSIZE(zShapeList)); + loadZShapes(zShapeList[chapter-1]); + + enterNewScene(scene, (chapter == 2) ? 2 : 0, 0, 0, 0); + + return 0; +} + +int KyraEngine_HoF::o2_getColorCodeFlag1(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_getColorCodeFlag1(%p) ()", (const void *)script); + return _colorCodeFlag1; +} + +int KyraEngine_HoF::o2_setColorCodeFlag1(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_getColorCodeFlag1(%p) (%d)", (const void *)script, stackPos(0)); + _colorCodeFlag1 = stackPos(0); + return 0; +} + +int KyraEngine_HoF::o2_getColorCodeFlag2(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_getColorCodeFlag2(%p) ()", (const void *)script); + return _colorCodeFlag2; +} + +int KyraEngine_HoF::o2_setColorCodeFlag2(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_getColorCodeFlag2(%p) (%d)", (const void *)script, stackPos(0)); + _colorCodeFlag2 = stackPos(0); + return 0; +} + +int KyraEngine_HoF::o2_getColorCodeValue(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_getColorCodeValue(%p) (%d)", (const void *)script, stackPos(0)); + return _presetColorCode[stackPos(0)]; +} + +int KyraEngine_HoF::o2_setColorCodeValue(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_setColorCodeValue(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + _presetColorCode[stackPos(0)] = stackPos(1) & 0xff; + return stackPos(1) & 0xff; +} + +int KyraEngine_HoF::o2_countItemInstances(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_countItemInstances(%p) (%d)", (const void *)script, stackPos(0)); + uint16 item = stackPos(0); + + int count = 0; + for (int i = 0; i < 20; ++i) { + if (_mainCharacter.inventory[i] == item) + ++count; + } + + if (_itemInHand == int16(item)) + ++count; + + for (int i = 0; i < 30; ++i) { + if (_itemList[i].id == item) + ++count; + } + + if (_hiddenItems[0] == item && _newChapterFile == 1) + ++count; + if (_hiddenItems[1] == item && _newChapterFile == 1) + ++count; + if (_hiddenItems[2] == item && _newChapterFile == 2) + ++count; + if (_hiddenItems[3] == item && _newChapterFile == 2) + ++count; + if (_hiddenItems[4] == item && _newChapterFile == 1) + ++count; + + return count; +} + +int KyraEngine_HoF::o2_removeItemFromScene(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_removeItemFromScene(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + const int scene = stackPos(0); + const uint16 item = stackPos(1); + for (int i = 0; i < 30; ++i) { + if (_itemList[i].sceneId == scene && _itemList[i].id == item) + _itemList[i].id = 0xFFFF; + } + return 0; +} + +int KyraEngine_HoF::o2_initObject(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_initObject(%p) (%d)", (const void *)script, stackPos(0)); + initTalkObject(stackPos(0)); + return 0; +} + +int KyraEngine_HoF::o2_npcChat(EMCState *script) { + if (_flags.isTalkie) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_npcChat(%p) ('%s', %d, %d, %d)", (const void *)script, stackPosString(0), stackPos(1), _vocHigh, stackPos(2)); + npcChatSequence(stackPosString(0), stackPos(1), _vocHigh, stackPos(2)); + } else { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_npcChat(%p) ('%s', %d)", (const void *)script, stackPosString(0), stackPos(1)); + npcChatSequence(stackPosString(0), stackPos(1)); + } + return 0; +} + +int KyraEngine_HoF::o2_deinitObject(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_deinitObject(%p) (%d)", (const void *)script, stackPos(0)); + deinitTalkObject(stackPos(0)); + return 0; +} + +int KyraEngine_HoF::o2_playTimSequence(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_playTimSequence(%p) ('%s')", (const void *)script, stackPosString(0)); + playTim(stackPosString(0)); + return 0; +} + +int KyraEngine_HoF::o2_makeBookOrCauldronAppear(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_makeBookOrCauldronAppear(%p) (%d)", (const void *)script, stackPos(0)); + seq_makeBookOrCauldronAppear(stackPos(0)); + return 0; +} + +int KyraEngine_HoF::o2_setSpecialSceneScriptState(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_setSpecialSceneScriptState(%p) (%d)", (const void *)script, stackPos(0)); + _specialSceneScriptState[stackPos(0)] = 1; + return 1; +} + +int KyraEngine_HoF::o2_clearSpecialSceneScriptState(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_clearSpecialSceneScriptState(%p) (%d)", (const void *)script, stackPos(0)); + _specialSceneScriptState[stackPos(0)] = 0; + return 0; +} + +int KyraEngine_HoF::o2_querySpecialSceneScriptState(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_querySpecialSceneScriptState(%p) (%d)", (const void *)script, stackPos(0)); + return _specialSceneScriptState[stackPos(0)]; +} + +int KyraEngine_HoF::o2_resetInputColorCode(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_resetInputColorCode(%p)", (const void *)script); + memset(_inputColorCode, 255, 7); + return 0; +} + +int KyraEngine_HoF::o2_setHiddenItemsEntry(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_setHiddenItemsEntry(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + return (_hiddenItems[stackPos(0)] = stackPos(1)); +} + +int KyraEngine_HoF::o2_getHiddenItemsEntry(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_getHiddenItemsEntry(%p) (%d)", (const void *)script, stackPos(0)); + return _hiddenItems[stackPos(0)]; +} + +int KyraEngine_HoF::o2_mushroomEffect(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_mushroomEffect(%p)", (const void *)script); + memcpy(_screen->getPalette(2), _screen->_currentPalette, 768); + + for (int i = 1; i < 768; i += 3) + _screen->_currentPalette[i] = 0; + snd_playSoundEffect(106); + _screen->fadePalette(_screen->_currentPalette, 90, &_updateFunctor); + memcpy(_screen->_currentPalette, _screen->getPalette(2), 768); + + for (int i = 0; i < 768; i += 3) { + _screen->_currentPalette[i] = _screen->_currentPalette[i + 1] = 0; + _screen->_currentPalette[i + 2] += (((int8)_screen->_currentPalette[i + 2]) >> 1); + if (_screen->_currentPalette[i + 2] > 63) + _screen->_currentPalette[i + 2] = 63; + } + snd_playSoundEffect(106); + _screen->fadePalette(_screen->_currentPalette, 90, &_updateFunctor); + + memcpy(_screen->_currentPalette, _screen->getPalette(2), 768); + _screen->fadePalette(_screen->_currentPalette, 30, &_updateFunctor); + + return 0; +} + +int KyraEngine_HoF::o2_customChat(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_customChat(%p) ('%s', %d, %d)", (const void *)script, stackPosString(0), stackPos(1), stackPos(2)); + strcpy((char*)_unkBuf500Bytes, stackPosString(0)); + _chatText = (char*)_unkBuf500Bytes; + _chatObject = stackPos(1); + + _chatVocHigh = _chatVocLow = -1; + objectChatInit(_chatText, _chatObject, _vocHigh, stackPos(2)); + playVoice(_vocHigh, stackPos(2)); + return 0; +} + +int KyraEngine_HoF::o2_customChatFinish(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_customChatFinish(%p) ()", (const void *)script); + _text->restoreScreen(); + _chatText = 0; + _chatObject = -1; + return 0; +} + +int KyraEngine_HoF::o2_setupSceneAnimation(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_setupSceneAnimation(%p) (%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, '%s')", (const void *)script, + stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7), stackPos(8), stackPos(9), stackPos(10), stackPos(11), stackPosString(12)); + const int index = stackPos(0); + const uint16 flags = stackPos(1); + + restorePage3(); + + SceneAnim &anim = _sceneAnims[index]; + anim.flags = flags; + anim.x = stackPos(2); + anim.y = stackPos(3); + anim.x2 = stackPos(4); + anim.y2 = stackPos(5); + anim.width = stackPos(6); + anim.height = stackPos(7); + anim.specialSize = stackPos(9); + anim.shapeIndex = stackPos(11); + if (stackPosString(12)) + strcpy(anim.filename, stackPosString(12)); + + if (flags & 0x40) { + _sceneAnimMovie[index]->open(stackPosString(12), 0, 0); + if (_sceneAnimMovie[index]->xAdd() || _sceneAnimMovie[index]->yAdd()) + anim.wsaFlag = 1; + else + anim.wsaFlag = 0; + } + + AnimObj *obj = &_animObjects[1+index]; + obj->enabled = 1; + obj->needRefresh = 1; + obj->specialRefresh = 1; + obj->animFlags = anim.flags & 8; + + if (anim.flags & 2) + obj->flags = 0x800; + else + obj->flags = 0; + + if (anim.flags & 4) + obj->flags |= 1; + + obj->xPos1 = anim.x; + obj->yPos1 = anim.y; + + if ((anim.flags & 0x20) && anim.shapeIndex >= 0) + obj->shapePtr = _sceneShapeTable[anim.shapeIndex]; + else + obj->shapePtr = 0; + + if (anim.flags & 0x40) { + obj->shapeIndex3 = anim.shapeIndex; + obj->animNum = index; + } else { + obj->shapeIndex3 = 0xFFFF; + obj->animNum = 0xFFFF; + } + + obj->shapeIndex2 = 0xFFFF; + obj->xPos2 = obj->xPos3 = anim.x2; + obj->yPos2 = obj->yPos3 = anim.y2; + obj->width = anim.width; + obj->height = anim.height; + obj->width2 = obj->height2 = anim.specialSize; + + _animList = addToAnimListSorted(_animList, obj); + obj->needRefresh = 1; + obj->specialRefresh = 1; + return 0; +} + +int KyraEngine_HoF::o2_stopSceneAnimation(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_stopSceneAnimation(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + const int index = stackPos(0); + AnimObj &obj = _animObjects[1+index]; + restorePage3(); + obj.shapeIndex3 = 0xFFFF; + obj.animNum = 0xFFFF; + obj.needRefresh = 1; + obj.specialRefresh = 1; + if (stackPos(1)) + refreshAnimObjectsIfNeed(); + obj.enabled = 0; + _animList = deleteAnimListEntry(_animList, &_animObjects[1+index]); + + if (_sceneAnimMovie[index]->opened()) + _sceneAnimMovie[index]->close(); + + return 0; +} + +int KyraEngine_HoF::o2_disableTimer(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_disableTimer(%p) (%d)", (const void *)script, stackPos(0)); + _timer->disable(stackPos(0)); + return 0; +} + +int KyraEngine_HoF::o2_enableTimer(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_enableTimer(%p) (%d)", (const void *)script, stackPos(0)); + _timer->enable(stackPos(0)); + return 0; +} + +int KyraEngine_HoF::o2_setTimerCountdown(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_setTimerCountdown(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + _timer->setCountdown(stackPos(0), stackPos(1)); + return 0; +} + +int KyraEngine_HoF::o2_processPaletteIndex(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_processPaletteIndex(%p) (%d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5)); + uint8 *palette = _screen->getPalette(0); + const int index = stackPos(0); + const bool updatePalette = (stackPos(4) != 0); + const int delayTime = stackPos(5); + palette[index*3+0] = (stackPos(1) * 0x3F) / 100; + palette[index*3+1] = (stackPos(2) * 0x3F) / 100; + palette[index*3+2] = (stackPos(3) * 0x3F) / 100; + if (updatePalette) { + if (delayTime > 0) + _screen->fadePalette(palette, delayTime, &_updateFunctor); + else + _screen->setScreenPalette(palette); + } + return 0; +} + +int KyraEngine_HoF::o2_updateTwoSceneAnims(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_updateTwoSceneAnims(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); + updateSceneAnim(stackPos(0), stackPos(1)); + updateSceneAnim(stackPos(2), stackPos(3)); + _specialSceneScriptRunFlag = false; + return 0; +} + +int KyraEngine_HoF::o2_getRainbowRoomData(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_getRainbowRoomData(%p) (%d)", (const void *)script, stackPos(0)); + return _rainbowRoomData[stackPos(0)]; +} + +int KyraEngine_HoF::o2_drawSceneShapeEx(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_drawSceneShapeEx(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); + const int itemShape = stackPos(0) + 64; + const int x = stackPos(1); + const int y = stackPos(2); + const bool skipFronUpdate = (stackPos(3) != 0); + + _screen->drawShape(2, _sceneShapeTable[6], x, y, 2, 0); + _screen->drawShape(2, getShapePtr(itemShape), x+2, y+2, 2, 0); + + if (!skipFronUpdate) { + _screen->copyRegion(x, y, x, y, 0x15, 0x14, 2, 0, Screen::CR_NO_P_CHECK); + _screen->updateScreen(); + } + + return 0; +} + +int KyraEngine_HoF::o2_getBoolFromStack(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_getBoolFromStack(%p) ()", (const void *)script); + return stackPos(0) ? 1 : 0; +} + +int KyraEngine_HoF::o2_getSfxDriver(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_getSfxDriver(%p) ()", (const void *)script); + if (_sound->getSfxType() == Sound::kAdlib) + return 1; + else if (_sound->getSfxType() == Sound::kMidiMT32) + return 6; + else if (_sound->getSfxType() == Sound::kMidiGM) + return 7; + // TODO: find nice default value + return 0; +} + +int KyraEngine_HoF::o2_getVocSupport(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_getVocSupport(%p) ()", (const void *)script); + // we always support VOC file playback + return 1; +} + +int KyraEngine_HoF::o2_getMusicDriver(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_getMusicDriver(%p) ()", (const void *)script); + if (_sound->getMusicType() == Sound::kAdlib) + return 1; + else if (_sound->getMusicType() == Sound::kMidiMT32) + return 6; + else if (_sound->getMusicType() == Sound::kMidiGM) + return 7; + // TODO: find nice default value + return 0; +} + +int KyraEngine_HoF::o2_setVocHigh(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_setVocHigh(%p) (%d)", (const void *)script, stackPos(0)); + _vocHigh = stackPos(0); + return _vocHigh; +} + +int KyraEngine_HoF::o2_getVocHigh(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_getVocHigh(%p) ()", (const void *)script); + return _vocHigh; +} + +int KyraEngine_HoF::o2_zanthiaChat(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_zanthiaChat(%p) ('%s', %d)", (const void *)script, stackPosString(0), stackPos(1)); + objectChat(stackPosString(0), 0, _vocHigh, stackPos(1)); + return 0; +} + +int KyraEngine_HoF::o2_isVoiceEnabled(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_isVoiceEnabled(%p) ()", (const void *)script); + return speechEnabled() ? 1 : 0; +} + +int KyraEngine_HoF::o2_isVoicePlaying(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_isVoicePlaying(%p) ()", (const void *)script); + return (snd_voiceIsPlaying() && !skipFlag()) ? 1 : 0; +} + +int KyraEngine_HoF::o2_stopVoicePlaying(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_stopVoicePlaying(%p) ()", (const void *)script); + snd_stopVoice(); + return 0; +} + +int KyraEngine_HoF::o2_getGameLanguage(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_getGameLanguage(%p) ()", (const void *)script); + return _lang; +} + +int KyraEngine_HoF::o2_demoFinale(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_demoFinale(%p) ()", (const void *)script); + if (!_flags.isDemo) + return 0; + + int tmpSize; + const char *const *strings = _staticres->loadStrings(k2IngameTlkDemoStrings, tmpSize); + assert(strings); + + _screen->clearPage(0); + _screen->loadPalette("THANKS.COL", _screen->_currentPalette); + _screen->loadBitmap("THANKS.CPS", 3, 3, 0); + _screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0); + + _screen->_curPage = 0; + _screen->setFont(Screen::FID_6_FNT); + int y = _lang == 1 ? 70 : 65; + for (int i = 0; i < 6; i++) + _text->printText(strings[i], _text->getCenterStringX(strings[i], 1, 319), y + i * 10, 255, 207, 0); + + _screen->setScreenPalette(_screen->_currentPalette); + _screen->updateScreen(); + + _eventList.clear(); + while (!skipFlag()) + delay(10); + + _sound->beginFadeOut(); + _screen->fadeToBlack(); + + _runFlag = 0; + return 0; +} + +int KyraEngine_HoF::o2_dummy(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_dummy(%p) ()", (const void *)script); + return 0; +} + +#pragma mark - + +int KyraEngine_HoF::o2t_defineNewShapes(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2t_defineNewShapes(%p) ('%s', %d, %d, %d, %d, %d, %d)", (const void *)script, stackPosString(0), + stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6)); + + strcpy(_newShapeFilename, stackPosString(0)); + _newShapeLastEntry = stackPos(1); + _newShapeWidth = stackPos(2); + _newShapeHeight = stackPos(3); + _newShapeXAdd = stackPos(4); + _newShapeYAdd = stackPos(5); + //word_324EB = stackPos(6); <- never used + + return 0; +} + +int KyraEngine_HoF::o2t_setCurrentFrame(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2t_setCurrentFrame(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + _newShapeAnimFrame = stackPos(0); + _newShapeDelay = stackPos(1); + _temporaryScriptExecBit = true; + return 0; +} + +int KyraEngine_HoF::o2t_playSoundEffect(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2t_playSoundEffect(%p) (%d)", (const void *)script, stackPos(0)); + snd_playSoundEffect(stackPos(0)); + return 0; +} + +int KyraEngine_HoF::o2t_fadeScenePal(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2t_fadeScenePal(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + fadeScenePal(stackPos(0), stackPos(1)); + return 0; +} + +int KyraEngine_HoF::o2t_setShapeFlag(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2t_setShapeFlag(%p) (%d)", (const void *)script, stackPos(0)); + if (_flags.isTalkie) + _newShapeFlag = stackPos(0); + return 0; +} + +#pragma mark - + +int KyraEngine_HoF::t2_initChat(const TIM *tim, const uint16 *param) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::t2_initChat(%p, %p) (%d)", (const void*)tim, (const void*)param, param[0]); + _chatText = (const char*)tim->text + READ_LE_UINT16(tim->text + (param[0] << 1)); + _chatObject = param[1]; + + if (_flags.lang == Common::JA_JPN) { + for (int i = 0; i < _ingameTimJpStrSize; i += 2) { + if (!scumm_stricmp(_chatText, _ingameTimJpStr[i])) + _chatText = _ingameTimJpStr[i + 1]; + } + } + + objectChatInit(_chatText, _chatObject); + return 0; +} + +int KyraEngine_HoF::t2_updateSceneAnim(const TIM *tim, const uint16 *param) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::t2_updateSceneAnim(%p, %p) (%d, %d)", (const void*)tim, (const void*)param, param[0], param[1]); + updateSceneAnim(param[1], param[0]); + return 0; +} + +int KyraEngine_HoF::t2_resetChat(const TIM *tim, const uint16 *param) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::t2_resetChat(%p, %p) ()", (const void*)tim, (const void*)param); + _text->restoreScreen(); + _chatText = 0; + _chatObject = -1; + return 0; +} + +int KyraEngine_HoF::t2_playSoundEffect(const TIM *tim, const uint16 *param) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::t2_playSoundEffect(%p, %p) (%d)", (const void*)tim, (const void*)param, param[0]); + snd_playSoundEffect(*param); + return 0; +} + +#pragma mark - + +typedef Common::Functor1Mem OpcodeV2; +#define SetOpcodeTable(x) table = &x; +#define Opcode(x) table->push_back(new OpcodeV2(this, &KyraEngine_HoF::x)) +#define OpcodeUnImpl() table->push_back(new OpcodeV2(this, 0)) + +typedef Common::Functor2Mem TIMOpcodeV2; +#define OpcodeTim(x) _timOpcodes.push_back(new TIMOpcodeV2(this, &KyraEngine_HoF::x)) +#define OpcodeTimUnImpl() _timOpcodes.push_back(TIMOpcodeV2(this, 0)) + +void KyraEngine_HoF::setupOpcodeTable() { + Common::Array *table = 0; + + SetOpcodeTable(_opcodes); + // 0x00 + Opcode(o2_setCharacterFacingRefresh); + Opcode(o2_setCharacterPos); + Opcode(o2_defineObject); + Opcode(o2_refreshCharacter); + // 0x04 + Opcode(o2_getCharacterX); + Opcode(o2_getCharacterY); + Opcode(o2_getCharacterFacing); + Opcode(o2_getCharacterScene); + // 0x08 + Opcode(o2_setSceneComment); + OpcodeUnImpl(); + OpcodeUnImpl(); + Opcode(o2_setCharacterAnimFrame); + // 0x0c + Opcode(o2_setCharacterFacing); + Opcode(o2_trySceneChange); + Opcode(o2_moveCharacter); + Opcode(o2_customCharacterChat); + // 0x10 + Opcode(o2_soundFadeOut); + Opcode(o2_showChapterMessage); + Opcode(o2_restoreTalkTextMessageBkgd); + OpcodeUnImpl(); + // 0x14 + Opcode(o2_wsaClose); + Opcode(o2_backUpScreen); + Opcode(o2_restoreScreen); + Opcode(o2_displayWsaFrame); + // 0x18 + Opcode(o2_displayWsaSequentialFramesLooping); + Opcode(o2_wsaOpen); + Opcode(o2_displayWsaSequentialFrames); + Opcode(o2_displayWsaSequence); + // 0x1c + Opcode(o2_addItemToInventory); + Opcode(o2_drawShape); + Opcode(o2_addItemToCurScene); + Opcode(o2_dummy); // the original used this opcode to limit the mouse range temporary, + // since that is of no use and not really important we just use a dummy here + // 0x20 + Opcode(o2_checkForItem); + Opcode(o2_loadSoundFile); + Opcode(o2_removeItemSlotFromInventory); + Opcode(o2_defineItem); + // 0x24 + Opcode(o2_removeItemFromInventory); + Opcode(o2_countItemInInventory); + Opcode(o2_countItemsInScene); + Opcode(o2_queryGameFlag); + // 0x28 + Opcode(o2_resetGameFlag); + Opcode(o2_setGameFlag); + Opcode(o2_setHandItem); + Opcode(o2_removeHandItem); + // 0x2c + Opcode(o2_handItemSet); + Opcode(o2_hideMouse); + Opcode(o2_addSpecialExit); + Opcode(o2_setMousePos); + // 0x30 + Opcode(o2_showMouse); + OpcodeUnImpl(); + Opcode(o2_wipeDownMouseItem); + Opcode(o2_getElapsedSecs); + // 0x34 + Opcode(o2_getTimerDelay); + Opcode(o2_playSoundEffect); + Opcode(o2_delaySecs); + Opcode(o2_delay); + // 0x38 + Opcode(o2_dummy); + Opcode(o2_setTimerDelay); + Opcode(o2_setScaleTableItem); + Opcode(o2_setDrawLayerTableItem); + // 0x3c + Opcode(o2_setCharPalEntry); + Opcode(o2_loadZShapes); + Opcode(o2_drawSceneShape); + Opcode(o2_drawSceneShapeOnPage); + // 0x40 + Opcode(o2_disableAnimObject); + Opcode(o2_enableAnimObject); + Opcode(o2_dummy); + Opcode(o2_loadPalette384); + // 0x44 + Opcode(o2_setPalette384); + Opcode(o2_restoreBackBuffer); + Opcode(o2_backUpInventoryGfx); + Opcode(o2_disableSceneAnim); + // 0x48 + Opcode(o2_enableSceneAnim); + Opcode(o2_restoreInventoryGfx); + Opcode(o2_setSceneAnimPos2); + Opcode(o2_update); + // 0x4c + OpcodeUnImpl(); + Opcode(o2_fadeScenePal); + Opcode(o2_dummy); + Opcode(o2_dummy); + // 0x50 + Opcode(o2_enterNewSceneEx); + Opcode(o2_switchScene); + Opcode(o2_getShapeFlag1); + Opcode(o2_setPathfinderFlag); + // 0x54 + Opcode(o2_getSceneExitToFacing); + Opcode(o2_setLayerFlag); + Opcode(o2_setZanthiaPos); + Opcode(o2_loadMusicTrack); + // 0x58 + Opcode(o2_playWanderScoreViaMap); + Opcode(o2_playSoundEffect); + Opcode(o2_setSceneAnimPos); + Opcode(o2_blockInRegion); + // 0x5c + Opcode(o2_blockOutRegion); + OpcodeUnImpl(); + Opcode(o2_setCauldronState); + Opcode(o2_showItemString); + // 0x60 + Opcode(o2_getRand); + Opcode(o2_isAnySoundPlaying); + Opcode(o2_setDeathHandlerFlag); + Opcode(o2_setDrawNoShapeFlag); + // 0x64 + Opcode(o2_setRunFlag); + Opcode(o2_showLetter); + OpcodeUnImpl(); + Opcode(o2_fillRect); + // 0x68 + OpcodeUnImpl(); + OpcodeUnImpl(); + OpcodeUnImpl(); + Opcode(o2_waitForConfirmationClick); + // 0x6c + Opcode(o2_encodeShape); + Opcode(o2_defineRoomEntrance); + Opcode(o2_runTemporaryScript); + Opcode(o2_setSpecialSceneScriptRunTime); + // 0x70 + Opcode(o2_defineSceneAnim); + Opcode(o2_updateSceneAnim); + Opcode(o2_updateSceneAnim); + Opcode(o2_addToSceneAnimPosAndUpdate); + // 0x74 + Opcode(o2_useItemOnMainChar); + Opcode(o2_startDialogue); + Opcode(o2_zanthRandomChat); + Opcode(o2_setupDialogue); + // 0x78 + Opcode(o2_getDlgIndex); + Opcode(o2_defineRoom); + Opcode(o2_addCauldronStateTableEntry); + Opcode(o2_setCountDown); + // 0x7c + Opcode(o2_getCountDown); + Opcode(o2_dummy); + Opcode(o2_dummy); + Opcode(o2_pressColorKey); + // 0x80 + Opcode(o2_objectChat); + Opcode(o2_chapterChange); + Opcode(o2_getColorCodeFlag1); + Opcode(o2_setColorCodeFlag1); + // 0x84 + Opcode(o2_getColorCodeFlag2); + Opcode(o2_setColorCodeFlag2); + Opcode(o2_getColorCodeValue); + Opcode(o2_setColorCodeValue); + // 0x88 + Opcode(o2_countItemInstances); + Opcode(o2_removeItemFromScene); + Opcode(o2_initObject); + Opcode(o2_npcChat); + // 0x8c + Opcode(o2_deinitObject); + Opcode(o2_playTimSequence); + Opcode(o2_makeBookOrCauldronAppear); + Opcode(o2_setSpecialSceneScriptState); + // 0x90 + Opcode(o2_clearSpecialSceneScriptState); + Opcode(o2_querySpecialSceneScriptState); + Opcode(o2_resetInputColorCode); + Opcode(o2_setHiddenItemsEntry); + // 0x94 + Opcode(o2_getHiddenItemsEntry); + Opcode(o2_mushroomEffect); + Opcode(o2_wsaClose); + Opcode(o2_meanWhileScene); + // 0x98 + Opcode(o2_customChat); + Opcode(o2_customChatFinish); + Opcode(o2_setupSceneAnimation); + Opcode(o2_stopSceneAnimation); + // 0x9c + Opcode(o2_disableTimer); + Opcode(o2_enableTimer); + Opcode(o2_setTimerCountdown); + Opcode(o2_processPaletteIndex); + // 0xa0 + Opcode(o2_updateTwoSceneAnims); + Opcode(o2_getRainbowRoomData); + Opcode(o2_drawSceneShapeEx); + Opcode(o2_getBoolFromStack); + // 0xa4 + Opcode(o2_getSfxDriver); + Opcode(o2_getVocSupport); + Opcode(o2_getMusicDriver); + Opcode(o2_setVocHigh); + // 0xa8 + Opcode(o2_getVocHigh); + Opcode(o2_zanthiaChat); + Opcode(o2_isVoiceEnabled); + Opcode(o2_isVoicePlaying); + // 0xac + Opcode(o2_stopVoicePlaying); + Opcode(o2_getGameLanguage); + Opcode(o2_demoFinale); + Opcode(o2_dummy); + + SetOpcodeTable(_opcodesTemporary); + + // 0x00 + Opcode(o2t_defineNewShapes); + Opcode(o2t_setCurrentFrame); + Opcode(o2t_playSoundEffect); + Opcode(o2t_fadeScenePal); + // 0x04 + Opcode(o2t_setShapeFlag); + Opcode(o2_dummy); + + // ---- TIM opcodes + + // 0x00 + OpcodeTim(t2_initChat); + OpcodeTim(t2_updateSceneAnim); + OpcodeTim(t2_resetChat); + OpcodeTim(t2_playSoundEffect); +} + +} // end of namespace Kyra + + + + diff --git a/engines/kyra/script_mr.cpp b/engines/kyra/script_mr.cpp new file mode 100644 index 0000000000..de535148d1 --- /dev/null +++ b/engines/kyra/script_mr.cpp @@ -0,0 +1,1686 @@ +/* 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_mr.h" +#include "kyra/script.h" +#include "kyra/screen_mr.h" +#include "kyra/text_mr.h" +#include "kyra/wsamovie.h" +#include "kyra/timer.h" +#include "kyra/resource.h" + +#include "common/endian.h" + +namespace Kyra { + +int KyraEngine_MR::o3_getMalcolmShapes(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_getMaloclmShapes(%p) ()", (const void *)script); + return _malcolmShapes; +} + +int KyraEngine_MR::o3_setCharacterPos(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_setCharacterPos(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + int x = stackPos(0); + int y = stackPos(1); + + if (x != -1 && y != -1) { + x &= ~3; + y &= ~1; + } + + _mainCharacter.x1 = _mainCharacter.x2 = x; + _mainCharacter.y1 = _mainCharacter.y2 = y; + + return 0; +} + +int KyraEngine_MR::o3_defineObject(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_defineObject(%p) (%d, '%s', %d, %d, %d, %d, %d, %d)", (const void *)script, + stackPos(0), stackPosString(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7)); + TalkObject &obj = _talkObjectList[stackPos(0)]; + strcpy(obj.filename, stackPosString(1)); + obj.sceneAnim = stackPos(2); + obj.sceneScript = stackPos(3); + obj.x = stackPos(4); + obj.y = stackPos(5); + obj.color = stackPos(6); + obj.sceneId = stackPos(7); + return 0; +} + +int KyraEngine_MR::o3_refreshCharacter(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_refreshCharacter(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); + const int frame = stackPos(0); + const int facing = stackPos(1); + const bool updateNeed = stackPos(2) != 0; + + if (facing >= 0) + _mainCharacter.facing = facing; + + if (frame >= 0 && frame != 87) + _mainCharacter.animFrame = _characterFrameTable[_mainCharacter.facing]; + else + _mainCharacter.animFrame = 87; + + updateCharacterAnim(0); + + if (updateNeed) + refreshAnimObjectsIfNeed(); + return 0; +} + +int KyraEngine_MR::o3_getCharacterX(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_getCharacterX(%p) ()", (const void *)script); + return _mainCharacter.x1; +} + +int KyraEngine_MR::o3_getCharacterY(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_getCharacterY(%p) ()", (const void *)script); + return _mainCharacter.y1; +} + +int KyraEngine_MR::o3_getCharacterFacing(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_getCharacterFacing(%p) ()", (const void *)script); + return _mainCharacter.facing; +} + +int KyraEngine_MR::o3_getCharacterScene(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_getCharacterScene(%p) ()", (const void *)script); + return _mainCharacter.sceneId; +} + +int KyraEngine_MR::o3_getMalcolmsMood(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_getMalcolmsMood(%p) ()", (const void *)script); + return _malcolmsMood; +} + +int KyraEngine_MR::o3_getCharacterFrameFromFacing(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_getCharacterFrameFromFacing(%p) ()", (const void *)script); + return _characterFrameTable[_mainCharacter.facing]; +} + +int KyraEngine_MR::o3_setCharacterFacingOverwrite(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_setCharacterFacingOverwrite(%p) (%d)", (const void *)script, stackPos(0)); + _mainCharacter.facing = stackPos(0); + _overwriteSceneFacing = true; + return 0; +} + +int KyraEngine_MR::o3_trySceneChange(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_trySceneChange(%p) (%d, %d, %d, %d)", (const void *)script, + stackPos(0), stackPos(1), stackPos(2), stackPos(3)); + + _unkHandleSceneChangeFlag = 1; + int success = inputSceneChange(stackPos(0), stackPos(1), stackPos(2), stackPos(3)); + _unkHandleSceneChangeFlag = 0; + + if (success) { + _emc->init(script, script->dataPtr); + _unk4 = 0; + _unk3 = -1; + _unk5 = 1; + return 0; + } else { + return (_unk4 != 0) ? 1 : 0; + } +} + +int KyraEngine_MR::o3_moveCharacter(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_moveCharacter(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); + moveCharacter(stackPos(0), stackPos(1), stackPos(2)); + return 0; +} + +int KyraEngine_MR::o3_setCharacterFacing(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_setCharacterFacing(%p) (%d)", (const void *)script, stackPos(0)); + _mainCharacter.facing = stackPos(0); + return 0; +} + +int KyraEngine_MR::o3_showSceneFileMessage(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_showSceneFileMessage(%p) (%d)", (const void *)script, stackPos(0)); + showMessage((const char*)getTableEntry(_scenesFile, stackPos(0)), 0xFF, 0xF0); + return 0; +} + +int KyraEngine_MR::o3_setCharacterAnimFrameFromFacing(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_setCharacterAnimFrameFromFacing(%p) ()", (const void *)script); + updateCharPal(0); + _mainCharacter.animFrame = _characterFrameTable[_mainCharacter.facing]; + updateCharacterAnim(0); + refreshAnimObjectsIfNeed(); + return 0; +} + +int KyraEngine_MR::o3_showBadConscience(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_showBadConscience(%p) ()", (const void *)script); + showBadConscience(); + return 0; +} + +int KyraEngine_MR::o3_hideBadConscience(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_hideBadConscience(%p) ()", (const void *)script); + hideBadConscience(); + return 0; +} + +int KyraEngine_MR::o3_setInventorySlot(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_setInventorySlot(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + const int slot = MAX(0, MIN(10, stackPos(0))); + return (_mainCharacter.inventory[slot] = stackPos(1)); +} + +int KyraEngine_MR::o3_getInventorySlot(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_getInventorySlot(%p) (%d)", (const void *)script, stackPos(0)); + return _mainCharacter.inventory[stackPos(0)]; +} + +int KyraEngine_MR::o3_addItemToInventory(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_addItemToInventory(%p) (%d)", (const void *)script, stackPos(0)); + int slot = findFreeInventorySlot(); + if (slot >= 0) { + _mainCharacter.inventory[slot] = stackPos(0); + if (_inventoryState) { + _screen->hideMouse(); + redrawInventory(0); + _screen->showMouse(); + } + } + return slot; +} + +int KyraEngine_MR::o3_addItemToCurScene(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_addItemToCurScene(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); + const uint16 item = stackPos(0); + int x = stackPos(1); + int y = stackPos(2); + int itemSlot = findFreeItem(); + + if (x < 20) + x = 20; + else if (x > 299) + x = 299; + + if (y < 18) + y = 18; + else if (y > 187) + y = 187; + + if (itemSlot >= 0) { + _itemList[itemSlot].x = x; + _itemList[itemSlot].y = y; + _itemList[itemSlot].id = item; + _itemList[itemSlot].sceneId = _mainCharacter.sceneId; + addItemToAnimList(itemSlot); + refreshAnimObjectsIfNeed(); + } + + return itemSlot; +} + +int KyraEngine_MR::o3_objectChat(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_objectChat(%p) (%d)", (const void *)script, stackPos(0)); + int id = stackPos(0); + const char *str = (const char*)getTableEntry(_useActorBuffer ? _actorFile : _sceneStrings, id); + if (str) { + objectChat(str, 0, _vocHigh, id); + playStudioSFX(str); + } + return 0; +} + +int KyraEngine_MR::o3_checkForItem(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_checkForItem(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + return findItem(stackPos(0), stackPos(1)) == -1 ? 0 : 1; +} + +int KyraEngine_MR::o3_resetInventory(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_resetInventory(%p) ()", (const void *)script); + memset(_mainCharacter.inventory, -1, sizeof(_mainCharacter.inventory)); + return 0; +} + +int KyraEngine_MR::o3_defineItem(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_defineItem(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); + int freeItem = findFreeItem(); + if (freeItem != -1) { + _itemList[freeItem].id = stackPos(0); + _itemList[freeItem].x = stackPos(1); + _itemList[freeItem].y = stackPos(2); + _itemList[freeItem].sceneId = stackPos(3); + } + return freeItem; +} + +int KyraEngine_MR::o3_removeInventoryItemInstances(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_removeInventoryItemInstances(%p) (%d)", (const void *)script, stackPos(0)); + const int item = stackPos(0); + for (int i = 0; i < 10; ++i) { + if (_mainCharacter.inventory[i] == item) + _mainCharacter.inventory[i] = 0xFFFF; + } + return 0; +} + +int KyraEngine_MR::o3_countInventoryItemInstances(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_countInventoryItemInstances(%p) (%d)", (const void *)script, stackPos(0)); + const int item = stackPos(0); + int count = 0; + + for (int i = 0; i < 10; ++i) { + if (_mainCharacter.inventory[i] == item) + ++count; + } + + if (_itemInHand == item) + ++count; + + return count; +} + +int KyraEngine_MR::o3_npcChatSequence(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_npcChatSequence(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + const int id = stackPos(0); + const char *str = (const char*)getTableEntry(_sceneStrings, id); + if (str) + npcChatSequence(str, stackPos(1), _vocHigh, id); + return 0; +} + +int KyraEngine_MR::o3_queryGameFlag(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_queryGameFlag(%p) (%d)", (const void *)script, stackPos(0)); + return queryGameFlag(stackPos(0)); +} + +int KyraEngine_MR::o3_resetGameFlag(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_resetGameFlag(%p) (%d)", (const void *)script, stackPos(0)); + resetGameFlag(stackPos(0)); + return 0; +} + +int KyraEngine_MR::o3_setGameFlag(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_setGameFlag(%p) (%d)", (const void *)script, stackPos(0)); + setGameFlag(stackPos(0)); + return 1; +} + +int KyraEngine_MR::o3_setHandItem(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_setHandItem(%p) (%d)", (const void *)script, stackPos(0)); + setHandItem(stackPos(0)); + return 0; +} + +int KyraEngine_MR::o3_removeHandItem(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_removeHandItem(%p) ()", (const void *)script); + removeHandItem(); + return 0; +} + +int KyraEngine_MR::o3_handItemSet(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_handItemSet(%p) ()", (const void *)script); + return _handItemSet; +} + +int KyraEngine_MR::o3_hideMouse(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_hideMouse(%p) ()", (const void *)script); + _screen->hideMouse(); + return 0; +} + +int KyraEngine_MR::o3_addSpecialExit(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_addSpecialExit(%p) (%d, %d, %d, %d, %d)", (const void *)script, + stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); + if (_specialExitCount < 5) { + _specialExitTable[_specialExitCount+0] = stackPos(0); + _specialExitTable[_specialExitCount+5] = stackPos(1); + _specialExitTable[_specialExitCount+10] = stackPos(2) + stackPos(0) - 1; + _specialExitTable[_specialExitCount+15] = stackPos(3) + stackPos(1) - 1; + _specialExitTable[_specialExitCount+20] = stackPos(4); + ++_specialExitCount; + } + return 0; +} + +int KyraEngine_MR::o3_setMousePos(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_setMousePos(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + setMousePos(stackPos(0), stackPos(1)); + return 0; +} + +int KyraEngine_MR::o3_showMouse(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_showMouse(%p) ()", (const void *)script); + _screen->showMouse(); + return 0; +} + +int KyraEngine_MR::o3_badConscienceChat(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_badConscienceChat(%p) (%d)", (const void *)script, stackPos(0)); + int id = stackPos(0); + const char *str = (const char*)getTableEntry(_useActorBuffer ? _actorFile : _sceneStrings, id); + badConscienceChat(str, _vocHigh, id); + return 0; +} + +int KyraEngine_MR::o3_wipeDownMouseItem(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o3_wipeDownMouseItem(%p) (-, %d, %d)", (const void *)script, stackPos(1), stackPos(2)); + _screen->hideMouse(); + const int x = stackPos(1) - 12; + const int y = stackPos(2) - 19; + + if (_itemInHand >= 0) { + backUpGfxRect32x32(x, y); + uint8 *shape = getShapePtr(_itemInHand+248); + for (int curY = y, height = 20; height > 0; height -= 2, curY += 2) { + restoreGfxRect32x32(x, y); + _screen->setNewShapeHeight(shape, height); + uint32 waitTime = _system->getMillis() + _tickLength; + _screen->drawShape(0, shape, x, curY, 0, 0); + _screen->updateScreen(); + delayUntil(waitTime); + } + restoreGfxRect32x32(x, y); + _screen->resetShapeHeight(shape); + } + + _screen->showMouse(); + removeHandItem(); + + return 0; +} + +int KyraEngine_MR::o3_setMalcolmsMood(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_setMalcolmsMood(%p) (%d)", (const void *)script, stackPos(0)); + return (_malcolmsMood = stackPos(0)); +} + +int KyraEngine_MR::o3_delay(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_delay(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + if (stackPos(1)) { + uint32 maxWaitTime = _system->getMillis() + stackPos(0) * _tickLength; + while (_system->getMillis() < maxWaitTime) { + int inputFlag = checkInput(0); + removeInputTop(); + + if (inputFlag == 198 || inputFlag == 199) + return 1; + + if (_chatText) + updateWithText(); + else + update(); + _system->delayMillis(10); + } + } else { + delay(stackPos(0) * _tickLength, true); + } + return 0; +} + +int KyraEngine_MR::o3_updateScore(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_updateScore(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + return updateScore(stackPos(0), stackPos(1)) ? 1 : 0; +} + +int KyraEngine_MR::o3_makeSecondChanceSave(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_makeSecondChanceSave(%p) ()", (const void *)script); + saveGame(getSavegameFilename(999), "SECOND CHANCE SAVE GAME"); + return 0; +} + +int KyraEngine_MR::o3_setSceneFilename(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_setSceneFilename(%p) (%d, '%s')", (const void *)script, stackPos(0), stackPosString(1)); + strcpy(_sceneList[stackPos(0)].filename1, stackPosString(1)); + _sceneList[stackPos(0)].filename1[9] = 0; + return 0; +} + +int KyraEngine_MR::o3_removeItemsFromScene(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_removeItemsFromScene(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); + const uint16 itemId = stackPos(0); + const uint16 sceneId = stackPos(1); + const bool allItems = (stackPos(2) != 0); + + int retValue = 0; + + for (int i = 0; i < 50; ++i) { + if (_itemList[i].sceneId == sceneId && _itemList[i].id == itemId) { + resetItem(i); + retValue = 1; + if (!allItems) + return 1; + } + } + + return retValue; +} + +int KyraEngine_MR::o3_disguiseMalcolm(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o3_disguiseMalcolm(%p) (%d)", (const void *)script, stackPos(0)); + loadMalcolmShapes(stackPos(0)); + updateDlgIndex(); + return 0; +} + +int KyraEngine_MR::o3_drawSceneShape(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o3_drawSceneShape(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + + int shape = stackPos(0); + int flag = (stackPos(1) != 0) ? 1 : 0; + + _screen->hideMouse(); + restorePage3(); + + const int x = _sceneShapeDescs[shape].drawX; + const int y = _sceneShapeDescs[shape].drawY; + + _screen->drawShape(2, _sceneShapes[shape], x, y, 2, flag); + + _screen->copyRegionToBuffer(3, 0, 0, 320, 200, _gamePlayBuffer); + + _screen->drawShape(0, _sceneShapes[shape], x, y, 2, flag); + + flagAnimObjsForRefresh(); + refreshAnimObjectsIfNeed(); + _screen->showMouse(); + return 0; +} + +int KyraEngine_MR::o3_drawSceneShapeOnPage(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_drawSceneShapeOnPage(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); + const int shape = stackPos(0); + + int x = _sceneShapeDescs[shape].drawX; + int y = _sceneShapeDescs[shape].drawY; + _screen->drawShape(stackPos(2), _sceneShapes[shape], x, y, 2, (stackPos(1) != 0) ? 1 : 0); + return 0; +} + +int KyraEngine_MR::o3_checkInRect(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_checkInRect(%p) (%d, %d, %d, %d, %d, %d)", (const void *)script, + stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5)); + const int x1 = stackPos(0); + const int y1 = stackPos(1); + const int x2 = stackPos(2); + const int y2 = stackPos(3); + int x = stackPos(4), y = stackPos(5); + if (_itemInHand >= 0) { + const int8 *desc = &_itemBuffer2[_itemInHand*2]; + x -= 12; + x += desc[0]; + y -= 19; + y += desc[1]; + } + + if (x >= x1 && x <= x2 && y >= y1 && y <= y2) { + //XXX + return 1; + } else { + //XXX + return 0; + } +} + +int KyraEngine_MR::o3_updateConversations(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_updateConversations(%p) (%d)", (const void *)script, stackPos(0)); + int dlgIndex = stackPos(0); + switch (_currentChapter-2) { + case 0: + dlgIndex -= 34; + break; + + case 1: + dlgIndex -= 54; + break; + + case 2: + dlgIndex -= 55; + break; + + case 3: + dlgIndex -= 70; + break; + + default: + break; + } + + int convs[4]; + Common::set_to(convs, convs+4, -1); + + if (_currentChapter == 1) { + switch (_mainCharacter.dlgIndex) { + case 0: + convs[0] = 6; + convs[1] = 12; + break; + + case 2: + convs[0] = 8; + convs[1] = 14; + break; + + case 3: + convs[0] = 9; + convs[1] = 15; + break; + + case 4: + convs[0] = 10; + convs[1] = 16; + break; + + case 5: + convs[0] = 11; + convs[1] = 17; + break; + + case 6: + convs[0] = 0; + convs[1] = 12; + break; + + case 8: + convs[0] = 2; + convs[1] = 14; + break; + + case 9: + convs[0] = 3; + convs[1] = 15; + break; + + case 10: + convs[0] = 4; + convs[1] = 16; + break; + + case 11: + convs[0] = 5; + convs[1] = 17; + break; + + case 12: + convs[0] = 0; + convs[1] = 6; + break; + + case 14: + convs[0] = 2; + convs[1] = 8; + break; + + case 15: + convs[0] = 3; + convs[1] = 9; + break; + + case 16: + convs[0] = 4; + convs[1] = 10; + break; + + case 17: + convs[0] = 5; + convs[1] = 11; + break; + + default: + break; + } + } else if (_currentChapter == 2) { + switch (_mainCharacter.dlgIndex) { + case 0: + convs[0] = 4; + convs[1] = 8; + convs[2] = 5; + convs[3] = 9; + break; + + case 1: + convs[0] = 4; + convs[1] = 8; + convs[2] = 0; + convs[3] = 5; + break; + + case 2: + convs[0] = 6; + convs[2] = 11; + break; + + case 3: + convs[0] = 7; + convs[2] = 12; + break; + + case 4: + convs[0] = 0; + convs[1] = 8; + convs[2] = 1; + convs[3] = 9; + break; + + case 5: + convs[0] = 0; + convs[1] = 8; + convs[2] = 4; + convs[3] = 1; + break; + + case 6: + convs[0] = 2; + convs[1] = 10; + break; + + case 7: + convs[0] = 3; + convs[1] = 11; + break; + + case 8: + convs[0] = 0; + convs[1] = 4; + convs[2] = 1; + break; + + case 9: + convs[0] = 0; + convs[1] = 4; + convs[2] = 0; + convs[4] = 1; + break; + + case 10: + convs[0] = 2; + convs[1] = 6; + break; + + case 11: + convs[0] = 3; + convs[1] = 7; + break; + + default: + break; + } + } else if (_currentChapter == 4) { + if (_malcolmsMood == 0) { + convs[0] = _mainCharacter.dlgIndex - 10; + convs[1] = _mainCharacter.dlgIndex - 5; + } else if (_malcolmsMood == 1) { + convs[0] = _mainCharacter.dlgIndex + 5; + convs[1] = _mainCharacter.dlgIndex + 10; + } else if (_malcolmsMood == 2) { + convs[0] = _mainCharacter.dlgIndex - 5; + convs[1] = _mainCharacter.dlgIndex + 5; + } + } + + for (int i = 0; i < 4; ++i) { + if (convs[i] != -1) + _conversationState[dlgIndex][convs[i]] = 0; + } + + return 1; +} + +int KyraEngine_MR::o3_setSceneDim(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_setSceneDim(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + _sceneMinX = stackPos(0); + _sceneMaxX = stackPos(1); + return 0; +} + +int KyraEngine_MR::o3_setSceneAnimPosAndFrame(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_setSceneAnimPosAndFrame(%p) (%d, %d, %d, %d, %d, %d)", (const void *)script, + stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5)); + SceneAnim &anim = _sceneAnims[stackPos(0)]; + const int newX2 = stackPos(1); + const int newY2 = stackPos(2); + const int newX = stackPos(3); + const int newY = stackPos(4); + + if (newX2 >= 0) + anim.x2 = newX2; + if (newY2 >= 0) + anim.y2 = newY2; + + if (newX >= 0) + anim.x = newX; + else + anim.x = anim.x2 + (anim.width >> 1); + + if (newY >= 0) + anim.y = newY; + else + anim.y = anim.y2 + anim.height - 1; + + updateSceneAnim(stackPos(0), stackPos(5)); + _specialSceneScriptRunFlag = false; + return 0; +} + +int KyraEngine_MR::o3_update(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_update(%p) (%d)", (const void *)script, stackPos(0)); + for (int times = stackPos(0); times != 0; --times) { + if (_chatText) + updateWithText(); + else + update(); + } + return 0; +} + +int KyraEngine_MR::o3_removeItemInstances(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_removeItemInstances(%p) (%d)", (const void *)script, stackPos(0)); + const int16 item = stackPos(0); + + int deleted = 0; + + for (int i = 0; i < 10; ++i) { + if (_mainCharacter.inventory[i] == item) { + _mainCharacter.inventory[i] = 0xFFFF; + ++deleted; + } + } + + if (_itemInHand == item) { + removeHandItem(); + ++deleted; + } + + for (int i = 0; i < 50; ++i) { + if (_itemList[i].id == item) { + _itemList[i].id = 0xFFFF; + ++deleted; + } + } + + return deleted; +} + +int KyraEngine_MR::o3_disableInventory(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_disableInventory(%p) ()", (const void *)script); + _enableInventory = false; + return 0; +} + +int KyraEngine_MR::o3_enableInventory(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_enableInventory(%p) ()", (const void *)script); + _enableInventory = true; + return 1; +} + +int KyraEngine_MR::o3_enterNewScene(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_enterNewScene(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), + stackPos(1), stackPos(2), stackPos(3), stackPos(4)); + + _screen->hideMouse(); + enterNewScene(stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); + + _unk5 = 1; + + if (_mainCharX == -1 || _mainCharY == -1) { + _mainCharacter.animFrame = _characterFrameTable[_mainCharacter.facing]; + updateCharacterAnim(0); + } + _screen->showMouse(); + + return 0; +} + +int KyraEngine_MR::o3_switchScene(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_switchScene(%p) (%d)", (const void *)script, stackPos(0)); + setGameFlag(1); + _mainCharX = _mainCharacter.x1; + _mainCharY = _mainCharacter.y1; + _noScriptEnter = false; + enterNewScene(stackPos(0), _mainCharacter.facing, 0, 0, 0); + _noScriptEnter = true; + return 0; +} + +int KyraEngine_MR::o3_getShapeFlag1(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_getShapeFlag1(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + return _screen->getShapeFlag1(stackPos(0), stackPos(1)); +} + +int KyraEngine_MR::o3_setMalcolmPos(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_setMalcolmPos(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + _mainCharX = stackPos(0); + _mainCharY = stackPos(1); + + if (_mainCharX == -1 && _mainCharY == -1) + _mainCharacter.animFrame = 87; + else + _mainCharacter.animFrame = _characterFrameTable[_mainCharacter.facing]; + + return 0; +} + +int KyraEngine_MR::o3_stopMusic(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_stopMusic(%p) ()", (const void *)script); + stopMusicTrack(); + return 0; +} + +int KyraEngine_MR::o3_playWanderScoreViaMap(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_playWanderScoreViaMap(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + snd_playWanderScoreViaMap(stackPos(0), stackPos(1)); + return 0; +} + +int KyraEngine_MR::o3_playSoundEffect(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_playSoundEffect(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + snd_playSoundEffect(stackPos(0), stackPos(1)); + return 0; +} + +int KyraEngine_MR::o3_getScore(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_getScore(%p) ()", (const void *)script); + return _score; +} + +int KyraEngine_MR::o3_blockOutRegion(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_blockOutRegion(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); + const int x1 = stackPos(0); + int y1 = stackPos(1); + const int x2 = stackPos(2); + int y2 = stackPos(3); + + if (y1 < _maskPageMinY) + y1 = _maskPageMinY; + if (y2 > _maskPageMaxY) + y2 = _maskPageMaxY; + + _screen->blockOutRegion(x1, y1, x2-x1+1, y2-y1+1); + return 0; +} + +int KyraEngine_MR::o3_showSceneStringsMessage(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_showSceneStringsMessage(%p) (%d)", (const void *)script, stackPos(0)); + showMessage((const char*)getTableEntry(_sceneStrings, stackPos(0)), 0xFF, 0xF0); + return 0; +} + +int KyraEngine_MR::o3_getRand(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_getRand(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + assert(stackPos(0) < stackPos(1)); + return _rnd.getRandomNumberRng(stackPos(0), stackPos(1)); +} + +int KyraEngine_MR::o3_setDeathHandler(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_setDeathHandler(%p) (%d)", (const void *)script, stackPos(0)); + _deathHandler = stackPos(0); + return 0; +} + +int KyraEngine_MR::o3_showGoodConscience(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_showGoodConscience(%p) ()", (const void *)script); + showGoodConscience(); + return 0; +} + +int KyraEngine_MR::o3_goodConscienceChat(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_goodConscienceChat(%p) (%d)", (const void *)script, stackPos(0)); + int id = stackPos(0); + const char *str = (const char*)getTableEntry(_useActorBuffer ? _actorFile : _sceneStrings, id); + goodConscienceChat(str, _vocHigh, id); + return 0; +} + +int KyraEngine_MR::o3_hideGoodConscience(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_hideGoodConscience(%p) ()", (const void *)script); + hideGoodConscience(); + return 0; +} + +int KyraEngine_MR::o3_waitForConfirmationClick(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o2_waitForConfirmationClick(%p) (%d)", (const void *)script, stackPos(0)); + resetSkipFlag(); + uint32 maxWaitTime = _system->getMillis() + stackPos(0) * _tickLength; + + while (_system->getMillis() < maxWaitTime) { + int inputFlag = checkInput(0); + removeInputTop(); + + if (inputFlag == 198 || inputFlag == 199) { + _sceneScriptState.regs[1] = _mouseX; + _sceneScriptState.regs[2] = _mouseY; + return 0; + } + + update(); + _system->delayMillis(10); + } + + _sceneScriptState.regs[1] = _mouseX; + _sceneScriptState.regs[2] = _mouseY; + return 1; +} + +int KyraEngine_MR::o3_defineRoomEntrance(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_defineRoomEntrance(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); + switch (stackPos(0)) { + case 0: + _sceneEnterX1 = stackPos(1); + _sceneEnterY1 = stackPos(2); + break; + + case 1: + _sceneEnterX2 = stackPos(1); + _sceneEnterY2 = stackPos(2); + break; + + case 2: + _sceneEnterX3 = stackPos(1); + _sceneEnterY3 = stackPos(2); + break; + + case 3: + _sceneEnterX4 = stackPos(1); + _sceneEnterY4 = stackPos(2); + break; + + default: + break; + } + return 0; +} + +int KyraEngine_MR::o3_runTemporaryScript(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_runTemporaryScript(%p) ('%s', %d, %d, %d)", (const void *)script, + stackPosString(0), stackPos(1), stackPos(2), stackPos(3)); + const int newShapes = stackPos(1); + const int unloadShapes = stackPos(2); + const int allowSkip = stackPos(3); + runTemporaryScript(stackPosString(0), allowSkip, (unloadShapes != 0) ? 1 : 0, newShapes, unloadShapes); + return 0; +} + +int KyraEngine_MR::o3_setSpecialSceneScriptRunTime(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_setSpecialSceneScriptRunTime(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + assert(stackPos(0) >= 0 && stackPos(0) < 10); + _sceneSpecialScriptsTimer[stackPos(0)] = _system->getMillis() + stackPos(1) * _tickLength; + return 0; +} + +int KyraEngine_MR::o3_defineSceneAnim(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_defineSceneAnim(%p) (%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, '%s')", + (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7), + stackPos(8), stackPos(9), stackPos(10), stackPos(11), stackPosString(12)); + const int animId = stackPos(0); + SceneAnim &anim = _sceneAnims[animId]; + + musicUpdate(0); + + uint16 flags = anim.flags = stackPos(1); + int x = anim.x = stackPos(2); + int y = anim.y = stackPos(3); + int x2 = anim.x2 = stackPos(4); + int y2 = anim.y2 = stackPos(5); + int w = anim.width = stackPos(6); + int h = anim.height = stackPos(7); + anim.specialSize = stackPos(9); + anim.shapeIndex = stackPos(11); + const char *filename = stackPosString(12); + + if (filename) + strcpy(anim.filename, filename); + + if (flags & 8) { + _sceneAnimMovie[animId]->open(filename, 1, 0); + musicUpdate(0); + if (_sceneAnimMovie[animId]->opened()) { + anim.wsaFlag = 1; + if (x2 == -1) + x2 = _sceneAnimMovie[animId]->xAdd(); + if (y2 == -1) + y2 = _sceneAnimMovie[animId]->yAdd(); + if (w == -1) + w = _sceneAnimMovie[animId]->width(); + if (h == -1) + h = _sceneAnimMovie[animId]->height(); + if (x == -1) + x = (w >> 1) + x2; + if (y == -1) + y = y2 + h - 1; + + anim.x = x; + anim.y = y; + anim.x2 = x2; + anim.y2 = y2; + anim.width = w; + anim.height = h; + } + } + + musicUpdate(0); + + return 9; +} + +int KyraEngine_MR::o3_updateSceneAnim(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_updateSceneAnim(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + updateSceneAnim(stackPos(0), stackPos(1)); + _specialSceneScriptRunFlag = false; + return 0; +} + +int KyraEngine_MR::o3_runActorScript(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_runActorScript(%p) ()", (const void *)script); + EMCData data; + EMCState state; + memset(&data, 0, sizeof(data)); + memset(&state, 0, sizeof(state)); + + _res->exists("_ACTOR.EMC", true); + _emc->load("_ACTOR.EMC", &data, &_opcodes); + _emc->init(&state, &data); + _emc->start(&state, 0); + + state.regs[4] = _itemInHand; + state.regs[0] = _mainCharacter.sceneId; + + int vocHigh = _vocHigh; + _vocHigh = 200; + _useActorBuffer = true; + + while (_emc->isValid(&state)) + _emc->run(&state); + + _useActorBuffer = false; + _vocHigh = vocHigh; + _emc->unload(&data); + + if (queryGameFlag(0x218)) { + resetGameFlag(0x218); + enterNewScene(78, -1, 0, 0, 0); + } + + return 0; +} + +int KyraEngine_MR::o3_runDialog(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_runDialog(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + runDialog(stackPos(0), stackPos(1)); + return 0; +} + +int KyraEngine_MR::o3_malcolmRandomChat(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_malcolmRandomChat(%p) ()", (const void *)script); + malcolmRandomChat(); + return 0; +} + +int KyraEngine_MR::o3_setDlgIndex(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_setDlgIndex(%p) (%d)", (const void *)script, stackPos(0)); + setDlgIndex(stackPos(0)); + return 0; +} + +int KyraEngine_MR::o3_getDlgIndex(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_getDlgIndex(%p) ()", (const void *)script); + return _mainCharacter.dlgIndex; +} + +int KyraEngine_MR::o3_defineScene(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_defineScene(%p) (%d, '%s', %d, %d, %d, %d, %d, %d)", + (const void *)script, stackPos(0), stackPosString(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7)); + const int scene = stackPos(0); + strcpy(_sceneList[scene].filename1, stackPosString(1)); + _sceneList[scene].filename1[9] = 0; + strcpy(_sceneList[scene].filename2, stackPosString(1)); + _sceneList[scene].filename2[9] = 0; + + _sceneList[scene].exit1 = stackPos(2); + _sceneList[scene].exit2 = stackPos(3); + _sceneList[scene].exit3 = stackPos(4); + _sceneList[scene].exit4 = stackPos(5); + _sceneList[scene].flags = stackPos(6); + _sceneList[scene].sound = stackPos(7); + + if (_mainCharacter.sceneId == scene) { + _sceneExit1 = _sceneList[scene].exit1; + _sceneExit2 = _sceneList[scene].exit2; + _sceneExit3 = _sceneList[scene].exit3; + _sceneExit4 = _sceneList[scene].exit4; + } + + return 0; +} + +int KyraEngine_MR::o3_setConversationState(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_setConversationState(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); + int id = stackPos(0); + const int dlgIndex = stackPos(1); + const int value = stackPos(2); + + switch (_currentChapter-2) { + case 0: + id -= 34; + break; + + case 1: + id -= 54; + break; + + case 2: + id -= 55; + break; + + case 3: + id -= 70; + break; + + default: + break; + } + + return (_conversationState[id][dlgIndex] = value); +} + +int KyraEngine_MR::o3_getConversationState(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_getConversationState(%p) (%d)", (const void *)script, stackPos(0)); + int id = stackPos(0); + const int dlgIndex = _mainCharacter.dlgIndex; + + switch (_currentChapter-2) { + case 0: + id -= 34; + break; + + case 1: + id -= 54; + break; + + case 2: + id -= 55; + break; + + case 3: + id -= 70; + break; + + default: + break; + } + + return _conversationState[id][dlgIndex]; +} + +int KyraEngine_MR::o3_changeChapter(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_changeChapter(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); + changeChapter(stackPos(0), stackPos(1), stackPos(2), stackPos(3)); + return 0; +} + +int KyraEngine_MR::o3_countItemInstances(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_countItemInstances(%p) (%d)", (const void *)script, stackPos(0)); + int count = 0; + const int16 item = stackPos(0); + + for (int i = 0; i < 10; ++i) { + if (_mainCharacter.inventory[i] == item) + ++count; + } + + if (_itemInHand == item) + ++count; + + for (int i = 0; i < 50; ++i) { + if (_itemList[i].id == item) + ++count; + } + + return count; +} + +int KyraEngine_MR::o3_dialogStartScript(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_dialogStartScript(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + dialogStartScript(stackPos(0), stackPos(1)); + return 0; +} + +int KyraEngine_MR::o3_dialogEndScript(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_dialogEndScript(%p) (%d)", (const void *)script, stackPos(0)); + dialogEndScript(stackPos(0)); + return 0; +} + +int KyraEngine_MR::o3_setSpecialSceneScriptState(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_setSpecialSceneScriptState(%p) (%d)", (const void *)script, stackPos(0)); + _specialSceneScriptState[stackPos(0)] = 1; + return 1; +} + +int KyraEngine_MR::o3_clearSpecialSceneScriptState(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_clearSpecialSceneScriptState(%p) (%d)", (const void *)script, stackPos(0)); + _specialSceneScriptState[stackPos(0)] = 0; + return 0; +} + +int KyraEngine_MR::o3_querySpecialSceneScriptState(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_querySpecialSceneScriptState(%p) (%d)", (const void *)script, stackPos(0)); + return _specialSceneScriptState[stackPos(0)]; +} + +int KyraEngine_MR::o3_setHiddenItemsEntry(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_setHiddenItemsEntry(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + return (_hiddenItems[stackPos(0)] = (uint16)stackPos(1)); +} + +int KyraEngine_MR::o3_getHiddenItemsEntry(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_getHiddenItemsEntry(%p) (%d)", (const void *)script, stackPos(0)); + return (int16)_hiddenItems[stackPos(0)]; +} + +int KyraEngine_MR::o3_customChat(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_customChat(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + const int id = stackPos(0); + const int object = stackPos(1); + const char *str = (const char *)getTableEntry(_sceneStrings, id); + + if (!str) + return 0; + + strcpy(_stringBuffer, str); + _chatText = _stringBuffer; + _chatObject = object; + _chatVocHigh = _chatVocLow = -1; + objectChatInit(_stringBuffer, object, _vocHigh, id); + playVoice(_vocHigh, id); + return 0; +} + +int KyraEngine_MR::o3_customChatFinish(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_customChatFinish(%p) ()", (const void *)script); + _text->restoreScreen(); + _chatText = 0; + _chatObject = -1; + return 0; +} + +int KyraEngine_MR::o3_setupSceneAnimObject(EMCState *script) { + debugC(9, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_setupSceneAnimObject(%p) (%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, '%s')", (const void *)script, + stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7), stackPos(8), stackPos(9), + stackPos(10), stackPos(11), stackPosString(12)); + musicUpdate(0); + setupSceneAnimObject(stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7), stackPos(8), + stackPos(9), stackPos(10), stackPos(11), stackPosString(12)); + return 0; +} + +int KyraEngine_MR::o3_removeSceneAnimObject(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_removeSceneAnimObject(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + removeSceneAnimObject(stackPos(0), stackPos(1)); + return 0; +} + +int KyraEngine_MR::o3_disableTimer(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_disableTimer(%p) (%d)", (const void *)script, stackPos(0)); + _timer->disable(stackPos(0)); + return 0; +} + +int KyraEngine_MR::o3_enableTimer(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_enableTimer(%p) (%d)", (const void *)script, stackPos(0)); + _timer->enable(stackPos(0)); + return 0; +} + +int KyraEngine_MR::o3_setTimerCountdown(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_setTimerCountdown(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + _timer->setCountdown(stackPos(0), stackPos(1)); + return 0; +} + +int KyraEngine_MR::o3_setVocHigh(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_setVocHigh(%p) (%d)", (const void *)script, stackPos(0)); + _vocHigh = stackPos(0); + return 0; +} + +int KyraEngine_MR::o3_getVocHigh(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_getVocHigh(%p) ()", (const void *)script); + return _vocHigh; +} + +int KyraEngine_MR::o3_dummy(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_dummy(%p) ()", (const void *)script); + return 0; +} + +#pragma mark - + +int KyraEngine_MR::o3t_defineNewShapes(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3t_defineNewShapes(%p) ('%s', %d, %d, %d, %d, %d)", (const void *)script, + stackPosString(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5)); + strcpy(_newShapeFilename, stackPosString(0)); + _newShapeLastEntry = stackPos(1); + _newShapeWidth = stackPos(2); + _newShapeHeight = stackPos(3); + _newShapeXAdd = stackPos(4); + _newShapeYAdd = stackPos(5); + return 0; +} + +int KyraEngine_MR::o3t_setCurrentFrame(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3t_setCurrentFrame(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + static const uint8 frameTable[] = { + 0x58, 0xD8, 0xD8, 0x98, 0x78, 0x78, 0xB8, 0xB8 + }; + + _newShapeAnimFrame = stackPos(0); + if (_useFrameTable) + _newShapeAnimFrame += frameTable[_mainCharacter.facing]; + + _newShapeDelay = stackPos(1); + _temporaryScriptExecBit = true; + return 0; +} + +int KyraEngine_MR::o3t_setNewShapeFlag(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3t_setNewShapeFlag(%p) (%d)", (const void *)script, stackPos(0)); + _newShapeFlag = stackPos(0); + return 0; +} + +#pragma mark - + +int KyraEngine_MR::o3d_updateAnim(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3d_updateAnim(%p) (%d)", (const void *)script, stackPos(0)); + if (_dialogSceneAnim >= 0) + updateSceneAnim(_dialogSceneAnim, stackPos(0)); + return 0; +} + +int KyraEngine_MR::o3d_delay(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3d_delay(%p) (%d)", (const void *)script, stackPos(0)); + const uint32 endTime = _system->getMillis() + stackPos(0) * _tickLength; + while (_system->getMillis() < endTime) { + if (_chatText) + updateWithText(); + else + update(); + _system->delayMillis(10); + } + return 0; +} + +#pragma mark - + +typedef Common::Functor1Mem OpcodeV3; +#define SetOpcodeTable(x) table = &x; +#define Opcode(x) table->push_back(new OpcodeV3(this, &KyraEngine_MR::x)) +#define OpcodeUnImpl() table->push_back(new OpcodeV3(this, 0)) +void KyraEngine_MR::setupOpcodeTable() { + Common::Array *table = 0; + + SetOpcodeTable(_opcodes); + // 0x00 + Opcode(o3_getMalcolmShapes); + Opcode(o3_setCharacterPos); + Opcode(o3_defineObject); + Opcode(o3_refreshCharacter); + // 0x04 + Opcode(o3_getCharacterX); + Opcode(o3_getCharacterY); + Opcode(o3_getCharacterFacing); + Opcode(o3_getCharacterScene); + // 0x08 + Opcode(o3_getMalcolmsMood); + Opcode(o3_dummy); + Opcode(o3_dummy); + Opcode(o3_getCharacterFrameFromFacing); + // 0x0c + Opcode(o3_setCharacterFacingOverwrite); + Opcode(o3_trySceneChange); + Opcode(o3_moveCharacter); + Opcode(o3_setCharacterFacing); + // 0x10 + OpcodeUnImpl(); + Opcode(o3_showSceneFileMessage); + Opcode(o3_dummy); + Opcode(o3_dummy); + // 0x14 + Opcode(o3_setCharacterAnimFrameFromFacing); + Opcode(o3_showBadConscience); + Opcode(o3_dummy); + Opcode(o3_hideBadConscience); + // 0x18 + OpcodeUnImpl(); + OpcodeUnImpl(); + Opcode(o3_setInventorySlot); + Opcode(o3_getInventorySlot); + // 0x1c + Opcode(o3_addItemToInventory); + OpcodeUnImpl(); + Opcode(o3_addItemToCurScene); + Opcode(o3_objectChat); + // 0x20 + Opcode(o3_checkForItem); + Opcode(o3_dummy); + Opcode(o3_resetInventory); + Opcode(o3_defineItem); + // 0x24 + Opcode(o3_removeInventoryItemInstances); + Opcode(o3_countInventoryItemInstances); + Opcode(o3_npcChatSequence); + Opcode(o3_queryGameFlag); + // 0x28 + Opcode(o3_resetGameFlag); + Opcode(o3_setGameFlag); + Opcode(o3_setHandItem); + Opcode(o3_removeHandItem); + // 0x2c + Opcode(o3_handItemSet); + Opcode(o3_hideMouse); + Opcode(o3_addSpecialExit); + Opcode(o3_setMousePos); + // 0x30 + Opcode(o3_showMouse); + Opcode(o3_badConscienceChat); + Opcode(o3_wipeDownMouseItem); + Opcode(o3_dummy); + // 0x34 + Opcode(o3_setMalcolmsMood); + Opcode(o3_playSoundEffect); + Opcode(o3_dummy); + Opcode(o3_delay); + // 0x38 + Opcode(o3_updateScore); + Opcode(o3_makeSecondChanceSave); + Opcode(o3_setSceneFilename); + OpcodeUnImpl(); + // 0x3c + Opcode(o3_removeItemsFromScene); + Opcode(o3_disguiseMalcolm); + Opcode(o3_drawSceneShape); + Opcode(o3_drawSceneShapeOnPage); + // 0x40 + Opcode(o3_checkInRect); + Opcode(o3_updateConversations); + OpcodeUnImpl(); + Opcode(o3_dummy); + // 0x44 + Opcode(o3_dummy); + Opcode(o3_setSceneDim); + OpcodeUnImpl(); + Opcode(o3_dummy); + // 0x48 + Opcode(o3_dummy); + Opcode(o3_dummy); + Opcode(o3_setSceneAnimPosAndFrame); + Opcode(o3_update); + // 0x4c + Opcode(o3_removeItemInstances); + Opcode(o3_dummy); + Opcode(o3_disableInventory); + Opcode(o3_enableInventory); + // 0x50 + Opcode(o3_enterNewScene); + Opcode(o3_switchScene); + Opcode(o3_getShapeFlag1); + Opcode(o3_dummy); + // 0x54 + Opcode(o3_dummy); + Opcode(o3_dummy); + Opcode(o3_setMalcolmPos); + Opcode(o3_stopMusic); + // 0x58 + Opcode(o3_playWanderScoreViaMap); + Opcode(o3_playSoundEffect); + Opcode(o3_getScore); + OpcodeUnImpl(); + // 0x5c + Opcode(o3_blockOutRegion); + Opcode(o3_dummy); + Opcode(o3_showSceneStringsMessage); + OpcodeUnImpl(); + // 0x60 + Opcode(o3_getRand); + Opcode(o3_dummy); + Opcode(o3_setDeathHandler); + Opcode(o3_showGoodConscience); + // 0x64 + Opcode(o3_goodConscienceChat); + Opcode(o3_hideGoodConscience); + Opcode(o3_dummy); + Opcode(o3_dummy); + // 0x68 + Opcode(o3_dummy); + Opcode(o3_dummy); + Opcode(o3_dummy); + Opcode(o3_waitForConfirmationClick); + // 0x6c + Opcode(o3_dummy); + Opcode(o3_defineRoomEntrance); + Opcode(o3_runTemporaryScript); + Opcode(o3_setSpecialSceneScriptRunTime); + // 0x70 + Opcode(o3_defineSceneAnim); + Opcode(o3_dummy); + Opcode(o3_updateSceneAnim); + Opcode(o3_dummy); + // 0x74 + Opcode(o3_runActorScript); + Opcode(o3_runDialog); + Opcode(o3_malcolmRandomChat); + Opcode(o3_setDlgIndex); + // 0x78 + Opcode(o3_getDlgIndex); + Opcode(o3_defineScene); + Opcode(o3_setConversationState); + OpcodeUnImpl(); + // 0x7c + OpcodeUnImpl(); + Opcode(o3_getConversationState); + Opcode(o3_dummy); + Opcode(o3_dummy); + // 0x80 + Opcode(o3_dummy); + Opcode(o3_changeChapter); + Opcode(o3_dummy); + Opcode(o3_dummy); + // 0x84 + Opcode(o3_dummy); + Opcode(o3_dummy); + Opcode(o3_dummy); + Opcode(o3_dummy); + // 0x88 + Opcode(o3_countItemInstances); + Opcode(o3_dummy); + Opcode(o3_dialogStartScript); + Opcode(o3_dummy); + // 0x8c + Opcode(o3_dialogEndScript); + Opcode(o3_dummy); + Opcode(o3_dummy); + Opcode(o3_setSpecialSceneScriptState); + // 0x90 + Opcode(o3_clearSpecialSceneScriptState); + Opcode(o3_querySpecialSceneScriptState); + Opcode(o3_dummy); + Opcode(o3_setHiddenItemsEntry); + // 0x94 + Opcode(o3_getHiddenItemsEntry); + Opcode(o3_dummy); + Opcode(o3_dummy); + OpcodeUnImpl(); + // 0x98 + Opcode(o3_customChat); + Opcode(o3_customChatFinish); + Opcode(o3_setupSceneAnimObject); + Opcode(o3_removeSceneAnimObject); + // 0x9c + Opcode(o3_disableTimer); + Opcode(o3_enableTimer); + Opcode(o3_setTimerCountdown); + OpcodeUnImpl(); + // 0xa0 + Opcode(o3_dummy); + Opcode(o3_dummy); + Opcode(o3_dummy); + Opcode(o3_dummy); + // 0xa4 + OpcodeUnImpl(); + OpcodeUnImpl(); + OpcodeUnImpl(); + Opcode(o3_setVocHigh); + // 0xa8 + Opcode(o3_getVocHigh); + OpcodeUnImpl(); + OpcodeUnImpl(); + OpcodeUnImpl(); + // 0xac + OpcodeUnImpl(); + Opcode(o3_dummy); + OpcodeUnImpl(); + Opcode(o3_dummy); + + SetOpcodeTable(_opcodesTemporary); + // 0x00 + Opcode(o3t_defineNewShapes); + Opcode(o3t_setCurrentFrame); + Opcode(o3_playSoundEffect); + Opcode(o3_dummy); + // 0x0a + Opcode(o3t_setNewShapeFlag); + Opcode(o3_getRand); + Opcode(o3_getMalcolmShapes); + Opcode(o3_dummy); + + SetOpcodeTable(_opcodesDialog); + // 0x00 + Opcode(o3d_updateAnim); + Opcode(o3d_delay); + Opcode(o3_getRand); + Opcode(o3_queryGameFlag); + // 0x04 + Opcode(o3_dummy); +} + +} // end of namespace Kyra diff --git a/engines/kyra/script_v2.cpp b/engines/kyra/script_v2.cpp deleted file mode 100644 index 585ce98295..0000000000 --- a/engines/kyra/script_v2.cpp +++ /dev/null @@ -1,2134 +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_v2.h" -#include "kyra/text_v2.h" -#include "kyra/wsamovie.h" -#include "kyra/sound.h" -#include "kyra/timer.h" -#include "kyra/script_tim.h" - -#include "common/endian.h" - -namespace Kyra { - -int KyraEngine_v2::o2_setCharacterFacingRefresh(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_setCharacterFacingRefresh(%p) (-, %d, %d)", (const void *)script, stackPos(1), stackPos(2)); - int animFrame = stackPos(2); - if (animFrame >= 0) - _mainCharacter.animFrame = animFrame; - _mainCharacter.facing = stackPos(1); - updateCharacterAnim(0); - refreshAnimObjectsIfNeed(); - return 0; -} - -int KyraEngine_v2::o2_setCharacterPos(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_setCharacterFacingRefresh(%p) (-, %d, %d)", (const void *)script, stackPos(1), stackPos(2)); - int x = stackPos(1); - int y = stackPos(2); - - if (x != -1 && y != -1) { - x &= ~3; - y &= ~1; - } - - restorePage3(); - _mainCharacter.x2 = _mainCharacter.x1 = x; - _mainCharacter.y2 = _mainCharacter.y1 = y; - return 0; -} - -int KyraEngine_v2::o2_defineObject(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_defineObject(%p) (%d, '%s', %d, %d, %d, %d)", (const void *)script, - stackPos(0), stackPosString(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5)); - TalkObject *object = &_talkObjectList[stackPos(0)]; - strcpy(object->filename, stackPosString(1)); - object->scriptId = stackPos(2); - object->x = stackPos(3); - object->y = stackPos(4); - object->color = stackPos(5); - return 0; -} - -int KyraEngine_v2::o2_refreshCharacter(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_refreshCharacter(%p) (-, %d, %d, %d)", (const void *)script, stackPos(1), stackPos(2), stackPos(3)); - int unk = stackPos(1); - int facing = stackPos(2); - int refresh = stackPos(3); - if (facing >= 0) - _mainCharacter.facing = facing; - if (unk >= 0 && unk != 32) - _mainCharacter.animFrame = _characterFrameTable[_mainCharacter.facing]; - updateCharacterAnim(0); - if (refresh) - refreshAnimObjectsIfNeed(); - return 0; -} - -int KyraEngine_v2::o2_getCharacterX(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_getCharacterX(%p) ()", (const void *)script); - return _mainCharacter.x1; -} - -int KyraEngine_v2::o2_getCharacterY(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_getCharacterY(%p) ()", (const void *)script); - return _mainCharacter.y1; -} - -int KyraEngine_v2::o2_getCharacterFacing(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_getCharacterFacing(%p) ()", (const void *)script); - return _mainCharacter.facing; -} - -int KyraEngine_v2::o2_getCharacterScene(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_getCharacterScene(%p) ()", (const void *)script); - return _mainCharacter.sceneId; -} - -int KyraEngine_v2::o2_setSceneComment(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_setSceneComment(%p) ('%s')", (const void *)script, stackPosString(0)); - _sceneCommentString = stackPosString(0); - return 0; -} - -int KyraEngine_v2::o2_setCharacterAnimFrame(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_setCharacterAnimFrame(%p) (-, %d, %d)", (const void *)script, stackPos(1), stackPos(2)); - int animFrame = stackPos(1); - int updateAnim = stackPos(2); - - _mainCharacter.animFrame = animFrame; - if (updateAnim) - updateCharacterAnim(0); - - return 0; -} - -int KyraEngine_v2::o2_setCharacterFacing(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_setCharacterFacing(%p) (%d)", (const void *)script, stackPos(0)); - _mainCharacter.facing = stackPos(0); - _overwriteSceneFacing = 1; - return 0; -} - -int KyraEngine_v2::o2_trySceneChange(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_trySceneChange(%p) (%d, %d, %d, %d)", (const void *)script, - stackPos(0), stackPos(1), stackPos(2), stackPos(3)); - - _unkHandleSceneChangeFlag = 1; - int success = inputSceneChange(stackPos(0), stackPos(1), stackPos(2), stackPos(3)); - _unkHandleSceneChangeFlag = 0; - - if (success) { - _emc->init(script, script->dataPtr); - _unk4 = 0; - _unk3 = -1; - _unk5 = 1; - return 0; - } else { - return (_unk4 != 0) ? 1 : 0; - } -} - -int KyraEngine_v2::o2_moveCharacter(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_moveCharacter(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); - moveCharacter(stackPos(0), stackPos(1), stackPos(2)); - return 0; -} - -int KyraEngine_v2::o2_customCharacterChat(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_customCharacterChat(%p) ('%s', %d, %d, %d, %d)", (const void *)script, stackPosString(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); - playVoice(_vocHigh, stackPos(4)); - _text->printCustomCharacterText(stackPosString(0), stackPos(1), stackPos(2), stackPos(3), 0, 2); - return 0; -} - -int KyraEngine_v2::o2_soundFadeOut(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_soundFadeOut(%p) ()", (const void *)script); - _sound->beginFadeOut(); - return 0; -} - -int KyraEngine_v2::o2_showChapterMessage(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_showChapterMessage(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - showChapterMessage(stackPos(0), stackPos(1)); - return 0; -} - -int KyraEngine_v2::o2_restoreTalkTextMessageBkgd(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_restoreTalkTextMessageBkgd(%p) ()", (const void *)script); - _text->restoreTalkTextMessageBkgd(2, 0); - return 0; -} - -int KyraEngine_v2::o2_wsaClose(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_wsaClose(%p) (%d)", (const void *)script, stackPos(0)); - assert(stackPos(0) >= 0 && stackPos(0) < ARRAYSIZE(_wsaSlots)); - _wsaSlots[stackPos(0)]->close(); - return 0; -} - -int KyraEngine_v2::o2_meanWhileScene(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_meanWhileScene(%p) (%d)", (const void *)script, stackPos(0)); - static const uint8 jpSubtitle[] = { 0x88, 0xEA, 0x95, 0xFB, 0x81, 0x45, 0x81, 0x45, 0x81, 0x45 }; - const char *cpsfile = stackPosString(0); - const char *palfile = stackPosString(1); - - _screen->loadBitmap(cpsfile, 3, 3, 0); - memcpy(_screen->getPalette(2), _screen->_currentPalette, 768); - _screen->loadPalette(palfile, _screen->getPalette(2)); - _screen->fillRect(0, 0, 319, 199, 207); - _screen->setScreenPalette(_screen->getPalette(2)); - _screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0); - if (!scumm_stricmp(cpsfile, "_MEANWIL.CPS") && _flags.lang == Common::JA_JPN) { - Screen::FontId o = _screen->setFont(Screen::FID_6_FNT); - _screen->printText((const char*)jpSubtitle, 140, 176, 255, 132); - _screen->setFont(o); - } - _screen->updateScreen(); - return 0; -} - -int KyraEngine_v2::o2_backUpScreen(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_backUpScreen(%p) (%d)", (const void *)script, stackPos(0)); - _screen->copyRegionToBuffer(stackPos(0), 0, 0, 320, 144, _screenBuffer); - return 0; -} - -int KyraEngine_v2::o2_restoreScreen(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_restoreScreen(%p) (%d)", (const void *)script, stackPos(0)); - _screen->copyBlockToPage(stackPos(0), 0, 0, 320, 144, _screenBuffer); - return 0; -} - -int KyraEngine_v2::o2_displayWsaFrame(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_displayWsaFrame(%p) (%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)); - int frame = stackPos(0); - int x = stackPos(1); - int y = stackPos(2); - int waitTime = stackPos(3); - int slot = stackPos(4); - int copyParam = stackPos(5); - int doUpdate = stackPos(6); - int dstPage = stackPos(7); - int backUp = stackPos(8); - - _screen->hideMouse(); - uint32 endTime = _system->getMillis() + waitTime * _tickLength; - _wsaSlots[slot]->setX(x); - _wsaSlots[slot]->setY(y); - _wsaSlots[slot]->setDrawPage(dstPage); - _wsaSlots[slot]->displayFrame(frame, copyParam | 0xC000, 0, 0); - _screen->updateScreen(); - - if (backUp) - memcpy(_gamePlayBuffer, _screen->getCPagePtr(3), 46080); - - while (_system->getMillis() < endTime) { - if (doUpdate) - update(); - - if (endTime - _system->getMillis() >= 10) - delay(10); - } - _screen->showMouse(); - return 0; -} - -int KyraEngine_v2::o2_displayWsaSequentialFramesLooping(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_displayWsaSequentialFramesLooping(%p) (%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)); - int startFrame = stackPos(0); - int endFrame = stackPos(1); - int x = stackPos(2); - int y = stackPos(3); - int waitTime = stackPos(4); - int slot = stackPos(5); - int maxTimes = stackPos(6); - int copyFlags = stackPos(7); - - if (maxTimes > 1) - maxTimes = 1; - - _wsaSlots[slot]->setX(x); - _wsaSlots[slot]->setY(y); - _wsaSlots[slot]->setDrawPage(0); - - _screen->hideMouse(); - int curTime = 0; - while (curTime < maxTimes) { - if (startFrame < endFrame) { - for (int i = startFrame; i <= endFrame; ++i) { - uint32 endTime = _system->getMillis() + waitTime * _tickLength; - _wsaSlots[slot]->displayFrame(i, 0xC000 | copyFlags, 0, 0); - - if (!skipFlag()) { - _screen->updateScreen(); - - do { - update(); - - if (endTime - _system->getMillis() >= 10) - delay(10); - } while (_system->getMillis() < endTime); - } - } - } else { - for (int i = startFrame; i >= endFrame; --i) { - uint32 endTime = _system->getMillis() + waitTime * _tickLength; - _wsaSlots[slot]->displayFrame(i, 0xC000 | copyFlags, 0, 0); - - if (!skipFlag()) { - _screen->updateScreen(); - - do { - update(); - - if (endTime - _system->getMillis() >= 10 && !skipFlag()) - delay(10); - } while (_system->getMillis() < endTime && !skipFlag()); - } - } - } - - ++curTime; - } - resetSkipFlag(); - _screen->showMouse(); - return 0; -} - -int KyraEngine_v2::o2_wsaOpen(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_wsaOpen(%p) ('%s', %d)", (const void *)script, stackPosString(0), stackPos(1)); - assert(stackPos(1) >= 0 && stackPos(1) < ARRAYSIZE(_wsaSlots)); - _wsaSlots[stackPos(1)]->open(stackPosString(0), 1, 0); - return 0; -} - -int KyraEngine_v2::o2_displayWsaSequentialFrames(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_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)); - - uint16 frameDelay = stackPos(2) * _tickLength; - uint16 currentFrame = stackPos(3); - uint16 lastFrame = stackPos(4); - uint16 index = stackPos(5); - uint16 copyParam = stackPos(6) | 0xc000; - - _wsaSlots[index]->setX(stackPos(0)); - _wsaSlots[index]->setY(stackPos(1)); - _wsaSlots[index]->setDrawPage(0); - - _screen->hideMouse(); - - while (currentFrame <= lastFrame) { - uint32 endTime = _system->getMillis() + frameDelay; - _wsaSlots[index]->displayFrame(currentFrame++, copyParam, 0, 0); - if (!skipFlag()) { - _screen->updateScreen(); - delayUntil(endTime); - } - } - - resetSkipFlag(); - _screen->showMouse(); - - return 0; -} - -int KyraEngine_v2::o2_displayWsaSequence(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_displayWsaSequence(%p) (%d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5)); - - const int frameDelay = stackPos(2) * _tickLength; - const int index = stackPos(3); - const bool doUpdate = (stackPos(4) != 0); - const uint16 copyParam = stackPos(5) | 0xc000; - - _wsaSlots[index]->setX(stackPos(0)); - _wsaSlots[index]->setY(stackPos(1)); - _wsaSlots[index]->setDrawPage(0); - - _screen->hideMouse(); - - int currentFrame = 0; - const int lastFrame = _wsaSlots[index]->frames(); - - while (currentFrame <= lastFrame) { - uint32 endTime = _system->getMillis() + frameDelay; - _wsaSlots[index]->displayFrame(currentFrame++, copyParam, 0, 0); - if (!skipFlag()) { - if (doUpdate) - update(); - _screen->updateScreen(); - delayUntil(endTime); - } - } - - resetSkipFlag(); - _screen->showMouse(); - - return 0; -} - -int KyraEngine_v2::o2_addItemToInventory(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_addItemToInventory(%p) (%d, -, %d)", (const void *)script, stackPos(0), stackPos(2)); - int slot = findFreeVisibleInventorySlot(); - if (slot != -1) { - _mainCharacter.inventory[slot] = stackPos(0); - if (stackPos(2)) - redrawInventory(0); - } - return slot; -} - -int KyraEngine_v2::o2_drawShape(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_drawShape(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); - - uint8 *shp = getShapePtr(stackPos(0) + 64); - int x = stackPos(1); - int y = stackPos(2); - uint8 dsFlag = stackPos(3) & 0xff; - uint8 modeFlag = stackPos(4) & 0xff; - - if (modeFlag) { - _screen->drawShape(2, shp, x, y, 2, dsFlag ? 1 : 0); - } else { - _screen->hideMouse(); - restorePage3(); - _screen->drawShape(2, shp, x, y, 2, dsFlag ? 1 : 0); - memcpy(_gamePlayBuffer, _screen->getCPagePtr(3), 46080); - _screen->drawShape(0, shp, x, y, 2, dsFlag ? 1 : 0); - - flagAnimObjsForRefresh(); - flagAnimObjsUnk8(); - refreshAnimObjectsIfNeed(); - _screen->showMouse(); - } - - return 0; -} - -int KyraEngine_v2::o2_addItemToCurScene(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_addItemToCurScene(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); - const int16 id = stackPos(0); - int x = stackPos(1); - int y = stackPos(2); - - int freeItem = findFreeItem(); - x = MAX(14, x); - x = MIN(304, x); - y = MAX(14, y); - y = MIN(136, y); - if (freeItem >= 0) { - _itemList[freeItem].id = id; - _itemList[freeItem].x = x; - _itemList[freeItem].y = y; - _itemList[freeItem].sceneId = _mainCharacter.sceneId; - addItemToAnimList(freeItem); - refreshAnimObjectsIfNeed(); - } - return 0; -} - -int KyraEngine_v2::o2_checkForItem(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_checkForItem(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - return findItem(stackPos(0), stackPos(1)) == -1 ? 0 : 1; -} - -int KyraEngine_v2::o2_loadSoundFile(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_loadSoundFile(%p) (%d)", (const void *)script, stackPos(0)); - if (_sound->hasSoundFile(stackPos(0))) - snd_playTheme(stackPos(0), -1); - return 0; -} - -int KyraEngine_v2::o2_removeItemSlotFromInventory(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_removeItemSlotFromInventory(%p) (%d)", (const void *)script, stackPos(0)); - removeItemFromInventory(stackPos(0)); - return 0; -} - -int KyraEngine_v2::o2_defineItem(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_defineItem(%p) (%d, %d, %d, %d)", (const void *)script, - stackPos(0), stackPos(1), stackPos(2), stackPos(3)); - int freeItem = findFreeItem(); - - if (freeItem >= 0) { - _itemList[freeItem].id = stackPos(0); - _itemList[freeItem].x = stackPos(1); - _itemList[freeItem].y = stackPos(2); - _itemList[freeItem].sceneId = stackPos(3); - } - - return freeItem; -} - -int KyraEngine_v2::o2_removeItemFromInventory(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_removeItemFromInventory(%p) (%d)", (const void *)script, stackPos(0)); - uint16 item = stackPos(0); - int slot = -1; - while ((slot = getInventoryItemSlot(item)) != -1) - removeItemFromInventory(slot); - return 0; -} - -int KyraEngine_v2::o2_countItemInInventory(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_countItemInInventory(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - uint16 item = stackPos(1); - int count = 0; - - for (int i = 0; i < 20; ++i) { - if (_mainCharacter.inventory[i] == item) - ++count; - } - - if ((stackPos(0) == 0) && _itemInHand == int16(item)) - ++count; - - return count; -} - -int KyraEngine_v2::o2_countItemsInScene(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_countItemsInScene(%p) (%d)", (const void *)script, stackPos(0)); - int count = 0; - for (int i = 0; i < 30; ++i) { - if (_itemList[i].sceneId == stackPos(0) && _itemList[i].id != 0xFFFF) - ++count; - } - return count; -} - -int KyraEngine_v2::o2_queryGameFlag(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_queryGameFlag(%p) (%d)", (const void *)script, stackPos(0)); - return queryGameFlag(stackPos(0)); -} - -int KyraEngine_v2::o2_resetGameFlag(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_resetGameFlag(%p) (%d)", (const void *)script, stackPos(0)); - return resetGameFlag(stackPos(0)); -} - -int KyraEngine_v2::o2_setGameFlag(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_setGameFlag(%p) (%d)", (const void *)script, stackPos(0)); - return setGameFlag(stackPos(0)); -} - -int KyraEngine_v2::o2_setHandItem(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_setHandItem(%p) (%d)", (const void *)script, stackPos(0)); - setHandItem(stackPos(0)); - return 0; -} - -int KyraEngine_v2::o2_removeHandItem(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_removeHandItem(%p) ()", (const void *)script); - removeHandItem(); - return 0; -} - -int KyraEngine_v2::o2_handItemSet(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_handItemSet(%p) ()", (const void *)script); - return _handItemSet; -} - -int KyraEngine_v2::o2_hideMouse(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_hideMouse(%p) ()", (const void *)script); - _screen->hideMouse(); - return 0; -} - -int KyraEngine_v2::o2_addSpecialExit(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_addSpecialExit(%p) (%d, %d, %d, %d, %d)", (const void *)script, - stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); - if (_specialExitCount < 5) { - _specialExitTable[_specialExitCount+0] = stackPos(0); - _specialExitTable[_specialExitCount+5] = stackPos(1); - _specialExitTable[_specialExitCount+10] = stackPos(2) + stackPos(0) - 1; - _specialExitTable[_specialExitCount+15] = stackPos(3) + stackPos(1) - 1; - _specialExitTable[_specialExitCount+20] = stackPos(4); - ++_specialExitCount; - } - return 0; -} - -int KyraEngine_v2::o2_setMousePos(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_setMousePos(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - setMousePos(stackPos(0), stackPos(1)); - return 0; -} - -int KyraEngine_v2::o2_showMouse(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_showMouse(%p) ()", (const void *)script); - _screen->showMouse(); - return 0; -} - -int KyraEngine_v2::o2_wipeDownMouseItem(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_wipeDownMouseItem(%p) (-, %d, %d)", (const void *)script, stackPos(1), stackPos(2)); - _screen->hideMouse(); - const int x = stackPos(1) - 8; - const int y = stackPos(2) - 15; - - if (_itemInHand >= 0) { - backUpGfxRect32x32(x, y); - uint8 *shape = getShapePtr(_itemInHand+64); - for (int curY = y, height = 16; height > 0; height -= 2, curY += 2) { - restoreGfxRect32x32(x, y); - _screen->setNewShapeHeight(shape, height); - uint32 waitTime = _system->getMillis() + _tickLength; - _screen->drawShape(0, shape, x, curY, 0, 0); - _screen->updateScreen(); - delayUntil(waitTime); - } - restoreGfxRect32x32(x, y); - _screen->resetShapeHeight(shape); - } - - _screen->showMouse(); - removeHandItem(); - - return 0; -} - -int KyraEngine_v2::o2_getElapsedSecs(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_getElapsedSecs(%p) ()", (const void *)script); - return _system->getMillis() / 1000; -} - -int KyraEngine_v2::o2_getTimerDelay(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_getTimerDelay(%p) (%d)", (const void *)script, stackPos(0)); - return _timer->getDelay(stackPos(0)); -} - -int KyraEngine_v2::o2_delaySecs(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_delaySecs(%p) (%d)", (const void *)script, stackPos(0)); - delay(stackPos(0) * 1000, true); - return 0; -} - -int KyraEngine_v2::o2_delay(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_delay(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - if (stackPos(1)) { - uint32 maxWaitTime = _system->getMillis() + stackPos(0) * _tickLength; - while (_system->getMillis() < maxWaitTime) { - int inputFlag = checkInput(0); - removeInputTop(); - - if (inputFlag == 198 || inputFlag == 199) - return 1; - - if (_chatText) - updateWithText(); - else - update(); - _system->delayMillis(10); - } - } else { - delay(stackPos(0) * _tickLength, true); - } - return 0; -} - -int KyraEngine_v2::o2_setTimerDelay(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_setTimerDelay(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - _timer->setDelay(stackPos(0), stackPos(1)); - return 0; -} - -int KyraEngine_v2::o2_setScaleTableItem(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_setScaleTableItem(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - setScaleTableItem(stackPos(0), stackPos(1)); - return 0; -} - -int KyraEngine_v2::o2_setDrawLayerTableItem(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_setDrawLayerTableItem(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - setDrawLayerTableEntry(stackPos(0), stackPos(1)); - return 0; -} - -int KyraEngine_v2::o2_setCharPalEntry(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_setCharPalEntry(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - setCharPalEntry(stackPos(0), stackPos(1)); - return 0; -} - -int KyraEngine_v2::o2_loadZShapes(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_loadZShapes(%p) (%d)", (const void *)script, stackPos(0)); - loadZShapes(stackPos(0)); - return 0; -} - -int KyraEngine_v2::o2_drawSceneShape(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_drawSceneShape(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), - stackPos(2), stackPos(3)); - - int shape = stackPos(0); - int x = stackPos(1); - int y = stackPos(2); - int flag = (stackPos(3) != 0) ? 1 : 0; - - _screen->hideMouse(); - restorePage3(); - - _screen->drawShape(2, _sceneShapeTable[shape], x, y, 2, flag); - - memcpy(_gamePlayBuffer, _screen->getCPagePtr(3), 46080); - - _screen->drawShape(0, _sceneShapeTable[shape], x, y, 2, flag); - - flagAnimObjsUnk8(); - flagAnimObjsForRefresh(); - refreshAnimObjectsIfNeed(); - _screen->showMouse(); - return 0; -} - -int KyraEngine_v2::o2_drawSceneShapeOnPage(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_drawSceneShapeOnPage(%p) (%d, %d, %d, %d, %d)", (const void *)script, - stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); - int shape = stackPos(0); - int x = stackPos(1); - int y = stackPos(2); - int flag = stackPos(3); - int drawPage = stackPos(4); - - _screen->drawShape(drawPage, _sceneShapeTable[shape], x, y, 2, flag ? 1 : 0); - return 0; -} - -int KyraEngine_v2::o2_disableAnimObject(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_disableAnimObject(%p) (%d)", (const void *)script, stackPos(0)); - _animObjects[stackPos(0)+1].enabled = false; - return 0; -} - -int KyraEngine_v2::o2_enableAnimObject(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_enableAnimObject(%p) (%d)", (const void *)script, stackPos(0)); - _animObjects[stackPos(0)+1].enabled = true; - return 0; -} - -int KyraEngine_v2::o2_loadPalette384(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_loadPalette384(%p) ('%s')", (const void *)script, stackPosString(0)); - memcpy(_screen->getPalette(1), _screen->getPalette(0), 768); - _res->loadFileToBuf(stackPosString(0), _screen->getPalette(1), 384); - return 0; -} - -int KyraEngine_v2::o2_setPalette384(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_setPalette384(%p) ()", (const void *)script); - memcpy(_screen->getPalette(0), _screen->getPalette(1), 384); - _screen->setScreenPalette(_screen->getPalette(0)); - return 0; -} - -int KyraEngine_v2::o2_restoreBackBuffer(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_restoreBackBuffer(%p) (%d)", (const void *)script, stackPos(0)); - int disable = stackPos(0); - int oldState = 0; - - if (disable) { - oldState = _animObjects[0].enabled; - _animObjects[0].enabled = 0; - } - - restorePage3(); - - if (disable) - _animObjects[0].enabled = oldState; - - return 0; -} - -int KyraEngine_v2::o2_backUpInventoryGfx(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_backUpInventoryGfx(%p) ()", (const void *)script); - _screen->copyRegionToBuffer(1, 0, 144, 320, 56, _screenBuffer); - _inventorySaved = true; - return 0; -} - -int KyraEngine_v2::o2_disableSceneAnim(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_disableSceneAnim(%p) (%d)", (const void *)script, stackPos(0)); - _sceneAnims[stackPos(0)].flags &= ~1; - return 0; -} - -int KyraEngine_v2::o2_enableSceneAnim(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_enableSceneAnim(%p) (%d)", (const void *)script, stackPos(0)); - _sceneAnims[stackPos(0)].flags |= 1; - return 0; -} - -int KyraEngine_v2::o2_restoreInventoryGfx(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_restoreInventoryGfx(%p) ()", (const void *)script); - _screen->copyBlockToPage(1, 0, 144, 320, 56, _screenBuffer); - _inventorySaved = false; - return 0; -} - -int KyraEngine_v2::o2_setSceneAnimPos2(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_setSceneAnimPos2(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); - _sceneAnims[stackPos(0)].x2 = stackPos(1); - _sceneAnims[stackPos(0)].y2 = stackPos(2); - return 0; -} - -int KyraEngine_v2::o2_update(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_update(%p) (%d)", (const void *)script, stackPos(0)); - - int times = stackPos(0); - while (times--) { - if (_chatText) - updateWithText(); - else - update(); - } - - return 0; -} - -int KyraEngine_v2::o2_fadeScenePal(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_fadeScenePal(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - fadeScenePal(stackPos(0), stackPos(1)); - return 0; -} - -int KyraEngine_v2::o2_enterNewSceneEx(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_enterNewSceneEx(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), - stackPos(1), stackPos(2), stackPos(3), stackPos(4)); - - int skipNpcScript = stackPos(3); - enterNewScene(stackPos(0), stackPos(1), stackPos(2), skipNpcScript, stackPos(4)); - - if (!skipNpcScript) - runSceneScript4(0); - - _unk5 = 1; - - if (_mainCharX == -1 || _mainCharY == -1) { - _mainCharacter.animFrame = _characterFrameTable[_mainCharacter.facing]; - updateCharacterAnim(0); - } - - return 0; -} - -int KyraEngine_v2::o2_switchScene(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_switchScene(%p) (%d)", (const void *)script, stackPos(0)); - setGameFlag(0x1EF); - _mainCharX = _mainCharacter.x1; - _mainCharY = _mainCharacter.y1; - _noScriptEnter = 0; - enterNewScene(stackPos(0), _mainCharacter.facing, 0, 0, 0); - _noScriptEnter = 1; - return 0; -} - -int KyraEngine_v2::o2_getShapeFlag1(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_getShapeFlag1(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - return _screen->getShapeFlag1(stackPos(0), stackPos(1)); -} - -int KyraEngine_v2::o2_setPathfinderFlag(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_setPathfinderFlag(%p) (%d)", (const void *)script, stackPos(0)); - _pathfinderFlag = stackPos(0); - return 0; -} - -int KyraEngine_v2::o2_getSceneExitToFacing(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_getSceneExitToFacing(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - const int scene = stackPos(0); - const int facing = stackPos(1); - - if (facing == 0) - return (int16)_sceneList[scene].exit1; - else if (facing == 2) - return (int16)_sceneList[scene].exit2; - else if (facing == 4) - return (int16)_sceneList[scene].exit3; - else if (facing == 6) - return (int16)_sceneList[scene].exit4; - return -1; -} - -int KyraEngine_v2::o2_setLayerFlag(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_setLayerFlag(%p) (%d)", (const void *)script, stackPos(0)); - int layer = stackPos(0); - if (layer >= 1 && layer <= 16) - _layerFlagTable[layer] = 1; - return 0; -} - -int KyraEngine_v2::o2_setZanthiaPos(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_setZanthiaPos(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - _mainCharX = stackPos(0); - _mainCharY = stackPos(1); - - if (_mainCharX == -1 && _mainCharY == -1) - _mainCharacter.animFrame = 32; - else - _mainCharacter.animFrame = _characterFrameTable[_mainCharacter.facing]; - - return 0; -} - -int KyraEngine_v2::o2_loadMusicTrack(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_loadMusicTrack(%p) (%d)", (const void *)script, stackPos(0)); - snd_loadSoundFile(stackPos(0)); - return 0; -} - -int KyraEngine_v2::o2_playWanderScoreViaMap(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_playWanderScoreViaMap(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - snd_playWanderScoreViaMap(stackPos(0), stackPos(1)); - return 0; -} - -int KyraEngine_v2::o2_playSoundEffect(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_playSoundEffect(%p) (%d)", (const void *)script, stackPos(0)); - snd_playSoundEffect(stackPos(0)); - return 0; -} - -int KyraEngine_v2::o2_setSceneAnimPos(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_setSceneAnimPos(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); - _sceneAnims[stackPos(0)].x = stackPos(1); - _sceneAnims[stackPos(0)].y = stackPos(2); - return 0; -} - -int KyraEngine_v2::o2_blockInRegion(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_blockInRegion(%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_v2::o2_blockOutRegion(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_blockOutRegion(%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_v2::o2_setCauldronState(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_setCauldronState(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - setCauldronState(stackPos(0), stackPos(1) != 0); - clearCauldronTable(); - return 0; -} - -int KyraEngine_v2::o2_showItemString(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_showItemString(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - const int item = stackPos(0); - - int string = 0; - if (stackPos(1) == 1) { - if (_lang == 1) - string = getItemCommandStringPickUp(item); - else - string = 7; - } else { - if (_lang == 1) - string = getItemCommandStringInv(item); - else - string = 8; - } - - updateCommandLineEx(item+54, string, 0xD6); - return 0; -} - -int KyraEngine_v2::o2_getRand(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_getRand(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - assert(stackPos(0) < stackPos(1)); - return _rnd.getRandomNumberRng(stackPos(0), stackPos(1)); -} - -int KyraEngine_v2::o2_isAnySoundPlaying(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_isAnySoundPlaying(%p) ()", (const void *)script); - return _sound->voiceIsPlaying(); -} - -int KyraEngine_v2::o2_setDeathHandlerFlag(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_setDeathHandlerFlag(%p) (%d)", (const void *)script, stackPos(0)); - _deathHandler = stackPos(0); - return 0; -} - -int KyraEngine_v2::o2_setDrawNoShapeFlag(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_setDrawNoShapeFlag(%p) (%d)", (const void *)script, stackPos(0)); - _drawNoShapeFlag = (stackPos(0) != 0); - return 0; -} - -int KyraEngine_v2::o2_setRunFlag(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_setRunFlag(%p) (%d)", (const void *)script, stackPos(0)); - // this is usually just _runFlag, but since this is just used when the game should play the credits - // we handle it a bit different :-) - _showCredits = true; - _runFlag = false; - return 0; -} - -int KyraEngine_v2::o2_showLetter(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_showLetter(%p) (%d)", (const void *)script, stackPos(0)); - const int letter = stackPos(0); - char filename[16]; - - _screen->hideMouse(); - - showMessage(0, 0xCF); - displayInvWsaLastFrame(); - backUpPage0(); - - memcpy(_screen->getPalette(2), _screen->getPalette(0), 768); - - _screen->clearPage(3); - _screen->loadBitmap("_NOTE.CPS", 3, 3, 0); - - sprintf(filename, "_NTEPAL%.1d.COL", letter+1); - _res->loadFileToBuf(filename, _screen->getPalette(0), 768); - - _screen->fadeToBlack(0x14); - - sprintf(filename, "LETTER%.1d.", letter); - strcat(filename, _languageExtension[_lang]); - - uint8 *letterBuffer = _res->fileData(filename, 0); - if (letterBuffer) { - bookDecodeText(letterBuffer); - bookPrintText(2, letterBuffer, 0xC, 0xA, 0x20); - } - - _screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0, Screen::CR_NO_P_CHECK); - _screen->fadePalette(_screen->getPalette(0), 0x14); - _screen->setMouseCursor(0, 0, getShapePtr(0)); - setMousePos(280, 160); - - _screen->showMouse(); - - bool running = true; - while (running) { - int inputFlag = checkInput(0); - removeInputTop(); - - if (inputFlag == 198 || inputFlag == 199) - running = false; - - _screen->updateScreen(); - _system->delayMillis(10); - } - - _screen->hideMouse(); - _screen->fadeToBlack(0x14); - restorePage0(); - memcpy(_screen->getPalette(0), _screen->getPalette(2), 768); - _screen->fadePalette(_screen->getPalette(0), 0x14); - setHandItem(_itemInHand); - _screen->showMouse(); - - return 0; -} - -int KyraEngine_v2::o2_fillRect(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_fillRect(%p) (%d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5)); - _screen->fillRect(stackPos(1), stackPos(2), stackPos(1)+stackPos(3), stackPos(2)+stackPos(4), stackPos(5), stackPos(0)); - return 0; -} - -int KyraEngine_v2::o2_waitForConfirmationClick(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_waitForConfirmationClick(%p) (%d)", (const void *)script, stackPos(0)); - resetSkipFlag(); - uint32 maxWaitTime = _system->getMillis() + stackPos(0) * _tickLength; - - while (_system->getMillis() < maxWaitTime) { - int inputFlag = checkInput(0); - removeInputTop(); - - if (inputFlag == 198 || inputFlag == 199) { - _sceneScriptState.regs[1] = _mouseX; - _sceneScriptState.regs[2] = _mouseY; - return 0; - } - - update(); - _system->delayMillis(10); - } - - _sceneScriptState.regs[1] = _mouseX; - _sceneScriptState.regs[2] = _mouseY; - return 1; -} - -int KyraEngine_v2::o2_encodeShape(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_encodeShape(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), - stackPos(2), stackPos(3), stackPos(4)); - _sceneShapeTable[stackPos(0)] = _screen->encodeShape(stackPos(1), stackPos(2), stackPos(3), stackPos(4), 2); - return 0; -} - -int KyraEngine_v2::o2_defineRoomEntrance(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_defineRoomEntrance(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); - switch (stackPos(0)) { - case 0: - _sceneEnterX1 = stackPos(1); - _sceneEnterY1 = stackPos(2); - break; - - case 1: - _sceneEnterX2 = stackPos(1); - _sceneEnterY2 = stackPos(2); - break; - - case 2: - _sceneEnterX3 = stackPos(1); - _sceneEnterY3 = stackPos(2); - break; - - case 3: - _sceneEnterX4 = stackPos(1); - _sceneEnterY4 = stackPos(2); - break; - - default: - break; - } - return 0; -} - -int KyraEngine_v2::o2_runTemporaryScript(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_runTemporaryScript(%p) ('%s', %d, %d, %d)", (const void *)script, stackPosString(0), stackPos(1), - stackPos(2), stackPos(3)); - - runTemporaryScript(stackPosString(0), stackPos(3), stackPos(2) ? 1 : 0, stackPos(1), stackPos(2)); - return 0; -} - -int KyraEngine_v2::o2_setSpecialSceneScriptRunTime(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_setSpecialSceneScriptRunTime(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - assert(stackPos(0) >= 0 && stackPos(0) < 10); - _sceneSpecialScriptsTimer[stackPos(0)] = _system->getMillis() + stackPos(1) * _tickLength; - return 0; -} - -int KyraEngine_v2::o2_defineSceneAnim(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_defineSceneAnim(%p) (%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, '%s')", (const void *)script, - stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7), stackPos(8), - stackPos(9), stackPos(10), stackPos(11), stackPosString(12)); - int animId = stackPos(0); - SceneAnim &anim = _sceneAnims[animId]; - anim.flags = stackPos(1); - anim.x = stackPos(2); - anim.y = stackPos(3); - anim.x2 = stackPos(4); - anim.y2 = stackPos(5); - anim.width = stackPos(6); - anim.height = stackPos(7); - anim.unkE = stackPos(8); - anim.specialSize = stackPos(9); - anim.unk12 = stackPos(10); - anim.shapeIndex = stackPos(11); - if (stackPosString(12) != 0) - strcpy(anim.filename, stackPosString(12)); - - if (anim.flags & 0x40) { - if (!_sceneAnimMovie[animId]->open(anim.filename, 1, 0)) - error("couldn't load '%s'", anim.filename); - - if (_sceneAnimMovie[animId]->xAdd() || _sceneAnimMovie[animId]->yAdd()) - anim.wsaFlag = 1; - else - anim.wsaFlag = 0; - } - - return 0; -} - -int KyraEngine_v2::o2_updateSceneAnim(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_updateSceneAnim(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - updateSceneAnim(stackPos(0), stackPos(1)); - - // HACK: Some animations are really too fast because of missing delay times. - // Notice that the delay time is purely subjective set here, it could look - // slower or maybe faster in the original, but at least this looks OK for - // Raziel^. - // - // We know currently of some different animations where this happens. - // - Where Marco is dangling from the flesh-eating plant (see bug #1923638 "HoF: Marco missing animation frames"). - // - After giving the ticket to the captain. He would move very fast (barely noticeable) onto the ship - // without this delay. - // - The scene after giving the sandwitch to the guards in the city. (see bug #1926838 "HoF: Animation plays too fast") - // This scene script calls o2_delay though, but since this updates the scene animation scripts again there is no delay - // for the animation. - if ((stackPos(0) == 2 && _mainCharacter.sceneId == 3) || (stackPos(0) == 3 && _mainCharacter.sceneId == 33) || - ((stackPos(0) == 1 || stackPos(0) == 2) && _mainCharacter.sceneId == 19)) - _sceneSpecialScriptsTimer[_lastProcessedSceneScript] = _system->getMillis() + _tickLength * 6; - - _specialSceneScriptRunFlag = false; - return 0; -} - -int KyraEngine_v2::o2_addToSceneAnimPosAndUpdate(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_addToSceneAnimPosAndUpdate(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); - const int anim = stackPos(0); - _sceneAnims[anim].x2 += stackPos(1); - _sceneAnims[anim].y2 += stackPos(2); - if (_sceneAnims[anim].flags & 2) { - _sceneAnims[anim].x += stackPos(1); - _sceneAnims[anim].y += stackPos(2); - } - updateSceneAnim(anim, stackPos(3)); - _specialSceneScriptRunFlag = false; - return 0; -} - -int KyraEngine_v2::o2_useItemOnMainChar(EMCState *script) { - EMCState tmpScript; - _emc->init(&tmpScript, &_npcScriptData); - _emc->start(&tmpScript, 0); - tmpScript.regs[4] = _itemInHand; - tmpScript.regs[0] = _mainCharacter.sceneId; - - int oldVocH = _vocHigh; - _vocHigh = 0x5a; - - while(_emc->isValid(&tmpScript)) - _emc->run(&tmpScript); - - _vocHigh = oldVocH; - - return 0; -} - -int KyraEngine_v2::o2_startDialogue(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_startDialogue(%p) (%d)", (const void *)script, stackPos(0)); - startDialogue(stackPos(0)); - return 0; -} - -int KyraEngine_v2::o2_zanthRandomChat(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_zanthRandomChat(%p)", (const void *)script); - zanthRandomIdleChat(); - return 0; -} - -int KyraEngine_v2::o2_setupDialogue(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_setupDialogue(%p) (%d)", (const void *)script, stackPos(0)); - setNewDlgIndex(stackPos(0)); - return 0; -} - -int KyraEngine_v2::o2_getDlgIndex(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_setNewDlgIndex(%p) (%d)", (const void *)script, stackPos(0)); - return _mainCharacter.dlgIndex; -} - -int KyraEngine_v2::o2_defineRoom(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_defineRoom(%p) (%d, '%s', %d, %d, %d, %d, %d, %d)", (const void *)script, - stackPos(0), stackPosString(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7)); - SceneDesc *scene = &_sceneList[stackPos(0)]; - strcpy(scene->filename, stackPosString(1)); - scene->exit1 = stackPos(2); - scene->exit2 = stackPos(3); - scene->exit3 = stackPos(4); - scene->exit4 = stackPos(5); - scene->flags = stackPos(6); - scene->sound = stackPos(7); - - if (_mainCharacter.sceneId == stackPos(0)) { - _sceneExit1 = scene->exit1; - _sceneExit2 = scene->exit2; - _sceneExit3 = scene->exit3; - _sceneExit4 = scene->exit4; - } - - return 0; -} - -int KyraEngine_v2::o2_addCauldronStateTableEntry(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_addCauldronStateTableEntry(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - return addToCauldronStateTable(stackPos(0), stackPos(1)) ? 1 : 0; -} - -int KyraEngine_v2::o2_setCountDown(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_setCountDown(%p) (%d)", (const void *)script, stackPos(0)); - _scriptCountDown = _system->getMillis() + stackPos(0) * _tickLength; - return 0; -} - -int KyraEngine_v2::o2_getCountDown(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_getCountDown(%p)", (const void *)script); - uint32 time = _system->getMillis(); - return (time > _scriptCountDown) ? 0 : (_scriptCountDown - time) / _tickLength; -} - -int KyraEngine_v2::o2_pressColorKey(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_pressColorKey(%p) (%d)", (const void *)script, stackPos(0)); - for (int i = 6; i; i--) - _inputColorCode[i] = _inputColorCode[i - 1]; - _inputColorCode[0] = stackPos(0) & 0xff; - for (int i = 0; i < 7; i++) { - if (_presetColorCode[i] != _inputColorCode[6 - i]) - return _dbgPass; - } - return 1; -} - -int KyraEngine_v2::o2_objectChat(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_objectChat(%p) ('%s', %d)", (const void *)script, stackPosString(0), stackPos(1)); - if (_flags.isTalkie) - warning("Unexpected call: o2_objectChat(%p) ('%s', %d)", (const void *)script, stackPosString(0), stackPos(1)); - else - objectChat(stackPosString(0), stackPos(1)); - return 0; -} - -int KyraEngine_v2::o2_chapterChange(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_chapterChange(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - const int chapter = stackPos(0); - const int scene = stackPos(1); - - resetItemList(); - - _newChapterFile = chapter; - runStartScript(chapter, 0); - - _mainCharacter.dlgIndex = 0; - memset(_newSceneDlgState, 0, 32); - - static const int zShapeList[] = { 1, 2, 2, 2, 4 }; - assert(chapter > 1 && chapter <= ARRAYSIZE(zShapeList)); - loadZShapes(zShapeList[chapter-1]); - - enterNewScene(scene, (chapter == 2) ? 2 : 0, 0, 0, 0); - - return 0; -} - -int KyraEngine_v2::o2_getColorCodeFlag1(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_getColorCodeFlag1(%p) ()", (const void *)script); - return _colorCodeFlag1; -} - -int KyraEngine_v2::o2_setColorCodeFlag1(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_getColorCodeFlag1(%p) (%d)", (const void *)script, stackPos(0)); - _colorCodeFlag1 = stackPos(0); - return 0; -} - -int KyraEngine_v2::o2_getColorCodeFlag2(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_getColorCodeFlag2(%p) ()", (const void *)script); - return _colorCodeFlag2; -} - -int KyraEngine_v2::o2_setColorCodeFlag2(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_getColorCodeFlag2(%p) (%d)", (const void *)script, stackPos(0)); - _colorCodeFlag2 = stackPos(0); - return 0; -} - -int KyraEngine_v2::o2_getColorCodeValue(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_getColorCodeValue(%p) (%d)", (const void *)script, stackPos(0)); - return _presetColorCode[stackPos(0)]; -} - -int KyraEngine_v2::o2_setColorCodeValue(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_setColorCodeValue(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - _presetColorCode[stackPos(0)] = stackPos(1) & 0xff; - return stackPos(1) & 0xff; -} - -int KyraEngine_v2::o2_countItemInstances(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_countItemInstances(%p) (%d)", (const void *)script, stackPos(0)); - uint16 item = stackPos(0); - - int count = 0; - for (int i = 0; i < 20; ++i) { - if (_mainCharacter.inventory[i] == item) - ++count; - } - - if (_itemInHand == int16(item)) - ++count; - - for (int i = 0; i < 30; ++i) { - if (_itemList[i].id == item) - ++count; - } - - if (_hiddenItems[0] == item && _newChapterFile == 1) - ++count; - if (_hiddenItems[1] == item && _newChapterFile == 1) - ++count; - if (_hiddenItems[2] == item && _newChapterFile == 2) - ++count; - if (_hiddenItems[3] == item && _newChapterFile == 2) - ++count; - if (_hiddenItems[4] == item && _newChapterFile == 1) - ++count; - - return count; -} - -int KyraEngine_v2::o2_removeItemFromScene(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_removeItemFromScene(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - const int scene = stackPos(0); - const uint16 item = stackPos(1); - for (int i = 0; i < 30; ++i) { - if (_itemList[i].sceneId == scene && _itemList[i].id == item) - _itemList[i].id = 0xFFFF; - } - return 0; -} - -int KyraEngine_v2::o2_initObject(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_initObject(%p) (%d)", (const void *)script, stackPos(0)); - initTalkObject(stackPos(0)); - return 0; -} - -int KyraEngine_v2::o2_npcChat(EMCState *script) { - if (_flags.isTalkie) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_npcChat(%p) ('%s', %d, %d, %d)", (const void *)script, stackPosString(0), stackPos(1), _vocHigh, stackPos(2)); - npcChatSequence(stackPosString(0), stackPos(1), _vocHigh, stackPos(2)); - } else { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_npcChat(%p) ('%s', %d)", (const void *)script, stackPosString(0), stackPos(1)); - npcChatSequence(stackPosString(0), stackPos(1)); - } - return 0; -} - -int KyraEngine_v2::o2_deinitObject(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_deinitObject(%p) (%d)", (const void *)script, stackPos(0)); - deinitTalkObject(stackPos(0)); - return 0; -} - -int KyraEngine_v2::o2_playTimSequence(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_playTimSequence(%p) ('%s')", (const void *)script, stackPosString(0)); - playTim(stackPosString(0)); - return 0; -} - -int KyraEngine_v2::o2_makeBookOrCauldronAppear(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_makeBookOrCauldronAppear(%p) (%d)", (const void *)script, stackPos(0)); - seq_makeBookOrCauldronAppear(stackPos(0)); - return 0; -} - -int KyraEngine_v2::o2_setSpecialSceneScriptState(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_setSpecialSceneScriptState(%p) (%d)", (const void *)script, stackPos(0)); - _specialSceneScriptState[stackPos(0)] = 1; - return 1; -} - -int KyraEngine_v2::o2_clearSpecialSceneScriptState(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_clearSpecialSceneScriptState(%p) (%d)", (const void *)script, stackPos(0)); - _specialSceneScriptState[stackPos(0)] = 0; - return 0; -} - -int KyraEngine_v2::o2_querySpecialSceneScriptState(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_querySpecialSceneScriptState(%p) (%d)", (const void *)script, stackPos(0)); - return _specialSceneScriptState[stackPos(0)]; -} - -int KyraEngine_v2::o2_resetInputColorCode(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_resetInputColorCode(%p)", (const void *)script); - memset(_inputColorCode, 255, 7); - return 0; -} - -int KyraEngine_v2::o2_setHiddenItemsEntry(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_setHiddenItemsEntry(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - return (_hiddenItems[stackPos(0)] = stackPos(1)); -} - -int KyraEngine_v2::o2_getHiddenItemsEntry(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_getHiddenItemsEntry(%p) (%d)", (const void *)script, stackPos(0)); - return _hiddenItems[stackPos(0)]; -} - -int KyraEngine_v2::o2_mushroomEffect(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_mushroomEffect(%p)", (const void *)script); - memcpy(_screen->getPalette(2), _screen->_currentPalette, 768); - - for (int i = 1; i < 768; i += 3) - _screen->_currentPalette[i] = 0; - snd_playSoundEffect(106); - _screen->fadePalette(_screen->_currentPalette, 90, &_updateFunctor); - memcpy(_screen->_currentPalette, _screen->getPalette(2), 768); - - for (int i = 0; i < 768; i += 3) { - _screen->_currentPalette[i] = _screen->_currentPalette[i + 1] = 0; - _screen->_currentPalette[i + 2] += (((int8)_screen->_currentPalette[i + 2]) >> 1); - if (_screen->_currentPalette[i + 2] > 63) - _screen->_currentPalette[i + 2] = 63; - } - snd_playSoundEffect(106); - _screen->fadePalette(_screen->_currentPalette, 90, &_updateFunctor); - - memcpy(_screen->_currentPalette, _screen->getPalette(2), 768); - _screen->fadePalette(_screen->_currentPalette, 30, &_updateFunctor); - - return 0; -} - -int KyraEngine_v2::o2_customChat(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_customChat(%p) ('%s', %d, %d)", (const void *)script, stackPosString(0), stackPos(1), stackPos(2)); - strcpy((char*)_unkBuf500Bytes, stackPosString(0)); - _chatText = (char*)_unkBuf500Bytes; - _chatObject = stackPos(1); - - _chatVocHigh = _chatVocLow = -1; - objectChatInit(_chatText, _chatObject, _vocHigh, stackPos(2)); - playVoice(_vocHigh, stackPos(2)); - return 0; -} - -int KyraEngine_v2::o2_customChatFinish(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_customChatFinish(%p) ()", (const void *)script); - _text->restoreScreen(); - _chatText = 0; - _chatObject = -1; - return 0; -} - -int KyraEngine_v2::o2_setupSceneAnimation(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_setupSceneAnimation(%p) (%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, '%s')", (const void *)script, - stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7), stackPos(8), stackPos(9), stackPos(10), stackPos(11), stackPosString(12)); - const int index = stackPos(0); - const uint16 flags = stackPos(1); - - restorePage3(); - - SceneAnim &anim = _sceneAnims[index]; - anim.flags = flags; - anim.x = stackPos(2); - anim.y = stackPos(3); - anim.x2 = stackPos(4); - anim.y2 = stackPos(5); - anim.width = stackPos(6); - anim.height = stackPos(7); - anim.unkE = stackPos(8); - anim.specialSize = stackPos(9); - anim.unk12 = stackPos(10); - anim.shapeIndex = stackPos(11); - if (stackPosString(12)) - strcpy(anim.filename, stackPosString(12)); - - if (flags & 0x40) { - _sceneAnimMovie[index]->open(stackPosString(12), 0, 0); - if (_sceneAnimMovie[index]->xAdd() || _sceneAnimMovie[index]->yAdd()) - anim.wsaFlag = 1; - else - anim.wsaFlag = 0; - } - - AnimObj *obj = &_animObjects[1+index]; - obj->enabled = 1; - obj->needRefresh = 1; - obj->unk8 = 1; - obj->animFlags = anim.flags & 8; - - if (anim.flags & 2) - obj->flags = 0x800; - else - obj->flags = 0; - - if (anim.flags & 4) - obj->flags |= 1; - - obj->xPos1 = anim.x; - obj->yPos1 = anim.y; - - if ((anim.flags & 0x20) && anim.shapeIndex >= 0) - obj->shapePtr = _sceneShapeTable[anim.shapeIndex]; - else - obj->shapePtr = 0; - - if (anim.flags & 0x40) { - obj->shapeIndex3 = anim.shapeIndex; - obj->animNum = index; - } else { - obj->shapeIndex3 = 0xFFFF; - obj->animNum = 0xFFFF; - } - - obj->shapeIndex2 = 0xFFFF; - obj->xPos2 = obj->xPos3 = anim.x2; - obj->yPos2 = obj->yPos3 = anim.y2; - obj->width = anim.width; - obj->height = anim.height; - obj->width2 = obj->height2 = anim.specialSize; - - _animList = addToAnimListSorted(_animList, obj); - obj->needRefresh = 1; - obj->unk8 = 1; - return 0; -} - -int KyraEngine_v2::o2_stopSceneAnimation(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_stopSceneAnimation(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - const int index = stackPos(0); - AnimObj &obj = _animObjects[1+index]; - restorePage3(); - obj.shapeIndex3 = 0xFFFF; - obj.animNum = 0xFFFF; - obj.needRefresh = 1; - obj.unk8 = 1; - if (stackPos(1)) - refreshAnimObjectsIfNeed(); - obj.enabled = 0; - _animList = deleteAnimListEntry(_animList, &_animObjects[1+index]); - - if (_sceneAnimMovie[index]->opened()) - _sceneAnimMovie[index]->close(); - - return 0; -} - -int KyraEngine_v2::o2_disableTimer(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_disableTimer(%p) (%d)", (const void *)script, stackPos(0)); - _timer->disable(stackPos(0)); - return 0; -} - -int KyraEngine_v2::o2_enableTimer(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_enableTimer(%p) (%d)", (const void *)script, stackPos(0)); - _timer->enable(stackPos(0)); - return 0; -} - -int KyraEngine_v2::o2_setTimerCountdown(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_setTimerCountdown(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - _timer->setCountdown(stackPos(0), stackPos(1)); - return 0; -} - -int KyraEngine_v2::o2_processPaletteIndex(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_processPaletteIndex(%p) (%d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5)); - uint8 *palette = _screen->getPalette(0); - const int index = stackPos(0); - const bool updatePalette = (stackPos(4) != 0); - const int delayTime = stackPos(5); - palette[index*3+0] = (stackPos(1) * 0x3F) / 100; - palette[index*3+1] = (stackPos(2) * 0x3F) / 100; - palette[index*3+2] = (stackPos(3) * 0x3F) / 100; - if (updatePalette) { - if (delayTime > 0) - _screen->fadePalette(palette, delayTime, &_updateFunctor); - else - _screen->setScreenPalette(palette); - } - return 0; -} - -int KyraEngine_v2::o2_updateTwoSceneAnims(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_updateTwoSceneAnims(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); - updateSceneAnim(stackPos(0), stackPos(1)); - updateSceneAnim(stackPos(2), stackPos(3)); - _specialSceneScriptRunFlag = false; - return 0; -} - -int KyraEngine_v2::o2_getRainbowRoomData(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_getRainbowRoomData(%p) (%d)", (const void *)script, stackPos(0)); - return _rainbowRoomData[stackPos(0)]; -} - -int KyraEngine_v2::o2_drawSceneShapeEx(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_drawSceneShapeEx(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); - const int itemShape = stackPos(0) + 64; - const int x = stackPos(1); - const int y = stackPos(2); - const bool skipFronUpdate = (stackPos(3) != 0); - - _screen->drawShape(2, _sceneShapeTable[6], x, y, 2, 0); - _screen->drawShape(2, getShapePtr(itemShape), x+2, y+2, 2, 0); - - if (!skipFronUpdate) { - _screen->copyRegion(x, y, x, y, 0x15, 0x14, 2, 0, Screen::CR_NO_P_CHECK); - _screen->updateScreen(); - } - - return 0; -} - -int KyraEngine_v2::o2_getBoolFromStack(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_getBoolFromStack(%p) ()", (const void *)script); - return stackPos(0) ? 1 : 0; -} - -int KyraEngine_v2::o2_getSfxDriver(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_getSfxDriver(%p) ()", (const void *)script); - if (_sound->getSfxType() == Sound::kAdlib) - return 1; - else if (_sound->getSfxType() == Sound::kMidiMT32) - return 6; - else if (_sound->getSfxType() == Sound::kMidiGM) - return 7; - // TODO: find nice default value - return 0; -} - -int KyraEngine_v2::o2_getVocSupport(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_getVocSupport(%p) ()", (const void *)script); - // we always support VOC file playback - return 1; -} - -int KyraEngine_v2::o2_getMusicDriver(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_getMusicDriver(%p) ()", (const void *)script); - if (_sound->getMusicType() == Sound::kAdlib) - return 1; - else if (_sound->getMusicType() == Sound::kMidiMT32) - return 6; - else if (_sound->getMusicType() == Sound::kMidiGM) - return 7; - // TODO: find nice default value - return 0; -} - -int KyraEngine_v2::o2_setVocHigh(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_setVocHigh(%p) (%d)", (const void *)script, stackPos(0)); - _vocHigh = stackPos(0); - return _vocHigh; -} - -int KyraEngine_v2::o2_getVocHigh(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_getVocHigh(%p) ()", (const void *)script); - return _vocHigh; -} - -int KyraEngine_v2::o2_zanthiaChat(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_zanthiaChat(%p) ('%s', %d)", (const void *)script, stackPosString(0), stackPos(1)); - objectChat(stackPosString(0), 0, _vocHigh, stackPos(1)); - return 0; -} - -int KyraEngine_v2::o2_isVoiceEnabled(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_isVoiceEnabled(%p) ()", (const void *)script); - return speechEnabled() ? 1 : 0; -} - -int KyraEngine_v2::o2_isVoicePlaying(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_isVoicePlaying(%p) ()", (const void *)script); - return (snd_voiceIsPlaying() && !skipFlag()) ? 1 : 0; -} - -int KyraEngine_v2::o2_stopVoicePlaying(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_stopVoicePlaying(%p) ()", (const void *)script); - snd_stopVoice(); - return 0; -} - -int KyraEngine_v2::o2_getGameLanguage(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_getGameLanguage(%p) ()", (const void *)script); - return _lang; -} - -int KyraEngine_v2::o2_demoFinale(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_demoFinale(%p) ()", (const void *)script); - if (!_flags.isDemo) - return 0; - - int tmpSize; - const char *const *strings = _staticres->loadStrings(k2IngameTlkDemoStrings, tmpSize); - assert(strings); - - _screen->clearPage(0); - _screen->loadPalette("THANKS.COL", _screen->_currentPalette); - _screen->loadBitmap("THANKS.CPS", 3, 3, 0); - _screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0); - - _screen->_curPage = 0; - _screen->setFont(Screen::FID_6_FNT); - int y = _lang == 1 ? 70 : 65; - for (int i = 0; i < 6; i++) - _text->printText(strings[i], _text->getCenterStringX(strings[i], 1, 319), y + i * 10, 255, 207, 0); - - _screen->setScreenPalette(_screen->_currentPalette); - _screen->updateScreen(); - - _eventList.clear(); - while (!skipFlag()) - delay(10); - - _sound->beginFadeOut(); - _screen->fadeToBlack(); - - _runFlag = 0; - return 0; -} - -int KyraEngine_v2::o2_dummy(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_dummy(%p) ()", (const void *)script); - return 0; -} - -#pragma mark - - -int KyraEngine_v2::o2t_defineNewShapes(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2t_defineNewShapes(%p) ('%s', %d, %d, %d, %d, %d, %d)", (const void *)script, stackPosString(0), - stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6)); - - strcpy(_newShapeFilename, stackPosString(0)); - _newShapeLastEntry = stackPos(1); - _newShapeWidth = stackPos(2); - _newShapeHeight = stackPos(3); - _newShapeXAdd = stackPos(4); - _newShapeYAdd = stackPos(5); - //word_324EB = stackPos(6); <- never used - - return 0; -} - -int KyraEngine_v2::o2t_setCurrentFrame(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2t_setCurrentFrame(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - _newShapeAnimFrame = stackPos(0); - _newShapeDelay = stackPos(1); - _temporaryScriptExecBit = true; - return 0; -} - -int KyraEngine_v2::o2t_playSoundEffect(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2t_playSoundEffect(%p) (%d)", (const void *)script, stackPos(0)); - snd_playSoundEffect(stackPos(0)); - return 0; -} - -int KyraEngine_v2::o2t_fadeScenePal(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2t_fadeScenePal(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - fadeScenePal(stackPos(0), stackPos(1)); - return 0; -} - -int KyraEngine_v2::o2t_setShapeFlag(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2t_setShapeFlag(%p) (%d)", (const void *)script, stackPos(0)); - if (_flags.isTalkie) - _newShapeFlag = stackPos(0); - return 0; -} - -#pragma mark - - -int KyraEngine_v2::t2_initChat(const TIM *tim, const uint16 *param) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::t2_initChat(%p, %p) (%d)", (const void*)tim, (const void*)param, param[0]); - _chatText = (const char*)tim->text + READ_LE_UINT16(tim->text + (param[0] << 1)); - _chatObject = param[1]; - - if (_flags.lang == Common::JA_JPN) { - for (int i = 0; i < _ingameTimJpStrSize; i += 2) { - if (!scumm_stricmp(_chatText, _ingameTimJpStr[i])) - _chatText = _ingameTimJpStr[i + 1]; - } - } - - objectChatInit(_chatText, _chatObject); - return 0; -} - -int KyraEngine_v2::t2_updateSceneAnim(const TIM *tim, const uint16 *param) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::t2_updateSceneAnim(%p, %p) (%d, %d)", (const void*)tim, (const void*)param, param[0], param[1]); - updateSceneAnim(param[1], param[0]); - return 0; -} - -int KyraEngine_v2::t2_resetChat(const TIM *tim, const uint16 *param) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::t2_resetChat(%p, %p) ()", (const void*)tim, (const void*)param); - _text->restoreScreen(); - _chatText = 0; - _chatObject = -1; - return 0; -} - -int KyraEngine_v2::t2_playSoundEffect(const TIM *tim, const uint16 *param) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::t2_playSoundEffect(%p, %p) (%d)", (const void*)tim, (const void*)param, param[0]); - snd_playSoundEffect(*param); - return 0; -} - -#pragma mark - - -typedef Common::Functor1Mem OpcodeV2; -#define SetOpcodeTable(x) table = &x; -#define Opcode(x) table->push_back(new OpcodeV2(this, &KyraEngine_v2::x)) -#define OpcodeUnImpl() table->push_back(new OpcodeV2(this, 0)) - -typedef Common::Functor2Mem TIMOpcodeV2; -#define OpcodeTim(x) _timOpcodes.push_back(new TIMOpcodeV2(this, &KyraEngine_v2::x)) -#define OpcodeTimUnImpl() _timOpcodes.push_back(TIMOpcodeV2(this, 0)) - -void KyraEngine_v2::setupOpcodeTable() { - Common::Array *table = 0; - - SetOpcodeTable(_opcodes); - // 0x00 - Opcode(o2_setCharacterFacingRefresh); - Opcode(o2_setCharacterPos); - Opcode(o2_defineObject); - Opcode(o2_refreshCharacter); - // 0x04 - Opcode(o2_getCharacterX); - Opcode(o2_getCharacterY); - Opcode(o2_getCharacterFacing); - Opcode(o2_getCharacterScene); - // 0x08 - Opcode(o2_setSceneComment); - OpcodeUnImpl(); - OpcodeUnImpl(); - Opcode(o2_setCharacterAnimFrame); - // 0x0c - Opcode(o2_setCharacterFacing); - Opcode(o2_trySceneChange); - Opcode(o2_moveCharacter); - Opcode(o2_customCharacterChat); - // 0x10 - Opcode(o2_soundFadeOut); - Opcode(o2_showChapterMessage); - Opcode(o2_restoreTalkTextMessageBkgd); - OpcodeUnImpl(); - // 0x14 - Opcode(o2_wsaClose); - Opcode(o2_backUpScreen); - Opcode(o2_restoreScreen); - Opcode(o2_displayWsaFrame); - // 0x18 - Opcode(o2_displayWsaSequentialFramesLooping); - Opcode(o2_wsaOpen); - Opcode(o2_displayWsaSequentialFrames); - Opcode(o2_displayWsaSequence); - // 0x1c - Opcode(o2_addItemToInventory); - Opcode(o2_drawShape); - Opcode(o2_addItemToCurScene); - Opcode(o2_dummy); // the original used this opcode to limit the mouse range temporary, - // since that is of no use and not really important we just use a dummy here - // 0x20 - Opcode(o2_checkForItem); - Opcode(o2_loadSoundFile); - Opcode(o2_removeItemSlotFromInventory); - Opcode(o2_defineItem); - // 0x24 - Opcode(o2_removeItemFromInventory); - Opcode(o2_countItemInInventory); - Opcode(o2_countItemsInScene); - Opcode(o2_queryGameFlag); - // 0x28 - Opcode(o2_resetGameFlag); - Opcode(o2_setGameFlag); - Opcode(o2_setHandItem); - Opcode(o2_removeHandItem); - // 0x2c - Opcode(o2_handItemSet); - Opcode(o2_hideMouse); - Opcode(o2_addSpecialExit); - Opcode(o2_setMousePos); - // 0x30 - Opcode(o2_showMouse); - OpcodeUnImpl(); - Opcode(o2_wipeDownMouseItem); - Opcode(o2_getElapsedSecs); - // 0x34 - Opcode(o2_getTimerDelay); - Opcode(o2_playSoundEffect); - Opcode(o2_delaySecs); - Opcode(o2_delay); - // 0x38 - Opcode(o2_dummy); - Opcode(o2_setTimerDelay); - Opcode(o2_setScaleTableItem); - Opcode(o2_setDrawLayerTableItem); - // 0x3c - Opcode(o2_setCharPalEntry); - Opcode(o2_loadZShapes); - Opcode(o2_drawSceneShape); - Opcode(o2_drawSceneShapeOnPage); - // 0x40 - Opcode(o2_disableAnimObject); - Opcode(o2_enableAnimObject); - Opcode(o2_dummy); - Opcode(o2_loadPalette384); - // 0x44 - Opcode(o2_setPalette384); - Opcode(o2_restoreBackBuffer); - Opcode(o2_backUpInventoryGfx); - Opcode(o2_disableSceneAnim); - // 0x48 - Opcode(o2_enableSceneAnim); - Opcode(o2_restoreInventoryGfx); - Opcode(o2_setSceneAnimPos2); - Opcode(o2_update); - // 0x4c - OpcodeUnImpl(); - Opcode(o2_fadeScenePal); - Opcode(o2_dummy); - Opcode(o2_dummy); - // 0x50 - Opcode(o2_enterNewSceneEx); - Opcode(o2_switchScene); - Opcode(o2_getShapeFlag1); - Opcode(o2_setPathfinderFlag); - // 0x54 - Opcode(o2_getSceneExitToFacing); - Opcode(o2_setLayerFlag); - Opcode(o2_setZanthiaPos); - Opcode(o2_loadMusicTrack); - // 0x58 - Opcode(o2_playWanderScoreViaMap); - Opcode(o2_playSoundEffect); - Opcode(o2_setSceneAnimPos); - Opcode(o2_blockInRegion); - // 0x5c - Opcode(o2_blockOutRegion); - OpcodeUnImpl(); - Opcode(o2_setCauldronState); - Opcode(o2_showItemString); - // 0x60 - Opcode(o2_getRand); - Opcode(o2_isAnySoundPlaying); - Opcode(o2_setDeathHandlerFlag); - Opcode(o2_setDrawNoShapeFlag); - // 0x64 - Opcode(o2_setRunFlag); - Opcode(o2_showLetter); - OpcodeUnImpl(); - Opcode(o2_fillRect); - // 0x68 - OpcodeUnImpl(); - OpcodeUnImpl(); - OpcodeUnImpl(); - Opcode(o2_waitForConfirmationClick); - // 0x6c - Opcode(o2_encodeShape); - Opcode(o2_defineRoomEntrance); - Opcode(o2_runTemporaryScript); - Opcode(o2_setSpecialSceneScriptRunTime); - // 0x70 - Opcode(o2_defineSceneAnim); - Opcode(o2_updateSceneAnim); - Opcode(o2_updateSceneAnim); - Opcode(o2_addToSceneAnimPosAndUpdate); - // 0x74 - Opcode(o2_useItemOnMainChar); - Opcode(o2_startDialogue); - Opcode(o2_zanthRandomChat); - Opcode(o2_setupDialogue); - // 0x78 - Opcode(o2_getDlgIndex); - Opcode(o2_defineRoom); - Opcode(o2_addCauldronStateTableEntry); - Opcode(o2_setCountDown); - // 0x7c - Opcode(o2_getCountDown); - Opcode(o2_dummy); - Opcode(o2_dummy); - Opcode(o2_pressColorKey); - // 0x80 - Opcode(o2_objectChat); - Opcode(o2_chapterChange); - Opcode(o2_getColorCodeFlag1); - Opcode(o2_setColorCodeFlag1); - // 0x84 - Opcode(o2_getColorCodeFlag2); - Opcode(o2_setColorCodeFlag2); - Opcode(o2_getColorCodeValue); - Opcode(o2_setColorCodeValue); - // 0x88 - Opcode(o2_countItemInstances); - Opcode(o2_removeItemFromScene); - Opcode(o2_initObject); - Opcode(o2_npcChat); - // 0x8c - Opcode(o2_deinitObject); - Opcode(o2_playTimSequence); - Opcode(o2_makeBookOrCauldronAppear); - Opcode(o2_setSpecialSceneScriptState); - // 0x90 - Opcode(o2_clearSpecialSceneScriptState); - Opcode(o2_querySpecialSceneScriptState); - Opcode(o2_resetInputColorCode); - Opcode(o2_setHiddenItemsEntry); - // 0x94 - Opcode(o2_getHiddenItemsEntry); - Opcode(o2_mushroomEffect); - Opcode(o2_wsaClose); - Opcode(o2_meanWhileScene); - // 0x98 - Opcode(o2_customChat); - Opcode(o2_customChatFinish); - Opcode(o2_setupSceneAnimation); - Opcode(o2_stopSceneAnimation); - // 0x9c - Opcode(o2_disableTimer); - Opcode(o2_enableTimer); - Opcode(o2_setTimerCountdown); - Opcode(o2_processPaletteIndex); - // 0xa0 - Opcode(o2_updateTwoSceneAnims); - Opcode(o2_getRainbowRoomData); - Opcode(o2_drawSceneShapeEx); - Opcode(o2_getBoolFromStack); - // 0xa4 - Opcode(o2_getSfxDriver); - Opcode(o2_getVocSupport); - Opcode(o2_getMusicDriver); - Opcode(o2_setVocHigh); - // 0xa8 - Opcode(o2_getVocHigh); - Opcode(o2_zanthiaChat); - Opcode(o2_isVoiceEnabled); - Opcode(o2_isVoicePlaying); - // 0xac - Opcode(o2_stopVoicePlaying); - Opcode(o2_getGameLanguage); - Opcode(o2_demoFinale); - Opcode(o2_dummy); - - SetOpcodeTable(_opcodesTemporary); - - // 0x00 - Opcode(o2t_defineNewShapes); - Opcode(o2t_setCurrentFrame); - Opcode(o2t_playSoundEffect); - Opcode(o2t_fadeScenePal); - // 0x04 - Opcode(o2t_setShapeFlag); - Opcode(o2_dummy); - - // ---- TIM opcodes - - // 0x00 - OpcodeTim(t2_initChat); - OpcodeTim(t2_updateSceneAnim); - OpcodeTim(t2_resetChat); - OpcodeTim(t2_playSoundEffect); -} - -} // end of namespace Kyra - - - - diff --git a/engines/kyra/script_v3.cpp b/engines/kyra/script_v3.cpp deleted file mode 100644 index 6cd469bdcd..0000000000 --- a/engines/kyra/script_v3.cpp +++ /dev/null @@ -1,1687 +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_v3.h" -#include "kyra/script.h" -#include "kyra/screen_v3.h" -#include "kyra/text_v3.h" -#include "kyra/wsamovie.h" -#include "kyra/timer.h" - -#include "common/endian.h" - -namespace Kyra { - -int KyraEngine_v3::o3_getMalcolmShapes(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_getMaloclmShapes(%p) ()", (const void *)script); - return _malcolmShapes; -} - -int KyraEngine_v3::o3_setCharacterPos(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_setCharacterPos(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - int x = stackPos(0); - int y = stackPos(1); - - if (x != -1 && y != -1) { - x &= ~3; - y &= ~1; - } - - _mainCharacter.x1 = _mainCharacter.x2 = x; - _mainCharacter.y1 = _mainCharacter.y2 = y; - - return 0; -} - -int KyraEngine_v3::o3_defineObject(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_defineObject(%p) (%d, '%s', %d, %d, %d, %d, %d, %d)", (const void *)script, - stackPos(0), stackPosString(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7)); - TalkObject &obj = _talkObjectList[stackPos(0)]; - strcpy(obj.filename, stackPosString(1)); - obj.sceneAnim = stackPos(2); - obj.sceneScript = stackPos(3); - obj.x = stackPos(4); - obj.y = stackPos(5); - obj.color = stackPos(6); - obj.sceneId = stackPos(7); - return 0; -} - -int KyraEngine_v3::o3_refreshCharacter(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_refreshCharacter(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); - const int frame = stackPos(0); - const int facing = stackPos(1); - const bool updateNeed = stackPos(2) != 0; - - if (facing >= 0) - _mainCharacter.facing = facing; - - if (frame >= 0 && frame != 87) - _mainCharacter.animFrame = _characterFrameTable[_mainCharacter.facing]; - else - _mainCharacter.animFrame = 87; - - updateCharacterAnim(0); - - if (updateNeed) - refreshAnimObjectsIfNeed(); - return 0; -} - -int KyraEngine_v3::o3_getCharacterX(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_getCharacterX(%p) ()", (const void *)script); - return _mainCharacter.x1; -} - -int KyraEngine_v3::o3_getCharacterY(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_getCharacterY(%p) ()", (const void *)script); - return _mainCharacter.y1; -} - -int KyraEngine_v3::o3_getCharacterFacing(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_getCharacterFacing(%p) ()", (const void *)script); - return _mainCharacter.facing; -} - -int KyraEngine_v3::o3_getCharacterScene(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_getCharacterScene(%p) ()", (const void *)script); - return _mainCharacter.sceneId; -} - -int KyraEngine_v3::o3_getMalcolmsMood(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_getMalcolmsMood(%p) ()", (const void *)script); - return _malcolmsMood; -} - -int KyraEngine_v3::o3_getCharacterFrameFromFacing(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_getCharacterFrameFromFacing(%p) ()", (const void *)script); - return _characterFrameTable[_mainCharacter.facing]; -} - -int KyraEngine_v3::o3_setCharacterFacingOverwrite(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_setCharacterFacingOverwrite(%p) (%d)", (const void *)script, stackPos(0)); - _mainCharacter.facing = stackPos(0); - _overwriteSceneFacing = true; - return 0; -} - -int KyraEngine_v3::o3_trySceneChange(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_trySceneChange(%p) (%d, %d, %d, %d)", (const void *)script, - stackPos(0), stackPos(1), stackPos(2), stackPos(3)); - - _unkHandleSceneChangeFlag = 1; - int success = inputSceneChange(stackPos(0), stackPos(1), stackPos(2), stackPos(3)); - _unkHandleSceneChangeFlag = 0; - - if (success) { - _emc->init(script, script->dataPtr); - _unk4 = 0; - _unk3 = -1; - _unk5 = 1; - return 0; - } else { - return (_unk4 != 0) ? 1 : 0; - } -} - -int KyraEngine_v3::o3_moveCharacter(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_moveCharacter(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); - moveCharacter(stackPos(0), stackPos(1), stackPos(2)); - return 0; -} - -int KyraEngine_v3::o3_setCharacterFacing(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_setCharacterFacing(%p) (%d)", (const void *)script, stackPos(0)); - _mainCharacter.facing = stackPos(0); - return 0; -} - -int KyraEngine_v3::o3_showSceneFileMessage(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_showSceneFileMessage(%p) (%d)", (const void *)script, stackPos(0)); - showMessage((const char*)getTableEntry(_scenesFile, stackPos(0)), 0xFF, 0xF0); - return 0; -} - -int KyraEngine_v3::o3_setCharacterAnimFrameFromFacing(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_setCharacterAnimFrameFromFacing(%p) ()", (const void *)script); - updateCharPal(0); - _mainCharacter.animFrame = _characterFrameTable[_mainCharacter.facing]; - updateCharacterAnim(0); - refreshAnimObjectsIfNeed(); - return 0; -} - -int KyraEngine_v3::o3_showBadConscience(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_showBadConscience(%p) ()", (const void *)script); - showBadConscience(); - return 0; -} - -int KyraEngine_v3::o3_hideBadConscience(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_hideBadConscience(%p) ()", (const void *)script); - hideBadConscience(); - return 0; -} - -int KyraEngine_v3::o3_setInventorySlot(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_setInventorySlot(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - const int slot = MAX(0, MIN(10, stackPos(0))); - return (_mainCharacter.inventory[slot] = stackPos(1)); -} - -int KyraEngine_v3::o3_getInventorySlot(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_getInventorySlot(%p) (%d)", (const void *)script, stackPos(0)); - return _mainCharacter.inventory[stackPos(0)]; -} - -int KyraEngine_v3::o3_addItemToInventory(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_addItemToInventory(%p) (%d)", (const void *)script, stackPos(0)); - int slot = findFreeInventorySlot(); - if (slot >= 0) { - _mainCharacter.inventory[slot] = stackPos(0); - if (_inventoryState) { - _screen->hideMouse(); - redrawInventory(0); - _screen->showMouse(); - } - } - return slot; -} - -int KyraEngine_v3::o3_addItemToCurScene(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_addItemToCurScene(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); - const uint16 item = stackPos(0); - int x = stackPos(1); - int y = stackPos(2); - int itemSlot = findFreeItem(); - - if (x < 20) - x = 20; - else if (x > 299) - x = 299; - - if (y < 18) - y = 18; - else if (y > 187) - y = 187; - - if (itemSlot >= 0) { - _itemList[itemSlot].x = x; - _itemList[itemSlot].y = y; - _itemList[itemSlot].id = item; - _itemList[itemSlot].sceneId = _mainCharacter.sceneId; - addItemToAnimList(itemSlot); - refreshAnimObjectsIfNeed(); - } - - return itemSlot; -} - -int KyraEngine_v3::o3_objectChat(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_objectChat(%p) (%d)", (const void *)script, stackPos(0)); - int id = stackPos(0); - const char *str = (const char*)getTableEntry(_useActorBuffer ? _actorFile : _sceneStrings, id); - if (str) { - objectChat(str, 0, _vocHigh, id); - playStudioSFX(str); - } - return 0; -} - -int KyraEngine_v3::o3_checkForItem(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_checkForItem(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - return findItem(stackPos(0), stackPos(1)) == -1 ? 0 : 1; -} - -int KyraEngine_v3::o3_resetInventory(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_resetInventory(%p) ()", (const void *)script); - memset(_mainCharacter.inventory, -1, sizeof(_mainCharacter.inventory)); - return 0; -} - -int KyraEngine_v3::o3_defineItem(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_defineItem(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); - int freeItem = findFreeItem(); - if (freeItem != -1) { - _itemList[freeItem].id = stackPos(0); - _itemList[freeItem].x = stackPos(1); - _itemList[freeItem].y = stackPos(2); - _itemList[freeItem].sceneId = stackPos(3); - } - return freeItem; -} - -int KyraEngine_v3::o3_removeInventoryItemInstances(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_removeInventoryItemInstances(%p) (%d)", (const void *)script, stackPos(0)); - const int item = stackPos(0); - for (int i = 0; i < 10; ++i) { - if (_mainCharacter.inventory[i] == item) - _mainCharacter.inventory[i] = 0xFFFF; - } - return 0; -} - -int KyraEngine_v3::o3_countInventoryItemInstances(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_countInventoryItemInstances(%p) (%d)", (const void *)script, stackPos(0)); - const int item = stackPos(0); - int count = 0; - - for (int i = 0; i < 10; ++i) { - if (_mainCharacter.inventory[i] == item) - ++count; - } - - if (_itemInHand == item) - ++count; - - return count; -} - -int KyraEngine_v3::o3_npcChatSequence(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_npcChatSequence(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - const int id = stackPos(0); - const char *str = (const char*)getTableEntry(_sceneStrings, id); - if (str) - npcChatSequence(str, stackPos(1), _vocHigh, id); - return 0; -} - -int KyraEngine_v3::o3_queryGameFlag(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_queryGameFlag(%p) (%d)", (const void *)script, stackPos(0)); - return queryGameFlag(stackPos(0)); -} - -int KyraEngine_v3::o3_resetGameFlag(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_resetGameFlag(%p) (%d)", (const void *)script, stackPos(0)); - resetGameFlag(stackPos(0)); - return 0; -} - -int KyraEngine_v3::o3_setGameFlag(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_setGameFlag(%p) (%d)", (const void *)script, stackPos(0)); - setGameFlag(stackPos(0)); - return 1; -} - -int KyraEngine_v3::o3_setHandItem(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_setHandItem(%p) (%d)", (const void *)script, stackPos(0)); - setHandItem(stackPos(0)); - return 0; -} - -int KyraEngine_v3::o3_removeHandItem(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_removeHandItem(%p) ()", (const void *)script); - removeHandItem(); - return 0; -} - -int KyraEngine_v3::o3_handItemSet(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_handItemSet(%p) ()", (const void *)script); - return _handItemSet; -} - -int KyraEngine_v3::o3_hideMouse(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_hideMouse(%p) ()", (const void *)script); - _screen->hideMouse(); - return 0; -} - -int KyraEngine_v3::o3_addSpecialExit(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_addSpecialExit(%p) (%d, %d, %d, %d, %d)", (const void *)script, - stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); - if (_specialExitCount < 5) { - _specialExitTable[_specialExitCount+0] = stackPos(0); - _specialExitTable[_specialExitCount+5] = stackPos(1); - _specialExitTable[_specialExitCount+10] = stackPos(2) + stackPos(0) - 1; - _specialExitTable[_specialExitCount+15] = stackPos(3) + stackPos(1) - 1; - _specialExitTable[_specialExitCount+20] = stackPos(4); - ++_specialExitCount; - } - return 0; -} - -int KyraEngine_v3::o3_setMousePos(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_setMousePos(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - setMousePos(stackPos(0), stackPos(1)); - return 0; -} - -int KyraEngine_v3::o3_showMouse(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_showMouse(%p) ()", (const void *)script); - _screen->showMouse(); - return 0; -} - -int KyraEngine_v3::o3_badConscienceChat(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_badConscienceChat(%p) (%d)", (const void *)script, stackPos(0)); - int id = stackPos(0); - const char *str = (const char*)getTableEntry(_useActorBuffer ? _actorFile : _sceneStrings, id); - badConscienceChat(str, _vocHigh, id); - return 0; -} - -int KyraEngine_v3::o3_wipeDownMouseItem(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o3_wipeDownMouseItem(%p) (-, %d, %d)", (const void *)script, stackPos(1), stackPos(2)); - _screen->hideMouse(); - const int x = stackPos(1) - 12; - const int y = stackPos(2) - 19; - - if (_itemInHand >= 0) { - backUpGfxRect32x32(x, y); - uint8 *shape = getShapePtr(_itemInHand+248); - for (int curY = y, height = 20; height > 0; height -= 2, curY += 2) { - restoreGfxRect32x32(x, y); - _screen->setNewShapeHeight(shape, height); - uint32 waitTime = _system->getMillis() + _tickLength; - _screen->drawShape(0, shape, x, curY, 0, 0); - _screen->updateScreen(); - delayUntil(waitTime); - } - restoreGfxRect32x32(x, y); - _screen->resetShapeHeight(shape); - } - - _screen->showMouse(); - removeHandItem(); - - return 0; -} - -int KyraEngine_v3::o3_setMalcolmsMood(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_setMalcolmsMood(%p) (%d)", (const void *)script, stackPos(0)); - return (_malcolmsMood = stackPos(0)); -} - -int KyraEngine_v3::o3_delay(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_delay(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - if (stackPos(1)) { - uint32 maxWaitTime = _system->getMillis() + stackPos(0) * _tickLength; - while (_system->getMillis() < maxWaitTime) { - int inputFlag = checkInput(0); - removeInputTop(); - - if (inputFlag == 198 || inputFlag == 199) - return 1; - - if (_chatText) - updateWithText(); - else - update(); - _system->delayMillis(10); - } - } else { - delay(stackPos(0) * _tickLength, true); - } - return 0; -} - -int KyraEngine_v3::o3_updateScore(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_updateScore(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - return updateScore(stackPos(0), stackPos(1)) ? 1 : 0; -} - -int KyraEngine_v3::o3_makeSecondChanceSave(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_makeSecondChanceSave(%p) ()", (const void *)script); - saveGame(getSavegameFilename(999), "SECOND CHANCE SAVE GAME"); - return 0; -} - -int KyraEngine_v3::o3_setSceneFilename(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_setSceneFilename(%p) (%d, '%s')", (const void *)script, stackPos(0), stackPosString(1)); - strcpy(_sceneList[stackPos(0)].filename1, stackPosString(1)); - _sceneList[stackPos(0)].filename1[9] = 0; - return 0; -} - -int KyraEngine_v3::o3_removeItemsFromScene(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_removeItemsFromScene(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); - const uint16 itemId = stackPos(0); - const uint16 sceneId = stackPos(1); - const bool allItems = (stackPos(2) != 0); - - int retValue = 0; - - for (int i = 0; i < 50; ++i) { - if (_itemList[i].sceneId == sceneId && _itemList[i].id == itemId) { - resetItem(i); - retValue = 1; - if (!allItems) - return 1; - } - } - - return retValue; -} - -int KyraEngine_v3::o3_disguiseMalcolm(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o3_disguiseMalcolm(%p) (%d)", (const void *)script, stackPos(0)); - loadMalcolmShapes(stackPos(0)); - updateDlgIndex(); - return 0; -} - -int KyraEngine_v3::o3_drawSceneShape(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o3_drawSceneShape(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - - int shape = stackPos(0); - int flag = (stackPos(1) != 0) ? 1 : 0; - - _screen->hideMouse(); - restorePage3(); - - const int x = _sceneShapeDescs[shape].drawX; - const int y = _sceneShapeDescs[shape].drawY; - - _screen->drawShape(2, _sceneShapes[shape], x, y, 2, flag); - - _screen->copyRegionToBuffer(3, 0, 0, 320, 200, _gamePlayBuffer); - - _screen->drawShape(0, _sceneShapes[shape], x, y, 2, flag); - - flagAnimObjsForRefresh(); - refreshAnimObjectsIfNeed(); - _screen->showMouse(); - return 0; -} - -int KyraEngine_v3::o3_drawSceneShapeOnPage(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_drawSceneShapeOnPage(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); - const int shape = stackPos(0); - - int x = _sceneShapeDescs[shape].drawX; - int y = _sceneShapeDescs[shape].drawY; - _screen->drawShape(stackPos(2), _sceneShapes[shape], x, y, 2, (stackPos(1) != 0) ? 1 : 0); - return 0; -} - -int KyraEngine_v3::o3_checkInRect(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_checkInRect(%p) (%d, %d, %d, %d, %d, %d)", (const void *)script, - stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5)); - const int x1 = stackPos(0); - const int y1 = stackPos(1); - const int x2 = stackPos(2); - const int y2 = stackPos(3); - int x = stackPos(4), y = stackPos(5); - if (_itemInHand >= 0) { - const int8 *desc = &_itemBuffer2[_itemInHand*2]; - x -= 12; - x += desc[0]; - y -= 19; - y += desc[1]; - } - - if (x >= x1 && x <= x2 && y >= y1 && y <= y2) { - //XXX - return 1; - } else { - //XXX - return 0; - } -} - -int KyraEngine_v3::o3_updateConversations(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_updateConversations(%p) (%d)", (const void *)script, stackPos(0)); - int dlgIndex = stackPos(0); - switch (_currentChapter-2) { - case 0: - dlgIndex -= 34; - break; - - case 1: - dlgIndex -= 54; - break; - - case 2: - dlgIndex -= 55; - break; - - case 3: - dlgIndex -= 70; - break; - - default: - break; - } - - int convs[4]; - Common::set_to(convs, convs+4, -1); - - if (_currentChapter == 1) { - switch (_mainCharacter.dlgIndex) { - case 0: - convs[0] = 6; - convs[1] = 12; - break; - - case 2: - convs[0] = 8; - convs[1] = 14; - break; - - case 3: - convs[0] = 9; - convs[1] = 15; - break; - - case 4: - convs[0] = 10; - convs[1] = 16; - break; - - case 5: - convs[0] = 11; - convs[1] = 17; - break; - - case 6: - convs[0] = 0; - convs[1] = 12; - break; - - case 8: - convs[0] = 2; - convs[1] = 14; - break; - - case 9: - convs[0] = 3; - convs[1] = 15; - break; - - case 10: - convs[0] = 4; - convs[1] = 16; - break; - - case 11: - convs[0] = 5; - convs[1] = 17; - break; - - case 12: - convs[0] = 0; - convs[1] = 6; - break; - - case 14: - convs[0] = 2; - convs[1] = 8; - break; - - case 15: - convs[0] = 3; - convs[1] = 9; - break; - - case 16: - convs[0] = 4; - convs[1] = 10; - break; - - case 17: - convs[0] = 5; - convs[1] = 11; - break; - - default: - break; - } - } else if (_currentChapter == 2) { - switch (_mainCharacter.dlgIndex) { - case 0: - convs[0] = 4; - convs[1] = 8; - convs[2] = 5; - convs[3] = 9; - break; - - case 1: - convs[0] = 4; - convs[1] = 8; - convs[2] = 0; - convs[3] = 5; - break; - - case 2: - convs[0] = 6; - convs[2] = 11; - break; - - case 3: - convs[0] = 7; - convs[2] = 12; - break; - - case 4: - convs[0] = 0; - convs[1] = 8; - convs[2] = 1; - convs[3] = 9; - break; - - case 5: - convs[0] = 0; - convs[1] = 8; - convs[2] = 4; - convs[3] = 1; - break; - - case 6: - convs[0] = 2; - convs[1] = 10; - break; - - case 7: - convs[0] = 3; - convs[1] = 11; - break; - - case 8: - convs[0] = 0; - convs[1] = 4; - convs[2] = 1; - break; - - case 9: - convs[0] = 0; - convs[1] = 4; - convs[2] = 0; - convs[4] = 1; - break; - - case 10: - convs[0] = 2; - convs[1] = 6; - break; - - case 11: - convs[0] = 3; - convs[1] = 7; - break; - - default: - break; - } - } else if (_currentChapter == 4) { - if (_malcolmsMood == 0) { - convs[0] = _mainCharacter.dlgIndex - 10; - convs[1] = _mainCharacter.dlgIndex - 5; - } else if (_malcolmsMood == 1) { - convs[0] = _mainCharacter.dlgIndex + 5; - convs[1] = _mainCharacter.dlgIndex + 10; - } else if (_malcolmsMood == 2) { - convs[0] = _mainCharacter.dlgIndex - 5; - convs[1] = _mainCharacter.dlgIndex + 5; - } - } - - for (int i = 0; i < 4; ++i) { - if (convs[i] != -1) - _conversationState[dlgIndex][convs[i]] = 0; - } - - return 1; -} - -int KyraEngine_v3::o3_setSceneDim(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_setSceneDim(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - _sceneMinX = stackPos(0); - _sceneMaxX = stackPos(1); - return 0; -} - -int KyraEngine_v3::o3_setSceneAnimPosAndFrame(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_setSceneAnimPosAndFrame(%p) (%d, %d, %d, %d, %d, %d)", (const void *)script, - stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5)); - SceneAnim &anim = _sceneAnims[stackPos(0)]; - const int newX2 = stackPos(1); - const int newY2 = stackPos(2); - const int newX = stackPos(3); - const int newY = stackPos(4); - - if (newX2 >= 0) - anim.x2 = newX2; - if (newY2 >= 0) - anim.y2 = newY2; - - if (newX >= 0) - anim.x = newX; - else - anim.x = anim.x2 + (anim.width >> 1); - - if (newY >= 0) - anim.y = newY; - else - anim.y = anim.y2 + anim.height - 1; - - updateSceneAnim(stackPos(0), stackPos(5)); - _specialSceneScriptRunFlag = false; - return 0; -} - -int KyraEngine_v3::o3_update(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_update(%p) (%d)", (const void *)script, stackPos(0)); - for (int times = stackPos(0); times != 0; --times) { - if (_chatText) - updateWithText(); - else - update(); - } - return 0; -} - -int KyraEngine_v3::o3_removeItemInstances(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_removeItemInstances(%p) (%d)", (const void *)script, stackPos(0)); - const int16 item = stackPos(0); - - int deleted = 0; - - for (int i = 0; i < 10; ++i) { - if (_mainCharacter.inventory[i] == item) { - _mainCharacter.inventory[i] = 0xFFFF; - ++deleted; - } - } - - if (_itemInHand == item) { - removeHandItem(); - ++deleted; - } - - for (int i = 0; i < 50; ++i) { - if (_itemList[i].id == item) { - _itemList[i].id = 0xFFFF; - ++deleted; - } - } - - return deleted; -} - -int KyraEngine_v3::o3_disableInventory(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_disableInventory(%p) ()", (const void *)script); - _enableInventory = false; - return 0; -} - -int KyraEngine_v3::o3_enableInventory(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_enableInventory(%p) ()", (const void *)script); - _enableInventory = true; - return 1; -} - -int KyraEngine_v3::o3_enterNewScene(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_enterNewScene(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), - stackPos(1), stackPos(2), stackPos(3), stackPos(4)); - - _screen->hideMouse(); - enterNewScene(stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); - - _unk5 = 1; - - if (_mainCharX == -1 || _mainCharY == -1) { - _mainCharacter.animFrame = _characterFrameTable[_mainCharacter.facing]; - updateCharacterAnim(0); - } - _screen->showMouse(); - - return 0; -} - -int KyraEngine_v3::o3_switchScene(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_switchScene(%p) (%d)", (const void *)script, stackPos(0)); - setGameFlag(1); - _mainCharX = _mainCharacter.x1; - _mainCharY = _mainCharacter.y1; - _noScriptEnter = false; - enterNewScene(stackPos(0), _mainCharacter.facing, 0, 0, 0); - _noScriptEnter = true; - return 0; -} - -int KyraEngine_v3::o3_getShapeFlag1(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_getShapeFlag1(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - return _screen->getShapeFlag1(stackPos(0), stackPos(1)); -} - -int KyraEngine_v3::o3_setMalcolmPos(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_setMalcolmPos(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - _mainCharX = stackPos(0); - _mainCharY = stackPos(1); - - if (_mainCharX == -1 && _mainCharY == -1) - _mainCharacter.animFrame = 87; - else - _mainCharacter.animFrame = _characterFrameTable[_mainCharacter.facing]; - - return 0; -} - -int KyraEngine_v3::o3_stopMusic(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_stopMusic(%p) ()", (const void *)script); - stopMusicTrack(); - return 0; -} - -int KyraEngine_v3::o3_playWanderScoreViaMap(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_playWanderScoreViaMap(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - snd_playWanderScoreViaMap(stackPos(0), stackPos(1)); - return 0; -} - -int KyraEngine_v3::o3_playSoundEffect(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_playSoundEffect(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - snd_playSoundEffect(stackPos(0), stackPos(1)); - return 0; -} - -int KyraEngine_v3::o3_getScore(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_getScore(%p) ()", (const void *)script); - return _score; -} - -int KyraEngine_v3::o3_blockOutRegion(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_blockOutRegion(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); - const int x1 = stackPos(0); - int y1 = stackPos(1); - const int x2 = stackPos(2); - int y2 = stackPos(3); - - if (y1 < _maskPageMinY) - y1 = _maskPageMinY; - if (y2 > _maskPageMaxY) - y2 = _maskPageMaxY; - - _screen->blockOutRegion(x1, y1, x2-x1+1, y2-y1+1); - return 0; -} - -int KyraEngine_v3::o3_showSceneStringsMessage(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_showSceneStringsMessage(%p) (%d)", (const void *)script, stackPos(0)); - showMessage((const char*)getTableEntry(_sceneStrings, stackPos(0)), 0xFF, 0xF0); - return 0; -} - -int KyraEngine_v3::o3_getRand(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_getRand(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - assert(stackPos(0) < stackPos(1)); - return _rnd.getRandomNumberRng(stackPos(0), stackPos(1)); -} - -int KyraEngine_v3::o3_setDeathHandler(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_setDeathHandler(%p) (%d)", (const void *)script, stackPos(0)); - _deathHandler = stackPos(0); - return 0; -} - -int KyraEngine_v3::o3_showGoodConscience(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_showGoodConscience(%p) ()", (const void *)script); - showGoodConscience(); - return 0; -} - -int KyraEngine_v3::o3_goodConscienceChat(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_goodConscienceChat(%p) (%d)", (const void *)script, stackPos(0)); - int id = stackPos(0); - const char *str = (const char*)getTableEntry(_useActorBuffer ? _actorFile : _sceneStrings, id); - goodConscienceChat(str, _vocHigh, id); - return 0; -} - -int KyraEngine_v3::o3_hideGoodConscience(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_hideGoodConscience(%p) ()", (const void *)script); - hideGoodConscience(); - return 0; -} - -int KyraEngine_v3::o3_waitForConfirmationClick(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o2_waitForConfirmationClick(%p) (%d)", (const void *)script, stackPos(0)); - resetSkipFlag(); - uint32 maxWaitTime = _system->getMillis() + stackPos(0) * _tickLength; - - while (_system->getMillis() < maxWaitTime) { - int inputFlag = checkInput(0); - removeInputTop(); - - if (inputFlag == 198 || inputFlag == 199) { - _sceneScriptState.regs[1] = _mouseX; - _sceneScriptState.regs[2] = _mouseY; - return 0; - } - - update(); - _system->delayMillis(10); - } - - _sceneScriptState.regs[1] = _mouseX; - _sceneScriptState.regs[2] = _mouseY; - return 1; -} - -int KyraEngine_v3::o3_defineRoomEntrance(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_defineRoomEntrance(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); - switch (stackPos(0)) { - case 0: - _sceneEnterX1 = stackPos(1); - _sceneEnterY1 = stackPos(2); - break; - - case 1: - _sceneEnterX2 = stackPos(1); - _sceneEnterY2 = stackPos(2); - break; - - case 2: - _sceneEnterX3 = stackPos(1); - _sceneEnterY3 = stackPos(2); - break; - - case 3: - _sceneEnterX4 = stackPos(1); - _sceneEnterY4 = stackPos(2); - break; - - default: - break; - } - return 0; -} - -int KyraEngine_v3::o3_runTemporaryScript(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_runTemporaryScript(%p) ('%s', %d, %d, %d)", (const void *)script, - stackPosString(0), stackPos(1), stackPos(2), stackPos(3)); - const int newShapes = stackPos(1); - const int unloadShapes = stackPos(2); - const int allowSkip = stackPos(3); - runTemporaryScript(stackPosString(0), allowSkip, (unloadShapes != 0) ? 1 : 0, newShapes, unloadShapes); - return 0; -} - -int KyraEngine_v3::o3_setSpecialSceneScriptRunTime(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_setSpecialSceneScriptRunTime(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - assert(stackPos(0) >= 0 && stackPos(0) < 10); - _sceneSpecialScriptsTimer[stackPos(0)] = _system->getMillis() + stackPos(1) * _tickLength; - return 0; -} - -int KyraEngine_v3::o3_defineSceneAnim(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_defineSceneAnim(%p) (%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, '%s')", - (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7), - stackPos(8), stackPos(9), stackPos(10), stackPos(11), stackPosString(12)); - const int animId = stackPos(0); - SceneAnim &anim = _sceneAnims[animId]; - - musicUpdate(0); - - uint16 flags = anim.flags = stackPos(1); - int x = anim.x = stackPos(2); - int y = anim.y = stackPos(3); - int x2 = anim.x2 = stackPos(4); - int y2 = anim.y2 = stackPos(5); - int w = anim.width = stackPos(6); - int h = anim.height = stackPos(7); - anim.unk10 = stackPos(8); - anim.specialSize = stackPos(9); - anim.unk14 = stackPos(10); - anim.shapeIndex = stackPos(11); - const char *filename = stackPosString(12); - - if (filename) - strcpy(anim.filename, filename); - - if (flags & 8) { - _sceneAnimMovie[animId]->open(filename, 1, 0); - musicUpdate(0); - if (_sceneAnimMovie[animId]->opened()) { - anim.wsaFlag = 1; - if (x2 == -1) - x2 = _sceneAnimMovie[animId]->xAdd(); - if (y2 == -1) - y2 = _sceneAnimMovie[animId]->yAdd(); - if (w == -1) - w = _sceneAnimMovie[animId]->width(); - if (h == -1) - h = _sceneAnimMovie[animId]->height(); - if (x == -1) - x = (w >> 1) + x2; - if (y == -1) - y = y2 + h - 1; - - anim.x = x; - anim.y = y; - anim.x2 = x2; - anim.y2 = y2; - anim.width = w; - anim.height = h; - } - } - - musicUpdate(0); - - return 9; -} - -int KyraEngine_v3::o3_updateSceneAnim(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_updateSceneAnim(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - updateSceneAnim(stackPos(0), stackPos(1)); - _specialSceneScriptRunFlag = false; - return 0; -} - -int KyraEngine_v3::o3_runActorScript(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_runActorScript(%p) ()", (const void *)script); - EMCData data; - EMCState state; - memset(&data, 0, sizeof(data)); - memset(&state, 0, sizeof(state)); - - _res->exists("_ACTOR.EMC", true); - _emc->load("_ACTOR.EMC", &data, &_opcodes); - _emc->init(&state, &data); - _emc->start(&state, 0); - - state.regs[4] = _itemInHand; - state.regs[0] = _mainCharacter.sceneId; - - int vocHigh = _vocHigh; - _vocHigh = 200; - _useActorBuffer = true; - - while (_emc->isValid(&state)) - _emc->run(&state); - - _useActorBuffer = false; - _vocHigh = vocHigh; - _emc->unload(&data); - - if (queryGameFlag(0x218)) { - resetGameFlag(0x218); - enterNewScene(78, -1, 0, 0, 0); - } - - return 0; -} - -int KyraEngine_v3::o3_runDialog(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_runDialog(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - runDialog(stackPos(0), stackPos(1)); - return 0; -} - -int KyraEngine_v3::o3_malcolmRandomChat(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_malcolmRandomChat(%p) ()", (const void *)script); - malcolmRandomChat(); - return 0; -} - -int KyraEngine_v3::o3_setDlgIndex(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_setDlgIndex(%p) (%d)", (const void *)script, stackPos(0)); - setDlgIndex(stackPos(0)); - return 0; -} - -int KyraEngine_v3::o3_getDlgIndex(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_getDlgIndex(%p) ()", (const void *)script); - return _mainCharacter.dlgIndex; -} - -int KyraEngine_v3::o3_defineScene(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_defineScene(%p) (%d, '%s', %d, %d, %d, %d, %d, %d)", - (const void *)script, stackPos(0), stackPosString(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7)); - const int scene = stackPos(0); - strcpy(_sceneList[scene].filename1, stackPosString(1)); - _sceneList[scene].filename1[9] = 0; - strcpy(_sceneList[scene].filename2, stackPosString(1)); - _sceneList[scene].filename2[9] = 0; - - _sceneList[scene].exit1 = stackPos(2); - _sceneList[scene].exit2 = stackPos(3); - _sceneList[scene].exit3 = stackPos(4); - _sceneList[scene].exit4 = stackPos(5); - _sceneList[scene].flags = stackPos(6); - _sceneList[scene].sound = stackPos(7); - - if (_mainCharacter.sceneId == scene) { - _sceneExit1 = _sceneList[scene].exit1; - _sceneExit2 = _sceneList[scene].exit2; - _sceneExit3 = _sceneList[scene].exit3; - _sceneExit4 = _sceneList[scene].exit4; - } - - return 0; -} - -int KyraEngine_v3::o3_setConversationState(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_setConversationState(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); - int id = stackPos(0); - const int dlgIndex = stackPos(1); - const int value = stackPos(2); - - switch (_currentChapter-2) { - case 0: - id -= 34; - break; - - case 1: - id -= 54; - break; - - case 2: - id -= 55; - break; - - case 3: - id -= 70; - break; - - default: - break; - } - - return (_conversationState[id][dlgIndex] = value); -} - -int KyraEngine_v3::o3_getConversationState(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_getConversationState(%p) (%d)", (const void *)script, stackPos(0)); - int id = stackPos(0); - const int dlgIndex = _mainCharacter.dlgIndex; - - switch (_currentChapter-2) { - case 0: - id -= 34; - break; - - case 1: - id -= 54; - break; - - case 2: - id -= 55; - break; - - case 3: - id -= 70; - break; - - default: - break; - } - - return _conversationState[id][dlgIndex]; -} - -int KyraEngine_v3::o3_changeChapter(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_changeChapter(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); - changeChapter(stackPos(0), stackPos(1), stackPos(2), stackPos(3)); - return 0; -} - -int KyraEngine_v3::o3_countItemInstances(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_countItemInstances(%p) (%d)", (const void *)script, stackPos(0)); - int count = 0; - const int16 item = stackPos(0); - - for (int i = 0; i < 10; ++i) { - if (_mainCharacter.inventory[i] == item) - ++count; - } - - if (_itemInHand == item) - ++count; - - for (int i = 0; i < 50; ++i) { - if (_itemList[i].id == item) - ++count; - } - - return count; -} - -int KyraEngine_v3::o3_dialogStartScript(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_dialogStartScript(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - dialogStartScript(stackPos(0), stackPos(1)); - return 0; -} - -int KyraEngine_v3::o3_dialogEndScript(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_dialogEndScript(%p) (%d)", (const void *)script, stackPos(0)); - dialogEndScript(stackPos(0)); - return 0; -} - -int KyraEngine_v3::o3_setSpecialSceneScriptState(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_setSpecialSceneScriptState(%p) (%d)", (const void *)script, stackPos(0)); - _specialSceneScriptState[stackPos(0)] = 1; - return 1; -} - -int KyraEngine_v3::o3_clearSpecialSceneScriptState(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_clearSpecialSceneScriptState(%p) (%d)", (const void *)script, stackPos(0)); - _specialSceneScriptState[stackPos(0)] = 0; - return 0; -} - -int KyraEngine_v3::o3_querySpecialSceneScriptState(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_querySpecialSceneScriptState(%p) (%d)", (const void *)script, stackPos(0)); - return _specialSceneScriptState[stackPos(0)]; -} - -int KyraEngine_v3::o3_setHiddenItemsEntry(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_setHiddenItemsEntry(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - return (_hiddenItems[stackPos(0)] = (uint16)stackPos(1)); -} - -int KyraEngine_v3::o3_getHiddenItemsEntry(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_getHiddenItemsEntry(%p) (%d)", (const void *)script, stackPos(0)); - return (int16)_hiddenItems[stackPos(0)]; -} - -int KyraEngine_v3::o3_customChat(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_customChat(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - const int id = stackPos(0); - const int object = stackPos(1); - const char *str = (const char *)getTableEntry(_sceneStrings, id); - - if (!str) - return 0; - - strcpy(_stringBuffer, str); - _chatText = _stringBuffer; - _chatObject = object; - _chatVocHigh = _chatVocLow = -1; - objectChatInit(_stringBuffer, object, _vocHigh, id); - playVoice(_vocHigh, id); - return 0; -} - -int KyraEngine_v3::o3_customChatFinish(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_customChatFinish(%p) ()", (const void *)script); - _text->restoreScreen(); - _chatText = 0; - _chatObject = -1; - return 0; -} - -int KyraEngine_v3::o3_setupSceneAnimObject(EMCState *script) { - debugC(9, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_setupSceneAnimObject(%p) (%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, '%s')", (const void *)script, - stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7), stackPos(8), stackPos(9), - stackPos(10), stackPos(11), stackPosString(12)); - musicUpdate(0); - setupSceneAnimObject(stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7), stackPos(8), - stackPos(9), stackPos(10), stackPos(11), stackPosString(12)); - return 0; -} - -int KyraEngine_v3::o3_removeSceneAnimObject(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_removeSceneAnimObject(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - removeSceneAnimObject(stackPos(0), stackPos(1)); - return 0; -} - -int KyraEngine_v3::o3_disableTimer(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_disableTimer(%p) (%d)", (const void *)script, stackPos(0)); - _timer->disable(stackPos(0)); - return 0; -} - -int KyraEngine_v3::o3_enableTimer(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_enableTimer(%p) (%d)", (const void *)script, stackPos(0)); - _timer->enable(stackPos(0)); - return 0; -} - -int KyraEngine_v3::o3_setTimerCountdown(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_setTimerCountdown(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - _timer->setCountdown(stackPos(0), stackPos(1)); - return 0; -} - -int KyraEngine_v3::o3_setVocHigh(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_setVocHigh(%p) (%d)", (const void *)script, stackPos(0)); - _vocHigh = stackPos(0); - return 0; -} - -int KyraEngine_v3::o3_getVocHigh(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_getVocHigh(%p) ()", (const void *)script); - return _vocHigh; -} - -int KyraEngine_v3::o3_dummy(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_dummy(%p) ()", (const void *)script); - return 0; -} - -#pragma mark - - -int KyraEngine_v3::o3t_defineNewShapes(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3t_defineNewShapes(%p) ('%s', %d, %d, %d, %d, %d)", (const void *)script, - stackPosString(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5)); - strcpy(_newShapeFilename, stackPosString(0)); - _newShapeLastEntry = stackPos(1); - _newShapeWidth = stackPos(2); - _newShapeHeight = stackPos(3); - _newShapeXAdd = stackPos(4); - _newShapeYAdd = stackPos(5); - return 0; -} - -int KyraEngine_v3::o3t_setCurrentFrame(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3t_setCurrentFrame(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - static const uint8 frameTable[] = { - 0x58, 0xD8, 0xD8, 0x98, 0x78, 0x78, 0xB8, 0xB8 - }; - - _newShapeAnimFrame = stackPos(0); - if (_useFrameTable) - _newShapeAnimFrame += frameTable[_mainCharacter.facing]; - - _newShapeDelay = stackPos(1); - _temporaryScriptExecBit = true; - return 0; -} - -int KyraEngine_v3::o3t_setNewShapeFlag(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3t_setNewShapeFlag(%p) (%d)", (const void *)script, stackPos(0)); - _newShapeFlag = stackPos(0); - return 0; -} - -#pragma mark - - -int KyraEngine_v3::o3d_updateAnim(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3d_updateAnim(%p) (%d)", (const void *)script, stackPos(0)); - if (_dialogSceneAnim >= 0) - updateSceneAnim(_dialogSceneAnim, stackPos(0)); - return 0; -} - -int KyraEngine_v3::o3d_delay(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3d_delay(%p) (%d)", (const void *)script, stackPos(0)); - const uint32 endTime = _system->getMillis() + stackPos(0) * _tickLength; - while (_system->getMillis() < endTime) { - if (_chatText) - updateWithText(); - else - update(); - _system->delayMillis(10); - } - return 0; -} - -#pragma mark - - -typedef Common::Functor1Mem OpcodeV3; -#define SetOpcodeTable(x) table = &x; -#define Opcode(x) table->push_back(new OpcodeV3(this, &KyraEngine_v3::x)) -#define OpcodeUnImpl() table->push_back(new OpcodeV3(this, 0)) -void KyraEngine_v3::setupOpcodeTable() { - Common::Array *table = 0; - - SetOpcodeTable(_opcodes); - // 0x00 - Opcode(o3_getMalcolmShapes); - Opcode(o3_setCharacterPos); - Opcode(o3_defineObject); - Opcode(o3_refreshCharacter); - // 0x04 - Opcode(o3_getCharacterX); - Opcode(o3_getCharacterY); - Opcode(o3_getCharacterFacing); - Opcode(o3_getCharacterScene); - // 0x08 - Opcode(o3_getMalcolmsMood); - Opcode(o3_dummy); - Opcode(o3_dummy); - Opcode(o3_getCharacterFrameFromFacing); - // 0x0c - Opcode(o3_setCharacterFacingOverwrite); - Opcode(o3_trySceneChange); - Opcode(o3_moveCharacter); - Opcode(o3_setCharacterFacing); - // 0x10 - OpcodeUnImpl(); - Opcode(o3_showSceneFileMessage); - Opcode(o3_dummy); - Opcode(o3_dummy); - // 0x14 - Opcode(o3_setCharacterAnimFrameFromFacing); - Opcode(o3_showBadConscience); - Opcode(o3_dummy); - Opcode(o3_hideBadConscience); - // 0x18 - OpcodeUnImpl(); - OpcodeUnImpl(); - Opcode(o3_setInventorySlot); - Opcode(o3_getInventorySlot); - // 0x1c - Opcode(o3_addItemToInventory); - OpcodeUnImpl(); - Opcode(o3_addItemToCurScene); - Opcode(o3_objectChat); - // 0x20 - Opcode(o3_checkForItem); - Opcode(o3_dummy); - Opcode(o3_resetInventory); - Opcode(o3_defineItem); - // 0x24 - Opcode(o3_removeInventoryItemInstances); - Opcode(o3_countInventoryItemInstances); - Opcode(o3_npcChatSequence); - Opcode(o3_queryGameFlag); - // 0x28 - Opcode(o3_resetGameFlag); - Opcode(o3_setGameFlag); - Opcode(o3_setHandItem); - Opcode(o3_removeHandItem); - // 0x2c - Opcode(o3_handItemSet); - Opcode(o3_hideMouse); - Opcode(o3_addSpecialExit); - Opcode(o3_setMousePos); - // 0x30 - Opcode(o3_showMouse); - Opcode(o3_badConscienceChat); - Opcode(o3_wipeDownMouseItem); - Opcode(o3_dummy); - // 0x34 - Opcode(o3_setMalcolmsMood); - Opcode(o3_playSoundEffect); - Opcode(o3_dummy); - Opcode(o3_delay); - // 0x38 - Opcode(o3_updateScore); - Opcode(o3_makeSecondChanceSave); - Opcode(o3_setSceneFilename); - OpcodeUnImpl(); - // 0x3c - Opcode(o3_removeItemsFromScene); - Opcode(o3_disguiseMalcolm); - Opcode(o3_drawSceneShape); - Opcode(o3_drawSceneShapeOnPage); - // 0x40 - Opcode(o3_checkInRect); - Opcode(o3_updateConversations); - OpcodeUnImpl(); - Opcode(o3_dummy); - // 0x44 - Opcode(o3_dummy); - Opcode(o3_setSceneDim); - OpcodeUnImpl(); - Opcode(o3_dummy); - // 0x48 - Opcode(o3_dummy); - Opcode(o3_dummy); - Opcode(o3_setSceneAnimPosAndFrame); - Opcode(o3_update); - // 0x4c - Opcode(o3_removeItemInstances); - Opcode(o3_dummy); - Opcode(o3_disableInventory); - Opcode(o3_enableInventory); - // 0x50 - Opcode(o3_enterNewScene); - Opcode(o3_switchScene); - Opcode(o3_getShapeFlag1); - Opcode(o3_dummy); - // 0x54 - Opcode(o3_dummy); - Opcode(o3_dummy); - Opcode(o3_setMalcolmPos); - Opcode(o3_stopMusic); - // 0x58 - Opcode(o3_playWanderScoreViaMap); - Opcode(o3_playSoundEffect); - Opcode(o3_getScore); - OpcodeUnImpl(); - // 0x5c - Opcode(o3_blockOutRegion); - Opcode(o3_dummy); - Opcode(o3_showSceneStringsMessage); - OpcodeUnImpl(); - // 0x60 - Opcode(o3_getRand); - Opcode(o3_dummy); - Opcode(o3_setDeathHandler); - Opcode(o3_showGoodConscience); - // 0x64 - Opcode(o3_goodConscienceChat); - Opcode(o3_hideGoodConscience); - Opcode(o3_dummy); - Opcode(o3_dummy); - // 0x68 - Opcode(o3_dummy); - Opcode(o3_dummy); - Opcode(o3_dummy); - Opcode(o3_waitForConfirmationClick); - // 0x6c - Opcode(o3_dummy); - Opcode(o3_defineRoomEntrance); - Opcode(o3_runTemporaryScript); - Opcode(o3_setSpecialSceneScriptRunTime); - // 0x70 - Opcode(o3_defineSceneAnim); - Opcode(o3_dummy); - Opcode(o3_updateSceneAnim); - Opcode(o3_dummy); - // 0x74 - Opcode(o3_runActorScript); - Opcode(o3_runDialog); - Opcode(o3_malcolmRandomChat); - Opcode(o3_setDlgIndex); - // 0x78 - Opcode(o3_getDlgIndex); - Opcode(o3_defineScene); - Opcode(o3_setConversationState); - OpcodeUnImpl(); - // 0x7c - OpcodeUnImpl(); - Opcode(o3_getConversationState); - Opcode(o3_dummy); - Opcode(o3_dummy); - // 0x80 - Opcode(o3_dummy); - Opcode(o3_changeChapter); - Opcode(o3_dummy); - Opcode(o3_dummy); - // 0x84 - Opcode(o3_dummy); - Opcode(o3_dummy); - Opcode(o3_dummy); - Opcode(o3_dummy); - // 0x88 - Opcode(o3_countItemInstances); - Opcode(o3_dummy); - Opcode(o3_dialogStartScript); - Opcode(o3_dummy); - // 0x8c - Opcode(o3_dialogEndScript); - Opcode(o3_dummy); - Opcode(o3_dummy); - Opcode(o3_setSpecialSceneScriptState); - // 0x90 - Opcode(o3_clearSpecialSceneScriptState); - Opcode(o3_querySpecialSceneScriptState); - Opcode(o3_dummy); - Opcode(o3_setHiddenItemsEntry); - // 0x94 - Opcode(o3_getHiddenItemsEntry); - Opcode(o3_dummy); - Opcode(o3_dummy); - OpcodeUnImpl(); - // 0x98 - Opcode(o3_customChat); - Opcode(o3_customChatFinish); - Opcode(o3_setupSceneAnimObject); - Opcode(o3_removeSceneAnimObject); - // 0x9c - Opcode(o3_disableTimer); - Opcode(o3_enableTimer); - Opcode(o3_setTimerCountdown); - OpcodeUnImpl(); - // 0xa0 - Opcode(o3_dummy); - Opcode(o3_dummy); - Opcode(o3_dummy); - Opcode(o3_dummy); - // 0xa4 - OpcodeUnImpl(); - OpcodeUnImpl(); - OpcodeUnImpl(); - Opcode(o3_setVocHigh); - // 0xa8 - Opcode(o3_getVocHigh); - OpcodeUnImpl(); - OpcodeUnImpl(); - OpcodeUnImpl(); - // 0xac - OpcodeUnImpl(); - Opcode(o3_dummy); - OpcodeUnImpl(); - Opcode(o3_dummy); - - SetOpcodeTable(_opcodesTemporary); - // 0x00 - Opcode(o3t_defineNewShapes); - Opcode(o3t_setCurrentFrame); - Opcode(o3_playSoundEffect); - Opcode(o3_dummy); - // 0x0a - Opcode(o3t_setNewShapeFlag); - Opcode(o3_getRand); - Opcode(o3_getMalcolmShapes); - Opcode(o3_dummy); - - SetOpcodeTable(_opcodesDialog); - // 0x00 - Opcode(o3d_updateAnim); - Opcode(o3d_delay); - Opcode(o3_getRand); - Opcode(o3_queryGameFlag); - // 0x04 - Opcode(o3_dummy); -} - -} // end of namespace Kyra diff --git a/engines/kyra/sequences_hof.cpp b/engines/kyra/sequences_hof.cpp new file mode 100644 index 0000000000..6a170b1127 --- /dev/null +++ b/engines/kyra/sequences_hof.cpp @@ -0,0 +1,2782 @@ +/* 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_hof.h" +#include "kyra/screen.h" +#include "kyra/wsamovie.h" +#include "kyra/sound.h" +#include "kyra/text_hof.h" +#include "kyra/timer.h" +#include "kyra/resource.h" + +#include "common/system.h" + +namespace Kyra { + +void KyraEngine_HoF::seq_playSequences(int startSeq, int endSeq) { + debugC(9, kDebugLevelMain, "KyraEngine_HoF::seq_playSequences(%i, %i)", startSeq, endSeq); + seq_init(); + + bool allowSkip = (!(_flags.isDemo && !_flags.isTalkie) && (startSeq == kSequenceTitle)) ? false : true; + + if (endSeq == -1) + endSeq = startSeq; + + assert(startSeq >= 0 && endSeq < kSequenceArraySize && startSeq <= endSeq); + + _sound->setSoundList(&_soundData[(startSeq > kSequenceZanfaun) ? kMusicFinale : kMusicIntro]); + _sound->loadSoundFile(0); + + _screen->_charWidth = -2; + + memset(_activeWSA, 0, sizeof(ActiveWSA) * 8); + for (int i = 0; i < 8; ++i) + _activeWSA[i].flags = -1; + + memset(_activeText, 0, sizeof(ActiveText) * 10); + seq_resetAllTextEntries(); + + _screen->hideMouse(); + int oldPage = _screen->setCurPage(2); + + for (int i = 0; i < 4; ++i) + memset(_screen->getPalette(i), 0, 0x300); + + _screen->clearPage(10); + _screen->clearPage(12); + + _seqSubframePlaying = false; + + _seqWsaCurrentFrame = 0; + _seqTextColor[0] = _seqTextColor[1] = 0; + _seqEndTime = 0; + _menuChoice = 0; + + for (int seqNum = startSeq; seqNum <= endSeq && !((skipFlag() && allowSkip) || _quitFlag || (_abortIntroFlag && allowSkip) || _menuChoice); seqNum++) { + _screen->clearPage(0); + _screen->clearPage(8); + memcpy(_screen->getPalette(1), _screen->getPalette(0), 0x300); + _seqFrameCounter = 0; + _seqStartTime = _system->getMillis(); + + allowSkip = (!(_flags.isDemo && !_flags.isTalkie) && (seqNum == kSequenceTitle)) ? false : true; + + Sequence cseq = _sequences->seq[seqNum]; + SeqProc cb = _callbackS[seqNum]; + + if (cseq.flags & 2) { + _screen->loadBitmap(cseq.cpsFile, 2, 2, _screen->getPalette(0)); + _screen->setScreenPalette(_screen->getPalette(0)); + } else { + _screen->setCurPage(2); + _screen->clearPage(2); + _screen->loadPalette("goldfont.col", _screen->getPalette(0)); + } + + if (cb && !(_flags.isDemo && !_flags.isTalkie)) + (this->*cb)(0, 0, 0, -1); + + if (cseq.flags & 1) { + _seqWsa->close(); + _seqWsa->open(cseq.wsaFile, 0, _screen->getPalette(0)); + _screen->setScreenPalette(_screen->getPalette(0)); + _seqWsa->setX(cseq.xPos); + _seqWsa->setY(cseq.yPos); + _seqWsa->setDrawPage(2); + _seqWsa->displayFrame(0, 0); + } + + if (cseq.flags & 4) { + int cp = _screen->setCurPage(2); + Screen::FontId cf = _screen->setFont(Screen::FID_GOLDFONT_FNT); + if (cseq.stringIndex1 != -1) { + int sX = (320 - _screen->getTextWidth(_sequenceStrings[cseq.stringIndex1])) / 2; + _screen->printText(_sequenceStrings[cseq.stringIndex1], sX, 100 - _screen->getFontHeight(), 1, 0); + } + if (cseq.stringIndex2 != -1) { + int sX = (320 - _screen->getTextWidth(_sequenceStrings[cseq.stringIndex2])) / 2; + _screen->printText(_sequenceStrings[cseq.stringIndex2], sX, 100, 1, 0); + } + _screen->setFont(cf); + _screen->setCurPage(cp); + } + + _screen->copyPage(2, 12); + _screen->copyPage(0, 2); + _screen->copyPage(2, 10); + _screen->copyPage(12, 2); + + seq_sequenceCommand(cseq.startupCommand); + + if (!((skipFlag() && allowSkip) || _quitFlag || (_abortIntroFlag && allowSkip) || _menuChoice)) { + _screen->copyPage(2, 0); + _screen->updateScreen(); + } + + if (cseq.flags & 1) { + int w2 = _seqWsa->width(); + int h2 = _seqWsa->height(); + int x = cseq.xPos; + int y = cseq.yPos; + + _seqFrameDelay = cseq.frameDelay; + + if (_seqWsa) { + if (x < 0) { + x = 0; + w2 = 0; + } + + if (y < 0) { + y = 0; + h2 = 0; + } + + if (cseq.xPos + _seqWsa->width() > 319) + _seqWsa->setWidth(320 - cseq.xPos); + + if (cseq.yPos + _seqWsa->height() > 199) + _seqWsa->setHeight(199 - cseq.yPos); + } + uint8 dir = (cseq.startFrame > cseq.numFrames) ? 0 : 1; + _seqWsaCurrentFrame = cseq.startFrame; + + bool loop = true; + while (loop && !((skipFlag() && allowSkip) || _quitFlag || (_abortIntroFlag && allowSkip) || _menuChoice)) { + _seqEndTime = _system->getMillis() + _seqFrameDelay * _tickLength; + + if (_seqWsa || !cb) + _screen->copyPage(12, 2); + + if (cb) { + int f = _seqWsaCurrentFrame % _seqWsa->frames(); + (this->*cb)(_seqWsa, cseq.xPos, cseq.yPos, f); + } + + if (_seqWsa) { + int f = _seqWsaCurrentFrame % _seqWsa->frames(); + _seqWsa->setX(cseq.xPos); + _seqWsa->setY(cseq.yPos); + _seqWsa->setDrawPage(2); + _seqWsa->displayFrame(f, 0); + } + + _screen->copyPage(2, 12); + + seq_processWSAs(); + seq_processText(); + + if ((_seqWsa || !cb) && !((skipFlag() && allowSkip) || _quitFlag || (_abortIntroFlag && allowSkip) || _menuChoice)) { + _screen->copyPage(2, 0); + _screen->updateScreen(); + } + + bool loop2 = true; + while (loop2 && !((skipFlag() && allowSkip) || _quitFlag || (_abortIntroFlag && allowSkip) || _menuChoice)) { + if (_seqWsa) { + seq_processText(); + if (!((skipFlag() && allowSkip) || _quitFlag || (_abortIntroFlag && allowSkip) || _menuChoice)) { + _screen->copyPage(2, 0); + _screen->updateScreen(); + } + + uint32 now = _system->getMillis(); + if (now >= _seqEndTime) { + loop2 = false; + } else { + uint32 tdiff = _seqEndTime - now; + uint32 dly = tdiff < _tickLength ? tdiff : _tickLength; + delay(dly); + } + } else { + loop = loop2 = false; + } + } + + if (loop) { + if (dir == 1) { + if (++_seqWsaCurrentFrame >= cseq.numFrames) + loop = false; + } else { + if (--_seqWsaCurrentFrame < cseq.numFrames) + loop = false; + } + } + } + _seqWsa->close(); + } else { + _seqFrameDelay = cseq.frameDelay; + _seqEndTime = _system->getMillis() + _seqFrameDelay * _tickLength; + while (!((skipFlag() && allowSkip) || _quitFlag || (_abortIntroFlag && allowSkip) || _menuChoice)) { + uint32 starttime = _system->getMillis(); + seq_processWSAs(); + if (cb) + (this->*cb)(0, 0, 0, 0); + + seq_processText(); + + _screen->copyPage(2, 0); + _screen->updateScreen(); + _screen->copyPage(12, 2); + + uint32 now = _system->getMillis(); + if (now >= _seqEndTime && !_seqSubframePlaying) + break; + + uint32 tdiff = _seqEndTime - starttime; + int32 dly = _tickLength - (now - starttime); + if (dly > 0) + delay(MIN(dly, tdiff)); + } + } + + if (cb && !(_flags.isDemo && !_flags.isTalkie)) + (this->*cb)(0, 0, 0, -2); + + uint32 ct = seq_activeTextsTimeLeft(); + uint32 dl = cseq.duration * _tickLength; + if (dl < ct) + dl = ct; + _seqEndTime = _system->getMillis() + dl; + + while (!((skipFlag() && allowSkip) || _quitFlag || (_abortIntroFlag && allowSkip) || _menuChoice)) { + uint32 starttime = _system->getMillis(); + seq_processWSAs(); + + _screen->copyPage(2, 0); + _screen->updateScreen(); + _screen->copyPage(12, 2); + + uint32 now = _system->getMillis(); + if (now >= _seqEndTime && !_seqSubframePlaying) { + break; + } + + uint32 tdiff = _seqEndTime - starttime; + int32 dly = _tickLength - (now - starttime); + if (dly > 0) + delay(MIN(dly, tdiff)); + } + + seq_sequenceCommand(cseq.finalCommand); + seq_resetAllTextEntries(); + + if (_flags.isDemo && !_flags.isTalkie) { + if (seqNum == kSequenceDemoFisher) { + _abortIntroFlag = false; + resetSkipFlag(); + seqNum = kSequenceDemoVirgin; + } + } else { + if ((seqNum != kSequenceTitle && seqNum < kSequenceZanfaun && + (_abortIntroFlag || skipFlag())) || seqNum == kSequenceZanfaun) { + _abortIntroFlag = false; + _eventList.clear(); + seqNum = kSequenceWestwood; + } else if (seqNum < kSequenceFrash && (_abortIntroFlag || skipFlag())) { + _abortIntroFlag = false; + _eventList.clear(); + seqNum = kSequenceFirates; + } + } + + if (_menuChoice) { + _abortIntroFlag = false; + _eventList.clear(); + + if (_menuChoice == 2) { + seqNum = kSequenceTitle; + _menuChoice = 0; + } + } + } + + if (!_menuChoice) + delay(1000); + + _screen->setCurPage(oldPage); + _screen->showMouse(); + + for (int i = 0; i < 8; i++) + seq_unloadWSA(i); + + _seqWsa->close(); + + _screen->_charWidth = 0; + + seq_uninit(); +} + +int KyraEngine_HoF::seq_introWestwood(WSAMovieV2 *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) { + if (_flags.platform == Common::kPlatformFMTowns || _flags.platform == Common::kPlatformPC98) + delay(300 * _tickLength); + } else if (!frm) { + _sound->playTrack(2); + } + + return 0; +} + +int KyraEngine_HoF::seq_introTitle(WSAMovieV2 *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) { + _sound->playTrack(3); + } else if (frm == 25) { + int cp = _screen->setCurPage(0); + _screen->showMouse(); + _system->updateScreen(); + _menuChoice = _menu->handle(11) + 1; + _seqEndTime = 0; + _seqSubframePlaying = false; + if (_menuChoice == 4) + quitGame(); + + _screen->hideMouse(); + _screen->setCurPage(cp); + } + + return 0; +} + +int KyraEngine_HoF::seq_introOverview(WSAMovieV2 *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]); + memset(tmpPal, 0, 256); + uint32 endtime = 0, now = 0; + + switch (_seqFrameCounter) { + case 0: + _seqSubframePlaying = true; + _sound->playTrack(4); + endtime = _system->getMillis() + 60 * _tickLength; + + _seqTextColor[1] = _screen->findLeastDifferentColor(_seqTextColorPresets, _screen->getPalette(0) + 3, 255) & 0xff; + memset(_seqTextColorMap, _seqTextColor[1], 16); + _seqTextColorMap[1] = _seqTextColor[0] = _screen->findLeastDifferentColor(_seqTextColorPresets + 3, _screen->getPalette(0) + 3, 255) & 0xff; + + _screen->setTextColorMap(_seqTextColorMap); + + now = _system->getMillis(); + if (endtime > now) + delay(endtime - now); + break; + + case 1: + _screen->generateGrayOverlay(_screen->getPalette(0), _screen->getPalette(3), 0x40, 0, 0, 0, 0x100, true); + for (int i = 0; i < 256; i++) + tmpPal[_screen->getPalette(3)[i]] = 1; + + for (int i = 0; i < 256; i++) { + int v = (tmpPal[i] == 1) ? i : _screen->getPalette(3)[i]; + v *= 3; + _screen->getPalette(2)[3 * i] = _screen->getPalette(0)[v]; + _screen->getPalette(2)[3 * i + 1] = _screen->getPalette(0)[v + 1]; + _screen->getPalette(2)[3 * i + 2] = _screen->getPalette(0)[v + 2]; + } + break; + + case 40: + seq_loadNestedSequence(0, kSequenceOver1); + break; + + case 60: + seq_loadNestedSequence(1, kSequenceOver2); + break; + + case 120: + seq_playTalkText(0); + break; + + case 200: + seq_waitForTextsTimeout(); + _screen->fadePalette(_screen->getPalette(2), 64); + break; + + case 201: + _screen->setScreenPalette(_screen->getPalette(2)); + _screen->updateScreen(); + _screen->applyOverlay(0, 0, 320, 200, 2, _screen->getPalette(3)); + _screen->copyPage(2, 12); + _screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0); + _screen->setScreenPalette(_screen->getPalette(0)); + _screen->updateScreen(); + seq_resetActiveWSA(0); + seq_resetActiveWSA(1); + break; + + case 282: + seq_loadNestedSequence(0, kSequenceForest); + seq_playTalkText(1); + break; + + case 354: + case 434: + if (!((_seqFrameCounter == 354 && (_flags.platform == Common::kPlatformFMTowns || _flags.platform == Common::kPlatformPC98)) || (_seqFrameCounter == 434 && _flags.platform == Common::kPlatformPC))) + break; + + seq_resetActiveWSA(0); + seq_loadNestedSequence(0, kSequenceDragon); + break; + + case 400: + case 540: + if (!((_seqFrameCounter == 400 && (_flags.platform == Common::kPlatformFMTowns || _flags.platform == Common::kPlatformPC98)) || (_seqFrameCounter == 540 && _flags.platform == Common::kPlatformPC))) + break; + + seq_waitForTextsTimeout(); + seq_resetActiveWSA(0); + _seqEndTime = 0; + _seqSubframePlaying = false; + break; + + default: + break; + } + + _seqFrameCounter++; + return 0; +} + +int KyraEngine_HoF::seq_introLibrary(WSAMovieV2 *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) { + case 0: + _seqSubframePlaying = true; + _sound->playTrack(5); + + _screen->generateGrayOverlay(_screen->getPalette(0), _screen->getPalette(3), 0x24, 0, 0, 0, 0x100, false); + _seqTextColor[1] = _screen->findLeastDifferentColor(_seqTextColorPresets, _screen->getPalette(0) + 3, 255) & 0xff; + memset(_seqTextColorMap, _seqTextColor[1], 16); + _seqTextColorMap[1] = _seqTextColor[0] = _screen->findLeastDifferentColor(_seqTextColorPresets + 3, _screen->getPalette(0) + 3, 255) & 0xff; + + _screen->setTextColorMap(_seqTextColorMap); + break; + + case 1: + seq_loadNestedSequence(0, kSequenceLibrary3); + seq_playTalkText(4); + break; + + case 100: + seq_waitForTextsTimeout(); + + _screen->copyPage(12, 2); + _screen->applyOverlay(0, 0, 320, 200, 2, _screen->getPalette(3)); + _screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0); + _screen->updateScreen(); + _screen->copyPage(2, 12); + + seq_resetActiveWSA(0); + seq_loadNestedSequence(0, kSequenceDarm); + break; + + case 104: + seq_playTalkText(5); + break; + + case 240: + seq_waitForTextsTimeout(); + seq_resetActiveWSA(0); + seq_loadNestedSequence(0, kSequenceLibrary2); + break; + + case 340: + seq_resetActiveWSA(0); + _screen->applyOverlay(0, 0, 320, 200, 2, _screen->getPalette(3)); + _screen->copyPage(2, 12); + _screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0); + _screen->updateScreen(); + + seq_loadNestedSequence(0, kSequenceMarco); + seq_playTalkText(6); + break; + + case 480: + case 660: + if (!((_seqFrameCounter == 480 && (_flags.platform == Common::kPlatformFMTowns || _flags.platform == Common::kPlatformPC98)) || (_seqFrameCounter == 660 && _flags.platform == Common::kPlatformPC))) + break; + + _screen->copyPage(2, 12); + seq_waitForTextsTimeout(); + seq_resetActiveWSA(0); + _seqEndTime = 0; + _seqSubframePlaying = false; + break; + + default: + break; + } + + _seqFrameCounter++; + return 0; +} + + +int KyraEngine_HoF::seq_introHand(WSAMovieV2 *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) { + case 0: + _seqSubframePlaying = true; + _sound->playTrack(6); + + _screen->generateGrayOverlay(_screen->getPalette(0), _screen->getPalette(3), 0x24, 0, 0, 0, 0x100, false); + _seqTextColor[1] = _screen->findLeastDifferentColor(_seqTextColorPresets, _screen->getPalette(0) + 3, 255) & 0xff; + memset(_seqTextColorMap, _seqTextColor[1], 16); + _seqTextColorMap[1] = _seqTextColor[0] = _screen->findLeastDifferentColor(_seqTextColorPresets + 3, _screen->getPalette(0) + 3, 255) & 0xff; + + _screen->setTextColorMap(_seqTextColorMap); + break; + + case 1: + seq_loadNestedSequence(0, kSequenceHand1a); + seq_loadNestedSequence(1, kSequenceHand1b); + seq_loadNestedSequence(2, kSequenceHand1c); + seq_playTalkText(7); + break; + + case 201: + seq_waitForTextsTimeout(); + _screen->applyOverlay(0, 0, 320, 200, 2, _screen->getPalette(3)); + _screen->copyPage(2, 12); + _screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0); + _screen->updateScreen(); + seq_resetActiveWSA(0); + seq_resetActiveWSA(1); + seq_resetActiveWSA(2); + seq_loadNestedSequence(0, kSequenceHand2); + seq_playTalkText(8); + break; + + case 260: + case 395: + if (!((_seqFrameCounter == 260 && (_flags.platform == Common::kPlatformFMTowns || _flags.platform == Common::kPlatformPC98)) || (_seqFrameCounter == 395 && _flags.platform == Common::kPlatformPC))) + break; + + seq_waitForTextsTimeout(); + seq_resetActiveWSA(0); + seq_loadNestedSequence(1, kSequenceHand3); + seq_playTalkText(9); + break; + + case 365: + case 500: + if (!((_seqFrameCounter == 365 && (_flags.platform == Common::kPlatformFMTowns || _flags.platform == Common::kPlatformPC98)) || (_seqFrameCounter == 500 && _flags.platform == Common::kPlatformPC))) + break; + + seq_waitForTextsTimeout(); + seq_resetActiveWSA(1); + seq_loadNestedSequence(0, kSequenceHand4); + break; + + case 405: + case 540: + if (!((_seqFrameCounter == 405 && (_flags.platform == Common::kPlatformFMTowns || _flags.platform == Common::kPlatformPC98)) || (_seqFrameCounter == 540 && _flags.platform == Common::kPlatformPC))) + break; + + seq_playTalkText(10); + break; + + case 484: + case 630: + if (!((_seqFrameCounter == 484 && (_flags.platform == Common::kPlatformFMTowns || _flags.platform == Common::kPlatformPC98)) || (_seqFrameCounter == 630 && _flags.platform == Common::kPlatformPC))) + break; + + seq_waitForTextsTimeout(); + seq_resetActiveWSA(0); + _seqEndTime = 0; + _seqSubframePlaying = false; + break; + + default: + break; + } + + _seqFrameCounter++; + return 0; +} + +int KyraEngine_HoF::seq_introPoint(WSAMovieV2 *wsaObj, int x, int y, int frm) { + if (frm == -2) { + seq_waitForTextsTimeout(); + _seqEndTime = 0; + } + + switch (_seqFrameCounter) { + case -2: + seq_waitForTextsTimeout(); + break; + + case 0: + _sound->playTrack(7); + + _seqTextColor[1] = 0xf7; + memset(_seqTextColorMap, _seqTextColor[1], 16); + _seqTextColorMap[1] = _seqTextColor[0] = _screen->findLeastDifferentColor(_seqTextColorPresets + 3, _screen->getPalette(0) + 3, 255) & 0xff; + _screen->setTextColorMap(_seqTextColorMap); + _screen->generateGrayOverlay(_screen->getPalette(0), _screen->getPalette(3), 0x24, 0, 0, 0, 0x100, false); + break; + + case 1: + seq_playTalkText(11); + break; + + default: + break; + } + + _seqFrameCounter++; + return 0; +} + +int KyraEngine_HoF::seq_introZanfaun(WSAMovieV2 *wsaObj, int x, int y, int frm) { + if (frm == -2) { + seq_waitForTextsTimeout(); + _seqEndTime = 0; + return 0; + } + + switch (_seqFrameCounter) { + case 0: + _sound->playTrack(8); + + _seqTextColor[1] = 0xfd; + memset(_seqTextColorMap, _seqTextColor[1], 16); + _seqTextColorMap[1] = _seqTextColor[0] = _screen->findLeastDifferentColor(_seqTextColorPresets + 3, _screen->getPalette(0) + 3, 255) & 0xff; + _screen->setTextColorMap(_seqTextColorMap); + break; + + case 1: + if (_flags.isTalkie) { + seq_playWsaSyncDialogue(21, 13, -1, 140, 70, 160, wsaObj, 0, 8, x, y); + } else { + seq_setTextEntry(21, 140, 70, 200, 160); + _seqFrameDelay = 200; + } + break; + + case 2: + case 11: + case 21: + if (!_flags.isTalkie) + _seqFrameDelay = 12; + break; + + case 9: + if (_flags.isTalkie) + seq_playWsaSyncDialogue(13, 14, -1, 140, (_flags.lang == Common::FR_FRA + || _flags.lang == Common::DE_DEU) ? 50 : 70, 160, wsaObj, 9, 15, x, y); + break; + + case 10: + if (!_flags.isTalkie) { + seq_waitForTextsTimeout(); + seq_setTextEntry(13, 140, 50, _sequenceStringsDuration[13], 160); + _seqFrameDelay = 300; + } + break; + + case 16: + if (_flags.isTalkie) + seq_playWsaSyncDialogue(18, 15, -1, 140, (_flags.lang == Common::FR_FRA) ? 50 : + (_flags.lang == Common::DE_DEU ? 40 : 70), 160, wsaObj, 10, 16, x, y); + break; + + case 17: + if (_flags.isTalkie) + _seqFrameDelay = 12; + break; + + case 20: + if (!_flags.isTalkie) { + seq_waitForTextsTimeout(); + seq_setTextEntry(18, 160, 50, _sequenceStringsDuration[18], 160); + _seqFrameDelay = 200; + } + break; + + case 26: + seq_waitForTextsTimeout(); + break; + + case 46: + if (_flags.isTalkie) { + seq_playWsaSyncDialogue(16, 16, -1, 200, 50, 120, wsaObj, 46, 46, x, y); + } else { + seq_waitForTextsTimeout(); + seq_setTextEntry(16, 200, 50, _sequenceStringsDuration[16], 120); + } + + _seqEndTime = _system->getMillis() + 120 * _tickLength; + break; + + default: + break; + } + + _seqFrameCounter++; + return 0; +} + +int KyraEngine_HoF::seq_introOver1(WSAMovieV2 *wsaObj, int x, int y, int frm) { + if (frm == 2) + seq_waitForTextsTimeout(); + else if (frm == 3) + seq_playTalkText(12); + return frm; +} + + +int KyraEngine_HoF::seq_introOver2(WSAMovieV2 *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) { + if (frm == 11) + seq_waitForTextsTimeout(); + else if (frm == 12) + seq_playTalkText(2); + + return frm; +} + +int KyraEngine_HoF::seq_introDragon(WSAMovieV2 *wsaObj, int x, int y, int frm) { + if (frm == 11) + seq_waitForTextsTimeout(); + else if (frm == 3) + seq_playTalkText(3); + return frm; +} + +int KyraEngine_HoF::seq_introDarm(WSAMovieV2 *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) { + //NULLSUB (at least in fm-towns version) + return frm; +} + +int KyraEngine_HoF::seq_introMarco(WSAMovieV2 *wsaObj, int x, int y, int frm) { + if (frm == 36) { + seq_waitForTextsTimeout(); + _seqEndTime = 0; + } + return frm; +} + +int KyraEngine_HoF::seq_introHand1a(WSAMovieV2 *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) { + if (frm == 15) + frm = 12; + return frm; +} + +int KyraEngine_HoF::seq_introHand1c(WSAMovieV2 *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) { + //NULLSUB (at least in fm-towns version) + return frm; +} + +int KyraEngine_HoF::seq_introHand3(WSAMovieV2 *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) { + uint32 endtime = 0; + int chatX = 0; + int chatY = 0; + int chatW = 0; + int chatFirstFrame = 0; + int chatLastFrame = 0; + uint16 voiceIndex = 0; + + switch (frm) { + case -2: + seq_sequenceCommand(9); + break; + + case 0: + _sound->playTrack(3); + + _seqTextColor[1] = _screen->findLeastDifferentColor(_seqTextColorPresets, _screen->getPalette(0) + 3, 255) & 0xff; + memset(_seqTextColorMap, _seqTextColor[1], 16); + _seqTextColor[0] = _seqTextColorMap[1] = 0xff; + _screen->setTextColorMap(_seqTextColorMap); + + endtime = _system->getMillis() + 480 * _tickLength; + seq_printCreditsString(81, 240, 70, _seqTextColorMap, 252); + seq_printCreditsString(82, 240, 90, _seqTextColorMap, _seqTextColor[0]); + _screen->copyPage(2, 12); + delay(endtime - _system->getMillis()); + seq_playTalkText(_flags.isTalkie ? 28 : 24); + _seqTextColor[0] = 1; + + if (_flags.isTalkie) { + chatY = (_flags.lang == Common::FR_FRA) ? 70 : 78; + chatFirstFrame = 9; + chatLastFrame = 15; + voiceIndex = 34; + } else { + chatY = (_flags.lang == Common::FR_FRA) ? 78 : 70; + chatFirstFrame = 0; + chatLastFrame = 8; + } + chatX = (_flags.lang == Common::FR_FRA) ? 84 : 88; + chatW = 100; + + seq_playWsaSyncDialogue(22, voiceIndex, 187, chatX, chatY, chatW, wsaObj, chatFirstFrame, chatLastFrame, x, y); + break; + + case 9: + case 16: + if (!((frm == 9 && !_flags.isTalkie) || (frm == 16 && _flags.isTalkie))) + break; + + _seqFrameDelay = 12; + + if (_flags.lang == Common::FR_FRA) { + chatX = 80; + chatW = 112; + } else { + chatX = (_flags.lang == Common::DE_DEU) ? 84 : 96; + chatW = 100; + } + + if (_flags.isTalkie) { + chatFirstFrame = 0; + chatLastFrame = 8; + voiceIndex = 35; + } else { + chatFirstFrame = 9; + chatLastFrame = 15; + } + chatY = 70; + + seq_playWsaSyncDialogue(23, voiceIndex, 137, chatX, chatY, chatW, wsaObj, chatFirstFrame, chatLastFrame, x, y); + if (_flags.isTalkie) + _seqWsaCurrentFrame = 17; + break; + + default: + break; + } + + _seqFrameCounter++; + return 0; +} + +int KyraEngine_HoF::seq_finaleFerb(WSAMovieV2 *wsaObj, int x, int y, int frm) { + uint32 endtime = 0; + int chatX = 0; + int chatY = 0; + int chatW = 0; + int chatFirstFrame = 0; + int chatLastFrame = 0; + uint16 voiceIndex = 0; + + switch (frm) { + case -2: + seq_sequenceCommand(9); + endtime = _system->getMillis() + 480 * _tickLength; + seq_printCreditsString(34, 240, _flags.isTalkie ? 60 : 40, _seqTextColorMap, 252); + seq_printCreditsString(35, 240, _flags.isTalkie ? 70 : 50, _seqTextColorMap, _seqTextColor[0]); + seq_printCreditsString(36, 240, _flags.isTalkie ? 90 : 70, _seqTextColorMap, 252); + seq_printCreditsString(37, 240, _flags.isTalkie ? 100 : 90, _seqTextColorMap, _seqTextColor[0]); + seq_printCreditsString(38, 240, _flags.isTalkie ? 120 : 110, _seqTextColorMap, 252); + seq_printCreditsString(39, 240, _flags.isTalkie ? 130 : 120, _seqTextColorMap, _seqTextColor[0]); + if (_flags.platform == Common::kPlatformFMTowns || _flags.platform == Common::kPlatformPC98) + seq_printCreditsString(103, 240, 130, _seqTextColorMap, _seqTextColor[0]); + delay(endtime - _system->getMillis()); + _seqEndTime = 0; + break; + + case 0: + _seqTextColor[1] = _screen->findLeastDifferentColor(_seqTextColorPresets, _screen->getPalette(0) + 3, 255) & 0xff; + memset(_seqTextColorMap, _seqTextColor[1], 16); + _seqTextColor[0] = _seqTextColorMap[1] = 255; + _screen->setTextColorMap(_seqTextColorMap); + break; + + case 5: + if (!_flags.isTalkie) + seq_playTalkText(18); + _seqFrameDelay = 16; + + if (_flags.isTalkie) { + chatFirstFrame = 5; + chatLastFrame = 8; + voiceIndex = 22; + } else { + chatLastFrame = 14; + } + chatX = 116; + chatY = 90; + chatW = 60; + + seq_playWsaSyncDialogue(24, voiceIndex, 149, chatX, chatY, chatW, wsaObj, chatFirstFrame, chatLastFrame, x, y); + break; + + case 11: + if (_flags.isTalkie) + seq_playWsaSyncDialogue(24, 22, 149, 116, 90, 60, wsaObj, 11, 14, x, y); + break; + + case 16: + seq_playTalkText(_flags.isTalkie ? 23 : 19); + _seqFrameDelay = _flags.isTalkie ? 20 : 16; + + if (_flags.lang == Common::FR_FRA) { + chatY = 48; + chatW = 88; + } else { + chatY = 60; + chatW = 100; + } + chatX = 60; + + if (_flags.isTalkie) + voiceIndex = 36; + + seq_playWsaSyncDialogue(25, voiceIndex, 143, chatX, chatY, chatW, wsaObj, 16, 25, x, y); + _seqFrameDelay = 16; + break; + + default: + break; + } + + _seqFrameCounter++; + return 0; +} + +int KyraEngine_HoF::seq_finaleFish(WSAMovieV2 *wsaObj, int x, int y, int frm) { + uint32 endtime = 0; + int chatX = 0; + int chatY = 0; + int chatW = 0; + uint16 voiceIndex = 0; + + switch (frm) { + case -2: + seq_sequenceCommand(9); + endtime = _system->getMillis() + 480 * _tickLength; + + seq_printCreditsString(40, 240, _flags.isTalkie ? 55 : 40, _seqTextColorMap, 252); + seq_printCreditsString(41, 240, _flags.isTalkie ? 65 : 50, _seqTextColorMap, _seqTextColor[0]); + seq_printCreditsString(42, 240, _flags.isTalkie ? 75 : 60, _seqTextColorMap, _seqTextColor[0]); + seq_printCreditsString(43, 240, _flags.isTalkie ? 95 : 80, _seqTextColorMap, 252); + seq_printCreditsString(44, 240, _flags.isTalkie ? 105 : 90, _seqTextColorMap, _seqTextColor[0]); + seq_printCreditsString(93, 240, _flags.isTalkie ? 125 : 110, _seqTextColorMap, 252); + seq_printCreditsString(94, 240, _flags.isTalkie ? 135 : 120, _seqTextColorMap, _seqTextColor[0]); + delay(endtime - _system->getMillis()); + _seqEndTime = 0; + break; + + case 0: + _seqTextColor[1] = _screen->findLeastDifferentColor(_seqTextColorPresets, _screen->getPalette(0) + 3, 255) & 0xff; + memset(_seqTextColorMap, _seqTextColor[1], 16); + _seqTextColor[0] = _seqTextColorMap[1] = 0xff; + _screen->setTextColorMap(_seqTextColorMap); + break; + + case 4: + chatX = 94; + chatY = 42; + chatW = 100; + if (_flags.isTalkie) + voiceIndex = 37; + seq_playWsaSyncDialogue(26, voiceIndex, 149, chatX, chatY, chatW, wsaObj, 3, 12, x, y); + break; + + case 14: + seq_playTalkText(_flags.isTalkie ? 19 : 15); + break; + + case 23: + seq_playTalkText(_flags.isTalkie ? 20 : 16); + break; + + case 29: + chatX = (_flags.lang == Common::DE_DEU) ? 82 : ((_flags.lang == Common::FR_FRA) ? 92 : 88); + chatY = 40; + chatW = 100; + + if (_flags.isTalkie) { + if (_flags.lang == Common::DE_DEU) + chatY = 35; + voiceIndex = 38; + } + + seq_playWsaSyncDialogue(27, voiceIndex, 187, chatX, chatY, chatW, wsaObj, 28, 34, x, y); + break; + + case 45: + seq_playTalkText(_flags.isTalkie ? 21 : 17); + break; + + case 50: + seq_playTalkText(_flags.isTalkie ? 29 : 25); + break; + + default: + break; + } + + _seqFrameCounter++; + return 0; +} + +int KyraEngine_HoF::seq_finaleFheep(WSAMovieV2 *wsaObj, int x, int y, int frm) { + uint32 endtime = 0; + int chatX = 0; + int chatY = 0; + int chatW = 0; + int chatFirstFrame = 0; + int chatLastFrame = 0; + uint16 voiceIndex = 0; + + switch (frm) { + case -2: + _screen->copyPage(12, 2); + _screen->copyPage(2, 0); + _screen->updateScreen(); + seq_sequenceCommand(9); + endtime = _system->getMillis() + 480 * _tickLength; + seq_printCreditsString(49, 240, 20, _seqTextColorMap, 252); + seq_printCreditsString(50, 240, 30, _seqTextColorMap, _seqTextColor[0]); + seq_printCreditsString(51, 240, 40, _seqTextColorMap, _seqTextColor[0]); + seq_printCreditsString(52, 240, 50, _seqTextColorMap, _seqTextColor[0]); + seq_printCreditsString(53, 240, 60, _seqTextColorMap, _seqTextColor[0]); + seq_printCreditsString(54, 240, 70, _seqTextColorMap, _seqTextColor[0]); + seq_printCreditsString(55, 240, 80, _seqTextColorMap, _seqTextColor[0]); + seq_printCreditsString(56, 240, 90, _seqTextColorMap, _seqTextColor[0]); + seq_printCreditsString(57, 240, 100, _seqTextColorMap, _seqTextColor[0]); + seq_printCreditsString(58, 240, 110, _seqTextColorMap, _seqTextColor[0]); + seq_printCreditsString(60, 240, 120, _seqTextColorMap, _seqTextColor[0]); + seq_printCreditsString(61, 240, 130, _seqTextColorMap, _seqTextColor[0]); + seq_printCreditsString(62, 240, 140, _seqTextColorMap, _seqTextColor[0]); + seq_printCreditsString(63, 240, 150, _seqTextColorMap, _seqTextColor[0]); + seq_printCreditsString(64, 240, 160, _seqTextColorMap, _seqTextColor[0]); + + delay(endtime - _system->getMillis()); + _seqEndTime = 0; + break; + + case 0: + _seqTextColor[1] = _screen->findLeastDifferentColor(_seqTextColorPresets, _screen->getPalette(0) + 3, 255) & 0xff; + memset(_seqTextColorMap, _seqTextColor[1], 16); + _seqTextColor[0] = _seqTextColorMap[1] = 0xff; + _screen->setTextColorMap(_seqTextColorMap); + break; + + case 2: + seq_playTalkText(_flags.isTalkie ? 25 : 21); + + if (_flags.lang == Common::FR_FRA) { + chatX = 92; + chatY = 72; + } else { + chatX = (_flags.lang == Common::DE_DEU) ? 90 : 98; + chatY = 84; + } + + if (_flags.isTalkie) { + chatFirstFrame = 8; + chatLastFrame = 9; + voiceIndex = 39; + } else { + chatFirstFrame = 2; + chatLastFrame = -8; + } + chatW = 100; + + seq_playWsaSyncDialogue(28, voiceIndex, -1, chatX, chatY, chatW, wsaObj, chatFirstFrame, chatLastFrame, x, y); + if (_flags.isTalkie) + _seqWsaCurrentFrame = 4; + break; + + case 9: + seq_playTalkText(_flags.isTalkie ? 24 : 20); + _seqFrameDelay = 100; + break; + + default: + break; + } + + _seqFrameCounter++; + return 0; +} + +int KyraEngine_HoF::seq_finaleFarmer(WSAMovieV2 *wsaObj, int x, int y, int frm) { + uint32 endtime = 0; + int chatX = 0; + int chatY = 0; + int chatW = 0; + uint16 voiceIndex = 0; + + switch (frm) { + case -2: + _screen->copyPage(12, 2); + _screen->copyPage(2, 0); + _screen->updateScreen(); + seq_sequenceCommand(9); + endtime = _system->getMillis() + 480 * _tickLength; + seq_printCreditsString(45, 240, 40, _seqTextColorMap, 252); + seq_printCreditsString(46, 240, 50, _seqTextColorMap, _seqTextColor[0]); + seq_printCreditsString(47, 240, 60, _seqTextColorMap, _seqTextColor[0]); + seq_printCreditsString(83, 240, 80, _seqTextColorMap, 252); + seq_printCreditsString(48, 240, 90, _seqTextColorMap, _seqTextColor[0]); + seq_printCreditsString(65, 240, 110, _seqTextColorMap, 252); + seq_printCreditsString(66, 240, 120, _seqTextColorMap, _seqTextColor[0]); + seq_printCreditsString(67, 240, 130, _seqTextColorMap, _seqTextColor[0]); + seq_printCreditsString(68, 240, 140, _seqTextColorMap, _seqTextColor[0]); + seq_printCreditsString(69, 240, 150, _seqTextColorMap, _seqTextColor[0]); + if (_flags.platform == Common::kPlatformFMTowns || _flags.platform == Common::kPlatformPC98) + seq_printCreditsString(104, 240, 160, _seqTextColorMap, _seqTextColor[0]); + delay(endtime - _system->getMillis()); + _seqEndTime = 0; + break; + + case 0: + _seqTextColor[1] = 1 + (_screen->findLeastDifferentColor(_seqTextColorPresets, _screen->getPalette(0) + 3, 254) & 0xff); + memset(_seqTextColorMap, _seqTextColor[1], 16); + _seqTextColorMap[1] = _seqTextColor[0] = 1 + (_screen->findLeastDifferentColor(_seqTextColorPresets + 3, _screen->getPalette(0) + 3, 254) & 0xff); + _screen->setTextColorMap(_seqTextColorMap); + seq_playTalkText(_flags.isTalkie ? 30 : 26); + break; + + case 6: + if (_flags.isTalkie) + seq_playTalkText(18); + break; + + case 12: + if (!_flags.isTalkie) + seq_playTalkText(14); + + chatX = 90; + chatY = 30; + chatW = 100; + + if (_flags.isTalkie) { + if (_flags.lang == Common::FR_FRA || _flags.lang == Common::DE_DEU) { + chatX = 75; + chatY = 25; + } + voiceIndex = 40; + } + + seq_playWsaSyncDialogue(29, voiceIndex, 150, chatX, chatY, chatW, wsaObj, 12, -21, x, y); + break; + + default: + break; + } + + _seqFrameCounter++; + return 0; +} + +int KyraEngine_HoF::seq_finaleFuards(WSAMovieV2 *wsaObj, int x, int y, int frm) { + uint32 endtime = 0; + int chatX = 0; + int chatY = 0; + int chatW = 0; + int chatFirstFrame = 0; + int chatLastFrame = 0; + int textCol = 0; + + uint16 voiceIndex = 0; + + switch (frm) { + case -2: + seq_sequenceCommand(9); + endtime = _system->getMillis() + 480 * _tickLength; + seq_printCreditsString(70, 240, 20, _seqTextColorMap, 252); + seq_printCreditsString(71, 240, 30, _seqTextColorMap, _seqTextColor[0]); + seq_printCreditsString(72, 240, 40, _seqTextColorMap, _seqTextColor[0]); + seq_printCreditsString(73, 240, 50, _seqTextColorMap, _seqTextColor[0]); + seq_printCreditsString(74, 240, 60, _seqTextColorMap, _seqTextColor[0]); + seq_printCreditsString(75, 240, 70, _seqTextColorMap, _seqTextColor[0]); + seq_printCreditsString(101, 240, 80, _seqTextColorMap, _seqTextColor[0]); + seq_printCreditsString(102, 240, 90, _seqTextColorMap, _seqTextColor[0]); + seq_printCreditsString(87, 240, 100, _seqTextColorMap, _seqTextColor[0]); + seq_printCreditsString(88, 240, 110, _seqTextColorMap, _seqTextColor[0]); + seq_printCreditsString(89, 240, 120, _seqTextColorMap, _seqTextColor[0]); + seq_printCreditsString(90, 240, 130, _seqTextColorMap, _seqTextColor[0]); + seq_printCreditsString(91, 240, 140, _seqTextColorMap, _seqTextColor[0]); + seq_printCreditsString(92, 240, 150, _seqTextColorMap, _seqTextColor[0]); + delay(endtime - _system->getMillis()); + _seqEndTime = 0; + break; + + case 0: + for (int i = 0; i < 0x300; i++) + _screen->getPalette(0)[i] &= 0x3f; + _seqTextColor[1] = 0xCf; + memset(_seqTextColorMap, _seqTextColor[1], 16); + _seqTextColor[0] = _seqTextColorMap[1] = 0xfe; + + _screen->setTextColorMap(_seqTextColorMap); + break; + + case 6: + _seqFrameDelay = 20; + + if (_flags.isTalkie) { + chatX = 82; + textCol = 143; + chatFirstFrame = 16; + chatLastFrame = 21; + voiceIndex = 41; + } else { + chatX = 62; + textCol = 137; + chatFirstFrame = 9; + chatLastFrame = 13; + } + chatY = (_flags.lang == Common::FR_FRA || _flags.lang == Common::DE_DEU) ? 88 :100; + chatW = 80; + + seq_playWsaSyncDialogue(30, voiceIndex, 137, chatX, chatY, chatW, wsaObj, chatFirstFrame, chatLastFrame, x, y); + if (_flags.isTalkie) + _seqWsaCurrentFrame = 8; + break; + + case 9: + case 16: + if (_flags.isTalkie) { + if (frm == 16) + break; + chatX = 64; + textCol = 137; + chatFirstFrame = 9; + chatLastFrame = 13; + voiceIndex = 42; + } else { + if (frm == 9) + break; + chatX = 80; + textCol = 143; + chatFirstFrame = 16; + chatLastFrame = 21; + } + chatY = 100; + chatW = 100; + + seq_playWsaSyncDialogue(31, voiceIndex, 143, chatX, chatY, chatW, wsaObj, chatFirstFrame, chatLastFrame, x, y); + if (_flags.isTalkie) + _seqWsaCurrentFrame = 21; + break; + + default: + break; + } + + _seqFrameCounter++; + return 0; +} + +int KyraEngine_HoF::seq_finaleFirates(WSAMovieV2 *wsaObj, int x, int y, int frm) { + uint32 endtime = 0; + int chatX = 0; + int chatY = 0; + int chatW = 0; + uint16 voiceIndex = 0; + + switch (frm) { + case -2: + _screen->copyPage(12, 2); + _screen->copyPage(2, 0); + _screen->updateScreen(); + seq_sequenceCommand(9); + endtime = _system->getMillis() + 480 * _tickLength; + seq_printCreditsString(76, 240, 40, _seqTextColorMap, 252); + seq_printCreditsString(77, 240, 50, _seqTextColorMap, 252); + seq_printCreditsString(78, 240, 60, _seqTextColorMap, _seqTextColor[0]); + seq_printCreditsString(79, 240, 70, _seqTextColorMap, _seqTextColor[0]); + seq_printCreditsString(80, 240, 80, _seqTextColorMap, _seqTextColor[0]); + seq_printCreditsString(84, 240, 100, _seqTextColorMap, 252); + seq_printCreditsString(85, 240, 110, _seqTextColorMap, _seqTextColor[0]); + seq_printCreditsString(99, 240, 130, _seqTextColorMap, 252); + seq_printCreditsString(100, 240, 140, _seqTextColorMap, _seqTextColor[0]); + delay(endtime - _system->getMillis()); + _seqEndTime = 0; + break; + + case 0: + _seqTextColor[1] = _screen->findLeastDifferentColor(_seqTextColorPresets, _screen->getPalette(0) + 3, 255) & 0xff; + memset(_seqTextColorMap, _seqTextColor[1], 16); + _seqTextColor[0] = _seqTextColorMap[1] = 0xff; + _screen->setTextColorMap(_seqTextColorMap); + break; + + case 6: + seq_playTalkText(_flags.isTalkie ? 31 : 27); + break; + + case 14: + case 15: + if (!((frm == 15 && !_flags.isTalkie) || (frm == 14 && _flags.isTalkie))) + break; + + seq_playTalkText(_flags.isTalkie ? 31 : 27); + + if (_flags.lang == Common::DE_DEU) { + chatX = 82; + chatY = 84; + chatW = 140; + } else { + chatX = 74; + chatY = (_flags.lang == Common::FR_FRA) ? 96: 108; + chatW = 80; + } + + if (_flags.isTalkie) + voiceIndex = 43; + + seq_playWsaSyncDialogue(32, voiceIndex, 137, chatX, chatY, chatW, wsaObj, 14, 16, x, y); + break; + + case 28: + seq_playTalkText(_flags.isTalkie ? 32 : 28); + break; + + case 29: + seq_playTalkText(_flags.isTalkie ? 33 : 29); + break; + + case 31: + if (_flags.isTalkie) + voiceIndex = 44; + + chatX = 90; + chatY = (_flags.lang == Common::DE_DEU) ? 60 : 76; + chatW = 80; + + seq_playWsaSyncDialogue(33, voiceIndex, 143, chatX, chatY, chatW, wsaObj, 31, 34, x, y); + break; + + case 35: + _seqFrameDelay = 300; + break; + + default: + break; + } + + _seqFrameCounter++; + return 0; +} + +int KyraEngine_HoF::seq_finaleFrash(WSAMovieV2 *wsaObj, int x, int y, int frm) { + int tmp = 0; + + switch (frm) { + case -2: + _screen->setCurPage(2); + _screen->clearCurPage(); + _screen->copyPage(2, 12); + _screen->copyPage(2, 0); + _screen->updateScreen(); + _seqFrameCounter = 0; + seq_loadNestedSequence(0, kSequenceFiggle); + break; + + case -1: + if (_flags.isTalkie) + seq_finaleActorScreen(); + _seqSpecialFlag = _flags.isTalkie; + break; + + case 0: + if (_seqFrameCounter == 1) { + _sound->playTrack(4); + _seqTextColor[1] = _screen->findLeastDifferentColor(_seqTextColorPresets, _screen->getPalette(0) + 3, 255) & 0xff; + memset(_seqTextColorMap, _seqTextColor[1], 16); + _seqTextColor[0] = _seqTextColorMap[1] = 0xff; + _screen->setTextColorMap(_seqTextColorMap); + } + _seqFrameDelay = 10; + break; + + case 1: + if (_seqFrameCounter < 20 && _seqSpecialFlag) { + _seqWsaCurrentFrame = 0; + } else { + _seqFrameDelay = _flags.isTalkie ? 500 : (300 + _rnd.getRandomNumberRng(1, 300)); + seq_playTalkText(_flags.isTalkie ? 26 : 22); + if (_seqSpecialFlag) { + _seqFrameCounter = 3; + _seqSpecialFlag = false; + } + } + break; + + case 2: + _seqFrameDelay = 20; + break; + + case 3: + seq_playTalkText(_flags.isTalkie ? 27 : 23); + _seqFrameDelay = _flags.isTalkie ? 500 : (300 + _rnd.getRandomNumberRng(1, 300)); + break; + + case 4: + _seqFrameDelay = 10; + break; + + case 5: + seq_playTalkText(_flags.isTalkie ? 27 : 23); + tmp = _seqFrameCounter / 6; + if (tmp == 2) + _seqFrameDelay = _flags.isTalkie ? 7 : (1 + _rnd.getRandomNumberRng(1, 10)); + else if (tmp < 2) + _seqFrameDelay = _flags.isTalkie ? 500 : (300 + _rnd.getRandomNumberRng(1, 300)); + break; + + case 6: + _seqFrameDelay = 10; + tmp = _seqFrameCounter / 6; + if (tmp == 2) + _seqWsaCurrentFrame = 4; + else if (tmp < 2) + _seqWsaCurrentFrame = 0; + break; + + case 7: + _seqFrameCounter = 0; + _seqFrameDelay = 5; + seq_playTalkText(_flags.isTalkie ? 26 : 22); + break; + + case 11: + if (_seqFrameCounter < 8) + _seqWsaCurrentFrame = 8; + break; + + default: + break; + } + + _seqFrameCounter++; + return 0; +} + +void KyraEngine_HoF::seq_finaleActorScreen() { + static const uint8 colormap[] = {0, 0, 102, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + static const ScreenDim d = { 0x00, 0x0C, 0x28, 0xB4, 0xFF, 0x00, 0x00, 0x00 }; + + _screen->loadBitmap("finale.cps", 3, 3, _screen->_currentPalette); + _screen->setFont(Screen::FID_GOLDFONT_FNT); + + int talkieCreditsSize, talkieCreditsSpecialSize; + const uint8 *talkieCredits = _staticres->loadRawData(k2SeqplayCredits, talkieCreditsSize); + const char *const *talkieCreditsSpecial = _staticres->loadStrings(k2SeqplayCreditsSpecial, talkieCreditsSpecialSize); + + _sound->setSoundList(&_soundData[kMusicIngame]); + _sound->loadSoundFile(3); + _sound->playTrack(3); + + _screen->setTextColorMap(colormap); + _screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0); + _screen->updateScreen(); + _screen->fadeFromBlack(); + + _screen->_charWidth = -2; + uint8 *dataPtr = new uint8[0xafd]; + memcpy(dataPtr, talkieCredits, talkieCreditsSize); + _staticres->unloadId(k2SeqplayCredits); + + seq_displayScrollText(dataPtr, &d, 2, 6, 5, 1, Screen::FID_GOLDFONT_FNT, Screen::FID_GOLDFONT_FNT, 0, talkieCreditsSpecial); + delay(120); + + delete [] dataPtr; + _staticres->unloadId(k2SeqplayCreditsSpecial); + _sound->setSoundList(&_soundData[kMusicFinale]); + _sound->loadSoundFile(0); +} + +int KyraEngine_HoF::seq_finaleFiggle(WSAMovieV2 *wsaObj, int x, int y, int frm) { + if (_seqFrameCounter == 10) + _seqEndTime = 0; + if (_seqFrameCounter == 10 || _seqFrameCounter == 5 || _seqFrameCounter == 7) + seq_playTalkText(_flags.isTalkie ? 45 : 30); + + _seqFrameCounter++; + return frm; +} + +int KyraEngine_HoF::seq_demoVirgin(WSAMovieV2 *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) { + if (!frm) + _sound->playTrack(2); + return 0; +} +int KyraEngine_HoF::seq_demoTitle(WSAMovieV2 *wsaObj, int x, int y, int frm) { + if (!frm) { + _sound->playTrack(3); + } else if (frm == 25) { + delay(60 * _tickLength); + _seqEndTime = 0; + seq_sequenceCommand(0); + } + return 0; +} + +int KyraEngine_HoF::seq_demoHill(WSAMovieV2 *wsaObj, int x, int y, int frm) { + if (!frm) { + _sound->playTrack(4); + } else if (frm == 25) { + seq_loadNestedSequence(0, kSequenceDemoWater); + _seqFrameDelay--; + } else if (frm > 25 && frm < 50) { + if (_seqFrameDelay > 3) + _seqFrameDelay--; + } else if (frm == 95) { + _seqFrameDelay = 70; + } else if (frm == 96) { + _seqFrameDelay = 7; + } else if (frm == 129) { + seq_resetActiveWSA(0); + } + + return 0; +} + +int KyraEngine_HoF::seq_demoOuthome(WSAMovieV2 *wsaObj, int x, int y, int frm) { + switch (frm) { + case 12: + seq_playTalkText(4); + break; + + case 32: + seq_playTalkText(7); + break; + + case 36: + seq_playTalkText(10); + break; + + case 57: + seq_playTalkText(9); + break; + + case 80: + case 96: + case 149: + _seqFrameDelay = 70; + break; + + case 81: + case 97: + _seqFrameDelay = 5; + break; + + case 110: + seq_playTalkText(5); + break; + + case 137: + seq_playTalkText(6); + break; + } + + return 0; +} + +int KyraEngine_HoF::seq_demoWharf(WSAMovieV2 *wsaObj, int x, int y, int frm) { + if (!_seqFrameCounter) + seq_loadNestedSequence(0, kSequenceDemoWharf2); + + switch (frm) { + case 0: + seq_playTalkText(11); + break; + + case 5: + if ((_seqFrameCounter / 8) <= 2 || _activeWSA[0].flags != -1) + _seqWsaCurrentFrame = 0; + else + seq_resetActiveWSA(0); + break; + + case 6: + seq_resetActiveWSA(0); + break; + + case 8: + case 10: + seq_playTalkText(2); + break; + + case 13: + seq_playTalkText(7); + break; + + case 16: + seq_playTalkText(12); + break; + + default: + break; + } + + _seqFrameCounter++; + return 0; +} + +int KyraEngine_HoF::seq_demoDinob(WSAMovieV2 *wsaObj, int x, int y, int frm) { + if (frm == 0) { + if (!(_seqFrameCounter/8)) { + seq_loadNestedSequence(0, kSequenceDemoDinob2); + _seqWsaCurrentFrame = 0; + } + } else if (frm == 3) { + if (_activeWSA[0].flags != -1) { + _seqWsaCurrentFrame = 0; + } else { + seq_resetActiveWSA(0); + _screen->copyPage(2, 12); + } + } else if (frm == 4) { + seq_resetActiveWSA(0); + } + + _seqFrameCounter++; + return 0; +} + +int KyraEngine_HoF::seq_demoFisher(WSAMovieV2 *wsaObj, int x, int y, int frm) { + if (((_system->getMillis() - _seqStartTime) / (5 * _tickLength)) > 0) { + _seqStartTime = _system->getMillis(); + if (!_seqFrameCounter) { + seq_loadNestedSequence(0, kSequenceDemoBail); + seq_loadNestedSequence(1, kSequenceDemoDig); + } + + if (_seqScrollTextCounter >= 0x18f && !_seqFrameCounter) + return 0; + + if (!_seqFrameCounter) { + _screen->loadBitmap("adtext.cps", 4, 4, 0); + _screen->loadBitmap("adtext2.cps", 6, 6, 0); + _screen->copyPageMemory(6, 0, 4, 64000, 1024); + _screen->copyPageMemory(6, 1023, 6, 0, 64000); + _seqScrollTextCounter = 0; + } + + seq_scrollPage(); + _seqFrameCounter++; + if (_seqFrameCounter < 0x256 || _seqFrameCounter > 0x31c) { + if (_seqFrameCounter < 0x174 || _seqFrameCounter > 0x1d7) { + if (_seqFrameCounter < 0x84 || _seqFrameCounter > 0xe7) { + _seqScrollTextCounter++; + } + } + } + + if (_seqFrameCounter > 0x31e) { + seq_resetActiveWSA(0); + seq_resetActiveWSA(1); + _seqEndTime = 0; + _screen->copyPage(2, 12); + } + + } else { + seq_scrollPage(); + } + return 0; +} + +int KyraEngine_HoF::seq_demoWharf2(WSAMovieV2 *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) { + switch (frm) { + case 19: + seq_playTalkText(13); + break; + + case 54: + seq_playTalkText(15); + break; + + case 61: + seq_playTalkText(16); + break; + + case 69: + seq_playTalkText(14); + break; + + case 77: + seq_playTalkText(13); + break; + + case 79: + _seqWsaCurrentFrame = 4; + break; + } + + return frm; +} + +int KyraEngine_HoF::seq_demoWater(WSAMovieV2 *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) { + return frm; +} + +int KyraEngine_HoF::seq_demoDig(WSAMovieV2 *wsaObj, int x, int y, int frm) { + return frm; +} + +uint32 KyraEngine_HoF::seq_activeTextsTimeLeft() { + uint32 res = 0; + + for (int i = 0; i < 10; i++) { + uint32 chatend = (_activeText[i].duration + _activeText[i].startTime); + uint32 curtime = _system->getMillis(); + if (_activeText[i].duration != -1 && chatend > curtime) { + chatend -= curtime; + if (res < chatend) + res = chatend; + } + } + + return res; +} + +void KyraEngine_HoF::seq_processWSAs() { + for (int i = 0; i < 8; i++) { + if (_activeWSA[i].flags != -1) { + if (seq_processNextSubFrame(i)) + seq_resetActiveWSA(i); + } + } +} + +void KyraEngine_HoF::seq_processText() { + Screen::FontId curFont = _screen->setFont(Screen::FID_GOLDFONT_FNT); + int curPage = _screen->setCurPage(2); + char outputStr[70]; + + for (int i = 0; i < 10; i++) { + if (_activeText[i].startTime + _activeText[i].duration > _system->getMillis() && _activeText[i].duration != -1) { + + char *srcStr = seq_preprocessString(_sequenceStrings[_activeText[i].strIndex], _activeText[i].width); + int yPos = _activeText[i].y; + + while (*srcStr) { + uint32 linePos = 0; + for (; *srcStr; linePos++) { + if (*srcStr == 0x0d) // Carriage return + break; + outputStr[linePos] = *srcStr; + srcStr++; + } + outputStr[linePos] = 0; + if (*srcStr == 0x0d) + srcStr++; + + uint8 textColor = (_activeText[i].textcolor >= 0) ? _activeText[i].textcolor : _seqTextColor[0]; + _screen->printText(outputStr, _activeText[i].x - (_screen->getTextWidth(outputStr) / 2), yPos, textColor, 0); + yPos += 10; + } + } else { + _activeText[i].duration = -1; + } + } + + _screen->setCurPage(curPage); + _screen->setFont(curFont); +} + +char *KyraEngine_HoF::seq_preprocessString(const char *srcStr, int width) { + char *dstStr = _seqProcessedString; + int lineStart = 0; + int linePos = 0; + + while (*srcStr) { + while (*srcStr && *srcStr != 0x20) // Space + dstStr[lineStart + linePos++] = *srcStr++; + dstStr[lineStart + linePos] = 0; + + int len = _screen->getTextWidth(&dstStr[lineStart]); + if (width >= len && *srcStr) { + dstStr[lineStart + linePos++] = *srcStr++; + } else { + dstStr[lineStart + linePos] = 0x0d; // Carriage return + lineStart += linePos + 1; + linePos = 0; + if (*srcStr) + srcStr++; + } + } + dstStr[lineStart + linePos] = 0; + + return strlen(_seqProcessedString) ? dstStr : 0; +} + +void KyraEngine_HoF::seq_sequenceCommand(int command) { + uint8 pal[768]; + + for (int i = 0; i < 8; i++) + seq_resetActiveWSA(i); + + switch (command) { + case 0: + memset(pal, 0, 0x300); + _screen->fadePalette(pal, 16); + memcpy (_screen->getPalette(0), pal, 0x300); + memcpy (_screen->getPalette(1), pal, 0x300); + break; + + case 1: + memset(pal, 0x3F, 0x300); + //////////XXX + //////////Unused anyway (at least by fm-towns intro/outro) + + _screen->fadePalette(pal, 16); + memcpy (_screen->getPalette(0), pal, 0x300); + memcpy (_screen->getPalette(1), pal, 0x300); + break; + + case 3: + _screen->copyPage(2, 0); + _screen->fadePalette(_screen->getPalette(0), 16); + memcpy (_screen->getPalette(1), _screen->getPalette(0), 0x300); + break; + + case 4: + _screen->copyPage(2, 0); + _screen->fadePalette(_screen->getPalette(0), 36); + memcpy (_screen->getPalette(1), _screen->getPalette(0), 0x300); + break; + + case 5: + _screen->copyPage(2, 0); + break; + + case 6: + // UNUSED + // seq_loadBLD("library.bld"); + break; + + case 7: + // UNUSED + // seq_loadBLD("marco.bld"); + break; + + case 8: + memset(pal, 0, 0x300); + _screen->fadePalette(pal, 16); + memcpy (_screen->getPalette(0), pal, 0x300); + memcpy (_screen->getPalette(1), pal, 0x300); + + delay(120 * _tickLength); + break; + + case 9: + for (int i = 0; i < 0x100; i++) { + int pv = (_screen->getPalette(0)[3 * i] + _screen->getPalette(0)[3 * i + 1] + _screen->getPalette(0)[3 * i + 2]) / 3; + pal[3 * i] = pal[3 * i + 1] = pal[3 * i + 2] = pv & 0xff; + } + + //int a = 0x100; + //int d = (0x800 << 5) - 0x100; + //pal[3 * i] = pal[3 * i + 1] = pal[3 * i + 2] = 0x3f; + + _screen->fadePalette(pal, 64); + memcpy (_screen->getPalette(0), pal, 0x300); + memcpy (_screen->getPalette(1), pal, 0x300); + break; + + default: + break; + } +} + +void KyraEngine_HoF::seq_cmpFadeFrame(const char *cmpFile) { + _screen->copyPage(10, 2); + _screen->copyPage(4, 10); + _screen->clearPage(6); + _screen->loadBitmap(cmpFile, 6, 6, 0); + _screen->copyPage(12, 4); + + for (int i = 0; i < 3; i++) { + uint32 endtime = _system->getMillis() + 4 * _tickLength; + _screen->cmpFadeFrameStep(4, 320, 200, 0, 0, 2, 320, 200, 0, 0, 320, 200, 6); + _screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0); + _screen->updateScreen(); + delayUntil(endtime); + } + + _screen->copyPage(4, 0); + _screen->updateScreen(); + _screen->copyPage(4, 2); + _screen->copyPage(4, 6); + _screen->copyPage(10, 4); +} + +void KyraEngine_HoF::seq_playTalkText(uint8 chatNum) { + debugC(9, kDebugLevelMain, "KyraEngine_HoF::seq_playTalkText(%i)", chatNum); + + assert(chatNum < _sequenceSoundListSize); + + if (chatNum < 12 && !_flags.isDemo && textEnabled()) + seq_setTextEntry(chatNum, 160, 168, _sequenceStringsDuration[chatNum], 160); + + _speechFile = _sequenceSoundList[chatNum]; + _sound->voicePlay(_sequenceSoundList[chatNum]); +} + +void KyraEngine_HoF::seq_waitForTextsTimeout() { + debugC(9, kDebugLevelMain, "KyraEngine_HoF::seq_waitForTextsTimeout()"); + + uint32 longest = seq_activeTextsTimeLeft() + _system->getMillis(); + uint32 now = _system->getMillis(); + + if (textEnabled()) { + if (longest > now) + delay(longest - now); + } else if (speechEnabled()) { + while (snd_voiceIsPlaying()) + delay(_tickLength); + } + + seq_resetAllTextEntries(); +} + +void KyraEngine_HoF::seq_resetAllTextEntries() { + debugC(9, kDebugLevelMain, "KyraEngine_HoF::seq_resetAllTextEntries()"); + for (int i = 0; i < 10; i++) + _activeText[i].duration = -1; +} + +int KyraEngine_HoF::seq_setTextEntry(uint16 strIndex, uint16 posX, uint16 posY, int duration, uint16 width) { + debugC(9, kDebugLevelMain, "KyraEngine_HoF::seq_setTextEntry(%i, %i, %i, %i, %i)", strIndex, posX, posY, duration, width); + + for (int i = 0; i < 10; i++) { + if (_activeText[i].duration != -1) { + if (i < 9) + continue; + else + return -1; + } + + _activeText[i].strIndex = strIndex; + _activeText[i].x = posX; + _activeText[i].y = posY; + _activeText[i].duration = duration * _tickLength; + _activeText[i].width = width; + _activeText[i].startTime = _system->getMillis(); + _activeText[i].textcolor = -1; + + return i; + } + return -1; +} + +void KyraEngine_HoF::seq_loadNestedSequence(int wsaNum, int seqNum) { + debugC(9, kDebugLevelMain, "KyraEngine_HoF::seq_loadNestedSequence(%i, %i)", wsaNum, seqNum); + + if (_activeWSA[wsaNum].flags != -1) + return; + + NestedSequence s = _sequences->seqn[seqNum]; + + if (!_activeWSA[wsaNum].movie) { + _activeWSA[wsaNum].movie = new WSAMovieV2(this, _screen); + assert(_activeWSA[wsaNum].movie); + } + + _activeWSA[wsaNum].movie->close(); + + _activeWSA[wsaNum].movie->open(s.wsaFile, 0, 0); + + if (!_activeWSA[wsaNum].movie->opened()) { + delete _activeWSA[wsaNum].movie; + _activeWSA[wsaNum].movie = 0; + return; + } + + _activeWSA[wsaNum].endFrame = s.endFrame; + _activeWSA[wsaNum].startFrame = _activeWSA[wsaNum].currentFrame = s.startframe; + _activeWSA[wsaNum].frameDelay = s.frameDelay; + _activeWSA[wsaNum].movie->setX(0); + _activeWSA[wsaNum].movie->setY(0); + _activeWSA[wsaNum].movie->setDrawPage(_screen->_curPage); + _activeWSA[wsaNum].callback = _callbackN[seqNum]; + _activeWSA[wsaNum].control = s.wsaControl; + + _activeWSA[wsaNum].flags = s.flags | 1; + _activeWSA[wsaNum].x = s.x; + _activeWSA[wsaNum].y = s.y; + _activeWSA[wsaNum].startupCommand = s.startupCommand; + _activeWSA[wsaNum].finalCommand = s.finalCommand; + _activeWSA[wsaNum].lastFrame = 0xffff; + + seq_nestedSequenceFrame(s.startupCommand, wsaNum); + + if (!s.startupCommand) + seq_processNextSubFrame(wsaNum); + + _activeWSA[wsaNum].nextFrame = _system->getMillis(); +} + +void KyraEngine_HoF::seq_nestedSequenceFrame(int command, int wsaNum) { + int xa = 0, ya = 0; + command--; + if (!_activeWSA[wsaNum].movie || skipFlag() || _quitFlag || _abortIntroFlag) + return; + + switch (command) { + case 0: + _activeWSA[wsaNum].movie->setDrawPage(8); + xa = -_activeWSA[wsaNum].movie->xAdd(); + ya = -_activeWSA[wsaNum].movie->yAdd(); + _activeWSA[wsaNum].movie->setX(xa); + _activeWSA[wsaNum].movie->setY(ya); + _activeWSA[wsaNum].movie->displayFrame(0, 0); + _activeWSA[wsaNum].movie->setX(0); + _activeWSA[wsaNum].movie->setY(0); + seq_animatedSubFrame(8, 2, 7, 8, _activeWSA[wsaNum].movie->xAdd(), _activeWSA[wsaNum].movie->yAdd(), + _activeWSA[wsaNum].movie->width(), _activeWSA[wsaNum].movie->height(), 1, 2); + break; + + case 1: + _activeWSA[wsaNum].movie->setDrawPage(8); + xa = -_activeWSA[wsaNum].movie->xAdd(); + ya = -_activeWSA[wsaNum].movie->yAdd(); + _activeWSA[wsaNum].movie->setX(xa); + _activeWSA[wsaNum].movie->setY(ya); + _activeWSA[wsaNum].movie->displayFrame(0, 0); + _activeWSA[wsaNum].movie->setX(0); + _activeWSA[wsaNum].movie->setY(0); + seq_animatedSubFrame(8, 2, 7, 8, _activeWSA[wsaNum].movie->xAdd(), _activeWSA[wsaNum].movie->yAdd(), + _activeWSA[wsaNum].movie->width(), _activeWSA[wsaNum].movie->height(), 1, 1); + break; + + case 2: + seq_waitForTextsTimeout(); + _activeWSA[wsaNum].movie->setDrawPage(8); + xa = -_activeWSA[wsaNum].movie->xAdd(); + ya = -_activeWSA[wsaNum].movie->yAdd(); + _activeWSA[wsaNum].movie->setX(xa); + _activeWSA[wsaNum].movie->setY(ya); + _activeWSA[wsaNum].movie->displayFrame(0x15, 0); + _activeWSA[wsaNum].movie->setX(0); + _activeWSA[wsaNum].movie->setY(0); + seq_animatedSubFrame(8, 2, 7, 8, _activeWSA[wsaNum].movie->xAdd(), _activeWSA[wsaNum].movie->yAdd(), + _activeWSA[wsaNum].movie->width(), _activeWSA[wsaNum].movie->height(), 0, 2); + break; + + case 3: + _screen->copyPage(2, 10); + _activeWSA[wsaNum].movie->setDrawPage(2); + _activeWSA[wsaNum].movie->setX(0); + _activeWSA[wsaNum].movie->setY(0); + _activeWSA[wsaNum].movie->displayFrame(0, 0); + _screen->copyPage(2, 12); + seq_cmpFadeFrame("scene2.cmp"); + break; + + case 4: + _screen->copyPage(2, 10); + _activeWSA[wsaNum].movie->setDrawPage(2); + _activeWSA[wsaNum].movie->setX(0); + _activeWSA[wsaNum].movie->setY(0); + _activeWSA[wsaNum].movie->displayFrame(0, 0); + _screen->copyPage(2, 12); + seq_cmpFadeFrame("scene3.cmp"); + break; + + default: + break; + } +} + +void KyraEngine_HoF::seq_animatedSubFrame(int srcPage, int dstPage, int delaytime, int steps, + int x, int y, int w, int h, int openClose, int directionFlags) { + if (openClose) { + for (int i = 1; i < steps; i++) { + uint32 endtime = _system->getMillis() + delaytime * _tickLength; + + int w2 = (((w * 256) / steps) * i) / 256; + int h2 = (((h * 256) / steps) * i) / 256; + + int ym = (directionFlags & 2) ? (h - h2) : 0; + int xm = (directionFlags & 1) ? (w - w2) : 0; + + _screen->wsaFrameAnimationStep(0, 0, x + xm, y + ym, w, h, w2, h2, srcPage, dstPage, 0); + + _screen->copyPage(dstPage, 6); + _screen->copyPage(dstPage, 0); + _screen->updateScreen(); + + _screen->copyPage(12, dstPage); + delayUntil(endtime); + } + + _screen->wsaFrameAnimationStep(0, 0, x, y, w, h, w, h, srcPage, dstPage, 0); + _screen->copyPage(dstPage, 6); + _screen->copyPage(dstPage, 0); + _screen->updateScreen(); + } else { + _screen->copyPage(12, dstPage); + for (int i = steps; i; i--) { + uint32 endtime = _system->getMillis() + delaytime * _tickLength; + + int w2 = (((w * 256) / steps) * i) / 256; + int h2 = (((h * 256) / steps) * i) / 256; + + int ym = (directionFlags & 2) ? (h - h2) : 0; + int xm = (directionFlags & 1) ? (w - w2) : 0; + + _screen->wsaFrameAnimationStep(0, 0, x + xm, y + ym, w, h, w2, h2, srcPage, dstPage, 0); + + _screen->copyPage(dstPage, 6); + _screen->copyPage(dstPage, 0); + _screen->updateScreen(); + + _screen->copyPage(12, dstPage); + delayUntil(endtime); + } + } +} + +void KyraEngine_HoF::seq_resetActiveWSA(int wsaNum) { + if (_activeWSA[wsaNum].flags == -1) + return; + + _activeWSA[wsaNum].flags = -1; + seq_nestedSequenceFrame(_activeWSA[wsaNum].finalCommand, wsaNum); + _activeWSA[wsaNum].movie->close(); +} + +void KyraEngine_HoF::seq_unloadWSA(int wsaNum) { + if (_activeWSA[wsaNum].movie) { + _activeWSA[wsaNum].movie->close(); + delete _activeWSA[wsaNum].movie; + _activeWSA[wsaNum].movie = 0; + } +} + +bool KyraEngine_HoF::seq_processNextSubFrame(int wsaNum) { + uint32 currentFrame = _activeWSA[wsaNum].currentFrame; + uint32 currentTime = _system->getMillis(); + + if (_activeWSA[wsaNum].callback && currentFrame != _activeWSA[wsaNum].lastFrame) { + _activeWSA[wsaNum].lastFrame = currentFrame; + currentFrame = (this->*_activeWSA[wsaNum].callback)(_activeWSA[wsaNum].movie, _activeWSA[wsaNum].x, _activeWSA[wsaNum].y, currentFrame); + } + + if (_activeWSA[wsaNum].movie) { + _activeWSA[wsaNum].movie->setDrawPage(2); + _activeWSA[wsaNum].movie->setX(_activeWSA[wsaNum].x); + _activeWSA[wsaNum].movie->setY(_activeWSA[wsaNum].y); + + if (_activeWSA[wsaNum].flags & 0x20) { + _activeWSA[wsaNum].movie->displayFrame(_activeWSA[wsaNum].control[currentFrame].index, 0x4000); + _activeWSA[wsaNum].frameDelay = _activeWSA[wsaNum].control[currentFrame].delay; + } else { + _activeWSA[wsaNum].movie->displayFrame(currentFrame % _activeWSA[wsaNum].movie->frames(), 0x4000); + } + } + + if (_activeWSA[wsaNum].flags & 0x10) { + currentFrame = (currentTime - _activeWSA[wsaNum].nextFrame) / (_activeWSA[wsaNum].frameDelay * _tickLength); + } else { + if (((int32)(currentTime - _activeWSA[wsaNum].nextFrame) / (int32)(_activeWSA[wsaNum].frameDelay * _tickLength)) > 0) { + currentFrame++; + _activeWSA[wsaNum].nextFrame = currentTime; + } + } + + bool res = false; + + if (currentFrame >= _activeWSA[wsaNum].endFrame) { + int sw = ((_activeWSA[wsaNum].flags & 0x1e) - 2); + switch (sw) { + case 0: + res = true; + currentFrame = _activeWSA[wsaNum].endFrame; + _screen->copyPage(2, 12); + break; + + case 6: + case 8: + currentFrame = _activeWSA[wsaNum].endFrame - 1; + break; + + case 2: + case 10: + currentFrame = _activeWSA[wsaNum].startFrame; + break; + + default: + currentFrame = _activeWSA[wsaNum].endFrame - 1; + res = true; + break; + } + } + + _activeWSA[wsaNum].currentFrame = currentFrame & 0xffff; + return res; +} + +void KyraEngine_HoF::seq_printCreditsString(uint16 strIndex, int x, int y, const uint8 *colorMap, uint8 textcolor) { + uint8 colormap[16]; + if (skipFlag() || _quitFlag || _abortIntroFlag || _menuChoice) + return; + + memset(&_screen->getPalette(0)[0x2fa], 0x3f, 6); + _screen->getPalette(0)[0x2f6] = 0x3f; + _screen->getPalette(0)[0x2f5] = 0x20; + _screen->getPalette(0)[0x2f4] = 0x30; + colormap[0] = colorMap[0]; + colormap[1] = 0xfd; + memcpy(&colormap[2], &colorMap[2], 14); + uint8 seqTextColor0 = _seqTextColor[0]; + + _seqTextColor[0] = 0xfd; + _screen->setTextColorMap(colormap); + seq_resetAllTextEntries(); + seq_setTextEntry(strIndex, x, y, 0x80, 0x78); + seq_processText(); + _screen->copyPage(2, 0); + _screen->updateScreen(); + _screen->getPalette(0)[0x2f7] = _screen->getPalette(0)[textcolor * 3]; + _screen->getPalette(0)[0x2f8] = _screen->getPalette(0)[textcolor * 3 + 1]; + _screen->getPalette(0)[0x2f9] = _screen->getPalette(0)[textcolor * 3 + 2]; + _screen->fadePalette(_screen->getPalette(0), 0x18); + + _seqTextColor[0] = textcolor; + _screen->setTextColorMap(colorMap); + seq_resetAllTextEntries(); + seq_setTextEntry(strIndex, x, y, 0x80, 0x78); + seq_processText(); + _screen->copyPage(2, 0); + _screen->updateScreen(); + _screen->getPalette(0)[0x2f7] = _screen->getPalette(0)[0x2f8] = _screen->getPalette(0)[0x2f9] = 0; + _screen->fadePalette(_screen->getPalette(0), 1); + _screen->copyPage(2, 12); + seq_resetAllTextEntries(); + + _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) { + 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; + uint32 chatTimeout = _system->getMillis() + dur * _tickLength; + int curframe = firstframe; + + if (vocIndex && speechEnabled()) + seq_playTalkText(vocIndex); + + while (_system->getMillis() < chatTimeout && !(_abortIntroFlag || skipFlag())) { + if (lastframe < 0) { + int t = ABS(lastframe); + if (t < curframe) + curframe = t; + } + + if (ABS(lastframe) < curframe) + curframe = firstframe; + + uint32 frameTimeout = _seqEndTime = _system->getMillis() + _seqFrameDelay * _tickLength; + if (wsa) { + wsa->setDrawPage(2); + wsa->setX(wsaXpos); + wsa->setY(wsaYpos); + wsa->displayFrame(curframe % wsa->frames(), 0); + } + + _screen->copyPage(2, 12); + + seq_processText(); + + uint32 tm = _system->getMillis(); + if (frameTimeout > tm && chatTimeout > tm) + delay(MIN(frameTimeout - tm, chatTimeout - tm)); + + if (speechEnabled() && !textEnabled() && !snd_voiceIsPlaying()) + break; + + _screen->copyPage(2, 0); + _screen->updateScreen(); + curframe++; + } + + if (_abortIntroFlag || skipFlag()) + _sound->voiceStop(); + + if (lastframe < 0) { + int t = ABS(lastframe); + if (t < curframe) + curframe = t; + } + + if (curframe == firstframe) + curframe++; + + _seqWsaCurrentFrame = curframe; +} + +void KyraEngine_HoF::seq_displayScrollText(uint8 *data, const ScreenDim *d, int tempPage1, int tempPage2, int speed, + int step, Screen::FontId fid1, Screen::FontId fid2, const uint8 *shapeData, const char *const *specialData) { + + if (!data) + return; + + static const char mark[] = { 5, 13, 0}; + + _screen->clearPage(tempPage1); + _screen->clearPage(tempPage2); + _screen->copyRegion(d->sx << 3, d->sy, d->sx << 3, d->sy, d->w << 3, d->h, 0, tempPage1); + + uint8 *tmp = new uint8[397]; + memset(tmp, 0, 397); + uint8 **tmpStringTable = new uint8*[35]; + uint8 *ptr = data; + int strTblIndex = 0; + + bool loop = true; + int cnt = 0; + + while (loop) { + uint32 endTime = _system->getMillis() + speed * _tickLength; + + while (cnt < 35 && *ptr) { + int m = cnt * 11; + uint16 cH = cnt ? READ_LE_UINT16(&tmp[m + 2]) + tmp[m + 9] + (tmp[m + 9] >> 3) : d->h; + + char *str = (char*)ptr; + + ptr = (uint8*)strpbrk(str, mark); + if (!ptr) + ptr = (uint8*)strchr(str, 0); + + tmp[m + 19] = *ptr; + *ptr = 0; + if (tmp[m + 19]) + ptr++; + + tmp[m + 21] = (*str == 3 || *str == 4) ? tmp[m + 21] = *str++ : 0; + + _screen->setFont(fid1); + + if (*str == 1) { + _screen->setFont(fid2); + str++; + } else if (*str == 2) { + str++; + } + + tmp[m + 20] = _screen->getFontHeight(); + + WRITE_LE_UINT16(&tmp[m + 11], (tmp[m + 21] == 3) ? 157 - _screen->getTextWidth(str) : + ((tmp[m + 21] == 4) ? 161 : (((d->w << 3) - _screen->getTextWidth(str)) >> 1) + 1)); + + if (tmp[m + 8] == 5) + cH -= (tmp[m + 9] + (tmp[m + 9] >> 3)); + + WRITE_LE_UINT16(&tmp[m + 13], cH); + WRITE_LE_UINT32(&tmp[m + 15], strTblIndex); + tmpStringTable[strTblIndex] = (uint8*) str; + strTblIndex = (strTblIndex + 1) % 35; + cnt++; + } + + _screen->copyRegion(d->sx << 3, d->sy, d->sx << 3, d->sy, d->w << 3, d->h, tempPage1, tempPage2); + + int cnt2 = 0; + bool palCycle = 0; + + while (cnt2 < cnt) { + int m = cnt2 * 11; + const char *str = (const char*)tmpStringTable[READ_LE_UINT32(&tmp[m + 15])]; + const char *str2 = str; + uint16 cW = READ_LE_UINT16(&tmp[m + 11]) - 10; + uint16 cH = READ_LE_UINT16(&tmp[m + 13]); + int x = (d->sx << 3) + cW; + int y = d->sy + cH; + int col1 = 255; + + if (cH < d->h) { + _screen->setCurPage(tempPage2); + _screen->setFont(fid1); + if (tmp[m + 20] != _screen->getFontHeight()) + _screen->setFont(fid2); + + if (specialData) { + if (!strcmp(str, specialData[0])) { + col1 = 112; + char cChar[2] = " "; + while (*str2) { + cChar[0] = *str2; + _screen->printText(cChar, x, y, col1++, 0); + x += _screen->getCharWidth(*str2++); + } + palCycle = true; + } else if (!strcmp(str, specialData[1])) { + col1 = 133; + char cChar[2] = " "; + while (*str2) { + cChar[0] = *str2; + _screen->printText(cChar, x, y, col1--, 0); + x += _screen->getCharWidth(*str2++); + } + palCycle = true; + } else { + _screen->printText(str, x, y, col1, 0); + } + } else { + _screen->printText(str, x, y, col1, 0); + } + _screen->setCurPage(0); + } + + WRITE_LE_UINT16(&tmp[m + 13], READ_LE_UINT16(&tmp[m + 13]) - step); + cnt2++; + } + + _screen->copyRegion(d->sx << 3, d->sy, d->sx << 3, d->sy, d->w << 3, d->h, tempPage2, 0); + _screen->updateScreen(); + + if ((int16)READ_LE_UINT16(&tmp[13]) < -10) { + tmpStringTable[tmp[15]] += strlen((char*)tmpStringTable[tmp[15]]); + tmpStringTable[tmp[15]][0] = tmp[19]; + cnt--; + memcpy(&tmp[11], &tmp[22], cnt * 11); + } + + if (palCycle) { + for (int col = 133; col > 112; col--) + memcpy(_screen->_currentPalette + (col * 3), _screen->_currentPalette + ((col - 1) * 3), 3); + memcpy(_screen->_currentPalette + 336, _screen->_currentPalette + 399, 3); + _screen->setScreenPalette(_screen->_currentPalette); + } + + delayUntil(endTime); + + if ((cnt < 36) && ((d->sy + d->h) > (READ_LE_UINT16(&tmp[cnt * 11 + 2]) + tmp[cnt * 11 + 9])) && !skipFlag()) { + resetSkipFlag(); + delay(_tickLength * 500); + cnt = 0; + } + + if (!cnt || skipFlag()) + loop = false; + } + + _sound->beginFadeOut(); + _screen->fadeToBlack(); + + _abortIntroFlag= false; + resetSkipFlag(); + + delete [] tmp; + delete [] tmpStringTable; +} + +void KyraEngine_HoF::seq_scrollPage() { + int dstY, dstH, srcH; + + static const ScreenDim d = { 0x00, 0x00, 0x28, 0x320, 0xFF, 0xFE, 0x00, 0x00 }; + + if (_seqScrollTextCounter - 143 < 0) { + dstY = 144 - _seqScrollTextCounter; + dstH = _seqScrollTextCounter; + srcH = 0; + } else { + dstY = 0; + srcH = _seqScrollTextCounter - 144; + dstH = (400 - srcH <= 144) ? 400 - srcH : 144; + } + + if (dstH > 0) { + for (int i = 0; i < 4; i++) { + const ItemAnimData_v1 *def = &_demoAnimData[i]; + ActiveItemAnim *a = &_activeItemAnim[i]; + + _screen->fillRect(12, def->y - 8, 28, def->y + 8, 0, 4); + _screen->drawShape(4, getShapePtr(def->itemIndex + def->frames[a->currentFrame]), 12, def->y - 8, 0, 0); + if(_seqFrameCounter % 2 == 0) + a->currentFrame = ++a->currentFrame % 20; + } + _screen->copyRegionEx(4, 0, srcH, 2, 2, dstY + 24, 320, dstH, &d); + } +} + +void KyraEngine_HoF::seq_showStarcraftLogo() { + WSAMovieV2 *ci = new WSAMovieV2(this, _screen); + assert(ci); + _screen->clearPage(2); + _res->loadPakFile("INTROGEN.PAK"); + int endframe = ci->open("ci.wsa", 0, _screen->_currentPalette); + _res->unloadPakFile("INTROGEN.PAK"); + if (!ci->opened()) { + delete ci; + return; + } + _screen->hideMouse(); + ci->setX(0); + ci->setY(0); + ci->setDrawPage(2); + ci->displayFrame(0, 0); + _screen->copyPage(2, 0); + _screen->fadeFromBlack(); + for (int i = 1; i < endframe; i++) { + uint32 endTime = _system->getMillis() + 50; + if (skipFlag()) + break; + ci->displayFrame(i, 0); + _screen->copyPage(2, 0); + _screen->updateScreen(); + delay(endTime - _system->getMillis()); + } + if(!skipFlag()) { + uint32 endTime = _system->getMillis() + 50; + ci->displayFrame(0, 0); + _screen->copyPage(2, 0); + _screen->updateScreen(); + delay(endTime - _system->getMillis()); + } + _screen->fadeToBlack(); + _screen->showMouse(); + + _eventList.clear(); + delete ci; +} + +void KyraEngine_HoF::seq_init() { + _seqProcessedString = new char[200]; + _seqWsa = new WSAMovieV2(this, _screen); + _activeWSA = new ActiveWSA[8]; + _activeText = new ActiveText[10]; + + _res->unloadAllPakFiles(); + _res->loadPakFile(StaticResource::staticDataFilename()); + _res->loadFileList(_sequencePakList, _sequencePakListSize); + + int numShp = -1; + if (_flags.isDemo && !_flags.isTalkie) { + _demoAnimData = _staticres->loadHofShapeAnimDataV1(k2SeqplayShapeAnimData, _itemAnimDataSize); + uint8 *shp = _res->fileData("icons.shp", 0); + uint32 outsize = READ_LE_UINT16(shp + 4); + _newShapeFiledata = new uint8[outsize]; + Screen::decodeFrame4(shp + 10, _newShapeFiledata, outsize); + delete [] shp; + + do { + numShp++; + addShapeToPool(_screen->getPtrToShape(_newShapeFiledata, numShp), numShp); + } while (getShapePtr(numShp)); + } else { + MainMenu::StaticData data = { + { _sequenceStrings[97], _sequenceStrings[96], _sequenceStrings[95], _sequenceStrings[98] }, + { 0x01, 0x04, 0x0C, 0x04, 0x00, 0xd7, 0xd6, 0x00, 0x01, 0x02, 0x03 }, + { 0xd8, 0xda, 0xd9, 0xd8 }, + 0xd7, 0xd6 + }; + _menu = new MainMenu(this); + _menu->init(data, MainMenu::Animation()); + } +} + +void KyraEngine_HoF::seq_uninit() { + delete [] _seqProcessedString; + _seqProcessedString = NULL; + + delete [] _activeWSA; + _activeWSA = NULL; + + delete [] _activeText; + _activeText = NULL; + + delete _seqWsa; + _seqWsa = NULL; + + delete [] _newShapeFiledata; + _newShapeFiledata = 0; + + if (_flags.isDemo && !_flags.isTalkie) + _staticres->unloadId(k2SeqplayShapeAnimData); + + _gameShapes.clear(); + + delete _menu; + _menu = 0; +} + +#pragma mark - +#pragma mark - Ingame sequences +#pragma mark - + +void KyraEngine_HoF::seq_makeBookOrCauldronAppear(int type) { + _screen->hideMouse(); + showMessage(0, 0xCF); + + if (type == 1) + seq_makeBookAppear(); + else if (type == 2) + loadInvWsa("CAULDRON.WSA", 1, 6, 0, -2, -2, 1); + + _screen->copyRegionToBuffer(2, 0, 0, 320, 200, _screenBuffer); + _screen->loadBitmap("_PLAYALL.CPS", 3, 3, 0); + + static const uint8 bookCauldronRects[] = { + 0x46, 0x90, 0x7F, 0x2B, // unknown rect (maybe unused?) + 0xCE, 0x90, 0x2C, 0x2C, // book rect + 0xFA, 0x90, 0x46, 0x2C // cauldron rect + }; + + int x = bookCauldronRects[type*4+0]; + int y = bookCauldronRects[type*4+1]; + int w = bookCauldronRects[type*4+2]; + int h = bookCauldronRects[type*4+3]; + _screen->copyRegion(x, y, x, y, w, h, 2, 0, Screen::CR_NO_P_CHECK); + + _screen->copyBlockToPage(2, 0, 0, 320, 200, _screenBuffer); + + if (type == 2) { + int32 countdown = _rnd.getRandomNumberRng(45, 80); + _timer->setCountdown(2, countdown * 60); + } + + _screen->showMouse(); +} + +void KyraEngine_HoF::seq_makeBookAppear() { + _screen->hideMouse(); + + displayInvWsaLastFrame(); + + showMessage(0, 0xCF); + + loadInvWsa("BOOK2.WSA", 0, 4, 2, -1, -1, 0); + + uint8 *rect = new uint8[_screen->getRectSize(_invWsa.w, _invWsa.h)]; + assert(rect); + + _screen->copyRegionToBuffer(_invWsa.page, _invWsa.x, _invWsa.y, _invWsa.w, _invWsa.h, rect); + + _invWsa.running = false; + snd_playSoundEffect(0xAF); + + _invWsa.wsa->setX(0); + _invWsa.wsa->setY(0); + _invWsa.wsa->setDrawPage(_invWsa.page); + + while (true) { + _invWsa.timer = _system->getMillis() + _invWsa.delay * _tickLength; + + _screen->copyBlockToPage(_invWsa.page, _invWsa.x, _invWsa.y, _invWsa.w, _invWsa.h, rect); + + _invWsa.wsa->displayFrame(_invWsa.curFrame, 0x4000, 0, 0); + + if (_invWsa.page) + _screen->copyRegion(_invWsa.x, _invWsa.y, _invWsa.x, _invWsa.y, _invWsa.w, _invWsa.h, _invWsa.page, 0, Screen::CR_NO_P_CHECK); + + ++_invWsa.curFrame; + + if (_invWsa.curFrame >= _invWsa.lastFrame && !_quitFlag) + break; + + switch (_invWsa.curFrame) { + case 39: + snd_playSoundEffect(0xCA); + break; + + case 50: + snd_playSoundEffect(0x6A); + break; + + case 72: + snd_playSoundEffect(0xCB); + break; + + case 85: + snd_playSoundEffect(0x38); + break; + + default: + break; + } + + do { + update(); + } while (_invWsa.timer > _system->getMillis() && !skipFlag()); + } + + closeInvWsa(); + delete [] rect; + _invWsa.running = false; + + _screen->showMouse(); +} + +} // end of namespace Kyra + diff --git a/engines/kyra/sequences_mr.cpp b/engines/kyra/sequences_mr.cpp new file mode 100644 index 0000000000..a09e4f7232 --- /dev/null +++ b/engines/kyra/sequences_mr.cpp @@ -0,0 +1,354 @@ +/* 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_mr.h" +#include "kyra/resource.h" + +namespace Kyra { + +void KyraEngine_MR::showBadConscience() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::showBadConscience()"); + if (_badConscienceShown) + return; + + _badConscienceShown = true; + _badConscienceAnim = _rnd.getRandomNumberRng(0, 2); + if (_currentChapter == 2) + _badConscienceAnim = 5; + else if (_currentChapter == 3) + _badConscienceAnim = 3; + else if (_currentChapter == 4 && _rnd.getRandomNumberRng(1, 100) <= 25) + _badConscienceAnim = 6; + else if (_currentChapter == 5 && _rnd.getRandomNumberRng(1, 100) <= 25) + _badConscienceAnim = 7; + else if (_malcolmShapes == 9) + _badConscienceAnim = 4; + + _badConsciencePosition = (_mainCharacter.x1 <= 160); + + if (_goodConscienceShown) + _badConsciencePosition = !_goodConsciencePosition; + + int anim = _badConscienceAnim + (_badConsciencePosition ? 0 : 8); + TalkObject &talkObject = _talkObjectList[1]; + + if (_badConsciencePosition) + talkObject.x = 290; + else + talkObject.x = 30; + talkObject.y = 30; + + static const char *animFilenames[] = { + "GUNFL00.WSA", "GUNFL01.WSA", "GUNFL02.WSA", "GUNFL03.WSA", "GUNFL04.WSA", "GUNFL05.WSA", "GUNFL06.WSA", "GUNFL07.WSA", + "GUNFR00.WSA", "GUNFR01.WSA", "GUNFR02.WSA", "GUNFR03.WSA", "GUNFR04.WSA", "GUNFR05.WSA", "GUNFR06.WSA", "GUNFR07.WSA" + }; + + setupSceneAnimObject(0x0E, 9, 0, 187, -1, -1, -1, -1, 0, 0, 0, -1, animFilenames[anim]); + for (uint i = 0; i <= _badConscienceFrameTable[_badConscienceAnim]; ++i) { + if (i == 8) + snd_playSoundEffect(0x1B, 0xC8); + updateSceneAnim(0x0E, i); + delay(3*_tickLength, true); + } + + if (_mainCharacter.animFrame < 50 || _mainCharacter.animFrame > 87) + return; + + if (_mainCharacter.y1 == -1 || (_mainCharacter.x1 != -1 && _mainCharacter.animFrame == 87) || _mainCharacter.animFrame == 87) { + _mainCharacter.animFrame = 87; + } else { + if (_badConsciencePosition) + _mainCharacter.facing = 3; + else + _mainCharacter.facing = 5; + _mainCharacter.animFrame = _characterFrameTable[_mainCharacter.facing]; + } + + updateCharacterAnim(0); + refreshAnimObjectsIfNeed(); +} + +void KyraEngine_MR::hideBadConscience() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::hideBadConscience()"); + if (!_badConscienceShown) + return; + + _badConscienceShown = false; + for (int frame = _badConscienceFrameTable[_badConscienceAnim+8]; frame >= 0; --frame) { + if (frame == 15) + snd_playSoundEffect(0x31, 0xC8); + updateSceneAnim(0x0E, frame); + delay(1*_tickLength, true); + } + + updateSceneAnim(0x0E, -1); + update(); + removeSceneAnimObject(0x0E, 1); + setNextIdleAnimTimer(); +} + +void KyraEngine_MR::showGoodConscience() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::showGoodConscience()"); + + if (_goodConscienceShown) + return; + + _goodConscienceShown = true; + ++_goodConscienceAnim; + _goodConscienceAnim %= 5; + + setNextIdleAnimTimer(); + _goodConsciencePosition = (_mainCharacter.x1 <= 160); + + if (_badConscienceShown) + _goodConsciencePosition = !_badConsciencePosition; + + int anim = _goodConscienceAnim + (_goodConsciencePosition ? 0 : 5); + TalkObject &talkObject = _talkObjectList[87]; + + if (_goodConsciencePosition) + talkObject.x = 290; + else + talkObject.x = 30; + talkObject.y = 30; + + static const char *animFilenames[] = { + "STUFL00.WSA", "STUFL02.WSA", "STUFL04.WSA", "STUFL03.WSA", "STUFL01.WSA", + "STUFR00.WSA", "STUFR02.WSA", "STUFR04.WSA", "STUFR03.WSA", "STUFR01.WSA" + }; + + setupSceneAnimObject(0x0F, 9, 0, 187, -1, -1, -1, -1, 0, 0, 0, -1, animFilenames[anim]); + for (uint i = 0; i <= _goodConscienceFrameTable[_goodConscienceAnim]; ++i) { + if (i == 10) + snd_playSoundEffect(0x7F, 0xC8); + updateSceneAnim(0x0F, i); + delay(2*_tickLength, true); + } + + if (_mainCharacter.animFrame < 50 || _mainCharacter.animFrame > 87) + return; + + if (_mainCharacter.y1 == -1 || (_mainCharacter.x1 != -1 && _mainCharacter.animFrame == 87) || _mainCharacter.animFrame == 87) { + _mainCharacter.animFrame = 87; + } else { + if (_goodConsciencePosition) + _mainCharacter.facing = 3; + else + _mainCharacter.facing = 5; + _mainCharacter.animFrame = _characterFrameTable[_mainCharacter.facing]; + } + + updateCharacterAnim(0); + refreshAnimObjectsIfNeed(); +} + +void KyraEngine_MR::hideGoodConscience() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::hideGoodConscience()"); + if (!_goodConscienceShown) + return; + + _goodConscienceShown = false; + for (int frame = _goodConscienceFrameTable[_goodConscienceAnim+5]; frame >= 0; --frame) { + if (frame == 17) + snd_playSoundEffect(0x31, 0xC8); + updateSceneAnim(0x0F, frame); + delay(1*_tickLength, true); + } + + updateSceneAnim(0x0F, -1); + update(); + removeSceneAnimObject(0x0F, 1); + setNextIdleAnimTimer(); +} + +void KyraEngine_MR::runTemporaryScript(const char *filename, int allowSkip, int resetChar, int newShapes, int shapeUnload) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::runTemporaryScript('%s', %d, %d, %d, %d)", filename, allowSkip, resetChar, newShapes, shapeUnload); + memset(&_temporaryScriptData, 0, sizeof(_temporaryScriptData)); + memset(&_temporaryScriptState, 0, sizeof(_temporaryScriptState)); + + if (!_emc->load(filename, &_temporaryScriptData, &_opcodesTemporary)) + error("Couldn't load temporary script '%s'", filename); + + _emc->init(&_temporaryScriptState, &_temporaryScriptData); + _emc->start(&_temporaryScriptState, 0); + + _newShapeFlag = -1; + + if (_newShapeFiledata && newShapes) { + resetNewShapes(_newShapeCount, _newShapeFiledata); + _newShapeFiledata = 0; + _newShapeCount = 0; + } + + while (_emc->isValid(&_temporaryScriptState)) + _emc->run(&_temporaryScriptState); + + uint8 *fileData = 0; + + if (newShapes) + _newShapeFiledata = _res->fileData(_newShapeFilename, 0); + + fileData = _newShapeFiledata; + + if (!fileData) { + _emc->unload(&_temporaryScriptData); + return; + } + + if (newShapes) + _newShapeCount = initNewShapes(fileData); + + processNewShapes(allowSkip, resetChar); + + if (shapeUnload) { + resetNewShapes(_newShapeCount, fileData); + _newShapeCount = 0; + _newShapeFiledata = 0; + } + + _emc->unload(&_temporaryScriptData); +} + +void KyraEngine_MR::eelScript() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::eelScript()"); + if (_chatText) + return; + _screen->hideMouse(); + + if (_inventoryState) + hideInventory(); + removeHandItem(); + + objectChat((const char*)getTableEntry(_cCodeFile, 35), 0, 204, 35); + objectChat((const char*)getTableEntry(_cCodeFile, 40), 0, 204, 40); + + setGameFlag(0xD1); + + snd_playSoundEffect(0x2A, 0xC8); + + setGameFlag(0x171); + + switch (_malcolmShapes-1) { + case 0: + runTemporaryScript("EELS01.EMC", 0, 0, 1, 1); + break; + + case 1: + runTemporaryScript("EELS02.EMC", 0, 0, 1, 1); + break; + + case 2: + runTemporaryScript("EELS03.EMC", 0, 0, 1, 1); + break; + + case 3: + runTemporaryScript("EELS04.EMC", 0, 0, 1, 1); + break; + + default: + resetGameFlag(0x171); + runTemporaryScript("EELS00.EMC", 0, 0, 1, 1); + break; + } + + changeChapter(2, 29, 0, 4); + _screen->showMouse(); +} + +int KyraEngine_MR::initNewShapes(uint8 *filedata) { + debugC(9, kDebugLevelAnimator, "KyraEngine_MR::initNewShapes(%p)", (const void*)filedata); + const int lastEntry = MIN(_newShapeLastEntry, 41); + for (int i = 0; i < lastEntry; ++i) + _gameShapes[9+i] = _screen->getPtrToShape(filedata, i); + return lastEntry; +} + +void KyraEngine_MR::processNewShapes(int allowSkip, int resetChar) { + debugC(9, kDebugLevelAnimator, "KyraEngine_MR::processNewShapes(%d, %d)", allowSkip, resetChar); + setCharacterAnimDim(_newShapeWidth, _newShapeHeight); + + _emc->init(&_temporaryScriptState, &_temporaryScriptData); + _emc->start(&_temporaryScriptState, 1); + + resetSkipFlag(); + + while (_emc->isValid(&_temporaryScriptState)) { + _temporaryScriptExecBit = false; + while (_emc->isValid(&_temporaryScriptState) && !_temporaryScriptExecBit) + _emc->run(&_temporaryScriptState); + + if (_newShapeAnimFrame < 0) + continue; + + _mainCharacter.animFrame = _newShapeAnimFrame + 9; + updateCharacterAnim(0); + if (_chatText) + updateWithText(); + else + update(); + + uint32 delayEnd = _system->getMillis() + _newShapeDelay * _tickLength; + + while ((!skipFlag() || !allowSkip) && _system->getMillis() < delayEnd) { + if (_chatText) + updateWithText(); + else + update(); + + delay(10); + } + + if (skipFlag()) + resetSkipFlag(); + } + + if (resetChar) { + if (_newShapeFlag >= 0) { + _mainCharacter.animFrame = _newShapeFlag + 9; + updateCharacterAnim(0); + if (_chatText) + updateWithText(); + else + update(); + } + + _mainCharacter.animFrame = _characterFrameTable[_mainCharacter.facing]; + updateCharacterAnim(0); + } + + _newShapeFlag = -1; + resetCharacterAnimDim(); +} + +void KyraEngine_MR::resetNewShapes(int count, uint8 *filedata) { + debugC(9, kDebugLevelAnimator, "KyraEngine_MR::resetNewShapes(%d, %p)", count, (const void*)filedata); + for (int i = 0; i < count; ++i) + _gameShapes[9+i] = 0; + delete [] filedata; + setNextIdleAnimTimer(); +} + +} // end of namespace Kyra + diff --git a/engines/kyra/sequences_v2.cpp b/engines/kyra/sequences_v2.cpp deleted file mode 100644 index 8e089f58be..0000000000 --- a/engines/kyra/sequences_v2.cpp +++ /dev/null @@ -1,2781 +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_v2.h" -#include "kyra/screen.h" -#include "kyra/wsamovie.h" -#include "kyra/sound.h" -#include "kyra/text_v2.h" -#include "kyra/timer.h" - -#include "common/system.h" - -namespace Kyra { - -void KyraEngine_v2::seq_playSequences(int startSeq, int endSeq) { - debugC(9, kDebugLevelMain, "KyraEngine_v2::seq_playSequences(%i, %i)", startSeq, endSeq); - seq_init(); - - bool allowSkip = (!(_flags.isDemo && !_flags.isTalkie) && (startSeq == kSequenceTitle)) ? false : true; - - if (endSeq == -1) - endSeq = startSeq; - - assert(startSeq >= 0 && endSeq < kSequenceArraySize && startSeq <= endSeq); - - _sound->setSoundList(&_soundData[(startSeq > kSequenceZanfaun) ? kMusicFinale : kMusicIntro]); - _sound->loadSoundFile(0); - - _screen->_charWidth = -2; - - memset(_activeWSA, 0, sizeof(ActiveWSA) * 8); - for (int i = 0; i < 8; ++i) - _activeWSA[i].flags = -1; - - memset(_activeText, 0, sizeof(ActiveText) * 10); - seq_resetAllTextEntries(); - - _screen->hideMouse(); - int oldPage = _screen->setCurPage(2); - - for (int i = 0; i < 4; ++i) - memset(_screen->getPalette(i), 0, 0x300); - - _screen->clearPage(10); - _screen->clearPage(12); - - _seqSubframePlaying = false; - - _seqWsaCurrentFrame = 0; - _seqTextColor[0] = _seqTextColor[1] = 0; - _seqEndTime = 0; - _menuChoice = 0; - - for (int seqNum = startSeq; seqNum <= endSeq && !((skipFlag() && allowSkip) || _quitFlag || (_abortIntroFlag && allowSkip) || _menuChoice); seqNum++) { - _screen->clearPage(0); - _screen->clearPage(8); - memcpy(_screen->getPalette(1), _screen->getPalette(0), 0x300); - _seqFrameCounter = 0; - _seqStartTime = _system->getMillis(); - - allowSkip = (!(_flags.isDemo && !_flags.isTalkie) && (seqNum == kSequenceTitle)) ? false : true; - - Sequence cseq = _sequences->seq[seqNum]; - SeqProc cb = _callbackS[seqNum]; - - if (cseq.flags & 2) { - _screen->loadBitmap(cseq.cpsFile, 2, 2, _screen->getPalette(0)); - _screen->setScreenPalette(_screen->getPalette(0)); - } else { - _screen->setCurPage(2); - _screen->clearPage(2); - _screen->loadPalette("goldfont.col", _screen->getPalette(0)); - } - - if (cb && !(_flags.isDemo && !_flags.isTalkie)) - (this->*cb)(0, 0, 0, -1); - - if (cseq.flags & 1) { - _seqWsa->close(); - _seqWsa->open(cseq.wsaFile, 0, _screen->getPalette(0)); - _screen->setScreenPalette(_screen->getPalette(0)); - _seqWsa->setX(cseq.xPos); - _seqWsa->setY(cseq.yPos); - _seqWsa->setDrawPage(2); - _seqWsa->displayFrame(0, 0); - } - - if (cseq.flags & 4) { - int cp = _screen->setCurPage(2); - Screen::FontId cf = _screen->setFont(Screen::FID_GOLDFONT_FNT); - if (cseq.stringIndex1 != -1) { - int sX = (320 - _screen->getTextWidth(_sequenceStrings[cseq.stringIndex1])) / 2; - _screen->printText(_sequenceStrings[cseq.stringIndex1], sX, 100 - _screen->getFontHeight(), 1, 0); - } - if (cseq.stringIndex2 != -1) { - int sX = (320 - _screen->getTextWidth(_sequenceStrings[cseq.stringIndex2])) / 2; - _screen->printText(_sequenceStrings[cseq.stringIndex2], sX, 100, 1, 0); - } - _screen->setFont(cf); - _screen->setCurPage(cp); - } - - _screen->copyPage(2, 12); - _screen->copyPage(0, 2); - _screen->copyPage(2, 10); - _screen->copyPage(12, 2); - - seq_sequenceCommand(cseq.startupCommand); - - if (!((skipFlag() && allowSkip) || _quitFlag || (_abortIntroFlag && allowSkip) || _menuChoice)) { - _screen->copyPage(2, 0); - _screen->updateScreen(); - } - - if (cseq.flags & 1) { - int w2 = _seqWsa->width(); - int h2 = _seqWsa->height(); - int x = cseq.xPos; - int y = cseq.yPos; - - _seqFrameDelay = cseq.frameDelay; - - if (_seqWsa) { - if (x < 0) { - x = 0; - w2 = 0; - } - - if (y < 0) { - y = 0; - h2 = 0; - } - - if (cseq.xPos + _seqWsa->width() > 319) - _seqWsa->setWidth(320 - cseq.xPos); - - if (cseq.yPos + _seqWsa->height() > 199) - _seqWsa->setHeight(199 - cseq.yPos); - } - uint8 dir = (cseq.startFrame > cseq.numFrames) ? 0 : 1; - _seqWsaCurrentFrame = cseq.startFrame; - - bool loop = true; - while (loop && !((skipFlag() && allowSkip) || _quitFlag || (_abortIntroFlag && allowSkip) || _menuChoice)) { - _seqEndTime = _system->getMillis() + _seqFrameDelay * _tickLength; - - if (_seqWsa || !cb) - _screen->copyPage(12, 2); - - if (cb) { - int f = _seqWsaCurrentFrame % _seqWsa->frames(); - (this->*cb)(_seqWsa, cseq.xPos, cseq.yPos, f); - } - - if (_seqWsa) { - int f = _seqWsaCurrentFrame % _seqWsa->frames(); - _seqWsa->setX(cseq.xPos); - _seqWsa->setY(cseq.yPos); - _seqWsa->setDrawPage(2); - _seqWsa->displayFrame(f, 0); - } - - _screen->copyPage(2, 12); - - seq_processWSAs(); - seq_processText(); - - if ((_seqWsa || !cb) && !((skipFlag() && allowSkip) || _quitFlag || (_abortIntroFlag && allowSkip) || _menuChoice)) { - _screen->copyPage(2, 0); - _screen->updateScreen(); - } - - bool loop2 = true; - while (loop2 && !((skipFlag() && allowSkip) || _quitFlag || (_abortIntroFlag && allowSkip) || _menuChoice)) { - if (_seqWsa) { - seq_processText(); - if (!((skipFlag() && allowSkip) || _quitFlag || (_abortIntroFlag && allowSkip) || _menuChoice)) { - _screen->copyPage(2, 0); - _screen->updateScreen(); - } - - uint32 now = _system->getMillis(); - if (now >= _seqEndTime) { - loop2 = false; - } else { - uint32 tdiff = _seqEndTime - now; - uint32 dly = tdiff < _tickLength ? tdiff : _tickLength; - delay(dly); - } - } else { - loop = loop2 = false; - } - } - - if (loop) { - if (dir == 1) { - if (++_seqWsaCurrentFrame >= cseq.numFrames) - loop = false; - } else { - if (--_seqWsaCurrentFrame < cseq.numFrames) - loop = false; - } - } - } - _seqWsa->close(); - } else { - _seqFrameDelay = cseq.frameDelay; - _seqEndTime = _system->getMillis() + _seqFrameDelay * _tickLength; - while (!((skipFlag() && allowSkip) || _quitFlag || (_abortIntroFlag && allowSkip) || _menuChoice)) { - uint32 starttime = _system->getMillis(); - seq_processWSAs(); - if (cb) - (this->*cb)(0, 0, 0, 0); - - seq_processText(); - - _screen->copyPage(2, 0); - _screen->updateScreen(); - _screen->copyPage(12, 2); - - uint32 now = _system->getMillis(); - if (now >= _seqEndTime && !_seqSubframePlaying) - break; - - uint32 tdiff = _seqEndTime - starttime; - int32 dly = _tickLength - (now - starttime); - if (dly > 0) - delay(MIN(dly, tdiff)); - } - } - - if (cb && !(_flags.isDemo && !_flags.isTalkie)) - (this->*cb)(0, 0, 0, -2); - - uint32 ct = seq_activeTextsTimeLeft(); - uint32 dl = cseq.duration * _tickLength; - if (dl < ct) - dl = ct; - _seqEndTime = _system->getMillis() + dl; - - while (!((skipFlag() && allowSkip) || _quitFlag || (_abortIntroFlag && allowSkip) || _menuChoice)) { - uint32 starttime = _system->getMillis(); - seq_processWSAs(); - - _screen->copyPage(2, 0); - _screen->updateScreen(); - _screen->copyPage(12, 2); - - uint32 now = _system->getMillis(); - if (now >= _seqEndTime && !_seqSubframePlaying) { - break; - } - - uint32 tdiff = _seqEndTime - starttime; - int32 dly = _tickLength - (now - starttime); - if (dly > 0) - delay(MIN(dly, tdiff)); - } - - seq_sequenceCommand(cseq.finalCommand); - seq_resetAllTextEntries(); - - if (_flags.isDemo && !_flags.isTalkie) { - if (seqNum == kSequenceDemoFisher) { - _abortIntroFlag = false; - resetSkipFlag(); - seqNum = kSequenceDemoVirgin; - } - } else { - if ((seqNum != kSequenceTitle && seqNum < kSequenceZanfaun && - (_abortIntroFlag || skipFlag())) || seqNum == kSequenceZanfaun) { - _abortIntroFlag = false; - _eventList.clear(); - seqNum = kSequenceWestwood; - } else if (seqNum < kSequenceFrash && (_abortIntroFlag || skipFlag())) { - _abortIntroFlag = false; - _eventList.clear(); - seqNum = kSequenceFirates; - } - } - - if (_menuChoice) { - _abortIntroFlag = false; - _eventList.clear(); - - if (_menuChoice == 2) { - seqNum = kSequenceTitle; - _menuChoice = 0; - } - } - } - - if (!_menuChoice) - delay(1000); - - _screen->setCurPage(oldPage); - _screen->showMouse(); - - for (int i = 0; i < 8; i++) - seq_unloadWSA(i); - - _seqWsa->close(); - - _screen->_charWidth = 0; - - seq_uninit(); -} - -int KyraEngine_v2::seq_introWestwood(WSAMovieV2 *wsaObj, int x, int y, int frm) { - debugC(9, kDebugLevelMain, "KyraEngine_v2::seq_introWestwood(%p, %i, %i, %i)", (const void*)wsaObj, x, y, frm); - - if (frm == -2) { - if (_flags.platform == Common::kPlatformFMTowns || _flags.platform == Common::kPlatformPC98) - delay(300 * _tickLength); - } else if (!frm) { - _sound->playTrack(2); - } - - return 0; -} - -int KyraEngine_v2::seq_introTitle(WSAMovieV2 *wsaObj, int x, int y, int frm) { - debugC(9, kDebugLevelMain, "KyraEngine_v2::seq_introTitle(%p, %i, %i, %i)", (const void*)wsaObj, x, y, frm); - - if (frm == 1) { - _sound->playTrack(3); - } else if (frm == 25) { - int cp = _screen->setCurPage(0); - _screen->showMouse(); - _system->updateScreen(); - _menuChoice = _menu->handle(11) + 1; - _seqEndTime = 0; - _seqSubframePlaying = false; - if (_menuChoice == 4) - quitGame(); - - _screen->hideMouse(); - _screen->setCurPage(cp); - } - - return 0; -} - -int KyraEngine_v2::seq_introOverview(WSAMovieV2 *wsaObj, int x, int y, int frm) { - debugC(9, kDebugLevelMain, "KyraEngine_v2::seq_introOverview(%p, %i, %i, %i)", (const void*)wsaObj, x, y, frm); - - uint8 *tmpPal = &(_screen->getPalette(3)[0x101]); - memset(tmpPal, 0, 256); - uint32 endtime = 0, now = 0; - - switch (_seqFrameCounter) { - case 0: - _seqSubframePlaying = true; - _sound->playTrack(4); - endtime = _system->getMillis() + 60 * _tickLength; - - _seqTextColor[1] = _screen->findLeastDifferentColor(_seqTextColorPresets, _screen->getPalette(0) + 3, 255) & 0xff; - memset(_seqTextColorMap, _seqTextColor[1], 16); - _seqTextColorMap[1] = _seqTextColor[0] = _screen->findLeastDifferentColor(_seqTextColorPresets + 3, _screen->getPalette(0) + 3, 255) & 0xff; - - _screen->setTextColorMap(_seqTextColorMap); - - now = _system->getMillis(); - if (endtime > now) - delay(endtime - now); - break; - - case 1: - _screen->generateGrayOverlay(_screen->getPalette(0), _screen->getPalette(3), 0x40, 0, 0, 0, 0x100, true); - for (int i = 0; i < 256; i++) - tmpPal[_screen->getPalette(3)[i]] = 1; - - for (int i = 0; i < 256; i++) { - int v = (tmpPal[i] == 1) ? i : _screen->getPalette(3)[i]; - v *= 3; - _screen->getPalette(2)[3 * i] = _screen->getPalette(0)[v]; - _screen->getPalette(2)[3 * i + 1] = _screen->getPalette(0)[v + 1]; - _screen->getPalette(2)[3 * i + 2] = _screen->getPalette(0)[v + 2]; - } - break; - - case 40: - seq_loadNestedSequence(0, kSequenceOver1); - break; - - case 60: - seq_loadNestedSequence(1, kSequenceOver2); - break; - - case 120: - seq_playTalkText(0); - break; - - case 200: - seq_waitForTextsTimeout(); - _screen->fadePalette(_screen->getPalette(2), 64); - break; - - case 201: - _screen->setScreenPalette(_screen->getPalette(2)); - _screen->updateScreen(); - _screen->applyOverlay(0, 0, 320, 200, 2, _screen->getPalette(3)); - _screen->copyPage(2, 12); - _screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0); - _screen->setScreenPalette(_screen->getPalette(0)); - _screen->updateScreen(); - seq_resetActiveWSA(0); - seq_resetActiveWSA(1); - break; - - case 282: - seq_loadNestedSequence(0, kSequenceForest); - seq_playTalkText(1); - break; - - case 354: - case 434: - if (!((_seqFrameCounter == 354 && (_flags.platform == Common::kPlatformFMTowns || _flags.platform == Common::kPlatformPC98)) || (_seqFrameCounter == 434 && _flags.platform == Common::kPlatformPC))) - break; - - seq_resetActiveWSA(0); - seq_loadNestedSequence(0, kSequenceDragon); - break; - - case 400: - case 540: - if (!((_seqFrameCounter == 400 && (_flags.platform == Common::kPlatformFMTowns || _flags.platform == Common::kPlatformPC98)) || (_seqFrameCounter == 540 && _flags.platform == Common::kPlatformPC))) - break; - - seq_waitForTextsTimeout(); - seq_resetActiveWSA(0); - _seqEndTime = 0; - _seqSubframePlaying = false; - break; - - default: - break; - } - - _seqFrameCounter++; - return 0; -} - -int KyraEngine_v2::seq_introLibrary(WSAMovieV2 *wsaObj, int x, int y, int frm) { - debugC(9, kDebugLevelMain, "KyraEngine_v2::seq_introLibrary(%p, %i, %i, %i)", (const void*)wsaObj, x, y, frm); - - switch (_seqFrameCounter) { - case 0: - _seqSubframePlaying = true; - _sound->playTrack(5); - - _screen->generateGrayOverlay(_screen->getPalette(0), _screen->getPalette(3), 0x24, 0, 0, 0, 0x100, false); - _seqTextColor[1] = _screen->findLeastDifferentColor(_seqTextColorPresets, _screen->getPalette(0) + 3, 255) & 0xff; - memset(_seqTextColorMap, _seqTextColor[1], 16); - _seqTextColorMap[1] = _seqTextColor[0] = _screen->findLeastDifferentColor(_seqTextColorPresets + 3, _screen->getPalette(0) + 3, 255) & 0xff; - - _screen->setTextColorMap(_seqTextColorMap); - break; - - case 1: - seq_loadNestedSequence(0, kSequenceLibrary3); - seq_playTalkText(4); - break; - - case 100: - seq_waitForTextsTimeout(); - - _screen->copyPage(12, 2); - _screen->applyOverlay(0, 0, 320, 200, 2, _screen->getPalette(3)); - _screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0); - _screen->updateScreen(); - _screen->copyPage(2, 12); - - seq_resetActiveWSA(0); - seq_loadNestedSequence(0, kSequenceDarm); - break; - - case 104: - seq_playTalkText(5); - break; - - case 240: - seq_waitForTextsTimeout(); - seq_resetActiveWSA(0); - seq_loadNestedSequence(0, kSequenceLibrary2); - break; - - case 340: - seq_resetActiveWSA(0); - _screen->applyOverlay(0, 0, 320, 200, 2, _screen->getPalette(3)); - _screen->copyPage(2, 12); - _screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0); - _screen->updateScreen(); - - seq_loadNestedSequence(0, kSequenceMarco); - seq_playTalkText(6); - break; - - case 480: - case 660: - if (!((_seqFrameCounter == 480 && (_flags.platform == Common::kPlatformFMTowns || _flags.platform == Common::kPlatformPC98)) || (_seqFrameCounter == 660 && _flags.platform == Common::kPlatformPC))) - break; - - _screen->copyPage(2, 12); - seq_waitForTextsTimeout(); - seq_resetActiveWSA(0); - _seqEndTime = 0; - _seqSubframePlaying = false; - break; - - default: - break; - } - - _seqFrameCounter++; - return 0; -} - - -int KyraEngine_v2::seq_introHand(WSAMovieV2 *wsaObj, int x, int y, int frm) { - debugC(9, kDebugLevelMain, "KyraEngine_v2::seq_introHand(%p, %i, %i, %i)", (const void*)wsaObj, x, y, frm); - - switch (_seqFrameCounter) { - case 0: - _seqSubframePlaying = true; - _sound->playTrack(6); - - _screen->generateGrayOverlay(_screen->getPalette(0), _screen->getPalette(3), 0x24, 0, 0, 0, 0x100, false); - _seqTextColor[1] = _screen->findLeastDifferentColor(_seqTextColorPresets, _screen->getPalette(0) + 3, 255) & 0xff; - memset(_seqTextColorMap, _seqTextColor[1], 16); - _seqTextColorMap[1] = _seqTextColor[0] = _screen->findLeastDifferentColor(_seqTextColorPresets + 3, _screen->getPalette(0) + 3, 255) & 0xff; - - _screen->setTextColorMap(_seqTextColorMap); - break; - - case 1: - seq_loadNestedSequence(0, kSequenceHand1a); - seq_loadNestedSequence(1, kSequenceHand1b); - seq_loadNestedSequence(2, kSequenceHand1c); - seq_playTalkText(7); - break; - - case 201: - seq_waitForTextsTimeout(); - _screen->applyOverlay(0, 0, 320, 200, 2, _screen->getPalette(3)); - _screen->copyPage(2, 12); - _screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0); - _screen->updateScreen(); - seq_resetActiveWSA(0); - seq_resetActiveWSA(1); - seq_resetActiveWSA(2); - seq_loadNestedSequence(0, kSequenceHand2); - seq_playTalkText(8); - break; - - case 260: - case 395: - if (!((_seqFrameCounter == 260 && (_flags.platform == Common::kPlatformFMTowns || _flags.platform == Common::kPlatformPC98)) || (_seqFrameCounter == 395 && _flags.platform == Common::kPlatformPC))) - break; - - seq_waitForTextsTimeout(); - seq_resetActiveWSA(0); - seq_loadNestedSequence(1, kSequenceHand3); - seq_playTalkText(9); - break; - - case 365: - case 500: - if (!((_seqFrameCounter == 365 && (_flags.platform == Common::kPlatformFMTowns || _flags.platform == Common::kPlatformPC98)) || (_seqFrameCounter == 500 && _flags.platform == Common::kPlatformPC))) - break; - - seq_waitForTextsTimeout(); - seq_resetActiveWSA(1); - seq_loadNestedSequence(0, kSequenceHand4); - break; - - case 405: - case 540: - if (!((_seqFrameCounter == 405 && (_flags.platform == Common::kPlatformFMTowns || _flags.platform == Common::kPlatformPC98)) || (_seqFrameCounter == 540 && _flags.platform == Common::kPlatformPC))) - break; - - seq_playTalkText(10); - break; - - case 484: - case 630: - if (!((_seqFrameCounter == 484 && (_flags.platform == Common::kPlatformFMTowns || _flags.platform == Common::kPlatformPC98)) || (_seqFrameCounter == 630 && _flags.platform == Common::kPlatformPC))) - break; - - seq_waitForTextsTimeout(); - seq_resetActiveWSA(0); - _seqEndTime = 0; - _seqSubframePlaying = false; - break; - - default: - break; - } - - _seqFrameCounter++; - return 0; -} - -int KyraEngine_v2::seq_introPoint(WSAMovieV2 *wsaObj, int x, int y, int frm) { - if (frm == -2) { - seq_waitForTextsTimeout(); - _seqEndTime = 0; - } - - switch (_seqFrameCounter) { - case -2: - seq_waitForTextsTimeout(); - break; - - case 0: - _sound->playTrack(7); - - _seqTextColor[1] = 0xf7; - memset(_seqTextColorMap, _seqTextColor[1], 16); - _seqTextColorMap[1] = _seqTextColor[0] = _screen->findLeastDifferentColor(_seqTextColorPresets + 3, _screen->getPalette(0) + 3, 255) & 0xff; - _screen->setTextColorMap(_seqTextColorMap); - _screen->generateGrayOverlay(_screen->getPalette(0), _screen->getPalette(3), 0x24, 0, 0, 0, 0x100, false); - break; - - case 1: - seq_playTalkText(11); - break; - - default: - break; - } - - _seqFrameCounter++; - return 0; -} - -int KyraEngine_v2::seq_introZanfaun(WSAMovieV2 *wsaObj, int x, int y, int frm) { - if (frm == -2) { - seq_waitForTextsTimeout(); - _seqEndTime = 0; - return 0; - } - - switch (_seqFrameCounter) { - case 0: - _sound->playTrack(8); - - _seqTextColor[1] = 0xfd; - memset(_seqTextColorMap, _seqTextColor[1], 16); - _seqTextColorMap[1] = _seqTextColor[0] = _screen->findLeastDifferentColor(_seqTextColorPresets + 3, _screen->getPalette(0) + 3, 255) & 0xff; - _screen->setTextColorMap(_seqTextColorMap); - break; - - case 1: - if (_flags.isTalkie) { - seq_playWsaSyncDialogue(21, 13, -1, 140, 70, 160, wsaObj, 0, 8, x, y); - } else { - seq_setTextEntry(21, 140, 70, 200, 160); - _seqFrameDelay = 200; - } - break; - - case 2: - case 11: - case 21: - if (!_flags.isTalkie) - _seqFrameDelay = 12; - break; - - case 9: - if (_flags.isTalkie) - seq_playWsaSyncDialogue(13, 14, -1, 140, (_flags.lang == Common::FR_FRA - || _flags.lang == Common::DE_DEU) ? 50 : 70, 160, wsaObj, 9, 15, x, y); - break; - - case 10: - if (!_flags.isTalkie) { - seq_waitForTextsTimeout(); - seq_setTextEntry(13, 140, 50, _sequenceStringsDuration[13], 160); - _seqFrameDelay = 300; - } - break; - - case 16: - if (_flags.isTalkie) - seq_playWsaSyncDialogue(18, 15, -1, 140, (_flags.lang == Common::FR_FRA) ? 50 : - (_flags.lang == Common::DE_DEU ? 40 : 70), 160, wsaObj, 10, 16, x, y); - break; - - case 17: - if (_flags.isTalkie) - _seqFrameDelay = 12; - break; - - case 20: - if (!_flags.isTalkie) { - seq_waitForTextsTimeout(); - seq_setTextEntry(18, 160, 50, _sequenceStringsDuration[18], 160); - _seqFrameDelay = 200; - } - break; - - case 26: - seq_waitForTextsTimeout(); - break; - - case 46: - if (_flags.isTalkie) { - seq_playWsaSyncDialogue(16, 16, -1, 200, 50, 120, wsaObj, 46, 46, x, y); - } else { - seq_waitForTextsTimeout(); - seq_setTextEntry(16, 200, 50, _sequenceStringsDuration[16], 120); - } - - _seqEndTime = _system->getMillis() + 120 * _tickLength; - break; - - default: - break; - } - - _seqFrameCounter++; - return 0; -} - -int KyraEngine_v2::seq_introOver1(WSAMovieV2 *wsaObj, int x, int y, int frm) { - if (frm == 2) - seq_waitForTextsTimeout(); - else if (frm == 3) - seq_playTalkText(12); - return frm; -} - - -int KyraEngine_v2::seq_introOver2(WSAMovieV2 *wsaObj, int x, int y, int frm) { - if (frm == 1) - seq_playTalkText(12); - return frm; -} - -int KyraEngine_v2::seq_introForest(WSAMovieV2 *wsaObj, int x, int y, int frm) { - if (frm == 11) - seq_waitForTextsTimeout(); - else if (frm == 12) - seq_playTalkText(2); - - return frm; -} - -int KyraEngine_v2::seq_introDragon(WSAMovieV2 *wsaObj, int x, int y, int frm) { - if (frm == 11) - seq_waitForTextsTimeout(); - else if (frm == 3) - seq_playTalkText(3); - return frm; -} - -int KyraEngine_v2::seq_introDarm(WSAMovieV2 *wsaObj, int x, int y, int frm) { - //NULLSUB (at least in fm-towns version) - return frm; -} - -int KyraEngine_v2::seq_introLibrary2(WSAMovieV2 *wsaObj, int x, int y, int frm) { - //NULLSUB (at least in fm-towns version) - return frm; -} - -int KyraEngine_v2::seq_introMarco(WSAMovieV2 *wsaObj, int x, int y, int frm) { - if (frm == 36) { - seq_waitForTextsTimeout(); - _seqEndTime = 0; - } - return frm; -} - -int KyraEngine_v2::seq_introHand1a(WSAMovieV2 *wsaObj, int x, int y, int frm) { - //NULLSUB (at least in fm-towns version) - return frm; -} - -int KyraEngine_v2::seq_introHand1b(WSAMovieV2 *wsaObj, int x, int y, int frm) { - if (frm == 15) - frm = 12; - return frm; -} - -int KyraEngine_v2::seq_introHand1c(WSAMovieV2 *wsaObj, int x, int y, int frm) { - if (frm == 8) - frm = 4; - return frm; -} - -int KyraEngine_v2::seq_introHand2(WSAMovieV2 *wsaObj, int x, int y, int frm) { - //NULLSUB (at least in fm-towns version) - return frm; -} - -int KyraEngine_v2::seq_introHand3(WSAMovieV2 *wsaObj, int x, int y, int frm) { - //NULLSUB (at least in fm-towns version) - return frm; -} - -int KyraEngine_v2::seq_finaleFunters(WSAMovieV2 *wsaObj, int x, int y, int frm) { - uint32 endtime = 0; - int chatX = 0; - int chatY = 0; - int chatW = 0; - int chatFirstFrame = 0; - int chatLastFrame = 0; - uint16 voiceIndex = 0; - - switch (frm) { - case -2: - seq_sequenceCommand(9); - break; - - case 0: - _sound->playTrack(3); - - _seqTextColor[1] = _screen->findLeastDifferentColor(_seqTextColorPresets, _screen->getPalette(0) + 3, 255) & 0xff; - memset(_seqTextColorMap, _seqTextColor[1], 16); - _seqTextColor[0] = _seqTextColorMap[1] = 0xff; - _screen->setTextColorMap(_seqTextColorMap); - - endtime = _system->getMillis() + 480 * _tickLength; - seq_printCreditsString(81, 240, 70, _seqTextColorMap, 252); - seq_printCreditsString(82, 240, 90, _seqTextColorMap, _seqTextColor[0]); - _screen->copyPage(2, 12); - delay(endtime - _system->getMillis()); - seq_playTalkText(_flags.isTalkie ? 28 : 24); - _seqTextColor[0] = 1; - - if (_flags.isTalkie) { - chatY = (_flags.lang == Common::FR_FRA) ? 70 : 78; - chatFirstFrame = 9; - chatLastFrame = 15; - voiceIndex = 34; - } else { - chatY = (_flags.lang == Common::FR_FRA) ? 78 : 70; - chatFirstFrame = 0; - chatLastFrame = 8; - } - chatX = (_flags.lang == Common::FR_FRA) ? 84 : 88; - chatW = 100; - - seq_playWsaSyncDialogue(22, voiceIndex, 187, chatX, chatY, chatW, wsaObj, chatFirstFrame, chatLastFrame, x, y); - break; - - case 9: - case 16: - if (!((frm == 9 && !_flags.isTalkie) || (frm == 16 && _flags.isTalkie))) - break; - - _seqFrameDelay = 12; - - if (_flags.lang == Common::FR_FRA) { - chatX = 80; - chatW = 112; - } else { - chatX = (_flags.lang == Common::DE_DEU) ? 84 : 96; - chatW = 100; - } - - if (_flags.isTalkie) { - chatFirstFrame = 0; - chatLastFrame = 8; - voiceIndex = 35; - } else { - chatFirstFrame = 9; - chatLastFrame = 15; - } - chatY = 70; - - seq_playWsaSyncDialogue(23, voiceIndex, 137, chatX, chatY, chatW, wsaObj, chatFirstFrame, chatLastFrame, x, y); - if (_flags.isTalkie) - _seqWsaCurrentFrame = 17; - break; - - default: - break; - } - - _seqFrameCounter++; - return 0; -} - -int KyraEngine_v2::seq_finaleFerb(WSAMovieV2 *wsaObj, int x, int y, int frm) { - uint32 endtime = 0; - int chatX = 0; - int chatY = 0; - int chatW = 0; - int chatFirstFrame = 0; - int chatLastFrame = 0; - uint16 voiceIndex = 0; - - switch (frm) { - case -2: - seq_sequenceCommand(9); - endtime = _system->getMillis() + 480 * _tickLength; - seq_printCreditsString(34, 240, _flags.isTalkie ? 60 : 40, _seqTextColorMap, 252); - seq_printCreditsString(35, 240, _flags.isTalkie ? 70 : 50, _seqTextColorMap, _seqTextColor[0]); - seq_printCreditsString(36, 240, _flags.isTalkie ? 90 : 70, _seqTextColorMap, 252); - seq_printCreditsString(37, 240, _flags.isTalkie ? 100 : 90, _seqTextColorMap, _seqTextColor[0]); - seq_printCreditsString(38, 240, _flags.isTalkie ? 120 : 110, _seqTextColorMap, 252); - seq_printCreditsString(39, 240, _flags.isTalkie ? 130 : 120, _seqTextColorMap, _seqTextColor[0]); - if (_flags.platform == Common::kPlatformFMTowns || _flags.platform == Common::kPlatformPC98) - seq_printCreditsString(103, 240, 130, _seqTextColorMap, _seqTextColor[0]); - delay(endtime - _system->getMillis()); - _seqEndTime = 0; - break; - - case 0: - _seqTextColor[1] = _screen->findLeastDifferentColor(_seqTextColorPresets, _screen->getPalette(0) + 3, 255) & 0xff; - memset(_seqTextColorMap, _seqTextColor[1], 16); - _seqTextColor[0] = _seqTextColorMap[1] = 255; - _screen->setTextColorMap(_seqTextColorMap); - break; - - case 5: - if (!_flags.isTalkie) - seq_playTalkText(18); - _seqFrameDelay = 16; - - if (_flags.isTalkie) { - chatFirstFrame = 5; - chatLastFrame = 8; - voiceIndex = 22; - } else { - chatLastFrame = 14; - } - chatX = 116; - chatY = 90; - chatW = 60; - - seq_playWsaSyncDialogue(24, voiceIndex, 149, chatX, chatY, chatW, wsaObj, chatFirstFrame, chatLastFrame, x, y); - break; - - case 11: - if (_flags.isTalkie) - seq_playWsaSyncDialogue(24, 22, 149, 116, 90, 60, wsaObj, 11, 14, x, y); - break; - - case 16: - seq_playTalkText(_flags.isTalkie ? 23 : 19); - _seqFrameDelay = _flags.isTalkie ? 20 : 16; - - if (_flags.lang == Common::FR_FRA) { - chatY = 48; - chatW = 88; - } else { - chatY = 60; - chatW = 100; - } - chatX = 60; - - if (_flags.isTalkie) - voiceIndex = 36; - - seq_playWsaSyncDialogue(25, voiceIndex, 143, chatX, chatY, chatW, wsaObj, 16, 25, x, y); - _seqFrameDelay = 16; - break; - - default: - break; - } - - _seqFrameCounter++; - return 0; -} - -int KyraEngine_v2::seq_finaleFish(WSAMovieV2 *wsaObj, int x, int y, int frm) { - uint32 endtime = 0; - int chatX = 0; - int chatY = 0; - int chatW = 0; - uint16 voiceIndex = 0; - - switch (frm) { - case -2: - seq_sequenceCommand(9); - endtime = _system->getMillis() + 480 * _tickLength; - - seq_printCreditsString(40, 240, _flags.isTalkie ? 55 : 40, _seqTextColorMap, 252); - seq_printCreditsString(41, 240, _flags.isTalkie ? 65 : 50, _seqTextColorMap, _seqTextColor[0]); - seq_printCreditsString(42, 240, _flags.isTalkie ? 75 : 60, _seqTextColorMap, _seqTextColor[0]); - seq_printCreditsString(43, 240, _flags.isTalkie ? 95 : 80, _seqTextColorMap, 252); - seq_printCreditsString(44, 240, _flags.isTalkie ? 105 : 90, _seqTextColorMap, _seqTextColor[0]); - seq_printCreditsString(93, 240, _flags.isTalkie ? 125 : 110, _seqTextColorMap, 252); - seq_printCreditsString(94, 240, _flags.isTalkie ? 135 : 120, _seqTextColorMap, _seqTextColor[0]); - delay(endtime - _system->getMillis()); - _seqEndTime = 0; - break; - - case 0: - _seqTextColor[1] = _screen->findLeastDifferentColor(_seqTextColorPresets, _screen->getPalette(0) + 3, 255) & 0xff; - memset(_seqTextColorMap, _seqTextColor[1], 16); - _seqTextColor[0] = _seqTextColorMap[1] = 0xff; - _screen->setTextColorMap(_seqTextColorMap); - break; - - case 4: - chatX = 94; - chatY = 42; - chatW = 100; - if (_flags.isTalkie) - voiceIndex = 37; - seq_playWsaSyncDialogue(26, voiceIndex, 149, chatX, chatY, chatW, wsaObj, 3, 12, x, y); - break; - - case 14: - seq_playTalkText(_flags.isTalkie ? 19 : 15); - break; - - case 23: - seq_playTalkText(_flags.isTalkie ? 20 : 16); - break; - - case 29: - chatX = (_flags.lang == Common::DE_DEU) ? 82 : ((_flags.lang == Common::FR_FRA) ? 92 : 88); - chatY = 40; - chatW = 100; - - if (_flags.isTalkie) { - if (_flags.lang == Common::DE_DEU) - chatY = 35; - voiceIndex = 38; - } - - seq_playWsaSyncDialogue(27, voiceIndex, 187, chatX, chatY, chatW, wsaObj, 28, 34, x, y); - break; - - case 45: - seq_playTalkText(_flags.isTalkie ? 21 : 17); - break; - - case 50: - seq_playTalkText(_flags.isTalkie ? 29 : 25); - break; - - default: - break; - } - - _seqFrameCounter++; - return 0; -} - -int KyraEngine_v2::seq_finaleFheep(WSAMovieV2 *wsaObj, int x, int y, int frm) { - uint32 endtime = 0; - int chatX = 0; - int chatY = 0; - int chatW = 0; - int chatFirstFrame = 0; - int chatLastFrame = 0; - uint16 voiceIndex = 0; - - switch (frm) { - case -2: - _screen->copyPage(12, 2); - _screen->copyPage(2, 0); - _screen->updateScreen(); - seq_sequenceCommand(9); - endtime = _system->getMillis() + 480 * _tickLength; - seq_printCreditsString(49, 240, 20, _seqTextColorMap, 252); - seq_printCreditsString(50, 240, 30, _seqTextColorMap, _seqTextColor[0]); - seq_printCreditsString(51, 240, 40, _seqTextColorMap, _seqTextColor[0]); - seq_printCreditsString(52, 240, 50, _seqTextColorMap, _seqTextColor[0]); - seq_printCreditsString(53, 240, 60, _seqTextColorMap, _seqTextColor[0]); - seq_printCreditsString(54, 240, 70, _seqTextColorMap, _seqTextColor[0]); - seq_printCreditsString(55, 240, 80, _seqTextColorMap, _seqTextColor[0]); - seq_printCreditsString(56, 240, 90, _seqTextColorMap, _seqTextColor[0]); - seq_printCreditsString(57, 240, 100, _seqTextColorMap, _seqTextColor[0]); - seq_printCreditsString(58, 240, 110, _seqTextColorMap, _seqTextColor[0]); - seq_printCreditsString(60, 240, 120, _seqTextColorMap, _seqTextColor[0]); - seq_printCreditsString(61, 240, 130, _seqTextColorMap, _seqTextColor[0]); - seq_printCreditsString(62, 240, 140, _seqTextColorMap, _seqTextColor[0]); - seq_printCreditsString(63, 240, 150, _seqTextColorMap, _seqTextColor[0]); - seq_printCreditsString(64, 240, 160, _seqTextColorMap, _seqTextColor[0]); - - delay(endtime - _system->getMillis()); - _seqEndTime = 0; - break; - - case 0: - _seqTextColor[1] = _screen->findLeastDifferentColor(_seqTextColorPresets, _screen->getPalette(0) + 3, 255) & 0xff; - memset(_seqTextColorMap, _seqTextColor[1], 16); - _seqTextColor[0] = _seqTextColorMap[1] = 0xff; - _screen->setTextColorMap(_seqTextColorMap); - break; - - case 2: - seq_playTalkText(_flags.isTalkie ? 25 : 21); - - if (_flags.lang == Common::FR_FRA) { - chatX = 92; - chatY = 72; - } else { - chatX = (_flags.lang == Common::DE_DEU) ? 90 : 98; - chatY = 84; - } - - if (_flags.isTalkie) { - chatFirstFrame = 8; - chatLastFrame = 9; - voiceIndex = 39; - } else { - chatFirstFrame = 2; - chatLastFrame = -8; - } - chatW = 100; - - seq_playWsaSyncDialogue(28, voiceIndex, -1, chatX, chatY, chatW, wsaObj, chatFirstFrame, chatLastFrame, x, y); - if (_flags.isTalkie) - _seqWsaCurrentFrame = 4; - break; - - case 9: - seq_playTalkText(_flags.isTalkie ? 24 : 20); - _seqFrameDelay = 100; - break; - - default: - break; - } - - _seqFrameCounter++; - return 0; -} - -int KyraEngine_v2::seq_finaleFarmer(WSAMovieV2 *wsaObj, int x, int y, int frm) { - uint32 endtime = 0; - int chatX = 0; - int chatY = 0; - int chatW = 0; - uint16 voiceIndex = 0; - - switch (frm) { - case -2: - _screen->copyPage(12, 2); - _screen->copyPage(2, 0); - _screen->updateScreen(); - seq_sequenceCommand(9); - endtime = _system->getMillis() + 480 * _tickLength; - seq_printCreditsString(45, 240, 40, _seqTextColorMap, 252); - seq_printCreditsString(46, 240, 50, _seqTextColorMap, _seqTextColor[0]); - seq_printCreditsString(47, 240, 60, _seqTextColorMap, _seqTextColor[0]); - seq_printCreditsString(83, 240, 80, _seqTextColorMap, 252); - seq_printCreditsString(48, 240, 90, _seqTextColorMap, _seqTextColor[0]); - seq_printCreditsString(65, 240, 110, _seqTextColorMap, 252); - seq_printCreditsString(66, 240, 120, _seqTextColorMap, _seqTextColor[0]); - seq_printCreditsString(67, 240, 130, _seqTextColorMap, _seqTextColor[0]); - seq_printCreditsString(68, 240, 140, _seqTextColorMap, _seqTextColor[0]); - seq_printCreditsString(69, 240, 150, _seqTextColorMap, _seqTextColor[0]); - if (_flags.platform == Common::kPlatformFMTowns || _flags.platform == Common::kPlatformPC98) - seq_printCreditsString(104, 240, 160, _seqTextColorMap, _seqTextColor[0]); - delay(endtime - _system->getMillis()); - _seqEndTime = 0; - break; - - case 0: - _seqTextColor[1] = 1 + (_screen->findLeastDifferentColor(_seqTextColorPresets, _screen->getPalette(0) + 3, 254) & 0xff); - memset(_seqTextColorMap, _seqTextColor[1], 16); - _seqTextColorMap[1] = _seqTextColor[0] = 1 + (_screen->findLeastDifferentColor(_seqTextColorPresets + 3, _screen->getPalette(0) + 3, 254) & 0xff); - _screen->setTextColorMap(_seqTextColorMap); - seq_playTalkText(_flags.isTalkie ? 30 : 26); - break; - - case 6: - if (_flags.isTalkie) - seq_playTalkText(18); - break; - - case 12: - if (!_flags.isTalkie) - seq_playTalkText(14); - - chatX = 90; - chatY = 30; - chatW = 100; - - if (_flags.isTalkie) { - if (_flags.lang == Common::FR_FRA || _flags.lang == Common::DE_DEU) { - chatX = 75; - chatY = 25; - } - voiceIndex = 40; - } - - seq_playWsaSyncDialogue(29, voiceIndex, 150, chatX, chatY, chatW, wsaObj, 12, -21, x, y); - break; - - default: - break; - } - - _seqFrameCounter++; - return 0; -} - -int KyraEngine_v2::seq_finaleFuards(WSAMovieV2 *wsaObj, int x, int y, int frm) { - uint32 endtime = 0; - int chatX = 0; - int chatY = 0; - int chatW = 0; - int chatFirstFrame = 0; - int chatLastFrame = 0; - int textCol = 0; - - uint16 voiceIndex = 0; - - switch (frm) { - case -2: - seq_sequenceCommand(9); - endtime = _system->getMillis() + 480 * _tickLength; - seq_printCreditsString(70, 240, 20, _seqTextColorMap, 252); - seq_printCreditsString(71, 240, 30, _seqTextColorMap, _seqTextColor[0]); - seq_printCreditsString(72, 240, 40, _seqTextColorMap, _seqTextColor[0]); - seq_printCreditsString(73, 240, 50, _seqTextColorMap, _seqTextColor[0]); - seq_printCreditsString(74, 240, 60, _seqTextColorMap, _seqTextColor[0]); - seq_printCreditsString(75, 240, 70, _seqTextColorMap, _seqTextColor[0]); - seq_printCreditsString(101, 240, 80, _seqTextColorMap, _seqTextColor[0]); - seq_printCreditsString(102, 240, 90, _seqTextColorMap, _seqTextColor[0]); - seq_printCreditsString(87, 240, 100, _seqTextColorMap, _seqTextColor[0]); - seq_printCreditsString(88, 240, 110, _seqTextColorMap, _seqTextColor[0]); - seq_printCreditsString(89, 240, 120, _seqTextColorMap, _seqTextColor[0]); - seq_printCreditsString(90, 240, 130, _seqTextColorMap, _seqTextColor[0]); - seq_printCreditsString(91, 240, 140, _seqTextColorMap, _seqTextColor[0]); - seq_printCreditsString(92, 240, 150, _seqTextColorMap, _seqTextColor[0]); - delay(endtime - _system->getMillis()); - _seqEndTime = 0; - break; - - case 0: - for (int i = 0; i < 0x300; i++) - _screen->getPalette(0)[i] &= 0x3f; - _seqTextColor[1] = 0xCf; - memset(_seqTextColorMap, _seqTextColor[1], 16); - _seqTextColor[0] = _seqTextColorMap[1] = 0xfe; - - _screen->setTextColorMap(_seqTextColorMap); - break; - - case 6: - _seqFrameDelay = 20; - - if (_flags.isTalkie) { - chatX = 82; - textCol = 143; - chatFirstFrame = 16; - chatLastFrame = 21; - voiceIndex = 41; - } else { - chatX = 62; - textCol = 137; - chatFirstFrame = 9; - chatLastFrame = 13; - } - chatY = (_flags.lang == Common::FR_FRA || _flags.lang == Common::DE_DEU) ? 88 :100; - chatW = 80; - - seq_playWsaSyncDialogue(30, voiceIndex, 137, chatX, chatY, chatW, wsaObj, chatFirstFrame, chatLastFrame, x, y); - if (_flags.isTalkie) - _seqWsaCurrentFrame = 8; - break; - - case 9: - case 16: - if (_flags.isTalkie) { - if (frm == 16) - break; - chatX = 64; - textCol = 137; - chatFirstFrame = 9; - chatLastFrame = 13; - voiceIndex = 42; - } else { - if (frm == 9) - break; - chatX = 80; - textCol = 143; - chatFirstFrame = 16; - chatLastFrame = 21; - } - chatY = 100; - chatW = 100; - - seq_playWsaSyncDialogue(31, voiceIndex, 143, chatX, chatY, chatW, wsaObj, chatFirstFrame, chatLastFrame, x, y); - if (_flags.isTalkie) - _seqWsaCurrentFrame = 21; - break; - - default: - break; - } - - _seqFrameCounter++; - return 0; -} - -int KyraEngine_v2::seq_finaleFirates(WSAMovieV2 *wsaObj, int x, int y, int frm) { - uint32 endtime = 0; - int chatX = 0; - int chatY = 0; - int chatW = 0; - uint16 voiceIndex = 0; - - switch (frm) { - case -2: - _screen->copyPage(12, 2); - _screen->copyPage(2, 0); - _screen->updateScreen(); - seq_sequenceCommand(9); - endtime = _system->getMillis() + 480 * _tickLength; - seq_printCreditsString(76, 240, 40, _seqTextColorMap, 252); - seq_printCreditsString(77, 240, 50, _seqTextColorMap, 252); - seq_printCreditsString(78, 240, 60, _seqTextColorMap, _seqTextColor[0]); - seq_printCreditsString(79, 240, 70, _seqTextColorMap, _seqTextColor[0]); - seq_printCreditsString(80, 240, 80, _seqTextColorMap, _seqTextColor[0]); - seq_printCreditsString(84, 240, 100, _seqTextColorMap, 252); - seq_printCreditsString(85, 240, 110, _seqTextColorMap, _seqTextColor[0]); - seq_printCreditsString(99, 240, 130, _seqTextColorMap, 252); - seq_printCreditsString(100, 240, 140, _seqTextColorMap, _seqTextColor[0]); - delay(endtime - _system->getMillis()); - _seqEndTime = 0; - break; - - case 0: - _seqTextColor[1] = _screen->findLeastDifferentColor(_seqTextColorPresets, _screen->getPalette(0) + 3, 255) & 0xff; - memset(_seqTextColorMap, _seqTextColor[1], 16); - _seqTextColor[0] = _seqTextColorMap[1] = 0xff; - _screen->setTextColorMap(_seqTextColorMap); - break; - - case 6: - seq_playTalkText(_flags.isTalkie ? 31 : 27); - break; - - case 14: - case 15: - if (!((frm == 15 && !_flags.isTalkie) || (frm == 14 && _flags.isTalkie))) - break; - - seq_playTalkText(_flags.isTalkie ? 31 : 27); - - if (_flags.lang == Common::DE_DEU) { - chatX = 82; - chatY = 84; - chatW = 140; - } else { - chatX = 74; - chatY = (_flags.lang == Common::FR_FRA) ? 96: 108; - chatW = 80; - } - - if (_flags.isTalkie) - voiceIndex = 43; - - seq_playWsaSyncDialogue(32, voiceIndex, 137, chatX, chatY, chatW, wsaObj, 14, 16, x, y); - break; - - case 28: - seq_playTalkText(_flags.isTalkie ? 32 : 28); - break; - - case 29: - seq_playTalkText(_flags.isTalkie ? 33 : 29); - break; - - case 31: - if (_flags.isTalkie) - voiceIndex = 44; - - chatX = 90; - chatY = (_flags.lang == Common::DE_DEU) ? 60 : 76; - chatW = 80; - - seq_playWsaSyncDialogue(33, voiceIndex, 143, chatX, chatY, chatW, wsaObj, 31, 34, x, y); - break; - - case 35: - _seqFrameDelay = 300; - break; - - default: - break; - } - - _seqFrameCounter++; - return 0; -} - -int KyraEngine_v2::seq_finaleFrash(WSAMovieV2 *wsaObj, int x, int y, int frm) { - int tmp = 0; - - switch (frm) { - case -2: - _screen->setCurPage(2); - _screen->clearCurPage(); - _screen->copyPage(2, 12); - _screen->copyPage(2, 0); - _screen->updateScreen(); - _seqFrameCounter = 0; - seq_loadNestedSequence(0, kSequenceFiggle); - break; - - case -1: - if (_flags.isTalkie) - seq_finaleActorScreen(); - _seqSpecialFlag = _flags.isTalkie; - break; - - case 0: - if (_seqFrameCounter == 1) { - _sound->playTrack(4); - _seqTextColor[1] = _screen->findLeastDifferentColor(_seqTextColorPresets, _screen->getPalette(0) + 3, 255) & 0xff; - memset(_seqTextColorMap, _seqTextColor[1], 16); - _seqTextColor[0] = _seqTextColorMap[1] = 0xff; - _screen->setTextColorMap(_seqTextColorMap); - } - _seqFrameDelay = 10; - break; - - case 1: - if (_seqFrameCounter < 20 && _seqSpecialFlag) { - _seqWsaCurrentFrame = 0; - } else { - _seqFrameDelay = _flags.isTalkie ? 500 : (300 + _rnd.getRandomNumberRng(1, 300)); - seq_playTalkText(_flags.isTalkie ? 26 : 22); - if (_seqSpecialFlag) { - _seqFrameCounter = 3; - _seqSpecialFlag = false; - } - } - break; - - case 2: - _seqFrameDelay = 20; - break; - - case 3: - seq_playTalkText(_flags.isTalkie ? 27 : 23); - _seqFrameDelay = _flags.isTalkie ? 500 : (300 + _rnd.getRandomNumberRng(1, 300)); - break; - - case 4: - _seqFrameDelay = 10; - break; - - case 5: - seq_playTalkText(_flags.isTalkie ? 27 : 23); - tmp = _seqFrameCounter / 6; - if (tmp == 2) - _seqFrameDelay = _flags.isTalkie ? 7 : (1 + _rnd.getRandomNumberRng(1, 10)); - else if (tmp < 2) - _seqFrameDelay = _flags.isTalkie ? 500 : (300 + _rnd.getRandomNumberRng(1, 300)); - break; - - case 6: - _seqFrameDelay = 10; - tmp = _seqFrameCounter / 6; - if (tmp == 2) - _seqWsaCurrentFrame = 4; - else if (tmp < 2) - _seqWsaCurrentFrame = 0; - break; - - case 7: - _seqFrameCounter = 0; - _seqFrameDelay = 5; - seq_playTalkText(_flags.isTalkie ? 26 : 22); - break; - - case 11: - if (_seqFrameCounter < 8) - _seqWsaCurrentFrame = 8; - break; - - default: - break; - } - - _seqFrameCounter++; - return 0; -} - -void KyraEngine_v2::seq_finaleActorScreen() { - static const uint8 colormap[] = {0, 0, 102, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - static const ScreenDim d = { 0x00, 0x0C, 0x28, 0xB4, 0xFF, 0x00, 0x00, 0x00 }; - - _screen->loadBitmap("finale.cps", 3, 3, _screen->_currentPalette); - _screen->setFont(Screen::FID_GOLDFONT_FNT); - - int talkieCreditsSize, talkieCreditsSpecialSize; - const uint8 *talkieCredits = _staticres->loadRawData(k2SeqplayCredits, talkieCreditsSize); - const char *const *talkieCreditsSpecial = _staticres->loadStrings(k2SeqplayCreditsSpecial, talkieCreditsSpecialSize); - - _sound->setSoundList(&_soundData[kMusicIngame]); - _sound->loadSoundFile(3); - _sound->playTrack(3); - - _screen->setTextColorMap(colormap); - _screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0); - _screen->updateScreen(); - _screen->fadeFromBlack(); - - _screen->_charWidth = -2; - uint8 *dataPtr = new uint8[0xafd]; - memcpy(dataPtr, talkieCredits, talkieCreditsSize); - _staticres->unloadId(k2SeqplayCredits); - - seq_displayScrollText(dataPtr, &d, 2, 6, 5, 1, Screen::FID_GOLDFONT_FNT, Screen::FID_GOLDFONT_FNT, 0, talkieCreditsSpecial); - delay(120); - - delete [] dataPtr; - _staticres->unloadId(k2SeqplayCreditsSpecial); - _sound->setSoundList(&_soundData[kMusicFinale]); - _sound->loadSoundFile(0); -} - -int KyraEngine_v2::seq_finaleFiggle(WSAMovieV2 *wsaObj, int x, int y, int frm) { - if (_seqFrameCounter == 10) - _seqEndTime = 0; - if (_seqFrameCounter == 10 || _seqFrameCounter == 5 || _seqFrameCounter == 7) - seq_playTalkText(_flags.isTalkie ? 45 : 30); - - _seqFrameCounter++; - return frm; -} - -int KyraEngine_v2::seq_demoVirgin(WSAMovieV2 *wsaObj, int x, int y, int frm) { - if (!frm) - delay(50 * _tickLength); - return 0; -} - -int KyraEngine_v2::seq_demoWestwood(WSAMovieV2 *wsaObj, int x, int y, int frm) { - if (!frm) - _sound->playTrack(2); - return 0; -} -int KyraEngine_v2::seq_demoTitle(WSAMovieV2 *wsaObj, int x, int y, int frm) { - if (!frm) { - _sound->playTrack(3); - } else if (frm == 25) { - delay(60 * _tickLength); - _seqEndTime = 0; - seq_sequenceCommand(0); - } - return 0; -} - -int KyraEngine_v2::seq_demoHill(WSAMovieV2 *wsaObj, int x, int y, int frm) { - if (!frm) { - _sound->playTrack(4); - } else if (frm == 25) { - seq_loadNestedSequence(0, kSequenceDemoWater); - _seqFrameDelay--; - } else if (frm > 25 && frm < 50) { - if (_seqFrameDelay > 3) - _seqFrameDelay--; - } else if (frm == 95) { - _seqFrameDelay = 70; - } else if (frm == 96) { - _seqFrameDelay = 7; - } else if (frm == 129) { - seq_resetActiveWSA(0); - } - - return 0; -} - -int KyraEngine_v2::seq_demoOuthome(WSAMovieV2 *wsaObj, int x, int y, int frm) { - switch (frm) { - case 12: - seq_playTalkText(4); - break; - - case 32: - seq_playTalkText(7); - break; - - case 36: - seq_playTalkText(10); - break; - - case 57: - seq_playTalkText(9); - break; - - case 80: - case 96: - case 149: - _seqFrameDelay = 70; - break; - - case 81: - case 97: - _seqFrameDelay = 5; - break; - - case 110: - seq_playTalkText(5); - break; - - case 137: - seq_playTalkText(6); - break; - } - - return 0; -} - -int KyraEngine_v2::seq_demoWharf(WSAMovieV2 *wsaObj, int x, int y, int frm) { - if (!_seqFrameCounter) - seq_loadNestedSequence(0, kSequenceDemoWharf2); - - switch (frm) { - case 0: - seq_playTalkText(11); - break; - - case 5: - if ((_seqFrameCounter / 8) <= 2 || _activeWSA[0].flags != -1) - _seqWsaCurrentFrame = 0; - else - seq_resetActiveWSA(0); - break; - - case 6: - seq_resetActiveWSA(0); - break; - - case 8: - case 10: - seq_playTalkText(2); - break; - - case 13: - seq_playTalkText(7); - break; - - case 16: - seq_playTalkText(12); - break; - - default: - break; - } - - _seqFrameCounter++; - return 0; -} - -int KyraEngine_v2::seq_demoDinob(WSAMovieV2 *wsaObj, int x, int y, int frm) { - if (frm == 0) { - if (!(_seqFrameCounter/8)) { - seq_loadNestedSequence(0, kSequenceDemoDinob2); - _seqWsaCurrentFrame = 0; - } - } else if (frm == 3) { - if (_activeWSA[0].flags != -1) { - _seqWsaCurrentFrame = 0; - } else { - seq_resetActiveWSA(0); - _screen->copyPage(2, 12); - } - } else if (frm == 4) { - seq_resetActiveWSA(0); - } - - _seqFrameCounter++; - return 0; -} - -int KyraEngine_v2::seq_demoFisher(WSAMovieV2 *wsaObj, int x, int y, int frm) { - if (((_system->getMillis() - _seqStartTime) / (5 * _tickLength)) > 0) { - _seqStartTime = _system->getMillis(); - if (!_seqFrameCounter) { - seq_loadNestedSequence(0, kSequenceDemoBail); - seq_loadNestedSequence(1, kSequenceDemoDig); - } - - if (_seqScrollTextCounter >= 0x18f && !_seqFrameCounter) - return 0; - - if (!_seqFrameCounter) { - _screen->loadBitmap("adtext.cps", 4, 4, 0); - _screen->loadBitmap("adtext2.cps", 6, 6, 0); - _screen->copyPageMemory(6, 0, 4, 64000, 1024); - _screen->copyPageMemory(6, 1023, 6, 0, 64000); - _seqScrollTextCounter = 0; - } - - seq_scrollPage(); - _seqFrameCounter++; - if (_seqFrameCounter < 0x256 || _seqFrameCounter > 0x31c) { - if (_seqFrameCounter < 0x174 || _seqFrameCounter > 0x1d7) { - if (_seqFrameCounter < 0x84 || _seqFrameCounter > 0xe7) { - _seqScrollTextCounter++; - } - } - } - - if (_seqFrameCounter > 0x31e) { - seq_resetActiveWSA(0); - seq_resetActiveWSA(1); - _seqEndTime = 0; - _screen->copyPage(2, 12); - } - - } else { - seq_scrollPage(); - } - return 0; -} - -int KyraEngine_v2::seq_demoWharf2(WSAMovieV2 *wsaObj, int x, int y, int frm) { - if (frm == 69) - _seqWsaCurrentFrame = 8; - - return frm; -} - -int KyraEngine_v2::seq_demoDinob2(WSAMovieV2 *wsaObj, int x, int y, int frm) { - switch (frm) { - case 19: - seq_playTalkText(13); - break; - - case 54: - seq_playTalkText(15); - break; - - case 61: - seq_playTalkText(16); - break; - - case 69: - seq_playTalkText(14); - break; - - case 77: - seq_playTalkText(13); - break; - - case 79: - _seqWsaCurrentFrame = 4; - break; - } - - return frm; -} - -int KyraEngine_v2::seq_demoWater(WSAMovieV2 *wsaObj, int x, int y, int frm) { - if (frm == 1) - seq_playTalkText(11); - return frm; -} - -int KyraEngine_v2::seq_demoBail(WSAMovieV2 *wsaObj, int x, int y, int frm) { - return frm; -} - -int KyraEngine_v2::seq_demoDig(WSAMovieV2 *wsaObj, int x, int y, int frm) { - return frm; -} - -uint32 KyraEngine_v2::seq_activeTextsTimeLeft() { - uint32 res = 0; - - for (int i = 0; i < 10; i++) { - uint32 chatend = (_activeText[i].duration + _activeText[i].startTime); - uint32 curtime = _system->getMillis(); - if (_activeText[i].duration != -1 && chatend > curtime) { - chatend -= curtime; - if (res < chatend) - res = chatend; - } - } - - return res; -} - -void KyraEngine_v2::seq_processWSAs() { - for (int i = 0; i < 8; i++) { - if (_activeWSA[i].flags != -1) { - if (seq_processNextSubFrame(i)) - seq_resetActiveWSA(i); - } - } -} - -void KyraEngine_v2::seq_processText() { - Screen::FontId curFont = _screen->setFont(Screen::FID_GOLDFONT_FNT); - int curPage = _screen->setCurPage(2); - char outputStr[70]; - - for (int i = 0; i < 10; i++) { - if (_activeText[i].startTime + _activeText[i].duration > _system->getMillis() && _activeText[i].duration != -1) { - - char *srcStr = seq_preprocessString(_sequenceStrings[_activeText[i].strIndex], _activeText[i].width); - int yPos = _activeText[i].y; - - while (*srcStr) { - uint32 linePos = 0; - for (; *srcStr; linePos++) { - if (*srcStr == 0x0d) // Carriage return - break; - outputStr[linePos] = *srcStr; - srcStr++; - } - outputStr[linePos] = 0; - if (*srcStr == 0x0d) - srcStr++; - - uint8 textColor = (_activeText[i].textcolor >= 0) ? _activeText[i].textcolor : _seqTextColor[0]; - _screen->printText(outputStr, _activeText[i].x - (_screen->getTextWidth(outputStr) / 2), yPos, textColor, 0); - yPos += 10; - } - } else { - _activeText[i].duration = -1; - } - } - - _screen->setCurPage(curPage); - _screen->setFont(curFont); -} - -char *KyraEngine_v2::seq_preprocessString(const char *srcStr, int width) { - char *dstStr = _seqProcessedString; - int lineStart = 0; - int linePos = 0; - - while (*srcStr) { - while (*srcStr && *srcStr != 0x20) // Space - dstStr[lineStart + linePos++] = *srcStr++; - dstStr[lineStart + linePos] = 0; - - int len = _screen->getTextWidth(&dstStr[lineStart]); - if (width >= len && *srcStr) { - dstStr[lineStart + linePos++] = *srcStr++; - } else { - dstStr[lineStart + linePos] = 0x0d; // Carriage return - lineStart += linePos + 1; - linePos = 0; - if (*srcStr) - srcStr++; - } - } - dstStr[lineStart + linePos] = 0; - - return strlen(_seqProcessedString) ? dstStr : 0; -} - -void KyraEngine_v2::seq_sequenceCommand(int command) { - uint8 pal[768]; - - for (int i = 0; i < 8; i++) - seq_resetActiveWSA(i); - - switch (command) { - case 0: - memset(pal, 0, 0x300); - _screen->fadePalette(pal, 16); - memcpy (_screen->getPalette(0), pal, 0x300); - memcpy (_screen->getPalette(1), pal, 0x300); - break; - - case 1: - memset(pal, 0x3F, 0x300); - //////////XXX - //////////Unused anyway (at least by fm-towns intro/outro) - - _screen->fadePalette(pal, 16); - memcpy (_screen->getPalette(0), pal, 0x300); - memcpy (_screen->getPalette(1), pal, 0x300); - break; - - case 3: - _screen->copyPage(2, 0); - _screen->fadePalette(_screen->getPalette(0), 16); - memcpy (_screen->getPalette(1), _screen->getPalette(0), 0x300); - break; - - case 4: - _screen->copyPage(2, 0); - _screen->fadePalette(_screen->getPalette(0), 36); - memcpy (_screen->getPalette(1), _screen->getPalette(0), 0x300); - break; - - case 5: - _screen->copyPage(2, 0); - break; - - case 6: - // UNUSED - // seq_loadBLD("library.bld"); - break; - - case 7: - // UNUSED - // seq_loadBLD("marco.bld"); - break; - - case 8: - memset(pal, 0, 0x300); - _screen->fadePalette(pal, 16); - memcpy (_screen->getPalette(0), pal, 0x300); - memcpy (_screen->getPalette(1), pal, 0x300); - - delay(120 * _tickLength); - break; - - case 9: - for (int i = 0; i < 0x100; i++) { - int pv = (_screen->getPalette(0)[3 * i] + _screen->getPalette(0)[3 * i + 1] + _screen->getPalette(0)[3 * i + 2]) / 3; - pal[3 * i] = pal[3 * i + 1] = pal[3 * i + 2] = pv & 0xff; - } - - //int a = 0x100; - //int d = (0x800 << 5) - 0x100; - //pal[3 * i] = pal[3 * i + 1] = pal[3 * i + 2] = 0x3f; - - _screen->fadePalette(pal, 64); - memcpy (_screen->getPalette(0), pal, 0x300); - memcpy (_screen->getPalette(1), pal, 0x300); - break; - - default: - break; - } -} - -void KyraEngine_v2::seq_cmpFadeFrame(const char *cmpFile) { - _screen->copyPage(10, 2); - _screen->copyPage(4, 10); - _screen->clearPage(6); - _screen->loadBitmap(cmpFile, 6, 6, 0); - _screen->copyPage(12, 4); - - for (int i = 0; i < 3; i++) { - uint32 endtime = _system->getMillis() + 4 * _tickLength; - _screen->cmpFadeFrameStep(4, 320, 200, 0, 0, 2, 320, 200, 0, 0, 320, 200, 6); - _screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0); - _screen->updateScreen(); - delayUntil(endtime); - } - - _screen->copyPage(4, 0); - _screen->updateScreen(); - _screen->copyPage(4, 2); - _screen->copyPage(4, 6); - _screen->copyPage(10, 4); -} - -void KyraEngine_v2::seq_playTalkText(uint8 chatNum) { - debugC(9, kDebugLevelMain, "KyraEngine_v2::seq_playTalkText(%i)", chatNum); - - assert(chatNum < _sequenceSoundListSize); - - if (chatNum < 12 && !_flags.isDemo && textEnabled()) - seq_setTextEntry(chatNum, 160, 168, _sequenceStringsDuration[chatNum], 160); - - _speechFile = _sequenceSoundList[chatNum]; - _sound->voicePlay(_sequenceSoundList[chatNum]); -} - -void KyraEngine_v2::seq_waitForTextsTimeout() { - debugC(9, kDebugLevelMain, "KyraEngine_v2::seq_waitForTextsTimeout()"); - - uint32 longest = seq_activeTextsTimeLeft() + _system->getMillis(); - uint32 now = _system->getMillis(); - - if (textEnabled()) { - if (longest > now) - delay(longest - now); - } else if (speechEnabled()) { - while (snd_voiceIsPlaying()) - delay(_tickLength); - } - - seq_resetAllTextEntries(); -} - -void KyraEngine_v2::seq_resetAllTextEntries() { - debugC(9, kDebugLevelMain, "KyraEngine_v2::seq_resetAllTextEntries()"); - for (int i = 0; i < 10; i++) - _activeText[i].duration = -1; -} - -int KyraEngine_v2::seq_setTextEntry(uint16 strIndex, uint16 posX, uint16 posY, int duration, uint16 width) { - debugC(9, kDebugLevelMain, "KyraEngine_v2::seq_setTextEntry(%i, %i, %i, %i, %i)", strIndex, posX, posY, duration, width); - - for (int i = 0; i < 10; i++) { - if (_activeText[i].duration != -1) { - if (i < 9) - continue; - else - return -1; - } - - _activeText[i].strIndex = strIndex; - _activeText[i].x = posX; - _activeText[i].y = posY; - _activeText[i].duration = duration * _tickLength; - _activeText[i].width = width; - _activeText[i].startTime = _system->getMillis(); - _activeText[i].textcolor = -1; - - return i; - } - return -1; -} - -void KyraEngine_v2::seq_loadNestedSequence(int wsaNum, int seqNum) { - debugC(9, kDebugLevelMain, "KyraEngine_v2::seq_loadNestedSequence(%i, %i)", wsaNum, seqNum); - - if (_activeWSA[wsaNum].flags != -1) - return; - - NestedSequence s = _sequences->seqn[seqNum]; - - if (!_activeWSA[wsaNum].movie) { - _activeWSA[wsaNum].movie = new WSAMovieV2(this, _screen); - assert(_activeWSA[wsaNum].movie); - } - - _activeWSA[wsaNum].movie->close(); - - _activeWSA[wsaNum].movie->open(s.wsaFile, 0, 0); - - if (!_activeWSA[wsaNum].movie->opened()) { - delete _activeWSA[wsaNum].movie; - _activeWSA[wsaNum].movie = 0; - return; - } - - _activeWSA[wsaNum].endFrame = s.endFrame; - _activeWSA[wsaNum].startFrame = _activeWSA[wsaNum].currentFrame = s.startframe; - _activeWSA[wsaNum].frameDelay = s.frameDelay; - _activeWSA[wsaNum].movie->setX(0); - _activeWSA[wsaNum].movie->setY(0); - _activeWSA[wsaNum].movie->setDrawPage(_screen->_curPage); - _activeWSA[wsaNum].callback = _callbackN[seqNum]; - _activeWSA[wsaNum].control = s.wsaControl; - - _activeWSA[wsaNum].flags = s.flags | 1; - _activeWSA[wsaNum].x = s.x; - _activeWSA[wsaNum].y = s.y; - _activeWSA[wsaNum].startupCommand = s.startupCommand; - _activeWSA[wsaNum].finalCommand = s.finalCommand; - _activeWSA[wsaNum].lastFrame = 0xffff; - - seq_nestedSequenceFrame(s.startupCommand, wsaNum); - - if (!s.startupCommand) - seq_processNextSubFrame(wsaNum); - - _activeWSA[wsaNum].nextFrame = _system->getMillis(); -} - -void KyraEngine_v2::seq_nestedSequenceFrame(int command, int wsaNum) { - int xa = 0, ya = 0; - command--; - if (!_activeWSA[wsaNum].movie || skipFlag() || _quitFlag || _abortIntroFlag) - return; - - switch (command) { - case 0: - _activeWSA[wsaNum].movie->setDrawPage(8); - xa = -_activeWSA[wsaNum].movie->xAdd(); - ya = -_activeWSA[wsaNum].movie->yAdd(); - _activeWSA[wsaNum].movie->setX(xa); - _activeWSA[wsaNum].movie->setY(ya); - _activeWSA[wsaNum].movie->displayFrame(0, 0); - _activeWSA[wsaNum].movie->setX(0); - _activeWSA[wsaNum].movie->setY(0); - seq_animatedSubFrame(8, 2, 7, 8, _activeWSA[wsaNum].movie->xAdd(), _activeWSA[wsaNum].movie->yAdd(), - _activeWSA[wsaNum].movie->width(), _activeWSA[wsaNum].movie->height(), 1, 2); - break; - - case 1: - _activeWSA[wsaNum].movie->setDrawPage(8); - xa = -_activeWSA[wsaNum].movie->xAdd(); - ya = -_activeWSA[wsaNum].movie->yAdd(); - _activeWSA[wsaNum].movie->setX(xa); - _activeWSA[wsaNum].movie->setY(ya); - _activeWSA[wsaNum].movie->displayFrame(0, 0); - _activeWSA[wsaNum].movie->setX(0); - _activeWSA[wsaNum].movie->setY(0); - seq_animatedSubFrame(8, 2, 7, 8, _activeWSA[wsaNum].movie->xAdd(), _activeWSA[wsaNum].movie->yAdd(), - _activeWSA[wsaNum].movie->width(), _activeWSA[wsaNum].movie->height(), 1, 1); - break; - - case 2: - seq_waitForTextsTimeout(); - _activeWSA[wsaNum].movie->setDrawPage(8); - xa = -_activeWSA[wsaNum].movie->xAdd(); - ya = -_activeWSA[wsaNum].movie->yAdd(); - _activeWSA[wsaNum].movie->setX(xa); - _activeWSA[wsaNum].movie->setY(ya); - _activeWSA[wsaNum].movie->displayFrame(0x15, 0); - _activeWSA[wsaNum].movie->setX(0); - _activeWSA[wsaNum].movie->setY(0); - seq_animatedSubFrame(8, 2, 7, 8, _activeWSA[wsaNum].movie->xAdd(), _activeWSA[wsaNum].movie->yAdd(), - _activeWSA[wsaNum].movie->width(), _activeWSA[wsaNum].movie->height(), 0, 2); - break; - - case 3: - _screen->copyPage(2, 10); - _activeWSA[wsaNum].movie->setDrawPage(2); - _activeWSA[wsaNum].movie->setX(0); - _activeWSA[wsaNum].movie->setY(0); - _activeWSA[wsaNum].movie->displayFrame(0, 0); - _screen->copyPage(2, 12); - seq_cmpFadeFrame("scene2.cmp"); - break; - - case 4: - _screen->copyPage(2, 10); - _activeWSA[wsaNum].movie->setDrawPage(2); - _activeWSA[wsaNum].movie->setX(0); - _activeWSA[wsaNum].movie->setY(0); - _activeWSA[wsaNum].movie->displayFrame(0, 0); - _screen->copyPage(2, 12); - seq_cmpFadeFrame("scene3.cmp"); - break; - - default: - break; - } -} - -void KyraEngine_v2::seq_animatedSubFrame(int srcPage, int dstPage, int delaytime, int steps, - int x, int y, int w, int h, int openClose, int directionFlags) { - if (openClose) { - for (int i = 1; i < steps; i++) { - uint32 endtime = _system->getMillis() + delaytime * _tickLength; - - int w2 = (((w * 256) / steps) * i) / 256; - int h2 = (((h * 256) / steps) * i) / 256; - - int ym = (directionFlags & 2) ? (h - h2) : 0; - int xm = (directionFlags & 1) ? (w - w2) : 0; - - _screen->wsaFrameAnimationStep(0, 0, x + xm, y + ym, w, h, w2, h2, srcPage, dstPage, 0); - - _screen->copyPage(dstPage, 6); - _screen->copyPage(dstPage, 0); - _screen->updateScreen(); - - _screen->copyPage(12, dstPage); - delayUntil(endtime); - } - - _screen->wsaFrameAnimationStep(0, 0, x, y, w, h, w, h, srcPage, dstPage, 0); - _screen->copyPage(dstPage, 6); - _screen->copyPage(dstPage, 0); - _screen->updateScreen(); - } else { - _screen->copyPage(12, dstPage); - for (int i = steps; i; i--) { - uint32 endtime = _system->getMillis() + delaytime * _tickLength; - - int w2 = (((w * 256) / steps) * i) / 256; - int h2 = (((h * 256) / steps) * i) / 256; - - int ym = (directionFlags & 2) ? (h - h2) : 0; - int xm = (directionFlags & 1) ? (w - w2) : 0; - - _screen->wsaFrameAnimationStep(0, 0, x + xm, y + ym, w, h, w2, h2, srcPage, dstPage, 0); - - _screen->copyPage(dstPage, 6); - _screen->copyPage(dstPage, 0); - _screen->updateScreen(); - - _screen->copyPage(12, dstPage); - delayUntil(endtime); - } - } -} - -void KyraEngine_v2::seq_resetActiveWSA(int wsaNum) { - if (_activeWSA[wsaNum].flags == -1) - return; - - _activeWSA[wsaNum].flags = -1; - seq_nestedSequenceFrame(_activeWSA[wsaNum].finalCommand, wsaNum); - _activeWSA[wsaNum].movie->close(); -} - -void KyraEngine_v2::seq_unloadWSA(int wsaNum) { - if (_activeWSA[wsaNum].movie) { - _activeWSA[wsaNum].movie->close(); - delete _activeWSA[wsaNum].movie; - _activeWSA[wsaNum].movie = 0; - } -} - -bool KyraEngine_v2::seq_processNextSubFrame(int wsaNum) { - uint32 currentFrame = _activeWSA[wsaNum].currentFrame; - uint32 currentTime = _system->getMillis(); - - if (_activeWSA[wsaNum].callback && currentFrame != _activeWSA[wsaNum].lastFrame) { - _activeWSA[wsaNum].lastFrame = currentFrame; - currentFrame = (this->*_activeWSA[wsaNum].callback)(_activeWSA[wsaNum].movie, _activeWSA[wsaNum].x, _activeWSA[wsaNum].y, currentFrame); - } - - if (_activeWSA[wsaNum].movie) { - _activeWSA[wsaNum].movie->setDrawPage(2); - _activeWSA[wsaNum].movie->setX(_activeWSA[wsaNum].x); - _activeWSA[wsaNum].movie->setY(_activeWSA[wsaNum].y); - - if (_activeWSA[wsaNum].flags & 0x20) { - _activeWSA[wsaNum].movie->displayFrame(_activeWSA[wsaNum].control[currentFrame].index, 0x4000); - _activeWSA[wsaNum].frameDelay = _activeWSA[wsaNum].control[currentFrame].delay; - } else { - _activeWSA[wsaNum].movie->displayFrame(currentFrame % _activeWSA[wsaNum].movie->frames(), 0x4000); - } - } - - if (_activeWSA[wsaNum].flags & 0x10) { - currentFrame = (currentTime - _activeWSA[wsaNum].nextFrame) / (_activeWSA[wsaNum].frameDelay * _tickLength); - } else { - if (((int32)(currentTime - _activeWSA[wsaNum].nextFrame) / (int32)(_activeWSA[wsaNum].frameDelay * _tickLength)) > 0) { - currentFrame++; - _activeWSA[wsaNum].nextFrame = currentTime; - } - } - - bool res = false; - - if (currentFrame >= _activeWSA[wsaNum].endFrame) { - int sw = ((_activeWSA[wsaNum].flags & 0x1e) - 2); - switch (sw) { - case 0: - res = true; - currentFrame = _activeWSA[wsaNum].endFrame; - _screen->copyPage(2, 12); - break; - - case 6: - case 8: - currentFrame = _activeWSA[wsaNum].endFrame - 1; - break; - - case 2: - case 10: - currentFrame = _activeWSA[wsaNum].startFrame; - break; - - default: - currentFrame = _activeWSA[wsaNum].endFrame - 1; - res = true; - break; - } - } - - _activeWSA[wsaNum].currentFrame = currentFrame & 0xffff; - return res; -} - -void KyraEngine_v2::seq_printCreditsString(uint16 strIndex, int x, int y, const uint8 *colorMap, uint8 textcolor) { - uint8 colormap[16]; - if (skipFlag() || _quitFlag || _abortIntroFlag || _menuChoice) - return; - - memset(&_screen->getPalette(0)[0x2fa], 0x3f, 6); - _screen->getPalette(0)[0x2f6] = 0x3f; - _screen->getPalette(0)[0x2f5] = 0x20; - _screen->getPalette(0)[0x2f4] = 0x30; - colormap[0] = colorMap[0]; - colormap[1] = 0xfd; - memcpy(&colormap[2], &colorMap[2], 14); - uint8 seqTextColor0 = _seqTextColor[0]; - - _seqTextColor[0] = 0xfd; - _screen->setTextColorMap(colormap); - seq_resetAllTextEntries(); - seq_setTextEntry(strIndex, x, y, 0x80, 0x78); - seq_processText(); - _screen->copyPage(2, 0); - _screen->updateScreen(); - _screen->getPalette(0)[0x2f7] = _screen->getPalette(0)[textcolor * 3]; - _screen->getPalette(0)[0x2f8] = _screen->getPalette(0)[textcolor * 3 + 1]; - _screen->getPalette(0)[0x2f9] = _screen->getPalette(0)[textcolor * 3 + 2]; - _screen->fadePalette(_screen->getPalette(0), 0x18); - - _seqTextColor[0] = textcolor; - _screen->setTextColorMap(colorMap); - seq_resetAllTextEntries(); - seq_setTextEntry(strIndex, x, y, 0x80, 0x78); - seq_processText(); - _screen->copyPage(2, 0); - _screen->updateScreen(); - _screen->getPalette(0)[0x2f7] = _screen->getPalette(0)[0x2f8] = _screen->getPalette(0)[0x2f9] = 0; - _screen->fadePalette(_screen->getPalette(0), 1); - _screen->copyPage(2, 12); - seq_resetAllTextEntries(); - - _seqTextColor[0] = seqTextColor0; -} - -void KyraEngine_v2::seq_playWsaSyncDialogue(uint16 strIndex, uint16 vocIndex, int textColor, int x, int y, int width, WSAMovieV2 *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; - uint32 chatTimeout = _system->getMillis() + dur * _tickLength; - int curframe = firstframe; - - if (vocIndex && speechEnabled()) - seq_playTalkText(vocIndex); - - while (_system->getMillis() < chatTimeout && !(_abortIntroFlag || skipFlag())) { - if (lastframe < 0) { - int t = ABS(lastframe); - if (t < curframe) - curframe = t; - } - - if (ABS(lastframe) < curframe) - curframe = firstframe; - - uint32 frameTimeout = _seqEndTime = _system->getMillis() + _seqFrameDelay * _tickLength; - if (wsa) { - wsa->setDrawPage(2); - wsa->setX(wsaXpos); - wsa->setY(wsaYpos); - wsa->displayFrame(curframe % wsa->frames(), 0); - } - - _screen->copyPage(2, 12); - - seq_processText(); - - uint32 tm = _system->getMillis(); - if (frameTimeout > tm && chatTimeout > tm) - delay(MIN(frameTimeout - tm, chatTimeout - tm)); - - if (speechEnabled() && !textEnabled() && !snd_voiceIsPlaying()) - break; - - _screen->copyPage(2, 0); - _screen->updateScreen(); - curframe++; - } - - if (_abortIntroFlag || skipFlag()) - _sound->voiceStop(); - - if (lastframe < 0) { - int t = ABS(lastframe); - if (t < curframe) - curframe = t; - } - - if (curframe == firstframe) - curframe++; - - _seqWsaCurrentFrame = curframe; -} - -void KyraEngine_v2::seq_displayScrollText(uint8 *data, const ScreenDim *d, int tempPage1, int tempPage2, int speed, - int step, Screen::FontId fid1, Screen::FontId fid2, const uint8 *shapeData, const char *const *specialData) { - - if (!data) - return; - - static const char mark[] = { 5, 13, 0}; - - _screen->clearPage(tempPage1); - _screen->clearPage(tempPage2); - _screen->copyRegion(d->sx << 3, d->sy, d->sx << 3, d->sy, d->w << 3, d->h, 0, tempPage1); - - uint8 *tmp = new uint8[397]; - memset(tmp, 0, 397); - uint8 **tmpStringTable = new uint8*[35]; - uint8 *ptr = data; - int strTblIndex = 0; - - bool loop = true; - int cnt = 0; - - while (loop) { - uint32 endTime = _system->getMillis() + speed * _tickLength; - - while (cnt < 35 && *ptr) { - int m = cnt * 11; - uint16 cH = cnt ? READ_LE_UINT16(&tmp[m + 2]) + tmp[m + 9] + (tmp[m + 9] >> 3) : d->h; - - char *str = (char*)ptr; - - ptr = (uint8*)strpbrk(str, mark); - if (!ptr) - ptr = (uint8*)strchr(str, 0); - - tmp[m + 19] = *ptr; - *ptr = 0; - if (tmp[m + 19]) - ptr++; - - tmp[m + 21] = (*str == 3 || *str == 4) ? tmp[m + 21] = *str++ : 0; - - _screen->setFont(fid1); - - if (*str == 1) { - _screen->setFont(fid2); - str++; - } else if (*str == 2) { - str++; - } - - tmp[m + 20] = _screen->getFontHeight(); - - WRITE_LE_UINT16(&tmp[m + 11], (tmp[m + 21] == 3) ? 157 - _screen->getTextWidth(str) : - ((tmp[m + 21] == 4) ? 161 : (((d->w << 3) - _screen->getTextWidth(str)) >> 1) + 1)); - - if (tmp[m + 8] == 5) - cH -= (tmp[m + 9] + (tmp[m + 9] >> 3)); - - WRITE_LE_UINT16(&tmp[m + 13], cH); - WRITE_LE_UINT32(&tmp[m + 15], strTblIndex); - tmpStringTable[strTblIndex] = (uint8*) str; - strTblIndex = (strTblIndex + 1) % 35; - cnt++; - } - - _screen->copyRegion(d->sx << 3, d->sy, d->sx << 3, d->sy, d->w << 3, d->h, tempPage1, tempPage2); - - int cnt2 = 0; - bool palCycle = 0; - - while (cnt2 < cnt) { - int m = cnt2 * 11; - const char *str = (const char*)tmpStringTable[READ_LE_UINT32(&tmp[m + 15])]; - const char *str2 = str; - uint16 cW = READ_LE_UINT16(&tmp[m + 11]) - 10; - uint16 cH = READ_LE_UINT16(&tmp[m + 13]); - int x = (d->sx << 3) + cW; - int y = d->sy + cH; - int col1 = 255; - - if (cH < d->h) { - _screen->setCurPage(tempPage2); - _screen->setFont(fid1); - if (tmp[m + 20] != _screen->getFontHeight()) - _screen->setFont(fid2); - - if (specialData) { - if (!strcmp(str, specialData[0])) { - col1 = 112; - char cChar[2] = " "; - while (*str2) { - cChar[0] = *str2; - _screen->printText(cChar, x, y, col1++, 0); - x += _screen->getCharWidth(*str2++); - } - palCycle = true; - } else if (!strcmp(str, specialData[1])) { - col1 = 133; - char cChar[2] = " "; - while (*str2) { - cChar[0] = *str2; - _screen->printText(cChar, x, y, col1--, 0); - x += _screen->getCharWidth(*str2++); - } - palCycle = true; - } else { - _screen->printText(str, x, y, col1, 0); - } - } else { - _screen->printText(str, x, y, col1, 0); - } - _screen->setCurPage(0); - } - - WRITE_LE_UINT16(&tmp[m + 13], READ_LE_UINT16(&tmp[m + 13]) - step); - cnt2++; - } - - _screen->copyRegion(d->sx << 3, d->sy, d->sx << 3, d->sy, d->w << 3, d->h, tempPage2, 0); - _screen->updateScreen(); - - if ((int16)READ_LE_UINT16(&tmp[13]) < -10) { - tmpStringTable[tmp[15]] += strlen((char*)tmpStringTable[tmp[15]]); - tmpStringTable[tmp[15]][0] = tmp[19]; - cnt--; - memcpy(&tmp[11], &tmp[22], cnt * 11); - } - - if (palCycle) { - for (int col = 133; col > 112; col--) - memcpy(_screen->_currentPalette + (col * 3), _screen->_currentPalette + ((col - 1) * 3), 3); - memcpy(_screen->_currentPalette + 336, _screen->_currentPalette + 399, 3); - _screen->setScreenPalette(_screen->_currentPalette); - } - - delayUntil(endTime); - - if ((cnt < 36) && ((d->sy + d->h) > (READ_LE_UINT16(&tmp[cnt * 11 + 2]) + tmp[cnt * 11 + 9])) && !skipFlag()) { - resetSkipFlag(); - delay(_tickLength * 500); - cnt = 0; - } - - if (!cnt || skipFlag()) - loop = false; - } - - _sound->beginFadeOut(); - _screen->fadeToBlack(); - - _abortIntroFlag= false; - resetSkipFlag(); - - delete [] tmp; - delete [] tmpStringTable; -} - -void KyraEngine_v2::seq_scrollPage() { - int dstY, dstH, srcH; - - static const ScreenDim d = { 0x00, 0x00, 0x28, 0x320, 0xFF, 0xFE, 0x00, 0x00 }; - - if (_seqScrollTextCounter - 143 < 0) { - dstY = 144 - _seqScrollTextCounter; - dstH = _seqScrollTextCounter; - srcH = 0; - } else { - dstY = 0; - srcH = _seqScrollTextCounter - 144; - dstH = (400 - srcH <= 144) ? 400 - srcH : 144; - } - - if (dstH > 0) { - for (int i = 0; i < 4; i++) { - const ItemAnimData_v1 *def = &_demoAnimData[i]; - ActiveItemAnim *a = &_activeItemAnim[i]; - - _screen->fillRect(12, def->y - 8, 28, def->y + 8, 0, 4); - _screen->drawShape(4, _defaultShapeTable[def->itemIndex + def->frames[a->currentFrame]], 12, def->y - 8, 0, 0); - if(_seqFrameCounter % 2 == 0) - a->currentFrame = ++a->currentFrame % 20; - } - _screen->copyRegionEx(4, 0, srcH, 2, 2, dstY + 24, 320, dstH, &d); - } -} - -void KyraEngine_v2::seq_showStarcraftLogo() { - WSAMovieV2 *ci = new WSAMovieV2(this, _screen); - assert(ci); - _screen->clearPage(2); - _res->loadPakFile("INTROGEN.PAK"); - int endframe = ci->open("ci.wsa", 0, _screen->_currentPalette); - _res->unloadPakFile("INTROGEN.PAK"); - if (!ci->opened()) { - delete ci; - return; - } - _screen->hideMouse(); - ci->setX(0); - ci->setY(0); - ci->setDrawPage(2); - ci->displayFrame(0, 0); - _screen->copyPage(2, 0); - _screen->fadeFromBlack(); - for (int i = 1; i < endframe; i++) { - uint32 endTime = _system->getMillis() + 50; - if (skipFlag()) - break; - ci->displayFrame(i, 0); - _screen->copyPage(2, 0); - _screen->updateScreen(); - delay(endTime - _system->getMillis()); - } - if(!skipFlag()) { - uint32 endTime = _system->getMillis() + 50; - ci->displayFrame(0, 0); - _screen->copyPage(2, 0); - _screen->updateScreen(); - delay(endTime - _system->getMillis()); - } - _screen->fadeToBlack(); - _screen->showMouse(); - - _eventList.clear(); - delete ci; -} - -void KyraEngine_v2::seq_init() { - _seqProcessedString = new char[200]; - _seqWsa = new WSAMovieV2(this, _screen); - _activeWSA = new ActiveWSA[8]; - _activeText = new ActiveText[10]; - - _res->unloadAllPakFiles(); - _res->loadPakFile(StaticResource::staticDataFilename()); - _res->loadFileList(_sequencePakList, _sequencePakListSize); - - int numShp = -1; - if (_flags.isDemo && !_flags.isTalkie) { - _demoAnimData = _staticres->loadHofShapeAnimDataV1(k2SeqplayShapeAnimData, _itemAnimDataSize); - uint8 *shp = _res->fileData("icons.shp", 0); - uint32 outsize = READ_LE_UINT16(shp + 4); - _newShapeFiledata = new uint8[outsize]; - Screen::decodeFrame4(shp + 10, _newShapeFiledata, outsize); - delete [] shp; - - do { - numShp++; - _defaultShapeTable[numShp] = _screen->getPtrToShape(_newShapeFiledata, numShp); - } while (_defaultShapeTable[numShp]); - } else { - MainMenu::StaticData data = { - { _sequenceStrings[97], _sequenceStrings[96], _sequenceStrings[95], _sequenceStrings[98] }, - { 0x01, 0x04, 0x0C, 0x04, 0x00, 0xd7, 0xd6, 0x00, 0x01, 0x02, 0x03 }, - { 0xd8, 0xda, 0xd9, 0xd8 }, - 0xd7, 0xd6 - }; - _menu = new MainMenu(this); - _menu->init(data, MainMenu::Animation()); - } -} - -void KyraEngine_v2::seq_uninit() { - delete [] _seqProcessedString; - _seqProcessedString = NULL; - - delete [] _activeWSA; - _activeWSA = NULL; - - delete [] _activeText; - _activeText = NULL; - - delete _seqWsa; - _seqWsa = NULL; - - delete [] _newShapeFiledata; - _newShapeFiledata = 0; - - if (_flags.isDemo && !_flags.isTalkie) - _staticres->unloadId(k2SeqplayShapeAnimData); - - memset(&_defaultShapeTable, 0, sizeof(_defaultShapeTable)); - - delete _menu; - _menu = 0; -} - -#pragma mark - -#pragma mark - Ingame sequences -#pragma mark - - -void KyraEngine_v2::seq_makeBookOrCauldronAppear(int type) { - _screen->hideMouse(); - showMessage(0, 0xCF); - - if (type == 1) - seq_makeBookAppear(); - else if (type == 2) - loadInvWsa("CAULDRON.WSA", 1, 6, 0, -2, -2, 1); - - _screen->copyRegionToBuffer(2, 0, 0, 320, 200, _screenBuffer); - _screen->loadBitmap("_PLAYALL.CPS", 3, 3, 0); - - static const uint8 bookCauldronRects[] = { - 0x46, 0x90, 0x7F, 0x2B, // unknown rect (maybe unused?) - 0xCE, 0x90, 0x2C, 0x2C, // book rect - 0xFA, 0x90, 0x46, 0x2C // cauldron rect - }; - - int x = bookCauldronRects[type*4+0]; - int y = bookCauldronRects[type*4+1]; - int w = bookCauldronRects[type*4+2]; - int h = bookCauldronRects[type*4+3]; - _screen->copyRegion(x, y, x, y, w, h, 2, 0, Screen::CR_NO_P_CHECK); - - _screen->copyBlockToPage(2, 0, 0, 320, 200, _screenBuffer); - - if (type == 2) { - int32 countdown = _rnd.getRandomNumberRng(45, 80); - _timer->setCountdown(2, countdown * 60); - } - - _screen->showMouse(); -} - -void KyraEngine_v2::seq_makeBookAppear() { - _screen->hideMouse(); - - displayInvWsaLastFrame(); - - showMessage(0, 0xCF); - - loadInvWsa("BOOK2.WSA", 0, 4, 2, -1, -1, 0); - - uint8 *rect = new uint8[_screen->getRectSize(_invWsa.w, _invWsa.h)]; - assert(rect); - - _screen->copyRegionToBuffer(_invWsa.page, _invWsa.x, _invWsa.y, _invWsa.w, _invWsa.h, rect); - - _invWsa.running = false; - snd_playSoundEffect(0xAF); - - _invWsa.wsa->setX(0); - _invWsa.wsa->setY(0); - _invWsa.wsa->setDrawPage(_invWsa.page); - - while (true) { - _invWsa.timer = _system->getMillis() + _invWsa.delay * _tickLength; - - _screen->copyBlockToPage(_invWsa.page, _invWsa.x, _invWsa.y, _invWsa.w, _invWsa.h, rect); - - _invWsa.wsa->displayFrame(_invWsa.curFrame, 0x4000, 0, 0); - - if (_invWsa.page) - _screen->copyRegion(_invWsa.x, _invWsa.y, _invWsa.x, _invWsa.y, _invWsa.w, _invWsa.h, _invWsa.page, 0, Screen::CR_NO_P_CHECK); - - ++_invWsa.curFrame; - - if (_invWsa.curFrame >= _invWsa.lastFrame && !_quitFlag) - break; - - switch (_invWsa.curFrame) { - case 39: - snd_playSoundEffect(0xCA); - break; - - case 50: - snd_playSoundEffect(0x6A); - break; - - case 72: - snd_playSoundEffect(0xCB); - break; - - case 85: - snd_playSoundEffect(0x38); - break; - - default: - break; - } - - do { - update(); - } while (_invWsa.timer > _system->getMillis() && !skipFlag()); - } - - closeInvWsa(); - delete [] rect; - _invWsa.running = false; - - _screen->showMouse(); -} - -} // end of namespace Kyra - diff --git a/engines/kyra/sequences_v3.cpp b/engines/kyra/sequences_v3.cpp deleted file mode 100644 index 5a67c3bd68..0000000000 --- a/engines/kyra/sequences_v3.cpp +++ /dev/null @@ -1,354 +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_v3.h" -#include "kyra/resource.h" - -namespace Kyra { - -void KyraEngine_v3::showBadConscience() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::showBadConscience()"); - if (_badConscienceShown) - return; - - _badConscienceShown = true; - _badConscienceAnim = _rnd.getRandomNumberRng(0, 2); - if (_currentChapter == 2) - _badConscienceAnim = 5; - else if (_currentChapter == 3) - _badConscienceAnim = 3; - else if (_currentChapter == 4 && _rnd.getRandomNumberRng(1, 100) <= 25) - _badConscienceAnim = 6; - else if (_currentChapter == 5 && _rnd.getRandomNumberRng(1, 100) <= 25) - _badConscienceAnim = 7; - else if (_malcolmShapes == 9) - _badConscienceAnim = 4; - - _badConsciencePosition = (_mainCharacter.x1 <= 160); - - if (_goodConscienceShown) - _badConsciencePosition = !_goodConsciencePosition; - - int anim = _badConscienceAnim + (_badConsciencePosition ? 0 : 8); - TalkObject &talkObject = _talkObjectList[1]; - - if (_badConsciencePosition) - talkObject.x = 290; - else - talkObject.x = 30; - talkObject.y = 30; - - static const char *animFilenames[] = { - "GUNFL00.WSA", "GUNFL01.WSA", "GUNFL02.WSA", "GUNFL03.WSA", "GUNFL04.WSA", "GUNFL05.WSA", "GUNFL06.WSA", "GUNFL07.WSA", - "GUNFR00.WSA", "GUNFR01.WSA", "GUNFR02.WSA", "GUNFR03.WSA", "GUNFR04.WSA", "GUNFR05.WSA", "GUNFR06.WSA", "GUNFR07.WSA" - }; - - setupSceneAnimObject(0x0E, 9, 0, 187, -1, -1, -1, -1, 0, 0, 0, -1, animFilenames[anim]); - for (uint i = 0; i <= _badConscienceFrameTable[_badConscienceAnim]; ++i) { - if (i == 8) - snd_playSoundEffect(0x1B, 0xC8); - updateSceneAnim(0x0E, i); - delay(3*_tickLength, true); - } - - if (_mainCharacter.animFrame < 50 || _mainCharacter.animFrame > 87) - return; - - if (_mainCharacter.y1 == -1 || (_mainCharacter.x1 != -1 && _mainCharacter.animFrame == 87) || _mainCharacter.animFrame == 87) { - _mainCharacter.animFrame = 87; - } else { - if (_badConsciencePosition) - _mainCharacter.facing = 3; - else - _mainCharacter.facing = 5; - _mainCharacter.animFrame = _characterFrameTable[_mainCharacter.facing]; - } - - updateCharacterAnim(0); - refreshAnimObjectsIfNeed(); -} - -void KyraEngine_v3::hideBadConscience() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::hideBadConscience()"); - if (!_badConscienceShown) - return; - - _badConscienceShown = false; - for (int frame = _badConscienceFrameTable[_badConscienceAnim+8]; frame >= 0; --frame) { - if (frame == 15) - snd_playSoundEffect(0x31, 0xC8); - updateSceneAnim(0x0E, frame); - delay(1*_tickLength, true); - } - - updateSceneAnim(0x0E, -1); - update(); - removeSceneAnimObject(0x0E, 1); - setNextIdleAnimTimer(); -} - -void KyraEngine_v3::showGoodConscience() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::showGoodConscience()"); - - if (_goodConscienceShown) - return; - - _goodConscienceShown = true; - ++_goodConscienceAnim; - _goodConscienceAnim %= 5; - - setNextIdleAnimTimer(); - _goodConsciencePosition = (_mainCharacter.x1 <= 160); - - if (_badConscienceShown) - _goodConsciencePosition = !_badConsciencePosition; - - int anim = _goodConscienceAnim + (_goodConsciencePosition ? 0 : 5); - TalkObject &talkObject = _talkObjectList[87]; - - if (_goodConsciencePosition) - talkObject.x = 290; - else - talkObject.x = 30; - talkObject.y = 30; - - static const char *animFilenames[] = { - "STUFL00.WSA", "STUFL02.WSA", "STUFL04.WSA", "STUFL03.WSA", "STUFL01.WSA", - "STUFR00.WSA", "STUFR02.WSA", "STUFR04.WSA", "STUFR03.WSA", "STUFR01.WSA" - }; - - setupSceneAnimObject(0x0F, 9, 0, 187, -1, -1, -1, -1, 0, 0, 0, -1, animFilenames[anim]); - for (uint i = 0; i <= _goodConscienceFrameTable[_goodConscienceAnim]; ++i) { - if (i == 10) - snd_playSoundEffect(0x7F, 0xC8); - updateSceneAnim(0x0F, i); - delay(2*_tickLength, true); - } - - if (_mainCharacter.animFrame < 50 || _mainCharacter.animFrame > 87) - return; - - if (_mainCharacter.y1 == -1 || (_mainCharacter.x1 != -1 && _mainCharacter.animFrame == 87) || _mainCharacter.animFrame == 87) { - _mainCharacter.animFrame = 87; - } else { - if (_goodConsciencePosition) - _mainCharacter.facing = 3; - else - _mainCharacter.facing = 5; - _mainCharacter.animFrame = _characterFrameTable[_mainCharacter.facing]; - } - - updateCharacterAnim(0); - refreshAnimObjectsIfNeed(); -} - -void KyraEngine_v3::hideGoodConscience() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::hideGoodConscience()"); - if (!_goodConscienceShown) - return; - - _goodConscienceShown = false; - for (int frame = _goodConscienceFrameTable[_goodConscienceAnim+5]; frame >= 0; --frame) { - if (frame == 17) - snd_playSoundEffect(0x31, 0xC8); - updateSceneAnim(0x0F, frame); - delay(1*_tickLength, true); - } - - updateSceneAnim(0x0F, -1); - update(); - removeSceneAnimObject(0x0F, 1); - setNextIdleAnimTimer(); -} - -void KyraEngine_v3::runTemporaryScript(const char *filename, int allowSkip, int resetChar, int newShapes, int shapeUnload) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::runTemporaryScript('%s', %d, %d, %d, %d)", filename, allowSkip, resetChar, newShapes, shapeUnload); - memset(&_temporaryScriptData, 0, sizeof(_temporaryScriptData)); - memset(&_temporaryScriptState, 0, sizeof(_temporaryScriptState)); - - if (!_emc->load(filename, &_temporaryScriptData, &_opcodesTemporary)) - error("Couldn't load temporary script '%s'", filename); - - _emc->init(&_temporaryScriptState, &_temporaryScriptData); - _emc->start(&_temporaryScriptState, 0); - - _newShapeFlag = -1; - - if (_newShapeFiledata && newShapes) { - resetNewShapes(_newShapeCount, _newShapeFiledata); - _newShapeFiledata = 0; - _newShapeCount = 0; - } - - while (_emc->isValid(&_temporaryScriptState)) - _emc->run(&_temporaryScriptState); - - uint8 *fileData = 0; - - if (newShapes) - _newShapeFiledata = _res->fileData(_newShapeFilename, 0); - - fileData = _newShapeFiledata; - - if (!fileData) { - _emc->unload(&_temporaryScriptData); - return; - } - - if (newShapes) - _newShapeCount = initNewShapes(fileData); - - processNewShapes(allowSkip, resetChar); - - if (shapeUnload) { - resetNewShapes(_newShapeCount, fileData); - _newShapeCount = 0; - _newShapeFiledata = 0; - } - - _emc->unload(&_temporaryScriptData); -} - -void KyraEngine_v3::eelScript() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::eelScript()"); - if (_chatText) - return; - _screen->hideMouse(); - - if (_inventoryState) - hideInventory(); - removeHandItem(); - - objectChat((const char*)getTableEntry(_cCodeFile, 35), 0, 204, 35); - objectChat((const char*)getTableEntry(_cCodeFile, 40), 0, 204, 40); - - setGameFlag(0xD1); - - snd_playSoundEffect(0x2A, 0xC8); - - setGameFlag(0x171); - - switch (_malcolmShapes-1) { - case 0: - runTemporaryScript("EELS01.EMC", 0, 0, 1, 1); - break; - - case 1: - runTemporaryScript("EELS02.EMC", 0, 0, 1, 1); - break; - - case 2: - runTemporaryScript("EELS03.EMC", 0, 0, 1, 1); - break; - - case 3: - runTemporaryScript("EELS04.EMC", 0, 0, 1, 1); - break; - - default: - resetGameFlag(0x171); - runTemporaryScript("EELS00.EMC", 0, 0, 1, 1); - break; - } - - changeChapter(2, 29, 0, 4); - _screen->showMouse(); -} - -int KyraEngine_v3::initNewShapes(uint8 *filedata) { - debugC(9, kDebugLevelAnimator, "KyraEngine_v3::initNewShapes(%p)", (const void*)filedata); - const int lastEntry = MIN(_newShapeLastEntry, 41); - for (int i = 0; i < lastEntry; ++i) - _gameShapes[9+i] = _screen->getPtrToShape(filedata, i); - return lastEntry; -} - -void KyraEngine_v3::processNewShapes(int allowSkip, int resetChar) { - debugC(9, kDebugLevelAnimator, "KyraEngine_v3::processNewShapes(%d, %d)", allowSkip, resetChar); - setCharacterAnimDim(_newShapeWidth, _newShapeHeight); - - _emc->init(&_temporaryScriptState, &_temporaryScriptData); - _emc->start(&_temporaryScriptState, 1); - - resetSkipFlag(); - - while (_emc->isValid(&_temporaryScriptState)) { - _temporaryScriptExecBit = false; - while (_emc->isValid(&_temporaryScriptState) && !_temporaryScriptExecBit) - _emc->run(&_temporaryScriptState); - - if (_newShapeAnimFrame < 0) - continue; - - _mainCharacter.animFrame = _newShapeAnimFrame + 9; - updateCharacterAnim(0); - if (_chatText) - updateWithText(); - else - update(); - - uint32 delayEnd = _system->getMillis() + _newShapeDelay * _tickLength; - - while ((!skipFlag() || !allowSkip) && _system->getMillis() < delayEnd) { - if (_chatText) - updateWithText(); - else - update(); - - delay(10); - } - - if (skipFlag()) - resetSkipFlag(); - } - - if (resetChar) { - if (_newShapeFlag >= 0) { - _mainCharacter.animFrame = _newShapeFlag + 9; - updateCharacterAnim(0); - if (_chatText) - updateWithText(); - else - update(); - } - - _mainCharacter.animFrame = _characterFrameTable[_mainCharacter.facing]; - updateCharacterAnim(0); - } - - _newShapeFlag = -1; - resetCharacterAnimDim(); -} - -void KyraEngine_v3::resetNewShapes(int count, uint8 *filedata) { - debugC(9, kDebugLevelAnimator, "KyraEngine_v3::resetNewShapes(%d, %p)", count, (const void*)filedata); - for (int i = 0; i < count; ++i) - _gameShapes[9+i] = 0; - delete [] filedata; - setNextIdleAnimTimer(); -} - -} // end of namespace Kyra - diff --git a/engines/kyra/staticres.cpp b/engines/kyra/staticres.cpp index dca9342def..6f9d005288 100644 --- a/engines/kyra/staticres.cpp +++ b/engines/kyra/staticres.cpp @@ -28,12 +28,12 @@ #include "common/md5.h" #include "kyra/kyra.h" #include "kyra/kyra_v1.h" -#include "kyra/kyra_v2.h" -#include "kyra/kyra_v3.h" +#include "kyra/kyra_hof.h" +#include "kyra/kyra_mr.h" #include "kyra/screen.h" #include "kyra/screen_v1.h" -#include "kyra/screen_v2.h" -#include "kyra/screen_v3.h" +#include "kyra/screen_hof.h" +#include "kyra/screen_mr.h" #include "kyra/resource.h" #include "kyra/gui_v1.h" #include "kyra/gui_v2.h" @@ -1179,7 +1179,7 @@ void KyraEngine_v1::loadMainScreen(int page) { _screen->copyRegion(0, 0, 0, 0, 320, 200, page, 0); } -void KyraEngine_v2::initStaticResource() { +void KyraEngine_HoF::initStaticResource() { int tmpSize = 0; _sequencePakList = _staticres->loadStrings(k2SeqplayPakFiles, _sequencePakListSize); @@ -1252,37 +1252,37 @@ void KyraEngine_v2::initStaticResource() { _sequences = _staticres->loadHofSequenceData(k2SeqplaySeqData, tmpSize); static const SeqProc hofSequenceCallbacks[] = { 0, - &KyraEngine_v2::seq_introWestwood, - &KyraEngine_v2::seq_introTitle, &KyraEngine_v2::seq_introOverview, - &KyraEngine_v2::seq_introLibrary, &KyraEngine_v2::seq_introHand, - &KyraEngine_v2::seq_introPoint, &KyraEngine_v2::seq_introZanfaun, - &KyraEngine_v2::seq_finaleFunters, &KyraEngine_v2::seq_finaleFerb, - &KyraEngine_v2::seq_finaleFish, &KyraEngine_v2::seq_finaleFheep, - &KyraEngine_v2::seq_finaleFarmer, &KyraEngine_v2::seq_finaleFuards, - &KyraEngine_v2::seq_finaleFirates, &KyraEngine_v2::seq_finaleFrash + &KyraEngine_HoF::seq_introWestwood, + &KyraEngine_HoF::seq_introTitle, &KyraEngine_HoF::seq_introOverview, + &KyraEngine_HoF::seq_introLibrary, &KyraEngine_HoF::seq_introHand, + &KyraEngine_HoF::seq_introPoint, &KyraEngine_HoF::seq_introZanfaun, + &KyraEngine_HoF::seq_finaleFunters, &KyraEngine_HoF::seq_finaleFerb, + &KyraEngine_HoF::seq_finaleFish, &KyraEngine_HoF::seq_finaleFheep, + &KyraEngine_HoF::seq_finaleFarmer, &KyraEngine_HoF::seq_finaleFuards, + &KyraEngine_HoF::seq_finaleFirates, &KyraEngine_HoF::seq_finaleFrash }; static const SeqProc hofNestedSequenceCallbacks[] = { - &KyraEngine_v2::seq_finaleFiggle, &KyraEngine_v2::seq_introOver1, - &KyraEngine_v2::seq_introOver2, &KyraEngine_v2::seq_introForest, - &KyraEngine_v2::seq_introDragon, &KyraEngine_v2::seq_introDarm, - &KyraEngine_v2::seq_introLibrary2, &KyraEngine_v2::seq_introLibrary2, - &KyraEngine_v2::seq_introMarco, &KyraEngine_v2::seq_introHand1a, - &KyraEngine_v2::seq_introHand1b, &KyraEngine_v2::seq_introHand1c, - &KyraEngine_v2::seq_introHand2, &KyraEngine_v2::seq_introHand3, 0 + &KyraEngine_HoF::seq_finaleFiggle, &KyraEngine_HoF::seq_introOver1, + &KyraEngine_HoF::seq_introOver2, &KyraEngine_HoF::seq_introForest, + &KyraEngine_HoF::seq_introDragon, &KyraEngine_HoF::seq_introDarm, + &KyraEngine_HoF::seq_introLibrary2, &KyraEngine_HoF::seq_introLibrary2, + &KyraEngine_HoF::seq_introMarco, &KyraEngine_HoF::seq_introHand1a, + &KyraEngine_HoF::seq_introHand1b, &KyraEngine_HoF::seq_introHand1c, + &KyraEngine_HoF::seq_introHand2, &KyraEngine_HoF::seq_introHand3, 0 }; static const SeqProc hofDemoSequenceCallbacks[] = { - &KyraEngine_v2::seq_demoVirgin, &KyraEngine_v2::seq_demoWestwood, - &KyraEngine_v2::seq_demoTitle, &KyraEngine_v2::seq_demoHill, - &KyraEngine_v2::seq_demoOuthome, &KyraEngine_v2::seq_demoWharf, - &KyraEngine_v2::seq_demoDinob, &KyraEngine_v2::seq_demoFisher, 0 + &KyraEngine_HoF::seq_demoVirgin, &KyraEngine_HoF::seq_demoWestwood, + &KyraEngine_HoF::seq_demoTitle, &KyraEngine_HoF::seq_demoHill, + &KyraEngine_HoF::seq_demoOuthome, &KyraEngine_HoF::seq_demoWharf, + &KyraEngine_HoF::seq_demoDinob, &KyraEngine_HoF::seq_demoFisher, 0 }; static const SeqProc hofDemoNestedSequenceCallbacks[] = { - &KyraEngine_v2::seq_demoWharf2, &KyraEngine_v2::seq_demoDinob2, - &KyraEngine_v2::seq_demoWater, &KyraEngine_v2::seq_demoBail, - &KyraEngine_v2::seq_demoDig, 0 + &KyraEngine_HoF::seq_demoWharf2, &KyraEngine_HoF::seq_demoDinob2, + &KyraEngine_HoF::seq_demoWater, &KyraEngine_HoF::seq_demoBail, + &KyraEngine_HoF::seq_demoDig, 0 }; _callbackS = (_flags.isDemo && !_flags.isTalkie) ? hofDemoSequenceCallbacks : hofSequenceCallbacks; @@ -1305,7 +1305,7 @@ const ScreenDim Screen_v1::_screenDimTable[] = { const int Screen_v1::_screenDimTableCount = ARRAYSIZE(Screen_v1::_screenDimTable); -const ScreenDim Screen_v2::_screenDimTable[] = { +const ScreenDim Screen_HoF::_screenDimTable[] = { { 0x00, 0x00, 0x28, 0xC8, 0xC7, 0xCF, 0x00, 0x00 }, { 0x08, 0x48, 0x18, 0x38, 0xC7, 0xCF, 0x00, 0x00 }, { 0x00, 0x00, 0x28, 0x90, 0xC7, 0xCF, 0x00, 0x00 }, @@ -1320,16 +1320,16 @@ const ScreenDim Screen_v2::_screenDimTable[] = { { 0x0A, 0x96, 0x14, 0x30, 0x19, 0xF0, 0x00, 0x00 } // menu, just present for current menu code }; -const int Screen_v2::_screenDimTableCount = ARRAYSIZE(Screen_v2::_screenDimTable); +const int Screen_HoF::_screenDimTableCount = ARRAYSIZE(Screen_HoF::_screenDimTable); -const ScreenDim Screen_v3::_screenDimTable[] = { +const ScreenDim Screen_MR::_screenDimTable[] = { { 0x00, 0x00, 0x28, 0xC8, 0xFF, 0xF0, 0x00, 0x00 }, { 0x08, 0x48, 0x18, 0x38, 0xFF, 0xF0, 0x00, 0x00 }, { 0x00, 0x00, 0x28, 0xBC, 0xFF, 0xF0, 0x00, 0x00 }, { 0x0A, 0x96, 0x14, 0x30, 0x19, 0xF0, 0x00, 0x00 } }; -const int Screen_v3::_screenDimTableCount = ARRAYSIZE(Screen_v3::_screenDimTable); +const int Screen_MR::_screenDimTableCount = ARRAYSIZE(Screen_MR::_screenDimTable); const int8 KyraEngine::_addXPosTable[] = { 4, 4, 0, -4, -4, -4, 0, 4 @@ -1510,7 +1510,7 @@ const int KyraEngine_v1::_dosTrackMapSize = ARRAYSIZE(KyraEngine_v1::_dosTrackMa // Kyra 2 and 3 main menu -const char *KyraEngine_v3::_mainMenuStrings[] = { +const char *KyraEngine_MR::_mainMenuStrings[] = { "Start a new game", "Introduction", "Load a game", @@ -1528,9 +1528,9 @@ const char *KyraEngine_v3::_mainMenuStrings[] = { // kyra 2 static res -const uint8 KyraEngine_v2::_seqTextColorPresets[] = { 0x01, 0x01, 0x00, 0x3f, 0x3f, 0x3f }; +const uint8 KyraEngine_HoF::_seqTextColorPresets[] = { 0x01, 0x01, 0x00, 0x3f, 0x3f, 0x3f }; -const char *KyraEngine_v2::_languageExtension[] = { +const char *KyraEngine_HoF::_languageExtension[] = { "ENG", "FRE", "GER",/*, @@ -1539,7 +1539,7 @@ const char *KyraEngine_v2::_languageExtension[] = { "JPN" }; -const char *KyraEngine_v2::_scriptLangExt[] = { +const char *KyraEngine_HoF::_scriptLangExt[] = { "EMC", "FMC", "GMC",/*, @@ -1548,19 +1548,19 @@ const char *KyraEngine_v2::_scriptLangExt[] = { "JMC" }; -const int KyraEngine_v2::_characterFrameTable[] = { +const int KyraEngine_HoF::_characterFrameTable[] = { 0x19, 0x09, 0x09, 0x12, 0x12, 0x12, 0x09, 0x09 }; -const int KyraEngine_v2::_inventoryX[] = { +const int KyraEngine_HoF::_inventoryX[] = { 0x4F, 0x63, 0x77, 0x8B, 0x9F, 0x4F, 0x63, 0x77, 0x8B, 0x9F }; -const int KyraEngine_v2::_inventoryY[] = { +const int KyraEngine_HoF::_inventoryY[] = { 0x95, 0x95, 0x95, 0x95, 0x95, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA }; -const byte KyraEngine_v2::_itemStringMap[] = { +const byte KyraEngine_HoF::_itemStringMap[] = { 2, 2, 0, 0, 2, 2, 2, 0, 2, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, @@ -1585,9 +1585,9 @@ const byte KyraEngine_v2::_itemStringMap[] = { 0, 2, 0, 0, 0, 0, 0, 0 }; -const int KyraEngine_v2::_itemStringMapSize = ARRAYSIZE(KyraEngine_v2::_itemStringMap); +const int KyraEngine_HoF::_itemStringMapSize = ARRAYSIZE(KyraEngine_HoF::_itemStringMap); -const int8 KyraEngine_v2::_dosTrackMap[] = { +const int8 KyraEngine_HoF::_dosTrackMap[] = { -1, 0, -1, 1, 9, 6, 5, 4, 8, 3, -2, 0, -2, 0, 2, 3, -2, 0, -2, 0, -2, 0, -2, 0, @@ -1612,9 +1612,9 @@ const int8 KyraEngine_v2::_dosTrackMap[] = { 4, 3, 4, 4, 4, 5, 4, 6 }; -const int KyraEngine_v2::_dosTrackMapSize = ARRAYSIZE(KyraEngine_v2::_dosTrackMap); +const int KyraEngine_HoF::_dosTrackMapSize = ARRAYSIZE(KyraEngine_HoF::_dosTrackMap); -void KyraEngine_v2::initInventoryButtonList() { +void KyraEngine_HoF::initInventoryButtonList() { delete [] _inventoryButtons; _inventoryButtons = new Button[15]; @@ -1624,18 +1624,18 @@ void KyraEngine_v2::initInventoryButtonList() { _inventoryButtons[0].buttonCallback = BUTTON_FUNCTOR(GUI_v2, _gui, &GUI_v2::optionsButton); GUI_V2_BUTTON(_inventoryButtons[1], 0x2, 0x00, 0, 1, 1, 1, 0x4487, 0, 0x104, 0x90, 0x3C, 0x2C, 0xC7, 0xCF, 0xC7, 0xCF, 0xC7, 0xCF, 0); - _inventoryButtons[1].buttonCallback = BUTTON_FUNCTOR(KyraEngine_v2, this, &KyraEngine_v2::cauldronButton); + _inventoryButtons[1].buttonCallback = BUTTON_FUNCTOR(KyraEngine_HoF, this, &KyraEngine_HoF::cauldronButton); GUI_V2_BUTTON(_inventoryButtons[2], 0x5, 0x00, 0, 1, 1, 1, 0x4487, 0, 0x0FA, 0x90, 0x0A, 0x2C, 0xC7, 0xCF, 0xC7, 0xCF, 0xC7, 0xCF, 0); - _inventoryButtons[2].buttonCallback = BUTTON_FUNCTOR(KyraEngine_v2, this, &KyraEngine_v2::cauldronClearButton); + _inventoryButtons[2].buttonCallback = BUTTON_FUNCTOR(KyraEngine_HoF, this, &KyraEngine_HoF::cauldronClearButton); GUI_V2_BUTTON(_inventoryButtons[3], 0x3, 0x00, 0, 1, 1, 1, 0x4487, 0, 0x0CE, 0x90, 0x2C, 0x2C, 0xC7, 0xCF, 0xC7, 0xCF, 0xC7, 0xCF, 0); - _inventoryButtons[3].buttonCallback = BUTTON_FUNCTOR(KyraEngine_v2, this, &KyraEngine_v2::bookButton); + _inventoryButtons[3].buttonCallback = BUTTON_FUNCTOR(KyraEngine_HoF, this, &KyraEngine_HoF::bookButton); GUI_V2_BUTTON(_inventoryButtons[4], 0x4, 0x00, 0, 1, 1, 1, 0x4487, 0, 0x0B6, 0x9D, 0x18, 0x1E, 0xC7, 0xCF, 0xC7, 0xCF, 0xC7, 0xCF, 0); - _inventoryButtons[4].buttonCallback = BUTTON_FUNCTOR(KyraEngine_v2, this, &KyraEngine_v2::scrollInventory); + _inventoryButtons[4].buttonCallback = BUTTON_FUNCTOR(KyraEngine_HoF, this, &KyraEngine_HoF::scrollInventory); - Button::Callback inventoryCallback = BUTTON_FUNCTOR(KyraEngine_v2, this, &KyraEngine_v2::buttonInventory); + Button::Callback inventoryCallback = BUTTON_FUNCTOR(KyraEngine_HoF, this, &KyraEngine_HoF::buttonInventory); GUI_V2_BUTTON(_inventoryButtons[5], 0x6, 0x00, 0, 0, 0, 0, 0x1100, 0, 0x04D, 0x92, 0x13, 0x15, 0xC7, 0xCF, 0xC7, 0xCF, 0xC7, 0xCF, 0); GUI_V2_BUTTON(_inventoryButtons[6], 0x7, 0x00, 0, 0, 0, 0, 0x1100, 0, 0x061, 0x92, 0x13, 0x15, 0xC7, 0xCF, 0xC7, 0xCF, 0xC7, 0xCF, 0); GUI_V2_BUTTON(_inventoryButtons[7], 0x8, 0x00, 0, 0, 0, 0, 0x1100, 0, 0x075, 0x92, 0x13, 0x15, 0xC7, 0xCF, 0xC7, 0xCF, 0xC7, 0xCF, 0); @@ -1831,7 +1831,7 @@ const int GUI_v2::_sliderBarsPosition[] = { 0x92, 0x1F, 0x92, 0x30, 0x92, 0x41, 0x92, 0x52 }; -const uint16 KyraEngine_v2::_itemMagicTable[] = { +const uint16 KyraEngine_HoF::_itemMagicTable[] = { 0x0D, 0x0A, 0x0B, 0, 0x0D, 0x0B, 0x0A, 0, 0x0D, 0x38, 0x37, 0, @@ -1863,17 +1863,17 @@ const uint16 KyraEngine_v2::_itemMagicTable[] = { 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF }; -const int KyraEngine_v2::_bookPageYOffset[] = { +const int KyraEngine_HoF::_bookPageYOffset[] = { 0, 0, 2, 2, 0, 0, 2, 2, 0, 0, 2, 2 }; -const byte KyraEngine_v2::_bookTextColorMap[] = { +const byte KyraEngine_HoF::_bookTextColorMap[] = { 0x00, 0xC7, 0xCF, 0x00 }; -const int16 KyraEngine_v2::_cauldronProtectedItems[] = { +const int16 KyraEngine_HoF::_cauldronProtectedItems[] = { 0x07, 0x0D, 0x47, 0x48, 0x29, 0x1A, 0x1C, 0x6D, 0x4D, 0x3A, 0x0E, 0x0F, @@ -1884,7 +1884,7 @@ const int16 KyraEngine_v2::_cauldronProtectedItems[] = { 0x8A, 0x79, 0x61, -1 }; -const int16 KyraEngine_v2::_cauldronBowlTable[] = { +const int16 KyraEngine_HoF::_cauldronBowlTable[] = { 0x0027, 0x0029, 0x0028, 0x0029, 0x0033, 0x0029, @@ -1897,7 +1897,7 @@ const int16 KyraEngine_v2::_cauldronBowlTable[] = { -1, -1 }; -const int16 KyraEngine_v2::_cauldronMagicTable[] = { +const int16 KyraEngine_HoF::_cauldronMagicTable[] = { 0x0, 0x16, 0x2, 0x1A, 0x7, 0xA4, 0x5, 0x4D, 0x1, 0xA5, 0x3, 0xA6, @@ -1906,7 +1906,7 @@ const int16 KyraEngine_v2::_cauldronMagicTable[] = { 0x9, 0xAC, -1, -1 }; -const int16 KyraEngine_v2::_cauldronMagicTableScene77[] = { +const int16 KyraEngine_HoF::_cauldronMagicTableScene77[] = { 0x0, 0x16, 0x2, 0x1A, 0x7, 0xAB, 0x5, 0x4D, 0x1, 0xAE, 0x3, 0xAF, @@ -1915,18 +1915,18 @@ const int16 KyraEngine_v2::_cauldronMagicTableScene77[] = { 0x9, 0xAC, -1, -1 }; -const uint8 KyraEngine_v2::_cauldronStateTable[] = { +const uint8 KyraEngine_HoF::_cauldronStateTable[] = { 3, 1, 3, 1, 1, 4, 4, 2, 3, 1, 1, 3, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }; -const int16 KyraEngine_v2::_flaskTable[] = { +const int16 KyraEngine_HoF::_flaskTable[] = { 0x19, 0x14, 0x15, 0x16, 0x17, 0x18, 0x34, 0x1B, 0x39, 0x1A, 0x3A, 0x4D, 0x72, -1 }; -const uint8 KyraEngine_v2::_rainbowRoomData[] = { +const uint8 KyraEngine_HoF::_rainbowRoomData[] = { 0x02, 0xA9, 0x9E, 0x75, 0x73, 0x17, 0x00, 0xA0, 0x08, 0x01, 0x19, 0x9F, 0x66, 0x05, 0x22, 0x7D, 0x20, 0x25, 0x1D, 0x64, 0xA0, 0x78, 0x85, 0x3B, @@ -1940,7 +1940,7 @@ const uint8 KyraEngine_v2::_rainbowRoomData[] = { // kyra 3 static res -const char *KyraEngine_v3::_soundList[] = { +const char *KyraEngine_MR::_soundList[] = { "ARREST1.AUD", "BATH1.AUD", "OCEAN1.AUD", @@ -1985,9 +1985,9 @@ const char *KyraEngine_v3::_soundList[] = { "SQUIRL1.AUD" }; -const int KyraEngine_v3::_soundListSize = ARRAYSIZE(KyraEngine_v3::_soundList); +const int KyraEngine_MR::_soundListSize = ARRAYSIZE(KyraEngine_MR::_soundList); -const char *KyraEngine_v3::_languageExtension[] = { +const char *KyraEngine_MR::_languageExtension[] = { "TRE", "TRF", "TRG"/*, @@ -1995,9 +1995,9 @@ const char *KyraEngine_v3::_languageExtension[] = { "TRS"*/ }; -const int KyraEngine_v3::_languageExtensionSize = ARRAYSIZE(KyraEngine_v3::_languageExtension); +const int KyraEngine_MR::_languageExtensionSize = ARRAYSIZE(KyraEngine_MR::_languageExtension); -const KyraEngine_v3::ShapeDesc KyraEngine_v3::_shapeDescs[] = { +const KyraEngine_MR::ShapeDesc KyraEngine_MR::_shapeDescs[] = { { 57, 91, -31, -82 }, { 57, 91, -31, -82 }, { 57, 91, -31, -82 }, @@ -2012,21 +2012,21 @@ const KyraEngine_v3::ShapeDesc KyraEngine_v3::_shapeDescs[] = { { 57, 91, -31, -82 } }; -const int KyraEngine_v3::_shapeDescsSize = ARRAYSIZE(KyraEngine_v3::_shapeDescs); +const int KyraEngine_MR::_shapeDescsSize = ARRAYSIZE(KyraEngine_MR::_shapeDescs); -const int8 KyraEngine_v3::_updateCharPosXTable[] = { +const int8 KyraEngine_MR::_updateCharPosXTable[] = { 0, 4, 4, 4, 0, -4, -4, -4 }; -const int8 KyraEngine_v3::_updateCharPosYTable[] = { +const int8 KyraEngine_MR::_updateCharPosYTable[] = { -2, -2, 0, 2, 2, 2, 0, -2 }; -const uint8 KyraEngine_v3::_characterFrameTable[] = { +const uint8 KyraEngine_MR::_characterFrameTable[] = { 0x36, 0x35, 0x35, 0x33, 0x32, 0x32, 0x34, 0x34 }; -const uint8 KyraEngine_v3::_sfxFileMap[] = { +const uint8 KyraEngine_MR::_sfxFileMap[] = { 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x99, 0x00, @@ -2105,9 +2105,9 @@ const uint8 KyraEngine_v3::_sfxFileMap[] = { 0x23, 0x00, 0x97, 0x00, 0x73, 0x00 }; -const int KyraEngine_v3::_sfxFileMapSize = ARRAYSIZE(KyraEngine_v3::_sfxFileMap); +const int KyraEngine_MR::_sfxFileMapSize = ARRAYSIZE(KyraEngine_MR::_sfxFileMap); -const char *KyraEngine_v3::_sfxFileList[] = { +const char *KyraEngine_MR::_sfxFileList[] = { "ALARM1", "ARMOIRE1", "ARROW1", @@ -2334,9 +2334,9 @@ const char *KyraEngine_v3::_sfxFileList[] = { "ZIPPER1" }; -const int KyraEngine_v3::_sfxFileListSize = ARRAYSIZE(KyraEngine_v3::_sfxFileList); +const int KyraEngine_MR::_sfxFileListSize = ARRAYSIZE(KyraEngine_MR::_sfxFileList); -const uint8 KyraEngine_v3::_badConscienceFrameTable[] = { +const uint8 KyraEngine_MR::_badConscienceFrameTable[] = { 0x13, 0x13, 0x13, 0x18, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x10, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x18, 0x13, 0x13, 0x13, 0x13, @@ -2344,7 +2344,7 @@ const uint8 KyraEngine_v3::_badConscienceFrameTable[] = { 0x24, 0x24, 0x24, 0x24, 0x24, 0x1D, 0x1D, 0x1D }; -const uint8 KyraEngine_v3::_goodConscienceFrameTable[] = { +const uint8 KyraEngine_MR::_goodConscienceFrameTable[] = { 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, @@ -2352,31 +2352,31 @@ const uint8 KyraEngine_v3::_goodConscienceFrameTable[] = { 0x1E, 0x1E, 0x1E, 0x1E, 0x1E }; -const uint8 KyraEngine_v3::_chapterLowestScene[] = { +const uint8 KyraEngine_MR::_chapterLowestScene[] = { 0x00, 0x00, 0x19, 0x2B, 0x33, 0x3B }; -const uint8 KyraEngine_v3::_vocHighTable[] = { +const uint8 KyraEngine_MR::_vocHighTable[] = { 0x64, 0x76, 0x82, 0x83, 0x92 }; -const uint8 KyraEngine_v3::_inventoryX[] = { +const uint8 KyraEngine_MR::_inventoryX[] = { 0x45, 0x61, 0x7D, 0x99, 0xB5, 0x45, 0x61, 0x7D, 0x99, 0xB5 }; -const uint8 KyraEngine_v3::_inventoryY[] = { +const uint8 KyraEngine_MR::_inventoryY[] = { 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0xB2, 0xB2, 0xB2, 0xB2, 0xB2 }; -const uint8 KyraEngine_v3::_trashItemList[] = { +const uint8 KyraEngine_MR::_trashItemList[] = { 0x1E, 0x1D, 0x1C, 0x1F, 0x0F, 0x05, 0x04, 0x00, 0x03, 0x22, 0x0B, 0x20, 0x21, 0x10, 0x11, 0x3A, 0x39, 0x40, 0x3E, 0x3D, 0x3C, 0x3F, 0xFF }; -const uint8 KyraEngine_v3::_itemMagicTable[] = { +const uint8 KyraEngine_MR::_itemMagicTable[] = { 0x06, 0x05, 0x07, 0xFE, 0x05, 0x06, 0x07, 0xFE, 0x03, 0x00, 0x22, 0xFE, 0x00, 0x03, 0x22, 0xFE, 0x10, 0x00, 0x20, 0x0F, 0x00, 0x10, 0x0F, 0x20, @@ -2384,7 +2384,7 @@ const uint8 KyraEngine_v3::_itemMagicTable[] = { 0xFF, 0xFF, 0xFF, 0xFF }; -const uint8 KyraEngine_v3::_itemStringMap[] = { +const uint8 KyraEngine_MR::_itemStringMap[] = { 1, 0, 2, 0, 2, 2, 0, 0, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 3, 1, @@ -2396,21 +2396,21 @@ const uint8 KyraEngine_v3::_itemStringMap[] = { 0, 0, 0, 0, 2, 0, 0, 2 }; -const uint KyraEngine_v3::_itemStringMapSize = ARRAYSIZE(KyraEngine_v3::_itemStringMap); +const uint KyraEngine_MR::_itemStringMapSize = ARRAYSIZE(KyraEngine_MR::_itemStringMap); -const uint8 KyraEngine_v3::_itemStringPickUp[] = { +const uint8 KyraEngine_MR::_itemStringPickUp[] = { 0x4, 0x7, 0x0, 0xA }; -const uint8 KyraEngine_v3::_itemStringDrop[] = { +const uint8 KyraEngine_MR::_itemStringDrop[] = { 0x5, 0x8, 0x1, 0xB }; -const uint8 KyraEngine_v3::_itemStringInv[] = { +const uint8 KyraEngine_MR::_itemStringInv[] = { 0x6, 0x9, 0x2, 0xC }; -const int8 KyraEngine_v3::_scoreTable[] = { +const int8 KyraEngine_MR::_scoreTable[] = { 10, 8, 5, 9, 10, 10, 7, 8, 9, 9, 8, 8, 7, 8, 5, 9, 6, 10, 7, 8, 5, 9, 6, 6, @@ -2438,22 +2438,22 @@ const int8 KyraEngine_v3::_scoreTable[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; -const int KyraEngine_v3::_scoreTableSize = ARRAYSIZE(KyraEngine_v3::_scoreTable); +const int KyraEngine_MR::_scoreTableSize = ARRAYSIZE(KyraEngine_MR::_scoreTable); -void KyraEngine_v3::initMainButtonList(bool disable) { +void KyraEngine_MR::initMainButtonList(bool disable) { if (!_mainButtonListInitialized) { _mainButtonData = new Button[14]; assert(_mainButtonData); GUI_V3_BUTTON(_mainButtonData[0], 1, 0, 0, 4, 4, 4, 0x4487, 0, 5, 162, 50, 25, 0xFF, 0xF0, 0xFF, 0xF0, 0xFF, 0xF0, 0); GUI_V3_BUTTON(_mainButtonData[1], 2, 0, 0, 1, 1, 1, 0x4487, 0, 245, 156, 69, 33, 0xFF, 0xF0, 0xFF, 0xF0, 0xFF, 0xF0, 0); - _mainButtonData[1].buttonCallback = BUTTON_FUNCTOR(KyraEngine_v3, this, &KyraEngine_v3::buttonMoodChange); + _mainButtonData[1].buttonCallback = BUTTON_FUNCTOR(KyraEngine_MR, this, &KyraEngine_MR::buttonMoodChange); GUI_V3_BUTTON(_mainButtonData[2], 3, 0, 0, 1, 1, 1, 0x4487, 0, 215, 191, 24, 9, 0xFF, 0xF0, 0xFF, 0xF0, 0xFF, 0xF0, 0); - _mainButtonData[2].buttonCallback = BUTTON_FUNCTOR(KyraEngine_v3, this, &KyraEngine_v3::buttonShowScore); + _mainButtonData[2].buttonCallback = BUTTON_FUNCTOR(KyraEngine_MR, this, &KyraEngine_MR::buttonShowScore); GUI_V3_BUTTON(_mainButtonData[3], 4, 0, 0, 1, 1, 1, 0x4487, 0, 215, 155, 25, 36, 0xFF, 0xF0, 0xFF, 0xF0, 0xFF, 0xF0, 0); - _mainButtonData[3].buttonCallback = BUTTON_FUNCTOR(KyraEngine_v3, this, &KyraEngine_v3::buttonJesterStaff); + _mainButtonData[3].buttonCallback = BUTTON_FUNCTOR(KyraEngine_MR, this, &KyraEngine_MR::buttonJesterStaff); - Button::Callback buttonInventoryFunctor = BUTTON_FUNCTOR(KyraEngine_v3, this, &KyraEngine_v3::buttonInventory); + Button::Callback buttonInventoryFunctor = BUTTON_FUNCTOR(KyraEngine_MR, this, &KyraEngine_MR::buttonInventory); for (int i = 0; i < 5; ++i) { GUI_V3_BUTTON(_mainButtonData[i+4], i+5, 0, 0, 0, 0, 0, 0x1100, 0, 67+i*28, 155, 27, 21, 0xFF, 0xF0, 0xFF, 0xF0, 0xFF, 0xF0, 0); _mainButtonData[i+4].buttonCallback = buttonInventoryFunctor; diff --git a/engines/kyra/text_hof.cpp b/engines/kyra/text_hof.cpp new file mode 100644 index 0000000000..43f28f9a00 --- /dev/null +++ b/engines/kyra/text_hof.cpp @@ -0,0 +1,690 @@ +/* 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/text_hof.h" +#include "kyra/kyra_hof.h" +#include "kyra/script_tim.h" +#include "kyra/resource.h" + +#include "common/endian.h" + +namespace Kyra { + +TextDisplayer_v2::TextDisplayer_v2(KyraEngine_HoF *vm, Screen_v2 *screen) + : TextDisplayer(vm, screen), _vm(vm) { +} + +void TextDisplayer_v2::backupTalkTextMessageBkgd(int srcPage, int dstPage) { + _screen->copyRegion(_talkCoords.x, _talkMessageY, 0, 144, _talkCoords.w, _talkMessageH, srcPage, dstPage); +} + +void TextDisplayer_v2::restoreTalkTextMessageBkgd(int srcPage, int dstPage) { + _screen->copyRegion(0, 144, _talkCoords.x, _talkMessageY, _talkCoords.w, _talkMessageH, srcPage, dstPage); +} + +void TextDisplayer_v2::restoreScreen() { + _vm->restorePage3(); + _vm->drawAnimObjects(); + _screen->hideMouse(); + _screen->copyRegion(_talkCoords.x, _talkMessageY, _talkCoords.x, _talkMessageY, _talkCoords.w, _talkMessageH, 2, 0, Screen::CR_NO_P_CHECK); + _screen->showMouse(); + _vm->flagAnimObjsForRefresh(); + _vm->refreshAnimObjects(0); +} + +void TextDisplayer_v2::printCustomCharacterText(const char *text, int x, int y, uint8 c1, int srcPage, int dstPage) { + text = preprocessString(text); + int lineCount = buildMessageSubstrings(text); + int w = getWidestLineWidth(lineCount); + int h = lineCount * 10; + y = MAX(0, y - (lineCount * 10)); + int x1 = 0, x2 = 0; + calcWidestLineBounds(x1, x2, w, x); + + _screen->hideMouse(); + + _talkCoords.x = x1; + _talkCoords.w = w+2; + _talkCoords.y = y; + _talkMessageY = y; + _talkMessageH = h; + + backupTalkTextMessageBkgd(srcPage, dstPage); + int curPageBackUp = _screen->_curPage; + _screen->_curPage = srcPage; + + if (_vm->textEnabled()) { + for (int i = 0; i < lineCount; ++i) { + const char *msg = &_talkSubstrings[i * TALK_SUBSTRING_LEN]; + printText(msg, getCenterStringX(msg, x1, x2), i * 10 + _talkMessageY, c1, 0xCF, 0); + } + } + + _screen->_curPage = curPageBackUp; + _screen->showMouse(); +} + +char *TextDisplayer_v2::preprocessString(const char *str) { + debugC(9, kDebugLevelMain, "TextDisplayer_v2::preprocessString('%s')", str); + + if (str != _talkBuffer) { + assert(strlen(str) < sizeof(_talkBuffer) - 1); + strcpy(_talkBuffer, str); + } + + char *p = _talkBuffer; + while (*p) { + if (*p == '\r') + return _talkBuffer; + ++p; + } + + p = _talkBuffer; + Screen::FontId curFont = _screen->setFont(Screen::FID_8_FNT); + _screen->_charWidth = -2; + int textWidth = _screen->getTextWidth(p); + _screen->_charWidth = 0; + + // longer text strings for German versions + int maxTextWidth = (_vm->language() == 2 ? 240 : 176); + + if (textWidth > maxTextWidth) { + if (textWidth > (maxTextWidth*2)) { + int count = getCharLength(p, textWidth / 3); + int offs = dropCRIntoString(p, count); + p += count + offs; + _screen->_charWidth = -2; + textWidth = _screen->getTextWidth(p); + _screen->_charWidth = 0; + count = getCharLength(p, textWidth / 2); + dropCRIntoString(p, count); + } else { + int count = getCharLength(p, textWidth / 2); + dropCRIntoString(p, count); + } + } + _screen->setFont(curFont); + return _talkBuffer; +} + +void TextDisplayer_v2::calcWidestLineBounds(int &x1, int &x2, int w, int x) { + debugC(9, kDebugLevelMain, "TextDisplayer_v2::calcWidestLineBounds(%d, %d)", w, x); + x1 = x; + x1 -= (w >> 1); + x2 = x1 + w + 1; + + if (x1 + w >= 311) + x1 = 311 - w - 1; + + if (x1 < 8) + x1 = 8; + + x2 = x1 + w + 1; +} + +#pragma mark - + +int KyraEngine_HoF::chatGetType(const char *str) { + str += strlen(str); + --str; + switch (*str) { + case '!': + return 2; + + case ')': + return -1; + + case '?': + return 1; + + default: + return 0; + } +} + +int KyraEngine_HoF::chatCalcDuration(const char *str) { + static const uint8 durationMultiplicator[] = { 16, 14, 12, 10, 8, 8, 7, 6, 5, 4 }; + + int duration = strlen(str); + duration *= _flags.isTalkie ? 8 : durationMultiplicator[(_configTextspeed / 10)]; + return MAX(duration, 120); +} + +void KyraEngine_HoF::objectChat(const char *str, int object, int vocHigh, int vocLow) { + setNextIdleAnimTimer(); + + _chatVocHigh = _chatVocLow = -1; + + objectChatInit(str, object, vocHigh, vocLow); + _chatText = str; + _chatObject = object; + int chatType = chatGetType(str); + if (chatType == -1) { + _chatIsNote = true; + chatType = 0; + } + + if (_mainCharacter.facing > 7) + _mainCharacter.facing = 5; + + static const uint8 talkScriptTable[] = { + 6, 7, 8, + 3, 4, 5, + 3, 4, 5, + 0, 1, 2, + 0, 1, 2, + 0, 1, 2, + 3, 4, 5, + 3, 4, 5 + }; + + assert(_mainCharacter.facing * 3 + chatType < ARRAYSIZE(talkScriptTable)); + int script = talkScriptTable[_mainCharacter.facing * 3 + chatType]; + + static const char *chatScriptFilenames[] = { + "_Z1FSTMT.EMC", + "_Z1FQUES.EMC", + "_Z1FEXCL.EMC", + "_Z1SSTMT.EMC", + "_Z1SQUES.EMC", + "_Z1SEXCL.EMC", + "_Z1BSTMT.EMC", + "_Z1BQUES.EMC", + "_Z1BEXCL.EMC" + }; + + objectChatProcess(chatScriptFilenames[script]); + _chatIsNote = false; + + _text->restoreScreen(); + + _mainCharacter.animFrame = _characterFrameTable[_mainCharacter.facing]; + updateCharacterAnim(0); + + _chatText = 0; + _chatObject = -1; + + setNextIdleAnimTimer(); +} + +void KyraEngine_HoF::objectChatInit(const char *str, int object, int vocHigh, int vocLow) { + str = _text->preprocessString(str); + int lineNum = _text->buildMessageSubstrings(str); + + int yPos = 0, xPos = 0; + + if (!object) { + int scale = getScale(_mainCharacter.x1, _mainCharacter.y1); + yPos = _mainCharacter.y1 - ((_mainCharacter.height * scale) >> 8) - 8; + xPos = _mainCharacter.x1; + } else { + yPos = _talkObjectList[object].y; + xPos = _talkObjectList[object].x; + } + + yPos -= lineNum * 10; + yPos = MAX(yPos, 0); + _text->_talkMessageY = yPos; + _text->_talkMessageH = lineNum*10; + + int width = _text->getWidestLineWidth(lineNum); + _text->calcWidestLineBounds(xPos, yPos, width, xPos); + _text->_talkCoords.x = xPos; + _text->_talkCoords.w = width + 2; + + restorePage3(); + _text->backupTalkTextMessageBkgd(2, 2); + + _screen->hideMouse(); + + if (textEnabled()) { + objectChatPrintText(str, object); + _chatEndTime = _system->getMillis() + chatCalcDuration(str) * _tickLength; + } else { + _chatEndTime = _system->getMillis(); + } + + if (speechEnabled()) { + _chatVocHigh = vocHigh; + _chatVocLow = vocLow; + } else { + _chatVocHigh = _chatVocLow = -1; + } + + _screen->showMouse(); +} + +void KyraEngine_HoF::objectChatPrintText(const char *str, int object) { + int c1 = _talkObjectList[object].color; + str = _text->preprocessString(str); + int lineNum = _text->buildMessageSubstrings(str); + int maxWidth = _text->getWidestLineWidth(lineNum); + int x = (object == 0) ? _mainCharacter.x1 : _talkObjectList[object].x; + int cX1 = 0, cX2 = 0; + _text->calcWidestLineBounds(cX1, cX2, maxWidth, x); + + for (int i = 0; i < lineNum; ++i) { + str = &_text->_talkSubstrings[i*_text->maxSubstringLen()]; + + int y = _text->_talkMessageY + i * 10; + x = _text->getCenterStringX(str, cX1, cX2); + + _text->printText(str, x, y, c1, 0xCF, 0); + } +} + +void KyraEngine_HoF::objectChatProcess(const char *script) { + memset(&_chatScriptData, 0, sizeof(_chatScriptData)); + memset(&_chatScriptState, 0, sizeof(_chatScriptState)); + + _emc->load(script, &_chatScriptData, &_opcodesTemporary); + _emc->init(&_chatScriptState, &_chatScriptData); + _emc->start(&_chatScriptState, 0); + while (_emc->isValid(&_chatScriptState)) + _emc->run(&_chatScriptState); + + _newShapeFilename[2] = _loadedZTable + '0'; + uint8 *shapeBuffer = _res->fileData(_newShapeFilename, 0); + if (shapeBuffer) { + int shapeCount = initNewShapes(shapeBuffer); + + if (_chatVocHigh >= 0) { + playVoice(_chatVocHigh, _chatVocLow); + _chatVocHigh = _chatVocLow = -1; + } + + objectChatWaitToFinish(); + + resetNewShapes(shapeCount, shapeBuffer); + } else { + warning("couldn't load file '%s'", _newShapeFilename); + } + + _emc->unload(&_chatScriptData); +} + +void KyraEngine_HoF::objectChatWaitToFinish() { + int charAnimFrame = _mainCharacter.animFrame; + setCharacterAnimDim(_newShapeWidth, _newShapeHeight); + + _emc->init(&_chatScriptState, &_chatScriptData); + _emc->start(&_chatScriptState, 1); + + bool running = true; + const uint32 endTime = _chatEndTime; + resetSkipFlag(); + + while (running && !_quitFlag) { + if (!_emc->isValid(&_chatScriptState)) + _emc->start(&_chatScriptState, 1); + + _temporaryScriptExecBit = false; + while (!_temporaryScriptExecBit && _emc->isValid(&_chatScriptState)) + _emc->run(&_chatScriptState); + + int curFrame = _newShapeAnimFrame; + uint32 delayTime = _newShapeDelay; + + if (!_chatIsNote) + _mainCharacter.animFrame = 33 + curFrame; + + updateCharacterAnim(0); + + uint32 nextFrame = _system->getMillis() + delayTime * _tickLength; + + while (_system->getMillis() < nextFrame && !_quitFlag) { + updateWithText(); + + const uint32 curTime = _system->getMillis(); + if ((textEnabled() && curTime > endTime) || (speechEnabled() && !textEnabled() && !snd_voiceIsPlaying()) || skipFlag()) { + resetSkipFlag(); + nextFrame = curTime; + running = false; + } + + delay(10); + } + } + + _mainCharacter.animFrame = charAnimFrame; + updateCharacterAnim(0); + resetCharacterAnimDim(); +} + +void KyraEngine_HoF::startDialogue(int dlgIndex) { + updateDlgBuffer(); + int csEntry, vocH, unused1, unused2; + loadDlgHeader(csEntry, vocH, unused1, unused2); + int s = _conversationState[dlgIndex][csEntry]; + uint8 bufferIndex = 8; + + if (s == -1) { + bufferIndex += (dlgIndex * 6); + _conversationState[dlgIndex][csEntry] = 0; + } else if (!s || s == 2) { + bufferIndex += (dlgIndex * 6 + 2); + _conversationState[dlgIndex][csEntry] = 1; + } else { + bufferIndex += (dlgIndex * 6 + 4); + _conversationState[dlgIndex][csEntry] = 2; + } + + int offs = READ_LE_UINT16(_dlgBuffer + bufferIndex); + processDialogue(offs, vocH, csEntry); +} + +void KyraEngine_HoF::zanthSceneStartupChat() { + int lowest = _flags.isTalkie ? 6 : 5; + int tableIndex = _mainCharacter.sceneId - READ_LE_UINT16(&_ingameTalkObjIndex[lowest + _newChapterFile]); + if (queryGameFlag(0x159) || _newSceneDlgState[tableIndex]) + return; + + int csEntry, vocH, scIndex1, scIndex2; + updateDlgBuffer(); + loadDlgHeader(csEntry, vocH, scIndex1, scIndex2); + + uint8 bufferIndex = 8 + scIndex1 * 6 + scIndex2 * 4 + tableIndex * 2; + int offs = READ_LE_UINT16(_dlgBuffer + bufferIndex); + processDialogue(offs, vocH, csEntry); + + _newSceneDlgState[tableIndex] = 1; +} + +void KyraEngine_HoF::zanthRandomIdleChat() { + int lowest = _flags.isTalkie ? 6 : 5; + int tableIndex = (_mainCharacter.sceneId - READ_LE_UINT16(&_ingameTalkObjIndex[lowest + _newChapterFile])) << 2; + if (queryGameFlag(0x164)) + return; + + int csEntry, vocH, scIndex1, unused; + updateDlgBuffer(); + loadDlgHeader(csEntry, vocH, scIndex1, unused); + + if (_chatAltFlag) { + _chatAltFlag = 0; + tableIndex += 2; + } else { + _chatAltFlag = 1; + } + + uint8 bufferIndex = 8 + scIndex1 * 6 + tableIndex; + int offs = READ_LE_UINT16(_dlgBuffer + bufferIndex); + processDialogue(offs, vocH, csEntry); +} + +void KyraEngine_HoF::updateDlgBuffer() { + static const char suffixTalkie[] = "EFG"; + static const char suffixTowns[] = "G J"; + + if (_currentChapter == _npcTalkChpIndex && _mainCharacter.dlgIndex == _npcTalkDlgIndex) + return; + + _npcTalkChpIndex = _currentChapter; + _npcTalkDlgIndex = _mainCharacter.dlgIndex; + + char filename[13]; + snprintf(filename, 13, "CH%.02d-S%.02d.DLG", _currentChapter, _npcTalkDlgIndex); + + const char *suffix = _flags.isTalkie ? suffixTalkie : suffixTowns; + if (_flags.platform != Common::kPlatformPC || _flags.isTalkie) + filename[11] = suffix[_lang]; + + if (_dlgBuffer) + delete [] _dlgBuffer; + + _dlgBuffer = _res->fileData(filename, 0); +} + +void KyraEngine_HoF::loadDlgHeader(int &csEntry, int &vocH, int &scIndex1, int &scIndex2) { + csEntry = READ_LE_UINT16(_dlgBuffer); + vocH = READ_LE_UINT16(_dlgBuffer + 2); + scIndex1 = READ_LE_UINT16(_dlgBuffer + 4); + scIndex2 = READ_LE_UINT16(_dlgBuffer + 6); +} + +void KyraEngine_HoF::processDialogue(int dlgOffset, int vocH, int csEntry) { + int activeTimSequence = -1; + int nextTimSequence = -1; + int cmd = 0; + int vocHi = -1; + int vocLo = -1; + bool loop = true; + int offs = dlgOffset; + + _screen->hideMouse(); + + while (loop) { + cmd = READ_LE_UINT16(_dlgBuffer + offs); + offs += 2; + + nextTimSequence = READ_LE_UINT16(&_ingameTalkObjIndex[cmd]); + + if (nextTimSequence == 10) { + if (queryGameFlag(0x3e)) + nextTimSequence = 14; + if (queryGameFlag(0x3f)) + nextTimSequence = 15; + if (queryGameFlag(0x40)) + nextTimSequence = 16; + } + + if (nextTimSequence == 27 && _mainCharacter.sceneId == 34) + nextTimSequence = 41; + + if (queryGameFlag(0x72)) { + if (nextTimSequence == 18) + nextTimSequence = 43; + else if (nextTimSequence == 19) + nextTimSequence = 44; + } + + if (_mainCharacter.x1 > 160) { + if (nextTimSequence == 4) + nextTimSequence = 46; + else if (nextTimSequence == 5) + nextTimSequence = 47; + } + + if (cmd == 10) { + loop = false; + + } else if (cmd == 4) { + csEntry = READ_LE_UINT16(_dlgBuffer + offs); + setNewDlgIndex(csEntry); + offs += 2; + + } else { + if (!_flags.isTalkie || cmd == 11) { + int len = READ_LE_UINT16(_dlgBuffer + offs); + offs += 2; + if (_flags.isTalkie) { + vocLo = READ_LE_UINT16(_dlgBuffer + offs); + offs += 2; + } + memcpy(_unkBuf500Bytes, _dlgBuffer + offs, len); + _unkBuf500Bytes[len] = 0; + offs += len; + if (_flags.isTalkie) + continue; + + } else if (_flags.isTalkie) { + int len = READ_LE_UINT16(_dlgBuffer + offs); + offs += 2; + static const int irnv[] = { 91, 105, 110, 114, 118 }; + vocHi = irnv[vocH - 1] + csEntry; + vocLo = READ_LE_UINT16(_dlgBuffer + offs); + offs += 2; + memcpy(_unkBuf500Bytes, _dlgBuffer + offs, len); + _unkBuf500Bytes[len] = 0; + offs += len; + } + + if (_unkBuf500Bytes[0]) { + if ((!_flags.isTalkie && cmd == 11) || (_flags.isTalkie && cmd == 12)) { + if (activeTimSequence > -1) { + deinitTalkObject(activeTimSequence); + activeTimSequence = -1; + } + objectChat((const char*) _unkBuf500Bytes, 0, vocHi, vocLo); + } else { + if (activeTimSequence != nextTimSequence ) { + if (activeTimSequence > -1) { + deinitTalkObject(activeTimSequence); + activeTimSequence = -1; + } + initTalkObject(nextTimSequence); + activeTimSequence = nextTimSequence; + } + npcChatSequence((const char *)_unkBuf500Bytes, nextTimSequence, vocHi, vocLo); + } + } + } + } + + if (activeTimSequence > -1) + deinitTalkObject(activeTimSequence); + + _screen->showMouse(); +} + +void KyraEngine_HoF::initTalkObject(int index) { + TalkObject &object = _talkObjectList[index]; + + char STAFilename[13]; + char ENDFilename[13]; + + strcpy(STAFilename, object.filename); + strcpy(_TLKFilename, object.filename); + strcpy(ENDFilename, object.filename); + + strcat(STAFilename + 4, "_STA.TIM"); + strcat(_TLKFilename + 4, "_TLK.TIM"); + strcat(ENDFilename + 4, "_END.TIM"); + + _currentTalkSections.STATim = _tim->load(STAFilename, &_timOpcodes); + _currentTalkSections.TLKTim = _tim->load(_TLKFilename, &_timOpcodes); + _currentTalkSections.ENDTim = _tim->load(ENDFilename, &_timOpcodes); + + if (object.scriptId != -1) { + _specialSceneScriptStateBackup[object.scriptId] = _specialSceneScriptState[object.scriptId]; + _specialSceneScriptState[object.scriptId] = 1; + } + + if (_currentTalkSections.STATim) { + _tim->resetFinishedFlag(); + while (!_quitFlag && !_tim->finished()) { + _tim->exec(_currentTalkSections.STATim, false); + if (_chatText) + updateWithText(); + else + update(); + delay(10); + } + } +} + +void KyraEngine_HoF::deinitTalkObject(int index) { + TalkObject &object = _talkObjectList[index]; + + if (_currentTalkSections.ENDTim) { + _tim->resetFinishedFlag(); + while (!_quitFlag && !_tim->finished()) { + _tim->exec(_currentTalkSections.ENDTim, false); + if (_chatText) + updateWithText(); + else + update(); + delay(10); + } + } + + if (object.scriptId != -1) + _specialSceneScriptState[object.scriptId] = _specialSceneScriptStateBackup[object.scriptId]; + + _tim->unload(_currentTalkSections.STATim); + _tim->unload(_currentTalkSections.TLKTim); + _tim->unload(_currentTalkSections.ENDTim); +} + +void KyraEngine_HoF::npcChatSequence(const char *str, int objectId, int vocHigh, int vocLow) { + _chatText = str; + _chatObject = objectId; + objectChatInit(str, objectId, vocHigh, vocLow); + + if (!_currentTalkSections.TLKTim) + _currentTalkSections.TLKTim = _tim->load(_TLKFilename, &_timOpcodes); + + setNextIdleAnimTimer(); + + uint32 ct = chatCalcDuration(str); + uint32 time = _system->getMillis(); + _chatEndTime = time + (3 + ct) * _tickLength; + uint32 chatAnimEndTime = time + (3 + (ct >> 1)) * _tickLength; + + if (_chatVocHigh >= 0) { + playVoice(_chatVocHigh, _chatVocLow); + _chatVocHigh = _chatVocLow = -1; + } + + while (((textEnabled() && _chatEndTime > _system->getMillis()) || (speechEnabled() && snd_voiceIsPlaying())) && !(_quitFlag || skipFlag())) { + if (!speechEnabled() && chatAnimEndTime > _system->getMillis() || speechEnabled() && snd_voiceIsPlaying()) { + _tim->resetFinishedFlag(); + while (!_tim->finished() && !skipFlag() && !_quitFlag) { + if (_currentTalkSections.TLKTim) + _tim->exec(_currentTalkSections.TLKTim, false); + else + _tim->resetFinishedFlag(); + + updateWithText(); + delay(10); + } + + if (_currentTalkSections.TLKTim) + _tim->stopCurFunc(); + } + updateWithText(); + } + + resetSkipFlag(); + + _tim->unload(_currentTalkSections.TLKTim); + + _text->restoreScreen(); + _chatText = 0; + _chatObject = -1; + setNextIdleAnimTimer(); +} + +void KyraEngine_HoF::setNewDlgIndex(int dlgIndex) { + if (dlgIndex == _mainCharacter.dlgIndex) + return; + memset(_newSceneDlgState, 0, 32); + for (int i = 0; i < 19; i++) + memset(_conversationState[i], -1, 14); + _chatAltFlag = false; + _mainCharacter.dlgIndex = dlgIndex; +} + +} // end of namespace Kyra diff --git a/engines/kyra/text_hof.h b/engines/kyra/text_hof.h new file mode 100644 index 0000000000..0b26262f0e --- /dev/null +++ b/engines/kyra/text_hof.h @@ -0,0 +1,56 @@ +/* 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_TEXT_V2_H +#define KYRA_TEXT_V2_H + +#include "kyra/text.h" + +namespace Kyra { + +class Screen_v2; +class KyraEngine_HoF; + +class TextDisplayer_v2 : public TextDisplayer { +friend class KyraEngine_HoF; +public: + TextDisplayer_v2(KyraEngine_HoF *vm, Screen_v2 *screen); + + void backupTalkTextMessageBkgd(int srcPage, int dstPage); + void restoreTalkTextMessageBkgd(int srcPage, int dstPage); + void restoreScreen(); + + void printCustomCharacterText(const char *src, int x, int y, uint8 c1, int srcPage, int dstPage); + + char *preprocessString(const char *str); + void calcWidestLineBounds(int &x1, int &x2, int w, int x); +private: + KyraEngine_HoF *_vm; +}; + +} // end of namespace Kyra + +#endif + diff --git a/engines/kyra/text_mr.cpp b/engines/kyra/text_mr.cpp new file mode 100644 index 0000000000..4f3c350099 --- /dev/null +++ b/engines/kyra/text_mr.cpp @@ -0,0 +1,817 @@ +/* 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/text_mr.h" +#include "kyra/screen_mr.h" +#include "kyra/resource.h" + +namespace Kyra { + +TextDisplayer_MR::TextDisplayer_MR(KyraEngine_MR *vm, Screen_MR *screen) + : TextDisplayer(vm, screen), _vm(vm), _screen(screen) { +} + +char *TextDisplayer_MR::preprocessString(const char *str) { + debugC(9, kDebugLevelMain, "TextDisplayer_MR::preprocessString('%s')", str); + if (_talkBuffer != str) + strncpy(_talkBuffer, str, sizeof(_talkBuffer)); + + char *p = _talkBuffer; + while (*p) { + if (*p++ == '\r') + return _talkBuffer; + } + + p = _talkBuffer; + Screen::FontId curFont = _screen->setFont(Screen::FID_8_FNT); + _screen->_charWidth = -2; + + const int maxTextWidth = (_vm->language() == 0) ? 176 : 240; + int textWidth = _screen->getTextWidth(p); + + if (textWidth > maxTextWidth) { + int count = 0, offs = 0; + if (textWidth > (3*maxTextWidth)) { + count = getCharLength(p, textWidth/4); + offs = dropCRIntoString(p, getCharLength(p, maxTextWidth), count); + p += count + offs; + } + + if (textWidth > (2*maxTextWidth)) { + count = getCharLength(p, textWidth/3); + offs = dropCRIntoString(p, getCharLength(p, maxTextWidth), count); + p += count + offs; + textWidth = _screen->getTextWidth(p); + } + + count = getCharLength(p, textWidth/2); + offs = dropCRIntoString(p, getCharLength(p, maxTextWidth), count); + p += count + offs; + textWidth = _screen->getTextWidth(p); + + if (textWidth > maxTextWidth) { + count = getCharLength(p, textWidth/2); + offs = dropCRIntoString(p, getCharLength(p, maxTextWidth), count); + } + } + + _screen->setFont(curFont); + return _talkBuffer; +} + +int TextDisplayer_MR::dropCRIntoString(char *str, int minOffs, int maxOffs) { + debugC(9, kDebugLevelMain, "TextDisplayer_MR::dropCRIntoString('%s', %d, %d)", str, maxOffs, minOffs); + + int offset = 0; + char *proc = str + minOffs; + + for (int i = minOffs; i < maxOffs; ++i) { + if (*proc == ' ') { + *proc = '\r'; + return offset; + } else if (*proc == '-') { + memmove(proc+1, proc, strlen(proc)+1); + *(++proc) = '\r'; + ++offset; + return offset; + } + + ++offset; + ++proc; + + if (!*proc) + return 0; + } + + offset = 0; + proc = str + minOffs; + for (int i = minOffs; i >= 0; --i) { + if (*proc == ' ') { + *proc = '\r'; + return offset; + } else if (*proc == '-') { + memmove(proc+1, proc, strlen(proc)+1); + *(++proc) = '\r'; + ++offset; + return offset; + } + + --offset; + --proc; + + if (!*proc) + return 0; + } + + *(str + minOffs) = '\r'; + return 0; +} + +void TextDisplayer_MR::printText(const char *str, int x, int y, uint8 c0, uint8 c1, uint8 c2, Screen::FontId font) { + debugC(9, kDebugLevelMain, "TextDisplayer_MR::printText('%s', %d, %d, %d, %d, %d)", str, x, y, c0, c1, c2); + uint8 colorMap[] = { 0, 255, 240, 240 }; + colorMap[3] = c1; + _screen->setTextColor(colorMap, 0, 3); + Screen::FontId curFont = _screen->setFont(font); + _screen->_charWidth = -2; + _screen->printText(str, x, y, c0, c2); + _screen->_charWidth = 0; + _screen->setFont(curFont); +} + +void TextDisplayer_MR::restoreScreen() { + debugC(9, kDebugLevelMain, "TextDisplayer_MR::restoreScreen()"); + _vm->restorePage3(); + _vm->drawAnimObjects(); + _screen->hideMouse(); + _screen->copyRegion(_talkCoords.x, _talkMessageY, _talkCoords.x, _talkMessageY, _talkCoords.w, _talkMessageH, 2, 0, Screen::CR_NO_P_CHECK); + _screen->showMouse(); + _vm->flagAnimObjsForRefresh(); + _vm->refreshAnimObjects(0); +} + +void TextDisplayer_MR::calcWidestLineBounds(int &x1, int &x2, int w, int x) { + debugC(9, kDebugLevelMain, "TextDisplayer_MR::calcWidestLineBounds(%d, %d)", w, x); + x1 = x; + x1 -= (w >> 1); + x2 = x1 + w + 1; + + if (x1 + w >= 311) + x1 = 311 - w - 1; + + if (x1 < 8) + x1 = 8; + + x2 = x1 + w + 1; +} + +#pragma mark - + +int KyraEngine_MR::chatGetType(const char *str) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::chatGetType('%s')", str); + while (*str) + ++str; + --str; + switch (*str) { + case '!': + return 2; + + case ')': + return 3; + + case '?': + return 1; + + case '.': + default: + return 0; + } +} + +int KyraEngine_MR::chatCalcDuration(const char *str) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::chatCalcDuration('%s')", str); + return MAX(120, strlen(str)*6); +} + +void KyraEngine_MR::objectChat(const char *str, int object, int vocHigh, int vocLow) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::objectChat('%s', %d, %d, %d)", str, object, vocHigh, vocLow); + + if (_mainCharacter.animFrame == 87 || _mainCharacter.animFrame == 0xFFFF || _mainCharacter.x1 <= 0 || _mainCharacter.y1 <= 0) + return; + + _chatVocLow = _chatVocHigh = -1; + objectChatInit(str, object, vocHigh, vocLow); + _chatText = str; + _chatObject = object; + int chatType = chatGetType(str); + + if (_mainCharacter.facing > 7) + _mainCharacter.facing = 5; + + static const uint8 talkScriptTable[] = { + 0x10, 0x11, 0x12, 0x13, + 0x0C, 0x0D, 0x0E, 0x0F, + 0x0C, 0x0D, 0x0E, 0x0F, + 0x04, 0x05, 0x06, 0x07, + 0x00, 0x01, 0x02, 0x03, + 0x00, 0x01, 0x02, 0x03, + 0x08, 0x09, 0x0A, 0x0B, + 0x08, 0x09, 0x0A, 0x0B + }; + + static const char *talkFilenameTable[] = { + "MTFL00S.EMC", "MTFL00Q.EMC", "MTFL00E.EMC", "MTFL00T.EMC", + "MTFR00S.EMC", "MTFR00Q.EMC", "MTFR00E.EMC", "MTFR00T.EMC", + "MTL00S.EMC", "MTL00Q.EMC", "MTL00E.EMC", "MTL00T.EMC", + "MTR00S.EMC", "MTR00Q.EMC", "MTR00E.EMC", "MTR00T.EMC", + "MTA00S.EMC", "MTA00Q.EMC", "MTA00Q.EMC", "MTA00T.EMC" + }; + + int chat = talkScriptTable[chatType + _mainCharacter.facing * 4]; + objectChatProcess(talkFilenameTable[chat]); + _text->restoreScreen(); + _mainCharacter.animFrame = _characterFrameTable[_mainCharacter.facing]; + updateCharacterAnim(0); + _chatText = 0; + _chatObject = -1; + setNextIdleAnimTimer(); +} + +void KyraEngine_MR::objectChatInit(const char *str, int object, int vocHigh, int vocLow) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::objectChatInit('%s', %d, %d, %d)", str, object, vocHigh, vocLow); + str = _text->preprocessString(str); + int lineNum = _text->buildMessageSubstrings(str); + + int xPos = 0, yPos = 0; + + if (!object) { + int scale = getScale(_mainCharacter.x1, _mainCharacter.y1); + yPos = _mainCharacter.y1 - ((_mainCharacter.height * scale) >> 8) - 8; + xPos = _mainCharacter.x1; + } else { + yPos = _talkObjectList[object].y; + xPos = _talkObjectList[object].x; + } + + yPos -= lineNum * 10; + yPos = MAX(yPos, 0); + _text->_talkMessageY = yPos; + _text->_talkMessageH = lineNum*10; + + int width = _text->getWidestLineWidth(lineNum); + _text->calcWidestLineBounds(xPos, yPos, width, xPos); + _text->_talkCoords.x = xPos; + _text->_talkCoords.w = width + 2; + + restorePage3(); + + _screen->hideMouse(); + + if (textEnabled()) { + objectChatPrintText(str, object); + _chatEndTime = _system->getMillis() + chatCalcDuration(str) * _tickLength; + } else { + _chatEndTime = _system->getMillis(); + } + + if (speechEnabled()) { + _chatVocHigh = vocHigh; + _chatVocLow = vocLow; + } else { + _chatVocHigh = _chatVocLow = -1; + } + + _screen->showMouse(); +} + +void KyraEngine_MR::objectChatPrintText(const char *str, int object) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::objectChatPrintText('%s', %d)", str, object); + int c1 = _talkObjectList[object].color; + str = _text->preprocessString(str); + int lineNum = _text->buildMessageSubstrings(str); + int maxWidth = _text->getWidestLineWidth(lineNum); + int x = (object == 0) ? _mainCharacter.x1 : _talkObjectList[object].x; + int cX1 = 0, cX2 = 0; + _text->calcWidestLineBounds(cX1, cX2, maxWidth, x); + + for (int i = 0; i < lineNum; ++i) { + str = &_text->_talkSubstrings[i*_text->maxSubstringLen()]; + + int y = _text->_talkMessageY + i * 10; + x = _text->getCenterStringX(str, cX1, cX2); + + _text->printText(str, x, y, c1, 0xF0, 0); + } +} + +void KyraEngine_MR::objectChatProcess(const char *script) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::objectChatProcess('%s')", script); + + memset(&_chatScriptData, 0, sizeof(_chatScriptData)); + memset(&_chatScriptState, 0, sizeof(_chatScriptState)); + + _emc->load(script, &_chatScriptData, &_opcodesTemporary); + _emc->init(&_chatScriptState, &_chatScriptData); + _emc->start(&_chatScriptState, 0); + while (_emc->isValid(&_chatScriptState)) + _emc->run(&_chatScriptState); + + if (_chatVocHigh >= 0) { + playVoice(_chatVocHigh, _chatVocLow); + _chatVocHigh = _chatVocLow = -1; + } + + _useFrameTable = true; + objectChatWaitToFinish(); + _useFrameTable = false; + + _emc->unload(&_chatScriptData); +} + +void KyraEngine_MR::objectChatWaitToFinish() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::objectChatWaitToFinish()"); + int charAnimFrame = _mainCharacter.animFrame; + setCharacterAnimDim(_newShapeWidth, _newShapeHeight); + + _emc->init(&_chatScriptState, &_chatScriptData); + _emc->start(&_chatScriptState, 1); + + bool running = true; + const uint32 endTime = _chatEndTime; + resetSkipFlag(); + + while (running && !_quitFlag) { + if (!_emc->isValid(&_chatScriptState)) + _emc->start(&_chatScriptState, 1); + + _temporaryScriptExecBit = false; + while (!_temporaryScriptExecBit && _emc->isValid(&_chatScriptState)) { + musicUpdate(0); + _emc->run(&_chatScriptState); + } + + int curFrame = _newShapeAnimFrame; + uint32 delayTime = _newShapeDelay; + + _mainCharacter.animFrame = curFrame; + updateCharacterAnim(0); + + uint32 nextFrame = _system->getMillis() + delayTime * _tickLength; + + while (_system->getMillis() < nextFrame && !_quitFlag) { + updateWithText(); + + const uint32 curTime = _system->getMillis(); + if ((textEnabled() && !speechEnabled() && curTime > endTime) || (speechEnabled() && !snd_voiceIsPlaying()) || skipFlag()) { + snd_stopVoice(); + resetSkipFlag(); + nextFrame = curTime; + running = false; + } + + delay(10); + } + } + + _mainCharacter.animFrame = charAnimFrame; + updateCharacterAnim(0); + resetCharacterAnimDim(); +} + +void KyraEngine_MR::badConscienceChat(const char *str, int vocHigh, int vocLow) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::badConscienceChat('%s', %d, %d)", str, vocHigh, vocLow); + if (!_badConscienceShown) + return; + + setNextIdleAnimTimer(); + _chatVocHigh = _chatVocLow = -1; + objectChatInit(str, 1, vocHigh, vocLow); + _chatText = str; + _chatObject = 1; + badConscienceChatWaitToFinish(); + updateSceneAnim(0x0E, _badConscienceFrameTable[_badConscienceAnim+16]); + _text->restoreScreen(); + update(); + _chatText = 0; + _chatObject = -1; +} + +void KyraEngine_MR::badConscienceChatWaitToFinish() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::badConscienceChatWaitToFinish()"); + if (_chatVocHigh) { + playVoice(_chatVocHigh, _chatVocLow); + _chatVocHigh = _chatVocLow = -1; + } + + bool running = true; + const uint32 endTime = _chatEndTime; + resetSkipFlag(); + + uint32 nextFrame = _system->getMillis() + _rnd.getRandomNumberRng(4, 8) * _tickLength; + + int frame = _badConscienceFrameTable[_badConscienceAnim+24]; + while (running && !_quitFlag) { + if (nextFrame < _system->getMillis()) { + ++frame; + if (_badConscienceFrameTable[_badConscienceAnim+32] < frame) + frame = _badConscienceFrameTable[_badConscienceAnim+24]; + + updateSceneAnim(0x0E, frame); + updateWithText(); + + nextFrame = _system->getMillis() + _rnd.getRandomNumberRng(4, 8) * _tickLength; + } + + updateWithText(); + + const uint32 curTime = _system->getMillis(); + if ((textEnabled() && !speechEnabled() && curTime > endTime) || (speechEnabled() && !snd_voiceIsPlaying()) || skipFlag()) { + snd_stopVoice(); + resetSkipFlag(); + nextFrame = curTime; + running = false; + } + + delay(10); + } +} + +void KyraEngine_MR::goodConscienceChat(const char *str, int vocHigh, int vocLow) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::goodConscienceChat('%s', %d, %d)", str, vocHigh, vocLow); + if (!_goodConscienceShown) + return; + + setNextIdleAnimTimer(); + _chatVocHigh = _chatVocLow = -1; + objectChatInit(str, 87, vocHigh, vocLow); + _chatText = str; + _chatObject = 87; + goodConscienceChatWaitToFinish(); + updateSceneAnim(0x0F, _goodConscienceFrameTable[_goodConscienceAnim+10]); + _text->restoreScreen(); + update(); + _chatText = 0; + _chatObject = -1; +} + +void KyraEngine_MR::goodConscienceChatWaitToFinish() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::goodConscienceChatWaitToFinish()"); + if (_chatVocHigh) { + playVoice(_chatVocHigh, _chatVocLow); + _chatVocHigh = _chatVocLow = -1; + } + + bool running = true; + const uint32 endTime = _chatEndTime; + resetSkipFlag(); + + uint32 nextFrame = _system->getMillis() + _rnd.getRandomNumberRng(3, 6) * _tickLength; + + int frame = _goodConscienceFrameTable[_goodConscienceAnim+15]; + while (running && !_quitFlag) { + if (nextFrame < _system->getMillis()) { + ++frame; + if (_goodConscienceFrameTable[_goodConscienceAnim+20] < frame) + frame = _goodConscienceFrameTable[_goodConscienceAnim+15]; + + updateSceneAnim(0x0F, frame); + updateWithText(); + + nextFrame = _system->getMillis() + _rnd.getRandomNumberRng(3, 6) * _tickLength; + } + + updateWithText(); + + const uint32 curTime = _system->getMillis(); + if ((textEnabled() && !speechEnabled() && curTime > endTime) || (speechEnabled() && !snd_voiceIsPlaying()) || skipFlag()) { + snd_stopVoice(); + resetSkipFlag(); + nextFrame = curTime; + running = false; + } + + delay(10); + } +} + +void KyraEngine_MR::malcolmSceneStartupChat() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::malcolmSceneStartupChat()"); + + if (_noStartupChat) + return; + + int index = _mainCharacter.sceneId - _chapterLowestScene[_currentChapter]; + if (_newSceneDlgState[index]) + return; + + updateDlgBuffer(); + int vocHighBase = 0, vocHighIndex = 0, index1 = 0, index2 = 0; + loadDlgHeader(vocHighBase, vocHighIndex, index1, index2); + + _cnvFile->seek(index1*6, SEEK_CUR); + _cnvFile->seek(index2*4, SEEK_CUR); + _cnvFile->seek(index*2, SEEK_CUR); + _cnvFile->seek(_cnvFile->readUint16LE(), SEEK_SET); + + _isStartupDialog = true; + processDialog(vocHighIndex, vocHighBase, 0); + _isStartupDialog = false; + _newSceneDlgState[index] = true; +} + +void KyraEngine_MR::updateDlgBuffer() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::updateDlgBuffer()"); + char dlgFile[16]; + char cnvFile[16]; + + if (_cnvFile) + _cnvFile->seek(0, SEEK_SET); + + if (_curDlgIndex == _mainCharacter.dlgIndex && _curDlgChapter == _currentChapter && _curDlgLang == _lang) + return; + + snprintf(dlgFile, 16, "CH%.02d-S%.02d.", _currentChapter, _mainCharacter.dlgIndex); + appendLanguage(dlgFile, _lang, 16); + snprintf(cnvFile, 16, "CH%.02d-S%.02d.CNV", _currentChapter, _mainCharacter.dlgIndex); + + delete _cnvFile; + delete _dlgBuffer; + + _res->exists(cnvFile, true); + _res->exists(dlgFile, true); + _cnvFile = _res->getFileStream(cnvFile); + _dlgBuffer = _res->getFileStream(dlgFile); + assert(_cnvFile); + assert(_dlgBuffer); +} + +void KyraEngine_MR::loadDlgHeader(int &vocHighBase, int &vocHighIndex, int &index1, int &index2) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::loadDlgHeader(-, -, -, -)"); + assert(_cnvFile); + vocHighIndex = _cnvFile->readSint16LE(); + vocHighBase = _cnvFile->readSint16LE(); + index1 = _cnvFile->readSint16LE(); + index2 = _cnvFile->readSint16LE(); +} + +void KyraEngine_MR::setDlgIndex(uint16 index) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::setDlgIndex(%d)", index); + if (_mainCharacter.dlgIndex != index) { + Common::set_to(_newSceneDlgState, _newSceneDlgState+ARRAYSIZE(_newSceneDlgState), 0); + memset(_conversationState, -1, sizeof(_conversationState)); + _chatAltFlag = false; + _mainCharacter.dlgIndex = index; + } +} + +void KyraEngine_MR::updateDlgIndex() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::updateDlgIndex()"); + uint16 dlgIndex = _mainCharacter.dlgIndex; + + if (_currentChapter == 1) { + static const uint8 dlgIndexMoodNice[] = { 0x0C, 0x0E, 0x10, 0x0F, 0x11 }; + static const uint8 dlgIndexMoodNormal[] = { 0x00, 0x02, 0x04, 0x03, 0x05 }; + static const uint8 dlgIndexMoodEvil[] = { 0x06, 0x08, 0x0A, 0x09, 0x0B }; + + if (_malcolmsMood == 0) + dlgIndex = dlgIndexMoodNice[_malcolmShapes]; + else if (_malcolmsMood == 1) + dlgIndex = dlgIndexMoodNormal[_malcolmShapes]; + else if (_malcolmsMood == 2) + dlgIndex = dlgIndexMoodEvil[_malcolmShapes]; + } else if (_currentChapter == 2) { + if (dlgIndex >= 8) + dlgIndex -= 4; + if (dlgIndex >= 4) + dlgIndex -= 4; + + if (_malcolmsMood == 0) + dlgIndex += 8; + else if (_malcolmsMood == 2) + dlgIndex += 4; + } else if (_currentChapter == 4) { + if (dlgIndex >= 10) + dlgIndex -= 5; + if (dlgIndex >= 5) + dlgIndex -= 5; + + if (_malcolmsMood == 0) + dlgIndex += 10; + else if (_malcolmsMood == 2) + dlgIndex += 5; + } + + _mainCharacter.dlgIndex = dlgIndex; +} + +void KyraEngine_MR::processDialog(int vocHighIndex, int vocHighBase, int funcNum) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::processDialog(%d, %d, %d)", vocHighIndex, vocHighBase, funcNum); + bool running = true; + int script = -1; + int vocHigh = -1, vocLow = -1; + + while (running) { + uint16 cmd = _cnvFile->readUint16LE(); + int object = cmd - 12; + + if (cmd == 10) { + break; + } else if (cmd == 4) { + vocHighBase = _cnvFile->readUint16LE(); + setDlgIndex(vocHighBase); + } else if (cmd == 11) { + int strSize = _cnvFile->readUint16LE(); + vocLow = _cnvFile->readUint16LE(); + _cnvFile->read(_stringBuffer, strSize); + _stringBuffer[strSize] = 0; + } else { + vocHigh = _vocHighTable[vocHighIndex-1] + vocHighBase; + vocLow = _cnvFile->readUint16LE(); + getTableEntry(_dlgBuffer, vocLow, _stringBuffer); + + if (_isStartupDialog) { + delay(60*_tickLength, true); + _isStartupDialog = false; + } + + if (*_stringBuffer == 0) + continue; + + if (cmd != 12) { + if (object != script) { + if (script >= 0) { + dialogEndScript(script); + script = -1; + } + + dialogStartScript(object, funcNum); + script = object; + } + + npcChatSequence(_stringBuffer, object, vocHigh, vocLow); + } else { + if (script >= 0) { + dialogEndScript(script); + script = -1; + } + + objectChat(_stringBuffer, 0, vocHigh, vocLow); + playStudioSFX(_stringBuffer); + } + } + } + + if (script != -1) + dialogEndScript(script); +} + +void KyraEngine_MR::dialogStartScript(int object, int funcNum) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::dialogStartScript(%d, %d)", object, funcNum); + _dialogSceneAnim = _talkObjectList[object].sceneAnim; + _dialogSceneScript = _talkObjectList[object].sceneScript; + if (_dialogSceneAnim >= 0 && _dialogSceneScript >= 0) { + _specialSceneScriptStateBackup[_dialogSceneScript] = _specialSceneScriptState[_dialogSceneScript]; + _specialSceneScriptState[_dialogSceneScript] = true; + } + + _emc->init(&_dialogScriptState, &_dialogScriptData); + _emc->load(_talkObjectList[object].filename, &_dialogScriptData, &_opcodesDialog); + + _dialogScriptFuncStart = funcNum * 3 + 0; + _dialogScriptFuncProc = funcNum * 3 + 1; + _dialogScriptFuncEnd = funcNum * 3 + 2; + + _emc->start(&_dialogScriptState, _dialogScriptFuncStart); + while (_emc->isValid(&_dialogScriptState)) + _emc->run(&_dialogScriptState); +} + +void KyraEngine_MR::dialogEndScript(int object) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::dialogEndScript(%d)", object); + + _emc->init(&_dialogScriptState, &_dialogScriptData); + _emc->start(&_dialogScriptState, _dialogScriptFuncEnd); + + while (_emc->isValid(&_dialogScriptState)) + _emc->run(&_dialogScriptState); + + if (_dialogSceneAnim >= 0 && _dialogSceneScript >= 0) { + _specialSceneScriptState[_dialogSceneScript] = _specialSceneScriptStateBackup[_dialogSceneScript]; + _dialogSceneScript = _dialogSceneAnim = -1; + } + + _emc->unload(&_dialogScriptData); +} + +void KyraEngine_MR::npcChatSequence(const char *str, int object, int vocHigh, int vocLow) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::npcChatSequence('%s', %d, %d, %d)", str, object, vocHigh, vocLow); + + _chatText = str; + _chatObject = object; + _chatVocHigh = _chatVocLow = -1; + + objectChatInit(str, object, vocHigh, vocLow); + + if (_chatVocHigh >= 0 && _chatVocLow >= 0) { + playVoice(_chatVocHigh, _chatVocLow); + _chatVocHigh = _chatVocLow = -1; + } + + _emc->init(&_dialogScriptState, &_dialogScriptData); + _emc->start(&_dialogScriptState, _dialogScriptFuncProc); + + resetSkipFlag(); + + uint32 endTime = _chatEndTime; + bool running = true; + while (running) { + if (!_emc->run(&_dialogScriptState)) { + _emc->init(&_dialogScriptState, &_dialogScriptData); + _emc->start(&_dialogScriptState, _dialogScriptFuncProc); + } + + const uint32 curTime = _system->getMillis(); + if ((textEnabled() && !speechEnabled() && curTime > endTime) || (speechEnabled() && !snd_voiceIsPlaying()) || skipFlag()) { + snd_stopVoice(); + resetSkipFlag(); + running = false; + } + + delay(10); + } + _text->restoreScreen(); + _chatText = 0; + _chatObject= - 1; +} + +void KyraEngine_MR::malcolmRandomChat() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::malcolmRandomChat()"); + updateDlgBuffer(); + + int index = (_mainCharacter.sceneId - _chapterLowestScene[_currentChapter]) * 2; + + int vocHighBase = 0, vocHighIndex = 0, index1 = 0, index2 = 0; + loadDlgHeader(vocHighBase, vocHighIndex, index1, index2); + + if (_chatAltFlag) + index++; + _chatAltFlag = !_chatAltFlag; + + _cnvFile->seek(index1*6, SEEK_CUR); + _cnvFile->seek(index*2, SEEK_CUR); + _cnvFile->seek(_cnvFile->readUint16LE(), SEEK_SET); + + processDialog(vocHighIndex, vocHighBase, 0); +} + +void KyraEngine_MR::runDialog(int dlgIndex, int funcNum) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::runDialog(%d, %d)", dlgIndex, funcNum); + + switch (_currentChapter-2) { + case 0: + dlgIndex -= 34; + break; + + case 1: + dlgIndex -= 54; + break; + + case 2: + dlgIndex -= 55; + break; + + case 3: + dlgIndex -= 70; + break; + + default: + break; + } + + updateDlgBuffer(); + + int vocHighBase = 0, vocHighIndex = 0, index1 = 0, index2 = 0; + loadDlgHeader(vocHighBase, vocHighIndex, index1, index2); + + int convState = _conversationState[dlgIndex][vocHighBase]; + uint32 offset = ((vocHighIndex == 1) ? dlgIndex - 1 : dlgIndex) * 6; + if (convState == -1) { + _cnvFile->seek(offset, SEEK_CUR); + _conversationState[dlgIndex][vocHighBase] = 0; + } else if (convState == 0 || convState == 2) { + _cnvFile->seek(offset+2, SEEK_CUR); + _conversationState[dlgIndex][vocHighBase] = 1; + } else { + _cnvFile->seek(offset+4, SEEK_CUR); + _conversationState[dlgIndex][vocHighBase] = 2; + } + + _cnvFile->seek(_cnvFile->readUint16LE(), SEEK_SET); + + processDialog(vocHighIndex, vocHighBase, funcNum); +} + +} // end of namespace Kyra + diff --git a/engines/kyra/text_mr.h b/engines/kyra/text_mr.h new file mode 100644 index 0000000000..d96b0964ba --- /dev/null +++ b/engines/kyra/text_mr.h @@ -0,0 +1,55 @@ +/* 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_TEXT_MR_H +#define KYRA_TEXT_MR_H + +#include "kyra/text.h" + +#include "kyra/kyra_mr.h" + +namespace Kyra { + +class TextDisplayer_MR : public TextDisplayer { +friend class KyraEngine_MR; +public: + TextDisplayer_MR(KyraEngine_MR *vm, Screen_MR *screen); + + char *preprocessString(const char *str); + int dropCRIntoString(char *str, int minOffs, int maxOffs); + + void printText(const char *str, int x, int y, uint8 c0, uint8 c1, uint8 c2, Screen::FontId font=Screen::FID_8_FNT); + + void restoreScreen(); + + void calcWidestLineBounds(int &x1, int &x2, int w, int x); +protected: + KyraEngine_MR *_vm; + Screen_MR *_screen; +}; + +} // end of namespace Kyra + +#endif diff --git a/engines/kyra/text_v2.cpp b/engines/kyra/text_v2.cpp deleted file mode 100644 index 0fa1d3cd9f..0000000000 --- a/engines/kyra/text_v2.cpp +++ /dev/null @@ -1,690 +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/text_v2.h" -#include "kyra/kyra_v2.h" -#include "kyra/script_tim.h" -#include "kyra/resource.h" - -#include "common/endian.h" - -namespace Kyra { - -TextDisplayer_v2::TextDisplayer_v2(KyraEngine_v2 *vm, Screen_v2 *screen) - : TextDisplayer(vm, screen), _vm(vm) { -} - -void TextDisplayer_v2::backupTalkTextMessageBkgd(int srcPage, int dstPage) { - _screen->copyRegion(_talkCoords.x, _talkMessageY, 0, 144, _talkCoords.w, _talkMessageH, srcPage, dstPage); -} - -void TextDisplayer_v2::restoreTalkTextMessageBkgd(int srcPage, int dstPage) { - _screen->copyRegion(0, 144, _talkCoords.x, _talkMessageY, _talkCoords.w, _talkMessageH, srcPage, dstPage); -} - -void TextDisplayer_v2::restoreScreen() { - _vm->restorePage3(); - _vm->drawAnimObjects(); - _screen->hideMouse(); - _screen->copyRegion(_talkCoords.x, _talkMessageY, _talkCoords.x, _talkMessageY, _talkCoords.w, _talkMessageH, 2, 0, Screen::CR_NO_P_CHECK); - _screen->showMouse(); - _vm->flagAnimObjsForRefresh(); - _vm->refreshAnimObjects(0); -} - -void TextDisplayer_v2::printCustomCharacterText(const char *text, int x, int y, uint8 c1, int srcPage, int dstPage) { - text = preprocessString(text); - int lineCount = buildMessageSubstrings(text); - int w = getWidestLineWidth(lineCount); - int h = lineCount * 10; - y = MAX(0, y - (lineCount * 10)); - int x1 = 0, x2 = 0; - calcWidestLineBounds(x1, x2, w, x); - - _screen->hideMouse(); - - _talkCoords.x = x1; - _talkCoords.w = w+2; - _talkCoords.y = y; - _talkMessageY = y; - _talkMessageH = h; - - backupTalkTextMessageBkgd(srcPage, dstPage); - int curPageBackUp = _screen->_curPage; - _screen->_curPage = srcPage; - - if (_vm->textEnabled()) { - for (int i = 0; i < lineCount; ++i) { - const char *msg = &_talkSubstrings[i * TALK_SUBSTRING_LEN]; - printText(msg, getCenterStringX(msg, x1, x2), i * 10 + _talkMessageY, c1, 0xCF, 0); - } - } - - _screen->_curPage = curPageBackUp; - _screen->showMouse(); -} - -char *TextDisplayer_v2::preprocessString(const char *str) { - debugC(9, kDebugLevelMain, "TextDisplayer_v2::preprocessString('%s')", str); - - if (str != _talkBuffer) { - assert(strlen(str) < sizeof(_talkBuffer) - 1); - strcpy(_talkBuffer, str); - } - - char *p = _talkBuffer; - while (*p) { - if (*p == '\r') - return _talkBuffer; - ++p; - } - - p = _talkBuffer; - Screen::FontId curFont = _screen->setFont(Screen::FID_8_FNT); - _screen->_charWidth = -2; - int textWidth = _screen->getTextWidth(p); - _screen->_charWidth = 0; - - // longer text strings for German versions - int maxTextWidth = (_vm->language() == 2 ? 240 : 176); - - if (textWidth > maxTextWidth) { - if (textWidth > (maxTextWidth*2)) { - int count = getCharLength(p, textWidth / 3); - int offs = dropCRIntoString(p, count); - p += count + offs; - _screen->_charWidth = -2; - textWidth = _screen->getTextWidth(p); - _screen->_charWidth = 0; - count = getCharLength(p, textWidth / 2); - dropCRIntoString(p, count); - } else { - int count = getCharLength(p, textWidth / 2); - dropCRIntoString(p, count); - } - } - _screen->setFont(curFont); - return _talkBuffer; -} - -void TextDisplayer_v2::calcWidestLineBounds(int &x1, int &x2, int w, int x) { - debugC(9, kDebugLevelMain, "TextDisplayer_v2::calcWidestLineBounds(%d, %d)", w, x); - x1 = x; - x1 -= (w >> 1); - x2 = x1 + w + 1; - - if (x1 + w >= 311) - x1 = 311 - w - 1; - - if (x1 < 8) - x1 = 8; - - x2 = x1 + w + 1; -} - -#pragma mark - - -int KyraEngine_v2::chatGetType(const char *str) { - str += strlen(str); - --str; - switch (*str) { - case '!': - return 2; - - case ')': - return -1; - - case '?': - return 1; - - default: - return 0; - } -} - -int KyraEngine_v2::chatCalcDuration(const char *str) { - static const uint8 durationMultiplicator[] = { 16, 14, 12, 10, 8, 8, 7, 6, 5, 4 }; - - int duration = strlen(str); - duration *= _flags.isTalkie ? 8 : durationMultiplicator[(_configTextspeed / 10)]; - return MAX(duration, 120); -} - -void KyraEngine_v2::objectChat(const char *str, int object, int vocHigh, int vocLow) { - setNextIdleAnimTimer(); - - _chatVocHigh = _chatVocLow = -1; - - objectChatInit(str, object, vocHigh, vocLow); - _chatText = str; - _chatObject = object; - int chatType = chatGetType(str); - if (chatType == -1) { - _chatIsNote = true; - chatType = 0; - } - - if (_mainCharacter.facing > 7) - _mainCharacter.facing = 5; - - static const uint8 talkScriptTable[] = { - 6, 7, 8, - 3, 4, 5, - 3, 4, 5, - 0, 1, 2, - 0, 1, 2, - 0, 1, 2, - 3, 4, 5, - 3, 4, 5 - }; - - assert(_mainCharacter.facing * 3 + chatType < ARRAYSIZE(talkScriptTable)); - int script = talkScriptTable[_mainCharacter.facing * 3 + chatType]; - - static const char *chatScriptFilenames[] = { - "_Z1FSTMT.EMC", - "_Z1FQUES.EMC", - "_Z1FEXCL.EMC", - "_Z1SSTMT.EMC", - "_Z1SQUES.EMC", - "_Z1SEXCL.EMC", - "_Z1BSTMT.EMC", - "_Z1BQUES.EMC", - "_Z1BEXCL.EMC" - }; - - objectChatProcess(chatScriptFilenames[script]); - _chatIsNote = false; - - _text->restoreScreen(); - - _mainCharacter.animFrame = _characterFrameTable[_mainCharacter.facing]; - updateCharacterAnim(0); - - _chatText = 0; - _chatObject = -1; - - setNextIdleAnimTimer(); -} - -void KyraEngine_v2::objectChatInit(const char *str, int object, int vocHigh, int vocLow) { - str = _text->preprocessString(str); - int lineNum = _text->buildMessageSubstrings(str); - - int yPos = 0, xPos = 0; - - if (!object) { - int scale = getScale(_mainCharacter.x1, _mainCharacter.y1); - yPos = _mainCharacter.y1 - ((_mainCharacter.height * scale) >> 8) - 8; - xPos = _mainCharacter.x1; - } else { - yPos = _talkObjectList[object].y; - xPos = _talkObjectList[object].x; - } - - yPos -= lineNum * 10; - yPos = MAX(yPos, 0); - _text->_talkMessageY = yPos; - _text->_talkMessageH = lineNum*10; - - int width = _text->getWidestLineWidth(lineNum); - _text->calcWidestLineBounds(xPos, yPos, width, xPos); - _text->_talkCoords.x = xPos; - _text->_talkCoords.w = width + 2; - - restorePage3(); - _text->backupTalkTextMessageBkgd(2, 2); - - _screen->hideMouse(); - - if (textEnabled()) { - objectChatPrintText(str, object); - _chatEndTime = _system->getMillis() + chatCalcDuration(str) * _tickLength; - } else { - _chatEndTime = _system->getMillis(); - } - - if (speechEnabled()) { - _chatVocHigh = vocHigh; - _chatVocLow = vocLow; - } else { - _chatVocHigh = _chatVocLow = -1; - } - - _screen->showMouse(); -} - -void KyraEngine_v2::objectChatPrintText(const char *str, int object) { - int c1 = _talkObjectList[object].color; - str = _text->preprocessString(str); - int lineNum = _text->buildMessageSubstrings(str); - int maxWidth = _text->getWidestLineWidth(lineNum); - int x = (object == 0) ? _mainCharacter.x1 : _talkObjectList[object].x; - int cX1 = 0, cX2 = 0; - _text->calcWidestLineBounds(cX1, cX2, maxWidth, x); - - for (int i = 0; i < lineNum; ++i) { - str = &_text->_talkSubstrings[i*_text->maxSubstringLen()]; - - int y = _text->_talkMessageY + i * 10; - x = _text->getCenterStringX(str, cX1, cX2); - - _text->printText(str, x, y, c1, 0xCF, 0); - } -} - -void KyraEngine_v2::objectChatProcess(const char *script) { - memset(&_chatScriptData, 0, sizeof(_chatScriptData)); - memset(&_chatScriptState, 0, sizeof(_chatScriptState)); - - _emc->load(script, &_chatScriptData, &_opcodesTemporary); - _emc->init(&_chatScriptState, &_chatScriptData); - _emc->start(&_chatScriptState, 0); - while (_emc->isValid(&_chatScriptState)) - _emc->run(&_chatScriptState); - - _newShapeFilename[2] = _loadedZTable + '0'; - uint8 *shapeBuffer = _res->fileData(_newShapeFilename, 0); - if (shapeBuffer) { - int shapeCount = initNewShapes(shapeBuffer); - - if (_chatVocHigh >= 0) { - playVoice(_chatVocHigh, _chatVocLow); - _chatVocHigh = _chatVocLow = -1; - } - - objectChatWaitToFinish(); - - resetNewShapes(shapeCount, shapeBuffer); - } else { - warning("couldn't load file '%s'", _newShapeFilename); - } - - _emc->unload(&_chatScriptData); -} - -void KyraEngine_v2::objectChatWaitToFinish() { - int charAnimFrame = _mainCharacter.animFrame; - setCharacterAnimDim(_newShapeWidth, _newShapeHeight); - - _emc->init(&_chatScriptState, &_chatScriptData); - _emc->start(&_chatScriptState, 1); - - bool running = true; - const uint32 endTime = _chatEndTime; - resetSkipFlag(); - - while (running && !_quitFlag) { - if (!_emc->isValid(&_chatScriptState)) - _emc->start(&_chatScriptState, 1); - - _temporaryScriptExecBit = false; - while (!_temporaryScriptExecBit && _emc->isValid(&_chatScriptState)) - _emc->run(&_chatScriptState); - - int curFrame = _newShapeAnimFrame; - uint32 delayTime = _newShapeDelay; - - if (!_chatIsNote) - _mainCharacter.animFrame = 33 + curFrame; - - updateCharacterAnim(0); - - uint32 nextFrame = _system->getMillis() + delayTime * _tickLength; - - while (_system->getMillis() < nextFrame && !_quitFlag) { - updateWithText(); - - const uint32 curTime = _system->getMillis(); - if ((textEnabled() && curTime > endTime) || (speechEnabled() && !textEnabled() && !snd_voiceIsPlaying()) || skipFlag()) { - resetSkipFlag(); - nextFrame = curTime; - running = false; - } - - delay(10); - } - } - - _mainCharacter.animFrame = charAnimFrame; - updateCharacterAnim(0); - resetCharacterAnimDim(); -} - -void KyraEngine_v2::startDialogue(int dlgIndex) { - updateDlgBuffer(); - int csEntry, vocH, unused1, unused2; - loadDlgHeader(csEntry, vocH, unused1, unused2); - int s = _conversationState[dlgIndex][csEntry]; - uint8 bufferIndex = 8; - - if (s == -1) { - bufferIndex += (dlgIndex * 6); - _conversationState[dlgIndex][csEntry] = 0; - } else if (!s || s == 2) { - bufferIndex += (dlgIndex * 6 + 2); - _conversationState[dlgIndex][csEntry] = 1; - } else { - bufferIndex += (dlgIndex * 6 + 4); - _conversationState[dlgIndex][csEntry] = 2; - } - - int offs = READ_LE_UINT16(_dlgBuffer + bufferIndex); - processDialogue(offs, vocH, csEntry); -} - -void KyraEngine_v2::zanthSceneStartupChat() { - int lowest = _flags.isTalkie ? 6 : 5; - int tableIndex = _mainCharacter.sceneId - READ_LE_UINT16(&_ingameTalkObjIndex[lowest + _newChapterFile]); - if (queryGameFlag(0x159) || _newSceneDlgState[tableIndex]) - return; - - int csEntry, vocH, scIndex1, scIndex2; - updateDlgBuffer(); - loadDlgHeader(csEntry, vocH, scIndex1, scIndex2); - - uint8 bufferIndex = 8 + scIndex1 * 6 + scIndex2 * 4 + tableIndex * 2; - int offs = READ_LE_UINT16(_dlgBuffer + bufferIndex); - processDialogue(offs, vocH, csEntry); - - _newSceneDlgState[tableIndex] = 1; -} - -void KyraEngine_v2::zanthRandomIdleChat() { - int lowest = _flags.isTalkie ? 6 : 5; - int tableIndex = (_mainCharacter.sceneId - READ_LE_UINT16(&_ingameTalkObjIndex[lowest + _newChapterFile])) << 2; - if (queryGameFlag(0x164)) - return; - - int csEntry, vocH, scIndex1, unused; - updateDlgBuffer(); - loadDlgHeader(csEntry, vocH, scIndex1, unused); - - if (_chatAltFlag) { - _chatAltFlag = 0; - tableIndex += 2; - } else { - _chatAltFlag = 1; - } - - uint8 bufferIndex = 8 + scIndex1 * 6 + tableIndex; - int offs = READ_LE_UINT16(_dlgBuffer + bufferIndex); - processDialogue(offs, vocH, csEntry); -} - -void KyraEngine_v2::updateDlgBuffer() { - static const char suffixTalkie[] = "EFG"; - static const char suffixTowns[] = "G J"; - - if (_currentChapter == _npcTalkChpIndex && _mainCharacter.dlgIndex == _npcTalkDlgIndex) - return; - - _npcTalkChpIndex = _currentChapter; - _npcTalkDlgIndex = _mainCharacter.dlgIndex; - - char filename[13]; - snprintf(filename, 13, "CH%.02d-S%.02d.DLG", _currentChapter, _npcTalkDlgIndex); - - const char *suffix = _flags.isTalkie ? suffixTalkie : suffixTowns; - if (_flags.platform != Common::kPlatformPC || _flags.isTalkie) - filename[11] = suffix[_lang]; - - if (_dlgBuffer) - delete [] _dlgBuffer; - - _dlgBuffer = _res->fileData(filename, 0); -} - -void KyraEngine_v2::loadDlgHeader(int &csEntry, int &vocH, int &scIndex1, int &scIndex2) { - csEntry = READ_LE_UINT16(_dlgBuffer); - vocH = READ_LE_UINT16(_dlgBuffer + 2); - scIndex1 = READ_LE_UINT16(_dlgBuffer + 4); - scIndex2 = READ_LE_UINT16(_dlgBuffer + 6); -} - -void KyraEngine_v2::processDialogue(int dlgOffset, int vocH, int csEntry) { - int activeTimSequence = -1; - int nextTimSequence = -1; - int cmd = 0; - int vocHi = -1; - int vocLo = -1; - bool loop = true; - int offs = dlgOffset; - - _screen->hideMouse(); - - while (loop) { - cmd = READ_LE_UINT16(_dlgBuffer + offs); - offs += 2; - - nextTimSequence = READ_LE_UINT16(&_ingameTalkObjIndex[cmd]); - - if (nextTimSequence == 10) { - if (queryGameFlag(0x3e)) - nextTimSequence = 14; - if (queryGameFlag(0x3f)) - nextTimSequence = 15; - if (queryGameFlag(0x40)) - nextTimSequence = 16; - } - - if (nextTimSequence == 27 && _mainCharacter.sceneId == 34) - nextTimSequence = 41; - - if (queryGameFlag(0x72)) { - if (nextTimSequence == 18) - nextTimSequence = 43; - else if (nextTimSequence == 19) - nextTimSequence = 44; - } - - if (_mainCharacter.x1 > 160) { - if (nextTimSequence == 4) - nextTimSequence = 46; - else if (nextTimSequence == 5) - nextTimSequence = 47; - } - - if (cmd == 10) { - loop = false; - - } else if (cmd == 4) { - csEntry = READ_LE_UINT16(_dlgBuffer + offs); - setNewDlgIndex(csEntry); - offs += 2; - - } else { - if (!_flags.isTalkie || cmd == 11) { - int len = READ_LE_UINT16(_dlgBuffer + offs); - offs += 2; - if (_flags.isTalkie) { - vocLo = READ_LE_UINT16(_dlgBuffer + offs); - offs += 2; - } - memcpy(_unkBuf500Bytes, _dlgBuffer + offs, len); - _unkBuf500Bytes[len] = 0; - offs += len; - if (_flags.isTalkie) - continue; - - } else if (_flags.isTalkie) { - int len = READ_LE_UINT16(_dlgBuffer + offs); - offs += 2; - static const int irnv[] = { 91, 105, 110, 114, 118 }; - vocHi = irnv[vocH - 1] + csEntry; - vocLo = READ_LE_UINT16(_dlgBuffer + offs); - offs += 2; - memcpy(_unkBuf500Bytes, _dlgBuffer + offs, len); - _unkBuf500Bytes[len] = 0; - offs += len; - } - - if (_unkBuf500Bytes[0]) { - if ((!_flags.isTalkie && cmd == 11) || (_flags.isTalkie && cmd == 12)) { - if (activeTimSequence > -1) { - deinitTalkObject(activeTimSequence); - activeTimSequence = -1; - } - objectChat((const char*) _unkBuf500Bytes, 0, vocHi, vocLo); - } else { - if (activeTimSequence != nextTimSequence ) { - if (activeTimSequence > -1) { - deinitTalkObject(activeTimSequence); - activeTimSequence = -1; - } - initTalkObject(nextTimSequence); - activeTimSequence = nextTimSequence; - } - npcChatSequence((const char *)_unkBuf500Bytes, nextTimSequence, vocHi, vocLo); - } - } - } - } - - if (activeTimSequence > -1) - deinitTalkObject(activeTimSequence); - - _screen->showMouse(); -} - -void KyraEngine_v2::initTalkObject(int index) { - TalkObject &object = _talkObjectList[index]; - - char STAFilename[13]; - char ENDFilename[13]; - - strcpy(STAFilename, object.filename); - strcpy(_TLKFilename, object.filename); - strcpy(ENDFilename, object.filename); - - strcat(STAFilename + 4, "_STA.TIM"); - strcat(_TLKFilename + 4, "_TLK.TIM"); - strcat(ENDFilename + 4, "_END.TIM"); - - _currentTalkSections.STATim = _tim->load(STAFilename, &_timOpcodes); - _currentTalkSections.TLKTim = _tim->load(_TLKFilename, &_timOpcodes); - _currentTalkSections.ENDTim = _tim->load(ENDFilename, &_timOpcodes); - - if (object.scriptId != -1) { - _specialSceneScriptStateBackup[object.scriptId] = _specialSceneScriptState[object.scriptId]; - _specialSceneScriptState[object.scriptId] = 1; - } - - if (_currentTalkSections.STATim) { - _tim->resetFinishedFlag(); - while (!_quitFlag && !_tim->finished()) { - _tim->exec(_currentTalkSections.STATim, false); - if (_chatText) - updateWithText(); - else - update(); - delay(10); - } - } -} - -void KyraEngine_v2::deinitTalkObject(int index) { - TalkObject &object = _talkObjectList[index]; - - if (_currentTalkSections.ENDTim) { - _tim->resetFinishedFlag(); - while (!_quitFlag && !_tim->finished()) { - _tim->exec(_currentTalkSections.ENDTim, false); - if (_chatText) - updateWithText(); - else - update(); - delay(10); - } - } - - if (object.scriptId != -1) - _specialSceneScriptState[object.scriptId] = _specialSceneScriptStateBackup[object.scriptId]; - - _tim->unload(_currentTalkSections.STATim); - _tim->unload(_currentTalkSections.TLKTim); - _tim->unload(_currentTalkSections.ENDTim); -} - -void KyraEngine_v2::npcChatSequence(const char *str, int objectId, int vocHigh, int vocLow) { - _chatText = str; - _chatObject = objectId; - objectChatInit(str, objectId, vocHigh, vocLow); - - if (!_currentTalkSections.TLKTim) - _currentTalkSections.TLKTim = _tim->load(_TLKFilename, &_timOpcodes); - - setNextIdleAnimTimer(); - - uint32 ct = chatCalcDuration(str); - uint32 time = _system->getMillis(); - _chatEndTime = time + (3 + ct) * _tickLength; - uint32 chatAnimEndTime = time + (3 + (ct >> 1)) * _tickLength; - - if (_chatVocHigh >= 0) { - playVoice(_chatVocHigh, _chatVocLow); - _chatVocHigh = _chatVocLow = -1; - } - - while (((textEnabled() && _chatEndTime > _system->getMillis()) || (speechEnabled() && snd_voiceIsPlaying())) && !(_quitFlag || skipFlag())) { - if (!speechEnabled() && chatAnimEndTime > _system->getMillis() || speechEnabled() && snd_voiceIsPlaying()) { - _tim->resetFinishedFlag(); - while (!_tim->finished() && !skipFlag() && !_quitFlag) { - if (_currentTalkSections.TLKTim) - _tim->exec(_currentTalkSections.TLKTim, false); - else - _tim->resetFinishedFlag(); - - updateWithText(); - delay(10); - } - - if (_currentTalkSections.TLKTim) - _tim->stopCurFunc(); - } - updateWithText(); - } - - resetSkipFlag(); - - _tim->unload(_currentTalkSections.TLKTim); - - _text->restoreScreen(); - _chatText = 0; - _chatObject = -1; - setNextIdleAnimTimer(); -} - -void KyraEngine_v2::setNewDlgIndex(int dlgIndex) { - if (dlgIndex == _mainCharacter.dlgIndex) - return; - memset(_newSceneDlgState, 0, 32); - for (int i = 0; i < 19; i++) - memset(_conversationState[i], -1, 14); - _chatAltFlag = false; - _mainCharacter.dlgIndex = dlgIndex; -} - -} // end of namespace Kyra diff --git a/engines/kyra/text_v2.h b/engines/kyra/text_v2.h deleted file mode 100644 index 6b8cf5d38e..0000000000 --- a/engines/kyra/text_v2.h +++ /dev/null @@ -1,56 +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_TEXT_V2_H -#define KYRA_TEXT_V2_H - -#include "kyra/text.h" - -namespace Kyra { - -class Screen_v2; -class KyraEngine_v2; - -class TextDisplayer_v2 : public TextDisplayer { -friend class KyraEngine_v2; -public: - TextDisplayer_v2(KyraEngine_v2 *vm, Screen_v2 *screen); - - void backupTalkTextMessageBkgd(int srcPage, int dstPage); - void restoreTalkTextMessageBkgd(int srcPage, int dstPage); - void restoreScreen(); - - void printCustomCharacterText(const char *src, int x, int y, uint8 c1, int srcPage, int dstPage); - - char *preprocessString(const char *str); - void calcWidestLineBounds(int &x1, int &x2, int w, int x); -private: - KyraEngine_v2 *_vm; -}; - -} // end of namespace Kyra - -#endif - diff --git a/engines/kyra/text_v3.cpp b/engines/kyra/text_v3.cpp deleted file mode 100644 index 47301eacec..0000000000 --- a/engines/kyra/text_v3.cpp +++ /dev/null @@ -1,817 +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/text_v3.h" -#include "kyra/screen_v3.h" -#include "kyra/resource.h" - -namespace Kyra { - -TextDisplayer_v3::TextDisplayer_v3(KyraEngine_v3 *vm, Screen_v3 *screen) - : TextDisplayer(vm, screen), _vm(vm), _screen(screen) { -} - -char *TextDisplayer_v3::preprocessString(const char *str) { - debugC(9, kDebugLevelMain, "TextDisplayer_v3::preprocessString('%s')", str); - if (_talkBuffer != str) - strncpy(_talkBuffer, str, sizeof(_talkBuffer)); - - char *p = _talkBuffer; - while (*p) { - if (*p++ == '\r') - return _talkBuffer; - } - - p = _talkBuffer; - Screen::FontId curFont = _screen->setFont(Screen::FID_8_FNT); - _screen->_charWidth = -2; - - const int maxTextWidth = (_vm->language() == 0) ? 176 : 240; - int textWidth = _screen->getTextWidth(p); - - if (textWidth > maxTextWidth) { - int count = 0, offs = 0; - if (textWidth > (3*maxTextWidth)) { - count = getCharLength(p, textWidth/4); - offs = dropCRIntoString(p, getCharLength(p, maxTextWidth), count); - p += count + offs; - } - - if (textWidth > (2*maxTextWidth)) { - count = getCharLength(p, textWidth/3); - offs = dropCRIntoString(p, getCharLength(p, maxTextWidth), count); - p += count + offs; - textWidth = _screen->getTextWidth(p); - } - - count = getCharLength(p, textWidth/2); - offs = dropCRIntoString(p, getCharLength(p, maxTextWidth), count); - p += count + offs; - textWidth = _screen->getTextWidth(p); - - if (textWidth > maxTextWidth) { - count = getCharLength(p, textWidth/2); - offs = dropCRIntoString(p, getCharLength(p, maxTextWidth), count); - } - } - - _screen->setFont(curFont); - return _talkBuffer; -} - -int TextDisplayer_v3::dropCRIntoString(char *str, int minOffs, int maxOffs) { - debugC(9, kDebugLevelMain, "TextDisplayer_v3::dropCRIntoString('%s', %d, %d)", str, maxOffs, minOffs); - - int offset = 0; - char *proc = str + minOffs; - - for (int i = minOffs; i < maxOffs; ++i) { - if (*proc == ' ') { - *proc = '\r'; - return offset; - } else if (*proc == '-') { - memmove(proc+1, proc, strlen(proc)+1); - *(++proc) = '\r'; - ++offset; - return offset; - } - - ++offset; - ++proc; - - if (!*proc) - return 0; - } - - offset = 0; - proc = str + minOffs; - for (int i = minOffs; i >= 0; --i) { - if (*proc == ' ') { - *proc = '\r'; - return offset; - } else if (*proc == '-') { - memmove(proc+1, proc, strlen(proc)+1); - *(++proc) = '\r'; - ++offset; - return offset; - } - - --offset; - --proc; - - if (!*proc) - return 0; - } - - *(str + minOffs) = '\r'; - return 0; -} - -void TextDisplayer_v3::printText(const char *str, int x, int y, uint8 c0, uint8 c1, uint8 c2, Screen::FontId font) { - debugC(9, kDebugLevelMain, "TextDisplayer_v3::printText('%s', %d, %d, %d, %d, %d)", str, x, y, c0, c1, c2); - uint8 colorMap[] = { 0, 255, 240, 240 }; - colorMap[3] = c1; - _screen->setTextColor(colorMap, 0, 3); - Screen::FontId curFont = _screen->setFont(font); - _screen->_charWidth = -2; - _screen->printText(str, x, y, c0, c2); - _screen->_charWidth = 0; - _screen->setFont(curFont); -} - -void TextDisplayer_v3::restoreScreen() { - debugC(9, kDebugLevelMain, "TextDisplayer_v3::restoreScreen()"); - _vm->restorePage3(); - _vm->drawAnimObjects(); - _screen->hideMouse(); - _screen->copyRegion(_talkCoords.x, _talkMessageY, _talkCoords.x, _talkMessageY, _talkCoords.w, _talkMessageH, 2, 0, Screen::CR_NO_P_CHECK); - _screen->showMouse(); - _vm->flagAnimObjsForRefresh(); - _vm->refreshAnimObjects(0); -} - -void TextDisplayer_v3::calcWidestLineBounds(int &x1, int &x2, int w, int x) { - debugC(9, kDebugLevelMain, "TextDisplayer_v3::calcWidestLineBounds(%d, %d)", w, x); - x1 = x; - x1 -= (w >> 1); - x2 = x1 + w + 1; - - if (x1 + w >= 311) - x1 = 311 - w - 1; - - if (x1 < 8) - x1 = 8; - - x2 = x1 + w + 1; -} - -#pragma mark - - -int KyraEngine_v3::chatGetType(const char *str) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::chatGetType('%s')", str); - while (*str) - ++str; - --str; - switch (*str) { - case '!': - return 2; - - case ')': - return 3; - - case '?': - return 1; - - case '.': - default: - return 0; - } -} - -int KyraEngine_v3::chatCalcDuration(const char *str) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::chatCalcDuration('%s')", str); - return MAX(120, strlen(str)*6); -} - -void KyraEngine_v3::objectChat(const char *str, int object, int vocHigh, int vocLow) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::objectChat('%s', %d, %d, %d)", str, object, vocHigh, vocLow); - - if (_mainCharacter.animFrame == 87 || _mainCharacter.animFrame == 0xFFFF || _mainCharacter.x1 <= 0 || _mainCharacter.y1 <= 0) - return; - - _chatVocLow = _chatVocHigh = -1; - objectChatInit(str, object, vocHigh, vocLow); - _chatText = str; - _chatObject = object; - int chatType = chatGetType(str); - - if (_mainCharacter.facing > 7) - _mainCharacter.facing = 5; - - static const uint8 talkScriptTable[] = { - 0x10, 0x11, 0x12, 0x13, - 0x0C, 0x0D, 0x0E, 0x0F, - 0x0C, 0x0D, 0x0E, 0x0F, - 0x04, 0x05, 0x06, 0x07, - 0x00, 0x01, 0x02, 0x03, - 0x00, 0x01, 0x02, 0x03, - 0x08, 0x09, 0x0A, 0x0B, - 0x08, 0x09, 0x0A, 0x0B - }; - - static const char *talkFilenameTable[] = { - "MTFL00S.EMC", "MTFL00Q.EMC", "MTFL00E.EMC", "MTFL00T.EMC", - "MTFR00S.EMC", "MTFR00Q.EMC", "MTFR00E.EMC", "MTFR00T.EMC", - "MTL00S.EMC", "MTL00Q.EMC", "MTL00E.EMC", "MTL00T.EMC", - "MTR00S.EMC", "MTR00Q.EMC", "MTR00E.EMC", "MTR00T.EMC", - "MTA00S.EMC", "MTA00Q.EMC", "MTA00Q.EMC", "MTA00T.EMC" - }; - - int chat = talkScriptTable[chatType + _mainCharacter.facing * 4]; - objectChatProcess(talkFilenameTable[chat]); - _text->restoreScreen(); - _mainCharacter.animFrame = _characterFrameTable[_mainCharacter.facing]; - updateCharacterAnim(0); - _chatText = 0; - _chatObject = -1; - setNextIdleAnimTimer(); -} - -void KyraEngine_v3::objectChatInit(const char *str, int object, int vocHigh, int vocLow) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::objectChatInit('%s', %d, %d, %d)", str, object, vocHigh, vocLow); - str = _text->preprocessString(str); - int lineNum = _text->buildMessageSubstrings(str); - - int xPos = 0, yPos = 0; - - if (!object) { - int scale = getScale(_mainCharacter.x1, _mainCharacter.y1); - yPos = _mainCharacter.y1 - ((_mainCharacter.height * scale) >> 8) - 8; - xPos = _mainCharacter.x1; - } else { - yPos = _talkObjectList[object].y; - xPos = _talkObjectList[object].x; - } - - yPos -= lineNum * 10; - yPos = MAX(yPos, 0); - _text->_talkMessageY = yPos; - _text->_talkMessageH = lineNum*10; - - int width = _text->getWidestLineWidth(lineNum); - _text->calcWidestLineBounds(xPos, yPos, width, xPos); - _text->_talkCoords.x = xPos; - _text->_talkCoords.w = width + 2; - - restorePage3(); - - _screen->hideMouse(); - - if (textEnabled()) { - objectChatPrintText(str, object); - _chatEndTime = _system->getMillis() + chatCalcDuration(str) * _tickLength; - } else { - _chatEndTime = _system->getMillis(); - } - - if (speechEnabled()) { - _chatVocHigh = vocHigh; - _chatVocLow = vocLow; - } else { - _chatVocHigh = _chatVocLow = -1; - } - - _screen->showMouse(); -} - -void KyraEngine_v3::objectChatPrintText(const char *str, int object) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::objectChatPrintText('%s', %d)", str, object); - int c1 = _talkObjectList[object].color; - str = _text->preprocessString(str); - int lineNum = _text->buildMessageSubstrings(str); - int maxWidth = _text->getWidestLineWidth(lineNum); - int x = (object == 0) ? _mainCharacter.x1 : _talkObjectList[object].x; - int cX1 = 0, cX2 = 0; - _text->calcWidestLineBounds(cX1, cX2, maxWidth, x); - - for (int i = 0; i < lineNum; ++i) { - str = &_text->_talkSubstrings[i*_text->maxSubstringLen()]; - - int y = _text->_talkMessageY + i * 10; - x = _text->getCenterStringX(str, cX1, cX2); - - _text->printText(str, x, y, c1, 0xF0, 0); - } -} - -void KyraEngine_v3::objectChatProcess(const char *script) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::objectChatProcess('%s')", script); - - memset(&_chatScriptData, 0, sizeof(_chatScriptData)); - memset(&_chatScriptState, 0, sizeof(_chatScriptState)); - - _emc->load(script, &_chatScriptData, &_opcodesTemporary); - _emc->init(&_chatScriptState, &_chatScriptData); - _emc->start(&_chatScriptState, 0); - while (_emc->isValid(&_chatScriptState)) - _emc->run(&_chatScriptState); - - if (_chatVocHigh >= 0) { - playVoice(_chatVocHigh, _chatVocLow); - _chatVocHigh = _chatVocLow = -1; - } - - _useFrameTable = true; - objectChatWaitToFinish(); - _useFrameTable = false; - - _emc->unload(&_chatScriptData); -} - -void KyraEngine_v3::objectChatWaitToFinish() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::objectChatWaitToFinish()"); - int charAnimFrame = _mainCharacter.animFrame; - setCharacterAnimDim(_newShapeWidth, _newShapeHeight); - - _emc->init(&_chatScriptState, &_chatScriptData); - _emc->start(&_chatScriptState, 1); - - bool running = true; - const uint32 endTime = _chatEndTime; - resetSkipFlag(); - - while (running && !_quitFlag) { - if (!_emc->isValid(&_chatScriptState)) - _emc->start(&_chatScriptState, 1); - - _temporaryScriptExecBit = false; - while (!_temporaryScriptExecBit && _emc->isValid(&_chatScriptState)) { - musicUpdate(0); - _emc->run(&_chatScriptState); - } - - int curFrame = _newShapeAnimFrame; - uint32 delayTime = _newShapeDelay; - - _mainCharacter.animFrame = curFrame; - updateCharacterAnim(0); - - uint32 nextFrame = _system->getMillis() + delayTime * _tickLength; - - while (_system->getMillis() < nextFrame && !_quitFlag) { - updateWithText(); - - const uint32 curTime = _system->getMillis(); - if ((textEnabled() && !speechEnabled() && curTime > endTime) || (speechEnabled() && !snd_voiceIsPlaying()) || skipFlag()) { - snd_stopVoice(); - resetSkipFlag(); - nextFrame = curTime; - running = false; - } - - delay(10); - } - } - - _mainCharacter.animFrame = charAnimFrame; - updateCharacterAnim(0); - resetCharacterAnimDim(); -} - -void KyraEngine_v3::badConscienceChat(const char *str, int vocHigh, int vocLow) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::badConscienceChat('%s', %d, %d)", str, vocHigh, vocLow); - if (!_badConscienceShown) - return; - - setNextIdleAnimTimer(); - _chatVocHigh = _chatVocLow = -1; - objectChatInit(str, 1, vocHigh, vocLow); - _chatText = str; - _chatObject = 1; - badConscienceChatWaitToFinish(); - updateSceneAnim(0x0E, _badConscienceFrameTable[_badConscienceAnim+16]); - _text->restoreScreen(); - update(); - _chatText = 0; - _chatObject = -1; -} - -void KyraEngine_v3::badConscienceChatWaitToFinish() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::badConscienceChatWaitToFinish()"); - if (_chatVocHigh) { - playVoice(_chatVocHigh, _chatVocLow); - _chatVocHigh = _chatVocLow = -1; - } - - bool running = true; - const uint32 endTime = _chatEndTime; - resetSkipFlag(); - - uint32 nextFrame = _system->getMillis() + _rnd.getRandomNumberRng(4, 8) * _tickLength; - - int frame = _badConscienceFrameTable[_badConscienceAnim+24]; - while (running && !_quitFlag) { - if (nextFrame < _system->getMillis()) { - ++frame; - if (_badConscienceFrameTable[_badConscienceAnim+32] < frame) - frame = _badConscienceFrameTable[_badConscienceAnim+24]; - - updateSceneAnim(0x0E, frame); - updateWithText(); - - nextFrame = _system->getMillis() + _rnd.getRandomNumberRng(4, 8) * _tickLength; - } - - updateWithText(); - - const uint32 curTime = _system->getMillis(); - if ((textEnabled() && !speechEnabled() && curTime > endTime) || (speechEnabled() && !snd_voiceIsPlaying()) || skipFlag()) { - snd_stopVoice(); - resetSkipFlag(); - nextFrame = curTime; - running = false; - } - - delay(10); - } -} - -void KyraEngine_v3::goodConscienceChat(const char *str, int vocHigh, int vocLow) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::goodConscienceChat('%s', %d, %d)", str, vocHigh, vocLow); - if (!_goodConscienceShown) - return; - - setNextIdleAnimTimer(); - _chatVocHigh = _chatVocLow = -1; - objectChatInit(str, 87, vocHigh, vocLow); - _chatText = str; - _chatObject = 87; - goodConscienceChatWaitToFinish(); - updateSceneAnim(0x0F, _goodConscienceFrameTable[_goodConscienceAnim+10]); - _text->restoreScreen(); - update(); - _chatText = 0; - _chatObject = -1; -} - -void KyraEngine_v3::goodConscienceChatWaitToFinish() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::goodConscienceChatWaitToFinish()"); - if (_chatVocHigh) { - playVoice(_chatVocHigh, _chatVocLow); - _chatVocHigh = _chatVocLow = -1; - } - - bool running = true; - const uint32 endTime = _chatEndTime; - resetSkipFlag(); - - uint32 nextFrame = _system->getMillis() + _rnd.getRandomNumberRng(3, 6) * _tickLength; - - int frame = _goodConscienceFrameTable[_goodConscienceAnim+15]; - while (running && !_quitFlag) { - if (nextFrame < _system->getMillis()) { - ++frame; - if (_goodConscienceFrameTable[_goodConscienceAnim+20] < frame) - frame = _goodConscienceFrameTable[_goodConscienceAnim+15]; - - updateSceneAnim(0x0F, frame); - updateWithText(); - - nextFrame = _system->getMillis() + _rnd.getRandomNumberRng(3, 6) * _tickLength; - } - - updateWithText(); - - const uint32 curTime = _system->getMillis(); - if ((textEnabled() && !speechEnabled() && curTime > endTime) || (speechEnabled() && !snd_voiceIsPlaying()) || skipFlag()) { - snd_stopVoice(); - resetSkipFlag(); - nextFrame = curTime; - running = false; - } - - delay(10); - } -} - -void KyraEngine_v3::malcolmSceneStartupChat() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::malcolmSceneStartupChat()"); - - if (_noStartupChat) - return; - - int index = _mainCharacter.sceneId - _chapterLowestScene[_currentChapter]; - if (_newSceneDlgState[index]) - return; - - updateDlgBuffer(); - int vocHighBase = 0, vocHighIndex = 0, index1 = 0, index2 = 0; - loadDlgHeader(vocHighBase, vocHighIndex, index1, index2); - - _cnvFile->seek(index1*6, SEEK_CUR); - _cnvFile->seek(index2*4, SEEK_CUR); - _cnvFile->seek(index*2, SEEK_CUR); - _cnvFile->seek(_cnvFile->readUint16LE(), SEEK_SET); - - _isStartupDialog = true; - processDialog(vocHighIndex, vocHighBase, 0); - _isStartupDialog = false; - _newSceneDlgState[index] = true; -} - -void KyraEngine_v3::updateDlgBuffer() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::updateDlgBuffer()"); - char dlgFile[16]; - char cnvFile[16]; - - if (_cnvFile) - _cnvFile->seek(0, SEEK_SET); - - if (_curDlgIndex == _mainCharacter.dlgIndex && _curDlgChapter == _currentChapter && _curDlgLang == _lang) - return; - - snprintf(dlgFile, 16, "CH%.02d-S%.02d.", _currentChapter, _mainCharacter.dlgIndex); - appendLanguage(dlgFile, _lang, 16); - snprintf(cnvFile, 16, "CH%.02d-S%.02d.CNV", _currentChapter, _mainCharacter.dlgIndex); - - delete _cnvFile; - delete _dlgBuffer; - - _res->exists(cnvFile, true); - _res->exists(dlgFile, true); - _cnvFile = _res->getFileStream(cnvFile); - _dlgBuffer = _res->getFileStream(dlgFile); - assert(_cnvFile); - assert(_dlgBuffer); -} - -void KyraEngine_v3::loadDlgHeader(int &vocHighBase, int &vocHighIndex, int &index1, int &index2) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::loadDlgHeader(-, -, -, -)"); - assert(_cnvFile); - vocHighIndex = _cnvFile->readSint16LE(); - vocHighBase = _cnvFile->readSint16LE(); - index1 = _cnvFile->readSint16LE(); - index2 = _cnvFile->readSint16LE(); -} - -void KyraEngine_v3::setDlgIndex(uint16 index) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::setDlgIndex(%d)", index); - if (_mainCharacter.dlgIndex != index) { - Common::set_to(_newSceneDlgState, _newSceneDlgState+ARRAYSIZE(_newSceneDlgState), 0); - memset(_conversationState, -1, sizeof(_conversationState)); - _chatAltFlag = false; - _mainCharacter.dlgIndex = index; - } -} - -void KyraEngine_v3::updateDlgIndex() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::updateDlgIndex()"); - uint16 dlgIndex = _mainCharacter.dlgIndex; - - if (_currentChapter == 1) { - static const uint8 dlgIndexMoodNice[] = { 0x0C, 0x0E, 0x10, 0x0F, 0x11 }; - static const uint8 dlgIndexMoodNormal[] = { 0x00, 0x02, 0x04, 0x03, 0x05 }; - static const uint8 dlgIndexMoodEvil[] = { 0x06, 0x08, 0x0A, 0x09, 0x0B }; - - if (_malcolmsMood == 0) - dlgIndex = dlgIndexMoodNice[_malcolmShapes]; - else if (_malcolmsMood == 1) - dlgIndex = dlgIndexMoodNormal[_malcolmShapes]; - else if (_malcolmsMood == 2) - dlgIndex = dlgIndexMoodEvil[_malcolmShapes]; - } else if (_currentChapter == 2) { - if (dlgIndex >= 8) - dlgIndex -= 4; - if (dlgIndex >= 4) - dlgIndex -= 4; - - if (_malcolmsMood == 0) - dlgIndex += 8; - else if (_malcolmsMood == 2) - dlgIndex += 4; - } else if (_currentChapter == 4) { - if (dlgIndex >= 10) - dlgIndex -= 5; - if (dlgIndex >= 5) - dlgIndex -= 5; - - if (_malcolmsMood == 0) - dlgIndex += 10; - else if (_malcolmsMood == 2) - dlgIndex += 5; - } - - _mainCharacter.dlgIndex = dlgIndex; -} - -void KyraEngine_v3::processDialog(int vocHighIndex, int vocHighBase, int funcNum) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::processDialog(%d, %d, %d)", vocHighIndex, vocHighBase, funcNum); - bool running = true; - int script = -1; - int vocHigh = -1, vocLow = -1; - - while (running) { - uint16 cmd = _cnvFile->readUint16LE(); - int object = cmd - 12; - - if (cmd == 10) { - break; - } else if (cmd == 4) { - vocHighBase = _cnvFile->readUint16LE(); - setDlgIndex(vocHighBase); - } else if (cmd == 11) { - int strSize = _cnvFile->readUint16LE(); - vocLow = _cnvFile->readUint16LE(); - _cnvFile->read(_stringBuffer, strSize); - _stringBuffer[strSize] = 0; - } else { - vocHigh = _vocHighTable[vocHighIndex-1] + vocHighBase; - vocLow = _cnvFile->readUint16LE(); - getTableEntry(_dlgBuffer, vocLow, _stringBuffer); - - if (_isStartupDialog) { - delay(60*_tickLength, true); - _isStartupDialog = false; - } - - if (*_stringBuffer == 0) - continue; - - if (cmd != 12) { - if (object != script) { - if (script >= 0) { - dialogEndScript(script); - script = -1; - } - - dialogStartScript(object, funcNum); - script = object; - } - - npcChatSequence(_stringBuffer, object, vocHigh, vocLow); - } else { - if (script >= 0) { - dialogEndScript(script); - script = -1; - } - - objectChat(_stringBuffer, 0, vocHigh, vocLow); - playStudioSFX(_stringBuffer); - } - } - } - - if (script != -1) - dialogEndScript(script); -} - -void KyraEngine_v3::dialogStartScript(int object, int funcNum) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::dialogStartScript(%d, %d)", object, funcNum); - _dialogSceneAnim = _talkObjectList[object].sceneAnim; - _dialogSceneScript = _talkObjectList[object].sceneScript; - if (_dialogSceneAnim >= 0 && _dialogSceneScript >= 0) { - _specialSceneScriptStateBackup[_dialogSceneScript] = _specialSceneScriptState[_dialogSceneScript]; - _specialSceneScriptState[_dialogSceneScript] = true; - } - - _emc->init(&_dialogScriptState, &_dialogScriptData); - _emc->load(_talkObjectList[object].filename, &_dialogScriptData, &_opcodesDialog); - - _dialogScriptFuncStart = funcNum * 3 + 0; - _dialogScriptFuncProc = funcNum * 3 + 1; - _dialogScriptFuncEnd = funcNum * 3 + 2; - - _emc->start(&_dialogScriptState, _dialogScriptFuncStart); - while (_emc->isValid(&_dialogScriptState)) - _emc->run(&_dialogScriptState); -} - -void KyraEngine_v3::dialogEndScript(int object) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::dialogEndScript(%d)", object); - - _emc->init(&_dialogScriptState, &_dialogScriptData); - _emc->start(&_dialogScriptState, _dialogScriptFuncEnd); - - while (_emc->isValid(&_dialogScriptState)) - _emc->run(&_dialogScriptState); - - if (_dialogSceneAnim >= 0 && _dialogSceneScript >= 0) { - _specialSceneScriptState[_dialogSceneScript] = _specialSceneScriptStateBackup[_dialogSceneScript]; - _dialogSceneScript = _dialogSceneAnim = -1; - } - - _emc->unload(&_dialogScriptData); -} - -void KyraEngine_v3::npcChatSequence(const char *str, int object, int vocHigh, int vocLow) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::npcChatSequence('%s', %d, %d, %d)", str, object, vocHigh, vocLow); - - _chatText = str; - _chatObject = object; - _chatVocHigh = _chatVocLow = -1; - - objectChatInit(str, object, vocHigh, vocLow); - - if (_chatVocHigh >= 0 && _chatVocLow >= 0) { - playVoice(_chatVocHigh, _chatVocLow); - _chatVocHigh = _chatVocLow = -1; - } - - _emc->init(&_dialogScriptState, &_dialogScriptData); - _emc->start(&_dialogScriptState, _dialogScriptFuncProc); - - resetSkipFlag(); - - uint32 endTime = _chatEndTime; - bool running = true; - while (running) { - if (!_emc->run(&_dialogScriptState)) { - _emc->init(&_dialogScriptState, &_dialogScriptData); - _emc->start(&_dialogScriptState, _dialogScriptFuncProc); - } - - const uint32 curTime = _system->getMillis(); - if ((textEnabled() && !speechEnabled() && curTime > endTime) || (speechEnabled() && !snd_voiceIsPlaying()) || skipFlag()) { - snd_stopVoice(); - resetSkipFlag(); - running = false; - } - - delay(10); - } - _text->restoreScreen(); - _chatText = 0; - _chatObject= - 1; -} - -void KyraEngine_v3::malcolmRandomChat() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::malcolmRandomChat()"); - updateDlgBuffer(); - - int index = (_mainCharacter.sceneId - _chapterLowestScene[_currentChapter]) * 2; - - int vocHighBase = 0, vocHighIndex = 0, index1 = 0, index2 = 0; - loadDlgHeader(vocHighBase, vocHighIndex, index1, index2); - - if (_chatAltFlag) - index++; - _chatAltFlag = !_chatAltFlag; - - _cnvFile->seek(index1*6, SEEK_CUR); - _cnvFile->seek(index*2, SEEK_CUR); - _cnvFile->seek(_cnvFile->readUint16LE(), SEEK_SET); - - processDialog(vocHighIndex, vocHighBase, 0); -} - -void KyraEngine_v3::runDialog(int dlgIndex, int funcNum) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::runDialog(%d, %d)", dlgIndex, funcNum); - - switch (_currentChapter-2) { - case 0: - dlgIndex -= 34; - break; - - case 1: - dlgIndex -= 54; - break; - - case 2: - dlgIndex -= 55; - break; - - case 3: - dlgIndex -= 70; - break; - - default: - break; - } - - updateDlgBuffer(); - - int vocHighBase = 0, vocHighIndex = 0, index1 = 0, index2 = 0; - loadDlgHeader(vocHighBase, vocHighIndex, index1, index2); - - int convState = _conversationState[dlgIndex][vocHighBase]; - uint32 offset = ((vocHighIndex == 1) ? dlgIndex - 1 : dlgIndex) * 6; - if (convState == -1) { - _cnvFile->seek(offset, SEEK_CUR); - _conversationState[dlgIndex][vocHighBase] = 0; - } else if (convState == 0 || convState == 2) { - _cnvFile->seek(offset+2, SEEK_CUR); - _conversationState[dlgIndex][vocHighBase] = 1; - } else { - _cnvFile->seek(offset+4, SEEK_CUR); - _conversationState[dlgIndex][vocHighBase] = 2; - } - - _cnvFile->seek(_cnvFile->readUint16LE(), SEEK_SET); - - processDialog(vocHighIndex, vocHighBase, funcNum); -} - -} // end of namespace Kyra - diff --git a/engines/kyra/text_v3.h b/engines/kyra/text_v3.h deleted file mode 100644 index 9271c6b520..0000000000 --- a/engines/kyra/text_v3.h +++ /dev/null @@ -1,55 +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_TEXT_V3_H -#define KYRA_TEXT_V3_H - -#include "kyra/text.h" - -#include "kyra/kyra_v3.h" - -namespace Kyra { - -class TextDisplayer_v3 : public TextDisplayer { -friend class KyraEngine_v3; -public: - TextDisplayer_v3(KyraEngine_v3 *vm, Screen_v3 *screen); - - char *preprocessString(const char *str); - int dropCRIntoString(char *str, int minOffs, int maxOffs); - - void printText(const char *str, int x, int y, uint8 c0, uint8 c1, uint8 c2, Screen::FontId font=Screen::FID_8_FNT); - - void restoreScreen(); - - void calcWidestLineBounds(int &x1, int &x2, int w, int x); -protected: - KyraEngine_v3 *_vm; - Screen_v3 *_screen; -}; - -} // end of namespace Kyra - -#endif diff --git a/engines/kyra/timer_hof.cpp b/engines/kyra/timer_hof.cpp new file mode 100644 index 0000000000..a96717bdb3 --- /dev/null +++ b/engines/kyra/timer_hof.cpp @@ -0,0 +1,121 @@ +/* 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_hof.h" +#include "kyra/timer.h" + +namespace Kyra { + +#define TimerV2(x) new Common::Functor1Mem(this, &KyraEngine_HoF::x) + +void KyraEngine_HoF::setupTimers() { + debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_HoF::setupTimers()"); + + _timer->addTimer(0, 0, 5, 1); + _timer->addTimer(1, TimerV2(timerFadeOutMessage), -1, 1); + _timer->addTimer(2, TimerV2(timerCauldronAnimation), 1, 1); + _timer->addTimer(3, TimerV2(timerFunc4), 1, 0); + _timer->addTimer(4, TimerV2(timerFunc5), 1, 0); + _timer->addTimer(5, TimerV2(timerBurnZanthia), 1, 0); +} + +void KyraEngine_HoF::timerFadeOutMessage(int arg) { + debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_HoF::timerFadeOutMessage(%d)", arg); + if (_shownMessage) + _fadeMessagePalette = 1; +} + +void KyraEngine_HoF::timerCauldronAnimation(int arg) { + debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_HoF::timerCauldronAnimation(%d)", arg); + int animation = -1; + + // HACK: We don't allow inventory animations while the inventory is backed off, which means not shown usually. + // This prevents for example that the cauldron animation is shown in the meanwhile scene with Marco and the Hand in Chapter 2. + if (_inventorySaved) + return; + + if (queryGameFlag(2) && _mainCharacter.sceneId != 34 && _mainCharacter.sceneId != 73 && !_invWsa.wsa && !_invWsa.running) { + if (animation == -1) + animation = _rnd.getRandomNumberRng(1, 6); + + char filename[13]; + strcpy(filename, "CAULD00.WSA"); + filename[5] = (animation / 10) + '0'; + filename[6] = (animation % 10) + '0'; + loadInvWsa(filename, 0, 8, 0, -1, -1, 1); + } +} + +void KyraEngine_HoF::timerFunc4(int arg) { + debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_HoF::timerFunc4(%d)", arg); + _timer->disable(3); + setGameFlag(0xD8); +} + +void KyraEngine_HoF::timerFunc5(int arg) { + debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_HoF::timerFunc5(%d)", arg); + _timer->disable(4); + _screen->hideMouse(); + _specialSceneScriptState[5] = 1; + for (int i = 68; i <= 75; ++i) { + updateSceneAnim(4, i); + delay(6); + } + _deathHandler = 4; +} + +void KyraEngine_HoF::timerBurnZanthia(int arg) { + debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_HoF::timerBurnZanthia(%d)", arg); + _timer->disable(5); + _screen->hideMouse(); + snd_playSoundEffect(0x2D); + runTemporaryScript("_ZANBURN.EMC", 0, 1, 1, 0); + _deathHandler = 7; + snd_playWanderScoreViaMap(0x53, 1); +} + +void KyraEngine_HoF::setTimer1DelaySecs(int secs) { + debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_HoF::setTimer1DelaySecs(%d)", secs); + + if (secs == -1) + secs = 32000; + + _timer->setCountdown(1, secs * 60); +} + +void KyraEngine_HoF::setWalkspeed(uint8 newSpeed) { + debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_HoF::setWalkspeed(%i)", newSpeed); + + if (newSpeed < 5) + newSpeed = 3; + else + newSpeed = 5; + + _configWalkspeed = newSpeed; + _timer->setDelay(0, newSpeed); +} + + +} // end of namespace Kyra diff --git a/engines/kyra/timer_mr.cpp b/engines/kyra/timer_mr.cpp new file mode 100644 index 0000000000..53865ba0e3 --- /dev/null +++ b/engines/kyra/timer_mr.cpp @@ -0,0 +1,93 @@ +/* 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_mr.h" +#include "kyra/timer.h" + +namespace Kyra { + +#define TimerV3(x) new Common::Functor1Mem(this, &KyraEngine_MR::x) + +void KyraEngine_MR::setupTimers() { + debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_MR::setupTimers()"); + + _timer->addTimer(0, TimerV3(timerRestoreCommandLine), -1, 1); + for (int i = 1; i <= 3; ++i) + _timer->addTimer(i, TimerV3(timerRunSceneScript7), -1, 0); + _timer->addTimer(4, TimerV3(timerFleaDeath), -1, 0); + for (int i = 5; i <= 11; ++i) + _timer->addTimer(i, TimerV3(timerRunSceneScript7), -1, 0); + for (int i = 12; i <= 13; ++i) + _timer->addTimer(i, TimerV3(timerRunSceneScript7), 0, 0); +} + +void KyraEngine_MR::timerRestoreCommandLine(int arg) { + debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_MR::timerRestoreCommandLine(%d)", arg); + if (_shownMessage) + _restoreCommandLine = true; +} + +void KyraEngine_MR::timerRunSceneScript7(int arg) { + debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_MR::timerRunSceneScript7(%d)", arg); + _emc->init(&_sceneScriptState, &_sceneScriptData); + _sceneScriptState.regs[1] = _mouseX; + _sceneScriptState.regs[2] = _mouseY; + _sceneScriptState.regs[3] = 0; + _sceneScriptState.regs[4] = _itemInHand; + _emc->start(&_sceneScriptState, 7); + + while (_emc->isValid(&_sceneScriptState)) + _emc->run(&_sceneScriptState); +} + +void KyraEngine_MR::timerFleaDeath(int arg) { + debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_MR::timerFleaDeath(%d)", arg); + warning("STUB timerFleaDeath"); +} + +void KyraEngine_MR::setWalkspeed(uint8 speed) { + debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_MR::setWalkspeed(%d)", speed); + + if (speed < 5) + speed = 3; + else + speed = 5; + + _mainCharacter.walkspeed = speed; +} + +void KyraEngine_MR::setCommandLineRestoreTimer(int secs) { + debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_MR::setCommandLineRestoreTimer(%d)", secs); + if (secs == -1) + secs = 32000; + _timer->setCountdown(0, secs*60); +} + +void KyraEngine_MR::setNextIdleAnimTimer() { + debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_MR::setNextIdleAnimTimer()"); + _nextIdleAnim = _system->getMillis() + _rnd.getRandomNumberRng(10, 15) * 1000; +} + +} // end of namespace Kyra diff --git a/engines/kyra/timer_v2.cpp b/engines/kyra/timer_v2.cpp deleted file mode 100644 index 4c97a6dd2d..0000000000 --- a/engines/kyra/timer_v2.cpp +++ /dev/null @@ -1,121 +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_v2.h" -#include "kyra/timer.h" - -namespace Kyra { - -#define TimerV2(x) new Common::Functor1Mem(this, &KyraEngine_v2::x) - -void KyraEngine_v2::setupTimers() { - debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v2::setupTimers()"); - - _timer->addTimer(0, 0, 5, 1); - _timer->addTimer(1, TimerV2(timerFadeOutMessage), -1, 1); - _timer->addTimer(2, TimerV2(timerCauldronAnimation), 1, 1); - _timer->addTimer(3, TimerV2(timerFunc4), 1, 0); - _timer->addTimer(4, TimerV2(timerFunc5), 1, 0); - _timer->addTimer(5, TimerV2(timerBurnZanthia), 1, 0); -} - -void KyraEngine_v2::timerFadeOutMessage(int arg) { - debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v2::timerFadeOutMessage(%d)", arg); - if (_shownMessage) - _fadeMessagePalette = 1; -} - -void KyraEngine_v2::timerCauldronAnimation(int arg) { - debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v2::timerCauldronAnimation(%d)", arg); - int animation = -1; - - // HACK: We don't allow inventory animations while the inventory is backed off, which means not shown usually. - // This prevents for example that the cauldron animation is shown in the meanwhile scene with Marco and the Hand in Chapter 2. - if (_inventorySaved) - return; - - if (queryGameFlag(2) && _mainCharacter.sceneId != 34 && _mainCharacter.sceneId != 73 && !_invWsa.wsa && !_invWsa.running) { - if (animation == -1) - animation = _rnd.getRandomNumberRng(1, 6); - - char filename[13]; - strcpy(filename, "CAULD00.WSA"); - filename[5] = (animation / 10) + '0'; - filename[6] = (animation % 10) + '0'; - loadInvWsa(filename, 0, 8, 0, -1, -1, 1); - } -} - -void KyraEngine_v2::timerFunc4(int arg) { - debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v2::timerFunc4(%d)", arg); - _timer->disable(3); - setGameFlag(0xD8); -} - -void KyraEngine_v2::timerFunc5(int arg) { - debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v2::timerFunc5(%d)", arg); - _timer->disable(4); - _screen->hideMouse(); - _specialSceneScriptState[5] = 1; - for (int i = 68; i <= 75; ++i) { - updateSceneAnim(4, i); - delay(6); - } - _deathHandler = 4; -} - -void KyraEngine_v2::timerBurnZanthia(int arg) { - debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v2::timerBurnZanthia(%d)", arg); - _timer->disable(5); - _screen->hideMouse(); - snd_playSoundEffect(0x2D); - runTemporaryScript("_ZANBURN.EMC", 0, 1, 1, 0); - _deathHandler = 7; - snd_playWanderScoreViaMap(0x53, 1); -} - -void KyraEngine_v2::setTimer1DelaySecs(int secs) { - debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v2::setTimer1DelaySecs(%d)", secs); - - if (secs == -1) - secs = 32000; - - _timer->setCountdown(1, secs * 60); -} - -void KyraEngine_v2::setWalkspeed(uint8 newSpeed) { - debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v2::setWalkspeed(%i)", newSpeed); - - if (newSpeed < 5) - newSpeed = 3; - else - newSpeed = 5; - - _configWalkspeed = newSpeed; - _timer->setDelay(0, newSpeed); -} - - -} // end of namespace Kyra diff --git a/engines/kyra/timer_v3.cpp b/engines/kyra/timer_v3.cpp deleted file mode 100644 index 5688895758..0000000000 --- a/engines/kyra/timer_v3.cpp +++ /dev/null @@ -1,93 +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_v3.h" -#include "kyra/timer.h" - -namespace Kyra { - -#define TimerV3(x) new Common::Functor1Mem(this, &KyraEngine_v3::x) - -void KyraEngine_v3::setupTimers() { - debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v3::setupTimers()"); - - _timer->addTimer(0, TimerV3(timerRestoreCommandLine), -1, 1); - for (int i = 1; i <= 3; ++i) - _timer->addTimer(i, TimerV3(timerRunSceneScript7), -1, 0); - _timer->addTimer(4, TimerV3(timerFleaDeath), -1, 0); - for (int i = 5; i <= 11; ++i) - _timer->addTimer(i, TimerV3(timerRunSceneScript7), -1, 0); - for (int i = 12; i <= 13; ++i) - _timer->addTimer(i, TimerV3(timerRunSceneScript7), 0, 0); -} - -void KyraEngine_v3::timerRestoreCommandLine(int arg) { - debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v3::timerRestoreCommandLine(%d)", arg); - if (_shownMessage) - _restoreCommandLine = true; -} - -void KyraEngine_v3::timerRunSceneScript7(int arg) { - debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v3::timerRunSceneScript7(%d)", arg); - _emc->init(&_sceneScriptState, &_sceneScriptData); - _sceneScriptState.regs[1] = _mouseX; - _sceneScriptState.regs[2] = _mouseY; - _sceneScriptState.regs[3] = 0; - _sceneScriptState.regs[4] = _itemInHand; - _emc->start(&_sceneScriptState, 7); - - while (_emc->isValid(&_sceneScriptState)) - _emc->run(&_sceneScriptState); -} - -void KyraEngine_v3::timerFleaDeath(int arg) { - debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v3::timerFleaDeath(%d)", arg); - warning("STUB timerFleaDeath"); -} - -void KyraEngine_v3::setWalkspeed(uint8 speed) { - debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v3::setWalkspeed(%d)", speed); - - if (speed < 5) - speed = 3; - else - speed = 5; - - _mainCharacter.walkspeed = speed; -} - -void KyraEngine_v3::setCommandLineRestoreTimer(int secs) { - debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v3::setCommandLineRestoreTimer(%d)", secs); - if (secs == -1) - secs = 32000; - _timer->setCountdown(0, secs*60); -} - -void KyraEngine_v3::setNextIdleAnimTimer() { - debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v3::setNextIdleAnimTimer()"); - _nextIdleAnim = _system->getMillis() + _rnd.getRandomNumberRng(10, 15) * 1000; -} - -} // end of namespace Kyra diff --git a/engines/kyra/wsamovie.cpp b/engines/kyra/wsamovie.cpp index 9da75ed20c..764327d701 100644 --- a/engines/kyra/wsamovie.cpp +++ b/engines/kyra/wsamovie.cpp @@ -32,6 +32,7 @@ #include "kyra/screen.h" #include "kyra/screen_v2.h" #include "kyra/wsamovie.h" +#include "kyra/resource.h" namespace Kyra { WSAMovieV1::WSAMovieV1(KyraEngine *vm) : Movie(vm) {} @@ -341,7 +342,7 @@ void WSAMovieAmiga::processFrame(int frameNum, uint8 *dst) { #pragma mark - -WSAMovieV2::WSAMovieV2(KyraEngine *vm, ScreenEx *screen) : WSAMovieV1(vm), _screen(screen), _xAdd(0), _yAdd(0) {} +WSAMovieV2::WSAMovieV2(KyraEngine *vm, Screen_v2 *screen) : WSAMovieV1(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); diff --git a/engines/kyra/wsamovie.h b/engines/kyra/wsamovie.h index ad577f7029..d1f3465c07 100644 --- a/engines/kyra/wsamovie.h +++ b/engines/kyra/wsamovie.h @@ -26,8 +26,6 @@ #ifndef KYRA_WSAMOVIE_H #define KYRA_WSAMOVIE_H -#include "kyra/resource.h" - namespace Audio { class AppendableAudioStream; class SoundHandle; @@ -35,7 +33,7 @@ class SoundHandle; namespace Kyra { class KyraEngine; -class ScreenEx; +class Screen_v2; class Movie { public: @@ -111,7 +109,7 @@ private: class WSAMovieV2 : public WSAMovieV1 { public: - WSAMovieV2(KyraEngine *vm, ScreenEx *scren); + WSAMovieV2(KyraEngine *vm, Screen_v2 *scren); int open(const char *filename, int unk1, uint8 *palette); @@ -129,7 +127,7 @@ public: void setWidth(int w) { _width = w; } void setHeight(int h) { _height = h; } protected: - ScreenEx *_screen; + Screen_v2 *_screen; int16 _xAdd; int16 _yAdd; -- cgit v1.2.3