diff options
Diffstat (limited to 'engines/kyra')
75 files changed, 17056 insertions, 15061 deletions
diff --git a/engines/kyra/animator_hof.cpp b/engines/kyra/animator_hof.cpp new file mode 100644 index 0000000000..9314f8604e --- /dev/null +++ b/engines/kyra/animator_hof.cpp @@ -0,0 +1,339 @@ +/* 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()"); + _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; + + _charScale = getScale(c->x1, c->y1); + + animState->xPos2 += (xAdd * _charScale) >> 8; + animState->yPos2 += (yAdd * _charScale) >> 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, _charScale, _charScale); +} + +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_v3.cpp b/engines/kyra/animator_mr.cpp index 078b914e86..ab3d347549 100644 --- a/engines/kyra/animator_v3.cpp +++ b/engines/kyra/animator_mr.cpp @@ -23,13 +23,19 @@ * */ -#include "kyra/kyra_v3.h" +#include "kyra/kyra_mr.h" +#include "kyra/resource.h" #include "kyra/wsamovie.h" namespace Kyra { -void KyraEngine_v3::clearAnimObjects() { - debugC(9, kDebugLevelAnimator, "KyraEngine_v3::clearAnimObjects()"); +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; @@ -37,7 +43,7 @@ void KyraEngine_v3::clearAnimObjects() { _animObjects[0].index = 0; _animObjects[0].type = 0; _animObjects[0].enabled = true; - _animObjects[0].unk8 = 1; + _animObjects[0].specialRefresh = 1; _animObjects[0].flags = 0x800; _animObjects[0].width = 57; _animObjects[0].height = 91; @@ -50,13 +56,13 @@ void KyraEngine_v3::clearAnimObjects() { _animObjects[i].flags = 0; _animObjects[i].enabled = false; _animObjects[i].needRefresh = 0; - _animObjects[i].unk8 = 1; + _animObjects[i].specialRefresh = 1; } for (int i = 17; i <= 66; ++i) { _animObjects[i].index = i; _animObjects[i].type = 1; - _animObjects[i].unk8 = 1; + _animObjects[i].specialRefresh = 1; _animObjects[i].flags = 0x800; _animObjects[i].width = 24; _animObjects[i].height = 20; @@ -65,87 +71,8 @@ void KyraEngine_v3::clearAnimObjects() { } } -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); +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) @@ -156,15 +83,8 @@ void KyraEngine_v3::animSetupPaletteEntry(AnimObj *anim) { 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()"); +void KyraEngine_MR::drawAnimObjects() { + debugC(9, kDebugLevelAnimator, "KyraEngine_MR::drawAnimObjects()"); for (AnimObj *curObject = _animList; curObject; curObject = curObject->nextObject) { if (!curObject->enabled) continue; @@ -174,7 +94,7 @@ void KyraEngine_v3::drawAnimObjects() { int layer = 7; if (curObject->flags & 0x800) { - if (!curObject->unk8) + if (!curObject->specialRefresh) layer = 0; else layer = getDrawLayer(curObject->xPos1, curObject->yPos1); @@ -187,13 +107,13 @@ void KyraEngine_v3::drawAnimObjects() { } } -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); +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->shapeIndex == 0xFFFF) + if (obj->shapeIndex1 == 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); + _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); @@ -213,15 +133,15 @@ void KyraEngine_v3::drawSceneAnimObject(AnimObj *obj, int x, int y, int 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); +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->shapeIndex == 0xFFFF || _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); @@ -230,8 +150,8 @@ void KyraEngine_v3::drawCharacterAnimObject(AnimObj *obj, int x, int y, int laye _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); +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; @@ -276,27 +196,8 @@ void KyraEngine_v3::refreshAnimObjects(int force) { } } -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); +void KyraEngine_MR::updateCharacterAnim(int charId) { + debugC(9, kDebugLevelAnimator, "KyraEngine_MR::updateCharacterAnim(%d)", charId); AnimObj *obj = &_animObjects[0]; obj->needRefresh = true; @@ -304,15 +205,15 @@ void KyraEngine_v3::updateCharacterAnim(int charId) { obj->xPos1 = _mainCharacter.x1; obj->yPos1 = _mainCharacter.y1; obj->shapePtr = getShapePtr(_mainCharacter.animFrame); - obj->shapeIndex = obj->shapeIndex2 = _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; + shapeOffsetX = _animShapeXAdd; + shapeOffsetY = _animShapeYAdd; } obj->xPos2 = _mainCharacter.x1; @@ -328,7 +229,7 @@ void KyraEngine_v3::updateCharacterAnim(int charId) { } for (int i = 1; i <= 16; ++i) { - if (_animObjects[i].enabled && _animObjects[i].unk8) + if (_animObjects[i].enabled && _animObjects[i].specialRefresh) _animObjects[i].needRefresh = true; } @@ -342,8 +243,8 @@ void KyraEngine_v3::updateCharacterAnim(int charId) { updateCharPal(1); } -void KyraEngine_v3::updateSceneAnim(int anim, int newFrame) { - debugC(9, kDebugLevelAnimator, "KyraEngine_v3::updateSceneAnim(%d, %d)", anim, newFrame); +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; @@ -380,9 +281,9 @@ void KyraEngine_v3::updateSceneAnim(int anim, int newFrame) { } } -void KyraEngine_v3::setupSceneAnimObject(int animId, uint16 flags, int x, int y, int x2, int y2, int w, +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_v3::setupSceneAnimObject(%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, '%s')", + 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]; @@ -393,9 +294,7 @@ void KyraEngine_v3::setupSceneAnimObject(int animId, uint16 flags, int x, int y, 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); @@ -431,7 +330,7 @@ void KyraEngine_v3::setupSceneAnimObject(int animId, uint16 flags, int x, int y, obj->enabled = true; obj->needRefresh = true; - obj->unk8 = (anim.flags & 0x20) ? 1 : 0; + obj->specialRefresh = (anim.flags & 0x20) ? 1 : 0; obj->flags = (anim.flags & 0x10) ? 0x800 : 0; if (anim.flags & 2) obj->flags |= 1; @@ -439,7 +338,7 @@ void KyraEngine_v3::setupSceneAnimObject(int animId, uint16 flags, int x, int y, obj->xPos1 = anim.x; obj->yPos1 = anim.y; - if ((anim.flags & 4) && anim.shapeIndex != 0xFFFF) + if ((anim.flags & 4) && anim.shapeIndex != -1) obj->shapePtr = _sceneShapes[anim.shapeIndex]; else obj->shapePtr = 0; @@ -464,8 +363,8 @@ void KyraEngine_v3::setupSceneAnimObject(int animId, uint16 flags, int x, int y, _animList = initAnimList(_animList, obj); } -void KyraEngine_v3::removeSceneAnimObject(int anim, int refresh) { - debugC(9, kDebugLevelAnimator, "KyraEngine_v3::removeSceneAnimObject(%d, %d)", anim, refresh); +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; @@ -480,8 +379,8 @@ void KyraEngine_v3::removeSceneAnimObject(int anim, int refresh) { _sceneAnimMovie[anim]->close(); } -void KyraEngine_v3::setCharacterAnimDim(int w, int h) { - debugC(9, kDebugLevelAnimator, "KyraEngine_v3::setCharacterAnimDim(%d, %d)", w, h); +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; @@ -494,8 +393,8 @@ void KyraEngine_v3::setCharacterAnimDim(int w, int h) { _animObjects[0].height = h; } -void KyraEngine_v3::resetCharacterAnimDim() { - debugC(9, kDebugLevelAnimator, "KyraEngine_v3::resetCharacterAnimDim()"); +void KyraEngine_MR::resetCharacterAnimDim() { + debugC(9, kDebugLevelAnimator, "KyraEngine_MR::resetCharacterAnimDim()"); restorePage3(); _animObjects[0].width2 = _charBackUpWidth2; _animObjects[0].height2 = _charBackUpHeight2; @@ -505,8 +404,8 @@ void KyraEngine_v3::resetCharacterAnimDim() { _charBackUpWidth = _charBackUpHeight = -1; } -void KyraEngine_v3::showIdleAnim() { - debugC(9, kDebugLevelMain | kDebugLevelAnimator, "KyraEngine_v3::showIdleAnim()"); +void KyraEngine_MR::showIdleAnim() { + debugC(9, kDebugLevelMain | kDebugLevelAnimator, "KyraEngine_MR::showIdleAnim()"); if (_mainCharacter.sceneId == 20 || _mainCharacter.sceneId == 21 || _mainCharacter.sceneId == 12 || _mainCharacter.sceneId == 11) @@ -516,142 +415,21 @@ void KyraEngine_v3::showIdleAnim() { return; if (!_nextIdleType && !talkObjectsInCurScene()) { - malcolmRandomChat(); + randomSceneChat(); } 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); + snprintf(filename, 14, "MI0%s%.02d.EMC", facingTable[_mainCharacter.facing], _characterShapeFile); if (_res->exists(filename)) - runTemporaryScript(filename, 1, 1, 1, 1); + runAnimationScript(filename, 1, 1, 1, 1); } _nextIdleType = !_nextIdleType; } -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); - - _scriptInterpreter->initScript(&_temporaryScriptState, &_temporaryScriptData); - _scriptInterpreter->startScript(&_temporaryScriptState, 1); - - resetSkipFlag(); - - while (_scriptInterpreter->validScript(&_temporaryScriptState)) { - _temporaryScriptExecBit = false; - while (_scriptInterpreter->validScript(&_temporaryScriptState) && !_temporaryScriptExecBit) - _scriptInterpreter->runScript(&_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(); -} - -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/animator_v1.cpp b/engines/kyra/animator_v1.cpp index 69dc473d32..ea56efd9fb 100644 --- a/engines/kyra/animator_v1.cpp +++ b/engines/kyra/animator_v1.cpp @@ -33,7 +33,7 @@ #include "common/system.h" namespace Kyra { -ScreenAnimator::ScreenAnimator(KyraEngine_v1 *vm, OSystem *system) { +Animator_v1::Animator_v1(KyraEngine_v1 *vm, OSystem *system) { _vm = vm; _screen = vm->screen(); _initOk = false; @@ -48,14 +48,14 @@ ScreenAnimator::ScreenAnimator(KyraEngine_v1 *vm, OSystem *system) { memset(_actorBkgBackUp[1], 0, _screen->getRectSize(8, 69)); } -ScreenAnimator::~ScreenAnimator() { +Animator_v1::~Animator_v1() { close(); delete [] _actorBkgBackUp[0]; delete [] _actorBkgBackUp[1]; } -void ScreenAnimator::init(int actors_, int items_, int sprites_) { - debugC(9, kDebugLevelAnimator, "ScreenAnimator::init(%d, %d, %d)", actors_, items_, sprites_); +void Animator_v1::init(int actors_, int items_, int sprites_) { + debugC(9, kDebugLevelAnimator, "Animator_v1::init(%d, %d, %d)", actors_, items_, sprites_); _screenObjects = new AnimObject[actors_ + items_ + sprites_]; assert(_screenObjects); memset(_screenObjects, 0, sizeof(AnimObject) * (actors_ + items_ + sprites_)); @@ -67,8 +67,8 @@ void ScreenAnimator::init(int actors_, int items_, int sprites_) { _initOk = true; } -void ScreenAnimator::close() { - debugC(9, kDebugLevelAnimator, "ScreenAnimator::close()"); +void Animator_v1::close() { + debugC(9, kDebugLevelAnimator, "Animator_v1::close()"); if (_initOk) { _initOk = false; delete [] _screenObjects; @@ -76,7 +76,7 @@ void ScreenAnimator::close() { } } -void ScreenAnimator::initAnimStateList() { +void Animator_v1::initAnimStateList() { AnimObject *animStates = _screenObjects; animStates[0].index = 0; animStates[0].active = 1; @@ -118,8 +118,8 @@ void ScreenAnimator::initAnimStateList() { } } -void ScreenAnimator::preserveAllBackgrounds() { - debugC(9, kDebugLevelAnimator, "ScreenAnimator::preserveAllBackgrounds()"); +void Animator_v1::preserveAllBackgrounds() { + debugC(9, kDebugLevelAnimator, "Animator_v1::preserveAllBackgrounds()"); uint8 curPage = _screen->_curPage; _screen->_curPage = 2; @@ -134,8 +134,8 @@ void ScreenAnimator::preserveAllBackgrounds() { _screen->_curPage = curPage; } -void ScreenAnimator::flagAllObjectsForBkgdChange() { - debugC(9, kDebugLevelAnimator, "ScreenAnimator::flagAllObjectsForBkgdChange()"); +void Animator_v1::flagAllObjectsForBkgdChange() { + debugC(9, kDebugLevelAnimator, "Animator_v1::flagAllObjectsForBkgdChange()"); AnimObject *curObject = _objectQueue; while (curObject) { curObject->bkgdChangeFlag = 1; @@ -143,8 +143,8 @@ void ScreenAnimator::flagAllObjectsForBkgdChange() { } } -void ScreenAnimator::flagAllObjectsForRefresh() { - debugC(9, kDebugLevelAnimator, "ScreenAnimator::flagAllObjectsForRefresh()"); +void Animator_v1::flagAllObjectsForRefresh() { + debugC(9, kDebugLevelAnimator, "Animator_v1::flagAllObjectsForRefresh()"); AnimObject *curObject = _objectQueue; while (curObject) { curObject->refreshFlag = 1; @@ -152,8 +152,8 @@ void ScreenAnimator::flagAllObjectsForRefresh() { } } -void ScreenAnimator::restoreAllObjectBackgrounds() { - debugC(9, kDebugLevelAnimator, "ScreenAnimator::restoreAllObjectBackground()"); +void Animator_v1::restoreAllObjectBackgrounds() { + debugC(9, kDebugLevelAnimator, "Animator_v1::restoreAllObjectBackground()"); AnimObject *curObject = _objectQueue; _screen->_curPage = 2; @@ -169,8 +169,8 @@ void ScreenAnimator::restoreAllObjectBackgrounds() { _screen->_curPage = 0; } -void ScreenAnimator::preserveAnyChangedBackgrounds() { - debugC(9, kDebugLevelAnimator, "ScreenAnimator::preserveAnyChangedBackgrounds()"); +void Animator_v1::preserveAnyChangedBackgrounds() { + debugC(9, kDebugLevelAnimator, "Animator_v1::preserveAnyChangedBackgrounds()"); AnimObject *curObject = _objectQueue; _screen->_curPage = 2; @@ -185,8 +185,8 @@ void ScreenAnimator::preserveAnyChangedBackgrounds() { _screen->_curPage = 0; } -void ScreenAnimator::preserveOrRestoreBackground(AnimObject *obj, bool restore) { - debugC(9, kDebugLevelAnimator, "ScreenAnimator::preserveOrRestoreBackground(%p, %d)", (const void *)obj, restore); +void Animator_v1::preserveOrRestoreBackground(AnimObject *obj, bool restore) { + debugC(9, kDebugLevelAnimator, "Animator_v1::preserveOrRestoreBackground(%p, %d)", (const void *)obj, restore); int x = 0, y = 0, width = obj->width, height = obj->height; if (restore) { @@ -217,8 +217,8 @@ void ScreenAnimator::preserveOrRestoreBackground(AnimObject *obj, bool restore) _screen->copyRegionToBuffer(_screen->_curPage, x << 3, y, width << 3, height, obj->background); } -void ScreenAnimator::prepDrawAllObjects() { - debugC(9, kDebugLevelAnimator, "ScreenAnimator::prepDrawAllObjects()"); +void Animator_v1::prepDrawAllObjects() { + debugC(9, kDebugLevelAnimator, "Animator_v1::prepDrawAllObjects()"); AnimObject *curObject = _objectQueue; int drawPage = 2; int flagUnk1 = 0, flagUnk2 = 0, flagUnk3 = 0; @@ -363,8 +363,8 @@ void ScreenAnimator::prepDrawAllObjects() { } } -void ScreenAnimator::copyChangedObjectsForward(int refreshFlag) { - debugC(9, kDebugLevelAnimator, "ScreenAnimator::copyChangedObjectsForward(%d)", refreshFlag); +void Animator_v1::copyChangedObjectsForward(int refreshFlag) { + debugC(9, kDebugLevelAnimator, "Animator_v1::copyChangedObjectsForward(%d)", refreshFlag); for (AnimObject *curObject = _objectQueue; curObject; curObject = curObject->nextAnimObject) { if (curObject->active) { @@ -404,16 +404,16 @@ void ScreenAnimator::copyChangedObjectsForward(int refreshFlag) { } } -void ScreenAnimator::updateAllObjectShapes() { - debugC(9, kDebugLevelAnimator, "ScreenAnimator::updateAllObjectShapes()"); +void Animator_v1::updateAllObjectShapes() { + debugC(9, kDebugLevelAnimator, "Animator_v1::updateAllObjectShapes()"); restoreAllObjectBackgrounds(); preserveAnyChangedBackgrounds(); prepDrawAllObjects(); copyChangedObjectsForward(0); } -void ScreenAnimator::animRemoveGameItem(int index) { - debugC(9, kDebugLevelAnimator, "ScreenAnimator::animRemoveGameItem(%d)", index); +void Animator_v1::animRemoveGameItem(int index) { + debugC(9, kDebugLevelAnimator, "Animator_v1::animRemoveGameItem(%d)", index); restoreAllObjectBackgrounds(); AnimObject *animObj = &_items[index]; @@ -427,8 +427,8 @@ void ScreenAnimator::animRemoveGameItem(int index) { objectRemoveQueue(_objectQueue, animObj); } -void ScreenAnimator::animAddGameItem(int index, uint16 sceneId) { - debugC(9, kDebugLevelAnimator, "ScreenAnimator::animRemoveGameItem(%d, %d)", index, sceneId); +void Animator_v1::animAddGameItem(int index, uint16 sceneId) { + debugC(9, kDebugLevelAnimator, "Animator_v1::animRemoveGameItem(%d, %d)", index, sceneId); restoreAllObjectBackgrounds(); assert(sceneId < _vm->_roomTableSize); Room *currentRoom = &_vm->_roomTable[sceneId]; @@ -453,8 +453,8 @@ void ScreenAnimator::animAddGameItem(int index, uint16 sceneId) { animObj->bkgdChangeFlag = 1; } -void ScreenAnimator::animAddNPC(int character) { - debugC(9, kDebugLevelAnimator, "ScreenAnimator::animAddNPC(%d)", character); +void Animator_v1::animAddNPC(int character) { + debugC(9, kDebugLevelAnimator, "Animator_v1::animAddNPC(%d)", character); restoreAllObjectBackgrounds(); AnimObject *animObj = &_actors[character]; const Character *ch = &_vm->_characterList[character]; @@ -478,8 +478,8 @@ void ScreenAnimator::animAddNPC(int character) { animObj->bkgdChangeFlag = 1; } -AnimObject *ScreenAnimator::objectRemoveQueue(AnimObject *queue, AnimObject *rem) { - debugC(9, kDebugLevelAnimator, "ScreenAnimator::objectRemoveQueue(%p, %p)", (const void *)queue, (const void *)rem); +Animator_v1::AnimObject *Animator_v1::objectRemoveQueue(AnimObject *queue, AnimObject *rem) { + debugC(9, kDebugLevelAnimator, "Animator_v1::objectRemoveQueue(%p, %p)", (const void *)queue, (const void *)rem); AnimObject *cur = queue; AnimObject *prev = queue; @@ -512,14 +512,14 @@ AnimObject *ScreenAnimator::objectRemoveQueue(AnimObject *queue, AnimObject *rem return queue; } -AnimObject *ScreenAnimator::objectAddHead(AnimObject *queue, AnimObject *head) { - debugC(9, kDebugLevelAnimator, "ScreenAnimator::objectAddHead(%p, %p)", (const void *)queue, (const void *)head); +Animator_v1::AnimObject *Animator_v1::objectAddHead(AnimObject *queue, AnimObject *head) { + debugC(9, kDebugLevelAnimator, "Animator_v1::objectAddHead(%p, %p)", (const void *)queue, (const void *)head); head->nextAnimObject = queue; return head; } -AnimObject *ScreenAnimator::objectQueue(AnimObject *queue, AnimObject *add) { - debugC(9, kDebugLevelAnimator, "ScreenAnimator::objectQueue(%p, %p)", (const void *)queue, (const void *)add); +Animator_v1::AnimObject *Animator_v1::objectQueue(AnimObject *queue, AnimObject *add) { + debugC(9, kDebugLevelAnimator, "Animator_v1::objectQueue(%p, %p)", (const void *)queue, (const void *)add); if (add->drawY <= queue->drawY || !queue) { add->nextAnimObject = queue; return add; @@ -544,16 +544,16 @@ AnimObject *ScreenAnimator::objectQueue(AnimObject *queue, AnimObject *add) { return queue; } -void ScreenAnimator::addObjectToQueue(AnimObject *object) { - debugC(9, kDebugLevelAnimator, "ScreenAnimator::addObjectToQueue(%p)", (const void *)object); +void Animator_v1::addObjectToQueue(AnimObject *object) { + debugC(9, kDebugLevelAnimator, "Animator_v1::addObjectToQueue(%p)", (const void *)object); if (!_objectQueue) _objectQueue = objectAddHead(0, object); else _objectQueue = objectQueue(_objectQueue, object); } -void ScreenAnimator::refreshObject(AnimObject *object) { - debugC(9, kDebugLevelAnimator, "ScreenAnimator::refreshObject(%p)", (const void *)object); +void Animator_v1::refreshObject(AnimObject *object) { + debugC(9, kDebugLevelAnimator, "Animator_v1::refreshObject(%p)", (const void *)object); _objectQueue = objectRemoveQueue(_objectQueue, object); if (_objectQueue) _objectQueue = objectQueue(_objectQueue, object); @@ -561,8 +561,8 @@ void ScreenAnimator::refreshObject(AnimObject *object) { _objectQueue = objectAddHead(0, object); } -void ScreenAnimator::makeBrandonFaceMouse() { - debugC(9, kDebugLevelAnimator, "ScreenAnimator::makeBrandonFaceMouse()"); +void Animator_v1::makeBrandonFaceMouse() { + debugC(9, kDebugLevelAnimator, "Animator_v1::makeBrandonFaceMouse()"); Common::Point mouse = _vm->getMousePos(); if (mouse.x >= _vm->_currentCharacter->x1) _vm->_currentCharacter->facing = 3; @@ -572,22 +572,22 @@ void ScreenAnimator::makeBrandonFaceMouse() { updateAllObjectShapes(); } -int16 ScreenAnimator::fetchAnimWidth(const uint8 *shape, int16 mult) { - debugC(9, kDebugLevelAnimator, "ScreenAnimator::fetchAnimWidth(%p, %d)", (const void *)shape, mult); +int16 Animator_v1::fetchAnimWidth(const uint8 *shape, int16 mult) { + debugC(9, kDebugLevelAnimator, "Animator_v1::fetchAnimWidth(%p, %d)", (const void *)shape, mult); if (_vm->gameFlags().useAltShapeHeader) shape += 2; return (((int16)READ_LE_UINT16((shape+3))) * mult) >> 8; } -int16 ScreenAnimator::fetchAnimHeight(const uint8 *shape, int16 mult) { - debugC(9, kDebugLevelAnimator, "ScreenAnimator::fetchAnimHeight(%p, %d)", (const void *)shape, mult); +int16 Animator_v1::fetchAnimHeight(const uint8 *shape, int16 mult) { + debugC(9, kDebugLevelAnimator, "Animator_v1::fetchAnimHeight(%p, %d)", (const void *)shape, mult); if (_vm->gameFlags().useAltShapeHeader) shape += 2; return (int16)(((int8)*(shape+2)) * mult) >> 8; } -void ScreenAnimator::setBrandonAnimSeqSize(int width, int height) { - debugC(9, kDebugLevelAnimator, "ScreenAnimator::setBrandonAnimSeqSize(%d, %d)", width, height); +void Animator_v1::setBrandonAnimSeqSize(int width, int height) { + debugC(9, kDebugLevelAnimator, "Animator_v1::setBrandonAnimSeqSize(%d, %d)", width, height); restoreAllObjectBackgrounds(); _brandonAnimSeqSizeWidth = _actors[0].width; _brandonAnimSeqSizeHeight = _actors[0].height; @@ -596,16 +596,16 @@ void ScreenAnimator::setBrandonAnimSeqSize(int width, int height) { preserveAllBackgrounds(); } -void ScreenAnimator::resetBrandonAnimSeqSize() { - debugC(9, kDebugLevelAnimator, "ScreenAnimator::resetBrandonAnimSeqSize()"); +void Animator_v1::resetBrandonAnimSeqSize() { + debugC(9, kDebugLevelAnimator, "Animator_v1::resetBrandonAnimSeqSize()"); restoreAllObjectBackgrounds(); _actors[0].width = _brandonAnimSeqSizeWidth; _actors[0].height = _brandonAnimSeqSizeHeight; preserveAllBackgrounds(); } -void ScreenAnimator::animRefreshNPC(int character) { - debugC(9, kDebugLevelAnimator, "ScreenAnimator::animRefreshNPC(%d)", character); +void Animator_v1::animRefreshNPC(int character) { + debugC(9, kDebugLevelAnimator, "Animator_v1::animRefreshNPC(%d)", character); AnimObject *animObj = &_actors[character]; Character *ch = &_vm->characterList()[character]; @@ -663,8 +663,8 @@ void ScreenAnimator::animRefreshNPC(int character) { refreshObject(animObj); } -void ScreenAnimator::setCharacterDefaultFrame(int character) { - debugC(9, kDebugLevelAnimator, "ScreenAnimator::setCharacterDefaultFrame()"); +void Animator_v1::setCharacterDefaultFrame(int character) { + debugC(9, kDebugLevelAnimator, "Animator_v1::setCharacterDefaultFrame()"); static uint16 initFrameTable[] = { 7, 41, 77, 0, 0 }; @@ -676,8 +676,8 @@ void ScreenAnimator::setCharacterDefaultFrame(int character) { // edit->unk6 = 1; } -void ScreenAnimator::setCharactersHeight() { - debugC(9, kDebugLevelAnimator, "ScreenAnimator::setCharactersHeight()"); +void Animator_v1::setCharactersHeight() { + debugC(9, kDebugLevelAnimator, "Animator_v1::setCharactersHeight()"); static int8 initHeightTable[] = { 48, 40, 48, 47, 56, 44, 42, 47, 38, 35, diff --git a/engines/kyra/animator_v1.h b/engines/kyra/animator_v1.h index 7bfb872651..3ae0b23da4 100644 --- a/engines/kyra/animator_v1.h +++ b/engines/kyra/animator_v1.h @@ -23,38 +23,38 @@ * */ -#ifndef KYRA_ANIMATOR_H -#define KYRA_ANIMATOR_H +#ifndef KYRA_ANIMATOR_V1_H +#define KYRA_ANIMATOR_V1_H namespace Kyra { class KyraEngine_v1; class Screen; -struct AnimObject { - uint8 index; - uint32 active; - uint32 refreshFlag; - uint32 bkgdChangeFlag; - bool disable; - uint32 flags; - int16 drawY; - uint8 *sceneAnimPtr; - int16 animFrameNumber; - uint8 *background; - uint16 rectSize; - int16 x1, y1; - int16 x2, y2; - uint16 width; - uint16 height; - uint16 width2; - uint16 height2; - AnimObject *nextAnimObject; -}; - -class ScreenAnimator { +class Animator_v1 { public: - ScreenAnimator(KyraEngine_v1 *vm, OSystem *system); - virtual ~ScreenAnimator(); + struct AnimObject { + uint8 index; + uint32 active; + uint32 refreshFlag; + uint32 bkgdChangeFlag; + bool disable; + uint32 flags; + int16 drawY; + uint8 *sceneAnimPtr; + int16 animFrameNumber; + uint8 *background; + uint16 rectSize; + int16 x1, y1; + int16 x2, y2; + uint16 width; + uint16 height; + uint16 width2; + uint16 height2; + AnimObject *nextAnimObject; + }; + + Animator_v1(KyraEngine_v1 *vm, OSystem *system); + virtual ~Animator_v1(); operator bool() const { return _initOk; } diff --git a/engines/kyra/animator_v2.cpp b/engines/kyra/animator_v2.cpp index 8efbdbe747..af22056eee 100644 --- a/engines/kyra/animator_v2.cpp +++ b/engines/kyra/animator_v2.cpp @@ -24,37 +24,23 @@ */ #include "kyra/kyra_v2.h" +#include "kyra/screen_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; - } +void KyraEngine_v2::allocAnimObjects(int actors, int anims, int items) { + debugC(9, kDebugLevelAnimator, "KyraEngine_v2::allocAnimObjects(%d, %d, %d)", actors, anims, items); + _animObjects = new AnimObj[actors+anims+items]; + assert(_animObjects); - 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; - } + memset(_animObjects, 0, sizeof(AnimObj)*(actors+anims+items)); + + _animActor = _animObjects; + _animAnims = _animObjects + actors; + _animItems = _animObjects + actors + anims; } KyraEngine_v2::AnimObj *KyraEngine_v2::initAnimList(AnimObj *list, AnimObj *entry) { @@ -136,65 +122,6 @@ KyraEngine_v2::AnimObj *KyraEngine_v2::deleteAnimListEntry(AnimObj *list, AnimOb 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) { @@ -202,256 +129,62 @@ void KyraEngine_v2::refreshAnimObjectsIfNeed() { restorePage3(); drawAnimObjects(); refreshAnimObjects(0); - _screen->updateScreen(); + 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()"); +void KyraEngine_v2::flagAnimObjsSpecialRefresh() { + debugC(9, kDebugLevelAnimator, "KyraEngine_v2::flagAnimObjsSpecialRefresh()"); 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); + curEntry->specialRefresh = 1; } void KyraEngine_v2::addItemToAnimList(int item) { debugC(9, kDebugLevelAnimator, "KyraEngine_v2::addItemToAnimList(%d)", item); + assert(item < _itemListSize); + restorePage3(); - AnimObj *animObj = &_animObjects[11+item]; + AnimObj *animObj = _animItems + 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; + animObj->shapePtr = getShapePtr(itemId + _desc.itemShapeStart); + animSetupPaletteEntry(animObj); + animObj->shapeIndex2 = animObj->shapeIndex1 = itemId + _desc.itemShapeStart; 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)); + uint8 *shapePtr = getShapePtr(itemId + _desc.itemShapeStart); + animObj->xPos3 = (animObj->xPos2 -= (screen_v2()->getShapeScaledWidth(shapePtr, scaleX) >> 1)); + animObj->yPos3 = (animObj->yPos2 -= screen_v2()->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]; + assert(item < _itemListSize); + + AnimObj *animObj = _animItems + item; restorePage3(); @@ -459,7 +192,6 @@ void KyraEngine_v2::deleteItemAnimEntry(int item) { animObj->shapeIndex1 = 0xFFFF; animObj->shapeIndex2 = 0xFFFF; animObj->needRefresh = 1; - animObj->unk8 = 1; refreshAnimObjectsIfNeed(); @@ -467,24 +199,5 @@ void KyraEngine_v2::deleteItemAnimEntry(int item) { _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/debugger.cpp b/engines/kyra/debugger.cpp index ab49f18e97..51e4d17487 100644 --- a/engines/kyra/debugger.cpp +++ b/engines/kyra/debugger.cpp @@ -29,6 +29,7 @@ #include "kyra/debugger.h" #include "kyra/kyra_v1.h" #include "kyra/kyra_v2.h" +#include "kyra/kyra_hof.h" #include "kyra/screen.h" #include "kyra/timer.h" #include "kyra/resource.h" @@ -39,6 +40,7 @@ Debugger::Debugger(KyraEngine *vm) : ::GUI::Debugger() { _vm = vm; + DCmd_Register("continue", WRAP_METHOD(Debugger, Cmd_Exit)); DCmd_Register("screen_debug_mode", WRAP_METHOD(Debugger, cmd_setScreenDebug)); DCmd_Register("load_palette", WRAP_METHOD(Debugger, cmd_loadPalette)); DCmd_Register("facings", WRAP_METHOD(Debugger, cmd_showFacings)); @@ -189,11 +191,7 @@ bool Debugger::cmd_setTimerCountdown(int argc, const char **argv) { #pragma mark - Debugger_v1::Debugger_v1(KyraEngine_v1 *vm) - : Debugger(vm) { - _vm = vm; - - DCmd_Register("continue", WRAP_METHOD(Debugger_v1, Cmd_Exit)); - DCmd_Register("enter", WRAP_METHOD(Debugger_v1, cmd_enterRoom)); + : Debugger(vm), _vm(vm) { DCmd_Register("rooms", WRAP_METHOD(Debugger_v1, cmd_listRooms)); DCmd_Register("give", WRAP_METHOD(Debugger_v1, cmd_giveItem)); DCmd_Register("birthstones", WRAP_METHOD(Debugger_v1, cmd_listBirthstones)); @@ -235,7 +233,8 @@ bool Debugger_v1::cmd_enterRoom(int argc, const char **argv) { _vm->_currentCharacter->facing = direction; _vm->enterNewScene(room, _vm->_currentCharacter->facing, 0, 0, 1); - _vm->_screen->_mouseLockCount = 0; + while (!_vm->_screen->isMouseVisible()) + _vm->_screen->showMouse(); _detach_now = true; return false; @@ -285,7 +284,6 @@ bool Debugger_v1::cmd_listBirthstones(int argc, const char **argv) { #pragma mark - Debugger_v2::Debugger_v2(KyraEngine_v2 *vm) : Debugger(vm), _vm(vm) { - DCmd_Register("continue", WRAP_METHOD(Debugger_v2, Cmd_Exit)); 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 @@ -293,7 +291,6 @@ Debugger_v2::Debugger_v2(KyraEngine_v2 *vm) : Debugger(vm), _vm(vm) { DCmd_Register("scene_info", WRAP_METHOD(Debugger_v2, cmd_sceneInfo)); DCmd_Register("scene_to_facing", WRAP_METHOD(Debugger_v2, cmd_sceneToFacing)); DCmd_Register("give", WRAP_METHOD(Debugger_v2, cmd_giveItem)); - DCmd_Register("pass_codes", WRAP_METHOD(Debugger_v2, cmd_passcodes)); } bool Debugger_v2::cmd_enterScene(int argc, const char **argv) { @@ -324,7 +321,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_v2()->isMouseVisible()) + _vm->screen_v2()->showMouse(); _detach_now = true; return false; @@ -337,8 +335,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; @@ -350,7 +348,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); @@ -373,7 +371,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"); @@ -437,7 +435,13 @@ bool Debugger_v2::cmd_giveItem(int argc, const char **argv) { return true; } -bool Debugger_v2::cmd_passcodes(int argc, const char **argv) { +#pragma mark - + +Debugger_HoF::Debugger_HoF(KyraEngine_HoF *vm) : Debugger_v2(vm), _vm(vm) { + DCmd_Register("pass_codes", WRAP_METHOD(Debugger_HoF, cmd_passcodes)); +} + +bool Debugger_HoF::cmd_passcodes(int argc, const char **argv) { if (argc == 2) { int val = atoi(argv[1]); diff --git a/engines/kyra/debugger.h b/engines/kyra/debugger.h index dedcd672c7..ab5657bbde 100644 --- a/engines/kyra/debugger.h +++ b/engines/kyra/debugger.h @@ -33,6 +33,7 @@ namespace Kyra { class KyraEngine; class KyraEngine_v1; class KyraEngine_v2; +class KyraEngine_HoF; class Debugger : public ::GUI::Debugger { public: @@ -84,6 +85,15 @@ protected: bool cmd_characterInfo(int argc, const char **argv); bool cmd_sceneToFacing(int argc, const char **argv); bool cmd_giveItem(int argc, const char **argv); +}; + +class Debugger_HoF : public Debugger_v2 { +public: + Debugger_HoF(KyraEngine_HoF *vm); + +protected: + KyraEngine_HoF *_vm; + bool cmd_passcodes(int argc, const char **argv); }; diff --git a/engines/kyra/detection.cpp b/engines/kyra/detection.cpp index 02e501b31a..b921314e68 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" @@ -41,22 +41,22 @@ struct KYRAGameDescription { namespace { -#define FLAGS(x, y, z, a, id) { Common::UNK_LANG, Common::kPlatformUnknown, x, y, z, a, id } +#define FLAGS(x, y, z, a, b, id) { Common::UNK_LANG, Common::kPlatformUnknown, x, y, z, a, b, id } -#define KYRA1_FLOPPY_FLAGS FLAGS(false, false, false, false, Kyra::GI_KYRA1) -#define KYRA1_AMIGA_FLAGS FLAGS(false, false, false, false, Kyra::GI_KYRA1) -#define KYRA1_TOWNS_FLAGS FLAGS(false, true, false, false, Kyra::GI_KYRA1) -#define KYRA1_TOWNS_SJIS_FLAGS FLAGS(false, true, false, true, Kyra::GI_KYRA1) -#define KYRA1_CD_FLAGS FLAGS(false, true, true, false, Kyra::GI_KYRA1) -#define KYRA1_DEMO_FLAGS FLAGS(true, false, false, false, Kyra::GI_KYRA1) +#define KYRA1_FLOPPY_FLAGS FLAGS(false, false, false, false, false, Kyra::GI_KYRA1) +#define KYRA1_AMIGA_FLAGS FLAGS(false, false, false, false, false, Kyra::GI_KYRA1) +#define KYRA1_TOWNS_FLAGS FLAGS(false, true, false, false, false, Kyra::GI_KYRA1) +#define KYRA1_TOWNS_SJIS_FLAGS FLAGS(false, true, false, true, false, Kyra::GI_KYRA1) +#define KYRA1_CD_FLAGS FLAGS(false, true, true, false, false, Kyra::GI_KYRA1) +#define KYRA1_DEMO_FLAGS FLAGS(true, false, false, false, false, Kyra::GI_KYRA1) -#define KYRA2_CD_FLAGS FLAGS(false, false, true, false, Kyra::GI_KYRA2) -#define KYRA2_CD_DEMO_FLAGS FLAGS(true, false, true, false, Kyra::GI_KYRA2) -#define KYRA2_DEMO_FLAGS FLAGS(true, false, false, false, Kyra::GI_KYRA2) -#define KYRA2_TOWNS_FLAGS FLAGS(false, false, false, false, Kyra::GI_KYRA2) -#define KYRA2_TOWNS_SJIS_FLAGS FLAGS(false, false, false, true, Kyra::GI_KYRA2) +#define KYRA2_CD_FLAGS FLAGS(false, false, true, false, false, Kyra::GI_KYRA2) +#define KYRA2_CD_DEMO_FLAGS FLAGS(true, false, true, false, false, Kyra::GI_KYRA2) +#define KYRA2_DEMO_FLAGS FLAGS(true, false, false, false, false, Kyra::GI_KYRA2) +#define KYRA2_TOWNS_FLAGS FLAGS(false, false, false, false, false, Kyra::GI_KYRA2) +#define KYRA2_TOWNS_SJIS_FLAGS FLAGS(false, false, false, true, false, Kyra::GI_KYRA2) -#define KYRA3_CD_FLAGS FLAGS(false, false, true, false, Kyra::GI_KYRA3) +#define KYRA3_CD_FLAGS FLAGS(false, false, true, false, true, Kyra::GI_KYRA3) const KYRAGameDescription adGameDescs[] = { { @@ -435,7 +435,7 @@ const KYRAGameDescription adGameDescs[] = { KYRA3_CD_FLAGS }, - { AD_TABLE_END_MARKER, FLAGS(0, 0, 0, 0, 0) } + { AD_TABLE_END_MARKER, FLAGS(0, 0, 0, 0, 0, 0) } }; const PlainGameDescriptor gameList[] = { @@ -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; @@ -550,4 +550,8 @@ SaveStateList KyraMetaEngine::listSaves(const char *target) const { return saveList; } -REGISTER_PLUGIN(KYRA, PLUGIN_TYPE_ENGINE, KyraMetaEngine); +#if PLUGIN_ENABLED_DYNAMIC(KYRA) + REGISTER_PLUGIN_DYNAMIC(KYRA, PLUGIN_TYPE_ENGINE, KyraMetaEngine); +#else + REGISTER_PLUGIN_STATIC(KYRA, PLUGIN_TYPE_ENGINE, KyraMetaEngine); +#endif diff --git a/engines/kyra/gui.cpp b/engines/kyra/gui.cpp index 5581f636b1..d2e02671c9 100644 --- a/engines/kyra/gui.cpp +++ b/engines/kyra/gui.cpp @@ -306,10 +306,15 @@ void GUI::updateSaveList() { for (Common::StringList::const_iterator i = saveFileList.begin(); i != saveFileList.end(); ++i) { char s1 = 0, s2 = 0, s3 = 0; - s1 = (*i)[i->size()-3] - '0'; - s2 = (*i)[i->size()-2] - '0'; - s3 = (*i)[i->size()-1] - '0'; - if (s1 < 0 || s2 < 0 || s3 < 0 || s1 > 9 || s2 > 9 || s3 > 9) + s1 = (*i)[i->size()-3]; + s2 = (*i)[i->size()-2]; + s3 = (*i)[i->size()-1]; + if (!isdigit(s1) || !isdigit(s2) || !isdigit(s3)) + continue; + s1 -= '0'; + s2 -= '0'; + s3 -= '0'; + if (s1 == 9 && s2 == 9 && s3 == 9) continue; _saveSlots.push_back(s1*100+s2*10+s3); } diff --git a/engines/kyra/gui.h b/engines/kyra/gui.h index dfbca22441..a04ac20de3 100644 --- a/engines/kyra/gui.h +++ b/engines/kyra/gui.h @@ -142,8 +142,8 @@ public: virtual void processButton(Button *button) = 0; virtual int processButtonList(Button *buttonList, uint16 inputFlags) = 0; - int redrawShadedButtonCallback(Button *button); - int redrawButtonCallback(Button *button); + virtual int redrawShadedButtonCallback(Button *button); + virtual int redrawButtonCallback(Button *button); // menu specific virtual void initMenuLayout(Menu &menu); diff --git a/engines/kyra/gui_hof.cpp b/engines/kyra/gui_hof.cpp new file mode 100644 index 0000000000..d1fcaa4712 --- /dev/null +++ b/engines/kyra/gui_hof.cpp @@ -0,0 +1,1183 @@ +/* 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/timer.h" +#include "kyra/sound.h" +#include "kyra/resource.h" + +#include "common/savefile.h" + +namespace Kyra { + +void KyraEngine_HoF::loadButtonShapes() { + const uint8 *src = _screen->getCPagePtr(3); + _screen->loadBitmap("_BUTTONS.CSH", 3, 3, 0); + + _gui->_scrollUpButton.data0ShapePtr = _buttonShapes[0] = _screen->makeShapeCopy(src, 0); + _gui->_scrollUpButton.data2ShapePtr = _buttonShapes[1] = _screen->makeShapeCopy(src, 1); + _gui->_scrollUpButton.data1ShapePtr = _buttonShapes[2] = _screen->makeShapeCopy(src, 2); + _gui->_scrollDownButton.data0ShapePtr = _buttonShapes[3] = _screen->makeShapeCopy(src, 3); + _gui->_scrollDownButton.data2ShapePtr = _buttonShapes[4] = _screen->makeShapeCopy(src, 4); + _gui->_scrollDownButton.data1ShapePtr = _buttonShapes[5] = _screen->makeShapeCopy(src, 5); + _buttonShapes[6] = _screen->makeShapeCopy(src, 6); + _buttonShapes[7] = _screen->makeShapeCopy(src, 7); + _buttonShapes[8] = _screen->makeShapeCopy(src, 6); + _buttonShapes[9] = _screen->makeShapeCopy(src, 7); + _buttonShapes[10] = _screen->makeShapeCopy(src, 10); + _buttonShapes[11] = _screen->makeShapeCopy(src, 11); + _buttonShapes[16] = _screen->makeShapeCopy(src, 16); + _buttonShapes[17] = _screen->makeShapeCopy(src, 17); + _buttonShapes[18] = _screen->makeShapeCopy(src, 18); +} + +void KyraEngine_HoF::setupLangButtonShapes() { + switch (_lang) { + case 0: + _inventoryButtons[0].data0ShapePtr = _buttonShapes[6]; + _inventoryButtons[0].data1ShapePtr = _inventoryButtons[0].data2ShapePtr = _buttonShapes[7]; + break; + + case 1: + _inventoryButtons[0].data0ShapePtr = _buttonShapes[8]; + _inventoryButtons[0].data1ShapePtr = _inventoryButtons[0].data2ShapePtr = _buttonShapes[9]; + break; + + case 2: + _inventoryButtons[0].data0ShapePtr = _buttonShapes[10]; + _inventoryButtons[0].data1ShapePtr = _inventoryButtons[0].data2ShapePtr = _buttonShapes[11]; + break; + + default: + _inventoryButtons[0].data0ShapePtr = _buttonShapes[6]; + _inventoryButtons[0].data1ShapePtr = _inventoryButtons[0].data2ShapePtr = _buttonShapes[7]; + break; + } +} + +GUI_HoF::GUI_HoF(KyraEngine_HoF *vm) : GUI_v2(vm), _vm(vm), _screen(_vm->_screen) { +} + +const char *GUI_HoF::getMenuTitle(const Menu &menu) { + if (!menu.menuNameId) + return 0; + + return _vm->getTableString(menu.menuNameId, _vm->_optionsBuffer, 1); +} + +const char *GUI_HoF::getMenuItemTitle(const MenuItem &menuItem) { + if (!menuItem.itemId) + return 0; + + return _vm->getTableString(menuItem.itemId, _vm->_optionsBuffer, 1); +} + +const char *GUI_HoF::getMenuItemLabel(const MenuItem &menuItem) { + if (!menuItem.labelId) + return 0; + + return _vm->getTableString(menuItem.labelId, _vm->_optionsBuffer, 1); +} + +char *GUI_HoF::getTableString(int id) { + return _vm->getTableString(id, _vm->_optionsBuffer, 0); +} + +#pragma mark - + + +int KyraEngine_HoF::buttonInventory(Button *button) { + if (!_screen->isMouseVisible()) + return 0; + + int inventorySlot = button->index - 6; + + uint16 item = _mainCharacter.inventory[inventorySlot]; + if (_itemInHand == -1) { + if (item == 0xFFFF) + return 0; + _screen->hideMouse(); + clearInventorySlot(inventorySlot, 0); + snd_playSoundEffect(0x0B); + setMouseCursor(item); + int string = (_lang == 1) ? getItemCommandStringPickUp(item) : 7; + updateCommandLineEx(item+54, string, 0xD6); + _itemInHand = (int16)item; + _screen->showMouse(); + _mainCharacter.inventory[inventorySlot] = 0xFFFF; + } else { + if (_mainCharacter.inventory[inventorySlot] != 0xFFFF) { + if (checkInventoryItemExchange(_itemInHand, inventorySlot)) + return 0; + + item = _mainCharacter.inventory[inventorySlot]; + snd_playSoundEffect(0x0B); + _screen->hideMouse(); + clearInventorySlot(inventorySlot, 0); + drawInventoryShape(0, _itemInHand, inventorySlot); + setMouseCursor(item); + int string = (_lang == 1) ? getItemCommandStringPickUp(item) : 7; + updateCommandLineEx(item+54, string, 0xD6); + _screen->showMouse(); + _mainCharacter.inventory[inventorySlot] = _itemInHand; + setHandItem(item); + } else { + snd_playSoundEffect(0x0C); + _screen->hideMouse(); + drawInventoryShape(0, _itemInHand, inventorySlot); + _screen->setMouseCursor(0, 0, getShapePtr(0)); + int string = (_lang == 1) ? getItemCommandStringInv(_itemInHand) : 8; + updateCommandLineEx(_itemInHand+54, string, 0xD6); + _screen->showMouse(); + _mainCharacter.inventory[inventorySlot] = _itemInHand; + _itemInHand = -1; + } + } + + return 0; +} + +int KyraEngine_HoF::scrollInventory(Button *button) { + uint16 *src = _mainCharacter.inventory; + uint16 *dst = &_mainCharacter.inventory[10]; + uint16 temp[5]; + + memcpy(temp, src, sizeof(uint16)*5); + memcpy(src, src+5, sizeof(uint16)*5); + memcpy(src+5, dst, sizeof(uint16)*5); + memcpy(dst, dst+5, sizeof(uint16)*5); + memcpy(dst+5, temp, sizeof(uint16)*5); + _screen->hideMouse(); + _screen->copyRegion(0x46, 0x90, 0x46, 0x90, 0x71, 0x2E, 0, 2); + _screen->showMouse(); + redrawInventory(2); + scrollInventoryWheel(); + return 0; +} + +int KyraEngine_HoF::getInventoryItemSlot(uint16 item) { + for (int i = 0; i < 20; ++i) { + if (_mainCharacter.inventory[i] == item) + return i; + } + return -1; +} + +int KyraEngine_HoF::findFreeVisibleInventorySlot() { + for (int i = 0; i < 10; ++i) { + if (_mainCharacter.inventory[i] == 0xFFFF) + return i; + } + return -1; +} + +void KyraEngine_HoF::removeSlotFromInventory(int slot) { + _mainCharacter.inventory[slot] = 0xFFFF; + if (slot < 10) { + _screen->hideMouse(); + clearInventorySlot(slot, 0); + _screen->showMouse(); + } +} + +bool KyraEngine_HoF::checkInventoryItemExchange(uint16 handItem, int slot) { + bool removeItem = false; + uint16 newItem = 0xFFFF; + + uint16 invItem = _mainCharacter.inventory[slot]; + + for (const uint16 *table = _itemMagicTable; *table != 0xFFFF; table += 4) { + if (table[0] != handItem || table[1] != invItem) + continue; + + if (table[3] == 0xFFFF) + continue; + + removeItem = (table[3] == 1); + newItem = table[2]; + + snd_playSoundEffect(0x68); + _mainCharacter.inventory[slot] = newItem; + _screen->hideMouse(); + clearInventorySlot(slot, 0); + drawInventoryShape(0, newItem, slot); + + if (removeItem) + removeHandItem(); + + _screen->showMouse(); + + if (_lang != 1) + updateCommandLineEx(newItem+54, 0x2E, 0xD6); + + return true; + } + + return false; +} + +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_HoF::clearInventorySlot(int slot, int page) { + _screen->drawShape(page, getShapePtr(240+slot), _inventoryX[slot], _inventoryY[slot], 0, 0); + _screen->updateScreen(); +} + +void KyraEngine_HoF::redrawInventory(int page) { + int pageBackUp = _screen->_curPage; + _screen->_curPage = page; + + const uint16 *inventory = _mainCharacter.inventory; + _screen->hideMouse(); + for (int i = 0; i < 10; ++i) { + clearInventorySlot(i, page); + if (inventory[i] != 0xFFFF) { + _screen->drawShape(page, getShapePtr(inventory[i]+64), _inventoryX[i], _inventoryY[i], 0, 0); + drawInventoryShape(page, inventory[i], i); + } + } + _screen->showMouse(); + _screen->updateScreen(); + + _screen->_curPage = pageBackUp; +} + +void KyraEngine_HoF::scrollInventoryWheel() { + WSAMovieV2 movie(this, _screen); + movie.open("INVWHEEL.WSA", 0, 0); + int frames = movie.opened() ? movie.frames() : 6; + memcpy(_screenBuffer, _screen->getCPagePtr(2), 64000); + uint8 overlay[0x100]; + _screen->generateOverlay(_screen->getPalette(0), overlay, 0, 50); + _screen->hideMouse(); + _screen->copyRegion(0x46, 0x90, 0x46, 0x79, 0x71, 0x17, 0, 2, Screen::CR_NO_P_CHECK); + _screen->showMouse(); + snd_playSoundEffect(0x25); + + movie.setDrawPage(0); + movie.setX(0); + movie.setY(0); + + bool breakFlag = false; + for (int i = 0; i <= 6 && !breakFlag; ++i) { + if (movie.opened()) { + _screen->hideMouse(); + movie.displayFrame(i % frames, 0, 0); + _screen->showMouse(); + _screen->updateScreen(); + } + + uint32 endTime = _system->getMillis() + _tickLength; + + int y = (i * 981) >> 8; + if (y >= 23 || i == 6) { + y = 23; + breakFlag = true; + } + + _screen->applyOverlay(0x46, 0x79, 0x71, 0x17, 2, overlay); + _screen->copyRegion(0x46, y+0x79, 0x46, 0x90, 0x71, 0x2E, 2, 0, Screen::CR_NO_P_CHECK); + _screen->updateScreen(); + + delayUntil(endTime); + } + + _screen->copyBlockToPage(2, 0, 0, 320, 200, _screenBuffer); + movie.close(); +} + +// spellbook specific code + +int KyraEngine_HoF::bookButton(Button *button) { + if (!queryGameFlag(1)) { + objectChat(getTableString(0xEB, _cCodeBuffer, 1), 0, 0x83, 0xEB); + return 0; + } + + if (!_screen->isMouseVisible()) + return 0; + + if (queryGameFlag(0xE5)) { + snd_playSoundEffect(0x0D); + return 0; + } + + if (_itemInHand == 72) { + if (!queryGameFlag(0xE2)) { + _bookMaxPage += 2; + removeHandItem(); + snd_playSoundEffect(0x6C); + setGameFlag(0xE2); + } + + if (!queryGameFlag(0x18A) && queryGameFlag(0x170)) { + _bookMaxPage += 2; + removeHandItem(); + snd_playSoundEffect(0x6C); + setGameFlag(0x18A); + } + + return 0; + } + + if (_handItemSet != -1) { + snd_playSoundEffect(0x0D); + return 0; + } + + _screen->hideMouse(); + showMessage(0, 0xCF); + displayInvWsaLastFrame(); + _bookNewPage = _bookCurPage; + + if (_screenBuffer) { + _screen->hideMouse(); + memcpy(_screenBuffer, _screen->getCPagePtr(0), 64000); + _screen->showMouse(); + } + + memcpy(_screen->getPalette(2), _screen->getPalette(0), 768); + _screen->fadeToBlack(7, &_updateFunctor); + _res->loadFileToBuf("_BOOK.COL", _screen->getPalette(0), 768); + loadBookBkgd(); + showBookPage(); + _screen->copyRegion(0, 0, 0, 0, 0x140, 0xC8, 2, 0, Screen::CR_NO_P_CHECK); + _screen->updateScreen(); + + int oldItemInHand = _itemInHand; + removeHandItem(); + _screen->fadePalette(_screen->getPalette(0), 7); + _screen->showMouse(); + + bookLoop(); + + _screen->fadeToBlack(7); + _screen->hideMouse(); + setHandItem(oldItemInHand); + updateMouse(); + restorePage3(); + + if (_screenBuffer) { + _screen->hideMouse(); + _screen->copyBlockToPage(0, 0, 0, 320, 200, _screenBuffer); + _screen->showMouse(); + } + + setHandItem(_itemInHand); + memcpy(_screen->getPalette(0), _screen->getPalette(2), 768); + _screen->fadePalette(_screen->getPalette(0), 7, &_updateFunctor); + _screen->showMouse(); + + if (!queryGameFlag(4) && !queryGameFlag(0xB8)) { + objectChat(getTableString(0xEC, _cCodeBuffer, 1), 0, 0x83, 0xEC); + objectChat(getTableString(0xED, _cCodeBuffer, 1), 0, 0x83, 0xED); + objectChat(getTableString(0xEE, _cCodeBuffer, 1), 0, 0x83, 0xEE); + objectChat(getTableString(0xEF, _cCodeBuffer, 1), 0, 0x83, 0xEF); + setGameFlag(4); + } + + return 0; +} + +void KyraEngine_HoF::loadBookBkgd() { + char filename[16]; + + if (_flags.isTalkie) + strcpy(filename, (_bookBkgd == 0) ? "_XBOOKD.CPS" : "_XBOOKC.CPS"); + else + strcpy(filename, (_bookBkgd == 0) ? "_BOOKD.CPS" : "_BOOKC.CPS"); + + _bookBkgd ^= 1; + + if (_flags.isTalkie) { + if (!_bookCurPage) + strcpy(filename, "_XBOOKB.CPS"); + if (_bookCurPage == _bookMaxPage) + strcpy(filename, "_XBOOKA.CPS"); + + switch (_lang) { + case 0: + filename[1] = 'E'; + break; + + case 1: + filename[1] = 'F'; + break; + + case 2: + filename[1] = 'G'; + break; + + default: + warning("loadBookBkgd unsupported language"); + filename[1] = 'E'; + break; + } + } else { + if (!_bookCurPage) + strcpy(filename, "_BOOKB.CPS"); + if (_bookCurPage == _bookMaxPage) + strcpy(filename, "_BOOKA.CPS"); + } + + _screen->loadBitmap(filename, 3, 3, 0); +} + +void KyraEngine_HoF::showBookPage() { + char filename[16]; + + sprintf(filename, "PAGE%.01X.", _bookCurPage); + strcat(filename, _languageExtension[_lang]); + uint8 *leftPage = _res->fileData(filename, 0); + int leftPageY = _bookPageYOffset[_bookCurPage]; + + sprintf(filename, "PAGE%.01X.", _bookCurPage+1); + strcat(filename, _languageExtension[_lang]); + uint8 *rightPage = (_bookCurPage != _bookMaxPage) ? _res->fileData(filename, 0) : 0; + int rightPageY = _bookPageYOffset[_bookCurPage+1]; + + _screen->hideMouse(); + if (leftPage) { + bookDecodeText(leftPage); + bookPrintText(2, leftPage, 20, leftPageY+20, 0x31); + delete [] leftPage; + } + + if (rightPage) { + bookDecodeText(rightPage); + bookPrintText(2, rightPage, 176, rightPageY+20, 0x31); + delete [] rightPage; + } + _screen->showMouse(); +} + +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_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_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_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_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_HoF, this, &KyraEngine_HoF::bookNextPage); + + Button *buttonList = 0; + + for (uint i = 0; i < ARRAYSIZE(bookButtons); ++i) + buttonList = _gui->addButtonToList(buttonList, &bookButtons[i]); + + showBookPage(); + _bookShown = true; + while (_bookShown && !_quitFlag) { + checkInput(buttonList); + removeInputTop(); + + if (_bookCurPage != _bookNewPage) { + _bookCurPage = _bookNewPage; + _screen->clearPage(2); + loadBookBkgd(); + showBookPage(); + snd_playSoundEffect(0x64); + _screen->hideMouse(); + _screen->copyRegion(0, 0, 0, 0, 0x140, 0xC8, 2, 0, Screen::CR_NO_P_CHECK); + _screen->updateScreen(); + _screen->showMouse(); + } + } + _screen->clearPage(2); +} + +void KyraEngine_HoF::bookDecodeText(uint8 *str) { + uint8 *dst = str, *op = str; + while (*op != 0x1A) { + while (*op != 0x1A && *op != 0x0D) + *dst++ = *op++; + + if (*op == 0x1A) + break; + + op += 2; + *dst++ = 0x0D; + } + *dst = 0; +} + +void KyraEngine_HoF::bookPrintText(int dstPage, const uint8 *str, int x, int y, uint8 color) { + int curPageBackUp = _screen->_curPage; + _screen->_curPage = dstPage; + + _screen->setTextColor(_bookTextColorMap, 0, 3); + Screen::FontId oldFont = _screen->setFont(Screen::FID_BOOKFONT_FNT); + _screen->_charWidth = -2; + + _screen->hideMouse(); + _screen->printText((const char*)str, x, y, color, (_flags.lang == Common::JA_JPN) ? 0xf6 : 0); + _screen->showMouse(); + + _screen->_charWidth = 0; + _screen->setFont(oldFont); + _screen->_curPage = curPageBackUp; +} + +int KyraEngine_HoF::bookPrevPage(Button *button) { + _bookNewPage = MAX<int>(_bookCurPage-2, 0); + return 0; +} + +int KyraEngine_HoF::bookNextPage(Button *button) { + _bookNewPage = MIN<int>(_bookCurPage+2, _bookMaxPage); + return 0; +} + +int KyraEngine_HoF::bookClose(Button *button) { + _bookShown = false; + return 0; +} + +// cauldron specific code + +int KyraEngine_HoF::cauldronClearButton(Button *button) { + if (!queryGameFlag(2)) { + updateCharFacing(); + objectChat(getTableString(0xF0, _cCodeBuffer, 1), 0, 0x83, 0xF0); + return 0; + } + + if (queryGameFlag(0xE4)) { + snd_playSoundEffect(0x0D); + return 0; + } + + _screen->hideMouse(); + displayInvWsaLastFrame(); + snd_playSoundEffect(0x25); + loadInvWsa("PULL.WSA", 1, 6, 0, -1, -1, 1); + loadInvWsa("CAULD00.WSA", 1, 7, 0, 0xD4, 0x0F, 1); + showMessage(0, 0xCF); + setCauldronState(0, 0); + clearCauldronTable(); + snd_playSoundEffect(0x57); + loadInvWsa("CAULDFIL.WSA", 1, 7, 0, -1, -1, 1); + _screen->showMouse(); + return 0; +} + +int KyraEngine_HoF::cauldronButton(Button *button) { + if (!queryGameFlag(2)) { + objectChat(getTableString(0xF0, _cCodeBuffer, 1), 0, 0x83, 0xF0); + return 0; + } + + if (!_screen->isMouseVisible() || _handItemSet < -1) + return 0; + + if (queryGameFlag(0xE4)) { + snd_playSoundEffect(0x0D); + return 0; + } + + updateCharFacing(); + + for (int i = 0; _cauldronProtectedItems[i] != -1; ++i) { + if (_itemInHand == _cauldronProtectedItems[i]) { + objectChat(getTableString(0xF1, _cCodeBuffer, 1), 0, 0x83, 0xF1); + return 0; + } + } + + if (_itemInHand == -1) { + listItemsInCauldron(); + return 0; + } + + for (int i = 0; _cauldronBowlTable[i] != -1; i += 2) { + if (_itemInHand == _cauldronBowlTable[i]) { + addFrontCauldronTable(_itemInHand); + setHandItem(_cauldronBowlTable[i+1]); + if (!updateCauldron()) { + _cauldronState = 0; + cauldronRndPaletteFade(); + } + return 0; + } + } + + if (_itemInHand == 18) { + const int16 *magicTable = (_mainCharacter.sceneId == 77) ? _cauldronMagicTableScene77 : _cauldronMagicTable; + while (magicTable[0] != -1) { + if (_cauldronState == magicTable[0]) { + setHandItem(magicTable[1]); + snd_playSoundEffect(0x6C); + ++_cauldronUseCount; + if (_cauldronStateTable[_cauldronState] <= _cauldronUseCount && _cauldronUseCount) { + showMessage(0, 0xCF); + setCauldronState(0, true); + clearCauldronTable(); + } + return 0; + } + magicTable += 2; + } + } else if (_itemInHand >= 0) { + int item = _itemInHand; + cauldronItemAnim(item); + addFrontCauldronTable(item); + if (!updateCauldron()) { + _cauldronState = 0; + cauldronRndPaletteFade(); + } + } + + return 0; +} + +#pragma mark - + +int GUI_HoF::optionsButton(Button *button) { + _restartGame = false; + _reloadTemporarySave = false; + + _screen->hideMouse(); + updateButton(&_vm->_inventoryButtons[0]); + _screen->showMouse(); + + if (!_screen->isMouseVisible() && button) + return 0; + + _vm->showMessage(0, 0xCF); + + if (_vm->_handItemSet < -1) { + _vm->_handItemSet = -1; + _screen->hideMouse(); + _screen->setMouseCursor(1, 1, _vm->getShapePtr(0)); + _screen->showMouse(); + return 0; + } + + int oldHandItem = _vm->_itemInHand; + _screen->setMouseCursor(0, 0, _vm->getShapePtr(0)); + _vm->displayInvWsaLastFrame(); + //XXX + _displayMenu = true; + + for (uint i = 0; i < ARRAYSIZE(_menuButtons); ++i) { + _menuButtons[i].data0Val1 = _menuButtons[i].data1Val1 = _menuButtons[i].data2Val1 = 4; + _menuButtons[i].data0Callback = _redrawShadedButtonFunctor; + _menuButtons[i].data1Callback = _menuButtons[i].data2Callback = _redrawButtonFunctor; + } + + initMenuLayout(_mainMenu); + initMenuLayout(_gameOptions); + initMenuLayout(_audioOptions); + initMenuLayout(_choiceMenu); + _loadMenu.numberOfItems = 6; + initMenuLayout(_loadMenu); + initMenuLayout(_saveMenu); + initMenuLayout(_savenameMenu); + initMenuLayout(_deathMenu); + + _currentMenu = &_mainMenu; + + if (_vm->_menuDirectlyToLoad) { + backUpPage1(_vm->_screenBuffer); + setupPalette(); + + _loadedSave = false; + + loadMenu(0); + + if (_loadedSave) { + if (_restartGame) + _vm->_itemInHand = -1; + } else { + restorePage1(_vm->_screenBuffer); + restorePalette(); + } + + resetState(-1); + _vm->_menuDirectlyToLoad = false; + return 0; + } + + if (!button) { + _currentMenu = &_deathMenu; + _isDeathMenu = true; + } else { + _isDeathMenu = false; + } + + backUpPage1(_vm->_screenBuffer); + setupPalette(); + initMenu(*_currentMenu); + _madeSave = false; + _loadedSave = false; + _vm->_itemInHand = -1; + updateAllMenuButtons(); + + if (_isDeathMenu) { + while (!_screen->isMouseVisible()) + _screen->showMouse(); + } + + while (_displayMenu) { + processHighlights(*_currentMenu, _vm->_mouseX, _vm->_mouseY); + getInput(); + } + + if (_vm->_runFlag && !_loadedSave && !_madeSave) { + restorePalette(); + restorePage1(_vm->_screenBuffer); + } + + if (_vm->_runFlag) + updateMenuButton(&_vm->_inventoryButtons[0]); + + resetState(oldHandItem); + + if (!_loadedSave && _reloadTemporarySave) { + _vm->_unkSceneScreenFlag1 = true; + _vm->loadGame(_vm->getSavegameFilename(999)); + _vm->_saveFileMan->removeSavefile(_vm->getSavegameFilename(999)); + _vm->_unkSceneScreenFlag1 = false; + } + + return 0; +} + +#pragma mark - + +void GUI_HoF::setupPalette() { + memcpy(_screen->getPalette(1), _screen->getPalette(0), 768); + + uint8 *palette = _screen->getPalette(0); + for (int i = 0; i < 768; ++i) + palette[i] >>= 1; + + static const uint8 guiPal[] = { 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFc, 0xFD, 0xFE }; + + for (uint i = 0; i < ARRAYSIZE(guiPal); ++i) + memcpy(_screen->getPalette(0)+guiPal[i]*3, _screen->getPalette(1)+guiPal[i]*3, 3); + + if (_isDeathMenu) + _screen->fadePalette(_screen->getPalette(0), 0x64); + else + _screen->setScreenPalette(_screen->getPalette(0)); +} + +void GUI_HoF::restorePalette() { + memcpy(_screen->getPalette(0), _screen->getPalette(1), 768); + _screen->setScreenPalette(_screen->getPalette(0)); +} + +void GUI_HoF::resetState(int item) { + _vm->_timer->resetNextRun(); + _vm->setNextIdleAnimTimer(); + _isDeathMenu = false; + if (!_loadedSave) { + _vm->setHandItem(item); + } else { + _vm->setHandItem(_vm->_itemInHand); + _vm->setTimer1DelaySecs(7); + _vm->_shownMessage = " "; + _vm->_fadeMessagePalette = false; + } + _buttonListChanged = true; +} + +void GUI_HoF::drawSliderBar(int slider, const uint8 *shape) { + const int menuX = _audioOptions.x; + const int menuY = _audioOptions.y; + int x = menuX + _sliderBarsPosition[slider*2+0] + 10; + int y = menuY + _sliderBarsPosition[slider*2+1]; + + int position = 0; + if (_vm->gameFlags().isTalkie) { + position = _vm->getVolume(KyraEngine::kVolumeEntry(slider)); + } else { + if (slider < 2) + position = _vm->getVolume(KyraEngine::kVolumeEntry(slider)); + else if (slider == 2) + position = (_vm->_configWalkspeed == 3) ? 97 : 2; + else if (slider == 3) + position = _vm->_configTextspeed; + } + + position = MAX(2, position); + position = MIN(97, position); + _screen->drawShape(0, shape, x+position, y, 0, 0); +} + +#pragma mark - + +int GUI_HoF::quitGame(Button *caller) { + updateMenuButton(caller); + if (choiceDialog(_vm->gameFlags().isTalkie ? 0xF : 0x17, 1)) { + _displayMenu = false; + _vm->_runFlag = false; + _vm->_sound->beginFadeOut(); + _screen->fadeToBlack(); + _screen->clearCurPage(); + } + + if (_vm->_runFlag) { + initMenu(*_currentMenu); + updateAllMenuButtons(); + } + + return 0; +} + +int GUI_HoF::audioOptions(Button *caller) { + updateMenuButton(caller); + restorePage1(_vm->_screenBuffer); + backUpPage1(_vm->_screenBuffer); + initMenu(_audioOptions); + const int menuX = _audioOptions.x; + const int menuY = _audioOptions.y; + const int maxButton = 3; // 2 if voc is disabled + + for (int i = 0; i < maxButton; ++i) { + int x = menuX + _sliderBarsPosition[i*2+0]; + int y = menuY + _sliderBarsPosition[i*2+1]; + _screen->drawShape(0, _vm->_buttonShapes[16], x, y, 0, 0); + drawSliderBar(i, _vm->_buttonShapes[17]); + _sliderButtons[0][i].buttonCallback = _sliderHandlerFunctor; + _sliderButtons[0][i].x = x; + _sliderButtons[0][i].y = y; + _menuButtonList = addButtonToList(_menuButtonList, &_sliderButtons[0][i]); + _sliderButtons[2][i].buttonCallback = _sliderHandlerFunctor; + _sliderButtons[2][i].x = x + 10; + _sliderButtons[2][i].y = y; + _menuButtonList = addButtonToList(_menuButtonList, &_sliderButtons[2][i]); + _sliderButtons[1][i].buttonCallback = _sliderHandlerFunctor; + _sliderButtons[1][i].x = x + 120; + _sliderButtons[1][i].y = y; + _menuButtonList = addButtonToList(_menuButtonList, &_sliderButtons[1][i]); + } + + _isOptionsMenu = true; + updateAllMenuButtons(); + bool speechEnabled = _vm->speechEnabled(); + while (_isOptionsMenu) { + processHighlights(_audioOptions, _vm->_mouseX, _vm->_mouseY); + getInput(); + } + + restorePage1(_vm->_screenBuffer); + backUpPage1(_vm->_screenBuffer); + if (speechEnabled && !_vm->textEnabled() && (!_vm->speechEnabled() || _vm->getVolume(KyraEngine::kVolumeSpeech) == 2)) { + _vm->_configVoice = 0; + choiceDialog(0x1D, 0); + } + + _vm->writeSettings(); + + initMenu(*_currentMenu); + updateAllMenuButtons(); + return 0; +} + +int GUI_HoF::gameOptions(Button *caller) { + updateMenuButton(caller); + restorePage1(_vm->_screenBuffer); + backUpPage1(_vm->_screenBuffer); + initMenu(_gameOptions); + _isOptionsMenu = true; + + const int menuX = _gameOptions.x; + const int menuY = _gameOptions.y; + + for (int i = 0; i < 4; ++i) { + int x = menuX + _sliderBarsPosition[i*2+0]; + int y = menuY + _sliderBarsPosition[i*2+1]; + _screen->drawShape(0, _vm->_buttonShapes[16], x, y, 0, 0); + drawSliderBar(i, _vm->_buttonShapes[17]); + _sliderButtons[0][i].buttonCallback = _sliderHandlerFunctor; + _sliderButtons[0][i].x = x; + _sliderButtons[0][i].y = y; + _menuButtonList = addButtonToList(_menuButtonList, &_sliderButtons[0][i]); + _sliderButtons[2][i].buttonCallback = _sliderHandlerFunctor; + _sliderButtons[2][i].x = x + 10; + _sliderButtons[2][i].y = y; + _menuButtonList = addButtonToList(_menuButtonList, &_sliderButtons[2][i]); + _sliderButtons[1][i].buttonCallback = _sliderHandlerFunctor; + _sliderButtons[1][i].x = x + 120; + _sliderButtons[1][i].y = y; + _menuButtonList = addButtonToList(_menuButtonList, &_sliderButtons[1][i]); + } + + while (_isOptionsMenu) { + processHighlights(_gameOptions, _vm->_mouseX, _vm->_mouseY); + getInput(); + } + + restorePage1(_vm->_screenBuffer); + backUpPage1(_vm->_screenBuffer); + + _vm->writeSettings(); + + initMenu(*_currentMenu); + updateAllMenuButtons(); + + return 0; +} + +int GUI_HoF::gameOptionsTalkie(Button *caller) { + updateMenuButton(caller); + restorePage1(_vm->_screenBuffer); + backUpPage1(_vm->_screenBuffer); + bool textEnabled = _vm->textEnabled(); + int lang = _vm->_lang; + + setupOptionsButtons(); + initMenu(_gameOptions); + _isOptionsMenu = true; + + while (_isOptionsMenu) { + processHighlights(_gameOptions, _vm->_mouseX, _vm->_mouseY); + getInput(); + } + + restorePage1(_vm->_screenBuffer); + backUpPage1(_vm->_screenBuffer); + + if (textEnabled && !_vm->textEnabled() && !_vm->speechEnabled()) { + _vm->_configVoice = 1; + _vm->setVolume(KyraEngine::kVolumeSpeech, 75); + choiceDialog(0x1E, 0); + } + + if (_vm->_lang != lang) { + _reloadTemporarySave = true; + _vm->saveGame(_vm->getSavegameFilename(999), "Temporary Kyrandia 2 Savegame"); + _vm->loadCCodeBuffer("C_CODE.XXX"); + if (_vm->_flags.isTalkie) + _vm->loadOptionsBuffer("OPTIONS.XXX"); + else + _vm->_optionsBuffer = _vm->_cCodeBuffer; + _vm->loadChapterBuffer(_vm->_newChapterFile); + _vm->loadNPCScript(); + _vm->setupLangButtonShapes(); + } + + _vm->writeSettings(); + + initMenu(*_currentMenu); + updateAllMenuButtons(); + return 0; +} + +int GUI_HoF::changeLanguage(Button *caller) { + updateMenuButton(caller); + ++_vm->_lang; + _vm->_lang %= 3; + setupOptionsButtons(); + renewHighlight(_gameOptions); + return 0; +} + +void GUI_HoF::setupOptionsButtons() { + if (_vm->_configWalkspeed == 3) + _gameOptions.item[0].itemId = 28; + else + _gameOptions.item[0].itemId = 27; + + if (_vm->textEnabled()) + _gameOptions.item[2].itemId = 18; + else + _gameOptions.item[2].itemId = 17; + + switch (_vm->_lang) { + case 0: + _gameOptions.item[1].itemId = 31; + break; + + case 1: + _gameOptions.item[1].itemId = 32; + break; + + case 2: + _gameOptions.item[1].itemId = 33; + break; + + default: + break; + } +} + +int GUI_HoF::sliderHandler(Button *caller) { + int button = 0; + if (caller->index >= 24 && caller->index <= 27) + button = caller->index - 24; + else if (caller->index >= 28 && caller->index <= 31) + button = caller->index - 28; + else + button = caller->index - 32; + + assert(button >= 0 && button <= 3); + + int oldVolume = 0; + + if (_vm->gameFlags().isTalkie) { + oldVolume = _vm->getVolume(KyraEngine::kVolumeEntry(button)); + } else { + if (button < 2) + oldVolume = _vm->getVolume(KyraEngine::kVolumeEntry(button)); + else if (button == 2) + oldVolume = (_vm->_configWalkspeed == 3) ? 97 : 2; + else if (button == 3) + oldVolume = _vm->_configTextspeed; + } + + int newVolume = oldVolume; + + if (caller->index >= 24 && caller->index <= 27) + newVolume -= 10; + else if (caller->index >= 28 && caller->index <= 31) + newVolume += 10; + else + newVolume = _vm->_mouseX - caller->x - 7; + + newVolume = MAX(2, newVolume); + newVolume = MIN(97, newVolume); + + if (newVolume == oldVolume) + return 0; + + int lastMusicCommand = -1; + bool playSoundEffect = false; + + drawSliderBar(button, _vm->_buttonShapes[18]); + + if (_vm->gameFlags().isTalkie) { + if (button == 2) { + if (_vm->textEnabled()) + _vm->_configVoice = 2; + else + _vm->_configVoice = 1; + } + + _vm->setVolume(KyraEngine::kVolumeEntry(button), newVolume); + + switch (button) { + case 0: + lastMusicCommand = _vm->_lastMusicCommand; + break; + + case 1: + playSoundEffect = true; + break; + + case 2: + _vm->playVoice(90, 28); + break; + + default: + return 0; + } + } else { + if (button < 2) { + _vm->setVolume(KyraEngine::kVolumeEntry(button), newVolume); + if (button == 0) + lastMusicCommand = _vm->_lastMusicCommand; + else + playSoundEffect = true; + } else if (button == 2) { + _vm->_configWalkspeed = (newVolume > 48) ? 3 : 5; + _vm->setWalkspeed(_vm->_configWalkspeed); + } else if (button == 3) { + _vm->_configTextspeed = newVolume; + } + } + + drawSliderBar(button, _vm->_buttonShapes[17]); + if (playSoundEffect) + _vm->snd_playSoundEffect(0x18); + else if (lastMusicCommand >= 0) + _vm->snd_playWanderScoreViaMap(lastMusicCommand, 1); + + _screen->updateScreen(); + return 0; +} + +int GUI_HoF::loadMenu(Button *caller) { + updateSaveList(); + + if (!_vm->_menuDirectlyToLoad) { + updateMenuButton(caller); + restorePage1(_vm->_screenBuffer); + backUpPage1(_vm->_screenBuffer); + } + + _savegameOffset = 0; + setupSavegameNames(_loadMenu, 5); + initMenu(_loadMenu); + _isLoadMenu = true; + _noLoadProcess = false; + _vm->_gameToLoad = -1; + updateAllMenuButtons(); + + _screen->updateScreen(); + while (_isLoadMenu) { + processHighlights(_loadMenu, _vm->_mouseX, _vm->_mouseY); + getInput(); + } + + if (_noLoadProcess) { + if (!_vm->_menuDirectlyToLoad) { + restorePage1(_vm->_screenBuffer); + backUpPage1(_vm->_screenBuffer); + initMenu(*_currentMenu); + updateAllMenuButtons(); + } + } else if (_vm->_gameToLoad >= 0) { + restorePage1(_vm->_screenBuffer); + restorePalette(); + _vm->loadGame(_vm->getSavegameFilename(_vm->_gameToLoad)); + if (_vm->_gameToLoad == 0) { + _restartGame = true; + for (int i = 0; i < 23; ++i) + _vm->resetCauldronStateTable(i); + _vm->runStartScript(1, 1); + } + _displayMenu = false; + _loadedSave = true; + } + + return 0; +} + +} // end of namespace Kyra + diff --git a/engines/kyra/gui_hof.h b/engines/kyra/gui_hof.h new file mode 100644 index 0000000000..f64336a8f6 --- /dev/null +++ b/engines/kyra/gui_hof.h @@ -0,0 +1,86 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#ifndef KYRA_GUI_HOF_H +#define KYRA_GUI_HOF_H + +#include "kyra/gui_v2.h" + +namespace Kyra { + +class KyraEngine_HoF; +class Screen_HoF; + +class GUI_HoF : public GUI_v2 { +friend class KyraEngine_HoF; +public: + GUI_HoF(KyraEngine_HoF *engine); + + void initStaticData(); + + int optionsButton(Button *button); +private: + const char *getMenuTitle(const Menu &menu); + const char *getMenuItemTitle(const MenuItem &menuItem); + const char *getMenuItemLabel(const MenuItem &menuItem); + + uint8 defaultColor1() const { return 0xCF; } + uint8 defaultColor2() const { return 0xF8; } + + uint8 textFieldColor1() const { return 0xFD; } + uint8 textFieldColor2() const { return 0xFA; } + uint8 textFieldColor3() const { return 0xFE; } + + void setupPalette(); + void restorePalette(); + + void resetState(int item); + + char *getTableString(int id); + + KyraEngine_HoF *_vm; + Screen_HoF *_screen; + + int quitGame(Button *caller); + int loadMenu(Button *caller); + int audioOptions(Button *caller); + int gameOptions(Button *caller); + int gameOptionsTalkie(Button *caller); + + int changeLanguage(Button *caller); + + void setupOptionsButtons(); + + int sliderHandler(Button *caller); + void drawSliderBar(int slider, const uint8 *shape); + + static const uint16 _menuStringsTalkie[]; + static const uint16 _menuStringsOther[]; +}; + +} // end of namespace Kyra + +#endif + diff --git a/engines/kyra/gui_mr.cpp b/engines/kyra/gui_mr.cpp new file mode 100644 index 0000000000..8d27938aff --- /dev/null +++ b/engines/kyra/gui_mr.cpp @@ -0,0 +1,1223 @@ +/* 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/gui_mr.h" +#include "kyra/kyra_mr.h" +#include "kyra/text_mr.h" +#include "kyra/wsamovie.h" +#include "kyra/resource.h" +#include "kyra/sound.h" +#include "kyra/timer.h" + +#include "common/savefile.h" + +namespace Kyra { + +void KyraEngine_MR::loadButtonShapes() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::loadButtonShapes()"); + _res->exists("BUTTONS.SHP", true); + uint8 *data = _res->fileData("BUTTONS.SHP", 0); + assert(data); + for (int i = 0; i <= 10; ++i) + addShapeToPool(data, 0x1C7+i, i); + delete[] data; + + Button::Callback callback1 = BUTTON_FUNCTOR(KyraEngine_MR, this, &KyraEngine_MR::callbackButton1); + Button::Callback callback2 = BUTTON_FUNCTOR(KyraEngine_MR, this, &KyraEngine_MR::callbackButton2); + Button::Callback callback3 = BUTTON_FUNCTOR(KyraEngine_MR, this, &KyraEngine_MR::callbackButton3); + + _gui->getScrollUpButton()->data0Callback = callback1; + _gui->getScrollUpButton()->data1Callback = callback2; + _gui->getScrollUpButton()->data2Callback = callback3; + _gui->getScrollDownButton()->data0Callback = callback1; + _gui->getScrollDownButton()->data1Callback = callback2; + _gui->getScrollDownButton()->data2Callback = callback3; + + _mainButtonData[0].data0Callback = callback1; + _mainButtonData[0].data1Callback = callback2; + _mainButtonData[0].data2Callback = callback3; +} + +int KyraEngine_MR::callbackButton1(Button *button) { + const uint8 *shapePtr = 0; + if (button->index == 1) + shapePtr = getShapePtr(0x1CD); + else if (button->index == 22) + shapePtr = getShapePtr(0x1C7); + else if (button->index == 23) + shapePtr = getShapePtr(0x1CA); + + if (shapePtr) + _screen->drawShape(0, shapePtr, button->x, button->y, 0, 0, 0); + + return 0; +} + +int KyraEngine_MR::callbackButton2(Button *button) { + const uint8 *shapePtr = 0; + if (button->index == 1) + shapePtr = getShapePtr(0x1CE); + else if (button->index == 22) + shapePtr = getShapePtr(0x1C9); + else if (button->index == 23) + shapePtr = getShapePtr(0x1CC); + + if (shapePtr) + _screen->drawShape(0, shapePtr, button->x, button->y, 0, 0, 0); + + return 0; +} + +int KyraEngine_MR::callbackButton3(Button *button) { + const uint8 *shapePtr = 0; + if (button->index == 1) + shapePtr = getShapePtr(0x1CE); + else if (button->index == 22) + shapePtr = getShapePtr(0x1C8); + else if (button->index == 23) + shapePtr = getShapePtr(0x1CB); + + if (shapePtr) + _screen->drawShape(0, shapePtr, button->x, button->y, 0, 0, 0); + + return 0; +} + +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(); + + restoreCommandLine(); + _restoreCommandLine = false; + + if (string) { + int x = _text->getCenterStringX(string, 0, 320); + int pageBackUp = _screen->_curPage; + _screen->_curPage = 0; + _text->printText(string, x, _commandLineY, c0, c1, 0); + _screen->_curPage = pageBackUp; + _screen->updateScreen(); + setCommandLineRestoreTimer(7); + } + + _screen->showMouse(); +} + +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_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); + + while (*src != ' ') + ++src; + ++src; + + *src = toupper(*src); + + strcpy(buffer, src); + strcat(buffer, " "); + strcat(buffer, (const char*)getTableEntry(_cCodeFile, str)); + + showMessage(buffer, c0, 0xF0); +} + +void KyraEngine_MR::updateCommandLine() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::updateCommandLine()"); + if (_restoreCommandLine) { + restoreCommandLine(); + _restoreCommandLine = false; + } +} + +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_MR::updateCLState() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::updateCLState()"); + if (_inventoryState) + _commandLineY = 145; + else + _commandLineY = 189; +} + +void KyraEngine_MR::showInventory() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::showInventory()"); + if (!_screen->isMouseVisible()) + return; + if (queryGameFlag(3)) + return; + + _screen->copyBlockToPage(3, 0, 0, 320, 56, _interface); + drawMalcolmsMoodText(); + + _inventoryState = true; + updateCLState(); + + redrawInventory(30); + drawMalcolmsMoodPointer(-1, 30); + drawScore(30, 215, 191); + + if (queryGameFlag(0x97)) + drawJestersStaff(1, 30); + + _screen->hideMouse(); + + if (_itemInHand < 0) { + _handItemSet = -1; + _screen->setMouseCursor(0, 0, getShapePtr(0)); + } + + _screen->copyRegion(0, 188, 0, 0, 320, 12, 0, 2, Screen::CR_NO_P_CHECK); + + if (_inventoryScrollSpeed == -1) { + uint32 endTime = _system->getMillis() + _tickLength * 15; + int times = 0; + while (_system->getMillis() < endTime) { + _screen->copyRegion(0, 188, 0, 0, 320, 12, 0, 2, Screen::CR_NO_P_CHECK); + _screen->copyRegion(0, 188, 0, 0, 320, 12, 0, 2, Screen::CR_NO_P_CHECK); + ++times; + } + + times = MAX(times, 1); + + int speed = 60 / times; + if (speed <= 1) + _inventoryScrollSpeed = 1; + else if (speed >= 8) + _inventoryScrollSpeed = 8; + else + _inventoryScrollSpeed = speed; + } + + int height = 12; + int y = 188; + int times = 0; + uint32 waitTill = _system->getMillis() + _tickLength; + + while (y > 144) { + _screen->copyRegion(0, 0, 0, y, 320, height, 2, 0, Screen::CR_NO_P_CHECK); + _screen->updateScreen(); + + ++times; + if (_inventoryScrollSpeed == 1 && times == 3) { + while (waitTill > _system->getMillis()) + _system->delayMillis(10); + times = 0; + waitTill = _system->getMillis() + _tickLength; + } + + height += _inventoryScrollSpeed; + y -= _inventoryScrollSpeed; + } + + _screen->copyRegion(0, 0, 0, 144, 320, 56, 2, 0, Screen::CR_NO_P_CHECK); + _screen->updateScreen(); + + initMainButtonList(false); + + restorePage3(); + _screen->showMouse(); +} + +void KyraEngine_MR::hideInventory() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::hideInventory()"); + if (queryGameFlag(3)) + return; + + _inventoryState = false; + updateCLState(); + initMainButtonList(true); + + _screen->copyBlockToPage(3, 0, 0, 320, 56, _interface); + _screen->hideMouse(); + + restorePage3(); + flagAnimObjsForRefresh(); + drawAnimObjects(); + _screen->copyRegion(0, 144, 0, 0, 320, 56, 0, 2, Screen::CR_NO_P_CHECK); + + if (_inventoryScrollSpeed == -1) { + uint32 endTime = _system->getMillis() + _tickLength * 15; + int times = 0; + while (_system->getMillis() < endTime) { + _screen->copyRegion(0, 144, 0, 0, 320, 12, 0, 2, Screen::CR_NO_P_CHECK); + _screen->copyRegion(0, 144, 0, 0, 320, 12, 0, 2, Screen::CR_NO_P_CHECK); + ++times; + } + + times = MAX(times, 1); + + int speed = 60 / times; + if (speed <= 1) + _inventoryScrollSpeed = 1; + else if (speed >= 8) + _inventoryScrollSpeed = 8; + else + _inventoryScrollSpeed = speed; + } + + int y = 144; + int y2 = 144 + _inventoryScrollSpeed; + uint32 waitTill = _system->getMillis() + _tickLength; + int times = 0; + + while (y2 < 188) { + _screen->copyRegion(0, 0, 0, y2, 320, 56, 2, 0, Screen::CR_NO_P_CHECK); + _screen->copyRegion(0, y, 0, y, 320, _inventoryScrollSpeed, 2, 0, Screen::CR_NO_P_CHECK); + _screen->updateScreen(); + + ++times; + if (_inventoryScrollSpeed == 1 && times == 3) { + while (waitTill > _system->getMillis()) + _system->delayMillis(10); + times = 0; + waitTill = _system->getMillis() + _tickLength; + } + + y += _inventoryScrollSpeed; + y2 += _inventoryScrollSpeed; + } + + _screen->copyRegion(0, 0, 0, 188, 320, 56, 2, 0, Screen::CR_NO_P_CHECK); + _screen->copyRegion(0, y, 0, y, 320, 188-y, 2, 0, Screen::CR_NO_P_CHECK); + _screen->showMouse(); +} + +void KyraEngine_MR::drawMalcolmsMoodText() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::drawMalcolmsMoodText()"); + static const int stringId[] = { 0x32, 0x37, 0x3C }; + + if (queryGameFlag(0x219)) + return; + + const char *string = (const char*)getTableEntry(_cCodeFile, stringId[_malcolmsMood]); + + Screen::FontId oldFont = _screen->setFont(Screen::FID_8_FNT); + _screen->_charWidth = -2; + + int width = _screen->getTextWidth(string); + + _screen->_charWidth = 0; + _screen->setFont(oldFont); + + int pageBackUp = _screen->_curPage; + const int x = 280 - (width / 2); + int y = 0; + if (_inventoryState) { + y = 189; + _screen->_curPage = 0; + } else { + y = 45; + _screen->_curPage = 2; + } + + _screen->hideMouse(); + _screen->drawShape(_screen->_curPage, getShapePtr(432), 244, 189, 0, 0); + _text->printText(string, x, y+1, 0xFF, 0xF0, 0x00); + _screen->showMouse(); + _screen->_curPage = pageBackUp; +} + +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 + }; + + if (frame == -1) + frame = stateTable[_malcolmsMood]; + if (queryGameFlag(0x219)) + frame = 13; + + if (page == 0) { + _invWsa->setX(0); + _invWsa->setY(0); + _invWsa->setDrawPage(0); + _invWsa->displayFrame(frame, 0); + _screen->updateScreen(); + } else if (page == 30) { + _invWsa->setX(0); + _invWsa->setY(-144); + _invWsa->setDrawPage(2); + _invWsa->displayFrame(frame, 0); + } + + _invWsaFrame = frame; +} + +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; + y -= 144; + } + + int shape = (type != 0) ? 454 : 453; + _screen->drawShape(page, getShapePtr(shape), 217, y, 0, 0); +} + +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; + } + + int shape1 = _score / 100; + int shape2 = (_score - shape1*100) / 10; + int shape3 = _score % 10; + + _screen->drawShape(page, getShapePtr(shape1+433), x, y, 0, 0); + x += 8; + _screen->drawShape(page, getShapePtr(shape2+433), x, y, 0, 0); + x += 8; + _screen->drawShape(page, getShapePtr(shape3+433), x, y, 0, 0); +} + +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; + + int old100 = oldScore / 100; + int old010 = (oldScore - old100*100) / 10; + int old001 = oldScore % 10; + + int new100 = newScore / 100; + int new010 = (newScore - new100*100) / 10; + int new001 = newScore % 10; + + if (drawOld) { + _screen->drawShape(0, getShapePtr(old100+433), x + 0, y, 0, 0); + _screen->drawShape(0, getShapePtr(old010+433), x + 8, y, 0, 0); + _screen->drawShape(0, getShapePtr(old001+433), x + 16, y, 0, 0); + } + + if (old100 != new100) + _screen->drawShape(0, getShapePtr(old100+443), x + 0, y, 0, 0); + + if (old010 != new010) + _screen->drawShape(0, getShapePtr(old010+443), x + 8, y, 0, 0); + + _screen->drawShape(0, getShapePtr(old001+443), x + 16, y, 0, 0); + + _screen->updateScreen(); + + _screen->drawShape(0, getShapePtr(new100+433), x + 0, y, 0, 0); + _screen->drawShape(0, getShapePtr(new010+433), x + 8, y, 0, 0); + _screen->drawShape(0, getShapePtr(new001+433), x + 16, y, 0, 0); +} + +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; + + int width = _screen->getTextWidth(str); + int x = 160 + (width / 2) - 32; + + _screen->setFont(oldFont); + _screen->_charWidth = 0; + return x; +} + +void KyraEngine_MR::redrawInventory(int page) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::redrawInventory(%d)", page); + int yOffset = 0; + + if (page == 30) { + page = 2; + yOffset = -144; + } + + int pageBackUp = _screen->_curPage; + _screen->_curPage = page; + _screen->hideMouse(); + + for (int i = 0; i < 10; ++i) { + clearInventorySlot(i, page); + if (_mainCharacter.inventory[i] != 0xFFFF) { + _screen->drawShape(page, getShapePtr(_mainCharacter.inventory[i]+248), _inventoryX[i], _inventoryY[i] + yOffset, 0, 0); + drawInventorySlot(page, _mainCharacter.inventory[i], i); + } + } + + _screen->showMouse(); + _screen->_curPage = pageBackUp; + + if (page == 0 || page == 1) + _screen->updateScreen(); +} + +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; + yOffset = -144; + } + + _screen->drawShape(page, getShapePtr(slot+422), _inventoryX[slot], _inventoryY[slot] + yOffset, 0, 0); +} + +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; + yOffset = -144; + } + + _screen->drawShape(page, getShapePtr(item+248), _inventoryX[slot], _inventoryY[slot] + yOffset, 0, 0); +} + +int KyraEngine_MR::buttonInventory(Button *button) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::buttonInventory(%p)", (const void*)button); + setNextIdleAnimTimer(); + if (!_enableInventory || !_inventoryState || !_screen->isMouseVisible()) + return 0; + + const int slot = button->index - 5; + const int16 slotItem = (int16)_mainCharacter.inventory[slot]; + if (_itemInHand == -1) { + if (slotItem == -1) + return 0; + + _screen->hideMouse(); + clearInventorySlot(slot, 0); + snd_playSoundEffect(0x0B, 0xC8); + setMouseCursor(slotItem); + updateItemCommand(slotItem, (_lang == 1) ? getItemCommandStringPickUp(slotItem) : 0, 0xFF); + _itemInHand = slotItem; + _mainCharacter.inventory[slot] = 0xFFFF; + _screen->showMouse(); + } else if (_itemInHand == 27) { + if (_chatText) + return 0; + return buttonJesterStaff(&_mainButtonData[3]); + } else { + if (slotItem >= 0) { + if (itemInventoryMagic(_itemInHand, slot)) + return 0; + + snd_playSoundEffect(0x0B, 0xC8); + + _screen->hideMouse(); + clearInventorySlot(slot, 0); + drawInventorySlot(0, _itemInHand, slot); + setMouseCursor(slotItem); + updateItemCommand(slotItem, (_lang == 1) ? getItemCommandStringPickUp(slotItem) : 0, 0xFF); + _mainCharacter.inventory[slot] = _itemInHand; + _itemInHand = slotItem; + _screen->showMouse(); + } else { + snd_playSoundEffect(0x0C, 0xC8); + _screen->hideMouse(); + drawInventorySlot(0, _itemInHand, slot); + _screen->setMouseCursor(0, 0, getShapePtr(0)); + updateItemCommand(_itemInHand, (_lang == 1) ? getItemCommandStringInv(_itemInHand) : 2, 0xFF); + _screen->showMouse(); + _mainCharacter.inventory[slot] = _itemInHand; + _itemInHand = -1; + } + } + + return 0; +} + +int KyraEngine_MR::buttonMoodChange(Button *button) { + if (queryGameFlag(0x219)) { + snd_playSoundEffect(0x0D, 0xC8); + return 0; + } + + static const uint8 frameTable[] = { 1, 6, 11 }; + + if (_mouseX >= 245 && _mouseX <= 267 && _mouseY >= 159 && _mouseY <= 198) + _malcolmsMood = 0; + else if (_mouseX >= 268 && _mouseX <= 289 && _mouseY >= 159 && _mouseY <= 198) + _malcolmsMood = 1; + else if (_mouseX >= 290 && _mouseX <= 312 && _mouseY >= 159 && _mouseY <= 198) + _malcolmsMood = 2; + + int direction = (_invWsaFrame > frameTable[_malcolmsMood]) ? -1 : 1; + + if (_invWsaFrame != frameTable[_malcolmsMood]) { + _screen->hideMouse(); + setGameFlag(3); + + snd_playSoundEffect(0x2E, 0xC8); + + while (_invWsaFrame != frameTable[_malcolmsMood]) { + uint32 endTime = _system->getMillis() + 2 * _tickLength; + _invWsaFrame += direction; + + drawMalcolmsMoodPointer(_invWsaFrame, 0); + _screen->updateScreen(); + + while (endTime > _system->getMillis()) { + update(); + _system->delayMillis(10); + } + } + + resetGameFlag(3); + _screen->showMouse(); + + drawMalcolmsMoodText(); + updateDlgIndex(); + + 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, 1); + + int vocHigh = _vocHigh; + _vocHigh = 200; + _useActorBuffer = true; + + while (_emc->isValid(&state)) + _emc->run(&state); + + _useActorBuffer = false; + _vocHigh = vocHigh; + _emc->unload(&data); + } + + return 0; +} + +int KyraEngine_MR::buttonShowScore(Button *button) { + strcpy(_stringBuffer, (const char*)getTableEntry(_cCodeFile, 18)); + + char *buffer = _stringBuffer; + + while (*buffer != '%') + ++buffer; + + buffer[0] = (_score / 100) + '0'; + buffer[1] = ((_score % 100) / 10) + '0'; + buffer[2] = (_score % 10) + '0'; + + while (*buffer != '%') + ++buffer; + + buffer[0] = (_scoreMax / 100) + '0'; + buffer[1] = ((_scoreMax % 100) / 10) + '0'; + buffer[2] = (_scoreMax % 10) + '0'; + + showMessage(_stringBuffer, 0xFF, 0xF0); + return 0; +} + +int KyraEngine_MR::buttonJesterStaff(Button *button) { + makeCharFacingMouse(); + if (_itemInHand == 27) { + _screen->hideMouse(); + removeHandItem(); + snd_playSoundEffect(0x0C, 0xC8); + drawJestersStaff(1, 0); + updateItemCommand(27, 2, 0xFF); + setGameFlag(0x97); + _screen->showMouse(); + } else if (_itemInHand == -1) { + if (queryGameFlag(0x97)) { + _screen->hideMouse(); + snd_playSoundEffect(0x0B, 0xC8); + setHandItem(27); + drawJestersStaff(0, 0); + updateItemCommand(27, 0, 0xFF); + resetGameFlag(0x97); + _screen->showMouse(); + } else { + if (queryGameFlag(0x2F)) + objectChat((const char*)getTableEntry(_cCodeFile, 20), 0, 204, 20); + else + objectChat((const char*)getTableEntry(_cCodeFile, 25), 0, 204, 25); + } + } else { + objectChat((const char*)getTableEntry(_cCodeFile, 30), 0, 204, 30); + } + return 0; +} + +#pragma mark - + +GUI_MR::GUI_MR(KyraEngine_MR *vm) : GUI_v2(vm), _vm(vm), _screen(vm->_screen) { +} + +void GUI_MR::flagButtonEnable(Button *button) { + if (!button) + return; + + if (button->flags & 8) { + button->flags &= ~8; + processButton(button); + } +} + +void GUI_MR::flagButtonDisable(Button *button) { + if (!button) + return; + + if (!(button->flags & 8)) { + button->flags |= 8; + processButton(button); + } +} + +const char *GUI_MR::getMenuTitle(const Menu &menu) { + if (!menu.menuNameId) + return 0; + + return (const char *)_vm->getTableEntry(_vm->_optionsFile, menu.menuNameId); +} + +const char *GUI_MR::getMenuItemTitle(const MenuItem &menuItem) { + if (!menuItem.itemId) + return 0; + + return (const char *)_vm->getTableEntry(_vm->_optionsFile, menuItem.itemId); +} + +const char *GUI_MR::getMenuItemLabel(const MenuItem &menuItem) { + if (!menuItem.labelId) + return 0; + + return (const char *)_vm->getTableEntry(_vm->_optionsFile, menuItem.labelId); +} + +char *GUI_MR::getTableString(int id) { + return (char *)_vm->getTableEntry(_vm->_optionsFile, id); +} + +int GUI_MR::redrawButtonCallback(Button *button) { + if (!_displayMenu) + return 0; + + _screen->hideMouse(); + _screen->drawBox(button->x + 1, button->y + 1, button->x + button->width - 1, button->y + button->height - 1, 0xD0); + _screen->showMouse(); + + return 0; +} + +int GUI_MR::redrawShadedButtonCallback(Button *button) { + if (!_displayMenu) + return 0; + + _screen->hideMouse(); + _screen->drawShadedBox(button->x, button->y, button->x + button->width, button->y + button->height, 0xD1, 0xCF); + _screen->showMouse(); + + return 0; +} +void GUI_MR::resetState(int item) { + _vm->_timer->resetNextRun(); + _vm->setNextIdleAnimTimer(); + _isDeathMenu = false; + if (!_loadedSave) { + _vm->setHandItem(item); + } else { + _vm->setHandItem(_vm->_itemInHand); + _vm->setCommandLineRestoreTimer(7); + _vm->_shownMessage = " "; + _vm->_restoreCommandLine = false; + } + _buttonListChanged = true; +} + +int GUI_MR::quitGame(Button *caller) { + updateMenuButton(caller); + if (choiceDialog(0x0F, 1)) { + _displayMenu = false; + _vm->_runFlag = false; + _vm->fadeOutMusic(60); + _screen->fadeToBlack(60); + _screen->clearCurPage(); + } + + if (_vm->_runFlag) { + initMenu(*_currentMenu); + updateAllMenuButtons(); + } + + return 0; +} + +int GUI_MR::optionsButton(Button *button) { + _vm->musicUpdate(0); + + _screen->hideMouse(); + updateButton(&_vm->_mainButtonData[0]); + _screen->showMouse(); + + if (!_vm->_inventoryState && button && !_vm->_menuDirectlyToLoad) + return 0; + + _restartGame = false; + _reloadTemporarySave = false; + + if (!_screen->isMouseVisible() && button && !_vm->_menuDirectlyToLoad) + return 0; + + _vm->showMessage(0, 0xF0, 0xF0); + + if (_vm->_handItemSet < -1) { + _vm->_handItemSet = -1; + _screen->hideMouse(); + _screen->setMouseCursor(1, 1, _vm->getShapePtr(0)); + _screen->showMouse(); + return 0; + } + + int oldHandItem = _vm->_itemInHand; + _screen->setMouseCursor(0, 0, _vm->getShapePtr(0)); + _vm->musicUpdate(0); + + _displayMenu = true; + for (int i = 0; i < 4; ++i) { + if (_vm->_musicSoundChannel != i) + _vm->_soundDigital->stopSound(i); + } + + for (uint i = 0; i < ARRAYSIZE(_menuButtons); ++i) { + _menuButtons[i].data0Val1 = _menuButtons[i].data1Val1 = _menuButtons[i].data2Val1 = 4; + _menuButtons[i].data0Callback = _redrawShadedButtonFunctor; + _menuButtons[i].data1Callback = _menuButtons[i].data2Callback = _redrawButtonFunctor; + } + + initMenuLayout(_mainMenu); + initMenuLayout(_gameOptions); + initMenuLayout(_audioOptions); + initMenuLayout(_choiceMenu); + _loadMenu.numberOfItems = 6; + initMenuLayout(_loadMenu); + initMenuLayout(_saveMenu); + initMenuLayout(_savenameMenu); + initMenuLayout(_deathMenu); + + _currentMenu = &_mainMenu; + + _vm->musicUpdate(0); + + if (_vm->_menuDirectlyToLoad) { + backUpPage1(_vm->_screenBuffer); + + _loadedSave = false; + + --_loadMenu.numberOfItems; + loadMenu(0); + ++_loadMenu.numberOfItems; + + if (_loadedSave) { + if (_restartGame) + _vm->_itemInHand = -1; + } else { + restorePage1(_vm->_screenBuffer); + } + + resetState(-1); + _vm->_menuDirectlyToLoad = false; + return 0; + } + + if (!button) { + _currentMenu = &_deathMenu; + _isDeathMenu = true; + } else { + _isDeathMenu = false; + } + + _vm->musicUpdate(0); + backUpPage1(_vm->_screenBuffer); + initMenu(*_currentMenu); + _madeSave = false; + _loadedSave = false; + _vm->_itemInHand = -1; + updateAllMenuButtons(); + + if (_isDeathMenu) { + while (!_screen->isMouseVisible()) + _screen->showMouse(); + } + + while (_displayMenu) { + processHighlights(*_currentMenu, _vm->_mouseX, _vm->_mouseY); + getInput(); + } + + if (_vm->_runFlag && !_loadedSave && !_madeSave) { + restorePalette(); + restorePage1(_vm->_screenBuffer); + } + + if (_vm->_runFlag) + updateMenuButton(&_vm->_mainButtonData[0]); + + resetState(oldHandItem); + + if (!_loadedSave && _reloadTemporarySave) { + _vm->_unkSceneScreenFlag1 = true; + _vm->loadGame(_vm->getSavegameFilename(999)); + _vm->_saveFileMan->removeSavefile(_vm->getSavegameFilename(999)); + _vm->_unkSceneScreenFlag1 = false; + } + + return 0; +} + +int GUI_MR::loadMenu(Button *caller) { + updateSaveList(); + + if (!_vm->_menuDirectlyToLoad) { + updateMenuButton(caller); + restorePage1(_vm->_screenBuffer); + backUpPage1(_vm->_screenBuffer); + } + + _savegameOffset = 0; + setupSavegameNames(_loadMenu, 5); + initMenu(_loadMenu); + _isLoadMenu = true; + _noLoadProcess = false; + _vm->_gameToLoad = -1; + updateAllMenuButtons(); + + _screen->updateScreen(); + while (_isLoadMenu) { + processHighlights(_loadMenu, _vm->_mouseX, _vm->_mouseY); + getInput(); + } + + if (_noLoadProcess) { + if (!_vm->_menuDirectlyToLoad) { + restorePage1(_vm->_screenBuffer); + backUpPage1(_vm->_screenBuffer); + initMenu(*_currentMenu); + updateAllMenuButtons(); + } + } else if (_vm->_gameToLoad >= 0) { + restorePage1(_vm->_screenBuffer); + restorePalette(); + _vm->loadGame(_vm->getSavegameFilename(_vm->_gameToLoad)); + if (_vm->_gameToLoad == 0) { + _restartGame = true; + _vm->runStartupScript(1, 1); + } + _displayMenu = false; + _loadedSave = true; + } + + return 0; +} + +int GUI_MR::loadSecondChance(Button *button) { + updateMenuButton(button); + + _vm->_gameToLoad = 999; + restorePage1(_vm->_screenBuffer); + _vm->loadGame(_vm->getSavegameFilename(_vm->_gameToLoad)); + _displayMenu = false; + _loadedSave = true; + return 0; +} + +int GUI_MR::gameOptions(Button *caller) { + updateMenuButton(caller); + restorePage1(_vm->_screenBuffer); + backUpPage1(_vm->_screenBuffer); + bool textEnabled = _vm->textEnabled(); + int lang = _vm->_lang; + + setupOptionsButtons(); + initMenu(_gameOptions); + _isOptionsMenu = true; + + while (_isOptionsMenu) { + processHighlights(_gameOptions, _vm->_mouseX, _vm->_mouseY); + getInput(); + } + + restorePage1(_vm->_screenBuffer); + backUpPage1(_vm->_screenBuffer); + + if (textEnabled && !_vm->textEnabled() && !_vm->speechEnabled()) { + _vm->_configVoice = 1; + _vm->setVolume(KyraEngine::kVolumeSpeech, 75); + choiceDialog(0x1E, 0); + } + + if (_vm->_lang != lang) { + _reloadTemporarySave = true; + _vm->saveGame(_vm->getSavegameFilename(999), "Temporary Kyrandia 3 Savegame"); + if (!_vm->loadLanguageFile("ITEMS.", _vm->_itemFile)) + error("Couldn't load ITEMS"); + if (!_vm->loadLanguageFile("SCORE.", _vm->_scoreFile)) + error("Couldn't load SCORE"); + if (!_vm->loadLanguageFile("C_CODE.", _vm->_cCodeFile)) + error("Couldn't load C_CODE"); + if (!_vm->loadLanguageFile("SCENES.", _vm->_scenesFile)) + error("Couldn't load SCENES"); + if (!_vm->loadLanguageFile("OPTIONS.", _vm->_optionsFile)) + error("Couldn't load OPTIONS"); + if (!_vm->loadLanguageFile("_ACTOR.", _vm->_actorFile)) + error("couldn't load _ACTOR"); + } + + _vm->writeSettings(); + + initMenu(*_currentMenu); + updateAllMenuButtons(); + return 0; +} + +void GUI_MR::setupOptionsButtons() { + _vm->musicUpdate(0); + if (_vm->_configWalkspeed == 3) + _gameOptions.item[0].itemId = 28; + else + _gameOptions.item[0].itemId = 27; + + if (_vm->textEnabled()) + _gameOptions.item[4].itemId = 18; + else + _gameOptions.item[4].itemId = 17; + + switch (_vm->_lang) { + case 0: + _gameOptions.item[1].itemId = 31; + break; + + case 1: + _gameOptions.item[1].itemId = 32; + break; + + case 2: + _gameOptions.item[1].itemId = 33; + break; + + default: + break; + } + + if (_vm->_configStudio) + _gameOptions.item[2].itemId = 18; + else + _gameOptions.item[2].itemId = 17; + + if (_vm->_configSkip) + _gameOptions.item[3].itemId = 18; + else + _gameOptions.item[3].itemId = 17; +} + +int GUI_MR::changeLanguage(Button *caller) { + updateMenuButton(caller); + if (!_vm->queryGameFlag(0x1B2)) { + ++_vm->_lang; + _vm->_lang %= 3; + setupOptionsButtons(); + renewHighlight(_gameOptions); + } + return 0; +} + +int GUI_MR::toggleStudioSFX(Button *caller) { + updateMenuButton(caller); + _vm->_configStudio ^= 1; + setupOptionsButtons(); + renewHighlight(_gameOptions); + return 0; +} + +int GUI_MR::toggleSkipSupport(Button *caller) { + updateMenuButton(caller); + _vm->_configSkip ^= 1; + setupOptionsButtons(); + renewHighlight(_gameOptions); + return 0; +} + +int GUI_MR::audioOptions(Button *caller) { + updateMenuButton(caller); + + restorePage1(_vm->_screenBuffer); + backUpPage1(_vm->_screenBuffer); + + //if (_configHelium) + // _audioOptions.item[3].itemId = 18; + //else + _audioOptions.item[3].itemId = 17; + + initMenu(_audioOptions); + + const int menuX = _audioOptions.x; + const int menuY = _audioOptions.y; + + const int maxButton = 3; // 2 if voc is disabled + + for (int i = 0; i < maxButton; ++i) { + int x = menuX + _sliderBarsPosition[i*2+0]; + int y = menuY + _sliderBarsPosition[i*2+1]; + _screen->drawShape(0, _vm->getShapePtr(0x1CF), x, y, 0, 0); + drawSliderBar(i, _vm->getShapePtr(0x1D0)); + _sliderButtons[0][i].buttonCallback = _sliderHandlerFunctor; + _sliderButtons[0][i].x = x; + _sliderButtons[0][i].y = y; + _menuButtonList = addButtonToList(_menuButtonList, &_sliderButtons[0][i]); + _sliderButtons[2][i].buttonCallback = _sliderHandlerFunctor; + _sliderButtons[2][i].x = x + 10; + _sliderButtons[2][i].y = y; + _menuButtonList = addButtonToList(_menuButtonList, &_sliderButtons[2][i]); + _sliderButtons[1][i].buttonCallback = _sliderHandlerFunctor; + _sliderButtons[1][i].x = x + 120; + _sliderButtons[1][i].y = y; + _menuButtonList = addButtonToList(_menuButtonList, &_sliderButtons[1][i]); + } + + _isOptionsMenu = true; + updateAllMenuButtons(); + bool speechEnabled = _vm->speechEnabled(); + while (_isOptionsMenu) { + processHighlights(_audioOptions, _vm->_mouseX, _vm->_mouseY); + getInput(); + } + + restorePage1(_vm->_screenBuffer); + backUpPage1(_vm->_screenBuffer); + if (speechEnabled && !_vm->textEnabled() && (!_vm->speechEnabled() || _vm->getVolume(KyraEngine::kVolumeSpeech) == 2)) { + _vm->_configVoice = 0; + choiceDialog(0x1D, 0); + } + + _vm->writeSettings(); + + initMenu(*_currentMenu); + updateAllMenuButtons(); + return 0; +} + +int GUI_MR::sliderHandler(Button *caller) { + int button = 0; + if (caller->index >= 24 && caller->index <= 27) + button = caller->index - 24; + else if (caller->index >= 28 && caller->index <= 31) + button = caller->index - 28; + else + button = caller->index - 32; + + assert(button >= 0 && button <= 3); + + int oldVolume = _vm->getVolume(KyraEngine::kVolumeEntry(button)); + int newVolume = oldVolume; + + if (caller->index >= 24 && caller->index <= 27) + newVolume -= 10; + else if (caller->index >= 28 && caller->index <= 31) + newVolume += 10; + else + newVolume = _vm->_mouseX - caller->x - 7; + + newVolume = MAX(2, newVolume); + newVolume = MIN(97, newVolume); + + if (newVolume == oldVolume) + return 0; + + int lastMusicCommand = -1; + bool playSoundEffect = false; + + drawSliderBar(button, _vm->getShapePtr(0x1D1)); + + if (button == 2) { + if (_vm->textEnabled()) + _vm->_configVoice = 2; + else + _vm->_configVoice = 1; + } + + _vm->setVolume(KyraEngine::kVolumeEntry(button), newVolume); + + switch (button) { + case 0: + lastMusicCommand = _vm->_lastMusicCommand; + break; + + case 1: + playSoundEffect = true; + break; + + case 2: + if (_vm->_voiceSoundChannel != _vm->_musicSoundChannel) + _vm->_soundDigital->stopSound(_vm->_voiceSoundChannel); + _vm->playVoice(200, 943); + break; + + default: + return 0; + } + + drawSliderBar(button, _vm->getShapePtr(0x1D0)); + if (playSoundEffect) + _vm->snd_playSoundEffect(0x18, 0xC8); + else if (lastMusicCommand >= 0) + _vm->snd_playWanderScoreViaMap(lastMusicCommand, 1); + + _screen->updateScreen(); + return 0; +} + +void GUI_MR::drawSliderBar(int slider, const uint8 *shape) { + const int menuX = _audioOptions.x; + const int menuY = _audioOptions.y; + int x = menuX + _sliderBarsPosition[slider*2+0] + 10; + int y = menuY + _sliderBarsPosition[slider*2+1]; + + int position = _vm->getVolume(KyraEngine::kVolumeEntry(slider)); + + position = MAX(2, position); + position = MIN(97, position); + _screen->drawShape(0, shape, x+position, y, 0, 0); +} + +} // end of namespace Kyra + diff --git a/engines/kyra/gui_mr.h b/engines/kyra/gui_mr.h new file mode 100644 index 0000000000..d73b21b73b --- /dev/null +++ b/engines/kyra/gui_mr.h @@ -0,0 +1,88 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#ifndef KYRA_GUI_MR_H +#define KYRA_GUI_MR_H + +#include "kyra/gui_v2.h" + +namespace Kyra { + +class KyraEngine_MR; +class Screen_MR; + +class GUI_MR : public GUI_v2 { +friend class KyraEngine_MR; +public: + GUI_MR(KyraEngine_MR *engine); + + void initStaticData(); + + void flagButtonEnable(Button *button); + void flagButtonDisable(Button *button); + + int redrawShadedButtonCallback(Button *button); + int redrawButtonCallback(Button *button); + + int optionsButton(Button *button); +private: + const char *getMenuTitle(const Menu &menu); + const char *getMenuItemTitle(const MenuItem &menuItem); + const char *getMenuItemLabel(const MenuItem &menuItem); + char *getTableString(int id); + + uint8 textFieldColor1() const { return 0xFF; } + uint8 textFieldColor2() const { return 0xCF; } + uint8 textFieldColor3() const { return 0xBA; } + + uint8 defaultColor1() const { return 0xF0; } + uint8 defaultColor2() const { return 0xD0; } + + void resetState(int item); + + int quitGame(Button *button); + int loadMenu(Button *button); + int loadSecondChance(Button *button); + + int gameOptions(Button *button); + void setupOptionsButtons(); + + int audioOptions(Button *button); + + int sliderHandler(Button *caller); + void drawSliderBar(int slider, const uint8 *shape); + + int changeLanguage(Button *caller); + int toggleStudioSFX(Button *caller); + int toggleSkipSupport(Button *caller); + + KyraEngine_MR *_vm; + Screen_MR *_screen; +}; + +} // end of namespace Kyra + +#endif + diff --git a/engines/kyra/gui_v1.cpp b/engines/kyra/gui_v1.cpp index 12c9648f10..e5a0c42281 100644 --- a/engines/kyra/gui_v1.cpp +++ b/engines/kyra/gui_v1.cpp @@ -119,15 +119,15 @@ int KyraEngine_v1::buttonAmuletCallback(Button *caller) { drawJewelsFadeOutStart(); drawJewelsFadeOutEnd(jewel); - _scriptInterpreter->initScript(_scriptClick, _scriptClickData); - _scriptClick->regs[3] = 0; - _scriptClick->regs[6] = jewel; - _scriptInterpreter->startScript(_scriptClick, 4); + _emc->init(&_scriptClick, &_scriptClickData); + _scriptClick.regs[3] = 0; + _scriptClick.regs[6] = jewel; + _emc->start(&_scriptClick, 4); - while (_scriptInterpreter->validScript(_scriptClick)) - _scriptInterpreter->runScript(_scriptClick); + while (_emc->isValid(&_scriptClick)) + _emc->run(&_scriptClick); - if (_scriptClick->regs[3]) + if (_scriptClick.regs[3]) return 1; _unkAmuletVar = 1; @@ -624,6 +624,8 @@ int GUI_v1::loadGameMenu(Button *button) { _displaySubMenu = true; _cancelSubMenu = false; + _vm->_gameToLoad = -1; + while (_displaySubMenu && !_vm->_quitFlag) { getInput(); Common::Point mouse = _vm->getMousePos(); @@ -639,7 +641,8 @@ int GUI_v1::loadGameMenu(Button *button) { updateAllMenuButtons(); } else { restorePalette(); - _vm->loadGame(_vm->getSavegameFilename(_vm->_gameToLoad)); + if (_vm->_gameToLoad != -1) + _vm->loadGame(_vm->getSavegameFilename(_vm->_gameToLoad)); _displayMenu = false; _menuRestoreScreen = false; } diff --git a/engines/kyra/gui_v2.cpp b/engines/kyra/gui_v2.cpp index 2e16de5112..d835c4f8d5 100644 --- a/engines/kyra/gui_v2.cpp +++ b/engines/kyra/gui_v2.cpp @@ -11,7 +11,7 @@ * 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 + * 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 @@ -23,65 +23,19 @@ * */ -#include "kyra/kyra.h" +#include "kyra/gui_v2.h" #include "kyra/kyra_v2.h" -#include "kyra/screen.h" -#include "kyra/wsamovie.h" -#include "kyra/timer.h" -#include "kyra/sound.h" +#include "kyra/screen_v2.h" +#include "kyra/text.h" #include "common/savefile.h" namespace Kyra { -void KyraEngine_v2::loadButtonShapes() { - const uint8 *src = _screen->getCPagePtr(3); - _screen->loadBitmap("_BUTTONS.CSH", 3, 3, 0); - - _gui->_scrollUpButton.data0ShapePtr = _buttonShapes[0] = _screen->makeShapeCopy(src, 0); - _gui->_scrollUpButton.data2ShapePtr = _buttonShapes[1] = _screen->makeShapeCopy(src, 1); - _gui->_scrollUpButton.data1ShapePtr = _buttonShapes[2] = _screen->makeShapeCopy(src, 2); - _gui->_scrollDownButton.data0ShapePtr = _buttonShapes[3] = _screen->makeShapeCopy(src, 3); - _gui->_scrollDownButton.data2ShapePtr = _buttonShapes[4] = _screen->makeShapeCopy(src, 4); - _gui->_scrollDownButton.data1ShapePtr = _buttonShapes[5] = _screen->makeShapeCopy(src, 5); - _buttonShapes[6] = _screen->makeShapeCopy(src, 6); - _buttonShapes[7] = _screen->makeShapeCopy(src, 7); - _buttonShapes[8] = _screen->makeShapeCopy(src, 6); - _buttonShapes[9] = _screen->makeShapeCopy(src, 7); - _buttonShapes[10] = _screen->makeShapeCopy(src, 10); - _buttonShapes[11] = _screen->makeShapeCopy(src, 11); - _buttonShapes[16] = _screen->makeShapeCopy(src, 16); - _buttonShapes[17] = _screen->makeShapeCopy(src, 17); - _buttonShapes[18] = _screen->makeShapeCopy(src, 18); -} - -void KyraEngine_v2::setupLangButtonShapes() { - switch (_lang) { - case 0: - _inventoryButtons[0].data0ShapePtr = _buttonShapes[6]; - _inventoryButtons[0].data1ShapePtr = _inventoryButtons[0].data2ShapePtr = _buttonShapes[7]; - break; - - case 1: - _inventoryButtons[0].data0ShapePtr = _buttonShapes[8]; - _inventoryButtons[0].data1ShapePtr = _inventoryButtons[0].data2ShapePtr = _buttonShapes[9]; - break; - - case 2: - _inventoryButtons[0].data0ShapePtr = _buttonShapes[10]; - _inventoryButtons[0].data1ShapePtr = _inventoryButtons[0].data2ShapePtr = _buttonShapes[11]; - break; - - default: - _inventoryButtons[0].data0ShapePtr = _buttonShapes[6]; - _inventoryButtons[0].data1ShapePtr = _inventoryButtons[0].data2ShapePtr = _buttonShapes[7]; - break; - } -} - GUI_v2::GUI_v2(KyraEngine_v2 *vm) : GUI(vm), _vm(vm), _screen(vm->screen_v2()) { _backUpButtonList = _unknownButtonList = 0; - initStaticData(); + _buttonListChanged = false; + _currentMenu = 0; _isDeathMenu = false; _isSaveMenu = false; @@ -419,584 +373,27 @@ int GUI_v2::processButtonList(Button *buttonList, uint16 inputFlag) { return returnValue; } -const char *GUI_v2::getMenuTitle(const Menu &menu) { - if (!menu.menuNameId) - return 0; - - return _vm->getTableString(menu.menuNameId, _vm->_optionsBuffer, 1); -} - -const char *GUI_v2::getMenuItemTitle(const MenuItem &menuItem) { - if (!menuItem.itemId) - return 0; - - return _vm->getTableString(menuItem.itemId, _vm->_optionsBuffer, 1); -} - -const char *GUI_v2::getMenuItemLabel(const MenuItem &menuItem) { - if (!menuItem.labelId) - return 0; - - return _vm->getTableString(menuItem.labelId, _vm->_optionsBuffer, 1); -} - -#pragma mark - - - -int KyraEngine_v2::buttonInventory(Button *button) { - if (!_screen->isMouseVisible()) - return 0; - - int inventorySlot = button->index - 6; - - uint16 item = _mainCharacter.inventory[inventorySlot]; - if (_itemInHand == -1) { - if (item == 0xFFFF) - return 0; - _screen->hideMouse(); - clearInventorySlot(inventorySlot, 0); - snd_playSoundEffect(0x0B); - setMouseCursor(item); - int string = (_lang == 1) ? getItemCommandStringPickUp(item) : 7; - updateCommandLineEx(item+54, string, 0xD6); - _itemInHand = (int16)item; - _screen->showMouse(); - _mainCharacter.inventory[inventorySlot] = 0xFFFF; - } else { - if (_mainCharacter.inventory[inventorySlot] != 0xFFFF) { - if (checkInventoryItemExchange(_itemInHand, inventorySlot)) - return 0; - - item = _mainCharacter.inventory[inventorySlot]; - snd_playSoundEffect(0x0B); - _screen->hideMouse(); - clearInventorySlot(inventorySlot, 0); - drawInventoryShape(0, _itemInHand, inventorySlot); - setMouseCursor(item); - int string = (_lang == 1) ? getItemCommandStringPickUp(item) : 7; - updateCommandLineEx(item+54, string, 0xD6); - _screen->showMouse(); - _mainCharacter.inventory[inventorySlot] = _itemInHand; - setHandItem(item); - } else { - snd_playSoundEffect(0x0C); - _screen->hideMouse(); - drawInventoryShape(0, _itemInHand, inventorySlot); - _screen->setMouseCursor(0, 0, getShapePtr(0)); - int string = (_lang == 1) ? getItemCommandStringInv(_itemInHand) : 8; - updateCommandLineEx(_itemInHand+54, string, 0xD6); - _screen->showMouse(); - _mainCharacter.inventory[inventorySlot] = _itemInHand; - _itemInHand = -1; - } - } - - return 0; -} - -int KyraEngine_v2::scrollInventory(Button *button) { - uint16 *src = _mainCharacter.inventory; - uint16 *dst = &_mainCharacter.inventory[10]; - uint16 temp[5]; - - memcpy(temp, src, sizeof(uint16)*5); - memcpy(src, src+5, sizeof(uint16)*5); - memcpy(src+5, dst, sizeof(uint16)*5); - memcpy(dst, dst+5, sizeof(uint16)*5); - memcpy(dst+5, temp, sizeof(uint16)*5); - _screen->hideMouse(); - _screen->copyRegion(0x46, 0x90, 0x46, 0x90, 0x71, 0x2E, 0, 2); - _screen->showMouse(); - redrawInventory(2); - scrollInventoryWheel(); - return 0; -} - -int KyraEngine_v2::getInventoryItemSlot(uint16 item) { - for (int i = 0; i < 20; ++i) { - if (_mainCharacter.inventory[i] == item) - return i; - } - return -1; -} - -int KyraEngine_v2::findFreeVisibleInventorySlot() { - for (int i = 0; i < 10; ++i) { - if (_mainCharacter.inventory[i] == 0xFFFF) - return i; - } - return -1; -} - -void KyraEngine_v2::removeItemFromInventory(int slot) { - _mainCharacter.inventory[slot] = 0xFFFF; - if (slot < 10) { - _screen->hideMouse(); - clearInventorySlot(slot, 0); - _screen->showMouse(); - } -} - -bool KyraEngine_v2::checkInventoryItemExchange(uint16 handItem, int slot) { - bool removeItem = false; - uint16 newItem = 0xFFFF; - - uint16 invItem = _mainCharacter.inventory[slot]; - - for (const uint16 *table = _itemMagicTable; *table != 0xFFFF; table += 4) { - if (table[0] != handItem || table[1] != invItem) - continue; - - if (table[3] == 0xFFFF) - continue; - - removeItem = (table[3] == 1); - newItem = table[2]; - - snd_playSoundEffect(0x68); - _mainCharacter.inventory[slot] = newItem; - _screen->hideMouse(); - clearInventorySlot(slot, 0); - drawInventoryShape(0, newItem, slot); - - if (removeItem) - removeHandItem(); - - _screen->showMouse(); - - if (_lang != 1) - updateCommandLineEx(newItem+54, 0x2E, 0xD6); - - return true; - } - - return false; -} - -void KyraEngine_v2::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); - _screen->updateScreen(); -} - -void KyraEngine_v2::redrawInventory(int page) { - int pageBackUp = _screen->_curPage; - _screen->_curPage = page; - - const uint16 *inventory = _mainCharacter.inventory; - _screen->hideMouse(); - for (int i = 0; i < 10; ++i) { - clearInventorySlot(i, page); - if (inventory[i] != 0xFFFF) { - _screen->drawShape(page, getShapePtr(inventory[i]+64), _inventoryX[i], _inventoryY[i], 0, 0); - drawInventoryShape(page, inventory[i], i); - } - } - _screen->showMouse(); - _screen->updateScreen(); - - _screen->_curPage = pageBackUp; -} - -void KyraEngine_v2::scrollInventoryWheel() { - WSAMovieV2 movie(this, _screen); - movie.open("INVWHEEL.WSA", 0, 0); - int frames = movie.opened() ? movie.frames() : 6; - memcpy(_screenBuffer, _screen->getCPagePtr(2), 64000); - uint8 overlay[0x100]; - _screen->generateOverlay(_screen->getPalette(0), overlay, 0, 50); - _screen->hideMouse(); - _screen->copyRegion(0x46, 0x90, 0x46, 0x79, 0x71, 0x17, 0, 2, Screen::CR_NO_P_CHECK); - _screen->showMouse(); - snd_playSoundEffect(0x25); - - movie.setDrawPage(0); - movie.setX(0); - movie.setY(0); - - bool breakFlag = false; - for (int i = 0; i <= 6 && !breakFlag; ++i) { - if (movie.opened()) { - _screen->hideMouse(); - movie.displayFrame(i % frames, 0, 0); - _screen->showMouse(); - _screen->updateScreen(); - } - - uint32 endTime = _system->getMillis() + _tickLength; - - int y = (i * 981) >> 8; - if (y >= 23 || i == 6) { - y = 23; - breakFlag = true; - } - - _screen->applyOverlay(0x46, 0x79, 0x71, 0x17, 2, overlay); - _screen->copyRegion(0x46, y+0x79, 0x46, 0x90, 0x71, 0x2E, 2, 0, Screen::CR_NO_P_CHECK); - _screen->updateScreen(); - - delayUntil(endTime); - } - - _screen->copyBlockToPage(2, 0, 0, 320, 200, _screenBuffer); - movie.close(); -} - -// spellbook specific code - -int KyraEngine_v2::bookButton(Button *button) { - if (!queryGameFlag(1)) { - objectChat(getTableString(0xEB, _cCodeBuffer, 1), 0, 0x83, 0xEB); - return 0; - } - - if (!_screen->isMouseVisible()) - return 0; - - if (queryGameFlag(0xE5)) { - snd_playSoundEffect(0x0D); - return 0; - } - - if (_itemInHand == 72) { - if (!queryGameFlag(0xE2)) { - _bookMaxPage += 2; - removeHandItem(); - snd_playSoundEffect(0x6C); - setGameFlag(0xE2); - } - - if (!queryGameFlag(0x18A) && queryGameFlag(0x170)) { - _bookMaxPage += 2; - removeHandItem(); - snd_playSoundEffect(0x6C); - setGameFlag(0x18A); - } - - return 0; - } - - if (_handItemSet != -1) { - snd_playSoundEffect(0x0D); - return 0; - } - - _screen->hideMouse(); - showMessage(0, 0xCF); - displayInvWsaLastFrame(); - _bookNewPage = _bookCurPage; - - if (_screenBuffer) { - _screen->hideMouse(); - memcpy(_screenBuffer, _screen->getCPagePtr(0), 64000); - _screen->showMouse(); - } - - memcpy(_screen->getPalette(2), _screen->getPalette(0), 768); - _screen->fadeToBlack(7, &_updateFunctor); - _res->loadFileToBuf("_BOOK.COL", _screen->getPalette(0), 768); - loadBookBkgd(); - showBookPage(); - _screen->copyRegion(0, 0, 0, 0, 0x140, 0xC8, 2, 0, Screen::CR_NO_P_CHECK); - _screen->updateScreen(); - - int oldItemInHand = _itemInHand; - removeHandItem(); - _screen->fadePalette(_screen->getPalette(0), 7); - _screen->showMouse(); - - bookLoop(); - - _screen->fadeToBlack(7); - _screen->hideMouse(); - setHandItem(oldItemInHand); - updateMouse(); - restorePage3(); - - if (_screenBuffer) { - _screen->hideMouse(); - _screen->copyBlockToPage(0, 0, 0, 320, 200, _screenBuffer); - _screen->showMouse(); - } - - setHandItem(_itemInHand); - memcpy(_screen->getPalette(0), _screen->getPalette(2), 768); - _screen->fadePalette(_screen->getPalette(0), 7, &_updateFunctor); - _screen->showMouse(); - - if (!queryGameFlag(4) && !queryGameFlag(0xB8)) { - objectChat(getTableString(0xEC, _cCodeBuffer, 1), 0, 0x83, 0xEC); - objectChat(getTableString(0xED, _cCodeBuffer, 1), 0, 0x83, 0xED); - objectChat(getTableString(0xEE, _cCodeBuffer, 1), 0, 0x83, 0xEE); - objectChat(getTableString(0xEF, _cCodeBuffer, 1), 0, 0x83, 0xEF); - setGameFlag(4); - } - - return 0; -} - -void KyraEngine_v2::loadBookBkgd() { - char filename[16]; +void GUI_v2::updateButton(Button *button) { + if (!button || (button->flags & 8)) + return; - if (_flags.isTalkie) - strcpy(filename, (_bookBkgd == 0) ? "_XBOOKD.CPS" : "_XBOOKC.CPS"); + if (button->flags2 & 1) + button->flags2 |= 8; else - strcpy(filename, (_bookBkgd == 0) ? "_BOOKD.CPS" : "_BOOKC.CPS"); - - _bookBkgd ^= 1; - - if (_flags.isTalkie) { - if (!_bookCurPage) - strcpy(filename, "_XBOOKB.CPS"); - if (_bookCurPage == _bookMaxPage) - strcpy(filename, "_XBOOKA.CPS"); - - switch (_lang) { - case 0: - filename[1] = 'E'; - break; - - case 1: - filename[1] = 'F'; - break; - - case 2: - filename[1] = 'G'; - break; - - default: - warning("loadBookBkgd unsupported language"); - filename[1] = 'E'; - break; - } - } else { - if (!_bookCurPage) - strcpy(filename, "_BOOKB.CPS"); - if (_bookCurPage == _bookMaxPage) - strcpy(filename, "_BOOKA.CPS"); - } - - _screen->loadBitmap(filename, 3, 3, 0); -} - -void KyraEngine_v2::showBookPage() { - char filename[16]; - - sprintf(filename, "PAGE%.01X.", _bookCurPage); - strcat(filename, _languageExtension[_lang]); - uint8 *leftPage = _res->fileData(filename, 0); - int leftPageY = _bookPageYOffset[_bookCurPage]; - - sprintf(filename, "PAGE%.01X.", _bookCurPage+1); - strcat(filename, _languageExtension[_lang]); - uint8 *rightPage = (_bookCurPage != _bookMaxPage) ? _res->fileData(filename, 0) : 0; - int rightPageY = _bookPageYOffset[_bookCurPage+1]; - - _screen->hideMouse(); - if (leftPage) { - bookDecodeText(leftPage); - bookPrintText(2, leftPage, 20, leftPageY+20, 0x31); - delete [] leftPage; - } - - if (rightPage) { - bookDecodeText(rightPage); - bookPrintText(2, rightPage, 176, rightPageY+20, 0x31); - delete [] rightPage; - } - _screen->showMouse(); -} - -void KyraEngine_v2::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); - 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); - 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); - 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); - 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); - - Button *buttonList = 0; - - for (uint i = 0; i < ARRAYSIZE(bookButtons); ++i) - buttonList = _gui->addButtonToList(buttonList, &bookButtons[i]); - - showBookPage(); - _bookShown = true; - while (_bookShown && !_quitFlag) { - checkInput(buttonList); - removeInputTop(); - - if (_bookCurPage != _bookNewPage) { - _bookCurPage = _bookNewPage; - _screen->clearPage(2); - loadBookBkgd(); - showBookPage(); - snd_playSoundEffect(0x64); - _screen->hideMouse(); - _screen->copyRegion(0, 0, 0, 0, 0x140, 0xC8, 2, 0, Screen::CR_NO_P_CHECK); - _screen->updateScreen(); - _screen->showMouse(); - } - } - _screen->clearPage(2); -} - -void KyraEngine_v2::bookDecodeText(uint8 *str) { - uint8 *dst = str, *op = str; - while (*op != 0x1A) { - while (*op != 0x1A && *op != 0x0D) - *dst++ = *op++; - - if (*op == 0x1A) - break; - - op += 2; - *dst++ = 0x0D; - } - *dst = 0; -} - -void KyraEngine_v2::bookPrintText(int dstPage, const uint8 *str, int x, int y, uint8 color) { - int curPageBackUp = _screen->_curPage; - _screen->_curPage = dstPage; - - _screen->setTextColor(_bookTextColorMap, 0, 3); - Screen::FontId oldFont = _screen->setFont(Screen::FID_BOOKFONT_FNT); - _screen->_charWidth = -2; - - _screen->hideMouse(); - _screen->printText((const char*)str, x, y, color, (_flags.lang == Common::JA_JPN) ? 0xf6 : 0); - _screen->showMouse(); - - _screen->_charWidth = 0; - _screen->setFont(oldFont); - _screen->_curPage = curPageBackUp; -} + button->flags2 |= ~8; -int KyraEngine_v2::bookPrevPage(Button *button) { - _bookNewPage = MAX<int>(_bookCurPage-2, 0); - return 0; -} - -int KyraEngine_v2::bookNextPage(Button *button) { - _bookNewPage = MIN<int>(_bookCurPage+2, _bookMaxPage); - return 0; -} - -int KyraEngine_v2::bookClose(Button *button) { - _bookShown = false; - return 0; -} - -// cauldron specific code - -int KyraEngine_v2::cauldronClearButton(Button *button) { - if (!queryGameFlag(2)) { - updateCharFacing(); - objectChat(getTableString(0xF0, _cCodeBuffer, 1), 0, 0x83, 0xF0); - return 0; - } - - if (queryGameFlag(0xE4)) { - snd_playSoundEffect(0x0D); - return 0; - } - - _screen->hideMouse(); - displayInvWsaLastFrame(); - snd_playSoundEffect(0x25); - loadInvWsa("PULL.WSA", 1, 6, 0, -1, -1, 1); - loadInvWsa("CAULD00.WSA", 1, 7, 0, 0xD4, 0x0F, 1); - showMessage(0, 0xCF); - setCauldronState(0, 0); - clearCauldronTable(); - snd_playSoundEffect(0x57); - loadInvWsa("CAULDFIL.WSA", 1, 7, 0, -1, -1, 1); - _screen->showMouse(); - return 0; -} - -int KyraEngine_v2::cauldronButton(Button *button) { - if (!queryGameFlag(2)) { - objectChat(getTableString(0xF0, _cCodeBuffer, 1), 0, 0x83, 0xF0); - return 0; - } + button->flags2 &= ~1; - if (!_screen->isMouseVisible() || _handItemSet < -1) - return 0; - - if (queryGameFlag(0xE4)) { - snd_playSoundEffect(0x0D); - return 0; - } - - updateCharFacing(); - - for (int i = 0; _cauldronProtectedItems[i] != -1; ++i) { - if (_itemInHand == _cauldronProtectedItems[i]) { - objectChat(getTableString(0xF1, _cCodeBuffer, 1), 0, 0x83, 0xF1); - return 0; - } - } - - if (_itemInHand == -1) { - listItemsInCauldron(); - return 0; - } - - for (int i = 0; _cauldronBowlTable[i] != -1; i += 2) { - if (_itemInHand == _cauldronBowlTable[i]) { - addFrontCauldronTable(_itemInHand); - setHandItem(_cauldronBowlTable[i+1]); - if (!updateCauldron()) { - _cauldronState = 0; - cauldronRndPaletteFade(); - } - return 0; - } - } + if (button->flags2 & 4) + button->flags2 |= 0x10; + else + button->flags2 &= ~0x10; - if (_itemInHand == 18) { - const int16 *magicTable = (_mainCharacter.sceneId == 77) ? _cauldronMagicTableScene77 : _cauldronMagicTable; - while (magicTable[0] != -1) { - if (_cauldronState == magicTable[0]) { - setHandItem(magicTable[1]); - snd_playSoundEffect(0x6C); - ++_cauldronUseCount; - if (_cauldronStateTable[_cauldronState] <= _cauldronUseCount && _cauldronUseCount) { - showMessage(0, 0xCF); - setCauldronState(0, true); - clearCauldronTable(); - } - return 0; - } - magicTable += 2; - } - } else if (_itemInHand >= 0) { - int item = _itemInHand; - cauldronItemAnim(item); - addFrontCauldronTable(item); - if (!updateCauldron()) { - _cauldronState = 0; - cauldronRndPaletteFade(); - } - } + button->flags2 &= ~4; - return 0; + processButton(button); } -#pragma mark - - void GUI_v2::getInput() { if (!_displayMenu) return; @@ -1012,119 +409,6 @@ void GUI_v2::getInput() { } } -int GUI_v2::optionsButton(Button *button) { - _restartGame = false; - _reloadTemporarySave = false; - - _screen->hideMouse(); - updateButton(&_vm->_inventoryButtons[0]); - _screen->showMouse(); - - if (!_screen->isMouseVisible() && button) - return 0; - - _vm->showMessage(0, 0xCF); - - if (_vm->_handItemSet < -1) { - _vm->_handItemSet = -1; - _screen->hideMouse(); - _screen->setMouseCursor(1, 1, _vm->getShapePtr(0)); - _screen->showMouse(); - return 0; - } - - int oldHandItem = _vm->_itemInHand; - _screen->setMouseCursor(0, 0, _vm->getShapePtr(0)); - _vm->displayInvWsaLastFrame(); - //XXX - _displayMenu = true; - - for (uint i = 0; i < ARRAYSIZE(_menuButtons); ++i) { - _menuButtons[i].data0Val1 = _menuButtons[i].data1Val1 = _menuButtons[i].data2Val1 = 4; - _menuButtons[i].data0Callback = _redrawShadedButtonFunctor; - _menuButtons[i].data1Callback = _menuButtons[i].data2Callback = _redrawButtonFunctor; - } - - initMenuLayout(_mainMenu); - initMenuLayout(_gameOptions); - initMenuLayout(_audioOptions); - initMenuLayout(_choiceMenu); - _loadMenu.numberOfItems = 6; - initMenuLayout(_loadMenu); - initMenuLayout(_saveMenu); - initMenuLayout(_savenameMenu); - initMenuLayout(_deathMenu); - - _currentMenu = &_mainMenu; - - if (_vm->_menuDirectlyToLoad) { - backUpPage1(_vm->_screenBuffer); - setupPalette(); - - _loadedSave = false; - - loadMenu(0); - - if (_loadedSave) { - if (_restartGame) - _vm->_itemInHand = -1; - } else { - restorePage1(_vm->_screenBuffer); - restorePalette(); - } - - resetState(-1); - _vm->_menuDirectlyToLoad = false; - return 0; - } - - if (!button) { - _currentMenu = &_deathMenu; - _isDeathMenu = true; - } else { - _isDeathMenu = false; - } - - backUpPage1(_vm->_screenBuffer); - setupPalette(); - initMenu(*_currentMenu); - _madeSave = false; - _loadedSave = false; - _vm->_itemInHand = -1; - updateAllMenuButtons(); - - if (_isDeathMenu) { - while (!_screen->isMouseVisible()) - _screen->showMouse(); - } - - while (_displayMenu) { - processHighlights(*_currentMenu, _vm->_mouseX, _vm->_mouseY); - getInput(); - } - - if (_vm->_runFlag && !_loadedSave && !_madeSave) { - restorePalette(); - restorePage1(_vm->_screenBuffer); - } - - if (_vm->_runFlag) - updateMenuButton(&_vm->_inventoryButtons[0]); - - resetState(oldHandItem); - - if (!_loadedSave && _reloadTemporarySave) { - _vm->_unkSceneScreenFlag1 = true; - _vm->loadGame(_vm->getSavegameFilename(999)); - _vm->_saveFileMan->removeSavefile(_vm->getSavegameFilename(999)); - _vm->_unkSceneScreenFlag1 = false; - } - - return 0; -} - -#pragma mark - - void GUI_v2::renewHighlight(Menu &menu) { if (!_displayMenu) return; @@ -1138,29 +422,6 @@ void GUI_v2::renewHighlight(Menu &menu) { _screen->updateScreen(); } -void GUI_v2::setupPalette() { - memcpy(_screen->getPalette(1), _screen->getPalette(0), 768); - - uint8 *palette = _screen->getPalette(0); - for (int i = 0; i < 768; ++i) - palette[i] >>= 1; - - static const uint8 guiPal[] = { 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFc, 0xFD, 0xFE }; - - for (uint i = 0; i < ARRAYSIZE(guiPal); ++i) - memcpy(_screen->getPalette(0)+guiPal[i]*3, _screen->getPalette(1)+guiPal[i]*3, 3); - - if (_isDeathMenu) - _screen->fadePalette(_screen->getPalette(0), 0x64); - else - _screen->setScreenPalette(_screen->getPalette(0)); -} - -void GUI_v2::restorePalette() { - memcpy(_screen->getPalette(0), _screen->getPalette(1), 768); - _screen->setScreenPalette(_screen->getPalette(0)); -} - void GUI_v2::backUpPage1(uint8 *buffer) { _screen->copyRegionToBuffer(1, 0, 0, 320, 200, buffer); } @@ -1169,24 +430,9 @@ void GUI_v2::restorePage1(const uint8 *buffer) { _screen->copyBlockToPage(1, 0, 0, 320, 200, buffer); } -void GUI_v2::resetState(int item) { - _vm->_timer->resetNextRun(); - _vm->setNextIdleAnimTimer(); - _isDeathMenu = false; - if (!_loadedSave) { - _vm->setHandItem(item); - } else { - _vm->setHandItem(_vm->_itemInHand); - _vm->setTimer1DelaySecs(7); - _vm->_shownMessage = " "; - _vm->_fadeMessagePalette = false; - } - _buttonListChanged = true; -} - void GUI_v2::setupSavegameNames(Menu &menu, int num) { for (int i = 0; i < num; ++i) { - strcpy(_vm->getTableString(menu.item[i].itemId, _vm->_optionsBuffer, 0), ""); + strcpy(getTableString(menu.item[i].itemId), ""); menu.item[i].saveSlot = -1; menu.item[i].enabled = false; } @@ -1199,7 +445,7 @@ void GUI_v2::setupSavegameNames(Menu &menu, int num) { Common::InSaveFile *in; for (int i = startSlot; i < num && uint(_savegameOffset + i) < _saveSlots.size(); ++i) { if ((in = _vm->openSaveForReading(_vm->getSavegameFilename(_saveSlots[i + _savegameOffset]), header)) != 0) { - strncpy(_vm->getTableString(menu.item[i].itemId, _vm->_optionsBuffer, 0), header.description.c_str(), 80); + strncpy(getTableString(menu.item[i].itemId), header.description.c_str(), 80); menu.item[i].saveSlot = _saveSlots[i + _savegameOffset]; menu.item[i].enabled = true; delete in; @@ -1208,14 +454,14 @@ void GUI_v2::setupSavegameNames(Menu &menu, int num) { if (_savegameOffset == 0) { if (_isSaveMenu) { - char *dst = _vm->getTableString(menu.item[0].itemId, _vm->_optionsBuffer, 0); - const char *src = _vm->getTableString(_vm->gameFlags().isTalkie ? 10 : 18, _vm->_optionsBuffer, 0); + char *dst = getTableString(menu.item[0].itemId); + const char *src = getTableString(_vm->gameFlags().isTalkie ? 10 : 18); strcpy(dst, src); menu.item[0].saveSlot = -2; menu.item[0].enabled = true; } else { - char *dst = _vm->getTableString(menu.item[0].itemId, _vm->_optionsBuffer, 0); - const char *src = _vm->getTableString(_vm->gameFlags().isTalkie ? 34 : 42, _vm->_optionsBuffer, 0); + char *dst = getTableString(menu.item[0].itemId); + const char *src = getTableString(_vm->gameFlags().isTalkie ? 34 : 42); strcpy(dst, src); } } @@ -1261,121 +507,12 @@ int GUI_v2::scrollDownButton(Button *button) { return 0; } -#pragma mark - - -int GUI_v2::quitGame(Button *caller) { - updateMenuButton(caller); - if (choiceDialog(_vm->gameFlags().isTalkie ? 0xF : 0x17, 1)) { - _displayMenu = false; - _vm->_runFlag = false; - _vm->_sound->beginFadeOut(); - _screen->fadeToBlack(); - _screen->clearCurPage(); - } - - if (_vm->_runFlag) { - initMenu(*_currentMenu); - updateAllMenuButtons(); - } - - return 0; -} - int GUI_v2::resumeGame(Button *caller) { updateMenuButton(caller); _displayMenu = false; return 0; } -int GUI_v2::gameOptions(Button *caller) { - updateMenuButton(caller); - restorePage1(_vm->_screenBuffer); - backUpPage1(_vm->_screenBuffer); - initMenu(_gameOptions); - _isOptionsMenu = true; - - const int menuX = _gameOptions.x; - const int menuY = _gameOptions.y; - - for (int i = 0; i < 4; ++i) { - int x = menuX + _sliderBarsPosition[i*2+0]; - int y = menuY + _sliderBarsPosition[i*2+1]; - _screen->drawShape(0, _vm->_buttonShapes[16], x, y, 0, 0); - drawSliderBar(i, _vm->_buttonShapes[17]); - _sliderButtons[0][i].buttonCallback = _sliderHandlerFunctor; - _sliderButtons[0][i].x = x; - _sliderButtons[0][i].y = y; - _menuButtonList = addButtonToList(_menuButtonList, &_sliderButtons[0][i]); - _sliderButtons[2][i].buttonCallback = _sliderHandlerFunctor; - _sliderButtons[2][i].x = x + 10; - _sliderButtons[2][i].y = y; - _menuButtonList = addButtonToList(_menuButtonList, &_sliderButtons[2][i]); - _sliderButtons[1][i].buttonCallback = _sliderHandlerFunctor; - _sliderButtons[1][i].x = x + 120; - _sliderButtons[1][i].y = y; - _menuButtonList = addButtonToList(_menuButtonList, &_sliderButtons[1][i]); - } - - while (_isOptionsMenu) { - processHighlights(_gameOptions, _vm->_mouseX, _vm->_mouseY); - getInput(); - } - - restorePage1(_vm->_screenBuffer); - backUpPage1(_vm->_screenBuffer); - - _vm->writeSettings(); - - initMenu(*_currentMenu); - updateAllMenuButtons(); - - return 0; -} - -int GUI_v2::gameOptionsTalkie(Button *caller) { - updateMenuButton(caller); - restorePage1(_vm->_screenBuffer); - backUpPage1(_vm->_screenBuffer); - bool textEnabled = _vm->textEnabled(); - int lang = _vm->_lang; - - setupOptionsButtons(); - initMenu(_gameOptions); - _isOptionsMenu = true; - - while (_isOptionsMenu) { - processHighlights(_gameOptions, _vm->_mouseX, _vm->_mouseY); - getInput(); - } - - restorePage1(_vm->_screenBuffer); - backUpPage1(_vm->_screenBuffer); - - if (textEnabled && !_vm->textEnabled() && !_vm->speechEnabled()) { - _vm->_configVoice = 1; - choiceDialog(0x1E, 0); - } - - if (_vm->_lang != lang) { - _reloadTemporarySave = true; - _vm->saveGame(_vm->getSavegameFilename(999), "Temporary Kyrandia 2 Savegame"); - _vm->loadCCodeBuffer("C_CODE.XXX"); - if (_vm->_flags.isTalkie) - _vm->loadOptionsBuffer("OPTIONS.XXX"); - else - _vm->_optionsBuffer = _vm->_cCodeBuffer; - _vm->loadChapterBuffer(_vm->_newChapterFile); - _vm->loadNPCScript(); - _vm->setupLangButtonShapes(); - } - - _vm->writeSettings(); - - initMenu(*_currentMenu); - updateAllMenuButtons(); - return 0; -} - int GUI_v2::quitOptionsMenu(Button *caller) { updateMenuButton(caller); _isOptionsMenu = false; @@ -1388,16 +525,7 @@ int GUI_v2::toggleWalkspeed(Button *caller) { _vm->_configWalkspeed = 3; else _vm->_configWalkspeed = 5; - _vm->_timer->setDelay(0, _vm->_configWalkspeed); - setupOptionsButtons(); - renewHighlight(_gameOptions); - return 0; -} - -int GUI_v2::changeLanguage(Button *caller) { - updateMenuButton(caller); - ++_vm->_lang; - _vm->_lang %= 3; + _vm->setWalkspeed(_vm->_configWalkspeed); setupOptionsButtons(); renewHighlight(_gameOptions); return 0; @@ -1423,256 +551,12 @@ int GUI_v2::toggleText(Button *caller) { return 0; } -void GUI_v2::setupOptionsButtons() { - if (_vm->_configWalkspeed == 3) - _gameOptions.item[0].itemId = 28; - else - _gameOptions.item[0].itemId = 27; - - if (_vm->textEnabled()) - _gameOptions.item[2].itemId = 18; - else - _gameOptions.item[2].itemId = 17; - - switch (_vm->_lang) { - case 0: - _gameOptions.item[1].itemId = 31; - break; - - case 1: - _gameOptions.item[1].itemId = 32; - break; - - case 2: - _gameOptions.item[1].itemId = 33; - break; - - default: - break; - } -} - -int GUI_v2::audioOptions(Button *caller) { - updateMenuButton(caller); - restorePage1(_vm->_screenBuffer); - backUpPage1(_vm->_screenBuffer); - initMenu(_audioOptions); - const int menuX = _audioOptions.x; - const int menuY = _audioOptions.y; - const int maxButton = 3; // 2 if voc is disabled - - for (int i = 0; i < maxButton; ++i) { - int x = menuX + _sliderBarsPosition[i*2+0]; - int y = menuY + _sliderBarsPosition[i*2+1]; - _screen->drawShape(0, _vm->_buttonShapes[16], x, y, 0, 0); - drawSliderBar(i, _vm->_buttonShapes[17]); - _sliderButtons[0][i].buttonCallback = _sliderHandlerFunctor; - _sliderButtons[0][i].x = x; - _sliderButtons[0][i].y = y; - _menuButtonList = addButtonToList(_menuButtonList, &_sliderButtons[0][i]); - _sliderButtons[2][i].buttonCallback = _sliderHandlerFunctor; - _sliderButtons[2][i].x = x + 10; - _sliderButtons[2][i].y = y; - _menuButtonList = addButtonToList(_menuButtonList, &_sliderButtons[2][i]); - _sliderButtons[1][i].buttonCallback = _sliderHandlerFunctor; - _sliderButtons[1][i].x = x + 120; - _sliderButtons[1][i].y = y; - _menuButtonList = addButtonToList(_menuButtonList, &_sliderButtons[1][i]); - } - - _isOptionsMenu = true; - updateAllMenuButtons(); - bool speechEnabled = _vm->speechEnabled(); - while (_isOptionsMenu) { - processHighlights(_audioOptions, _vm->_mouseX, _vm->_mouseY); - getInput(); - } - - restorePage1(_vm->_screenBuffer); - backUpPage1(_vm->_screenBuffer); - if (speechEnabled && !_vm->textEnabled() && (!_vm->speechEnabled() || _vm->getVolume(KyraEngine::kVolumeSpeech) == 2)) { - _vm->_configVoice = 0; - _vm->setVolume(KyraEngine::kVolumeSpeech, 75); - choiceDialog(0x1D, 0); - } - - _vm->writeSettings(); - - initMenu(*_currentMenu); - updateAllMenuButtons(); - return 0; -} - -int GUI_v2::sliderHandler(Button *caller) { - int button = 0; - if (caller->index >= 24 && caller->index <= 27) - button = caller->index - 24; - else if (caller->index >= 28 && caller->index <= 31) - button = caller->index - 28; - else - button = caller->index - 32; - - assert(button >= 0 && button <= 3); - - int oldVolume = 0; - - if (_vm->gameFlags().isTalkie) { - oldVolume = _vm->getVolume(KyraEngine::kVolumeEntry(button)); - } else { - if (button < 2) - oldVolume = _vm->getVolume(KyraEngine::kVolumeEntry(button)); - else if (button == 2) - oldVolume = (_vm->_configWalkspeed == 3) ? 97 : 2; - else if (button == 3) - oldVolume = _vm->_configTextspeed; - } - - int newVolume = oldVolume; - - if (caller->index >= 24 && caller->index <= 27) - newVolume -= 10; - else if (caller->index >= 28 && caller->index <= 31) - newVolume += 10; - else - newVolume = _vm->_mouseX - caller->x - 7; - - newVolume = MAX(2, newVolume); - newVolume = MIN(97, newVolume); - - if (newVolume == oldVolume) - return 0; - - int lastMusicCommand = -1; - bool playSoundEffect = false; - - drawSliderBar(button, _vm->_buttonShapes[18]); - - if (_vm->gameFlags().isTalkie) { - if (button == 2) { - if (_vm->textEnabled()) - _vm->_configVoice = 2; - else - _vm->_configVoice = 1; - } - - _vm->setVolume(KyraEngine::kVolumeEntry(button), newVolume); - - switch (button) { - case 0: - lastMusicCommand = _vm->_lastMusicCommand; - break; - - case 1: - playSoundEffect = true; - break; - - case 2: - _vm->playVoice(90, 28); - break; - - default: - return 0; - } - } else { - if (button < 2) { - _vm->setVolume(KyraEngine::kVolumeEntry(button), newVolume); - if (button == 0) - lastMusicCommand = _vm->_lastMusicCommand; - else - playSoundEffect = true; - } else if (button == 2) { - _vm->_configWalkspeed = (newVolume > 48) ? 3 : 5; - _vm->setWalkspeed(_vm->_configWalkspeed); - } else if (button == 3) { - _vm->_configTextspeed = newVolume; - } - } - - drawSliderBar(button, _vm->_buttonShapes[17]); - if (playSoundEffect) - _vm->snd_playSoundEffect(0x18); - else if (lastMusicCommand >= 0) - _vm->snd_playWanderScoreViaMap(lastMusicCommand, 1); - - _screen->updateScreen(); - return 0; -} - -void GUI_v2::drawSliderBar(int slider, const uint8 *shape) { - const int menuX = _audioOptions.x; - const int menuY = _audioOptions.y; - int x = menuX + _sliderBarsPosition[slider*2+0] + 10; - int y = menuY + _sliderBarsPosition[slider*2+1]; - - int position = 0; - if (_vm->gameFlags().isTalkie) { - position = _vm->getVolume(KyraEngine::kVolumeEntry(slider)); - } else { - if (slider < 2) - position = _vm->getVolume(KyraEngine::kVolumeEntry(slider)); - else if (slider == 2) - position = (_vm->_configWalkspeed == 3) ? 97 : 2; - else if (slider == 3) - position = _vm->_configTextspeed; - } - - position = MAX(2, position); - position = MIN(97, position); - _screen->drawShape(0, shape, x+position, y, 0, 0); -} - -int GUI_v2::loadMenu(Button *caller) { - updateSaveList(); - - if (!_vm->_menuDirectlyToLoad) { - updateMenuButton(caller); - restorePage1(_vm->_screenBuffer); - backUpPage1(_vm->_screenBuffer); - } - - _savegameOffset = 0; - setupSavegameNames(_loadMenu, 5); - initMenu(_loadMenu); - _isLoadMenu = true; - _noLoadProcess = false; - _vm->_gameToLoad = -1; - updateAllMenuButtons(); - - _screen->updateScreen(); - while (_isLoadMenu) { - processHighlights(_loadMenu, _vm->_mouseX, _vm->_mouseY); - getInput(); - } - - if (_noLoadProcess) { - if (!_vm->_menuDirectlyToLoad) { - restorePage1(_vm->_screenBuffer); - backUpPage1(_vm->_screenBuffer); - initMenu(*_currentMenu); - updateAllMenuButtons(); - } - } else if (_vm->_gameToLoad >= 0) { - restorePage1(_vm->_screenBuffer); - restorePalette(); - _vm->loadGame(_vm->getSavegameFilename(_vm->_gameToLoad)); - if (_vm->_gameToLoad == 0) { - _restartGame = true; - for (int i = 0; i < 23; ++i) - _vm->resetCauldronStateTable(i); - _vm->runStartScript(1, 1); - } - _displayMenu = false; - _loadedSave = true; - } - - return 0; -} - int GUI_v2::clickLoadSlot(Button *caller) { updateMenuButton(caller); - - assert((caller->index-0x10) >= 0 && (caller->index-0x10 <= 6)); - MenuItem &item = _loadMenu.item[caller->index-0x10]; + + int index = caller->index - _menuButtons[0].index; + assert(index >= 0 && index <= 6); + MenuItem &item = _loadMenu.item[index]; if (item.saveSlot >= 0) { _vm->_gameToLoad = item.saveSlot; @@ -1733,8 +617,9 @@ int GUI_v2::saveMenu(Button *caller) { int GUI_v2::clickSaveSlot(Button *caller) { updateMenuButton(caller); - assert((caller->index-0x10) >= 0 && (caller->index-0x10 <= 6)); - MenuItem &item = _saveMenu.item[caller->index-0x10]; + int index = caller->index - _menuButtons[0].index; + assert(index >= 0 && index <= 6); + MenuItem &item = _saveMenu.item[index]; if (item.saveSlot >= 0) { if (_isDeleteMenu) { @@ -1743,7 +628,7 @@ int GUI_v2::clickSaveSlot(Button *caller) { return 0; } else { _saveSlot = item.saveSlot; - strcpy(_saveDescription, _vm->getTableString(item.itemId, _vm->_optionsBuffer, 0)); + strcpy(_saveDescription, getTableString(item.itemId)); } } else if (item.saveSlot == -2) { _saveSlot = getNextSavegameSlot(); @@ -1754,8 +639,8 @@ int GUI_v2::clickSaveSlot(Button *caller) { backUpPage1(_vm->_screenBuffer); initMenu(_savenameMenu); - _screen->fillRect(0x26, 0x5B, 0x11F, 0x66, 0xFA); - const char *desc = nameInputProcess(_saveDescription, 0x27, 0x5C, 0xFD, 0xFA, 0xFE, 0x50); + _screen->fillRect(0x26, 0x5B, 0x11F, 0x66, textFieldColor2()); + const char *desc = nameInputProcess(_saveDescription, 0x27, 0x5C, textFieldColor1(), textFieldColor2(), textFieldColor3(), 0x50); restorePage1(_vm->_screenBuffer); backUpPage1(_vm->_screenBuffer); if (desc) { diff --git a/engines/kyra/gui_v2.h b/engines/kyra/gui_v2.h index b5a25d29bf..4e94b58742 100644 --- a/engines/kyra/gui_v2.h +++ b/engines/kyra/gui_v2.h @@ -28,6 +28,8 @@ #include "kyra/gui.h" +namespace Kyra { + #define GUI_V2_BUTTON(button, a, b, c, d, e, f, h, i, j, k, l, m, n, o, p, q, r, s, t) \ button.nextButton = 0; \ button.index = a; \ @@ -89,34 +91,46 @@ item.labelY = p; \ item.unk1F = q -namespace Kyra { - class KyraEngine_v2; class Screen_v2; class GUI_v2 : public GUI { -friend class KyraEngine_v2; public: - GUI_v2(KyraEngine_v2 *engine); + GUI_v2(KyraEngine_v2 *vm); + + virtual void initStaticData() = 0; Button *addButtonToList(Button *list, Button *newButton); void processButton(Button *button); int processButtonList(Button *button, uint16 inputFlag); - int optionsButton(Button *button); -private: +protected: + void updateButton(Button *button); + + KyraEngine_v2 *_vm; + Screen_v2 *_screen; + + bool _buttonListChanged; + Button *_backUpButtonList; + Button *_unknownButtonList; + +protected: + virtual void setupPalette() {} + virtual void restorePalette() {} + + virtual char *getTableString(int id) = 0; + + virtual uint8 textFieldColor1() const = 0; + virtual uint8 textFieldColor2() const = 0; + virtual uint8 textFieldColor3() const = 0; +protected: void getInput(); Button _menuButtons[7]; Button _scrollUpButton; Button _scrollDownButton; Menu _mainMenu, _gameOptions, _audioOptions, _choiceMenu, _loadMenu, _saveMenu, _savenameMenu, _deathMenu; - void initStaticData(); - - const char *getMenuTitle(const Menu &menu); - const char *getMenuItemTitle(const MenuItem &menuItem); - const char *getMenuItemLabel(const MenuItem &menuItem); Button *getButtonListData() { return _menuButtons; } @@ -132,26 +146,11 @@ private: Button _sliderButtons[3][4]; - uint8 defaultColor1() const { return 0xCF; } - uint8 defaultColor2() const { return 0xF8; } - void renewHighlight(Menu &menu); - void setupPalette(); - void restorePalette(); - void backUpPage1(uint8 *buffer); void restorePage1(const uint8 *buffer); - void resetState(int item); - - KyraEngine_v2 *_vm; - Screen_v2 *_screen; - - bool _buttonListChanged; - Button *_backUpButtonList; - Button *_unknownButtonList; - Menu *_currentMenu; bool _isLoadMenu; bool _isDeathMenu; @@ -169,33 +168,13 @@ private: void setupSavegameNames(Menu &menu, int num); // main menu - int quitGame(Button *caller); int resumeGame(Button *caller); - // options menu - int gameOptions(Button *caller); - int gameOptionsTalkie(Button *caller); - int quitOptionsMenu(Button *caller); - - int toggleWalkspeed(Button *caller); - int changeLanguage(Button *caller); - int toggleText(Button *caller); - - void setupOptionsButtons(); - // audio menu - int audioOptions(Button *caller); - - Button::Callback _sliderHandlerFunctor; - int sliderHandler(Button *caller); - - void drawSliderBar(int slider, const uint8 *shape); - static const int _sliderBarsPosition[]; // load menu bool _noLoadProcess; - int loadMenu(Button *caller); int clickLoadSlot(Button *caller); int cancelLoadMenu(Button *caller); @@ -212,6 +191,18 @@ private: int _slotToDelete; int deleteMenu(Button *caller); + // options menu + int quitOptionsMenu(Button *caller); + + int toggleWalkspeed(Button *caller); + int toggleText(Button *caller); + + virtual void setupOptionsButtons() = 0; + + // audio options + Button::Callback _sliderHandlerFunctor; + virtual int sliderHandler(Button *caller) = 0; + // savename menu bool _finishNameInput, _cancelNameInput; Common::KeyState _keyPressed; @@ -232,8 +223,6 @@ private: int choiceYes(Button *caller); int choiceNo(Button *caller); - static const uint16 _menuStringsTalkie[]; - static const uint16 _menuStringsOther[]; }; } // end of namespace Kyra diff --git a/engines/kyra/gui_v3.cpp b/engines/kyra/gui_v3.cpp deleted file mode 100644 index c797ca0812..0000000000 --- a/engines/kyra/gui_v3.cpp +++ /dev/null @@ -1,366 +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/text_v3.h" -#include "kyra/wsamovie.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); - _shownMessage = string; - _screen->hideMouse(); - - restoreCommandLine(); - _restoreCommandLine = false; - - if (string) { - int x = _text->getCenterStringX(string, 0, 320); - int pageBackUp = _screen->_curPage; - _screen->_curPage = 0; - _text->printText(string, x, _commandLineY, c0, c1, 0); - _screen->_curPage = pageBackUp; - _screen->updateScreen(); - setCommandLineRestoreTimer(7); - } - - _screen->showMouse(); -} - -void KyraEngine_v3::showMessageFromCCode(int string, uint8 c0, int) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::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); - char buffer[100]; - char *src = (char*)getTableEntry(_itemFile, item); - - while (*src != ' ') - ++src; - ++src; - - *src = toupper(*src); - - strcpy(buffer, src); - strcat(buffer, " "); - strcat(buffer, (const char*)getTableEntry(_cCodeFile, str)); - - showMessage(buffer, c0, 0xF0); -} - -void KyraEngine_v3::updateCommandLine() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::updateCommandLine()"); - if (_restoreCommandLine) { - restoreCommandLine(); - _restoreCommandLine = false; - } -} - -void KyraEngine_v3::restoreCommandLine() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::restoreCommandLine()"); - int y = _inventoryState ? 144 : 188; - _screen->copyBlockToPage(0, 0, y, 320, 12, _interfaceCommandLine); -} - -void KyraEngine_v3::updateCLState() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::updateCLState()"); - if (_inventoryState) - _commandLineY = 145; - else - _commandLineY = 189; -} - -void KyraEngine_v3::showInventory() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::showInventory()"); - if (!_screen->isMouseVisible()) - return; - if (queryGameFlag(3)) - return; - - _screen->copyBlockToPage(3, 0, 0, 320, 56, _interface); - drawMalcolmsMoodText(); - - _inventoryState = true; - updateCLState(); - - redrawInventory(30); - drawMalcolmsMoodPointer(-1, 30); - //XXX - - if (queryGameFlag(0x97)) - drawJestersStaff(1, 30); - - _screen->hideMouse(); - - if (_itemInHand < 0) { - _handItemSet = -1; - _screen->setMouseCursor(0, 0, getShapePtr(0)); - } - - _screen->copyRegion(0, 188, 0, 0, 320, 12, 0, 2, Screen::CR_NO_P_CHECK); - - if (_inventoryScrollSpeed == -1) { - uint32 endTime = _system->getMillis() + _tickLength * 15; - int times = 0; - while (_system->getMillis() < endTime) { - _screen->copyRegion(0, 188, 0, 0, 320, 12, 0, 2, Screen::CR_NO_P_CHECK); - _screen->copyRegion(0, 188, 0, 0, 320, 12, 0, 2, Screen::CR_NO_P_CHECK); - ++times; - } - - times = MAX(times, 1); - - int speed = 60 / times; - if (speed <= 1) - _inventoryScrollSpeed = 1; - else if (speed >= 8) - _inventoryScrollSpeed = 8; - else - _inventoryScrollSpeed = speed; - } - - int height = 12; - int y = 188; - int times = 0; - uint32 waitTill = _system->getMillis() + _tickLength; - - while (y > 144) { - _screen->copyRegion(0, 0, 0, y, 320, height, 2, 0, Screen::CR_NO_P_CHECK); - _screen->updateScreen(); - - ++times; - if (_inventoryScrollSpeed == 1 && times == 3) { - while (waitTill > _system->getMillis()) - _system->delayMillis(10); - times = 0; - waitTill = _system->getMillis() + _tickLength; - } - - height += _inventoryScrollSpeed; - y -= _inventoryScrollSpeed; - } - - _screen->copyRegion(0, 0, 0, 144, 320, 56, 2, 0, Screen::CR_NO_P_CHECK); - _screen->updateScreen(); - - //initInventoryButtonList(0); - - restorePage3(); - _screen->showMouse(); -} - -void KyraEngine_v3::hideInventory() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::hideInventory()"); - if (queryGameFlag(3)) - return; - - _inventoryState = false; - updateCLState(); - //initInventoryButtonList(1); - - _screen->copyBlockToPage(3, 0, 0, 320, 56, _interface); - _screen->hideMouse(); - - restorePage3(); - flagAnimObjsForRefresh(); - drawAnimObjects(); - _screen->copyRegion(0, 144, 0, 0, 320, 56, 0, 2, Screen::CR_NO_P_CHECK); - - if (_inventoryScrollSpeed == -1) { - uint32 endTime = _system->getMillis() + _tickLength * 15; - int times = 0; - while (_system->getMillis() < endTime) { - _screen->copyRegion(0, 144, 0, 0, 320, 12, 0, 2, Screen::CR_NO_P_CHECK); - _screen->copyRegion(0, 144, 0, 0, 320, 12, 0, 2, Screen::CR_NO_P_CHECK); - ++times; - } - - times = MAX(times, 1); - - int speed = 60 / times; - if (speed <= 1) - _inventoryScrollSpeed = 1; - else if (speed >= 8) - _inventoryScrollSpeed = 8; - else - _inventoryScrollSpeed = speed; - } - - int y = 144; - int y2 = 144 + _inventoryScrollSpeed; - uint32 waitTill = _system->getMillis() + _tickLength; - int times = 0; - - while (y2 < 188) { - _screen->copyRegion(0, 0, 0, y2, 320, 56, 2, 0, Screen::CR_NO_P_CHECK); - _screen->copyRegion(0, y, 0, y, 320, _inventoryScrollSpeed, 2, 0, Screen::CR_NO_P_CHECK); - _screen->updateScreen(); - - ++times; - if (_inventoryScrollSpeed == 1 && times == 3) { - while (waitTill > _system->getMillis()) - _system->delayMillis(10); - times = 0; - waitTill = _system->getMillis() + _tickLength; - } - - y += _inventoryScrollSpeed; - y2 += _inventoryScrollSpeed; - } - - _screen->copyRegion(0, 0, 0, 188, 320, 56, 2, 0, Screen::CR_NO_P_CHECK); - _screen->copyRegion(0, y, 0, y, 320, 188-y, 2, 0, Screen::CR_NO_P_CHECK); - _screen->showMouse(); -} - -void KyraEngine_v3::drawMalcolmsMoodText() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::drawMalcolmsMoodText()"); - static const int stringId[] = { 0x32, 0x37, 0x3C }; - - if (queryGameFlag(0x219)) - return; - - const char *string = (const char*)getTableEntry(_cCodeFile, stringId[_malcolmsMood]); - - Screen::FontId oldFont = _screen->setFont(Screen::FID_8_FNT); - _screen->_charWidth = -2; - - int width = _screen->getTextWidth(string); - - _screen->_charWidth = 0; - _screen->setFont(oldFont); - - int pageBackUp = _screen->_curPage; - const int x = 280 - (width / 2); - int y = 0; - if (_inventoryState) { - y = 189; - _screen->_curPage = 0; - } else { - y = 45; - _screen->_curPage = 2; - } - - _screen->hideMouse(); - _screen->drawShape(_screen->_curPage, getShapePtr(432), 244, 189, 0, 0); - _text->printText(string, x, y+1, 0xFF, 0xF0, 0x00); - _screen->showMouse(); - _screen->_curPage = pageBackUp; -} - -void KyraEngine_v3::drawMalcolmsMoodPointer(int frame, int page) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::drawMalcolmsMoodPointer(%d, %d)", frame, page); - static const int stateTable[] = { - 1, 6, 11 - }; - - if (frame == -1) - frame = stateTable[_malcolmsMood]; - if (queryGameFlag(0x219)) - frame = 13; - - if (page == 0) { - _invWsa->setX(0); - _invWsa->setY(0); - _invWsa->setDrawPage(0); - _invWsa->displayFrame(frame, 0); - _screen->updateScreen(); - } else if (page == 30) { - _invWsa->setX(0); - _invWsa->setY(-144); - _invWsa->setDrawPage(2); - _invWsa->displayFrame(frame, 0); - } - - _invWsaFrame = frame; -} - -void KyraEngine_v3::drawJestersStaff(int type, int page) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::drawJestersStaff(%d, %d)", type, page); - int y = 155; - if (page == 30) { - page = 2; - y -= 144; - } - - int shape = (type != 0) ? 454 : 453; - _screen->drawShape(page, getShapePtr(shape), 217, y, 0, 0); -} - -void KyraEngine_v3::redrawInventory(int page) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::redrawInventory(%d)", page); - int yOffset = 0; - - if (page == 30) { - page = 2; - yOffset = -144; - } - - int pageBackUp = _screen->_curPage; - _screen->_curPage = page; - _screen->hideMouse(); - - for (int i = 0; i < 10; ++i) { - clearInventorySlot(i, page); - if (_mainCharacter.inventory[i] != 0xFFFF) { - _screen->drawShape(page, getShapePtr(_mainCharacter.inventory[i]+248), _inventoryX[i], _inventoryY[i] + yOffset, 0, 0); - drawInventorySlot(page, _mainCharacter.inventory[i], i); - } - } - - _screen->showMouse(); - _screen->_curPage = pageBackUp; - - if (page == 0 || page == 1) - _screen->updateScreen(); -} - -void KyraEngine_v3::clearInventorySlot(int slot, int page) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::clearInventorySlot(%d, %d)", slot, page); - int yOffset = 0; - if (page == 30) { - page = 2; - yOffset = -144; - } - - _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); - int yOffset = 0; - if (page == 30) { - page = 2; - yOffset = -144; - } - - _screen->drawShape(page, getShapePtr(item+248), _inventoryX[slot], _inventoryY[slot] + yOffset, 0, 0); -} - -} // end of namespace Kyra - diff --git a/engines/kyra/items_hof.cpp b/engines/kyra/items_hof.cpp new file mode 100644 index 0000000000..da3062fe2c --- /dev/null +++ b/engines/kyra/items_hof.cpp @@ -0,0 +1,448 @@ +/* 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::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::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].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]; +} + +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; +} + +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)); +} + +} // end of namespace Kyra + diff --git a/engines/kyra/items_v3.cpp b/engines/kyra/items_mr.cpp index 23162514c2..8ace9f8a3c 100644 --- a/engines/kyra/items_v3.cpp +++ b/engines/kyra/items_mr.cpp @@ -18,33 +18,18 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * - * $URL $ + * $URL$ * $Id$ * */ -#include "kyra/kyra_v3.h" +#include "kyra/kyra_mr.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()"); +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) @@ -55,47 +40,17 @@ void KyraEngine_v3::removeTrashItems() { } } -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::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) +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_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 KyraEngine_MR::checkItemCollision(int x, int y) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::checkItemCollision(%d, %d)", x, y); int itemIndex = -1; int maxItemY = -1; @@ -124,8 +79,8 @@ int KyraEngine_v3::checkItemCollision(int x, int y) { return itemIndex; } -void KyraEngine_v3::setMouseCursor(uint16 item) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::setMouseCursor(%u)", item); +void KyraEngine_MR::setMouseCursor(uint16 item) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::setMouseCursor(%u)", item); int shape = 0; int hotX = 1; int hotY = 1; @@ -140,8 +95,8 @@ void KyraEngine_v3::setMouseCursor(uint16 item) { _screen->setMouseCursor(hotX, hotY, getShapePtr(shape)); } -void KyraEngine_v3::setItemMouseCursor() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::setItemMouseCursor()"); +void KyraEngine_MR::setItemMouseCursor() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::setItemMouseCursor()"); _handItemSet = _itemInHand; if (_itemInHand == -1) _screen->setMouseCursor(0, 0, _gameShapes[0]); @@ -149,31 +104,8 @@ void KyraEngine_v3::setItemMouseCursor() { _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); +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; @@ -181,7 +113,7 @@ bool KyraEngine_v3::dropItem(int unk1, uint16 item, int x, int y, int unk2) { if (processItemDrop(_mainCharacter.sceneId, item, x, y, unk1, unk2)) return true; - playSoundEffect(13, 200); + snd_playSoundEffect(13, 200); if (countAllItems() >= 50) { removeTrashItems(); @@ -193,12 +125,12 @@ bool KyraEngine_v3::dropItem(int unk1, uint16 item, int x, int y, int unk2) { } if (!_chatText) - playSoundEffect(13, 200); + 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); +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); @@ -228,7 +160,6 @@ bool KyraEngine_v3::processItemDrop(uint16 sceneId, uint16 item, int x, int y, i _itemList[freeItemSlot].x = x; _itemList[freeItemSlot].y = y; _itemList[freeItemSlot].id = item; - _itemList[freeItemSlot].unk8 = 1; _itemList[freeItemSlot].sceneId = sceneId; return true; } @@ -304,14 +235,14 @@ bool KyraEngine_v3::processItemDrop(uint16 sceneId, uint16 item, int x, int y, i return true; } -void KyraEngine_v3::itemDropDown(int startX, int startY, int dstX, int dstY, int itemSlot, uint16 item, int remove) { +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; - playSoundEffect(0x0C, 0xC8); + snd_playSoundEffect(0x0C, 0xC8); addItemToAnimList(itemSlot); } else { uint8 *itemShape = getShapePtr(item + 248); @@ -340,7 +271,7 @@ void KyraEngine_v3::itemDropDown(int startX, int startY, int dstX, int dstY, int restoreGfxRect32x32(curX, curY-16); if (dstX != dstY || (dstY - startY > 16)) { - playSoundEffect(0x11, 0xC8); + snd_playSoundEffect(0x11, 0xC8); speed = MAX(speed, 6); int speedX = ((dstX - startX) << 4) / speed; int origSpeed = speed; @@ -380,7 +311,7 @@ void KyraEngine_v3::itemDropDown(int startX, int startY, int dstX, int dstY, int _itemList[itemSlot].y = dstY; _itemList[itemSlot].id = item; _itemList[itemSlot].sceneId = _mainCharacter.sceneId; - playSoundEffect(0x0C, 0xC8); + snd_playSoundEffect(0x0C, 0xC8); addItemToAnimList(itemSlot); _screen->showMouse(); } @@ -389,9 +320,8 @@ void KyraEngine_v3::itemDropDown(int startX, int startY, int dstX, int dstY, int removeHandItem(); } -void KyraEngine_v3::exchangeMouseItem(int itemPos, int runScript) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::exchangeMouseItem(%d, %d)", itemPos, runScript); - _screen->hideMouse(); +void KyraEngine_MR::exchangeMouseItem(int itemPos, int runScript) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::exchangeMouseItem(%d, %d)", itemPos, runScript); if (itemListMagic(_itemInHand, itemPos)) return; @@ -401,6 +331,7 @@ void KyraEngine_v3::exchangeMouseItem(int itemPos, int runScript) { return; } + _screen->hideMouse(); deleteItemAnimEntry(itemPos); int itemId = _itemList[itemPos].id; @@ -408,7 +339,7 @@ void KyraEngine_v3::exchangeMouseItem(int itemPos, int runScript) { _itemInHand = itemId; addItemToAnimList(itemPos); - playSoundEffect(0x0B, 0xC8); + snd_playSoundEffect(0x0B, 0xC8); setMouseCursor(_itemInHand); int str2 = 0; @@ -422,8 +353,8 @@ void KyraEngine_v3::exchangeMouseItem(int itemPos, int runScript) { runSceneScript6(); } -bool KyraEngine_v3::pickUpItem(int x, int y, int runScript) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::pickUpItem(%d, %d, %d)", x, y, runScript); +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) @@ -436,7 +367,7 @@ bool KyraEngine_v3::pickUpItem(int x, int y, int runScript) { deleteItemAnimEntry(itemPos); int itemId = _itemList[itemPos].id; _itemList[itemPos].id = 0xFFFF; - playSoundEffect(0x0B, 0xC8); + snd_playSoundEffect(0x0B, 0xC8); setMouseCursor(itemId); int itemString = 0; @@ -454,8 +385,8 @@ bool KyraEngine_v3::pickUpItem(int x, int y, int runScript) { return true; } -bool KyraEngine_v3::isDropable(int x, int y) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::isDropable(%d, %d)", x, y); +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; @@ -469,12 +400,12 @@ bool KyraEngine_v3::isDropable(int x, int y) { return true; } -bool KyraEngine_v3::itemListMagic(int handItem, int itemSlot) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::itemListMagic(%d, %d)", handItem, itemSlot); +bool KyraEngine_MR::itemListMagic(int handItem, int itemSlot) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::itemListMagic(%d, %d)", handItem, itemSlot); uint16 item = _itemList[itemSlot].id; - if (_curChapter == 1 && handItem == 3 && item == 3 && queryGameFlag(0x76)) { - //eelScript(); + if (_currentChapter == 1 && handItem == 3 && item == 3 && queryGameFlag(0x76)) { + eelScript(); return true; } else if ((handItem == 6 || handItem == 7) && item == 2) { int animObjIndex = -1; @@ -486,11 +417,11 @@ bool KyraEngine_v3::itemListMagic(int handItem, int itemSlot) { assert(animObjIndex != -1); _screen->hideMouse(); - playSoundEffect(0x93, 0xC8); + snd_playSoundEffect(0x93, 0xC8); for (int i = 109; i <= 141; ++i) { - _animObjects[animObjIndex].shapeIndex = i+248; + _animObjects[animObjIndex].shapeIndex1 = i+248; _animObjects[animObjIndex].needRefresh = true; - delay(1, true); + delay(1*_tickLength, true); } deleteItemAnimEntry(itemSlot); @@ -520,9 +451,9 @@ bool KyraEngine_v3::itemListMagic(int handItem, int itemSlot) { uint8 resItem = _itemMagicTable[i+2]; uint8 newItem = _itemMagicTable[i+3]; - playSoundEffect(0x0F, 0xC8); + snd_playSoundEffect(0x0F, 0xC8); - _itemList[itemSlot].id = resItem; + _itemList[itemSlot].id = (resItem == 0xFF) ? 0xFFFF : resItem; _screen->hideMouse(); deleteItemAnimEntry(itemSlot); @@ -537,28 +468,95 @@ bool KyraEngine_v3::itemListMagic(int handItem, int itemSlot) { 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_v3::getItemCommandStringDrop(uint16 item) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::getItemCommandStringDrop(%u)", item); +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_v3::getItemCommandStringPickUp(uint16 item) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::getItemCommandStringPickUp(%u)", item); +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_v3::getItemCommandStringInv(uint16 item) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::getItemCommandStringInv(%u)", item); +int KyraEngine_MR::getItemCommandStringInv(uint16 item) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::getItemCommandStringInv(%u)", item); assert(item < _itemStringMapSize); int stringId = _itemStringMap[item]; return _itemStringInv[stringId]; diff --git a/engines/kyra/items_v2.cpp b/engines/kyra/items_v2.cpp index ee010b62e6..78768c70ab 100644 --- a/engines/kyra/items_v2.cpp +++ b/engines/kyra/items_v2.cpp @@ -24,12 +24,25 @@ */ #include "kyra/kyra_v2.h" +#include "kyra/screen_v2.h" namespace Kyra { +void KyraEngine_v2::initItemList(int size) { + debugC(9, kDebugLevelMain, "KyraEngine_v2::initItemList(%d)", size); + delete [] _itemList; + + _itemList = new Item[size]; + assert(_itemList); + memset(_itemList, 0, sizeof(Item)*size); + _itemListSize = size; + + resetItemList(); +} + int KyraEngine_v2::findFreeItem() { debugC(9, kDebugLevelMain, "KyraEngine_v2::findFreeItem()"); - for (int i = 0; i < 30; ++i) { + for (int i = 0; i < _itemListSize; ++i) { if (_itemList[i].id == 0xFFFF) return i; } @@ -39,7 +52,7 @@ int KyraEngine_v2::findFreeItem() { int KyraEngine_v2::countAllItems() { debugC(9, kDebugLevelMain, "KyraEngine_v2::countAllItems()"); int num = 0; - for (int i = 0; i < 30; ++i) { + for (int i = 0; i < _itemListSize; ++i) { if (_itemList[i].id != 0xFFFF) ++num; } @@ -48,435 +61,40 @@ int KyraEngine_v2::countAllItems() { 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) { + for (int i = 0; i < _itemListSize; ++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; - } +int KyraEngine_v2::findItem(uint16 item) { + debugC(9, kDebugLevelMain, "KyraEngine_v2::findItem(%u)", item); + for (int i = 0; i < _itemListSize; ++i) { + if (_itemList[i].id == item) + return i; } - - return itemPos; + return -1; } 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; - } + for (int i = 0; i < _itemListSize; ++i) + resetItem(i); } -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::resetItem(int index) { + debugC(9, kDebugLevelMain, "KyraEngine_v2::resetItem(%d)", index); + _itemList[index].id = 0xFFFF; + _itemList[index].sceneId = 0xFFFF; + _itemList[index].x = 0; + _itemList[index].y = 0; } void KyraEngine_v2::setHandItem(uint16 item) { debugC(9, kDebugLevelMain, "KyraEngine_v2::setHandItem(%u)", item); - _screen->hideMouse(); + Screen *scr = screen(); + scr->hideMouse(); if (item == 0xFFFF) { removeHandItem(); @@ -485,27 +103,18 @@ void KyraEngine_v2::setHandItem(uint16 item) { _itemInHand = item; } - _screen->showMouse(); + scr->showMouse(); } void KyraEngine_v2::removeHandItem() { debugC(9, kDebugLevelMain, "KyraEngine_v2::removeHandItem()"); - _screen->hideMouse(); - _screen->setMouseCursor(0, 0, _defaultShapeTable[0]); + Screen *scr = screen(); + scr->hideMouse(); + scr->setMouseCursor(0, 0, getShapePtr(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; + scr->showMouse(); } -} // end of namespace Kyra +} // end of namesapce Kyra diff --git a/engines/kyra/kyra.cpp b/engines/kyra/kyra.cpp index 5ee2c1ed0c..05d8b79a4e 100644 --- a/engines/kyra/kyra.cpp +++ b/engines/kyra/kyra.cpp @@ -39,15 +39,14 @@ namespace Kyra { KyraEngine::KyraEngine(OSystem *system, const GameFlags &flags) - : Engine(system) { + : Engine(system), _flags(flags) { _res = 0; _sound = 0; _text = 0; _staticres = 0; _timer = 0; - _scriptInterpreter = 0; + _emc = 0; - _flags = flags; _gameSpeed = 60; _tickLength = (uint8)(1000.0 / _gameSpeed); @@ -87,50 +86,53 @@ int KyraEngine::init() { _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, ConfMan.getInt("music_volume")); _mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, ConfMan.getInt("speech_volume")); - // We prefer AdLib over native MIDI, since our AdLib playback code is much - // more mature than our MIDI player. For example we are missing MT-32 support - // and it seems our MIDI playback code has threading issues (see bug #1506583 - // "KYRA1: Crash on exceeded polyphony" for more information). - int midiDriver = MidiDriver::detectMusicDriver(MDT_MIDI | MDT_ADLIB/* | MDT_PREFER_MIDI*/); - - if (_flags.platform == Common::kPlatformFMTowns || _flags.platform == Common::kPlatformPC98) { - // TODO: currently we don't support the PC98 sound data, - // but since it has the FM-Towns data files, we just use the - // FM-Towns driver - if (_flags.gameID == GI_KYRA1) - _sound = new SoundTowns(this, _mixer); - else - _sound = new SoundTowns_v2(this, _mixer); - } else if (midiDriver == MD_ADLIB) { - _sound = new SoundAdlibPC(this, _mixer); - assert(_sound); - } else { - bool native_mt32 = ((midiDriver == MD_MT32) || ConfMan.getBool("native_mt32")); - - MidiDriver *driver = MidiDriver::createMidi(midiDriver); - assert(driver); - if (native_mt32) - driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE); - - SoundMidiPC *soundMidiPc = new SoundMidiPC(this, _mixer, driver); - _sound = soundMidiPc; - assert(_sound); - soundMidiPc->hasNativeMT32(native_mt32); - - // Unlike some SCUMM games, it's not that the MIDI sounds are - // missing. It's just that at least at the time of writing they - // are decidedly inferior to the Adlib ones. - if (ConfMan.getBool("multi_midi")) { - SoundAdlibPC *adlib = new SoundAdlibPC(this, _mixer); - assert(adlib); - - _sound = new MixedSoundDriver(this, _mixer, soundMidiPc, adlib); + if (!_flags.useDigSound) { + // We prefer AdLib over native MIDI, since our AdLib playback code is much + // more mature than our MIDI player. For example we are missing MT-32 support + // and it seems our MIDI playback code has threading issues (see bug #1506583 + // "KYRA1: Crash on exceeded polyphony" for more information). + int midiDriver = MidiDriver::detectMusicDriver(MDT_MIDI | MDT_ADLIB/* | MDT_PREFER_MIDI*/); + + if (_flags.platform == Common::kPlatformFMTowns || _flags.platform == Common::kPlatformPC98) { + // TODO: currently we don't support the PC98 sound data, + // but since it has the FM-Towns data files, we just use the + // FM-Towns driver + if (_flags.gameID == GI_KYRA1) + _sound = new SoundTowns(this, _mixer); + else + _sound = new SoundTowns_v2(this, _mixer); + } else if (midiDriver == MD_ADLIB) { + _sound = new SoundAdlibPC(this, _mixer); + assert(_sound); + } else { + bool native_mt32 = ((midiDriver == MD_MT32) || ConfMan.getBool("native_mt32")); + + MidiDriver *driver = MidiDriver::createMidi(midiDriver); + assert(driver); + if (native_mt32) + driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE); + + SoundMidiPC *soundMidiPc = new SoundMidiPC(this, _mixer, driver); + _sound = soundMidiPc; assert(_sound); + soundMidiPc->hasNativeMT32(native_mt32); + + // Unlike some SCUMM games, it's not that the MIDI sounds are + // missing. It's just that at least at the time of writing they + // are decidedly inferior to the Adlib ones. + if (ConfMan.getBool("multi_midi")) { + SoundAdlibPC *adlib = new SoundAdlibPC(this, _mixer); + assert(adlib); + + _sound = new MixedSoundDriver(this, _mixer, soundMidiPc, adlib); + assert(_sound); + } } } if (_sound) _sound->updateVolumeSettings(); + _res = new Resource(this); assert(_res); _res->reset(); @@ -143,8 +145,8 @@ int KyraEngine::init() { _timer = new TimerManager(this, _system); assert(_timer); setupTimers(); - _scriptInterpreter = new ScriptHelper(this); - assert(_scriptInterpreter); + _emc = new EMCInterpreter(this); + assert(_emc); setupOpcodeTable(); readSettings(); @@ -198,7 +200,7 @@ KyraEngine::~KyraEngine() { delete _sound; delete _text; delete _timer; - delete _scriptInterpreter; + delete _emc; } void KyraEngine::quitGame() { @@ -271,8 +273,10 @@ void KyraEngine::readSettings() { } _configSounds = ConfMan.getBool("sfx_mute") ? 0 : 1; - _sound->enableMusic(_configMusic); - _sound->enableSFX(_configSounds); + if (_sound) { + _sound->enableMusic(_configMusic); + _sound->enableSFX(_configSounds); + } bool speechMute = ConfMan.getBool("speech_mute"); bool subtitles = ConfMan.getBool("subtitles"); @@ -311,11 +315,12 @@ void KyraEngine::writeSettings() { break; } - if (!_configMusic) - _sound->beginFadeOut(); - - _sound->enableMusic(_configMusic); - _sound->enableSFX(_configSounds); + if (_sound) { + if (!_configMusic) + _sound->beginFadeOut(); + _sound->enableMusic(_configMusic); + _sound->enableSFX(_configSounds); + } ConfMan.setBool("speech_mute", speechMute); ConfMan.setBool("subtitles", subtitles); diff --git a/engines/kyra/kyra.h b/engines/kyra/kyra.h index 0fee9e4e3e..18a4a52fe2 100644 --- a/engines/kyra/kyra.h +++ b/engines/kyra/kyra.h @@ -28,10 +28,8 @@ #include "engines/engine.h" -#include "common/rect.h" #include "common/array.h" #include "common/events.h" -#include "common/func.h" #include "kyra/script.h" @@ -47,16 +45,14 @@ namespace Kyra { struct GameFlags { Common::Language lang; Common::Platform platform; - bool isDemo; - bool useAltShapeHeader; // alternative shape header (uses 2 bytes more, those are unused though) - bool isTalkie; - bool useHiResOverlay; - byte gameID; -}; -struct Rect { - int x, y; - int x2, y2; + bool isDemo : 1; + bool useAltShapeHeader : 1; // alternative shape header (uses 2 bytes more, those are unused though) + bool isTalkie : 1; + bool useHiResOverlay : 1; + bool useDigSound : 1; + + byte gameID; }; enum { @@ -76,7 +72,7 @@ struct AudioDataStruct { // in the future we maybe merge some flags and/or create new ones enum kDebugLevels { kDebugLevelScriptFuncs = 1 << 0, // prints debug output of o#_* functions - kDebugLevelScript = 1 << 1, // prints debug output of "ScriptHelper" functions + kDebugLevelScript = 1 << 1, // prints debug output of "EMCInterpreter" functions kDebugLevelSprites = 1 << 2, // prints debug output of "Sprites" functions kDebugLevelScreen = 1 << 3, // prints debug output of "Screen" functions kDebugLevelSound = 1 << 4, // prints debug output of "Sound" functions @@ -125,8 +121,6 @@ public: uint32 tickLength() const { return _tickLength; } - virtual Movie *createWSAMovie() = 0; - Common::RandomSource _rnd; // input @@ -157,7 +151,7 @@ public: // sound virtual void snd_playTheme(int file, int track); - virtual void snd_playSoundEffect(int id); + virtual void snd_playSoundEffect(int id, int volume=0xFF); virtual void snd_playWanderScoreViaMap(int command, int restart); virtual void snd_playVoiceFile(int id) = 0; virtual bool snd_voiceIsPlaying(); @@ -181,7 +175,7 @@ protected: TextDisplayer *_text; StaticResource *_staticres; TimerManager *_timer; - ScriptHelper *_scriptInterpreter; + EMCInterpreter *_emc; // config specific virtual void registerDefaultSettings(); diff --git a/engines/kyra/kyra_hof.cpp b/engines/kyra/kyra_hof.cpp new file mode 100644 index 0000000000..c25af91bec --- /dev/null +++ b/engines/kyra/kyra_hof.cpp @@ -0,0 +1,2013 @@ +/* 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 { + +const KyraEngine_v2::EngineDesc KyraEngine_HoF::_hofEngineDesc = { + // Generic shape related + 64, + KyraEngine_HoF::_characterFrameTable, + + // Scene script + 8, + + // Animation script specific + 33 +}; + +KyraEngine_HoF::KyraEngine_HoF(OSystem *system, const GameFlags &flags) : KyraEngine_v2(system, flags, _hofEngineDesc), _updateFunctor(this, &KyraEngine_HoF::update) { + _mouseSHPBuf = 0; + _screen = 0; + _text = 0; + + _seqProcessedString = 0; + _activeWSA = 0; + _activeText = 0; + _seqWsa = 0; + _sequences = 0; + _sequenceSoundList = 0; + + _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; + _unkHandleSceneChangeFlag = false; + _pathfinderFlag = 0; + _mouseX = _mouseY = 0; + + _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; + _inventorySaved = false; + _unkBuf200kByte = 0; + memset(&_sceneShapeTable, 0, sizeof(_sceneShapeTable)); + + _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; + setDlgIndex(-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 _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<const TIMOpcode*>::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_HoF(this); + assert(_debugger); + _text = new TextDisplayer_HoF(this, _screen); + assert(_text); + _gui = new GUI_HoF(this); + assert(_gui); + _gui->initStaticData(); + _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; + _menuDirectlyToLoad &= saveFileLoadable(0); + + if (_menuChoice & 1) { + startup(); + if (!quit()) + runLoop(); + cleanup(); + + if (_showOutro) + 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; + + allocAnimObjects(1, 10, 30); + + _screen->_curPage = 0; + delete [] _mouseSHPBuf; + _mouseSHPBuf = 0; + + _gameShapes.clear(); + 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)]; + initItemList(30); + loadButtonShapes(); + resetItemList(); + _characterShapeFile = 1; + loadCharacterShapes(_characterShapeFile); + 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)); + 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) && _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)) { + 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(); + _showOutro = 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(); + } + } +} + +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 [] _unkBuf200kByte; _unkBuf200kByte = 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::loadCharacterShapes(int shapes) { + char file[10]; + strcpy(file, "_ZX.SHP"); + + _characterShapeFile = 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; + + _characterShapeFile = 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); +} + +#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); + runAnimationScript("_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; +} + +int KyraEngine_HoF::getCharacterWalkspeed() const { + return _timer->getDelay(0); +} + +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); +} + +bool 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 true; + + return false; +} + +int KyraEngine_HoF::initAnimationShapes(uint8 *filedata) { + const int lastEntry = MIN(_animShapeLastEntry, 31); + for (int i = 0; i < lastEntry; ++i) { + addShapeToPool(filedata, i+33, i); + ShapeDesc *desc = &_shapeDescTable[24+i]; + desc->xAdd = _animShapeXAdd; + desc->yAdd = _animShapeYAdd; + desc->width = _animShapeWidth; + desc->height = _animShapeHeight; + } + return lastEntry; +} + +void KyraEngine_HoF::uninitAnimationShapes(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; + randomSceneChat(); + } else { + scriptAnimation = false; + if (_characterShapeFile > 8) + return; + + int scriptMin = scriptMinTable[_characterShapeFile-1]; + int scriptMax = scriptMaxTable[_characterShapeFile-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" + }; + + runAnimationScript(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_hof.h b/engines/kyra/kyra_hof.h new file mode 100644 index 0000000000..1e6c23331e --- /dev/null +++ b/engines/kyra/kyra_hof.h @@ -0,0 +1,916 @@ +/* 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_HOF_H +#define KYRA_KYRA_HOF_H + +#include "kyra/kyra_v2.h" +#include "kyra/script.h" +#include "kyra/script_tim.h" +#include "kyra/screen_hof.h" +#include "kyra/text_hof.h" +#include "kyra/gui_hof.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_HoF; +class TextDisplayer_HoF; + +struct TIM; + +typedef int (KyraEngine_HoF::*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_HoF : public KyraEngine_v2 { +friend class Debugger_HoF; +friend class TextDisplayer_HoF; +friend class GUI_HoF; +public: + KyraEngine_HoF(OSystem *system, const GameFlags &flags); + ~KyraEngine_HoF(); + + Screen *screen() { return _screen; } + Screen_v2 *screen_v2() const { return _screen; } + GUI_v2 *gui_v2() const { return _gui; } + virtual TextDisplayer *text() { return _text; } + int language() const { return _lang; } +protected: + static const EngineDesc _hofEngineDesc; + + // 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_HoF *_screen; + TextDisplayer_HoF *_text; + 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 + void update(); + void updateWithText(); + + Common::Functor0Mem<void, KyraEngine_HoF> _updateFunctor; + + void updateMouse(); + + void dinoRide(); + + int _mouseState; + + void handleInput(int x, int y); + bool handleInputUnkSub(int x, int y); + + int inputSceneChange(int x, int y, int unk1, int unk2); + + // gfx/animation specific + 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 *_sceneShapeTable[50]; + + WSAMovieV2 *_wsaSlots[10]; + + void freeSceneShapePtrs(); + + struct ShapeDesc { + uint8 unk0, unk1, unk2, unk3, unk4; + uint16 width, height; + int16 xAdd, yAdd; + }; + + ShapeDesc *_shapeDescTable; + + void loadCharacterShapes(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!) + + int initAnimationShapes(uint8 *filedata); + void uninitAnimationShapes(int count, uint8 *filedata); + + // animator + uint8 *_gamePlayBuffer; + void restorePage3(); + + void clearAnimObjects(); + + void refreshAnimObjects(int force); + + void drawAnimObjects(); + void drawSceneAnimObject(AnimObj *obj, int x, int y, int drawLayer); + void drawCharacterAnimObject(AnimObj *obj, int x, int y, int drawLayer); + + void updateItemAnimations(); + + void updateCharFacing(); + void updateCharacterAnim(int); + void updateSceneAnim(int anim, int newFrame); + + int _animObj0Width, _animObj0Height; + void setCharacterAnimDim(int w, int h); + void resetCharacterAnimDim(); + + // scene + const char *_sceneCommentString; + uint8 _scenePal[688]; + + 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 runSceneScript7(); + + void initSceneAnims(int unk1); + void initSceneScreen(int unk1); + + int trySceneChange(int *moveTable, int unk1, int updateChar); + int checkSceneChange(); + + // pathfinder + bool lineIsPassable(int x, int y); + + // item + void setMouseCursor(uint16 item); + + uint8 _itemHtDat[176]; + + int checkItemCollision(int x, int y); + void updateWaterFlasks(); + + 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; + + 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 removeSlotFromInventory(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_HoF *_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 + bool _useCharPal; + int _charPalEntry; + uint8 _charPalTable[16]; + void updateCharPal(int unk1); + void setCharPalEntry(int entry, int value); + + int getCharacterWalkspeed() const; + void updateCharAnimFrame(int num, int *table); + + bool checkCharCollision(int x, int y); + + static const uint8 _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 + bool _chatIsNote; + + 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 randomSceneChat(); + 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 setDlgIndex(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<const TIMOpcode*> _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_HoF::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_setSceneComment(EMCState *script); + int o2_setCharacterAnimFrame(EMCState *script); + int o2_setCharacterFacing(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_loadSoundFile(EMCState *script); + int o2_removeSlotFromInventory(EMCState *script); + int o2_removeItemFromInventory(EMCState *script); + int o2_countItemInInventory(EMCState *script); + int o2_countItemsInScene(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_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_fadeScenePal(EMCState *script); + int o2_enterNewScene(EMCState *script); + int o2_switchScene(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_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_isAnySoundPlaying(EMCState *script); + int o2_setDrawNoShapeFlag(EMCState *script); + int o2_setRunFlag(EMCState *script); + int o2_showLetter(EMCState *script); + int o2_fillRect(EMCState *script); + int o2_encodeShape(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_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_changeChapter(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_resetInputColorCode(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_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_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); + + // animation opcodes + int o2a_setCharacterFrame(EMCState *script); + + // script + void runStartScript(int script, int unk1); + void loadNPCScript(); + + bool _noScriptEnter; + + EMCData _npcScriptData; + + // pathfinder + uint8 *_unkBuf500Bytes; + uint8 *_unkBuf200kByte; + bool _chatAltFlag; + + // 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_mr.cpp index 0fbe3de456..61546fc2e7 100644 --- a/engines/kyra/kyra_v3.cpp +++ b/engines/kyra/kyra_mr.cpp @@ -24,24 +24,40 @@ */ #include "kyra/kyra.h" -#include "kyra/kyra_v3.h" -#include "kyra/screen_v3.h" +#include "kyra/kyra_mr.h" +#include "kyra/screen_mr.h" #include "kyra/wsamovie.h" #include "kyra/sound.h" -#include "kyra/text_v3.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_mr.h" +#include "kyra/resource.h" #include "common/system.h" #include "common/config-manager.h" namespace Kyra { -KyraEngine_v3::KyraEngine_v3(OSystem *system, const GameFlags &flags) : KyraEngine(system, flags) { + +const KyraEngine_v2::EngineDesc KyraEngine_MR::_mrEngineDesc = { + // Generic shape related + 248, + KyraEngine_MR::_characterFrameTable, + + // Scene script + 9, + + // Animation script specific + 9 +}; + +KyraEngine_MR::KyraEngine_MR(OSystem *system, const GameFlags &flags) : KyraEngine_v2(system, flags, _mrEngineDesc) { _soundDigital = 0; _musicSoundChannel = -1; _menuAudioFile = "TITLE1.AUD"; - _curMusicTrack = -1; + _lastMusicCommand = -1; _itemBuffer1 = _itemBuffer2 = 0; _scoreFile = 0; _cCodeFile = 0; @@ -50,13 +66,9 @@ KyraEngine_v3::KyraEngine_v3(OSystem *system, const GameFlags &flags) : KyraEngi _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)); @@ -69,10 +81,6 @@ KyraEngine_v3::KyraEngine_v3(OSystem *system, const GameFlags &flags) : KyraEngi _text = 0; _commandLineY = 189; _inventoryState = false; - memset(&_sceneScriptState, 0, sizeof(_sceneScriptState)); - memset(&_sceneScriptData, 0, sizeof(_sceneScriptData)); - memset(_wsaSlots, 0, sizeof(_wsaSlots)); - _updateCharPosNextUpdate = 0; memset(_characterAnimTable, 0, sizeof(_characterAnimTable)); _overwriteSceneFacing = false; _maskPageMinY = _maskPageMaxY = 0; @@ -81,7 +89,7 @@ KyraEngine_v3::KyraEngine_v3(OSystem *system, const GameFlags &flags) : KyraEngi _mainCharX = _mainCharY = -1; _animList = 0; _drawNoShapeFlag = false; - _wsaPlayingVQA = false; + _wasPlayingVQA = false; _lastCharPalLayer = -1; _charPalUpdate = false; _runFlag = false; @@ -93,12 +101,8 @@ KyraEngine_v3::KyraEngine_v3(OSystem *system, const GameFlags &flags) : KyraEngi _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; @@ -107,9 +111,7 @@ KyraEngine_v3::KyraEngine_v3(OSystem *system, const GameFlags &flags) : KyraEngi _useActorBuffer = false; _curStudioSFX = 283; _badConscienceShown = false; - _curChapter = 1; - _deathHandler = -1; - _moveFacingTable = 0; + _currentChapter = 1; _unkHandleSceneChangeFlag = false; memset(_sceneShapeDescs, 0, sizeof(_sceneShapeDescs)); _cnvFile = _dlgBuffer = 0; @@ -123,59 +125,56 @@ KyraEngine_v3::KyraEngine_v3(OSystem *system, const GameFlags &flags) : KyraEngi _malcolmsMood = 1; _nextIdleAnim = 0; _nextIdleType = false; - _newShapeFlag = -1; - _newShapeFiledata = 0; _inventoryScrollSpeed = -1; _invWsa = 0; _invWsaFrame = -1; + _score = 0; + memset(_scoreFlagTable, 0, sizeof(_scoreFlagTable)); + _mainButtonData = 0; + _mainButtonList = 0; + _mainButtonListInitialized = false; + _enableInventory = true; + _goodConscienceShown = false; + _goodConscienceAnim = -1; + _goodConsciencePosition = false; + _menuDirectlyToLoad = false; + _optionsFile = 0; + _actorFile = 0; } -KyraEngine_v3::~KyraEngine_v3() { +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; - delete [] _sceneAnims; + delete[] _itemBuffer1; + delete[] _itemBuffer2; + delete[] _scoreFile; + delete[] _cCodeFile; + delete[] _scenesFile; + delete[] _itemFile; + delete[] _gamePlayBuffer; + delete[] _interface; + delete[] _interfaceCommandLine; + delete[] _costPalBuffer; for (uint i = 0; i < ARRAYSIZE(_sceneShapes); ++i) - delete [] _sceneShapes[i]; + delete[] _sceneShapes[i]; for (uint i = 0; i < ARRAYSIZE(_sceneAnimMovie); ++i) delete _sceneAnimMovie[i]; - delete [] _gfxBackUpRect; - delete [] _itemList; - delete [] _paletteOverlay; - delete [] _sceneList; + delete[] _gfxBackUpRect; + delete[] _paletteOverlay; + delete[] _sceneList; for (ShapeMap::iterator i = _gameShapes.begin(); i != _gameShapes.end(); ++i) { - delete [] i->_value; + delete[] i->_value; i->_value = 0; } _gameShapes.clear(); - _scriptInterpreter->unloadScript(&_sceneScriptData); - - for (int i = 0; i < ARRAYSIZE(_wsaSlots); ++i) - delete _wsaSlots[i]; - - delete [] _sceneStrings; - delete [] _talkObjectList; - delete [] _moveFacingTable; - - for (Common::Array<const Opcode*>::iterator i = _opcodesTemporary.begin(); i != _opcodesTemporary.end(); ++i) - delete *i; - _opcodesTemporary.clear(); + delete[] _sceneStrings; + delete[] _talkObjectList; for (Common::Array<const Opcode*>::iterator i = _opcodesDialog.begin(); i != _opcodesDialog.end(); ++i) delete *i; @@ -183,25 +182,32 @@ KyraEngine_v3::~KyraEngine_v3() { delete _cnvFile; delete _dlgBuffer; - delete [] _stringBuffer; - delete [] _newShapeFiledata; + delete[] _stringBuffer; delete _invWsa; + delete[] _mainButtonData; + delete _gui; + delete[] _optionsFile; } -int KyraEngine_v3::init() { - _screen = new Screen_v3(this, _system); +int KyraEngine_MR::init() { + _screen = new Screen_MR(this, _system); assert(_screen); - if (!_screen->init()) - error("_screen->init() failed"); + _screen->setResolution(); KyraEngine::init(); + + _debugger = new Debugger_v2(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); + KyraEngine::_text = _text = new TextDisplayer_MR(this, _screen); assert(_text); + _gui = new GUI_MR(this); + assert(_gui); + _gui->initStaticData(); _screen->loadFont(Screen::FID_6_FNT, "6.FNT"); _screen->loadFont(Screen::FID_8_FNT, "8FAT.FNT"); @@ -216,7 +222,7 @@ int KyraEngine_v3::init() { return 0; } -int KyraEngine_v3::go() { +int KyraEngine_MR::go() { bool running = true; preinit(); _screen->hideMouse(); @@ -225,6 +231,24 @@ int KyraEngine_v3::go() { _screen->clearPage(0); _screen->clearPage(2); + const bool firstTimeGame = !saveFileLoadable(0); + + if (firstTimeGame) { + playVQA("K3INTRO"); + _wasPlayingVQA = false; + } + + if (_gameToLoad != -1 || firstTimeGame) { + while (!_screen->isMouseVisible()) + _screen->showMouse(); + + uninitMainMenu(); + _musicSoundChannel = -1; + startup(); + runLoop(); + running = false; + } + while (running && !_quitFlag) { _screen->_curPage = 0; _screen->clearPage(0); @@ -249,11 +273,15 @@ int KyraEngine_v3::go() { } switch (_menu->handle(3)) { + case 2: + _menuDirectlyToLoad = true; + // fall through + case 0: uninitMainMenu(); fadeOutMusic(60); - _screen->fadeToBlack(); + _screen->fadeToBlack(60); _musicSoundChannel = -1; startup(); runLoop(); @@ -262,20 +290,14 @@ int KyraEngine_v3::go() { case 1: playVQA("K3INTRO"); - _wsaPlayingVQA = false; + _wasPlayingVQA = false; _screen->hideMouse(); break; - case 2: - //uninitMainMenu(); - //show load dialog - //running = false; - break; - case 3: default: fadeOutMusic(60); - _screen->fadeToBlack(); + _screen->fadeToBlack(60); uninitMainMenu(); quitGame(); running = false; @@ -283,10 +305,13 @@ int KyraEngine_v3::go() { } } + if (_showOutro) + playVQA("CREDITS"); + return 0; } -void KyraEngine_v3::initMainMenu() { +void KyraEngine_MR::initMainMenu() { _menuAnim = new WSAMovieV2(this, _screen); _menuAnim->open("REVENGE.WSA", 1, _screen->getPalette(0)); _menuAnim->setX(0); @@ -311,15 +336,15 @@ void KyraEngine_v3::initMainMenu() { _menu->init(data, anim); } -void KyraEngine_v3::uninitMainMenu() { +void KyraEngine_MR::uninitMainMenu() { delete _menuAnim; _menuAnim = 0; delete _menu; _menu = 0; } -void KyraEngine_v3::playVQA(const char *name) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::playVQA('%s')", name); +void KyraEngine_MR::playVQA(const char *name) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::playVQA('%s')", name); VQAMovie vqa(this, _system); @@ -334,7 +359,7 @@ void KyraEngine_v3::playVQA(const char *name) { _screen->hideMouse(); memcpy(_screen->getPalette(1), _screen->getPalette(0), 768); fadeOutMusic(60); - _screen->fadeToBlack(); + _screen->fadeToBlack(60); _screen->clearPage(0); vqa.setDrawPage(0); @@ -350,22 +375,22 @@ void KyraEngine_v3::playVQA(const char *name) { _screen->setScreenPalette(pal); _screen->clearPage(0); memcpy(_screen->getPalette(0), _screen->getPalette(1), 768); - _wsaPlayingVQA = true; + _wasPlayingVQA = true; } } #pragma mark - -void KyraEngine_v3::playMenuAudioFile() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::playMenuAudioFile()"); +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_v3::playMusicTrack(int track, int force) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::playMusicTrack(%d, %d)", track, force); +void KyraEngine_MR::snd_playWanderScoreViaMap(int track, int force) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::snd_playWanderScoreViaMap(%d, %d)", track, force); // XXX byte_3C87C compare @@ -374,7 +399,7 @@ void KyraEngine_v3::playMusicTrack(int track, int force) { else if (_musicSoundChannel == -1) force = 1; - if (track == _curMusicTrack && !force) + if (track == _lastMusicCommand && !force) return; stopMusicTrack(); @@ -385,21 +410,21 @@ void KyraEngine_v3::playMusicTrack(int track, int force) { _musicSoundChannel = _soundDigital->playSound(_soundList[track], 0xFF, Audio::Mixer::kMusicSoundType); } - _curMusicTrack = track; + _lastMusicCommand = track; } -void KyraEngine_v3::stopMusicTrack() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::stopMusicTrack()"); +void KyraEngine_MR::stopMusicTrack() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::stopMusicTrack()"); if (_musicSoundChannel != -1 && _soundDigital->isPlaying(_musicSoundChannel)) _soundDigital->stopSound(_musicSoundChannel); - _curMusicTrack = -1; + _lastMusicCommand = -1; _musicSoundChannel = -1; } -int KyraEngine_v3::musicUpdate(int forceRestart) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::musicUpdate(%d)", forceRestart); +int KyraEngine_MR::musicUpdate(int forceRestart) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::musicUpdate(%d)", forceRestart); static uint32 mTimer = 0; static uint16 lock = 0; @@ -414,8 +439,8 @@ int KyraEngine_v3::musicUpdate(int forceRestart) { lock = 1; if (_musicSoundChannel >= 0) { if (!_soundDigital->isPlaying(_musicSoundChannel)) { - if (_curMusicTrack != -1) - playMusicTrack(_curMusicTrack, 1); + if (_lastMusicCommand != -1) + snd_playWanderScoreViaMap(_lastMusicCommand, 1); } } lock = 0; @@ -425,17 +450,17 @@ int KyraEngine_v3::musicUpdate(int forceRestart) { return 1; } -void KyraEngine_v3::fadeOutMusic(int ticks) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::fadeOutMusic(%d)", ticks); +void KyraEngine_MR::fadeOutMusic(int ticks) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::fadeOutMusic(%d)", ticks); if (_musicSoundChannel >= 0) { _fadeOutMusicChannel = _musicSoundChannel; _soundDigital->beginFadeOut(_musicSoundChannel, ticks); - _curMusicTrack = -1; + _lastMusicCommand = -1; } } -void KyraEngine_v3::playSoundEffect(int item, int volume) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::playSoundEffect(%d, %d)", item, volume); +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]]); @@ -445,32 +470,35 @@ void KyraEngine_v3::playSoundEffect(int item, int volume) { } } -void KyraEngine_v3::playVoice(int high, int low) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::playVoice(%d, %d)", high, low); +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_v3::snd_playVoiceFile(int file) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::snd_playVoiceFile(%d)", file); +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_v3::snd_voiceIsPlaying() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::snd_voiceIsPlaying()"); +bool KyraEngine_MR::snd_voiceIsPlaying() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::snd_voiceIsPlaying()"); return _soundDigital->isPlaying(_voiceSoundChannel); } -void KyraEngine_v3::snd_stopVoice() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::snd_stopVoice()"); +void KyraEngine_MR::snd_stopVoice() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::snd_stopVoice()"); if (_voiceSoundChannel != -1) _soundDigital->stopSound(_voiceSoundChannel); } -void KyraEngine_v3::playStudioSFX(const char *str) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::playStudioSFX('%s')", str); +void KyraEngine_MR::playStudioSFX(const char *str) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::playStudioSFX('%s')", str); + if (!_configStudio) + return; + if (_rnd.getRandomNumberRng(1, 2) != 2) return; @@ -478,7 +506,7 @@ void KyraEngine_v3::playStudioSFX(const char *str) { if (str[strSize] != '?' && str[strSize] != '!') return; - playSoundEffect(_curStudioSFX++, 128); + snd_playSoundEffect(_curStudioSFX++, 128); if (_curStudioSFX > 291) _curStudioSFX = 283; @@ -486,8 +514,8 @@ void KyraEngine_v3::playStudioSFX(const char *str) { #pragma mark - -void KyraEngine_v3::preinit() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::preinit()"); +void KyraEngine_MR::preinit() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::preinit()"); _itemBuffer1 = new int8[72]; _itemBuffer2 = new int8[144]; @@ -497,8 +525,8 @@ void KyraEngine_v3::preinit() { _screen->setMouseCursor(0, 0, _gameShapes[0]); } -void KyraEngine_v3::initMouseShapes() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::initMouseShapes()"); +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) @@ -506,13 +534,8 @@ void KyraEngine_v3::initMouseShapes() { delete [] data; } -void KyraEngine_v3::startup() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::startup()"); - for (int i = 0; i < ARRAYSIZE(_wsaSlots); ++i) { - _wsaSlots[i] = new WSAMovieV2(this, _screen); - assert(_wsaSlots[i]); - } - +void KyraEngine_MR::startup() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::startup()"); musicUpdate(0); memset(_flagsTable, 0, sizeof(_flagsTable)); @@ -529,11 +552,9 @@ void KyraEngine_v3::startup() { _stringBuffer = new char[500]; //XXX musicUpdate(0); - _moveFacingTable = new int[600]; _costPalBuffer = new uint8[864]; //XXX - _animObjects = new AnimObj[67]; - _sceneAnims = new SceneAnim[16]; + allocAnimObjects(1, 16, 50); musicUpdate(0); @@ -544,15 +565,16 @@ void KyraEngine_v3::startup() { musicUpdate(0); if (!loadLanguageFile("ITEMS.", _itemFile)) - error("couldn't load ITEMS"); + 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"); + 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 SCENES"); + if (!loadLanguageFile("OPTIONS.", _optionsFile)) + error("Couldn't load OPTIONS"); + if (!loadLanguageFile("_ACTOR.", _actorFile)) error("couldn't load _ACTOR"); musicUpdate(0); @@ -580,19 +602,20 @@ void KyraEngine_v3::startup() { _talkObjectList[i].sceneId = 0xFF; musicUpdate(0); - updateMalcolmShapes(); _gfxBackUpRect = new uint8[_screen->getRectSize(32, 32)]; - _itemList = new Item[50]; + initItemList(50); resetItemList(); loadShadowShape(); - //loadButtonShapes(); musicUpdate(0); loadExtrasShapes(); musicUpdate(0); - loadMalcolmShapes(_malcolmShapes); + _characterShapeFile = 0; + loadCharacterShapes(_characterShapeFile); + updateMalcolmShapes(); musicUpdate(0); - //initInventoryButtonList(1); + initMainButtonList(true); + loadButtonShapes(); loadInterfaceShapes(); musicUpdate(0); @@ -605,15 +628,22 @@ void KyraEngine_v3::startup() { clearAnimObjects(); - //XXX + _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); @@ -621,28 +651,38 @@ void KyraEngine_v3::startup() { assert(_invWsa); _invWsa->open("MOODOMTR.WSA", 1, 0); _invWsaFrame = 6; + saveGame(getSavegameFilename(0), (const char*)getTableEntry(_optionsFile, 33)); _soundDigital->beginFadeOut(_musicSoundChannel, 60); delayWithTicks(60); - enterNewScene(_mainCharacter.sceneId, _mainCharacter.facing, 0, 0, 1); + if (_gameToLoad == -1) + enterNewScene(_mainCharacter.sceneId, _mainCharacter.facing, 0, 0, 1); + else + loadGame(getSavegameFilename(_gameToLoad)); + + if (_menuDirectlyToLoad) + (*_mainButtonData[0].buttonCallback)(&_mainButtonData[0]); + _screen->updateScreen(); musicUpdate(0); _screen->showMouse(); - //XXX + + setNextIdleAnimTimer(); + setWalkspeed(_configWalkspeed); } -void KyraEngine_v3::loadCostPal() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::loadCostPal()"); +void KyraEngine_MR::loadCostPal() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::loadCostPal()"); _costPalBuffer = _res->fileData("_COSTPAL.DAT", 0); } -void KyraEngine_v3::loadShadowShape() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::loadShadowShape()"); +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_v3::loadExtrasShapes() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::loadExtrasShapes()"); +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); @@ -650,22 +690,22 @@ void KyraEngine_v3::loadExtrasShapes() { addShapeToPool(_screen->getCPagePtr(3), 454, 21); } -void KyraEngine_v3::loadInterfaceShapes() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::loadInterfaceShapes()"); +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_v3::loadInterface() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::loadInterface()"); +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_v3::initItems() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::initItems()"); +void KyraEngine_MR::initItems() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::initItems()"); _screen->loadBitmap("ITEMS.CSH", 3, 3, 0); @@ -690,29 +730,29 @@ void KyraEngine_v3::initItems() { _screen->_curPage = 0; } -void KyraEngine_v3::runStartupScript(int script, int unk1) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::runStartupScript(%d, %d)", script, unk1); - ScriptState state; - ScriptData data; +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'; - _scriptInterpreter->loadScript(filename, &data, &_opcodes); - _scriptInterpreter->initScript(&state, &data); - _scriptInterpreter->startScript(&state, 0); + _emc->load(filename, &data, &_opcodes); + _emc->init(&state, &data); + _emc->start(&state, 0); state.regs[6] = unk1; - while (_scriptInterpreter->validScript(&state)) - _scriptInterpreter->runScript(&state); + while (_emc->isValid(&state)) + _emc->run(&state); - _scriptInterpreter->unloadScript(&data); + _emc->unload(&data); } -void KyraEngine_v3::openTalkFile(int file) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::openTalkFile(%d)", file); +void KyraEngine_MR::openTalkFile(int file) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::openTalkFile(%d)", file); char talkFilename[16]; if (file == 0) { @@ -731,27 +771,8 @@ void KyraEngine_v3::openTalkFile(int file) { #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); +void KyraEngine_MR::loadCharacterShapes(int newShapes) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::loadCharacterShapes(%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 }; @@ -785,81 +806,34 @@ void KyraEngine_v3::loadMalcolmShapes(int newShapes) { filename[numberOffset[i]+1] = lowNum; _res->exists(filename, true); _res->loadFileToBuf(filename, _screenBuffer, 64000); - for (int j = startShape[i]; j < endShape[i]; ++j) { + for (int j = startShape[i]; j <= endShape[i]; ++j) { if (j == 87) continue; addShapeToPool(_screenBuffer, j, j-startShape[i]); } } - _malcolmShapes = newShapes; + _characterShapeFile = 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; +void KyraEngine_MR::updateMalcolmShapes() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::updateMalcolmShapes()"); + assert(_characterShapeFile >= 0 && _characterShapeFile < _shapeDescsSize); + _malcolmShapeXOffset = _shapeDescs[_characterShapeFile].xOffset; + _malcolmShapeYOffset = _shapeDescs[_characterShapeFile].yOffset; + _animObjects[0].width = _shapeDescs[_characterShapeFile].width; + _animObjects[0].height = _shapeDescs[_characterShapeFile].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_MR::getCharacterWalkspeed() const { + return _mainCharacter.walkspeed; } -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); +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; @@ -914,10 +888,10 @@ void KyraEngine_v3::updateCharAnimFrame(int character, int *table) { updateCharacterAnim(0); } -void KyraEngine_v3::updateCharPal(int unk1) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::updateCharPal(%d)", unk1); +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; + const uint8 *src = _costPalBuffer + _characterShapeFile * 72; uint8 *dst = _screen->getPalette(0) + 432; const int8 *sceneDatPal = &_sceneDatPalette[layer * 3]; @@ -949,7 +923,7 @@ void KyraEngine_v3::updateCharPal(int unk1) { ++dst; ++sceneDatPal; ++j; - if (j > 3) { + if (j >= 3) { sceneDatPal = &_sceneDatPalette[layer * 3]; j = 0; } @@ -960,8 +934,8 @@ void KyraEngine_v3::updateCharPal(int unk1) { } } -bool KyraEngine_v3::checkCharCollision(int x, int y) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::checkCharCollision(%d, %d)", x, y); +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; @@ -979,17 +953,25 @@ bool KyraEngine_v3::checkCharCollision(int x, int y) { #pragma mark - -void KyraEngine_v3::runLoop() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::runLoop()"); +void KyraEngine_MR::runLoop() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::runLoop()"); + + _eventList.clear(); _runFlag = true; while (_runFlag && !_quitFlag) { - //XXX deathHandler + if (_deathHandler >= 0) { + removeHandItem(); + delay(5); + _drawNoShapeFlag = 0; + _gui->optionsButton(0); + _deathHandler = -1; + } if (_system->getMillis() >= _nextIdleAnim) showIdleAnim(); - int inputFlag = checkInput(0/*_mainButtonList*/); + int inputFlag = checkInput(_mainButtonList, true); removeInputTop(); update(); @@ -1005,8 +987,8 @@ void KyraEngine_v3::runLoop() { } } -void KyraEngine_v3::handleInput(int x, int y) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::handleInput(%d, %d)", x, y); +void KyraEngine_MR::handleInput(int x, int y) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::handleInput(%d, %d)", x, y); if (_inventoryState) return; setNextIdleAnimTimer(); @@ -1020,7 +1002,7 @@ void KyraEngine_v3::handleInput(int x, int y) { return; if (_unk3 == -3) { - playSoundEffect(0x0D, 0x80); + snd_playSoundEffect(0x0D, 0x80); return; } @@ -1078,8 +1060,8 @@ void KyraEngine_v3::handleInput(int x, int y) { 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); +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; @@ -1121,17 +1103,17 @@ int KyraEngine_v3::inputSceneChange(int x, int y, int unk1, int unk2) { x &= ~3; y &= ~1; - int size = findWay(x1, y1, x, y, _moveFacingTable, 600); + int size = findWay(x1, y1, x, y, _movFacingTable, 600); _pathfinderFlag = 0; if (!size || size == 0x7D00) return 0; - return trySceneChange(_moveFacingTable, unk1, unk2); + return trySceneChange(_movFacingTable, unk1, unk2); } -void KyraEngine_v3::update() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::update()"); +void KyraEngine_MR::update() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::update()"); updateInput(); musicUpdate(0); @@ -1146,8 +1128,8 @@ void KyraEngine_v3::update() { _screen->updateScreen(); } -void KyraEngine_v3::updateWithText() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::update()"); +void KyraEngine_MR::updateWithText() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::update()"); updateInput(); musicUpdate(0); @@ -1155,7 +1137,6 @@ void KyraEngine_v3::updateWithText() { //XXX updateSpecialSceneScripts(); updateCommandLine(); - //XXX musicUpdate(0); restorePage3(); @@ -1171,8 +1152,8 @@ void KyraEngine_v3::updateWithText() { _screen->updateScreen(); } -void KyraEngine_v3::updateMouse() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::updateMouse()"); +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; @@ -1290,8 +1271,8 @@ void KyraEngine_v3::updateMouse() { } } -void KyraEngine_v3::delay(uint32 millis, bool doUpdate, bool isMainLoop) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::delay(%d, %d, %d)", millis, doUpdate, isMainLoop); +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) { @@ -1305,133 +1286,8 @@ void KyraEngine_v3::delay(uint32 millis, bool doUpdate, bool isMainLoop) { #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<Event>::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<Event>::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()"); +void KyraEngine_MR::makeCharFacingMouse() { + debugC(9, kDebugLevelAnimator, "KyraEngine_MR::makeCharFacingMouse()"); if (_mainCharacter.x1 > _mouseX) _mainCharacter.facing = 5; else @@ -1443,34 +1299,34 @@ void KyraEngine_v3::makeCharFacingMouse() { #pragma mark - -int KyraEngine_v3::getDrawLayer(int x, int y) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::getDrawLayer(%d, %d)", x, y); +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_v3::getScale(int x, int y) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::getScale(%d, %d)", x, y); +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_v3::backUpGfxRect32x32(int x, int y) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::backUpGfxRect32x32(%d, %d)", x, y); +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_v3::restoreGfxRect32x32(int x, int y) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::restoreGfxRect32x32(%d, %d)", x, y); +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_v3::appendLanguage(char *buf, int lang, int bufSize) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::appendLanguage([%p|'%s'], %d, %d)", (const void*)buf, buf, lang, bufSize); +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]); @@ -1488,8 +1344,11 @@ char *KyraEngine_v3::appendLanguage(char *buf, int lang, int bufSize) { return buf; } -int KyraEngine_v3::loadLanguageFile(const char *file, uint8 *&buffer) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::loadLanguageFile('%s', %p)", file, (const void*)buffer); +int KyraEngine_MR::loadLanguageFile(const char *file, uint8 *&buffer) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::loadLanguageFile('%s', %p)", file, (const void*)buffer); + + delete[] buffer; + buffer = 0; uint32 size = 0; char nBuf[32]; @@ -1499,8 +1358,8 @@ int KyraEngine_v3::loadLanguageFile(const char *file, uint8 *&buffer) { return buffer ? size : 0 ; } -uint8 *KyraEngine_v3::getTableEntry(uint8 *buffer, int id) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::getTableEntry(%p, %d)", (const void*)buffer, id); +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; @@ -1514,8 +1373,8 @@ uint8 *KyraEngine_v3::getTableEntry(uint8 *buffer, int id) { 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); +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(); @@ -1533,8 +1392,8 @@ void KyraEngine_v3::getTableEntry(Common::SeekableReadStream *stream, int id, ch #pragma mark - -bool KyraEngine_v3::talkObjectsInCurScene() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::talkObjectsInCurScene()"); +bool KyraEngine_MR::talkObjectsInCurScene() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::talkObjectsInCurScene()"); for (int i = 0; i < 88; ++i) { if (_talkObjectList[i].sceneId == _mainCharacter.sceneId) @@ -1546,60 +1405,142 @@ bool KyraEngine_v3::talkObjectsInCurScene() { #pragma mark - -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)); +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, ": "); - if (!_scriptInterpreter->loadScript(filename, &_temporaryScriptData, &_opcodesTemporary)) - error("Couldn't load temporary script '%s'", filename); + assert(scoreId < _scoreTableSize); - _scriptInterpreter->initScript(&_temporaryScriptState, &_temporaryScriptData); - _scriptInterpreter->startScript(&_temporaryScriptState, 0); + int count = _scoreTable[scoreId]; + if (count > 0) + scoreIncrease(count, _stringBuffer); - _newShapeFlag = -1; + _screen->showMouse(); + setNextIdleAnimTimer(); + return true; +} - if (_newShapeFiledata && newShapes) { - resetNewShapes(_newShapeCount, _newShapeFiledata); - _newShapeFiledata = 0; - _newShapeCount = 0; +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; } - while (_scriptInterpreter->validScript(&_temporaryScriptState)) - _scriptInterpreter->runScript(&_temporaryScriptState); + _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) + loadCharacterShapes(malcolmShapes); - uint8 *fileData = 0; + enterNewScene(sceneId, facing, 0, 0, 0); +} - if (newShapes) - _newShapeFiledata = _res->fileData(_newShapeFilename, 0); +#pragma mark - - fileData = _newShapeFiledata; +bool KyraEngine_MR::skipFlag() const { + if (!_configSkip) + return false; + return KyraEngine_v2::skipFlag(); +} - if (!fileData) { - _scriptInterpreter->unloadScript(&_temporaryScriptData); +void KyraEngine_MR::resetSkipFlag(bool removeEvent) { + if (!_configSkip) { + if (removeEvent) + _eventList.clear(); return; } + KyraEngine_v2::resetSkipFlag(removeEvent); +} - if (newShapes) - _newShapeCount = initNewShapes(fileData); +#pragma mark - - processNewShapes(allowSkip, resetChar); +void KyraEngine_MR::registerDefaultSettings() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::registerDefaultSettings()"); + KyraEngine::registerDefaultSettings(); - if (shapeUnload) { - resetNewShapes(_newShapeCount, fileData); - _newShapeCount = 0; - _newShapeFiledata = 0; + // Most settings already have sensible defaults. This one, however, is + // specific to the Kyra engine. + ConfMan.registerDefault("walkspeed", 5); + ConfMan.registerDefault("studio_audience", true); + ConfMan.registerDefault("skip_support", true); +} + +void KyraEngine_MR::writeSettings() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::writeSettings()"); + switch (_lang) { + case 1: + _flags.lang = Common::FR_FRA; + break; + + case 2: + _flags.lang = Common::DE_DEU; + break; + + case 0: + default: + _flags.lang = Common::EN_ANY; + break; } - _scriptInterpreter->unloadScript(&_temporaryScriptData); + ConfMan.set("language", Common::getLanguageCode(_flags.lang)); + + ConfMan.setBool("studio_audience", _configStudio); + ConfMan.setBool("skip_support", _configSkip); + + KyraEngine::writeSettings(); } -#pragma mark - +void KyraEngine_MR::readSettings() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::readSettings()"); + KyraEngine::readSettings(); -Movie *KyraEngine_v3::createWSAMovie() { - WSAMovieV2 *movie = new WSAMovieV2(this, _screen); - assert(movie); - return movie; + _configStudio = ConfMan.getBool("studio_audience"); + _configSkip = ConfMan.getBool("skip_support"); } } // end of namespace Kyra diff --git a/engines/kyra/kyra_v3.h b/engines/kyra/kyra_mr.h index 440596cb58..3dba3ec8d9 100644 --- a/engines/kyra/kyra_v3.h +++ b/engines/kyra/kyra_mr.h @@ -26,9 +26,10 @@ #ifndef KYRA_KYRA_V3_H #define KYRA_KYRA_V3_H -#include "kyra/kyra.h" -#include "kyra/screen_v3.h" +#include "kyra/kyra_v2.h" +#include "kyra/screen_mr.h" #include "kyra/script.h" +#include "kyra/gui_mr.h" #include "common/hashmap.h" #include "common/list.h" @@ -36,19 +37,22 @@ namespace Kyra { class SoundDigital; -class Screen_v3; +class Screen_MR; class MainMenu; class WSAMovieV2; -class TextDisplayer_v3; +class TextDisplayer_MR; struct Button; -class KyraEngine_v3 : public KyraEngine { -friend class TextDisplayer_v3; +class KyraEngine_MR : public KyraEngine_v2 { +friend class TextDisplayer_MR; +friend class GUI_MR; public: - KyraEngine_v3(OSystem *system, const GameFlags &flags); - ~KyraEngine_v3(); + KyraEngine_MR(OSystem *system, const GameFlags &flags); + ~KyraEngine_MR(); Screen *screen() { return _screen; } + Screen_v2 *screen_v2() const { return _screen; } + GUI_v2 *gui_v2() const { return _gui; } SoundDigital *soundDigital() { return _soundDigital; } int language() const { return _lang; } @@ -56,9 +60,19 @@ public: void playVQA(const char *name); - virtual Movie *createWSAMovie(); private: - Screen_v3 *_screen; + static const EngineDesc _mrEngineDesc; + + // config + bool _configStudio; + bool _configSkip; + + void registerDefaultSettings(); + void writeSettings(); + void readSettings(); + + // -- + Screen_MR *_screen; SoundDigital *_soundDigital; int init(); @@ -69,13 +83,15 @@ private: void setupOpcodeTable(); + // input + bool skipFlag() const; + void resetSkipFlag(bool removeEvent = true); + // run - bool _runFlag; - int _deathHandler; + bool _menuDirectlyToLoad; void runLoop(); void handleInput(int x, int y); - bool _unkHandleSceneChangeFlag; int inputSceneChange(int x, int y, int unk1, int unk2); void update(); @@ -84,29 +100,6 @@ private: 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<Event> _eventList; - - bool skipFlag() const; - void resetSkipFlag(bool removeEvent = true); - // sound specific private: void playMenuAudioFile(); @@ -118,15 +111,13 @@ private: static const char *_soundList[]; static const int _soundListSize; - int _curMusicTrack; - - void playMusicTrack(int track, int force); + void snd_playWanderScoreViaMap(int track, int force); void stopMusicTrack(); int musicUpdate(int forceRestart); void fadeOutMusic(int ticks); - void playSoundEffect(int item, int volume); + void snd_playSoundEffect(int item, int volume); static const uint8 _sfxFileMap[]; static const int _sfxFileMapSize; @@ -143,12 +134,30 @@ private: int _curStudioSFX; void playStudioSFX(const char *str); - // main menu + // gui + GUI_MR *_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); + + void loadButtonShapes(); + int callbackButton1(Button *button); + int callbackButton2(Button *button); + int callbackButton3(Button *button); + + // -> main menu void initMainMenu(); void uninitMainMenu(); WSAMovieV2 *_menuAnim; - MainMenu *_menu; // timer void setupTimers(); @@ -164,10 +173,6 @@ private: 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: @@ -175,50 +180,18 @@ private: 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 restorePage3(); 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); @@ -236,9 +209,6 @@ private: bool _nextIdleType; void showIdleAnim(); - void addItemToAnimList(int item); - void deleteItemAnimEntry(int item); - // interface uint8 *_interface; uint8 *_interfaceCommandLine; @@ -266,6 +236,10 @@ private: 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[]; @@ -281,6 +255,7 @@ private: uint8 *_cCodeFile; uint8 *_scenesFile; uint8 *_itemFile; + uint8 *_optionsFile; uint8 *_actorFile; uint32 _actorFileSize; uint8 *_sceneStrings; @@ -291,27 +266,10 @@ private: // 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); @@ -326,6 +284,7 @@ private: static const uint8 _itemMagicTable[]; bool itemListMagic(int handItem, int itemSlot); + bool itemInventoryMagic(int handItem, int invSlot); static const uint8 _itemStringMap[]; static const uint _itemStringMapSize; @@ -338,26 +297,13 @@ private: int getItemCommandStringInv(uint16 item); // -> hand item - void setMouseCursor(uint16 item); - - void setHandItem(uint16 item); - void removeHandItem(); void setItemMouseCursor(); - - int _itemInHand; - int _handItemSet; + void setMouseCursor(uint16 item); // shapes - typedef Common::HashMap<int, uint8*> 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 loadCharacterShapes(int newShapes); void updateMalcolmShapes(); int _malcolmShapeXOffset, _malcolmShapeYOffset; @@ -370,49 +316,15 @@ private: 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; - 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); @@ -431,25 +343,11 @@ private: int runSceneScript2(); bool _noStartupChat; void runSceneScript4(int unk1); - void runSceneScript6(); void runSceneScript8(); int _sceneMinX, _sceneMaxX; int _maskPageMinY, _maskPageMaxY; - ScriptState _sceneScriptState; - ScriptData _sceneScriptData; - WSAMovieV2 *_wsaSlots[10]; - - bool _specialSceneScriptState[10]; - bool _specialSceneScriptStateBackup[10]; - ScriptState _sceneSpecialScripts[10]; - uint32 _sceneSpecialScriptsTimer[10]; - int _lastProcessedSceneScript; - bool _specialSceneScriptRunFlag; - - void updateSpecialSceneScripts(); - int trySceneChange(int *moveTable, int unk1, int unk2); int checkSceneChange(); @@ -469,42 +367,12 @@ private: 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; - uint32 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[]; - + int getCharacterWalkspeed() const; void updateCharAnimFrame(int character, int *table); int8 _characterAnimTable[2]; static const uint8 _characterFrameTable[]; - bool _overwriteSceneFacing; - void updateCharPal(int unk1); int _lastCharPalLayer; bool _charPalUpdate; @@ -515,6 +383,8 @@ private: void makeCharFacingMouse(); + int findFreeInventorySlot(); + // talk object struct TalkObject { char filename[13]; @@ -530,16 +400,6 @@ private: bool talkObjectsInCurScene(); // chat - int _vocHigh; - - const char *_chatText; - int _chatObject; - uint32 _chatEndTime; - int _chatVocHigh, _chatVocLow; - - ScriptData _chatScriptData; - ScriptState _chatScriptState; - int chatGetType(const char *text); int chatCalcDuration(const char *text); @@ -552,12 +412,16 @@ private: void badConscienceChat(const char *str, int vocHigh, int vocLow); void badConscienceChatWaitToFinish(); + void goodConscienceChat(const char *str, int vocHigh, int vocLow); + void goodConscienceChatWaitToFinish(); + void malcolmSceneStartupChat(); - bool _newSceneDlgState[40]; + byte _newSceneDlgState[40]; int8 _conversationState[30][30]; bool _chatAltFlag; - void setDlgIndex(uint16 index); + void setDlgIndex(int index); + void updateDlgIndex(); Common::SeekableReadStream *_cnvFile; Common::SeekableReadStream *_dlgBuffer; @@ -569,8 +433,8 @@ private: bool _isStartupDialog; void processDialog(int vocHighIndex, int vocHighBase, int funcNum); - ScriptData _dialogScriptData; - ScriptState _dialogScriptState; + EMCData _dialogScriptData; + EMCState _dialogScriptState; int _dialogSceneAnim; int _dialogSceneScript; int _dialogScriptFuncStart, _dialogScriptFuncProc, _dialogScriptFuncEnd; @@ -582,10 +446,10 @@ private: Common::Array<const Opcode *> _opcodesDialog; - int o3d_updateAnim(ScriptState *script); - int o3d_delay(ScriptState *script); + int o3d_updateAnim(EMCState *script); + int o3d_delay(EMCState *script); - void malcolmRandomChat(); + void randomSceneChat(); void runDialog(int dlgIndex, int funcNum); // conscience @@ -598,47 +462,33 @@ private: void showBadConscience(); void hideBadConscience(); - // special script code - bool _temporaryScriptExecBit; - bool _useFrameTable; - - Common::Array<const Opcode *> _opcodesTemporary; + bool _goodConscienceShown; + int _goodConscienceAnim; + bool _goodConsciencePosition; - int o3t_defineNewShapes(ScriptState *script); - int o3t_setCurrentFrame(ScriptState *script); + static const uint8 _goodConscienceFrameTable[]; - ScriptData _temporaryScriptData; - ScriptState _temporaryScriptState; + void showGoodConscience(); + void hideGoodConscience(); - void runTemporaryScript(const char *filename, int allowSkip, int resetChar, int newShapes, int shapeUnload); + // special script code + bool _useFrameTable; + + int o3a_setCharacterFrame(EMCState *script); // 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); + int initAnimationShapes(uint8 *filedata); + void uninitAnimationShapes(int count, uint8 *filedata); // unk uint8 *_costPalBuffer; - uint8 *_screenBuffer; uint8 *_paletteOverlay; bool _useActorBuffer; - int _curChapter; - static const uint8 _chapterLowestScene[]; + int _currentChapter; + void changeChapter(int newChapter, int sceneId, int malcolmShapes, int facing); - int _unk3, _unk4, _unk5; + static const uint8 _chapterLowestScene[]; void loadCostPal(); void loadShadowShape(); @@ -650,82 +500,90 @@ private: 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(ScriptState *script); - int o3_setCharacterPos(ScriptState *script); - int o3_defineObject(ScriptState *script); - int o3_refreshCharacter(ScriptState *script); - int o3_getCharacterX(ScriptState *script); - int o3_getCharacterY(ScriptState *script); - int o3_getCharacterFacing(ScriptState *script); - int o3_getCharacterScene(ScriptState *script); - int o3_getMalcolmsMood(ScriptState *script); - int o3_trySceneChange(ScriptState *script); - int o3_moveCharacter(ScriptState *script); - int o3_setCharacterFacing(ScriptState *script); - int o3_showSceneFileMessage(ScriptState *script); - int o3_showBadConscience(ScriptState *script); - int o3_hideBadConscience(ScriptState *script); - int o3_objectChat(ScriptState *script); - int o3_checkForItem(ScriptState *script); - int o3_defineItem(ScriptState *script); - int o3_npcChatSequence(ScriptState *script); - int o3_queryGameFlag(ScriptState *script); - int o3_resetGameFlag(ScriptState *script); - int o3_setGameFlag(ScriptState *script); - int o3_setHandItem(ScriptState *script); - int o3_removeHandItem(ScriptState *script); - int o3_handItemSet(ScriptState *script); - int o3_hideMouse(ScriptState *script); - int o3_addSpecialExit(ScriptState *script); - int o3_setMousePos(ScriptState *script); - int o3_showMouse(ScriptState *script); - int o3_badConscienceChat(ScriptState *script); - int o3_wipeDownMouseItem(ScriptState *script); - int o3_setMalcolmsMood(ScriptState *script); - int o3_delay(ScriptState *script); - int o3_setSceneFilename(ScriptState *script); - int o3_drawSceneShape(ScriptState *script); - int o3_checkInRect(ScriptState *script); - int o3_updateConversations(ScriptState *script); - int o3_setSceneDim(ScriptState *script); - int o3_update(ScriptState *script); - int o3_enterNewScene(ScriptState *script); - int o3_setMalcolmPos(ScriptState *script); - int o3_stopMusic(ScriptState *script); - int o3_playMusicTrack(ScriptState *script); - int o3_playSoundEffect(ScriptState *script); - int o3_blockOutRegion(ScriptState *script); - int o3_getRand(ScriptState *script); - int o3_waitForConfirmationClick(ScriptState *script); - int o3_defineRoomEntrance(ScriptState *script); - int o3_runTemporaryScript(ScriptState *script); - int o3_setSpecialSceneScriptRunTime(ScriptState *script); - int o3_defineSceneAnim(ScriptState *script); - int o3_updateSceneAnim(ScriptState *script); - int o3_runActorScript(ScriptState *script); - int o3_runDialog(ScriptState *script); - int o3_malcolmRandomChat(ScriptState *script); - int o3_setDlgIndex(ScriptState *script); - int o3_getDlgIndex(ScriptState *script); - int o3_defineScene(ScriptState *script); - int o3_countItemInstances(ScriptState *script); - int o3_dialogStartScript(ScriptState *script); - int o3_dialogEndScript(ScriptState *script); - int o3_setSpecialSceneScriptState(ScriptState *script); - int o3_clearSpecialSceneScriptState(ScriptState *script); - int o3_querySpecialSceneScriptState(ScriptState *script); - int o3_setHiddenItemsEntry(ScriptState *script); - int o3_getHiddenItemsEntry(ScriptState *script); - int o3_setupSceneAnimObject(ScriptState *script); - int o3_removeSceneAnimObject(ScriptState *script); - int o3_setVocHigh(ScriptState *script); - int o3_getVocHigh(ScriptState *script); - int o3_dummy(ScriptState *script); + int o3_getMalcolmShapes(EMCState *script); + int o3_setCharacterPos(EMCState *script); + int o3_defineObject(EMCState *script); + int o3_refreshCharacter(EMCState *script); + int o3_getMalcolmsMood(EMCState *script); + int o3_getCharacterFrameFromFacing(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_resetInventory(EMCState *script); + int o3_removeInventoryItemInstances(EMCState *script); + int o3_countInventoryItemInstances(EMCState *script); + int o3_npcChatSequence(EMCState *script); + int o3_badConscienceChat(EMCState *script); + int o3_wipeDownMouseItem(EMCState *script); + int o3_setMalcolmsMood(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_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_setMalcolmPos(EMCState *script); + int o3_stopMusic(EMCState *script); + int o3_playSoundEffect(EMCState *script); + int o3_getScore(EMCState *script); + int o3_daggerWarning(EMCState *script); + int o3_blockOutRegion(EMCState *script); + int o3_showSceneStringsMessage(EMCState *script); + int o3_showGoodConscience(EMCState *script); + int o3_goodConscienceChat(EMCState *script); + int o3_hideGoodConscience(EMCState *script); + int o3_defineSceneAnim(EMCState *script); + int o3_updateSceneAnim(EMCState *script); + int o3_runActorScript(EMCState *script); + int o3_runDialog(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_customChat(EMCState *script); + int o3_customChatFinish(EMCState *script); + int o3_setupSceneAnimObject(EMCState *script); + int o3_removeSceneAnimObject(EMCState *script); + int o3_dummy(EMCState *script); // misc - TextDisplayer_v3 *_text; - bool _wsaPlayingVQA; + TextDisplayer_MR *_text; + bool _wasPlayingVQA; // resource specific private: diff --git a/engines/kyra/kyra_v1.cpp b/engines/kyra/kyra_v1.cpp index 90e62895d0..e9bb25fe5f 100644 --- a/engines/kyra/kyra_v1.cpp +++ b/engines/kyra/kyra_v1.cpp @@ -49,7 +49,6 @@ namespace Kyra { KyraEngine_v1::KyraEngine_v1(OSystem *system, const GameFlags &flags) : KyraEngine(system, flags) { _skipFlag = false; - _flags = flags; _seq_Forest = _seq_KallakWriting = _seq_KyrandiaLogo = _seq_KallakMalcolm = _seq_MalcolmTree = _seq_WestwoodLogo = _seq_Demo1 = _seq_Demo2 = _seq_Demo3 = @@ -82,10 +81,6 @@ KyraEngine_v1::KyraEngine_v1(OSystem *system, const GameFlags &flags) _sprites = 0; _animator = 0; _seq = 0; - _npcScriptData = 0; - _scriptMain = 0; - _scriptClickData = 0; - _scriptClick = 0; _characterList = 0; _movFacingTable = 0; _buttonData = 0; @@ -95,7 +90,6 @@ KyraEngine_v1::KyraEngine_v1(OSystem *system, const GameFlags &flags) _finalA = _finalB = _finalC = 0; _endSequenceBackUpRect = 0; memset(_panPagesTable, 0, sizeof(_panPagesTable)); - _npcScriptData = _scriptClickData = 0; memset(_sceneAnimTable, 0, sizeof(_sceneAnimTable)); _currHeadShape = 0; @@ -111,9 +105,9 @@ KyraEngine_v1::~KyraEngine_v1() { } closeFinalWsa(); - if (_scriptInterpreter) { - _scriptInterpreter->unloadScript(_npcScriptData); - _scriptInterpreter->unloadScript(_scriptClickData); + if (_emc) { + _emc->unload(&_npcScriptData); + _emc->unload(&_scriptClickData); } Common::clearAllSpecialDebugLevels(); @@ -124,12 +118,6 @@ KyraEngine_v1::~KyraEngine_v1() { delete _animator; delete _seq; - delete _npcScriptData; - delete _scriptMain; - - delete _scriptClickData; - delete _scriptClick; - delete [] _characterList; delete [] _movFacingTable; @@ -168,13 +156,15 @@ KyraEngine_v1::~KyraEngine_v1() { int KyraEngine_v1::init() { _screen = new Screen_v1(this, _system); assert(_screen); + _screen->setResolution(); + KyraEngine::init(); _sprites = new Sprites(this, _system); assert(_sprites); _seq = new SeqPlayer(this, _system); assert(_seq); - _animator = new ScreenAnimator(this, _system); + _animator = new Animator_v1(this, _system); assert(_animator); _animator->init(5, 11, 12); assert(*_animator); @@ -211,23 +201,12 @@ int KyraEngine_v1::init() { _characterList[0].facing = 3; _characterList[0].currentAnimFrame = 7; - _npcScriptData = new ScriptData; - memset(_npcScriptData, 0, sizeof(ScriptData)); - assert(_npcScriptData); - _npcScript = new ScriptState; - assert(_npcScript); - memset(_npcScript, 0, sizeof(ScriptState)); - - _scriptMain = new ScriptState; - assert(_scriptMain); - memset(_scriptMain, 0, sizeof(ScriptState)); + memset(&_npcScriptData, 0, sizeof(EMCData)); + memset(&_scriptClickData, 0, sizeof(EMCData)); - _scriptClickData = new ScriptData; - assert(_scriptClickData); - memset(_scriptClickData, 0, sizeof(ScriptData)); - _scriptClick = new ScriptState; - assert(_scriptClick); - memset(_scriptClick, 0, sizeof(ScriptState)); + memset(&_npcScript, 0, sizeof(EMCState)); + memset(&_scriptMain, 0, sizeof(EMCState)); + memset(&_scriptClick, 0, sizeof(EMCState)); _debugger = new Debugger_v1(this); assert(_debugger); @@ -386,19 +365,19 @@ void KyraEngine_v1::startup() { _animator->initAnimStateList(); setCharactersInDefaultScene(); - if (!_scriptInterpreter->loadScript("_STARTUP.EMC", _npcScriptData, &_opcodes)) + if (!_emc->load("_STARTUP.EMC", &_npcScriptData, &_opcodes)) error("Could not load \"_STARTUP.EMC\" script"); - _scriptInterpreter->initScript(_scriptMain, _npcScriptData); + _emc->init(&_scriptMain, &_npcScriptData); - if (!_scriptInterpreter->startScript(_scriptMain, 0)) + if (!_emc->start(&_scriptMain, 0)) error("Could not start script function 0 of script \"_STARTUP.EMC\""); - while (_scriptInterpreter->validScript(_scriptMain)) - _scriptInterpreter->runScript(_scriptMain); + while (_emc->isValid(&_scriptMain)) + _emc->run(&_scriptMain); - _scriptInterpreter->unloadScript(_npcScriptData); + _emc->unload(&_npcScriptData); - if (!_scriptInterpreter->loadScript("_NPC.EMC", _npcScriptData, &_opcodes)) + if (!_emc->load("_NPC.EMC", &_npcScriptData, &_opcodes)) error("Could not load \"_NPC.EMC\" script"); snd_playTheme(1, -1); @@ -784,17 +763,17 @@ int KyraEngine_v1::processInputHelper(int xpos, int ypos) { int KyraEngine_v1::clickEventHandler(int xpos, int ypos) { debugC(9, kDebugLevelMain, "KyraEngine_v1::clickEventHandler(%d, %d)", xpos, ypos); - _scriptInterpreter->initScript(_scriptClick, _scriptClickData); - _scriptClick->regs[1] = xpos; - _scriptClick->regs[2] = ypos; - _scriptClick->regs[3] = 0; - _scriptClick->regs[4] = _itemInHand; - _scriptInterpreter->startScript(_scriptClick, 1); + _emc->init(&_scriptClick, &_scriptClickData); + _scriptClick.regs[1] = xpos; + _scriptClick.regs[2] = ypos; + _scriptClick.regs[3] = 0; + _scriptClick.regs[4] = _itemInHand; + _emc->start(&_scriptClick, 1); - while (_scriptInterpreter->validScript(_scriptClick)) - _scriptInterpreter->runScript(_scriptClick); + while (_emc->isValid(&_scriptClick)) + _emc->run(&_scriptClick); - return _scriptClick->regs[3]; + return _scriptClick.regs[3]; } void KyraEngine_v1::updateMousePointer(bool forceUpdate) { @@ -928,15 +907,15 @@ void KyraEngine_v1::clickEventHandler2() { Common::Point mouse = getMousePos(); - _scriptInterpreter->initScript(_scriptClick, _scriptClickData); - _scriptClick->regs[0] = _currentCharacter->sceneId; - _scriptClick->regs[1] = mouse.x; - _scriptClick->regs[2] = mouse.y; - _scriptClick->regs[4] = _itemInHand; - _scriptInterpreter->startScript(_scriptClick, 6); + _emc->init(&_scriptClick, &_scriptClickData); + _scriptClick.regs[0] = _currentCharacter->sceneId; + _scriptClick.regs[1] = mouse.x; + _scriptClick.regs[2] = mouse.y; + _scriptClick.regs[4] = _itemInHand; + _emc->start(&_scriptClick, 6); - while (_scriptInterpreter->validScript(_scriptClick)) - _scriptInterpreter->runScript(_scriptClick); + while (_emc->isValid(&_scriptClick)) + _emc->run(&_scriptClick); } int KyraEngine_v1::checkForNPCScriptRun(int xpos, int ypos) { @@ -990,14 +969,14 @@ int KyraEngine_v1::checkForNPCScriptRun(int xpos, int ypos) { void KyraEngine_v1::runNpcScript(int func) { debugC(9, kDebugLevelMain, "KyraEngine_v1::runNpcScript(%d)", func); - _scriptInterpreter->initScript(_npcScript, _npcScriptData); - _scriptInterpreter->startScript(_npcScript, func); - _npcScript->regs[0] = _currentCharacter->sceneId; - _npcScript->regs[4] = _itemInHand; - _npcScript->regs[5] = func; - - while (_scriptInterpreter->validScript(_npcScript)) - _scriptInterpreter->runScript(_npcScript); + _emc->init(&_npcScript, &_npcScriptData); + _emc->start(&_npcScript, func); + _npcScript.regs[0] = _currentCharacter->sceneId; + _npcScript.regs[4] = _itemInHand; + _npcScript.regs[5] = func; + + while (_emc->isValid(&_npcScript)) + _emc->run(&_npcScript); } void KyraEngine_v1::checkAmuletAnimFlags() { diff --git a/engines/kyra/kyra_v1.h b/engines/kyra/kyra_v1.h index 3fa089e0d5..50791c3ade 100644 --- a/engines/kyra/kyra_v1.h +++ b/engines/kyra/kyra_v1.h @@ -38,7 +38,7 @@ class SoundDigital; class SeqPlayer; class Sprites; class Debugger; -class ScreenAnimator; +class Animator_v1; class TextDisplayer; class KyraEngine_v1; @@ -108,14 +108,14 @@ struct BeadState { class KyraEngine_v1 : public KyraEngine { friend class MusicPlayer; friend class Debugger_v1; - friend class ScreenAnimator; + friend class Animator_v1; friend class GUI_v1; public: KyraEngine_v1(OSystem *system, const GameFlags &flags); ~KyraEngine_v1(); Screen *screen() { return _screen; } - ScreenAnimator *animator() { return _animator; } + Animator_v1 *animator() { return _animator; } virtual Movie *createWSAMovie(); uint8 **shapes() { return _shapes; } @@ -202,7 +202,7 @@ public: void readSettings(); void writeSettings(); - void snd_playSoundEffect(int track); + void snd_playSoundEffect(int track, int volume=0xFF); void snd_playWanderScoreViaMap(int command, int restart); virtual void snd_playVoiceFile(int id); void snd_voiceWaitForFinish(bool ingame = true); @@ -476,19 +476,19 @@ protected: uint8 _configTextspeed; - ScreenAnimator *_animator; + Animator_v1 *_animator; SeqPlayer *_seq; Sprites *_sprites; Screen_v1 *_screen; Debugger *_debugger; - ScriptState *_scriptMain; + EMCState _scriptMain; - ScriptState *_npcScript; - ScriptData *_npcScriptData; + EMCState _npcScript; + EMCData _npcScriptData; - ScriptState *_scriptClick; - ScriptData *_scriptClickData; + EMCState _scriptClick; + EMCData _scriptClickData; Character *_characterList; Character *_currentCharacter; @@ -656,163 +656,163 @@ protected: void setupOpcodeTable(); // Opcodes - int o1_magicInMouseItem(ScriptState *script); - int o1_characterSays(ScriptState *script); - int o1_pauseTicks(ScriptState *script); - int o1_drawSceneAnimShape(ScriptState *script); - int o1_queryGameFlag(ScriptState *script); - int o1_setGameFlag(ScriptState *script); - int o1_resetGameFlag(ScriptState *script); - int o1_runNPCScript(ScriptState *script); - int o1_setSpecialExitList(ScriptState *script); - int o1_blockInWalkableRegion(ScriptState *script); - int o1_blockOutWalkableRegion(ScriptState *script); - int o1_walkPlayerToPoint(ScriptState *script); - int o1_dropItemInScene(ScriptState *script); - int o1_drawAnimShapeIntoScene(ScriptState *script); - int o1_createMouseItem(ScriptState *script); - int o1_savePageToDisk(ScriptState *script); - int o1_sceneAnimOn(ScriptState *script); - int o1_sceneAnimOff(ScriptState *script); - int o1_getElapsedSeconds(ScriptState *script); - int o1_mouseIsPointer(ScriptState *script); - int o1_destroyMouseItem(ScriptState *script); - int o1_runSceneAnimUntilDone(ScriptState *script); - int o1_fadeSpecialPalette(ScriptState *script); - int o1_playAdlibSound(ScriptState *script); - int o1_playAdlibScore(ScriptState *script); - int o1_phaseInSameScene(ScriptState *script); - int o1_setScenePhasingFlag(ScriptState *script); - int o1_resetScenePhasingFlag(ScriptState *script); - int o1_queryScenePhasingFlag(ScriptState *script); - int o1_sceneToDirection(ScriptState *script); - int o1_setBirthstoneGem(ScriptState *script); - int o1_placeItemInGenericMapScene(ScriptState *script); - int o1_setBrandonStatusBit(ScriptState *script); - int o1_pauseSeconds(ScriptState *script); - int o1_getCharactersLocation(ScriptState *script); - int o1_runNPCSubscript(ScriptState *script); - int o1_magicOutMouseItem(ScriptState *script); - int o1_internalAnimOn(ScriptState *script); - int o1_forceBrandonToNormal(ScriptState *script); - int o1_poisonDeathNow(ScriptState *script); - int o1_setScaleMode(ScriptState *script); - int o1_openWSAFile(ScriptState *script); - int o1_closeWSAFile(ScriptState *script); - int o1_runWSAFromBeginningToEnd(ScriptState *script); - int o1_displayWSAFrame(ScriptState *script); - int o1_enterNewScene(ScriptState *script); - int o1_setSpecialEnterXAndY(ScriptState *script); - int o1_runWSAFrames(ScriptState *script); - int o1_popBrandonIntoScene(ScriptState *script); - int o1_restoreAllObjectBackgrounds(ScriptState *script); - int o1_setCustomPaletteRange(ScriptState *script); - int o1_loadPageFromDisk(ScriptState *script); - int o1_customPrintTalkString(ScriptState *script); - int o1_restoreCustomPrintBackground(ScriptState *script); - int o1_hideMouse(ScriptState *script); - int o1_showMouse(ScriptState *script); - int o1_getCharacterX(ScriptState *script); - int o1_getCharacterY(ScriptState *script); - int o1_changeCharactersFacing(ScriptState *script); - int o1_copyWSARegion(ScriptState *script); - int o1_printText(ScriptState *script); - int o1_random(ScriptState *script); - int o1_loadSoundFile(ScriptState *script); - int o1_displayWSAFrameOnHidPage(ScriptState *script); - int o1_displayWSASequentialFrames(ScriptState *script); - int o1_drawCharacterStanding(ScriptState *script); - int o1_internalAnimOff(ScriptState *script); - int o1_changeCharactersXAndY(ScriptState *script); - int o1_clearSceneAnimatorBeacon(ScriptState *script); - int o1_querySceneAnimatorBeacon(ScriptState *script); - int o1_refreshSceneAnimator(ScriptState *script); - int o1_placeItemInOffScene(ScriptState *script); - int o1_wipeDownMouseItem(ScriptState *script); - int o1_placeCharacterInOtherScene(ScriptState *script); - int o1_getKey(ScriptState *script); - int o1_specificItemInInventory(ScriptState *script); - int o1_popMobileNPCIntoScene(ScriptState *script); - int o1_mobileCharacterInScene(ScriptState *script); - int o1_hideMobileCharacter(ScriptState *script); - int o1_unhideMobileCharacter(ScriptState *script); - int o1_setCharactersLocation(ScriptState *script); - int o1_walkCharacterToPoint(ScriptState *script); - int o1_specialEventDisplayBrynnsNote(ScriptState *script); - int o1_specialEventRemoveBrynnsNote(ScriptState *script); - int o1_setLogicPage(ScriptState *script); - int o1_fatPrint(ScriptState *script); - int o1_preserveAllObjectBackgrounds(ScriptState *script); - int o1_updateSceneAnimations(ScriptState *script); - int o1_sceneAnimationActive(ScriptState *script); - int o1_setCharactersMovementDelay(ScriptState *script); - int o1_getCharactersFacing(ScriptState *script); - int o1_bkgdScrollSceneAndMasksRight(ScriptState *script); - int o1_dispelMagicAnimation(ScriptState *script); - int o1_findBrightestFireberry(ScriptState *script); - int o1_setFireberryGlowPalette(ScriptState *script); - int o1_setDeathHandlerFlag(ScriptState *script); - int o1_drinkPotionAnimation(ScriptState *script); - int o1_makeAmuletAppear(ScriptState *script); - int o1_drawItemShapeIntoScene(ScriptState *script); - int o1_setCharactersCurrentFrame(ScriptState *script); - int o1_waitForConfirmationMouseClick(ScriptState *script); - int o1_pageFlip(ScriptState *script); - int o1_setSceneFile(ScriptState *script); - int o1_getItemInMarbleVase(ScriptState *script); - int o1_setItemInMarbleVase(ScriptState *script); - int o1_addItemToInventory(ScriptState *script); - int o1_intPrint(ScriptState *script); - int o1_shakeScreen(ScriptState *script); - int o1_createAmuletJewel(ScriptState *script); - int o1_setSceneAnimCurrXY(ScriptState *script); - int o1_poisonBrandonAndRemaps(ScriptState *script); - int o1_fillFlaskWithWater(ScriptState *script); - int o1_getCharactersMovementDelay(ScriptState *script); - int o1_getBirthstoneGem(ScriptState *script); - int o1_queryBrandonStatusBit(ScriptState *script); - int o1_playFluteAnimation(ScriptState *script); - int o1_playWinterScrollSequence(ScriptState *script); - int o1_getIdolGem(ScriptState *script); - int o1_setIdolGem(ScriptState *script); - int o1_totalItemsInScene(ScriptState *script); - int o1_restoreBrandonsMovementDelay(ScriptState *script); - int o1_setMousePos(ScriptState *script); - int o1_getMouseState(ScriptState *script); - int o1_setEntranceMouseCursorTrack(ScriptState *script); - int o1_itemAppearsOnGround(ScriptState *script); - int o1_setNoDrawShapesFlag(ScriptState *script); - int o1_fadeEntirePalette(ScriptState *script); - int o1_itemOnGroundHere(ScriptState *script); - int o1_queryCauldronState(ScriptState *script); - int o1_setCauldronState(ScriptState *script); - int o1_queryCrystalState(ScriptState *script); - int o1_setCrystalState(ScriptState *script); - int o1_setPaletteRange(ScriptState *script); - int o1_shrinkBrandonDown(ScriptState *script); - int o1_growBrandonUp(ScriptState *script); - int o1_setBrandonScaleXAndY(ScriptState *script); - int o1_resetScaleMode(ScriptState *script); - int o1_getScaleDepthTableValue(ScriptState *script); - int o1_setScaleDepthTableValue(ScriptState *script); - int o1_message(ScriptState *script); - int o1_checkClickOnNPC(ScriptState *script); - int o1_getFoyerItem(ScriptState *script); - int o1_setFoyerItem(ScriptState *script); - int o1_setNoItemDropRegion(ScriptState *script); - int o1_walkMalcolmOn(ScriptState *script); - int o1_passiveProtection(ScriptState *script); - int o1_setPlayingLoop(ScriptState *script); - int o1_brandonToStoneSequence(ScriptState *script); - int o1_brandonHealingSequence(ScriptState *script); - int o1_protectCommandLine(ScriptState *script); - int o1_pauseMusicSeconds(ScriptState *script); - int o1_resetMaskRegion(ScriptState *script); - int o1_setPaletteChangeFlag(ScriptState *script); - int o1_fillRect(ScriptState *script); - int o1_dummy(ScriptState *script); - int o1_vocUnload(ScriptState *script); - int o1_vocLoad(ScriptState *script); + int o1_magicInMouseItem(EMCState *script); + int o1_characterSays(EMCState *script); + int o1_pauseTicks(EMCState *script); + int o1_drawSceneAnimShape(EMCState *script); + int o1_queryGameFlag(EMCState *script); + int o1_setGameFlag(EMCState *script); + int o1_resetGameFlag(EMCState *script); + int o1_runNPCScript(EMCState *script); + int o1_setSpecialExitList(EMCState *script); + int o1_blockInWalkableRegion(EMCState *script); + int o1_blockOutWalkableRegion(EMCState *script); + int o1_walkPlayerToPoint(EMCState *script); + int o1_dropItemInScene(EMCState *script); + int o1_drawAnimShapeIntoScene(EMCState *script); + int o1_createMouseItem(EMCState *script); + int o1_savePageToDisk(EMCState *script); + int o1_sceneAnimOn(EMCState *script); + int o1_sceneAnimOff(EMCState *script); + int o1_getElapsedSeconds(EMCState *script); + int o1_mouseIsPointer(EMCState *script); + int o1_destroyMouseItem(EMCState *script); + int o1_runSceneAnimUntilDone(EMCState *script); + int o1_fadeSpecialPalette(EMCState *script); + int o1_playAdlibSound(EMCState *script); + int o1_playAdlibScore(EMCState *script); + int o1_phaseInSameScene(EMCState *script); + int o1_setScenePhasingFlag(EMCState *script); + int o1_resetScenePhasingFlag(EMCState *script); + int o1_queryScenePhasingFlag(EMCState *script); + int o1_sceneToDirection(EMCState *script); + int o1_setBirthstoneGem(EMCState *script); + int o1_placeItemInGenericMapScene(EMCState *script); + int o1_setBrandonStatusBit(EMCState *script); + int o1_pauseSeconds(EMCState *script); + int o1_getCharactersLocation(EMCState *script); + int o1_runNPCSubscript(EMCState *script); + int o1_magicOutMouseItem(EMCState *script); + int o1_internalAnimOn(EMCState *script); + int o1_forceBrandonToNormal(EMCState *script); + int o1_poisonDeathNow(EMCState *script); + int o1_setScaleMode(EMCState *script); + int o1_openWSAFile(EMCState *script); + int o1_closeWSAFile(EMCState *script); + int o1_runWSAFromBeginningToEnd(EMCState *script); + int o1_displayWSAFrame(EMCState *script); + int o1_enterNewScene(EMCState *script); + int o1_setSpecialEnterXAndY(EMCState *script); + int o1_runWSAFrames(EMCState *script); + int o1_popBrandonIntoScene(EMCState *script); + int o1_restoreAllObjectBackgrounds(EMCState *script); + int o1_setCustomPaletteRange(EMCState *script); + int o1_loadPageFromDisk(EMCState *script); + int o1_customPrintTalkString(EMCState *script); + int o1_restoreCustomPrintBackground(EMCState *script); + int o1_hideMouse(EMCState *script); + int o1_showMouse(EMCState *script); + int o1_getCharacterX(EMCState *script); + int o1_getCharacterY(EMCState *script); + int o1_changeCharactersFacing(EMCState *script); + int o1_copyWSARegion(EMCState *script); + int o1_printText(EMCState *script); + int o1_random(EMCState *script); + int o1_loadSoundFile(EMCState *script); + int o1_displayWSAFrameOnHidPage(EMCState *script); + int o1_displayWSASequentialFrames(EMCState *script); + int o1_drawCharacterStanding(EMCState *script); + int o1_internalAnimOff(EMCState *script); + int o1_changeCharactersXAndY(EMCState *script); + int o1_clearSceneAnimatorBeacon(EMCState *script); + int o1_querySceneAnimatorBeacon(EMCState *script); + int o1_refreshSceneAnimator(EMCState *script); + int o1_placeItemInOffScene(EMCState *script); + int o1_wipeDownMouseItem(EMCState *script); + int o1_placeCharacterInOtherScene(EMCState *script); + int o1_getKey(EMCState *script); + int o1_specificItemInInventory(EMCState *script); + int o1_popMobileNPCIntoScene(EMCState *script); + int o1_mobileCharacterInScene(EMCState *script); + int o1_hideMobileCharacter(EMCState *script); + int o1_unhideMobileCharacter(EMCState *script); + int o1_setCharactersLocation(EMCState *script); + int o1_walkCharacterToPoint(EMCState *script); + int o1_specialEventDisplayBrynnsNote(EMCState *script); + int o1_specialEventRemoveBrynnsNote(EMCState *script); + int o1_setLogicPage(EMCState *script); + int o1_fatPrint(EMCState *script); + int o1_preserveAllObjectBackgrounds(EMCState *script); + int o1_updateSceneAnimations(EMCState *script); + int o1_sceneAnimationActive(EMCState *script); + int o1_setCharactersMovementDelay(EMCState *script); + int o1_getCharactersFacing(EMCState *script); + int o1_bkgdScrollSceneAndMasksRight(EMCState *script); + int o1_dispelMagicAnimation(EMCState *script); + int o1_findBrightestFireberry(EMCState *script); + int o1_setFireberryGlowPalette(EMCState *script); + int o1_setDeathHandlerFlag(EMCState *script); + int o1_drinkPotionAnimation(EMCState *script); + int o1_makeAmuletAppear(EMCState *script); + int o1_drawItemShapeIntoScene(EMCState *script); + int o1_setCharactersCurrentFrame(EMCState *script); + int o1_waitForConfirmationMouseClick(EMCState *script); + int o1_pageFlip(EMCState *script); + int o1_setSceneFile(EMCState *script); + int o1_getItemInMarbleVase(EMCState *script); + int o1_setItemInMarbleVase(EMCState *script); + int o1_addItemToInventory(EMCState *script); + int o1_intPrint(EMCState *script); + int o1_shakeScreen(EMCState *script); + int o1_createAmuletJewel(EMCState *script); + int o1_setSceneAnimCurrXY(EMCState *script); + int o1_poisonBrandonAndRemaps(EMCState *script); + int o1_fillFlaskWithWater(EMCState *script); + int o1_getCharactersMovementDelay(EMCState *script); + int o1_getBirthstoneGem(EMCState *script); + int o1_queryBrandonStatusBit(EMCState *script); + int o1_playFluteAnimation(EMCState *script); + int o1_playWinterScrollSequence(EMCState *script); + int o1_getIdolGem(EMCState *script); + int o1_setIdolGem(EMCState *script); + int o1_totalItemsInScene(EMCState *script); + int o1_restoreBrandonsMovementDelay(EMCState *script); + int o1_setMousePos(EMCState *script); + int o1_getMouseState(EMCState *script); + int o1_setEntranceMouseCursorTrack(EMCState *script); + int o1_itemAppearsOnGround(EMCState *script); + int o1_setNoDrawShapesFlag(EMCState *script); + int o1_fadeEntirePalette(EMCState *script); + int o1_itemOnGroundHere(EMCState *script); + int o1_queryCauldronState(EMCState *script); + int o1_setCauldronState(EMCState *script); + int o1_queryCrystalState(EMCState *script); + int o1_setCrystalState(EMCState *script); + int o1_setPaletteRange(EMCState *script); + int o1_shrinkBrandonDown(EMCState *script); + int o1_growBrandonUp(EMCState *script); + int o1_setBrandonScaleXAndY(EMCState *script); + int o1_resetScaleMode(EMCState *script); + int o1_getScaleDepthTableValue(EMCState *script); + int o1_setScaleDepthTableValue(EMCState *script); + int o1_message(EMCState *script); + int o1_checkClickOnNPC(EMCState *script); + int o1_getFoyerItem(EMCState *script); + int o1_setFoyerItem(EMCState *script); + int o1_setNoItemDropRegion(EMCState *script); + int o1_walkMalcolmOn(EMCState *script); + int o1_passiveProtection(EMCState *script); + int o1_setPlayingLoop(EMCState *script); + int o1_brandonToStoneSequence(EMCState *script); + int o1_brandonHealingSequence(EMCState *script); + int o1_protectCommandLine(EMCState *script); + int o1_pauseMusicSeconds(EMCState *script); + int o1_resetMaskRegion(EMCState *script); + int o1_setPaletteChangeFlag(EMCState *script); + int o1_fillRect(EMCState *script); + int o1_dummy(EMCState *script); + int o1_vocUnload(EMCState *script); + int o1_vocLoad(EMCState *script); }; } // end of namespace Kyra diff --git a/engines/kyra/kyra_v2.cpp b/engines/kyra/kyra_v2.cpp index 56512eb030..176f8e4e2f 100644 --- a/engines/kyra/kyra_v2.cpp +++ b/engines/kyra/kyra_v2.cpp @@ -23,775 +23,74 @@ * */ -#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/screen_v2.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; +KyraEngine_v2::KyraEngine_v2(OSystem *system, const GameFlags &flags, const EngineDesc &desc) : KyraEngine(system, flags), _desc(desc) { + memset(&_sceneAnims, 0, sizeof(_sceneAnims)); + memset(&_sceneAnimMovie, 0, sizeof(_sceneAnimMovie)); - _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; + _itemList = 0; + _itemListSize = 0; - for (int i = 0; i < 15; i++) - memset(&_activeItemAnim[i], 0, sizeof(ActiveItemAnim)); + _characterShapeFile = -1; - _colorCodeFlag1 = 0; - _colorCodeFlag2 = -1; - _scriptCountDown = 0; - _dbgPass = 0; + _updateCharPosNextUpdate = 0; - _gamePlayBuffer = 0; - _unkBuf500Bytes = 0; - _screenBuffer = 0; - _inventorySaved = false; - _unkBuf200kByte = 0; - memset(&_defaultShapeTable, 0, sizeof(_defaultShapeTable)); - memset(&_sceneShapeTable, 0, sizeof(_sceneShapeTable)); + memset(&_sceneScriptState, 0, sizeof(_sceneScriptState)); 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); + _animObjects = 0; + _runFlag = true; + _showOutro = false; _deathHandler = -1; + _animNeedUpdate = false; - _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<const Opcode*>::iterator i = _opcodesTemporary.begin(); i != _opcodesTemporary.end(); ++i) - delete *i; - _opcodesTemporary.clear(); - - for (Common::Array<const TIMOpcode*>::iterator i = _timOpcodes.begin(); i != _timOpcodes.end(); ++i) - delete *i; - _timOpcodes.clear(); -} - -Movie *KyraEngine_v2::createWSAMovie() { - return new WSAMovieV2(this, _screen); -} - -int KyraEngine_v2::init() { - _screen = new Screen_v2(this, _system); - assert(_screen); - - 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; - } + _animShapeCount = 0; + _animShapeFiledata = 0; - // 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(); + _vocHigh = -1; + _chatVocHigh = -1; + _chatVocLow = -1; + _chatText = 0; + _chatObject = -1; - 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 { - _scriptInterpreter->initScript(&_sceneScriptState, &_sceneScriptData); - - _sceneScriptState.regs[1] = x; - _sceneScriptState.regs[2] = y; - _sceneScriptState.regs[3] = 0; - _sceneScriptState.regs[4] = _itemInHand; - - _scriptInterpreter->startScript(&_sceneScriptState, 1); - - while (_scriptInterpreter->validScript(&_sceneScriptState)) - _scriptInterpreter->runScript(&_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(); + _debugger = 0; + _screenBuffer = 0; } -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(); - } +KyraEngine_v2::~KyraEngine_v2() { + for (ShapeMap::iterator i = _gameShapes.begin(); i != _gameShapes.end(); ++i) { + delete[] i->_value; + i->_value = 0; } -} + _gameShapes.clear(); -void KyraEngine_v2::updateInput() { - Common::Event event; + delete[] _itemList; - while (_eventMan->pollEvent(event)) { - switch (event.type) { - case Common::EVENT_QUIT: - _quitFlag = true; - break; + _emc->unload(&_sceneScriptData); - 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; + delete[] _animObjects; - case Common::EVENT_LBUTTONUP: - case Common::EVENT_MOUSEMOVE: - _eventList.push_back(event); - break; + for (Common::Array<const Opcode*>::iterator i = _opcodesAnimation.begin(); i != _opcodesAnimation.end(); ++i) + delete *i; + _opcodesAnimation.clear(); - default: - break; - } - } + delete _debugger; + delete[] _screenBuffer; } int KyraEngine_v2::checkInput(Button *buttonList, bool mainLoop) { + debugC(9, kDebugLevelMain, "KyraEngine_v2::checkInput(%p, %d)", (const void*)buttonList, mainLoop); updateInput(); int keys = 0; @@ -825,7 +124,6 @@ int KyraEngine_v2::checkInput(Button *buttonList, bool mainLoop) { Common::Point pos = getMousePos(); _mouseX = pos.x; _mouseY = pos.y; - _screen->updateScreen(); } break; case Common::EVENT_LBUTTONDOWN: @@ -833,7 +131,7 @@ int KyraEngine_v2::checkInput(Button *buttonList, bool mainLoop) { Common::Point pos = getMousePos(); _mouseX = pos.x; _mouseY = pos.y; - keys = event.type == Common::EVENT_LBUTTONDOWN ? 199 : (200 | 0x800); + keys = (event.type == Common::EVENT_LBUTTONDOWN ? 199 : (200 | 0x800)); breakLoop = true; } break; @@ -850,7 +148,43 @@ int KyraEngine_v2::checkInput(Button *buttonList, bool mainLoop) { _eventList.erase(_eventList.begin()); } - return _gui->processButtonList(buttonList, keys | 0x8000); + return gui_v2()->processButtonList(buttonList, keys | 0x8000); +} + +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_MOUSEMOVE: + screen_v2()->updateScreen(); + // fall through + + case Common::EVENT_LBUTTONUP: + _eventList.push_back(event); + break; + + default: + break; + } + } } void KyraEngine_v2::removeInputTop() { @@ -878,625 +212,54 @@ void KyraEngine_v2::resetSkipFlag(bool removeEvent) { } } -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'; - - ScriptData scriptData; - ScriptState scriptState; - - _scriptInterpreter->loadScript(filename, &scriptData, &_opcodes); - _scriptInterpreter->initScript(&scriptState, &scriptData); - scriptState.regs[6] = unk1; - _scriptInterpreter->startScript(&scriptState, 0); - while (_scriptInterpreter->validScript(&scriptState)) - _scriptInterpreter->runScript(&scriptState); - _scriptInterpreter->unloadScript(&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; - }; - } - - _scriptInterpreter->loadScript(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 (!_scriptInterpreter->loadScript(filename, &_temporaryScriptData, &_opcodesTemporary)) - error("Couldn't load temporary script '%s'", filename); - - _scriptInterpreter->initScript(&_temporaryScriptState, &_temporaryScriptData); - _scriptInterpreter->startScript(&_temporaryScriptState, 0); - - _newShapeFlag = -1; - - if (_newShapeFiledata && newShapes) { - resetNewShapes(_newShapeCount, _newShapeFiledata); - _newShapeFiledata = 0; - _newShapeCount = 0; - } - - while (_scriptInterpreter->validScript(&_temporaryScriptState)) - _scriptInterpreter->runScript(&_temporaryScriptState); - - uint8 *fileData = 0; - - if (newShapes) - _newShapeFiledata = _res->fileData(_newShapeFilename, 0); - - fileData = _newShapeFiledata; - - if (!fileData) { - _scriptInterpreter->unloadScript(&_temporaryScriptData); - return; - } - - if (newShapes) - _newShapeCount = initNewShapes(fileData); - - processNewShapes(allowSkip, resetChar); - - if (shapeUnload) { - resetNewShapes(_newShapeCount, fileData); - _newShapeCount = 0; - _newShapeFiledata = 0; - } - - _scriptInterpreter->unloadScript(&_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); +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 false; + return true; } -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::addShapeToPool(const uint8 *data, int realIndex, int shape) { + debugC(9, kDebugLevelMain, "KyraEngine_v2::addShapeToPool(%p, %d, %d)", data, realIndex, shape); + remShapeFromPool(realIndex); + _gameShapes[realIndex] = screen_v2()->makeShapeCopy(data, shape); + assert(_gameShapes[realIndex]); } -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; +void KyraEngine_v2::addShapeToPool(uint8 *shpData, int index) { + debugC(9, kDebugLevelMain, "KyraEngine_v2::addShapeToPool(%p, %d)", shpData, index); + remShapeFromPool(index); + _gameShapes[index] = shpData; + assert(_gameShapes[index]); } -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); +void KyraEngine_v2::remShapeFromPool(int idx) { + ShapeMap::iterator iter = _gameShapes.find(idx); + if (iter != _gameShapes.end()) { + delete [] iter->_value; + iter->_value = 0; } - - 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) +uint8 *KyraEngine_v2::getShapePtr(int shape) const { + debugC(9, kDebugLevelMain, "KyraEngine_v2::getShapePtr(%d)", shape); + ShapeMap::iterator iter = _gameShapes.find(shape); + if (iter == _gameShapes.end()) return 0; - return 1; + return iter->_value; } void KyraEngine_v2::moveCharacter(int facing, int x, int y) { - _mainCharacter.facing = facing; + debugC(9, kDebugLevelMain, "KyraEngine_v2::moveCharacter(%d, %d, %d)", facing, x, y); x &= ~3; y &= ~1; + _mainCharacter.facing = facing; - _screen->hideMouse(); + Screen *scr = screen(); + scr->hideMouse(); switch (facing) { case 0: - while (y < _mainCharacter.y1) + while (_mainCharacter.y1 > y) updateCharPosWithUpdate(); break; @@ -1506,7 +269,7 @@ void KyraEngine_v2::moveCharacter(int facing, int x, int y) { break; case 4: - while (y > _mainCharacter.y1) + while (_mainCharacter.y1 < y) updateCharPosWithUpdate(); break; @@ -1518,815 +281,25 @@ void KyraEngine_v2::moveCharacter(int facing, int x, int y) { 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; + scr->showMouse(); } void KyraEngine_v2::updateCharPosWithUpdate() { - updateCharPos(0); + debugC(9, kDebugLevelMain, "KyraEngine_v2::updateCharPosWithUpdate()"); + updateCharPos(0, 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) +int KyraEngine_v2::updateCharPos(int *table, int force) { + debugC(9, kDebugLevelMain, "KyraEngine_v2::updateCharPos(%p, %d)", (const void*)table, force); + if (_updateCharPosNextUpdate > _system->getMillis() && !force) 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); - - _scriptInterpreter->initScript(&_temporaryScriptState, &_temporaryScriptData); - _scriptInterpreter->startScript(&_temporaryScriptState, 1); - - resetSkipFlag(); - - while (_scriptInterpreter->validScript(&_temporaryScriptState)) { - _temporaryScriptExecBit = false; - while (_scriptInterpreter->validScript(&_temporaryScriptState) && !_temporaryScriptExecBit) - _scriptInterpreter->runScript(&_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) { - debugC(9, kDebugLevelMain | kDebugLevelSound, "KyraEngine_v2::snd_playSoundEffect(%d)", track); - - 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). - // For now this is used as a fallback only (if no voc file exists). - 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(); + _mainCharacter.x1 += _updateCharPosXTable[_mainCharacter.facing]; + _mainCharacter.y1 += _updateCharPosYTable[_mainCharacter.facing]; + updateCharAnimFrame(0, table); + _updateCharPosNextUpdate = _system->getMillis() + getCharacterWalkspeed() * _tickLength; + return 1; } } // end of namespace Kyra - - - diff --git a/engines/kyra/kyra_v2.h b/engines/kyra/kyra_v2.h index 7a7aec803f..f0d26ca011 100644 --- a/engines/kyra/kyra_v2.h +++ b/engines/kyra/kyra_v2.h @@ -27,326 +27,63 @@ #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 "kyra/gui.h" +#include "kyra/wsamovie.h" #include "common/list.h" -#include "common/func.h" +#include "common/hashmap.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 Screen_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; } + struct EngineDesc { + // Generic shape related + const int itemShapeStart; + const uint8 *characterFrameTable; - virtual Movie *createWSAMovie(); -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; + // Scene script + const int firstAnimSceneScript; - uint8 *_mouseSHPBuf; + // Animation script specific + const int animScriptFrameAdd; + }; - static const int8 _dosTrackMap[]; - static const int _dosTrackMapSize; + KyraEngine_v2(OSystem *system, const GameFlags &flags, const EngineDesc &desc); + ~KyraEngine_v2(); - const AudioDataStruct *_soundData; + virtual Screen_v2 *screen_v2() const = 0; + virtual GUI *gui_v2() const = 0; + const EngineDesc &engineDesc() const { return _desc; } 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(); + EngineDesc _desc; + Debugger_v2 *_debugger; // run - MainMenu *_menu; - bool _runFlag; - bool _showCredits; - - void update(); - void updateWithText(); + bool _showOutro; + int8 _deathHandler; - Common::Functor0Mem<void, KyraEngine_v2> _updateFunctor; + virtual void update() = 0; + virtual void updateWithText() = 0; - void updateMouse(); + // MainMenu + MainMenu *_menu; - void dinoRide(); + // Input + virtual int inputSceneChange(int x, int y, int unk1, int unk2) = 0; + void updateInput(); 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; @@ -360,102 +97,16 @@ protected: }; Common::List<Event> _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]; - ScriptState _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]; + virtual bool skipFlag() const; + virtual void resetSkipFlag(bool removeEvent = true); - 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 + // Animator struct AnimObj { uint16 index; uint16 type; - uint16 enabled; + bool enabled; uint16 needRefresh; - uint16 unk8; + uint16 specialRefresh; uint16 animFlags; uint16 flags; int16 xPos1, yPos1; @@ -464,52 +115,60 @@ protected: 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; + uint16 palette; AnimObj *nextObject; }; - AnimObj _animObjects[42]; - void clearAnimObjects(); + void allocAnimObjects(int actors, int anims, int items); + AnimObj *_animObjects; + + AnimObj *_animActor; + AnimObj *_animAnims; + AnimObj *_animItems; - AnimObj *_animList; bool _drawNoShapeFlag; + AnimObj *_animList; + 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); + virtual void refreshAnimObjects(int force) = 0; void refreshAnimObjectsIfNeed(); - void updateItemAnimations(); - void flagAnimObjsUnk8(); + void flagAnimObjsSpecialRefresh(); void flagAnimObjsForRefresh(); - void updateCharFacing(); - void updateCharacterAnim(int); - void updateSceneAnim(int anim, int newFrame); + virtual void clearAnimObjects() = 0; + + virtual void drawAnimObjects() = 0; + virtual void drawSceneAnimObject(AnimObj *obj, int x, int y, int drawLayer) = 0; + virtual void drawCharacterAnimObject(AnimObj *obj, int x, int y, int drawLayer) = 0; + + virtual void updateCharacterAnim(int) = 0; + virtual void updateSceneAnim(int anim, int newFrame) = 0; void addItemToAnimList(int item); void deleteItemAnimEntry(int item); - int _animObj0Width, _animObj0Height; - void setCharacterAnimDim(int w, int h); - void resetCharacterAnimDim(); + virtual void animSetupPaletteEntry(AnimObj *) {} + + virtual void setCharacterAnimDim(int w, int h) = 0; + virtual void resetCharacterAnimDim() = 0; - // scene + virtual int getScale(int x, int y) = 0; + + uint8 *_screenBuffer; + + // Scene struct SceneDesc { - char filename[10]; + char filename1[10]; + char filename2[10]; + uint16 exit1, exit2, exit3, exit4; uint8 flags; uint8 sound; @@ -519,42 +178,100 @@ protected: 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(); + virtual void enterNewScene(uint16 newScene, int facing, int unk1, int unk2, int unk3) = 0; + + void runSceneScript6(); - void loadScenePal(); - void loadSceneMsc(); + EMCData _sceneScriptData; + EMCState _sceneScriptState; - void fadeScenePal(int srcIndex, int delay); + virtual int trySceneChange(int *moveTable, int unk1, int unk2) = 0; - void startSceneScript(int unk1); - void runSceneScript2(); - void runSceneScript4(int unk1); - void runSceneScript6(); - void runSceneScript7(); + // Animation + virtual void restorePage3() = 0; + + struct SceneAnim { + uint16 flags; + int16 x, y; + int16 x2, y2; + int16 width, height; + uint16 specialSize; + int16 shapeIndex; + uint16 wsaFlag; + char filename[14]; + }; - void initSceneAnims(int unk1); - void initSceneScreen(int unk1); + SceneAnim _sceneAnims[16]; + WSAMovieV2 *_sceneAnimMovie[16]; - int trySceneChange(int *moveTable, int unk1, int updateChar); - int checkSceneChange(); + void freeSceneAnims(); + bool _specialSceneScriptState[10]; + bool _specialSceneScriptStateBackup[10]; + EMCState _sceneSpecialScripts[10]; + uint32 _sceneSpecialScriptsTimer[10]; + int _lastProcessedSceneScript; + bool _specialSceneScriptRunFlag; + + void updateSpecialSceneScripts(); + + // Sequences + EMCData _animationScriptData; + EMCState _animationScriptState; + Common::Array<const Opcode*> _opcodesAnimation; + + void runAnimationScript(const char *filename, int allowSkip, int resetChar, int newShapes, int shapeUnload); + + int o2a_setAnimationShapes(EMCState *script); + int o2a_setResetFrame(EMCState *script); + + char _animShapeFilename[14]; + + uint8 *_animShapeFiledata; + int _animShapeCount; + int _animShapeLastEntry; + + int _animNewFrame; + int _animDelayTime; + + int _animResetFrame; + + int _animShapeWidth, _animShapeHeight; + int _animShapeXAdd, _animShapeYAdd; + + bool _animNeedUpdate; + + virtual int initAnimationShapes(uint8 *filedata) = 0; + void processAnimationScript(int allowSkip, int resetChar); + virtual void uninitAnimationShapes(int count, uint8 *filedata) = 0; + + // Shapes + typedef Common::HashMap<int, uint8*> ShapeMap; + ShapeMap _gameShapes; + + uint8 *getShapePtr(int index) const; + void addShapeToPool(const uint8 *data, int realIndex, int shape); + void addShapeToPool(uint8 *shpData, int index); + void remShapeFromPool(int idx); + + int _characterShapeFile; + virtual void loadCharacterShapes(int shapes) = 0; + // pathfinder int _movFacingTable[600]; + int _pathfinderFlag; + 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); @@ -566,603 +283,138 @@ protected: int _pathfinderPositionTable[400]; int _pathfinderPositionIndexTable[200]; - // item - uint8 _itemHtDat[176]; - + // items struct Item { uint16 id; uint16 sceneId; int16 x; uint8 y; - uint16 unk7; }; - Item *_itemList; - uint16 _hiddenItems[20]; + void initItemList(int size); - int findFreeItem(); - int countAllItems(); - int findItem(uint16 sceneId, uint16 id); - int checkItemCollision(int x, int y); - void resetItemList(); - void updateWaterFlasks(); + uint16 _hiddenItems[100]; + + Item *_itemList; + int _itemListSize; 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); + int findFreeItem(); + int countAllItems(); + + int findItem(uint16 sceneId, uint16 id); + int findItem(uint16 item); - bool isDropable(int x, int y); + void resetItemList(); + void resetItem(int index); - static const byte _itemStringMap[]; - static const int _itemStringMapSize; + virtual void setMouseCursor(uint16 item) = 0; - 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; + int16 dlgIndex; uint8 height; uint8 facing; uint16 animFrame; - uint8 unk8; - uint8 unk9; - uint8 unkA; + byte walkspeed; uint16 inventory[20]; int16 x1, y1; int16 x2, y2; + int16 x3, y3; }; - int8 _deathHandler; Character _mainCharacter; - bool _useCharPal; - int _charPalEntry; - uint8 _charPalTable[16]; - void updateCharPal(int unk1); - void setCharPalEntry(int entry, int value); + int _mainCharX, _mainCharY; + int _charScale; void moveCharacter(int facing, int x, int y); - int updateCharPos(int *table); + int updateCharPos(int *table, int force = 0); void updateCharPosWithUpdate(); - void updateCharAnimFrame(int num, int *table); - int checkCharCollision(int x, int y); + uint32 _updateCharPosNextUpdate; + static const int8 _updateCharPosXTable[]; + static const int8 _updateCharPosYTable[]; - 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(); + virtual int getCharacterWalkspeed() const = 0; + virtual void updateCharAnimFrame(int num, int *table) = 0; // chat int _vocHigh; const char *_chatText; int _chatObject; - bool _chatIsNote; uint32 _chatEndTime; int _chatVocHigh, _chatVocLow; - ScriptData _chatScriptData; - ScriptState _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]; + EMCData _chatScriptData; + EMCState _chatScriptState; - // tim - void playTim(const char *filename); + virtual void setDlgIndex(int dlgIndex) = 0; - 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); + virtual void randomSceneChat() = 0; - Common::Array<const TIMOpcode*> _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); - - // 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(ScriptState *script); - int o2_setCharacterPos(ScriptState *script); - int o2_defineObject(ScriptState *script); - int o2_refreshCharacter(ScriptState *script); - int o2_getCharacterX(ScriptState *script); - int o2_getCharacterY(ScriptState *script); - int o2_getCharacterFacing(ScriptState *script); - int o2_getCharacterScene(ScriptState *script); - int o2_setSceneComment(ScriptState *script); - int o2_setCharacterAnimFrame(ScriptState *script); - int o2_setCharacterFacing(ScriptState *script); - int o2_trySceneChange(ScriptState *script); - int o2_moveCharacter(ScriptState *script); - int o2_customCharacterChat(ScriptState *script); - int o2_soundFadeOut(ScriptState *script); - int o2_showChapterMessage(ScriptState *script); - int o2_restoreTalkTextMessageBkgd(ScriptState *script); - int o2_wsaClose(ScriptState *script); - int o2_meanWhileScene(ScriptState *script); - int o2_backUpScreen(ScriptState *script); - int o2_restoreScreen(ScriptState *script); - int o2_displayWsaFrame(ScriptState *script); - int o2_displayWsaSequentialFramesLooping(ScriptState *script); - int o2_wsaOpen(ScriptState *script); - int o2_displayWsaSequentialFrames(ScriptState *script); - int o2_displayWsaSequence(ScriptState *script); - int o2_addItemToInventory(ScriptState *script); - int o2_drawShape(ScriptState *script); - int o2_addItemToCurScene(ScriptState *script); - int o2_checkForItem(ScriptState *script); - int o2_loadSoundFile(ScriptState *script); - int o2_removeItemSlotFromInventory(ScriptState *script); - int o2_defineItem(ScriptState *script); - int o2_removeItemFromInventory(ScriptState *script); - int o2_countItemInInventory(ScriptState *script); - int o2_countItemsInScene(ScriptState *script); - int o2_queryGameFlag(ScriptState *script); - int o2_resetGameFlag(ScriptState *script); - int o2_setGameFlag(ScriptState *script); - int o2_setHandItem(ScriptState *script); - int o2_removeHandItem(ScriptState *script); - int o2_handItemSet(ScriptState *script); - int o2_hideMouse(ScriptState *script); - int o2_addSpecialExit(ScriptState *script); - int o2_setMousePos(ScriptState *script); - int o2_showMouse(ScriptState *script); - int o2_wipeDownMouseItem(ScriptState *script); - int o2_getElapsedSecs(ScriptState *script); - int o2_getTimerDelay(ScriptState *script); - //int o2_playSoundEffect(ScriptState *script); - int o2_delaySecs(ScriptState *script); - int o2_delay(ScriptState *script); - int o2_setTimerDelay(ScriptState *script); - int o2_setScaleTableItem(ScriptState *script); - int o2_setDrawLayerTableItem(ScriptState *script); - int o2_setCharPalEntry(ScriptState *script); - int o2_loadZShapes(ScriptState *script); - int o2_drawSceneShape(ScriptState *script); - int o2_drawSceneShapeOnPage(ScriptState *script); - int o2_disableAnimObject(ScriptState *script); - int o2_enableAnimObject(ScriptState *script); - int o2_loadPalette384(ScriptState *script); - int o2_setPalette384(ScriptState *script); - int o2_restoreBackBuffer(ScriptState *script); - int o2_backUpInventoryGfx(ScriptState *script); - int o2_disableSceneAnim(ScriptState *script); - int o2_enableSceneAnim(ScriptState *script); - int o2_restoreInventoryGfx(ScriptState *script); - int o2_setSceneAnimPos2(ScriptState *script); - int o2_update(ScriptState *script); - int o2_fadeScenePal(ScriptState *script); - int o2_enterNewSceneEx(ScriptState *script); - int o2_switchScene(ScriptState *script); - int o2_getShapeFlag1(ScriptState *script); - int o2_setPathfinderFlag(ScriptState *script); - int o2_getSceneExitToFacing(ScriptState *script); - int o2_setLayerFlag(ScriptState *script); - int o2_setZanthiaPos(ScriptState *script); - int o2_loadMusicTrack(ScriptState *script); - int o2_playWanderScoreViaMap(ScriptState *script); - int o2_playSoundEffect(ScriptState *script); - int o2_setSceneAnimPos(ScriptState *script); - int o2_blockInRegion(ScriptState *script); - int o2_blockOutRegion(ScriptState *script); - int o2_setCauldronState(ScriptState *script); - int o2_showItemString(ScriptState *script); - int o2_getRand(ScriptState *script); - int o2_isAnySoundPlaying(ScriptState *script); - int o2_setDeathHandlerFlag(ScriptState *script); - int o2_setDrawNoShapeFlag(ScriptState *script); - int o2_setRunFlag(ScriptState *script); - int o2_showLetter(ScriptState *script); - int o2_fillRect(ScriptState *script); - int o2_waitForConfirmationClick(ScriptState *script); - int o2_encodeShape(ScriptState *script); - int o2_defineRoomEntrance(ScriptState *script); - int o2_runTemporaryScript(ScriptState *script); - int o2_setSpecialSceneScriptRunTime(ScriptState *script); - int o2_defineSceneAnim(ScriptState *script); - int o2_updateSceneAnim(ScriptState *script); - int o2_addToSceneAnimPosAndUpdate(ScriptState *script); - int o2_useItemOnMainChar(ScriptState *script); - int o2_startDialogue(ScriptState *script); - int o2_zanthRandomChat(ScriptState *script); - int o2_setupDialogue(ScriptState *script); - int o2_getDlgIndex(ScriptState *script); - int o2_defineRoom(ScriptState *script); - int o2_addCauldronStateTableEntry(ScriptState *script); - int o2_setCountDown(ScriptState *script); - int o2_getCountDown(ScriptState *script); - int o2_pressColorKey(ScriptState *script); - int o2_objectChat(ScriptState *script); - int o2_chapterChange(ScriptState *script); - int o2_getColorCodeFlag1(ScriptState *script); - int o2_setColorCodeFlag1(ScriptState *script); - int o2_getColorCodeFlag2(ScriptState *script); - int o2_setColorCodeFlag2(ScriptState *script); - int o2_getColorCodeValue(ScriptState *script); - int o2_setColorCodeValue(ScriptState *script); - int o2_countItemInstances(ScriptState *script); - int o2_removeItemFromScene(ScriptState *script); - int o2_initObject(ScriptState *script); - int o2_npcChat(ScriptState *script); - int o2_deinitObject(ScriptState *script); - int o2_playTimSequence(ScriptState *script); - int o2_makeBookOrCauldronAppear(ScriptState *script); - int o2_setSpecialSceneScriptState(ScriptState *script); - int o2_clearSpecialSceneScriptState(ScriptState *script); - int o2_querySpecialSceneScriptState(ScriptState *script); - int o2_resetInputColorCode(ScriptState *script); - int o2_setHiddenItemsEntry(ScriptState *script); - int o2_getHiddenItemsEntry(ScriptState *script); - int o2_mushroomEffect(ScriptState *script); - int o2_customChat(ScriptState *script); - int o2_customChatFinish(ScriptState *script); - int o2_setupSceneAnimation(ScriptState *script); - int o2_stopSceneAnimation(ScriptState *script); - int o2_disableTimer(ScriptState *script); - int o2_enableTimer(ScriptState *script); - int o2_setTimerCountdown(ScriptState *script); - int o2_processPaletteIndex(ScriptState *script); - int o2_updateTwoSceneAnims(ScriptState *script); - int o2_getRainbowRoomData(ScriptState *script); - int o2_drawSceneShapeEx(ScriptState *script); - int o2_getBoolFromStack(ScriptState *script); - int o2_getSfxDriver(ScriptState *script); - int o2_getVocSupport(ScriptState *script); - int o2_getMusicDriver(ScriptState *script); - int o2_setVocHigh(ScriptState *script); - int o2_getVocHigh(ScriptState *script); - int o2_zanthiaChat(ScriptState *script); - int o2_isVoiceEnabled(ScriptState *script); - int o2_isVoicePlaying(ScriptState *script); - int o2_stopVoicePlaying(ScriptState *script); - int o2_getGameLanguage(ScriptState *script); - int o2_demoFinale(ScriptState *script); - int o2_dummy(ScriptState *script); - - // opcodes temporary - // TODO: rename it from temporary to something more appropriate - int o2t_defineNewShapes(ScriptState *script); - int o2t_setCurrentFrame(ScriptState *script); - int o2t_playSoundEffect(ScriptState *script); - int o2t_fadeScenePal(ScriptState *script); - int o2t_setShapeFlag(ScriptState *script); - - // script - void runStartScript(int script, int unk1); - void loadNPCScript(); - - bool _noScriptEnter; - - ScriptData _npcScriptData; - - ScriptData _sceneScriptData; - ScriptState _sceneScriptState; - - ScriptData _temporaryScriptData; - ScriptState _temporaryScriptState; - bool _temporaryScriptExecBit; - Common::Array<const Opcode*> _opcodesTemporary; - - void runTemporaryScript(const char *filename, int allowSkip, int resetChar, int newShapes, int shapeUnload); - - // pathfinder - int _pathfinderFlag; - - uint8 *_unkBuf500Bytes; - uint8 *_unkBuf200kByte; - bool _chatAltFlag; + // unknown 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; + // opcodes + int o2_getCharacterX(EMCState *script); + int o2_getCharacterY(EMCState *script); + int o2_getCharacterFacing(EMCState *script); + int o2_getCharacterScene(EMCState *script); + int o2_setCharacterFacingOverwrite(EMCState *script); + int o2_trySceneChange(EMCState *script); + int o2_moveCharacter(EMCState *script); + int o2_checkForItem(EMCState *script); + int o2_defineItem(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_delay(EMCState *script); + int o2_update(EMCState *script); + int o2_getShapeFlag1(EMCState *script); + int o2_playWanderScoreViaMap(EMCState *script); + int o2_getRand(EMCState *script); + int o2_setDeathHandler(EMCState *script); + int o2_waitForConfirmationClick(EMCState *script); + int o2_randomSceneChat(EMCState *script); + int o2_setDlgIndex(EMCState *script); + int o2_getDlgIndex(EMCState *script); + int o2_defineRoomEntrance(EMCState *script); + int o2_runAnimationScript(EMCState *script); + int o2_setSpecialSceneScriptRunTime(EMCState *script); + int o2_defineScene(EMCState *script); + int o2_setSpecialSceneScriptState(EMCState *script); + int o2_clearSpecialSceneScriptState(EMCState *script); + int o2_querySpecialSceneScriptState(EMCState *script); + int o2_setHiddenItemsEntry(EMCState *script); + int o2_getHiddenItemsEntry(EMCState *script); + int o2_disableTimer(EMCState *script); + int o2_enableTimer(EMCState *script); + int o2_setTimerCountdown(EMCState *script); + int o2_setVocHigh(EMCState *script); + int o2_getVocHigh(EMCState *script); // save/load specific - void saveGame(const char *fileName, const char *saveName); - void loadGame(const char *fileName); + virtual void saveGame(const char *fileName, const char *saveName) = 0; + virtual void loadGame(const char *fileName) = 0; }; } // end of namespace Kyra #endif - - - diff --git a/engines/kyra/module.mk b/engines/kyra/module.mk index bfb0e057fe..aec2778def 100644 --- a/engines/kyra/module.mk +++ b/engines/kyra/module.mk @@ -3,41 +3,50 @@ 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 \ gui_v1.o \ gui_v2.o \ - gui_v3.o \ + gui_hof.o \ + gui_mr.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_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 \ @@ -47,17 +56,17 @@ 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 # This module can be built as a plugin -ifdef BUILD_PLUGINS +ifeq ($(ENABLE_KYRA), DYNAMIC_PLUGIN) PLUGIN := 1 endif diff --git a/engines/kyra/resource.cpp b/engines/kyra/resource.cpp index 0a07392d8d..b2564221fc 100644 --- a/engines/kyra/resource.cpp +++ b/engines/kyra/resource.cpp @@ -716,7 +716,6 @@ bool ResLoaderTlk::loadFile(const Common::String &filename, Common::SeekableRead char realFilename[20]; snprintf(realFilename, 20, "%u.AUD", resFilename); - uint32 curOffset = stream.pos(); stream.seek(resOffset, SEEK_SET); entry.size = stream.readUint32LE(); 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.cpp b/engines/kyra/saveload.cpp index 358f61addf..fa3266685f 100644 --- a/engines/kyra/saveload.cpp +++ b/engines/kyra/saveload.cpp @@ -29,7 +29,7 @@ #include "kyra/kyra.h" -#define CURRENT_SAVE_VERSION 9 +#define CURRENT_SAVE_VERSION 11 #define GF_FLOPPY (1 << 0) #define GF_TALKIE (1 << 1) @@ -188,6 +188,9 @@ Common::OutSaveFile *KyraEngine::openSaveForWriting(const char *filename, const const char *KyraEngine::getSavegameFilename(int num) { static Common::String filename; + + assert(num >= 0 && num <= 999); + char extension[5]; sprintf(extension, "%.3d", num); diff --git a/engines/kyra/saveload_v2.cpp b/engines/kyra/saveload_hof.cpp index 94824c9895..954cbccfa9 100644 --- a/engines/kyra/saveload_v2.cpp +++ b/engines/kyra/saveload_hof.cpp @@ -35,8 +35,8 @@ namespace Kyra { -void KyraEngine_v2::saveGame(const char *fileName, const char *saveName) { - debugC(9, kDebugLevelMain, "KyraEngine_v2::saveGame('%s', '%s')", fileName, saveName); +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) { @@ -53,7 +53,7 @@ void KyraEngine_v2::saveGame(const char *fileName, const char *saveName) { //out->writeUint16BE(word_2AB05); out->writeSint16BE(_lastMusicCommand); out->writeByte(_newChapterFile); - out->writeByte(_loadedZTable); + out->writeByte(_characterShapeFile); out->writeByte(_cauldronState); out->writeByte(_colorCodeFlag1); out->writeByte(_colorCodeFlag2); @@ -73,13 +73,10 @@ void KyraEngine_v2::saveGame(const char *fileName, const char *saveName) { out->writeSint16BE(_cauldronUseCount); out->writeUint16BE(_mainCharacter.sceneId); - out->writeUint16BE(_mainCharacter.dlgIndex); + out->writeSint16BE(_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); @@ -92,7 +89,6 @@ void KyraEngine_v2::saveGame(const char *fileName, const char *saveName) { 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) { @@ -104,7 +100,7 @@ void KyraEngine_v2::saveGame(const char *fileName, const char *saveName) { } for (int i = 0; i < 86; ++i) { - out->write(_sceneList[i].filename, 10); + out->write(_sceneList[i].filename1, 10); out->writeUint16BE(_sceneList[i].exit1); out->writeUint16BE(_sceneList[i].exit2); out->writeUint16BE(_sceneList[i].exit3); @@ -130,8 +126,8 @@ void KyraEngine_v2::saveGame(const char *fileName, const char *saveName) { delete out; } -void KyraEngine_v2::loadGame(const char *fileName) { - debugC(9, kDebugLevelMain, "KyraEngine_v2::loadGame('%s')", fileName); +void KyraEngine_HoF::loadGame(const char *fileName) { + debugC(9, kDebugLevelMain, "KyraEngine_HoF::loadGame('%s')", fileName); SaveHeader header; Common::InSaveFile *saveFile = openSaveForReading(fileName, header); @@ -153,7 +149,7 @@ void KyraEngine_v2::loadGame(const char *fileName) { _lastMusicCommand = -1; } - int loadedZTable = _loadedZTable; + int loadedZTable = _characterShapeFile; Common::SeekableSubReadStreamEndian in(saveFile, saveFile->pos(), saveFile->size(), !header.originalSave, true); @@ -173,7 +169,7 @@ void KyraEngine_v2::loadGame(const char *fileName) { in.readUint16(); _lastMusicCommand = in.readSint16(); _newChapterFile = in.readByte(); - _loadedZTable = in.readByte(); + _characterShapeFile = in.readByte(); _cauldronState = in.readByte(); _colorCodeFlag1 = in.readByte(); _colorCodeFlag2 = in.readByte(); @@ -209,13 +205,14 @@ void KyraEngine_v2::loadGame(const char *fileName) { in.seek(6, SEEK_CUR); _mainCharacter.sceneId = in.readUint16(); - _mainCharacter.dlgIndex = in.readUint16(); + _mainCharacter.dlgIndex = in.readSint16(); _mainCharacter.height = in.readByte(); _mainCharacter.facing = in.readByte(); _mainCharacter.animFrame = in.readUint16(); - _mainCharacter.unk8 = in.readByte(); - _mainCharacter.unk9 = in.readByte(); - _mainCharacter.unkA = in.readByte(); + + if (header.version <= 10 || header.originalSave) + in.seek(3, SEEK_CUR); + for (int i = 0; i < 20; ++i) _mainCharacter.inventory[i] = in.readUint16(); _mainCharacter.x1 = in.readSint16(); @@ -228,7 +225,8 @@ void KyraEngine_v2::loadGame(const char *fileName) { _itemList[i].sceneId = in.readUint16(); _itemList[i].x = in.readSint16(); _itemList[i].y = in.readByte(); - _itemList[i].unk7 = in.readUint16(); + if (header.version <= 9 || header.originalSave) + in.readUint16(); } for (int i = 0; i < 72; ++i) { @@ -241,10 +239,10 @@ void KyraEngine_v2::loadGame(const char *fileName) { for (int i = 0; i < 86; ++i) { if (!header.originalSave) { - in.read(_sceneList[i].filename, 10); + in.read(_sceneList[i].filename1, 10); } else { - in.read(_sceneList[i].filename, 9); - _sceneList[i].filename[9] = 0; + in.read(_sceneList[i].filename1, 9); + _sceneList[i].filename1[9] = 0; } _sceneList[i].exit1 = in.readUint16(); @@ -286,8 +284,8 @@ void KyraEngine_v2::loadGame(const char *fileName) { else debugC(1, kDebugLevelMain, "Loaded savegame '%s.'", header.description.c_str()); - if (loadedZTable != _loadedZTable) - loadZShapes(_loadedZTable); + if (loadedZTable != _characterShapeFile) + loadCharacterShapes(_characterShapeFile); _screen->loadBitmap("_PLAYFLD.CPS", 3, 3, 0); if (!queryGameFlag(1)) diff --git a/engines/kyra/saveload_mr.cpp b/engines/kyra/saveload_mr.cpp new file mode 100644 index 0000000000..8b727862a5 --- /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(_characterShapeFile); + //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->writeSint16BE(_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); + } + + 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 = _characterShapeFile; + + 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(); + _characterShapeFile = 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.readSint16(); + _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(); + if (header.version <= 9) + 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 != _characterShapeFile) + loadCharacterShapes(_characterShapeFile); + + _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..3fc7947253 --- /dev/null +++ b/engines/kyra/scene_hof.cpp @@ -0,0 +1,763 @@ +/* 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::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; + + _charScale = getScale(_mainCharacter.x1, _mainCharacter.y1); + + int shapeXScaled = (shapeX * _charScale) >> 8; + int shapeYScaled = (shapeY * _charScale) >> 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_v3.cpp b/engines/kyra/scene_mr.cpp index 27144ff505..196c87424d 100644 --- a/engines/kyra/scene_v3.cpp +++ b/engines/kyra/scene_mr.cpp @@ -23,15 +23,16 @@ * */ -#include "kyra/kyra_v3.h" -#include "kyra/screen_v3.h" +#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_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); +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(); @@ -42,7 +43,10 @@ void KyraEngine_v3::enterNewScene(uint16 sceneId, int facing, int unk1, int unk2 } musicUpdate(0); - //XXX + if (_currentChapter != _currentTalkFile) { + _currentTalkFile = _currentChapter; + openTalkFile(_currentTalkFile); + } musicUpdate(0); if (!unk3) { @@ -79,7 +83,7 @@ void KyraEngine_v3::enterNewScene(uint16 sceneId, int facing, int unk1, int unk2 musicUpdate(0); uint32 waitUntilTimer = 0; bool newSoundFile = false; - if (_curMusicTrack != _sceneList[sceneId].sound) { + if (_lastMusicCommand != _sceneList[sceneId].sound) { fadeOutMusic(60); waitUntilTimer = _system->getMillis() + 60 * _tickLength; newSoundFile = true; @@ -88,21 +92,16 @@ void KyraEngine_v3::enterNewScene(uint16 sceneId, int facing, int unk1, int unk2 //XXX if (!unk3) { - _scriptInterpreter->initScript(&_sceneScriptState, &_sceneScriptData); - _scriptInterpreter->startScript(&_sceneScriptState, 5); - while (_scriptInterpreter->validScript(&_sceneScriptState)) { - _scriptInterpreter->runScript(&_sceneScriptState); + _emc->init(&_sceneScriptState, &_sceneScriptData); + _emc->start(&_sceneScriptState, 5); + while (_emc->isValid(&_sceneScriptState)) { + _emc->run(&_sceneScriptState); musicUpdate(0); } } musicUpdate(0); - for (int i = 0; i < 10; ++i) - _wsaSlots[i]->close(); - - musicUpdate(0); - _specialExitCount = 0; Common::set_to(_specialExitTable, _specialExitTable+ARRAYSIZE(_specialExitTable), 0xFFFF); @@ -113,7 +112,6 @@ void KyraEngine_v3::enterNewScene(uint16 sceneId, int facing, int unk1, int unk2 musicUpdate(0); unloadScene(); musicUpdate(0); - //XXX resetMaskPage(); for (int i = 0; i < 4; ++i) { if (i != _musicSoundChannel && i != _fadeOutMusicChannel) @@ -125,7 +123,27 @@ void KyraEngine_v3::enterNewScene(uint16 sceneId, int facing, int unk1, int unk2 musicUpdate(0); if (queryGameFlag(0x1D9)) { - //XXX VQA code here + 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); @@ -154,6 +172,7 @@ void KyraEngine_v3::enterNewScene(uint16 sceneId, int facing, int unk1, int unk2 _sceneScriptState.regs[3] = 1; enterNewSceneUnk2(unk3); if (queryGameFlag(0)) { + _showOutro = true; _runFlag = false; } else { if (!--_enterNewSceneLock) @@ -161,7 +180,7 @@ void KyraEngine_v3::enterNewScene(uint16 sceneId, int facing, int unk1, int unk2 setNextIdleAnimTimer(); - if (_itemInHand <= 0) { + if (_itemInHand < 0) { _itemInHand = -1; _handItemSet = -1; _screen->setMouseCursor(0, 0, _gameShapes[0]); @@ -174,8 +193,8 @@ void KyraEngine_v3::enterNewScene(uint16 sceneId, int facing, int unk1, int unk2 _screen->showMouse(); } -void KyraEngine_v3::enterNewSceneUnk1(int facing, int unk1, int unk2) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::enterNewSceneUnk1(%d, %d, %d)", facing, unk1, unk2); +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; @@ -264,16 +283,16 @@ void KyraEngine_v3::enterNewSceneUnk1(int facing, int unk1, int unk2) { initSceneAnims(unk2); if (_mainCharacter.sceneId == 9 && !_soundDigital->isPlaying(_musicSoundChannel)) - playMusicTrack(_sceneList[_mainCharacter.sceneId].sound, 0); + snd_playWanderScoreViaMap(_sceneList[_mainCharacter.sceneId].sound, 0); if (!unk2) - playMusicTrack(_sceneList[_mainCharacter.sceneId].sound, 0); + 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); +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]; @@ -290,12 +309,12 @@ void KyraEngine_v3::enterNewSceneUnk2(int unk1) { _unk3 = -1; } -void KyraEngine_v3::unloadScene() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::unloadScene()"); +void KyraEngine_MR::unloadScene() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::unloadScene()"); delete [] _sceneStrings; _sceneStrings = 0; musicUpdate(0); - _scriptInterpreter->unloadScript(&_sceneScriptData); + _emc->unload(&_sceneScriptData); musicUpdate(0); freeSceneShapes(); musicUpdate(0); @@ -303,24 +322,16 @@ void KyraEngine_v3::unloadScene() { musicUpdate(0); } -void KyraEngine_v3::freeSceneShapes() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::freeSceneShapes()"); +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_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()"); +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); @@ -339,12 +350,12 @@ void KyraEngine_v3::loadScenePal() { _screen->generateOverlay(_screen->getPalette(2), _paletteOverlay, 0xF0, 0x19); uint8 *palette = _screen->getPalette(2) + 432; - const uint8 *costPal = _costPalBuffer + _malcolmShapes * 72; + const uint8 *costPal = _costPalBuffer + _characterShapeFile * 72; memcpy(palette, costPal, 24*3); } -void KyraEngine_v3::loadSceneMsc() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::loadSceneMsc()"); +void KyraEngine_MR::loadSceneMsc() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::loadSceneMsc()"); char filename[16]; strcpy(filename, _sceneList[_mainCharacter.sceneId].filename1); strcat(filename, ".MSC"); @@ -375,8 +386,8 @@ void KyraEngine_v3::loadSceneMsc() { musicUpdate(0); } -void KyraEngine_v3::initSceneScript(int unk1) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::initSceneScript(%d)", unk1); +void KyraEngine_MR::initSceneScript(int unk1) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::initSceneScript(%d)", unk1); const SceneDesc &scene = _sceneList[_mainCharacter.sceneId]; musicUpdate(0); @@ -438,31 +449,31 @@ void KyraEngine_v3::initSceneScript(int unk1) { _sceneMinX = 0; _sceneMaxX = 319; - _scriptInterpreter->initScript(&_sceneScriptState, &_sceneScriptData); + _emc->init(&_sceneScriptState, &_sceneScriptData); strcpy(filename, scene.filename2); strcat(filename, ".EMC"); musicUpdate(0); _res->exists(filename, true); - _scriptInterpreter->loadScript(filename, &_sceneScriptData, &_opcodes); + _emc->load(filename, &_sceneScriptData, &_opcodes); - strcpy(filename, scene.filename1); + strcpy(filename, scene.filename2); strcat(filename, "."); loadLanguageFile(filename, _sceneStrings); musicUpdate(0); runSceneScript8(); - _scriptInterpreter->startScript(&_sceneScriptState, 0); + _emc->start(&_sceneScriptState, 0); _sceneScriptState.regs[0] = _mainCharacter.sceneId; _sceneScriptState.regs[5] = unk1; - while (_scriptInterpreter->validScript(&_sceneScriptState)) - _scriptInterpreter->runScript(&_sceneScriptState); + while (_emc->isValid(&_sceneScriptState)) + _emc->run(&_sceneScriptState); _screen->copyRegionToBuffer(3, 0, 0, 320, 200, _gamePlayBuffer); musicUpdate(0); for (int i = 0; i < 10; ++i) { - _scriptInterpreter->initScript(&_sceneSpecialScripts[i], &_sceneScriptData); - _scriptInterpreter->startScript(&_sceneSpecialScripts[i], i+9); + _emc->init(&_sceneSpecialScripts[i], &_sceneScriptData); + _emc->start(&_sceneSpecialScripts[i], i+9); musicUpdate(0); _sceneSpecialScriptsTimer[i] = 0; } @@ -478,8 +489,8 @@ void KyraEngine_v3::initSceneScript(int unk1) { musicUpdate(0); } -void KyraEngine_v3::initSceneAnims(int unk1) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::initSceneAnims(%d)", unk1); +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; @@ -492,7 +503,7 @@ void KyraEngine_v3::initSceneAnims(int unk1) { obj->xPos1 = _mainCharacter.x1; obj->yPos1 = _mainCharacter.y1; obj->shapePtr = getShapePtr(_mainCharacter.animFrame); - obj->shapeIndex2 = obj->shapeIndex = _mainCharacter.animFrame; + obj->shapeIndex2 = obj->shapeIndex1 = _mainCharacter.animFrame; obj->xPos2 = _mainCharacter.x1; obj->yPos2 = _mainCharacter.y1; _charScale = getScale(_mainCharacter.x1, _mainCharacter.y1); @@ -514,7 +525,7 @@ void KyraEngine_v3::initSceneAnims(int unk1) { obj->needRefresh = true; } - obj->unk8 = (anim.flags & 0x20) ? 1 : 0; + obj->specialRefresh = (anim.flags & 0x20) ? 1 : 0; obj->flags = (anim.flags & 0x10) ? 0x800 : 0; if (anim.flags & 2) obj->flags |= 1; @@ -522,7 +533,7 @@ void KyraEngine_v3::initSceneAnims(int unk1) { obj->xPos1 = anim.x; obj->yPos1 = anim.y; - if ((anim.flags & 4) && anim.shapeIndex != 0xFFFF) + if ((anim.flags & 4) && anim.shapeIndex != -1) obj->shapePtr = _sceneShapes[anim.shapeIndex]; else obj->shapePtr = 0; @@ -562,12 +573,12 @@ void KyraEngine_v3::initSceneAnims(int unk1) { obj->yPos1 = item.y; animSetupPaletteEntry(obj); obj->shapePtr = 0; - obj->shapeIndex = obj->shapeIndex2 = item.id + 248; + 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->shapeIndex); + 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; @@ -594,8 +605,8 @@ void KyraEngine_v3::initSceneAnims(int unk1) { refreshAnimObjects(0); } -void KyraEngine_v3::initSceneScreen(int unk1) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::initSceneScreen(%d)", unk1); +void KyraEngine_MR::initSceneScreen(int unk1) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::initSceneScreen(%d)", unk1); _screen->copyBlockToPage(2, 0, 188, 320, 12, _interfaceCommandLine); if (_unkSceneScreenFlag1) { @@ -605,65 +616,35 @@ void KyraEngine_v3::initSceneScreen(int unk1) { if (_noScriptEnter) { memset(_screen->getPalette(0), 0, 432); - if (!_wsaPlayingVQA) + if (!_wasPlayingVQA) _screen->setScreenPalette(_screen->getPalette(0)); } _screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0, Screen::CR_NO_P_CHECK); if (_noScriptEnter) { - if (!_wsaPlayingVQA) + if (!_wasPlayingVQA) _screen->setScreenPalette(_screen->getPalette(2)); memcpy(_screen->getPalette(0), _screen->getPalette(2), 432); - if (_wsaPlayingVQA) { + if (_wasPlayingVQA) { _screen->fadeFromBlack(0x3C); - _wsaPlayingVQA = false; + _wasPlayingVQA = false; } } updateCharPal(0); - if (1/*!_menuDirectlyToLoad*/) { - _scriptInterpreter->startScript(&_sceneScriptState, 3); + if (!_menuDirectlyToLoad) { + _emc->start(&_sceneScriptState, 3); _sceneScriptState.regs[5] = unk1; - while (_scriptInterpreter->validScript(&_sceneScriptState)) - _scriptInterpreter->runScript(&_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 (!_scriptInterpreter->runScript(&_sceneSpecialScripts[_lastProcessedSceneScript])) - _specialSceneScriptRunFlag = false; - } - } - - if (!_scriptInterpreter->validScript(&_sceneSpecialScripts[_lastProcessedSceneScript])) { - _scriptInterpreter->startScript(&_sceneSpecialScripts[_lastProcessedSceneScript], 9+_lastProcessedSceneScript); - _specialSceneScriptRunFlag = false; - } - - ++_lastProcessedSceneScript; - if (_lastProcessedSceneScript >= 10) - _lastProcessedSceneScript = 0; - - if (_lastProcessedSceneScript == startScript) - return; + while (_emc->isValid(&_sceneScriptState)) + _emc->run(&_sceneScriptState); } } -int KyraEngine_v3::trySceneChange(int *moveTable, int unk1, int updateChar) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::trySceneChange(%p, %d, %d)", (const void*)moveTable, unk1, updateChar); +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; @@ -689,7 +670,9 @@ int KyraEngine_v3::trySceneChange(int *moveTable, int unk1, int updateChar) { } if (unk1) { - if (skipFlag()) { + // Notice that we can't use KyraEngine_MR's skipFlag handling + // here, since Kyra3 allows disabling of skipFlag support + if (KyraEngine_v2::skipFlag()) { resetSkipFlag(false); running = false; _unk4 = 1; @@ -720,8 +703,8 @@ int KyraEngine_v3::trySceneChange(int *moveTable, int unk1, int updateChar) { return changedScene; } -int KyraEngine_v3::checkSceneChange() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::checkSceneChange()"); +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; @@ -773,97 +756,66 @@ int KyraEngine_v3::checkSceneChange() { 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); +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; - _scriptInterpreter->initScript(&_sceneScriptState, &_sceneScriptData); + _emc->init(&_sceneScriptState, &_sceneScriptData); _sceneScriptState.regs[1] = x; _sceneScriptState.regs[2] = y; _sceneScriptState.regs[3] = 0; _sceneScriptState.regs[4] = _itemInHand; - _scriptInterpreter->startScript(&_sceneScriptState, 1); - while (_scriptInterpreter->validScript(&_sceneScriptState)) - _scriptInterpreter->runScript(&_sceneScriptState); + _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()"); +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; - _scriptInterpreter->startScript(&_sceneScriptState, 2); - while (_scriptInterpreter->validScript(&_sceneScriptState)) - _scriptInterpreter->runScript(&_sceneScriptState); + _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); +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; - _scriptInterpreter->startScript(&_sceneScriptState, 4); - while (_scriptInterpreter->validScript(&_sceneScriptState)) - _scriptInterpreter->runScript(&_sceneScriptState); + _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()"); - _scriptInterpreter->initScript(&_sceneScriptState, &_sceneScriptData); - - _sceneScriptState.regs[0] = _mainCharacter.sceneId; - _sceneScriptState.regs[1] = _mouseX; - _sceneScriptState.regs[2] = _mouseY; - _sceneScriptState.regs[3] = _itemInHand; - - _scriptInterpreter->startScript(&_sceneScriptState, 6); - while (_scriptInterpreter->validScript(&_sceneScriptState)) - _scriptInterpreter->runScript(&_sceneScriptState); -} - -void KyraEngine_v3::runSceneScript8() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::runSceneScript8()"); - _scriptInterpreter->startScript(&_sceneScriptState, 8); - while (_scriptInterpreter->validScript(&_sceneScriptState)) { +void KyraEngine_MR::runSceneScript8() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::runSceneScript8()"); + _emc->start(&_sceneScriptState, 8); + while (_emc->isValid(&_sceneScriptState)) { musicUpdate(0); - _scriptInterpreter->runScript(&_sceneScriptState); + _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); +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) diff --git a/engines/kyra/scene_v1.cpp b/engines/kyra/scene_v1.cpp index c531ac11e5..c5d1de82a9 100644 --- a/engines/kyra/scene_v1.cpp +++ b/engines/kyra/scene_v1.cpp @@ -135,10 +135,10 @@ void KyraEngine_v1::enterNewScene(int sceneId, int facing, int unk1, int unk2, i _movieObjects[i]->close(); if (!brandonAlive) { - _scriptInterpreter->initScript(_scriptClick, _scriptClickData); - _scriptInterpreter->startScript(_scriptClick, 5); - while (_scriptInterpreter->validScript(_scriptClick)) - _scriptInterpreter->runScript(_scriptClick); + _emc->init(&_scriptClick, &_scriptClickData); + _emc->start(&_scriptClick, 5); + while (_emc->isValid(&_scriptClick)) + _emc->run(&_scriptClick); } memset(_entranceMouseCursorTracks, 0xFFFF, sizeof(uint16)*4); @@ -159,7 +159,7 @@ void KyraEngine_v1::enterNewScene(int sceneId, int facing, int unk1, int unk2, i strcat(fileNameBuffer, ".DAT"); _sprites->loadDat(fileNameBuffer, _sceneExits); _sprites->setupSceneAnims(); - _scriptInterpreter->unloadScript(_scriptClickData); + _emc->unload(&_scriptClickData); loadSceneMsc(); _walkBlockNorth = currentRoom->northExit; @@ -424,18 +424,18 @@ void KyraEngine_v1::startSceneScript(int brandonAlive) { _scaleTable[i] = 256; clearNoDropRects(); - _scriptInterpreter->initScript(_scriptClick, _scriptClickData); + _emc->init(&_scriptClick, &_scriptClickData); strcpy(fileNameBuffer, _roomFilenameTable[tableId]); strcat(fileNameBuffer, ".EMC"); _res->exists(fileNameBuffer, true); - _scriptInterpreter->unloadScript(_scriptClickData); - _scriptInterpreter->loadScript(fileNameBuffer, _scriptClickData, &_opcodes); - _scriptInterpreter->startScript(_scriptClick, 0); - _scriptClick->regs[0] = _currentCharacter->sceneId; - _scriptClick->regs[7] = brandonAlive; - - while (_scriptInterpreter->validScript(_scriptClick)) - _scriptInterpreter->runScript(_scriptClick); + _emc->unload(&_scriptClickData); + _emc->load(fileNameBuffer, &_scriptClickData, &_opcodes); + _emc->start(&_scriptClick, 0); + _scriptClick.regs[0] = _currentCharacter->sceneId; + _scriptClick.regs[7] = brandonAlive; + + while (_emc->isValid(&_scriptClick)) + _emc->run(&_scriptClick); } void KyraEngine_v1::initSceneData(int facing, int unk1, int brandonAlive) { @@ -601,11 +601,11 @@ void KyraEngine_v1::initSceneData(int facing, int unk1, int brandonAlive) { if (unk1 && brandonAlive == 0) moveCharacterToPos(0, facing, xpos2, ypos2); - _scriptClick->regs[4] = _itemInHand; - _scriptClick->regs[7] = brandonAlive; - _scriptInterpreter->startScript(_scriptClick, 3); - while (_scriptInterpreter->validScript(_scriptClick)) - _scriptInterpreter->runScript(_scriptClick); + _scriptClick.regs[4] = _itemInHand; + _scriptClick.regs[7] = brandonAlive; + _emc->start(&_scriptClick, 3); + while (_emc->isValid(&_scriptClick)) + _emc->run(&_scriptClick); } void KyraEngine_v1::initSceneObjectList(int brandonAlive) { @@ -615,7 +615,7 @@ void KyraEngine_v1::initSceneObjectList(int brandonAlive) { int startAnimFrame = 0; - AnimObject *curAnimState = _animator->actors(); + Animator_v1::AnimObject *curAnimState = _animator->actors(); curAnimState->active = 1; curAnimState->drawY = _currentCharacter->y1; curAnimState->sceneAnimPtr = _shapes[_currentCharacter->currentAnimFrame]; @@ -827,13 +827,13 @@ void KyraEngine_v1::initSceneScreen(int brandonAlive) { } } - if (!_scriptInterpreter->startScript(_scriptClick, 2)) + if (!_emc->start(&_scriptClick, 2)) error("Could not start script function 2 of scene script"); - _scriptClick->regs[7] = brandonAlive; + _scriptClick.regs[7] = brandonAlive; - while (_scriptInterpreter->validScript(_scriptClick)) - _scriptInterpreter->runScript(_scriptClick); + while (_emc->isValid(&_scriptClick)) + _emc->run(&_scriptClick); setTextFadeTimerCountdown(-1); if (_currentCharacter->sceneId == 210) { diff --git a/engines/kyra/scene_v2.cpp b/engines/kyra/scene_v2.cpp index 80353eb468..5d811bcf44 100644 --- a/engines/kyra/scene_v2.cpp +++ b/engines/kyra/scene_v2.cpp @@ -24,692 +24,20 @@ */ #include "kyra/kyra_v2.h" -#include "kyra/screen_v2.h" -#include "kyra/sound.h" -#include "kyra/wsamovie.h" - -#include "common/func.h" +#include "kyra/screen.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) { - _scriptInterpreter->initScript(&_sceneScriptState, &_sceneScriptData); - _scriptInterpreter->startScript(&_sceneScriptState, 5); - while (_scriptInterpreter->validScript(&_sceneScriptState)) - _scriptInterpreter->runScript(&_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()"); - _scriptInterpreter->unloadScript(&_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!"; - _scriptInterpreter->initScript(&_sceneScriptState, &_sceneScriptData); - - strcpy(filename, _sceneList[sceneId].filename); - strcat(filename, "."); - strcat(filename, _scriptLangExt[(_flags.platform == Common::kPlatformPC && !_flags.isTalkie) ? 0 : _lang]); - - _res->exists(filename, true); - _scriptInterpreter->loadScript(filename, &_sceneScriptData, &_opcodes); - runSceneScript7(); - - _scriptInterpreter->startScript(&_sceneScriptState, 0); - _sceneScriptState.regs[0] = sceneId; - _sceneScriptState.regs[5] = unk1; - while (_scriptInterpreter->validScript(&_sceneScriptState)) - _scriptInterpreter->runScript(&_sceneScriptState); - - memcpy(_gamePlayBuffer, _screen->getCPagePtr(3), 46080); - - for (int i = 0; i < 10; ++i) { - _scriptInterpreter->initScript(&_sceneSpecialScripts[i], &_sceneScriptData); - _scriptInterpreter->startScript(&_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()"); - _scriptInterpreter->initScript(&_sceneScriptState, &_sceneScriptData); - _sceneScriptState.regs[4] = _itemInHand; - _scriptInterpreter->startScript(&_sceneScriptState, 2); - - while (_scriptInterpreter->validScript(&_sceneScriptState)) - _scriptInterpreter->runScript(&_sceneScriptState); -} - -void KyraEngine_v2::runSceneScript4(int unk1) { - debugC(9, kDebugLevelMain, "KyraEngine_v2::runSceneScript4(%d)", unk1); - _sceneScriptState.regs[4] = _itemInHand; - _sceneScriptState.regs[5] = unk1; - - _scriptInterpreter->startScript(&_sceneScriptState, 4); - while (_scriptInterpreter->validScript(&_sceneScriptState)) - _scriptInterpreter->runScript(&_sceneScriptState); -} - -void KyraEngine_v2::runSceneScript6() { - debugC(9, kDebugLevelMain, "KyraEngine_v2::runSceneScript6()"); - _scriptInterpreter->initScript(&_sceneScriptState, &_sceneScriptData); - - _sceneScriptState.regs[0] = _mainCharacter.sceneId; - _sceneScriptState.regs[1] = _mouseX; - _sceneScriptState.regs[2] = _mouseY; - _sceneScriptState.regs[4] = _itemInHand; - - _scriptInterpreter->startScript(&_sceneScriptState, 6); - while (_scriptInterpreter->validScript(&_sceneScriptState)) - _scriptInterpreter->runScript(&_sceneScriptState); -} - -void KyraEngine_v2::runSceneScript7() { - debugC(9, kDebugLevelMain, "KyraEngine_v2::runSceneScript7()"); - int oldPage = _screen->_curPage; - _screen->_curPage = 2; - - _scriptInterpreter->startScript(&_sceneScriptState, 7); - while (_scriptInterpreter->validScript(&_sceneScriptState)) - _scriptInterpreter->runScript(&_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)); - } +void KyraEngine_v2::freeSceneAnims() { + debugC(9, kDebugLevelMain, "KyraEngine_v2::freeSceneAnims()"); - _screen->copyRegion(0, 0, 0, 0, 320, 144, 2, 0, Screen::CR_NO_P_CHECK); + for (int i = 0; i < ARRAYSIZE(_sceneAnims); ++i) + _sceneAnims[i].flags = 0; - if (_noScriptEnter) { - _screen->setScreenPalette(_screen->getPalette(1)); - memcpy(_screen->getPalette(0), _screen->getPalette(1), 384); + for (int i = 0; i < ARRAYSIZE(_sceneAnimMovie); ++i) { + if (_sceneAnimMovie[i]) + _sceneAnimMovie[i]->close(); } - - updateCharPal(0); - - _scriptInterpreter->startScript(&_sceneScriptState, 3); - _sceneScriptState.regs[5] = unk1; - while (_scriptInterpreter->validScript(&_sceneScriptState)) - _scriptInterpreter->runScript(&_sceneScriptState); } void KyraEngine_v2::updateSpecialSceneScripts() { @@ -723,13 +51,13 @@ void KyraEngine_v2::updateSpecialSceneScripts() { _specialSceneScriptRunFlag = true; while (_specialSceneScriptRunFlag && _sceneSpecialScriptsTimer[_lastProcessedSceneScript] <= _system->getMillis()) { - if (!_scriptInterpreter->runScript(&_sceneSpecialScripts[_lastProcessedSceneScript])) + if (!_emc->run(&_sceneSpecialScripts[_lastProcessedSceneScript])) _specialSceneScriptRunFlag = false; } } - if (!_scriptInterpreter->validScript(&_sceneSpecialScripts[_lastProcessedSceneScript])) { - _scriptInterpreter->startScript(&_sceneSpecialScripts[_lastProcessedSceneScript], 8+_lastProcessedSceneScript); + if (!_emc->isValid(&_sceneSpecialScripts[_lastProcessedSceneScript])) { + _emc->start(&_sceneSpecialScripts[_lastProcessedSceneScript], _desc.firstAnimSceneScript+_lastProcessedSceneScript); _specialSceneScriptRunFlag = false; } @@ -742,32 +70,21 @@ void KyraEngine_v2::updateSpecialSceneScripts() { } } -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::runSceneScript6() { + debugC(9, kDebugLevelMain, "KyraEngine_v2::runSceneScript6()"); + _emc->init(&_sceneScriptState, &_sceneScriptData); -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); + _sceneScriptState.regs[0] = _mainCharacter.sceneId; + _sceneScriptState.regs[1] = _mouseX; + _sceneScriptState.regs[2] = _mouseY; + _sceneScriptState.regs[3] = _itemInHand; - _screen->fadePalette(_screen->getPalette(0), delayTime, &_updateFunctor); + _emc->start(&_sceneScriptState, 6); + while (_emc->isValid(&_sceneScriptState)) + _emc->run(&_sceneScriptState); } -#pragma mark - -#pragma mark - Pathfinder -#pragma mark - +#pragma mark - pathfinder 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); @@ -785,53 +102,15 @@ int KyraEngine_v2::findWay(int x, int y, int toX, int toY, int *moveTable, int m 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); + Screen *scr = screen(); + while (x != toX && y != toY) { int facing = getFacingFromPointToPoint(x, y, toX, toY); x += _addXPosTable[facing]; y += _addYPosTable[facing]; - if (!_screen->getShapeFlag1(x, y)) + if (!scr->getShapeFlag1(x, y)) return false; } return true; @@ -957,3 +236,4 @@ void KyraEngine_v2::pathfinderFinializePath(int *moveTable, int tableLen, int x, } } // end of namespace Kyra + diff --git a/engines/kyra/screen.cpp b/engines/kyra/screen.cpp index 6ffd0ace79..298483465e 100644 --- a/engines/kyra/screen.cpp +++ b/engines/kyra/screen.cpp @@ -34,7 +34,8 @@ namespace Kyra { Screen::Screen(KyraEngine *vm, OSystem *system) -: _system(system), _vm(vm), _sjisInvisibleColor(0) { + : _system(system), _vm(vm), _sjisInvisibleColor(0) { + _debugEnabled = false; } Screen::~Screen() { @@ -75,7 +76,34 @@ bool Screen::init() { _useSJIS = false; _sjisTempPage = _sjisFontData = 0; - setResolution(); + if (_vm->gameFlags().useHiResOverlay) { + _useOverlays = true; + _useSJIS = (_vm->gameFlags().lang == Common::JA_JPN); + _sjisInvisibleColor = (_vm->gameFlags().gameID == GI_KYRA1) ? 0x80 : 0xF6; + + for (int i = 0; i < SCREEN_OVLS_NUM; ++i) { + if (!_sjisOverlayPtrs[i]) { + _sjisOverlayPtrs[i] = new uint8[SCREEN_OVL_SJIS_SIZE]; + assert(_sjisOverlayPtrs[i]); + memset(_sjisOverlayPtrs[i], _sjisInvisibleColor, SCREEN_OVL_SJIS_SIZE); + } + } + + if (_useSJIS) { + if (!_sjisFontData) { + _sjisFontData = _vm->resource()->fileData("FMT_FNT.ROM", 0); + if (!_sjisFontData) + error("missing font rom ('FMT_FNT.ROM') required for this version"); + } + + if (!_sjisTempPage) { + _sjisTempPage = new uint8[420]; + assert(_sjisTempPage); + _sjisTempPage2 = _sjisTempPage + 60; + _sjisSourceChar = _sjisTempPage + 384; + } + } + } _curPage = 0; uint8 *pagePtr = new uint8[SCREEN_PAGE_SIZE * 8]; @@ -155,32 +183,6 @@ void Screen::setResolution() { else _system->initSize(640, 400); _system->endGFXTransaction(); - - _useOverlays = true; - _useSJIS = (_vm->gameFlags().lang == Common::JA_JPN); - _sjisInvisibleColor = (_vm->gameFlags().gameID == GI_KYRA1) ? 0x80 : 0xF6; - - for (int i = 0; i < SCREEN_OVLS_NUM; ++i) { - if (!_sjisOverlayPtrs[i]) { - _sjisOverlayPtrs[i] = new uint8[SCREEN_OVL_SJIS_SIZE]; - assert(_sjisOverlayPtrs[i]); - memset(_sjisOverlayPtrs[i], _sjisInvisibleColor, SCREEN_OVL_SJIS_SIZE); - } - } - if (_useSJIS) { - if (!_sjisFontData) { - _sjisFontData = _vm->resource()->fileData("FMT_FNT.ROM", 0); - if (!_sjisFontData) - error("missing font rom ('FMT_FNT.ROM') required for this version"); - } - - if (!_sjisTempPage) { - _sjisTempPage = new uint8[420]; - assert(_sjisTempPage); - _sjisTempPage2 = _sjisTempPage + 60; - _sjisSourceChar = _sjisTempPage + 384; - } - } } else { _system->beginGFXTransaction(); _vm->initCommonGFX(false); @@ -1181,7 +1183,7 @@ void Screen::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int &Screen::drawShapePlotType0, // used by Kyra 1 + 2 &Screen::drawShapePlotType1, // used by Kyra 3 0, - &Screen::drawShapePlotType3_7, // used by Kyra 1 (invisibility) + &Screen::drawShapePlotType3_7, // used by Kyra 3 (shadow) &Screen::drawShapePlotType4, // used by Kyra 1, 2 + 3 &Screen::drawShapePlotType5, // used by Kyra 1 &Screen::drawShapePlotType6, // used by Kyra 1 (invisibility) @@ -1189,7 +1191,7 @@ void Screen::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int &Screen::drawShapePlotType8, // used by Kyra 2 &Screen::drawShapePlotType9, // used by Kyra 1 + 3 0, - &Screen::drawShapePlotType11_15, // used by Kyra 1 /invisibility) + &Screen::drawShapePlotType11_15, // used by Kyra 1 (invisibility) + Kyra 3 (shadow) &Screen::drawShapePlotType12, // used by Kyra 2 &Screen::drawShapePlotType13, // used by Kyra 1 &Screen::drawShapePlotType14, // used by Kyra 1 (invisibility) @@ -1635,7 +1637,7 @@ void Screen::drawShapePlotType1(uint8 *dst, uint8 cmd) { } void Screen::drawShapePlotType3_7(uint8 *dst, uint8 cmd) { - cmd = dst[cmd]; + cmd = *dst; for (int i = 0; i < _dsTableLoopCount; ++i) cmd = _dsTable[cmd]; @@ -3110,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<uint16>(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 ed69e9260e..bf23747daf 100644 --- a/engines/kyra/screen.h +++ b/engines/kyra/screen.h @@ -36,7 +36,11 @@ namespace Kyra { typedef Common::Functor0<void> UpdateFunctor; class KyraEngine; -struct Rect; + +struct Rect { + int x, y; + int x2, y2; +}; struct ScreenDim { uint16 sx; @@ -59,9 +63,7 @@ struct Font { }; class Screen { - friend class Debugger_v1; public: - enum { SCREEN_W = 320, SCREEN_H = 200, @@ -97,7 +99,10 @@ public: Screen(KyraEngine *vm, OSystem *system); virtual ~Screen(); + // init virtual bool init(); + virtual void setResolution(); + void updateScreen(); @@ -349,48 +354,10 @@ protected: int _drawShapeVar4; int _drawShapeVar5; - // init - virtual void setResolution(); - // debug 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_v3.cpp b/engines/kyra/screen_mr.cpp index 938307b774..4cea50927c 100644 --- a/engines/kyra/screen_v3.cpp +++ b/engines/kyra/screen_mr.cpp @@ -23,32 +23,32 @@ * */ -#include "kyra/screen_v3.h" +#include "kyra/screen_mr.h" -#include "kyra/kyra_v3.h" +#include "kyra/kyra_mr.h" namespace Kyra { -Screen_v3::Screen_v3(KyraEngine_v3 *vm, OSystem *system) : ScreenEx(vm, system) { +Screen_MR::Screen_MR(KyraEngine_MR *vm, OSystem *system) : Screen_v2(vm, system) { } -Screen_v3::~Screen_v3() { +Screen_MR::~Screen_MR() { } -void Screen_v3::setScreenDim(int dim) { - debugC(9, kDebugLevelScreen, "Screen_v3::setScreenDim(%d)", dim); +void Screen_MR::setScreenDim(int dim) { + debugC(9, kDebugLevelScreen, "Screen_MR::setScreenDim(%d)", dim); assert(dim < _screenDimTableCount); _curDim = &_screenDimTable[dim]; } -const ScreenDim *Screen_v3::getScreenDim(int dim) { - debugC(9, kDebugLevelScreen, "Screen_v3::getScreenDim(%d)", dim); +const ScreenDim *Screen_MR::getScreenDim(int dim) { + debugC(9, kDebugLevelScreen, "Screen_MR::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); +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) @@ -72,8 +72,8 @@ int Screen_v3::getLayer(int x, int y) { return pixel; } -byte Screen_v3::getShapeFlag1(int x, int y) { - debugC(9, kDebugLevelScreen, "Screen_v3::getShapeFlag1(%d, %d)", x, y); +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; @@ -86,8 +86,8 @@ byte Screen_v3::getShapeFlag1(int x, int y) { return 0; } -byte Screen_v3::getShapeFlag2(int x, int y) { - debugC(9, kDebugLevelScreen, "Screen_v3::getShapeFlag2(%d, %d)", x, y); +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; @@ -97,8 +97,8 @@ byte Screen_v3::getShapeFlag2(int x, int y) { return color; } -int Screen_v3::getDrawLayer(int x, int y) { - debugC(9, kDebugLevelScreen, "Screen_v3::getDrawLayer(%d, %d)", x, y); +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; @@ -115,8 +115,8 @@ int Screen_v3::getDrawLayer(int x, int y) { 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 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; @@ -135,4 +135,18 @@ int Screen_v3::getDrawLayer2(int x, int y, int height) { return layer; } +void Screen_MR::drawFilledBox(int x1, int y1, int x2, int y2, uint8 c1, uint8 c2, uint8 c3) { + debugC(9, kDebugLevelScreen, "Screen_MR::drawFilledBox(%d, %d, %d, %d, %d, %d, %d,)", x1, y1, x2, y2, c1, c2, c3); + + fillRect(x1, y1, x2, y2, c1); + + fillRect(x1, y1, x2, y1+1, c2); + fillRect(x2-1, y1, x2, y2, c2); + + drawClippedLine(x1, y1, x1, y2, c3); + drawClippedLine(x1+1, y1+1, x1+1, y2-2, c3); + drawClippedLine(x1, y2, x2, y2, c3); + drawClippedLine(x1, y2-1, x2-1, y2-1, c3); +} + } // end of namespace Kyra diff --git a/engines/kyra/screen_v3.h b/engines/kyra/screen_mr.h index dc49268ad6..7fbcbdcb6e 100644 --- a/engines/kyra/screen_v3.h +++ b/engines/kyra/screen_mr.h @@ -23,22 +23,22 @@ * */ -#ifndef KYRA_SCREEN_V3_H -#define KYRA_SCREEN_V3_H +#ifndef KYRA_SCREEN_MR_H +#define KYRA_SCREEN_MR_H -#include "kyra/screen.h" +#include "kyra/screen_v2.h" namespace Kyra { -class KyraEngine_v3; +class KyraEngine_MR; -class Screen_v3 : public ScreenEx { +class Screen_MR : public Screen_v2 { public: - Screen_v3(KyraEngine_v3 *vm, OSystem *system); - virtual ~Screen_v3(); + Screen_MR(KyraEngine_MR *vm, OSystem *system); + ~Screen_MR(); - virtual void setScreenDim(int dim); - virtual const ScreenDim *getScreenDim(int dim); + void setScreenDim(int dim); + const ScreenDim *getScreenDim(int dim); int getLayer(int x, int y); @@ -47,6 +47,8 @@ public: int getDrawLayer(int x, int y); int getDrawLayer2(int x, int y, int height); + + void drawFilledBox(int x1, int y1, int x2, int y2, uint8 c1, uint8 c2, uint8 c3); private: static const ScreenDim _screenDimTable[]; static const int _screenDimTableCount; diff --git a/engines/kyra/screen_v2.cpp b/engines/kyra/screen_v2.cpp index f3eb840ca2..704296c534 100644 --- a/engines/kyra/screen_v2.cpp +++ b/engines/kyra/screen_v2.cpp @@ -11,7 +11,7 @@ * 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 + * 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 @@ -23,256 +23,314 @@ * */ -#include "common/endian.h" - -#include "kyra/kyra_v2.h" #include "kyra/screen_v2.h" +#include "common/endian.h" + namespace Kyra { -Screen_v2::Screen_v2(KyraEngine_v2 *vm, OSystem *system) - : ScreenEx(vm, system) { - _vm = vm; - _wsaFrameAnimBuffer = new uint8[1024]; -} +uint8 *Screen_v2::generateOverlay(const uint8 *palette, uint8 *buffer, int startColor, uint16 factor) { + if (!palette || !buffer) + return buffer; -Screen_v2::~Screen_v2() { - delete [] _wsaFrameAnimBuffer; -} + factor = MIN<uint16>(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]; -void Screen_v2::setScreenDim(int dim) { - debugC(9, kDebugLevelScreen, "Screen_v2::setScreenDim(%d)", dim); - assert(dim < _screenDimTableCount); - _curDim = &_screenDimTable[dim]; + 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; } -const ScreenDim *Screen_v2::getScreenDim(int dim) { - debugC(9, kDebugLevelScreen, "Screen_v2::getScreenDim(%d)", dim); - assert(dim < _screenDimTableCount); - return &_screenDimTable[dim]; +void Screen_v2::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; + } } -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; +int Screen_v2::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; } } - for (int i = 0; i < lastColor; i++) - grayOverlay[i] = findLeastDifferentColor(tmpPal + 3 * i, srcPal, lastColor); + return r; } -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) { +void Screen_v2::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; + } + } - if (!(w1 || h1 || w2 || h2)) + temp = dimY2 - y; + if (temp <= 0) return; - ScreenDim cdm = _screenDimTable[dim]; - cdm.sx <<= 3; - cdm.w <<= 3; + if (temp < h) + h = temp; - int na = 0, nb = 0, nc = w2; - - if (!calcBounds(cdm.w, cdm.h, x2, y2, w2, h2, na, nb, nc)) - return; + int srcOffset = 0; + temp = x - dimX1; + if (temp < 0) { + temp = -temp; + srcOffset = temp; + x += temp; + w -= temp; + } - const uint8 *src = getPagePtr(srcPage) + y1 * 320; - uint8 *dst = getPagePtr(dstPage) + (y2 + cdm.sy) * 320; + int srcAdd = 0; - int u = -1; + temp = dimX2 - x; + if (temp <= 0) + return; - do { - int t = (nb * h1) / h2; - if (t != u) { - u = t; - const uint8 *s = src + (x1 + t) * 320; - uint8 *dt = (uint8*) _wsaFrameAnimBuffer; + if (temp < w) { + SWAP(w, temp); + temp -= w; + srcAdd = temp; + } - 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; - } + 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; } - } else { - if (w2 == 1) { - *dt = *s; + ++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 { - 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); - } + d = _shapePages[1][dst - origDst]; + *dst++ = d; } } - } - memcpy(dst + x2 + cdm.sx, _wsaFrameAnimBuffer + na, w2); - dst += 320; - } while (++nb < h2); -} + break; -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; + default: + break; + } - int r1, r2, r3, r4, r5, r6; + dst = (dstPtr += SCREEN_W); + src += srcAdd; + } +} - int X1 = srcX; - int Y1 = srcY; - int W1 = cmpW; - int H1 = cmpH; +const uint8 *Screen_v2::getPtrToShape(const uint8 *shpFile, int shape) { + debugC(9, kDebugLevelScreen, "Screen_v2::getPtrToShape(%p, %d)", (const void *)shpFile, shape); + uint16 shapes = READ_LE_UINT16(shpFile); - if (!calcBounds(srcW, srcH, X1, Y1, W1, H1, r1, r2, r3)) - return; + if (shapes <= shape) + return 0; - int X2 = dstX; - int Y2 = dstY; - int W2 = W1; - int H2 = H1; + uint32 offset = READ_LE_UINT32(shpFile + (shape << 2) + 2); - if (!calcBounds(dstW, dstH, X2, Y2, W2, H2, r4, r5, r6)) - return; + return shpFile + offset + 2; +} - const uint8 *src = getPagePtr(srcPage) + srcW * (Y1 + r5); - uint8 *dst = getPagePtr(dstPage) + dstW * (Y2 + r2); - const uint8 *cmp = getPagePtr(cmpPage); +uint8 *Screen_v2::getPtrToShape(uint8 *shpFile, int shape) { + debugC(9, kDebugLevelScreen, "Screen_v2::getPtrToShape(%p, %d)", (void *)shpFile, shape); + uint16 shapes = READ_LE_UINT16(shpFile); - while (H2--) { - const uint8 *s = src + r4 + X1; - uint8 *d = dst + r1 + X2; + if (shapes <= shape) + return 0; - for (int i = 0; i < W2; i++) { - int ix = (*s++ << 8) + *d; - *d++ = cmp[ix]; - } + uint32 offset = READ_LE_UINT32(shpFile + (shape << 2) + 2); - src += W1; - dst += W2; - } + return shpFile + offset + 2; } -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); +int Screen_v2::getShapeScaledWidth(const uint8 *shpFile, int scale) { + debugC(9, kDebugLevelScreen, "Screen_v2::getShapeScaledWidth(%p, %d)", (const void*)shpFile, scale); + int width = READ_LE_UINT16(shpFile+3); + return (width * scale) >> 8; } +int Screen_v2::getShapeScaledHeight(const uint8 *shpFile, int scale) { + debugC(9, kDebugLevelScreen, "Screen_v2::getShapeScaledHeight(%p, %d)", (const void*)shpFile, scale); + int height = shpFile[2]; + return (height * scale) >> 8; +} -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; +uint16 Screen_v2::getShapeSize(const uint8 *shp) { + debugC(9, kDebugLevelScreen, "Screen_v2::getShapeSize(%p)", (const void *)shp); - int x2, y2, w2; + return READ_LE_UINT16(shp+6); +} - calcBounds(w0, h0, x1, y1, w1, h1, x2, y2, w2); +uint8 *Screen_v2::makeShapeCopy(const uint8 *src, int index) { + debugC(9, kDebugLevelScreen, "Screen_v2::makeShapeCopy(%p, %d)", (const void *)src, index); - const uint8 *src = getPagePtr(srcPage) + (320 * srcH) + srcW; - uint8 *dst = getPagePtr(dstPage) + 320 * (y0 + y1); + const uint8 *shape = getPtrToShape(src, index); + int size = getShapeSize(shape); - for (int y = 0; y < h1; y++) { - const uint8 *s = src + x2; - uint8 *d = dst + x0 + x1; + uint8 *copy = new uint8[size]; + assert(copy); + memcpy(copy, shape, size); - if (flag) - d += (h1 >> 1); + return copy; +} - for (int x = 0; x < w1; x++) { - if (*s) - *d = *s; - s++; - d++; - } - dst += 320; - src += 320; - } +int Screen_v2::getLayer(int x, int y) { + debugC(9, kDebugLevelScreen, "Screen_v2::getLayer(%d, %d)", x, 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; } -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; - } - } - } - } - } +int Screen_v2::getRectSize(int w, int h) { + debugC(9, kDebugLevelScreen, "Screen_v2::getRectSize(%d, %d)", w, h); + if (w > 320 || h > 200) + return 0; + return w*h; +} - return (w1 == -1) ? false : true; +void Screen_v2::setTextColorMap(const uint8 *cmap) { + debugC(9, kDebugLevelScreen, "Screen_v2::setTextColorMap(%p)", (const void *)cmap); + setTextColor(cmap, 0, 15); } } // end of namespace Kyra diff --git a/engines/kyra/screen_v2.h b/engines/kyra/screen_v2.h index 665f71ace4..5679dadf39 100644 --- a/engines/kyra/screen_v2.h +++ b/engines/kyra/screen_v2.h @@ -11,7 +11,7 @@ * 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 + * 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 @@ -27,36 +27,46 @@ #define KYRA_SCREEN_V2_H #include "kyra/screen.h" +#include "kyra/kyra_v2.h" namespace Kyra { -class KyraEngine_v2; - -class Screen_v2 : public ScreenEx { -friend class Debugger_v2; +class Screen_v2 : public Screen { 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; + Screen_v2(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 +} // end of namespace Kyra + +#endif -#endif diff --git a/engines/kyra/script.cpp b/engines/kyra/script.cpp index 8db71a7b5e..e9dc34e581 100644 --- a/engines/kyra/script.cpp +++ b/engines/kyra/script.cpp @@ -33,8 +33,8 @@ #include "kyra/script.h" namespace Kyra { -ScriptHelper::ScriptHelper(KyraEngine *vm) : _vm(vm) { -#define COMMAND(x) { &ScriptHelper::x, #x } +EMCInterpreter::EMCInterpreter(KyraEngine *vm) : _vm(vm) { +#define COMMAND(x) { &EMCInterpreter::x, #x } static CommandEntry commandProcs[] = { // 0x00 COMMAND(cmd_jmpTo), @@ -65,14 +65,14 @@ ScriptHelper::ScriptHelper(KyraEngine *vm) : _vm(vm) { #undef COMMAND } -bool ScriptHelper::loadScript(const char *filename, ScriptData *scriptData, const Common::Array<const Opcode*> *opcodes) { +bool EMCInterpreter::load(const char *filename, EMCData *scriptData, const Common::Array<const Opcode*> *opcodes) { ScriptFileParser file(filename, _vm->resource()); if (!file) { error("Couldn't open script file '%s'", filename); return false; } - memset(scriptData, 0, sizeof(ScriptData)); + memset(scriptData, 0, sizeof(EMCData)); uint32 formBlockSize = file.getFORMBlockSize(); if (formBlockSize == (uint32)-1) { @@ -85,7 +85,7 @@ bool ScriptHelper::loadScript(const char *filename, ScriptData *scriptData, cons scriptData->text = new byte[chunkSize]; if (!file.loadIFFBlock(TEXT_CHUNK, scriptData->text, chunkSize)) { - unloadScript(scriptData); + unload(scriptData); error("Couldn't load TEXT chunk from file: '%s'", filename); return false; } @@ -93,7 +93,7 @@ bool ScriptHelper::loadScript(const char *filename, ScriptData *scriptData, cons chunkSize = file.getIFFBlockSize(ORDR_CHUNK); if (chunkSize == (uint32)-1) { - unloadScript(scriptData); + unload(scriptData); error("No ORDR chunk found in file: '%s'", filename); return false; } @@ -102,7 +102,7 @@ bool ScriptHelper::loadScript(const char *filename, ScriptData *scriptData, cons scriptData->ordr = new uint16[chunkSize]; if (!file.loadIFFBlock(ORDR_CHUNK, scriptData->ordr, chunkSize << 1)) { - unloadScript(scriptData); + unload(scriptData); error("Couldn't load ORDR chunk from file: '%s'", filename); return false; } @@ -112,7 +112,7 @@ bool ScriptHelper::loadScript(const char *filename, ScriptData *scriptData, cons chunkSize = file.getIFFBlockSize(DATA_CHUNK); if (chunkSize == (uint32)-1) { - unloadScript(scriptData); + unload(scriptData); error("No DATA chunk found in file: '%s'", filename); return false; } @@ -121,7 +121,7 @@ bool ScriptHelper::loadScript(const char *filename, ScriptData *scriptData, cons scriptData->data = new uint16[chunkSize]; if (!file.loadIFFBlock(DATA_CHUNK, scriptData->data, chunkSize << 1)) { - unloadScript(scriptData); + unload(scriptData); error("Couldn't load DATA chunk from file: '%s'", filename); return false; } @@ -135,7 +135,7 @@ bool ScriptHelper::loadScript(const char *filename, ScriptData *scriptData, cons return true; } -void ScriptHelper::unloadScript(ScriptData *data) { +void EMCInterpreter::unload(EMCData *data) { if (!data) return; @@ -147,7 +147,7 @@ void ScriptHelper::unloadScript(ScriptData *data) { data->ordr = data->data = 0; } -void ScriptHelper::initScript(ScriptState *scriptStat, const ScriptData *data) { +void EMCInterpreter::init(EMCState *scriptStat, const EMCData *data) { scriptStat->dataPtr = data; scriptStat->ip = 0; scriptStat->stack[60] = 0; @@ -155,7 +155,7 @@ void ScriptHelper::initScript(ScriptState *scriptStat, const ScriptData *data) { scriptStat->sp = 60; } -bool ScriptHelper::startScript(ScriptState *script, int function) { +bool EMCInterpreter::start(EMCState *script, int function) { if (!script->dataPtr) return false; @@ -175,13 +175,13 @@ bool ScriptHelper::startScript(ScriptState *script, int function) { return true; } -bool ScriptHelper::validScript(ScriptState *script) { +bool EMCInterpreter::isValid(EMCState *script) { if (!script->ip || !script->dataPtr || _vm->quit()) return false; return true; } -bool ScriptHelper::runScript(ScriptState *script) { +bool EMCInterpreter::run(EMCState *script) { _parameter = 0; if (!script->ip) @@ -207,7 +207,7 @@ bool ScriptHelper::runScript(ScriptState *script) { if (opcode > 18) { error("Script unknown command: %d", opcode); } else { - debugC(5, kDebugLevelScript, "[0x%.08X] ScriptHelper::%s([%d/%u])", instOffset, _commands[opcode].desc, _parameter, (uint)_parameter); + debugC(5, kDebugLevelScript, "[0x%.08X] EMCInterpreter::%s([%d/%u])", instOffset, _commands[opcode].desc, _parameter, (uint)_parameter); (this->*(_commands[opcode].proc))(script); } @@ -295,15 +295,15 @@ bool ScriptFileParser::loadIFFBlock(const uint32 chunkName, void *loadTo, uint32 #pragma mark - Command implementations #pragma mark - -void ScriptHelper::cmd_jmpTo(ScriptState* script) { +void EMCInterpreter::cmd_jmpTo(EMCState* script) { script->ip = script->dataPtr->data + _parameter; } -void ScriptHelper::cmd_setRetValue(ScriptState* script) { +void EMCInterpreter::cmd_setRetValue(EMCState* script) { script->retValue = _parameter; } -void ScriptHelper::cmd_pushRetOrPos(ScriptState* script) { +void EMCInterpreter::cmd_pushRetOrPos(EMCState* script) { switch (_parameter) { case 0: script->stack[--script->sp] = script->retValue; @@ -321,23 +321,23 @@ void ScriptHelper::cmd_pushRetOrPos(ScriptState* script) { } } -void ScriptHelper::cmd_push(ScriptState* script) { +void EMCInterpreter::cmd_push(EMCState* script) { script->stack[--script->sp] = _parameter; } -void ScriptHelper::cmd_pushReg(ScriptState* script) { +void EMCInterpreter::cmd_pushReg(EMCState* script) { script->stack[--script->sp] = script->regs[_parameter]; } -void ScriptHelper::cmd_pushBPNeg(ScriptState* script) { +void EMCInterpreter::cmd_pushBPNeg(EMCState* script) { script->stack[--script->sp] = script->stack[(-(int32)(_parameter + 2)) + script->bp]; } -void ScriptHelper::cmd_pushBPAdd(ScriptState* script) { +void EMCInterpreter::cmd_pushBPAdd(EMCState* script) { script->stack[--script->sp] = script->stack[(_parameter - 1) + script->bp]; } -void ScriptHelper::cmd_popRetOrPos(ScriptState* script) { +void EMCInterpreter::cmd_popRetOrPos(EMCState* script) { switch (_parameter) { case 0: script->retValue = script->stack[script->sp++]; @@ -358,27 +358,27 @@ void ScriptHelper::cmd_popRetOrPos(ScriptState* script) { } } -void ScriptHelper::cmd_popReg(ScriptState* script) { +void EMCInterpreter::cmd_popReg(EMCState* script) { script->regs[_parameter] = script->stack[script->sp++]; } -void ScriptHelper::cmd_popBPNeg(ScriptState* script) { +void EMCInterpreter::cmd_popBPNeg(EMCState* script) { script->stack[(-(int32)(_parameter + 2)) + script->bp] = script->stack[script->sp++]; } -void ScriptHelper::cmd_popBPAdd(ScriptState* script) { +void EMCInterpreter::cmd_popBPAdd(EMCState* script) { script->stack[(_parameter - 1) + script->bp] = script->stack[script->sp++]; } -void ScriptHelper::cmd_addSP(ScriptState* script) { +void EMCInterpreter::cmd_addSP(EMCState* script) { script->sp += _parameter; } -void ScriptHelper::cmd_subSP(ScriptState* script) { +void EMCInterpreter::cmd_subSP(EMCState* script) { script->sp -= _parameter; } -void ScriptHelper::cmd_execOpcode(ScriptState* script) { +void EMCInterpreter::cmd_execOpcode(EMCState* script) { uint8 opcode = _parameter; assert(script->dataPtr->opcodes); @@ -392,14 +392,14 @@ void ScriptHelper::cmd_execOpcode(ScriptState* script) { } } -void ScriptHelper::cmd_ifNotJmp(ScriptState* script) { +void EMCInterpreter::cmd_ifNotJmp(EMCState* script) { if (!script->stack[script->sp++]) { _parameter &= 0x7FFF; script->ip = script->dataPtr->data + _parameter; } } -void ScriptHelper::cmd_negate(ScriptState* script) { +void EMCInterpreter::cmd_negate(EMCState* script) { int16 value = script->stack[script->sp]; switch (_parameter) { case 0: @@ -424,7 +424,7 @@ void ScriptHelper::cmd_negate(ScriptState* script) { } } -void ScriptHelper::cmd_eval(ScriptState* script) { +void EMCInterpreter::cmd_eval(EMCState* script) { int16 ret = 0; bool error = false; @@ -540,7 +540,7 @@ void ScriptHelper::cmd_eval(ScriptState* script) { script->stack[--script->sp] = ret; } -void ScriptHelper::cmd_setRetAndJmp(ScriptState* script) { +void EMCInterpreter::cmd_setRetAndJmp(EMCState* script) { if (script->sp >= 60) { script->ip = 0; } else { diff --git a/engines/kyra/script.h b/engines/kyra/script.h index bc92aebc5e..df86ec79c3 100644 --- a/engines/kyra/script.h +++ b/engines/kyra/script.h @@ -31,10 +31,10 @@ namespace Kyra { -struct ScriptState; -typedef Common::Functor1<ScriptState*, int> Opcode; +struct EMCState; +typedef Common::Functor1<EMCState*, int> Opcode; -struct ScriptData { +struct EMCData { byte *text; uint16 *data; uint16 *ordr; @@ -43,9 +43,9 @@ struct ScriptData { const Common::Array<const Opcode*> *opcodes; }; -struct ScriptState { +struct EMCState { uint16 *ip; - const ScriptData *dataPtr; + const EMCData *dataPtr; int16 retValue; uint16 bp; uint16 sp; @@ -87,24 +87,24 @@ private: uint32 _endOffset; }; -class ScriptHelper { +class EMCInterpreter { public: - ScriptHelper(KyraEngine *vm); + EMCInterpreter(KyraEngine *vm); - bool loadScript(const char *filename, ScriptData *data, const Common::Array<const Opcode*> *opcodes); - void unloadScript(ScriptData *data); + bool load(const char *filename, EMCData *data, const Common::Array<const Opcode*> *opcodes); + void unload(EMCData *data); - void initScript(ScriptState *scriptState, const ScriptData *data); - bool startScript(ScriptState *script, int function); + void init(EMCState *scriptState, const EMCData *data); + bool start(EMCState *script, int function); - bool validScript(ScriptState *script); + bool isValid(EMCState *script); - bool runScript(ScriptState *script); + bool run(EMCState *script); protected: KyraEngine *_vm; int16 _parameter; - typedef void (ScriptHelper::*CommandProc)(ScriptState*); + typedef void (EMCInterpreter::*CommandProc)(EMCState*); struct CommandEntry { CommandProc proc; const char *desc; @@ -112,24 +112,24 @@ protected: const CommandEntry *_commands; private: - void cmd_jmpTo(ScriptState*); - void cmd_setRetValue(ScriptState*); - void cmd_pushRetOrPos(ScriptState*); - void cmd_push(ScriptState*); - void cmd_pushReg(ScriptState*); - void cmd_pushBPNeg(ScriptState*); - void cmd_pushBPAdd(ScriptState*); - void cmd_popRetOrPos(ScriptState*); - void cmd_popReg(ScriptState*); - void cmd_popBPNeg(ScriptState*); - void cmd_popBPAdd(ScriptState*); - void cmd_addSP(ScriptState*); - void cmd_subSP(ScriptState*); - void cmd_execOpcode(ScriptState*); - void cmd_ifNotJmp(ScriptState*); - void cmd_negate(ScriptState*); - void cmd_eval(ScriptState*); - void cmd_setRetAndJmp(ScriptState*); + void cmd_jmpTo(EMCState*); + void cmd_setRetValue(EMCState*); + void cmd_pushRetOrPos(EMCState*); + void cmd_push(EMCState*); + void cmd_pushReg(EMCState*); + void cmd_pushBPNeg(EMCState*); + void cmd_pushBPAdd(EMCState*); + void cmd_popRetOrPos(EMCState*); + void cmd_popReg(EMCState*); + void cmd_popBPNeg(EMCState*); + void cmd_popBPAdd(EMCState*); + void cmd_addSP(EMCState*); + void cmd_subSP(EMCState*); + void cmd_execOpcode(EMCState*); + void cmd_ifNotJmp(EMCState*); + void cmd_negate(EMCState*); + void cmd_eval(EMCState*); + void cmd_setRetAndJmp(EMCState*); }; } // end of namespace Kyra diff --git a/engines/kyra/script_hof.cpp b/engines/kyra/script_hof.cpp new file mode 100644 index 0000000000..ff28e08960 --- /dev/null +++ b/engines/kyra/script_hof.cpp @@ -0,0 +1,1735 @@ +/* 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_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_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_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_removeSlotFromInventory(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_removeSlotFromInventory(%p) (%d)", (const void *)script, stackPos(0)); + removeSlotFromInventory(stackPos(0)); + return 0; +} + +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) + removeSlotFromInventory(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_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_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)); + loadCharacterShapes(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 != 0); + + 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_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_enterNewScene(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_enterNewScene(%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 = false; + enterNewScene(stackPos(0), _mainCharacter.facing, 0, 0, 0); + _noScriptEnter = true; + return 0; +} + +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_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_isAnySoundPlaying(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_isAnySoundPlaying(%p) ()", (const void *)script); + return _sound->voiceIsPlaying(); +} + +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 :-) + _showOutro = 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_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_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_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_changeChapter(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_changeChapter(%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)); + loadCharacterShapes(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_resetInputColorCode(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_resetInputColorCode(%p)", (const void *)script); + memset(_inputColorCode, 255, 7); + return 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_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_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::o2a_setCharacterFrame(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2a_setCharacterFrame(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + _animNewFrame = stackPos(0); + _animDelayTime = stackPos(1); + _animNeedUpdate = true; + 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<EMCState*, int, KyraEngine_HoF> 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<const TIM*, const uint16*, int, KyraEngine_HoF> 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<const Opcode*> *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_setCharacterFacingOverwrite); + 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_removeSlotFromInventory); + 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_enterNewScene); + 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_setDeathHandler); + 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_runAnimationScript); + 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_randomSceneChat); + Opcode(o2_setDlgIndex); + // 0x78 + Opcode(o2_getDlgIndex); + Opcode(o2_defineScene); + 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_changeChapter); + 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(_opcodesAnimation); + + // 0x00 + Opcode(o2a_setAnimationShapes); + Opcode(o2a_setCharacterFrame); + Opcode(o2_playSoundEffect); + Opcode(o2_fadeScenePal); + // 0x04 + _flags.isTalkie ? Opcode(o2a_setResetFrame) : Opcode(o2_dummy); + 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..8746ec83d7 --- /dev/null +++ b/engines/kyra/script_mr.cpp @@ -0,0 +1,1383 @@ +/* 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 _characterShapeFile; +} + +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_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_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<int16>(0, MIN<int16>(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_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_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_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_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)); + loadCharacterShapes(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_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_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_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_daggerWarning(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_daggerWarning(%p) ()", (const void *)script); + int selection = 1; + + _screen->hideMouse(); + _screen->copyRegionToBuffer(1, 0, 0, 320, 200, _screenBuffer); + int curPageBackUp = _screen->_curPage; + _screen->_curPage = 2; + + _screen->drawFilledBox(0, 0, 0x13F, 0xC7, 0xB4, 0xB3, 0xB6); + _screen->drawFilledBox(0xF, 0xAA, 0x68, 0xBA, 0xB4, 0xB3, 0xB6); + _screen->drawFilledBox(0x73, 0xAA, 0xCC, 0xBA, 0xB4, 0xB3, 0xB6); + _screen->drawFilledBox(0xD6, 0xAA, 0x12F, 0xBA, 0xB4, 0xB3, 0xB6); + + int y = 15; + for (int i = 100; i <= 107; ++i) { + const char *str = (const char *)getTableEntry(_cCodeFile, i); + int x = _text->getCenterStringX(str, 0, 0x13F); + _text->printText(str, x, y, 0xFF, 0xF0, 0x00); + y += 10; + } + y += 15; + for (int i = 110; i <= 113; ++i) { + const char *str = (const char *)getTableEntry(_cCodeFile, i); + int x = _text->getCenterStringX(str, 0, 0x13F); + _text->printText(str, x, y, 0xFF, 0xF0, 0x00); + y += 10; + } + + const char *str = 0; + int x = 0; + + str = (const char *)getTableEntry(_cCodeFile, 120); + x = _text->getCenterStringX(str, 0xF, 0x68); + _text->printText(str, x, 174, 0xFF, 0xF0, 0x00); + + str = (const char *)getTableEntry(_cCodeFile, 121); + x = _text->getCenterStringX(str, 0x73, 0xCC); + _text->printText(str, x, 174, 0xFF, 0xF0, 0x00); + + str = (const char *)getTableEntry(_cCodeFile, 122); + x = _text->getCenterStringX(str, 0xD6, 0x12F); + _text->printText(str, x, 174, 0xFF, 0xF0, 0x00); + + _screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0); + _screen->updateScreen(); + + _screen->_curPage = curPageBackUp; + _screen->showMouse(); + + while (!_quitFlag) { + int keys = checkInput(0); + removeInputTop(); + + if (keys == 198 || keys == 199) { + if (_mouseX >= 15 && _mouseX <= 104 && _mouseY >= 170 && _mouseY <= 186) { + selection = 1; + break; + } else if (_mouseX >= 115 && _mouseX <= 204 && _mouseY >= 170 && _mouseY <= 186) { + selection = 2; + break; + } else if (_mouseX >= 214 && _mouseX <= 303 && _mouseY >= 170 && _mouseY <= 186) { + selection = 3; + break; + } + } + + delay(10); + } + + restorePage3(); + _screen->copyBlockToPage(1, 0, 0, 320, 200, _screenBuffer); + return selection; +} + +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_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_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_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_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_dummy(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_dummy(%p) ()", (const void *)script); + return 0; +} + +#pragma mark - + +int KyraEngine_MR::o3a_setCharacterFrame(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3a_setCharacterFrame(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + static const uint8 frameTable[] = { + 0x58, 0xD8, 0xD8, 0x98, 0x78, 0x78, 0xB8, 0xB8 + }; + + _animNewFrame = stackPos(0); + if (_useFrameTable) + _animNewFrame += frameTable[_mainCharacter.facing]; + + _animDelayTime = stackPos(1); + _animNeedUpdate = true; + 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<EMCState*, int, KyraEngine_MR> 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<const Opcode*> *table = 0; + + SetOpcodeTable(_opcodes); + // 0x00 + Opcode(o3_getMalcolmShapes); + Opcode(o3_setCharacterPos); + Opcode(o3_defineObject); + Opcode(o3_refreshCharacter); + // 0x04 + Opcode(o2_getCharacterX); + Opcode(o2_getCharacterY); + Opcode(o2_getCharacterFacing); + Opcode(o2_getCharacterScene); + // 0x08 + Opcode(o3_getMalcolmsMood); + Opcode(o3_dummy); + Opcode(o3_dummy); + Opcode(o3_getCharacterFrameFromFacing); + // 0x0c + Opcode(o2_setCharacterFacingOverwrite); + Opcode(o2_trySceneChange); + Opcode(o2_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(o2_checkForItem); + Opcode(o3_dummy); + Opcode(o3_resetInventory); + Opcode(o2_defineItem); + // 0x24 + Opcode(o3_removeInventoryItemInstances); + Opcode(o3_countInventoryItemInstances); + Opcode(o3_npcChatSequence); + 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); + Opcode(o3_badConscienceChat); + Opcode(o3_wipeDownMouseItem); + Opcode(o3_dummy); + // 0x34 + Opcode(o3_setMalcolmsMood); + Opcode(o3_playSoundEffect); + Opcode(o3_dummy); + Opcode(o2_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(o2_update); + // 0x4c + Opcode(o3_removeItemInstances); + Opcode(o3_dummy); + Opcode(o3_disableInventory); + Opcode(o3_enableInventory); + // 0x50 + Opcode(o3_enterNewScene); + Opcode(o3_switchScene); + Opcode(o2_getShapeFlag1); + Opcode(o3_dummy); + // 0x54 + Opcode(o3_dummy); + Opcode(o3_dummy); + Opcode(o3_setMalcolmPos); + Opcode(o3_stopMusic); + // 0x58 + Opcode(o2_playWanderScoreViaMap); + Opcode(o3_playSoundEffect); + Opcode(o3_getScore); + Opcode(o3_daggerWarning); + // 0x5c + Opcode(o3_blockOutRegion); + Opcode(o3_dummy); + Opcode(o3_showSceneStringsMessage); + OpcodeUnImpl(); + // 0x60 + Opcode(o2_getRand); + Opcode(o3_dummy); + Opcode(o2_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(o2_waitForConfirmationClick); + // 0x6c + Opcode(o3_dummy); + Opcode(o2_defineRoomEntrance); + Opcode(o2_runAnimationScript); + Opcode(o2_setSpecialSceneScriptRunTime); + // 0x70 + Opcode(o3_defineSceneAnim); + Opcode(o3_dummy); + Opcode(o3_updateSceneAnim); + Opcode(o3_dummy); + // 0x74 + Opcode(o3_runActorScript); + Opcode(o3_runDialog); + Opcode(o2_randomSceneChat); + Opcode(o2_setDlgIndex); + // 0x78 + Opcode(o2_getDlgIndex); + Opcode(o2_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(o2_setSpecialSceneScriptState); + // 0x90 + Opcode(o2_clearSpecialSceneScriptState); + Opcode(o2_querySpecialSceneScriptState); + Opcode(o3_dummy); + Opcode(o2_setHiddenItemsEntry); + // 0x94 + Opcode(o2_getHiddenItemsEntry); + Opcode(o3_dummy); + Opcode(o3_dummy); + OpcodeUnImpl(); + // 0x98 + Opcode(o3_customChat); + Opcode(o3_customChatFinish); + Opcode(o3_setupSceneAnimObject); + Opcode(o3_removeSceneAnimObject); + // 0x9c + Opcode(o2_disableTimer); + Opcode(o2_enableTimer); + Opcode(o2_setTimerCountdown); + OpcodeUnImpl(); + // 0xa0 + Opcode(o3_dummy); + Opcode(o3_dummy); + Opcode(o3_dummy); + Opcode(o3_dummy); + // 0xa4 + OpcodeUnImpl(); + OpcodeUnImpl(); + OpcodeUnImpl(); + Opcode(o2_setVocHigh); + // 0xa8 + Opcode(o2_getVocHigh); + OpcodeUnImpl(); + OpcodeUnImpl(); + OpcodeUnImpl(); + // 0xac + OpcodeUnImpl(); + Opcode(o3_dummy); + OpcodeUnImpl(); + Opcode(o3_dummy); + + SetOpcodeTable(_opcodesAnimation); + // 0x00 + Opcode(o2a_setAnimationShapes); + Opcode(o3a_setCharacterFrame); + Opcode(o3_playSoundEffect); + Opcode(o3_dummy); + // 0x0a + Opcode(o2a_setResetFrame); + Opcode(o2_getRand); + Opcode(o3_getMalcolmShapes); + Opcode(o3_dummy); + + SetOpcodeTable(_opcodesDialog); + // 0x00 + Opcode(o3d_updateAnim); + Opcode(o3d_delay); + Opcode(o2_getRand); + Opcode(o2_queryGameFlag); + // 0x04 + Opcode(o3_dummy); +} + +} // end of namespace Kyra diff --git a/engines/kyra/script_v1.cpp b/engines/kyra/script_v1.cpp index 50ad1b8b0c..a258482802 100644 --- a/engines/kyra/script_v1.cpp +++ b/engines/kyra/script_v1.cpp @@ -37,13 +37,13 @@ #include "kyra/timer.h" namespace Kyra { -int KyraEngine_v1::o1_magicInMouseItem(ScriptState *script) { +int KyraEngine_v1::o1_magicInMouseItem(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_magicInMouseItem(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); magicInMouseItem(stackPos(0), stackPos(1), -1); return 0; } -int KyraEngine_v1::o1_characterSays(ScriptState *script) { +int KyraEngine_v1::o1_characterSays(EMCState *script) { _skipFlag = false; if (_flags.isTalkie) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_characterSays(%p) (%d, '%s', %d, %d)", (const void *)script, stackPos(0), stackPosString(1), stackPos(2), stackPos(3)); @@ -74,7 +74,7 @@ int KyraEngine_v1::o1_characterSays(ScriptState *script) { return 0; } -int KyraEngine_v1::o1_pauseTicks(ScriptState *script) { +int KyraEngine_v1::o1_pauseTicks(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_pauseTicks(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); if (stackPos(1)) { warning("STUB: special o1_pauseTicks"); @@ -86,33 +86,33 @@ int KyraEngine_v1::o1_pauseTicks(ScriptState *script) { return 0; } -int KyraEngine_v1::o1_drawSceneAnimShape(ScriptState *script) { +int KyraEngine_v1::o1_drawSceneAnimShape(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_drawSceneAnimShape(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); _screen->drawShape(stackPos(4), _sprites->_sceneShapes[stackPos(0)], stackPos(1), stackPos(2), 0, (stackPos(3) != 0) ? 1 : 0); return 0; } -int KyraEngine_v1::o1_queryGameFlag(ScriptState *script) { +int KyraEngine_v1::o1_queryGameFlag(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_queryGameFlag(%p) (0x%X)", (const void *)script, stackPos(0)); return queryGameFlag(stackPos(0)); } -int KyraEngine_v1::o1_setGameFlag(ScriptState *script) { +int KyraEngine_v1::o1_setGameFlag(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setGameFlag(%p) (0x%X)", (const void *)script, stackPos(0)); return setGameFlag(stackPos(0)); } -int KyraEngine_v1::o1_resetGameFlag(ScriptState *script) { +int KyraEngine_v1::o1_resetGameFlag(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_resetGameFlag(%p) (0x%X)", (const void *)script, stackPos(0)); return resetGameFlag(stackPos(0)); } -int KyraEngine_v1::o1_runNPCScript(ScriptState *script) { +int KyraEngine_v1::o1_runNPCScript(EMCState *script) { warning("STUB: o1_runNPCScript"); return 0; } -int KyraEngine_v1::o1_setSpecialExitList(ScriptState *script) { +int KyraEngine_v1::o1_setSpecialExitList(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setSpecialExitList(%p) (%d, %d, %d, %d, %d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7), stackPos(8), stackPos(9)); for (int i = 0; i < 10; ++i) @@ -122,19 +122,19 @@ int KyraEngine_v1::o1_setSpecialExitList(ScriptState *script) { return 0; } -int KyraEngine_v1::o1_blockInWalkableRegion(ScriptState *script) { +int KyraEngine_v1::o1_blockInWalkableRegion(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_blockInWalkableRegion(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); _screen->blockInRegion(stackPos(0), stackPos(1), stackPos(2)-stackPos(0)+1, stackPos(3)-stackPos(1)+1); return 0; } -int KyraEngine_v1::o1_blockOutWalkableRegion(ScriptState *script) { +int KyraEngine_v1::o1_blockOutWalkableRegion(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_blockOutWalkableRegion(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); _screen->blockOutRegion(stackPos(0), stackPos(1), stackPos(2)-stackPos(0)+1, stackPos(3)-stackPos(1)+1); return 0; } -int KyraEngine_v1::o1_walkPlayerToPoint(ScriptState *script) { +int KyraEngine_v1::o1_walkPlayerToPoint(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_walkPlayerToPoint(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); int normalTimers = stackPos(2); @@ -153,7 +153,7 @@ int KyraEngine_v1::o1_walkPlayerToPoint(ScriptState *script) { } if (reinitScript) - _scriptInterpreter->initScript(script, script->dataPtr); + _emc->init(script, script->dataPtr); if (_sceneChangeState) { _sceneChangeState = 0; @@ -162,7 +162,7 @@ int KyraEngine_v1::o1_walkPlayerToPoint(ScriptState *script) { return 0; } -int KyraEngine_v1::o1_dropItemInScene(ScriptState *script) { +int KyraEngine_v1::o1_dropItemInScene(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_dropItemInScene(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); int item = stackPos(0); int xpos = stackPos(1); @@ -187,7 +187,7 @@ int KyraEngine_v1::o1_dropItemInScene(ScriptState *script) { return 0; } -int KyraEngine_v1::o1_drawAnimShapeIntoScene(ScriptState *script) { +int KyraEngine_v1::o1_drawAnimShapeIntoScene(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_drawAnimShapeIntoScene(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); _screen->hideMouse(); _animator->restoreAllObjectBackgrounds(); @@ -205,49 +205,49 @@ int KyraEngine_v1::o1_drawAnimShapeIntoScene(ScriptState *script) { return 0; } -int KyraEngine_v1::o1_createMouseItem(ScriptState *script) { +int KyraEngine_v1::o1_createMouseItem(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_createMouseItem(%p) (%d)", (const void *)script, stackPos(0)); createMouseItem(stackPos(0)); return 0; } -int KyraEngine_v1::o1_savePageToDisk(ScriptState *script) { +int KyraEngine_v1::o1_savePageToDisk(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_savePageToDisk(%p) ('%s', %d)", (const void *)script, stackPosString(0), stackPos(1)); _screen->savePageToDisk(stackPosString(0), stackPos(1)); return 0; } -int KyraEngine_v1::o1_sceneAnimOn(ScriptState *script) { +int KyraEngine_v1::o1_sceneAnimOn(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_sceneAnimOn(%p) (%d)", (const void *)script, stackPos(0)); _sprites->_anims[stackPos(0)].play = true; return 0; } -int KyraEngine_v1::o1_sceneAnimOff(ScriptState *script) { +int KyraEngine_v1::o1_sceneAnimOff(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_sceneAnimOff(%p) (%d)", (const void *)script, stackPos(0)); _sprites->_anims[stackPos(0)].play = false; return 0; } -int KyraEngine_v1::o1_getElapsedSeconds(ScriptState *script) { +int KyraEngine_v1::o1_getElapsedSeconds(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_getElapsedSeconds(%p) ()", (const void *)script); return _system->getMillis() / 1000; } -int KyraEngine_v1::o1_mouseIsPointer(ScriptState *script) { +int KyraEngine_v1::o1_mouseIsPointer(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_mouseIsPointer(%p) ()", (const void *)script); if (_itemInHand == -1) return 1; return 0; } -int KyraEngine_v1::o1_destroyMouseItem(ScriptState *script) { +int KyraEngine_v1::o1_destroyMouseItem(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_destroyMouseItem(%p) ()", (const void *)script); destroyMouseItem(); return 0; } -int KyraEngine_v1::o1_runSceneAnimUntilDone(ScriptState *script) { +int KyraEngine_v1::o1_runSceneAnimUntilDone(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_runSceneAnimUntilDone(%p) (%d)", (const void *)script, stackPos(0)); _screen->hideMouse(); _animator->restoreAllObjectBackgrounds(); @@ -265,7 +265,7 @@ int KyraEngine_v1::o1_runSceneAnimUntilDone(ScriptState *script) { return 0; } -int KyraEngine_v1::o1_fadeSpecialPalette(ScriptState *script) { +int KyraEngine_v1::o1_fadeSpecialPalette(EMCState *script) { if (_flags.platform == Common::kPlatformAmiga) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_fadeSpecialPalette(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); if (_currentCharacter->sceneId != 45) { @@ -283,42 +283,42 @@ int KyraEngine_v1::o1_fadeSpecialPalette(ScriptState *script) { return 0; } -int KyraEngine_v1::o1_playAdlibSound(ScriptState *script) { +int KyraEngine_v1::o1_playAdlibSound(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_playAdlibSound(%p) (%d)", (const void *)script, stackPos(0)); snd_playSoundEffect(stackPos(0)); return 0; } -int KyraEngine_v1::o1_playAdlibScore(ScriptState *script) { +int KyraEngine_v1::o1_playAdlibScore(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_playAdlibScore(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); snd_playWanderScoreViaMap(stackPos(0), stackPos(1)); return 0; } -int KyraEngine_v1::o1_phaseInSameScene(ScriptState *script) { +int KyraEngine_v1::o1_phaseInSameScene(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_phaseInSameScene(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); transcendScenes(stackPos(0), stackPos(1)); return 0; } -int KyraEngine_v1::o1_setScenePhasingFlag(ScriptState *script) { +int KyraEngine_v1::o1_setScenePhasingFlag(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setScenePhasingFlag(%p) ()", (const void *)script); _scenePhasingFlag = 1; return 1; } -int KyraEngine_v1::o1_resetScenePhasingFlag(ScriptState *script) { +int KyraEngine_v1::o1_resetScenePhasingFlag(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_resetScenePhasingFlag(%p) ()", (const void *)script); _scenePhasingFlag = 0; return 0; } -int KyraEngine_v1::o1_queryScenePhasingFlag(ScriptState *script) { +int KyraEngine_v1::o1_queryScenePhasingFlag(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_queryScenePhasingFlag(%p) ()", (const void *)script); return _scenePhasingFlag; } -int KyraEngine_v1::o1_sceneToDirection(ScriptState *script) { +int KyraEngine_v1::o1_sceneToDirection(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_sceneToDirection(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); assert(stackPos(0) < _roomTableSize); Room *curRoom = &_roomTable[stackPos(0)]; @@ -348,7 +348,7 @@ int KyraEngine_v1::o1_sceneToDirection(ScriptState *script) { return returnValue; } -int KyraEngine_v1::o1_setBirthstoneGem(ScriptState *script) { +int KyraEngine_v1::o1_setBirthstoneGem(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setBirthstoneGem(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); int index = stackPos(0); if (index < 4 && index >= 0) { @@ -358,19 +358,19 @@ int KyraEngine_v1::o1_setBirthstoneGem(ScriptState *script) { return 0; } -int KyraEngine_v1::o1_placeItemInGenericMapScene(ScriptState *script) { +int KyraEngine_v1::o1_placeItemInGenericMapScene(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_placeItemInGenericMapScene(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); placeItemInGenericMapScene(stackPos(0), stackPos(1)); return 0; } -int KyraEngine_v1::o1_setBrandonStatusBit(ScriptState *script) { +int KyraEngine_v1::o1_setBrandonStatusBit(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setBrandonStatusBit(%p) (%d)", (const void *)script, stackPos(0)); _brandonStatusBit |= stackPos(0); return 0; } -int KyraEngine_v1::o1_pauseSeconds(ScriptState *script) { +int KyraEngine_v1::o1_pauseSeconds(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_pauseSeconds(%p) (%d)", (const void *)script, stackPos(0)); if (stackPos(0) > 0 && !_skipFlag) delay(stackPos(0)*1000, true); @@ -378,41 +378,41 @@ int KyraEngine_v1::o1_pauseSeconds(ScriptState *script) { return 0; } -int KyraEngine_v1::o1_getCharactersLocation(ScriptState *script) { +int KyraEngine_v1::o1_getCharactersLocation(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_getCharactersLocation(%p) (%d)", (const void *)script, stackPos(0)); return _characterList[stackPos(0)].sceneId; } -int KyraEngine_v1::o1_runNPCSubscript(ScriptState *script) { +int KyraEngine_v1::o1_runNPCSubscript(EMCState *script) { warning("STUB: o1_runNPCSubscript"); return 0; } -int KyraEngine_v1::o1_magicOutMouseItem(ScriptState *script) { +int KyraEngine_v1::o1_magicOutMouseItem(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_magicOutMouseItem(%p) (%d)", (const void *)script, stackPos(0)); magicOutMouseItem(stackPos(0), -1); return 0; } -int KyraEngine_v1::o1_internalAnimOn(ScriptState *script) { +int KyraEngine_v1::o1_internalAnimOn(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_internalAnimOn(%p) (%d)", (const void *)script, stackPos(0)); _animator->sprites()[stackPos(0)].active = 1; return 0; } -int KyraEngine_v1::o1_forceBrandonToNormal(ScriptState *script) { +int KyraEngine_v1::o1_forceBrandonToNormal(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_forceBrandonToNormal(%p) ()", (const void *)script); checkAmuletAnimFlags(); return 0; } -int KyraEngine_v1::o1_poisonDeathNow(ScriptState *script) { +int KyraEngine_v1::o1_poisonDeathNow(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_poisonDeathNow(%p) ()", (const void *)script); seq_poisonDeathNow(1); return 0; } -int KyraEngine_v1::o1_setScaleMode(ScriptState *script) { +int KyraEngine_v1::o1_setScaleMode(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setScaleMode(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); int len = stackPos(0); int setValue1 = stackPos(1); @@ -430,7 +430,7 @@ int KyraEngine_v1::o1_setScaleMode(ScriptState *script) { return _scaleMode; } -int KyraEngine_v1::o1_openWSAFile(ScriptState *script) { +int KyraEngine_v1::o1_openWSAFile(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_openWSAFile(%p) ('%s', %d, %d, %d)", (const void *)script, stackPosString(0), stackPos(1), stackPos(2), stackPos(3)); const char *filename = stackPosString(0); @@ -442,7 +442,7 @@ int KyraEngine_v1::o1_openWSAFile(ScriptState *script) { return 0; } -int KyraEngine_v1::o1_closeWSAFile(ScriptState *script) { +int KyraEngine_v1::o1_closeWSAFile(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_closeWSAFile(%p) (%d)", (const void *)script, stackPos(0)); int wsaIndex = stackPos(0); @@ -452,7 +452,7 @@ int KyraEngine_v1::o1_closeWSAFile(ScriptState *script) { return 0; } -int KyraEngine_v1::o1_runWSAFromBeginningToEnd(ScriptState *script) { +int KyraEngine_v1::o1_runWSAFromBeginningToEnd(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_runWSAFromBeginningToEnd(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); _screen->hideMouse(); @@ -493,7 +493,7 @@ int KyraEngine_v1::o1_runWSAFromBeginningToEnd(ScriptState *script) { return 0; } -int KyraEngine_v1::o1_displayWSAFrame(ScriptState *script) { +int KyraEngine_v1::o1_displayWSAFrame(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_displayWSAFrame(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); int frame = stackPos(0); int xpos = stackPos(1); @@ -520,13 +520,13 @@ int KyraEngine_v1::o1_displayWSAFrame(ScriptState *script) { return 0; } -int KyraEngine_v1::o1_enterNewScene(ScriptState *script) { +int KyraEngine_v1::o1_enterNewScene(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_enterNewScene(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); enterNewScene(stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); return 0; } -int KyraEngine_v1::o1_setSpecialEnterXAndY(ScriptState *script) { +int KyraEngine_v1::o1_setSpecialEnterXAndY(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setSpecialEnterXAndY(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); _brandonPosX = stackPos(0); _brandonPosY = stackPos(1); @@ -535,7 +535,7 @@ int KyraEngine_v1::o1_setSpecialEnterXAndY(ScriptState *script) { return 0; } -int KyraEngine_v1::o1_runWSAFrames(ScriptState *script) { +int KyraEngine_v1::o1_runWSAFrames(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_runWSAFrames(%p) (%d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5)); int xpos = stackPos(0); int ypos = stackPos(1); @@ -562,7 +562,7 @@ int KyraEngine_v1::o1_runWSAFrames(ScriptState *script) { return 0; } -int KyraEngine_v1::o1_popBrandonIntoScene(ScriptState *script) { +int KyraEngine_v1::o1_popBrandonIntoScene(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_popBrandonIntoScene(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); int changeScaleMode = stackPos(3); int xpos = (int16)(stackPos(0) & 0xFFFC); @@ -576,7 +576,7 @@ int KyraEngine_v1::o1_popBrandonIntoScene(ScriptState *script) { int yOffset = _defaultShapeTable[0].yOffset; int width = _defaultShapeTable[0].w << 3; int height = _defaultShapeTable[0].h; - AnimObject *curAnim = _animator->actors(); + Animator_v1::AnimObject *curAnim = _animator->actors(); if (changeScaleMode) { curAnim->x1 = _currentCharacter->x1; @@ -611,7 +611,7 @@ int KyraEngine_v1::o1_popBrandonIntoScene(ScriptState *script) { return 0; } -int KyraEngine_v1::o1_restoreAllObjectBackgrounds(ScriptState *script) { +int KyraEngine_v1::o1_restoreAllObjectBackgrounds(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_restoreAllObjectBackgrounds(%p) (%d)", (const void *)script, stackPos(0)); int disable = stackPos(0); int activeBackup = 0; @@ -625,20 +625,20 @@ int KyraEngine_v1::o1_restoreAllObjectBackgrounds(ScriptState *script) { return 0; } -int KyraEngine_v1::o1_setCustomPaletteRange(ScriptState *script) { +int KyraEngine_v1::o1_setCustomPaletteRange(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setCustomPaletteRange(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); memcpy(_screen->getPalette(1) + stackPos(1)*3, _specialPalettes[stackPos(0)], stackPos(2)*3); return 0; } -int KyraEngine_v1::o1_loadPageFromDisk(ScriptState *script) { +int KyraEngine_v1::o1_loadPageFromDisk(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_loadPageFromDisk(%p) ('%s', %d)", (const void *)script, stackPosString(0), stackPos(1)); _screen->loadPageFromDisk(stackPosString(0), stackPos(1)); _animator->_updateScreen = true; return 0; } -int KyraEngine_v1::o1_customPrintTalkString(ScriptState *script) { +int KyraEngine_v1::o1_customPrintTalkString(EMCState *script) { if (_flags.isTalkie) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_customPrintTalkString(%p) (%d, '%s', %d, %d, %d)", (const void *)script, stackPos(0), stackPosString(1), stackPos(2), stackPos(3), stackPos(4) & 0xFF); @@ -659,35 +659,35 @@ int KyraEngine_v1::o1_customPrintTalkString(ScriptState *script) { return 0; } -int KyraEngine_v1::o1_restoreCustomPrintBackground(ScriptState *script) { +int KyraEngine_v1::o1_restoreCustomPrintBackground(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_restoreCustomPrintBackground(%p) ()", (const void *)script); _text->restoreTalkTextMessageBkgd(2, 0); return 0; } -int KyraEngine_v1::o1_hideMouse(ScriptState *script) { +int KyraEngine_v1::o1_hideMouse(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_hideMouse(%p) ()", (const void *)script); _screen->hideMouse(); return 0; } -int KyraEngine_v1::o1_showMouse(ScriptState *script) { +int KyraEngine_v1::o1_showMouse(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_showMouse(%p) ()", (const void *)script); _screen->showMouse(); return 0; } -int KyraEngine_v1::o1_getCharacterX(ScriptState *script) { +int KyraEngine_v1::o1_getCharacterX(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_getCharacterX(%p) (%d)", (const void *)script, stackPos(0)); return _characterList[stackPos(0)].x1; } -int KyraEngine_v1::o1_getCharacterY(ScriptState *script) { +int KyraEngine_v1::o1_getCharacterY(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_getCharacterY(%p) (%d)", (const void *)script, stackPos(0)); return _characterList[stackPos(0)].y1; } -int KyraEngine_v1::o1_changeCharactersFacing(ScriptState *script) { +int KyraEngine_v1::o1_changeCharactersFacing(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_changeCharactersFacing(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); int character = stackPos(0); int facing = stackPos(1); @@ -705,7 +705,7 @@ int KyraEngine_v1::o1_changeCharactersFacing(ScriptState *script) { return 0; } -int KyraEngine_v1::o1_copyWSARegion(ScriptState *script) { +int KyraEngine_v1::o1_copyWSARegion(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_copyWSARegion(%p) (%d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5)); int xpos = stackPos(0); int ypos = stackPos(1); @@ -718,7 +718,7 @@ int KyraEngine_v1::o1_copyWSARegion(ScriptState *script) { return 0; } -int KyraEngine_v1::o1_printText(ScriptState *script) { +int KyraEngine_v1::o1_printText(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_printText(%p) ('%s', %d, %d, 0x%X, 0x%X)", (const void *)script, stackPosString(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); if (_flags.lang == Common::JA_JPN && stackPos(3) == 7) _screen->printText(stackPosString(0), stackPos(1), stackPos(2), 0, 0x80); @@ -728,18 +728,18 @@ int KyraEngine_v1::o1_printText(ScriptState *script) { return 0; } -int KyraEngine_v1::o1_random(ScriptState *script) { +int KyraEngine_v1::o1_random(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_random(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); assert(stackPos(0) < stackPos(1)); return _rnd.getRandomNumberRng(stackPos(0), stackPos(1)); } -int KyraEngine_v1::o1_loadSoundFile(ScriptState *script) { +int KyraEngine_v1::o1_loadSoundFile(EMCState *script) { warning("STUB: o1_loadSoundFile"); return 0; } -int KyraEngine_v1::o1_displayWSAFrameOnHidPage(ScriptState *script) { +int KyraEngine_v1::o1_displayWSAFrameOnHidPage(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_displayWSAFrameOnHidPage(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); int frame = stackPos(0); int xpos = stackPos(1); @@ -768,7 +768,7 @@ int KyraEngine_v1::o1_displayWSAFrameOnHidPage(ScriptState *script) { return 0; } -int KyraEngine_v1::o1_displayWSASequentialFrames(ScriptState *script) { +int KyraEngine_v1::o1_displayWSASequentialFrames(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_displayWSASequentialFrames(%p) (%d, %d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6)); int startFrame = stackPos(0); int endFrame = stackPos(1); @@ -844,7 +844,7 @@ int KyraEngine_v1::o1_displayWSASequentialFrames(ScriptState *script) { return 0; } -int KyraEngine_v1::o1_drawCharacterStanding(ScriptState *script) { +int KyraEngine_v1::o1_drawCharacterStanding(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_drawCharacterStanding(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); int character = stackPos(0); int animFrame = stackPos(1); @@ -859,13 +859,13 @@ int KyraEngine_v1::o1_drawCharacterStanding(ScriptState *script) { return 0; } -int KyraEngine_v1::o1_internalAnimOff(ScriptState *script) { +int KyraEngine_v1::o1_internalAnimOff(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_internalAnimOff(%p) (%d)", (const void *)script, stackPos(0)); _animator->sprites()[stackPos(0)].active = 0; return 0; } -int KyraEngine_v1::o1_changeCharactersXAndY(ScriptState *script) { +int KyraEngine_v1::o1_changeCharactersXAndY(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_changeCharactersXAndY(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); Character *ch = &_characterList[stackPos(0)]; int16 x = stackPos(1); @@ -881,25 +881,25 @@ int KyraEngine_v1::o1_changeCharactersXAndY(ScriptState *script) { return 0; } -int KyraEngine_v1::o1_clearSceneAnimatorBeacon(ScriptState *script) { +int KyraEngine_v1::o1_clearSceneAnimatorBeacon(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_clearSceneAnimatorBeacon(%p) ()", (const void *)script); _sprites->_sceneAnimatorBeaconFlag = 0; return 0; } -int KyraEngine_v1::o1_querySceneAnimatorBeacon(ScriptState *script) { +int KyraEngine_v1::o1_querySceneAnimatorBeacon(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_querySceneAnimatorBeacon(%p) ()", (const void *)script); return _sprites->_sceneAnimatorBeaconFlag; } -int KyraEngine_v1::o1_refreshSceneAnimator(ScriptState *script) { +int KyraEngine_v1::o1_refreshSceneAnimator(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_refreshSceneAnimator(%p) ()", (const void *)script); _sprites->updateSceneAnims(); _animator->updateAllObjectShapes(); return 0; } -int KyraEngine_v1::o1_placeItemInOffScene(ScriptState *script) { +int KyraEngine_v1::o1_placeItemInOffScene(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_placeItemInOffScene(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); int item = stackPos(0); int xpos = stackPos(1); @@ -918,7 +918,7 @@ int KyraEngine_v1::o1_placeItemInOffScene(ScriptState *script) { return 0; } -int KyraEngine_v1::o1_wipeDownMouseItem(ScriptState *script) { +int KyraEngine_v1::o1_wipeDownMouseItem(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_wipeDownMouseItem(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); _screen->hideMouse(); wipeDownMouseItem(stackPos(1), stackPos(2)); @@ -927,7 +927,7 @@ int KyraEngine_v1::o1_wipeDownMouseItem(ScriptState *script) { return 0; } -int KyraEngine_v1::o1_placeCharacterInOtherScene(ScriptState *script) { +int KyraEngine_v1::o1_placeCharacterInOtherScene(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_placeCharacterInOtherScene(%p) (%d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5)); int id = stackPos(0); int sceneId = stackPos(1); @@ -944,18 +944,18 @@ int KyraEngine_v1::o1_placeCharacterInOtherScene(ScriptState *script) { return 0; } -int KyraEngine_v1::o1_getKey(ScriptState *script) { +int KyraEngine_v1::o1_getKey(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_getKey(%p) ()", (const void *)script); waitForEvent(); return 0; } -int KyraEngine_v1::o1_specificItemInInventory(ScriptState *script) { +int KyraEngine_v1::o1_specificItemInInventory(EMCState *script) { warning("STUB: o1_specificItemInInventory"); return 0; } -int KyraEngine_v1::o1_popMobileNPCIntoScene(ScriptState *script) { +int KyraEngine_v1::o1_popMobileNPCIntoScene(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_popMobileNPCIntoScene(%p) (%d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), (int16)(stackPos(4) & 0xFFFC), (int8)(stackPos(5) & 0xFE)); int character = stackPos(0); int sceneId = stackPos(1); @@ -976,25 +976,25 @@ int KyraEngine_v1::o1_popMobileNPCIntoScene(ScriptState *script) { return 0; } -int KyraEngine_v1::o1_mobileCharacterInScene(ScriptState *script) { +int KyraEngine_v1::o1_mobileCharacterInScene(EMCState *script) { warning("STUB: o1_mobileCharacterInScene"); return 0; } -int KyraEngine_v1::o1_hideMobileCharacter(ScriptState *script) { +int KyraEngine_v1::o1_hideMobileCharacter(EMCState *script) { warning("STUB: o1_hideMobileCharacter"); return 0; } -int KyraEngine_v1::o1_unhideMobileCharacter(ScriptState *script) { +int KyraEngine_v1::o1_unhideMobileCharacter(EMCState *script) { warning("STUB: o1_unhideMobileCharacter"); return 0; } -int KyraEngine_v1::o1_setCharactersLocation(ScriptState *script) { +int KyraEngine_v1::o1_setCharactersLocation(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setCharactersLocation(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); Character *ch = &_characterList[stackPos(0)]; - AnimObject *animObj = &_animator->actors()[stackPos(0)]; + Animator_v1::AnimObject *animObj = &_animator->actors()[stackPos(0)]; int newScene = stackPos(1); if (_currentCharacter->sceneId == ch->sceneId) { if (_currentCharacter->sceneId != newScene) @@ -1008,7 +1008,7 @@ int KyraEngine_v1::o1_setCharactersLocation(ScriptState *script) { return 0; } -int KyraEngine_v1::o1_walkCharacterToPoint(ScriptState *script) { +int KyraEngine_v1::o1_walkCharacterToPoint(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_walkCharacterToPoint(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); int character = stackPos(0); int toX = stackPos(1); @@ -1090,7 +1090,7 @@ int KyraEngine_v1::o1_walkCharacterToPoint(ScriptState *script) { return 0; } -int KyraEngine_v1::o1_specialEventDisplayBrynnsNote(ScriptState *script) { +int KyraEngine_v1::o1_specialEventDisplayBrynnsNote(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_specialEventDisplayBrynnsNote(%p) ()", (const void *)script); _screen->hideMouse(); _screen->savePageToDisk("HIDPAGE.TMP", 2); @@ -1112,7 +1112,7 @@ int KyraEngine_v1::o1_specialEventDisplayBrynnsNote(ScriptState *script) { return 0; } -int KyraEngine_v1::o1_specialEventRemoveBrynnsNote(ScriptState *script) { +int KyraEngine_v1::o1_specialEventRemoveBrynnsNote(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_specialEventRemoveBrynnsNote(%p) ()", (const void *)script); _screen->hideMouse(); _screen->loadPageFromDisk("SEENPAGE.TMP", 0); @@ -1123,13 +1123,13 @@ int KyraEngine_v1::o1_specialEventRemoveBrynnsNote(ScriptState *script) { return 0; } -int KyraEngine_v1::o1_setLogicPage(ScriptState *script) { +int KyraEngine_v1::o1_setLogicPage(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setLogicPage(%p) (%d)", (const void *)script, stackPos(0)); _screen->_curPage = stackPos(0); return stackPos(0); } -int KyraEngine_v1::o1_fatPrint(ScriptState *script) { +int KyraEngine_v1::o1_fatPrint(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_fatPrint(%p) ('%s', %d, %d, %d, %d, %d)", (const void *)script, stackPosString(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5)); // Workaround for bug #1582672 ("KYRA1: Text crippled and drawn wrong") @@ -1142,13 +1142,13 @@ int KyraEngine_v1::o1_fatPrint(ScriptState *script) { return 0; } -int KyraEngine_v1::o1_preserveAllObjectBackgrounds(ScriptState *script) { +int KyraEngine_v1::o1_preserveAllObjectBackgrounds(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_preserveAllObjectBackgrounds(%p) ()", (const void *)script); _animator->preserveAllBackgrounds(); return 0; } -int KyraEngine_v1::o1_updateSceneAnimations(ScriptState *script) { +int KyraEngine_v1::o1_updateSceneAnimations(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_updateSceneAnimations(%p) (%d)", (const void *)script, stackPos(0)); int times = stackPos(0); while (times--) { @@ -1158,23 +1158,23 @@ int KyraEngine_v1::o1_updateSceneAnimations(ScriptState *script) { return 0; } -int KyraEngine_v1::o1_sceneAnimationActive(ScriptState *script) { +int KyraEngine_v1::o1_sceneAnimationActive(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_sceneAnimationActive(%p) (%d)", (const void *)script, stackPos(0)); return _sprites->_anims[stackPos(0)].play; } -int KyraEngine_v1::o1_setCharactersMovementDelay(ScriptState *script) { +int KyraEngine_v1::o1_setCharactersMovementDelay(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setCharactersMovementDelay(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); _timer->setDelay(stackPos(0)+5, stackPos(1)); return 0; } -int KyraEngine_v1::o1_getCharactersFacing(ScriptState *script) { +int KyraEngine_v1::o1_getCharactersFacing(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_getCharactersFacing(%p) (%d)", (const void *)script, stackPos(0)); return _characterList[stackPos(0)].facing; } -int KyraEngine_v1::o1_bkgdScrollSceneAndMasksRight(ScriptState *script) { +int KyraEngine_v1::o1_bkgdScrollSceneAndMasksRight(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_bkgdScrollSceneAndMasksRight(%p) (%d)", (const void *)script, stackPos(0)); _screen->copyBackgroundBlock(stackPos(0), 2, 0); _screen->copyBackgroundBlock2(stackPos(0)); @@ -1188,13 +1188,13 @@ int KyraEngine_v1::o1_bkgdScrollSceneAndMasksRight(ScriptState *script) { return 0; } -int KyraEngine_v1::o1_dispelMagicAnimation(ScriptState *script) { +int KyraEngine_v1::o1_dispelMagicAnimation(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_dispelMagicAnimation(%p) ()", (const void *)script); seq_dispelMagicAnimation(); return 0; } -int KyraEngine_v1::o1_findBrightestFireberry(ScriptState *script) { +int KyraEngine_v1::o1_findBrightestFireberry(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_findBrightestFireberry(%p) ()", (const void *)script); if (_currentCharacter->sceneId >= 187 && _currentCharacter->sceneId <= 198) return 29; @@ -1238,7 +1238,7 @@ int KyraEngine_v1::o1_findBrightestFireberry(ScriptState *script) { return brightestFireberry; } -int KyraEngine_v1::o1_setFireberryGlowPalette(ScriptState *script) { +int KyraEngine_v1::o1_setFireberryGlowPalette(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setFireberryGlowPalette(%p) (%d)", (const void *)script, stackPos(0)); int palIndex = 0; switch (stackPos(0)) { @@ -1275,19 +1275,19 @@ int KyraEngine_v1::o1_setFireberryGlowPalette(ScriptState *script) { return 0; } -int KyraEngine_v1::o1_setDeathHandlerFlag(ScriptState *script) { +int KyraEngine_v1::o1_setDeathHandlerFlag(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setDeathHandlerFlag(%p) (%d)", (const void *)script, stackPos(0)); _deathHandler = stackPos(0); return 0; } -int KyraEngine_v1::o1_drinkPotionAnimation(ScriptState *script) { +int KyraEngine_v1::o1_drinkPotionAnimation(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_drinkPotionAnimation(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); seq_playDrinkPotionAnim(stackPos(0), stackPos(1), stackPos(2)); return 0; } -int KyraEngine_v1::o1_makeAmuletAppear(ScriptState *script) { +int KyraEngine_v1::o1_makeAmuletAppear(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_makeAmuletAppear(%p) ()", (const void *)script); WSAMovieV1 amulet(this); amulet.open("AMULET.WSA", 1, 0); @@ -1328,7 +1328,7 @@ int KyraEngine_v1::o1_makeAmuletAppear(ScriptState *script) { return 0; } -int KyraEngine_v1::o1_drawItemShapeIntoScene(ScriptState *script) { +int KyraEngine_v1::o1_drawItemShapeIntoScene(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_drawItemShapeIntoScene(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); int item = stackPos(0); int x = stackPos(1); @@ -1355,13 +1355,13 @@ int KyraEngine_v1::o1_drawItemShapeIntoScene(ScriptState *script) { return 0; } -int KyraEngine_v1::o1_setCharactersCurrentFrame(ScriptState *script) { +int KyraEngine_v1::o1_setCharactersCurrentFrame(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setCharactersCurrentFrame(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); _characterList[stackPos(0)].currentAnimFrame = stackPos(1); return 0; } -int KyraEngine_v1::o1_waitForConfirmationMouseClick(ScriptState *script) { +int KyraEngine_v1::o1_waitForConfirmationMouseClick(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_waitForConfirmationMouseClick(%p) ()", (const void *)script); // if (mouseEnabled) { while (!_mousePressFlag) { @@ -1386,39 +1386,39 @@ int KyraEngine_v1::o1_waitForConfirmationMouseClick(ScriptState *script) { return 0; } -int KyraEngine_v1::o1_pageFlip(ScriptState *script) { +int KyraEngine_v1::o1_pageFlip(EMCState *script) { warning("STUB: o1_pageFlip"); return 0; } -int KyraEngine_v1::o1_setSceneFile(ScriptState *script) { +int KyraEngine_v1::o1_setSceneFile(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setSceneFile(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); setSceneFile(stackPos(0), stackPos(1)); return 0; } -int KyraEngine_v1::o1_getItemInMarbleVase(ScriptState *script) { +int KyraEngine_v1::o1_getItemInMarbleVase(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_getItemInMarbleVase(%p) ()", (const void *)script); return _marbleVaseItem; } -int KyraEngine_v1::o1_setItemInMarbleVase(ScriptState *script) { +int KyraEngine_v1::o1_setItemInMarbleVase(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setItemInMarbleVase(%p) (%d)", (const void *)script, stackPos(0)); _marbleVaseItem = stackPos(0); return 0; } -int KyraEngine_v1::o1_addItemToInventory(ScriptState *script) { +int KyraEngine_v1::o1_addItemToInventory(EMCState *script) { warning("STUB: o1_addItemToInventory"); return 0; } -int KyraEngine_v1::o1_intPrint(ScriptState *script) { +int KyraEngine_v1::o1_intPrint(EMCState *script) { warning("STUB: o1_intPrint"); return 0; } -int KyraEngine_v1::o1_shakeScreen(ScriptState *script) { +int KyraEngine_v1::o1_shakeScreen(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_shakeScreen(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); int waitTicks = stackPos(1); int times = stackPos(0); @@ -1431,57 +1431,57 @@ int KyraEngine_v1::o1_shakeScreen(ScriptState *script) { return 0; } -int KyraEngine_v1::o1_createAmuletJewel(ScriptState *script) { +int KyraEngine_v1::o1_createAmuletJewel(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_createAmuletJewel(%p) (%d)", (const void *)script, stackPos(0)); seq_createAmuletJewel(stackPos(0), 0, 0, 0); return 0; } -int KyraEngine_v1::o1_setSceneAnimCurrXY(ScriptState *script) { +int KyraEngine_v1::o1_setSceneAnimCurrXY(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setSceneAnimCurrXY(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); _sprites->_anims[stackPos(0)].x = stackPos(1); _sprites->_anims[stackPos(0)].y = stackPos(2); return 0; } -int KyraEngine_v1::o1_poisonBrandonAndRemaps(ScriptState *script) { +int KyraEngine_v1::o1_poisonBrandonAndRemaps(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_poisonBrandonAndRemaps(%p) ()", (const void *)script); setBrandonPoisonFlags(1); return 0; } -int KyraEngine_v1::o1_fillFlaskWithWater(ScriptState *script) { +int KyraEngine_v1::o1_fillFlaskWithWater(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_fillFlaskWithWater(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); seq_fillFlaskWithWater(stackPos(0), stackPos(1)); return 0; } -int KyraEngine_v1::o1_getCharactersMovementDelay(ScriptState *script) { +int KyraEngine_v1::o1_getCharactersMovementDelay(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_getCharactersMovementDelay(%p) (%d)", (const void *)script, stackPos(0)); return _timer->getDelay(stackPos(0)+5); } -int KyraEngine_v1::o1_getBirthstoneGem(ScriptState *script) { +int KyraEngine_v1::o1_getBirthstoneGem(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_getBirthstoneGem(%p) (%d)", (const void *)script, stackPos(0)); if (stackPos(0) < 4) return _birthstoneGemTable[stackPos(0)]; return 0; } -int KyraEngine_v1::o1_queryBrandonStatusBit(ScriptState *script) { +int KyraEngine_v1::o1_queryBrandonStatusBit(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_queryBrandonStatusBit(%p) (%d)", (const void *)script, stackPos(0)); if (_brandonStatusBit & stackPos(0)) return 1; return 0; } -int KyraEngine_v1::o1_playFluteAnimation(ScriptState *script) { +int KyraEngine_v1::o1_playFluteAnimation(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_playFluteAnimation(%p) ()", (const void *)script); seq_playFluteAnimation(); return 0; } -int KyraEngine_v1::o1_playWinterScrollSequence(ScriptState *script) { +int KyraEngine_v1::o1_playWinterScrollSequence(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_playWinterScrollSequence(%p) (%d)", (const void *)script, stackPos(0)); if (!stackPos(0)) seq_winterScroll2(); @@ -1490,40 +1490,40 @@ int KyraEngine_v1::o1_playWinterScrollSequence(ScriptState *script) { return 0; } -int KyraEngine_v1::o1_getIdolGem(ScriptState *script) { +int KyraEngine_v1::o1_getIdolGem(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_getIdolGem(%p) (%d)", (const void *)script, stackPos(0)); return _idolGemsTable[stackPos(0)]; } -int KyraEngine_v1::o1_setIdolGem(ScriptState *script) { +int KyraEngine_v1::o1_setIdolGem(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setIdolGem(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); _idolGemsTable[stackPos(0)] = stackPos(1); return 0; } -int KyraEngine_v1::o1_totalItemsInScene(ScriptState *script) { +int KyraEngine_v1::o1_totalItemsInScene(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_totalItemsInScene(%p) (%d)", (const void *)script, stackPos(0)); return countItemsInScene(stackPos(0)); } -int KyraEngine_v1::o1_restoreBrandonsMovementDelay(ScriptState *script) { +int KyraEngine_v1::o1_restoreBrandonsMovementDelay(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_restoreBrandonsMovementDelay(%p) ()", (const void *)script); setWalkspeed(_configWalkspeed); return 0; } -int KyraEngine_v1::o1_setMousePos(ScriptState *script) { +int KyraEngine_v1::o1_setMousePos(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setMousePos(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); _system->warpMouse(stackPos(0), stackPos(1)); return 0; } -int KyraEngine_v1::o1_getMouseState(ScriptState *script) { +int KyraEngine_v1::o1_getMouseState(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_getMouseState(%p) ()", (const void *)script); return _mouseState; } -int KyraEngine_v1::o1_setEntranceMouseCursorTrack(ScriptState *script) { +int KyraEngine_v1::o1_setEntranceMouseCursorTrack(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setEntranceMouseCursorTrack(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); _entranceMouseCursorTracks[0] = stackPos(0); _entranceMouseCursorTracks[1] = stackPos(1); @@ -1533,19 +1533,19 @@ int KyraEngine_v1::o1_setEntranceMouseCursorTrack(ScriptState *script) { return 0; } -int KyraEngine_v1::o1_itemAppearsOnGround(ScriptState *script) { +int KyraEngine_v1::o1_itemAppearsOnGround(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_itemAppearsOnGround(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); processItemDrop(_currentCharacter->sceneId, stackPos(0), stackPos(1), stackPos(2), 2, 0); return 0; } -int KyraEngine_v1::o1_setNoDrawShapesFlag(ScriptState *script) { +int KyraEngine_v1::o1_setNoDrawShapesFlag(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setNoDrawShapesFlag(%p) (%d)", (const void *)script, stackPos(0)); _animator->_noDrawShapesFlag = stackPos(0); return 0; } -int KyraEngine_v1::o1_fadeEntirePalette(ScriptState *script) { +int KyraEngine_v1::o1_fadeEntirePalette(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_fadeEntirePalette(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); int cmd = stackPos(0); uint8 *fadePal = 0; @@ -1585,7 +1585,7 @@ int KyraEngine_v1::o1_fadeEntirePalette(ScriptState *script) { return 0; } -int KyraEngine_v1::o1_itemOnGroundHere(ScriptState *script) { +int KyraEngine_v1::o1_itemOnGroundHere(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_itemOnGroundHere(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); assert(stackPos(0) < _roomTableSize); Room *curRoom = &_roomTable[stackPos(0)]; @@ -1596,18 +1596,18 @@ int KyraEngine_v1::o1_itemOnGroundHere(ScriptState *script) { return 0; } -int KyraEngine_v1::o1_queryCauldronState(ScriptState *script) { +int KyraEngine_v1::o1_queryCauldronState(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_queryCauldronState(%p) ()", (const void *)script); return _cauldronState; } -int KyraEngine_v1::o1_setCauldronState(ScriptState *script) { +int KyraEngine_v1::o1_setCauldronState(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setCauldronState(%p) (%d)", (const void *)script, stackPos(0)); _cauldronState = stackPos(0); return _cauldronState; } -int KyraEngine_v1::o1_queryCrystalState(ScriptState *script) { +int KyraEngine_v1::o1_queryCrystalState(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_queryCrystalState(%p) (%d)", (const void *)script, stackPos(0)); if (!stackPos(0)) return _crystalState[0]; @@ -1616,7 +1616,7 @@ int KyraEngine_v1::o1_queryCrystalState(ScriptState *script) { return -1; } -int KyraEngine_v1::o1_setCrystalState(ScriptState *script) { +int KyraEngine_v1::o1_setCrystalState(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setCrystalState(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); if (!stackPos(0)) _crystalState[0] = stackPos(1); @@ -1625,12 +1625,12 @@ int KyraEngine_v1::o1_setCrystalState(ScriptState *script) { return stackPos(1); } -int KyraEngine_v1::o1_setPaletteRange(ScriptState *script) { +int KyraEngine_v1::o1_setPaletteRange(EMCState *script) { warning("STUB: o1_setPaletteRange"); return 0; } -int KyraEngine_v1::o1_shrinkBrandonDown(ScriptState *script) { +int KyraEngine_v1::o1_shrinkBrandonDown(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_shrinkBrandonDown(%p) (%d)", (const void *)script, stackPos(0)); int delayTime = stackPos(0); checkAmuletAnimFlags(); @@ -1656,7 +1656,7 @@ int KyraEngine_v1::o1_shrinkBrandonDown(ScriptState *script) { return 0; } -int KyraEngine_v1::o1_growBrandonUp(ScriptState *script) { +int KyraEngine_v1::o1_growBrandonUp(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_growBrandonUp(%p) ()", (const void *)script); int scaleValue = _scaleTable[_currentCharacter->y1]; int scale = 0; @@ -1677,33 +1677,33 @@ int KyraEngine_v1::o1_growBrandonUp(ScriptState *script) { return 0; } -int KyraEngine_v1::o1_setBrandonScaleXAndY(ScriptState *script) { +int KyraEngine_v1::o1_setBrandonScaleXAndY(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setBrandonScaleXAndY(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); _animator->_brandonScaleX = stackPos(0); _animator->_brandonScaleY = stackPos(1); return 0; } -int KyraEngine_v1::o1_resetScaleMode(ScriptState *script) { +int KyraEngine_v1::o1_resetScaleMode(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_resetScaleMode(%p) ()", (const void *)script); _scaleMode = 0; return 0; } -int KyraEngine_v1::o1_getScaleDepthTableValue(ScriptState *script) { +int KyraEngine_v1::o1_getScaleDepthTableValue(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_getScaleDepthTableValue(%p) (%d)", (const void *)script, stackPos(0)); assert(stackPos(0) < ARRAYSIZE(_scaleTable)); return _scaleTable[stackPos(0)]; } -int KyraEngine_v1::o1_setScaleDepthTableValue(ScriptState *script) { +int KyraEngine_v1::o1_setScaleDepthTableValue(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setScaleDepthTableValue(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); assert(stackPos(0) < ARRAYSIZE(_scaleTable)); _scaleTable[stackPos(0)] = stackPos(1); return stackPos(1); } -int KyraEngine_v1::o1_message(ScriptState *script) { +int KyraEngine_v1::o1_message(EMCState *script) { if (_flags.isTalkie) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_message(%p) (%d, '%s', %d)", (const void *)script, stackPos(0), stackPosString(1), stackPos(2)); drawSentenceCommand(stackPosString(1), stackPos(2)); @@ -1715,65 +1715,65 @@ int KyraEngine_v1::o1_message(ScriptState *script) { return 0; } -int KyraEngine_v1::o1_checkClickOnNPC(ScriptState *script) { +int KyraEngine_v1::o1_checkClickOnNPC(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_checkClickOnNPC(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); return checkForNPCScriptRun(stackPos(0), stackPos(1)); } -int KyraEngine_v1::o1_getFoyerItem(ScriptState *script) { +int KyraEngine_v1::o1_getFoyerItem(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_getFoyerItem(%p) (%d)", (const void *)script, stackPos(0)); assert(stackPos(0) < ARRAYSIZE(_foyerItemTable)); return _foyerItemTable[stackPos(0)]; } -int KyraEngine_v1::o1_setFoyerItem(ScriptState *script) { +int KyraEngine_v1::o1_setFoyerItem(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setFoyerItem(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); assert(stackPos(0) < ARRAYSIZE(_foyerItemTable)); _foyerItemTable[stackPos(0)] = stackPos(1); return stackPos(1); } -int KyraEngine_v1::o1_setNoItemDropRegion(ScriptState *script) { +int KyraEngine_v1::o1_setNoItemDropRegion(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setNoItemDropRegion(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); addToNoDropRects(stackPos(0), stackPos(1), stackPos(2), stackPos(3)); return 0; } -int KyraEngine_v1::o1_walkMalcolmOn(ScriptState *script) { +int KyraEngine_v1::o1_walkMalcolmOn(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_walkMalcolmOn(%p) ()", (const void *)script); if (!_malcolmFlag) _malcolmFlag = 1; return 0; } -int KyraEngine_v1::o1_passiveProtection(ScriptState *script) { +int KyraEngine_v1::o1_passiveProtection(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_passiveProtection(%p) ()", (const void *)script); return 1; } -int KyraEngine_v1::o1_setPlayingLoop(ScriptState *script) { +int KyraEngine_v1::o1_setPlayingLoop(EMCState *script) { warning("STUB: o1_setPlayingLoop"); return 0; } -int KyraEngine_v1::o1_brandonToStoneSequence(ScriptState *script) { +int KyraEngine_v1::o1_brandonToStoneSequence(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_brandonToStoneSequence(%p) ()", (const void *)script); seq_brandonToStone(); return 0; } -int KyraEngine_v1::o1_brandonHealingSequence(ScriptState *script) { +int KyraEngine_v1::o1_brandonHealingSequence(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_brandonHealingSequence(%p) ()", (const void *)script); seq_brandonHealing(); return 0; } -int KyraEngine_v1::o1_protectCommandLine(ScriptState *script) { +int KyraEngine_v1::o1_protectCommandLine(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_protectCommandLine(%p) (%d)", (const void *)script, stackPos(0)); return stackPos(0); } -int KyraEngine_v1::o1_pauseMusicSeconds(ScriptState *script) { +int KyraEngine_v1::o1_pauseMusicSeconds(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_pauseMusicSeconds(%p) ()", (const void *)script); // if music disabled // return @@ -1781,18 +1781,18 @@ int KyraEngine_v1::o1_pauseMusicSeconds(ScriptState *script) { return 0; } -int KyraEngine_v1::o1_resetMaskRegion(ScriptState *script) { +int KyraEngine_v1::o1_resetMaskRegion(EMCState *script) { warning("STUB: o1_resetMaskRegion"); return 0; } -int KyraEngine_v1::o1_setPaletteChangeFlag(ScriptState *script) { +int KyraEngine_v1::o1_setPaletteChangeFlag(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setPaletteChangeFlag(%p) (%d)", (const void *)script, stackPos(0)); _paletteChanged = stackPos(0); return _paletteChanged; } -int KyraEngine_v1::o1_fillRect(ScriptState *script) { +int KyraEngine_v1::o1_fillRect(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_fillRect(%p) (%d, %d, %d, %d, %d, 0x%X)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5)); int videoPageBackup = _screen->_curPage; _screen->_curPage = stackPos(0); @@ -1801,26 +1801,26 @@ int KyraEngine_v1::o1_fillRect(ScriptState *script) { return 0; } -int KyraEngine_v1::o1_vocUnload(ScriptState *script) { +int KyraEngine_v1::o1_vocUnload(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_vocUnload(%p) ()", (const void *)script); // this should unload all voc files (not needed) return 0; } -int KyraEngine_v1::o1_vocLoad(ScriptState *script) { +int KyraEngine_v1::o1_vocLoad(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_vocLoad(%p) (%d)", (const void *)script, stackPos(0)); // this should load the specified voc file (not needed) return 0; } -int KyraEngine_v1::o1_dummy(ScriptState *script) { +int KyraEngine_v1::o1_dummy(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_dummy(%p) ()", (const void *)script); return 0; } #pragma mark - -typedef Common::Functor1Mem<ScriptState*, int, KyraEngine_v1> OpcodeV1; +typedef Common::Functor1Mem<EMCState*, int, KyraEngine_v1> OpcodeV1; #define SetOpcodeTable(x) table = &x; #define Opcode(x) table->push_back(new OpcodeV1(this, &KyraEngine_v1::x)) void KyraEngine_v1::setupOpcodeTable() { diff --git a/engines/kyra/script_v2.cpp b/engines/kyra/script_v2.cpp index e0b863a60d..fcfb34561f 100644 --- a/engines/kyra/script_v2.cpp +++ b/engines/kyra/script_v2.cpp @@ -24,116 +24,41 @@ */ #include "kyra/kyra_v2.h" -#include "kyra/text_v2.h" -#include "kyra/wsamovie.h" -#include "kyra/sound.h" +#include "kyra/screen_v2.h" #include "kyra/timer.h" -#include "kyra/script_tim.h" #include "common/endian.h" namespace Kyra { -int KyraEngine_v2::o2_setCharacterFacingRefresh(ScriptState *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(ScriptState *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(ScriptState *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(ScriptState *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(ScriptState *script) { +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(ScriptState *script) { +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(ScriptState *script) { +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(ScriptState *script) { +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(ScriptState *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(ScriptState *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(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_setCharacterFacing(%p) (%d)", (const void *)script, stackPos(0)); +int KyraEngine_v2::o2_setCharacterFacingOverwrite(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_setCharacterFacingOverwrite(%p) (%d)", (const void *)script, stackPos(0)); _mainCharacter.facing = stackPos(0); - _overwriteSceneFacing = 1; + _overwriteSceneFacing = true; return 0; } -int KyraEngine_v2::o2_trySceneChange(ScriptState *script) { +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)); @@ -142,7 +67,7 @@ int KyraEngine_v2::o2_trySceneChange(ScriptState *script) { _unkHandleSceneChangeFlag = 0; if (success) { - _scriptInterpreter->initScript(script, script->dataPtr); + _emc->init(script, script->dataPtr); _unk4 = 0; _unk3 = -1; _unk5 = 1; @@ -152,325 +77,18 @@ int KyraEngine_v2::o2_trySceneChange(ScriptState *script) { } } -int KyraEngine_v2::o2_moveCharacter(ScriptState *script) { +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(ScriptState *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(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_soundFadeOut(%p) ()", (const void *)script); - _sound->beginFadeOut(); - return 0; -} - -int KyraEngine_v2::o2_showChapterMessage(ScriptState *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(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_restoreTalkTextMessageBkgd(%p) ()", (const void *)script); - _text->restoreTalkTextMessageBkgd(2, 0); - return 0; -} - -int KyraEngine_v2::o2_wsaClose(ScriptState *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(ScriptState *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(ScriptState *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(ScriptState *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(ScriptState *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(ScriptState *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(ScriptState *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(ScriptState *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(ScriptState *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(ScriptState *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(ScriptState *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(ScriptState *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(ScriptState *script) { +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(ScriptState *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(ScriptState *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(ScriptState *script) { +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(); @@ -485,80 +103,45 @@ int KyraEngine_v2::o2_defineItem(ScriptState *script) { return freeItem; } -int KyraEngine_v2::o2_removeItemFromInventory(ScriptState *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(ScriptState *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(ScriptState *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(ScriptState *script) { +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(ScriptState *script) { +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(ScriptState *script) { +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(ScriptState *script) { +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(ScriptState *script) { +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(ScriptState *script) { +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(ScriptState *script) { +int KyraEngine_v2::o2_hideMouse(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_hideMouse(%p) ()", (const void *)script); - _screen->hideMouse(); + screen()->hideMouse(); return 0; } -int KyraEngine_v2::o2_addSpecialExit(ScriptState *script) { +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) { @@ -572,62 +155,19 @@ int KyraEngine_v2::o2_addSpecialExit(ScriptState *script) { return 0; } -int KyraEngine_v2::o2_setMousePos(ScriptState *script) { +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(ScriptState *script) { +int KyraEngine_v2::o2_showMouse(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_showMouse(%p) ()", (const void *)script); - _screen->showMouse(); + screen()->showMouse(); return 0; } -int KyraEngine_v2::o2_wipeDownMouseItem(ScriptState *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(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_getElapsedSecs(%p) ()", (const void *)script); - return _system->getMillis() / 1000; -} - -int KyraEngine_v2::o2_getTimerDelay(ScriptState *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(ScriptState *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(ScriptState *script) { +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; @@ -650,414 +190,41 @@ int KyraEngine_v2::o2_delay(ScriptState *script) { return 0; } -int KyraEngine_v2::o2_setTimerDelay(ScriptState *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(ScriptState *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(ScriptState *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(ScriptState *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(ScriptState *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(ScriptState *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(ScriptState *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(ScriptState *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(ScriptState *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(ScriptState *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(ScriptState *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(ScriptState *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(ScriptState *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(ScriptState *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(ScriptState *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(ScriptState *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(ScriptState *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(ScriptState *script) { +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--) { + for (int times = stackPos(0); times != 0; --times) { if (_chatText) updateWithText(); else update(); } - - return 0; -} - -int KyraEngine_v2::o2_fadeScenePal(ScriptState *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(ScriptState *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(ScriptState *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(ScriptState *script) { +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(ScriptState *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(ScriptState *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(ScriptState *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; + return screen()->getShapeFlag1(stackPos(0), stackPos(1)); } -int KyraEngine_v2::o2_setZanthiaPos(ScriptState *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(ScriptState *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(ScriptState *script) { +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(ScriptState *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(ScriptState *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(ScriptState *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(ScriptState *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(ScriptState *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(ScriptState *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(ScriptState *script) { +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(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_isAnySoundPlaying(%p) ()", (const void *)script); - return _sound->voiceIsPlaying(); -} - -int KyraEngine_v2::o2_setDeathHandlerFlag(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_setDeathHandlerFlag(%p) (%d)", (const void *)script, stackPos(0)); +int KyraEngine_v2::o2_setDeathHandler(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_setDeathHandler(%p) (%d)", (const void *)script, stackPos(0)); _deathHandler = stackPos(0); return 0; } -int KyraEngine_v2::o2_setDrawNoShapeFlag(ScriptState *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(ScriptState *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(ScriptState *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(ScriptState *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(ScriptState *script) { +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; @@ -1081,14 +248,25 @@ int KyraEngine_v2::o2_waitForConfirmationClick(ScriptState *script) { return 1; } -int KyraEngine_v2::o2_encodeShape(ScriptState *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); +int KyraEngine_v2::o2_randomSceneChat(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_randomSceneChat(%p)", (const void *)script); + randomSceneChat(); + return 0; +} + +int KyraEngine_v2::o2_setDlgIndex(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_setDlgIndex(%p) (%d)", (const void *)script, stackPos(0)); + setDlgIndex(stackPos(0)); return 0; } -int KyraEngine_v2::o2_defineRoomEntrance(ScriptState *script) { +int KyraEngine_v2::o2_getDlgIndex(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_getDlgIndex(%p) ()", (const void *)script); + return _mainCharacter.dlgIndex; +} + + +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: @@ -1117,1018 +295,120 @@ int KyraEngine_v2::o2_defineRoomEntrance(ScriptState *script) { return 0; } -int KyraEngine_v2::o2_runTemporaryScript(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_runTemporaryScript(%p) ('%s', %d, %d, %d)", (const void *)script, stackPosString(0), stackPos(1), +int KyraEngine_v2::o2_runAnimationScript(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_runAnimationScript(%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)); + runAnimationScript(stackPosString(0), stackPos(3), stackPos(2) ? 1 : 0, stackPos(1), stackPos(2)); return 0; } -int KyraEngine_v2::o2_setSpecialSceneScriptRunTime(ScriptState *script) { +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(ScriptState *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(ScriptState *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(ScriptState *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(ScriptState *script) { - ScriptState tmpScript; - _scriptInterpreter->initScript(&tmpScript, &_npcScriptData); - _scriptInterpreter->startScript(&tmpScript, 0); - tmpScript.regs[4] = _itemInHand; - tmpScript.regs[0] = _mainCharacter.sceneId; - - int oldVocH = _vocHigh; - _vocHigh = 0x5a; - - while(_scriptInterpreter->validScript(&tmpScript)) - _scriptInterpreter->runScript(&tmpScript); - - _vocHigh = oldVocH; - - return 0; -} - -int KyraEngine_v2::o2_startDialogue(ScriptState *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(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_zanthRandomChat(%p)", (const void *)script); - zanthRandomIdleChat(); - return 0; -} - -int KyraEngine_v2::o2_setupDialogue(ScriptState *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(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_setNewDlgIndex(%p) (%d)", (const void *)script, stackPos(0)); - return _mainCharacter.dlgIndex; -} - -int KyraEngine_v2::o2_defineRoom(ScriptState *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(ScriptState *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(ScriptState *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(ScriptState *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(ScriptState *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(ScriptState *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(ScriptState *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(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_getColorCodeFlag1(%p) ()", (const void *)script); - return _colorCodeFlag1; -} - -int KyraEngine_v2::o2_setColorCodeFlag1(ScriptState *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(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_getColorCodeFlag2(%p) ()", (const void *)script); - return _colorCodeFlag2; -} - -int KyraEngine_v2::o2_setColorCodeFlag2(ScriptState *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(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_getColorCodeValue(%p) (%d)", (const void *)script, stackPos(0)); - return _presetColorCode[stackPos(0)]; -} - -int KyraEngine_v2::o2_setColorCodeValue(ScriptState *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(ScriptState *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(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_removeItemFromScene(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); +int KyraEngine_v2::o2_defineScene(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_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); - 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; -} + strcpy(_sceneList[scene].filename1, stackPosString(1)); + strcpy(_sceneList[scene].filename2, stackPosString(1)); -int KyraEngine_v2::o2_initObject(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_initObject(%p) (%d)", (const void *)script, stackPos(0)); - initTalkObject(stackPos(0)); - return 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); -int KyraEngine_v2::o2_npcChat(ScriptState *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)); + if (_mainCharacter.sceneId == scene) { + _sceneExit1 = _sceneList[scene].exit1; + _sceneExit2 = _sceneList[scene].exit2; + _sceneExit3 = _sceneList[scene].exit3; + _sceneExit4 = _sceneList[scene].exit4; } - return 0; -} - -int KyraEngine_v2::o2_deinitObject(ScriptState *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(ScriptState *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(ScriptState *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(ScriptState *script) { +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(ScriptState *script) { +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(ScriptState *script) { +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(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_resetInputColorCode(%p)", (const void *)script); - memset(_inputColorCode, 255, 7); - return 0; -} - -int KyraEngine_v2::o2_setHiddenItemsEntry(ScriptState *script) { +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(ScriptState *script) { +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(ScriptState *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(ScriptState *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(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_customChatFinish(%p) ()", (const void *)script); - _text->restoreScreen(); - _chatText = 0; - _chatObject = -1; - return 0; + return (int16)_hiddenItems[stackPos(0)]; } -int KyraEngine_v2::o2_setupSceneAnimation(ScriptState *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(ScriptState *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(ScriptState *script) { +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(ScriptState *script) { +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(ScriptState *script) { +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(ScriptState *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(ScriptState *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(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_getRainbowRoomData(%p) (%d)", (const void *)script, stackPos(0)); - return _rainbowRoomData[stackPos(0)]; -} - -int KyraEngine_v2::o2_drawSceneShapeEx(ScriptState *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(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_getBoolFromStack(%p) ()", (const void *)script); - return stackPos(0) ? 1 : 0; -} - -int KyraEngine_v2::o2_getSfxDriver(ScriptState *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(ScriptState *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(ScriptState *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(ScriptState *script) { +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(ScriptState *script) { +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(ScriptState *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(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_isVoiceEnabled(%p) ()", (const void *)script); - return speechEnabled() ? 1 : 0; -} - -int KyraEngine_v2::o2_isVoicePlaying(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_isVoicePlaying(%p) ()", (const void *)script); - return (snd_voiceIsPlaying() && !skipFlag()) ? 1 : 0; -} - -int KyraEngine_v2::o2_stopVoicePlaying(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_stopVoicePlaying(%p) ()", (const void *)script); - snd_stopVoice(); - return 0; -} - -int KyraEngine_v2::o2_getGameLanguage(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_getGameLanguage(%p) ()", (const void *)script); - return _lang; -} - -int KyraEngine_v2::o2_demoFinale(ScriptState *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(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_dummy(%p) ()", (const void *)script); - return 0; -} - #pragma mark - -int KyraEngine_v2::o2t_defineNewShapes(ScriptState *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(ScriptState *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; +int KyraEngine_v2::o2a_setAnimationShapes(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2a_setAnimationShapes(%p) ('%s', %d, %d, %d, %d, %d)", (const void *)script, + stackPosString(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5)); + strcpy(_animShapeFilename, stackPosString(0)); + _animShapeLastEntry = stackPos(1); + _animShapeWidth = stackPos(2); + _animShapeHeight = stackPos(3); + _animShapeXAdd = stackPos(4); + _animShapeYAdd = stackPos(5); return 0; } -int KyraEngine_v2::o2t_playSoundEffect(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2t_playSoundEffect(%p) (%d)", (const void *)script, stackPos(0)); - snd_playSoundEffect(stackPos(0)); +int KyraEngine_v2::o2a_setResetFrame(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3t_setResetFrame(%p) (%d)", (const void *)script, stackPos(0)); + _animResetFrame = stackPos(0); return 0; } -int KyraEngine_v2::o2t_fadeScenePal(ScriptState *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(ScriptState *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<ScriptState*, int, KyraEngine_v2> 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<const TIM*, const uint16*, int, KyraEngine_v2> 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<const Opcode*> *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 09af5b169e..0000000000 --- a/engines/kyra/script_v3.cpp +++ /dev/null @@ -1,1268 +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/wsamovie.h" - -#include "common/endian.h" - -namespace Kyra { - -int KyraEngine_v3::o3_getMalcolmShapes(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_getMaloclmShapes(%p) ()", (const void *)script); - return _malcolmShapes; -} - -int KyraEngine_v3::o3_setCharacterPos(ScriptState *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(ScriptState *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(ScriptState *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(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_getCharacterX(%p) ()", (const void *)script); - return _mainCharacter.x1; -} - -int KyraEngine_v3::o3_getCharacterY(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_getCharacterY(%p) ()", (const void *)script); - return _mainCharacter.y1; -} - -int KyraEngine_v3::o3_getCharacterFacing(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_getCharacterFacing(%p) ()", (const void *)script); - return _mainCharacter.facing; -} - -int KyraEngine_v3::o3_getCharacterScene(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_getCharacterScene(%p) ()", (const void *)script); - return _mainCharacter.sceneId; -} - -int KyraEngine_v3::o3_getMalcolmsMood(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_getMalcolmsMood(%p) ()", (const void *)script); - return _malcolmsMood; -} - -int KyraEngine_v3::o3_trySceneChange(ScriptState *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) { - _scriptInterpreter->initScript(script, script->dataPtr); - _unk4 = 0; - _unk3 = -1; - _unk5 = 1; - return 0; - } else { - return (_unk4 != 0) ? 1 : 0; - } -} - -int KyraEngine_v3::o3_moveCharacter(ScriptState *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(ScriptState *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(ScriptState *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_showBadConscience(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_showBadConscience(%p) ()", (const void *)script); - showBadConscience(); - return 0; -} - -int KyraEngine_v3::o3_hideBadConscience(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_hideBadConscience(%p) ()", (const void *)script); - hideBadConscience(); - return 0; -} - -int KyraEngine_v3::o3_objectChat(ScriptState *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(ScriptState *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_defineItem(ScriptState *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_npcChatSequence(ScriptState *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(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_queryGameFlag(%p) (%d)", (const void *)script, stackPos(0)); - return queryGameFlag(stackPos(0)); -} - -int KyraEngine_v3::o3_resetGameFlag(ScriptState *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(ScriptState *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(ScriptState *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(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_removeHandItem(%p) ()", (const void *)script); - removeHandItem(); - return 0; -} - -int KyraEngine_v3::o3_handItemSet(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_handItemSet(%p) ()", (const void *)script); - return _handItemSet; -} - -int KyraEngine_v3::o3_hideMouse(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_hideMouse(%p) ()", (const void *)script); - _screen->hideMouse(); - return 0; -} - -int KyraEngine_v3::o3_addSpecialExit(ScriptState *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(ScriptState *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(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_showMouse(%p) ()", (const void *)script); - _screen->showMouse(); - return 0; -} - -int KyraEngine_v3::o3_badConscienceChat(ScriptState *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(ScriptState *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(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_setMalcolmsMood(%p) (%d)", (const void *)script, stackPos(0)); - return (_malcolmsMood = stackPos(0)); -} - -int KyraEngine_v3::o3_delay(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_delay(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - const uint32 delayTime = stackPos(0) * _tickLength; - const int delayFunc = stackPos(1); - - if (delayFunc) - warning("STUB o3_delay func 1"); - - delay(delayTime, true); - return 0; -} - -int KyraEngine_v3::o3_setSceneFilename(ScriptState *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_drawSceneShape(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_drawSceneShape(%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(ScriptState *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(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_updateConversations(%p) (%d)", (const void *)script, stackPos(0)); - int dlgIndex = stackPos(0); - switch (_curChapter-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 (_curChapter == 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 (_curChapter == 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 (_curChapter == 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(ScriptState *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_update(ScriptState *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_enterNewScene(ScriptState *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_setMalcolmPos(ScriptState *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(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_stopMusic(%p) ()", (const void *)script); - stopMusicTrack(); - return 0; -} - -int KyraEngine_v3::o3_playMusicTrack(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_playMusicTrack(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - playMusicTrack(stackPos(0), stackPos(1)); - return 0; -} - -int KyraEngine_v3::o3_playSoundEffect(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_playSoundEffect(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - playSoundEffect(stackPos(0), stackPos(1)); - return 0; -} - -int KyraEngine_v3::o3_blockOutRegion(ScriptState *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_getRand(ScriptState *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_waitForConfirmationClick(ScriptState *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(ScriptState *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(ScriptState *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(ScriptState *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(ScriptState *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(ScriptState *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(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_runActorScript(%p) ()", (const void *)script); - ScriptData data; - ScriptState state; - memset(&data, 0, sizeof(data)); - memset(&state, 0, sizeof(state)); - - _res->exists("_ACTOR.EMC", true); - _scriptInterpreter->loadScript("_ACTOR.EMC", &data, &_opcodes); - _scriptInterpreter->initScript(&state, &data); - _scriptInterpreter->startScript(&state, 0); - - state.regs[4] = _itemInHand; - state.regs[0] = _mainCharacter.sceneId; - - int vocHigh = _vocHigh; - _vocHigh = 200; - _useActorBuffer = true; - - while (_scriptInterpreter->validScript(&state)) - _scriptInterpreter->runScript(&state); - - _useActorBuffer = false; - _vocHigh = vocHigh; - _scriptInterpreter->unloadScript(&data); - - if (queryGameFlag(0x218)) { - resetGameFlag(0x218); - enterNewScene(78, -1, 0, 0, 0); - } - - return 0; -} - -int KyraEngine_v3::o3_runDialog(ScriptState *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(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_malcolmRandomChat(%p) ()", (const void *)script); - malcolmRandomChat(); - return 0; -} - -int KyraEngine_v3::o3_setDlgIndex(ScriptState *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(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_getDlgIndex(%p) ()", (const void *)script); - return _mainCharacter.dlgIndex; -} - -int KyraEngine_v3::o3_defineScene(ScriptState *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_countItemInstances(ScriptState *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(ScriptState *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(ScriptState *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(ScriptState *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(ScriptState *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(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_querySpecialSceneScriptState(%p) (%d)", (const void *)script, stackPos(0)); - return _specialSceneScriptState[stackPos(0)]; -} - -int KyraEngine_v3::o3_setHiddenItemsEntry(ScriptState *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(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_getHiddenItemsEntry(%p) (%d)", (const void *)script, stackPos(0)); - return (int16)_hiddenItems[stackPos(0)]; -} - -int KyraEngine_v3::o3_setupSceneAnimObject(ScriptState *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(ScriptState *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_setVocHigh(ScriptState *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(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_getVocHigh(%p) ()", (const void *)script); - return _vocHigh; -} - -int KyraEngine_v3::o3_dummy(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_dummy(%p) ()", (const void *)script); - return 0; -} - -#pragma mark - - -int KyraEngine_v3::o3t_defineNewShapes(ScriptState *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(ScriptState *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; -} - -#pragma mark - - -int KyraEngine_v3::o3d_updateAnim(ScriptState *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(ScriptState *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<ScriptState*, int, KyraEngine_v3> 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<const Opcode*> *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); - OpcodeUnImpl(); - // 0x0c - OpcodeUnImpl(); - Opcode(o3_trySceneChange); - Opcode(o3_moveCharacter); - Opcode(o3_setCharacterFacing); - // 0x10 - OpcodeUnImpl(); - Opcode(o3_showSceneFileMessage); - Opcode(o3_dummy); - Opcode(o3_dummy); - // 0x14 - OpcodeUnImpl(); - Opcode(o3_showBadConscience); - Opcode(o3_dummy); - Opcode(o3_hideBadConscience); - // 0x18 - OpcodeUnImpl(); - OpcodeUnImpl(); - OpcodeUnImpl(); - OpcodeUnImpl(); - // 0x1c - OpcodeUnImpl(); - OpcodeUnImpl(); - OpcodeUnImpl(); - Opcode(o3_objectChat); - // 0x20 - Opcode(o3_checkForItem); - Opcode(o3_dummy); - OpcodeUnImpl(); - Opcode(o3_defineItem); - // 0x24 - OpcodeUnImpl(); - OpcodeUnImpl(); - 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); - OpcodeUnImpl(); - Opcode(o3_dummy); - Opcode(o3_delay); - // 0x38 - OpcodeUnImpl(); - OpcodeUnImpl(); - Opcode(o3_setSceneFilename); - OpcodeUnImpl(); - // 0x3c - OpcodeUnImpl(); - OpcodeUnImpl(); - OpcodeUnImpl(); - Opcode(o3_drawSceneShape); - // 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); - OpcodeUnImpl(); - Opcode(o3_update); - // 0x4c - OpcodeUnImpl(); - OpcodeUnImpl(); - OpcodeUnImpl(); - OpcodeUnImpl(); - // 0x50 - Opcode(o3_enterNewScene); - OpcodeUnImpl(); - OpcodeUnImpl(); - Opcode(o3_dummy); - // 0x54 - Opcode(o3_dummy); - Opcode(o3_dummy); - Opcode(o3_setMalcolmPos); - Opcode(o3_stopMusic); - // 0x58 - Opcode(o3_playMusicTrack); - Opcode(o3_playSoundEffect); - OpcodeUnImpl(); - OpcodeUnImpl(); - // 0x5c - Opcode(o3_blockOutRegion); - Opcode(o3_dummy); - OpcodeUnImpl(); - OpcodeUnImpl(); - // 0x60 - Opcode(o3_getRand); - Opcode(o3_dummy); - OpcodeUnImpl(); - OpcodeUnImpl(); - // 0x64 - OpcodeUnImpl(); - OpcodeUnImpl(); - Opcode(o3_dummy); - OpcodeUnImpl(); - // 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); - OpcodeUnImpl(); - OpcodeUnImpl(); - // 0x7c - OpcodeUnImpl(); - OpcodeUnImpl(); - Opcode(o3_dummy); - Opcode(o3_dummy); - // 0x80 - Opcode(o3_dummy); - OpcodeUnImpl(); - 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 - OpcodeUnImpl(); - OpcodeUnImpl(); - Opcode(o3_setupSceneAnimObject); - Opcode(o3_removeSceneAnimObject); - // 0x9c - OpcodeUnImpl(); - OpcodeUnImpl(); - OpcodeUnImpl(); - 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 - OpcodeUnImpl(); - 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..1c74f48990 --- /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<uint32>(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<uint32>(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); + _animShapeFiledata = new uint8[outsize]; + Screen::decodeFrame4(shp + 10, _animShapeFiledata, outsize); + delete [] shp; + + do { + numShp++; + addShapeToPool(_screen->getPtrToShape(_animShapeFiledata, 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 [] _animShapeFiledata; + _animShapeFiledata = 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..8c826e2048 --- /dev/null +++ b/engines/kyra/sequences_mr.cpp @@ -0,0 +1,249 @@ +/* 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 (_characterShapeFile == 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::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 (_characterShapeFile-1) { + case 0: + runAnimationScript("EELS01.EMC", 0, 0, 1, 1); + break; + + case 1: + runAnimationScript("EELS02.EMC", 0, 0, 1, 1); + break; + + case 2: + runAnimationScript("EELS03.EMC", 0, 0, 1, 1); + break; + + case 3: + runAnimationScript("EELS04.EMC", 0, 0, 1, 1); + break; + + default: + resetGameFlag(0x171); + runAnimationScript("EELS00.EMC", 0, 0, 1, 1); + break; + } + + changeChapter(2, 29, 0, 4); + _screen->showMouse(); +} + +int KyraEngine_MR::initAnimationShapes(uint8 *filedata) { + debugC(9, kDebugLevelAnimator, "KyraEngine_MR::initAnimationShapes(%p)", (const void*)filedata); + const int lastEntry = MIN(_animShapeLastEntry, 41); + for (int i = 0; i < lastEntry; ++i) + _gameShapes[9+i] = _screen->getPtrToShape(filedata, i); + return lastEntry; +} + +void KyraEngine_MR::uninitAnimationShapes(int count, uint8 *filedata) { + debugC(9, kDebugLevelAnimator, "KyraEngine_MR::uninitAnimationShapes(%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 index 8e089f58be..aef510a616 100644 --- a/engines/kyra/sequences_v2.cpp +++ b/engines/kyra/sequences_v2.cpp @@ -23,2758 +23,114 @@ * */ -#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" +#include "kyra/resource.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<uint32>(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<uint32>(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; +void KyraEngine_v2::runAnimationScript(const char *filename, int allowSkip, int resetChar, int newShapes, int shapeUnload) { + debugC(9, kDebugLevelMain, "KyraEngine_v2::runAnimationScript('%s', %d, %d, %d, %d)", filename, allowSkip, resetChar, newShapes, shapeUnload); + memset(&_animationScriptData, 0, sizeof(_animationScriptData)); + memset(&_animationScriptState, 0, sizeof(_animationScriptState)); - 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; + if (!_emc->load(filename, &_animationScriptData, &_opcodesAnimation)) + error("Couldn't load temporary script '%s'", filename); - 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; + _emc->init(&_animationScriptState, &_animationScriptData); + _emc->start(&_animationScriptState, 0); - 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; + _animResetFrame = -1; - 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; + if (_animShapeFiledata && newShapes) { + uninitAnimationShapes(_animShapeCount, _animShapeFiledata); + _animShapeFiledata = 0; + _animShapeCount = 0; } -} - -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; + while (_emc->isValid(&_animationScriptState)) + _emc->run(&_animationScriptState); - int ym = (directionFlags & 2) ? (h - h2) : 0; - int xm = (directionFlags & 1) ? (w - w2) : 0; + uint8 *fileData = 0; - _screen->wsaFrameAnimationStep(0, 0, x + xm, y + ym, w, h, w2, h2, srcPage, dstPage, 0); + if (newShapes) + _animShapeFiledata = _res->fileData(_animShapeFilename, 0); - _screen->copyPage(dstPage, 6); - _screen->copyPage(dstPage, 0); - _screen->updateScreen(); + fileData = _animShapeFiledata; - _screen->copyPage(12, dstPage); - delayUntil(endtime); - } - } -} - -void KyraEngine_v2::seq_resetActiveWSA(int wsaNum) { - if (_activeWSA[wsaNum].flags == -1) + if (!fileData) { + _emc->unload(&_animationScriptData); 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 (newShapes) + _animShapeCount = initAnimationShapes(fileData); - 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); - } + processAnimationScript(allowSkip, resetChar); - 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; - } + if (shapeUnload) { + uninitAnimationShapes(_animShapeCount, fileData); + _animShapeCount = 0; + _animShapeFiledata = 0; } - _activeWSA[wsaNum].currentFrame = currentFrame & 0xffff; - return res; + _emc->unload(&_animationScriptData); } -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(); +void KyraEngine_v2::processAnimationScript(int allowSkip, int resetChar) { + debugC(9, kDebugLevelAnimator, "KyraEngine_v2::processAnimationScript(%d, %d)", allowSkip, resetChar); + setCharacterAnimDim(_animShapeWidth, _animShapeHeight); - 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)); + _emc->init(&_animationScriptState, &_animationScriptData); + _emc->start(&_animationScriptState, 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; -} + while (_emc->isValid(&_animationScriptState)) { + _animNeedUpdate = false; + while (_emc->isValid(&_animationScriptState) && !_animNeedUpdate) + _emc->run(&_animationScriptState); -void KyraEngine_v2::seq_scrollPage() { - int dstY, dstH, srcH; + if (_animNewFrame < 0) + continue; - static const ScreenDim d = { 0x00, 0x00, 0x28, 0x320, 0xFF, 0xFE, 0x00, 0x00 }; + _mainCharacter.animFrame = _animNewFrame + _desc.animScriptFrameAdd; + updateCharacterAnim(0); + if (_chatText) + updateWithText(); + else + update(); - if (_seqScrollTextCounter - 143 < 0) { - dstY = 144 - _seqScrollTextCounter; - dstH = _seqScrollTextCounter; - srcH = 0; - } else { - dstY = 0; - srcH = _seqScrollTextCounter - 144; - dstH = (400 - srcH <= 144) ? 400 - srcH : 144; - } + uint32 delayEnd = _system->getMillis() + _animDelayTime * _tickLength; - if (dstH > 0) { - for (int i = 0; i < 4; i++) { - const ItemAnimData_v1 *def = &_demoAnimData[i]; - ActiveItemAnim *a = &_activeItemAnim[i]; + while ((!skipFlag() || !allowSkip) && _system->getMillis() < delayEnd) { + if (_chatText) + updateWithText(); + else + update(); - _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; + delay(10); } - _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); + resetSkipFlag(); } - _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; + if (resetChar) { + if (_animResetFrame >= 0) { + _mainCharacter.animFrame = _animResetFrame + _desc.animScriptFrameAdd; + updateCharacterAnim(0); + if (_chatText) + updateWithText(); + else + update(); } - do { - update(); - } while (_invWsa.timer > _system->getMillis() && !skipFlag()); + _mainCharacter.animFrame = _desc.characterFrameTable[_mainCharacter.facing]; + updateCharacterAnim(0); } - closeInvWsa(); - delete [] rect; - _invWsa.running = false; - - _screen->showMouse(); + _animResetFrame = -1; + resetCharacterAnimDim(); } } // end of namespace Kyra diff --git a/engines/kyra/sequences_v3.cpp b/engines/kyra/sequences_v3.cpp deleted file mode 100644 index 16fd991022..0000000000 --- a/engines/kyra/sequences_v3.cpp +++ /dev/null @@ -1,112 +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" - -namespace Kyra { - -void KyraEngine_v3::showBadConscience() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::showBadConscience()"); - if (_badConscienceShown) - return; - - _badConscienceShown = true; - _badConscienceAnim = _rnd.getRandomNumberRng(0, 2); - if (_curChapter == 2) - _badConscienceAnim = 5; - else if (_curChapter == 3) - _badConscienceAnim = 3; - else if (_curChapter == 4 && _rnd.getRandomNumberRng(1, 100) <= 25) - _badConscienceAnim = 6; - else if (_curChapter == 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) - 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) - playSoundEffect(0x31, 0xC8); - updateSceneAnim(0x0E, frame); - delay(1*_tickLength, true); - } - - updateSceneAnim(0x0E, -1); - update(); - removeSceneAnimObject(0x0E, 1); - //setNextIdleAnimTimer(); -} - -} // end of namespace Kyra - diff --git a/engines/kyra/sound.cpp b/engines/kyra/sound.cpp index 694ea14404..887e9c7267 100644 --- a/engines/kyra/sound.cpp +++ b/engines/kyra/sound.cpp @@ -478,8 +478,8 @@ void KyraEngine::snd_playTheme(int file, int track) { _sound->playTrack(track); } -void KyraEngine::snd_playSoundEffect(int track) { - debugC(9, kDebugLevelMain | kDebugLevelSound, "KyraEngine::snd_playSoundEffect(%d)", track); +void KyraEngine::snd_playSoundEffect(int track, int volume) { + debugC(9, kDebugLevelMain | kDebugLevelSound, "KyraEngine::snd_playSoundEffect(%d, %d)", track, volume); _sound->playSoundEffect(track); } diff --git a/engines/kyra/sound_digital.cpp b/engines/kyra/sound_digital.cpp index 24a33e5539..f8c6fbdb04 100644 --- a/engines/kyra/sound_digital.cpp +++ b/engines/kyra/sound_digital.cpp @@ -366,8 +366,10 @@ int SoundDigital::playSound(const char *filename, uint8 priority, Audio::Mixer:: } Common::SeekableReadStream *stream = _vm->resource()->getFileStream(filename); - if (!stream) + if (!stream) { + warning("Couldn't find soundfile '%s'", filename); return -1; + } strncpy(use->filename, filename, sizeof(use->filename)); use->priority = priority; @@ -401,6 +403,9 @@ bool SoundDigital::isPlaying(int channel) { } void SoundDigital::stopSound(int channel) { + if (channel == -1) + return; + assert(channel >= 0 && channel < ARRAYSIZE(_sounds)); _mixer->stopHandle(_sounds[channel].handle); _sounds[channel].stream = 0; diff --git a/engines/kyra/sound_v1.cpp b/engines/kyra/sound_v1.cpp index 9cb135983d..8293eb7508 100644 --- a/engines/kyra/sound_v1.cpp +++ b/engines/kyra/sound_v1.cpp @@ -28,8 +28,8 @@ namespace Kyra { -void KyraEngine_v1::snd_playSoundEffect(int track) { - debugC(9, kDebugLevelMain | kDebugLevelSound, "KyraEngine_v1::snd_playSoundEffect(%d)", track); +void KyraEngine_v1::snd_playSoundEffect(int track, int volume) { + debugC(9, kDebugLevelMain | kDebugLevelSound, "KyraEngine_v1::snd_playSoundEffect(%d, %d)", track, volume); if ((_flags.platform == Common::kPlatformFMTowns || _flags.platform == Common::kPlatformPC98) && track == 49) { snd_playWanderScoreViaMap(56, 1); return; diff --git a/engines/kyra/sprites.cpp b/engines/kyra/sprites.cpp index 531033f5c4..b54192abae 100644 --- a/engines/kyra/sprites.cpp +++ b/engines/kyra/sprites.cpp @@ -554,7 +554,7 @@ void Sprites::loadSceneShapes() { void Sprites::refreshSceneAnimObject(uint8 animNum, uint8 shapeNum, uint16 x, uint16 y, bool flipX, bool unkFlag) { debugC(9, kDebugLevelSprites, "Sprites::refreshSceneAnimObject(%i, %i, %i, %i, %i, %i", animNum, shapeNum, x, y, flipX, unkFlag); - AnimObject &anim = _vm->animator()->sprites()[animNum]; + Animator_v1::AnimObject &anim = _vm->animator()->sprites()[animNum]; anim.refreshFlag = 1; anim.bkgdChangeFlag = 1; diff --git a/engines/kyra/staticres.cpp b/engines/kyra/staticres.cpp index abafeceeb4..16d7ca4d9b 100644 --- a/engines/kyra/staticres.cpp +++ b/engines/kyra/staticres.cpp @@ -28,14 +28,16 @@ #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_hof.h" +#include "kyra/gui_mr.h" #include "gui/message.h" @@ -1177,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); @@ -1250,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; @@ -1303,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 }, @@ -1318,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 @@ -1506,29 +1508,25 @@ const int8 KyraEngine_v1::_dosTrackMap[] = { const int KyraEngine_v1::_dosTrackMapSize = ARRAYSIZE(KyraEngine_v1::_dosTrackMap); -// Kyra 2 and 3 main menu +// kyra engine v2 static data -const char *KyraEngine_v3::_mainMenuStrings[] = { - "Start a new game", - "Introduction", - "Load a game", - "Exit the game", - "Nouvelle Partie", - "Introduction", - "Charger une partie", - "Quitter le jeu", - "Neues Spiel starten", - "Intro", - "Spielstand laden", - "Spiel beenden", - 0 +const int8 KyraEngine_v2::_updateCharPosXTable[] = { + 0, 4, 4, 4, 0, -4, -4, -4 +}; + +const int8 KyraEngine_v2::_updateCharPosYTable[] = { + -2, -2, 0, 2, 2, 2, 0, -2 +}; + +const int GUI_v2::_sliderBarsPosition[] = { + 0x92, 0x1F, 0x92, 0x30, 0x92, 0x41, 0x92, 0x52 }; // 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",/*, @@ -1537,7 +1535,7 @@ const char *KyraEngine_v2::_languageExtension[] = { "JPN" }; -const char *KyraEngine_v2::_scriptLangExt[] = { +const char *KyraEngine_HoF::_scriptLangExt[] = { "EMC", "FMC", "GMC",/*, @@ -1546,19 +1544,19 @@ const char *KyraEngine_v2::_scriptLangExt[] = { "JMC" }; -const int KyraEngine_v2::_characterFrameTable[] = { +const uint8 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, @@ -1583,9 +1581,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, @@ -1610,30 +1608,30 @@ 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]; assert(_inventoryButtons); GUI_V2_BUTTON(_inventoryButtons[0], 0x1, 0x4F, 0, 1, 1, 1, 0x4487, 0, 0x00A, 0x95, 0x39, 0x1D, 0xC7, 0xCF, 0xC7, 0xCF, 0xC7, 0xCF, 0); - _inventoryButtons[0].buttonCallback = BUTTON_FUNCTOR(GUI_v2, _gui, &GUI_v2::optionsButton); + _inventoryButtons[0].buttonCallback = BUTTON_FUNCTOR(GUI_HoF, _gui, &GUI_HoF::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); @@ -1653,7 +1651,7 @@ void KyraEngine_v2::initInventoryButtonList() { _buttonList = _gui->addButtonToList(_buttonList, &_inventoryButtons[i]); } -void GUI_v2::initStaticData() { +void GUI_HoF::initStaticData() { GUI_V2_BUTTON(_scrollUpButton, 0x17, 0, 0, 1, 1, 1, 0x4487, 0, 0, 0, 0x18, 0x0F, 0xC7, 0xCF, 0xC7, 0xCF, 0xC7, 0xCF, 0); GUI_V2_BUTTON(_scrollDownButton, 0x18, 0, 0, 1, 1, 1, 0x4487, 0, 0, 0, 0x18, 0x0F, 0xC7, 0xCF, 0xC7, 0xCF, 0xC7, 0xCF, 0); @@ -1671,11 +1669,11 @@ void GUI_v2::initStaticData() { GUI_V2_BUTTON(_menuButtons[i], 0x10+i, 0, 0, 1, 1, 1, 0x4487, 0, 0, 0, 0, 0, 0xC7, 0xCF, 0xC7, 0xCF, 0xC7, 0xCF, 0); } - Button::Callback clickLoadSlotFunctor = BUTTON_FUNCTOR(GUI_v2, this, &GUI_v2::clickLoadSlot); - Button::Callback clickSaveSlotFunctor = BUTTON_FUNCTOR(GUI_v2, this, &GUI_v2::clickSaveSlot); - Button::Callback clickLoadMenuFunctor = BUTTON_FUNCTOR(GUI_v2, this, &GUI_v2::loadMenu); - Button::Callback clickQuitGameFunctor = BUTTON_FUNCTOR(GUI_v2, this, &GUI_v2::quitGame); - Button::Callback clickQuitOptionsFunctor = BUTTON_FUNCTOR(GUI_v2, this, &GUI_v2::quitOptionsMenu); + Button::Callback clickLoadSlotFunctor = BUTTON_FUNCTOR(GUI_HoF, this, &GUI_HoF::clickLoadSlot); + Button::Callback clickSaveSlotFunctor = BUTTON_FUNCTOR(GUI_HoF, this, &GUI_HoF::clickSaveSlot); + Button::Callback clickLoadMenuFunctor = BUTTON_FUNCTOR(GUI_HoF, this, &GUI_HoF::loadMenu); + Button::Callback clickQuitGameFunctor = BUTTON_FUNCTOR(GUI_HoF, this, &GUI_HoF::quitGame); + Button::Callback clickQuitOptionsFunctor = BUTTON_FUNCTOR(GUI_HoF, this, &GUI_HoF::quitOptionsMenu); const uint16 *menuStr = _vm->gameFlags().isTalkie ? _menuStringsTalkie : _menuStringsOther; @@ -1683,17 +1681,17 @@ void GUI_v2::initStaticData() { GUI_V2_MENU_ITEM(_mainMenu.item[0], 1, 0x02, -1, 0x1E, 0xDC, 0x0F, 0xFC, 0xFD, -1, 0xF8, 0xF9, 0xFA, -1, 0, 0, 0, 0); _mainMenu.item[0].callback = clickLoadMenuFunctor; GUI_V2_MENU_ITEM(_mainMenu.item[1], 1, 0x03, -1, 0x2F, 0xDC, 0x0F, 0xFC, 0xFD, -1, 0xF8, 0xF9, 0xFA, -1, 0, 0, 0, 0); - _mainMenu.item[1].callback = BUTTON_FUNCTOR(GUI_v2, this, &GUI_v2::saveMenu); + _mainMenu.item[1].callback = BUTTON_FUNCTOR(GUI_HoF, this, &GUI_HoF::saveMenu); GUI_V2_MENU_ITEM(_mainMenu.item[2], 1, 0x23, -1, 0x40, 0xDC, 0x0F, 0xFC, 0xFD, -1, 0xF8, 0xF9, 0xFA, -1, 0, 0, 0, 0); - _mainMenu.item[2].callback = BUTTON_FUNCTOR(GUI_v2, this, &GUI_v2::deleteMenu); + _mainMenu.item[2].callback = BUTTON_FUNCTOR(GUI_HoF, this, &GUI_HoF::deleteMenu); GUI_V2_MENU_ITEM(_mainMenu.item[3], 1, 0x04, -1, 0x51, 0xDC, 0x0F, 0xFC, 0xFD, -1, 0xF8, 0xF9, 0xFA, -1, 0, 0, 0, 0); - _mainMenu.item[3].callback = BUTTON_FUNCTOR(GUI_v2, this, &GUI_v2::gameOptionsTalkie); + _mainMenu.item[3].callback = BUTTON_FUNCTOR(GUI_HoF, this, &GUI_HoF::gameOptionsTalkie); GUI_V2_MENU_ITEM(_mainMenu.item[4], 1, 0x25, -1, 0x62, 0xDC, 0x0F, 0xFC, 0xFD, -1, 0xF8, 0xF9, 0xFA, -1, 0, 0, 0, 0); - _mainMenu.item[4].callback = BUTTON_FUNCTOR(GUI_v2, this, &GUI_v2::audioOptions); + _mainMenu.item[4].callback = BUTTON_FUNCTOR(GUI_HoF, this, &GUI_HoF::audioOptions); GUI_V2_MENU_ITEM(_mainMenu.item[5], 1, 0x05, -1, 0x73, 0xDC, 0x0F, 0xFC, 0xFD, -1, 0xF8, 0xF9, 0xFA, -1, 0, 0, 0, 0); _mainMenu.item[5].callback = clickQuitGameFunctor; GUI_V2_MENU_ITEM(_mainMenu.item[6], 1, 0x06, -1, 0x90, 0xDC, 0x0F, 0xFC, 0xFD, -1, 0xF8, 0xF9, 0xFA, -1, 0, 0, 0, 0); - _mainMenu.item[6].callback = BUTTON_FUNCTOR(GUI_v2, this, &GUI_v2::resumeGame); + _mainMenu.item[6].callback = BUTTON_FUNCTOR(GUI_HoF, this, &GUI_HoF::resumeGame); for (int i = 0; i < 7; ++i) _mainMenu.item[i].itemId = menuStr[0 * 8 + i + 1]; @@ -1703,7 +1701,7 @@ void GUI_v2::initStaticData() { _mainMenu.item[6].enabled = false; for (int i = 4; i < 6; ++i) _mainMenu.item[i].callback = _mainMenu.item[i+1].callback; - _mainMenu.item[3].callback = BUTTON_FUNCTOR(GUI_v2, this, &GUI_v2::gameOptions); + _mainMenu.item[3].callback = BUTTON_FUNCTOR(GUI_HoF, this, &GUI_HoF::gameOptions); _mainMenu.item[6].callback = Button::Callback(); _mainMenu.item[5].y = 0x7F; } @@ -1711,11 +1709,11 @@ void GUI_v2::initStaticData() { GUI_V2_MENU(_gameOptions, -1, -1, 0x120, 0x88, 0xF8, 0xF9, 0xFA, menuStr[1 * 8], 0xFB, -1, 8, 4, 4, -1, -1, -1, -1); if (_vm->gameFlags().isTalkie) { GUI_V2_MENU_ITEM(_gameOptions.item[0], 1, 0, 0xA0, 0x1E, 0x74, 0x0F, 0xFC, 0xFD, 5, 0xF8, 0xF9, 0xFA, -1, 0x15, 8, 0x20, 0); - _gameOptions.item[0].callback = BUTTON_FUNCTOR(GUI_v2, this, &GUI_v2::toggleWalkspeed); + _gameOptions.item[0].callback = BUTTON_FUNCTOR(GUI_HoF, this, &GUI_HoF::toggleWalkspeed); GUI_V2_MENU_ITEM(_gameOptions.item[1], 1, 0, 0xA0, 0x2F, 0x74, 0x0F, 0xFC, 0xFD, 5, 0xF8, 0xF9, 0xFA, -1, 0x26, 8, 0x31, 0); - _gameOptions.item[1].callback = BUTTON_FUNCTOR(GUI_v2, this, &GUI_v2::changeLanguage); + _gameOptions.item[1].callback = BUTTON_FUNCTOR(GUI_HoF, this, &GUI_HoF::changeLanguage); GUI_V2_MENU_ITEM(_gameOptions.item[2], 1, 0, 0xA0, 0x40, 0x74, 0x0F, 0xFC, 0xFD, 5, 0xF8, 0xF9, 0xFA, -1, 0x16, 8, 0x42, 0); - _gameOptions.item[2].callback = BUTTON_FUNCTOR(GUI_v2, this, &GUI_v2::toggleText); + _gameOptions.item[2].callback = BUTTON_FUNCTOR(GUI_HoF, this, &GUI_HoF::toggleText); GUI_V2_MENU_ITEM(_gameOptions.item[3], 1, 0x10, -1, 0x6E, 0x6C, 0x0F, 0xFD, 0xFD, -1, 0xF8, 0xF9, 0xFA, -1, 0, 0, 0, 0); _gameOptions.item[3].callback = clickQuitOptionsFunctor; } else { @@ -1746,9 +1744,9 @@ void GUI_v2::initStaticData() { GUI_V2_MENU(_choiceMenu, -1, -1, 0x140, 0x38, 0xF8, 0xF9, 0xFA, 0, 0xFE, -1, 8, 0, 2, -1, -1, -1, -1); GUI_V2_MENU_ITEM(_choiceMenu.item[0], 1, 0x14, 0x18, 0x1E, 0x48, 0x0F, 0xFC, 0xFD, -1, 0xF8, 0xF9, 0xFA, -1, 0, 0, 0, 0); - _choiceMenu.item[0].callback = BUTTON_FUNCTOR(GUI_v2, this, &GUI_v2::choiceYes); + _choiceMenu.item[0].callback = BUTTON_FUNCTOR(GUI_HoF, this, &GUI_HoF::choiceYes); GUI_V2_MENU_ITEM(_choiceMenu.item[1], 1, 0x13, 0xD8, 0x1E, 0x48, 0x0F, 0xFC, 0xFD, -1, 0xF8, 0xF9, 0xFA, -1, 0, 0, 0, 0); - _choiceMenu.item[1].callback = BUTTON_FUNCTOR(GUI_v2, this, &GUI_v2::choiceNo); + _choiceMenu.item[1].callback = BUTTON_FUNCTOR(GUI_HoF, this, &GUI_HoF::choiceNo); for (int i = 2; i <= 6; ++i) _choiceMenu.item[i].enabled = false; for (int i = 0; i < 7; ++i) @@ -1763,7 +1761,7 @@ void GUI_v2::initStaticData() { for (int i = 0; i <= 4; ++i) _loadMenu.item[i].callback = clickLoadSlotFunctor; GUI_V2_MENU_ITEM(_loadMenu.item[5], 1, 0x0B, 0xB8, 0x86, 0x58, 0xF, 0xFC, 0xFD, -1, 0xF8, 0xF9, 0xFA, -1, 0, 0, 0, 0); - _loadMenu.item[5].callback = BUTTON_FUNCTOR(GUI_v2, this, &GUI_v2::cancelLoadMenu); + _loadMenu.item[5].callback = BUTTON_FUNCTOR(GUI_HoF, this, &GUI_HoF::cancelLoadMenu); _loadMenu.item[6].enabled = false; for (int i = 0; i < 7; ++i) _loadMenu.item[i].itemId = menuStr[4 * 8 + i + 1]; @@ -1777,16 +1775,16 @@ void GUI_v2::initStaticData() { for (int i = 0; i <= 4; ++i) _saveMenu.item[i].callback = clickSaveSlotFunctor; GUI_V2_MENU_ITEM(_saveMenu.item[5], 1, 0x0B, 0xB8, 0x86, 0x58, 0xF, 0xFC, 0xFD, -1, 0xF8, 0xF9, 0xFA, -1, 0, 0, 0, 0); - _saveMenu.item[5].callback = BUTTON_FUNCTOR(GUI_v2, this, &GUI_v2::cancelSaveMenu); + _saveMenu.item[5].callback = BUTTON_FUNCTOR(GUI_HoF, this, &GUI_HoF::cancelSaveMenu); _saveMenu.item[6].enabled = false; for (int i = 0; i < 7; ++i) _saveMenu.item[i].itemId = menuStr[5 * 8 + i + 1]; GUI_V2_MENU(_savenameMenu, -1, -1, 0x140, 0x43, 0xF8, 0xF9, 0xFA, menuStr[6 * 8], 0xFB, -1, 8, 0, 2, -1, -1, -1, -1); GUI_V2_MENU_ITEM(_savenameMenu.item[0], 1, 0xD, 0x18, 0x2C, 0x58, 0x0F, 0xFC, 0xFD, -1, 0xF8, 0xF9, 0xFA, -1, 0, 0, 0, 0); - _savenameMenu.item[0].callback = BUTTON_FUNCTOR(GUI_v2, this, &GUI_v2::finishSavename); + _savenameMenu.item[0].callback = BUTTON_FUNCTOR(GUI_HoF, this, &GUI_HoF::finishSavename); GUI_V2_MENU_ITEM(_savenameMenu.item[1], 1, 0xB, 0xD0, 0x2C, 0x58, 0x0F, 0xFC, 0xFD, -1, 0xF8, 0xF9, 0xFA, -1, 0, 0, 0, 0); - _savenameMenu.item[1].callback = BUTTON_FUNCTOR(GUI_v2, this, &GUI_v2::cancelSavename); + _savenameMenu.item[1].callback = BUTTON_FUNCTOR(GUI_HoF, this, &GUI_HoF::cancelSavename); for (int i = 2; i <= 6; ++i) _savenameMenu.item[i].enabled = false; for (int i = 0; i < 7; ++i) @@ -1803,7 +1801,7 @@ void GUI_v2::initStaticData() { _deathMenu.item[i].itemId = menuStr[7 * 8 + i + 1]; } -const uint16 GUI_v2::_menuStringsTalkie[] = { +const uint16 GUI_HoF::_menuStringsTalkie[] = { 0x001, 0x002, 0x003, 0x023, 0x004, 0x025, 0x005, 0x006, // Main Menu String IDs 0x025, 0x000, 0x000, 0x000, 0x010, 0x000, 0x000, 0x000, // Options Menu String IDs 0x007, 0x000, 0x000, 0x000, 0x010, 0x000, 0x000, 0x000, // Audio Menu String IDs @@ -1814,7 +1812,7 @@ const uint16 GUI_v2::_menuStringsTalkie[] = { 0x00E, 0x002, 0x005, 0x000, 0x000, 0x000, 0x000, 0x000 // Death Menu String IDs }; -const uint16 GUI_v2::_menuStringsOther[] = { +const uint16 GUI_HoF::_menuStringsOther[] = { 0x009, 0x00A, 0x00B, 0x001, 0x00C, 0x00D, 0x00E, 0x000, // Main Menu String IDs 0x00F, 0x02B, 0x02C, 0x02D, 0x02E, 0x018, 0x000, 0x000, // Options Menu String IDs 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, // Dummy @@ -1825,11 +1823,7 @@ const uint16 GUI_v2::_menuStringsOther[] = { 0x016, 0x00A, 0x00D, 0x000, 0x000, 0x000, 0x000, 0x000 // Death Menu String IDs }; -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, @@ -1861,17 +1855,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, @@ -1882,7 +1876,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, @@ -1895,7 +1889,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, @@ -1904,7 +1898,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, @@ -1913,18 +1907,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, @@ -1938,7 +1932,23 @@ const uint8 KyraEngine_v2::_rainbowRoomData[] = { // kyra 3 static res -const char *KyraEngine_v3::_soundList[] = { +const char *KyraEngine_MR::_mainMenuStrings[] = { + "Start a new game", + "Introduction", + "Load a game", + "Exit the game", + "Nouvelle Partie", + "Introduction", + "Charger une partie", + "Quitter le jeu", + "Neues Spiel starten", + "Intro", + "Spielstand laden", + "Spiel beenden", + 0 +}; + +const char *KyraEngine_MR::_soundList[] = { "ARREST1.AUD", "BATH1.AUD", "OCEAN1.AUD", @@ -1983,9 +1993,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"/*, @@ -1993,9 +2003,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 }, @@ -2010,21 +2020,13 @@ const KyraEngine_v3::ShapeDesc KyraEngine_v3::_shapeDescs[] = { { 57, 91, -31, -82 } }; -const int KyraEngine_v3::_shapeDescsSize = ARRAYSIZE(KyraEngine_v3::_shapeDescs); - -const int8 KyraEngine_v3::_updateCharPosXTable[] = { - 0, 4, 4, 4, 0, -4, -4, -4 -}; - -const int8 KyraEngine_v3::_updateCharPosYTable[] = { - -2, -2, 0, 2, 2, 2, 0, -2 -}; +const int KyraEngine_MR::_shapeDescsSize = ARRAYSIZE(KyraEngine_MR::_shapeDescs); -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, @@ -2103,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", @@ -2332,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, @@ -2342,31 +2344,39 @@ const uint8 KyraEngine_v3::_badConscienceFrameTable[] = { 0x24, 0x24, 0x24, 0x24, 0x24, 0x1D, 0x1D, 0x1D }; -const uint8 KyraEngine_v3::_chapterLowestScene[] = { +const uint8 KyraEngine_MR::_goodConscienceFrameTable[] = { + 0x13, 0x13, 0x13, 0x13, 0x13, + 0x13, 0x13, 0x13, 0x13, 0x13, + 0x13, 0x13, 0x13, 0x13, 0x13, + 0x15, 0x15, 0x15, 0x15, 0x15, + 0x1E, 0x1E, 0x1E, 0x1E, 0x1E +}; + +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, @@ -2374,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, @@ -2386,19 +2396,201 @@ 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_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, + 7, 8, 5, 9, 6, 8, 7, 8, + 5, 9, 6, 10, 7, 8, 5, 5, + 5, 7, 5, 7, 10, 5, 10, 5, + 5, 8, 6, 8, 7, 5, 5, 8, + 6, 9, 5, 7, 6, 5, 5, 7, + 7, 7, 6, 5, 8, 6, 10, 5, + 7, 5, 10, 5, 5, 5, 5, 7, + 5, 8, 9, 7, 7, 6, 10, 6, + 5, 10, 8, 5, 8, 6, 10, 5, + 5, 8, 8, 5, 7, 7, 7, 6, + 8, 9, 8, 8, 6, 5, 7, 6, + 5, 8, 15, 7, 9, 6, 6, 8, + 5, 8, 15, 15, 5, 15, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 +}; + +const int KyraEngine_MR::_scoreTableSize = ARRAYSIZE(KyraEngine_MR::_scoreTable); + +void KyraEngine_MR::initMainButtonList(bool disable) { + if (!_mainButtonListInitialized) { + _mainButtonData = new Button[14]; + assert(_mainButtonData); + + GUI_V2_BUTTON(_mainButtonData[0], 1, 0, 0, 4, 4, 4, 0x4487, 0, 5, 162, 50, 25, 0xFF, 0xF0, 0xFF, 0xF0, 0xFF, 0xF0, 0); + _mainButtonData[0].buttonCallback = BUTTON_FUNCTOR(GUI_MR, _gui, &GUI_MR::optionsButton); + GUI_V2_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_MR, this, &KyraEngine_MR::buttonMoodChange); + GUI_V2_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_MR, this, &KyraEngine_MR::buttonShowScore); + GUI_V2_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_MR, this, &KyraEngine_MR::buttonJesterStaff); + + Button::Callback buttonInventoryFunctor = BUTTON_FUNCTOR(KyraEngine_MR, this, &KyraEngine_MR::buttonInventory); + for (int i = 0; i < 5; ++i) { + GUI_V2_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; + } + + for (int i = 0; i < 5; ++i) { + GUI_V2_BUTTON(_mainButtonData[i+9], i+10, 0, 0, 0, 0, 0, 0x1100, 0, 67+i*28, 177, 27, 21, 0xFF, 0xF0, 0xFF, 0xF0, 0xFF, 0xF0, 0); + _mainButtonData[i+9].buttonCallback = buttonInventoryFunctor; + } + + for (int i = 0; i < 14; ++i) + _mainButtonList = _gui->addButtonToList(_mainButtonList, &_mainButtonData[i]); + + _mainButtonListInitialized = true; + } + + for (int i = 0; i < 14; ++i) { + if (disable) + _gui->flagButtonDisable(&_mainButtonData[i]); + else + _gui->flagButtonEnable(&_mainButtonData[i]); + } +} + +void GUI_MR::initStaticData() { + GUI_V2_BUTTON(_scrollUpButton, 22, 0, 0, 4, 4, 4, 0x4487, 0, 0, 0, 0x18, 0x0F, 0xFF, 0xF0, 0xFF, 0xF0, 0xFF, 0xF0, 0); + GUI_V2_BUTTON(_scrollDownButton, 23, 0, 0, 4, 4, 4, 0x4487, 0, 0, 0, 0x18, 0x0F, 0xFF, 0xF0, 0xFF, 0xF0, 0xFF, 0xF0, 0); + + for (int i = 0; i < 4; ++i) { + GUI_V2_BUTTON(_sliderButtons[0][i], 0x18+i, 0, 0, 1, 1, 1, 0x4487, 0, 0, 0, 0x0A, 0x0E, 0xFF, 0xF0, 0xFF, 0xF0, 0xFF, 0xF0, 0); + } + for (int i = 0; i < 4; ++i) { + GUI_V2_BUTTON(_sliderButtons[1][i], 0x1C+i, 0, 0, 1, 1, 1, 0x4487, 0, 0, 0, 0x0A, 0x0E, 0xFF, 0xF0, 0xFF, 0xF0, 0xFF, 0xF0, 0); + } + for (int i = 0; i < 4; ++i) { + GUI_V2_BUTTON(_sliderButtons[2][i], 0x20+i, 0, 0, 0, 0, 0, 0x2200, 0, 0, 0, 0x6E, 0x0E, 0xFF, 0xF0, 0xFF, 0xF0, 0xFF, 0xF0, 0); + } + + for (uint i = 0; i < ARRAYSIZE(_menuButtons); ++i) { + GUI_V2_BUTTON(_menuButtons[i], 0x0F+i, 0, 0, 1, 1, 1, 0x4487, 0, 0, 0, 0, 0, 0xFF, 0xF0, 0xFF, 0xF0, 0xFF, 0xF0, 0); + } + + Button::Callback clickLoadSlotFunctor = BUTTON_FUNCTOR(GUI_MR, this, &GUI_MR::clickLoadSlot); + Button::Callback clickSaveSlotFunctor = BUTTON_FUNCTOR(GUI_MR, this, &GUI_MR::clickSaveSlot); + Button::Callback clickLoadMenuFunctor = BUTTON_FUNCTOR(GUI_MR, this, &GUI_MR::loadMenu); + Button::Callback clickQuitOptionsFunctor = BUTTON_FUNCTOR(GUI_MR, this, &GUI_MR::quitOptionsMenu); + + GUI_V2_MENU(_mainMenu, -1, -1, 256, 172, 0xD0, 0xD1, 0xCF, 1, 0xBD, -1, 8, 0, 7, -1, -1, -1, -1); + GUI_V2_MENU_ITEM(_mainMenu.item[0], 1, 2, -1, 30, 220, 15, 0xFA, 0xFF, -1, 0xD0, 0xD1, 0xCF, -1, 0, 0, 0, 0x0000); + _mainMenu.item[0].callback = clickLoadMenuFunctor; + GUI_V2_MENU_ITEM(_mainMenu.item[1], 1, 3, -1, 47, 220, 15, 0xFA, 0xFF, -1, 0xD0, 0xD1, 0xCF, -1, 0, 0, 0, 0x0000); + _mainMenu.item[1].callback = BUTTON_FUNCTOR(GUI_MR, this, &GUI_MR::saveMenu); + GUI_V2_MENU_ITEM(_mainMenu.item[2], 1, 35, -1, 64, 220, 15, 0xFA, 0xFF, -1, 0xD0, 0xD1, 0xCF, -1, 0, 0, 0, 0x0000); + _mainMenu.item[2].callback = BUTTON_FUNCTOR(GUI_MR, this, &GUI_MR::deleteMenu); + GUI_V2_MENU_ITEM(_mainMenu.item[3], 1, 4, -1, 81, 220, 15, 0xFA, 0xFF, -1, 0xD0, 0xD1, 0xCF, -1, 0, 0, 0, 0x0000); + _mainMenu.item[3].callback = BUTTON_FUNCTOR(GUI_MR, this, &GUI_MR::gameOptions); + GUI_V2_MENU_ITEM(_mainMenu.item[4], 1, 37, -1, 98, 220, 15, 0xFA, 0xFF, -1, 0xD0, 0xD1, 0xCF, -1, 0, 0, 0, 0x0000); + _mainMenu.item[4].callback = BUTTON_FUNCTOR(GUI_MR, this, &GUI_MR::audioOptions); + GUI_V2_MENU_ITEM(_mainMenu.item[5], 1, 5, -1, 115, 220, 15, 0xFA, 0xFF, -1, 0xD0, 0xD1, 0xCF, -1, 0, 0, 0, 0x0000); + _mainMenu.item[5].callback = BUTTON_FUNCTOR(GUI_MR, this, &GUI_MR::quitGame); + GUI_V2_MENU_ITEM(_mainMenu.item[6], 1, 6, -1, 144, 220, 15, 0xFA, 0xFF, -1, 0xD0, 0xD1, 0xCF, -1, 0, 0, 0, 0x0000); + _mainMenu.item[6].callback = BUTTON_FUNCTOR(GUI_MR, this, &GUI_MR::resumeGame); + + GUI_V2_MENU(_audioOptions, -1, -1, 288, 136, 0xD0, 0xD1, 0xCF, 37, 0xBD, -1, 8, 4, 5, -1, -1, -1, -1); + GUI_V2_MENU_ITEM(_audioOptions.item[0], 0, 0, 160, 30, 116, 15, 0xFA, 0xFF, 5, 0xD0, 0xD1, 0xCF, -1, 23, 8, 32, 0x0000); + GUI_V2_MENU_ITEM(_audioOptions.item[1], 0, 0, 160, 47, 116, 15, 0xFA, 0xFF, 5, 0xD0, 0xD1, 0xCF, -1, 24, 8, 49, 0x0000); + GUI_V2_MENU_ITEM(_audioOptions.item[2], 0, 0, 160, 64, 116, 15, 0xFA, 0xFF, 5, 0xD0, 0xD1, 0xCF, -1, 39, 8, 66, 0x0000); + GUI_V2_MENU_ITEM(_audioOptions.item[3], 1, 0, 152, 81, 116, 15, 0xFA, 0xFF, 5, 0xD0, 0xD1, 0xCF, -1, 47, 8, 83, 0x0000); + GUI_V2_MENU_ITEM(_audioOptions.item[4], 1, 16, -1, 110, 92, 15, 0xFA, 0xFF, -1, 0xD0, 0xD1, 0xCF, -1, 0, 0, 0, 0x0000); + _audioOptions.item[4].callback = clickQuitOptionsFunctor; + for (int i = 5; i < 7; ++i) + _audioOptions.item[i].enabled = false; + + GUI_V2_MENU(_gameOptions, -1, -1, 288, 154, 0xD0, 0xD1, 0xCF, 7, 0xBD, -1, 8, 0, 6, -1, -1, -1, -1); + GUI_V2_MENU_ITEM(_gameOptions.item[0], 1, 0, 160, 30, 116, 15, 0xFA, 0xFF, 5, 0xD0, 0xD1, 0xCF, -1, 21, 8, 32, 0x0000); + _gameOptions.item[0].callback = BUTTON_FUNCTOR(GUI_MR, this, &GUI_MR::toggleWalkspeed); + GUI_V2_MENU_ITEM(_gameOptions.item[1], 1, 0, 160, 47, 116, 15, 0xFA, 0xFF, 5, 0xD0, 0xD1, 0xCF, -1, 26, 8, 49, 0x0000); + _gameOptions.item[1].callback = BUTTON_FUNCTOR(GUI_MR, this, &GUI_MR::changeLanguage); + GUI_V2_MENU_ITEM(_gameOptions.item[2], 1, 0, 160, 64, 116, 15, 0xFA, 0xFF, 5, 0xD0, 0xD1, 0xCF, -1, 40, 8, 66, 0x0000); + _gameOptions.item[2].callback = BUTTON_FUNCTOR(GUI_MR, this, &GUI_MR::toggleStudioSFX); + GUI_V2_MENU_ITEM(_gameOptions.item[3], 1, 0, 160, 81, 116, 15, 0xFA, 0xFF, 5, 0xD0, 0xD1, 0xCF, -1, 46, 8, 83, 0x0000); + _gameOptions.item[3].callback = BUTTON_FUNCTOR(GUI_MR, this, &GUI_MR::toggleSkipSupport); + GUI_V2_MENU_ITEM(_gameOptions.item[4], 1, 0, 160, 98, 116, 15, 0xFA, 0xFF, 5, 0xD0, 0xD1, 0xCF, -1, 22, 8, 100, 0x0000); + _gameOptions.item[4].callback = BUTTON_FUNCTOR(GUI_MR, this, &GUI_MR::toggleText); + GUI_V2_MENU_ITEM(_gameOptions.item[5], 1, 16, -1, 127, 125, 15, 0xFA, 0xFF, -1, 0xD0, 0xD1, 0xCF, -1, 0, 0, 0, 0x0000); + _gameOptions.item[5].callback = clickQuitOptionsFunctor; + _gameOptions.item[6].enabled = false; + + GUI_V2_MENU(_choiceMenu, -1, -1, 320, 56, 0xD0, 0xD1, 0xCF, 0, 0xBA, -1, 8, 0, 2, -1, -1, -1, -1); + GUI_V2_MENU_ITEM(_choiceMenu.item[0], 1, 20, 24, 30, 72, 15, 0xFA, 0xFF, -1, 0xD0, 0xD1, 0xCF, -1, 0, 0, 0, 0x0000); + _choiceMenu.item[0].callback = BUTTON_FUNCTOR(GUI_MR, this, &GUI_MR::choiceYes); + GUI_V2_MENU_ITEM(_choiceMenu.item[1], 1, 19, 216, 30, 72, 15, 0xFA, 0xFF, -1, 0xD0, 0xD1, 0xCF, -1, 0, 0, 0, 0x0000); + _choiceMenu.item[1].callback = BUTTON_FUNCTOR(GUI_MR, this, &GUI_MR::choiceNo); + for (int i = 2; i < 7; ++i) + _choiceMenu.item[i].enabled = false; + + GUI_V2_MENU(_loadMenu, -1, -1, 288, 160, 0xD0, 0xD1, 0xCF, 8, 0xBD, -1, 8, 0, 6, 132, 22, 132, 124); + GUI_V2_MENU_ITEM(_loadMenu.item[0], 1, 41, -1, 39, 256, 15, 0xFA, 0xFF, 5, 0xD0, 0xD1, 0xCF, -1, 0, 0, 0, 0x0000); + GUI_V2_MENU_ITEM(_loadMenu.item[1], 1, 42, -1, 56, 256, 15, 0xFA, 0xFF, 5, 0xD0, 0xD1, 0xCF, -1, 0, 0, 0, 0x0000); + GUI_V2_MENU_ITEM(_loadMenu.item[2], 1, 43, -1, 73, 256, 15, 0xFA, 0xFF, 5, 0xD0, 0xD1, 0xCF, -1, 0, 0, 0, 0x0000); + GUI_V2_MENU_ITEM(_loadMenu.item[3], 1, 44, -1, 90, 256, 15, 0xFA, 0xFF, 5, 0xD0, 0xD1, 0xCF, -1, 0, 0, 0, 0x0000); + GUI_V2_MENU_ITEM(_loadMenu.item[4], 1, 45, -1, 107, 256, 15, 0xFA, 0xFF, 5, 0xD0, 0xD1, 0xCF, -1, 0, 0, 0, 0x0000); + for (int i = 0; i <= 4; ++i) + _loadMenu.item[i].callback = clickLoadSlotFunctor; + GUI_V2_MENU_ITEM(_loadMenu.item[5], 1, 11, 184, 134, 88, 15, 0xFA, 0xFF, -1, 0xD0, 0xD1, 0xCF, -1, 0, 0, 0, 0x0000); + _loadMenu.item[5].callback = BUTTON_FUNCTOR(GUI_MR, this, &GUI_MR::cancelLoadMenu); + _loadMenu.item[6].enabled = false; + + GUI_V2_MENU(_saveMenu, -1, -1, 288, 160, 0xD0, 0xD1, 0xCF, 9, 0xBD, -1, 8, 0, 6, 132, 22, 132, 124); + GUI_V2_MENU_ITEM(_saveMenu.item[0], 1, 41, -1, 39, 256, 15, 0xFA, 0xFF, 5, 0xD0, 0xD1, 0xCF, -1, 0, 0, 0, 0x0000); + GUI_V2_MENU_ITEM(_saveMenu.item[1], 1, 42, -1, 56, 256, 15, 0xFA, 0xFF, 5, 0xD0, 0xD1, 0xCF, -1, 0, 0, 0, 0x0000); + GUI_V2_MENU_ITEM(_saveMenu.item[2], 1, 43, -1, 73, 256, 15, 0xFA, 0xFF, 5, 0xD0, 0xD1, 0xCF, -1, 0, 0, 0, 0x0000); + GUI_V2_MENU_ITEM(_saveMenu.item[3], 1, 44, -1, 90, 256, 15, 0xFA, 0xFF, 5, 0xD0, 0xD1, 0xCF, -1, 0, 0, 0, 0x0000); + GUI_V2_MENU_ITEM(_saveMenu.item[4], 1, 45, -1, 107, 256, 15, 0xFA, 0xFF, 5, 0xD0, 0xD1, 0xCF, -1, 0, 0, 0, 0x0000); + for (int i = 0; i <= 4; ++i) + _saveMenu.item[i].callback = clickSaveSlotFunctor; + GUI_V2_MENU_ITEM(_saveMenu.item[5], 1, 11, 184, 134, 88, 15, 0xFA, 0xFF, -1, 0xD0, 0xD1, 0xCF, -1, 0, 0, 0, 0x0000); + _saveMenu.item[5].callback = BUTTON_FUNCTOR(GUI_MR, this, &GUI_MR::cancelSaveMenu); + _saveMenu.item[6].enabled = false; + + GUI_V2_MENU(_savenameMenu, -1, -1, 320, 67, 0xD0, 0xD1, 0xCF, 12, 0xBD, -1, 8, 0, 2, -1, -1, -1, -1); + GUI_V2_MENU_ITEM(_savenameMenu.item[0], 1, 13, 24, 44, 88, 15, 0xFA, 0xFF, -1, 0xD0, 0xD1, 0xCF, -1, 0, 0, 0, 0x0000); + _savenameMenu.item[0].callback = BUTTON_FUNCTOR(GUI_MR, this, &GUI_MR::finishSavename); + GUI_V2_MENU_ITEM(_savenameMenu.item[1], 1, 11, 208, 44, 88, 15, 0xFA, 0xFF, -1, 0xD0, 0xD1, 0xCF, -1, 0, 0, 0, 0x0000); + _savenameMenu.item[1].callback = BUTTON_FUNCTOR(GUI_MR, this, &GUI_MR::cancelSavename); + for (int i = 2; i < 7; ++i) + _savenameMenu.item[i].enabled = false; + + GUI_V2_MENU(_deathMenu, -1, -1, 208, 76, 0xD0, 0xD1, 0xCF, 14, 0xBD, -1, 8, 0, 2, -1, -1, -1, -1); + GUI_V2_MENU_ITEM(_deathMenu.item[0], 1, 2, -1, 30, 180, 15, 0xFA, 0xFF, 8, 0xD0, 0xD1, 0xCF, -1, 0, 0, 0, 0x0000); + _deathMenu.item[0].callback = clickLoadMenuFunctor; + GUI_V2_MENU_ITEM(_deathMenu.item[1], 1, 38, -1, 47, 180, 15, 0xFA, 0xFF, 8, 0xD0, 0xD1, 0xCF, -1, 0, 0, 0, 0x0000); + _deathMenu.item[1].callback = BUTTON_FUNCTOR(GUI_MR, this, &GUI_MR::loadSecondChance); + for (int i = 2; i < 7; ++i) + _deathMenu.item[i].enabled = false; +} + } // End of namespace Kyra diff --git a/engines/kyra/text_v2.cpp b/engines/kyra/text_hof.cpp index 3dbcd8b4cc..dd1796dd02 100644 --- a/engines/kyra/text_v2.cpp +++ b/engines/kyra/text_hof.cpp @@ -23,8 +23,8 @@ * */ -#include "kyra/text_v2.h" -#include "kyra/kyra_v2.h" +#include "kyra/text_hof.h" +#include "kyra/kyra_hof.h" #include "kyra/script_tim.h" #include "kyra/resource.h" @@ -32,19 +32,19 @@ namespace Kyra { -TextDisplayer_v2::TextDisplayer_v2(KyraEngine_v2 *vm, Screen_v2 *screen) +TextDisplayer_HoF::TextDisplayer_HoF(KyraEngine_HoF *vm, Screen_v2 *screen) : TextDisplayer(vm, screen), _vm(vm) { } -void TextDisplayer_v2::backupTalkTextMessageBkgd(int srcPage, int dstPage) { +void TextDisplayer_HoF::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) { +void TextDisplayer_HoF::restoreTalkTextMessageBkgd(int srcPage, int dstPage) { _screen->copyRegion(0, 144, _talkCoords.x, _talkMessageY, _talkCoords.w, _talkMessageH, srcPage, dstPage); } -void TextDisplayer_v2::restoreScreen() { +void TextDisplayer_HoF::restoreScreen() { _vm->restorePage3(); _vm->drawAnimObjects(); _screen->hideMouse(); @@ -54,7 +54,7 @@ void TextDisplayer_v2::restoreScreen() { _vm->refreshAnimObjects(0); } -void TextDisplayer_v2::printCustomCharacterText(const char *text, int x, int y, uint8 c1, int srcPage, int dstPage) { +void TextDisplayer_HoF::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); @@ -86,8 +86,8 @@ void TextDisplayer_v2::printCustomCharacterText(const char *text, int x, int y, _screen->showMouse(); } -char *TextDisplayer_v2::preprocessString(const char *str) { - debugC(9, kDebugLevelMain, "TextDisplayer_v2::preprocessString('%s')", str); +char *TextDisplayer_HoF::preprocessString(const char *str) { + debugC(9, kDebugLevelMain, "TextDisplayer_HoF::preprocessString('%s')", str); if (str != _talkBuffer) { assert(strlen(str) < sizeof(_talkBuffer) - 1); @@ -129,8 +129,8 @@ char *TextDisplayer_v2::preprocessString(const char *str) { return _talkBuffer; } -void TextDisplayer_v2::calcWidestLineBounds(int &x1, int &x2, int w, int x) { - debugC(9, kDebugLevelMain, "TextDisplayer_v2::calcWidestLineBounds(%d, %d)", w, x); +void TextDisplayer_HoF::calcWidestLineBounds(int &x1, int &x2, int w, int x) { + debugC(9, kDebugLevelMain, "TextDisplayer_HoF::calcWidestLineBounds(%d, %d)", w, x); x1 = x; x1 -= (w >> 1); x2 = x1 + w + 1; @@ -146,7 +146,7 @@ void TextDisplayer_v2::calcWidestLineBounds(int &x1, int &x2, int w, int x) { #pragma mark - -int KyraEngine_v2::chatGetType(const char *str) { +int KyraEngine_HoF::chatGetType(const char *str) { str += strlen(str); --str; switch (*str) { @@ -164,7 +164,7 @@ int KyraEngine_v2::chatGetType(const char *str) { } } -int KyraEngine_v2::chatCalcDuration(const char *str) { +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); @@ -172,7 +172,7 @@ int KyraEngine_v2::chatCalcDuration(const char *str) { return MAX<int>(duration, 120); } -void KyraEngine_v2::objectChat(const char *str, int object, int vocHigh, int vocLow) { +void KyraEngine_HoF::objectChat(const char *str, int object, int vocHigh, int vocLow) { setNextIdleAnimTimer(); _chatVocHigh = _chatVocLow = -1; @@ -229,7 +229,7 @@ void KyraEngine_v2::objectChat(const char *str, int object, int vocHigh, int voc setNextIdleAnimTimer(); } -void KyraEngine_v2::objectChatInit(const char *str, int object, int vocHigh, int vocLow) { +void KyraEngine_HoF::objectChatInit(const char *str, int object, int vocHigh, int vocLow) { str = _text->preprocessString(str); int lineNum = _text->buildMessageSubstrings(str); @@ -276,7 +276,7 @@ void KyraEngine_v2::objectChatInit(const char *str, int object, int vocHigh, int _screen->showMouse(); } -void KyraEngine_v2::objectChatPrintText(const char *str, int object) { +void KyraEngine_HoF::objectChatPrintText(const char *str, int object) { int c1 = _talkObjectList[object].color; str = _text->preprocessString(str); int lineNum = _text->buildMessageSubstrings(str); @@ -295,20 +295,20 @@ void KyraEngine_v2::objectChatPrintText(const char *str, int object) { } } -void KyraEngine_v2::objectChatProcess(const char *script) { +void KyraEngine_HoF::objectChatProcess(const char *script) { memset(&_chatScriptData, 0, sizeof(_chatScriptData)); memset(&_chatScriptState, 0, sizeof(_chatScriptState)); - _scriptInterpreter->loadScript(script, &_chatScriptData, &_opcodesTemporary); - _scriptInterpreter->initScript(&_chatScriptState, &_chatScriptData); - _scriptInterpreter->startScript(&_chatScriptState, 0); - while (_scriptInterpreter->validScript(&_chatScriptState)) - _scriptInterpreter->runScript(&_chatScriptState); + _emc->load(script, &_chatScriptData, &_opcodesAnimation); + _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); + _animShapeFilename[2] = _characterShapeFile + '0'; + uint8 *shapeBuffer = _res->fileData(_animShapeFilename, 0); if (shapeBuffer) { - int shapeCount = initNewShapes(shapeBuffer); + int shapeCount = initAnimationShapes(shapeBuffer); if (_chatVocHigh >= 0) { playVoice(_chatVocHigh, _chatVocLow); @@ -317,35 +317,35 @@ void KyraEngine_v2::objectChatProcess(const char *script) { objectChatWaitToFinish(); - resetNewShapes(shapeCount, shapeBuffer); + uninitAnimationShapes(shapeCount, shapeBuffer); } else { - warning("couldn't load file '%s'", _newShapeFilename); + warning("couldn't load file '%s'", _animShapeFilename); } - _scriptInterpreter->unloadScript(&_chatScriptData); + _emc->unload(&_chatScriptData); } -void KyraEngine_v2::objectChatWaitToFinish() { +void KyraEngine_HoF::objectChatWaitToFinish() { int charAnimFrame = _mainCharacter.animFrame; - setCharacterAnimDim(_newShapeWidth, _newShapeHeight); + setCharacterAnimDim(_animShapeWidth, _animShapeHeight); - _scriptInterpreter->initScript(&_chatScriptState, &_chatScriptData); - _scriptInterpreter->startScript(&_chatScriptState, 1); + _emc->init(&_chatScriptState, &_chatScriptData); + _emc->start(&_chatScriptState, 1); bool running = true; const uint32 endTime = _chatEndTime; resetSkipFlag(); while (running && !_quitFlag) { - if (!_scriptInterpreter->validScript(&_chatScriptState)) - _scriptInterpreter->startScript(&_chatScriptState, 1); + if (!_emc->isValid(&_chatScriptState)) + _emc->start(&_chatScriptState, 1); - _temporaryScriptExecBit = false; - while (!_temporaryScriptExecBit && _scriptInterpreter->validScript(&_chatScriptState)) - _scriptInterpreter->runScript(&_chatScriptState); + _animNeedUpdate = false; + while (!_animNeedUpdate && _emc->isValid(&_chatScriptState)) + _emc->run(&_chatScriptState); - int curFrame = _newShapeAnimFrame; - uint32 delayTime = _newShapeDelay; + int curFrame = _animNewFrame; + uint32 delayTime = _animDelayTime; if (!_chatIsNote) _mainCharacter.animFrame = 33 + curFrame; @@ -373,7 +373,7 @@ void KyraEngine_v2::objectChatWaitToFinish() { resetCharacterAnimDim(); } -void KyraEngine_v2::startDialogue(int dlgIndex) { +void KyraEngine_HoF::startDialogue(int dlgIndex) { updateDlgBuffer(); int csEntry, vocH, unused1, unused2; loadDlgHeader(csEntry, vocH, unused1, unused2); @@ -395,7 +395,7 @@ void KyraEngine_v2::startDialogue(int dlgIndex) { processDialogue(offs, vocH, csEntry); } -void KyraEngine_v2::zanthSceneStartupChat() { +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]) @@ -412,7 +412,7 @@ void KyraEngine_v2::zanthSceneStartupChat() { _newSceneDlgState[tableIndex] = 1; } -void KyraEngine_v2::zanthRandomIdleChat() { +void KyraEngine_HoF::randomSceneChat() { int lowest = _flags.isTalkie ? 6 : 5; int tableIndex = (_mainCharacter.sceneId - READ_LE_UINT16(&_ingameTalkObjIndex[lowest + _newChapterFile])) << 2; if (queryGameFlag(0x164)) @@ -434,7 +434,7 @@ void KyraEngine_v2::zanthRandomIdleChat() { processDialogue(offs, vocH, csEntry); } -void KyraEngine_v2::updateDlgBuffer() { +void KyraEngine_HoF::updateDlgBuffer() { static const char suffixTalkie[] = "EFG"; static const char suffixTowns[] = "G J"; @@ -457,14 +457,14 @@ void KyraEngine_v2::updateDlgBuffer() { _dlgBuffer = _res->fileData(filename, 0); } -void KyraEngine_v2::loadDlgHeader(int &csEntry, int &vocH, int &scIndex1, int &scIndex2) { +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_v2::processDialogue(int dlgOffset, int vocH, int csEntry) { +void KyraEngine_HoF::processDialogue(int dlgOffset, int vocH, int csEntry) { int activeTimSequence = -1; int nextTimSequence = -1; int cmd = 0; @@ -512,7 +512,7 @@ void KyraEngine_v2::processDialogue(int dlgOffset, int vocH, int csEntry) { } else if (cmd == 4) { csEntry = READ_LE_UINT16(_dlgBuffer + offs); - setNewDlgIndex(csEntry); + setDlgIndex(csEntry); offs += 2; } else { @@ -569,7 +569,7 @@ void KyraEngine_v2::processDialogue(int dlgOffset, int vocH, int csEntry) { _screen->showMouse(); } -void KyraEngine_v2::initTalkObject(int index) { +void KyraEngine_HoF::initTalkObject(int index) { TalkObject &object = _talkObjectList[index]; char STAFilename[13]; @@ -605,7 +605,7 @@ void KyraEngine_v2::initTalkObject(int index) { } } -void KyraEngine_v2::deinitTalkObject(int index) { +void KyraEngine_HoF::deinitTalkObject(int index) { TalkObject &object = _talkObjectList[index]; if (_currentTalkSections.ENDTim) { @@ -628,7 +628,7 @@ void KyraEngine_v2::deinitTalkObject(int index) { _tim->unload(_currentTalkSections.ENDTim); } -void KyraEngine_v2::npcChatSequence(const char *str, int objectId, int vocHigh, int vocLow) { +void KyraEngine_HoF::npcChatSequence(const char *str, int objectId, int vocHigh, int vocLow) { _chatText = str; _chatObject = objectId; objectChatInit(str, objectId, vocHigh, vocLow); @@ -677,7 +677,7 @@ void KyraEngine_v2::npcChatSequence(const char *str, int objectId, int vocHigh, setNextIdleAnimTimer(); } -void KyraEngine_v2::setNewDlgIndex(int dlgIndex) { +void KyraEngine_HoF::setDlgIndex(int dlgIndex) { if (dlgIndex == _mainCharacter.dlgIndex) return; memset(_newSceneDlgState, 0, 32); diff --git a/engines/kyra/text_v2.h b/engines/kyra/text_hof.h index 6b8cf5d38e..ef1f481c19 100644 --- a/engines/kyra/text_v2.h +++ b/engines/kyra/text_hof.h @@ -31,12 +31,12 @@ namespace Kyra { class Screen_v2; -class KyraEngine_v2; +class KyraEngine_HoF; -class TextDisplayer_v2 : public TextDisplayer { -friend class KyraEngine_v2; +class TextDisplayer_HoF : public TextDisplayer { +friend class KyraEngine_HoF; public: - TextDisplayer_v2(KyraEngine_v2 *vm, Screen_v2 *screen); + TextDisplayer_HoF(KyraEngine_HoF *vm, Screen_v2 *screen); void backupTalkTextMessageBkgd(int srcPage, int dstPage); void restoreTalkTextMessageBkgd(int srcPage, int dstPage); @@ -47,7 +47,7 @@ public: char *preprocessString(const char *str); void calcWidestLineBounds(int &x1, int &x2, int w, int x); private: - KyraEngine_v2 *_vm; + KyraEngine_HoF *_vm; }; } // end of namespace Kyra diff --git a/engines/kyra/text_v3.cpp b/engines/kyra/text_mr.cpp index 3b8c69177f..35f91c1ccc 100644 --- a/engines/kyra/text_v3.cpp +++ b/engines/kyra/text_mr.cpp @@ -23,18 +23,18 @@ * */ -#include "kyra/text_v3.h" -#include "kyra/screen_v3.h" +#include "kyra/text_mr.h" +#include "kyra/screen_mr.h" #include "kyra/resource.h" namespace Kyra { -TextDisplayer_v3::TextDisplayer_v3(KyraEngine_v3 *vm, Screen_v3 *screen) +TextDisplayer_MR::TextDisplayer_MR(KyraEngine_MR *vm, Screen_MR *screen) : TextDisplayer(vm, screen), _vm(vm), _screen(screen) { } -char *TextDisplayer_v3::preprocessString(const char *str) { - debugC(9, kDebugLevelMain, "TextDisplayer_v3::preprocessString('%s')", str); +char *TextDisplayer_MR::preprocessString(const char *str) { + debugC(9, kDebugLevelMain, "TextDisplayer_MR::preprocessString('%s')", str); if (_talkBuffer != str) strncpy(_talkBuffer, str, sizeof(_talkBuffer)); @@ -81,8 +81,8 @@ char *TextDisplayer_v3::preprocessString(const char *str) { 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 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; @@ -129,8 +129,8 @@ int TextDisplayer_v3::dropCRIntoString(char *str, int minOffs, int maxOffs) { 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); +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); @@ -141,8 +141,8 @@ void TextDisplayer_v3::printText(const char *str, int x, int y, uint8 c0, uint8 _screen->setFont(curFont); } -void TextDisplayer_v3::restoreScreen() { - debugC(9, kDebugLevelMain, "TextDisplayer_v3::restoreScreen()"); +void TextDisplayer_MR::restoreScreen() { + debugC(9, kDebugLevelMain, "TextDisplayer_MR::restoreScreen()"); _vm->restorePage3(); _vm->drawAnimObjects(); _screen->hideMouse(); @@ -152,8 +152,8 @@ void TextDisplayer_v3::restoreScreen() { _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); +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; @@ -169,8 +169,8 @@ void TextDisplayer_v3::calcWidestLineBounds(int &x1, int &x2, int w, int x) { #pragma mark - -int KyraEngine_v3::chatGetType(const char *str) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::chatGetType('%s')", str); +int KyraEngine_MR::chatGetType(const char *str) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::chatGetType('%s')", str); while (*str) ++str; --str; @@ -190,13 +190,13 @@ int KyraEngine_v3::chatGetType(const char *str) { } } -int KyraEngine_v3::chatCalcDuration(const char *str) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::chatCalcDuration('%s')", str); +int KyraEngine_MR::chatCalcDuration(const char *str) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::chatCalcDuration('%s')", str); return MAX<int>(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); +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; @@ -223,7 +223,7 @@ void KyraEngine_v3::objectChat(const char *str, int object, int vocHigh, int voc static const char *talkFilenameTable[] = { "MTFL00S.EMC", "MTFL00Q.EMC", "MTFL00E.EMC", "MTFL00T.EMC", - "MTFR00S.EMC", "MTFR00Q.EMC", "MTFR00E.EMC", "MTRF00T.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" @@ -239,8 +239,8 @@ void KyraEngine_v3::objectChat(const char *str, int object, int vocHigh, int voc 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); +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); @@ -286,8 +286,8 @@ void KyraEngine_v3::objectChatInit(const char *str, int object, int vocHigh, int _screen->showMouse(); } -void KyraEngine_v3::objectChatPrintText(const char *str, int object) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::objectChatPrintText('%s', %d)", str, object); +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); @@ -306,17 +306,17 @@ void KyraEngine_v3::objectChatPrintText(const char *str, int object) { } } -void KyraEngine_v3::objectChatProcess(const char *script) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::objectChatProcess('%s')", script); +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)); - _scriptInterpreter->loadScript(script, &_chatScriptData, &_opcodesTemporary); - _scriptInterpreter->initScript(&_chatScriptState, &_chatScriptData); - _scriptInterpreter->startScript(&_chatScriptState, 0); - while (_scriptInterpreter->validScript(&_chatScriptState)) - _scriptInterpreter->runScript(&_chatScriptState); + _emc->load(script, &_chatScriptData, &_opcodesAnimation); + _emc->init(&_chatScriptState, &_chatScriptData); + _emc->start(&_chatScriptState, 0); + while (_emc->isValid(&_chatScriptState)) + _emc->run(&_chatScriptState); if (_chatVocHigh >= 0) { playVoice(_chatVocHigh, _chatVocLow); @@ -327,33 +327,33 @@ void KyraEngine_v3::objectChatProcess(const char *script) { objectChatWaitToFinish(); _useFrameTable = false; - _scriptInterpreter->unloadScript(&_chatScriptData); + _emc->unload(&_chatScriptData); } -void KyraEngine_v3::objectChatWaitToFinish() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::objectChatWaitToFinish()"); +void KyraEngine_MR::objectChatWaitToFinish() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::objectChatWaitToFinish()"); int charAnimFrame = _mainCharacter.animFrame; - setCharacterAnimDim(_newShapeWidth, _newShapeHeight); + setCharacterAnimDim(_animShapeWidth, _animShapeHeight); - _scriptInterpreter->initScript(&_chatScriptState, &_chatScriptData); - _scriptInterpreter->startScript(&_chatScriptState, 1); + _emc->init(&_chatScriptState, &_chatScriptData); + _emc->start(&_chatScriptState, 1); bool running = true; const uint32 endTime = _chatEndTime; resetSkipFlag(); while (running && !_quitFlag) { - if (!_scriptInterpreter->validScript(&_chatScriptState)) - _scriptInterpreter->startScript(&_chatScriptState, 1); + if (!_emc->isValid(&_chatScriptState)) + _emc->start(&_chatScriptState, 1); - _temporaryScriptExecBit = false; - while (!_temporaryScriptExecBit && _scriptInterpreter->validScript(&_chatScriptState)) { + _animNeedUpdate = false; + while (!_animNeedUpdate && _emc->isValid(&_chatScriptState)) { musicUpdate(0); - _scriptInterpreter->runScript(&_chatScriptState); + _emc->run(&_chatScriptState); } - int curFrame = _newShapeAnimFrame; - uint32 delayTime = _newShapeDelay; + int curFrame = _animNewFrame; + uint32 delayTime = _animDelayTime; _mainCharacter.animFrame = curFrame; updateCharacterAnim(0); @@ -380,8 +380,8 @@ void KyraEngine_v3::objectChatWaitToFinish() { resetCharacterAnimDim(); } -void KyraEngine_v3::badConscienceChat(const char *str, int vocHigh, int vocLow) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::badConscienceChat('%s', %d, %d)", str, vocHigh, vocLow); +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; @@ -398,8 +398,8 @@ void KyraEngine_v3::badConscienceChat(const char *str, int vocHigh, int vocLow) _chatObject = -1; } -void KyraEngine_v3::badConscienceChatWaitToFinish() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::badConscienceChatWaitToFinish()"); +void KyraEngine_MR::badConscienceChatWaitToFinish() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::badConscienceChatWaitToFinish()"); if (_chatVocHigh) { playVoice(_chatVocHigh, _chatVocLow); _chatVocHigh = _chatVocLow = -1; @@ -438,13 +438,71 @@ void KyraEngine_v3::badConscienceChatWaitToFinish() { } } -void KyraEngine_v3::malcolmSceneStartupChat() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::malcolmSceneStartupChat()"); +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[_curChapter]; + int index = _mainCharacter.sceneId - _chapterLowestScene[_currentChapter]; if (_newSceneDlgState[index]) return; @@ -463,20 +521,20 @@ void KyraEngine_v3::malcolmSceneStartupChat() { _newSceneDlgState[index] = true; } -void KyraEngine_v3::updateDlgBuffer() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::updateDlgBuffer()"); +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 == _curChapter && _curDlgLang == _lang) + if (_curDlgIndex == _mainCharacter.dlgIndex && _curDlgChapter == _currentChapter && _curDlgLang == _lang) return; - snprintf(dlgFile, 16, "CH%.02d-S%.02d.", _curChapter, _mainCharacter.dlgIndex); + snprintf(dlgFile, 16, "CH%.02d-S%.02d.", _currentChapter, _mainCharacter.dlgIndex); appendLanguage(dlgFile, _lang, 16); - snprintf(cnvFile, 16, "CH%.02d-S%.02d.CNV", _curChapter, _mainCharacter.dlgIndex); + snprintf(cnvFile, 16, "CH%.02d-S%.02d.CNV", _currentChapter, _mainCharacter.dlgIndex); delete _cnvFile; delete _dlgBuffer; @@ -489,8 +547,8 @@ void KyraEngine_v3::updateDlgBuffer() { assert(_dlgBuffer); } -void KyraEngine_v3::loadDlgHeader(int &vocHighBase, int &vocHighIndex, int &index1, int &index2) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::loadDlgHeader(-, -, -, -)"); +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(); @@ -498,18 +556,58 @@ void KyraEngine_v3::loadDlgHeader(int &vocHighBase, int &vocHighIndex, int &inde index2 = _cnvFile->readSint16LE(); } -void KyraEngine_v3::setDlgIndex(uint16 index) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::setDlgIndex(%d)", index); +void KyraEngine_MR::setDlgIndex(int index) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::setDlgIndex(%d)", index); if (_mainCharacter.dlgIndex != index) { - Common::set_to(_newSceneDlgState, _newSceneDlgState+ARRAYSIZE(_newSceneDlgState), false); + memset(_newSceneDlgState, 0, sizeof(_newSceneDlgState)); memset(_conversationState, -1, sizeof(_conversationState)); _chatAltFlag = false; _mainCharacter.dlgIndex = index; } } -void KyraEngine_v3::processDialog(int vocHighIndex, int vocHighBase, int funcNum) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::processDialog(%d, %d, %d)", vocHighIndex, vocHighBase, funcNum); +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[_characterShapeFile]; + else if (_malcolmsMood == 1) + dlgIndex = dlgIndexMoodNormal[_characterShapeFile]; + else if (_malcolmsMood == 2) + dlgIndex = dlgIndexMoodEvil[_characterShapeFile]; + } 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; @@ -546,10 +644,10 @@ void KyraEngine_v3::processDialog(int vocHighIndex, int vocHighBase, int funcNum if (script >= 0) { dialogEndScript(script); script = -1; - } else { - dialogStartScript(object, funcNum); - script = object; } + + dialogStartScript(object, funcNum); + script = object; } npcChatSequence(_stringBuffer, object, vocHigh, vocLow); @@ -569,8 +667,8 @@ void KyraEngine_v3::processDialog(int vocHighIndex, int vocHighBase, int funcNum dialogEndScript(script); } -void KyraEngine_v3::dialogStartScript(int object, int funcNum) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::dialogStartScript(%d, %d)", object, funcNum); +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) { @@ -578,37 +676,37 @@ void KyraEngine_v3::dialogStartScript(int object, int funcNum) { _specialSceneScriptState[_dialogSceneScript] = true; } - _scriptInterpreter->initScript(&_dialogScriptState, &_dialogScriptData); - _scriptInterpreter->loadScript(_talkObjectList[object].filename, &_dialogScriptData, &_opcodesDialog); + _emc->init(&_dialogScriptState, &_dialogScriptData); + _emc->load(_talkObjectList[object].filename, &_dialogScriptData, &_opcodesDialog); _dialogScriptFuncStart = funcNum * 3 + 0; _dialogScriptFuncProc = funcNum * 3 + 1; _dialogScriptFuncEnd = funcNum * 3 + 2; - _scriptInterpreter->startScript(&_dialogScriptState, _dialogScriptFuncStart); - while (_scriptInterpreter->validScript(&_dialogScriptState)) - _scriptInterpreter->runScript(&_dialogScriptState); + _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); +void KyraEngine_MR::dialogEndScript(int object) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::dialogEndScript(%d)", object); - _scriptInterpreter->initScript(&_dialogScriptState, &_dialogScriptData); - _scriptInterpreter->startScript(&_dialogScriptState, _dialogScriptFuncEnd); + _emc->init(&_dialogScriptState, &_dialogScriptData); + _emc->start(&_dialogScriptState, _dialogScriptFuncEnd); - while (_scriptInterpreter->validScript(&_dialogScriptState)) - _scriptInterpreter->runScript(&_dialogScriptState); + while (_emc->isValid(&_dialogScriptState)) + _emc->run(&_dialogScriptState); if (_dialogSceneAnim >= 0 && _dialogSceneScript >= 0) { _specialSceneScriptState[_dialogSceneScript] = _specialSceneScriptStateBackup[_dialogSceneScript]; _dialogSceneScript = _dialogSceneAnim = -1; } - _scriptInterpreter->unloadScript(&_dialogScriptData); + _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); +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; @@ -621,17 +719,17 @@ void KyraEngine_v3::npcChatSequence(const char *str, int object, int vocHigh, in _chatVocHigh = _chatVocLow = -1; } - _scriptInterpreter->initScript(&_dialogScriptState, &_dialogScriptData); - _scriptInterpreter->startScript(&_dialogScriptState, _dialogScriptFuncProc); + _emc->init(&_dialogScriptState, &_dialogScriptData); + _emc->start(&_dialogScriptState, _dialogScriptFuncProc); resetSkipFlag(); uint32 endTime = _chatEndTime; bool running = true; while (running) { - if (!_scriptInterpreter->runScript(&_dialogScriptState)) { - _scriptInterpreter->initScript(&_dialogScriptState, &_dialogScriptData); - _scriptInterpreter->startScript(&_dialogScriptState, _dialogScriptFuncProc); + if (!_emc->run(&_dialogScriptState)) { + _emc->init(&_dialogScriptState, &_dialogScriptData); + _emc->start(&_dialogScriptState, _dialogScriptFuncProc); } const uint32 curTime = _system->getMillis(); @@ -640,19 +738,17 @@ void KyraEngine_v3::npcChatSequence(const char *str, int object, int vocHigh, in resetSkipFlag(); running = false; } - - delay(10); } _text->restoreScreen(); _chatText = 0; _chatObject= - 1; } -void KyraEngine_v3::malcolmRandomChat() { - debugC(9, kDebugLevelMain, "KyraEngine_v3::malcolmRandomChat()"); +void KyraEngine_MR::randomSceneChat() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::randomSceneChat()"); updateDlgBuffer(); - int index = (_mainCharacter.sceneId - _chapterLowestScene[_curChapter]) * 2; + int index = (_mainCharacter.sceneId - _chapterLowestScene[_currentChapter]) * 2; int vocHighBase = 0, vocHighIndex = 0, index1 = 0, index2 = 0; loadDlgHeader(vocHighBase, vocHighIndex, index1, index2); @@ -668,10 +764,10 @@ void KyraEngine_v3::malcolmRandomChat() { processDialog(vocHighIndex, vocHighBase, 0); } -void KyraEngine_v3::runDialog(int dlgIndex, int funcNum) { - debugC(9, kDebugLevelMain, "KyraEngine_v3::runDialog(%d, %d)", dlgIndex, funcNum); +void KyraEngine_MR::runDialog(int dlgIndex, int funcNum) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::runDialog(%d, %d)", dlgIndex, funcNum); - switch (_curChapter-2) { + switch (_currentChapter-2) { case 0: dlgIndex -= 34; break; diff --git a/engines/kyra/text_v3.h b/engines/kyra/text_mr.h index 9271c6b520..d96b0964ba 100644 --- a/engines/kyra/text_v3.h +++ b/engines/kyra/text_mr.h @@ -23,19 +23,19 @@ * */ -#ifndef KYRA_TEXT_V3_H -#define KYRA_TEXT_V3_H +#ifndef KYRA_TEXT_MR_H +#define KYRA_TEXT_MR_H #include "kyra/text.h" -#include "kyra/kyra_v3.h" +#include "kyra/kyra_mr.h" namespace Kyra { -class TextDisplayer_v3 : public TextDisplayer { -friend class KyraEngine_v3; +class TextDisplayer_MR : public TextDisplayer { +friend class KyraEngine_MR; public: - TextDisplayer_v3(KyraEngine_v3 *vm, Screen_v3 *screen); + TextDisplayer_MR(KyraEngine_MR *vm, Screen_MR *screen); char *preprocessString(const char *str); int dropCRIntoString(char *str, int minOffs, int maxOffs); @@ -46,8 +46,8 @@ public: void calcWidestLineBounds(int &x1, int &x2, int w, int x); protected: - KyraEngine_v3 *_vm; - Screen_v3 *_screen; + KyraEngine_MR *_vm; + Screen_MR *_screen; }; } // end of namespace Kyra diff --git a/engines/kyra/timer.cpp b/engines/kyra/timer.cpp index f275867516..1f25f88c97 100644 --- a/engines/kyra/timer.cpp +++ b/engines/kyra/timer.cpp @@ -99,17 +99,23 @@ void TimerManager::update() { _nextRun += 99999; for (Iterator pos = _timers.begin(); pos != _timers.end(); ++pos) { - if (pos->enabled && pos->countdown >= 0 && pos->nextRun <= _system->getMillis()) { - if (pos->func && pos->func->isValid()) - (*pos->func)(pos->id); + if (pos->enabled) - uint32 curTime = _system->getMillis(); - pos->lastUpdate = curTime; - pos->nextRun = curTime + pos->countdown * _vm->tickLength(); + if (pos->enabled && pos->countdown >= 0) { + if (pos->nextRun <= _system->getMillis()) { + if (pos->func && pos->func->isValid()) { + (*pos->func)(pos->id); + } + + uint32 curTime = _system->getMillis(); + pos->lastUpdate = curTime; + pos->nextRun = curTime + pos->countdown * _vm->tickLength(); + } _nextRun = MIN(_nextRun, pos->nextRun); } } + } void TimerManager::resync() { diff --git a/engines/kyra/timer_v2.cpp b/engines/kyra/timer_hof.cpp index 4c97a6dd2d..2643ae9b45 100644 --- a/engines/kyra/timer_v2.cpp +++ b/engines/kyra/timer_hof.cpp @@ -23,15 +23,15 @@ * */ -#include "kyra/kyra_v2.h" +#include "kyra/kyra_hof.h" #include "kyra/timer.h" namespace Kyra { -#define TimerV2(x) new Common::Functor1Mem<int, void, KyraEngine_v2>(this, &KyraEngine_v2::x) +#define TimerV2(x) new Common::Functor1Mem<int, void, KyraEngine_HoF>(this, &KyraEngine_HoF::x) -void KyraEngine_v2::setupTimers() { - debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v2::setupTimers()"); +void KyraEngine_HoF::setupTimers() { + debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_HoF::setupTimers()"); _timer->addTimer(0, 0, 5, 1); _timer->addTimer(1, TimerV2(timerFadeOutMessage), -1, 1); @@ -41,14 +41,14 @@ void KyraEngine_v2::setupTimers() { _timer->addTimer(5, TimerV2(timerBurnZanthia), 1, 0); } -void KyraEngine_v2::timerFadeOutMessage(int arg) { - debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v2::timerFadeOutMessage(%d)", arg); +void KyraEngine_HoF::timerFadeOutMessage(int arg) { + debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_HoF::timerFadeOutMessage(%d)", arg); if (_shownMessage) _fadeMessagePalette = 1; } -void KyraEngine_v2::timerCauldronAnimation(int arg) { - debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v2::timerCauldronAnimation(%d)", arg); +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. @@ -68,14 +68,14 @@ void KyraEngine_v2::timerCauldronAnimation(int arg) { } } -void KyraEngine_v2::timerFunc4(int arg) { - debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v2::timerFunc4(%d)", arg); +void KyraEngine_HoF::timerFunc4(int arg) { + debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_HoF::timerFunc4(%d)", arg); _timer->disable(3); setGameFlag(0xD8); } -void KyraEngine_v2::timerFunc5(int arg) { - debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v2::timerFunc5(%d)", arg); +void KyraEngine_HoF::timerFunc5(int arg) { + debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_HoF::timerFunc5(%d)", arg); _timer->disable(4); _screen->hideMouse(); _specialSceneScriptState[5] = 1; @@ -86,18 +86,18 @@ void KyraEngine_v2::timerFunc5(int arg) { _deathHandler = 4; } -void KyraEngine_v2::timerBurnZanthia(int arg) { - debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v2::timerBurnZanthia(%d)", arg); +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); + runAnimationScript("_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); +void KyraEngine_HoF::setTimer1DelaySecs(int secs) { + debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_HoF::setTimer1DelaySecs(%d)", secs); if (secs == -1) secs = 32000; @@ -105,8 +105,8 @@ void KyraEngine_v2::setTimer1DelaySecs(int secs) { _timer->setCountdown(1, secs * 60); } -void KyraEngine_v2::setWalkspeed(uint8 newSpeed) { - debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v2::setWalkspeed(%i)", newSpeed); +void KyraEngine_HoF::setWalkspeed(uint8 newSpeed) { + debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_HoF::setWalkspeed(%i)", newSpeed); if (newSpeed < 5) newSpeed = 3; diff --git a/engines/kyra/timer_v3.cpp b/engines/kyra/timer_mr.cpp index 4ce73ceaec..53865ba0e3 100644 --- a/engines/kyra/timer_v3.cpp +++ b/engines/kyra/timer_mr.cpp @@ -23,15 +23,15 @@ * */ -#include "kyra/kyra_v3.h" +#include "kyra/kyra_mr.h" #include "kyra/timer.h" namespace Kyra { -#define TimerV3(x) new Common::Functor1Mem<int, void, KyraEngine_v3>(this, &KyraEngine_v3::x) +#define TimerV3(x) new Common::Functor1Mem<int, void, KyraEngine_MR>(this, &KyraEngine_MR::x) -void KyraEngine_v3::setupTimers() { - debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v3::setupTimers()"); +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) @@ -43,31 +43,32 @@ void KyraEngine_v3::setupTimers() { _timer->addTimer(i, TimerV3(timerRunSceneScript7), 0, 0); } -void KyraEngine_v3::timerRestoreCommandLine(int arg) { - debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v3::timerRestoreCommandLine(%d)", arg); +void KyraEngine_MR::timerRestoreCommandLine(int arg) { + debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_MR::timerRestoreCommandLine(%d)", arg); if (_shownMessage) _restoreCommandLine = true; } -void KyraEngine_v3::timerRunSceneScript7(int arg) { - debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v3::timerRunSceneScript7(%d)", arg); +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; - _scriptInterpreter->startScript(&_sceneScriptState, 7); + _emc->start(&_sceneScriptState, 7); - while (_scriptInterpreter->validScript(&_sceneScriptState)) - _scriptInterpreter->runScript(&_sceneScriptState); + while (_emc->isValid(&_sceneScriptState)) + _emc->run(&_sceneScriptState); } -void KyraEngine_v3::timerFleaDeath(int arg) { - debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v3::timerFleaDeath(%d)", arg); +void KyraEngine_MR::timerFleaDeath(int arg) { + debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_MR::timerFleaDeath(%d)", arg); warning("STUB timerFleaDeath"); } -void KyraEngine_v3::setWalkspeed(uint8 speed) { - debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v3::setWalkspeed(%d)", speed); +void KyraEngine_MR::setWalkspeed(uint8 speed) { + debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_MR::setWalkspeed(%d)", speed); if (speed < 5) speed = 3; @@ -77,15 +78,15 @@ void KyraEngine_v3::setWalkspeed(uint8 speed) { _mainCharacter.walkspeed = speed; } -void KyraEngine_v3::setCommandLineRestoreTimer(int secs) { - debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v3::setCommandLineRestoreTimer(%d)", secs); +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_v3::setNextIdleAnimTimer() { - debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v3::setNextIdleAnimTimer()"); +void KyraEngine_MR::setNextIdleAnimTimer() { + debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_MR::setNextIdleAnimTimer()"); _nextIdleAnim = _system->getMillis() + _rnd.getRandomNumberRng(10, 15) * 1000; } diff --git a/engines/kyra/timer_v1.cpp b/engines/kyra/timer_v1.cpp index f2a31da554..f5e7c52ba1 100644 --- a/engines/kyra/timer_v1.cpp +++ b/engines/kyra/timer_v1.cpp @@ -170,7 +170,7 @@ void KyraEngine_v1::timerRedrawAmulet(int timerNum) { void KyraEngine_v1::setWalkspeed(uint8 newSpeed) { debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v1::setWalkspeed(%i)", newSpeed); - static const uint8 speeds[] = {11, 9, 6, 5, 3}; + static const uint8 speeds[] = { 11, 9, 6, 5, 3 }; assert(newSpeed < ARRAYSIZE(speeds)); _timer->setDelay(5, speeds[newSpeed]); 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; |