diff options
Diffstat (limited to 'engines/kyra')
90 files changed, 10018 insertions, 8310 deletions
diff --git a/engines/kyra/animator_hof.cpp b/engines/kyra/animator_hof.cpp index 9314f8604e..c5d44d10af 100644 --- a/engines/kyra/animator_hof.cpp +++ b/engines/kyra/animator_hof.cpp @@ -127,19 +127,15 @@ void KyraEngine_HoF::updateItemAnimations() { return; const ItemAnimData_v2 *s = &_itemAnimData[_nextAnimItem]; - ActiveItemAnim *a = &_activeItemAnim[_nextAnimItem]; - - if (++_nextAnimItem == 14) { - _nextAnimItem = 0; - return; - } + ActiveItemAnim *a = &_activeItemAnim[_nextAnimItem]; + _nextAnimItem = ++_nextAnimItem % _itemAnimDataSize; 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())) { + if (s->itemIndex == _mouseState && s->itemIndex == _itemInHand && _screen->isMouseVisible()) { nextFrame = true; _screen->setMouseCursor(8, 15, getShapePtr(shpIdx)); } diff --git a/engines/kyra/animator_v1.cpp b/engines/kyra/animator_lok.cpp index ea56efd9fb..1baa78b203 100644 --- a/engines/kyra/animator_v1.cpp +++ b/engines/kyra/animator_lok.cpp @@ -25,15 +25,15 @@ #include "common/endian.h" -#include "kyra/kyra_v1.h" +#include "kyra/kyra_lok.h" #include "kyra/screen.h" -#include "kyra/animator_v1.h" +#include "kyra/animator_lok.h" #include "kyra/sprites.h" #include "common/system.h" namespace Kyra { -Animator_v1::Animator_v1(KyraEngine_v1 *vm, OSystem *system) { +Animator_LoK::Animator_LoK(KyraEngine_LoK *vm, OSystem *system) { _vm = vm; _screen = vm->screen(); _initOk = false; @@ -48,14 +48,14 @@ Animator_v1::Animator_v1(KyraEngine_v1 *vm, OSystem *system) { memset(_actorBkgBackUp[1], 0, _screen->getRectSize(8, 69)); } -Animator_v1::~Animator_v1() { +Animator_LoK::~Animator_LoK() { close(); - delete [] _actorBkgBackUp[0]; - delete [] _actorBkgBackUp[1]; + delete[] _actorBkgBackUp[0]; + delete[] _actorBkgBackUp[1]; } -void Animator_v1::init(int actors_, int items_, int sprites_) { - debugC(9, kDebugLevelAnimator, "Animator_v1::init(%d, %d, %d)", actors_, items_, sprites_); +void Animator_LoK::init(int actors_, int items_, int sprites_) { + debugC(9, kDebugLevelAnimator, "Animator_LoK::init(%d, %d, %d)", actors_, items_, sprites_); _screenObjects = new AnimObject[actors_ + items_ + sprites_]; assert(_screenObjects); memset(_screenObjects, 0, sizeof(AnimObject) * (actors_ + items_ + sprites_)); @@ -67,16 +67,16 @@ void Animator_v1::init(int actors_, int items_, int sprites_) { _initOk = true; } -void Animator_v1::close() { - debugC(9, kDebugLevelAnimator, "Animator_v1::close()"); +void Animator_LoK::close() { + debugC(9, kDebugLevelAnimator, "Animator_LoK::close()"); if (_initOk) { _initOk = false; - delete [] _screenObjects; + delete[] _screenObjects; _screenObjects = _actors = _items = _sprites = _objectQueue = 0; } } -void Animator_v1::initAnimStateList() { +void Animator_LoK::initAnimStateList() { AnimObject *animStates = _screenObjects; animStates[0].index = 0; animStates[0].active = 1; @@ -118,8 +118,8 @@ void Animator_v1::initAnimStateList() { } } -void Animator_v1::preserveAllBackgrounds() { - debugC(9, kDebugLevelAnimator, "Animator_v1::preserveAllBackgrounds()"); +void Animator_LoK::preserveAllBackgrounds() { + debugC(9, kDebugLevelAnimator, "Animator_LoK::preserveAllBackgrounds()"); uint8 curPage = _screen->_curPage; _screen->_curPage = 2; @@ -134,8 +134,8 @@ void Animator_v1::preserveAllBackgrounds() { _screen->_curPage = curPage; } -void Animator_v1::flagAllObjectsForBkgdChange() { - debugC(9, kDebugLevelAnimator, "Animator_v1::flagAllObjectsForBkgdChange()"); +void Animator_LoK::flagAllObjectsForBkgdChange() { + debugC(9, kDebugLevelAnimator, "Animator_LoK::flagAllObjectsForBkgdChange()"); AnimObject *curObject = _objectQueue; while (curObject) { curObject->bkgdChangeFlag = 1; @@ -143,8 +143,8 @@ void Animator_v1::flagAllObjectsForBkgdChange() { } } -void Animator_v1::flagAllObjectsForRefresh() { - debugC(9, kDebugLevelAnimator, "Animator_v1::flagAllObjectsForRefresh()"); +void Animator_LoK::flagAllObjectsForRefresh() { + debugC(9, kDebugLevelAnimator, "Animator_LoK::flagAllObjectsForRefresh()"); AnimObject *curObject = _objectQueue; while (curObject) { curObject->refreshFlag = 1; @@ -152,8 +152,8 @@ void Animator_v1::flagAllObjectsForRefresh() { } } -void Animator_v1::restoreAllObjectBackgrounds() { - debugC(9, kDebugLevelAnimator, "Animator_v1::restoreAllObjectBackground()"); +void Animator_LoK::restoreAllObjectBackgrounds() { + debugC(9, kDebugLevelAnimator, "Animator_LoK::restoreAllObjectBackground()"); AnimObject *curObject = _objectQueue; _screen->_curPage = 2; @@ -169,8 +169,8 @@ void Animator_v1::restoreAllObjectBackgrounds() { _screen->_curPage = 0; } -void Animator_v1::preserveAnyChangedBackgrounds() { - debugC(9, kDebugLevelAnimator, "Animator_v1::preserveAnyChangedBackgrounds()"); +void Animator_LoK::preserveAnyChangedBackgrounds() { + debugC(9, kDebugLevelAnimator, "Animator_LoK::preserveAnyChangedBackgrounds()"); AnimObject *curObject = _objectQueue; _screen->_curPage = 2; @@ -185,8 +185,8 @@ void Animator_v1::preserveAnyChangedBackgrounds() { _screen->_curPage = 0; } -void Animator_v1::preserveOrRestoreBackground(AnimObject *obj, bool restore) { - debugC(9, kDebugLevelAnimator, "Animator_v1::preserveOrRestoreBackground(%p, %d)", (const void *)obj, restore); +void Animator_LoK::preserveOrRestoreBackground(AnimObject *obj, bool restore) { + debugC(9, kDebugLevelAnimator, "Animator_LoK::preserveOrRestoreBackground(%p, %d)", (const void *)obj, restore); int x = 0, y = 0, width = obj->width, height = obj->height; if (restore) { @@ -217,8 +217,8 @@ void Animator_v1::preserveOrRestoreBackground(AnimObject *obj, bool restore) { _screen->copyRegionToBuffer(_screen->_curPage, x << 3, y, width << 3, height, obj->background); } -void Animator_v1::prepDrawAllObjects() { - debugC(9, kDebugLevelAnimator, "Animator_v1::prepDrawAllObjects()"); +void Animator_LoK::prepDrawAllObjects() { + debugC(9, kDebugLevelAnimator, "Animator_LoK::prepDrawAllObjects()"); AnimObject *curObject = _objectQueue; int drawPage = 2; int flagUnk1 = 0, flagUnk2 = 0, flagUnk3 = 0; @@ -363,8 +363,8 @@ void Animator_v1::prepDrawAllObjects() { } } -void Animator_v1::copyChangedObjectsForward(int refreshFlag) { - debugC(9, kDebugLevelAnimator, "Animator_v1::copyChangedObjectsForward(%d)", refreshFlag); +void Animator_LoK::copyChangedObjectsForward(int refreshFlag) { + debugC(9, kDebugLevelAnimator, "Animator_LoK::copyChangedObjectsForward(%d)", refreshFlag); for (AnimObject *curObject = _objectQueue; curObject; curObject = curObject->nextAnimObject) { if (curObject->active) { @@ -404,16 +404,16 @@ void Animator_v1::copyChangedObjectsForward(int refreshFlag) { } } -void Animator_v1::updateAllObjectShapes() { - debugC(9, kDebugLevelAnimator, "Animator_v1::updateAllObjectShapes()"); +void Animator_LoK::updateAllObjectShapes() { + debugC(9, kDebugLevelAnimator, "Animator_LoK::updateAllObjectShapes()"); restoreAllObjectBackgrounds(); preserveAnyChangedBackgrounds(); prepDrawAllObjects(); copyChangedObjectsForward(0); } -void Animator_v1::animRemoveGameItem(int index) { - debugC(9, kDebugLevelAnimator, "Animator_v1::animRemoveGameItem(%d)", index); +void Animator_LoK::animRemoveGameItem(int index) { + debugC(9, kDebugLevelAnimator, "Animator_LoK::animRemoveGameItem(%d)", index); restoreAllObjectBackgrounds(); AnimObject *animObj = &_items[index]; @@ -427,8 +427,8 @@ void Animator_v1::animRemoveGameItem(int index) { objectRemoveQueue(_objectQueue, animObj); } -void Animator_v1::animAddGameItem(int index, uint16 sceneId) { - debugC(9, kDebugLevelAnimator, "Animator_v1::animRemoveGameItem(%d, %d)", index, sceneId); +void Animator_LoK::animAddGameItem(int index, uint16 sceneId) { + debugC(9, kDebugLevelAnimator, "Animator_LoK::animRemoveGameItem(%d, %d)", index, sceneId); restoreAllObjectBackgrounds(); assert(sceneId < _vm->_roomTableSize); Room *currentRoom = &_vm->_roomTable[sceneId]; @@ -453,8 +453,8 @@ void Animator_v1::animAddGameItem(int index, uint16 sceneId) { animObj->bkgdChangeFlag = 1; } -void Animator_v1::animAddNPC(int character) { - debugC(9, kDebugLevelAnimator, "Animator_v1::animAddNPC(%d)", character); +void Animator_LoK::animAddNPC(int character) { + debugC(9, kDebugLevelAnimator, "Animator_LoK::animAddNPC(%d)", character); restoreAllObjectBackgrounds(); AnimObject *animObj = &_actors[character]; const Character *ch = &_vm->_characterList[character]; @@ -478,8 +478,8 @@ void Animator_v1::animAddNPC(int character) { animObj->bkgdChangeFlag = 1; } -Animator_v1::AnimObject *Animator_v1::objectRemoveQueue(AnimObject *queue, AnimObject *rem) { - debugC(9, kDebugLevelAnimator, "Animator_v1::objectRemoveQueue(%p, %p)", (const void *)queue, (const void *)rem); +Animator_LoK::AnimObject *Animator_LoK::objectRemoveQueue(AnimObject *queue, AnimObject *rem) { + debugC(9, kDebugLevelAnimator, "Animator_LoK::objectRemoveQueue(%p, %p)", (const void *)queue, (const void *)rem); AnimObject *cur = queue; AnimObject *prev = queue; @@ -512,14 +512,14 @@ Animator_v1::AnimObject *Animator_v1::objectRemoveQueue(AnimObject *queue, AnimO return queue; } -Animator_v1::AnimObject *Animator_v1::objectAddHead(AnimObject *queue, AnimObject *head) { - debugC(9, kDebugLevelAnimator, "Animator_v1::objectAddHead(%p, %p)", (const void *)queue, (const void *)head); +Animator_LoK::AnimObject *Animator_LoK::objectAddHead(AnimObject *queue, AnimObject *head) { + debugC(9, kDebugLevelAnimator, "Animator_LoK::objectAddHead(%p, %p)", (const void *)queue, (const void *)head); head->nextAnimObject = queue; return head; } -Animator_v1::AnimObject *Animator_v1::objectQueue(AnimObject *queue, AnimObject *add) { - debugC(9, kDebugLevelAnimator, "Animator_v1::objectQueue(%p, %p)", (const void *)queue, (const void *)add); +Animator_LoK::AnimObject *Animator_LoK::objectQueue(AnimObject *queue, AnimObject *add) { + debugC(9, kDebugLevelAnimator, "Animator_LoK::objectQueue(%p, %p)", (const void *)queue, (const void *)add); if (add->drawY <= queue->drawY || !queue) { add->nextAnimObject = queue; return add; @@ -544,16 +544,16 @@ Animator_v1::AnimObject *Animator_v1::objectQueue(AnimObject *queue, AnimObject return queue; } -void Animator_v1::addObjectToQueue(AnimObject *object) { - debugC(9, kDebugLevelAnimator, "Animator_v1::addObjectToQueue(%p)", (const void *)object); +void Animator_LoK::addObjectToQueue(AnimObject *object) { + debugC(9, kDebugLevelAnimator, "Animator_LoK::addObjectToQueue(%p)", (const void *)object); if (!_objectQueue) _objectQueue = objectAddHead(0, object); else _objectQueue = objectQueue(_objectQueue, object); } -void Animator_v1::refreshObject(AnimObject *object) { - debugC(9, kDebugLevelAnimator, "Animator_v1::refreshObject(%p)", (const void *)object); +void Animator_LoK::refreshObject(AnimObject *object) { + debugC(9, kDebugLevelAnimator, "Animator_LoK::refreshObject(%p)", (const void *)object); _objectQueue = objectRemoveQueue(_objectQueue, object); if (_objectQueue) _objectQueue = objectQueue(_objectQueue, object); @@ -561,8 +561,8 @@ void Animator_v1::refreshObject(AnimObject *object) { _objectQueue = objectAddHead(0, object); } -void Animator_v1::makeBrandonFaceMouse() { - debugC(9, kDebugLevelAnimator, "Animator_v1::makeBrandonFaceMouse()"); +void Animator_LoK::makeBrandonFaceMouse() { + debugC(9, kDebugLevelAnimator, "Animator_LoK::makeBrandonFaceMouse()"); Common::Point mouse = _vm->getMousePos(); if (mouse.x >= _vm->_currentCharacter->x1) _vm->_currentCharacter->facing = 3; @@ -572,22 +572,22 @@ void Animator_v1::makeBrandonFaceMouse() { updateAllObjectShapes(); } -int16 Animator_v1::fetchAnimWidth(const uint8 *shape, int16 mult) { - debugC(9, kDebugLevelAnimator, "Animator_v1::fetchAnimWidth(%p, %d)", (const void *)shape, mult); +int16 Animator_LoK::fetchAnimWidth(const uint8 *shape, int16 mult) { + debugC(9, kDebugLevelAnimator, "Animator_LoK::fetchAnimWidth(%p, %d)", (const void *)shape, mult); if (_vm->gameFlags().useAltShapeHeader) shape += 2; return (((int16)READ_LE_UINT16((shape+3))) * mult) >> 8; } -int16 Animator_v1::fetchAnimHeight(const uint8 *shape, int16 mult) { - debugC(9, kDebugLevelAnimator, "Animator_v1::fetchAnimHeight(%p, %d)", (const void *)shape, mult); +int16 Animator_LoK::fetchAnimHeight(const uint8 *shape, int16 mult) { + debugC(9, kDebugLevelAnimator, "Animator_LoK::fetchAnimHeight(%p, %d)", (const void *)shape, mult); if (_vm->gameFlags().useAltShapeHeader) shape += 2; return (int16)(((int8)*(shape+2)) * mult) >> 8; } -void Animator_v1::setBrandonAnimSeqSize(int width, int height) { - debugC(9, kDebugLevelAnimator, "Animator_v1::setBrandonAnimSeqSize(%d, %d)", width, height); +void Animator_LoK::setBrandonAnimSeqSize(int width, int height) { + debugC(9, kDebugLevelAnimator, "Animator_LoK::setBrandonAnimSeqSize(%d, %d)", width, height); restoreAllObjectBackgrounds(); _brandonAnimSeqSizeWidth = _actors[0].width; _brandonAnimSeqSizeHeight = _actors[0].height; @@ -596,16 +596,16 @@ void Animator_v1::setBrandonAnimSeqSize(int width, int height) { preserveAllBackgrounds(); } -void Animator_v1::resetBrandonAnimSeqSize() { - debugC(9, kDebugLevelAnimator, "Animator_v1::resetBrandonAnimSeqSize()"); +void Animator_LoK::resetBrandonAnimSeqSize() { + debugC(9, kDebugLevelAnimator, "Animator_LoK::resetBrandonAnimSeqSize()"); restoreAllObjectBackgrounds(); _actors[0].width = _brandonAnimSeqSizeWidth; _actors[0].height = _brandonAnimSeqSizeHeight; preserveAllBackgrounds(); } -void Animator_v1::animRefreshNPC(int character) { - debugC(9, kDebugLevelAnimator, "Animator_v1::animRefreshNPC(%d)", character); +void Animator_LoK::animRefreshNPC(int character) { + debugC(9, kDebugLevelAnimator, "Animator_LoK::animRefreshNPC(%d)", character); AnimObject *animObj = &_actors[character]; Character *ch = &_vm->characterList()[character]; @@ -663,8 +663,8 @@ void Animator_v1::animRefreshNPC(int character) { refreshObject(animObj); } -void Animator_v1::setCharacterDefaultFrame(int character) { - debugC(9, kDebugLevelAnimator, "Animator_v1::setCharacterDefaultFrame()"); +void Animator_LoK::setCharacterDefaultFrame(int character) { + debugC(9, kDebugLevelAnimator, "Animator_LoK::setCharacterDefaultFrame()"); static uint16 initFrameTable[] = { 7, 41, 77, 0, 0 }; @@ -676,8 +676,8 @@ void Animator_v1::setCharacterDefaultFrame(int character) { // edit->unk6 = 1; } -void Animator_v1::setCharactersHeight() { - debugC(9, kDebugLevelAnimator, "Animator_v1::setCharactersHeight()"); +void Animator_LoK::setCharactersHeight() { + debugC(9, kDebugLevelAnimator, "Animator_LoK::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_lok.h index 3ae0b23da4..ba5882c710 100644 --- a/engines/kyra/animator_v1.h +++ b/engines/kyra/animator_lok.h @@ -23,14 +23,14 @@ * */ -#ifndef KYRA_ANIMATOR_V1_H -#define KYRA_ANIMATOR_V1_H +#ifndef KYRA_ANIMATOR_LOK_H +#define KYRA_ANIMATOR_LOK_H namespace Kyra { -class KyraEngine_v1; +class KyraEngine_LoK; class Screen; -class Animator_v1 { +class Animator_LoK { public: struct AnimObject { uint8 index; @@ -53,8 +53,8 @@ public: AnimObject *nextAnimObject; }; - Animator_v1(KyraEngine_v1 *vm, OSystem *system); - virtual ~Animator_v1(); + Animator_LoK(KyraEngine_LoK *vm, OSystem *system); + virtual ~Animator_LoK(); operator bool() const { return _initOk; } @@ -101,7 +101,7 @@ public: int _brandonScaleY; protected: - KyraEngine_v1 *_vm; + KyraEngine_LoK *_vm; Screen *_screen; OSystem *_system; bool _initOk; diff --git a/engines/kyra/animator_mr.cpp b/engines/kyra/animator_mr.cpp index ab3d347549..9702499fe7 100644 --- a/engines/kyra/animator_mr.cpp +++ b/engines/kyra/animator_mr.cpp @@ -196,6 +196,58 @@ void KyraEngine_MR::refreshAnimObjects(int force) { } } +void KyraEngine_MR::updateItemAnimations() { + debugC(9, kDebugLevelAnimator, "KyraEngine_MR::updateItemAnimations()"); + bool nextFrame = false; + + if (_itemAnimData[0].itemIndex == -1) + return; + + const ItemAnimData_v2 *s = &_itemAnimData[_nextAnimItem]; + ActiveItemAnim *a = &_activeItemAnim[_nextAnimItem]; + _nextAnimItem = ++_nextAnimItem % 10; + + uint32 ctime = _system->getMillis(); + if (ctime < a->nextFrame) + return; + + uint16 shpIdx = s->frames[a->currentFrame].index + 248; + if (s->itemIndex == _mouseState && s->itemIndex == _itemInHand && _screen->isMouseVisible()) { + nextFrame = true; + _screen->setMouseCursor(12, 19, getShapePtr(shpIdx)); + } + + if (_inventoryState) { + for (int i = 0; i < 10; i++) { + if (s->itemIndex == _mainCharacter.inventory[i]) { + nextFrame = true; + _screen->drawShape(2, getShapePtr(422 + i), 9, 0, 0, 0); + _screen->drawShape(2, getShapePtr(shpIdx), 9, 0, 0, 0); + _screen->hideMouse(); + _screen->copyRegion(9, 0, _inventoryX[i], _inventoryY[i], 24, 20, 2, 0, Screen::CR_NO_P_CHECK); + _screen->showMouse(); + } + } + } + + _screen->updateScreen(); + + for (int i = 17; i < 66; i++) { + AnimObj *animObject = &_animObjects[i]; + if (animObject->shapeIndex2 == s->itemIndex + 248) { + animObject->shapePtr = getShapePtr(shpIdx); + animObject->shapeIndex1 = shpIdx; + animObject->needRefresh = true; + nextFrame = true; + } + } + + if (nextFrame) { + a->nextFrame = _system->getMillis() + (s->frames[a->currentFrame].delay * _tickLength); + a->currentFrame = ++a->currentFrame % s->numFrames; + } +} + void KyraEngine_MR::updateCharacterAnim(int charId) { debugC(9, kDebugLevelAnimator, "KyraEngine_MR::updateCharacterAnim(%d)", charId); diff --git a/engines/kyra/debugger.cpp b/engines/kyra/debugger.cpp index 51e4d17487..7ae5414d82 100644 --- a/engines/kyra/debugger.cpp +++ b/engines/kyra/debugger.cpp @@ -27,7 +27,7 @@ #include "common/config-manager.h" #include "common/system.h" #include "kyra/debugger.h" -#include "kyra/kyra_v1.h" +#include "kyra/kyra_lok.h" #include "kyra/kyra_v2.h" #include "kyra/kyra_hof.h" #include "kyra/screen.h" @@ -36,7 +36,7 @@ namespace Kyra { -Debugger::Debugger(KyraEngine *vm) +Debugger::Debugger(KyraEngine_v1 *vm) : ::GUI::Debugger() { _vm = vm; @@ -190,22 +190,23 @@ bool Debugger::cmd_setTimerCountdown(int argc, const char **argv) { #pragma mark - -Debugger_v1::Debugger_v1(KyraEngine_v1 *vm) +Debugger_LoK::Debugger_LoK(KyraEngine_LoK *vm) : Debugger(vm), _vm(vm) { - DCmd_Register("rooms", WRAP_METHOD(Debugger_v1, cmd_listRooms)); - DCmd_Register("give", WRAP_METHOD(Debugger_v1, cmd_giveItem)); - DCmd_Register("birthstones", WRAP_METHOD(Debugger_v1, cmd_listBirthstones)); + DCmd_Register("enter", WRAP_METHOD(Debugger_LoK, cmd_enterRoom)); + DCmd_Register("rooms", WRAP_METHOD(Debugger_LoK, cmd_listRooms)); + DCmd_Register("give", WRAP_METHOD(Debugger_LoK, cmd_giveItem)); + DCmd_Register("birthstones", WRAP_METHOD(Debugger_LoK, cmd_listBirthstones)); } -void Debugger_v1::preEnter() { +void Debugger_LoK::preEnter() { //_vm->midi.pause(1); } -void Debugger_v1::postEnter() { +void Debugger_LoK::postEnter() { //_vm->midi.pause(0); } -bool Debugger_v1::cmd_enterRoom(int argc, const char **argv) { +bool Debugger_LoK::cmd_enterRoom(int argc, const char **argv) { uint direction = 0; if (argc > 1) { int room = atoi(argv[1]); @@ -244,7 +245,7 @@ bool Debugger_v1::cmd_enterRoom(int argc, const char **argv) { return true; } -bool Debugger_v1::cmd_listRooms(int argc, const char **argv) { +bool Debugger_LoK::cmd_listRooms(int argc, const char **argv) { for (int i = 0; i < _vm->_roomTableSize; i++) { DebugPrintf("%-3i: %-10s", i, _vm->_roomFilenameTable[_vm->_roomTable[i].nameIndex]); if (!(i % 8)) @@ -255,7 +256,7 @@ bool Debugger_v1::cmd_listRooms(int argc, const char **argv) { return true; } -bool Debugger_v1::cmd_giveItem(int argc, const char **argv) { +bool Debugger_LoK::cmd_giveItem(int argc, const char **argv) { if (argc == 2) { int item = atoi(argv[1]); @@ -274,7 +275,7 @@ bool Debugger_v1::cmd_giveItem(int argc, const char **argv) { return true; } -bool Debugger_v1::cmd_listBirthstones(int argc, const char **argv) { +bool Debugger_LoK::cmd_listBirthstones(int argc, const char **argv) { DebugPrintf("Needed Birthstone gems:\n"); for (int i = 0; i < ARRAYSIZE(_vm->_birthstoneGemTable); ++i) DebugPrintf("%-2d '%s'\n", _vm->_birthstoneGemTable[i], _vm->_itemList[_vm->_birthstoneGemTable[i]]); @@ -421,9 +422,8 @@ bool Debugger_v2::cmd_giveItem(int argc, const char **argv) { if (argc == 2) { int item = atoi(argv[1]); - // Kyrandia 2 has only 178 items (-1 to 176), otherwise it will crash - if (item < -1 || item > 176) { - DebugPrintf("itemid must be any value between (including) -1 and 176\n"); + if (item < -1 || item > _vm->engineDesc().maxItemId) { + DebugPrintf("itemid must be any value between (including) -1 and %d\n", _vm->engineDesc().maxItemId); return true; } diff --git a/engines/kyra/debugger.h b/engines/kyra/debugger.h index ab5657bbde..7cdfa26e93 100644 --- a/engines/kyra/debugger.h +++ b/engines/kyra/debugger.h @@ -30,18 +30,18 @@ namespace Kyra { -class KyraEngine; class KyraEngine_v1; +class KyraEngine_LoK; class KyraEngine_v2; class KyraEngine_HoF; class Debugger : public ::GUI::Debugger { public: - Debugger(KyraEngine *vm); + Debugger(KyraEngine_v1 *vm); virtual ~Debugger() {} // we need this for __SYMBIAN32__ archaic gcc/UIQ protected: - KyraEngine *_vm; + KyraEngine_v1 *_vm; bool cmd_setScreenDebug(int argc, const char **argv); bool cmd_loadPalette(int argc, const char **argv); @@ -54,13 +54,13 @@ protected: bool cmd_setTimerCountdown(int argc, const char **argv); }; -class Debugger_v1 : public Debugger { +class Debugger_LoK : public Debugger { public: - Debugger_v1(KyraEngine_v1 *vm); - virtual ~Debugger_v1() {} // we need this for __SYMBIAN32__ archaic gcc/UIQ + Debugger_LoK(KyraEngine_LoK *vm); + virtual ~Debugger_LoK() {} // we need this for __SYMBIAN32__ archaic gcc/UIQ protected: - KyraEngine_v1 *_vm; + KyraEngine_LoK *_vm; virtual void preEnter(); virtual void postEnter(); diff --git a/engines/kyra/detection.cpp b/engines/kyra/detection.cpp index b921314e68..344121b503 100644 --- a/engines/kyra/detection.cpp +++ b/engines/kyra/detection.cpp @@ -22,8 +22,8 @@ * $Id$ */ -#include "kyra/kyra.h" #include "kyra/kyra_v1.h" +#include "kyra/kyra_lok.h" #include "kyra/kyra_hof.h" #include "kyra/kyra_mr.h" @@ -41,22 +41,25 @@ struct KYRAGameDescription { namespace { -#define FLAGS(x, y, z, a, b, id) { Common::UNK_LANG, Common::kPlatformUnknown, x, y, z, a, b, id } +#define FLAGS(x, y, z, a, b, c, id) { Common::UNK_LANG, Common::kPlatformUnknown, x, y, z, a, b, c, id } -#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 KYRA1_FLOPPY_FLAGS FLAGS(false, false, false, false, false, false, Kyra::GI_KYRA1) +#define KYRA1_AMIGA_FLAGS FLAGS(false, false, false, false, false, false, Kyra::GI_KYRA1) +#define KYRA1_TOWNS_FLAGS FLAGS(false, true, false, false, false, false, Kyra::GI_KYRA1) +#define KYRA1_TOWNS_SJIS_FLAGS FLAGS(false, true, false, true, false, false, Kyra::GI_KYRA1) +#define KYRA1_CD_FLAGS FLAGS(false, true, true, false, false, false, Kyra::GI_KYRA1) +#define KYRA1_DEMO_FLAGS FLAGS(true, false, false, false, false, false, Kyra::GI_KYRA1) -#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 KYRA2_FLOPPY_FLAGS FLAGS(false, false, false, false, false, false, Kyra::GI_KYRA2) +#define KYRA2_FLOPPY_CMP_FLAGS FLAGS(false, false, false, false, false, true, Kyra::GI_KYRA2) +#define KYRA2_CD_FLAGS FLAGS(false, false, true, false, false, false, Kyra::GI_KYRA2) +#define KYRA2_CD_DEMO_FLAGS FLAGS(true, false, true, false, false, false, Kyra::GI_KYRA2) +#define KYRA2_DEMO_FLAGS FLAGS(true, false, false, false, false, false, Kyra::GI_KYRA2) +#define KYRA2_TOWNS_FLAGS FLAGS(false, false, false, false, false, false, Kyra::GI_KYRA2) +#define KYRA2_TOWNS_SJIS_FLAGS FLAGS(false, false, false, true, false, false, Kyra::GI_KYRA2) -#define KYRA3_CD_FLAGS FLAGS(false, false, true, false, true, Kyra::GI_KYRA3) +#define KYRA3_CD_FLAGS FLAGS(false, false, true, false, true, true, Kyra::GI_KYRA3) +#define KYRA3_CD_INS_FLAGS FLAGS(false, false, true, false, true, true, Kyra::GI_KYRA3) const KYRAGameDescription adGameDescs[] = { { @@ -279,7 +282,7 @@ const KYRAGameDescription adGameDescs[] = { AD_ENTRY1("GEMCUT.PAK", "d8327fc4b7a72b23c900fa13aef4093a"), Common::IT_ITA, Common::kPlatformPC, - Common::ADGF_NO_FLAGS + Common::ADGF_CD }, KYRA1_CD_FLAGS }, @@ -296,6 +299,66 @@ const KYRAGameDescription adGameDescs[] = { KYRA1_DEMO_FLAGS }, + { // Floppy version + { + "kyra2", + 0, + AD_ENTRY1("WESTWOOD.001", "3f52dda68c4f7696c8309038be9f4151"), + Common::EN_ANY, + Common::kPlatformPC, + Common::ADGF_NO_FLAGS + }, + KYRA2_FLOPPY_CMP_FLAGS + }, + + { // Floppy version + { + "kyra2", + 0, + AD_ENTRY1("WESTWOOD.001", "d787b9559afddfe058b84c0b3a787224"), + Common::DE_DEU, + Common::kPlatformPC, + Common::ADGF_NO_FLAGS + }, + KYRA2_FLOPPY_CMP_FLAGS + }, + + { // // Floppy version extracted + { + "kyra2", + "Extracted", + AD_ENTRY1("FATE.PAK", "1ba18be685ad8e5a0ab5d46a0ce4d345"), + Common::EN_ANY, + Common::kPlatformPC, + Common::ADGF_NO_FLAGS + }, + KYRA2_FLOPPY_FLAGS + }, + + { // Floppy version extracted + { + "kyra2", + "Extracted", + AD_ENTRY1("FATE.PAK", "262fb69dd8e52e596c7aefc6456f7c1b"), + Common::DE_DEU, + Common::kPlatformPC, + Common::ADGF_NO_FLAGS + }, + KYRA2_FLOPPY_FLAGS + }, + + { // Floppy version extracted + { + "kyra2", + "Extracted", + AD_ENTRY1("FATE.PAK", "f7de11506b4c8fdf64bc763206c3e4e7"), + Common::FR_FRA, + Common::kPlatformPC, + Common::ADGF_NO_FLAGS + }, + KYRA2_FLOPPY_FLAGS + }, + { // CD version { "kyra2", @@ -401,11 +464,65 @@ const KYRAGameDescription adGameDescs[] = { KYRA2_TOWNS_SJIS_FLAGS }, + // Kyra3 + + // non installed version + { + { + "kyra3", + 0, + { + { "ONETIME.PAK", 0, "3833ff312757b8e6147f464cca0a6587", -1 }, + { "WESTWOOD.001", 0, 0, -1 }, + { 0, 0, 0, 0 } + }, + Common::EN_ANY, + Common::kPlatformPC, + Common::ADGF_DROPLANGUAGE + }, + KYRA3_CD_INS_FLAGS + }, { { "kyra3", 0, - AD_ENTRY1("ONETIME.PAK", "3833ff312757b8e6147f464cca0a6587"), + { + { "ONETIME.PAK", 0, "3833ff312757b8e6147f464cca0a6587", -1 }, + { "WESTWOOD.001", 0, 0, -1 }, + { 0, 0, 0, 0 } + }, + Common::DE_DEU, + Common::kPlatformPC, + Common::ADGF_DROPLANGUAGE + }, + KYRA3_CD_INS_FLAGS + }, + { + { + "kyra3", + 0, + { + { "ONETIME.PAK", 0, "3833ff312757b8e6147f464cca0a6587", -1 }, + { "WESTWOOD.001", 0, 0, -1 }, + { 0, 0, 0, 0 } + }, + Common::FR_FRA, + Common::kPlatformPC, + Common::ADGF_DROPLANGUAGE + }, + KYRA3_CD_INS_FLAGS + }, + + // installed version + { + { + "kyra3", + 0, + { + { "ONETIME.PAK", 0, "3833ff312757b8e6147f464cca0a6587", -1 }, + { "AUD.PAK", 0, 0, -1 }, + { 0, 0, 0, 0 } + }, Common::EN_ANY, Common::kPlatformPC, Common::ADGF_DROPLANGUAGE @@ -416,7 +533,11 @@ const KYRAGameDescription adGameDescs[] = { { "kyra3", 0, - AD_ENTRY1("ONETIME.PAK", "3833ff312757b8e6147f464cca0a6587"), + { + { "ONETIME.PAK", 0, "3833ff312757b8e6147f464cca0a6587", -1 }, + { "AUD.PAK", 0, 0, -1 }, + { 0, 0, 0, 0 } + }, Common::DE_DEU, Common::kPlatformPC, Common::ADGF_DROPLANGUAGE @@ -427,7 +548,11 @@ const KYRAGameDescription adGameDescs[] = { { "kyra3", 0, - AD_ENTRY1("ONETIME.PAK", "3833ff312757b8e6147f464cca0a6587"), + { + { "ONETIME.PAK", 0, "3833ff312757b8e6147f464cca0a6587", -1 }, + { "AUD.PAK", 0, 0, -1 }, + { 0, 0, 0, 0 } + }, Common::FR_FRA, Common::kPlatformPC, Common::ADGF_DROPLANGUAGE @@ -435,7 +560,7 @@ const KYRAGameDescription adGameDescs[] = { KYRA3_CD_FLAGS }, - { AD_TABLE_END_MARKER, FLAGS(0, 0, 0, 0, 0, 0) } + { AD_TABLE_END_MARKER, FLAGS(0, 0, 0, 0, 0, 0, 0) } }; const PlainGameDescriptor gameList[] = { @@ -506,7 +631,7 @@ bool KyraMetaEngine::createInstance(OSystem *syst, Engine **engine, const Common switch (flags.gameID) { case Kyra::GI_KYRA1: - *engine = new Kyra::KyraEngine_v1(syst, flags); + *engine = new Kyra::KyraEngine_LoK(syst, flags); break; case Kyra::GI_KYRA2: *engine = new Kyra::KyraEngine_HoF(syst, flags); @@ -524,7 +649,7 @@ bool KyraMetaEngine::createInstance(OSystem *syst, Engine **engine, const Common SaveStateList KyraMetaEngine::listSaves(const char *target) const { Common::SaveFileManager *saveFileMan = g_system->getSavefileManager(); - Kyra::KyraEngine::SaveHeader header; + Kyra::KyraEngine_v1::SaveHeader header; Common::String pattern = target; pattern += ".???"; @@ -540,7 +665,7 @@ SaveStateList KyraMetaEngine::listSaves(const char *target) const { if (slotNum >= 0 && slotNum <= 999) { Common::InSaveFile *in = saveFileMan->openForLoading(file->c_str()); if (in) { - if (Kyra::KyraEngine::readSaveHeader(in, header) == Kyra::KyraEngine::kRSHENoError) + if (Kyra::KyraEngine_v1::readSaveHeader(in, header) == Kyra::KyraEngine_v1::kRSHENoError) saveList.push_back(SaveStateDescriptor(slotNum, header.description, *file)); delete in; } diff --git a/engines/kyra/gui.cpp b/engines/kyra/gui.cpp index d2e02671c9..96ea233025 100644 --- a/engines/kyra/gui.cpp +++ b/engines/kyra/gui.cpp @@ -33,10 +33,9 @@ namespace Kyra { -GUI::GUI(KyraEngine *kyra) +GUI::GUI(KyraEngine_v1 *kyra) : _vm(kyra), _screen(kyra->screen()), _text(kyra->text()) { _menuButtonList = 0; - _haveScrollButtons = false; _redrawButtonFunctor = BUTTON_FUNCTOR(GUI, this, &GUI::redrawButtonCallback); _redrawShadedButtonFunctor = BUTTON_FUNCTOR(GUI, this, &GUI::redrawShadedButtonCallback); @@ -148,13 +147,12 @@ void GUI::initMenu(Menu &menu) { } if (menu.scrollUpButtonX != -1) { - _haveScrollButtons = true; - Button *scrollUpButton = getScrollUpButton(); scrollUpButton->x = menu.scrollUpButtonX + menu.x; scrollUpButton->y = menu.scrollUpButtonY + menu.y; scrollUpButton->buttonCallback = getScrollUpButtonHandler(); scrollUpButton->nextButton = 0; + scrollUpButton->mouseWheel = -1; _menuButtonList = addButtonToList(_menuButtonList, scrollUpButton); updateMenuButton(scrollUpButton); @@ -164,11 +162,10 @@ void GUI::initMenu(Menu &menu) { scrollDownButton->y = menu.scrollDownButtonY + menu.y; scrollDownButton->buttonCallback = getScrollDownButtonHandler(); scrollDownButton->nextButton = 0; + scrollDownButton->mouseWheel = 1; _menuButtonList = addButtonToList(_menuButtonList, scrollDownButton); updateMenuButton(scrollDownButton); - } else { - _haveScrollButtons = false; } _screen->showMouse(); @@ -342,7 +339,7 @@ int GUI::getNextSavegameSlot() { #pragma mark - -MainMenu::MainMenu(KyraEngine *vm) : _vm(vm), _screen(0) { +MainMenu::MainMenu(KyraEngine_v1 *vm) : _vm(vm), _screen(0) { _screen = _vm->screen(); _nextUpdate = 0; _system = g_system; @@ -382,7 +379,7 @@ bool MainMenu::getInput() { while (_system->getEventManager()->pollEvent(event)) { switch (event.type) { case Common::EVENT_QUIT: - _quitFlag = true; + _vm->quitGame(); break; case Common::EVENT_LBUTTONUP: return true; @@ -396,7 +393,6 @@ bool MainMenu::getInput() { int MainMenu::handle(int dim) { debugC(9, kDebugLevelMain, "MainMenu::handle(%d)", dim); int command = -1; - _quitFlag = false; uint8 colorMap[16]; memset(colorMap, 0, sizeof(colorMap)); @@ -436,7 +432,7 @@ int MainMenu::handle(int dim) { Common::Rect menuRect(x + 16, y + 4, x + width - 16, y + 4 + fh * 4); - while (!_quitFlag) { + while (!_vm->quit()) { updateAnimation(); bool mousePressed = getInput(); @@ -467,7 +463,7 @@ int MainMenu::handle(int dim) { _system->delayMillis(10); } - if (_quitFlag) + if (_vm->quit()) command = -1; _screen->copyRegion(backUpX, backUpY, backUpX, backUpY, backUpWidth, backUpHeight, 3, 0); diff --git a/engines/kyra/gui.h b/engines/kyra/gui.h index a04ac20de3..1361bdb399 100644 --- a/engines/kyra/gui.h +++ b/engines/kyra/gui.h @@ -26,7 +26,7 @@ #ifndef KYRA_GUI_H #define KYRA_GUI_H -#include "kyra/kyra.h" +#include "kyra/kyra_v1.h" #include "common/ptr.h" #include "common/array.h" @@ -75,6 +75,8 @@ struct Button { uint16 flags2; + int8 mouseWheel; + Callback buttonCallback; }; @@ -133,14 +135,14 @@ class TextDisplayer; class GUI { public: - GUI(KyraEngine *vm); + GUI(KyraEngine_v1 *vm); virtual ~GUI() {} // button specific virtual Button *addButtonToList(Button *list, Button *newButton); virtual void processButton(Button *button) = 0; - virtual int processButtonList(Button *buttonList, uint16 inputFlags) = 0; + virtual int processButtonList(Button *buttonList, uint16 inputFlags, int8 mouseWheel) = 0; virtual int redrawShadedButtonCallback(Button *button); virtual int redrawButtonCallback(Button *button); @@ -152,12 +154,11 @@ public: void processHighlights(Menu &menu, int mouseX, int mouseY); protected: - KyraEngine *_vm; + KyraEngine_v1 *_vm; Screen *_screen; TextDisplayer *_text; Button *_menuButtonList; - bool _haveScrollButtons; bool _displayMenu; bool _displaySubMenu; bool _cancelSubMenu; @@ -195,7 +196,7 @@ class Movie; class MainMenu { public: - MainMenu(KyraEngine *vm); + MainMenu(KyraEngine_v1 *vm); virtual ~MainMenu() {} struct Animation { @@ -218,12 +219,10 @@ public: void init(StaticData data, Animation anim); int handle(int dim); private: - KyraEngine *_vm; + KyraEngine_v1 *_vm; Screen *_screen; OSystem *_system; - bool _quitFlag; - StaticData _static; struct AnimIntern { int curFrame; diff --git a/engines/kyra/gui_hof.cpp b/engines/kyra/gui_hof.cpp index d1fcaa4712..555934cb7f 100644 --- a/engines/kyra/gui_hof.cpp +++ b/engines/kyra/gui_hof.cpp @@ -23,7 +23,7 @@ * */ -#include "kyra/kyra.h" +#include "kyra/kyra_v1.h" #include "kyra/kyra_hof.h" #include "kyra/screen.h" #include "kyra/wsamovie.h" @@ -271,7 +271,7 @@ void KyraEngine_HoF::redrawInventory(int page) { } void KyraEngine_HoF::scrollInventoryWheel() { - WSAMovieV2 movie(this, _screen); + WSAMovie_v2 movie(this, _screen); movie.open("INVWHEEL.WSA", 0, 0); int frames = movie.opened() ? movie.frames() : 6; memcpy(_screenBuffer, _screen->getCPagePtr(2), 64000); @@ -348,7 +348,7 @@ int KyraEngine_HoF::bookButton(Button *button) { return 0; } - if (_handItemSet != -1) { + if (_mouseState != -1) { snd_playSoundEffect(0x0D); return 0; } @@ -455,12 +455,12 @@ void KyraEngine_HoF::showBookPage() { char filename[16]; sprintf(filename, "PAGE%.01X.", _bookCurPage); - strcat(filename, _languageExtension[_lang]); + strcat(filename, (_flags.isTalkie || _flags.platform == Common::kPlatformFMTowns || _lang) ? _languageExtension[_lang] : "TXT"); uint8 *leftPage = _res->fileData(filename, 0); int leftPageY = _bookPageYOffset[_bookCurPage]; sprintf(filename, "PAGE%.01X.", _bookCurPage+1); - strcat(filename, _languageExtension[_lang]); + strcat(filename, (_flags.isTalkie || _flags.platform == Common::kPlatformFMTowns || _lang) ? _languageExtension[_lang] : "TXT"); uint8 *rightPage = (_bookCurPage != _bookMaxPage) ? _res->fileData(filename, 0) : 0; int rightPageY = _bookPageYOffset[_bookCurPage+1]; @@ -468,13 +468,13 @@ void KyraEngine_HoF::showBookPage() { if (leftPage) { bookDecodeText(leftPage); bookPrintText(2, leftPage, 20, leftPageY+20, 0x31); - delete [] leftPage; + delete[] leftPage; } if (rightPage) { bookDecodeText(rightPage); bookPrintText(2, rightPage, 176, rightPageY+20, 0x31); - delete [] rightPage; + delete[] rightPage; } _screen->showMouse(); } @@ -515,6 +515,7 @@ void KyraEngine_HoF::bookLoop() { _screen->updateScreen(); _screen->showMouse(); } + _system->delayMillis(10); } _screen->clearPage(2); } @@ -600,7 +601,7 @@ int KyraEngine_HoF::cauldronButton(Button *button) { return 0; } - if (!_screen->isMouseVisible() || _handItemSet < -1) + if (!_screen->isMouseVisible() || _mouseState < -1) return 0; if (queryGameFlag(0xE4)) { @@ -666,6 +667,8 @@ int KyraEngine_HoF::cauldronButton(Button *button) { #pragma mark - int GUI_HoF::optionsButton(Button *button) { + PauseTimer pause(*_vm->_timer); + _restartGame = false; _reloadTemporarySave = false; @@ -678,8 +681,8 @@ int GUI_HoF::optionsButton(Button *button) { _vm->showMessage(0, 0xCF); - if (_vm->_handItemSet < -1) { - _vm->_handItemSet = -1; + if (_vm->_mouseState < -1) { + _vm->_mouseState = -1; _screen->hideMouse(); _screen->setMouseCursor(1, 1, _vm->getShapePtr(0)); _screen->showMouse(); @@ -824,10 +827,10 @@ void GUI_HoF::drawSliderBar(int slider, const uint8 *shape) { int position = 0; if (_vm->gameFlags().isTalkie) { - position = _vm->getVolume(KyraEngine::kVolumeEntry(slider)); + position = _vm->getVolume(KyraEngine_v1::kVolumeEntry(slider)); } else { if (slider < 2) - position = _vm->getVolume(KyraEngine::kVolumeEntry(slider)); + position = _vm->getVolume(KyraEngine_v1::kVolumeEntry(slider)); else if (slider == 2) position = (_vm->_configWalkspeed == 3) ? 97 : 2; else if (slider == 3) @@ -897,7 +900,7 @@ int GUI_HoF::audioOptions(Button *caller) { restorePage1(_vm->_screenBuffer); backUpPage1(_vm->_screenBuffer); - if (speechEnabled && !_vm->textEnabled() && (!_vm->speechEnabled() || _vm->getVolume(KyraEngine::kVolumeSpeech) == 2)) { + if (speechEnabled && !_vm->textEnabled() && (!_vm->speechEnabled() || _vm->getVolume(KyraEngine_v1::kVolumeSpeech) == 2)) { _vm->_configVoice = 0; choiceDialog(0x1D, 0); } @@ -975,7 +978,7 @@ int GUI_HoF::gameOptionsTalkie(Button *caller) { if (textEnabled && !_vm->textEnabled() && !_vm->speechEnabled()) { _vm->_configVoice = 1; - _vm->setVolume(KyraEngine::kVolumeSpeech, 75); + _vm->setVolume(KyraEngine_v1::kVolumeSpeech, 75); choiceDialog(0x1E, 0); } @@ -1051,10 +1054,10 @@ int GUI_HoF::sliderHandler(Button *caller) { int oldVolume = 0; if (_vm->gameFlags().isTalkie) { - oldVolume = _vm->getVolume(KyraEngine::kVolumeEntry(button)); + oldVolume = _vm->getVolume(KyraEngine_v1::kVolumeEntry(button)); } else { if (button < 2) - oldVolume = _vm->getVolume(KyraEngine::kVolumeEntry(button)); + oldVolume = _vm->getVolume(KyraEngine_v1::kVolumeEntry(button)); else if (button == 2) oldVolume = (_vm->_configWalkspeed == 3) ? 97 : 2; else if (button == 3) @@ -1089,7 +1092,7 @@ int GUI_HoF::sliderHandler(Button *caller) { _vm->_configVoice = 1; } - _vm->setVolume(KyraEngine::kVolumeEntry(button), newVolume); + _vm->setVolume(KyraEngine_v1::kVolumeEntry(button), newVolume); switch (button) { case 0: @@ -1109,7 +1112,7 @@ int GUI_HoF::sliderHandler(Button *caller) { } } else { if (button < 2) { - _vm->setVolume(KyraEngine::kVolumeEntry(button), newVolume); + _vm->setVolume(KyraEngine_v1::kVolumeEntry(button), newVolume); if (button == 0) lastMusicCommand = _vm->_lastMusicCommand; else @@ -1126,7 +1129,7 @@ int GUI_HoF::sliderHandler(Button *caller) { if (playSoundEffect) _vm->snd_playSoundEffect(0x18); else if (lastMusicCommand >= 0) - _vm->snd_playWanderScoreViaMap(lastMusicCommand, 1); + _vm->snd_playWanderScoreViaMap(lastMusicCommand, 0); _screen->updateScreen(); return 0; diff --git a/engines/kyra/gui_v1.cpp b/engines/kyra/gui_lok.cpp index e5a0c42281..6fa30c9e9a 100644 --- a/engines/kyra/gui_v1.cpp +++ b/engines/kyra/gui_lok.cpp @@ -23,13 +23,14 @@ * */ -#include "kyra/kyra_v1.h" +#include "kyra/kyra_lok.h" #include "kyra/screen.h" #include "kyra/script.h" #include "kyra/text.h" -#include "kyra/animator_v1.h" +#include "kyra/animator_lok.h" #include "kyra/sound.h" -#include "kyra/gui_v1.h" +#include "kyra/gui_lok.h" +#include "kyra/timer.h" #include "common/config-manager.h" #include "common/savefile.h" @@ -38,13 +39,13 @@ namespace Kyra { -void KyraEngine_v1::initMainButtonList() { +void KyraEngine_LoK::initMainButtonList() { _buttonList = &_buttonData[0]; for (int i = 0; _buttonDataListPtr[i]; ++i) _buttonList = _gui->addButtonToList(_buttonList, _buttonDataListPtr[i]); } -int KyraEngine_v1::buttonInventoryCallback(Button *caller) { +int KyraEngine_LoK::buttonInventoryCallback(Button *caller) { int itemOffset = caller->index - 2; uint8 inventoryItem = _currentCharacter->inventoryItems[itemOffset]; if (_itemInHand == -1) { @@ -88,7 +89,7 @@ int KyraEngine_v1::buttonInventoryCallback(Button *caller) { return 0; } -int KyraEngine_v1::buttonAmuletCallback(Button *caller) { +int KyraEngine_LoK::buttonAmuletCallback(Button *caller) { if (!(_deathHandler & 8)) return 1; int jewel = caller->index - 0x14; @@ -186,30 +187,30 @@ int KyraEngine_v1::buttonAmuletCallback(Button *caller) { #pragma mark - -GUI_v1::GUI_v1(KyraEngine_v1 *vm, Screen_v1 *screen) : GUI(vm), _vm(vm), _screen(screen) { +GUI_LoK::GUI_LoK(KyraEngine_LoK *vm, Screen_LoK *screen) : GUI(vm), _vm(vm), _screen(screen) { _menu = 0; initStaticResource(); - _scrollUpFunctor = BUTTON_FUNCTOR(GUI_v1, this, &GUI_v1::scrollUp); - _scrollDownFunctor = BUTTON_FUNCTOR(GUI_v1, this, &GUI_v1::scrollDown); + _scrollUpFunctor = BUTTON_FUNCTOR(GUI_LoK, this, &GUI_LoK::scrollUp); + _scrollDownFunctor = BUTTON_FUNCTOR(GUI_LoK, this, &GUI_LoK::scrollDown); } -GUI_v1::~GUI_v1() { - delete [] _menu; +GUI_LoK::~GUI_LoK() { + delete[] _menu; } -int GUI_v1::processButtonList(Button *list, uint16 inputFlag) { - if (_haveScrollButtons) { - if (_mouseWheel < 0) - scrollUp(&_scrollUpButton); - else if (_mouseWheel > 0) - scrollDown(&_scrollDownButton); - } +int GUI_LoK::processButtonList(Button *list, uint16 inputFlag, int8 mouseWheel) { while (list) { if (list->flags & 8) { list = list->nextButton; continue; } + if (mouseWheel && list->mouseWheel == mouseWheel && list->buttonCallback) { + if ((*list->buttonCallback.get())(list)) { + break; + } + } + int x = list->x; int y = list->y; assert(_screen->getScreenDim(list->dimTableIndex) != 0); @@ -271,7 +272,7 @@ int GUI_v1::processButtonList(Button *list, uint16 inputFlag) { return 0; } -void GUI_v1::processButton(Button *button) { +void GUI_LoK::processButton(Button *button) { if (!button) return; @@ -315,7 +316,7 @@ void GUI_v1::processButton(Button *button) { (*callback.get())(button); } -void GUI_v1::setGUILabels() { +void GUI_LoK::setGUILabels() { int offset = 0; int offsetOptions = 0; int offsetMainMenu = 0; @@ -336,6 +337,8 @@ void GUI_v1::setGUILabels() { } else if (_vm->gameFlags().lang == Common::ES_ESP) { offsetOn = offsetMainMenu = offsetOptions = offset = -4; menuLabelGarbageOffset = 72; + } else if (_vm->gameFlags().lang == Common::IT_ITA) { + offsetOn = offsetMainMenu = offsetOptions = offset = 32; } else if (_vm->gameFlags().lang == Common::DE_DEU) { offset = offsetMainMenu = offsetOn = offsetOptions = 24; } else if (_vm->gameFlags().platform == Common::kPlatformFMTowns || _vm->gameFlags().platform == Common::kPlatformPC98) { @@ -405,7 +408,9 @@ void GUI_v1::setGUILabels() { _onCDString = _vm->_guiStrings[21]; } -int GUI_v1::buttonMenuCallback(Button *caller) { +int GUI_LoK::buttonMenuCallback(Button *caller) { + PauseTimer pause(*_vm->_timer); + _displayMenu = true; assert(_vm->_guiStrings); @@ -420,7 +425,7 @@ int GUI_v1::buttonMenuCallback(Button *caller) { */ setGUILabels(); - if (_vm->_currentCharacter->sceneId == 210 && _vm->_deathHandler == 0xFF) { + if (_vm->_currentCharacter->sceneId == 210 && _vm->_deathHandler == -1) { _vm->snd_playSoundEffect(0x36); return 0; } @@ -457,7 +462,7 @@ int GUI_v1::buttonMenuCallback(Button *caller) { while (_displayMenu && !_vm->_quitFlag) { Common::Point mouse = _vm->getMousePos(); processHighlights(_menu[_toplevelMenu], mouse.x, mouse.y); - processButtonList(_menuButtonList, 0); + processButtonList(_menuButtonList, 0, 0); getInput(); } @@ -472,7 +477,7 @@ int GUI_v1::buttonMenuCallback(Button *caller) { return 0; } -void GUI_v1::getInput() { +void GUI_LoK::getInput() { Common::Event event; static uint32 lastScreenUpdate = 0; uint32 now = _vm->_system->getMillis(); @@ -515,15 +520,15 @@ void GUI_v1::getInput() { _vm->_system->delayMillis(3); } -int GUI_v1::resumeGame(Button *button) { - debugC(9, kDebugLevelGUI, "GUI_v1::resumeGame()"); +int GUI_LoK::resumeGame(Button *button) { + debugC(9, kDebugLevelGUI, "GUI_LoK::resumeGame()"); updateMenuButton(button); _displayMenu = false; return 0; } -void GUI_v1::setupSavegames(Menu &menu, int num) { +void GUI_LoK::setupSavegames(Menu &menu, int num) { Common::InSaveFile *in; static char savenames[5][31]; uint8 startSlot; @@ -541,7 +546,7 @@ void GUI_v1::setupSavegames(Menu &menu, int num) { for (int i = startSlot; i < num; ++i) menu.item[i].enabled = 0; - KyraEngine::SaveHeader header; + KyraEngine_v1::SaveHeader header; for (int i = startSlot; i < num && uint(_savegameOffset + i) < _saveSlots.size(); i++) { if ((in = _vm->openSaveForReading(_vm->getSavegameFilename(_saveSlots[i + _savegameOffset]), header))) { strncpy(savenames[i], header.description.c_str(), 31); @@ -553,8 +558,8 @@ void GUI_v1::setupSavegames(Menu &menu, int num) { } } -int GUI_v1::saveGameMenu(Button *button) { - debugC(9, kDebugLevelGUI, "GUI_v1::saveGameMenu()"); +int GUI_LoK::saveGameMenu(Button *button) { + debugC(9, kDebugLevelGUI, "GUI_LoK::saveGameMenu()"); updateSaveList(); updateMenuButton(button); @@ -566,7 +571,7 @@ int GUI_v1::saveGameMenu(Button *button) { _menu[2].menuNameString = _vm->_guiStrings[8]; // Select a position to save to: _specialSavegameString = _vm->_guiStrings[9]; // [ EMPTY SLOT ] for (int i = 0; i < 5; i++) - _menu[2].item[i].callback = BUTTON_FUNCTOR(GUI_v1, this, &GUI_v1::saveGame); + _menu[2].item[i].callback = BUTTON_FUNCTOR(GUI_LoK, this, &GUI_LoK::saveGame); _savegameOffset = 0; setupSavegames(_menu[2], 5); @@ -581,7 +586,7 @@ int GUI_v1::saveGameMenu(Button *button) { getInput(); Common::Point mouse = _vm->getMousePos(); processHighlights(_menu[2], mouse.x, mouse.y); - processButtonList(_menuButtonList, 0); + processButtonList(_menuButtonList, 0, _mouseWheel); } _screen->loadPageFromDisk("SEENPAGE.TMP", 0); @@ -596,8 +601,8 @@ int GUI_v1::saveGameMenu(Button *button) { return 0; } -int GUI_v1::loadGameMenu(Button *button) { - debugC(9, kDebugLevelGUI, "GUI_v1::loadGameMenu()"); +int GUI_LoK::loadGameMenu(Button *button) { + debugC(9, kDebugLevelGUI, "GUI_LoK::loadGameMenu()"); updateSaveList(); if (_vm->_menuDirectlyToLoad) { @@ -613,7 +618,7 @@ int GUI_v1::loadGameMenu(Button *button) { _specialSavegameString = _vm->_newGameString[0]; //[ START A NEW GAME ] _menu[2].menuNameString = _vm->_guiStrings[7]; // Which game would you like to reload? for (int i = 0; i < 5; i++) - _menu[2].item[i].callback = BUTTON_FUNCTOR(GUI_v1, this, &GUI_v1::loadGame); + _menu[2].item[i].callback = BUTTON_FUNCTOR(GUI_LoK, this, &GUI_LoK::loadGame); _savegameOffset = 0; setupSavegames(_menu[2], 5); @@ -630,7 +635,7 @@ int GUI_v1::loadGameMenu(Button *button) { getInput(); Common::Point mouse = _vm->getMousePos(); processHighlights(_menu[2], mouse.x, mouse.y); - processButtonList(_menuButtonList, 0); + processButtonList(_menuButtonList, 0, _mouseWheel); } _screen->loadPageFromDisk("SEENPAGE.TMP", 0); @@ -649,7 +654,7 @@ int GUI_v1::loadGameMenu(Button *button) { return 0; } -void GUI_v1::redrawTextfield() { +void GUI_LoK::redrawTextfield() { _screen->fillRect(38, 91, 287, 102, 250); _text->printText(_savegameName, 38, 92, 253, 0, 0); @@ -661,7 +666,7 @@ void GUI_v1::redrawTextfield() { _screen->updateScreen(); } -void GUI_v1::updateSavegameString() { +void GUI_LoK::updateSavegameString() { int length; if (_keyPressed.keycode) { @@ -688,8 +693,8 @@ void GUI_v1::updateSavegameString() { _keyPressed.reset(); } -int GUI_v1::saveGame(Button *button) { - debugC(9, kDebugLevelGUI, "GUI_v1::saveGame()"); +int GUI_LoK::saveGame(Button *button) { + debugC(9, kDebugLevelGUI, "GUI_LoK::saveGame()"); updateMenuButton(button); _vm->_gameToLoad = _menu[2].item[button->index-0xC].saveSlot; @@ -719,7 +724,7 @@ int GUI_v1::saveGame(Button *button) { updateSavegameString(); Common::Point mouse = _vm->getMousePos(); processHighlights(_menu[3], mouse.x, mouse.y); - processButtonList(_menuButtonList, 0); + processButtonList(_menuButtonList, 0, 0); } if (_cancelSubMenu) { @@ -737,16 +742,16 @@ int GUI_v1::saveGame(Button *button) { return 0; } -int GUI_v1::savegameConfirm(Button *button) { - debugC(9, kDebugLevelGUI, "GUI_v1::savegameConfirm()"); +int GUI_LoK::savegameConfirm(Button *button) { + debugC(9, kDebugLevelGUI, "GUI_LoK::savegameConfirm()"); updateMenuButton(button); _displaySubMenu = false; return 0; } -int GUI_v1::loadGame(Button *button) { - debugC(9, kDebugLevelGUI, "GUI_v1::loadGame()"); +int GUI_LoK::loadGame(Button *button) { + debugC(9, kDebugLevelGUI, "GUI_LoK::loadGame()"); updateMenuButton(button); _displaySubMenu = false; _vm->_gameToLoad = _menu[2].item[button->index-0xC].saveSlot; @@ -754,8 +759,8 @@ int GUI_v1::loadGame(Button *button) { return 0; } -int GUI_v1::cancelSubMenu(Button *button) { - debugC(9, kDebugLevelGUI, "GUI_v1::cancelSubMenu()"); +int GUI_LoK::cancelSubMenu(Button *button) { + debugC(9, kDebugLevelGUI, "GUI_LoK::cancelSubMenu()"); updateMenuButton(button); _displaySubMenu = false; _cancelSubMenu = true; @@ -763,8 +768,8 @@ int GUI_v1::cancelSubMenu(Button *button) { return 0; } -int GUI_v1::quitPlaying(Button *button) { - debugC(9, kDebugLevelGUI, "GUI_v1::quitPlaying()"); +int GUI_LoK::quitPlaying(Button *button) { + debugC(9, kDebugLevelGUI, "GUI_LoK::quitPlaying()"); updateMenuButton(button); if (quitConfirm(_vm->_guiStrings[14])) { // Are you sure you want to quit playing? @@ -777,8 +782,8 @@ int GUI_v1::quitPlaying(Button *button) { return 0; } -bool GUI_v1::quitConfirm(const char *str) { - debugC(9, kDebugLevelGUI, "GUI_v1::quitConfirm()"); +bool GUI_LoK::quitConfirm(const char *str) { + debugC(9, kDebugLevelGUI, "GUI_LoK::quitConfirm()"); _screen->loadPageFromDisk("SEENPAGE.TMP", 0); _screen->savePageToDisk("SEENPAGE.TMP", 0); @@ -794,7 +799,7 @@ bool GUI_v1::quitConfirm(const char *str) { getInput(); Common::Point mouse = _vm->getMousePos(); processHighlights(_menu[1], mouse.x, mouse.y); - processButtonList(_menuButtonList, 0); + processButtonList(_menuButtonList, 0, 0); } _screen->loadPageFromDisk("SEENPAGE.TMP", 0); @@ -803,8 +808,8 @@ bool GUI_v1::quitConfirm(const char *str) { return !_cancelSubMenu; } -int GUI_v1::quitConfirmYes(Button *button) { - debugC(9, kDebugLevelGUI, "GUI_v1::quitConfirmYes()"); +int GUI_LoK::quitConfirmYes(Button *button) { + debugC(9, kDebugLevelGUI, "GUI_LoK::quitConfirmYes()"); updateMenuButton(button); _displaySubMenu = false; _cancelSubMenu = false; @@ -812,8 +817,8 @@ int GUI_v1::quitConfirmYes(Button *button) { return 0; } -int GUI_v1::quitConfirmNo(Button *button) { - debugC(9, kDebugLevelGUI, "GUI_v1::quitConfirmNo()"); +int GUI_LoK::quitConfirmNo(Button *button) { + debugC(9, kDebugLevelGUI, "GUI_LoK::quitConfirmNo()"); updateMenuButton(button); _displaySubMenu = false; _cancelSubMenu = true; @@ -821,8 +826,8 @@ int GUI_v1::quitConfirmNo(Button *button) { return 0; } -int GUI_v1::gameControlsMenu(Button *button) { - debugC(9, kDebugLevelGUI, "GUI_v1::gameControlsMenu()"); +int GUI_LoK::gameControlsMenu(Button *button) { + debugC(9, kDebugLevelGUI, "GUI_LoK::gameControlsMenu()"); _vm->readSettings(); @@ -839,14 +844,14 @@ int GUI_v1::gameControlsMenu(Button *button) { } _menu[5].item[3].labelString = _voiceTextString; //"Voice / Text " - _menu[5].item[3].callback = BUTTON_FUNCTOR(GUI_v1, this, &GUI_v1::controlsChangeVoice); + _menu[5].item[3].callback = BUTTON_FUNCTOR(GUI_LoK, this, &GUI_LoK::controlsChangeVoice); } else { //_menu[5].height = 136; //_menu[5].item[5].y = 110; _menu[5].item[4].enabled = 0; _menu[5].item[3].labelString = _textSpeedString; // "Text speed " - _menu[5].item[3].callback = BUTTON_FUNCTOR(GUI_v1, this, &GUI_v1::controlsChangeText); + _menu[5].item[3].callback = BUTTON_FUNCTOR(GUI_LoK, this, &GUI_LoK::controlsChangeText); } setupControls(_menu[5]); @@ -860,7 +865,7 @@ int GUI_v1::gameControlsMenu(Button *button) { getInput(); Common::Point mouse = _vm->getMousePos(); processHighlights(_menu[5], mouse.x, mouse.y); - processButtonList(_menuButtonList, 0); + processButtonList(_menuButtonList, 0, 0); } _screen->loadPageFromDisk("SEENPAGE.TMP", 0); @@ -873,8 +878,8 @@ int GUI_v1::gameControlsMenu(Button *button) { return 0; } -void GUI_v1::setupControls(Menu &menu) { - debugC(9, kDebugLevelGUI, "GUI_v1::setupControls()"); +void GUI_LoK::setupControls(Menu &menu) { + debugC(9, kDebugLevelGUI, "GUI_LoK::setupControls()"); switch (_vm->_configMusic) { case 0: @@ -970,8 +975,8 @@ void GUI_v1::setupControls(Menu &menu) { initMenu(menu); } -int GUI_v1::controlsChangeMusic(Button *button) { - debugC(9, kDebugLevelGUI, "GUI_v1::controlsChangeMusic()"); +int GUI_LoK::controlsChangeMusic(Button *button) { + debugC(9, kDebugLevelGUI, "GUI_LoK::controlsChangeMusic()"); updateMenuButton(button); _vm->_configMusic = ++_vm->_configMusic % ((_vm->gameFlags().platform == Common::kPlatformFMTowns || _vm->gameFlags().platform == Common::kPlatformPC98) ? 3 : 2); @@ -979,8 +984,8 @@ int GUI_v1::controlsChangeMusic(Button *button) { return 0; } -int GUI_v1::controlsChangeSounds(Button *button) { - debugC(9, kDebugLevelGUI, "GUI_v1::controlsChangeSounds()"); +int GUI_LoK::controlsChangeSounds(Button *button) { + debugC(9, kDebugLevelGUI, "GUI_LoK::controlsChangeSounds()"); updateMenuButton(button); _vm->_configSounds = !_vm->_configSounds; @@ -988,8 +993,8 @@ int GUI_v1::controlsChangeSounds(Button *button) { return 0; } -int GUI_v1::controlsChangeWalk(Button *button) { - debugC(9, kDebugLevelGUI, "GUI_v1::controlsChangeWalk()"); +int GUI_LoK::controlsChangeWalk(Button *button) { + debugC(9, kDebugLevelGUI, "GUI_LoK::controlsChangeWalk()"); updateMenuButton(button); _vm->_configWalkspeed = ++_vm->_configWalkspeed % 5; @@ -998,8 +1003,8 @@ int GUI_v1::controlsChangeWalk(Button *button) { return 0; } -int GUI_v1::controlsChangeText(Button *button) { - debugC(9, kDebugLevelGUI, "GUI_v1::controlsChangeText()"); +int GUI_LoK::controlsChangeText(Button *button) { + debugC(9, kDebugLevelGUI, "GUI_LoK::controlsChangeText()"); updateMenuButton(button); _vm->_configTextspeed = ++_vm->_configTextspeed % 4; @@ -1007,8 +1012,8 @@ int GUI_v1::controlsChangeText(Button *button) { return 0; } -int GUI_v1::controlsChangeVoice(Button *button) { - debugC(9, kDebugLevelGUI, "GUI_v1::controlsChangeVoice()"); +int GUI_LoK::controlsChangeVoice(Button *button) { + debugC(9, kDebugLevelGUI, "GUI_LoK::controlsChangeVoice()"); updateMenuButton(button); _vm->_configVoice = ++_vm->_configVoice % 3; @@ -1016,14 +1021,14 @@ int GUI_v1::controlsChangeVoice(Button *button) { return 0; } -int GUI_v1::controlsApply(Button *button) { - debugC(9, kDebugLevelGUI, "GUI_v1::controlsApply()"); +int GUI_LoK::controlsApply(Button *button) { + debugC(9, kDebugLevelGUI, "GUI_LoK::controlsApply()"); _vm->writeSettings(); return cancelSubMenu(button); } -int GUI_v1::scrollUp(Button *button) { - debugC(9, kDebugLevelGUI, "GUI_v1::scrollUp()"); +int GUI_LoK::scrollUp(Button *button) { + debugC(9, kDebugLevelGUI, "GUI_LoK::scrollUp()"); updateMenuButton(button); if (_savegameOffset > 0) { @@ -1034,8 +1039,8 @@ int GUI_v1::scrollUp(Button *button) { return 0; } -int GUI_v1::scrollDown(Button *button) { - debugC(9, kDebugLevelGUI, "GUI_v1::scrollDown()"); +int GUI_LoK::scrollDown(Button *button) { + debugC(9, kDebugLevelGUI, "GUI_LoK::scrollDown()"); updateMenuButton(button); _savegameOffset++; @@ -1047,7 +1052,7 @@ int GUI_v1::scrollDown(Button *button) { return 0; } -void GUI_v1::fadePalette() { +void GUI_LoK::fadePalette() { if (_vm->gameFlags().platform == Common::kPlatformAmiga) return; @@ -1067,7 +1072,7 @@ void GUI_v1::fadePalette() { _screen->fadePalette(_screen->_currentPalette, 2); } -void GUI_v1::restorePalette() { +void GUI_LoK::restorePalette() { if (_vm->gameFlags().platform == Common::kPlatformAmiga) return; @@ -1077,8 +1082,8 @@ void GUI_v1::restorePalette() { #pragma mark - -void KyraEngine_v1::drawAmulet() { - debugC(9, kDebugLevelMain, "KyraEngine_v1::drawAmulet()"); +void KyraEngine_LoK::drawAmulet() { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::drawAmulet()"); static const int16 amuletTable1[] = {0x167, 0x162, 0x15D, 0x158, 0x153, 0x150, 0x155, 0x15A, 0x15F, 0x164, 0x145, -1}; static const int16 amuletTable3[] = {0x167, 0x162, 0x15D, 0x158, 0x153, 0x14F, 0x154, 0x159, 0x15E, 0x163, 0x144, -1}; static const int16 amuletTable2[] = {0x167, 0x162, 0x15D, 0x158, 0x153, 0x152, 0x157, 0x15C, 0x161, 0x166, 0x147, -1}; diff --git a/engines/kyra/gui_v1.h b/engines/kyra/gui_lok.h index 5f6d438689..607ef0b605 100644 --- a/engines/kyra/gui_v1.h +++ b/engines/kyra/gui_lok.h @@ -23,77 +23,84 @@ * */ -#ifndef KYRA_GUI_V1_H -#define KYRA_GUI_V1_H +#ifndef KYRA_GUI_LOK_H +#define KYRA_GUI_LOK_H #include "kyra/gui.h" namespace Kyra { #define GUI_V1_BUTTON(button, a, b, c, d, e, f, g, h, i, j, k) \ - button.nextButton = 0; \ - button.index = a; \ - button.unk6 = button.unk8 = 0; \ - button.data0Val1 = b; \ - button.data1Val1 = c; \ - button.data2Val1 = d; \ - button.data0ShapePtr = button.data1ShapePtr = button.data2ShapePtr = 0; \ - button.flags = e; \ - button.dimTableIndex = f; \ - button.x = g; \ - button.y = h; \ - button.width = i; \ - button.height = j; \ - button.flags2 = k + do { \ + button.nextButton = 0; \ + button.index = a; \ + button.unk6 = button.unk8 = 0; \ + button.data0Val1 = b; \ + button.data1Val1 = c; \ + button.data2Val1 = d; \ + button.data0ShapePtr = button.data1ShapePtr = button.data2ShapePtr = 0; \ + button.flags = e; \ + button.dimTableIndex = f; \ + button.x = g; \ + button.y = h; \ + button.width = i; \ + button.height = j; \ + button.flags2 = k; \ + button.mouseWheel = 0; \ + } while (0) #define GUI_V1_MENU(menu, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q) \ - menu.x = a; \ - menu.y = b; \ - menu.width = c; \ - menu.height = d; \ - menu.bkgdColor = e; \ - menu.color1 = f; \ - menu.color2 = g; \ - menu.menuNameString = h; \ - menu.textColor = i; \ - menu.titleX = j; \ - menu.titleY = k; \ - menu.highlightedItem = l; \ - menu.numberOfItems = m; \ - menu.scrollUpButtonX = n; \ - menu.scrollUpButtonY = o; \ - menu.scrollDownButtonX = p; \ - menu.scrollDownButtonY = q + do { \ + menu.x = a; \ + menu.y = b; \ + menu.width = c; \ + menu.height = d; \ + menu.bkgdColor = e; \ + menu.color1 = f; \ + menu.color2 = g; \ + menu.menuNameString = h; \ + menu.textColor = i; \ + menu.titleX = j; \ + menu.titleY = k; \ + menu.highlightedItem = l; \ + menu.numberOfItems = m; \ + menu.scrollUpButtonX = n; \ + menu.scrollUpButtonY = o; \ + menu.scrollDownButtonX = p; \ + menu.scrollDownButtonY = q; \ + } while (0) #define GUI_V1_MENU_ITEM(item, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v) \ - item.enabled = a; \ - item.itemString = d; \ - item.x = e; \ - item.y = g; \ - item.width = h; \ - item.height = i; \ - item.textColor = j; \ - item.highlightColor = k; \ - item.titleX = l; \ - item.bkgdColor = n; \ - item.color1 = o; \ - item.color2 = p; \ - item.saveSlot = q; \ - item.labelString = r; \ - item.labelX = s; \ - item.labelY = t; \ - item.unk1F = v - -class KyraEngine_v1; - -class GUI_v1 : public GUI { - friend class KyraEngine_v1; + do { \ + item.enabled = a; \ + item.itemString = d; \ + item.x = e; \ + item.y = g; \ + item.width = h; \ + item.height = i; \ + item.textColor = j; \ + item.highlightColor = k; \ + item.titleX = l; \ + item.bkgdColor = n; \ + item.color1 = o; \ + item.color2 = p; \ + item.saveSlot = q; \ + item.labelString = r; \ + item.labelX = s; \ + item.labelY = t; \ + item.unk1F = v; \ + } while (0) + +class KyraEngine_LoK; + +class GUI_LoK : public GUI { + friend class KyraEngine_LoK; public: - GUI_v1(KyraEngine_v1 *vm, Screen_v1 *screen); - ~GUI_v1(); + GUI_LoK(KyraEngine_LoK *vm, Screen_LoK *screen); + ~GUI_LoK(); void processButton(Button *button); - int processButtonList(Button *buttonList, uint16 inputFlags); + int processButtonList(Button *buttonList, uint16 inputFlags, int8 mouseWheel); int buttonMenuCallback(Button *caller); private: @@ -147,8 +154,8 @@ private: const char *getMenuItemTitle(const MenuItem &menuItem) { return menuItem.itemString; } const char *getMenuItemLabel(const MenuItem &menuItem) { return menuItem.labelString; } - KyraEngine_v1 *_vm; - Screen_v1 *_screen; + KyraEngine_LoK *_vm; + Screen_LoK *_screen; bool _menuRestoreScreen; uint8 _toplevelMenu; diff --git a/engines/kyra/gui_mr.cpp b/engines/kyra/gui_mr.cpp index 8d27938aff..6822b303c3 100644 --- a/engines/kyra/gui_mr.cpp +++ b/engines/kyra/gui_mr.cpp @@ -194,7 +194,7 @@ void KyraEngine_MR::showInventory() { _screen->hideMouse(); if (_itemInHand < 0) { - _handItemSet = -1; + _mouseState = -1; _screen->setMouseCursor(0, 0, getShapePtr(0)); } @@ -559,6 +559,7 @@ int KyraEngine_MR::buttonInventory(Button *button) { } int KyraEngine_MR::buttonMoodChange(Button *button) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::buttonMoodChange(%p)", (const void*)button); if (queryGameFlag(0x219)) { snd_playSoundEffect(0x0D, 0xC8); return 0; @@ -626,6 +627,7 @@ int KyraEngine_MR::buttonMoodChange(Button *button) { } int KyraEngine_MR::buttonShowScore(Button *button) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::buttonShowScore(%p)", (const void*)button); strcpy(_stringBuffer, (const char*)getTableEntry(_cCodeFile, 18)); char *buffer = _stringBuffer; @@ -649,6 +651,7 @@ int KyraEngine_MR::buttonShowScore(Button *button) { } int KyraEngine_MR::buttonJesterStaff(Button *button) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::buttonJesterStaff(%p)", (const void*)button); makeCharFacingMouse(); if (_itemInHand == 27) { _screen->hideMouse(); @@ -679,6 +682,457 @@ int KyraEngine_MR::buttonJesterStaff(Button *button) { return 0; } +void KyraEngine_MR::showAlbum() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::showAlbum()"); + if (!_screen->isMouseVisible() || queryGameFlag(4) || _mouseState != -1) + return; + + if (!loadLanguageFile("ALBUM.", _album.file)) + error("Couldn't load ALBUM"); + + if (!queryGameFlag(0x8B)) + _album.wsa->open("ALBMGNTH.WSA", 1, 0); + _album.backUpRect = new uint8[3100]; + assert(_album.backUpRect); + _album.backUpPage = new uint8[64000]; + assert(_album.backUpPage); + _album.nextPage = _album.curPage; + + _screen->copyRegionToBuffer(0, 0, 0, 320, 200, _screenBuffer); + _screen->copyRegionToBuffer(4, 0, 0, 320, 200, _album.backUpPage); + + memcpy(_screen->getPalette(1), _screen->getPalette(0), 768); + _screen->fadeToBlack(9); + + int itemInHand = _itemInHand; + removeHandItem(); + + _res->loadFileToBuf("ALBUM.COL", _screen->getPalette(0), 768); + loadAlbumPage(); + loadAlbumPageWSA(); + + if (_album.leftPage.wsa->opened()) { + _album.leftPage.wsa->setX(_albumWSAX[_album.nextPage+0]); + _album.leftPage.wsa->setY(_albumWSAY[_album.nextPage+0]); + _album.leftPage.wsa->setDrawPage(2); + + _album.leftPage.wsa->displayFrame(_album.leftPage.curFrame, 0x4000); + } + if (_album.rightPage.wsa->opened()) { + _album.rightPage.wsa->setX(_albumWSAX[_album.nextPage+1]); + _album.rightPage.wsa->setY(_albumWSAY[_album.nextPage+1]); + _album.rightPage.wsa->setDrawPage(2); + + _album.rightPage.wsa->displayFrame(_album.rightPage.curFrame, 0x4000); + } + + printAlbumPageText(); + _screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0, Screen::CR_NO_P_CHECK); + _screen->updateScreen(); + _screen->fadePalette(_screen->getPalette(0), 9); + + processAlbum(); + + _screen->fadeToBlack(9); + _album.wsa->close(); + + setHandItem(itemInHand); + updateMouse(); + + restorePage3(); + _screen->copyBlockToPage(0, 0, 0, 320, 200, _screenBuffer); + _screen->copyBlockToPage(4, 0, 0, 320, 200, _album.backUpPage); + + memcpy(_screen->getPalette(0), _screen->getPalette(1), 768); + _screen->fadePalette(_screen->getPalette(0), 9); + + delete[] _album.backUpRect; + _album.backUpRect = 0; + delete[] _album.backUpPage; + _album.backUpPage = 0; + delete[] _album.file; + _album.file = 0; + + _eventList.clear(); +} + +void KyraEngine_MR::loadAlbumPage() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::loadAlbumPage()"); + + char filename[16]; + int num = _album.curPage / 2; + + if (num == 0) { + strcpy(filename, "ALBUM0.CPS"); + } else if (num >= 1 && num <= 6) { + --num; + num %= 2; + snprintf(filename, 16, "ALBUM%d.CPS", num+1); + } else { + strcpy(filename, "ALBUM3.CPS"); + } + + _screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 4, Screen::CR_NO_P_CHECK); + _screen->loadBitmap(filename, 3, 3, 0); +} + +void KyraEngine_MR::loadAlbumPageWSA() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::loadAlbumPageWSA()"); + char filename[16]; + + _album.leftPage.curFrame = 0; + _album.leftPage.maxFrame = 0; + _album.leftPage.wsa->close(); + + _album.rightPage.curFrame = 0; + _album.rightPage.maxFrame = 0; + _album.rightPage.wsa->close(); + + if (_album.curPage) { + snprintf(filename, 16, "PAGE%x.WSA", _album.curPage); + _album.leftPage.wsa->open(filename, 1, 0); + _album.leftPage.maxFrame = _album.leftPage.wsa->frames()-1; + } + + if (_album.curPage != 14) { + snprintf(filename, 16, "PAGE%x.WSA", _album.curPage+1); + _album.rightPage.wsa->open(filename, 1, 0); + _album.rightPage.maxFrame = _album.leftPage.wsa->frames()-1; + } +} + +void KyraEngine_MR::printAlbumPageText() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::printAlbumPageText()"); + + static const uint8 posY[] = { + 0x41, 0x55, 0x55, 0x55, 0x55, 0x55, 0x5A, 0x5A, + 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x3C + }; + + const int leftY = posY[_album.curPage]; + const int rightY = posY[_album.curPage+1]; + + for (int i = 0; i < 5; ++i) { + const char *str = (const char *)getTableEntry(_album.file, _album.curPage*5+i); + int y = i * 10 + leftY + 20; + printAlbumText(2, str, 20, y, 10); + } + + for (int i = 0; i < 5; ++i) { + const char *str = (const char *)getTableEntry(_album.file, (_album.curPage+1)*5+i); + int y = i * 10 + rightY + 20; + printAlbumText(2, str, 176, y, 10); + } + + albumBackUpRect(); +} + +void KyraEngine_MR::printAlbumText(int page, const char *str, int x, int y, uint8 c0) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::printAlbumText(%d, '%s', %d, %d, %d)", page, str, x, y, c0); + int oldPage = _screen->_curPage; + _screen->_curPage = page; + + static const uint8 colorMap[] = { 0, 0x87, 0xA3, 0 }; + _screen->setTextColor(colorMap, 0, 3); + + Screen::FontId oldFont = _screen->setFont(Screen::FID_BOOKFONT_FNT); + _screen->_charWidth = -2; + + _screen->printText(str, x, y, c0, 0); + + _screen->_charWidth = 0; + _screen->setFont(oldFont); + _screen->_curPage = oldPage; +} + +void KyraEngine_MR::processAlbum() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::processAlbum()"); + Button albumButtons[5]; + + GUI_V2_BUTTON(albumButtons[0], 36, 0, 0, 1, 1, 1, 0x4487, 0, 130, 190, 10, 10, 0xFF, 0xF0, 0xFF, 0xF0, 0xFF, 0xF0, 0); + albumButtons[0].buttonCallback = BUTTON_FUNCTOR(KyraEngine_MR, this, &KyraEngine_MR::albumPrevPage); + GUI_V2_BUTTON(albumButtons[1], 37, 0, 0, 1, 1, 1, 0x4487, 0, 177, 190, 10, 10, 0xFF, 0xF0, 0xFF, 0xF0, 0xFF, 0xF0, 0); + albumButtons[1].buttonCallback = BUTTON_FUNCTOR(KyraEngine_MR, this, &KyraEngine_MR::albumNextPage); + GUI_V2_BUTTON(albumButtons[2], 38, 0, 0, 1, 1, 1, 0x4487, 0, 0, 0, 320, 8, 0xFF, 0xF0, 0xFF, 0xF0, 0xFF, 0xF0, 0); + albumButtons[2].buttonCallback = BUTTON_FUNCTOR(KyraEngine_MR, this, &KyraEngine_MR::albumClose); + GUI_V2_BUTTON(albumButtons[3], 39, 0, 0, 1, 1, 1, 0x4487, 0, 8, 8, 144, 180, 0xFF, 0xF0, 0xFF, 0xF0, 0xFF, 0xF0, 0); + albumButtons[3].buttonCallback = BUTTON_FUNCTOR(KyraEngine_MR, this, &KyraEngine_MR::albumPrevPage); + GUI_V2_BUTTON(albumButtons[4], 40, 0, 0, 1, 1, 1, 0x4487, 0, 170, 8, 142, 180, 0xFF, 0xF0, 0xFF, 0xF0, 0xFF, 0xF0, 0); + albumButtons[4].buttonCallback = BUTTON_FUNCTOR(KyraEngine_MR, this, &KyraEngine_MR::albumNextPage); + + Button *buttonList = 0; + for (int i = 0; i < 5; ++i) + buttonList = _gui->addButtonToList(buttonList, &albumButtons[i]); + + _album.leftPage.timer = _album.rightPage.timer = _system->getMillis(); + albumNewPage(); + _album.running = true; + + while (_album.running && !_quitFlag) { + updateInput(); + checkInput(buttonList); + removeInputTop(); + + musicUpdate(0); + + if (_album.curPage != _album.nextPage) { + int oldPage = _album.curPage; + _album.curPage = _album.nextPage; + + _album.leftPage.wsa->close(); + _album.rightPage.wsa->close(); + + loadAlbumPage(); + loadAlbumPageWSA(); + + if (_album.leftPage.wsa->opened()) { + _album.leftPage.wsa->setX(_albumWSAX[_album.nextPage+0]); + _album.leftPage.wsa->setY(_albumWSAY[_album.nextPage+0]); + _album.leftPage.wsa->setDrawPage(2); + + _album.leftPage.wsa->displayFrame(_album.leftPage.curFrame, 0x4000); + } + if (_album.rightPage.wsa->opened()) { + _album.rightPage.wsa->setX(_albumWSAX[_album.nextPage+1]); + _album.rightPage.wsa->setY(_albumWSAY[_album.nextPage+1]); + _album.rightPage.wsa->setDrawPage(2); + + _album.rightPage.wsa->displayFrame(_album.rightPage.curFrame, 0x4000); + } + + printAlbumPageText(); + + snd_playSoundEffect(0x85, 0x80); + albumSwitchPages(oldPage, _album.nextPage, 4); + + _album.leftPage.timer = _album.rightPage.timer = 0; + albumNewPage(); + + _eventList.clear(); + } + + albumUpdateAnims(); + _system->delayMillis(10); + } + + _album.leftPage.wsa->close(); + _album.rightPage.wsa->close(); +} + +void KyraEngine_MR::albumNewPage() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::albumNewPage()"); + int page = _album.nextPage / 2; + if (!queryGameFlag(0x84+page)) { + albumAnim1(); + delayWithTicks(8); + + int id = _album.curPage / 2 + 100; + albumChat((const char *)getTableEntry(_album.file, id), 205, id); + + if (id == 107) { + _screen->copyRegion(76, 100, 76, 100, 244, 100, 2, 0, Screen::CR_NO_P_CHECK); + albumChat((const char *)getTableEntry(_album.file, 108), 205, 108); + _screen->copyRegion(76, 100, 76, 100, 244, 100, 2, 0, Screen::CR_NO_P_CHECK); + albumChat((const char *)getTableEntry(_album.file, 109), 205, 109); + } + + delayWithTicks(5); + albumAnim2(); + + setGameFlag(0x84+page); + _album.isPage14 = (_album.nextPage == 14); + } +} + +void KyraEngine_MR::albumUpdateAnims() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::albumUpdateAnims()"); + if (_album.nextPage == 14 && !_album.isPage14) + return; + + uint32 nextRun = 0; + + nextRun = _album.leftPage.timer + 5 * _tickLength; + if (nextRun < _system->getMillis() && _album.leftPage.wsa->opened()) { + _album.leftPage.wsa->setX(_albumWSAX[_album.nextPage+0]); + _album.leftPage.wsa->setY(_albumWSAY[_album.nextPage+0]); + _album.leftPage.wsa->setDrawPage(2); + + _album.leftPage.wsa->displayFrame(_album.leftPage.curFrame, 0x4000); + _screen->copyRegion(40, 17, 40, 17, 87, 73, 2, 0, Screen::CR_NO_P_CHECK); + + ++_album.leftPage.curFrame; + _album.leftPage.timer = _system->getMillis(); + + if (_album.leftPage.curFrame > _album.leftPage.maxFrame) { + _album.leftPage.curFrame = 0; + if (_album.nextPage == 14) { + _album.isPage14 = false; + _album.leftPage.timer += 100000 * _tickLength; + } else { + _album.leftPage.timer += 180 * _tickLength; + } + } + } + + nextRun = _album.rightPage.timer + 5 * _tickLength; + if (nextRun < _system->getMillis() && _album.rightPage.wsa->opened()) { + _album.rightPage.wsa->setX(_albumWSAX[_album.nextPage+1]); + _album.rightPage.wsa->setY(_albumWSAY[_album.nextPage+1]); + _album.rightPage.wsa->setDrawPage(2); + + _album.rightPage.wsa->displayFrame(_album.rightPage.curFrame, 0x4000); + _screen->copyRegion(194, 20, 194, 20, 85, 69, 2, 0, Screen::CR_NO_P_CHECK); + + ++_album.rightPage.curFrame; + _album.rightPage.timer = _system->getMillis(); + + if (_album.rightPage.curFrame > _album.rightPage.maxFrame) { + _album.rightPage.curFrame = 0; + _album.rightPage.timer += 180 * _tickLength; + } + } + + _screen->updateScreen(); +} + +void KyraEngine_MR::albumAnim1() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::albumAnim1()"); + _album.wsa->setX(-100); + _album.wsa->setY(90); + _album.wsa->setDrawPage(2); + + for (int i = 6; i >= 3; --i) { + albumRestoreRect(); + _album.wsa->displayFrame(i, 0x4000); + albumUpdateRect(); + delayWithTicks(1); + } + + albumRestoreRect(); + _album.wsa->displayFrame(14, 0x4000); + albumUpdateRect(); + delayWithTicks(1); +} + +void KyraEngine_MR::albumAnim2() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::albumAnim2()"); + _album.wsa->setX(-100); + _album.wsa->setY(90); + _album.wsa->setDrawPage(2); + + for (int i = 3; i <= 6; ++i) { + albumRestoreRect(); + _album.wsa->displayFrame(i, 0x4000); + albumUpdateRect(); + delayWithTicks(1); + } + + albumRestoreRect(); + _screen->copyRegion(0, 100, 0, 100, 320, 100, 2, 0, Screen::CR_NO_P_CHECK); + _screen->updateScreen(); +} + +void KyraEngine_MR::albumBackUpRect() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::albumBackUpRect()"); + _screen->copyRegionToBuffer(2, 0, 146, 62, 50, _album.backUpRect); +} + +void KyraEngine_MR::albumRestoreRect() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::albumRestoreRect()"); + _screen->copyBlockToPage(2, 0, 146, 62, 50, _album.backUpRect); +} + +void KyraEngine_MR::albumUpdateRect() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::albumUpdateRect()"); + _screen->copyRegion(0, 146, 0, 146, 62, 50, 2, 0, Screen::CR_NO_P_CHECK); + _screen->updateScreen(); +} + +void KyraEngine_MR::albumSwitchPages(int oldPage, int newPage, int srcPage) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::albumSwitchPages(%d, %d, %d)", oldPage, newPage, srcPage); + if (newPage > oldPage) { + _screen->wsaFrameAnimationStep(0xA0, 0x07, 0xA0, 0x07, 0x96, 0xBA, 0x64, 0xBA, srcPage, 0, 2); + + _screen->copyRegion(260, 7, 260, 7, 50, 186, 2, 0, Screen::CR_NO_P_CHECK); + _screen->updateScreen(); + delayWithTicks(1); + + _screen->wsaFrameAnimationStep(0xA0, 0x07, 0xA0, 0x07, 0x96, 0xBA, 0x32, 0xBA, srcPage, 0, 2); + + _screen->copyRegion(210, 7, 210, 7, 50, 186, 2, 0, Screen::CR_NO_P_CHECK); + _screen->updateScreen(); + delayWithTicks(1); + + _screen->copyRegion(160, 7, 160, 7, 50, 186, 2, 0, Screen::CR_NO_P_CHECK); + _screen->updateScreen(); + delayWithTicks(1); + + _screen->wsaFrameAnimationStep(0x10, 0x07, 0x6E, 0x07, 0x96, 0xBA, 0x32, 0xBA, 2, 0, 2); + _screen->updateScreen(); + delayWithTicks(1); + + _screen->wsaFrameAnimationStep(0x10, 0x07, 0x3C, 0x07, 0x96, 0xBA, 0x64, 0xBA, 2, 0, 2); + _screen->updateScreen(); + delayWithTicks(1); + + _screen->copyRegion(10, 7, 10, 7, 150, 186, 2, 0, Screen::CR_NO_P_CHECK); + _screen->updateScreen(); + } else { + _screen->wsaFrameAnimationStep(0x0A, 0x07, 0x3C, 0x07, 0x96, 0xBA, 0x64, 0xBA, srcPage, 0, 2); + + _screen->copyRegion(10, 7, 10, 7, 50, 186, 2, 0, Screen::CR_NO_P_CHECK); + _screen->updateScreen(); + delayWithTicks(1); + + _screen->wsaFrameAnimationStep(0x0A, 0x07, 0x6E, 0x07, 0x96, 0xBA, 0x32, 0xBA, srcPage, 0, 2); + + _screen->copyRegion(60, 7, 60, 7, 50, 186, 2, 0, Screen::CR_NO_P_CHECK); + _screen->updateScreen(); + delayWithTicks(1); + + _screen->copyRegion(110, 7, 110, 7, 50, 186, 2, 0, Screen::CR_NO_P_CHECK); + _screen->updateScreen(); + delayWithTicks(1); + + _screen->wsaFrameAnimationStep(0xA0, 0x07, 0xA0, 0x07, 0x96, 0xBA, 0x32, 0xBA, 2, 0, 2); + _screen->updateScreen(); + delayWithTicks(1); + + _screen->wsaFrameAnimationStep(0xA0, 0x07, 0xA0, 0x07, 0x96, 0xBA, 0x64, 0xBA, 2, 0, 2); + _screen->updateScreen(); + delayWithTicks(1); + + _screen->copyRegion(160, 7, 160, 7, 150, 186, 2, 0, Screen::CR_NO_P_CHECK); + _screen->updateScreen(); + } +} + +int KyraEngine_MR::albumNextPage(Button *caller) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::albumNextPage(%p)", (const void *)caller); + _album.nextPage = _album.curPage + 2; + if (_album.nextPage >= 16) { + _album.nextPage -= 2; + _album.running = false; + } + return 0; +} + +int KyraEngine_MR::albumPrevPage(Button *caller) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::albumPrevPage(%p)", (const void *)caller); + _album.nextPage = _album.curPage - 2; + if (_album.nextPage < 0) { + _album.nextPage = 0; + _album.running = false; + } + return 0; +} + +int KyraEngine_MR::albumClose(Button *caller) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::albumClose(%p)", (const void *)caller); + _album.running = false; + return 0; +} + #pragma mark - GUI_MR::GUI_MR(KyraEngine_MR *vm) : GUI_v2(vm), _vm(vm), _screen(vm->_screen) { @@ -704,6 +1158,11 @@ void GUI_MR::flagButtonDisable(Button *button) { } } +void GUI_MR::getInput() { + _vm->musicUpdate(0); + GUI_v2::getInput(); +} + const char *GUI_MR::getMenuTitle(const Menu &menu) { if (!menu.menuNameId) return 0; @@ -784,6 +1243,8 @@ int GUI_MR::quitGame(Button *caller) { } int GUI_MR::optionsButton(Button *button) { + PauseTimer pause(*_vm->_timer); + _vm->musicUpdate(0); _screen->hideMouse(); @@ -801,8 +1262,8 @@ int GUI_MR::optionsButton(Button *button) { _vm->showMessage(0, 0xF0, 0xF0); - if (_vm->_handItemSet < -1) { - _vm->_handItemSet = -1; + if (_vm->_mouseState < -1) { + _vm->_mouseState = -1; _screen->hideMouse(); _screen->setMouseCursor(1, 1, _vm->getShapePtr(0)); _screen->showMouse(); @@ -938,6 +1399,7 @@ int GUI_MR::loadMenu(Button *caller) { } else if (_vm->_gameToLoad >= 0) { restorePage1(_vm->_screenBuffer); restorePalette(); + _vm->_menuDirectlyToLoad = false; _vm->loadGame(_vm->getSavegameFilename(_vm->_gameToLoad)); if (_vm->_gameToLoad == 0) { _restartGame = true; @@ -982,7 +1444,7 @@ int GUI_MR::gameOptions(Button *caller) { if (textEnabled && !_vm->textEnabled() && !_vm->speechEnabled()) { _vm->_configVoice = 1; - _vm->setVolume(KyraEngine::kVolumeSpeech, 75); + _vm->setVolume(KyraEngine_v1::kVolumeSpeech, 75); choiceDialog(0x1E, 0); } @@ -1077,15 +1539,26 @@ int GUI_MR::toggleSkipSupport(Button *caller) { return 0; } +int GUI_MR::toggleHeliumMode(Button *caller) { + updateMenuButton(caller); + _vm->_configHelium ^= 1; + if (_vm->_configHelium) + _audioOptions.item[3].itemId = 18; + else + _audioOptions.item[3].itemId = 17; + renewHighlight(_audioOptions); + return 0; +} + int GUI_MR::audioOptions(Button *caller) { updateMenuButton(caller); restorePage1(_vm->_screenBuffer); backUpPage1(_vm->_screenBuffer); - //if (_configHelium) - // _audioOptions.item[3].itemId = 18; - //else + if (_vm->_configHelium) + _audioOptions.item[3].itemId = 18; + else _audioOptions.item[3].itemId = 17; initMenu(_audioOptions); @@ -1124,7 +1597,7 @@ int GUI_MR::audioOptions(Button *caller) { restorePage1(_vm->_screenBuffer); backUpPage1(_vm->_screenBuffer); - if (speechEnabled && !_vm->textEnabled() && (!_vm->speechEnabled() || _vm->getVolume(KyraEngine::kVolumeSpeech) == 2)) { + if (speechEnabled && !_vm->textEnabled() && (!_vm->speechEnabled() || _vm->getVolume(KyraEngine_v1::kVolumeSpeech) == 2)) { _vm->_configVoice = 0; choiceDialog(0x1D, 0); } @@ -1147,7 +1620,7 @@ int GUI_MR::sliderHandler(Button *caller) { assert(button >= 0 && button <= 3); - int oldVolume = _vm->getVolume(KyraEngine::kVolumeEntry(button)); + int oldVolume = _vm->getVolume(KyraEngine_v1::kVolumeEntry(button)); int newVolume = oldVolume; if (caller->index >= 24 && caller->index <= 27) @@ -1175,7 +1648,7 @@ int GUI_MR::sliderHandler(Button *caller) { _vm->_configVoice = 1; } - _vm->setVolume(KyraEngine::kVolumeEntry(button), newVolume); + _vm->setVolume(KyraEngine_v1::kVolumeEntry(button), newVolume); switch (button) { case 0: @@ -1200,7 +1673,7 @@ int GUI_MR::sliderHandler(Button *caller) { if (playSoundEffect) _vm->snd_playSoundEffect(0x18, 0xC8); else if (lastMusicCommand >= 0) - _vm->snd_playWanderScoreViaMap(lastMusicCommand, 1); + _vm->snd_playWanderScoreViaMap(lastMusicCommand, 0); _screen->updateScreen(); return 0; @@ -1212,7 +1685,7 @@ void GUI_MR::drawSliderBar(int slider, const uint8 *shape) { int x = menuX + _sliderBarsPosition[slider*2+0] + 10; int y = menuY + _sliderBarsPosition[slider*2+1]; - int position = _vm->getVolume(KyraEngine::kVolumeEntry(slider)); + int position = _vm->getVolume(KyraEngine_v1::kVolumeEntry(slider)); position = MAX(2, position); position = MIN(97, position); diff --git a/engines/kyra/gui_mr.h b/engines/kyra/gui_mr.h index d73b21b73b..5bd3569031 100644 --- a/engines/kyra/gui_mr.h +++ b/engines/kyra/gui_mr.h @@ -48,6 +48,8 @@ public: int optionsButton(Button *button); private: + void getInput(); + const char *getMenuTitle(const Menu &menu); const char *getMenuItemTitle(const MenuItem &menuItem); const char *getMenuItemLabel(const MenuItem &menuItem); @@ -77,6 +79,7 @@ private: int changeLanguage(Button *caller); int toggleStudioSFX(Button *caller); int toggleSkipSupport(Button *caller); + int toggleHeliumMode(Button *caller); KyraEngine_MR *_vm; Screen_MR *_screen; diff --git a/engines/kyra/gui_v2.cpp b/engines/kyra/gui_v2.cpp index d835c4f8d5..2819c4f077 100644 --- a/engines/kyra/gui_v2.cpp +++ b/engines/kyra/gui_v2.cpp @@ -43,6 +43,8 @@ GUI_v2::GUI_v2(KyraEngine_v2 *vm) : GUI(vm), _vm(vm), _screen(vm->screen_v2()) { _scrollUpFunctor = BUTTON_FUNCTOR(GUI_v2, this, &GUI_v2::scrollUpButton); _scrollDownFunctor = BUTTON_FUNCTOR(GUI_v2, this, &GUI_v2::scrollDownButton); _sliderHandlerFunctor = BUTTON_FUNCTOR(GUI_v2, this, &GUI_v2::sliderHandler); + _savegameOffset = 0; + _isDeleteMenu = false; } Button *GUI_v2::addButtonToList(Button *list, Button *newButton) { @@ -138,7 +140,7 @@ void GUI_v2::processButton(Button *button) { _screen->updateScreen(); } -int GUI_v2::processButtonList(Button *buttonList, uint16 inputFlag) { +int GUI_v2::processButtonList(Button *buttonList, uint16 inputFlag, int8 mouseWheel) { static uint16 flagsModifier = 0; if (!buttonList) @@ -234,6 +236,12 @@ int GUI_v2::processButtonList(Button *buttonList, uint16 inputFlag) { } bool unk1 = false; + + if (mouseWheel && buttonList->mouseWheel == mouseWheel) { + progress = true; + unk1 = true; + } + if (!progress) buttonList->flags2 &= ~6; @@ -407,6 +415,8 @@ void GUI_v2::getInput() { _isOptionsMenu = false; _isDeleteMenu = false; } + + _vm->delay(10); } void GUI_v2::renewHighlight(Menu &menu) { @@ -441,7 +451,7 @@ void GUI_v2::setupSavegameNames(Menu &menu, int num) { if (_isSaveMenu && _savegameOffset == 0) startSlot = 1; - KyraEngine::SaveHeader header; + KyraEngine_v1::SaveHeader header; 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) { @@ -844,7 +854,7 @@ void GUI_v2::checkTextfieldInput() { } } - processButtonList(_menuButtonList, keys | 0x8000); + processButtonList(_menuButtonList, keys | 0x8000, 0); } void GUI_v2::drawTextfieldBlock(int x, int y, uint8 c) { diff --git a/engines/kyra/gui_v2.h b/engines/kyra/gui_v2.h index 4e94b58742..161752627b 100644 --- a/engines/kyra/gui_v2.h +++ b/engines/kyra/gui_v2.h @@ -31,65 +31,72 @@ 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; \ - button.unk6 = b; \ - button.unk8 = c; \ - button.data0Val1 = d; \ - button.data1Val1 = e; \ - button.data2Val1 = f; \ - button.flags = h; \ - button.data0ShapePtr = button.data1ShapePtr = button.data2ShapePtr = 0; \ - button.dimTableIndex = i; \ - button.x = j; \ - button.y = k; \ - button.width = l; \ - button.height = m; \ - button.data0Val2 = n; \ - button.data0Val3 = o; \ - button.data1Val2 = p; \ - button.data1Val3 = q; \ - button.data2Val2 = r; \ - button.data2Val3 = s; \ - button.flags2 = t; + do { \ + button.nextButton = 0; \ + button.index = a; \ + button.unk6 = b; \ + button.unk8 = c; \ + button.data0Val1 = d; \ + button.data1Val1 = e; \ + button.data2Val1 = f; \ + button.flags = h; \ + button.data0ShapePtr = button.data1ShapePtr = button.data2ShapePtr = 0; \ + button.dimTableIndex = i; \ + button.x = j; \ + button.y = k; \ + button.width = l; \ + button.height = m; \ + button.data0Val2 = n; \ + button.data0Val3 = o; \ + button.data1Val2 = p; \ + button.data1Val3 = q; \ + button.data2Val2 = r; \ + button.data2Val3 = s; \ + button.flags2 = t; \ + button.mouseWheel = 0; \ + } while (0) #define GUI_V2_MENU(menu, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q) \ - menu.x = a; \ - menu.y = b; \ - menu.width = c; \ - menu.height = d; \ - menu.bkgdColor = e; \ - menu.color1 = f; \ - menu.color2 = g; \ - menu.menuNameId = h; \ - menu.textColor = i; \ - menu.titleX = j; \ - menu.titleY = k; \ - menu.highlightedItem = l; \ - menu.numberOfItems = m; \ - menu.scrollUpButtonX = n; \ - menu.scrollUpButtonY = o; \ - menu.scrollDownButtonX = p; \ - menu.scrollDownButtonY = q + do { \ + menu.x = a; \ + menu.y = b; \ + menu.width = c; \ + menu.height = d; \ + menu.bkgdColor = e; \ + menu.color1 = f; \ + menu.color2 = g; \ + menu.menuNameId = h; \ + menu.textColor = i; \ + menu.titleX = j; \ + menu.titleY = k; \ + menu.highlightedItem = l; \ + menu.numberOfItems = m; \ + menu.scrollUpButtonX = n; \ + menu.scrollUpButtonY = o; \ + menu.scrollDownButtonX = p; \ + menu.scrollDownButtonY = q; \ + } while (0) #define GUI_V2_MENU_ITEM(item, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q) \ - item.enabled = a; \ - item.itemId = b; \ - item.x = c; \ - item.y = d; \ - item.width = e; \ - item.height = f; \ - item.textColor = g; \ - item.highlightColor = h; \ - item.titleX = i; \ - item.bkgdColor = j; \ - item.color1 = k; \ - item.color2 = l; \ - item.saveSlot = m; \ - item.labelId = n; \ - item.labelX = o; \ - item.labelY = p; \ - item.unk1F = q + do { \ + item.enabled = a; \ + item.itemId = b; \ + item.x = c; \ + item.y = d; \ + item.width = e; \ + item.height = f; \ + item.textColor = g; \ + item.highlightColor = h; \ + item.titleX = i; \ + item.bkgdColor = j; \ + item.color1 = k; \ + item.color2 = l; \ + item.saveSlot = m; \ + item.labelId = n; \ + item.labelX = o; \ + item.labelY = p; \ + item.unk1F = q; \ + } while (0) class KyraEngine_v2; class Screen_v2; @@ -103,7 +110,7 @@ public: Button *addButtonToList(Button *list, Button *newButton); void processButton(Button *button); - int processButtonList(Button *button, uint16 inputFlag); + int processButtonList(Button *button, uint16 inputFlag, int8 mouseWheel); protected: void updateButton(Button *button); @@ -125,7 +132,7 @@ protected: virtual uint8 textFieldColor2() const = 0; virtual uint8 textFieldColor3() const = 0; protected: - void getInput(); + virtual void getInput(); Button _menuButtons[7]; Button _scrollUpButton; diff --git a/engines/kyra/items_hof.cpp b/engines/kyra/items_hof.cpp index da3062fe2c..4dfc73a5ad 100644 --- a/engines/kyra/items_hof.cpp +++ b/engines/kyra/items_hof.cpp @@ -83,7 +83,7 @@ void KyraEngine_HoF::updateWaterFlasks() { 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) + if (_mouseState <= -1) return false; bool success = processItemDrop(_mainCharacter.sceneId, item, x, y, unk1, unk2); diff --git a/engines/kyra/items_v1.cpp b/engines/kyra/items_lok.cpp index ae3ba2821a..8eb62c20c2 100644 --- a/engines/kyra/items_v1.cpp +++ b/engines/kyra/items_lok.cpp @@ -23,14 +23,14 @@ * */ -#include "kyra/kyra_v1.h" +#include "kyra/kyra_lok.h" #include "kyra/seqplayer.h" #include "kyra/screen.h" #include "kyra/resource.h" #include "kyra/sound.h" #include "kyra/sprites.h" #include "kyra/wsamovie.h" -#include "kyra/animator_v1.h" +#include "kyra/animator_lok.h" #include "kyra/text.h" #include "common/system.h" @@ -38,7 +38,7 @@ namespace Kyra { -int KyraEngine_v1::findDuplicateItemShape(int shape) { +int KyraEngine_LoK::findDuplicateItemShape(int shape) { static uint8 dupTable[] = { 0x48, 0x46, 0x49, 0x47, 0x4a, 0x46, 0x4b, 0x47, 0x4c, 0x46, 0x4d, 0x47, 0x5b, 0x5a, 0x5c, 0x5a, @@ -55,8 +55,8 @@ int KyraEngine_v1::findDuplicateItemShape(int shape) { return -1; } -void KyraEngine_v1::addToNoDropRects(int x, int y, int w, int h) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::addToNoDropRects(%d, %d, %d, %d)", x, y, w, h); +void KyraEngine_LoK::addToNoDropRects(int x, int y, int w, int h) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::addToNoDropRects(%d, %d, %d, %d)", x, y, w, h); for (int rect = 0; rect < 11; ++rect) { if (_noDropRects[rect].x == -1) { _noDropRects[rect].x = x; @@ -68,13 +68,13 @@ void KyraEngine_v1::addToNoDropRects(int x, int y, int w, int h) { } } -void KyraEngine_v1::clearNoDropRects() { - debugC(9, kDebugLevelMain, "KyraEngine_v1::clearNoDropRects()"); +void KyraEngine_LoK::clearNoDropRects() { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::clearNoDropRects()"); memset(_noDropRects, -1, sizeof(_noDropRects)); } -byte KyraEngine_v1::findFreeItemInScene(int scene) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::findFreeItemInScene(%d)", scene); +byte KyraEngine_LoK::findFreeItemInScene(int scene) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::findFreeItemInScene(%d)", scene); assert(scene < _roomTableSize); Room *room = &_roomTable[scene]; for (int i = 0; i < 12; ++i) { @@ -84,8 +84,8 @@ byte KyraEngine_v1::findFreeItemInScene(int scene) { return 0xFF; } -byte KyraEngine_v1::findItemAtPos(int x, int y) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::findItemAtPos(%d, %d)", x, y); +byte KyraEngine_LoK::findItemAtPos(int x, int y) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::findItemAtPos(%d, %d)", x, y); assert(_currentCharacter->sceneId < _roomTableSize); const uint8 *itemsTable = _roomTable[_currentCharacter->sceneId].itemsTable; const uint16 *xposOffset = _roomTable[_currentCharacter->sceneId].itemsXPos; @@ -120,8 +120,8 @@ byte KyraEngine_v1::findItemAtPos(int x, int y) { return returnValue; } -void KyraEngine_v1::placeItemInGenericMapScene(int item, int index) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::placeItemInGenericMapScene(%d, %d)", item, index); +void KyraEngine_LoK::placeItemInGenericMapScene(int item, int index) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::placeItemInGenericMapScene(%d, %d)", item, index); static const uint16 itemMapSceneMinTable[] = { 0x0000, 0x0011, 0x006D, 0x0025, 0x00C7, 0x0000 }; @@ -175,32 +175,32 @@ void KyraEngine_v1::placeItemInGenericMapScene(int item, int index) { } } -void KyraEngine_v1::createMouseItem(int item) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::createMouseItem(%d)", item); +void KyraEngine_LoK::setHandItem(uint16 item) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::setHandItem(%u)", item); _screen->hideMouse(); setMouseItem(item); _itemInHand = item; _screen->showMouse(); } -void KyraEngine_v1::destroyMouseItem() { - debugC(9, kDebugLevelMain, "KyraEngine_v1::destroyMouseItem()"); +void KyraEngine_LoK::removeHandItem() { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::removeHandItem()"); _screen->hideMouse(); _screen->setMouseCursor(1, 1, _shapes[0]); _itemInHand = -1; _screen->showMouse(); } -void KyraEngine_v1::setMouseItem(int item) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::setMouseItem(%d)", item); - if (item == -1) +void KyraEngine_LoK::setMouseItem(uint16 item) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::setMouseItem(%u)", item); + if (item == 0xFFFF) _screen->setMouseCursor(1, 1, _shapes[6]); else _screen->setMouseCursor(8, 15, _shapes[216+item]); } -void KyraEngine_v1::wipeDownMouseItem(int xpos, int ypos) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::wipeDownMouseItem(%d, %d)", xpos, ypos); +void KyraEngine_LoK::wipeDownMouseItem(int xpos, int ypos) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::wipeDownMouseItem(%d, %d)", xpos, ypos); if (_itemInHand == -1) return; xpos -= 8; @@ -222,12 +222,12 @@ void KyraEngine_v1::wipeDownMouseItem(int xpos, int ypos) { } restoreItemRect1(xpos, ypos); _screen->resetShapeHeight(_shapes[216+_itemInHand]); - destroyMouseItem(); + removeHandItem(); _screen->showMouse(); } -void KyraEngine_v1::setupSceneItems() { - debugC(9, kDebugLevelMain, "KyraEngine_v1::setupSceneItems()"); +void KyraEngine_LoK::setupSceneItems() { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::setupSceneItems()"); uint16 sceneId = _currentCharacter->sceneId; assert(sceneId < _roomTableSize); Room *currentRoom = &_roomTable[sceneId]; @@ -264,8 +264,8 @@ void KyraEngine_v1::setupSceneItems() { } } -int KyraEngine_v1::countItemsInScene(uint16 sceneId) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::countItemsInScene(%d)", sceneId); +int KyraEngine_LoK::countItemsInScene(uint16 sceneId) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::countItemsInScene(%d)", sceneId); assert(sceneId < _roomTableSize); Room *currentRoom = &_roomTable[sceneId]; @@ -279,8 +279,8 @@ int KyraEngine_v1::countItemsInScene(uint16 sceneId) { return items; } -int KyraEngine_v1::processItemDrop(uint16 sceneId, uint8 item, int x, int y, int unk1, int unk2) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::processItemDrop(%d, %d, %d, %d, %d, %d)", sceneId, item, x, y, unk1, unk2); +int KyraEngine_LoK::processItemDrop(uint16 sceneId, uint8 item, int x, int y, int unk1, int unk2) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::processItemDrop(%d, %d, %d, %d, %d, %d)", sceneId, item, x, y, unk1, unk2); int freeItem = -1; uint8 itemIndex = findItemAtPos(x, y); if (unk1) @@ -420,7 +420,7 @@ int KyraEngine_v1::processItemDrop(uint16 sceneId, uint8 item, int x, int y, int itemSpecialFX(x, y, item); if (unk1 == 0) - destroyMouseItem(); + removeHandItem(); itemDropDown(x, y, destX, destY, freeItem, item); @@ -432,8 +432,8 @@ int KyraEngine_v1::processItemDrop(uint16 sceneId, uint8 item, int x, int y, int return 1; } -void KyraEngine_v1::exchangeItemWithMouseItem(uint16 sceneId, int itemIndex) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::exchangeItemWithMouseItem(%d, %d)", sceneId, itemIndex); +void KyraEngine_LoK::exchangeItemWithMouseItem(uint16 sceneId, int itemIndex) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::exchangeItemWithMouseItem(%d, %d)", sceneId, itemIndex); _screen->hideMouse(); _animator->animRemoveGameItem(itemIndex); assert(sceneId < _roomTableSize); @@ -452,8 +452,8 @@ void KyraEngine_v1::exchangeItemWithMouseItem(uint16 sceneId, int itemIndex) { clickEventHandler2(); } -void KyraEngine_v1::addItemToRoom(uint16 sceneId, uint8 item, int itemIndex, int x, int y) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::addItemToRoom(%d, %d, %d, %d, %d)", sceneId, item, itemIndex, x, y); +void KyraEngine_LoK::addItemToRoom(uint16 sceneId, uint8 item, int itemIndex, int x, int y) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::addItemToRoom(%d, %d, %d, %d, %d)", sceneId, item, itemIndex, x, y); assert(sceneId < _roomTableSize); Room *currentRoom = &_roomTable[sceneId]; currentRoom->itemsTable[itemIndex] = item; @@ -462,8 +462,8 @@ void KyraEngine_v1::addItemToRoom(uint16 sceneId, uint8 item, int itemIndex, int currentRoom->needInit[itemIndex] = 1; } -int KyraEngine_v1::checkNoDropRects(int x, int y) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::checkNoDropRects(%d, %d)", x, y); +int KyraEngine_LoK::checkNoDropRects(int x, int y) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::checkNoDropRects(%d, %d)", x, y); if (_lastProcessedItemHeight < 1 || _lastProcessedItemHeight > 16) _lastProcessedItemHeight = 16; if (_noDropRects[0].x == -1) @@ -492,8 +492,8 @@ int KyraEngine_v1::checkNoDropRects(int x, int y) { return 0; } -int KyraEngine_v1::isDropable(int x, int y) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::isDropable(%d, %d)", x, y); +int KyraEngine_LoK::isDropable(int x, int y) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::isDropable(%d, %d)", x, y); x -= 8; y -= 1; @@ -507,8 +507,8 @@ int KyraEngine_v1::isDropable(int x, int y) { return 1; } -void KyraEngine_v1::itemDropDown(int x, int y, int destX, int destY, byte freeItem, int item) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::itemDropDown(%d, %d, %d, %d, %d, %d)", x, y, destX, destY, freeItem, item); +void KyraEngine_LoK::itemDropDown(int x, int y, int destX, int destY, byte freeItem, int item) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::itemDropDown(%d, %d, %d, %d, %d, %d)", x, y, destX, destY, freeItem, item); assert(_currentCharacter->sceneId < _roomTableSize); Room *currentRoom = &_roomTable[_currentCharacter->sceneId]; if (x == destX && y == destY) { @@ -591,8 +591,8 @@ void KyraEngine_v1::itemDropDown(int x, int y, int destX, int destY, byte freeIt _screen->showMouse(); } -void KyraEngine_v1::dropItem(int unk1, int item, int x, int y, int unk2) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::dropItem(%d, %d, %d, %d, %d)", unk1, item, x, y, unk2); +void KyraEngine_LoK::dropItem(int unk1, int item, int x, int y, int unk2) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::dropItem(%d, %d, %d, %d, %d)", unk1, item, x, y, unk2); if (processItemDrop(_currentCharacter->sceneId, item, x, y, unk1, unk2)) return; snd_playSoundEffect(54); @@ -603,16 +603,16 @@ void KyraEngine_v1::dropItem(int unk1, int item, int x, int y, int unk2) { drawSentenceCommand(_noDropList[1], 6); } -void KyraEngine_v1::itemSpecialFX(int x, int y, int item) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::itemSpecialFX(%d, %d, %d)", x, y, item); +void KyraEngine_LoK::itemSpecialFX(int x, int y, int item) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::itemSpecialFX(%d, %d, %d)", x, y, item); if (item == 41) itemSpecialFX1(x, y, item); else itemSpecialFX2(x, y, item); } -void KyraEngine_v1::itemSpecialFX1(int x, int y, int item) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::itemSpecialFX1(%d, %d, %d)", x, y, item); +void KyraEngine_LoK::itemSpecialFX1(int x, int y, int item) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::itemSpecialFX1(%d, %d, %d)", x, y, item); uint8 *shape = _shapes[216+item]; x -= 8; int startY = y; @@ -632,8 +632,8 @@ void KyraEngine_v1::itemSpecialFX1(int x, int y, int item) { _screen->showMouse(); } -void KyraEngine_v1::itemSpecialFX2(int x, int y, int item) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::itemSpecialFX2(%d, %d, %d)", x, y, item); +void KyraEngine_LoK::itemSpecialFX2(int x, int y, int item) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::itemSpecialFX2(%d, %d, %d)", x, y, item); x -= 8; y -= 15; int yAdd = (int8)(((16 - _itemTable[item].height) >> 1) & 0xFF); @@ -660,8 +660,8 @@ void KyraEngine_v1::itemSpecialFX2(int x, int y, int item) { restoreItemRect0(x, y); } -void KyraEngine_v1::magicOutMouseItem(int animIndex, int itemPos) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::magicOutMouseItem(%d, %d)", animIndex, itemPos); +void KyraEngine_LoK::magicOutMouseItem(int animIndex, int itemPos) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::magicOutMouseItem(%d, %d)", animIndex, itemPos); int videoPageBackUp = _screen->_curPage; _screen->_curPage = 0; int x = 0, y = 0; @@ -744,8 +744,8 @@ void KyraEngine_v1::magicOutMouseItem(int animIndex, int itemPos) { _screen->_curPage = videoPageBackUp; } -void KyraEngine_v1::magicInMouseItem(int animIndex, int item, int itemPos) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::magicInMouseItem(%d, %d, %d)", animIndex, item, itemPos); +void KyraEngine_LoK::magicInMouseItem(int animIndex, int item, int itemPos) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::magicInMouseItem(%d, %d, %d)", animIndex, item, itemPos); int videoPageBackUp = _screen->_curPage; _screen->_curPage = 0; int x = 0, y = 0; @@ -817,8 +817,8 @@ void KyraEngine_v1::magicInMouseItem(int animIndex, int item, int itemPos) { _screen->_curPage = videoPageBackUp; } -void KyraEngine_v1::specialMouseItemFX(int shape, int x, int y, int animIndex, int tableIndex, int loopStart, int maxLoops) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::specialMouseItemFX(%d, %d, %d, %d, %d, %d, %d)", shape, x, y, animIndex, tableIndex, loopStart, maxLoops); +void KyraEngine_LoK::specialMouseItemFX(int shape, int x, int y, int animIndex, int tableIndex, int loopStart, int maxLoops) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::specialMouseItemFX(%d, %d, %d, %d, %d, %d, %d)", shape, x, y, animIndex, tableIndex, loopStart, maxLoops); static const uint8 table1[] = { 0x23, 0x45, 0x55, 0x72, 0x84, 0xCF, 0x00, 0x00 }; @@ -840,8 +840,8 @@ void KyraEngine_v1::specialMouseItemFX(int shape, int x, int y, int animIndex, i processSpecialMouseItemFX(shape, x, y, tableValue, loopStart, maxLoops); } -void KyraEngine_v1::processSpecialMouseItemFX(int shape, int x, int y, int tableValue, int loopStart, int maxLoops) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::processSpecialMouseItemFX(%d, %d, %d, %d, %d, %d)", shape, x, y, tableValue, loopStart, maxLoops); +void KyraEngine_LoK::processSpecialMouseItemFX(int shape, int x, int y, int tableValue, int loopStart, int maxLoops) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::processSpecialMouseItemFX(%d, %d, %d, %d, %d, %d)", shape, x, y, tableValue, loopStart, maxLoops); uint8 shapeColorTable[16]; uint8 *shapePtr = _shapes[shape] + 10; if (_flags.useAltShapeHeader) @@ -859,8 +859,8 @@ void KyraEngine_v1::processSpecialMouseItemFX(int shape, int x, int y, int table _screen->drawShape(0, _shapes[shape], x, y, 0, 0x8000, shapeColorTable); } -void KyraEngine_v1::updatePlayerItemsForScene() { - debugC(9, kDebugLevelMain, "KyraEngine_v1::updatePlayerItemsForScene()"); +void KyraEngine_LoK::updatePlayerItemsForScene() { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::updatePlayerItemsForScene()"); if (_itemInHand >= 29 && _itemInHand < 33) { ++_itemInHand; if (_itemInHand > 33) @@ -900,7 +900,7 @@ void KyraEngine_v1::updatePlayerItemsForScene() { _screen->showMouse(); } -void KyraEngine_v1::redrawInventory(int page) { +void KyraEngine_LoK::redrawInventory(int page) { int videoPageBackUp = _screen->_curPage; _screen->_curPage = page; _screen->hideMouse(); @@ -916,26 +916,26 @@ void KyraEngine_v1::redrawInventory(int page) { _screen->updateScreen(); } -void KyraEngine_v1::backUpItemRect0(int xpos, int ypos) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::backUpItemRect0(%d, %d)", xpos, ypos); +void KyraEngine_LoK::backUpItemRect0(int xpos, int ypos) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::backUpItemRect0(%d, %d)", xpos, ypos); _screen->rectClip(xpos, ypos, 3<<3, 24); _screen->copyRegionToBuffer(_screen->_curPage, xpos, ypos, 3<<3, 24, _itemBkgBackUp[0]); } -void KyraEngine_v1::restoreItemRect0(int xpos, int ypos) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::restoreItemRect0(%d, %d)", xpos, ypos); +void KyraEngine_LoK::restoreItemRect0(int xpos, int ypos) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::restoreItemRect0(%d, %d)", xpos, ypos); _screen->rectClip(xpos, ypos, 3<<3, 24); _screen->copyBlockToPage(_screen->_curPage, xpos, ypos, 3<<3, 24, _itemBkgBackUp[0]); } -void KyraEngine_v1::backUpItemRect1(int xpos, int ypos) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::backUpItemRect1(%d, %d)", xpos, ypos); +void KyraEngine_LoK::backUpItemRect1(int xpos, int ypos) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::backUpItemRect1(%d, %d)", xpos, ypos); _screen->rectClip(xpos, ypos, 4<<3, 32); _screen->copyRegionToBuffer(_screen->_curPage, xpos, ypos, 4<<3, 32, _itemBkgBackUp[1]); } -void KyraEngine_v1::restoreItemRect1(int xpos, int ypos) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::restoreItemRect1(%d, %d)", xpos, ypos); +void KyraEngine_LoK::restoreItemRect1(int xpos, int ypos) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::restoreItemRect1(%d, %d)", xpos, ypos); _screen->rectClip(xpos, ypos, 4<<3, 32); _screen->copyBlockToPage(_screen->_curPage, xpos, ypos, 4<<3, 32, _itemBkgBackUp[1]); } diff --git a/engines/kyra/items_mr.cpp b/engines/kyra/items_mr.cpp index 8ace9f8a3c..299c826e80 100644 --- a/engines/kyra/items_mr.cpp +++ b/engines/kyra/items_mr.cpp @@ -97,7 +97,7 @@ void KyraEngine_MR::setMouseCursor(uint16 item) { void KyraEngine_MR::setItemMouseCursor() { debugC(9, kDebugLevelMain, "KyraEngine_MR::setItemMouseCursor()"); - _handItemSet = _itemInHand; + _mouseState = _itemInHand; if (_itemInHand == -1) _screen->setMouseCursor(0, 0, _gameShapes[0]); else @@ -107,7 +107,7 @@ void KyraEngine_MR::setItemMouseCursor() { 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) + if (_mouseState <= -1) return false; if (processItemDrop(_mainCharacter.sceneId, item, x, y, unk1, unk2)) diff --git a/engines/kyra/items_v2.cpp b/engines/kyra/items_v2.cpp index 78768c70ab..83f637b06f 100644 --- a/engines/kyra/items_v2.cpp +++ b/engines/kyra/items_v2.cpp @@ -30,7 +30,7 @@ namespace Kyra { void KyraEngine_v2::initItemList(int size) { debugC(9, kDebugLevelMain, "KyraEngine_v2::initItemList(%d)", size); - delete [] _itemList; + delete[] _itemList; _itemList = new Item[size]; assert(_itemList); @@ -112,7 +112,7 @@ void KyraEngine_v2::removeHandItem() { scr->hideMouse(); scr->setMouseCursor(0, 0, getShapePtr(0)); _itemInHand = -1; - _handItemSet = -1; + _mouseState = -1; scr->showMouse(); } diff --git a/engines/kyra/kyra.cpp b/engines/kyra/kyra.cpp deleted file mode 100644 index 05d8b79a4e..0000000000 --- a/engines/kyra/kyra.cpp +++ /dev/null @@ -1,393 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include "common/config-manager.h" - -#include "sound/mididrv.h" -#include "sound/mixer.h" - -#include "kyra/kyra.h" -#include "kyra/sound.h" -#include "kyra/resource.h" -#include "kyra/screen.h" -#include "kyra/text.h" -#include "kyra/timer.h" -#include "kyra/script.h" - -namespace Kyra { - -KyraEngine::KyraEngine(OSystem *system, const GameFlags &flags) - : Engine(system), _flags(flags) { - _res = 0; - _sound = 0; - _text = 0; - _staticres = 0; - _timer = 0; - _emc = 0; - - _gameSpeed = 60; - _tickLength = (uint8)(1000.0 / _gameSpeed); - - _quitFlag = false; - - _speechFile = ""; - _trackMap = 0; - _trackMapSize = 0; - _lastMusicCommand = -1; - _curSfxFile = _curMusicTheme = -1; - - _gameToLoad = -1; - - memset(_flagsTable, 0, sizeof(_flagsTable)); - - // sets up all engine specific debug levels - Common::addSpecialDebugLevel(kDebugLevelScriptFuncs, "ScriptFuncs", "Script function debug level"); - Common::addSpecialDebugLevel(kDebugLevelScript, "Script", "Script interpreter debug level"); - Common::addSpecialDebugLevel(kDebugLevelSprites, "Sprites", "Sprite debug level"); - Common::addSpecialDebugLevel(kDebugLevelScreen, "Screen", "Screen debug level"); - Common::addSpecialDebugLevel(kDebugLevelSound, "Sound", "Sound debug level"); - Common::addSpecialDebugLevel(kDebugLevelAnimator, "Animator", "Animator debug level"); - Common::addSpecialDebugLevel(kDebugLevelMain, "Main", "Generic debug level"); - Common::addSpecialDebugLevel(kDebugLevelGUI, "GUI", "GUI debug level"); - Common::addSpecialDebugLevel(kDebugLevelSequence, "Sequence", "Sequence debug level"); - Common::addSpecialDebugLevel(kDebugLevelMovie, "Movie", "Movie debug level"); - Common::addSpecialDebugLevel(kDebugLevelTimer, "Timer", "Timer debug level"); - - system->getEventManager()->registerRandomSource(_rnd, "kyra"); -} - -int KyraEngine::init() { - registerDefaultSettings(); - - // Setup mixer - _mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, ConfMan.getInt("sfx_volume")); - _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, ConfMan.getInt("music_volume")); - _mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, ConfMan.getInt("speech_volume")); - - 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(); - _staticres = new StaticResource(this); - assert(_staticres); - if (!_staticres->init()) - error("_staticres->init() failed"); - if (!screen()->init()) - error("screen()->init() failed"); - _timer = new TimerManager(this, _system); - assert(_timer); - setupTimers(); - _emc = new EMCInterpreter(this); - assert(_emc); - - setupOpcodeTable(); - readSettings(); - - if (ConfMan.hasKey("save_slot")) { - _gameToLoad = ConfMan.getInt("save_slot"); - if (!saveFileLoadable(_gameToLoad)) - _gameToLoad = -1; - } - - _lang = 0; - Common::Language lang = Common::parseLanguage(ConfMan.get("language")); - - if (_flags.gameID == GI_KYRA2 || _flags.gameID == GI_KYRA3) { - switch (lang) { - case Common::EN_ANY: - case Common::EN_USA: - case Common::EN_GRB: - _lang = 0; - break; - - case Common::FR_FRA: - _lang = 1; - break; - - case Common::DE_DEU: - _lang = 2; - break; - - case Common::JA_JPN: - _lang = 3; - break; - - default: - warning("unsupported language, switching back to English"); - _lang = 0; - break; - } - } - - return 0; -} - -KyraEngine::~KyraEngine() { - for (Common::Array<const Opcode*>::iterator i = _opcodes.begin(); i != _opcodes.end(); ++i) - delete *i; - _opcodes.clear(); - - delete _res; - delete _staticres; - delete _sound; - delete _text; - delete _timer; - delete _emc; -} - -void KyraEngine::quitGame() { - debugC(9, kDebugLevelMain, "KyraEngine::quitGame()"); - _quitFlag = true; - // Nothing to do here -} - -Common::Point KyraEngine::getMousePos() const { - Common::Point mouse = _eventMan->getMousePos(); - - if (_flags.useHiResOverlay) { - mouse.x >>= 1; - mouse.y >>= 1; - } - - return mouse; -} - -void KyraEngine::setMousePos(int x, int y) { - if (_flags.useHiResOverlay) { - x <<= 1; - y <<= 1; - } - _system->warpMouse(x, y); -} - -int KyraEngine::setGameFlag(int flag) { - _flagsTable[flag >> 3] |= (1 << (flag & 7)); - return 1; -} - -int KyraEngine::queryGameFlag(int flag) const { - return ((_flagsTable[flag >> 3] >> (flag & 7)) & 1); -} - -int KyraEngine::resetGameFlag(int flag) { - _flagsTable[flag >> 3] &= ~(1 << (flag & 7)); - return 0; -} - -void KyraEngine::delayUntil(uint32 timestamp, bool updateTimers, bool update, bool isMainLoop) { - while (_system->getMillis() < timestamp && !_quitFlag) { - if (timestamp - _system->getMillis() >= 10) - delay(10, update, isMainLoop); - } -} - -void KyraEngine::delay(uint32 amount, bool update, bool isMainLoop) { - _system->delayMillis(amount); -} - -void KyraEngine::delayWithTicks(int ticks) { - delay(ticks * _tickLength); -} - -void KyraEngine::registerDefaultSettings() { - if (_flags.gameID != GI_KYRA3) - ConfMan.registerDefault("cdaudio", (_flags.platform == Common::kPlatformFMTowns || _flags.platform == Common::kPlatformPC98)); -} - -void KyraEngine::readSettings() { - _configWalkspeed = ConfMan.getInt("walkspeed"); - _configMusic = 0; - - if (!ConfMan.getBool("music_mute")) { - _configMusic = 1; - if (_flags.gameID != GI_KYRA3 && ConfMan.getBool("cdaudio") && (_flags.platform == Common::kPlatformFMTowns || _flags.platform == Common::kPlatformPC98)) - _configMusic = 2; - } - _configSounds = ConfMan.getBool("sfx_mute") ? 0 : 1; - - if (_sound) { - _sound->enableMusic(_configMusic); - _sound->enableSFX(_configSounds); - } - - bool speechMute = ConfMan.getBool("speech_mute"); - bool subtitles = ConfMan.getBool("subtitles"); - - if (!speechMute && subtitles) - _configVoice = 2; // Voice & Text - else if (!speechMute && !subtitles) - _configVoice = 1; // Voice only - else - _configVoice = 0; // Text only - - setWalkspeed(_configWalkspeed); -} - -void KyraEngine::writeSettings() { - bool speechMute, subtitles; - - ConfMan.setInt("walkspeed", _configWalkspeed); - ConfMan.setBool("music_mute", _configMusic == 0); - if (_flags.gameID != GI_KYRA3) - ConfMan.setBool("cdaudio", _configMusic == 2); - ConfMan.setBool("sfx_mute", _configSounds == 0); - - switch (_configVoice) { - case 0: // Text only - speechMute = true; - subtitles = true; - break; - case 1: // Voice only - speechMute = false; - subtitles = false; - break; - default: // Voice & Text - speechMute = false; - subtitles = true; - break; - } - - if (_sound) { - if (!_configMusic) - _sound->beginFadeOut(); - _sound->enableMusic(_configMusic); - _sound->enableSFX(_configSounds); - } - - ConfMan.setBool("speech_mute", speechMute); - ConfMan.setBool("subtitles", subtitles); - - ConfMan.flushToDisk(); -} - -bool KyraEngine::speechEnabled() { - return _flags.isTalkie && (_configVoice == 1 || _configVoice == 2); -} - -bool KyraEngine::textEnabled() { - return !_flags.isTalkie || (_configVoice == 0 || _configVoice == 2); -} - -inline int convertValueToMixer(int value) { - value -= 2; - return (value * Audio::Mixer::kMaxMixerVolume) / 95; -} - -inline int convertValueFromMixer(int value) { - return (value * 95) / Audio::Mixer::kMaxMixerVolume + 2; -} - -void KyraEngine::setVolume(kVolumeEntry vol, uint8 value) { - switch (vol) { - case kVolumeMusic: - ConfMan.setInt("music_volume", convertValueToMixer(value)); - break; - - case kVolumeSfx: - ConfMan.setInt("sfx_volume", convertValueToMixer(value)); - break; - - case kVolumeSpeech: - ConfMan.setInt("speech_volume", convertValueToMixer(value)); - break; - } - - // Resetup mixer - _mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, ConfMan.getInt("sfx_volume")); - _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, ConfMan.getInt("music_volume")); - _mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, ConfMan.getInt("speech_volume")); - if (_sound) - _sound->updateVolumeSettings(); -} - -uint8 KyraEngine::getVolume(kVolumeEntry vol) { - switch (vol) { - case kVolumeMusic: - return convertValueFromMixer(ConfMan.getInt("music_volume")); - break; - - case kVolumeSfx: - return convertValueFromMixer(ConfMan.getInt("sfx_volume")); - break; - - case kVolumeSpeech: - if (speechEnabled()) - return convertValueFromMixer(ConfMan.getInt("speech_volume")); - else - return 2; - break; - } - - return 2; -} - -} // End of namespace Kyra - diff --git a/engines/kyra/kyra.h b/engines/kyra/kyra.h deleted file mode 100644 index 18a4a52fe2..0000000000 --- a/engines/kyra/kyra.h +++ /dev/null @@ -1,268 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#ifndef KYRA_KYRA_H -#define KYRA_KYRA_H - -#include "engines/engine.h" - -#include "common/array.h" -#include "common/events.h" - -#include "kyra/script.h" - -namespace Common { -class InSaveFile; -class OutSaveFile; -} // end of namespace Common - -class KyraMetaEngine; - -namespace Kyra { - -struct GameFlags { - Common::Language lang; - Common::Platform platform; - - 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 { - GI_KYRA1 = 0, - GI_KYRA2 = 1, - GI_KYRA3 = 2 -}; - -struct AudioDataStruct { - const char * const *_fileList; - const int _fileListLen; - const void * const _cdaTracks; - const int _cdaNumTracks; -}; - -// TODO: this is just the start of makeing the debug output of the kyra engine a bit more useable -// 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 "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 - kDebugLevelAnimator = 1 << 5, // prints debug output of "ScreenAnimator" functions - kDebugLevelMain = 1 << 6, // prints debug output of common "KyraEngine(_v#)" functions && "TextDisplayer" functions - kDebugLevelGUI = 1 << 7, // prints debug output of "KyraEngine*" gui functions - kDebugLevelSequence = 1 << 8, // prints debug output of "SeqPlayer" functions - kDebugLevelMovie = 1 << 9, // prints debug output of movie specific funtions - kDebugLevelTimer = 1 << 10 // prints debug output of "TimerManager" functions -}; - -enum kMusicDataID { - kMusicIntro = 0, - kMusicIngame, - kMusicFinale -}; - -class Screen; -class Resource; -class Sound; -class Movie; -class TextDisplayer; -class StaticResource; -class TimerManager; - -class KyraEngine : public Engine { -friend class Debugger; -friend class ::KyraMetaEngine; -friend class GUI; -public: - KyraEngine(OSystem *system, const GameFlags &flags); - virtual ~KyraEngine(); - - bool quit() const { return _quitFlag; } - - uint8 game() const { return _flags.gameID; } - const GameFlags &gameFlags() const { return _flags; } - - // access to Kyra specific functionallity - Resource *resource() { return _res; } - virtual Screen *screen() = 0; - virtual TextDisplayer *text() { return _text; } - Sound *sound() { return _sound; } - StaticResource *staticres() { return _staticres; } - TimerManager *timer() { return _timer; } - - uint32 tickLength() const { return _tickLength; } - - Common::RandomSource _rnd; - - // input - void setMousePos(int x, int y); - Common::Point getMousePos() const; - - // config specific - bool speechEnabled(); - bool textEnabled(); - - enum kVolumeEntry { - kVolumeMusic = 0, - kVolumeSfx = 1, - kVolumeSpeech = 2 - }; - - // volume reaches from 2 to 97 - void setVolume(kVolumeEntry vol, uint8 value); - uint8 getVolume(kVolumeEntry vol); - - // quit handling - virtual void quitGame(); - - // game flag handling - int setGameFlag(int flag); - int queryGameFlag(int flag) const; - int resetGameFlag(int flag); - - // sound - virtual void snd_playTheme(int file, int track); - 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(); - virtual void snd_stopVoice(); - - // delay functionallity - virtual void delayUntil(uint32 timestamp, bool updateGameTimers = false, bool update = false, bool isMainLoop = false); - virtual void delay(uint32 millis, bool update = false, bool isMainLoop = false); - virtual void delayWithTicks(int ticks); - -protected: - virtual int go() = 0; - virtual int init(); - - // quit Handling - bool _quitFlag; - - // intern - Resource *_res; - Sound *_sound; - TextDisplayer *_text; - StaticResource *_staticres; - TimerManager *_timer; - EMCInterpreter *_emc; - - // config specific - virtual void registerDefaultSettings(); - virtual void readSettings(); - virtual void writeSettings(); - - uint8 _configWalkspeed; - - int _configMusic; - bool _configSounds; - uint8 _configVoice; - - // game speed - virtual bool skipFlag() const = 0; - virtual void resetSkipFlag(bool removeEvent = true) = 0; - - uint16 _tickLength; - uint16 _gameSpeed; - - // timer - virtual void setupTimers() = 0; - - virtual void setWalkspeed(uint8 speed) = 0; - - // detection - GameFlags _flags; - int _lang; - - // opcode - virtual void setupOpcodeTable() = 0; - Common::Array<const Opcode*> _opcodes; - - // game flags - uint8 _flagsTable[100]; // TODO: check this value - - // sound - Common::String _speechFile; - - int _curMusicTheme; - int _curSfxFile; - int16 _lastMusicCommand; - - const int8 *_trackMap; - int _trackMapSize; - - // pathfinder - virtual int findWay(int x, int y, int toX, int toY, int *moveTable, int moveTableSize); - int findSubPath(int x, int y, int toX, int toY, int *moveTable, int start, int end); - int getFacingFromPointToPoint(int x, int y, int toX, int toY); - int getOppositeFacingDirection(int dir); - void changePosTowardsFacing(int &x, int &y, int facing); - int getMoveTableSize(int *moveTable); - virtual bool lineIsPassable(int x, int y) = 0; - - static const int8 _addXPosTable[]; - static const int8 _addYPosTable[]; - - // save/load - int _gameToLoad; - - const char *getSavegameFilename(int num); - bool saveFileLoadable(int slot); - - struct SaveHeader { - Common::String description; - uint32 version; - byte gameID; - uint32 flags; - - bool originalSave; // savegame from original interpreter - bool oldHeader; // old scummvm save header - }; - - enum kReadSaveHeaderError { - kRSHENoError = 0, - kRSHEInvalidType = 1, - kRSHEInvalidVersion = 2, - kRSHEIoError = 3 - }; - - static kReadSaveHeaderError readSaveHeader(Common::InSaveFile *file, SaveHeader &header); - - Common::InSaveFile *openSaveForReading(const char *filename, SaveHeader &header); - Common::OutSaveFile *openSaveForWriting(const char *filename, const char *saveName) const; -}; - -} // End of namespace Kyra - -#endif - diff --git a/engines/kyra/kyra_hof.cpp b/engines/kyra/kyra_hof.cpp index c25af91bec..57f0dcc24a 100644 --- a/engines/kyra/kyra_hof.cpp +++ b/engines/kyra/kyra_hof.cpp @@ -23,7 +23,7 @@ * */ -#include "kyra/kyra.h" +#include "kyra/kyra_v1.h" #include "kyra/kyra_hof.h" #include "kyra/screen.h" #include "kyra/resource.h" @@ -49,11 +49,13 @@ const KyraEngine_v2::EngineDesc KyraEngine_HoF::_hofEngineDesc = { 8, // Animation script specific - 33 + 33, + + // Item specific + 175 }; 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; @@ -79,7 +81,7 @@ KyraEngine_HoF::KyraEngine_HoF(OSystem *system, const GameFlags &flags) : KyraEn _oldTalkFile = -1; _currentTalkFile = 0; _lastSfxTrack = -1; - _handItemSet = -1; + _mouseState = -1; _unkHandleSceneChangeFlag = false; _pathfinderFlag = 0; _mouseX = _mouseY = 0; @@ -140,13 +142,14 @@ KyraEngine_HoF::KyraEngine_HoF(OSystem *system, const GameFlags &flags) : KyraEn _menuDirectlyToLoad = false; _menu = 0; + _chatIsNote = false; + memset(&_npcScriptData, 0, sizeof(_npcScriptData)); } KyraEngine_HoF::~KyraEngine_HoF() { cleanup(); seq_uninit(); - delete [] _mouseSHPBuf; delete _screen; delete _text; delete _gui; @@ -157,29 +160,67 @@ KyraEngine_HoF::~KyraEngine_HoF() { if (_sequenceSoundList) { for (int i = 0; i < _sequenceSoundListSize; i++) { if (_sequenceSoundList[i]) - delete [] _sequenceSoundList[i]; + delete[] _sequenceSoundList[i]; } - delete [] _sequenceSoundList; + delete[] _sequenceSoundList; _sequenceSoundList = NULL; } if (_dlgBuffer) - delete [] _dlgBuffer; + delete[] _dlgBuffer; for (int i = 0; i < 19; i++) - delete [] _conversationState[i]; - delete [] _conversationState; + delete[] _conversationState[i]; + delete[] _conversationState; for (Common::Array<const TIMOpcode*>::iterator i = _timOpcodes.begin(); i != _timOpcodes.end(); ++i) delete *i; _timOpcodes.clear(); } +void KyraEngine_HoF::pauseEngineIntern(bool pause) { + KyraEngine_v2::pauseEngineIntern(pause); + + if (!pause) { + uint32 pausedTime = _system->getMillis() - _pauseStart; + _pauseStart = 0; + + // sequence player + // + // Timers in KyraEngine_HoF::seq_cmpFadeFrame() and KyraEngine_HoF::seq_animatedSubFrame() + // have been left out for now. I think we don't need them here. + + _seqStartTime += pausedTime; + _seqSubFrameStartTime += pausedTime; + _seqEndTime += pausedTime; + _seqSubFrameEndTimeInternal += pausedTime; + _seqWsaChatTimeout += pausedTime; + _seqWsaChatFrameTimeout += pausedTime; + + for (int x = 0; x < 10; x++) { + if (_activeText[x].duration != -1) + _activeText[x].startTime += pausedTime; + } + + for (int x = 0; x < 8; x++) { + if (_activeWSA[x].flags != -1) + _activeWSA[x].nextFrame += pausedTime; + } + + _nextIdleAnim += pausedTime; + + for (int x = 0; x < _itemAnimDataSize; x++) + _activeItemAnim[x].nextFrame += pausedTime; + + _tim->refreshTimersAfterPause(pausedTime); + } +} + int KyraEngine_HoF::init() { _screen = new Screen_HoF(this, _system); assert(_screen); _screen->setResolution(); - KyraEngine::init(); + KyraEngine_v1::init(); initStaticResource(); _debugger = new Debugger_HoF(this); @@ -218,11 +259,14 @@ int KyraEngine_HoF::init() { if (_flags.isDemo && !_flags.isTalkie) return 0; - _mouseSHPBuf = _res->fileData("PWGMOUSE.SHP", 0); - assert(_mouseSHPBuf); + _res->exists("PWGMOUSE.SHP", true); + uint8 *shapes = _res->fileData("PWGMOUSE.SHP", 0); + assert(shapes); for (int i = 0; i < 2; i++) - addShapeToPool(_screen->getPtrToShape(_mouseSHPBuf, i), i); + addShapeToPool(shapes, i, i); + + delete[] shapes; _screen->setMouseCursor(0, 0, getShapePtr(0)); return 0; @@ -280,10 +324,7 @@ void KyraEngine_HoF::startup() { 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]; @@ -316,18 +357,16 @@ void KyraEngine_HoF::startup() { _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); + _sceneAnimMovie[i] = new WSAMovie_v2(this, _screen); memset(_wsaSlots, 0, sizeof(_wsaSlots)); for (int i = 0; i < ARRAYSIZE(_wsaSlots); ++i) - _wsaSlots[i] = new WSAMovieV2(this, _screen); + _wsaSlots[i] = new WSAMovie_v2(this, _screen); _screen->_curPage = 0; @@ -448,7 +487,7 @@ void KyraEngine_HoF::runLoop() { update(); if (inputFlag == 198 || inputFlag == 199) { - _unk3 = _handItemSet; + _unk3 = _mouseState; handleInput(_mouseX, _mouseY); } @@ -567,7 +606,7 @@ 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) { + if (_mouseState <= -3 && findItem(_mainCharacter.sceneId, 13) >= 0) { updateCharFacing(); objectChat(getTableString(0xFC, _cCodeBuffer, 1), 0, 0x83, 0xFC); return true; @@ -722,17 +761,16 @@ void KyraEngine_HoF::updateMouse() { yOffset = 9; } - if (type != 0 && _handItemSet != type && _screen->isMouseVisible()) { - _mouseState = _handItemSet = type; + if (type != 0 && _mouseState != type && _screen->isMouseVisible()) { + _mouseState = type; _screen->hideMouse(); _screen->setMouseCursor(xOffset, yOffset, getShapePtr(shapeIndex)); _screen->showMouse(); } - if (type == 0 && _handItemSet != _itemInHand && _screen->isMouseVisible()) { + if (type == 0 && _mouseState != _itemInHand && _screen->isMouseVisible()) { if ((mouse.y > 145) || (mouse.x > 6 && mouse.x < 312 && mouse.y > 6 && mouse.y < 135)) { - _mouseState = 0; - _handItemSet = _itemInHand; + _mouseState = _itemInHand; _screen->hideMouse(); if (_itemInHand == -1) _screen->setMouseCursor(0, 0, getShapePtr(0)); @@ -743,44 +781,25 @@ void KyraEngine_HoF::updateMouse() { } } -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[] _inventoryButtons; _inventoryButtons = 0; - delete [] _gamePlayBuffer; _gamePlayBuffer = 0; - delete [] _unkBuf500Bytes; _unkBuf500Bytes = 0; - delete [] _unkBuf200kByte; _unkBuf200kByte = 0; + delete[] _gamePlayBuffer; _gamePlayBuffer = 0; + delete[] _unkBuf500Bytes; _unkBuf500Bytes = 0; + delete[] _unkBuf200kByte; _unkBuf200kByte = 0; freeSceneShapePtrs(); if (_optionsBuffer != _cCodeBuffer) - delete [] _optionsBuffer; + delete[] _optionsBuffer; _optionsBuffer = 0; - delete [] _cCodeBuffer; _cCodeBuffer = 0; - delete [] _chapterBuffer; _chapterBuffer = 0; + delete[] _cCodeBuffer; _cCodeBuffer = 0; + delete[] _chapterBuffer; _chapterBuffer = 0; - delete [] _talkObjectList; _talkObjectList = 0; - delete [] _shapeDescTable; _shapeDescTable = 0; + delete[] _talkObjectList; _talkObjectList = 0; + delete[] _shapeDescTable; _shapeDescTable = 0; - delete [] _gfxBackUpRect; _gfxBackUpRect = 0; - - delete [] _sceneList; _sceneList = 0; + delete[] _gfxBackUpRect; _gfxBackUpRect = 0; for (int i = 0; i < ARRAYSIZE(_sceneAnimMovie); ++i) { delete _sceneAnimMovie[i]; @@ -791,9 +810,11 @@ void KyraEngine_HoF::cleanup() { _wsaSlots[i] = 0; } for (int i = 0; i < ARRAYSIZE(_buttonShapes); ++i) { - delete [] _buttonShapes[i]; + delete[] _buttonShapes[i]; _buttonShapes[i] = 0; } + + _emc->unload(&_npcScriptData); } #pragma mark - Localization @@ -803,7 +824,7 @@ void KyraEngine_HoF::loadCCodeBuffer(const char *file) { strcpy(tempString, file); changeFileExtension(tempString); - delete [] _cCodeBuffer; + delete[] _cCodeBuffer; _cCodeBuffer = _res->fileData(tempString, 0); } @@ -812,7 +833,7 @@ void KyraEngine_HoF::loadOptionsBuffer(const char *file) { strcpy(tempString, file); changeFileExtension(tempString); - delete [] _optionsBuffer; + delete[] _optionsBuffer; _optionsBuffer = _res->fileData(tempString, 0); } @@ -827,7 +848,7 @@ void KyraEngine_HoF::loadChapterBuffer(int chapter) { strcpy(tempString, chapterFilenames[chapter-1]); changeFileExtension(tempString); - delete [] _chapterBuffer; + delete[] _chapterBuffer; _chapterBuffer = _res->fileData(tempString, 0); _currentChapter = chapter; } @@ -1008,7 +1029,7 @@ 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); + addShapeToPool(_screen->getCPagePtr(3), i, i); } void KyraEngine_HoF::loadItemShapes() { @@ -1033,7 +1054,7 @@ void KyraEngine_HoF::loadCharacterShapes(int shapes) { uint8 *data = _res->fileData(file, 0); for (int i = 9; i <= 32; ++i) addShapeToPool(data, i, i-9); - delete [] data; + delete[] data; _characterShapeFile = shapes; } @@ -1070,6 +1091,8 @@ void KyraEngine_HoF::runStartScript(int script, int unk1) { } void KyraEngine_HoF::loadNPCScript() { + _emc->unload(&_npcScriptData); + char filename[12]; strcpy(filename, "_NPC.EMC"); @@ -1382,7 +1405,7 @@ int KyraEngine_HoF::initAnimationShapes(uint8 *filedata) { void KyraEngine_HoF::uninitAnimationShapes(int count, uint8 *filedata) { for (int i = 0; i < count; ++i) remShapeFromPool(i+33); - delete [] filedata; + delete[] filedata; setNextIdleAnimTimer(); } @@ -1541,7 +1564,7 @@ void KyraEngine_HoF::snd_playSoundEffect(int track, int volume) { 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); + KyraEngine_v1::snd_playSoundEffect(track); } #pragma mark - @@ -1552,7 +1575,7 @@ void KyraEngine_HoF::loadInvWsa(const char *filename, int run, int delayTime, in wsaFlags |= 2; if (!_invWsa.wsa) - _invWsa.wsa = new WSAMovieV2(this, _screen); + _invWsa.wsa = new WSAMovie_v2(this, _screen); if (!_invWsa.wsa->open(filename, wsaFlags, 0)) error("Couldn't open inventory WSA file '%s'", filename); @@ -1969,7 +1992,7 @@ void KyraEngine_HoF::playTim(const char *filename) { #pragma mark - void KyraEngine_HoF::registerDefaultSettings() { - KyraEngine::registerDefaultSettings(); + KyraEngine_v1::registerDefaultSettings(); // Most settings already have sensible defaults. This one, however, is // specific to the Kyra engine. @@ -2000,13 +2023,13 @@ void KyraEngine_HoF::writeSettings() { ConfMan.set("language", Common::getLanguageCode(_flags.lang)); - KyraEngine::writeSettings(); + KyraEngine_v1::writeSettings(); } void KyraEngine_HoF::readSettings() { int talkspeed = ConfMan.getInt("talkspeed"); _configTextspeed = (talkspeed*95)/255 + 2; - KyraEngine::readSettings(); + KyraEngine_v1::readSettings(); } } // end of namespace Kyra diff --git a/engines/kyra/kyra_hof.h b/engines/kyra/kyra_hof.h index 1e6c23331e..866dd55d16 100644 --- a/engines/kyra/kyra_hof.h +++ b/engines/kyra/kyra_hof.h @@ -97,22 +97,17 @@ enum kNestedSequencesDemo { kSequenceDemoDig }; -class WSAMovieV2; +class WSAMovie_v2; class KyraEngine_HoF; class TextDisplayer_HoF; struct TIM; -typedef int (KyraEngine_HoF::*SeqProc)(WSAMovieV2*, int, int, int); - -struct FrameControl { - uint16 index; - uint16 delay; -}; +typedef int (KyraEngine_HoF::*SeqProc)(WSAMovie_v2*, int, int, int); struct ActiveWSA { int16 flags; - WSAMovieV2 *movie; + WSAMovie_v2 *movie; uint16 startFrame; uint16 endFrame; uint16 frameDelay; @@ -179,17 +174,6 @@ struct ItemAnimData_v1 { 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; @@ -198,6 +182,8 @@ public: KyraEngine_HoF(OSystem *system, const GameFlags &flags); ~KyraEngine_HoF(); + void pauseEngineIntern(bool pause); + Screen *screen() { return _screen; } Screen_v2 *screen_v2() const { return _screen; } GUI_v2 *gui_v2() const { return _gui; } @@ -209,52 +195,52 @@ protected: // intro/outro void seq_playSequences(int startSeq, int endSeq = -1); - int seq_introWestwood(WSAMovieV2 *wsaObj, int x, int y, int frm); - int seq_introTitle(WSAMovieV2 *wsaObj, int x, int y, int frm); - int seq_introOverview(WSAMovieV2 *wsaObj, int x, int y, int frm); - int seq_introLibrary(WSAMovieV2 *wsaObj, int x, int y, int frm); - int seq_introHand(WSAMovieV2 *wsaObj, int x, int y, int frm); - int seq_introPoint(WSAMovieV2 *wsaObj, int x, int y, int frm); - int seq_introZanfaun(WSAMovieV2 *wsaObj, int x, int y, int frm); - - int seq_introOver1(WSAMovieV2 *wsaObj, int x, int y, int frm); - int seq_introOver2(WSAMovieV2 *wsaObj, int x, int y, int frm); - int seq_introForest(WSAMovieV2 *wsaObj, int x, int y, int frm); - int seq_introDragon(WSAMovieV2 *wsaObj, int x, int y, int frm); - int seq_introDarm(WSAMovieV2 *wsaObj, int x, int y, int frm); - int seq_introLibrary2(WSAMovieV2 *wsaObj, int x, int y, int frm); - int seq_introMarco(WSAMovieV2 *wsaObj, int x, int y, int frm); - int seq_introHand1a(WSAMovieV2 *wsaObj, int x, int y, int frm); - int seq_introHand1b(WSAMovieV2 *wsaObj, int x, int y, int frm); - int seq_introHand1c(WSAMovieV2 *wsaObj, int x, int y, int frm); - int seq_introHand2(WSAMovieV2 *wsaObj, int x, int y, int frm); - int seq_introHand3(WSAMovieV2 *wsaObj, int x, int y, int frm); - - int seq_finaleFunters(WSAMovieV2 *wsaObj, int x, int y, int frm); - int seq_finaleFerb(WSAMovieV2 *wsaObj, int x, int y, int frm); - int seq_finaleFish(WSAMovieV2 *wsaObj, int x, int y, int frm); - int seq_finaleFheep(WSAMovieV2 *wsaObj, int x, int y, int frm); - int seq_finaleFarmer(WSAMovieV2 *wsaObj, int x, int y, int frm); - int seq_finaleFuards(WSAMovieV2 *wsaObj, int x, int y, int frm); - int seq_finaleFirates(WSAMovieV2 *wsaObj, int x, int y, int frm); - int seq_finaleFrash(WSAMovieV2 *wsaObj, int x, int y, int frm); - - int seq_finaleFiggle(WSAMovieV2 *wsaObj, int x, int y, int frm); - - int seq_demoVirgin(WSAMovieV2 *wsaObj, int x, int y, int frm); - int seq_demoWestwood(WSAMovieV2 *wsaObj, int x, int y, int frm); - int seq_demoTitle(WSAMovieV2 *wsaObj, int x, int y, int frm); - int seq_demoHill(WSAMovieV2 *wsaObj, int x, int y, int frm); - int seq_demoOuthome(WSAMovieV2 *wsaObj, int x, int y, int frm); - int seq_demoWharf(WSAMovieV2 *wsaObj, int x, int y, int frm); - int seq_demoDinob(WSAMovieV2 *wsaObj, int x, int y, int frm); - int seq_demoFisher(WSAMovieV2 *wsaObj, int x, int y, int frm); - - int seq_demoWharf2(WSAMovieV2 *wsaObj, int x, int y, int frm); - int seq_demoDinob2(WSAMovieV2 *wsaObj, int x, int y, int frm); - int seq_demoWater(WSAMovieV2 *wsaObj, int x, int y, int frm); - int seq_demoBail(WSAMovieV2 *wsaObj, int x, int y, int frm); - int seq_demoDig(WSAMovieV2 *wsaObj, int x, int y, int frm); + int seq_introWestwood(WSAMovie_v2 *wsaObj, int x, int y, int frm); + int seq_introTitle(WSAMovie_v2 *wsaObj, int x, int y, int frm); + int seq_introOverview(WSAMovie_v2 *wsaObj, int x, int y, int frm); + int seq_introLibrary(WSAMovie_v2 *wsaObj, int x, int y, int frm); + int seq_introHand(WSAMovie_v2 *wsaObj, int x, int y, int frm); + int seq_introPoint(WSAMovie_v2 *wsaObj, int x, int y, int frm); + int seq_introZanfaun(WSAMovie_v2 *wsaObj, int x, int y, int frm); + + int seq_introOver1(WSAMovie_v2 *wsaObj, int x, int y, int frm); + int seq_introOver2(WSAMovie_v2 *wsaObj, int x, int y, int frm); + int seq_introForest(WSAMovie_v2 *wsaObj, int x, int y, int frm); + int seq_introDragon(WSAMovie_v2 *wsaObj, int x, int y, int frm); + int seq_introDarm(WSAMovie_v2 *wsaObj, int x, int y, int frm); + int seq_introLibrary2(WSAMovie_v2 *wsaObj, int x, int y, int frm); + int seq_introMarco(WSAMovie_v2 *wsaObj, int x, int y, int frm); + int seq_introHand1a(WSAMovie_v2 *wsaObj, int x, int y, int frm); + int seq_introHand1b(WSAMovie_v2 *wsaObj, int x, int y, int frm); + int seq_introHand1c(WSAMovie_v2 *wsaObj, int x, int y, int frm); + int seq_introHand2(WSAMovie_v2 *wsaObj, int x, int y, int frm); + int seq_introHand3(WSAMovie_v2 *wsaObj, int x, int y, int frm); + + int seq_finaleFunters(WSAMovie_v2 *wsaObj, int x, int y, int frm); + int seq_finaleFerb(WSAMovie_v2 *wsaObj, int x, int y, int frm); + int seq_finaleFish(WSAMovie_v2 *wsaObj, int x, int y, int frm); + int seq_finaleFheep(WSAMovie_v2 *wsaObj, int x, int y, int frm); + int seq_finaleFarmer(WSAMovie_v2 *wsaObj, int x, int y, int frm); + int seq_finaleFuards(WSAMovie_v2 *wsaObj, int x, int y, int frm); + int seq_finaleFirates(WSAMovie_v2 *wsaObj, int x, int y, int frm); + int seq_finaleFrash(WSAMovie_v2 *wsaObj, int x, int y, int frm); + + int seq_finaleFiggle(WSAMovie_v2 *wsaObj, int x, int y, int frm); + + int seq_demoVirgin(WSAMovie_v2 *wsaObj, int x, int y, int frm); + int seq_demoWestwood(WSAMovie_v2 *wsaObj, int x, int y, int frm); + int seq_demoTitle(WSAMovie_v2 *wsaObj, int x, int y, int frm); + int seq_demoHill(WSAMovie_v2 *wsaObj, int x, int y, int frm); + int seq_demoOuthome(WSAMovie_v2 *wsaObj, int x, int y, int frm); + int seq_demoWharf(WSAMovie_v2 *wsaObj, int x, int y, int frm); + int seq_demoDinob(WSAMovie_v2 *wsaObj, int x, int y, int frm); + int seq_demoFisher(WSAMovie_v2 *wsaObj, int x, int y, int frm); + + int seq_demoWharf2(WSAMovie_v2 *wsaObj, int x, int y, int frm); + int seq_demoDinob2(WSAMovie_v2 *wsaObj, int x, int y, int frm); + int seq_demoWater(WSAMovie_v2 *wsaObj, int x, int y, int frm); + int seq_demoBail(WSAMovie_v2 *wsaObj, int x, int y, int frm); + int seq_demoDig(WSAMovie_v2 *wsaObj, int x, int y, int frm); void seq_sequenceCommand(int command); void seq_loadNestedSequence(int wsaNum, int seqNum); @@ -275,7 +261,7 @@ protected: char *seq_preprocessString(const char *str, int width); void seq_printCreditsString(uint16 strIndex, int x, int y, const uint8 *colorMap, uint8 textcolor); void seq_playWsaSyncDialogue(uint16 strIndex, uint16 vocIndex, int textColor, int x, int y, int width, - WSAMovieV2 * wsa, int firstframe, int lastframe, int wsaXpos, int wsaYpos); + WSAMovie_v2 * wsa, int firstframe, int lastframe, int wsaXpos, int wsaYpos); void seq_finaleActorScreen(); void seq_displayScrollText(uint8 *data, const ScreenDim *d, int tempPage1, int tempPage2, int speed, int step, Screen::FontId fid1, Screen::FontId fid2, const uint8 *shapeData = 0, const char *const *specialData = 0); void seq_scrollPage(); @@ -291,8 +277,6 @@ protected: TextDisplayer_HoF *_text; TIMInterpreter *_tim; - uint8 *_mouseSHPBuf; - static const int8 _dosTrackMap[]; static const int _dosTrackMapSize; @@ -329,8 +313,6 @@ protected: void dinoRide(); - int _mouseState; - void handleInput(int x, int y); bool handleInputUnkSub(int x, int y); @@ -350,7 +332,7 @@ protected: uint8 *_sceneShapeTable[50]; - WSAMovieV2 *_wsaSlots[10]; + WSAMovie_v2 *_wsaSlots[10]; void freeSceneShapePtrs(); @@ -675,9 +657,6 @@ protected: 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(); @@ -690,7 +669,7 @@ protected: int delay; bool running; uint32 timer; - WSAMovieV2 *wsa; + WSAMovie_v2 *wsa; } _invWsa; // TODO: move inside KyraEngine_HoF::InventoryWsa? @@ -732,7 +711,6 @@ protected: 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); @@ -759,17 +737,14 @@ protected: 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_playFireflyScore(EMCState *script); int o2_encodeShape(EMCState *script); int o2_defineSceneAnim(EMCState *script); int o2_updateSceneAnim(EMCState *script); @@ -805,7 +780,7 @@ protected: int o2_updateTwoSceneAnims(EMCState *script); int o2_getRainbowRoomData(EMCState *script); int o2_drawSceneShapeEx(EMCState *script); - int o2_getBoolFromStack(EMCState *script); + int o2_midiSoundFadeout(EMCState *script); int o2_getSfxDriver(EMCState *script); int o2_getVocSupport(EMCState *script); int o2_getMusicDriver(EMCState *script); @@ -876,14 +851,19 @@ protected: static const uint8 _seqTextColorPresets[]; char *_seqProcessedString; - WSAMovieV2 *_seqWsa; + WSAMovie_v2 *_seqWsa; bool _abortIntroFlag; int _menuChoice; uint32 _seqFrameDelay; uint32 _seqStartTime; + uint32 _seqSubFrameStartTime; uint32 _seqEndTime; + uint32 _seqSubFrameEndTimeInternal; + uint32 _seqWsaChatTimeout; + uint32 _seqWsaChatFrameTimeout; + int _seqFrameCounter; int _seqScrollTextCounter; int _seqWsaCurrentFrame; diff --git a/engines/kyra/kyra_lok.cpp b/engines/kyra/kyra_lok.cpp new file mode 100644 index 0000000000..c852f6e3ee --- /dev/null +++ b/engines/kyra/kyra_lok.cpp @@ -0,0 +1,1044 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "kyra/kyra_lok.h" + +#include "common/file.h" +#include "common/events.h" +#include "common/system.h" +#include "common/savefile.h" + +#include "gui/message.h" + +#include "kyra/resource.h" +#include "kyra/screen.h" +#include "kyra/script.h" +#include "kyra/seqplayer.h" +#include "kyra/sound.h" +#include "kyra/sprites.h" +#include "kyra/wsamovie.h" +#include "kyra/animator_lok.h" +#include "kyra/text.h" +#include "kyra/debugger.h" +#include "kyra/timer.h" + +namespace Kyra { + +KyraEngine_LoK::KyraEngine_LoK(OSystem *system, const GameFlags &flags) + : KyraEngine_v1(system, flags) { + _skipFlag = false; + + _seq_Forest = _seq_KallakWriting = _seq_KyrandiaLogo = _seq_KallakMalcolm = + _seq_MalcolmTree = _seq_WestwoodLogo = _seq_Demo1 = _seq_Demo2 = _seq_Demo3 = + _seq_Demo4 = 0; + + _seq_WSATable = _seq_CPSTable = _seq_COLTable = _seq_textsTable = 0; + _seq_WSATable_Size = _seq_CPSTable_Size = _seq_COLTable_Size = _seq_textsTable_Size = 0; + + _roomFilenameTable = _characterImageTable = 0; + _roomFilenameTableSize = _characterImageTableSize = 0; + _itemList = _takenList = _placedList = _droppedList = _noDropList = 0; + _itemList_Size = _takenList_Size = _placedList_Size = _droppedList_Size = _noDropList_Size = 0; + _putDownFirst = _waitForAmulet = _blackJewel = _poisonGone = _healingTip = 0; + _putDownFirst_Size = _waitForAmulet_Size = _blackJewel_Size = _poisonGone_Size = _healingTip_Size = 0; + _thePoison = _fluteString = _wispJewelStrings = _magicJewelString = _flaskFull = _fullFlask = 0; + _thePoison_Size = _fluteString_Size = _wispJewelStrings_Size = 0; + _magicJewelString_Size = _flaskFull_Size = _fullFlask_Size = 0; + + _defaultShapeTable = 0; + _healingShapeTable = _healingShape2Table = 0; + _defaultShapeTableSize = _healingShapeTableSize = _healingShape2TableSize = 0; + _posionDeathShapeTable = _fluteAnimShapeTable = 0; + _posionDeathShapeTableSize = _fluteAnimShapeTableSize = 0; + _winterScrollTable = _winterScroll1Table = _winterScroll2Table = 0; + _winterScrollTableSize = _winterScroll1TableSize = _winterScroll2TableSize = 0; + _drinkAnimationTable = _brandonToWispTable = _magicAnimationTable = _brandonStoneTable = 0; + _drinkAnimationTableSize = _brandonToWispTableSize = _magicAnimationTableSize = _brandonStoneTableSize = 0; + memset(&_specialPalettes, 0, sizeof(_specialPalettes)); + _sprites = 0; + _animator = 0; + _seq = 0; + _characterList = 0; + _movFacingTable = 0; + _buttonData = 0; + _buttonDataListPtr = 0; + memset(_shapes, 0, sizeof(_shapes)); + memset(_movieObjects, 0, sizeof(_movieObjects)); + _finalA = _finalB = _finalC = 0; + _endSequenceBackUpRect = 0; + memset(_panPagesTable, 0, sizeof(_panPagesTable)); + memset(_sceneAnimTable, 0, sizeof(_sceneAnimTable)); + _currHeadShape = 0; + _speechPlayTime = 0; + + memset(&_itemBkgBackUp, 0, sizeof(_itemBkgBackUp)); +} + +KyraEngine_LoK::~KyraEngine_LoK() { + for (int i = 0; i < ARRAYSIZE(_movieObjects); ++i) { + if (_movieObjects[i]) + _movieObjects[i]->close(); + delete _movieObjects[i]; + _movieObjects[i] = 0; + } + + closeFinalWsa(); + if (_emc) { + _emc->unload(&_npcScriptData); + _emc->unload(&_scriptClickData); + } + + Common::clearAllSpecialDebugLevels(); + + delete _screen; + delete _sprites; + delete _animator; + delete _seq; + + delete[] _characterList; + + delete[] _movFacingTable; + + delete[] _gui->_scrollUpButton.data0ShapePtr; + delete[] _gui->_scrollUpButton.data1ShapePtr; + delete[] _gui->_scrollUpButton.data2ShapePtr; + delete[] _gui->_scrollDownButton.data0ShapePtr; + delete[] _gui->_scrollDownButton.data1ShapePtr; + delete[] _gui->_scrollDownButton.data2ShapePtr; + + delete[] _buttonData; + delete[] _buttonDataListPtr; + + delete _gui; + + delete[] _itemBkgBackUp[0]; + delete[] _itemBkgBackUp[1]; + + for (int i = 0; i < ARRAYSIZE(_shapes); ++i) { + if (_shapes[i] != 0) { + delete[] _shapes[i]; + for (int i2 = 0; i2 < ARRAYSIZE(_shapes); i2++) { + if (_shapes[i2] == _shapes[i] && i2 != i) { + _shapes[i2] = 0; + } + } + _shapes[i] = 0; + } + } + + for (int i = 0; i < ARRAYSIZE(_sceneAnimTable); ++i) + delete[] _sceneAnimTable[i]; +} + +int KyraEngine_LoK::init() { + _screen = new Screen_LoK(this, _system); + assert(_screen); + _screen->setResolution(); + + KyraEngine_v1::init(); + + _sprites = new Sprites(this, _system); + assert(_sprites); + _seq = new SeqPlayer(this, _system); + assert(_seq); + _animator = new Animator_LoK(this, _system); + assert(_animator); + _animator->init(5, 11, 12); + assert(*_animator); + _text = new TextDisplayer(this, screen()); + assert(_text); + _gui = new GUI_LoK(this, _screen); + assert(_gui); + + initStaticResource(); + + _sound->setSoundList(&_soundData[kMusicIntro]); + + _trackMap = _dosTrackMap; + _trackMapSize = _dosTrackMapSize; + + if (!_sound->init()) + error("Couldn't init sound"); + + _sound->loadSoundFile(0); + + setupButtonData(); + + _paletteChanged = 1; + _currentCharacter = 0; + _characterList = new Character[11]; + assert(_characterList); + memset(_characterList, 0, sizeof(Character)*11); + + for (int i = 0; i < 11; ++i) + memset(_characterList[i].inventoryItems, 0xFF, sizeof(_characterList[i].inventoryItems)); + + _characterList[0].sceneId = 5; + _characterList[0].height = 48; + _characterList[0].facing = 3; + _characterList[0].currentAnimFrame = 7; + + memset(&_npcScriptData, 0, sizeof(EMCData)); + memset(&_scriptClickData, 0, sizeof(EMCData)); + + memset(&_npcScript, 0, sizeof(EMCState)); + memset(&_scriptMain, 0, sizeof(EMCState)); + memset(&_scriptClick, 0, sizeof(EMCState)); + + _debugger = new Debugger_LoK(this); + assert(_debugger); + memset(_shapes, 0, sizeof(_shapes)); + + for (int i = 0; i < ARRAYSIZE(_movieObjects); ++i) + _movieObjects[i] = createWSAMovie(); + + memset(_flagsTable, 0, sizeof(_flagsTable)); + + _abortWalkFlag = false; + _abortWalkFlag2 = false; + _talkingCharNum = -1; + _charSayUnk3 = -1; + memset(_currSentenceColor, 0, 3); + _startSentencePalIndex = -1; + _fadeText = false; + + _cauldronState = 0; + _crystalState[0] = _crystalState[1] = -1; + + _brandonStatusBit = 0; + _brandonStatusBit0x02Flag = _brandonStatusBit0x20Flag = 10; + _brandonPosX = _brandonPosY = -1; + _poisonDeathCounter = 0; + + memset(_itemTable, 0, sizeof(_itemTable)); + memset(_exitList, 0xFFFF, sizeof(_exitList)); + _exitListPtr = 0; + _pathfinderFlag = _pathfinderFlag2 = 0; + _lastFindWayRet = 0; + _sceneChangeState = _loopFlag2 = 0; + + _movFacingTable = new int[150]; + assert(_movFacingTable); + _movFacingTable[0] = 8; + + _skipFlag = false; + + _marbleVaseItem = -1; + memset(_foyerItemTable, -1, sizeof(_foyerItemTable)); + _itemInHand = -1; + _handleInput = false; + + _currentRoom = 0xFFFF; + _scenePhasingFlag = 0; + _lastProcessedItem = 0; + _lastProcessedItemHeight = 16; + + _unkScreenVar1 = 1; + _unkScreenVar2 = 0; + _unkScreenVar3 = 0; + _unkAmuletVar = 0; + + _endSequenceNeedLoading = 1; + _malcolmFlag = 0; + _beadStateVar = 0; + _endSequenceSkipFlag = 0; + _unkEndSeqVar2 = 0; + _endSequenceBackUpRect = 0; + _unkEndSeqVar4 = 0; + _unkEndSeqVar5 = 0; + _lastDisplayedPanPage = 0; + memset(_panPagesTable, 0, sizeof(_panPagesTable)); + _finalA = _finalB = _finalC = 0; + memset(&_kyragemFadingState, 0, sizeof(_kyragemFadingState)); + _kyragemFadingState.gOffset = 0x13; + _kyragemFadingState.bOffset = 0x13; + + _mousePressFlag = false; + + _menuDirectlyToLoad = false; + + _lastMusicCommand = 0; + + return 0; +} + +int KyraEngine_LoK::go() { + if (_res->getFileSize("6.FNT")) + _screen->loadFont(Screen::FID_6_FNT, "6.FNT"); + _screen->loadFont(Screen::FID_8_FNT, "8FAT.FNT"); + _screen->setScreenDim(0); + + _abortIntroFlag = false; + + if (_flags.isDemo) { + seq_demo(); + } else { + setGameFlag(0xF3); + setGameFlag(0xFD); + if (_gameToLoad == -1) { + setGameFlag(0xEF); + seq_intro(); + if (_quitFlag) + return 0; + if (_skipIntroFlag && _abortIntroFlag) + resetGameFlag(0xEF); + } + startup(); + resetGameFlag(0xEF); + mainLoop(); + } + return 0; +} + + +void KyraEngine_LoK::startup() { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::startup()"); + static const uint8 colorMap[] = { 0, 0, 0, 0, 12, 12, 12, 0, 0, 0, 0, 0 }; + _screen->setTextColorMap(colorMap); + _sound->setSoundList(&_soundData[kMusicIngame]); + _sound->loadSoundFile(0); +// _screen->setFont(Screen::FID_6_FNT); + _screen->setAnimBlockPtr(3750); + memset(_sceneAnimTable, 0, sizeof(_sceneAnimTable)); + loadMouseShapes(); + _currentCharacter = &_characterList[0]; + for (int i = 1; i < 5; ++i) + _animator->setCharacterDefaultFrame(i); + for (int i = 5; i <= 10; ++i) + setCharactersPositions(i); + _animator->setCharactersHeight(); + resetBrandonPoisonFlags(); + _screen->_curPage = 0; + // XXX + for (int i = 0; i < 12; ++i) { + int size = _screen->getRectSize(3, 24); + _shapes[361+i] = new byte[size]; + } + + _itemBkgBackUp[0] = new uint8[_screen->getRectSize(3, 24)]; + memset(_itemBkgBackUp[0], 0, _screen->getRectSize(3, 24)); + _itemBkgBackUp[1] = new uint8[_screen->getRectSize(4, 32)]; + memset(_itemBkgBackUp[1], 0, _screen->getRectSize(4, 32)); + + for (int i = 0; i < _roomTableSize; ++i) { + for (int item = 0; item < 12; ++item) { + _roomTable[i].itemsTable[item] = 0xFF; + _roomTable[i].itemsXPos[item] = 0xFFFF; + _roomTable[i].itemsYPos[item] = 0xFF; + _roomTable[i].needInit[item] = 0; + } + } + + loadCharacterShapes(); + loadSpecialEffectShapes(); + loadItems(); + loadButtonShapes(); + initMainButtonList(); + loadMainScreen(); + _screen->loadPalette("PALETTE.COL", _screen->_currentPalette); + + // XXX + _animator->initAnimStateList(); + setCharactersInDefaultScene(); + + if (!_emc->load("_STARTUP.EMC", &_npcScriptData, &_opcodes)) + error("Could not load \"_STARTUP.EMC\" script"); + _emc->init(&_scriptMain, &_npcScriptData); + + if (!_emc->start(&_scriptMain, 0)) + error("Could not start script function 0 of script \"_STARTUP.EMC\""); + + while (_emc->isValid(&_scriptMain)) + _emc->run(&_scriptMain); + + _emc->unload(&_npcScriptData); + + if (!_emc->load("_NPC.EMC", &_npcScriptData, &_opcodes)) + error("Could not load \"_NPC.EMC\" script"); + + snd_playTheme(1, -1); + if (_gameToLoad == -1) { + enterNewScene(_currentCharacter->sceneId, _currentCharacter->facing, 0, 0, 1); + if (_abortIntroFlag && _skipIntroFlag) { + _menuDirectlyToLoad = true; + _screen->setMouseCursor(1, 1, _shapes[0]); + _screen->showMouse(); + _gui->buttonMenuCallback(0); + _menuDirectlyToLoad = false; + } else + saveGame(getSavegameFilename(0), "New game"); + } else { + _screen->setFont(Screen::FID_8_FNT); + loadGame(getSavegameFilename(_gameToLoad)); + _gameToLoad = -1; + } +} + +void KyraEngine_LoK::mainLoop() { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::mainLoop()"); + + while (!_quitFlag) { + int32 frameTime = (int32)_system->getMillis(); + _skipFlag = false; + + if (_currentCharacter->sceneId == 210) { + updateKyragemFading(); + if (seq_playEnd() && _deathHandler != 8) + break; + } + + if (_deathHandler != -1) { + snd_playWanderScoreViaMap(0, 1); + snd_playSoundEffect(49); + _screen->hideMouse(); + _screen->setMouseCursor(1, 1, _shapes[0]); + removeHandItem(); + _screen->showMouse(); + _gui->buttonMenuCallback(0); + _deathHandler = -1; + } + + if ((_brandonStatusBit & 2) && _brandonStatusBit0x02Flag) + _animator->animRefreshNPC(0); + + if ((_brandonStatusBit & 0x20) && _brandonStatusBit0x20Flag) { + _animator->animRefreshNPC(0); + _brandonStatusBit0x20Flag = 0; + } + + _screen->showMouse(); + + _gui->processButtonList(_buttonList, 0, 0); + updateMousePointer(); + _timer->update(); + updateTextFade(); + + _handleInput = true; + delay((frameTime + _gameSpeed) - _system->getMillis(), true, true); + _handleInput = false; + + _sound->process(); + } +} + +void KyraEngine_LoK::delayUntil(uint32 timestamp, bool updateTimers, bool update, bool isMainLoop) { + while (_system->getMillis() < timestamp && !_quitFlag) { + if (updateTimers) + _timer->update(); + + if (timestamp - _system->getMillis() >= 10) + delay(10, update, isMainLoop); + } +} + +void KyraEngine_LoK::delay(uint32 amount, bool update, bool isMainLoop) { + Common::Event event; + + uint32 start = _system->getMillis(); + do { + while (_eventMan->pollEvent(event)) { + switch (event.type) { + case Common::EVENT_KEYDOWN: + if (event.kbd.keycode >= '1' && event.kbd.keycode <= '9' && + (event.kbd.flags == Common::KBD_CTRL || event.kbd.flags == Common::KBD_ALT) && isMainLoop) { + const char *saveLoadSlot = getSavegameFilename(9 - (event.kbd.keycode - '0') + 990); + + if (event.kbd.flags == Common::KBD_CTRL) + loadGame(saveLoadSlot); + else { + char savegameName[14]; + sprintf(savegameName, "Quicksave %d", event.kbd.keycode - '0'); + saveGame(saveLoadSlot, savegameName); + } + } else if (event.kbd.flags == Common::KBD_CTRL) { + if (event.kbd.keycode == 'd') + _debugger->attach(); + else if (event.kbd.keycode == 'q') + _quitFlag = true; + } else if (event.kbd.keycode == '.') { + _skipFlag = true; + } else if (event.kbd.keycode == Common::KEYCODE_RETURN || event.kbd.keycode == Common::KEYCODE_SPACE || event.kbd.keycode == Common::KEYCODE_ESCAPE) { + _abortIntroFlag = true; + _skipFlag = true; + } + + break; + case Common::EVENT_MOUSEMOVE: + _animator->_updateScreen = true; + break; + case Common::EVENT_QUIT: + quitGame(); + break; + case Common::EVENT_LBUTTONDOWN: + _mousePressFlag = true; + break; + case Common::EVENT_LBUTTONUP: + _mousePressFlag = false; + + if (_abortWalkFlag2) + _abortWalkFlag = true; + + if (_handleInput) { + _handleInput = false; + processInput(); + _handleInput = true; + } else + _skipFlag = true; + + break; + default: + break; + } + } + + if (_debugger->isAttached()) + _debugger->onFrame(); + + if (update) { + _sprites->updateSceneAnims(); + _animator->updateAllObjectShapes(); + updateTextFade(); + updateMousePointer(); + } + + if (_currentCharacter && _currentCharacter->sceneId == 210 && update) + updateKyragemFading(); + + if (_skipFlag && !_abortIntroFlag && !queryGameFlag(0xFE)) + _skipFlag = false; + + if (amount > 0 && !_skipFlag && !_quitFlag) + _system->delayMillis(10); + + if (_skipFlag) + _sound->voiceStop(); + } while (!_skipFlag && _system->getMillis() < start + amount && !_quitFlag); +} + +void KyraEngine_LoK::waitForEvent() { + bool finished = false; + Common::Event event; + + while (!finished && !_quitFlag) { + while (_eventMan->pollEvent(event)) { + switch (event.type) { + case Common::EVENT_KEYDOWN: + finished = true; + break; + case Common::EVENT_QUIT: + quitGame(); + break; + case Common::EVENT_LBUTTONDOWN: + finished = true; + _skipFlag = true; + break; + default: + break; + } + } + + if (_debugger->isAttached()) + _debugger->onFrame(); + + _system->delayMillis(10); + } +} + +void KyraEngine_LoK::delayWithTicks(int ticks) { + uint32 nextTime = _system->getMillis() + ticks * _tickLength; + + while (_system->getMillis() < nextTime) { + _sprites->updateSceneAnims(); + _animator->updateAllObjectShapes(); + + if (_currentCharacter->sceneId == 210) { + updateKyragemFading(); + seq_playEnd(); + } + + if (_skipFlag) + break; + + if (nextTime - _system->getMillis() >= 10) + delay(10); + } +} + +#pragma mark - +#pragma mark - Animation/shape specific code +#pragma mark - + +void KyraEngine_LoK::setupShapes123(const Shape *shapeTable, int endShape, int flags) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::setupShapes123(%p, %d, %d)", (const void *)shapeTable, endShape, flags); + + for (int i = 123; i <= 172; ++i) + _shapes[i] = 0; + + uint8 curImage = 0xFF; + int curPageBackUp = _screen->_curPage; + _screen->_curPage = 8; // we are using page 8 here in the original page 2 was backuped and then used for this stuff + int shapeFlags = 2; + if (flags) + shapeFlags = 3; + for (int i = 123; i < 123+endShape; ++i) { + uint8 newImage = shapeTable[i-123].imageIndex; + if (newImage != curImage && newImage != 0xFF) { + assert(_characterImageTable); + _screen->loadBitmap(_characterImageTable[newImage], 8, 8, 0); + curImage = newImage; + } + _shapes[i] = _screen->encodeShape(shapeTable[i-123].x<<3, shapeTable[i-123].y, shapeTable[i-123].w<<3, shapeTable[i-123].h, shapeFlags); + assert(i-7 < _defaultShapeTableSize); + _defaultShapeTable[i-7].xOffset = shapeTable[i-123].xOffset; + _defaultShapeTable[i-7].yOffset = shapeTable[i-123].yOffset; + _defaultShapeTable[i-7].w = shapeTable[i-123].w; + _defaultShapeTable[i-7].h = shapeTable[i-123].h; + } + _screen->_curPage = curPageBackUp; +} + +void KyraEngine_LoK::freeShapes123() { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::freeShapes123()"); + + for (int i = 123; i <= 172; ++i) { + delete[] _shapes[i]; + _shapes[i] = 0; + } +} + +#pragma mark - +#pragma mark - Misc stuff +#pragma mark - + +Movie *KyraEngine_LoK::createWSAMovie() { + if (_flags.platform == Common::kPlatformAmiga) + return new WSAMovieAmiga(this); + + return new WSAMovie_v1(this); +} + +void KyraEngine_LoK::setBrandonPoisonFlags(int reset) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::setBrandonPoisonFlags(%d)", reset); + _brandonStatusBit |= 1; + + if (reset) + _poisonDeathCounter = 0; + + for (int i = 0; i < 0x100; ++i) + _brandonPoisonFlagsGFX[i] = i; + + _brandonPoisonFlagsGFX[0x99] = 0x34; + _brandonPoisonFlagsGFX[0x9A] = 0x35; + _brandonPoisonFlagsGFX[0x9B] = 0x37; + _brandonPoisonFlagsGFX[0x9C] = 0x38; + _brandonPoisonFlagsGFX[0x9D] = 0x2B; +} + +void KyraEngine_LoK::resetBrandonPoisonFlags() { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::resetBrandonPoisonFlags()"); + _brandonStatusBit = 0; + + for (int i = 0; i < 0x100; ++i) + _brandonPoisonFlagsGFX[i] = i; +} + +#pragma mark - +#pragma mark - Input +#pragma mark - + +void KyraEngine_LoK::processInput() { + Common::Point mouse = getMousePos(); + int xpos = mouse.x; + int ypos = mouse.y; + + debugC(9, kDebugLevelMain, "KyraEngine_LoK::processInput(%d, %d)", xpos, ypos); + _abortWalkFlag2 = false; + + if (processInputHelper(xpos, ypos)) + return; + + uint8 item = findItemAtPos(xpos, ypos); + if (item == 0xFF) { + _changedScene = false; + int handled = clickEventHandler(xpos, ypos); + if (_changedScene || handled) + return; + } + + // XXX _deathHandler specific + if (ypos <= 158) { + uint16 exit = 0xFFFF; + if (xpos < 12) { + exit = _walkBlockWest; + } else if (xpos >= 308) { + exit = _walkBlockEast; + } else if (ypos >= 136) { + exit = _walkBlockSouth; + } else if (ypos < 12) { + exit = _walkBlockNorth; + } + + if (exit != 0xFFFF) { + _abortWalkFlag2 = true; + handleSceneChange(xpos, ypos, 1, 1); + _abortWalkFlag2 = false; + return; + } else { + int script = checkForNPCScriptRun(xpos, ypos); + if (script >= 0) { + runNpcScript(script); + return; + } + if (_itemInHand != -1) { + if (ypos < 155) { + if (hasClickedOnExit(xpos, ypos)) { + _abortWalkFlag2 = true; + handleSceneChange(xpos, ypos, 1, 1); + _abortWalkFlag2 = false; + return; + } + dropItem(0, _itemInHand, xpos, ypos, 1); + } + } else { + if (ypos <= 155) { + _abortWalkFlag2 = true; + handleSceneChange(xpos, ypos, 1, 1); + _abortWalkFlag2 = false; + } + } + } + } +} + +int KyraEngine_LoK::processInputHelper(int xpos, int ypos) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::processInputHelper(%d, %d)", xpos, ypos); + uint8 item = findItemAtPos(xpos, ypos); + if (item != 0xFF) { + if (_itemInHand == -1) { + _screen->hideMouse(); + _animator->animRemoveGameItem(item); + snd_playSoundEffect(53); + assert(_currentCharacter->sceneId < _roomTableSize); + Room *currentRoom = &_roomTable[_currentCharacter->sceneId]; + int item2 = currentRoom->itemsTable[item]; + currentRoom->itemsTable[item] = 0xFF; + setMouseItem(item2); + assert(_itemList && _takenList); + updateSentenceCommand(_itemList[item2], _takenList[0], 179); + _itemInHand = item2; + _screen->showMouse(); + clickEventHandler2(); + return 1; + } else { + exchangeItemWithMouseItem(_currentCharacter->sceneId, item); + return 1; + } + } + return 0; +} + +int KyraEngine_LoK::clickEventHandler(int xpos, int ypos) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::clickEventHandler(%d, %d)", xpos, ypos); + _emc->init(&_scriptClick, &_scriptClickData); + _scriptClick.regs[1] = xpos; + _scriptClick.regs[2] = ypos; + _scriptClick.regs[3] = 0; + _scriptClick.regs[4] = _itemInHand; + _emc->start(&_scriptClick, 1); + + while (_emc->isValid(&_scriptClick)) + _emc->run(&_scriptClick); + + return _scriptClick.regs[3]; +} + +void KyraEngine_LoK::updateMousePointer(bool forceUpdate) { + int shape = 0; + + int newMouseState = 0; + int newX = 0; + int newY = 0; + Common::Point mouse = getMousePos(); + if (mouse.y <= 158) { + if (mouse.x >= 12) { + if (mouse.x >= 308) { + if (_walkBlockEast == 0xFFFF) { + newMouseState = -2; + } else { + newMouseState = -5; + shape = 3; + newX = 7; + newY = 5; + } + } else if (mouse.y >= 136) { + if (_walkBlockSouth == 0xFFFF) { + newMouseState = -2; + } else { + newMouseState = -4; + shape = 4; + newX = 5; + newY = 7; + } + } else if (mouse.y < 12) { + if (_walkBlockNorth == 0xFFFF) { + newMouseState = -2; + } else { + newMouseState = -6; + shape = 2; + newX = 5; + newY = 1; + } + } + } else { + if (_walkBlockWest == 0xFFFF) { + newMouseState = -2; + } else { + newMouseState = -3; + newX = 1; + newY = shape = 5; + } + } + } + + if (mouse.x >= _entranceMouseCursorTracks[0] && mouse.y >= _entranceMouseCursorTracks[1] + && mouse.x <= _entranceMouseCursorTracks[2] && mouse.y <= _entranceMouseCursorTracks[3]) { + switch (_entranceMouseCursorTracks[4]) { + case 0: + newMouseState = -6; + shape = 2; + newX = 5; + newY = 1; + break; + + case 2: + newMouseState = -5; + shape = 3; + newX = 7; + newY = 5; + break; + + case 4: + newMouseState = -4; + shape = 4; + newX = 5; + newY = 7; + break; + + case 6: + newMouseState = -3; + shape = 5; + newX = 1; + newY = 5; + break; + + default: + break; + } + } + + if (newMouseState == -2) { + shape = 6; + newX = 4; + newY = 4; + } + + if ((newMouseState && _mouseState != newMouseState) || (newMouseState && forceUpdate)) { + _mouseState = newMouseState; + _screen->hideMouse(); + _screen->setMouseCursor(newX, newY, _shapes[shape]); + _screen->showMouse(); + } + + if (!newMouseState) { + if (_mouseState != _itemInHand || forceUpdate) { + if (mouse.y > 158 || (mouse.x >= 12 && mouse.x < 308 && mouse.y < 136 && mouse.y >= 12) || forceUpdate) { + _mouseState = _itemInHand; + _screen->hideMouse(); + if (_itemInHand == -1) + _screen->setMouseCursor(1, 1, _shapes[0]); + else + _screen->setMouseCursor(8, 15, _shapes[216+_itemInHand]); + _screen->showMouse(); + } + } + } +} + +bool KyraEngine_LoK::hasClickedOnExit(int xpos, int ypos) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::hasClickedOnExit(%d, %d)", xpos, ypos); + if (xpos < 16 || xpos >= 304) + return true; + + if (ypos < 8) + return true; + + if (ypos < 136 || ypos > 155) + return false; + + return true; +} + +void KyraEngine_LoK::clickEventHandler2() { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::clickEventHandler2()"); + + Common::Point mouse = getMousePos(); + + _emc->init(&_scriptClick, &_scriptClickData); + _scriptClick.regs[0] = _currentCharacter->sceneId; + _scriptClick.regs[1] = mouse.x; + _scriptClick.regs[2] = mouse.y; + _scriptClick.regs[4] = _itemInHand; + _emc->start(&_scriptClick, 6); + + while (_emc->isValid(&_scriptClick)) + _emc->run(&_scriptClick); +} + +int KyraEngine_LoK::checkForNPCScriptRun(int xpos, int ypos) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::checkForNPCScriptRun(%d, %d)", xpos, ypos); + int returnValue = -1; + const Character *currentChar = _currentCharacter; + int charLeft = 0, charRight = 0, charTop = 0, charBottom = 0; + + int scaleFactor = _scaleTable[currentChar->y1]; + int addX = (((scaleFactor*8)*3)>>8)>>1; + int addY = ((scaleFactor*3)<<4)>>8; + + charLeft = currentChar->x1 - addX; + charRight = currentChar->x1 + addX; + charTop = currentChar->y1 - addY; + charBottom = currentChar->y1; + + if (xpos >= charLeft && charRight >= xpos && charTop <= ypos && charBottom >= ypos) + return 0; + + if (xpos > 304 || xpos < 16) + return -1; + + for (int i = 1; i < 5; ++i) { + currentChar = &_characterList[i]; + + if (currentChar->sceneId != _currentCharacter->sceneId) + continue; + + charLeft = currentChar->x1 - 12; + charRight = currentChar->x1 + 11; + charTop = currentChar->y1 - 48; + // if (!i) + // charBottom = currentChar->y2 - 16; + // else + charBottom = currentChar->y1; + + if (xpos < charLeft || xpos > charRight || ypos < charTop || charBottom < ypos) + continue; + + if (returnValue != -1) { + if (currentChar->y1 >= _characterList[returnValue].y1) + returnValue = i; + } else { + returnValue = i; + } + } + + return returnValue; +} + +void KyraEngine_LoK::runNpcScript(int func) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::runNpcScript(%d)", func); + _emc->init(&_npcScript, &_npcScriptData); + _emc->start(&_npcScript, func); + _npcScript.regs[0] = _currentCharacter->sceneId; + _npcScript.regs[4] = _itemInHand; + _npcScript.regs[5] = func; + + while (_emc->isValid(&_npcScript)) + _emc->run(&_npcScript); +} + +void KyraEngine_LoK::checkAmuletAnimFlags() { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::checkSpecialAnimFlags()"); + + if (_brandonStatusBit & 2) { + seq_makeBrandonNormal2(); + _timer->setCountdown(19, 300); + } + + if (_brandonStatusBit & 0x20) { + seq_makeBrandonNormal(); + _timer->setCountdown(19, 300); + } +} + +#pragma mark - + +void KyraEngine_LoK::registerDefaultSettings() { + KyraEngine_v1::registerDefaultSettings(); + + // Most settings already have sensible defaults. This one, however, is + // specific to the Kyra engine. + ConfMan.registerDefault("walkspeed", 2); +} + +void KyraEngine_LoK::readSettings() { + int talkspeed = ConfMan.getInt("talkspeed"); + + // The default talk speed is 60. This should be mapped to "Normal". + + if (talkspeed == 0) + _configTextspeed = 3; // Clickable + if (talkspeed <= 50) + _configTextspeed = 0; // Slow + else if (talkspeed <= 150) + _configTextspeed = 1; // Normal + else + _configTextspeed = 2; // Fast + + KyraEngine_v1::readSettings(); +} + +void KyraEngine_LoK::writeSettings() { + int talkspeed; + + switch (_configTextspeed) { + case 0: // Slow + talkspeed = 1; + break; + case 1: // Normal + talkspeed = 60; + break; + case 2: // Fast + talkspeed = 255; + break; + default: // Clickable + talkspeed = 0; + break; + } + + ConfMan.setInt("talkspeed", talkspeed); + + KyraEngine_v1::writeSettings(); +} + +} // end of namespace Kyra diff --git a/engines/kyra/kyra_lok.h b/engines/kyra/kyra_lok.h new file mode 100644 index 0000000000..cb3062847e --- /dev/null +++ b/engines/kyra/kyra_lok.h @@ -0,0 +1,806 @@ +/* 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_LOK_H +#define KYRA_KYRA_LOK_H + +#include "kyra/kyra_v1.h" +#include "kyra/script.h" +#include "kyra/screen_lok.h" +#include "kyra/gui_lok.h" + +namespace Kyra { + +class Movie; +class SoundDigital; +class SeqPlayer; +class Sprites; +class Animator_LoK; +class TextDisplayer; +class KyraEngine_LoK; + +struct Character { + uint16 sceneId; + uint8 height; + uint8 facing; + uint16 currentAnimFrame; + uint8 inventoryItems[10]; + int16 x1, y1, x2, y2; +}; + +struct Shape { + uint8 imageIndex; + int8 xOffset, yOffset; + uint8 x, y, w, h; +}; + +struct Room { + uint8 nameIndex; + uint16 northExit; + uint16 eastExit; + uint16 southExit; + uint16 westExit; + uint8 itemsTable[12]; + uint16 itemsXPos[12]; + uint8 itemsYPos[12]; + uint8 needInit[12]; +}; + +struct Item { + uint8 unk1; + uint8 height; + uint8 unk2; + uint8 unk3; +}; + +struct SeqLoop { + const uint8 *ptr; + uint16 count; +}; + +struct SceneExits { + uint16 northXPos; + uint8 northYPos; + uint16 eastXPos; + uint8 eastYPos; + uint16 southXPos; + uint8 southYPos; + uint16 westXPos; + uint8 westYPos; +}; + +struct BeadState { + int16 x; + int16 y; + int16 width; + int16 height; + int16 dstX; + int16 dstY; + int16 width2; + int16 unk8; + int16 unk9; + int16 tableIndex; +}; + +class KyraEngine_LoK : public KyraEngine_v1 { + friend class MusicPlayer; + friend class Debugger_LoK; + friend class Animator_LoK; + friend class GUI_LoK; +public: + KyraEngine_LoK(OSystem *system, const GameFlags &flags); + ~KyraEngine_LoK(); + + //TODO: proper extended implementation of KyraEngine_v1::pauseEngineIntern. + // _sprites and _seqplayer should be paused here too, to avoid some animation glitches, + // also parts of the hardcoded Malcolm fight might need some special handling. + + Screen *screen() { return _screen; } + Animator_LoK *animator() { return _animator; } + virtual Movie *createWSAMovie(); + + uint8 **shapes() { return _shapes; } + Character *currentCharacter() { return _currentCharacter; } + Character *characterList() { return _characterList; } + uint16 brandonStatus() { return _brandonStatusBit; } + + // TODO: remove me with workaround in animator.cpp l209 + uint16 getScene() { return _currentRoom; } + + int _paletteChanged; + int16 _northExitHeight; + + typedef void (KyraEngine_LoK::*IntroProc)(); + + // static data access + const char * const*seqWSATable() { return _seq_WSATable; } + const char * const*seqCPSTable() { return _seq_CPSTable; } + const char * const*seqCOLTable() { return _seq_COLTable; } + const char * const*seqTextsTable() { return _seq_textsTable; } + + const uint8 * const*palTable1() { return &_specialPalettes[0]; } + const uint8 * const*palTable2() { return &_specialPalettes[29]; } + +protected: + virtual int go(); + virtual int init(); + +public: + // sequences + // -> misc + bool seq_skipSequence() const; +protected: + // -> demo + void seq_demo(); + + // -> intro + void seq_intro(); + void seq_introLogos(); + void seq_introStory(); + void seq_introMalcolmTree(); + void seq_introKallakWriting(); + void seq_introKallakMalcolm(); + + // -> ingame animations + void seq_createAmuletJewel(int jewel, int page, int noSound, int drawOnly); + void seq_brandonHealing(); + void seq_brandonHealing2(); + void seq_poisonDeathNow(int now); + void seq_poisonDeathNowAnim(); + void seq_playFluteAnimation(); + void seq_winterScroll1(); + void seq_winterScroll2(); + void seq_makeBrandonInv(); + void seq_makeBrandonNormal(); + void seq_makeBrandonNormal2(); + void seq_makeBrandonWisp(); + void seq_dispelMagicAnimation(); + void seq_fillFlaskWithWater(int item, int type); + void seq_playDrinkPotionAnim(int item, int unk2, int flags); + void seq_brandonToStone(); + + // -> end fight + int seq_playEnd(); + void seq_playEnding(); + + int handleMalcolmFlag(); + int handleBeadState(); + void initBeadState(int x, int y, int x2, int y2, int unk1, BeadState *ptr); + int processBead(int x, int y, int &x2, int &y2, BeadState *ptr); + + // -> credits + void seq_playCredits(); + +public: + // delay + void delayUntil(uint32 timestamp, bool updateGameTimers = false, bool update = false, bool isMainLoop = false); + void delay(uint32 millis, bool update = false, bool isMainLoop = false); + void delayWithTicks(int ticks); + void waitForEvent(); + + // TODO + void registerDefaultSettings(); + void readSettings(); + void writeSettings(); + + void snd_playSoundEffect(int track, int volume=0xFF); + void snd_playWanderScoreViaMap(int command, int restart); + virtual void snd_playVoiceFile(int id); + void snd_voiceWaitForFinish(bool ingame = true); + uint32 snd_getVoicePlayTime(); + +protected: + int32 _speechPlayTime; + + void saveGame(const char *fileName, const char *saveName); + void loadGame(const char *fileName); + +protected: + // input + void processInput(); + int processInputHelper(int xpos, int ypos); + int clickEventHandler(int xpos, int ypos); + void clickEventHandler2(); + void updateMousePointer(bool forceUpdate = false); + bool hasClickedOnExit(int xpos, int ypos); + + bool _skipFlag; + bool skipFlag() const { return _skipFlag; } + void resetSkipFlag(bool removeEvent = true) { _skipFlag = false; } + + // scene + // -> init + void loadSceneMsc(); + void startSceneScript(int brandonAlive); + void setupSceneItems(); + void initSceneData(int facing, int unk1, int brandonAlive); + void initSceneObjectList(int brandonAlive); + void initSceneScreen(int brandonAlive); + void setupSceneResource(int sceneId); + + // -> process + void enterNewScene(int sceneId, int facing, int unk1, int unk2, int brandonAlive); + int handleSceneChange(int xpos, int ypos, int unk1, int frameReset); + int processSceneChange(int *table, int unk1, int frameReset); + int changeScene(int facing); + + // -> modification + void transcendScenes(int roomIndex, int roomName); + void setSceneFile(int roomIndex, int roomName); + + // -> pathfinder + int findWay(int x, int y, int toX, int toY, int *moveTable, int moveTableSize); + bool lineIsPassable(int x, int y); + + // -> item handling + // --> misc + void addItemToRoom(uint16 sceneId, uint8 item, int itemIndex, int x, int y); + + // --> drop handling + void itemDropDown(int x, int y, int destX, int destY, byte freeItem, int item); + int processItemDrop(uint16 sceneId, uint8 item, int x, int y, int unk1, int unk2); + void dropItem(int unk1, int item, int x, int y, int unk2); + + // --> dropped item handling + int countItemsInScene(uint16 sceneId); + void exchangeItemWithMouseItem(uint16 sceneId, int itemIndex); + byte findFreeItemInScene(int scene); + byte findItemAtPos(int x, int y); + + // --> drop area handling + void addToNoDropRects(int x, int y, int w, int h); + void clearNoDropRects(); + int isDropable(int x, int y); + int checkNoDropRects(int x, int y); + + // --> player items handling + void updatePlayerItemsForScene(); + + // --> item GFX handling + void backUpItemRect0(int xpos, int ypos); + void restoreItemRect0(int xpos, int ypos); + void backUpItemRect1(int xpos, int ypos); + void restoreItemRect1(int xpos, int ypos); + + // items + // -> misc + void placeItemInGenericMapScene(int item, int index); + + // -> mouse item + void setHandItem(uint16 item); + void removeHandItem(); + void setMouseItem(uint16 item); + + // -> graphics effects + void wipeDownMouseItem(int xpos, int ypos); + void itemSpecialFX(int x, int y, int item); + void itemSpecialFX1(int x, int y, int item); + void itemSpecialFX2(int x, int y, int item); + void magicOutMouseItem(int animIndex, int itemPos); + void magicInMouseItem(int animIndex, int item, int itemPos); + void specialMouseItemFX(int shape, int x, int y, int animIndex, int tableIndex, int loopStart, int maxLoops); + void processSpecialMouseItemFX(int shape, int x, int y, int tableValue, int loopStart, int maxLoops); + + // character + // -> movement + void moveCharacterToPos(int character, int facing, int xpos, int ypos); + void setCharacterPositionWithUpdate(int character); + int setCharacterPosition(int character, int *facingTable); + void setCharacterPositionHelper(int character, int *facingTable); + void setCharactersPositions(int character); + + // -> brandon + void setBrandonPoisonFlags(int reset); + void resetBrandonPoisonFlags(); + + // chat + // -> process + void characterSays(int vocFile, const char *chatStr, int8 charNum, int8 chatDuration); + void waitForChatToFinish(int vocFile, int16 chatDuration, const char *str, uint8 charNum); + + // -> initialization + int initCharacterChat(int8 charNum); + void backupChatPartnerAnimFrame(int8 charNum); + void restoreChatPartnerAnimFrame(int8 charNum); + int8 getChatPartnerNum(); + + // -> deinitialization + void endCharacterChat(int8 charNum, int16 arg_4); + + // graphics + // -> misc + int findDuplicateItemShape(int shape); + void updateKyragemFading(); + + // -> interface + void loadMainScreen(int page = 3); + void redrawInventory(int page); +public: + void drawSentenceCommand(const char *sentence, int unk1); + void updateSentenceCommand(const char *str1, const char *str2, int unk1); + void updateTextFade(); + +protected: + // -> amulet + void drawJewelPress(int jewel, int drawSpecial); + void drawJewelsFadeOutStart(); + void drawJewelsFadeOutEnd(int jewel); + + // -> shape handling + void setupShapes123(const Shape *shapeTable, int endShape, int flags); + void freeShapes123(); + + // misc (TODO) + void startup(); + void mainLoop(); + + int checkForNPCScriptRun(int xpos, int ypos); + void runNpcScript(int func); + + void loadMouseShapes(); + void loadCharacterShapes(); + void loadSpecialEffectShapes(); + void loadItems(); + void loadButtonShapes(); + void initMainButtonList(); + void setCharactersInDefaultScene(); + void setupPanPages(); + void freePanPages(); + void closeFinalWsa(); + + //void setTimer19(); + void setupTimers(); + void timerUpdateHeadAnims(int timerNum); + void timerSetFlags1(int timerNum); + void timerSetFlags2(int timerNum); + void timerSetFlags3(int timerNum); + void timerCheckAnimFlag1(int timerNum); + void timerCheckAnimFlag2(int timerNum); + void checkAmuletAnimFlags(); + void timerRedrawAmulet(int timerNum); + void timerFadeText(int timerNum); + void updateAnimFlag1(int timerNum); + void updateAnimFlag2(int timerNum); + void drawAmulet(); + void setTextFadeTimerCountdown(int16 countdown); + void setWalkspeed(uint8 newSpeed); + + int buttonInventoryCallback(Button *caller); + int buttonAmuletCallback(Button *caller); + + bool _skipIntroFlag; + bool _abortIntroFlag; + bool _menuDirectlyToLoad; + bool _abortWalkFlag; + bool _abortWalkFlag2; + bool _mousePressFlag; + uint8 *_itemBkgBackUp[2]; + uint8 *_shapes[373]; + int8 _itemInHand; + bool _handleInput; + bool _changedScene; + int _unkScreenVar1, _unkScreenVar2, _unkScreenVar3; + int _beadStateVar; + int _unkAmuletVar; + + int _malcolmFlag; + int _endSequenceSkipFlag; + int _endSequenceNeedLoading; + int _unkEndSeqVar2; + uint8 *_endSequenceBackUpRect; + int _unkEndSeqVar4; + int _unkEndSeqVar5; + int _lastDisplayedPanPage; + uint8 *_panPagesTable[20]; + Movie *_finalA, *_finalB, *_finalC; + + Movie *_movieObjects[10]; + + uint16 _entranceMouseCursorTracks[8]; + uint16 _walkBlockNorth; + uint16 _walkBlockEast; + uint16 _walkBlockSouth; + uint16 _walkBlockWest; + + int32 _scaleMode; + int16 _scaleTable[145]; + + Rect _noDropRects[11]; + + int8 _birthstoneGemTable[4]; + int8 _idolGemsTable[3]; + + int8 _marbleVaseItem; + int8 _foyerItemTable[3]; + + int8 _cauldronState; + int8 _crystalState[2]; + + uint16 _brandonStatusBit; + uint8 _brandonStatusBit0x02Flag; + uint8 _brandonStatusBit0x20Flag; + uint8 _brandonPoisonFlagsGFX[256]; + int16 _brandonInvFlag; + uint8 _poisonDeathCounter; + int _brandonPosX; + int _brandonPosY; + + uint16 _currentChatPartnerBackupFrame; + uint16 _currentCharAnimFrame; + + int8 *_sceneAnimTable[50]; + + Item _itemTable[145]; + int _lastProcessedItem; + int _lastProcessedItemHeight; + + int16 *_exitListPtr; + int16 _exitList[11]; + SceneExits _sceneExits; + uint16 _currentRoom; + int _scenePhasingFlag; + + int _sceneChangeState; + int _loopFlag2; + + int _pathfinderFlag; + int _pathfinderFlag2; + int _lastFindWayRet; + int *_movFacingTable; + + int8 _talkingCharNum; + int8 _charSayUnk2; + int8 _charSayUnk3; + int8 _currHeadShape; + uint8 _currSentenceColor[3]; + int8 _startSentencePalIndex; + bool _fadeText; + + uint8 _configTextspeed; + + Animator_LoK *_animator; + SeqPlayer *_seq; + Sprites *_sprites; + Screen_LoK *_screen; + + EMCState _scriptMain; + + EMCState _npcScript; + EMCData _npcScriptData; + + EMCState _scriptClick; + EMCData _scriptClickData; + + Character *_characterList; + Character *_currentCharacter; + + Button *_buttonList; + GUI_LoK *_gui; + + struct KyragemState { + uint16 nextOperation; + uint16 rOffset; + uint16 gOffset; + uint16 bOffset; + uint32 timerCount; + } _kyragemFadingState; + + static const int8 _dosTrackMap[]; + static const int _dosTrackMapSize; + + // TODO: get rid of all variables having pointers to the static resources if possible + // i.e. let them directly use the _staticres functions + void initStaticResource(); + + const uint8 *_seq_Forest; + const uint8 *_seq_KallakWriting; + const uint8 *_seq_KyrandiaLogo; + const uint8 *_seq_KallakMalcolm; + const uint8 *_seq_MalcolmTree; + const uint8 *_seq_WestwoodLogo; + const uint8 *_seq_Demo1; + const uint8 *_seq_Demo2; + const uint8 *_seq_Demo3; + const uint8 *_seq_Demo4; + const uint8 *_seq_Reunion; + + const char * const*_seq_WSATable; + const char * const*_seq_CPSTable; + const char * const*_seq_COLTable; + const char * const*_seq_textsTable; + + int _seq_WSATable_Size; + int _seq_CPSTable_Size; + int _seq_COLTable_Size; + int _seq_textsTable_Size; + + const char * const*_itemList; + const char * const*_takenList; + const char * const*_placedList; + const char * const*_droppedList; + const char * const*_noDropList; + const char * const*_putDownFirst; + const char * const*_waitForAmulet; + const char * const*_blackJewel; + const char * const*_poisonGone; + const char * const*_healingTip; + const char * const*_thePoison; + const char * const*_fluteString; + const char * const*_wispJewelStrings; + const char * const*_magicJewelString; + const char * const*_flaskFull; + const char * const*_fullFlask; + const char * const*_veryClever; + const char * const*_homeString; + const char * const*_newGameString; + + int _itemList_Size; + int _takenList_Size; + int _placedList_Size; + int _droppedList_Size; + int _noDropList_Size; + int _putDownFirst_Size; + int _waitForAmulet_Size; + int _blackJewel_Size; + int _poisonGone_Size; + int _healingTip_Size; + int _thePoison_Size; + int _fluteString_Size; + int _wispJewelStrings_Size; + int _magicJewelString_Size; + int _flaskFull_Size; + int _fullFlask_Size; + int _veryClever_Size; + int _homeString_Size; + int _newGameString_Size; + + const char * const*_characterImageTable; + int _characterImageTableSize; + + const char * const*_guiStrings; + int _guiStringsSize; + + const char * const*_configStrings; + int _configStringsSize; + + Shape *_defaultShapeTable; + int _defaultShapeTableSize; + + const Shape *_healingShapeTable; + int _healingShapeTableSize; + const Shape *_healingShape2Table; + int _healingShape2TableSize; + + const Shape *_posionDeathShapeTable; + int _posionDeathShapeTableSize; + + const Shape *_fluteAnimShapeTable; + int _fluteAnimShapeTableSize; + + const Shape *_winterScrollTable; + int _winterScrollTableSize; + const Shape *_winterScroll1Table; + int _winterScroll1TableSize; + const Shape *_winterScroll2Table; + int _winterScroll2TableSize; + + const Shape *_drinkAnimationTable; + int _drinkAnimationTableSize; + + const Shape *_brandonToWispTable; + int _brandonToWispTableSize; + + const Shape *_magicAnimationTable; + int _magicAnimationTableSize; + + const Shape *_brandonStoneTable; + int _brandonStoneTableSize; + + Room *_roomTable; + int _roomTableSize; + const char * const*_roomFilenameTable; + int _roomFilenameTableSize; + + const uint8 *_amuleteAnim; + + const uint8 * const*_specialPalettes; + + const char *const *_soundFiles; + int _soundFilesSize; + const char *const *_soundFilesIntro; + int _soundFilesIntroSize; + const int32 *_cdaTrackTable; + int _cdaTrackTableSize; + const AudioDataStruct * _soundData; + + // positions of the inventory + static const uint16 _itemPosX[]; + static const uint8 _itemPosY[]; + + void setupButtonData(); + Button *_buttonData; + Button **_buttonDataListPtr; + + static const uint8 _magicMouseItemStartFrame[]; + static const uint8 _magicMouseItemEndFrame[]; + static const uint8 _magicMouseItemStartFrame2[]; + static const uint8 _magicMouseItemEndFrame2[]; + + static const uint16 _amuletX[]; + static const uint16 _amuletY[]; + static const uint16 _amuletX2[]; + static const uint16 _amuletY2[]; +protected: + void setupOpcodeTable(); + + // Opcodes + int o1_magicInMouseItem(EMCState *script); + int o1_characterSays(EMCState *script); + int o1_delay(EMCState *script); + int o1_drawSceneAnimShape(EMCState *script); + int o1_runNPCScript(EMCState *script); + int o1_setSpecialExitList(EMCState *script); + int o1_walkPlayerToPoint(EMCState *script); + int o1_dropItemInScene(EMCState *script); + int o1_drawAnimShapeIntoScene(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_runSceneAnimUntilDone(EMCState *script); + int o1_fadeSpecialPalette(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_delaySecs(EMCState *script); + int o1_getCharacterScene(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_getCharacterX(EMCState *script); + int o1_getCharacterY(EMCState *script); + int o1_setCharacterFacing(EMCState *script); + int o1_copyWSARegion(EMCState *script); + int o1_printText(EMCState *script); + int o1_loadSoundFile(EMCState *script); + int o1_displayWSAFrameOnHidPage(EMCState *script); + int o1_displayWSASequentialFrames(EMCState *script); + int o1_refreshCharacter(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_setCharacterLocation(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_setCharacterMovementDelay(EMCState *script); + int o1_getCharacterFacing(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_setCharacterCurrentFrame(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_getCharacterMovementDelay(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_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_vocUnload(EMCState *script); + int o1_vocLoad(EMCState *script); + int o1_dummy(EMCState *script); +}; + +} // end of namespace Kyra + +#endif + diff --git a/engines/kyra/kyra_mr.cpp b/engines/kyra/kyra_mr.cpp index 61546fc2e7..8a49b8e155 100644 --- a/engines/kyra/kyra_mr.cpp +++ b/engines/kyra/kyra_mr.cpp @@ -23,7 +23,7 @@ * */ -#include "kyra/kyra.h" +#include "kyra/kyra_v1.h" #include "kyra/kyra_mr.h" #include "kyra/screen_mr.h" #include "kyra/wsamovie.h" @@ -50,13 +50,16 @@ const KyraEngine_v2::EngineDesc KyraEngine_MR::_mrEngineDesc = { 9, // Animation script specific - 9 + 9, + + // Item specific + 71 }; KyraEngine_MR::KyraEngine_MR(OSystem *system, const GameFlags &flags) : KyraEngine_v2(system, flags, _mrEngineDesc) { _soundDigital = 0; _musicSoundChannel = -1; - _menuAudioFile = "TITLE1.AUD"; + _menuAudioFile = "TITLE1"; _lastMusicCommand = -1; _itemBuffer1 = _itemBuffer2 = 0; _scoreFile = 0; @@ -71,13 +74,13 @@ KyraEngine_MR::KyraEngine_MR(OSystem *system, const GameFlags &flags) : KyraEngi _gfxBackUpRect = 0; _paletteOverlay = 0; _sceneList = 0; - memset(&_mainCharacter, 0, sizeof(_mainCharacter)); _mainCharacter.sceneId = 9; _mainCharacter.height = 0x4C; _mainCharacter.facing = 5; _mainCharacter.animFrame = 0x57; _mainCharacter.walkspeed = 5; - memset(_mainCharacter.inventory, -1, sizeof(_mainCharacter.inventory)); + memset(_activeItemAnim, 0, sizeof(_activeItemAnim)); + _nextAnimItem = 0; _text = 0; _commandLineY = 189; _inventoryState = false; @@ -96,7 +99,7 @@ KyraEngine_MR::KyraEngine_MR(OSystem *system, const GameFlags &flags) : KyraEngi _unk5 = 0; _unkSceneScreenFlag1 = false; _noScriptEnter = true; - _itemInHand = _handItemSet = -1; + _itemInHand = _mouseState = -1; _unk3 = -1; _unk4 = 0; _loadingState = false; @@ -140,6 +143,12 @@ KyraEngine_MR::KyraEngine_MR(OSystem *system, const GameFlags &flags) : KyraEngi _menuDirectlyToLoad = false; _optionsFile = 0; _actorFile = 0; + _chatAltFlag = false; + _albumChatActive = false; + memset(&_album, 0, sizeof(_album)); + _configHelium = false; + _fadeOutMusicChannel = -1; + memset(_scaleTable, 0, sizeof(_scaleTable)); } KyraEngine_MR::~KyraEngine_MR() { @@ -152,6 +161,7 @@ KyraEngine_MR::~KyraEngine_MR() { delete[] _cCodeFile; delete[] _scenesFile; delete[] _itemFile; + delete[] _actorFile; delete[] _gamePlayBuffer; delete[] _interface; delete[] _interfaceCommandLine; @@ -165,7 +175,6 @@ KyraEngine_MR::~KyraEngine_MR() { delete[] _gfxBackUpRect; delete[] _paletteOverlay; - delete[] _sceneList; for (ShapeMap::iterator i = _gameShapes.begin(); i != _gameShapes.end(); ++i) { delete[] i->_value; @@ -187,6 +196,10 @@ KyraEngine_MR::~KyraEngine_MR() { delete[] _mainButtonData; delete _gui; delete[] _optionsFile; + + delete _album.wsa; + delete _album.leftPage.wsa; + delete _album.rightPage.wsa; } int KyraEngine_MR::init() { @@ -194,7 +207,8 @@ int KyraEngine_MR::init() { assert(_screen); _screen->setResolution(); - KyraEngine::init(); + KyraEngine_v1::init(); + initStaticResource(); _debugger = new Debugger_v2(this); assert(_debugger); @@ -203,7 +217,7 @@ int KyraEngine_MR::init() { assert(_soundDigital); if (!_soundDigital->init()) error("_soundDigital->init() failed"); - KyraEngine::_text = _text = new TextDisplayer_MR(this, _screen); + KyraEngine_v1::_text = _text = new TextDisplayer_MR(this, _screen); assert(_text); _gui = new GUI_MR(this); assert(_gui); @@ -272,6 +286,8 @@ int KyraEngine_MR::go() { delayUntil(nextRun); } + _eventList.clear(); + switch (_menu->handle(3)) { case 2: _menuDirectlyToLoad = true; @@ -312,7 +328,7 @@ int KyraEngine_MR::go() { } void KyraEngine_MR::initMainMenu() { - _menuAnim = new WSAMovieV2(this, _screen); + _menuAnim = new WSAMovie_v2(this, _screen); _menuAnim->open("REVENGE.WSA", 1, _screen->getPalette(0)); _menuAnim->setX(0); _menuAnim->setY(0); @@ -354,7 +370,10 @@ void KyraEngine_MR::playVQA(const char *name) { snprintf(filename, sizeof(filename), "%s%d.VQA", name, size); if (vqa.open(filename)) { - _soundDigital->stopAllSounds(); + for (int i = 0; i < 4; ++i) { + if (i != _musicSoundChannel) + _soundDigital->stopSound(i); + } _screen->hideMouse(); memcpy(_screen->getPalette(1), _screen->getPalette(0), 768); @@ -386,14 +405,12 @@ void KyraEngine_MR::playMenuAudioFile() { if (_soundDigital->isPlaying(_musicSoundChannel)) return; - _musicSoundChannel = _soundDigital->playSound(_menuAudioFile, 0xFF, Audio::Mixer::kMusicSoundType); + _musicSoundChannel = _soundDigital->playSound(_menuAudioFile, 0xFF, Audio::Mixer::kMusicSoundType, 255, true); } void KyraEngine_MR::snd_playWanderScoreViaMap(int track, int force) { debugC(9, kDebugLevelMain, "KyraEngine_MR::snd_playWanderScoreViaMap(%d, %d)", track, force); - // XXX byte_3C87C compare - if (_musicSoundChannel != -1 && !_soundDigital->isPlaying(_musicSoundChannel)) force = 1; else if (_musicSoundChannel == -1) @@ -407,7 +424,9 @@ void KyraEngine_MR::snd_playWanderScoreViaMap(int track, int force) { if (_musicSoundChannel == -1) { assert(track < _soundListSize && track >= 0); - _musicSoundChannel = _soundDigital->playSound(_soundList[track], 0xFF, Audio::Mixer::kMusicSoundType); + char file[13]; + sprintf(file, "%s", _soundList[track]); + _musicSoundChannel = _soundDigital->playSound(file, 0xFF, Audio::Mixer::kMusicSoundType); } _lastMusicCommand = track; @@ -463,7 +482,8 @@ 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]]); + assert(_sfxFileMap[item*2+0] < _sfxFileListSize); + snprintf(filename, 16, "%s", _sfxFileList[_sfxFileMap[item*2+0]]); uint8 priority = _sfxFileMap[item*2+1]; _soundDigital->playSound(filename, priority, Audio::Mixer::kSFXSoundType, volume); @@ -478,7 +498,7 @@ void KyraEngine_MR::playVoice(int high, int low) { void KyraEngine_MR::snd_playVoiceFile(int file) { debugC(9, kDebugLevelMain, "KyraEngine_MR::snd_playVoiceFile(%d)", file); char filename[16]; - snprintf(filename, 16, "%u.AUD", (uint)file); + snprintf(filename, 16, "%.08u", (uint)file); _voiceSoundChannel = _soundDigital->playSound(filename, 0xFE, Audio::Mixer::kSpeechSoundType, 255); } @@ -531,14 +551,19 @@ void KyraEngine_MR::initMouseShapes() { assert(data); for (int i = 0; i <= 6; ++i) _gameShapes[i] = _screen->makeShapeCopy(data, i); - delete [] data; + delete[] data; } void KyraEngine_MR::startup() { debugC(9, kDebugLevelMain, "KyraEngine_MR::startup()"); - musicUpdate(0); - memset(_flagsTable, 0, sizeof(_flagsTable)); + _album.wsa = new WSAMovie_v2(this, _screen); + assert(_album.wsa); + _album.leftPage.wsa = new WSAMovie_v2(this, _screen); + assert(_album.leftPage.wsa); + _album.rightPage.wsa = new WSAMovie_v2(this, _screen); + assert(_album.rightPage.wsa); + musicUpdate(0); _gamePlayBuffer = new uint8[64000]; musicUpdate(0); @@ -552,7 +577,6 @@ void KyraEngine_MR::startup() { _stringBuffer = new char[500]; //XXX musicUpdate(0); - _costPalBuffer = new uint8[864]; //XXX allocAnimObjects(1, 16, 50); @@ -590,7 +614,7 @@ void KyraEngine_MR::startup() { for (int i = 0; i < 16; ++i) { _sceneAnims[i].flags = 0; - _sceneAnimMovie[i] = new WSAMovieV2(this, _screen); + _sceneAnimMovie[i] = new WSAMovie_v2(this, _screen); assert(_sceneAnimMovie[i]); } @@ -647,7 +671,7 @@ void KyraEngine_MR::startup() { musicUpdate(0); runStartupScript(1, 0); _res->exists("MOODOMTR.WSA", true); - _invWsa = new WSAMovieV2(this, _screen); + _invWsa = new WSAMovie_v2(this, _screen); assert(_invWsa); _invWsa->open("MOODOMTR.WSA", 1, 0); _invWsaFrame = 6; @@ -672,7 +696,11 @@ void KyraEngine_MR::startup() { void KyraEngine_MR::loadCostPal() { debugC(9, kDebugLevelMain, "KyraEngine_MR::loadCostPal()"); - _costPalBuffer = _res->fileData("_COSTPAL.DAT", 0); + _res->exists("_COSTPAL.DAT", true); + uint32 size = 0; + _costPalBuffer = _res->fileData("_COSTPAL.DAT", &size); + assert(_costPalBuffer); + assert(size == 864); } void KyraEngine_MR::loadShadowShape() { @@ -725,7 +753,7 @@ void KyraEngine_MR::initItems() { memcpy(_itemBuffer1, itemsDat , 72); memcpy(_itemBuffer2, itemsDat+72, 144); - delete [] itemsDat; + delete[] itemsDat; _screen->_curPage = 0; } @@ -791,7 +819,7 @@ void KyraEngine_MR::loadCharacterShapes(int newShapes) { ShapeMap::iterator iter = _gameShapes.find(i); if (iter != _gameShapes.end()) { - delete iter->_value; + delete[] iter->_value; iter->_value = 0; } } @@ -978,7 +1006,7 @@ void KyraEngine_MR::runLoop() { _timer->update(); if (inputFlag == 198 || inputFlag == 199) { - _unk3 = _handItemSet; + _unk3 = _mouseState; Common::Point mouse = getMousePos(); handleInput(mouse.x, mouse.y); } @@ -1122,7 +1150,7 @@ void KyraEngine_MR::update() { updateMouse(); updateSpecialSceneScripts(); updateCommandLine(); - //XXX + updateItemAnimations(); musicUpdate(0); _screen->updateScreen(); @@ -1134,7 +1162,7 @@ void KyraEngine_MR::updateWithText() { musicUpdate(0); updateMouse(); - //XXX + updateItemAnimations(); updateSpecialSceneScripts(); updateCommandLine(); musicUpdate(0); @@ -1160,13 +1188,13 @@ void KyraEngine_MR::updateMouse() { if (mouse.y > 187) { bool setItemCursor = false; - if (_handItemSet == -6) { + if (_mouseState == -6) { if (mouse.x < 311) setItemCursor = true; - } else if (_handItemSet == -5) { + } else if (_mouseState == -5) { if (mouse.x < _sceneMinX || mouse.x > _sceneMaxX) setItemCursor = true; - } else if (_handItemSet == -4) { + } else if (_mouseState == -4) { if (mouse.x > 8) setItemCursor = true; } @@ -1183,8 +1211,8 @@ void KyraEngine_MR::updateMouse() { hideInventory(); } - if (hasItemCollision && _handItemSet < -1 && _itemInHand < 0) { - _handItemSet = -1; + if (hasItemCollision && _mouseState < -1 && _itemInHand < 0) { + _mouseState = -1; _itemInHand = -1; _screen->setMouseCursor(0, 0, _gameShapes[0]); } @@ -1261,29 +1289,16 @@ void KyraEngine_MR::updateMouse() { } } - if (type != 0 && type != _handItemSet && !hasItemCollision) { - _handItemSet = type; + if (type != 0 && type != _mouseState && !hasItemCollision) { + _mouseState = type; _screen->setMouseCursor(offsetX, offsetY, _gameShapes[shape]); - } else if (type == 0 && _handItemSet != _itemInHand && mouse.x > 8 && mouse.x < 311 && mouse.y < 171 && mouse.y > 8) { + } else if (type == 0 && _mouseState != _itemInHand && mouse.x > 8 && mouse.x < 311 && mouse.y < 171 && mouse.y > 8) { setItemMouseCursor(); - } else if (mouse.y > 187 && _handItemSet > -4 && type == 0 && !_inventoryState) { + } else if (mouse.y > 187 && _mouseState > -4 && type == 0 && !_inventoryState) { showInventory(); } } -void KyraEngine_MR::delay(uint32 millis, bool doUpdate, bool isMainLoop) { - debugC(9, kDebugLevelMain, "KyraEngine_MR::delay(%d, %d, %d)", millis, doUpdate, isMainLoop); - uint32 endTime = _system->getMillis() + millis; - while (endTime > _system->getMillis()) { - if (doUpdate) { - //XXX - update(); - } - - _system->delayMillis(10); - } -} - #pragma mark - void KyraEngine_MR::makeCharFacingMouse() { @@ -1501,13 +1516,14 @@ void KyraEngine_MR::resetSkipFlag(bool removeEvent) { void KyraEngine_MR::registerDefaultSettings() { debugC(9, kDebugLevelMain, "KyraEngine_MR::registerDefaultSettings()"); - KyraEngine::registerDefaultSettings(); + KyraEngine_v1::registerDefaultSettings(); // 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); + ConfMan.registerDefault("helium_mode", false); } void KyraEngine_MR::writeSettings() { @@ -1531,16 +1547,18 @@ void KyraEngine_MR::writeSettings() { ConfMan.setBool("studio_audience", _configStudio); ConfMan.setBool("skip_support", _configSkip); + ConfMan.setBool("helium_mode", _configHelium); - KyraEngine::writeSettings(); + KyraEngine_v1::writeSettings(); } void KyraEngine_MR::readSettings() { debugC(9, kDebugLevelMain, "KyraEngine_MR::readSettings()"); - KyraEngine::readSettings(); + KyraEngine_v1::readSettings(); _configStudio = ConfMan.getBool("studio_audience"); _configSkip = ConfMan.getBool("skip_support"); + _configHelium = ConfMan.getBool("helium_mode"); } } // end of namespace Kyra diff --git a/engines/kyra/kyra_mr.h b/engines/kyra/kyra_mr.h index 3dba3ec8d9..5af138373c 100644 --- a/engines/kyra/kyra_mr.h +++ b/engines/kyra/kyra_mr.h @@ -23,8 +23,8 @@ * */ -#ifndef KYRA_KYRA_V3_H -#define KYRA_KYRA_V3_H +#ifndef KYRA_KYRA_MR_H +#define KYRA_KYRA_MR_H #include "kyra/kyra_v2.h" #include "kyra/screen_mr.h" @@ -39,7 +39,7 @@ namespace Kyra { class SoundDigital; class Screen_MR; class MainMenu; -class WSAMovieV2; +class WSAMovie_v2; class TextDisplayer_MR; struct Button; @@ -50,11 +50,17 @@ public: KyraEngine_MR(OSystem *system, const GameFlags &flags); ~KyraEngine_MR(); + //TODO: proper extended implementation of KyraEngine_v2::pauseEngineIntern. + // Idle animation time, item animations and album animations should be taken + // care of, but since those would just produce minor glitches it's not that + // important. + 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; } + bool heliumMode() const { return _configHelium; } int go(); @@ -66,11 +72,14 @@ private: // config bool _configStudio; bool _configSkip; + bool _configHelium; void registerDefaultSettings(); void writeSettings(); void readSettings(); + void initStaticResource(); + // -- Screen_MR *_screen; SoundDigital *_soundDigital; @@ -98,8 +107,6 @@ private: void updateWithText(); void updateMouse(); - void delay(uint32 millis, bool update = false, bool isMainLoop = false); - // sound specific private: void playMenuAudioFile(); @@ -108,8 +115,8 @@ private: int _fadeOutMusicChannel; const char *_menuAudioFile; - static const char *_soundList[]; - static const int _soundListSize; + const char *const *_soundList; + int _soundListSize; void snd_playWanderScoreViaMap(int track, int force); void stopMusicTrack(); @@ -119,10 +126,10 @@ private: void snd_playSoundEffect(int item, int volume); - static const uint8 _sfxFileMap[]; - static const int _sfxFileMapSize; - static const char *_sfxFileList[]; - static const int _sfxFileListSize; + const uint8 *_sfxFileMap; + int _sfxFileMapSize; + const char *const *_sfxFileList; + int _sfxFileListSize; int _voiceSoundChannel; @@ -157,7 +164,7 @@ private: void initMainMenu(); void uninitMainMenu(); - WSAMovieV2 *_menuAnim; + WSAMovie_v2 *_menuAnim; // timer void setupTimers(); @@ -177,7 +184,8 @@ private: private: // main menu - static const char *_mainMenuStrings[]; + const char *const *_mainMenuStrings; + int _mainMenuStringsSize; // animator uint8 *_gamePlayBuffer; @@ -194,6 +202,7 @@ private: void refreshAnimObjects(int force); bool _loadingState; + void updateItemAnimations(); void updateCharacterAnim(int charId); void updateSceneAnim(int anim, int newFrame); @@ -209,6 +218,10 @@ private: bool _nextIdleType; void showIdleAnim(); + const ItemAnimData_v2 *_itemAnimData; + ActiveItemAnim _activeItemAnim[10]; + int _nextAnimItem; + // interface uint8 *_interface; uint8 *_interfaceCommandLine; @@ -247,7 +260,7 @@ private: void clearInventorySlot(int slot, int page); void drawInventorySlot(int page, int item, int slot); - WSAMovieV2 *_invWsa; + WSAMovie_v2 *_invWsa; int _invWsaFrame; // localization @@ -282,12 +295,12 @@ private: bool isDropable(int x, int y); - static const uint8 _itemMagicTable[]; + const uint8 *_itemMagicTable; bool itemListMagic(int handItem, int itemSlot); bool itemInventoryMagic(int handItem, int invSlot); - static const uint8 _itemStringMap[]; - static const uint _itemStringMapSize; + const uint8 *_itemStringMap; + int _itemStringMapSize; static const uint8 _itemStringPickUp[]; static const uint8 _itemStringDrop[]; static const uint8 _itemStringInv[]; @@ -415,6 +428,11 @@ private: void goodConscienceChat(const char *str, int vocHigh, int vocLow); void goodConscienceChatWaitToFinish(); + bool _albumChatActive; + void albumChat(const char *str, int vocHigh, int vocLow); + void albumChatInit(const char *str, int object, int vocHigh, int vocLow); + void albumChatWaitToFinish(); + void malcolmSceneStartupChat(); byte _newSceneDlgState[40]; @@ -503,14 +521,64 @@ private: int _score; int _scoreMax; - static const int8 _scoreTable[]; - static const int _scoreTableSize; + const uint8 *_scoreTable; + int _scoreTableSize; + int8 _scoreFlagTable[26]; bool updateScore(int scoreId, int strId); void scoreIncrease(int count, const char *str); void eelScript(); + // Album + struct Album { + uint8 *backUpPage; + uint8 *file; + WSAMovie_v2 *wsa; + uint8 *backUpRect; + + struct PageMovie { + WSAMovie_v2 *wsa; + int curFrame; + int maxFrame; + uint32 timer; + }; + + PageMovie leftPage, rightPage; + + int curPage, nextPage; + bool running; + bool isPage14; + } _album; + + static const int8 _albumWSAX[]; + static const int8 _albumWSAY[]; + + void showAlbum(); + + void loadAlbumPage(); + void loadAlbumPageWSA(); + + void printAlbumPageText(); + void printAlbumText(int page, const char *str, int x, int y, uint8 c0); + + void processAlbum(); + + void albumNewPage(); + void albumUpdateAnims(); + void albumAnim1(); + void albumAnim2(); + + void albumBackUpRect(); + void albumRestoreRect(); + void albumUpdateRect(); + + void albumSwitchPages(int oldPage, int newPage, int srcPage); + + int albumNextPage(Button *caller); + int albumPrevPage(Button *caller); + int albumClose(Button *caller); + // save/load void saveGame(const char *fileName, const char *saveName); void loadGame(const char *fileName); @@ -527,6 +595,7 @@ private: int o3_setCharacterAnimFrameFromFacing(EMCState *script); int o3_showBadConscience(EMCState *script); int o3_hideBadConscience(EMCState *script); + int o3_showAlbum(EMCState *script); int o3_setInventorySlot(EMCState *script); int o3_getInventorySlot(EMCState *script); int o3_addItemToInventory(EMCState *script); @@ -548,6 +617,7 @@ private: int o3_drawSceneShapeOnPage(EMCState *script); int o3_checkInRect(EMCState *script); int o3_updateConversations(EMCState *script); + int o3_removeItemSlot(EMCState *script); int o3_setSceneDim(EMCState *script); int o3_setSceneAnimPosAndFrame(EMCState *script); int o3_removeItemInstances(EMCState *script); @@ -560,7 +630,7 @@ private: int o3_playSoundEffect(EMCState *script); int o3_getScore(EMCState *script); int o3_daggerWarning(EMCState *script); - int o3_blockOutRegion(EMCState *script); + int o3_blockOutWalkableRegion(EMCState *script); int o3_showSceneStringsMessage(EMCState *script); int o3_showGoodConscience(EMCState *script); int o3_goodConscienceChat(EMCState *script); diff --git a/engines/kyra/kyra_v1.cpp b/engines/kyra/kyra_v1.cpp index e9bb25fe5f..1cc1d728bf 100644 --- a/engines/kyra/kyra_v1.cpp +++ b/engines/kyra/kyra_v1.cpp @@ -23,1024 +23,386 @@ * */ -#include "kyra/kyra_v1.h" - -#include "common/file.h" -#include "common/events.h" -#include "common/system.h" -#include "common/savefile.h" +#include "common/config-manager.h" -#include "gui/message.h" +#include "sound/mididrv.h" +#include "sound/mixer.h" +#include "kyra/kyra_v1.h" +#include "kyra/sound.h" #include "kyra/resource.h" #include "kyra/screen.h" -#include "kyra/script.h" -#include "kyra/seqplayer.h" -#include "kyra/sound.h" -#include "kyra/sprites.h" -#include "kyra/wsamovie.h" -#include "kyra/animator_v1.h" #include "kyra/text.h" -#include "kyra/debugger.h" #include "kyra/timer.h" +#include "kyra/script.h" +#include "kyra/debugger.h" namespace Kyra { KyraEngine_v1::KyraEngine_v1(OSystem *system, const GameFlags &flags) - : KyraEngine(system, flags) { - _skipFlag = false; - - _seq_Forest = _seq_KallakWriting = _seq_KyrandiaLogo = _seq_KallakMalcolm = - _seq_MalcolmTree = _seq_WestwoodLogo = _seq_Demo1 = _seq_Demo2 = _seq_Demo3 = - _seq_Demo4 = 0; - - _seq_WSATable = _seq_CPSTable = _seq_COLTable = _seq_textsTable = 0; - _seq_WSATable_Size = _seq_CPSTable_Size = _seq_COLTable_Size = _seq_textsTable_Size = 0; - - _roomFilenameTable = _characterImageTable = 0; - _roomFilenameTableSize = _characterImageTableSize = 0; - _itemList = _takenList = _placedList = _droppedList = _noDropList = 0; - _itemList_Size = _takenList_Size = _placedList_Size = _droppedList_Size = _noDropList_Size = 0; - _putDownFirst = _waitForAmulet = _blackJewel = _poisonGone = _healingTip = 0; - _putDownFirst_Size = _waitForAmulet_Size = _blackJewel_Size = _poisonGone_Size = _healingTip_Size = 0; - _thePoison = _fluteString = _wispJewelStrings = _magicJewelString = _flaskFull = _fullFlask = 0; - _thePoison_Size = _fluteString_Size = _wispJewelStrings_Size = 0; - _magicJewelString_Size = _flaskFull_Size = _fullFlask_Size = 0; - - _defaultShapeTable = 0; - _healingShapeTable = _healingShape2Table = 0; - _defaultShapeTableSize = _healingShapeTableSize = _healingShape2TableSize = 0; - _posionDeathShapeTable = _fluteAnimShapeTable = 0; - _posionDeathShapeTableSize = _fluteAnimShapeTableSize = 0; - _winterScrollTable = _winterScroll1Table = _winterScroll2Table = 0; - _winterScrollTableSize = _winterScroll1TableSize = _winterScroll2TableSize = 0; - _drinkAnimationTable = _brandonToWispTable = _magicAnimationTable = _brandonStoneTable = 0; - _drinkAnimationTableSize = _brandonToWispTableSize = _magicAnimationTableSize = _brandonStoneTableSize = 0; - memset(&_specialPalettes, 0, sizeof(_specialPalettes)); + : Engine(system), _flags(flags) { + _res = 0; + _sound = 0; + _text = 0; + _staticres = 0; + _timer = 0; + _emc = 0; _debugger = 0; - _sprites = 0; - _animator = 0; - _seq = 0; - _characterList = 0; - _movFacingTable = 0; - _buttonData = 0; - _buttonDataListPtr = 0; - memset(_shapes, 0, sizeof(_shapes)); - memset(_movieObjects, 0, sizeof(_movieObjects)); - _finalA = _finalB = _finalC = 0; - _endSequenceBackUpRect = 0; - memset(_panPagesTable, 0, sizeof(_panPagesTable)); - memset(_sceneAnimTable, 0, sizeof(_sceneAnimTable)); - _currHeadShape = 0; - - memset(&_itemBkgBackUp, 0, sizeof(_itemBkgBackUp)); -} - -KyraEngine_v1::~KyraEngine_v1() { - for (int i = 0; i < ARRAYSIZE(_movieObjects); ++i) { - if (_movieObjects[i]) - _movieObjects[i]->close(); - delete _movieObjects[i]; - _movieObjects[i] = 0; - } - - closeFinalWsa(); - if (_emc) { - _emc->unload(&_npcScriptData); - _emc->unload(&_scriptClickData); - } - - Common::clearAllSpecialDebugLevels(); - - delete _screen; - delete _debugger; - delete _sprites; - delete _animator; - delete _seq; - - delete [] _characterList; - - delete [] _movFacingTable; - - delete [] _gui->_scrollUpButton.data0ShapePtr; - delete [] _gui->_scrollUpButton.data1ShapePtr; - delete [] _gui->_scrollUpButton.data2ShapePtr; - delete [] _gui->_scrollDownButton.data0ShapePtr; - delete [] _gui->_scrollDownButton.data1ShapePtr; - delete [] _gui->_scrollDownButton.data2ShapePtr; - - delete [] _buttonData; - delete [] _buttonDataListPtr; - - delete _gui; - - delete [] _itemBkgBackUp[0]; - delete [] _itemBkgBackUp[1]; - - for (int i = 0; i < ARRAYSIZE(_shapes); ++i) { - if (_shapes[i] != 0) { - delete [] _shapes[i]; - for (int i2 = 0; i2 < ARRAYSIZE(_shapes); i2++) { - if (_shapes[i2] == _shapes[i] && i2 != i) { - _shapes[i2] = 0; - } - } - _shapes[i] = 0; - } - } - - for (int i = 0; i < ARRAYSIZE(_sceneAnimTable); ++i) - delete [] _sceneAnimTable[i]; -} - -int KyraEngine_v1::init() { - _screen = new Screen_v1(this, _system); - assert(_screen); - _screen->setResolution(); - - KyraEngine::init(); - - _sprites = new Sprites(this, _system); - assert(_sprites); - _seq = new SeqPlayer(this, _system); - assert(_seq); - _animator = new Animator_v1(this, _system); - assert(_animator); - _animator->init(5, 11, 12); - assert(*_animator); - _text = new TextDisplayer(this, screen()); - assert(_text); - _gui = new GUI_v1(this, _screen); - assert(_gui); - - initStaticResource(); - - _sound->setSoundList(&_soundData[kMusicIntro]); - - _trackMap = _dosTrackMap; - _trackMapSize = _dosTrackMapSize; - - if (!_sound->init()) - error("Couldn't init sound"); - _sound->loadSoundFile(0); + _gameSpeed = 60; + _tickLength = (uint8)(1000.0 / _gameSpeed); - setupButtonData(); + _quitFlag = false; - _paletteChanged = 1; - _currentCharacter = 0; - _characterList = new Character[11]; - assert(_characterList); - memset(_characterList, 0, sizeof(Character)*11); + _speechFile = ""; + _trackMap = 0; + _trackMapSize = 0; + _lastMusicCommand = -1; + _curSfxFile = _curMusicTheme = -1; - for (int i = 0; i < 11; ++i) - memset(_characterList[i].inventoryItems, 0xFF, sizeof(_characterList[i].inventoryItems)); + _gameToLoad = -1; - _characterList[0].sceneId = 5; - _characterList[0].height = 48; - _characterList[0].facing = 3; - _characterList[0].currentAnimFrame = 7; - - memset(&_npcScriptData, 0, sizeof(EMCData)); - memset(&_scriptClickData, 0, sizeof(EMCData)); - - memset(&_npcScript, 0, sizeof(EMCState)); - memset(&_scriptMain, 0, sizeof(EMCState)); - memset(&_scriptClick, 0, sizeof(EMCState)); - - _debugger = new Debugger_v1(this); - assert(_debugger); - memset(_shapes, 0, sizeof(_shapes)); - - for (int i = 0; i < ARRAYSIZE(_movieObjects); ++i) - _movieObjects[i] = createWSAMovie(); + _mouseState = -1; + _deathHandler = -1; memset(_flagsTable, 0, sizeof(_flagsTable)); - _abortWalkFlag = false; - _abortWalkFlag2 = false; - _talkingCharNum = -1; - _charSayUnk3 = -1; - memset(_currSentenceColor, 0, 3); - _startSentencePalIndex = -1; - _fadeText = false; - - _cauldronState = 0; - _crystalState[0] = _crystalState[1] = -1; - - _brandonStatusBit = 0; - _brandonStatusBit0x02Flag = _brandonStatusBit0x20Flag = 10; - _brandonPosX = _brandonPosY = -1; - _deathHandler = 0xFF; - _poisonDeathCounter = 0; - - memset(_itemTable, 0, sizeof(_itemTable)); - memset(_exitList, 0xFFFF, sizeof(_exitList)); - _exitListPtr = 0; - _pathfinderFlag = _pathfinderFlag2 = 0; - _lastFindWayRet = 0; - _sceneChangeState = _loopFlag2 = 0; - - _movFacingTable = new int[150]; - assert(_movFacingTable); - _movFacingTable[0] = 8; - - _skipFlag = false; - - _marbleVaseItem = -1; - memset(_foyerItemTable, -1, sizeof(_foyerItemTable)); - _mouseState = _itemInHand = -1; - _handleInput = false; - - _currentRoom = 0xFFFF; - _scenePhasingFlag = 0; - _lastProcessedItem = 0; - _lastProcessedItemHeight = 16; - - _unkScreenVar1 = 1; - _unkScreenVar2 = 0; - _unkScreenVar3 = 0; - _unkAmuletVar = 0; - - _endSequenceNeedLoading = 1; - _malcolmFlag = 0; - _beadStateVar = 0; - _endSequenceSkipFlag = 0; - _unkEndSeqVar2 = 0; - _endSequenceBackUpRect = 0; - _unkEndSeqVar4 = 0; - _unkEndSeqVar5 = 0; - _lastDisplayedPanPage = 0; - memset(_panPagesTable, 0, sizeof(_panPagesTable)); - _finalA = _finalB = _finalC = 0; - memset(&_kyragemFadingState, 0, sizeof(_kyragemFadingState)); - _kyragemFadingState.gOffset = 0x13; - _kyragemFadingState.bOffset = 0x13; - - _mousePressFlag = false; - - _menuDirectlyToLoad = false; - - _lastMusicCommand = 0; - - return 0; + // sets up all engine specific debug levels + Common::addSpecialDebugLevel(kDebugLevelScriptFuncs, "ScriptFuncs", "Script function debug level"); + Common::addSpecialDebugLevel(kDebugLevelScript, "Script", "Script interpreter debug level"); + Common::addSpecialDebugLevel(kDebugLevelSprites, "Sprites", "Sprite debug level"); + Common::addSpecialDebugLevel(kDebugLevelScreen, "Screen", "Screen debug level"); + Common::addSpecialDebugLevel(kDebugLevelSound, "Sound", "Sound debug level"); + Common::addSpecialDebugLevel(kDebugLevelAnimator, "Animator", "Animator debug level"); + Common::addSpecialDebugLevel(kDebugLevelMain, "Main", "Generic debug level"); + Common::addSpecialDebugLevel(kDebugLevelGUI, "GUI", "GUI debug level"); + Common::addSpecialDebugLevel(kDebugLevelSequence, "Sequence", "Sequence debug level"); + Common::addSpecialDebugLevel(kDebugLevelMovie, "Movie", "Movie debug level"); + Common::addSpecialDebugLevel(kDebugLevelTimer, "Timer", "Timer debug level"); + + system->getEventManager()->registerRandomSource(_rnd, "kyra"); } -int KyraEngine_v1::go() { - if (_res->getFileSize("6.FNT")) - _screen->loadFont(Screen::FID_6_FNT, "6.FNT"); - _screen->loadFont(Screen::FID_8_FNT, "8FAT.FNT"); - _screen->setScreenDim(0); - - _abortIntroFlag = false; - - if (_flags.isDemo) { - seq_demo(); - } else { - setGameFlag(0xF3); - setGameFlag(0xFD); - if (_gameToLoad == -1) { - setGameFlag(0xEF); - seq_intro(); - if (_quitFlag) - return 0; - if (_skipIntroFlag && _abortIntroFlag) - resetGameFlag(0xEF); - } - startup(); - resetGameFlag(0xEF); - mainLoop(); - } - return 0; +::GUI::Debugger *KyraEngine_v1::getDebugger() { + return _debugger; } +void KyraEngine_v1::pauseEngineIntern(bool pause) { + Engine::pauseEngineIntern(pause); + _timer->pause(pause); +} -void KyraEngine_v1::startup() { - debugC(9, kDebugLevelMain, "KyraEngine_v1::startup()"); - static const uint8 colorMap[] = { 0, 0, 0, 0, 12, 12, 12, 0, 0, 0, 0, 0 }; - _screen->setTextColorMap(colorMap); - _sound->setSoundList(&_soundData[kMusicIngame]); - _sound->loadSoundFile(0); -// _screen->setFont(Screen::FID_6_FNT); - _screen->setAnimBlockPtr(3750); - memset(_sceneAnimTable, 0, sizeof(_sceneAnimTable)); - loadMouseShapes(); - _currentCharacter = &_characterList[0]; - for (int i = 1; i < 5; ++i) - _animator->setCharacterDefaultFrame(i); - for (int i = 5; i <= 10; ++i) - setCharactersPositions(i); - _animator->setCharactersHeight(); - resetBrandonPoisonFlags(); - _screen->_curPage = 0; - // XXX - for (int i = 0; i < 12; ++i) { - int size = _screen->getRectSize(3, 24); - _shapes[361+i] = new byte[size]; - } - - _itemBkgBackUp[0] = new uint8[_screen->getRectSize(3, 24)]; - memset(_itemBkgBackUp[0], 0, _screen->getRectSize(3, 24)); - _itemBkgBackUp[1] = new uint8[_screen->getRectSize(4, 32)]; - memset(_itemBkgBackUp[1], 0, _screen->getRectSize(4, 32)); - - for (int i = 0; i < _roomTableSize; ++i) { - for (int item = 0; item < 12; ++item) { - _roomTable[i].itemsTable[item] = 0xFF; - _roomTable[i].itemsXPos[item] = 0xFFFF; - _roomTable[i].itemsYPos[item] = 0xFF; - _roomTable[i].needInit[item] = 0; +int KyraEngine_v1::init() { + registerDefaultSettings(); + + // Setup mixer + _mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, ConfMan.getInt("sfx_volume")); + _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, ConfMan.getInt("music_volume")); + _mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, ConfMan.getInt("speech_volume")); + + 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); + } } } - loadCharacterShapes(); - loadSpecialEffectShapes(); - loadItems(); - loadButtonShapes(); - initMainButtonList(); - loadMainScreen(); - _screen->loadPalette("PALETTE.COL", _screen->_currentPalette); - - // XXX - _animator->initAnimStateList(); - setCharactersInDefaultScene(); - - if (!_emc->load("_STARTUP.EMC", &_npcScriptData, &_opcodes)) - error("Could not load \"_STARTUP.EMC\" script"); - _emc->init(&_scriptMain, &_npcScriptData); - - if (!_emc->start(&_scriptMain, 0)) - error("Could not start script function 0 of script \"_STARTUP.EMC\""); - - while (_emc->isValid(&_scriptMain)) - _emc->run(&_scriptMain); - - _emc->unload(&_npcScriptData); - - if (!_emc->load("_NPC.EMC", &_npcScriptData, &_opcodes)) - error("Could not load \"_NPC.EMC\" script"); - - snd_playTheme(1, -1); - if (_gameToLoad == -1) { - enterNewScene(_currentCharacter->sceneId, _currentCharacter->facing, 0, 0, 1); - if (_abortIntroFlag && _skipIntroFlag) { - _menuDirectlyToLoad = true; - _screen->setMouseCursor(1, 1, _shapes[0]); - _screen->showMouse(); - _gui->buttonMenuCallback(0); - _menuDirectlyToLoad = false; - } else - saveGame(getSavegameFilename(0), "New game"); - } else { - _screen->setFont(Screen::FID_8_FNT); - loadGame(getSavegameFilename(_gameToLoad)); - _gameToLoad = -1; + if (_sound) + _sound->updateVolumeSettings(); + + _res = new Resource(this); + assert(_res); + _res->reset(); + _staticres = new StaticResource(this); + assert(_staticres); + if (!_staticres->init()) + error("_staticres->init() failed"); + if (!screen()->init()) + error("screen()->init() failed"); + _timer = new TimerManager(this, _system); + assert(_timer); + setupTimers(); + _emc = new EMCInterpreter(this); + assert(_emc); + + setupOpcodeTable(); + readSettings(); + + if (ConfMan.hasKey("save_slot")) { + _gameToLoad = ConfMan.getInt("save_slot"); + if (!saveFileLoadable(_gameToLoad)) + _gameToLoad = -1; } -} -void KyraEngine_v1::mainLoop() { - debugC(9, kDebugLevelMain, "KyraEngine_v1::mainLoop()"); + _lang = 0; + Common::Language lang = Common::parseLanguage(ConfMan.get("language")); - while (!_quitFlag) { - int32 frameTime = (int32)_system->getMillis(); - _skipFlag = false; + if (_flags.gameID == GI_KYRA2 || _flags.gameID == GI_KYRA3) { + switch (lang) { + case Common::EN_ANY: + case Common::EN_USA: + case Common::EN_GRB: + _lang = 0; + break; - if (_currentCharacter->sceneId == 210) { - updateKyragemFading(); - if (seq_playEnd() && _deathHandler != 8) - break; - } + case Common::FR_FRA: + _lang = 1; + break; - if (_deathHandler != 0xFF) { - snd_playWanderScoreViaMap(0, 1); - snd_playSoundEffect(49); - _screen->hideMouse(); - _screen->setMouseCursor(1, 1, _shapes[0]); - destroyMouseItem(); - _screen->showMouse(); - _gui->buttonMenuCallback(0); - _deathHandler = 0xFF; - } + case Common::DE_DEU: + _lang = 2; + break; - if ((_brandonStatusBit & 2) && _brandonStatusBit0x02Flag) - _animator->animRefreshNPC(0); + case Common::JA_JPN: + _lang = 3; + break; - if ((_brandonStatusBit & 0x20) && _brandonStatusBit0x20Flag) { - _animator->animRefreshNPC(0); - _brandonStatusBit0x20Flag = 0; + default: + warning("unsupported language, switching back to English"); + _lang = 0; + break; } - - _screen->showMouse(); - - _gui->processButtonList(_buttonList, 0); - updateMousePointer(); - _timer->update(); - updateTextFade(); - - _handleInput = true; - delay((frameTime + _gameSpeed) - _system->getMillis(), true, true); - _handleInput = false; - - _sound->process(); } -} - -void KyraEngine_v1::delayUntil(uint32 timestamp, bool updateTimers, bool update, bool isMainLoop) { - while (_system->getMillis() < timestamp && !_quitFlag) { - if (updateTimers) - _timer->update(); - if (timestamp - _system->getMillis() >= 10) - delay(10, update, isMainLoop); - } + return 0; } -void KyraEngine_v1::delay(uint32 amount, bool update, bool isMainLoop) { - Common::Event event; - - uint32 start = _system->getMillis(); - do { - while (_eventMan->pollEvent(event)) { - switch (event.type) { - case Common::EVENT_KEYDOWN: - if (event.kbd.keycode >= '1' && event.kbd.keycode <= '9' && - (event.kbd.flags == Common::KBD_CTRL || event.kbd.flags == Common::KBD_ALT) && isMainLoop) { - const char *saveLoadSlot = getSavegameFilename(9 - (event.kbd.keycode - '0') + 990); - - if (event.kbd.flags == Common::KBD_CTRL) - loadGame(saveLoadSlot); - else { - char savegameName[14]; - sprintf(savegameName, "Quicksave %d", event.kbd.keycode - '0'); - saveGame(saveLoadSlot, savegameName); - } - } else if (event.kbd.flags == Common::KBD_CTRL) { - if (event.kbd.keycode == 'd') - _debugger->attach(); - else if (event.kbd.keycode == 'q') - _quitFlag = true; - } else if (event.kbd.keycode == '.') { - _skipFlag = true; - } else if (event.kbd.keycode == Common::KEYCODE_RETURN || event.kbd.keycode == Common::KEYCODE_SPACE || event.kbd.keycode == Common::KEYCODE_ESCAPE) { - _abortIntroFlag = true; - _skipFlag = true; - } - - break; - case Common::EVENT_MOUSEMOVE: - _animator->_updateScreen = true; - break; - case Common::EVENT_QUIT: - quitGame(); - break; - case Common::EVENT_LBUTTONDOWN: - _mousePressFlag = true; - break; - case Common::EVENT_LBUTTONUP: - _mousePressFlag = false; - - if (_abortWalkFlag2) - _abortWalkFlag = true; - - if (_handleInput) { - _handleInput = false; - processInput(); - _handleInput = true; - } else - _skipFlag = true; - - break; - default: - break; - } - } - - if (_debugger->isAttached()) - _debugger->onFrame(); - - if (update) { - _sprites->updateSceneAnims(); - _animator->updateAllObjectShapes(); - updateTextFade(); - updateMousePointer(); - } - - if (_currentCharacter && _currentCharacter->sceneId == 210 && update) - updateKyragemFading(); - - if (_skipFlag && !_abortIntroFlag && !queryGameFlag(0xFE)) - _skipFlag = false; - - if (amount > 0 && !_skipFlag && !_quitFlag) - _system->delayMillis(10); - - if (_skipFlag) - _sound->voiceStop(); - } while (!_skipFlag && _system->getMillis() < start + amount && !_quitFlag); +KyraEngine_v1::~KyraEngine_v1() { + for (Common::Array<const Opcode*>::iterator i = _opcodes.begin(); i != _opcodes.end(); ++i) + delete *i; + _opcodes.clear(); + + delete _res; + delete _staticres; + delete _sound; + delete _text; + delete _timer; + delete _emc; + delete _debugger; } -void KyraEngine_v1::waitForEvent() { - bool finished = false; - Common::Event event; - - while (!finished && !_quitFlag) { - while (_eventMan->pollEvent(event)) { - switch (event.type) { - case Common::EVENT_KEYDOWN: - finished = true; - break; - case Common::EVENT_QUIT: - quitGame(); - break; - case Common::EVENT_LBUTTONDOWN: - finished = true; - _skipFlag = true; - break; - default: - break; - } - } - - if (_debugger->isAttached()) - _debugger->onFrame(); - - _system->delayMillis(10); - } +void KyraEngine_v1::quitGame() { + debugC(9, kDebugLevelMain, "KyraEngine_v1::quitGame()"); + _quitFlag = true; + // Nothing to do here } -void KyraEngine_v1::delayWithTicks(int ticks) { - uint32 nextTime = _system->getMillis() + ticks * _tickLength; - - while (_system->getMillis() < nextTime) { - _sprites->updateSceneAnims(); - _animator->updateAllObjectShapes(); +Common::Point KyraEngine_v1::getMousePos() const { + Common::Point mouse = _eventMan->getMousePos(); - if (_currentCharacter->sceneId == 210) { - updateKyragemFading(); - seq_playEnd(); - } - - if (_skipFlag) - break; - - if (nextTime - _system->getMillis() >= 10) - delay(10); + if (_flags.useHiResOverlay) { + mouse.x >>= 1; + mouse.y >>= 1; } -} -#pragma mark - -#pragma mark - Animation/shape specific code -#pragma mark - - -void KyraEngine_v1::setupShapes123(const Shape *shapeTable, int endShape, int flags) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::setupShapes123(%p, %d, %d)", (const void *)shapeTable, endShape, flags); - - for (int i = 123; i <= 172; ++i) - _shapes[i] = 0; - - uint8 curImage = 0xFF; - int curPageBackUp = _screen->_curPage; - _screen->_curPage = 8; // we are using page 8 here in the original page 2 was backuped and then used for this stuff - int shapeFlags = 2; - if (flags) - shapeFlags = 3; - for (int i = 123; i < 123+endShape; ++i) { - uint8 newImage = shapeTable[i-123].imageIndex; - if (newImage != curImage && newImage != 0xFF) { - assert(_characterImageTable); - _screen->loadBitmap(_characterImageTable[newImage], 8, 8, 0); - curImage = newImage; - } - _shapes[i] = _screen->encodeShape(shapeTable[i-123].x<<3, shapeTable[i-123].y, shapeTable[i-123].w<<3, shapeTable[i-123].h, shapeFlags); - assert(i-7 < _defaultShapeTableSize); - _defaultShapeTable[i-7].xOffset = shapeTable[i-123].xOffset; - _defaultShapeTable[i-7].yOffset = shapeTable[i-123].yOffset; - _defaultShapeTable[i-7].w = shapeTable[i-123].w; - _defaultShapeTable[i-7].h = shapeTable[i-123].h; - } - _screen->_curPage = curPageBackUp; + return mouse; } -void KyraEngine_v1::freeShapes123() { - debugC(9, kDebugLevelMain, "KyraEngine_v1::freeShapes123()"); - - for (int i = 123; i <= 172; ++i) { - delete [] _shapes[i]; - _shapes[i] = 0; +void KyraEngine_v1::setMousePos(int x, int y) { + if (_flags.useHiResOverlay) { + x <<= 1; + y <<= 1; } + _system->warpMouse(x, y); } -#pragma mark - -#pragma mark - Misc stuff -#pragma mark - - -Movie *KyraEngine_v1::createWSAMovie() { - if (_flags.platform == Common::kPlatformAmiga) - return new WSAMovieAmiga(this); - - return new WSAMovieV1(this); +int KyraEngine_v1::setGameFlag(int flag) { + _flagsTable[flag >> 3] |= (1 << (flag & 7)); + return 1; } -void KyraEngine_v1::setBrandonPoisonFlags(int reset) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::setBrandonPoisonFlags(%d)", reset); - _brandonStatusBit |= 1; - - if (reset) - _poisonDeathCounter = 0; - - for (int i = 0; i < 0x100; ++i) - _brandonPoisonFlagsGFX[i] = i; - - _brandonPoisonFlagsGFX[0x99] = 0x34; - _brandonPoisonFlagsGFX[0x9A] = 0x35; - _brandonPoisonFlagsGFX[0x9B] = 0x37; - _brandonPoisonFlagsGFX[0x9C] = 0x38; - _brandonPoisonFlagsGFX[0x9D] = 0x2B; +int KyraEngine_v1::queryGameFlag(int flag) const { + return ((_flagsTable[flag >> 3] >> (flag & 7)) & 1); } -void KyraEngine_v1::resetBrandonPoisonFlags() { - debugC(9, kDebugLevelMain, "KyraEngine_v1::resetBrandonPoisonFlags()"); - _brandonStatusBit = 0; - - for (int i = 0; i < 0x100; ++i) - _brandonPoisonFlagsGFX[i] = i; +int KyraEngine_v1::resetGameFlag(int flag) { + _flagsTable[flag >> 3] &= ~(1 << (flag & 7)); + return 0; } -#pragma mark - -#pragma mark - Input -#pragma mark - - -void KyraEngine_v1::processInput() { - Common::Point mouse = getMousePos(); - int xpos = mouse.x; - int ypos = mouse.y; - - debugC(9, kDebugLevelMain, "KyraEngine_v1::processInput(%d, %d)", xpos, ypos); - _abortWalkFlag2 = false; - - if (processInputHelper(xpos, ypos)) - return; - - uint8 item = findItemAtPos(xpos, ypos); - if (item == 0xFF) { - _changedScene = false; - int handled = clickEventHandler(xpos, ypos); - if (_changedScene || handled) - return; - } - - // XXX _deathHandler specific - if (ypos <= 158) { - uint16 exit = 0xFFFF; - if (xpos < 12) { - exit = _walkBlockWest; - } else if (xpos >= 308) { - exit = _walkBlockEast; - } else if (ypos >= 136) { - exit = _walkBlockSouth; - } else if (ypos < 12) { - exit = _walkBlockNorth; - } - - if (exit != 0xFFFF) { - _abortWalkFlag2 = true; - handleSceneChange(xpos, ypos, 1, 1); - _abortWalkFlag2 = false; - return; - } else { - int script = checkForNPCScriptRun(xpos, ypos); - if (script >= 0) { - runNpcScript(script); - return; - } - if (_itemInHand != -1) { - if (ypos < 155) { - if (hasClickedOnExit(xpos, ypos)) { - _abortWalkFlag2 = true; - handleSceneChange(xpos, ypos, 1, 1); - _abortWalkFlag2 = false; - return; - } - dropItem(0, _itemInHand, xpos, ypos, 1); - } - } else { - if (ypos <= 155) { - _abortWalkFlag2 = true; - handleSceneChange(xpos, ypos, 1, 1); - _abortWalkFlag2 = false; - } - } - } +void KyraEngine_v1::delayUntil(uint32 timestamp, bool updateTimers, bool update, bool isMainLoop) { + while (_system->getMillis() < timestamp && !_quitFlag) { + if (timestamp - _system->getMillis() >= 10) + delay(10, update, isMainLoop); } } -int KyraEngine_v1::processInputHelper(int xpos, int ypos) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::processInputHelper(%d, %d)", xpos, ypos); - uint8 item = findItemAtPos(xpos, ypos); - if (item != 0xFF) { - if (_itemInHand == -1) { - _screen->hideMouse(); - _animator->animRemoveGameItem(item); - snd_playSoundEffect(53); - assert(_currentCharacter->sceneId < _roomTableSize); - Room *currentRoom = &_roomTable[_currentCharacter->sceneId]; - int item2 = currentRoom->itemsTable[item]; - currentRoom->itemsTable[item] = 0xFF; - setMouseItem(item2); - assert(_itemList && _takenList); - updateSentenceCommand(_itemList[item2], _takenList[0], 179); - _itemInHand = item2; - _screen->showMouse(); - clickEventHandler2(); - return 1; - } else { - exchangeItemWithMouseItem(_currentCharacter->sceneId, item); - return 1; - } - } - return 0; +void KyraEngine_v1::delay(uint32 amount, bool update, bool isMainLoop) { + _system->delayMillis(amount); } -int KyraEngine_v1::clickEventHandler(int xpos, int ypos) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::clickEventHandler(%d, %d)", xpos, ypos); - _emc->init(&_scriptClick, &_scriptClickData); - _scriptClick.regs[1] = xpos; - _scriptClick.regs[2] = ypos; - _scriptClick.regs[3] = 0; - _scriptClick.regs[4] = _itemInHand; - _emc->start(&_scriptClick, 1); - - while (_emc->isValid(&_scriptClick)) - _emc->run(&_scriptClick); +void KyraEngine_v1::delayWithTicks(int ticks) { + delay(ticks * _tickLength); +} - return _scriptClick.regs[3]; +void KyraEngine_v1::registerDefaultSettings() { + if (_flags.gameID != GI_KYRA3) + ConfMan.registerDefault("cdaudio", (_flags.platform == Common::kPlatformFMTowns || _flags.platform == Common::kPlatformPC98)); } -void KyraEngine_v1::updateMousePointer(bool forceUpdate) { - int shape = 0; - - int newMouseState = 0; - int newX = 0; - int newY = 0; - Common::Point mouse = getMousePos(); - if (mouse.y <= 158) { - if (mouse.x >= 12) { - if (mouse.x >= 308) { - if (_walkBlockEast == 0xFFFF) { - newMouseState = -2; - } else { - newMouseState = -5; - shape = 3; - newX = 7; - newY = 5; - } - } else if (mouse.y >= 136) { - if (_walkBlockSouth == 0xFFFF) { - newMouseState = -2; - } else { - newMouseState = -4; - shape = 4; - newX = 5; - newY = 7; - } - } else if (mouse.y < 12) { - if (_walkBlockNorth == 0xFFFF) { - newMouseState = -2; - } else { - newMouseState = -6; - shape = 2; - newX = 5; - newY = 1; - } - } - } else { - if (_walkBlockWest == 0xFFFF) { - newMouseState = -2; - } else { - newMouseState = -3; - newX = 1; - newY = shape = 5; - } - } +void KyraEngine_v1::readSettings() { + _configWalkspeed = ConfMan.getInt("walkspeed"); + _configMusic = 0; + + if (!ConfMan.getBool("music_mute")) { + _configMusic = 1; + if (_flags.gameID != GI_KYRA3 && ConfMan.getBool("cdaudio") && (_flags.platform == Common::kPlatformFMTowns || _flags.platform == Common::kPlatformPC98)) + _configMusic = 2; } + _configSounds = ConfMan.getBool("sfx_mute") ? 0 : 1; - if (mouse.x >= _entranceMouseCursorTracks[0] && mouse.y >= _entranceMouseCursorTracks[1] - && mouse.x <= _entranceMouseCursorTracks[2] && mouse.y <= _entranceMouseCursorTracks[3]) { - switch (_entranceMouseCursorTracks[4]) { - case 0: - newMouseState = -6; - shape = 2; - newX = 5; - newY = 1; - break; + if (_sound) { + _sound->enableMusic(_configMusic); + _sound->enableSFX(_configSounds); + } - case 2: - newMouseState = -5; - shape = 3; - newX = 7; - newY = 5; - break; + bool speechMute = ConfMan.getBool("speech_mute"); + bool subtitles = ConfMan.getBool("subtitles"); - case 4: - newMouseState = -4; - shape = 4; - newX = 5; - newY = 7; - break; + if (!speechMute && subtitles) + _configVoice = 2; // Voice & Text + else if (!speechMute && !subtitles) + _configVoice = 1; // Voice only + else + _configVoice = 0; // Text only - case 6: - newMouseState = -3; - shape = 5; - newX = 1; - newY = 5; - break; + setWalkspeed(_configWalkspeed); +} - default: - break; - } +void KyraEngine_v1::writeSettings() { + bool speechMute, subtitles; + + ConfMan.setInt("walkspeed", _configWalkspeed); + ConfMan.setBool("music_mute", _configMusic == 0); + if (_flags.gameID != GI_KYRA3) + ConfMan.setBool("cdaudio", _configMusic == 2); + ConfMan.setBool("sfx_mute", _configSounds == 0); + + switch (_configVoice) { + case 0: // Text only + speechMute = true; + subtitles = true; + break; + case 1: // Voice only + speechMute = false; + subtitles = false; + break; + default: // Voice & Text + speechMute = false; + subtitles = true; + break; } - if (newMouseState == -2) { - shape = 6; - newX = 4; - newY = 4; + if (_sound) { + if (!_configMusic) + _sound->beginFadeOut(); + _sound->enableMusic(_configMusic); + _sound->enableSFX(_configSounds); } - if ((newMouseState && _mouseState != newMouseState) || (newMouseState && forceUpdate)) { - _mouseState = newMouseState; - _screen->hideMouse(); - _screen->setMouseCursor(newX, newY, _shapes[shape]); - _screen->showMouse(); - } + ConfMan.setBool("speech_mute", speechMute); + ConfMan.setBool("subtitles", subtitles); - if (!newMouseState) { - if (_mouseState != _itemInHand || forceUpdate) { - if (mouse.y > 158 || (mouse.x >= 12 && mouse.x < 308 && mouse.y < 136 && mouse.y >= 12) || forceUpdate) { - _mouseState = _itemInHand; - _screen->hideMouse(); - if (_itemInHand == -1) - _screen->setMouseCursor(1, 1, _shapes[0]); - else - _screen->setMouseCursor(8, 15, _shapes[216+_itemInHand]); - _screen->showMouse(); - } - } - } + ConfMan.flushToDisk(); } -bool KyraEngine_v1::hasClickedOnExit(int xpos, int ypos) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::hasClickedOnExit(%d, %d)", xpos, ypos); - if (xpos < 16 || xpos >= 304) - return true; - - if (ypos < 8) - return true; - - if (ypos < 136 || ypos > 155) - return false; - - return true; +bool KyraEngine_v1::speechEnabled() { + return _flags.isTalkie && (_configVoice == 1 || _configVoice == 2); } -void KyraEngine_v1::clickEventHandler2() { - debugC(9, kDebugLevelMain, "KyraEngine_v1::clickEventHandler2()"); - - Common::Point mouse = getMousePos(); - - _emc->init(&_scriptClick, &_scriptClickData); - _scriptClick.regs[0] = _currentCharacter->sceneId; - _scriptClick.regs[1] = mouse.x; - _scriptClick.regs[2] = mouse.y; - _scriptClick.regs[4] = _itemInHand; - _emc->start(&_scriptClick, 6); - - while (_emc->isValid(&_scriptClick)) - _emc->run(&_scriptClick); +bool KyraEngine_v1::textEnabled() { + return !_flags.isTalkie || (_configVoice == 0 || _configVoice == 2); } -int KyraEngine_v1::checkForNPCScriptRun(int xpos, int ypos) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::checkForNPCScriptRun(%d, %d)", xpos, ypos); - int returnValue = -1; - const Character *currentChar = _currentCharacter; - int charLeft = 0, charRight = 0, charTop = 0, charBottom = 0; - - int scaleFactor = _scaleTable[currentChar->y1]; - int addX = (((scaleFactor*8)*3)>>8)>>1; - int addY = ((scaleFactor*3)<<4)>>8; - - charLeft = currentChar->x1 - addX; - charRight = currentChar->x1 + addX; - charTop = currentChar->y1 - addY; - charBottom = currentChar->y1; - - if (xpos >= charLeft && charRight >= xpos && charTop <= ypos && charBottom >= ypos) - return 0; - - if (xpos > 304 || xpos < 16) - return -1; - - for (int i = 1; i < 5; ++i) { - currentChar = &_characterList[i]; - - if (currentChar->sceneId != _currentCharacter->sceneId) - continue; - - charLeft = currentChar->x1 - 12; - charRight = currentChar->x1 + 11; - charTop = currentChar->y1 - 48; - // if (!i) - // charBottom = currentChar->y2 - 16; - // else - charBottom = currentChar->y1; - - if (xpos < charLeft || xpos > charRight || ypos < charTop || charBottom < ypos) - continue; - - if (returnValue != -1) { - if (currentChar->y1 >= _characterList[returnValue].y1) - returnValue = i; - } else { - returnValue = i; - } - } - - return returnValue; +inline int convertValueToMixer(int value) { + value -= 2; + return (value * Audio::Mixer::kMaxMixerVolume) / 95; } -void KyraEngine_v1::runNpcScript(int func) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::runNpcScript(%d)", func); - _emc->init(&_npcScript, &_npcScriptData); - _emc->start(&_npcScript, func); - _npcScript.regs[0] = _currentCharacter->sceneId; - _npcScript.regs[4] = _itemInHand; - _npcScript.regs[5] = func; - - while (_emc->isValid(&_npcScript)) - _emc->run(&_npcScript); +inline int convertValueFromMixer(int value) { + return (value * 95) / Audio::Mixer::kMaxMixerVolume + 2; } -void KyraEngine_v1::checkAmuletAnimFlags() { - debugC(9, kDebugLevelMain, "KyraEngine_v1::checkSpecialAnimFlags()"); - - if (_brandonStatusBit & 2) { - seq_makeBrandonNormal2(); - _timer->setCountdown(19, 300); - } +void KyraEngine_v1::setVolume(kVolumeEntry vol, uint8 value) { + switch (vol) { + case kVolumeMusic: + ConfMan.setInt("music_volume", convertValueToMixer(value)); + break; - if (_brandonStatusBit & 0x20) { - seq_makeBrandonNormal(); - _timer->setCountdown(19, 300); + case kVolumeSfx: + ConfMan.setInt("sfx_volume", convertValueToMixer(value)); + break; + + case kVolumeSpeech: + ConfMan.setInt("speech_volume", convertValueToMixer(value)); + break; } -} - -#pragma mark - - -void KyraEngine_v1::registerDefaultSettings() { - KyraEngine::registerDefaultSettings(); - - // Most settings already have sensible defaults. This one, however, is - // specific to the Kyra engine. - ConfMan.registerDefault("walkspeed", 2); -} - -void KyraEngine_v1::readSettings() { - int talkspeed = ConfMan.getInt("talkspeed"); - - // The default talk speed is 60. This should be mapped to "Normal". - - if (talkspeed == 0) - _configTextspeed = 3; // Clickable - if (talkspeed <= 50) - _configTextspeed = 0; // Slow - else if (talkspeed <= 150) - _configTextspeed = 1; // Normal - else - _configTextspeed = 2; // Fast - KyraEngine::readSettings(); + // Resetup mixer + _mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, ConfMan.getInt("sfx_volume")); + _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, ConfMan.getInt("music_volume")); + _mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, ConfMan.getInt("speech_volume")); + if (_sound) + _sound->updateVolumeSettings(); } -void KyraEngine_v1::writeSettings() { - int talkspeed; - - switch (_configTextspeed) { - case 0: // Slow - talkspeed = 1; - break; - case 1: // Normal - talkspeed = 60; +uint8 KyraEngine_v1::getVolume(kVolumeEntry vol) { + switch (vol) { + case kVolumeMusic: + return convertValueFromMixer(ConfMan.getInt("music_volume")); break; - case 2: // Fast - talkspeed = 255; + + case kVolumeSfx: + return convertValueFromMixer(ConfMan.getInt("sfx_volume")); break; - default: // Clickable - talkspeed = 0; + + case kVolumeSpeech: + if (speechEnabled()) + return convertValueFromMixer(ConfMan.getInt("speech_volume")); + else + return 2; break; } - ConfMan.setInt("talkspeed", talkspeed); - - KyraEngine::writeSettings(); + return 2; } -} // end of namespace Kyra +} // End of namespace Kyra + diff --git a/engines/kyra/kyra_v1.h b/engines/kyra/kyra_v1.h index 50791c3ade..4f38ceca98 100644 --- a/engines/kyra/kyra_v1.h +++ b/engines/kyra/kyra_v1.h @@ -26,796 +26,281 @@ #ifndef KYRA_KYRA_V1_H #define KYRA_KYRA_V1_H -#include "kyra/kyra.h" +#include "engines/engine.h" + +#include "common/array.h" +#include "common/events.h" + #include "kyra/script.h" -#include "kyra/screen_v1.h" -#include "kyra/gui_v1.h" + +namespace Common { +class InSaveFile; +class OutSaveFile; +} // end of namespace Common + +class KyraMetaEngine; namespace Kyra { -class Movie; -class SoundDigital; -class SeqPlayer; -class Sprites; -class Debugger; -class Animator_v1; -class TextDisplayer; -class KyraEngine_v1; - -struct Character { - uint16 sceneId; - uint8 height; - uint8 facing; - uint16 currentAnimFrame; - uint8 inventoryItems[10]; - int16 x1, y1, x2, y2; -}; +struct GameFlags { + Common::Language lang; + Common::Platform platform; -struct Shape { - uint8 imageIndex; - int8 xOffset, yOffset; - uint8 x, y, w, h; -}; + 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; + bool useInstallerPackage : 1; -struct Room { - uint8 nameIndex; - uint16 northExit; - uint16 eastExit; - uint16 southExit; - uint16 westExit; - uint8 itemsTable[12]; - uint16 itemsXPos[12]; - uint8 itemsYPos[12]; - uint8 needInit[12]; + byte gameID; }; -struct Item { - uint8 unk1; - uint8 height; - uint8 unk2; - uint8 unk3; +enum { + GI_KYRA1 = 0, + GI_KYRA2 = 1, + GI_KYRA3 = 2 }; -struct SeqLoop { - const uint8 *ptr; - uint16 count; +struct AudioDataStruct { + const char * const *_fileList; + const int _fileListLen; + const void * const _cdaTracks; + const int _cdaNumTracks; }; -struct SceneExits { - uint16 northXPos; - uint8 northYPos; - uint16 eastXPos; - uint8 eastYPos; - uint16 southXPos; - uint8 southYPos; - uint16 westXPos; - uint8 westYPos; +// TODO: this is just the start of makeing the debug output of the kyra engine a bit more useable +// 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 "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 + kDebugLevelAnimator = 1 << 5, // prints debug output of "ScreenAnimator" functions + kDebugLevelMain = 1 << 6, // prints debug output of common "KyraEngine(_v#)" functions && "TextDisplayer" functions + kDebugLevelGUI = 1 << 7, // prints debug output of "KyraEngine*" gui functions + kDebugLevelSequence = 1 << 8, // prints debug output of "SeqPlayer" functions + kDebugLevelMovie = 1 << 9, // prints debug output of movie specific funtions + kDebugLevelTimer = 1 << 10 // prints debug output of "TimerManager" functions }; -struct BeadState { - int16 x; - int16 y; - int16 width; - int16 height; - int16 dstX; - int16 dstY; - int16 width2; - int16 unk8; - int16 unk9; - int16 tableIndex; +enum kMusicDataID { + kMusicIntro = 0, + kMusicIngame, + kMusicFinale }; -class KyraEngine_v1 : public KyraEngine { - friend class MusicPlayer; - friend class Debugger_v1; - friend class Animator_v1; - friend class GUI_v1; +class Screen; +class Resource; +class Sound; +class Movie; +class TextDisplayer; +class StaticResource; +class TimerManager; +class Debugger; + +class KyraEngine_v1 : public Engine { +friend class Debugger; +friend class ::KyraMetaEngine; +friend class GUI; public: KyraEngine_v1(OSystem *system, const GameFlags &flags); - ~KyraEngine_v1(); + virtual ~KyraEngine_v1(); + + ::GUI::Debugger *getDebugger(); - Screen *screen() { return _screen; } - Animator_v1 *animator() { return _animator; } - virtual Movie *createWSAMovie(); + virtual void pauseEngineIntern(bool pause); - uint8 **shapes() { return _shapes; } - Character *currentCharacter() { return _currentCharacter; } - Character *characterList() { return _characterList; } - uint16 brandonStatus() { return _brandonStatusBit; } + bool quit() const { return _quitFlag; } - // TODO: remove me with workaround in animator.cpp l209 - uint16 getScene() { return _currentRoom; } + uint8 game() const { return _flags.gameID; } + const GameFlags &gameFlags() const { return _flags; } - int _paletteChanged; - int16 _northExitHeight; + // access to Kyra specific functionallity + Resource *resource() { return _res; } + virtual Screen *screen() = 0; + virtual TextDisplayer *text() { return _text; } + Sound *sound() { return _sound; } + StaticResource *staticres() { return _staticres; } + TimerManager *timer() { return _timer; } - typedef void (KyraEngine_v1::*IntroProc)(); + uint32 tickLength() const { return _tickLength; } - // static data access - const char * const*seqWSATable() { return _seq_WSATable; } - const char * const*seqCPSTable() { return _seq_CPSTable; } - const char * const*seqCOLTable() { return _seq_COLTable; } - const char * const*seqTextsTable() { return _seq_textsTable; } + Common::RandomSource _rnd; - const uint8 * const*palTable1() { return &_specialPalettes[0]; } - const uint8 * const*palTable2() { return &_specialPalettes[29]; } + // input + void setMousePos(int x, int y); + Common::Point getMousePos() const; + + // config specific + bool speechEnabled(); + bool textEnabled(); + + enum kVolumeEntry { + kVolumeMusic = 0, + kVolumeSfx = 1, + kVolumeSpeech = 2 + }; + + // volume reaches from 2 to 97 + void setVolume(kVolumeEntry vol, uint8 value); + uint8 getVolume(kVolumeEntry vol); + + // quit handling + virtual void quitGame(); + + // game flag handling + int setGameFlag(int flag); + int queryGameFlag(int flag) const; + int resetGameFlag(int flag); + + // sound + virtual void snd_playTheme(int file, int track); + 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(); + virtual void snd_stopVoice(); + + // delay functionallity + virtual void delayUntil(uint32 timestamp, bool updateGameTimers = false, bool update = false, bool isMainLoop = false); + virtual void delay(uint32 millis, bool update = false, bool isMainLoop = false); + virtual void delayWithTicks(int ticks); protected: - virtual int go(); + virtual int go() = 0; virtual int init(); -public: - // sequences - // -> misc - bool seq_skipSequence() const; -protected: - // -> demo - void seq_demo(); - - // -> intro - void seq_intro(); - void seq_introLogos(); - void seq_introStory(); - void seq_introMalcolmTree(); - void seq_introKallakWriting(); - void seq_introKallakMalcolm(); - - // -> ingame animations - void seq_createAmuletJewel(int jewel, int page, int noSound, int drawOnly); - void seq_brandonHealing(); - void seq_brandonHealing2(); - void seq_poisonDeathNow(int now); - void seq_poisonDeathNowAnim(); - void seq_playFluteAnimation(); - void seq_winterScroll1(); - void seq_winterScroll2(); - void seq_makeBrandonInv(); - void seq_makeBrandonNormal(); - void seq_makeBrandonNormal2(); - void seq_makeBrandonWisp(); - void seq_dispelMagicAnimation(); - void seq_fillFlaskWithWater(int item, int type); - void seq_playDrinkPotionAnim(int item, int unk2, int flags); - void seq_brandonToStone(); - - // -> end fight - int seq_playEnd(); - void seq_playEnding(); - - int handleMalcolmFlag(); - int handleBeadState(); - void initBeadState(int x, int y, int x2, int y2, int unk1, BeadState *ptr); - int processBead(int x, int y, int &x2, int &y2, BeadState *ptr); - - // -> credits - void seq_playCredits(); + // quit Handling + bool _quitFlag; -public: - // delay - void delayUntil(uint32 timestamp, bool updateGameTimers = false, bool update = false, bool isMainLoop = false); - void delay(uint32 millis, bool update = false, bool isMainLoop = false); - void delayWithTicks(int ticks); - void waitForEvent(); - - // TODO - void registerDefaultSettings(); - void readSettings(); - void writeSettings(); - - void snd_playSoundEffect(int track, int volume=0xFF); - void snd_playWanderScoreViaMap(int command, int restart); - virtual void snd_playVoiceFile(int id); - void snd_voiceWaitForFinish(bool ingame = true); + // intern + Resource *_res; + Sound *_sound; + TextDisplayer *_text; + StaticResource *_staticres; + TimerManager *_timer; + EMCInterpreter *_emc; + Debugger *_debugger; -protected: - void saveGame(const char *fileName, const char *saveName); - void loadGame(const char *fileName); + // config specific + virtual void registerDefaultSettings(); + virtual void readSettings(); + virtual void writeSettings(); -protected: - // input - void processInput(); - int processInputHelper(int xpos, int ypos); - int clickEventHandler(int xpos, int ypos); - void clickEventHandler2(); - void updateMousePointer(bool forceUpdate = false); - bool hasClickedOnExit(int xpos, int ypos); - - bool _skipFlag; - bool skipFlag() const { return _skipFlag; } - void resetSkipFlag(bool removeEvent = true) { _skipFlag = false; } - - // scene - // -> init - void loadSceneMsc(); - void startSceneScript(int brandonAlive); - void setupSceneItems(); - void initSceneData(int facing, int unk1, int brandonAlive); - void initSceneObjectList(int brandonAlive); - void initSceneScreen(int brandonAlive); - void setupSceneResource(int sceneId); - - // -> process - void enterNewScene(int sceneId, int facing, int unk1, int unk2, int brandonAlive); - int handleSceneChange(int xpos, int ypos, int unk1, int frameReset); - int processSceneChange(int *table, int unk1, int frameReset); - int changeScene(int facing); - - // -> modification - void transcendScenes(int roomIndex, int roomName); - void setSceneFile(int roomIndex, int roomName); - - // -> pathfinder - int findWay(int x, int y, int toX, int toY, int *moveTable, int moveTableSize); - bool lineIsPassable(int x, int y); - - // -> item handling - // --> misc - void addItemToRoom(uint16 sceneId, uint8 item, int itemIndex, int x, int y); - - // --> drop handling - void itemDropDown(int x, int y, int destX, int destY, byte freeItem, int item); - int processItemDrop(uint16 sceneId, uint8 item, int x, int y, int unk1, int unk2); - void dropItem(int unk1, int item, int x, int y, int unk2); - - // --> dropped item handling - int countItemsInScene(uint16 sceneId); - void exchangeItemWithMouseItem(uint16 sceneId, int itemIndex); - byte findFreeItemInScene(int scene); - byte findItemAtPos(int x, int y); - - // --> drop area handling - void addToNoDropRects(int x, int y, int w, int h); - void clearNoDropRects(); - int isDropable(int x, int y); - int checkNoDropRects(int x, int y); - - // --> player items handling - void updatePlayerItemsForScene(); - - // --> item GFX handling - void backUpItemRect0(int xpos, int ypos); - void restoreItemRect0(int xpos, int ypos); - void backUpItemRect1(int xpos, int ypos); - void restoreItemRect1(int xpos, int ypos); + uint8 _configWalkspeed; - // items - // -> misc - void placeItemInGenericMapScene(int item, int index); - - // -> mouse item - void createMouseItem(int item); - void destroyMouseItem(); - void setMouseItem(int item); - - // -> graphics effects - void wipeDownMouseItem(int xpos, int ypos); - void itemSpecialFX(int x, int y, int item); - void itemSpecialFX1(int x, int y, int item); - void itemSpecialFX2(int x, int y, int item); - void magicOutMouseItem(int animIndex, int itemPos); - void magicInMouseItem(int animIndex, int item, int itemPos); - void specialMouseItemFX(int shape, int x, int y, int animIndex, int tableIndex, int loopStart, int maxLoops); - void processSpecialMouseItemFX(int shape, int x, int y, int tableValue, int loopStart, int maxLoops); - - // character - // -> movement - void moveCharacterToPos(int character, int facing, int xpos, int ypos); - void setCharacterPositionWithUpdate(int character); - int setCharacterPosition(int character, int *facingTable); - void setCharacterPositionHelper(int character, int *facingTable); - void setCharactersPositions(int character); - - // -> brandon - void setBrandonPoisonFlags(int reset); - void resetBrandonPoisonFlags(); - - // chat - // -> process - void characterSays(int vocFile, const char *chatStr, int8 charNum, int8 chatDuration); - void waitForChatToFinish(int vocFile, int16 chatDuration, const char *str, uint8 charNum); - - // -> initialization - int initCharacterChat(int8 charNum); - void backupChatPartnerAnimFrame(int8 charNum); - void restoreChatPartnerAnimFrame(int8 charNum); - int8 getChatPartnerNum(); - - // -> deinitialization - void endCharacterChat(int8 charNum, int16 arg_4); - - // graphics - // -> misc - int findDuplicateItemShape(int shape); - void updateKyragemFading(); - - // -> interface - void loadMainScreen(int page = 3); - void redrawInventory(int page); -public: - void drawSentenceCommand(const char *sentence, int unk1); - void updateSentenceCommand(const char *str1, const char *str2, int unk1); - void updateTextFade(); + int _configMusic; + bool _configSounds; + uint8 _configVoice; -protected: - // -> amulet - void drawJewelPress(int jewel, int drawSpecial); - void drawJewelsFadeOutStart(); - void drawJewelsFadeOutEnd(int jewel); - - // -> shape handling - void setupShapes123(const Shape *shapeTable, int endShape, int flags); - void freeShapes123(); - - // misc (TODO) - void startup(); - void mainLoop(); - - int checkForNPCScriptRun(int xpos, int ypos); - void runNpcScript(int func); - - void loadMouseShapes(); - void loadCharacterShapes(); - void loadSpecialEffectShapes(); - void loadItems(); - void loadButtonShapes(); - void initMainButtonList(); - void setCharactersInDefaultScene(); - void setupPanPages(); - void freePanPages(); - void closeFinalWsa(); - - //void setTimer19(); - void setupTimers(); - void timerUpdateHeadAnims(int timerNum); - void timerSetFlags1(int timerNum); - void timerSetFlags2(int timerNum); - void timerSetFlags3(int timerNum); - void timerCheckAnimFlag1(int timerNum); - void timerCheckAnimFlag2(int timerNum); - void checkAmuletAnimFlags(); - void timerRedrawAmulet(int timerNum); - void timerFadeText(int timerNum); - void updateAnimFlag1(int timerNum); - void updateAnimFlag2(int timerNum); - void drawAmulet(); - void setTextFadeTimerCountdown(int16 countdown); - void setWalkspeed(uint8 newSpeed); - - int buttonInventoryCallback(Button *caller); - int buttonAmuletCallback(Button *caller); - - bool _skipIntroFlag; - bool _abortIntroFlag; - bool _menuDirectlyToLoad; - bool _abortWalkFlag; - bool _abortWalkFlag2; - bool _mousePressFlag; - uint8 *_itemBkgBackUp[2]; - uint8 *_shapes[373]; - int8 _itemInHand; - int _mouseState; - bool _handleInput; - bool _changedScene; - int _unkScreenVar1, _unkScreenVar2, _unkScreenVar3; - int _beadStateVar; - int _unkAmuletVar; - - int _malcolmFlag; - int _endSequenceSkipFlag; - int _endSequenceNeedLoading; - int _unkEndSeqVar2; - uint8 *_endSequenceBackUpRect; - int _unkEndSeqVar4; - int _unkEndSeqVar5; - int _lastDisplayedPanPage; - uint8 *_panPagesTable[20]; - Movie *_finalA, *_finalB, *_finalC; - - Movie *_movieObjects[10]; - - uint16 _entranceMouseCursorTracks[8]; - uint16 _walkBlockNorth; - uint16 _walkBlockEast; - uint16 _walkBlockSouth; - uint16 _walkBlockWest; - - int32 _scaleMode; - int16 _scaleTable[145]; - - Rect _noDropRects[11]; - - int8 _birthstoneGemTable[4]; - int8 _idolGemsTable[3]; - - int8 _marbleVaseItem; - int8 _foyerItemTable[3]; - - int8 _cauldronState; - int8 _crystalState[2]; - - uint16 _brandonStatusBit; - uint8 _brandonStatusBit0x02Flag; - uint8 _brandonStatusBit0x20Flag; - uint8 _brandonPoisonFlagsGFX[256]; - uint8 _deathHandler; - int16 _brandonInvFlag; - uint8 _poisonDeathCounter; - int _brandonPosX; - int _brandonPosY; - - uint16 _currentChatPartnerBackupFrame; - uint16 _currentCharAnimFrame; - - int8 *_sceneAnimTable[50]; - - Item _itemTable[145]; - int _lastProcessedItem; - int _lastProcessedItemHeight; - - int16 *_exitListPtr; - int16 _exitList[11]; - SceneExits _sceneExits; - uint16 _currentRoom; - int _scenePhasingFlag; - - int _sceneChangeState; - int _loopFlag2; - - int _pathfinderFlag; - int _pathfinderFlag2; - int _lastFindWayRet; - int *_movFacingTable; - - int8 _talkingCharNum; - int8 _charSayUnk2; - int8 _charSayUnk3; - int8 _currHeadShape; - uint8 _currSentenceColor[3]; - int8 _startSentencePalIndex; - bool _fadeText; - - uint8 _configTextspeed; - - Animator_v1 *_animator; - SeqPlayer *_seq; - Sprites *_sprites; - Screen_v1 *_screen; - Debugger *_debugger; + // game speed + virtual bool skipFlag() const = 0; + virtual void resetSkipFlag(bool removeEvent = true) = 0; - EMCState _scriptMain; - - EMCState _npcScript; - EMCData _npcScriptData; - - EMCState _scriptClick; - EMCData _scriptClickData; - - Character *_characterList; - Character *_currentCharacter; - - Button *_buttonList; - GUI_v1 *_gui; - - struct KyragemState { - uint16 nextOperation; - uint16 rOffset; - uint16 gOffset; - uint16 bOffset; - uint32 timerCount; - } _kyragemFadingState; - - static const int8 _dosTrackMap[]; - static const int _dosTrackMapSize; - - // TODO: get rid of all variables having pointers to the static resources if possible - // i.e. let them directly use the _staticres functions - void initStaticResource(); - - const uint8 *_seq_Forest; - const uint8 *_seq_KallakWriting; - const uint8 *_seq_KyrandiaLogo; - const uint8 *_seq_KallakMalcolm; - const uint8 *_seq_MalcolmTree; - const uint8 *_seq_WestwoodLogo; - const uint8 *_seq_Demo1; - const uint8 *_seq_Demo2; - const uint8 *_seq_Demo3; - const uint8 *_seq_Demo4; - const uint8 *_seq_Reunion; - - const char * const*_seq_WSATable; - const char * const*_seq_CPSTable; - const char * const*_seq_COLTable; - const char * const*_seq_textsTable; - - int _seq_WSATable_Size; - int _seq_CPSTable_Size; - int _seq_COLTable_Size; - int _seq_textsTable_Size; - - const char * const*_itemList; - const char * const*_takenList; - const char * const*_placedList; - const char * const*_droppedList; - const char * const*_noDropList; - const char * const*_putDownFirst; - const char * const*_waitForAmulet; - const char * const*_blackJewel; - const char * const*_poisonGone; - const char * const*_healingTip; - const char * const*_thePoison; - const char * const*_fluteString; - const char * const*_wispJewelStrings; - const char * const*_magicJewelString; - const char * const*_flaskFull; - const char * const*_fullFlask; - const char * const*_veryClever; - const char * const*_homeString; - const char * const*_newGameString; - - int _itemList_Size; - int _takenList_Size; - int _placedList_Size; - int _droppedList_Size; - int _noDropList_Size; - int _putDownFirst_Size; - int _waitForAmulet_Size; - int _blackJewel_Size; - int _poisonGone_Size; - int _healingTip_Size; - int _thePoison_Size; - int _fluteString_Size; - int _wispJewelStrings_Size; - int _magicJewelString_Size; - int _flaskFull_Size; - int _fullFlask_Size; - int _veryClever_Size; - int _homeString_Size; - int _newGameString_Size; - - const char * const*_characterImageTable; - int _characterImageTableSize; - - const char * const*_guiStrings; - int _guiStringsSize; - - const char * const*_configStrings; - int _configStringsSize; - - Shape *_defaultShapeTable; - int _defaultShapeTableSize; - - const Shape *_healingShapeTable; - int _healingShapeTableSize; - const Shape *_healingShape2Table; - int _healingShape2TableSize; - - const Shape *_posionDeathShapeTable; - int _posionDeathShapeTableSize; - - const Shape *_fluteAnimShapeTable; - int _fluteAnimShapeTableSize; - - const Shape *_winterScrollTable; - int _winterScrollTableSize; - const Shape *_winterScroll1Table; - int _winterScroll1TableSize; - const Shape *_winterScroll2Table; - int _winterScroll2TableSize; - - const Shape *_drinkAnimationTable; - int _drinkAnimationTableSize; - - const Shape *_brandonToWispTable; - int _brandonToWispTableSize; - - const Shape *_magicAnimationTable; - int _magicAnimationTableSize; - - const Shape *_brandonStoneTable; - int _brandonStoneTableSize; - - Room *_roomTable; - int _roomTableSize; - const char * const*_roomFilenameTable; - int _roomFilenameTableSize; - - const uint8 *_amuleteAnim; - - const uint8 * const*_specialPalettes; - - const char *const *_soundFiles; - int _soundFilesSize; - const char *const *_soundFilesIntro; - int _soundFilesIntroSize; - const int32 *_cdaTrackTable; - int _cdaTrackTableSize; - const AudioDataStruct * _soundData; - - static const int8 _charXPosTable[]; - static const int8 _charYPosTable[]; - - // positions of the inventory - static const uint16 _itemPosX[]; - static const uint8 _itemPosY[]; - - void setupButtonData(); - Button *_buttonData; - Button **_buttonDataListPtr; - - static const uint8 _magicMouseItemStartFrame[]; - static const uint8 _magicMouseItemEndFrame[]; - static const uint8 _magicMouseItemStartFrame2[]; - static const uint8 _magicMouseItemEndFrame2[]; - - static const uint16 _amuletX[]; - static const uint16 _amuletY[]; - static const uint16 _amuletX2[]; - static const uint16 _amuletY2[]; -protected: - void setupOpcodeTable(); + uint16 _tickLength; + uint16 _gameSpeed; + + // run + int8 _deathHandler; + + // timer + virtual void setupTimers() = 0; + + virtual void setWalkspeed(uint8 speed) = 0; + + // detection + GameFlags _flags; + int _lang; + + // opcode + virtual void setupOpcodeTable() = 0; + Common::Array<const Opcode*> _opcodes; - // Opcodes - int o1_magicInMouseItem(EMCState *script); - int o1_characterSays(EMCState *script); - int o1_pauseTicks(EMCState *script); - int o1_drawSceneAnimShape(EMCState *script); int o1_queryGameFlag(EMCState *script); int o1_setGameFlag(EMCState *script); int o1_resetGameFlag(EMCState *script); - int o1_runNPCScript(EMCState *script); - int o1_setSpecialExitList(EMCState *script); - int o1_blockInWalkableRegion(EMCState *script); - int o1_blockOutWalkableRegion(EMCState *script); - int o1_walkPlayerToPoint(EMCState *script); - int o1_dropItemInScene(EMCState *script); - int o1_drawAnimShapeIntoScene(EMCState *script); - int o1_createMouseItem(EMCState *script); - int o1_savePageToDisk(EMCState *script); - int o1_sceneAnimOn(EMCState *script); - int o1_sceneAnimOff(EMCState *script); - int o1_getElapsedSeconds(EMCState *script); - int o1_mouseIsPointer(EMCState *script); - int o1_destroyMouseItem(EMCState *script); - int o1_runSceneAnimUntilDone(EMCState *script); - int o1_fadeSpecialPalette(EMCState *script); - int o1_playAdlibSound(EMCState *script); - int o1_playAdlibScore(EMCState *script); - int o1_phaseInSameScene(EMCState *script); - int o1_setScenePhasingFlag(EMCState *script); - int o1_resetScenePhasingFlag(EMCState *script); - int o1_queryScenePhasingFlag(EMCState *script); - int o1_sceneToDirection(EMCState *script); - int o1_setBirthstoneGem(EMCState *script); - int o1_placeItemInGenericMapScene(EMCState *script); - int o1_setBrandonStatusBit(EMCState *script); - int o1_pauseSeconds(EMCState *script); - int o1_getCharactersLocation(EMCState *script); - int o1_runNPCSubscript(EMCState *script); - int o1_magicOutMouseItem(EMCState *script); - int o1_internalAnimOn(EMCState *script); - int o1_forceBrandonToNormal(EMCState *script); - int o1_poisonDeathNow(EMCState *script); - int o1_setScaleMode(EMCState *script); - int o1_openWSAFile(EMCState *script); - int o1_closeWSAFile(EMCState *script); - int o1_runWSAFromBeginningToEnd(EMCState *script); - int o1_displayWSAFrame(EMCState *script); - int o1_enterNewScene(EMCState *script); - int o1_setSpecialEnterXAndY(EMCState *script); - int o1_runWSAFrames(EMCState *script); - int o1_popBrandonIntoScene(EMCState *script); - int o1_restoreAllObjectBackgrounds(EMCState *script); - int o1_setCustomPaletteRange(EMCState *script); - int o1_loadPageFromDisk(EMCState *script); - int o1_customPrintTalkString(EMCState *script); - int o1_restoreCustomPrintBackground(EMCState *script); + int o1_getRand(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_setHandItem(EMCState *script); + int o1_removeHandItem(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_setDeathHandler(EMCState *script); + int o1_playWanderScoreViaMap(EMCState *script); int o1_fillRect(EMCState *script); - int o1_dummy(EMCState *script); - int o1_vocUnload(EMCState *script); - int o1_vocLoad(EMCState *script); + int o1_blockInWalkableRegion(EMCState *script); + int o1_blockOutWalkableRegion(EMCState *script); + int o1_playSoundEffect(EMCState *script); + + // items + int _mouseState; + + virtual void setHandItem(uint16 item) = 0; + virtual void removeHandItem() = 0; + + // game flags + uint8 _flagsTable[100]; // TODO: check this value + + // sound + Common::String _speechFile; + + int _curMusicTheme; + int _curSfxFile; + int16 _lastMusicCommand; + + const int8 *_trackMap; + int _trackMapSize; + + // pathfinder + virtual int findWay(int x, int y, int toX, int toY, int *moveTable, int moveTableSize); + int findSubPath(int x, int y, int toX, int toY, int *moveTable, int start, int end); + int getFacingFromPointToPoint(int x, int y, int toX, int toY); + int getOppositeFacingDirection(int dir); + void changePosTowardsFacing(int &x, int &y, int facing); + int getMoveTableSize(int *moveTable); + virtual bool lineIsPassable(int x, int y) = 0; + + static const int8 _addXPosTable[]; + static const int8 _addYPosTable[]; + + // Character + + static const int8 _charAddXPosTable[]; + static const int8 _charAddYPosTable[]; + + // save/load + int _gameToLoad; + + const char *getSavegameFilename(int num); + bool saveFileLoadable(int slot); + + struct SaveHeader { + Common::String description; + uint32 version; + byte gameID; + uint32 flags; + + bool originalSave; // savegame from original interpreter + bool oldHeader; // old scummvm save header + }; + + enum kReadSaveHeaderError { + kRSHENoError = 0, + kRSHEInvalidType = 1, + kRSHEInvalidVersion = 2, + kRSHEIoError = 3 + }; + + static kReadSaveHeaderError readSaveHeader(Common::InSaveFile *file, SaveHeader &header); + + Common::InSaveFile *openSaveForReading(const char *filename, SaveHeader &header); + Common::OutSaveFile *openSaveForWriting(const char *filename, const char *saveName) const; }; -} // end of namespace Kyra +} // End of namespace Kyra #endif diff --git a/engines/kyra/kyra_v2.cpp b/engines/kyra/kyra_v2.cpp index 176f8e4e2f..12da338843 100644 --- a/engines/kyra/kyra_v2.cpp +++ b/engines/kyra/kyra_v2.cpp @@ -29,7 +29,7 @@ namespace Kyra { -KyraEngine_v2::KyraEngine_v2(OSystem *system, const GameFlags &flags, const EngineDesc &desc) : KyraEngine(system, flags), _desc(desc) { +KyraEngine_v2::KyraEngine_v2(OSystem *system, const GameFlags &flags, const EngineDesc &desc) : KyraEngine_v1(system, flags), _desc(desc) { memset(&_sceneAnims, 0, sizeof(_sceneAnims)); memset(&_sceneAnimMovie, 0, sizeof(_sceneAnimMovie)); @@ -64,18 +64,25 @@ KyraEngine_v2::KyraEngine_v2(OSystem *system, const GameFlags &flags, const Engi memset(_hiddenItems, -1, sizeof(_hiddenItems)); - _debugger = 0; _screenBuffer = 0; + + memset(&_mainCharacter, 0, sizeof(_mainCharacter)); + memset(&_mainCharacter.inventory, -1, sizeof(_mainCharacter.inventory)); + + _pauseStart = 0; } KyraEngine_v2::~KyraEngine_v2() { - for (ShapeMap::iterator i = _gameShapes.begin(); i != _gameShapes.end(); ++i) { - delete[] i->_value; - i->_value = 0; + if (!(_flags.isDemo && !_flags.isTalkie)) { + for (ShapeMap::iterator i = _gameShapes.begin(); i != _gameShapes.end(); ++i) { + delete[] i->_value; + i->_value = 0; + } + _gameShapes.clear(); } - _gameShapes.clear(); delete[] _itemList; + delete[] _sceneList; _emc->unload(&_sceneScriptData); @@ -85,15 +92,50 @@ KyraEngine_v2::~KyraEngine_v2() { delete *i; _opcodesAnimation.clear(); - delete _debugger; delete[] _screenBuffer; } +void KyraEngine_v2::pauseEngineIntern(bool pause) { + KyraEngine_v1::pauseEngineIntern(pause); + + if (!pause) { + uint32 pausedTime = _system->getMillis() - _pauseStart; + + for (int i = 0; i < ARRAYSIZE(_sceneSpecialScriptsTimer); ++i) { + if (_sceneSpecialScriptsTimer[i]) + _sceneSpecialScriptsTimer[i] += pausedTime; + } + + } else { + _pauseStart = _system->getMillis(); + } +} + +void KyraEngine_v2::delay(uint32 amount, bool updateGame, bool isMainLoop) { + debugC(9, kDebugLevelMain, "KyraEngine_v2::delay(%u, %d, %d)", amount, updateGame, 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); +} + int KyraEngine_v2::checkInput(Button *buttonList, bool mainLoop) { debugC(9, kDebugLevelMain, "KyraEngine_v2::checkInput(%p, %d)", (const void*)buttonList, mainLoop); updateInput(); int keys = 0; + int8 mouseWheel = 0; while (_eventList.size()) { Common::Event event = *_eventList.begin(); @@ -135,6 +177,14 @@ int KyraEngine_v2::checkInput(Button *buttonList, bool mainLoop) { breakLoop = true; } break; + case Common::EVENT_WHEELUP: + mouseWheel = -1; + break; + + case Common::EVENT_WHEELDOWN: + mouseWheel = 1; + break; + default: break; } @@ -148,7 +198,7 @@ int KyraEngine_v2::checkInput(Button *buttonList, bool mainLoop) { _eventList.erase(_eventList.begin()); } - return gui_v2()->processButtonList(buttonList, keys | 0x8000); + return gui_v2()->processButtonList(buttonList, keys | 0x8000, mouseWheel); } void KyraEngine_v2::updateInput() { @@ -178,6 +228,8 @@ void KyraEngine_v2::updateInput() { // fall through case Common::EVENT_LBUTTONUP: + case Common::EVENT_WHEELUP: + case Common::EVENT_WHEELDOWN: _eventList.push_back(event); break; @@ -223,20 +275,18 @@ 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::addShapeToPool(uint8 *shpData, int index) { debugC(9, kDebugLevelMain, "KyraEngine_v2::addShapeToPool(%p, %d)", shpData, index); remShapeFromPool(index); _gameShapes[index] = shpData; - assert(_gameShapes[index]); } void KyraEngine_v2::remShapeFromPool(int idx) { ShapeMap::iterator iter = _gameShapes.find(idx); if (iter != _gameShapes.end()) { - delete [] iter->_value; + delete[] iter->_value; iter->_value = 0; } } @@ -294,8 +344,8 @@ 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; - _mainCharacter.x1 += _updateCharPosXTable[_mainCharacter.facing]; - _mainCharacter.y1 += _updateCharPosYTable[_mainCharacter.facing]; + _mainCharacter.x1 += _charAddXPosTable[_mainCharacter.facing]; + _mainCharacter.y1 += _charAddYPosTable[_mainCharacter.facing]; updateCharAnimFrame(0, table); _updateCharPosNextUpdate = _system->getMillis() + getCharacterWalkspeed() * _tickLength; return 1; diff --git a/engines/kyra/kyra_v2.h b/engines/kyra/kyra_v2.h index f0d26ca011..24f7aad614 100644 --- a/engines/kyra/kyra_v2.h +++ b/engines/kyra/kyra_v2.h @@ -26,7 +26,7 @@ #ifndef KYRA_KYRA_V2_H #define KYRA_KYRA_V2_H -#include "kyra/kyra.h" +#include "kyra/kyra_v1.h" #include "kyra/gui.h" #include "kyra/wsamovie.h" @@ -35,10 +35,25 @@ namespace Kyra { +struct FrameControl { + uint16 index; + uint16 delay; +}; + +struct ItemAnimData_v2 { + int16 itemIndex; + uint8 numFrames; + const FrameControl *frames; +}; + +struct ActiveItemAnim { + uint16 currentFrame; + uint32 nextFrame; +}; + class Screen_v2; -class Debugger_v2; -class KyraEngine_v2 : public KyraEngine { +class KyraEngine_v2 : public KyraEngine_v1 { friend class Debugger_v2; friend class GUI_v2; public: @@ -52,23 +67,29 @@ public: // Animation script specific const int animScriptFrameAdd; + + // Item specific + const int maxItemId; }; KyraEngine_v2(OSystem *system, const GameFlags &flags, const EngineDesc &desc); ~KyraEngine_v2(); + virtual void pauseEngineIntern(bool pause); + virtual Screen_v2 *screen_v2() const = 0; virtual GUI *gui_v2() const = 0; + void delay(uint32 time, bool update = false, bool isMainLoop = false); + const EngineDesc &engineDesc() const { return _desc; } protected: EngineDesc _desc; - Debugger_v2 *_debugger; // run + uint32 _pauseStart; bool _runFlag; bool _showOutro; - int8 _deathHandler; virtual void update() = 0; virtual void updateWithText() = 0; @@ -211,7 +232,7 @@ protected: }; SceneAnim _sceneAnims[16]; - WSAMovieV2 *_sceneAnimMovie[16]; + WSAMovie_v2 *_sceneAnimMovie[16]; void freeSceneAnims(); @@ -299,7 +320,6 @@ protected: int _itemListSize; int _itemInHand; - int _handItemSet; int findFreeItem(); int countAllItems(); @@ -338,8 +358,6 @@ protected: void updateCharPosWithUpdate(); uint32 _updateCharPosNextUpdate; - static const int8 _updateCharPosXTable[]; - static const int8 _updateCharPosYTable[]; virtual int getCharacterWalkspeed() const = 0; virtual void updateCharAnimFrame(int num, int *table) = 0; @@ -374,22 +392,10 @@ protected: 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); diff --git a/engines/kyra/module.mk b/engines/kyra/module.mk index aec2778def..ebb63b4b4e 100644 --- a/engines/kyra/module.mk +++ b/engines/kyra/module.mk @@ -1,49 +1,50 @@ MODULE := engines/kyra MODULE_OBJS := \ - animator_v1.o \ + animator_lok.o \ animator_v2.o \ animator_hof.o \ animator_mr.o \ debugger.o \ detection.o \ gui.o \ - gui_v1.o \ + gui_lok.o \ gui_v2.o \ gui_hof.o \ gui_mr.o \ - items_v1.o \ + items_lok.o \ items_v2.o \ items_hof.o \ items_mr.o \ - kyra.o \ kyra_v1.o \ + kyra_lok.o \ kyra_v2.o \ kyra_hof.o \ kyra_mr.o \ resource.o \ saveload.o \ - saveload_v1.o \ + saveload_lok.o \ saveload_hof.o \ saveload_mr.o \ - scene.o \ scene_v1.o \ + scene_lok.o \ scene_v2.o \ scene_hof.o \ scene_mr.o \ screen.o \ - screen_v1.o \ + screen_lok.o \ screen_v2.o \ screen_hof.o \ screen_mr.o \ script_v1.o \ + script_lok.o \ script_v2.o \ script_hof.o \ script_mr.o \ script.o \ script_tim.o \ seqplayer.o \ - sequences_v1.o \ + sequences_lok.o \ sequences_v2.o \ sequences_hof.o \ sequences_mr.o \ @@ -51,15 +52,15 @@ MODULE_OBJS := \ sound_digital.o \ sound_towns.o \ sound.o \ - sound_v1.o \ + sound_lok.o \ sprites.o \ staticres.o \ text.o \ - text_v1.o \ + text_lok.o \ text_hof.o \ text_mr.o \ timer.o \ - timer_v1.o \ + timer_lok.o \ timer_hof.o \ timer_mr.o \ vqa.o \ diff --git a/engines/kyra/resource.cpp b/engines/kyra/resource.cpp index b2564221fc..afd7eacfda 100644 --- a/engines/kyra/resource.cpp +++ b/engines/kyra/resource.cpp @@ -30,22 +30,24 @@ #include "common/fs.h" #include "common/func.h" -#include "gui/message.h" - #include "kyra/resource.h" namespace Kyra { -Resource::Resource(KyraEngine *vm) : _loaders(), _map(), _vm(vm) { +Resource::Resource(KyraEngine_v1 *vm) : _loaders(), _map(), _vm(vm) { initializeLoaders(); } Resource::~Resource() { _map.clear(); _loaders.clear(); + + clearCompFileList(); + _compLoaders.clear(); } bool Resource::reset() { + clearCompFileList(); unloadAllPakFiles(); FilesystemNode dir(ConfMan.get("path")); @@ -53,13 +55,10 @@ bool Resource::reset() { if (!dir.exists() || !dir.isDirectory()) error("invalid game path '%s'", dir.getPath().c_str()); - if (_vm->game() != GI_KYRA3) { - if (!loadPakFile(StaticResource::staticDataFilename()) || !StaticResource::checkKyraDat()) { - Common::String errorMessage = "You're missing the '" + StaticResource::staticDataFilename() + "' file or it got corrupted, (re)get it from the ScummVM website"; - ::GUI::MessageDialog errorMsg(errorMessage); - errorMsg.runModal(); - error(errorMessage.c_str()); - } + if (!loadPakFile(StaticResource::staticDataFilename()) || !StaticResource::checkKyraDat()) { + Common::String errorMessage = "You're missing the '" + StaticResource::staticDataFilename() + "' file or it got corrupted, (re)get it from the ScummVM website"; + _vm->GUIErrorMessage(errorMessage); + error(errorMessage.c_str()); } if (_vm->game() == GI_KYRA1) { @@ -71,17 +70,32 @@ bool Resource::reset() { if (_vm->gameFlags().isTalkie) loadPakFile("CHAPTER1.VRM"); } else if (_vm->game() == GI_KYRA2) { + if (_vm->gameFlags().useInstallerPackage) + tryLoadCompFiles(); + // mouse pointer, fonts, etc. required for initializing if (_vm->gameFlags().isDemo && !_vm->gameFlags().isTalkie) { loadPakFile("GENERAL.PAK"); } else { + if (_vm->gameFlags().isTalkie) { + // Add default file directories + Common::File::addDefaultDirectory(ConfMan.get("path") + "hof_cd"); + Common::File::addDefaultDirectory(ConfMan.get("path") + "HOF_CD"); + } + loadPakFile("INTROGEN.PAK"); loadPakFile("OTHER.PAK"); } return true; } else if (_vm->game() == GI_KYRA3) { - loadPakFile("WESTWOOD.001"); + if (_vm->gameFlags().useInstallerPackage) + loadPakFile("WESTWOOD.001"); + + // Add default file directories + Common::File::addDefaultDirectory(ConfMan.get("path") + "malcolm"); + Common::File::addDefaultDirectory(ConfMan.get("path") + "MALCOLM"); + loadFileList("FILEDATA.FDT"); return true; @@ -212,7 +226,7 @@ bool Resource::loadFileList(const Common::String &filedata) { buffer[12] = 0; f.seek(offset + 16, SEEK_SET); - Common::String filename = (char*)buffer; + Common::String filename = Common::String((char*)buffer); filename.toUppercase(); if (filename.hasSuffix(".PAK")) { @@ -253,6 +267,13 @@ void Resource::unloadPakFile(const Common::String &filename) { } } +void Resource::clearCompFileList() { + for (CompFileMap::iterator i = _compFiles.begin(); i != _compFiles.end(); ++i) + delete[] i->_value.data; + + _compFiles.clear(); +} + bool Resource::isInPakList(const Common::String &filename) { if (!isAccessable(filename)) return false; @@ -293,6 +314,8 @@ bool Resource::exists(const char *file, bool errorOutOnFail) { } uint32 Resource::getFileSize(const char *file) { + CompFileMap::iterator compEntry; + if (Common::File::exists(file)) { Common::File f; if (f.open(file)) @@ -314,12 +337,14 @@ bool Resource::loadFileToBuf(const char *file, void *buf, uint32 maxSize) { return false; memset(buf, 0, maxSize); - stream->read(buf, stream->size()); + stream->read(buf, (maxSize <= stream->size()) ? maxSize : stream->size()); delete stream; return true; } Common::SeekableReadStream *Resource::getFileStream(const Common::String &file) { + CompFileMap::iterator compEntry; + if (Common::File::exists(file)) { Common::File *stream = new Common::File(); if (!stream->open(file)) { @@ -328,6 +353,8 @@ Common::SeekableReadStream *Resource::getFileStream(const Common::String &file) error("Couldn't open file '%s'", file.c_str()); } return stream; + } else if ((compEntry = _compFiles.find(file)) != _compFiles.end()) { + return new Common::MemoryReadStream(compEntry->_value.data, compEntry->_value.size, false); } else { if (!isAccessable(file)) return 0; @@ -376,19 +403,35 @@ bool Resource::isAccessable(const Common::String &file) { } void Resource::checkFile(const Common::String &file) { - if (_map.find(file) == _map.end() && Common::File::exists(file)) { - Common::File temp; - if (temp.open(file)) { + if (_map.find(file) == _map.end()) { + CompFileMap::const_iterator iter; + + if (Common::File::exists(file)) { + Common::File temp; + if (temp.open(file)) { + ResFileEntry entry; + entry.parent = ""; + entry.size = temp.size(); + entry.mounted = file.compareToIgnoreCase(StaticResource::staticDataFilename()) != 0; + entry.preload = false; + entry.prot = false; + entry.type = ResFileEntry::kAutoDetect; + entry.offset = 0; + _map[file] = entry; + temp.close(); + + detectFileTypes(); + } + } else if ((iter = _compFiles.find(file)) != _compFiles.end()) { ResFileEntry entry; entry.parent = ""; - entry.size = temp.size(); - entry.mounted = file.compareToIgnoreCase(StaticResource::staticDataFilename()) != 0; + entry.size = iter->_value.size; + entry.mounted = false; entry.preload = false; entry.prot = false; entry.type = ResFileEntry::kAutoDetect; entry.offset = 0; _map[file] = entry; - temp.close(); detectFileTypes(); } @@ -425,6 +468,13 @@ void Resource::detectFileTypes() { } } +void Resource::tryLoadCompFiles() { + for (CCompLoaderIterator i = _compLoaders.begin(); i != _compLoaders.end(); ++i) { + if ((*i)->checkForFiles()) + (*i)->loadFile(_compFiles); + } +} + #pragma mark - #pragma mark - ResFileLodaer #pragma mark - @@ -492,6 +542,20 @@ bool ResLoaderPak::isLoadable(const Common::String &filename, Common::SeekableRe return true; } +namespace { + +Common::String readString(Common::SeekableReadStream &stream) { + Common::String result; + char c = 0; + + while ((c = stream.readByte()) != 0) + result += c; + + return result; +} + +} // end of anonymous namespace + bool ResLoaderPak::loadFile(const Common::String &filename, Common::SeekableReadStream &stream, FileList &files) const { uint32 filesize = stream.size(); @@ -559,6 +623,33 @@ bool ResLoaderPak::loadFile(const Common::String &filename, Common::SeekableRead startoffset = endoffset; } + FileList::const_iterator iter = Common::find(files.begin(), files.end(), Common::String("LINKLIST")); + if (iter != files.end()) { + stream.seek(iter->entry.offset, SEEK_SET); + + uint32 magic = stream.readUint32BE(); + + if (magic != MKID_BE('SCVM')) + error("LINKLIST file does not contain 'SCVM' header"); + + uint32 links = stream.readUint32BE(); + for (uint i = 0; i < links; ++i) { + Common::String linksTo = readString(stream); + uint32 sources = stream.readUint32BE(); + + iter = Common::find(files.begin(), files.end(), linksTo); + if (iter == files.end()) + error("PAK file link destination '%s' not found", linksTo.c_str()); + + for (uint j = 0; j < sources; ++j) { + Common::String dest = readString(stream); + files.push_back(File(dest, iter->entry)); + // Better safe than sorry, we update the 'iter' value, in case push_back invalidated it + iter = Common::find(files.begin(), files.end(), linksTo); + } + } + } + return true; } @@ -571,7 +662,7 @@ Common::SeekableReadStream *ResLoaderPak::loadFileFromArchive(const Common::Stri return stream; } -class ResLoaderIns : public ResArchiveLoader { +class ResLoaderInsMalcolm : public ResArchiveLoader { public: bool checkFilename(Common::String filename) const; bool isLoadable(const Common::String &filename, Common::SeekableReadStream &stream) const; @@ -579,16 +670,18 @@ public: Common::SeekableReadStream *loadFileFromArchive(const Common::String &file, Common::SeekableReadStream *archive, const ResFileEntry entry) const; ResFileEntry::kType getType() const { - return ResFileEntry::kIns; + return ResFileEntry::kInsMal; } }; -bool ResLoaderIns::checkFilename(Common::String filename) const { +bool ResLoaderInsMalcolm::checkFilename(Common::String filename) const { filename.toUppercase(); - return (filename.hasSuffix(".001")); + if (!filename.hasSuffix(".001")) + return false; + return true; } -bool ResLoaderIns::isLoadable(const Common::String &filename, Common::SeekableReadStream &stream) const { +bool ResLoaderInsMalcolm::isLoadable(const Common::String &filename, Common::SeekableReadStream &stream) const { stream.seek(3); uint32 size = stream.readUint32LE(); @@ -602,7 +695,7 @@ bool ResLoaderIns::isLoadable(const Common::String &filename, Common::SeekableRe return (buffer[0] == 0x0D && buffer[1] == 0x0A); } -bool ResLoaderIns::loadFile(const Common::String &filename, Common::SeekableReadStream &stream, FileList &files) const { +bool ResLoaderInsMalcolm::loadFile(const Common::String &filename, Common::SeekableReadStream &stream, FileList &files) const { Common::List<Common::String> filenames; // thanks to eriktorbjorn for this code (a bit modified though) @@ -647,7 +740,7 @@ bool ResLoaderIns::loadFile(const Common::String &filename, Common::SeekableRead return true; } -Common::SeekableReadStream *ResLoaderIns::loadFileFromArchive(const Common::String &file, Common::SeekableReadStream *archive, const ResFileEntry entry) const { +Common::SeekableReadStream *ResLoaderInsMalcolm::loadFileFromArchive(const Common::String &file, Common::SeekableReadStream *archive, const ResFileEntry entry) const { assert(archive); archive->seek(entry.offset, SEEK_SET); @@ -714,7 +807,7 @@ bool ResLoaderTlk::loadFile(const Common::String &filename, Common::SeekableRead entry.offset = resOffset+4; char realFilename[20]; - snprintf(realFilename, 20, "%u.AUD", resFilename); + snprintf(realFilename, 20, "%.08u.AUD", resFilename); uint32 curOffset = stream.pos(); stream.seek(resOffset, SEEK_SET); @@ -737,11 +830,669 @@ Common::SeekableReadStream *ResLoaderTlk::loadFileFromArchive(const Common::Stri } #pragma mark - +#pragma mark - CompFileLoader +#pragma mark - + +class FileExpanderSource { +public: + FileExpanderSource(const uint8 *data, int dataSize) : _dataPtr(data), _endofBuffer(data + dataSize), _bitsLeft(8), _key(0), _index(0) {} + ~FileExpanderSource() {} + + void advSrcRefresh(); + void advSrcBitsBy1(); + void advSrcBitsByIndex(uint8 newIndex); + + uint8 getKeyLower() { return _key & 0xff; } + void setIndex(uint8 index) { _index = index; } + uint16 getKeyMasked(uint8 newIndex); + uint16 keyMaskedAlign(uint16 val); + + void copyBytes(uint8 *& dst); + +private: + const uint8 *_dataPtr; + const uint8 *_endofBuffer; + uint16 _key; + int8 _bitsLeft; + uint8 _index; +}; + +void FileExpanderSource::advSrcBitsBy1() { + _key >>= 1; + if (!--_bitsLeft) { + if (_dataPtr < _endofBuffer) + _key = ((*_dataPtr++) << 8 ) | (_key & 0xff); + _bitsLeft = 8; + } +} + +void FileExpanderSource::advSrcBitsByIndex(uint8 newIndex) { + _index = newIndex; + _bitsLeft -= _index; + if (_bitsLeft <= 0) { + _key >>= (_index + _bitsLeft); + _index = -_bitsLeft; + _bitsLeft = 8 - _index; + if (_dataPtr < _endofBuffer) + _key = (*_dataPtr++ << 8) | (_key & 0xff); + } + _key >>= _index; +} + +uint16 FileExpanderSource::getKeyMasked(uint8 newIndex) { + static const uint8 mskTable[] = { 0x0F, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF }; + _index = newIndex; + uint16 res = 0; + + if (_index > 8) { + newIndex = _index - 8; + res = (_key & 0xff) & mskTable[8]; + advSrcBitsByIndex(8); + _index = newIndex; + res |= (((_key & 0xff) & mskTable[_index]) << 8); + advSrcBitsByIndex(_index); + } else { + res = (_key & 0xff) & mskTable[_index]; + advSrcBitsByIndex(_index); + } + + return res; +} + +void FileExpanderSource::copyBytes(uint8 *& dst) { + advSrcBitsByIndex(_bitsLeft); + uint16 r = (READ_LE_UINT16(_dataPtr) ^ _key) + 1; + _dataPtr += 2; + + if (r) + error("decompression failure"); + + memcpy(dst, _dataPtr, _key); + _dataPtr += _key; + dst += _key; +} + +uint16 FileExpanderSource::keyMaskedAlign(uint16 val) { + val -= 0x101; + _index = (val & 0xff) >> 2; + int16 b = ((_bitsLeft << 8) | _index) - 1; + _bitsLeft = b >> 8; + _index = b & 0xff; + uint16 res = (((val & 3) + 4) << _index) + 0x101; + return res + getKeyMasked(_index); +} + +void FileExpanderSource::advSrcRefresh() { + _key = READ_LE_UINT16(_dataPtr); + if (_dataPtr < _endofBuffer - 1) + _dataPtr += 2; + _bitsLeft = 8; +} + +class FileExpander { +public: + FileExpander(); + ~FileExpander(); + + bool process(uint8 *dst, const uint8 *src, uint32 outsize, uint32 insize); + +private: + void generateTables(uint8 srcIndex, uint8 dstIndex, uint8 dstIndex2, int cnt); + uint8 calcCmdAndIndex(const uint8 *tbl, int16 ¶); + + FileExpanderSource *_src; + uint8 *_tables[9]; + uint16 *_tables16[3]; +}; + +FileExpander::FileExpander() : _src(0) { + _tables[0] = new uint8[3914]; + assert(_tables[0]); + + _tables[1] = _tables[0] + 320; + _tables[2] = _tables[0] + 352; + _tables[3] = _tables[0] + 864; + _tables[4] = _tables[0] + 2016; + _tables[5] = _tables[0] + 2528; + _tables[6] = _tables[0] + 2656; + _tables[7] = _tables[0] + 2736; + _tables[8] = _tables[0] + 2756; + + _tables16[0] = (uint16 *)(_tables[0] + 3268); + _tables16[1] = (uint16 *)(_tables[0] + 3302); + _tables16[2] = (uint16 *)(_tables[0] + 3338); +} + +FileExpander::~FileExpander() { + delete _src; + delete[] _tables[0]; +} + +bool FileExpander::process(uint8 *dst, const uint8 *src, uint32 outsize, uint32 compressedSize) { + static const uint8 indexTable[] = { + 0x10, 0x11, 0x12, 0x00, 0x08, 0x07, 0x09, 0x06, 0x0A, + 0x05, 0x0B, 0x04, 0x0C, 0x03, 0x0D, 0x02, 0x0E, 0x01, 0x0F + }; + + memset(_tables[0], 0, 3914); + + uint8 *d = dst; + uint16 tableSize0 = 0; + uint16 tableSize1 = 0; + bool needrefresh = true; + bool postprocess = false; + + _src = new FileExpanderSource(src, compressedSize); + + while (d < dst + outsize) { + + if (needrefresh) { + needrefresh = false; + _src->advSrcRefresh(); + } + + _src->advSrcBitsBy1(); + + int mode = _src->getKeyMasked(2) - 1; + if (mode == 1) { + tableSize0 = _src->getKeyMasked(5) + 257; + tableSize1 = _src->getKeyMasked(5) + 1; + memset(_tables[7], 0, 19); + + const uint8 *itbl = indexTable; + int numbytes = _src->getKeyMasked(4) + 4; + + while (numbytes--) + _tables[7][*itbl++] = _src->getKeyMasked(3); + + generateTables(7, 8, 255, 19); + + int cnt = tableSize0 + tableSize1; + uint8 *tmp = _tables[0]; + + while (cnt) { + uint16 cmd = _src->getKeyLower(); + cmd = READ_LE_UINT16(&_tables[8][cmd << 1]); + _src->advSrcBitsByIndex(_tables[7][cmd]); + + if (cmd < 16) { + *tmp++ = cmd; + cnt--; + } else { + uint8 tmpI = 0; + if (cmd == 16) { + cmd = _src->getKeyMasked(2) + 3; + tmpI = *(tmp - 1); + } else if (cmd == 17) { + cmd = _src->getKeyMasked(3) + 3; + } else { + cmd = _src->getKeyMasked(7) + 11; + } + _src->setIndex(tmpI); + memset(tmp, tmpI, cmd); + tmp += cmd; + + cnt -= cmd; + if (cnt < 0) + error("decompression failure"); + } + } + + memcpy(_tables[1], _tables[0] + tableSize0, tableSize1); + generateTables(0, 2, 3, tableSize0); + generateTables(1, 4, 5, tableSize1); + postprocess = true; + } else if (mode < 0) { + _src->copyBytes(d); + postprocess = false; + needrefresh = true; + } else if (mode == 0){ + uint8 *d2 = _tables[0]; + memset(d2, 8, 144); + memset(d2 + 144, 9, 112); + memset(d2 + 256, 7, 24); + memset(d2 + 280, 8, 8); + d2 = _tables[1]; + memset(d2, 5, 32); + tableSize0 = 288; + tableSize1 = 32; + + generateTables(0, 2, 3, tableSize0); + generateTables(1, 4, 5, tableSize1); + postprocess = true; + } else { + error("decompression failure"); + } + + if (!postprocess) + continue; + + int16 cmd = 0; + + do { + cmd = ((int16*) _tables[2])[_src->getKeyLower()]; + _src->advSrcBitsByIndex(cmd < 0 ? calcCmdAndIndex(_tables[3], cmd) : _tables[0][cmd]); + + if (cmd == 0x11d) { + cmd = 0x200; + } else if (cmd > 0x108) { + cmd = _src->keyMaskedAlign(cmd); + } + + if (!(cmd >> 8)) { + *d++ = cmd & 0xff; + } else if (cmd != 0x100) { + cmd -= 0xfe; + int16 offset = ((int16*) _tables[4])[_src->getKeyLower()]; + _src->advSrcBitsByIndex(offset < 0 ? calcCmdAndIndex(_tables[5], offset) : _tables[1][offset]); + if ((offset & 0xff) >= 4) { + uint8 newIndex = ((offset & 0xff) >> 1) - 1; + offset = (((offset & 1) + 2) << newIndex); + offset += _src->getKeyMasked(newIndex); + } + + uint8 *s2 = d - 1 - offset; + if (s2 >= dst) { + while (cmd--) + *d++ = *s2++; + } else { + uint32 pos = dst - s2; + s2 += (d - dst); + + if (pos < (uint32) cmd) { + cmd -= pos; + while (pos--) + *d++ = *s2++; + s2 = dst; + } + while (cmd--) + *d++ = *s2++; + } + } + } while (cmd != 0x100); + } + + delete _src; + _src = 0; + + return true; +} + +void FileExpander::generateTables(uint8 srcIndex, uint8 dstIndex, uint8 dstIndex2, int cnt) { + const uint8 *tbl1 = _tables[srcIndex]; + const uint8 *tbl2 = _tables[dstIndex]; + const uint8 *tbl3 = dstIndex2 == 0xff ? 0 : _tables[dstIndex2]; + + if (!cnt) + return; + + const uint8 *s = tbl1; + memset(_tables16[0], 0, 32); + + for (int i = 0; i < cnt; i++) + _tables16[0][(*s++)]++; + + _tables16[1][1] = 0; + + for (uint16 i = 1, r = 0; i < 16; i++) { + r = (r + _tables16[0][i]) << 1; + _tables16[1][i + 1] = r; + } + + if (_tables16[1][16]) { + uint16 r = 0; + for (uint16 i = 1; i < 16; i++) + r += _tables16[0][i]; + if (r > 1) + error("decompression failure"); + } + + s = tbl1; + uint16 *d = _tables16[2]; + for (int i = 0; i < cnt; i++) { + uint16 t = *s++; + if (t) { + _tables16[1][t]++; + t = _tables16[1][t] - 1; + } + *d++ = t; + } + + s = tbl1; + d = _tables16[2]; + for (int i = 0; i < cnt; i++) { + int8 t = ((int8)(*s++)) - 1; + if (t > 0) { + uint16 v1 = *d; + uint16 v2 = 0; + + do { + v2 = (v2 << 1) | (v1 & 1); + v1 >>= 1; + } while (--t && v1); + + t++; + uint8 c1 = (v1 & 1); + while (t--) { + uint8 c2 = v2 >> 15; + v2 = (v2 << 1) | c1; + c1 = c2; + }; + + *d++ = v2; + } else { + d++; + } + } + + memset((void*) tbl2, 0, 512); + + cnt--; + s = tbl1 + cnt; + d = &_tables16[2][cnt]; + uint16 * bt = (uint16*) tbl3; + uint16 inc = 0; + uint16 cnt2 = 0; + + do { + uint8 t = *s--; + uint16 *s2 = (uint16*) tbl2; + + if (t && t < 9) { + inc = 1 << t; + uint16 o = *d; + + do { + s2[o] = cnt; + o += inc; + } while (!(o & 0xf00)); + + } else if (t > 8) { + if (!bt) + error("decompression failure"); + + t -= 8; + uint8 shiftCnt = 1; + uint8 v = (*d) >> 8; + s2 = &((uint16*) tbl2)[*d & 0xff]; + + do { + if (!*s2) { + *s2 = (uint16)(~cnt2); + *(uint32*)&bt[cnt2] = 0; + cnt2 += 2; + } + + s2 = &bt[(uint16)(~*s2)]; + if (v & shiftCnt) + s2++; + + shiftCnt <<= 1; + } while (--t); + *s2 = cnt; + } + d--; + } while (--cnt >= 0); +} + +uint8 FileExpander::calcCmdAndIndex(const uint8 *tbl, int16 ¶) { + const uint16 *t = (const uint16*)tbl; + _src->advSrcBitsByIndex(8); + uint8 newIndex = 0; + uint16 v = _src->getKeyLower(); + + do { + newIndex++; + para = t[((~para) & 0xfffe) | (v & 1)]; + v >>= 1; + } while (para < 0); + + return newIndex; +} + +class CompLoaderInsHof : public CompArchiveLoader { +public: + bool checkForFiles() const; + bool loadFile(CompFileMap &loadTo) const; + +private: + struct Archive { + Common::String filename; + uint32 firstFile; + uint32 startOffset; + uint32 lastFile; + uint32 endOffset; + uint32 totalSize; + }; +}; + +bool CompLoaderInsHof::checkForFiles() const { + return (Common::File::exists("WESTWOOD.001") && Common::File::exists("WESTWOOD.002")); +} + +bool CompLoaderInsHof::loadFile(CompFileMap &loadTo) const { + Common::File tmpFile; + + uint32 pos = 0; + uint32 bytesleft = 0; + bool startFile = true; + + Common::String filenameBase = "WESTWOOD."; + Common::String filenameTemp; + char filenameExt[4]; + + while (filenameBase.lastChar() != '.') + filenameBase.deleteLastChar(); + + Archive newArchive; + + Common::List<Archive> archives; + + for (int8 currentFile = 1; currentFile; currentFile++) { + sprintf(filenameExt, "%03d", currentFile); + filenameTemp = filenameBase + Common::String(filenameExt); + + if (!tmpFile.open(filenameTemp)) { + debug(3, "couldn't open file '%s'\n", filenameTemp.c_str()); + break; + } + + tmpFile.seek(pos); + uint8 fileId = tmpFile.readByte(); + pos++; + + uint32 size = tmpFile.size() - 1; + if (startFile) { + size -= 4; + if (fileId == currentFile) { + size -= 6; + pos += 6; + tmpFile.seek(6, SEEK_CUR); + } else { + size = size + 1 - pos; + } + newArchive.filename = filenameBase; + bytesleft = newArchive.totalSize = tmpFile.readUint32LE(); + pos += 4; + newArchive.firstFile = currentFile; + newArchive.startOffset = pos; + startFile = false; + } + + uint32 cs = MIN(size, bytesleft); + bytesleft -= cs; + + tmpFile.close(); + + pos += cs; + if (cs == size) { + if (!bytesleft) { + newArchive.lastFile = currentFile; + newArchive.endOffset = --pos; + archives.push_back(newArchive); + currentFile = -1; + } else { + pos = 0; + } + } else { + startFile = true; + bytesleft = size - cs; + newArchive.lastFile = currentFile--; + newArchive.endOffset = --pos; + archives.push_back(newArchive); + } + } + + FileExpander exp; + CompFileEntry newEntry; + uint32 insize = 0; + uint32 outsize = 0; + uint8 *inbuffer = 0; + uint8 *outbuffer = 0; + uint32 inPart1 = 0; + uint32 inPart2 = 0; + Common::String entryStr; + + pos = 0; + + const uint32 kExecSize = 0x0bba; + const uint32 kHeaderSize = 30; + const uint32 kHeaderSize2 = 46; + + for (Common::List<Archive>::iterator a = archives.begin(); a != archives.end(); ++a) { + startFile = true; + for (uint32 i = a->firstFile; i != (a->lastFile + 1); i++) { + sprintf(filenameExt, "%03d", i); + filenameTemp = a->filename + Common::String(filenameExt); + + if (!tmpFile.open(filenameTemp)) { + debug(3, "couldn't open file '%s'\n", filenameTemp.c_str()); + break; + } + + uint32 size = (i == a->lastFile) ? a->endOffset : tmpFile.size(); + + if (startFile) { + startFile = false; + pos = a->startOffset + kExecSize; + if (pos > size) { + pos -= size; + tmpFile.close(); + continue; + } + } else { + if (inPart2) { + tmpFile.seek(1); + tmpFile.read(inbuffer + inPart1, inPart2); + inPart2 = 0; + exp.process(outbuffer, inbuffer, outsize, insize); + delete[] inbuffer; + inbuffer = 0; + newEntry.data = outbuffer; + newEntry.size = outsize; + loadTo[entryStr] = newEntry; + } + pos++; + } + + while (pos < size) { + uint8 hdr[43]; + uint32 m = 0; + tmpFile.seek(pos); + + if (pos + 42 > size) { + m = size - pos; + uint32 b = 42 - m; + + if (m >= 4) { + uint32 id = tmpFile.readUint32LE(); + if (id == 0x06054B50) { + startFile = true; + break; + } else { + tmpFile.seek(pos); + } + } + + sprintf(filenameExt, "%03d", i + 1); + filenameTemp = a->filename + Common::String(filenameExt); + + Common::File tmpFile2; + tmpFile2.open(filenameTemp); + tmpFile.read(hdr, m); + tmpFile2.read(hdr + m, b); + tmpFile2.close(); + + } else { + tmpFile.read(hdr, 42); + } + + uint32 id = READ_LE_UINT32(hdr); + + if (id == 0x04034B50) { + if (hdr[8] != 8) + error("compression type not implemented"); + insize = READ_LE_UINT32(hdr + 18); + outsize = READ_LE_UINT32(hdr + 22); + + uint16 filestrlen = READ_LE_UINT16(hdr + 26); + *(hdr + 30 + filestrlen) = 0; + entryStr = Common::String((const char *)(hdr + 30)); + pos += (kHeaderSize + filestrlen - m); + tmpFile.seek(pos); + + outbuffer = new uint8[outsize]; + if (!outbuffer) + error("Out of memory: Can't uncompress installer files"); + + if (!inbuffer) { + inbuffer = new uint8[insize]; + if (!inbuffer) + error("Out of memory: Can't uncompress installer files"); + } + + if ((pos + insize) > size) { + // this is for files that are split between two archive files + inPart1 = size - pos; + inPart2 = insize - inPart1; + tmpFile.read(inbuffer, inPart1); + } else { + tmpFile.read(inbuffer, insize); + inPart2 = 0; + exp.process(outbuffer, inbuffer, outsize, insize); + delete[] inbuffer; + inbuffer = 0; + newEntry.data = outbuffer; + newEntry.size = outsize; + loadTo[entryStr] = newEntry; + } + + pos += insize; + if (pos > size) { + pos -= size; + break; + } + } else { + uint32 filestrlen = READ_LE_UINT32(hdr + 28); + pos += (kHeaderSize2 + filestrlen - m); + } + } + tmpFile.close(); + } + } + + archives.clear(); + return true; +} + +#pragma mark - void Resource::initializeLoaders() { _loaders.push_back(LoaderList::value_type(new ResLoaderPak())); - _loaders.push_back(LoaderList::value_type(new ResLoaderIns())); + _loaders.push_back(LoaderList::value_type(new ResLoaderInsMalcolm())); _loaders.push_back(LoaderList::value_type(new ResLoaderTlk())); + + _compLoaders.push_back(CompLoaderList::value_type(new CompLoaderInsHof())); } const ResArchiveLoader *Resource::getLoader(ResFileEntry::kType type) const { @@ -755,3 +1506,4 @@ const ResArchiveLoader *Resource::getLoader(ResFileEntry::kType type) const { } // end of namespace Kyra + diff --git a/engines/kyra/resource.h b/engines/kyra/resource.h index f414cacee8..d43f730e6b 100644 --- a/engines/kyra/resource.h +++ b/engines/kyra/resource.h @@ -36,7 +36,7 @@ #include "common/stream.h" #include "common/ptr.h" -#include "kyra/kyra.h" +#include "kyra/kyra_v1.h" #include "kyra/kyra_hof.h" namespace Kyra { @@ -52,7 +52,7 @@ struct ResFileEntry { enum kType { kRaw = 0, kPak = 1, - kIns = 2, + kInsMal = 2, kTlk = 3, kAutoDetect }; @@ -60,7 +60,13 @@ struct ResFileEntry { uint32 offset; }; +struct CompFileEntry { + uint32 size; + uint8 *data; +}; + typedef Common::HashMap<Common::String, ResFileEntry, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> ResFileMap; +typedef Common::HashMap<Common::String, CompFileEntry, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> CompFileMap; class Resource; class ResArchiveLoader { @@ -69,6 +75,10 @@ public: File() : filename(), entry() {} File(const Common::String &f, const ResFileEntry &e) : filename(f), entry(e) {} + bool operator ==(const Common::String &r) const { + return filename.equalsIgnoreCase(r); + } + Common::String filename; ResFileEntry entry; }; @@ -86,9 +96,17 @@ public: protected: }; +class CompArchiveLoader { +public: + virtual ~CompArchiveLoader() {} + + virtual bool checkForFiles() const = 0; + virtual bool loadFile(CompFileMap &loadTo) const = 0; +}; + class Resource { public: - Resource(KyraEngine *vm); + Resource(KyraEngine_v1 *vm); ~Resource(); bool reset(); @@ -122,89 +140,97 @@ protected: LoaderList _loaders; ResFileMap _map; - KyraEngine *_vm; + typedef Common::List<Common::SharedPtr<CompArchiveLoader> > CompLoaderList; + typedef CompLoaderList::iterator CompLoaderIterator; + typedef CompLoaderList::const_iterator CCompLoaderIterator; + CompLoaderList _compLoaders; + CompFileMap _compFiles; + + void tryLoadCompFiles(); + void clearCompFileList(); + + KyraEngine_v1 *_vm; }; -// TODO?: maybe prefix all things here with 'kKyra1' instead of 'k' enum kKyraResources { kLoadAll = -1, - kForestSeq, - kKallakWritingSeq, - kKyrandiaLogoSeq, - kKallakMalcolmSeq, - kMalcolmTreeSeq, - kWestwoodLogoSeq, + k1ForestSeq, + k1KallakWritingSeq, + k1KyrandiaLogoSeq, + k1KallakMalcolmSeq, + k1MalcolmTreeSeq, + k1WestwoodLogoSeq, - kDemo1Seq, - kDemo2Seq, - kDemo3Seq, - kDemo4Seq, + k1Demo1Seq, + k1Demo2Seq, + k1Demo3Seq, + k1Demo4Seq, - kAmuleteAnimSeq, + k1AmuleteAnimSeq, - kOutroReunionSeq, + k1OutroReunionSeq, - kIntroCPSStrings, - kIntroCOLStrings, - kIntroWSAStrings, - kIntroStrings, + k1IntroCPSStrings, + k1IntroCOLStrings, + k1IntroWSAStrings, + k1IntroStrings, - kOutroHomeString, + k1OutroHomeString, - kRoomFilenames, - kRoomList, + k1RoomFilenames, + k1RoomList, - kCharacterImageFilenames, + k1CharacterImageFilenames, - kItemNames, - kTakenStrings, - kPlacedStrings, - kDroppedStrings, - kNoDropStrings, + k1ItemNames, + k1TakenStrings, + k1PlacedStrings, + k1DroppedStrings, + k1NoDropStrings, - kPutDownString, - kWaitAmuletString, - kBlackJewelString, - kPoisonGoneString, - kHealingTipString, - kWispJewelStrings, - kMagicJewelStrings, + k1PutDownString, + k1WaitAmuletString, + k1BlackJewelString, + k1PoisonGoneString, + k1HealingTipString, + k1WispJewelStrings, + k1MagicJewelStrings, - kThePoisonStrings, - kFluteStrings, + k1ThePoisonStrings, + k1FluteStrings, - kFlaskFullString, - kFullFlaskString, + k1FlaskFullString, + k1FullFlaskString, - kVeryCleverString, - kNewGameString, + k1VeryCleverString, + k1NewGameString, - kDefaultShapes, - kHealing1Shapes, - kHealing2Shapes, - kPoisonDeathShapes, - kFluteShapes, - kWinter1Shapes, - kWinter2Shapes, - kWinter3Shapes, - kDrinkShapes, - kWispShapes, - kMagicAnimShapes, - kBranStoneShapes, + k1DefaultShapes, + k1Healing1Shapes, + k1Healing2Shapes, + k1PoisonDeathShapes, + k1FluteShapes, + k1Winter1Shapes, + k1Winter2Shapes, + k1Winter3Shapes, + k1DrinkShapes, + k1WispShapes, + k1MagicAnimShapes, + k1BranStoneShapes, - kPaletteList, + k1PaletteList, - kGUIStrings, - kConfigStrings, + k1GUIStrings, + k1ConfigStrings, - kAudioTracks, - kAudioTracksIntro, + k1AudioTracks, + k1AudioTracksIntro, - kKyra1TownsSFXwdTable, - kKyra1TownsSFXbtTable, - kKyra1TownsCDATable, - kCreditsStrings, + k1TownsSFXwdTable, + k1TownsSFXbtTable, + k1TownsCDATable, + k1CreditsStrings, k2SeqplayPakFiles, k2SeqplayCredits, @@ -229,6 +255,15 @@ enum kKyraResources { k2IngameShapeAnimData, k2IngameTlkDemoStrings, + k3MainMenuStrings, + k3MusicFiles, + k3ScoreTable, + k3SfxFiles, + k3SfxMap, + k3ItemAnimData, + k3ItemMagicTable, + k3ItemStringMap, + kMaxResIDs }; @@ -239,7 +274,7 @@ class StaticResource { public: static const Common::String staticDataFilename() { return "kyra.dat"; } - StaticResource(KyraEngine *vm) : _vm(vm), _resList(), _fileLoader(0), _builtIn(0), _filenameTable(0) {} + StaticResource(KyraEngine_v1 *vm) : _vm(vm), _resList(), _fileLoader(0), _builtIn(0), _filenameTable(0) {} ~StaticResource() { deinit(); } static bool checkKyraDat(); @@ -253,8 +288,8 @@ public: const Room *loadRoomTable(int id, int &entries); const uint8 * const*loadPaletteTable(int id, int &entries); const HofSeqData *loadHofSequenceData(int id, int &entries); - const ItemAnimData_v1 *loadHofShapeAnimDataV1(int id, int &entries); - const ItemAnimData_v2 *loadHofShapeAnimDataV2(int id, int &entries); + const ItemAnimData_v1 *loadShapeAnimData_v1(int id, int &entries); + const ItemAnimData_v2 *loadShapeAnimData_v2(int id, int &entries); // use '-1' to prefetch/unload all ids // prefetchId retruns false if only on of the resources @@ -263,9 +298,9 @@ public: bool prefetchId(int id); void unloadId(int id); private: - void outputError(); + void outputError(const Common::String &error); - KyraEngine *_vm; + KyraEngine_v1 *_vm; struct FilenameTable; struct ResData; @@ -284,8 +319,8 @@ private: bool loadRoomTable(const char *filename, void *&ptr, int &size); bool loadPaletteTable(const char *filename, void *&ptr, int &size); bool loadHofSequenceData(const char *filename, void *&ptr, int &size); - bool loadHofShapeAnimDataV1(const char *filename, void *&ptr, int &size); - bool loadHofShapeAnimDataV2(const char *filename, void *&ptr, int &size); + bool loadShapeAnimData_v1(const char *filename, void *&ptr, int &size); + bool loadShapeAnimData_v2(const char *filename, void *&ptr, int &size); void freeRawData(void *&ptr, int &size); void freeStringTable(void *&ptr, int &size); @@ -354,3 +389,4 @@ private: + diff --git a/engines/kyra/saveload.cpp b/engines/kyra/saveload.cpp index fa3266685f..22f934ba69 100644 --- a/engines/kyra/saveload.cpp +++ b/engines/kyra/saveload.cpp @@ -27,9 +27,9 @@ #include "common/savefile.h" #include "common/system.h" -#include "kyra/kyra.h" +#include "kyra/kyra_v1.h" -#define CURRENT_SAVE_VERSION 11 +#define CURRENT_SAVE_VERSION 13 #define GF_FLOPPY (1 << 0) #define GF_TALKIE (1 << 1) @@ -37,7 +37,7 @@ namespace Kyra { -KyraEngine::kReadSaveHeaderError KyraEngine::readSaveHeader(Common::InSaveFile *in, SaveHeader &header) { +KyraEngine_v1::kReadSaveHeaderError KyraEngine_v1::readSaveHeader(Common::InSaveFile *in, SaveHeader &header) { uint32 type = in->readUint32BE(); header.originalSave = false; header.oldHeader = false; @@ -70,6 +70,11 @@ KyraEngine::kReadSaveHeaderError KyraEngine::readSaveHeader(Common::InSaveFile * header.description = descriptionBuffer; header.gameID = GI_KYRA2; break; + } else if (type == MKID_BE('MBL4') && header.version == 102) { + saveOk = true; + header.description = descriptionBuffer; + header.gameID = GI_KYRA3; + break; } } @@ -103,14 +108,14 @@ KyraEngine::kReadSaveHeaderError KyraEngine::readSaveHeader(Common::InSaveFile * return (in->ioFailed() ? kRSHEIoError : kRSHENoError); } -Common::InSaveFile *KyraEngine::openSaveForReading(const char *filename, SaveHeader &header) { - debugC(9, kDebugLevelMain, "KyraEngine::openSaveForReading('%s', -)", filename); +Common::InSaveFile *KyraEngine_v1::openSaveForReading(const char *filename, SaveHeader &header) { + debugC(9, kDebugLevelMain, "KyraEngine_v1::openSaveForReading('%s', -)", filename); Common::InSaveFile *in = 0; if (!(in = _saveFileMan->openForLoading(filename))) return 0; - kReadSaveHeaderError errorCode = KyraEngine::readSaveHeader(in, header); + kReadSaveHeaderError errorCode = KyraEngine_v1::readSaveHeader(in, header); if (errorCode != kRSHENoError) { if (errorCode == kRSHEInvalidType) warning("No ScummVM Kyra engine savefile header."); @@ -154,8 +159,8 @@ Common::InSaveFile *KyraEngine::openSaveForReading(const char *filename, SaveHea return in; } -Common::OutSaveFile *KyraEngine::openSaveForWriting(const char *filename, const char *saveName) const { - debugC(9, kDebugLevelMain, "KyraEngine::openSaveForWriting('%s', '%s')", filename, saveName); +Common::OutSaveFile *KyraEngine_v1::openSaveForWriting(const char *filename, const char *saveName) const { + debugC(9, kDebugLevelMain, "KyraEngine_v1::openSaveForWriting('%s', '%s')", filename, saveName); if (_quitFlag) return 0; @@ -186,7 +191,7 @@ Common::OutSaveFile *KyraEngine::openSaveForWriting(const char *filename, const return out; } -const char *KyraEngine::getSavegameFilename(int num) { +const char *KyraEngine_v1::getSavegameFilename(int num) { static Common::String filename; assert(num >= 0 && num <= 999); @@ -199,7 +204,7 @@ const char *KyraEngine::getSavegameFilename(int num) { return filename.c_str(); } -bool KyraEngine::saveFileLoadable(int slot) { +bool KyraEngine_v1::saveFileLoadable(int slot) { if (slot < 0 || slot > 999) return false; diff --git a/engines/kyra/saveload_v1.cpp b/engines/kyra/saveload_lok.cpp index 7e871876a0..8af73acc61 100644 --- a/engines/kyra/saveload_v1.cpp +++ b/engines/kyra/saveload_lok.cpp @@ -27,16 +27,16 @@ #include "common/savefile.h" #include "common/system.h" -#include "kyra/kyra_v1.h" -#include "kyra/animator_v1.h" +#include "kyra/kyra_lok.h" +#include "kyra/animator_lok.h" #include "kyra/screen.h" #include "kyra/resource.h" #include "kyra/sound.h" #include "kyra/timer.h" namespace Kyra { -void KyraEngine_v1::loadGame(const char *fileName) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::loadGame('%s')", fileName); +void KyraEngine_LoK::loadGame(const char *fileName) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::loadGame('%s')", fileName); SaveHeader header; Common::InSaveFile *in = openSaveForReading(fileName, header); @@ -183,7 +183,7 @@ void KyraEngine_v1::loadGame(const char *fileName) { _screen->copyRegion(0, 0, 0, 0, 320, 200, 8, 0); } - createMouseItem(_itemInHand); + setHandItem(_itemInHand); _animator->setBrandonAnimSeqSize(3, 48); redrawInventory(0); _animator->_noDrawShapesFlag = 1; @@ -218,8 +218,8 @@ void KyraEngine_v1::loadGame(const char *fileName) { delete in; } -void KyraEngine_v1::saveGame(const char *fileName, const char *saveName) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::saveGame('%s', '%s')", fileName, saveName); +void KyraEngine_LoK::saveGame(const char *fileName, const char *saveName) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::saveGame('%s', '%s')", fileName, saveName); if (_quitFlag) return; diff --git a/engines/kyra/saveload_mr.cpp b/engines/kyra/saveload_mr.cpp index 8b727862a5..51efc33723 100644 --- a/engines/kyra/saveload_mr.cpp +++ b/engines/kyra/saveload_mr.cpp @@ -49,15 +49,16 @@ void KyraEngine_MR::saveGame(const char *fileName, const char *saveName) { out->writeSint16BE(_lastMusicCommand); out->writeByte(_currentChapter); out->writeByte(_characterShapeFile); - //XXX + out->writeByte(_album.curPage); out->writeSint16BE(_score); out->writeSint16BE(_scoreMax); out->writeByte(_malcolmsMood); - out->write(_conversationState, sizeof(_conversationState)); - out->write(_newSceneDlgState, sizeof(_newSceneDlgState)); + for (int i = 0; i < 30; ++i) + out->write(_conversationState[i], 30); + out->write(_newSceneDlgState, 40); for (int i = 0; i < 100; ++i) out->writeUint16BE(_hiddenItems[i]); - out->write(_scoreFlagTable, sizeof(_scoreFlagTable)); + out->write(_scoreFlagTable, 26); out->writeUint16BE(_mainCharacter.sceneId); out->writeSint16BE(_mainCharacter.dlgIndex); @@ -88,6 +89,7 @@ void KyraEngine_MR::saveGame(const char *fileName, const char *saveName) { out->writeSint16BE(_talkObjectList[i].x); out->writeSint16BE(_talkObjectList[i].y); out->writeByte(_talkObjectList[i].color); + out->writeByte(_talkObjectList[i].sceneId); } for (int i = 0; i < 98; ++i) { @@ -129,6 +131,9 @@ void KyraEngine_MR::loadGame(const char *fileName) { return; } + if (header.originalSave) + warning("Trying to load savegame from original interpreter, while this is possible, it is not officially supported"); + if (_inventoryState) { updateCharacterAnim(0); restorePage3(); @@ -148,32 +153,58 @@ void KyraEngine_MR::loadGame(const char *fileName) { _screen->hideMouse(); - _timer->loadDataFromFile(in, header.version); + if (!header.originalSave) { + _timer->loadDataFromFile(in, header.version); - uint32 flagsSize = in.readUint32BE(); - assert(flagsSize <= sizeof(_flagsTable)); - in.read(_flagsTable, flagsSize); + 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 + + if (header.version >= 12 || header.originalSave) + _album.curPage = in.readByte(); + if (header.originalSave) + in.readByte(); + _score = in.readSint16(); _scoreMax = in.readSint16(); _malcolmsMood = in.readByte(); - in.read(_conversationState, sizeof(_conversationState)); - in.read(_newSceneDlgState, sizeof(_newSceneDlgState)); + + if (header.originalSave) + in.seek(8, SEEK_CUR); + + for (int i = 0; i < 30; ++i) + in.read(_conversationState[i], 30); + + if (!header.originalSave) { + in.read(_newSceneDlgState, 40); + } else { + for (int i = 0; i < 40; ++i) + _newSceneDlgState[i] = in.readUint16(); + } + for (int i = 0; i < 100; ++i) _hiddenItems[i] = in.readUint16(); - in.read(_scoreFlagTable, sizeof(_scoreFlagTable)); + + if (header.originalSave) + in.read(_flagsTable, 69); + in.read(_scoreFlagTable, 26); _mainCharacter.sceneId = in.readUint16(); _mainCharacter.dlgIndex = in.readSint16(); _mainCharacter.height = in.readByte(); _mainCharacter.facing = in.readByte(); _mainCharacter.animFrame = in.readUint16(); - _mainCharacter.walkspeed = in.readByte(); + if (!header.originalSave) { + _mainCharacter.walkspeed = in.readByte(); + } else { + in.seek(2, SEEK_CUR); + _mainCharacter.walkspeed = in.readUint32(); + } for (int i = 0; i < 10; ++i) _mainCharacter.inventory[i] = in.readUint16(); _mainCharacter.x1 = in.readSint16(); @@ -188,7 +219,7 @@ void KyraEngine_MR::loadGame(const char *fileName) { _itemList[i].sceneId = in.readUint16(); _itemList[i].x = in.readSint16(); _itemList[i].y = in.readSint16(); - if (header.version <= 9) + if (header.version <= 9 || header.originalSave) in.readUint16(); } @@ -199,11 +230,25 @@ void KyraEngine_MR::loadGame(const char *fileName) { _talkObjectList[i].x = in.readSint16(); _talkObjectList[i].y = in.readSint16(); _talkObjectList[i].color = in.readByte(); + if (header.version >= 13 || header.originalSave) + _talkObjectList[i].sceneId = in.readByte(); } for (int i = 0; i < 98; ++i) { - in.read(_sceneList[i].filename1, 10); - in.read(_sceneList[i].filename2, 10); + if (!header.originalSave) { + in.read(_sceneList[i].filename1, 10); + } else { + in.read(_sceneList[i].filename1, 9); + _sceneList[i].filename1[9] = 0; + } + + if (!header.originalSave) { + in.read(_sceneList[i].filename2, 10); + } else { + in.read(_sceneList[i].filename2, 9); + _sceneList[i].filename2[9] = 0; + } + _sceneList[i].exit1 = in.readUint16(); _sceneList[i].exit2 = in.readUint16(); _sceneList[i].exit3 = in.readUint16(); @@ -213,6 +258,26 @@ void KyraEngine_MR::loadGame(const char *fileName) { } _itemInHand = in.readSint16(); + + if (header.originalSave) { + uint32 currentTime = _system->getMillis(); + + for (int i = 0; i < 6; ++i) + _timer->setDelay(i, in.readSint32LE()); + + for (int i = 0; i < 6; ++i) { + if (in.readUint16LE()) + _timer->enable(i); + else + _timer->disable(i); + } + + for (int i = 0; i < 6; ++i) + _timer->setNextRun(i, currentTime + (in.readUint32LE() * _tickLength)); + + _timer->resetNextRun(); + } + _sceneExit1 = in.readUint16(); _sceneExit2 = in.readUint16(); _sceneExit3 = in.readUint16(); diff --git a/engines/kyra/scene.cpp b/engines/kyra/scene.cpp deleted file mode 100644 index f3e41b2d39..0000000000 --- a/engines/kyra/scene.cpp +++ /dev/null @@ -1,383 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include "kyra/kyra.h" -#include "kyra/screen.h" - -namespace Kyra { - -int KyraEngine::findWay(int x, int y, int toX, int toY, int *moveTable, int moveTableSize) { - debugC(9, kDebugLevelMain, "KyraEngine::findWay(%d, %d, %d, %d, %p, %d)", x, y, toX, toY, (const void *)moveTable, moveTableSize); - x &= 0xFFFC; toX &= 0xFFFC; - y &= 0xFFFE; toY &= 0xFFFE; - x = (int16)x; y = (int16)y; toX = (int16)toX; toY = (int16)toY; - - if (x == toY && y == toY) { - moveTable[0] = 8; - return 0; - } - - int curX = x; - int curY = y; - int tempValue = 0; - int lastUsedEntry = 0; - int *pathTable1 = new int[0x7D0]; - int *pathTable2 = new int[0x7D0]; - assert(pathTable1 && pathTable2); - - while (true) { - int newFacing = getFacingFromPointToPoint(x, y, toX, toY); - changePosTowardsFacing(curX, curY, newFacing); - - if (curX == toX && curY == toY) { - if (!lineIsPassable(curX, curY)) - break; - moveTable[lastUsedEntry++] = newFacing; - break; - } - - if (lineIsPassable(curX, curY)) { - if (lastUsedEntry == moveTableSize) { - delete [] pathTable1; - delete [] pathTable2; - return 0x7D00; - } - // debug drawing - /*if (curX >= 0 && curY >= 0 && curX < 320 && curY < 200) { - screen()->setPagePixel(0, curX, curY, 11); - screen()->updateScreen(); - //waitTicks(5); - }*/ - moveTable[lastUsedEntry++] = newFacing; - x = curX; - y = curY; - continue; - } - - int temp = 0; - while (true) { - newFacing = getFacingFromPointToPoint(curX, curY, toX, toY); - changePosTowardsFacing(curX, curY, newFacing); - // debug drawing - /*if (curX >= 0 && curY >= 0 && curX < 320 && curY < 200) { - screen()->setPagePixel(0, curX, curY, 8); - screen()->updateScreen(); - //waitTicks(5); - }*/ - - if (!lineIsPassable(curX, curY)) { - if (curX != toX || curY != toY) - continue; - } - - if (curX == toX && curY == toY) { - if (!lineIsPassable(curX, curY)) { - tempValue = 0; - temp = 0; - break; - } - } - - temp = findSubPath(x, y, curX, curY, pathTable1, 1, 0x7D0); - tempValue = findSubPath(x, y, curX, curY, pathTable2, 0, 0x7D0); - if (curX == toX && curY == toY) { - if (temp == 0x7D00 && tempValue == 0x7D00) { - delete [] pathTable1; - delete [] pathTable2; - return 0x7D00; - } - } - - if (temp != 0x7D00 || tempValue != 0x7D00) - break; - } - - if (temp < tempValue) { - if (lastUsedEntry + temp > moveTableSize) { - delete [] pathTable1; - delete [] pathTable2; - return 0x7D00; - } - memcpy(&moveTable[lastUsedEntry], pathTable1, temp*sizeof(int)); - lastUsedEntry += temp; - } else { - if (lastUsedEntry + tempValue > moveTableSize) { - delete [] pathTable1; - delete [] pathTable2; - return 0x7D00; - } - memcpy(&moveTable[lastUsedEntry], pathTable2, tempValue*sizeof(int)); - lastUsedEntry += tempValue; - } - x = curX; - y = curY; - if (curX == toX && curY == toY) - break; - } - - delete [] pathTable1; - delete [] pathTable2; - moveTable[lastUsedEntry] = 8; - return lastUsedEntry; -} - -int KyraEngine::findSubPath(int x, int y, int toX, int toY, int *moveTable, int start, int end) { - debugC(9, kDebugLevelMain, "KyraEngine::findSubPath(%d, %d, %d, %d, %p, %d, %d)", x, y, toX, toY, (const void *)moveTable, start, end); - // only used for debug specific code - //static uint16 unkTable[] = { 8, 5 }; - static const int8 facingTable1[] = { 7, 0, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 7, 0 }; - static const int8 facingTable2[] = { -1, 0, -1, 2, -1, 4, -1, 6, -1, 2, -1, 4, -1, 6, -1, 0 }; - static const int8 facingTable3[] = { 2, 4, 4, 6, 6, 0, 0, 2, 6, 6, 0, 0, 2, 2, 4, 4 }; - static const int8 addPosTableX[] = { -1, 0, -1, 4, -1, 0, -1, -4, -1, -4, -1, 0, -1, 4, -1, 0 }; - static const int8 addPosTableY[] = { -1, 2, -1, 0, -1, -2, -1, 0, -1, 0, -1, 2, -1, 0, -1, -2 }; - - // debug specific - /*++unkTable[start]; - while (screen()->getPalette(0)[unkTable[start]] != 0x0F) { - ++unkTable[start]; - }*/ - - int xpos1 = x, xpos2 = x; - int ypos1 = y, ypos2 = y; - int newFacing = getFacingFromPointToPoint(x, y, toX, toY); - int position = 0; - - while (position != end) { - int newFacing2 = newFacing; - while (true) { - changePosTowardsFacing(xpos1, ypos1, facingTable1[start*8 + newFacing2]); - if (!lineIsPassable(xpos1, ypos1)) { - if (facingTable1[start*8 + newFacing2] == newFacing) - return 0x7D00; - newFacing2 = facingTable1[start*8 + newFacing2]; - xpos1 = x; - ypos1 = y; - continue; - } - newFacing = facingTable1[start*8 + newFacing2]; - break; - } - // debug drawing - /*if (xpos1 >= 0 && ypos1 >= 0 && xpos1 < 320 && ypos1 < 200) { - screen()->setPagePixel(0, xpos1, ypos1, unkTable[start]); - screen()->updateScreen(); - //waitTicks(5); - }*/ - if (newFacing & 1) { - int temp = xpos1 + addPosTableX[newFacing + start * 8]; - if (toX == temp) { - temp = ypos1 + addPosTableY[newFacing + start * 8]; - if (toY == temp) { - moveTable[position++] = facingTable2[newFacing + start * 8]; - return position; - } - } - } - - moveTable[position++] = newFacing; - x = xpos1; - y = ypos1; - - if (x == toX && y == toY) - return position; - - if (xpos1 == xpos2 && ypos1 == ypos2) - break; - - newFacing = facingTable3[start*8 + newFacing]; - } - - return 0x7D00; -} - -int KyraEngine::getFacingFromPointToPoint(int x, int y, int toX, int toY) { - debugC(9, kDebugLevelMain, "KyraEngine::getFacingFromPointToPoint(%d, %d, %d, %d)", x, y, toX, toY); - static const int facingTable[] = { - 1, 0, 1, 2, 3, 4, 3, 2, 7, 0, 7, 6, 5, 4, 5, 6 - }; - - int facingEntry = 0; - int ydiff = y - toY; - if (ydiff < 0) { - ++facingEntry; - ydiff = -ydiff; - } - facingEntry <<= 1; - - int xdiff = toX - x; - if (xdiff < 0) { - ++facingEntry; - xdiff = -xdiff; - } - - if (xdiff >= ydiff) { - int temp = ydiff; - ydiff = xdiff; - xdiff = temp; - - facingEntry <<= 1; - } else { - facingEntry <<= 1; - facingEntry += 1; - } - int temp = (ydiff + 1) >> 1; - - if (xdiff < temp) { - facingEntry <<= 1; - facingEntry += 1; - } else { - facingEntry <<= 1; - } - - assert(facingEntry < ARRAYSIZE(facingTable)); - return facingTable[facingEntry]; -} - - -int KyraEngine::getOppositeFacingDirection(int dir) { - debugC(9, kDebugLevelMain, "KyraEngine::getOppositeFacingDirection(%d)", dir); - switch (dir) { - case 0: - return 2; - case 1: - return 1; - case 3: - return 7; - case 4: - return 6; - case 5: - return 5; - case 6: - return 4; - case 7: - return 3; - default: - break; - } - return 0; -} - -void KyraEngine::changePosTowardsFacing(int &x, int &y, int facing) { - debugC(9, kDebugLevelMain, "KyraEngine::changePosTowardsFacing(%d, %d, %d)", x, y, facing); - x += _addXPosTable[facing]; - y += _addYPosTable[facing]; -} - -int KyraEngine::getMoveTableSize(int *moveTable) { - debugC(9, kDebugLevelMain, "KyraEngine::getMoveTableSize(%p)", (const void *)moveTable); - int retValue = 0; - if (moveTable[0] == 8) - return 0; - - static const int facingTable[] = { - 4, 5, 6, 7, 0, 1, 2, 3 - }; - static const int unkTable[] = { - -1, -1, 1, 2, -1, 6, 7, -1, - -1, -1, -1, -1, 2, -1, 0, -1, - 1, -1, -1, -1, 3, 4, -1, 0, - 2, -1, -1, -1, -1, -1, 4, -1, - -1, 2, 3, -1, -1, -1, 5, 6, - 6, -1, 4, -1, -1, -1, -1, -1, - 7, 0, -1, 4, 5, -1, -1, -1, - -1, -1, 0, -1, 6, -1, -1, -1 - }; - - int *oldPosition = moveTable; - int *tempPosition = moveTable; - int *curPosition = moveTable + 1; - retValue = 1; - - while (*curPosition != 8) { - if (*oldPosition == facingTable[*curPosition]) { - retValue -= 2; - *oldPosition = 9; - *curPosition = 9; - - while (tempPosition != moveTable) { - --tempPosition; - if (*tempPosition != 9) - break; - } - - if (tempPosition == moveTable && *tempPosition == 9) { - while (*tempPosition != 8 && *tempPosition == 9) - ++tempPosition; - - if (*tempPosition == 8) - return 0; - } - - oldPosition = tempPosition; - curPosition = oldPosition+1; - - while (*curPosition != 8 && *curPosition == 9) - ++curPosition; - - continue; - } - - if (unkTable[*curPosition+((*oldPosition)*8)] != -1) { - --retValue; - *oldPosition = unkTable[*curPosition+((*oldPosition)*8)]; - *curPosition = 9; - - if (tempPosition != oldPosition) { - curPosition = oldPosition; - oldPosition = tempPosition; - while (true) { - if (tempPosition == moveTable) - break; - - --tempPosition; - if (*tempPosition != 9) - break; - - } - } else { - while (true) { - ++curPosition; - if (*curPosition != 9) - break; - } - } - continue; - } - - tempPosition = oldPosition; - oldPosition = curPosition; - ++retValue; - - while (true) { - ++curPosition; - if (*curPosition != 9) - break; - } - } - - return retValue; -} - -} // end of namespace Kyra diff --git a/engines/kyra/scene_hof.cpp b/engines/kyra/scene_hof.cpp index 3fc7947253..1882386b03 100644 --- a/engines/kyra/scene_hof.cpp +++ b/engines/kyra/scene_hof.cpp @@ -98,7 +98,7 @@ void KyraEngine_HoF::enterNewScene(uint16 newScene, int facing, int unk1, int un _emc->run(&_sceneScriptState); } - Common::for_each(_wsaSlots, _wsaSlots+ARRAYSIZE(_wsaSlots), Common::mem_fun(&WSAMovieV2::close)); + Common::for_each(_wsaSlots, _wsaSlots+ARRAYSIZE(_wsaSlots), Common::mem_fun(&WSAMovie_v2::close)); _specialExitCount = 0; memset(_specialExitTable, -1, sizeof(_specialExitTable)); @@ -322,6 +322,8 @@ int KyraEngine_HoF::trySceneChange(int *moveTable, int unk1, int updateChar) { refreshAnimObjectsIfNeed(); updateType = -1; } + + delay(10); } if (updateChar) @@ -702,7 +704,7 @@ void KyraEngine_HoF::initSceneScreen(int unk1) { void KyraEngine_HoF::freeSceneShapePtrs() { debugC(9, kDebugLevelMain, "KyraEngine_HoF::freeSceneShapePtrs()"); for (int i = 0; i < ARRAYSIZE(_sceneShapeTable); ++i) - delete [] _sceneShapeTable[i]; + delete[] _sceneShapeTable[i]; memset(_sceneShapeTable, 0, sizeof(_sceneShapeTable)); } diff --git a/engines/kyra/scene_lok.cpp b/engines/kyra/scene_lok.cpp new file mode 100644 index 0000000000..e4ae67f751 --- /dev/null +++ b/engines/kyra/scene_lok.cpp @@ -0,0 +1,1284 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "kyra/kyra_lok.h" +#include "kyra/seqplayer.h" +#include "kyra/screen.h" +#include "kyra/resource.h" +#include "kyra/sound.h" +#include "kyra/sprites.h" +#include "kyra/wsamovie.h" +#include "kyra/animator_lok.h" +#include "kyra/text.h" +#include "kyra/script.h" +#include "kyra/timer.h" + +#include "common/system.h" +#include "common/savefile.h" + +namespace Kyra { + +void KyraEngine_LoK::enterNewScene(int sceneId, int facing, int unk1, int unk2, int brandonAlive) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::enterNewScene(%d, %d, %d, %d, %d)", sceneId, facing, unk1, unk2, brandonAlive); + int unkVar1 = 1; + _screen->hideMouse(); + _handleInput = false; + _abortWalkFlag = false; + _abortWalkFlag2 = false; + + if (_flags.platform == Common::kPlatformFMTowns || _flags.platform == Common::kPlatformPC98) { + int newSfxFile = -1; + if (_currentCharacter->sceneId == 7 && sceneId == 24) + newSfxFile = 2; + else if (_currentCharacter->sceneId == 25 && sceneId == 109) + newSfxFile = 3; + else if (_currentCharacter->sceneId == 120 && sceneId == 37) + newSfxFile = 4; + else if (_currentCharacter->sceneId == 52 && sceneId == 199) + newSfxFile = 5; + else if (_currentCharacter->sceneId == 37 && sceneId == 120) + newSfxFile = 3; + else if (_currentCharacter->sceneId == 109 && sceneId == 25) + newSfxFile = 2; + else if (_currentCharacter->sceneId == 24 && sceneId == 7) + newSfxFile = 1; + + if (newSfxFile != -1) { + _curSfxFile = newSfxFile; + _sound->loadSoundFile(_curSfxFile); + } + } + + switch (_currentCharacter->sceneId) { + case 1: + if (sceneId == 0) { + moveCharacterToPos(0, 0, _currentCharacter->x1, 84); + unkVar1 = 0; + } + break; + + case 3: + if (sceneId == 2) { + moveCharacterToPos(0, 6, 155, _currentCharacter->y1); + unkVar1 = 0; + } + break; + + case 26: + if (sceneId == 27) { + moveCharacterToPos(0, 6, 155, _currentCharacter->y1); + unkVar1 = 0; + } + break; + + case 44: + if (sceneId == 45) { + moveCharacterToPos(0, 2, 192, _currentCharacter->y1); + unkVar1 = 0; + } + break; + + default: + break; + } + + if (unkVar1 && unk1) { + int xpos = _currentCharacter->x1; + int ypos = _currentCharacter->y1; + switch (facing) { + case 0: + ypos = _currentCharacter->y1 - 6; + break; + + case 2: + xpos = 336; + break; + + case 4: + ypos = 143; + break; + + case 6: + xpos = -16; + break; + + default: + break; + } + + moveCharacterToPos(0, facing, xpos, ypos); + } + + for (int i = 0; i < ARRAYSIZE(_movieObjects); ++i) + _movieObjects[i]->close(); + + if (!brandonAlive) { + _emc->init(&_scriptClick, &_scriptClickData); + _emc->start(&_scriptClick, 5); + while (_emc->isValid(&_scriptClick)) + _emc->run(&_scriptClick); + } + + memset(_entranceMouseCursorTracks, 0xFFFF, sizeof(uint16)*4); + _currentCharacter->sceneId = sceneId; + + assert(sceneId < _roomTableSize); + assert(_roomTable[sceneId].nameIndex < _roomFilenameTableSize); + + Room *currentRoom = &_roomTable[sceneId]; + + setupSceneResource(sceneId); + + _currentRoom = sceneId; + + int tableId = _roomTable[sceneId].nameIndex; + char fileNameBuffer[32]; + strcpy(fileNameBuffer, _roomFilenameTable[tableId]); + strcat(fileNameBuffer, ".DAT"); + _sprites->loadDat(fileNameBuffer, _sceneExits); + _sprites->setupSceneAnims(); + _emc->unload(&_scriptClickData); + loadSceneMsc(); + + _walkBlockNorth = currentRoom->northExit; + _walkBlockEast = currentRoom->eastExit; + _walkBlockSouth = currentRoom->southExit; + _walkBlockWest = currentRoom->westExit; + + if (_walkBlockNorth == 0xFFFF) + _screen->blockOutRegion(0, 0, 320, (_northExitHeight & 0xFF)+3); + if (_walkBlockEast == 0xFFFF) + _screen->blockOutRegion(312, 0, 8, 139); + if (_walkBlockSouth == 0xFFFF) + _screen->blockOutRegion(0, 135, 320, 8); + if (_walkBlockWest == 0xFFFF) + _screen->blockOutRegion(0, 0, 8, 139); + + if (!brandonAlive) + updatePlayerItemsForScene(); + + startSceneScript(brandonAlive); + setupSceneItems(); + + initSceneData(facing, unk2, brandonAlive); + + _loopFlag2 = 0; + _screen->showMouse(); + if (!brandonAlive) + seq_poisonDeathNow(0); + updateMousePointer(true); + _changedScene = true; +} + +void KyraEngine_LoK::transcendScenes(int roomIndex, int roomName) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::transcendScenes(%d, %d)", roomIndex, roomName); + assert(roomIndex < _roomTableSize); + + if (_flags.isTalkie) { + char file[32]; + assert(roomIndex < _roomTableSize); + int tableId = _roomTable[roomIndex].nameIndex; + assert(tableId < _roomFilenameTableSize); + strcpy(file, _roomFilenameTable[tableId]); + strcat(file, ".VRM"); + _res->unloadPakFile(file); + } + + _roomTable[roomIndex].nameIndex = roomName; + _unkScreenVar2 = 1; + _unkScreenVar3 = 1; + _unkScreenVar1 = 0; + _brandonPosX = _currentCharacter->x1; + _brandonPosY = _currentCharacter->y1; + enterNewScene(roomIndex, _currentCharacter->facing, 0, 0, 0); + _unkScreenVar1 = 1; + _unkScreenVar2 = 0; + _unkScreenVar3 = 0; +} + +void KyraEngine_LoK::setSceneFile(int roomIndex, int roomName) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::setSceneFile(%d, %d)", roomIndex, roomName); + assert(roomIndex < _roomTableSize); + _roomTable[roomIndex].nameIndex = roomName; +} + +void KyraEngine_LoK::moveCharacterToPos(int character, int facing, int xpos, int ypos) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::moveCharacterToPos(%d, %d, %d, %d)", character, facing, xpos, ypos); + Character *ch = &_characterList[character]; + ch->facing = facing; + _screen->hideMouse(); + xpos = (int16)(xpos & 0xFFFC); + ypos = (int16)(ypos & 0xFFFE); + _timer->disable(19); + _timer->disable(14); + _timer->disable(18); + uint32 nextFrame = 0; + + switch (facing) { + case 0: + while (ypos < ch->y1) { + nextFrame = _timer->getDelay(5 + character) * _tickLength + _system->getMillis(); + setCharacterPositionWithUpdate(character); + delayUntil(nextFrame, true); + } + break; + + case 2: + while (ch->x1 < xpos) { + nextFrame = _timer->getDelay(5 + character) * _tickLength + _system->getMillis(); + setCharacterPositionWithUpdate(character); + delayUntil(nextFrame, true); + } + break; + + case 4: + while (ypos > ch->y1) { + nextFrame = _timer->getDelay(5 + character) * _tickLength + _system->getMillis(); + setCharacterPositionWithUpdate(character); + delayUntil(nextFrame, true); + } + break; + + case 6: + while (ch->x1 > xpos) { + nextFrame = _timer->getDelay(5 + character) * _tickLength + _system->getMillis(); + setCharacterPositionWithUpdate(character); + delayUntil(nextFrame, true); + } + break; + + default: + break; + } + + _timer->enable(19); + _timer->enable(14); + _timer->enable(18); + _screen->showMouse(); +} + +void KyraEngine_LoK::setCharacterPositionWithUpdate(int character) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::setCharacterPositionWithUpdate(%d)", character); + setCharacterPosition(character, 0); + _sprites->updateSceneAnims(); + _timer->update(); + _animator->updateAllObjectShapes(); + updateTextFade(); + + if (_currentCharacter->sceneId == 210) + updateKyragemFading(); +} + +int KyraEngine_LoK::setCharacterPosition(int character, int *facingTable) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::setCharacterPosition(%d, %p)", character, (const void *)facingTable); + + if (character == 0) { + _currentCharacter->x1 += _charAddXPosTable[_currentCharacter->facing]; + _currentCharacter->y1 += _charAddYPosTable[_currentCharacter->facing]; + setCharacterPositionHelper(0, facingTable); + return 1; + } else { + _characterList[character].x1 += _charAddXPosTable[_characterList[character].facing]; + _characterList[character].y1 += _charAddYPosTable[_characterList[character].facing]; + if (_characterList[character].sceneId == _currentCharacter->sceneId) + setCharacterPositionHelper(character, 0); + } + return 0; +} + +void KyraEngine_LoK::setCharacterPositionHelper(int character, int *facingTable) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::setCharacterPositionHelper(%d, %p)", character, (const void *)facingTable); + Character *ch = &_characterList[character]; + ++ch->currentAnimFrame; + int facing = ch->facing; + if (facingTable) { + if (*facingTable != *(facingTable - 1)) { + if (*(facingTable - 1) == *(facingTable + 1)) { + facing = getOppositeFacingDirection(*(facingTable - 1)); + *facingTable = *(facingTable - 1); + } + } + } + + static uint8 facingIsZero[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + static uint8 facingIsFour[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + + if (facing == 0) { + ++facingIsZero[character]; + } else { + bool resetTables = false; + if (facing != 7) { + if (facing - 1 != 0) { + if (facing != 4) { + if (facing == 3 || facing == 5) { + if (facingIsFour[character] > 2) + facing = 4; + resetTables = true; + } + } else { + ++facingIsFour[character]; + } + } else { + if (facingIsZero[character] > 2) + facing = 0; + resetTables = true; + } + } else { + if (facingIsZero[character] > 2) + facing = 0; + resetTables = true; + } + + if (resetTables) { + facingIsZero[character] = 0; + facingIsFour[character] = 0; + } + } + + static const uint16 maxAnimationFrame[] = { + 0x000F, 0x0031, 0x0055, 0x0000, 0x0000, 0x0000, + 0x0008, 0x002A, 0x004E, 0x0000, 0x0000, 0x0000, + 0x0022, 0x0046, 0x006A, 0x0000, 0x0000, 0x0000, + 0x001D, 0x0041, 0x0065, 0x0000, 0x0000, 0x0000, + 0x001F, 0x0043, 0x0067, 0x0000, 0x0000, 0x0000, + 0x0028, 0x004C, 0x0070, 0x0000, 0x0000, 0x0000, + 0x0023, 0x0047, 0x006B, 0x0000, 0x0000, 0x0000 + }; + + if (facing == 0) { + if (maxAnimationFrame[36+character] > ch->currentAnimFrame) + ch->currentAnimFrame = maxAnimationFrame[36+character]; + if (maxAnimationFrame[30+character] < ch->currentAnimFrame) + ch->currentAnimFrame = maxAnimationFrame[36+character]; + } else if (facing == 4) { + if (maxAnimationFrame[18+character] > ch->currentAnimFrame) + ch->currentAnimFrame = maxAnimationFrame[18+character]; + if (maxAnimationFrame[12+character] < ch->currentAnimFrame) + ch->currentAnimFrame = maxAnimationFrame[18+character]; + } else { + if (maxAnimationFrame[18+character] < ch->currentAnimFrame) + ch->currentAnimFrame = maxAnimationFrame[30+character]; + if (maxAnimationFrame[character] == ch->currentAnimFrame) + ch->currentAnimFrame = maxAnimationFrame[6+character]; + if (maxAnimationFrame[character] < ch->currentAnimFrame) + ch->currentAnimFrame = maxAnimationFrame[6+character]+2; + } + + if (character == 0 && (_brandonStatusBit & 0x10)) + ch->currentAnimFrame = 88; + + _animator->animRefreshNPC(character); +} + +void KyraEngine_LoK::loadSceneMsc() { + assert(_currentCharacter->sceneId < _roomTableSize); + int tableId = _roomTable[_currentCharacter->sceneId].nameIndex; + assert(tableId < _roomFilenameTableSize); + char fileNameBuffer[32]; + strcpy(fileNameBuffer, _roomFilenameTable[tableId]); + strcat(fileNameBuffer, ".MSC"); + _screen->fillRect(0, 0, 319, 199, 0, 5); + _res->exists(fileNameBuffer, true); + _screen->loadBitmap(fileNameBuffer, 3, 5, 0); +} + +void KyraEngine_LoK::startSceneScript(int brandonAlive) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::startSceneScript(%d)", brandonAlive); + assert(_currentCharacter->sceneId < _roomTableSize); + int tableId = _roomTable[_currentCharacter->sceneId].nameIndex; + assert(tableId < _roomFilenameTableSize); + char fileNameBuffer[32]; + strcpy(fileNameBuffer, _roomFilenameTable[tableId]); + strcat(fileNameBuffer, ".CPS"); + _screen->clearPage(3); + _res->exists(fileNameBuffer, true); + // FIXME: check this hack for amiga version + _screen->loadBitmap(fileNameBuffer, 3, 3, (_flags.platform == Common::kPlatformAmiga ? _screen->getPalette(0) : 0)); + _sprites->loadSceneShapes(); + _exitListPtr = 0; + + _scaleMode = 1; + for (int i = 0; i < 145; ++i) + _scaleTable[i] = 256; + + clearNoDropRects(); + _emc->init(&_scriptClick, &_scriptClickData); + strcpy(fileNameBuffer, _roomFilenameTable[tableId]); + strcat(fileNameBuffer, ".EMC"); + _res->exists(fileNameBuffer, true); + _emc->unload(&_scriptClickData); + _emc->load(fileNameBuffer, &_scriptClickData, &_opcodes); + _emc->start(&_scriptClick, 0); + _scriptClick.regs[0] = _currentCharacter->sceneId; + _scriptClick.regs[7] = brandonAlive; + + while (_emc->isValid(&_scriptClick)) + _emc->run(&_scriptClick); +} + +void KyraEngine_LoK::initSceneData(int facing, int unk1, int brandonAlive) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::initSceneData(%d, %d, %d)", facing, unk1, brandonAlive); + + int16 xpos2 = 0; + int setFacing = 1; + + int16 xpos = 0, ypos = 0; + + if (_brandonPosX == -1 && _brandonPosY == -1) { + switch (facing + 1) { + case 0: + xpos = ypos = -1; + break; + + case 1: case 2: case 8: + xpos = _sceneExits.southXPos; + ypos = _sceneExits.southYPos; + break; + + case 3: + xpos = _sceneExits.westXPos; + ypos = _sceneExits.westYPos; + break; + + case 4: case 5: case 6: + xpos = _sceneExits.northXPos; + ypos = _sceneExits.northYPos; + break; + + case 7: + xpos = _sceneExits.eastXPos; + ypos = _sceneExits.eastYPos; + break; + + default: + break; + } + + if ((uint8)(_northExitHeight & 0xFF) + 2 >= ypos) + ypos = (_northExitHeight & 0xFF) + 4; + if (xpos >= 308) + xpos = 304; + if ((uint8)(_northExitHeight >> 8) - 2 <= ypos) + ypos = (_northExitHeight >> 8) - 4; + if (xpos <= 12) + xpos = 16; + } + + if (_brandonPosX > -1) + xpos = _brandonPosX; + if (_brandonPosY > -1) + ypos = _brandonPosY; + + int16 ypos2 = 0; + if (_brandonPosX > -1 && _brandonPosY > -1) { + switch (_currentCharacter->sceneId) { + case 1: + _currentCharacter->x1 = xpos; + _currentCharacter->x2 = xpos; + _currentCharacter->y1 = ypos; + _currentCharacter->y2 = ypos; + facing = 4; + xpos2 = 192; + ypos2 = 104; + setFacing = 0; + unk1 = 1; + break; + + case 3: + _currentCharacter->x1 = xpos; + _currentCharacter->x2 = xpos; + _currentCharacter->y1 = ypos; + _currentCharacter->y2 = ypos; + facing = 2; + xpos2 = 204; + ypos2 = 94; + setFacing = 0; + unk1 = 1; + break; + + case 26: + _currentCharacter->x1 = xpos; + _currentCharacter->x2 = xpos; + _currentCharacter->y1 = ypos; + _currentCharacter->y2 = ypos; + facing = 2; + xpos2 = 192; + ypos2 = 128; + setFacing = 0; + unk1 = 1; + break; + + case 44: + _currentCharacter->x1 = xpos; + _currentCharacter->x2 = xpos; + _currentCharacter->y1 = ypos; + _currentCharacter->y2 = ypos; + facing = 6; + xpos2 = 156; + ypos2 = 96; + setFacing = 0; + unk1 = 1; + break; + + case 37: + _currentCharacter->x1 = xpos; + _currentCharacter->x2 = xpos; + _currentCharacter->y1 = ypos; + _currentCharacter->y2 = ypos; + facing = 2; + xpos2 = 148; + ypos2 = 114; + setFacing = 0; + unk1 = 1; + break; + + default: + break; + } + } + + _brandonPosX = _brandonPosY = -1; + + if (unk1 && setFacing) { + ypos2 = ypos; + xpos2 = xpos; + switch (facing) { + case 0: + ypos = 142; + break; + + case 2: + xpos = -16; + break; + + case 4: + ypos = (uint8)(_northExitHeight & 0xFF) - 4; + break; + + case 6: + xpos = 336; + break; + + default: + break; + } + } + + xpos2 = (int16)(xpos2 & 0xFFFC); + ypos2 = (int16)(ypos2 & 0xFFFE); + xpos = (int16)(xpos & 0xFFFC); + ypos = (int16)(ypos & 0xFFFE); + _currentCharacter->facing = facing; + _currentCharacter->x1 = xpos; + _currentCharacter->x2 = xpos; + _currentCharacter->y1 = ypos; + _currentCharacter->y2 = ypos; + + initSceneObjectList(brandonAlive); + + if (unk1 && brandonAlive == 0) + moveCharacterToPos(0, facing, xpos2, ypos2); + + _scriptClick.regs[4] = _itemInHand; + _scriptClick.regs[7] = brandonAlive; + _emc->start(&_scriptClick, 3); + while (_emc->isValid(&_scriptClick)) + _emc->run(&_scriptClick); +} + +void KyraEngine_LoK::initSceneObjectList(int brandonAlive) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::initSceneObjectList(%d)", brandonAlive); + for (int i = 0; i < 28; ++i) + _animator->actors()[i].active = 0; + + int startAnimFrame = 0; + + Animator_LoK::AnimObject *curAnimState = _animator->actors(); + curAnimState->active = 1; + curAnimState->drawY = _currentCharacter->y1; + curAnimState->sceneAnimPtr = _shapes[_currentCharacter->currentAnimFrame]; + curAnimState->animFrameNumber = _currentCharacter->currentAnimFrame; + startAnimFrame = _currentCharacter->currentAnimFrame-7; + int xOffset = _defaultShapeTable[startAnimFrame].xOffset; + int yOffset = _defaultShapeTable[startAnimFrame].yOffset; + + if (_scaleMode) { + curAnimState->x1 = _currentCharacter->x1; + curAnimState->y1 = _currentCharacter->y1; + + _animator->_brandonScaleX = _scaleTable[_currentCharacter->y1]; + _animator->_brandonScaleY = _scaleTable[_currentCharacter->y1]; + + curAnimState->x1 += (_animator->_brandonScaleX * xOffset) >> 8; + curAnimState->y1 += (_animator->_brandonScaleY * yOffset) >> 8; + } else { + curAnimState->x1 = _currentCharacter->x1 + xOffset; + curAnimState->y1 = _currentCharacter->y1 + yOffset; + } + + curAnimState->x2 = curAnimState->x1; + curAnimState->y2 = curAnimState->y1; + curAnimState->refreshFlag = 1; + curAnimState->bkgdChangeFlag = 1; + _animator->clearQueue(); + _animator->addObjectToQueue(curAnimState); + + int listAdded = 0; + int addedObjects = 1; + + for (int i = 1; i < 5; ++i) { + Character *ch = &_characterList[i]; + curAnimState = &_animator->actors()[addedObjects]; + if (ch->sceneId != _currentCharacter->sceneId) { + curAnimState->active = 0; + curAnimState->refreshFlag = 0; + curAnimState->bkgdChangeFlag = 0; + ++addedObjects; + continue; + } + + curAnimState->drawY = ch->y1; + curAnimState->sceneAnimPtr = _shapes[ch->currentAnimFrame]; + curAnimState->animFrameNumber = ch->currentAnimFrame; + startAnimFrame = ch->currentAnimFrame-7; + xOffset = _defaultShapeTable[startAnimFrame].xOffset; + yOffset = _defaultShapeTable[startAnimFrame].yOffset; + if (_scaleMode) { + curAnimState->x1 = ch->x1; + curAnimState->y1 = ch->y1; + + _animator->_brandonScaleX = _scaleTable[ch->y1]; + _animator->_brandonScaleY = _scaleTable[ch->y1]; + + curAnimState->x1 += (_animator->_brandonScaleX * xOffset) >> 8; + curAnimState->y1 += (_animator->_brandonScaleY * yOffset) >> 8; + } else { + curAnimState->x1 = ch->x1 + xOffset; + curAnimState->y1 = ch->y1 + yOffset; + } + curAnimState->x2 = curAnimState->x1; + curAnimState->y2 = curAnimState->y1; + curAnimState->active = 1; + curAnimState->refreshFlag = 1; + curAnimState->bkgdChangeFlag = 1; + + if (ch->facing >= 1 && ch->facing <= 3) + curAnimState->flags |= 1; + else if (ch->facing >= 5 && ch->facing <= 7) + curAnimState->flags &= 0xFFFFFFFE; + + _animator->addObjectToQueue(curAnimState); + + ++addedObjects; + ++listAdded; + if (listAdded < 2) + i = 5; + } + + for (int i = 0; i < 11; ++i) { + curAnimState = &_animator->sprites()[i]; + + if (_sprites->_anims[i].play) { + curAnimState->active = 1; + curAnimState->refreshFlag = 1; + curAnimState->bkgdChangeFlag = 1; + } else { + curAnimState->active = 0; + curAnimState->refreshFlag = 0; + curAnimState->bkgdChangeFlag = 0; + } + curAnimState->height = _sprites->_anims[i].height; + curAnimState->height2 = _sprites->_anims[i].height2; + curAnimState->width = _sprites->_anims[i].width + 1; + curAnimState->width2 = _sprites->_anims[i].width2; + curAnimState->drawY = _sprites->_anims[i].drawY; + curAnimState->x1 = curAnimState->x2 = _sprites->_anims[i].x; + curAnimState->y1 = curAnimState->y2 = _sprites->_anims[i].y; + curAnimState->background = _sprites->_anims[i].background; + curAnimState->sceneAnimPtr = _sprites->_sceneShapes[_sprites->_anims[i].sprite]; + + curAnimState->disable = _sprites->_anims[i].disable; + + if (_sprites->_anims[i].unk2) + curAnimState->flags = 0x800; + else + curAnimState->flags = 0; + + if (_sprites->_anims[i].flipX) + curAnimState->flags |= 0x1; + + _animator->addObjectToQueue(curAnimState); + } + + for (int i = 0; i < 12; ++i) { + curAnimState = &_animator->items()[i]; + Room *curRoom = &_roomTable[_currentCharacter->sceneId]; + byte curItem = curRoom->itemsTable[i]; + if (curItem != 0xFF) { + curAnimState->drawY = curRoom->itemsYPos[i]; + curAnimState->sceneAnimPtr = _shapes[216+curItem]; + curAnimState->animFrameNumber = (int16)0xFFFF; + curAnimState->y1 = curRoom->itemsYPos[i]; + curAnimState->x1 = curRoom->itemsXPos[i]; + + curAnimState->x1 -= (_animator->fetchAnimWidth(curAnimState->sceneAnimPtr, _scaleTable[curAnimState->drawY])) >> 1; + curAnimState->y1 -= _animator->fetchAnimHeight(curAnimState->sceneAnimPtr, _scaleTable[curAnimState->drawY]); + + curAnimState->x2 = curAnimState->x1; + curAnimState->y2 = curAnimState->y1; + + curAnimState->active = 1; + curAnimState->refreshFlag = 1; + curAnimState->bkgdChangeFlag = 1; + + _animator->addObjectToQueue(curAnimState); + } else { + curAnimState->active = 0; + curAnimState->refreshFlag = 0; + curAnimState->bkgdChangeFlag = 0; + } + } + + _animator->preserveAnyChangedBackgrounds(); + curAnimState = _animator->actors(); + curAnimState->bkgdChangeFlag = 1; + curAnimState->refreshFlag = 1; + for (int i = 1; i < 28; ++i) { + curAnimState = &_animator->objects()[i]; + if (curAnimState->active) { + curAnimState->bkgdChangeFlag = 1; + curAnimState->refreshFlag = 1; + } + } + _animator->restoreAllObjectBackgrounds(); + _animator->preserveAnyChangedBackgrounds(); + _animator->prepDrawAllObjects(); + initSceneScreen(brandonAlive); + _animator->copyChangedObjectsForward(0); +} + +void KyraEngine_LoK::initSceneScreen(int brandonAlive) { + if (_flags.platform == Common::kPlatformAmiga) { + if (_unkScreenVar1 && !queryGameFlag(0xF0)) { + memset(_screen->getPalette(2), 0, 32*3); + if (_currentCharacter->sceneId != 117 || !queryGameFlag(0xB3)) + _screen->setScreenPalette(_screen->getPalette(2)); + } + + if (_unkScreenVar2 == 1) + _screen->shuffleScreen(8, 8, 304, 128, 2, 0, _unkScreenVar3, false); + else + _screen->copyRegion(8, 8, 8, 8, 304, 128, 2, 0); + + if (_unkScreenVar1 && !queryGameFlag(0xA0)) { + if (_currentCharacter->sceneId == 45 && _paletteChanged) + memcpy(_screen->getPalette(0) + 12*3, _screen->getPalette(4) + 12*3, 2); + + if (_currentCharacter->sceneId >= 229 && _currentCharacter->sceneId <= 245 && (_brandonStatusBit & 1)) + memcpy(_screen->getPalette(0), _screen->getPalette(0) + 320*3, 64); + + _screen->setScreenPalette(_screen->getPalette(0)); + } + } else { + if (_unkScreenVar1 && !queryGameFlag(0xA0)) { + for (int i = 0; i < 60; ++i) { + uint16 col = _screen->getPalette(0)[684+i]; + col += _screen->getPalette(1)[684+i] << 1; + col >>= 2; + _screen->getPalette(0)[684+i] = col; + } + _screen->setScreenPalette(_screen->getPalette(0)); + } + + if (_unkScreenVar2 == 1) + _screen->shuffleScreen(8, 8, 304, 128, 2, 0, _unkScreenVar3, false); + else + _screen->copyRegion(8, 8, 8, 8, 304, 128, 2, 0); + + if (_unkScreenVar1 && _paletteChanged) { + if (!queryGameFlag(0xA0)) { + memcpy(_screen->getPalette(0) + 684, _screen->getPalette(1) + 684, 60); + _screen->setScreenPalette(_screen->getPalette(0)); + } else { + memset(_screen->getPalette(0), 0, 768); + } + } + } + + if (!_emc->start(&_scriptClick, 2)) + error("Could not start script function 2 of scene script"); + + _scriptClick.regs[7] = brandonAlive; + + while (_emc->isValid(&_scriptClick)) + _emc->run(&_scriptClick); + + setTextFadeTimerCountdown(-1); + if (_currentCharacter->sceneId == 210) { + if (_itemInHand != -1) + magicOutMouseItem(2, -1); + + _screen->hideMouse(); + for (int i = 0; i < 10; ++i) { + if (_currentCharacter->inventoryItems[i] != 0xFF) + magicOutMouseItem(2, i); + } + _screen->showMouse(); + } +} + +int KyraEngine_LoK::handleSceneChange(int xpos, int ypos, int unk1, int frameReset) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::handleSceneChange(%d, %d, %d, %d)", xpos, ypos, unk1, frameReset); + if (queryGameFlag(0xEF)) + unk1 = 0; + + int sceneId = _currentCharacter->sceneId; + _pathfinderFlag = 0; + + if (xpos < 12) { + if (_roomTable[sceneId].westExit != 0xFFFF) { + xpos = 12; + ypos = _sceneExits.westYPos; + _pathfinderFlag = 7; + } + } else if (xpos >= 308) { + if (_roomTable[sceneId].eastExit != 0xFFFF) { + xpos = 307; + ypos = _sceneExits.eastYPos; + _pathfinderFlag = 13; + } + } + + if (ypos <= (_northExitHeight&0xFF)+2) { + if (_roomTable[sceneId].northExit != 0xFFFF) { + xpos = _sceneExits.northXPos; + ypos = _northExitHeight & 0xFF; + _pathfinderFlag = 14; + } + } else if (ypos >= 136) { + if (_roomTable[sceneId].southExit != 0xFFFF) { + xpos = _sceneExits.southXPos; + ypos = 136; + _pathfinderFlag = 11; + } + } + + int temp = xpos - _currentCharacter->x1; + if (ABS(temp) < 4) { + temp = ypos - _currentCharacter->y1; + if (ABS(temp) < 2) + return 0; + } + + int x = (int16)(_currentCharacter->x1 & 0xFFFC); + int y = (int16)(_currentCharacter->y1 & 0xFFFE); + xpos = (int16)(xpos & 0xFFFC); + ypos = (int16)(ypos & 0xFFFE); + + int ret = findWay(x, y, xpos, ypos, _movFacingTable, 150); + _pathfinderFlag = 0; + + if (ret >= _lastFindWayRet) + _lastFindWayRet = ret; + + if (ret == 0x7D00 || ret == 0) + return 0; + + return processSceneChange(_movFacingTable, unk1, frameReset); +} + +int KyraEngine_LoK::processSceneChange(int *table, int unk1, int frameReset) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::processSceneChange(%p, %d, %d)", (const void *)table, unk1, frameReset); + if (queryGameFlag(0xEF)) + unk1 = 0; + + int *tableStart = table; + _sceneChangeState = 0; + _loopFlag2 = 0; + bool running = true; + int returnValue = 0; + uint32 nextFrame = 0; + _abortWalkFlag = false; + _mousePressFlag = false; + + while (running) { + if (_abortWalkFlag) { + *table = 8; + _currentCharacter->currentAnimFrame = 7; + _animator->animRefreshNPC(0); + _animator->updateAllObjectShapes(); + processInput(); + return 0; + } + bool forceContinue = false; + switch (*table) { + case 0: case 1: case 2: + case 3: case 4: case 5: + case 6: case 7: + _currentCharacter->facing = getOppositeFacingDirection(*table); + break; + + case 8: + forceContinue = true; + running = false; + break; + + default: + ++table; + forceContinue = true; + break; + } + + returnValue = changeScene(_currentCharacter->facing); + if (returnValue) { + running = false; + _abortWalkFlag = false; + } + + if (unk1) { + if (_mousePressFlag) { + running = false; + _sceneChangeState = 1; + } + } + + if (forceContinue || !running) + continue; + + int temp = 0; + if (table == tableStart || table[1] == 8) + temp = setCharacterPosition(0, 0); + else + temp = setCharacterPosition(0, table); + + if (temp) + ++table; + + nextFrame = _timer->getDelay(5) * _tickLength + _system->getMillis(); + while (_system->getMillis() < nextFrame) { + _timer->update(); + + if (_currentCharacter->sceneId == 210) { + updateKyragemFading(); + if (seq_playEnd() || _beadStateVar == 4 || _beadStateVar == 5) { + *table = 8; + running = false; + break; + } + } + + if ((nextFrame - _system->getMillis()) >= 10) + delay(10, true); + } + } + + if (frameReset && !(_brandonStatusBit & 2)) + _currentCharacter->currentAnimFrame = 7; + + _animator->animRefreshNPC(0); + _animator->updateAllObjectShapes(); + return returnValue; +} + +int KyraEngine_LoK::changeScene(int facing) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::changeScene(%d)", facing); + if (queryGameFlag(0xEF)) { + if (_currentCharacter->sceneId == 5) + return 0; + } + + int xpos = _charAddXPosTable[facing] + _currentCharacter->x1; + int ypos = _charAddYPosTable[facing] + _currentCharacter->y1; + + if (xpos >= 12 && xpos <= 308) { + if (!lineIsPassable(xpos, ypos)) + return false; + } + + if (_exitListPtr) { + int16 *ptr = _exitListPtr; + // this loop should be only entered one time, seems to be some hack in the original + while (true) { + if (*ptr == -1) + break; + + if (*ptr > _currentCharacter->x1 || _currentCharacter->y1 < ptr[1] || _currentCharacter->x1 > ptr[2] || _currentCharacter->y1 > ptr[3]) { + ptr += 10; + break; + } + + _brandonPosX = ptr[6]; + _brandonPosY = ptr[7]; + uint16 sceneId = ptr[5]; + facing = ptr[4]; + int unk1 = ptr[8]; + int unk2 = ptr[9]; + + if (sceneId == 0xFFFF) { + switch (facing) { + case 0: + sceneId = _roomTable[_currentCharacter->sceneId].northExit; + break; + + case 2: + sceneId = _roomTable[_currentCharacter->sceneId].eastExit; + break; + + case 4: + sceneId = _roomTable[_currentCharacter->sceneId].southExit; + break; + + case 6: + sceneId = _roomTable[_currentCharacter->sceneId].westExit; + break; + + default: + break; + } + } + + _currentCharacter->facing = facing; + _animator->animRefreshNPC(0); + _animator->updateAllObjectShapes(); + enterNewScene(sceneId, facing, unk1, unk2, 0); + resetGameFlag(0xEE); + return 1; + } + } + + int returnValue = 0; + facing = 0; + + if ((_northExitHeight & 0xFF) + 2 >= ypos || (_northExitHeight & 0xFF) + 2 >= _currentCharacter->y1) { + facing = 0; + returnValue = 1; + } + + if (xpos >= 308 || (_currentCharacter->x1 + 4) >= 308) { + facing = 2; + returnValue = 1; + } + + if (((_northExitHeight >> 8) & 0xFF) - 2 < ypos || ((_northExitHeight >> 8) & 0xFF) - 2 < _currentCharacter->y1) { + facing = 4; + returnValue = 1; + } + + if (xpos <= 12 || _currentCharacter->y1 <= 12) { + facing = 6; + returnValue = 1; + } + + if (!returnValue) + return 0; + + uint16 sceneId = 0xFFFF; + switch (facing) { + case 0: + sceneId = _roomTable[_currentCharacter->sceneId].northExit; + break; + + case 2: + sceneId = _roomTable[_currentCharacter->sceneId].eastExit; + break; + + case 4: + sceneId = _roomTable[_currentCharacter->sceneId].southExit; + break; + + default: + sceneId = _roomTable[_currentCharacter->sceneId].westExit; + break; + } + + if (sceneId == 0xFFFF) + return 0; + + enterNewScene(sceneId, facing, 1, 1, 0); + return returnValue; +} + +void KyraEngine_LoK::setCharactersInDefaultScene() { + static const uint32 defaultSceneTable[][4] = { + { 0xFFFF, 0x0004, 0x0003, 0xFFFF }, + { 0xFFFF, 0x0022, 0xFFFF, 0x0000 }, + { 0xFFFF, 0x001D, 0x0021, 0xFFFF }, + { 0xFFFF, 0x0000, 0x0000, 0xFFFF } + }; + + for (int i = 1; i < 5; ++i) { + Character *cur = &_characterList[i]; + //cur->field_20 = 0; + + const uint32 *curTable = defaultSceneTable[i-1]; + cur->sceneId = curTable[0]; + + if (cur->sceneId == _currentCharacter->sceneId) + //++cur->field_20; + cur->sceneId = curTable[1/*cur->field_20*/]; + + //cur->field_23 = curTable[cur->field_20+1]; + } +} + +void KyraEngine_LoK::setCharactersPositions(int character) { + static uint16 initXPosTable[] = { + 0x3200, 0x0024, 0x2230, 0x2F00, 0x0020, 0x002B, + 0x00CA, 0x00F0, 0x0082, 0x00A2, 0x0042 + }; + static uint8 initYPosTable[] = { + 0x00, 0xA2, 0x00, 0x42, 0x00, + 0x67, 0x67, 0x60, 0x5A, 0x71, + 0x76 + }; + + assert(character < ARRAYSIZE(initXPosTable)); + Character *edit = &_characterList[character]; + edit->x1 = edit->x2 = initXPosTable[character]; + edit->y1 = edit->y2 = initYPosTable[character]; +} + +#pragma mark - +#pragma mark - Pathfinder +#pragma mark - + +int KyraEngine_LoK::findWay(int x, int y, int toX, int toY, int *moveTable, int moveTableSize) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::findWay(%d, %d, %d, %d, %p, %d)", x, y, toX, toY, (const void *)moveTable, moveTableSize); + int ret = KyraEngine_v1::findWay(x, y, toX, toY, moveTable, moveTableSize); + if (ret == 0x7D00) + return 0; + return getMoveTableSize(moveTable); +} + +bool KyraEngine_LoK::lineIsPassable(int x, int y) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::lineIsPassable(%d, %d)", x, y); + if (queryGameFlag(0xEF)) { + if (_currentCharacter->sceneId == 5) + return true; + } + + if (_pathfinderFlag & 2) { + if (x >= 312) + return false; + } + + if (_pathfinderFlag & 4) { + if (y >= 136) + return false; + } + + if (_pathfinderFlag & 8) { + if (x < 8) + return false; + } + + if (_pathfinderFlag2) { + if (x <= 8 || x >= 312) + return true; + if (y < (_northExitHeight & 0xFF) || y > 135) + return true; + } + + if (y > 137) + return false; + + if (y < 0) + y = 0; + + int ypos = 8; + if (_scaleMode) { + ypos = (_scaleTable[y] >> 5) + 1; + if (8 < ypos) + ypos = 8; + } + + x -= (ypos >> 1); + + int xpos = x; + int xtemp = xpos + ypos - 1; + if (x < 0) + xpos = 0; + + if (xtemp > 319) + xtemp = 319; + + for (; xpos < xtemp; ++xpos) { + if (!_screen->getShapeFlag1(xpos, y)) + return false; + } + return true; +} + +#pragma mark - + +void KyraEngine_LoK::setupSceneResource(int sceneId) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::setupSceneResource(%d)", sceneId); + if (!_flags.isTalkie) + return; + + if (_currentRoom != 0xFFFF) { + assert(_currentRoom < _roomTableSize); + int tableId = _roomTable[_currentRoom].nameIndex; + assert(tableId < _roomFilenameTableSize); + + // unload our old room + char file[64]; + strcpy(file, _roomFilenameTable[tableId]); + strcat(file, ".VRM"); + _res->unloadPakFile(file); + + strcpy(file, _roomFilenameTable[tableId]); + strcat(file, ".PAK"); + _res->unloadPakFile(file); + + strcpy(file, _roomFilenameTable[tableId]); + strcat(file, ".APK"); + _res->unloadPakFile(file); + } + + assert(sceneId < _roomTableSize); + int tableId = _roomTable[sceneId].nameIndex; + assert(tableId < _roomFilenameTableSize); + + // load our new room + char file[64]; + strcpy(file, _roomFilenameTable[tableId]); + strcat(file, ".VRM"); + if (_res->exists(file)) + _res->loadPakFile(file); + + strcpy(file, _roomFilenameTable[tableId]); + strcat(file, ".PAK"); + if (_res->exists(file)) + _res->loadPakFile(file); + + strcpy(file, _roomFilenameTable[tableId]); + strcat(file, ".APK"); + if (_res->exists(file)) + _res->loadPakFile(file); +} + +} // end of namespace Kyra + diff --git a/engines/kyra/scene_mr.cpp b/engines/kyra/scene_mr.cpp index 196c87424d..e4a3a5c54e 100644 --- a/engines/kyra/scene_mr.cpp +++ b/engines/kyra/scene_mr.cpp @@ -182,7 +182,7 @@ void KyraEngine_MR::enterNewScene(uint16 sceneId, int facing, int unk1, int unk2 if (_itemInHand < 0) { _itemInHand = -1; - _handItemSet = -1; + _mouseState = -1; _screen->setMouseCursor(0, 0, _gameShapes[0]); } @@ -311,7 +311,7 @@ void KyraEngine_MR::enterNewSceneUnk2(int unk1) { void KyraEngine_MR::unloadScene() { debugC(9, kDebugLevelMain, "KyraEngine_MR::unloadScene()"); - delete [] _sceneStrings; + delete[] _sceneStrings; _sceneStrings = 0; musicUpdate(0); _emc->unload(&_sceneScriptData); @@ -325,7 +325,7 @@ void KyraEngine_MR::unloadScene() { void KyraEngine_MR::freeSceneShapes() { debugC(9, kDebugLevelMain, "KyraEngine_MR::freeSceneShapes()"); for (uint i = 0; i < ARRAYSIZE(_sceneShapes); ++i) { - delete [] _sceneShapes[i]; + delete[] _sceneShapes[i]; _sceneShapes[i] = 0; } } @@ -430,6 +430,8 @@ void KyraEngine_MR::initSceneScript(int unk1) { _screen->_curPage = pageBackUp; musicUpdate(0); } + delete stream; + stream = 0; musicUpdate(0); strcpy(filename, scene.filename1); @@ -691,7 +693,7 @@ int KyraEngine_MR::trySceneChange(int *moveTable, int unk1, int updateChar) { if (ret) ++moveTable; - update(); + delay(10, true); } if (updateChar) diff --git a/engines/kyra/scene_v1.cpp b/engines/kyra/scene_v1.cpp index c5d1de82a9..65171ad831 100644 --- a/engines/kyra/scene_v1.cpp +++ b/engines/kyra/scene_v1.cpp @@ -24,1261 +24,360 @@ */ #include "kyra/kyra_v1.h" -#include "kyra/seqplayer.h" #include "kyra/screen.h" -#include "kyra/resource.h" -#include "kyra/sound.h" -#include "kyra/sprites.h" -#include "kyra/wsamovie.h" -#include "kyra/animator_v1.h" -#include "kyra/text.h" -#include "kyra/script.h" -#include "kyra/timer.h" - -#include "common/system.h" -#include "common/savefile.h" namespace Kyra { -void KyraEngine_v1::enterNewScene(int sceneId, int facing, int unk1, int unk2, int brandonAlive) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::enterNewScene(%d, %d, %d, %d, %d)", sceneId, facing, unk1, unk2, brandonAlive); - int unkVar1 = 1; - _screen->hideMouse(); - _handleInput = false; - _abortWalkFlag = false; - _abortWalkFlag2 = false; - - if (_flags.platform == Common::kPlatformFMTowns || _flags.platform == Common::kPlatformPC98) { - int newSfxFile = -1; - if (_currentCharacter->sceneId == 7 && sceneId == 24) - newSfxFile = 2; - else if (_currentCharacter->sceneId == 25 && sceneId == 109) - newSfxFile = 3; - else if (_currentCharacter->sceneId == 120 && sceneId == 37) - newSfxFile = 4; - else if (_currentCharacter->sceneId == 52 && sceneId == 199) - newSfxFile = 5; - else if (_currentCharacter->sceneId == 37 && sceneId == 120) - newSfxFile = 3; - else if (_currentCharacter->sceneId == 109 && sceneId == 25) - newSfxFile = 2; - else if (_currentCharacter->sceneId == 24 && sceneId == 7) - newSfxFile = 1; - - if (newSfxFile != -1) { - _curSfxFile = newSfxFile; - _sound->loadSoundFile(_curSfxFile); - } - } - - switch (_currentCharacter->sceneId) { - case 1: - if (sceneId == 0) { - moveCharacterToPos(0, 0, _currentCharacter->x1, 84); - unkVar1 = 0; - } - break; - - case 3: - if (sceneId == 2) { - moveCharacterToPos(0, 6, 155, _currentCharacter->y1); - unkVar1 = 0; - } - break; - - case 26: - if (sceneId == 27) { - moveCharacterToPos(0, 6, 155, _currentCharacter->y1); - unkVar1 = 0; - } - break; - - case 44: - if (sceneId == 45) { - moveCharacterToPos(0, 2, 192, _currentCharacter->y1); - unkVar1 = 0; - } - break; +int KyraEngine_v1::findWay(int x, int y, int toX, int toY, int *moveTable, int moveTableSize) { + debugC(9, kDebugLevelMain, "KyraEngine_v1::findWay(%d, %d, %d, %d, %p, %d)", x, y, toX, toY, (const void *)moveTable, moveTableSize); + x &= 0xFFFC; toX &= 0xFFFC; + y &= 0xFFFE; toY &= 0xFFFE; + x = (int16)x; y = (int16)y; toX = (int16)toX; toY = (int16)toY; - default: - break; + if (x == toY && y == toY) { + moveTable[0] = 8; + return 0; } - if (unkVar1 && unk1) { - int xpos = _currentCharacter->x1; - int ypos = _currentCharacter->y1; - switch (facing) { - case 0: - ypos = _currentCharacter->y1 - 6; - break; - - case 2: - xpos = 336; - break; - - case 4: - ypos = 143; - break; + int curX = x; + int curY = y; + int tempValue = 0; + int lastUsedEntry = 0; + int *pathTable1 = new int[0x7D0]; + int *pathTable2 = new int[0x7D0]; + assert(pathTable1 && pathTable2); - case 6: - xpos = -16; - break; + while (true) { + int newFacing = getFacingFromPointToPoint(x, y, toX, toY); + changePosTowardsFacing(curX, curY, newFacing); - default: + if (curX == toX && curY == toY) { + if (!lineIsPassable(curX, curY)) + break; + moveTable[lastUsedEntry++] = newFacing; break; } - moveCharacterToPos(0, facing, xpos, ypos); - } - - for (int i = 0; i < ARRAYSIZE(_movieObjects); ++i) - _movieObjects[i]->close(); - - if (!brandonAlive) { - _emc->init(&_scriptClick, &_scriptClickData); - _emc->start(&_scriptClick, 5); - while (_emc->isValid(&_scriptClick)) - _emc->run(&_scriptClick); - } - - memset(_entranceMouseCursorTracks, 0xFFFF, sizeof(uint16)*4); - _currentCharacter->sceneId = sceneId; - - assert(sceneId < _roomTableSize); - assert(_roomTable[sceneId].nameIndex < _roomFilenameTableSize); - - Room *currentRoom = &_roomTable[sceneId]; - - setupSceneResource(sceneId); - - _currentRoom = sceneId; - - int tableId = _roomTable[sceneId].nameIndex; - char fileNameBuffer[32]; - strcpy(fileNameBuffer, _roomFilenameTable[tableId]); - strcat(fileNameBuffer, ".DAT"); - _sprites->loadDat(fileNameBuffer, _sceneExits); - _sprites->setupSceneAnims(); - _emc->unload(&_scriptClickData); - loadSceneMsc(); - - _walkBlockNorth = currentRoom->northExit; - _walkBlockEast = currentRoom->eastExit; - _walkBlockSouth = currentRoom->southExit; - _walkBlockWest = currentRoom->westExit; - - if (_walkBlockNorth == 0xFFFF) - _screen->blockOutRegion(0, 0, 320, (_northExitHeight & 0xFF)+3); - if (_walkBlockEast == 0xFFFF) - _screen->blockOutRegion(312, 0, 8, 139); - if (_walkBlockSouth == 0xFFFF) - _screen->blockOutRegion(0, 135, 320, 8); - if (_walkBlockWest == 0xFFFF) - _screen->blockOutRegion(0, 0, 8, 139); - - if (!brandonAlive) - updatePlayerItemsForScene(); - - startSceneScript(brandonAlive); - setupSceneItems(); - - initSceneData(facing, unk2, brandonAlive); - - _loopFlag2 = 0; - _screen->showMouse(); - if (!brandonAlive) - seq_poisonDeathNow(0); - updateMousePointer(true); - _changedScene = true; -} - -void KyraEngine_v1::transcendScenes(int roomIndex, int roomName) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::transcendScenes(%d, %d)", roomIndex, roomName); - assert(roomIndex < _roomTableSize); - - if (_flags.isTalkie) { - char file[32]; - assert(roomIndex < _roomTableSize); - int tableId = _roomTable[roomIndex].nameIndex; - assert(tableId < _roomFilenameTableSize); - strcpy(file, _roomFilenameTable[tableId]); - strcat(file, ".VRM"); - _res->unloadPakFile(file); - } - - _roomTable[roomIndex].nameIndex = roomName; - _unkScreenVar2 = 1; - _unkScreenVar3 = 1; - _unkScreenVar1 = 0; - _brandonPosX = _currentCharacter->x1; - _brandonPosY = _currentCharacter->y1; - enterNewScene(roomIndex, _currentCharacter->facing, 0, 0, 0); - _unkScreenVar1 = 1; - _unkScreenVar2 = 0; - _unkScreenVar3 = 0; -} - -void KyraEngine_v1::setSceneFile(int roomIndex, int roomName) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::setSceneFile(%d, %d)", roomIndex, roomName); - assert(roomIndex < _roomTableSize); - _roomTable[roomIndex].nameIndex = roomName; -} - -void KyraEngine_v1::moveCharacterToPos(int character, int facing, int xpos, int ypos) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::moveCharacterToPos(%d, %d, %d, %d)", character, facing, xpos, ypos); - Character *ch = &_characterList[character]; - ch->facing = facing; - _screen->hideMouse(); - xpos = (int16)(xpos & 0xFFFC); - ypos = (int16)(ypos & 0xFFFE); - _timer->disable(19); - _timer->disable(14); - _timer->disable(18); - uint32 nextFrame = 0; - - switch (facing) { - case 0: - while (ypos < ch->y1) { - nextFrame = _timer->getDelay(5 + character) * _tickLength + _system->getMillis(); - setCharacterPositionWithUpdate(character); - delayUntil(nextFrame, true); - } - break; - - case 2: - while (ch->x1 < xpos) { - nextFrame = _timer->getDelay(5 + character) * _tickLength + _system->getMillis(); - setCharacterPositionWithUpdate(character); - delayUntil(nextFrame, true); - } - break; - - case 4: - while (ypos > ch->y1) { - nextFrame = _timer->getDelay(5 + character) * _tickLength + _system->getMillis(); - setCharacterPositionWithUpdate(character); - delayUntil(nextFrame, true); - } - break; - - case 6: - while (ch->x1 > xpos) { - nextFrame = _timer->getDelay(5 + character) * _tickLength + _system->getMillis(); - setCharacterPositionWithUpdate(character); - delayUntil(nextFrame, true); - } - break; - - default: - break; - } - - _timer->enable(19); - _timer->enable(14); - _timer->enable(18); - _screen->showMouse(); -} - -void KyraEngine_v1::setCharacterPositionWithUpdate(int character) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::setCharacterPositionWithUpdate(%d)", character); - setCharacterPosition(character, 0); - _sprites->updateSceneAnims(); - _timer->update(); - _animator->updateAllObjectShapes(); - updateTextFade(); - - if (_currentCharacter->sceneId == 210) - updateKyragemFading(); -} - -int KyraEngine_v1::setCharacterPosition(int character, int *facingTable) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::setCharacterPosition(%d, %p)", character, (const void *)facingTable); - - if (character == 0) { - _currentCharacter->x1 += _charXPosTable[_currentCharacter->facing]; - _currentCharacter->y1 += _charYPosTable[_currentCharacter->facing]; - setCharacterPositionHelper(0, facingTable); - return 1; - } else { - _characterList[character].x1 += _charXPosTable[_characterList[character].facing]; - _characterList[character].y1 += _charYPosTable[_characterList[character].facing]; - if (_characterList[character].sceneId == _currentCharacter->sceneId) - setCharacterPositionHelper(character, 0); - } - return 0; -} - -void KyraEngine_v1::setCharacterPositionHelper(int character, int *facingTable) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::setCharacterPositionHelper(%d, %p)", character, (const void *)facingTable); - Character *ch = &_characterList[character]; - ++ch->currentAnimFrame; - int facing = ch->facing; - if (facingTable) { - if (*facingTable != *(facingTable - 1)) { - if (*(facingTable - 1) == *(facingTable + 1)) { - facing = getOppositeFacingDirection(*(facingTable - 1)); - *facingTable = *(facingTable - 1); + if (lineIsPassable(curX, curY)) { + if (lastUsedEntry == moveTableSize) { + delete[] pathTable1; + delete[] pathTable2; + return 0x7D00; } + // debug drawing + /*if (curX >= 0 && curY >= 0 && curX < 320 && curY < 200) { + screen()->setPagePixel(0, curX, curY, 11); + screen()->updateScreen(); + delayWithTicks(5); + }*/ + moveTable[lastUsedEntry++] = newFacing; + x = curX; + y = curY; + continue; } - } - static uint8 facingIsZero[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; - static uint8 facingIsFour[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + int temp = 0; + while (true) { + newFacing = getFacingFromPointToPoint(curX, curY, toX, toY); + changePosTowardsFacing(curX, curY, newFacing); + // debug drawing + /*if (curX >= 0 && curY >= 0 && curX < 320 && curY < 200) { + screen()->setPagePixel(0, curX, curY, 8); + screen()->updateScreen(); + delayWithTicks(5); + }*/ + + if (!lineIsPassable(curX, curY)) { + if (curX != toX || curY != toY) + continue; + } - if (facing == 0) { - ++facingIsZero[character]; - } else { - bool resetTables = false; - if (facing != 7) { - if (facing - 1 != 0) { - if (facing != 4) { - if (facing == 3 || facing == 5) { - if (facingIsFour[character] > 2) - facing = 4; - resetTables = true; - } - } else { - ++facingIsFour[character]; + if (curX == toX && curY == toY) { + if (!lineIsPassable(curX, curY)) { + tempValue = 0; + temp = 0; + break; } - } else { - if (facingIsZero[character] > 2) - facing = 0; - resetTables = true; } - } else { - if (facingIsZero[character] > 2) - facing = 0; - resetTables = true; - } - - if (resetTables) { - facingIsZero[character] = 0; - facingIsFour[character] = 0; - } - } - - static const uint16 maxAnimationFrame[] = { - 0x000F, 0x0031, 0x0055, 0x0000, 0x0000, 0x0000, - 0x0008, 0x002A, 0x004E, 0x0000, 0x0000, 0x0000, - 0x0022, 0x0046, 0x006A, 0x0000, 0x0000, 0x0000, - 0x001D, 0x0041, 0x0065, 0x0000, 0x0000, 0x0000, - 0x001F, 0x0043, 0x0067, 0x0000, 0x0000, 0x0000, - 0x0028, 0x004C, 0x0070, 0x0000, 0x0000, 0x0000, - 0x0023, 0x0047, 0x006B, 0x0000, 0x0000, 0x0000 - }; - - if (facing == 0) { - if (maxAnimationFrame[36+character] > ch->currentAnimFrame) - ch->currentAnimFrame = maxAnimationFrame[36+character]; - if (maxAnimationFrame[30+character] < ch->currentAnimFrame) - ch->currentAnimFrame = maxAnimationFrame[36+character]; - } else if (facing == 4) { - if (maxAnimationFrame[18+character] > ch->currentAnimFrame) - ch->currentAnimFrame = maxAnimationFrame[18+character]; - if (maxAnimationFrame[12+character] < ch->currentAnimFrame) - ch->currentAnimFrame = maxAnimationFrame[18+character]; - } else { - if (maxAnimationFrame[18+character] < ch->currentAnimFrame) - ch->currentAnimFrame = maxAnimationFrame[30+character]; - if (maxAnimationFrame[character] == ch->currentAnimFrame) - ch->currentAnimFrame = maxAnimationFrame[6+character]; - if (maxAnimationFrame[character] < ch->currentAnimFrame) - ch->currentAnimFrame = maxAnimationFrame[6+character]+2; - } - - if (character == 0 && (_brandonStatusBit & 0x10)) - ch->currentAnimFrame = 88; - - _animator->animRefreshNPC(character); -} - -void KyraEngine_v1::loadSceneMsc() { - assert(_currentCharacter->sceneId < _roomTableSize); - int tableId = _roomTable[_currentCharacter->sceneId].nameIndex; - assert(tableId < _roomFilenameTableSize); - char fileNameBuffer[32]; - strcpy(fileNameBuffer, _roomFilenameTable[tableId]); - strcat(fileNameBuffer, ".MSC"); - _screen->fillRect(0, 0, 319, 199, 0, 5); - _res->exists(fileNameBuffer, true); - _screen->loadBitmap(fileNameBuffer, 3, 5, 0); -} - -void KyraEngine_v1::startSceneScript(int brandonAlive) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::startSceneScript(%d)", brandonAlive); - assert(_currentCharacter->sceneId < _roomTableSize); - int tableId = _roomTable[_currentCharacter->sceneId].nameIndex; - assert(tableId < _roomFilenameTableSize); - char fileNameBuffer[32]; - strcpy(fileNameBuffer, _roomFilenameTable[tableId]); - strcat(fileNameBuffer, ".CPS"); - _screen->clearPage(3); - _res->exists(fileNameBuffer, true); - // FIXME: check this hack for amiga version - _screen->loadBitmap(fileNameBuffer, 3, 3, (_flags.platform == Common::kPlatformAmiga ? _screen->getPalette(0) : 0)); - _sprites->loadSceneShapes(); - _exitListPtr = 0; - - _scaleMode = 1; - for (int i = 0; i < 145; ++i) - _scaleTable[i] = 256; - - clearNoDropRects(); - _emc->init(&_scriptClick, &_scriptClickData); - strcpy(fileNameBuffer, _roomFilenameTable[tableId]); - strcat(fileNameBuffer, ".EMC"); - _res->exists(fileNameBuffer, true); - _emc->unload(&_scriptClickData); - _emc->load(fileNameBuffer, &_scriptClickData, &_opcodes); - _emc->start(&_scriptClick, 0); - _scriptClick.regs[0] = _currentCharacter->sceneId; - _scriptClick.regs[7] = brandonAlive; - - while (_emc->isValid(&_scriptClick)) - _emc->run(&_scriptClick); -} - -void KyraEngine_v1::initSceneData(int facing, int unk1, int brandonAlive) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::initSceneData(%d, %d, %d)", facing, unk1, brandonAlive); - - int16 xpos2 = 0; - int setFacing = 1; - - int16 xpos = 0, ypos = 0; - - if (_brandonPosX == -1 && _brandonPosY == -1) { - switch (facing + 1) { - case 0: - xpos = ypos = -1; - break; - - case 1: case 2: case 8: - xpos = _sceneExits.southXPos; - ypos = _sceneExits.southYPos; - break; - - case 3: - xpos = _sceneExits.westXPos; - ypos = _sceneExits.westYPos; - break; - - case 4: case 5: case 6: - xpos = _sceneExits.northXPos; - ypos = _sceneExits.northYPos; - break; - - case 7: - xpos = _sceneExits.eastXPos; - ypos = _sceneExits.eastYPos; - break; - - default: - break; - } - - if ((uint8)(_northExitHeight & 0xFF) + 2 >= ypos) - ypos = (_northExitHeight & 0xFF) + 4; - if (xpos >= 308) - xpos = 304; - if ((uint8)(_northExitHeight >> 8) - 2 <= ypos) - ypos = (_northExitHeight >> 8) - 4; - if (xpos <= 12) - xpos = 16; - } - - if (_brandonPosX > -1) - xpos = _brandonPosX; - if (_brandonPosY > -1) - ypos = _brandonPosY; - - int16 ypos2 = 0; - if (_brandonPosX > -1 && _brandonPosY > -1) { - switch (_currentCharacter->sceneId) { - case 1: - _currentCharacter->x1 = xpos; - _currentCharacter->x2 = xpos; - _currentCharacter->y1 = ypos; - _currentCharacter->y2 = ypos; - facing = 4; - xpos2 = 192; - ypos2 = 104; - setFacing = 0; - unk1 = 1; - break; - - case 3: - _currentCharacter->x1 = xpos; - _currentCharacter->x2 = xpos; - _currentCharacter->y1 = ypos; - _currentCharacter->y2 = ypos; - facing = 2; - xpos2 = 204; - ypos2 = 94; - setFacing = 0; - unk1 = 1; - break; - - case 26: - _currentCharacter->x1 = xpos; - _currentCharacter->x2 = xpos; - _currentCharacter->y1 = ypos; - _currentCharacter->y2 = ypos; - facing = 2; - xpos2 = 192; - ypos2 = 128; - setFacing = 0; - unk1 = 1; - break; - - case 44: - _currentCharacter->x1 = xpos; - _currentCharacter->x2 = xpos; - _currentCharacter->y1 = ypos; - _currentCharacter->y2 = ypos; - facing = 6; - xpos2 = 156; - ypos2 = 96; - setFacing = 0; - unk1 = 1; - break; - - case 37: - _currentCharacter->x1 = xpos; - _currentCharacter->x2 = xpos; - _currentCharacter->y1 = ypos; - _currentCharacter->y2 = ypos; - facing = 2; - xpos2 = 148; - ypos2 = 114; - setFacing = 0; - unk1 = 1; - break; - - default: - break; - } - } - - _brandonPosX = _brandonPosY = -1; - - if (unk1 && setFacing) { - ypos2 = ypos; - xpos2 = xpos; - switch (facing) { - case 0: - ypos = 142; - break; - - case 2: - xpos = -16; - break; - - case 4: - ypos = (uint8)(_northExitHeight & 0xFF) - 4; - break; - - case 6: - xpos = 336; - break; - - default: - break; - } - } - - xpos2 = (int16)(xpos2 & 0xFFFC); - ypos2 = (int16)(ypos2 & 0xFFFE); - xpos = (int16)(xpos & 0xFFFC); - ypos = (int16)(ypos & 0xFFFE); - _currentCharacter->facing = facing; - _currentCharacter->x1 = xpos; - _currentCharacter->x2 = xpos; - _currentCharacter->y1 = ypos; - _currentCharacter->y2 = ypos; - - initSceneObjectList(brandonAlive); - - if (unk1 && brandonAlive == 0) - moveCharacterToPos(0, facing, xpos2, ypos2); - - _scriptClick.regs[4] = _itemInHand; - _scriptClick.regs[7] = brandonAlive; - _emc->start(&_scriptClick, 3); - while (_emc->isValid(&_scriptClick)) - _emc->run(&_scriptClick); -} - -void KyraEngine_v1::initSceneObjectList(int brandonAlive) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::initSceneObjectList(%d)", brandonAlive); - for (int i = 0; i < 28; ++i) - _animator->actors()[i].active = 0; - - int startAnimFrame = 0; - - Animator_v1::AnimObject *curAnimState = _animator->actors(); - curAnimState->active = 1; - curAnimState->drawY = _currentCharacter->y1; - curAnimState->sceneAnimPtr = _shapes[_currentCharacter->currentAnimFrame]; - curAnimState->animFrameNumber = _currentCharacter->currentAnimFrame; - startAnimFrame = _currentCharacter->currentAnimFrame-7; - int xOffset = _defaultShapeTable[startAnimFrame].xOffset; - int yOffset = _defaultShapeTable[startAnimFrame].yOffset; - - if (_scaleMode) { - curAnimState->x1 = _currentCharacter->x1; - curAnimState->y1 = _currentCharacter->y1; - - _animator->_brandonScaleX = _scaleTable[_currentCharacter->y1]; - _animator->_brandonScaleY = _scaleTable[_currentCharacter->y1]; - - curAnimState->x1 += (_animator->_brandonScaleX * xOffset) >> 8; - curAnimState->y1 += (_animator->_brandonScaleY * yOffset) >> 8; - } else { - curAnimState->x1 = _currentCharacter->x1 + xOffset; - curAnimState->y1 = _currentCharacter->y1 + yOffset; - } - - curAnimState->x2 = curAnimState->x1; - curAnimState->y2 = curAnimState->y1; - curAnimState->refreshFlag = 1; - curAnimState->bkgdChangeFlag = 1; - _animator->clearQueue(); - _animator->addObjectToQueue(curAnimState); - - int listAdded = 0; - int addedObjects = 1; - - for (int i = 1; i < 5; ++i) { - Character *ch = &_characterList[i]; - curAnimState = &_animator->actors()[addedObjects]; - if (ch->sceneId != _currentCharacter->sceneId) { - curAnimState->active = 0; - curAnimState->refreshFlag = 0; - curAnimState->bkgdChangeFlag = 0; - ++addedObjects; - continue; - } - - curAnimState->drawY = ch->y1; - curAnimState->sceneAnimPtr = _shapes[ch->currentAnimFrame]; - curAnimState->animFrameNumber = ch->currentAnimFrame; - startAnimFrame = ch->currentAnimFrame-7; - xOffset = _defaultShapeTable[startAnimFrame].xOffset; - yOffset = _defaultShapeTable[startAnimFrame].yOffset; - if (_scaleMode) { - curAnimState->x1 = ch->x1; - curAnimState->y1 = ch->y1; - _animator->_brandonScaleX = _scaleTable[ch->y1]; - _animator->_brandonScaleY = _scaleTable[ch->y1]; - - curAnimState->x1 += (_animator->_brandonScaleX * xOffset) >> 8; - curAnimState->y1 += (_animator->_brandonScaleY * yOffset) >> 8; - } else { - curAnimState->x1 = ch->x1 + xOffset; - curAnimState->y1 = ch->y1 + yOffset; - } - curAnimState->x2 = curAnimState->x1; - curAnimState->y2 = curAnimState->y1; - curAnimState->active = 1; - curAnimState->refreshFlag = 1; - curAnimState->bkgdChangeFlag = 1; - - if (ch->facing >= 1 && ch->facing <= 3) - curAnimState->flags |= 1; - else if (ch->facing >= 5 && ch->facing <= 7) - curAnimState->flags &= 0xFFFFFFFE; - - _animator->addObjectToQueue(curAnimState); - - ++addedObjects; - ++listAdded; - if (listAdded < 2) - i = 5; - } - - for (int i = 0; i < 11; ++i) { - curAnimState = &_animator->sprites()[i]; - - if (_sprites->_anims[i].play) { - curAnimState->active = 1; - curAnimState->refreshFlag = 1; - curAnimState->bkgdChangeFlag = 1; - } else { - curAnimState->active = 0; - curAnimState->refreshFlag = 0; - curAnimState->bkgdChangeFlag = 0; - } - curAnimState->height = _sprites->_anims[i].height; - curAnimState->height2 = _sprites->_anims[i].height2; - curAnimState->width = _sprites->_anims[i].width + 1; - curAnimState->width2 = _sprites->_anims[i].width2; - curAnimState->drawY = _sprites->_anims[i].drawY; - curAnimState->x1 = curAnimState->x2 = _sprites->_anims[i].x; - curAnimState->y1 = curAnimState->y2 = _sprites->_anims[i].y; - curAnimState->background = _sprites->_anims[i].background; - curAnimState->sceneAnimPtr = _sprites->_sceneShapes[_sprites->_anims[i].sprite]; - - curAnimState->disable = _sprites->_anims[i].disable; - - if (_sprites->_anims[i].unk2) - curAnimState->flags = 0x800; - else - curAnimState->flags = 0; - - if (_sprites->_anims[i].flipX) - curAnimState->flags |= 0x1; - - _animator->addObjectToQueue(curAnimState); - } - - for (int i = 0; i < 12; ++i) { - curAnimState = &_animator->items()[i]; - Room *curRoom = &_roomTable[_currentCharacter->sceneId]; - byte curItem = curRoom->itemsTable[i]; - if (curItem != 0xFF) { - curAnimState->drawY = curRoom->itemsYPos[i]; - curAnimState->sceneAnimPtr = _shapes[216+curItem]; - curAnimState->animFrameNumber = (int16)0xFFFF; - curAnimState->y1 = curRoom->itemsYPos[i]; - curAnimState->x1 = curRoom->itemsXPos[i]; - - curAnimState->x1 -= (_animator->fetchAnimWidth(curAnimState->sceneAnimPtr, _scaleTable[curAnimState->drawY])) >> 1; - curAnimState->y1 -= _animator->fetchAnimHeight(curAnimState->sceneAnimPtr, _scaleTable[curAnimState->drawY]); - - curAnimState->x2 = curAnimState->x1; - curAnimState->y2 = curAnimState->y1; - - curAnimState->active = 1; - curAnimState->refreshFlag = 1; - curAnimState->bkgdChangeFlag = 1; - - _animator->addObjectToQueue(curAnimState); - } else { - curAnimState->active = 0; - curAnimState->refreshFlag = 0; - curAnimState->bkgdChangeFlag = 0; - } - } - - _animator->preserveAnyChangedBackgrounds(); - curAnimState = _animator->actors(); - curAnimState->bkgdChangeFlag = 1; - curAnimState->refreshFlag = 1; - for (int i = 1; i < 28; ++i) { - curAnimState = &_animator->objects()[i]; - if (curAnimState->active) { - curAnimState->bkgdChangeFlag = 1; - curAnimState->refreshFlag = 1; - } - } - _animator->restoreAllObjectBackgrounds(); - _animator->preserveAnyChangedBackgrounds(); - _animator->prepDrawAllObjects(); - initSceneScreen(brandonAlive); - _animator->copyChangedObjectsForward(0); -} + temp = findSubPath(x, y, curX, curY, pathTable1, 1, 0x7D0); + tempValue = findSubPath(x, y, curX, curY, pathTable2, 0, 0x7D0); + if (curX == toX && curY == toY) { + if (temp == 0x7D00 && tempValue == 0x7D00) { + delete[] pathTable1; + delete[] pathTable2; + return 0x7D00; + } + } -void KyraEngine_v1::initSceneScreen(int brandonAlive) { - if (_flags.platform == Common::kPlatformAmiga) { - if (_unkScreenVar1 && !queryGameFlag(0xF0)) { - memset(_screen->getPalette(2), 0, 32*3); - if (_currentCharacter->sceneId != 117 || !queryGameFlag(0xB3)) - _screen->setScreenPalette(_screen->getPalette(2)); + if (temp != 0x7D00 || tempValue != 0x7D00) + break; } - if (_unkScreenVar2 == 1) - _screen->shuffleScreen(8, 8, 304, 128, 2, 0, _unkScreenVar3, false); - else - _screen->copyRegion(8, 8, 8, 8, 304, 128, 2, 0); - - if (_unkScreenVar1 && !queryGameFlag(0xA0)) { - if (_currentCharacter->sceneId == 45 && _paletteChanged) - memcpy(_screen->getPalette(0) + 12*3, _screen->getPalette(4) + 12*3, 2); - - if (_currentCharacter->sceneId >= 229 && _currentCharacter->sceneId <= 245 && (_brandonStatusBit & 1)) - memcpy(_screen->getPalette(0), _screen->getPalette(0) + 320*3, 64); - - _screen->setScreenPalette(_screen->getPalette(0)); - } - } else { - if (_unkScreenVar1 && !queryGameFlag(0xA0)) { - for (int i = 0; i < 60; ++i) { - uint16 col = _screen->getPalette(0)[684+i]; - col += _screen->getPalette(1)[684+i] << 1; - col >>= 2; - _screen->getPalette(0)[684+i] = col; + if (temp < tempValue) { + if (lastUsedEntry + temp > moveTableSize) { + delete[] pathTable1; + delete[] pathTable2; + return 0x7D00; } - _screen->setScreenPalette(_screen->getPalette(0)); - } - - if (_unkScreenVar2 == 1) - _screen->shuffleScreen(8, 8, 304, 128, 2, 0, _unkScreenVar3, false); - else - _screen->copyRegion(8, 8, 8, 8, 304, 128, 2, 0); - - if (_unkScreenVar1 && _paletteChanged) { - if (!queryGameFlag(0xA0)) { - memcpy(_screen->getPalette(0) + 684, _screen->getPalette(1) + 684, 60); - _screen->setScreenPalette(_screen->getPalette(0)); - } else { - memset(_screen->getPalette(0), 0, 768); + memcpy(&moveTable[lastUsedEntry], pathTable1, temp*sizeof(int)); + lastUsedEntry += temp; + } else { + if (lastUsedEntry + tempValue > moveTableSize) { + delete[] pathTable1; + delete[] pathTable2; + return 0x7D00; } + memcpy(&moveTable[lastUsedEntry], pathTable2, tempValue*sizeof(int)); + lastUsedEntry += tempValue; } + x = curX; + y = curY; + if (curX == toX && curY == toY) + break; } - if (!_emc->start(&_scriptClick, 2)) - error("Could not start script function 2 of scene script"); - - _scriptClick.regs[7] = brandonAlive; - - while (_emc->isValid(&_scriptClick)) - _emc->run(&_scriptClick); - - setTextFadeTimerCountdown(-1); - if (_currentCharacter->sceneId == 210) { - if (_itemInHand != -1) - magicOutMouseItem(2, -1); - - _screen->hideMouse(); - for (int i = 0; i < 10; ++i) { - if (_currentCharacter->inventoryItems[i] != 0xFF) - magicOutMouseItem(2, i); - } - _screen->showMouse(); - } -} - -int KyraEngine_v1::handleSceneChange(int xpos, int ypos, int unk1, int frameReset) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::handleSceneChange(%d, %d, %d, %d)", xpos, ypos, unk1, frameReset); - if (queryGameFlag(0xEF)) - unk1 = 0; - - int sceneId = _currentCharacter->sceneId; - _pathfinderFlag = 0; - - if (xpos < 12) { - if (_roomTable[sceneId].westExit != 0xFFFF) { - xpos = 12; - ypos = _sceneExits.westYPos; - _pathfinderFlag = 7; - } - } else if (xpos >= 308) { - if (_roomTable[sceneId].eastExit != 0xFFFF) { - xpos = 307; - ypos = _sceneExits.eastYPos; - _pathfinderFlag = 13; - } - } - - if (ypos <= (_northExitHeight&0xFF)+2) { - if (_roomTable[sceneId].northExit != 0xFFFF) { - xpos = _sceneExits.northXPos; - ypos = _northExitHeight & 0xFF; - _pathfinderFlag = 14; - } - } else if (ypos >= 136) { - if (_roomTable[sceneId].southExit != 0xFFFF) { - xpos = _sceneExits.southXPos; - ypos = 136; - _pathfinderFlag = 11; - } - } - - int temp = xpos - _currentCharacter->x1; - if (ABS(temp) < 4) { - temp = ypos - _currentCharacter->y1; - if (ABS(temp) < 2) - return 0; - } - - int x = (int16)(_currentCharacter->x1 & 0xFFFC); - int y = (int16)(_currentCharacter->y1 & 0xFFFE); - xpos = (int16)(xpos & 0xFFFC); - ypos = (int16)(ypos & 0xFFFE); - - int ret = findWay(x, y, xpos, ypos, _movFacingTable, 150); - _pathfinderFlag = 0; - - if (ret >= _lastFindWayRet) - _lastFindWayRet = ret; - - if (ret == 0x7D00 || ret == 0) - return 0; - - return processSceneChange(_movFacingTable, unk1, frameReset); + delete[] pathTable1; + delete[] pathTable2; + moveTable[lastUsedEntry] = 8; + return lastUsedEntry; } -int KyraEngine_v1::processSceneChange(int *table, int unk1, int frameReset) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::processSceneChange(%p, %d, %d)", (const void *)table, unk1, frameReset); - if (queryGameFlag(0xEF)) - unk1 = 0; - - int *tableStart = table; - _sceneChangeState = 0; - _loopFlag2 = 0; - bool running = true; - int returnValue = 0; - uint32 nextFrame = 0; - _abortWalkFlag = false; - _mousePressFlag = false; - - while (running) { - if (_abortWalkFlag) { - *table = 8; - _currentCharacter->currentAnimFrame = 7; - _animator->animRefreshNPC(0); - _animator->updateAllObjectShapes(); - processInput(); - return 0; - } - bool forceContinue = false; - switch (*table) { - case 0: case 1: case 2: - case 3: case 4: case 5: - case 6: case 7: - _currentCharacter->facing = getOppositeFacingDirection(*table); - break; - - case 8: - forceContinue = true; - running = false; - break; - - default: - ++table; - forceContinue = true; +int KyraEngine_v1::findSubPath(int x, int y, int toX, int toY, int *moveTable, int start, int end) { + debugC(9, kDebugLevelMain, "KyraEngine_v1::findSubPath(%d, %d, %d, %d, %p, %d, %d)", x, y, toX, toY, (const void *)moveTable, start, end); + // only used for debug specific code + //static uint16 unkTable[] = { 8, 5 }; + static const int8 facingTable1[] = { 7, 0, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 7, 0 }; + static const int8 facingTable2[] = { -1, 0, -1, 2, -1, 4, -1, 6, -1, 2, -1, 4, -1, 6, -1, 0 }; + static const int8 facingTable3[] = { 2, 4, 4, 6, 6, 0, 0, 2, 6, 6, 0, 0, 2, 2, 4, 4 }; + static const int8 addPosTableX[] = { -1, 0, -1, 4, -1, 0, -1, -4, -1, -4, -1, 0, -1, 4, -1, 0 }; + static const int8 addPosTableY[] = { -1, 2, -1, 0, -1, -2, -1, 0, -1, 0, -1, 2, -1, 0, -1, -2 }; + + // debug specific + /*++unkTable[start]; + while (screen()->getPalette(0)[unkTable[start]] != 0x0F) { + ++unkTable[start]; + }*/ + + int xpos1 = x, xpos2 = x; + int ypos1 = y, ypos2 = y; + int newFacing = getFacingFromPointToPoint(x, y, toX, toY); + int position = 0; + + while (position != end) { + int newFacing2 = newFacing; + while (true) { + changePosTowardsFacing(xpos1, ypos1, facingTable1[start*8 + newFacing2]); + if (!lineIsPassable(xpos1, ypos1)) { + if (facingTable1[start*8 + newFacing2] == newFacing) + return 0x7D00; + newFacing2 = facingTable1[start*8 + newFacing2]; + xpos1 = x; + ypos1 = y; + continue; + } + newFacing = facingTable1[start*8 + newFacing2]; break; } - - returnValue = changeScene(_currentCharacter->facing); - if (returnValue) { - running = false; - _abortWalkFlag = false; - } - - if (unk1) { - if (_mousePressFlag) { - running = false; - _sceneChangeState = 1; + // debug drawing + /*if (xpos1 >= 0 && ypos1 >= 0 && xpos1 < 320 && ypos1 < 200) { + screen()->setPagePixel(0, xpos1, ypos1, unkTable[start]); + screen()->updateScreen(); + delayWithTicks(5); + }*/ + if (newFacing & 1) { + int temp = xpos1 + addPosTableX[newFacing + start * 8]; + if (toX == temp) { + temp = ypos1 + addPosTableY[newFacing + start * 8]; + if (toY == temp) { + moveTable[position++] = facingTable2[newFacing + start * 8]; + return position; + } } } - if (forceContinue || !running) - continue; - - int temp = 0; - if (table == tableStart || table[1] == 8) - temp = setCharacterPosition(0, 0); - else - temp = setCharacterPosition(0, table); - - if (temp) - ++table; + moveTable[position++] = newFacing; + x = xpos1; + y = ypos1; - nextFrame = _timer->getDelay(5) * _tickLength + _system->getMillis(); - while (_system->getMillis() < nextFrame) { - _timer->update(); + if (x == toX && y == toY) + return position; - if (_currentCharacter->sceneId == 210) { - updateKyragemFading(); - if (seq_playEnd() || _beadStateVar == 4 || _beadStateVar == 5) { - *table = 8; - running = false; - break; - } - } + if (xpos1 == xpos2 && ypos1 == ypos2) + break; - if ((nextFrame - _system->getMillis()) >= 10) - delay(10, true); - } + newFacing = facingTable3[start*8 + newFacing]; } - if (frameReset && !(_brandonStatusBit & 2)) - _currentCharacter->currentAnimFrame = 7; - - _animator->animRefreshNPC(0); - _animator->updateAllObjectShapes(); - return returnValue; + return 0x7D00; } -int KyraEngine_v1::changeScene(int facing) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::changeScene(%d)", facing); - if (queryGameFlag(0xEF)) { - if (_currentCharacter->sceneId == 5) - return 0; - } - - int xpos = _charXPosTable[facing] + _currentCharacter->x1; - int ypos = _charYPosTable[facing] + _currentCharacter->y1; +int KyraEngine_v1::getFacingFromPointToPoint(int x, int y, int toX, int toY) { + debugC(9, kDebugLevelMain, "KyraEngine_v1::getFacingFromPointToPoint(%d, %d, %d, %d)", x, y, toX, toY); + static const int facingTable[] = { + 1, 0, 1, 2, 3, 4, 3, 2, 7, 0, 7, 6, 5, 4, 5, 6 + }; - if (xpos >= 12 && xpos <= 308) { - if (!lineIsPassable(xpos, ypos)) - return false; + int facingEntry = 0; + int ydiff = y - toY; + if (ydiff < 0) { + ++facingEntry; + ydiff = -ydiff; } + facingEntry <<= 1; - if (_exitListPtr) { - int16 *ptr = _exitListPtr; - // this loop should be only entered one time, seems to be some hack in the original - while (true) { - if (*ptr == -1) - break; - - if (*ptr > _currentCharacter->x1 || _currentCharacter->y1 < ptr[1] || _currentCharacter->x1 > ptr[2] || _currentCharacter->y1 > ptr[3]) { - ptr += 10; - break; - } - - _brandonPosX = ptr[6]; - _brandonPosY = ptr[7]; - uint16 sceneId = ptr[5]; - facing = ptr[4]; - int unk1 = ptr[8]; - int unk2 = ptr[9]; - - if (sceneId == 0xFFFF) { - switch (facing) { - case 0: - sceneId = _roomTable[_currentCharacter->sceneId].northExit; - break; - - case 2: - sceneId = _roomTable[_currentCharacter->sceneId].eastExit; - break; - - case 4: - sceneId = _roomTable[_currentCharacter->sceneId].southExit; - break; - - case 6: - sceneId = _roomTable[_currentCharacter->sceneId].westExit; - break; - - default: - break; - } - } - - _currentCharacter->facing = facing; - _animator->animRefreshNPC(0); - _animator->updateAllObjectShapes(); - enterNewScene(sceneId, facing, unk1, unk2, 0); - resetGameFlag(0xEE); - return 1; - } + int xdiff = toX - x; + if (xdiff < 0) { + ++facingEntry; + xdiff = -xdiff; } - int returnValue = 0; - facing = 0; + if (xdiff >= ydiff) { + int temp = ydiff; + ydiff = xdiff; + xdiff = temp; - if ((_northExitHeight & 0xFF) + 2 >= ypos || (_northExitHeight & 0xFF) + 2 >= _currentCharacter->y1) { - facing = 0; - returnValue = 1; + facingEntry <<= 1; + } else { + facingEntry <<= 1; + facingEntry += 1; } + int temp = (ydiff + 1) >> 1; - if (xpos >= 308 || (_currentCharacter->x1 + 4) >= 308) { - facing = 2; - returnValue = 1; + if (xdiff < temp) { + facingEntry <<= 1; + facingEntry += 1; + } else { + facingEntry <<= 1; } - if (((_northExitHeight >> 8) & 0xFF) - 2 < ypos || ((_northExitHeight >> 8) & 0xFF) - 2 < _currentCharacter->y1) { - facing = 4; - returnValue = 1; - } + assert(facingEntry < ARRAYSIZE(facingTable)); + return facingTable[facingEntry]; +} - if (xpos <= 12 || _currentCharacter->y1 <= 12) { - facing = 6; - returnValue = 1; - } - if (!returnValue) - return 0; - - uint16 sceneId = 0xFFFF; - switch (facing) { +int KyraEngine_v1::getOppositeFacingDirection(int dir) { + debugC(9, kDebugLevelMain, "KyraEngine_v1::getOppositeFacingDirection(%d)", dir); + switch (dir) { case 0: - sceneId = _roomTable[_currentCharacter->sceneId].northExit; - break; - - case 2: - sceneId = _roomTable[_currentCharacter->sceneId].eastExit; - break; - + return 2; + case 1: + return 1; + case 3: + return 7; case 4: - sceneId = _roomTable[_currentCharacter->sceneId].southExit; - break; - + return 6; + case 5: + return 5; + case 6: + return 4; + case 7: + return 3; default: - sceneId = _roomTable[_currentCharacter->sceneId].westExit; break; } - - if (sceneId == 0xFFFF) - return 0; - - enterNewScene(sceneId, facing, 1, 1, 0); - return returnValue; -} - -void KyraEngine_v1::setCharactersInDefaultScene() { - static const uint32 defaultSceneTable[][4] = { - { 0xFFFF, 0x0004, 0x0003, 0xFFFF }, - { 0xFFFF, 0x0022, 0xFFFF, 0x0000 }, - { 0xFFFF, 0x001D, 0x0021, 0xFFFF }, - { 0xFFFF, 0x0000, 0x0000, 0xFFFF } - }; - - for (int i = 1; i < 5; ++i) { - Character *cur = &_characterList[i]; - //cur->field_20 = 0; - - const uint32 *curTable = defaultSceneTable[i-1]; - cur->sceneId = curTable[0]; - - if (cur->sceneId == _currentCharacter->sceneId) - //++cur->field_20; - cur->sceneId = curTable[1/*cur->field_20*/]; - - //cur->field_23 = curTable[cur->field_20+1]; - } + return 0; } -void KyraEngine_v1::setCharactersPositions(int character) { - static uint16 initXPosTable[] = { - 0x3200, 0x0024, 0x2230, 0x2F00, 0x0020, 0x002B, - 0x00CA, 0x00F0, 0x0082, 0x00A2, 0x0042 - }; - static uint8 initYPosTable[] = { - 0x00, 0xA2, 0x00, 0x42, 0x00, - 0x67, 0x67, 0x60, 0x5A, 0x71, - 0x76 - }; - - assert(character < ARRAYSIZE(initXPosTable)); - Character *edit = &_characterList[character]; - edit->x1 = edit->x2 = initXPosTable[character]; - edit->y1 = edit->y2 = initYPosTable[character]; +void KyraEngine_v1::changePosTowardsFacing(int &x, int &y, int facing) { + debugC(9, kDebugLevelMain, "KyraEngine_v1::changePosTowardsFacing(%d, %d, %d)", x, y, facing); + x += _addXPosTable[facing]; + y += _addYPosTable[facing]; } -#pragma mark - -#pragma mark - Pathfinder -#pragma mark - - -int KyraEngine_v1::findWay(int x, int y, int toX, int toY, int *moveTable, int moveTableSize) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::findWay(%d, %d, %d, %d, %p, %d)", x, y, toX, toY, (const void *)moveTable, moveTableSize); - int ret = KyraEngine::findWay(x, y, toX, toY, moveTable, moveTableSize); - if (ret == 0x7D00) +int KyraEngine_v1::getMoveTableSize(int *moveTable) { + debugC(9, kDebugLevelMain, "KyraEngine_v1::getMoveTableSize(%p)", (const void *)moveTable); + int retValue = 0; + if (moveTable[0] == 8) return 0; - return getMoveTableSize(moveTable); -} - -bool KyraEngine_v1::lineIsPassable(int x, int y) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::lineIsPassable(%d, %d)", x, y); - if (queryGameFlag(0xEF)) { - if (_currentCharacter->sceneId == 5) - return true; - } - - if (_pathfinderFlag & 2) { - if (x >= 312) - return false; - } - if (_pathfinderFlag & 4) { - if (y >= 136) - return false; - } + static const int facingTable[] = { + 4, 5, 6, 7, 0, 1, 2, 3 + }; + static const int unkTable[] = { + -1, -1, 1, 2, -1, 6, 7, -1, + -1, -1, -1, -1, 2, -1, 0, -1, + 1, -1, -1, -1, 3, 4, -1, 0, + 2, -1, -1, -1, -1, -1, 4, -1, + -1, 2, 3, -1, -1, -1, 5, 6, + 6, -1, 4, -1, -1, -1, -1, -1, + 7, 0, -1, 4, 5, -1, -1, -1, + -1, -1, 0, -1, 6, -1, -1, -1 + }; - if (_pathfinderFlag & 8) { - if (x < 8) - return false; - } + int *oldPosition = moveTable; + int *tempPosition = moveTable; + int *curPosition = moveTable + 1; + retValue = 1; - if (_pathfinderFlag2) { - if (x <= 8 || x >= 312) - return true; - if (y < (_northExitHeight & 0xFF) || y > 135) - return true; - } + while (*curPosition != 8) { + if (*oldPosition == facingTable[*curPosition]) { + retValue -= 2; + *oldPosition = 9; + *curPosition = 9; - if (y > 137) - return false; - - if (y < 0) - y = 0; + while (tempPosition != moveTable) { + --tempPosition; + if (*tempPosition != 9) + break; + } - int ypos = 8; - if (_scaleMode) { - ypos = (_scaleTable[y] >> 5) + 1; - if (8 < ypos) - ypos = 8; - } + if (tempPosition == moveTable && *tempPosition == 9) { + while (*tempPosition != 8 && *tempPosition == 9) + ++tempPosition; - x -= (ypos >> 1); + if (*tempPosition == 8) + return 0; + } - int xpos = x; - int xtemp = xpos + ypos - 1; - if (x < 0) - xpos = 0; + oldPosition = tempPosition; + curPosition = oldPosition+1; - if (xtemp > 319) - xtemp = 319; + while (*curPosition != 8 && *curPosition == 9) + ++curPosition; - for (; xpos < xtemp; ++xpos) { - if (!_screen->getShapeFlag1(xpos, y)) - return false; - } - return true; -} + continue; + } -#pragma mark - + if (unkTable[*curPosition+((*oldPosition)*8)] != -1) { + --retValue; + *oldPosition = unkTable[*curPosition+((*oldPosition)*8)]; + *curPosition = 9; -void KyraEngine_v1::setupSceneResource(int sceneId) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::setupSceneResource(%d)", sceneId); - if (!_flags.isTalkie) - return; + if (tempPosition != oldPosition) { + curPosition = oldPosition; + oldPosition = tempPosition; + while (true) { + if (tempPosition == moveTable) + break; - if (_currentRoom != 0xFFFF) { - assert(_currentRoom < _roomTableSize); - int tableId = _roomTable[_currentRoom].nameIndex; - assert(tableId < _roomFilenameTableSize); + --tempPosition; + if (*tempPosition != 9) + break; - // unload our old room - char file[64]; - strcpy(file, _roomFilenameTable[tableId]); - strcat(file, ".VRM"); - _res->unloadPakFile(file); + } + } else { + while (true) { + ++curPosition; + if (*curPosition != 9) + break; + } + } + continue; + } - strcpy(file, _roomFilenameTable[tableId]); - strcat(file, ".PAK"); - _res->unloadPakFile(file); + tempPosition = oldPosition; + oldPosition = curPosition; + ++retValue; - strcpy(file, _roomFilenameTable[tableId]); - strcat(file, ".APK"); - _res->unloadPakFile(file); + while (true) { + ++curPosition; + if (*curPosition != 9) + break; + } } - assert(sceneId < _roomTableSize); - int tableId = _roomTable[sceneId].nameIndex; - assert(tableId < _roomFilenameTableSize); - - // load our new room - char file[64]; - strcpy(file, _roomFilenameTable[tableId]); - strcat(file, ".VRM"); - if (_res->exists(file)) - _res->loadPakFile(file); - - strcpy(file, _roomFilenameTable[tableId]); - strcat(file, ".PAK"); - if (_res->exists(file)) - _res->loadPakFile(file); - - strcpy(file, _roomFilenameTable[tableId]); - strcat(file, ".APK"); - if (_res->exists(file)) - _res->loadPakFile(file); + return retValue; } } // end of namespace Kyra - diff --git a/engines/kyra/scene_v2.cpp b/engines/kyra/scene_v2.cpp index 5d811bcf44..3bf81bfb39 100644 --- a/engines/kyra/scene_v2.cpp +++ b/engines/kyra/scene_v2.cpp @@ -90,7 +90,7 @@ int KyraEngine_v2::findWay(int x, int y, int toX, int toY, int *moveTable, int m debugC(9, kDebugLevelMain, "KyraEngine_v2::findWay(%d, %d, %d, %d, %p, %d)", x, y, toX, toY, (const void *)moveTable, moveTableSize); x &= ~3; toX &= ~3; y &= ~1; toY &= ~1; - int size = KyraEngine::findWay(x, y, toX, toY, moveTable, moveTableSize); + int size = KyraEngine_v1::findWay(x, y, toX, toY, moveTable, moveTableSize); static bool usePostProcess = false; if (size && !usePostProcess) { usePostProcess = true; @@ -98,7 +98,7 @@ int KyraEngine_v2::findWay(int x, int y, int toX, int toY, int *moveTable, int m temp = pathfinderInitPositionIndexTable(temp, x, y); pathfinderFinializePath(moveTable, temp, x, y, moveTableSize); usePostProcess = false; - } + } return usePostProcess ? size : getMoveTableSize(moveTable); } @@ -106,13 +106,14 @@ 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) { + while (x != toX || y != toY) { int facing = getFacingFromPointToPoint(x, y, toX, toY); x += _addXPosTable[facing]; y += _addYPosTable[facing]; if (!scr->getShapeFlag1(x, y)) return false; } + return true; } diff --git a/engines/kyra/screen.cpp b/engines/kyra/screen.cpp index 298483465e..f00c47ceea 100644 --- a/engines/kyra/screen.cpp +++ b/engines/kyra/screen.cpp @@ -28,40 +28,41 @@ #include "common/system.h" #include "graphics/cursorman.h" #include "kyra/screen.h" -#include "kyra/kyra.h" +#include "kyra/kyra_v1.h" #include "kyra/resource.h" namespace Kyra { -Screen::Screen(KyraEngine *vm, OSystem *system) +Screen::Screen(KyraEngine_v1 *vm, OSystem *system) : _system(system), _vm(vm), _sjisInvisibleColor(0) { _debugEnabled = false; + _maskMinY = _maskMaxY = -1; } Screen::~Screen() { for (int i = 0; i < SCREEN_OVLS_NUM; ++i) - delete [] _sjisOverlayPtrs[i]; + delete[] _sjisOverlayPtrs[i]; - delete [] _pagePtrs[0]; + delete[] _pagePtrs[0]; for (int f = 0; f < ARRAYSIZE(_fonts); ++f) { delete[] _fonts[f].fontData; _fonts[f].fontData = NULL; } - delete [] _sjisFontData; - delete [] _sjisTempPage; - delete [] _currentPalette; - delete [] _screenPalette; - delete [] _decodeShapeBuffer; - delete [] _animBlockPtr; + delete[] _sjisFontData; + delete[] _sjisTempPage; + delete[] _currentPalette; + delete[] _screenPalette; + delete[] _decodeShapeBuffer; + delete[] _animBlockPtr; if (_vm->gameFlags().platform != Common::kPlatformAmiga) { for (int i = 0; i < ARRAYSIZE(_palettes); ++i) - delete [] _palettes[i]; + delete[] _palettes[i]; } - delete [] _dirtyRects; + delete[] _dirtyRects; } bool Screen::init() { @@ -307,14 +308,16 @@ const uint8 *Screen::getCPagePtr(int pageNum) const { uint8 *Screen::getPageRect(int pageNum, int x, int y, int w, int h) { debugC(9, kDebugLevelScreen, "Screen::getPageRect(%d, %d, %d, %d, %d)", pageNum, x, y, w, h); assert(pageNum < SCREEN_PAGE_NUM); - if (pageNum == 0 || pageNum == 1) addDirtyRect(x, y, w, h); + if (pageNum == 0 || pageNum == 1) + addDirtyRect(x, y, w, h); return _pagePtrs[pageNum] + y * SCREEN_W + x; } void Screen::clearPage(int pageNum) { debugC(9, kDebugLevelScreen, "Screen::clearPage(%d)", pageNum); assert(pageNum < SCREEN_PAGE_NUM); - if (pageNum == 0 || pageNum == 1) _forceFullUpdate = true; + if (pageNum == 0 || pageNum == 1) + _forceFullUpdate = true; memset(getPagePtr(pageNum), 0, SCREEN_PAGE_SIZE); clearOverlayPage(pageNum); } @@ -329,7 +332,8 @@ int Screen::setCurPage(int pageNum) { void Screen::clearCurPage() { debugC(9, kDebugLevelScreen, "Screen::clearCurPage()"); - if (_curPage == 0 || _curPage == 1) _forceFullUpdate = true; + if (_curPage == 0 || _curPage == 1) + _forceFullUpdate = true; memset(getPagePtr(_curPage), 0, SCREEN_PAGE_SIZE); clearOverlayPage(_curPage); } @@ -478,7 +482,7 @@ void Screen::copyToPage0(int y, int h, uint8 page, uint8 *seqBuf) { } addDirtyRect(0, y, SCREEN_W, h); // This would remove the text in the end sequence of - // the FM-Towns version. + // the (Kyrandia 1) FM-Towns version. // Since this method is just used for the Seqplayer // this shouldn't be a problem anywhere else, so it's // safe to disable the call here. @@ -576,7 +580,8 @@ void Screen::copyPage(uint8 srcPage, uint8 dstPage) { memcpy(dst, src, SCREEN_W * SCREEN_H); copyOverlayRegion(0, 0, 0, 0, SCREEN_W, SCREEN_H, srcPage, dstPage); - if (dstPage == 0 || dstPage == 1) _forceFullUpdate = true; + if (dstPage == 0 || dstPage == 1) + _forceFullUpdate = true; } void Screen::copyBlockToPage(int pageNum, int x, int y, int w, int h, const uint8 *src) { @@ -843,7 +848,7 @@ void Screen::drawLine(bool vertical, int x, int y, int length, int color) { void Screen::setAnimBlockPtr(int size) { debugC(9, kDebugLevelScreen, "Screen::setAnimBlockPtr(%d)", size); - delete [] _animBlockPtr; + delete[] _animBlockPtr; _animBlockPtr = new uint8[size]; assert(_animBlockPtr); memset(_animBlockPtr, 0, size); @@ -867,18 +872,18 @@ bool Screen::loadFont(FontId fontId, const char *filename) { error("fontId %d is invalid", fontId); if (fnt->fontData) - delete [] fnt->fontData; + delete[] fnt->fontData; uint32 sz = 0; uint8 *fontData = fnt->fontData = _vm->resource()->fileData(filename, &sz); if (!fontData || !sz) - error("couldn't load font file '%s'", filename); + error("Couldn't load font file '%s'", filename); uint16 fontSig = READ_LE_UINT16(fontData + 2); if (fontSig != 0x500) - error("Invalid font data (file '%s')", filename); + error("Invalid font data (file '%s', fontSig: %.04X)", filename, fontSig); fnt->charWidthTable = fontData + READ_LE_UINT16(fontData + 8); fnt->charSizeOffset = READ_LE_UINT16(fontData + 4); @@ -934,15 +939,14 @@ int Screen::getTextWidth(const char *str) const { if (c == 0) { break; } else if (c == '\r') { - if (curLineLen > maxLineLen) { + if (curLineLen > maxLineLen) maxLineLen = curLineLen; - } else { + else curLineLen = 0; - } } else { - if (c <= 0x7F || !_useSJIS) + if (c <= 0x7F || !_useSJIS) { curLineLen += getCharWidth(c); - else { + } else { c = READ_LE_UINT16(str - 1); ++str; curLineLen += getCharWidth(c); @@ -1894,11 +1898,10 @@ void Screen::wrapped_decodeFrameDelta(uint8 *dst, const uint8 *src) { void Screen::decodeFrameDeltaPage(uint8 *dst, const uint8 *src, int pitch, bool noXor) { debugC(9, kDebugLevelScreen, "Screen::decodeFrameDeltaPage(%p, %p, %d, %d)", (const void *)dst, (const void *)src, pitch, noXor); - if (noXor) { + if (noXor) wrapped_decodeFrameDeltaPage<true>(dst, src, pitch); - } else { + else wrapped_decodeFrameDeltaPage<false>(dst, src, pitch); - } } void Screen::convertAmigaGfx(uint8 *data, int w, int h, bool offscreen) { @@ -1933,7 +1936,7 @@ void Screen::convertAmigaGfx(uint8 *data, int w, int h, bool offscreen) { for (int y = 0; y < h; ++y) { for (int x = 0; x < w; ++x) { int bytePos = x/8+y*40; - int bitPos = 7-x&7; + int bitPos = 7-(x&7); byte colorIndex = 0; colorIndex |= (((tmp[bytePos + 8000 * 0] & (1 << bitPos)) >> bitPos) & 0x1) << 0; @@ -2235,7 +2238,7 @@ uint8 *Screen::encodeShape(int x, int y, int w, int h, int flags) { uint8 *newShape2 = new uint8[shapeSize]; assert(newShape2); memcpy(newShape2, newShape, shapeSize); - delete [] newShape; + delete[] newShape; newShape = newShape2; } else { dst = shapePtrBackUp; @@ -2469,7 +2472,7 @@ void Screen::setMouseCursor(int x, int y, byte *shape) { copyRegionToBuffer(8, xOffset, 0, mouseWidth, mouseHeight, cursor); CursorMan.replaceCursor(cursor, mouseWidth, mouseHeight, x, y, 0); CursorMan.showMouse(true); - delete [] cursor; + delete[] cursor; // makes sure that the cursor is drawn // we do not use Screen::updateScreen here @@ -2642,7 +2645,7 @@ void Screen::shakeScreen(int times) { } void Screen::loadBitmap(const char *filename, int tempPage, int dstPage, uint8 *palData, bool skip) { - debugC(9, kDebugLevelScreen, "KyraEngine::loadBitmap('%s', %d, %d, %p, %d)", filename, tempPage, dstPage, (void *)palData, skip); + debugC(9, kDebugLevelScreen, "KyraEngine_v1::loadBitmap('%s', %d, %d, %p, %d)", filename, tempPage, dstPage, (void *)palData, skip); uint32 fileSize; uint8 *srcData = _vm->resource()->fileData(filename, &fileSize); @@ -2694,7 +2697,7 @@ void Screen::loadBitmap(const char *filename, int tempPage, int dstPage, uint8 * if (skip) srcData -= 4; - delete [] srcData; + delete[] srcData; } bool Screen::loadPalette(const char *filename, uint8 *palData) { @@ -2722,7 +2725,7 @@ bool Screen::loadPalette(const char *filename, uint8 *palData) { memcpy(palData, srcData, fileSize); } } - delete [] srcData; + delete[] srcData; return true; } diff --git a/engines/kyra/screen.h b/engines/kyra/screen.h index bf23747daf..f8c85a2bac 100644 --- a/engines/kyra/screen.h +++ b/engines/kyra/screen.h @@ -35,7 +35,7 @@ namespace Kyra { typedef Common::Functor0<void> UpdateFunctor; -class KyraEngine; +class KyraEngine_v1; struct Rect { int x, y; @@ -96,7 +96,7 @@ public: FID_NUM }; - Screen(KyraEngine *vm, OSystem *system); + Screen(KyraEngine_v1 *vm, OSystem *system); virtual ~Screen(); // init @@ -301,7 +301,7 @@ protected: void addDirtyRect(int x, int y, int w, int h); OSystem *_system; - KyraEngine *_vm; + KyraEngine_v1 *_vm; // shape int drawShapeMarginNoScaleUpwind(uint8 *&dst, const uint8 *&src, int &cnt); diff --git a/engines/kyra/screen_hof.cpp b/engines/kyra/screen_hof.cpp index 9192626159..2378c870a8 100644 --- a/engines/kyra/screen_hof.cpp +++ b/engines/kyra/screen_hof.cpp @@ -31,13 +31,7 @@ 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; + : Screen_v2(vm, system), _vm(vm) { } void Screen_HoF::setScreenDim(int dim) { @@ -74,80 +68,10 @@ void Screen_HoF::generateGrayOverlay(const uint8 *srcPal, uint8 *grayOverlay, in 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 )) + if (!cmpW || !cmpH) return; int r1, r2, r3, r4, r5, r6; @@ -192,8 +116,7 @@ void Screen_HoF::copyPageMemory(int srcPage, int srcPos, int dstPage, int 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) { +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; @@ -229,51 +152,5 @@ void Screen_HoF::copyRegionEx(int srcPage, int srcW, int srcH, int dstPage, int } } -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 index a6df749538..088e8b7f55 100644 --- a/engines/kyra/screen_hof.h +++ b/engines/kyra/screen_hof.h @@ -36,15 +36,12 @@ 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); @@ -53,8 +50,6 @@ private: static const ScreenDim _screenDimTable[]; static const int _screenDimTableCount; - - uint8 *_wsaFrameAnimBuffer; }; } // End of namespace Kyra diff --git a/engines/kyra/screen_v1.cpp b/engines/kyra/screen_lok.cpp index 9454418fd5..011c90dde9 100644 --- a/engines/kyra/screen_v1.cpp +++ b/engines/kyra/screen_lok.cpp @@ -23,36 +23,36 @@ * */ -#include "kyra/kyra_v1.h" -#include "kyra/screen_v1.h" +#include "kyra/kyra_lok.h" +#include "kyra/screen_lok.h" namespace Kyra { #define BITBLIT_RECTS 10 -Screen_v1::Screen_v1(KyraEngine_v1 *vm, OSystem *system) +Screen_LoK::Screen_LoK(KyraEngine_LoK *vm, OSystem *system) : Screen(vm, system) { _vm = vm; } -Screen_v1::~Screen_v1() { - delete [] _bitBlitRects; +Screen_LoK::~Screen_LoK() { + delete[] _bitBlitRects; for (int i = 0; i < ARRAYSIZE(_saveLoadPage); ++i) { - delete [] _saveLoadPage[i]; + delete[] _saveLoadPage[i]; _saveLoadPage[i] = 0; } for (int i = 0; i < ARRAYSIZE(_saveLoadPageOvl); ++i) { - delete [] _saveLoadPageOvl[i]; + delete[] _saveLoadPageOvl[i]; _saveLoadPageOvl[i] = 0; } - delete [] _unkPtr1; - delete [] _unkPtr2; + delete[] _unkPtr1; + delete[] _unkPtr2; } -bool Screen_v1::init() { +bool Screen_LoK::init() { if (!Screen::init()) return false; @@ -73,20 +73,20 @@ bool Screen_v1::init() { return true; } -void Screen_v1::setScreenDim(int dim) { - debugC(9, kDebugLevelScreen, "Screen_v1::setScreenDim(%d)", dim); +void Screen_LoK::setScreenDim(int dim) { + debugC(9, kDebugLevelScreen, "Screen_LoK::setScreenDim(%d)", dim); assert(dim < _screenDimTableCount); _curDim = &_screenDimTable[dim]; } -const ScreenDim *Screen_v1::getScreenDim(int dim) { - debugC(9, kDebugLevelScreen, "Screen_v1::getScreenDim(%d)", dim); +const ScreenDim *Screen_LoK::getScreenDim(int dim) { + debugC(9, kDebugLevelScreen, "Screen_LoK::getScreenDim(%d)", dim); assert(dim < _screenDimTableCount); return &_screenDimTable[dim]; } -void Screen_v1::fadeSpecialPalette(int palIndex, int startIndex, int size, int fadeTime) { - debugC(9, kDebugLevelScreen, "Screen_v1::fadeSpecialPalette(%d, %d, %d, %d)", palIndex, startIndex, size, fadeTime); +void Screen_LoK::fadeSpecialPalette(int palIndex, int startIndex, int size, int fadeTime) { + debugC(9, kDebugLevelScreen, "Screen_LoK::fadeSpecialPalette(%d, %d, %d, %d)", palIndex, startIndex, size, fadeTime); assert(_vm->palTable1()[palIndex]); assert(_currentPalette); @@ -99,8 +99,8 @@ void Screen_v1::fadeSpecialPalette(int palIndex, int startIndex, int size, int f _system->updateScreen(); } -void Screen_v1::addBitBlitRect(int x, int y, int w, int h) { - debugC(9, kDebugLevelScreen, "Screen_v1::addBitBlitRects(%d, %d, %d, %d)", x, y, w, h); +void Screen_LoK::addBitBlitRect(int x, int y, int w, int h) { + debugC(9, kDebugLevelScreen, "Screen_LoK::addBitBlitRects(%d, %d, %d, %d)", x, y, w, h); if (_bitBlitNum >= BITBLIT_RECTS) error("too many bit blit rects"); @@ -111,8 +111,8 @@ void Screen_v1::addBitBlitRect(int x, int y, int w, int h) { ++_bitBlitNum; } -void Screen_v1::bitBlitRects() { - debugC(9, kDebugLevelScreen, "Screen_v1::bitBlitRects()"); +void Screen_LoK::bitBlitRects() { + debugC(9, kDebugLevelScreen, "Screen_LoK::bitBlitRects()"); Rect *cur = _bitBlitRects; while (_bitBlitNum) { _bitBlitNum--; @@ -121,8 +121,8 @@ void Screen_v1::bitBlitRects() { } } -void Screen_v1::savePageToDisk(const char *file, int page) { - debugC(9, kDebugLevelScreen, "Screen_v1::savePageToDisk('%s', %d)", file, page); +void Screen_LoK::savePageToDisk(const char *file, int page) { + debugC(9, kDebugLevelScreen, "Screen_LoK::savePageToDisk('%s', %d)", file, page); if (!_saveLoadPage[page/2]) { _saveLoadPage[page/2] = new uint8[SCREEN_W * SCREEN_H]; assert(_saveLoadPage[page/2]); @@ -145,10 +145,10 @@ void Screen_v1::savePageToDisk(const char *file, int page) { } } -void Screen_v1::loadPageFromDisk(const char *file, int page) { - debugC(9, kDebugLevelScreen, "Screen_v1::loadPageFromDisk('%s', %d)", file, page); +void Screen_LoK::loadPageFromDisk(const char *file, int page) { + debugC(9, kDebugLevelScreen, "Screen_LoK::loadPageFromDisk('%s', %d)", file, page); copyBlockToPage(page, 0, 0, SCREEN_W, SCREEN_H, _saveLoadPage[page/2]); - delete [] _saveLoadPage[page/2]; + delete[] _saveLoadPage[page/2]; if (_saveLoadPageOvl[page/2]) { uint8 *dstPage = getOverlayPtr(page); @@ -158,24 +158,24 @@ void Screen_v1::loadPageFromDisk(const char *file, int page) { } memcpy(dstPage, _saveLoadPageOvl[page/2], SCREEN_OVL_SJIS_SIZE); - delete [] _saveLoadPageOvl[page/2]; + delete[] _saveLoadPageOvl[page/2]; _saveLoadPageOvl[page/2] = 0; } _saveLoadPage[page/2] = 0; } -void Screen_v1::deletePageFromDisk(int page) { - debugC(9, kDebugLevelScreen, "Screen_v1::deletePageFromDisk(%d)", page); - delete [] _saveLoadPage[page/2]; +void Screen_LoK::deletePageFromDisk(int page) { + debugC(9, kDebugLevelScreen, "Screen_LoK::deletePageFromDisk(%d)", page); + delete[] _saveLoadPage[page/2]; _saveLoadPage[page/2] = 0; if (_saveLoadPageOvl[page/2]) { - delete [] _saveLoadPageOvl[page/2]; + delete[] _saveLoadPageOvl[page/2]; _saveLoadPageOvl[page/2] = 0; } } -void Screen_v1::copyBackgroundBlock(int x, int page, int flag) { - debugC(9, kDebugLevelScreen, "Screen_v1::copyBackgroundBlock(%d, %d, %d)", x, page, flag); +void Screen_LoK::copyBackgroundBlock(int x, int page, int flag) { + debugC(9, kDebugLevelScreen, "Screen_LoK::copyBackgroundBlock(%d, %d, %d)", x, page, flag); if (x < 1) return; @@ -216,17 +216,17 @@ void Screen_v1::copyBackgroundBlock(int x, int page, int flag) { _curPage = oldVideoPage; } -void Screen_v1::copyBackgroundBlock2(int x) { - debugC(9, kDebugLevelScreen, "Screen_v1::copyBackgroundBlock2(%d)", x); +void Screen_LoK::copyBackgroundBlock2(int x) { + debugC(9, kDebugLevelScreen, "Screen_LoK::copyBackgroundBlock2(%d)", x); copyBackgroundBlock(x, 4, 1); } -void Screen_v1::setTextColorMap(const uint8 *cmap) { - debugC(9, kDebugLevelScreen, "Screen_v1::setTextColorMap(%p)", (const void *)cmap); +void Screen_LoK::setTextColorMap(const uint8 *cmap) { + debugC(9, kDebugLevelScreen, "Screen_LoK::setTextColorMap(%p)", (const void *)cmap); setTextColor(cmap, 0, 11); } -int Screen_v1::getRectSize(int x, int y) { +int Screen_LoK::getRectSize(int x, int y) { if (x < 1) x = 1; else if (x > 40) diff --git a/engines/kyra/screen_v1.h b/engines/kyra/screen_lok.h index 10219ae6b5..74df23a543 100644 --- a/engines/kyra/screen_v1.h +++ b/engines/kyra/screen_lok.h @@ -23,19 +23,19 @@ * */ -#ifndef KYRA_SCREEN_V1_H -#define KYRA_SCREEN_V1_H +#ifndef KYRA_SCREEN_LOK_H +#define KYRA_SCREEN_LOK_H #include "kyra/screen.h" namespace Kyra { -class KyraEngine_v1; +class KyraEngine_LoK; -class Screen_v1 : public Screen { +class Screen_LoK : public Screen { public: - Screen_v1(KyraEngine_v1 *vm, OSystem *system); - virtual ~Screen_v1(); + Screen_LoK(KyraEngine_LoK *vm, OSystem *system); + virtual ~Screen_LoK(); bool init(); @@ -59,7 +59,7 @@ public: void bitBlitRects(); protected: - KyraEngine_v1 *_vm; + KyraEngine_LoK *_vm; static const ScreenDim _screenDimTable[]; static const int _screenDimTableCount; diff --git a/engines/kyra/screen_v2.cpp b/engines/kyra/screen_v2.cpp index 704296c534..e26ef87bad 100644 --- a/engines/kyra/screen_v2.cpp +++ b/engines/kyra/screen_v2.cpp @@ -29,6 +29,15 @@ namespace Kyra { +Screen_v2::Screen_v2(KyraEngine_v1 *vm, OSystem *system) : Screen(vm, system), _wsaFrameAnimBuffer(0) { + _wsaFrameAnimBuffer = new uint8[1024]; + assert(_wsaFrameAnimBuffer); +} + +Screen_v2::~Screen_v2() { + delete[] _wsaFrameAnimBuffer; +} + uint8 *Screen_v2::generateOverlay(const uint8 *palette, uint8 *buffer, int startColor, uint16 factor) { if (!palette || !buffer) return buffer; @@ -290,6 +299,9 @@ uint8 *Screen_v2::makeShapeCopy(const uint8 *src, int index) { debugC(9, kDebugLevelScreen, "Screen_v2::makeShapeCopy(%p, %d)", (const void *)src, index); const uint8 *shape = getPtrToShape(src, index); + if (!shape) + return 0; + int size = getShapeSize(shape); uint8 *copy = new uint8[size]; @@ -333,5 +345,121 @@ void Screen_v2::setTextColorMap(const uint8 *cmap) { setTextColor(cmap, 0, 15); } +void Screen_v2::wsaFrameAnimationStep(int x1, int y1, int x2, int y2, + int w1, int h1, int w2, int h2, int srcPage, int dstPage, int dim) { + + if (!(w1 || h1 || w2 || h2)) + return; + + ScreenDim cdm = *getScreenDim(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); +} + +bool Screen_v2::calcBounds(int w0, int h0, int &x1, int &y1, int &w1, int &h1, int &x2, int &y2, int &w2) { + x2 = 0; + y2 = 0; + w2 = w1; + + int t = x1 + w1; + if (t < 1) { + w1 = h1 = -1; + } else { + if (t <= x1) { + x2 = w1 - t; + w1 = t; + x1 = 0; + } + t = w0 - x1; + if (t < 1) { + w1 = h1 = -1; + } else { + if (t <= w1) { + w1 = t; + } + w2 -= w1; + t = h1 + y1; + if (t < 1) { + w1 = h1 = -1; + } else { + if (t <= y1) { + y2 = h1 - t; + h1 = t; + y1 = 0; + } + t = h0 - y1; + if (t < 1) { + w1 = h1 = -1; + } else { + if (t <= h1) { + h1 = t; + } + } + } + } + } + + return (w1 == -1) ? false : true; +} + } // end of namespace Kyra diff --git a/engines/kyra/screen_v2.h b/engines/kyra/screen_v2.h index 5679dadf39..f624228445 100644 --- a/engines/kyra/screen_v2.h +++ b/engines/kyra/screen_v2.h @@ -33,7 +33,8 @@ namespace Kyra { class Screen_v2 : public Screen { public: - Screen_v2(KyraEngine *vm, OSystem *system) : Screen(vm, system) {} + Screen_v2(KyraEngine_v1 *vm, OSystem *system); + ~Screen_v2(); // screen page handling void copyWsaRect(int x, int y, int w, int h, int dimState, int plotFunc, const uint8 *src, @@ -57,13 +58,18 @@ public: // rect handling int getRectSize(int w, int h); + bool calcBounds(int w0, int h0, int &x1, int &y1, int &w1, int &h1, int &x2, int &y2, int &w2); // text display void setTextColorMap(const uint8 *cmap); // layer handling virtual int getLayer(int x, int y); + + // special WSA handling + void wsaFrameAnimationStep(int x1, int y1, int x2, int y2, int w1, int h1, int w2, int h2, int srcPage, int dstPage, int dim); protected: + uint8 *_wsaFrameAnimBuffer; }; } // end of namespace Kyra diff --git a/engines/kyra/script.cpp b/engines/kyra/script.cpp index e9dc34e581..ef3e259cfa 100644 --- a/engines/kyra/script.cpp +++ b/engines/kyra/script.cpp @@ -28,12 +28,12 @@ #include "common/stream.h" #include "common/util.h" #include "common/system.h" -#include "kyra/kyra.h" +#include "kyra/kyra_v1.h" #include "kyra/resource.h" #include "kyra/script.h" namespace Kyra { -EMCInterpreter::EMCInterpreter(KyraEngine *vm) : _vm(vm) { +EMCInterpreter::EMCInterpreter(KyraEngine_v1 *vm) : _vm(vm) { #define COMMAND(x) { &EMCInterpreter::x, #x } static CommandEntry commandProcs[] = { // 0x00 @@ -139,9 +139,9 @@ void EMCInterpreter::unload(EMCData *data) { if (!data) return; - delete [] data->text; - delete [] data->ordr; - delete [] data->data; + delete[] data->text; + delete[] data->ordr; + delete[] data->data; data->text = 0; data->ordr = data->data = 0; diff --git a/engines/kyra/script.h b/engines/kyra/script.h index df86ec79c3..de52093f66 100644 --- a/engines/kyra/script.h +++ b/engines/kyra/script.h @@ -27,6 +27,7 @@ #define KYRA_SCRIPT_H #include "common/stream.h" +#include "common/array.h" #include "common/func.h" namespace Kyra { @@ -63,7 +64,7 @@ struct EMCState { #define AVTL_CHUNK 0x4C545641 class Resource; -class KyraEngine; +class KyraEngine_v1; class ScriptFileParser { public: @@ -89,7 +90,7 @@ private: class EMCInterpreter { public: - EMCInterpreter(KyraEngine *vm); + EMCInterpreter(KyraEngine_v1 *vm); bool load(const char *filename, EMCData *data, const Common::Array<const Opcode*> *opcodes); void unload(EMCData *data); @@ -101,7 +102,7 @@ public: bool run(EMCState *script); protected: - KyraEngine *_vm; + KyraEngine_v1 *_vm; int16 _parameter; typedef void (EMCInterpreter::*CommandProc)(EMCState*); diff --git a/engines/kyra/script_hof.cpp b/engines/kyra/script_hof.cpp index ff28e08960..91fbfb3e49 100644 --- a/engines/kyra/script_hof.cpp +++ b/engines/kyra/script_hof.cpp @@ -723,12 +723,6 @@ int KyraEngine_HoF::o2_loadMusicTrack(EMCState *script) { 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); @@ -736,18 +730,6 @@ int KyraEngine_HoF::o2_setSceneAnimPos(EMCState *script) { 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); @@ -778,7 +760,7 @@ int KyraEngine_HoF::o2_showItemString(EMCState *script) { int KyraEngine_HoF::o2_isAnySoundPlaying(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_isAnySoundPlaying(%p) ()", (const void *)script); - return _sound->voiceIsPlaying(); + return _sound->voiceIsPlaying() ? 1 : 0; } int KyraEngine_HoF::o2_setDrawNoShapeFlag(EMCState *script) { @@ -818,7 +800,7 @@ int KyraEngine_HoF::o2_showLetter(EMCState *script) { _screen->fadeToBlack(0x14); sprintf(filename, "LETTER%.1d.", letter); - strcat(filename, _languageExtension[_lang]); + strcat(filename, (_flags.isTalkie || _flags.platform == Common::kPlatformFMTowns || _lang) ? _languageExtension[_lang] : "TXT"); uint8 *letterBuffer = _res->fileData(filename, 0); if (letterBuffer) { @@ -856,10 +838,14 @@ int KyraEngine_HoF::o2_showLetter(EMCState *script) { 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_playFireflyScore(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_playFireflyScore(%p) ()", (const void *)script); + if (_sound->getSfxType() == Sound::kAdlib || _sound->getSfxType() == Sound::kMidiMT32 || _sound->getSfxType() == Sound::kMidiGM) { + snd_playWanderScoreViaMap(86, 1); + return 1; + } else { + return 0; + } } int KyraEngine_HoF::o2_encodeShape(EMCState *script) { @@ -910,14 +896,22 @@ int KyraEngine_HoF::o2_updateSceneAnim(EMCState *script) { // 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)) + // - 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. + // - When the sheriff enters the jail, either to lock you up or to throw + // away the key. (see bug #1926838 "HoF: Animation plays too fast"). + + if ((stackPos(0) == 2 && _mainCharacter.sceneId == 3) || + (stackPos(0) == 3 && _mainCharacter.sceneId == 33) || + ((stackPos(0) == 1 || stackPos(0) == 2) && _mainCharacter.sceneId == 19) || + ((stackPos(0) == 1 || stackPos(0) == 2) && _mainCharacter.sceneId == 27)) _sceneSpecialScriptsTimer[_lastProcessedSceneScript] = _system->getMillis() + _tickLength * 6; _specialSceneScriptRunFlag = false; @@ -1325,9 +1319,20 @@ int KyraEngine_HoF::o2_drawSceneShapeEx(EMCState *script) { 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_midiSoundFadeout(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_midiSoundFadeout(%p) ()", (const void *)script); + if (!stackPos(0)) { + if ((_sound->getMusicType() == Sound::kMidiMT32 || _sound->getMusicType() == Sound::kMidiGM) && + (_sound->getSfxType() == Sound::kMidiMT32 || _sound->getSfxType() == Sound::kMidiGM)) { + _sound->beginFadeOut(); + delay(2000, true); + _lastMusicCommand = -1; + } else { + return 0; + } + } + + return 1; } int KyraEngine_HoF::o2_getSfxDriver(EMCState *script) { @@ -1539,25 +1544,25 @@ void KyraEngine_HoF::setupOpcodeTable() { Opcode(o2_removeItemFromInventory); Opcode(o2_countItemInInventory); Opcode(o2_countItemsInScene); - Opcode(o2_queryGameFlag); + Opcode(o1_queryGameFlag); // 0x28 - Opcode(o2_resetGameFlag); - Opcode(o2_setGameFlag); - Opcode(o2_setHandItem); - Opcode(o2_removeHandItem); + Opcode(o1_resetGameFlag); + Opcode(o1_setGameFlag); + Opcode(o1_setHandItem); + Opcode(o1_removeHandItem); // 0x2c - Opcode(o2_handItemSet); - Opcode(o2_hideMouse); + Opcode(o1_getMouseState); + Opcode(o1_hideMouse); Opcode(o2_addSpecialExit); - Opcode(o2_setMousePos); + Opcode(o1_setMousePos); // 0x30 - Opcode(o2_showMouse); + Opcode(o1_showMouse); OpcodeUnImpl(); Opcode(o2_wipeDownMouseItem); Opcode(o2_getElapsedSecs); // 0x34 Opcode(o2_getTimerDelay); - Opcode(o2_playSoundEffect); + Opcode(o1_playSoundEffect); Opcode(o2_delaySecs); Opcode(o2_delay); // 0x38 @@ -1601,29 +1606,29 @@ void KyraEngine_HoF::setupOpcodeTable() { Opcode(o2_setZanthiaPos); Opcode(o2_loadMusicTrack); // 0x58 - Opcode(o2_playWanderScoreViaMap); - Opcode(o2_playSoundEffect); + Opcode(o1_playWanderScoreViaMap); + Opcode(o1_playSoundEffect); Opcode(o2_setSceneAnimPos); - Opcode(o2_blockInRegion); + Opcode(o1_blockInWalkableRegion); // 0x5c - Opcode(o2_blockOutRegion); + Opcode(o1_blockOutWalkableRegion); OpcodeUnImpl(); Opcode(o2_setCauldronState); Opcode(o2_showItemString); // 0x60 - Opcode(o2_getRand); + Opcode(o1_getRand); Opcode(o2_isAnySoundPlaying); - Opcode(o2_setDeathHandler); + Opcode(o1_setDeathHandler); Opcode(o2_setDrawNoShapeFlag); // 0x64 Opcode(o2_setRunFlag); Opcode(o2_showLetter); OpcodeUnImpl(); - Opcode(o2_fillRect); + Opcode(o1_fillRect); // 0x68 OpcodeUnImpl(); OpcodeUnImpl(); - OpcodeUnImpl(); + Opcode(o2_playFireflyScore); Opcode(o2_waitForConfirmationClick); // 0x6c Opcode(o2_encodeShape); @@ -1694,7 +1699,7 @@ void KyraEngine_HoF::setupOpcodeTable() { Opcode(o2_updateTwoSceneAnims); Opcode(o2_getRainbowRoomData); Opcode(o2_drawSceneShapeEx); - Opcode(o2_getBoolFromStack); + Opcode(o2_midiSoundFadeout); // 0xa4 Opcode(o2_getSfxDriver); Opcode(o2_getVocSupport); @@ -1716,7 +1721,7 @@ void KyraEngine_HoF::setupOpcodeTable() { // 0x00 Opcode(o2a_setAnimationShapes); Opcode(o2a_setCharacterFrame); - Opcode(o2_playSoundEffect); + Opcode(o1_playSoundEffect); Opcode(o2_fadeScenePal); // 0x04 _flags.isTalkie ? Opcode(o2a_setResetFrame) : Opcode(o2_dummy); diff --git a/engines/kyra/script_lok.cpp b/engines/kyra/script_lok.cpp new file mode 100644 index 0000000000..efa0f8e48f --- /dev/null +++ b/engines/kyra/script_lok.cpp @@ -0,0 +1,1987 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + + +#include "common/endian.h" +#include "common/system.h" + +#include "kyra/kyra_lok.h" +#include "kyra/script.h" +#include "kyra/screen.h" +#include "kyra/sprites.h" +#include "kyra/wsamovie.h" +#include "kyra/animator_lok.h" +#include "kyra/text.h" +#include "kyra/timer.h" +#include "kyra/sound.h" + +namespace Kyra { +int KyraEngine_LoK::o1_magicInMouseItem(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_magicInMouseItem(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + magicInMouseItem(stackPos(0), stackPos(1), -1); + return 0; +} + +int KyraEngine_LoK::o1_characterSays(EMCState *script) { + _skipFlag = false; + if (_flags.isTalkie) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_characterSays(%p) (%d, '%s', %d, %d)", (const void *)script, stackPos(0), stackPosString(1), stackPos(2), stackPos(3)); + characterSays(stackPos(0), stackPosString(1), stackPos(2), stackPos(3)); + } else { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_characterSays(%p) ('%s', %d, %d)", (const void *)script, stackPosString(0), stackPos(1), stackPos(2)); + const char *string = stackPosString(0); + + if ((_flags.platform == Common::kPlatformFMTowns || _flags.platform == Common::kPlatformPC98) && _flags.lang == Common::JA_JPN) { + static const uint8 townsString1[] = { + 0x83, 0x75, 0x83, 0x89, 0x83, 0x93, 0x83, 0x83, 0x93, 0x81, + 0x41, 0x82, 0xDC, 0x82, 0xBD, 0x97, 0x88, 0x82, 0xBD, 0x82, + 0xCC, 0x82, 0xA9, 0x81, 0x48, 0x00, 0x00, 0x00 + }; + static const uint8 townsString2[] = { + 0x83, 0x75, 0x83, 0x89, 0x83, 0x93, 0x83, 0x5C, 0x83, 0x93, + 0x81, 0x41, 0x82, 0xDC, 0x82, 0xBD, 0x97, 0x88, 0x82, 0xBD, + 0x82, 0xCC, 0x82, 0xA9, 0x81, 0x48, 0x00, 0x00 + }; + + if (strncmp((const char *)townsString1, string, sizeof(townsString1)) == 0) + string = (const char *)townsString2; + } + + characterSays(-1, string, stackPos(1), stackPos(2)); + } + + return 0; +} + +int KyraEngine_LoK::o1_delay(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_delay(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + if (stackPos(1)) { + warning("STUB: special o1_delay"); + // delete this after correct implementing + delayWithTicks(stackPos(0)); + } else { + delayWithTicks(stackPos(0)); + } + return 0; +} + +int KyraEngine_LoK::o1_drawSceneAnimShape(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_drawSceneAnimShape(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); + _screen->drawShape(stackPos(4), _sprites->_sceneShapes[stackPos(0)], stackPos(1), stackPos(2), 0, (stackPos(3) != 0) ? 1 : 0); + return 0; +} + +int KyraEngine_LoK::o1_runNPCScript(EMCState *script) { + warning("STUB: o1_runNPCScript"); + return 0; +} + +int KyraEngine_LoK::o1_setSpecialExitList(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_setSpecialExitList(%p) (%d, %d, %d, %d, %d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7), stackPos(8), stackPos(9)); + + for (int i = 0; i < 10; ++i) + _exitList[i] = stackPos(i); + _exitListPtr = _exitList; + + return 0; +} + +int KyraEngine_LoK::o1_walkPlayerToPoint(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_walkPlayerToPoint(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); + + int normalTimers = stackPos(2); + if (!normalTimers) { + _timer->disable(19); + _timer->disable(14); + _timer->disable(18); + } + + int reinitScript = handleSceneChange(stackPos(0), stackPos(1), stackPos(2), stackPos(3)); + + if (!normalTimers) { + _timer->enable(19); + _timer->enable(14); + _timer->enable(18); + } + + if (reinitScript) + _emc->init(script, script->dataPtr); + + if (_sceneChangeState) { + _sceneChangeState = 0; + return 1; + } + return 0; +} + +int KyraEngine_LoK::o1_dropItemInScene(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_dropItemInScene(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); + int item = stackPos(0); + int xpos = stackPos(1); + int ypos = stackPos(2); + + byte freeItem = findFreeItemInScene(_currentCharacter->sceneId); + if (freeItem != 0xFF) { + int sceneId = _currentCharacter->sceneId; + Room *room = &_roomTable[sceneId]; + room->itemsXPos[freeItem] = xpos; + room->itemsYPos[freeItem] = ypos; + room->itemsTable[freeItem] = item; + + _animator->animAddGameItem(freeItem, sceneId); + _animator->updateAllObjectShapes(); + } else { + if (item == 43) + placeItemInGenericMapScene(item, 0); + else + placeItemInGenericMapScene(item, 1); + } + return 0; +} + +int KyraEngine_LoK::o1_drawAnimShapeIntoScene(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_drawAnimShapeIntoScene(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); + _screen->hideMouse(); + _animator->restoreAllObjectBackgrounds(); + int shape = stackPos(0); + int xpos = stackPos(1); + int ypos = stackPos(2); + int flags = (stackPos(3) != 0) ? 1 : 0; + _screen->drawShape(2, _sprites->_sceneShapes[shape], xpos, ypos, 0, flags); + _screen->drawShape(0, _sprites->_sceneShapes[shape], xpos, ypos, 0, flags); + _animator->flagAllObjectsForBkgdChange(); + _animator->preserveAnyChangedBackgrounds(); + _animator->flagAllObjectsForRefresh(); + _animator->updateAllObjectShapes(); + _screen->showMouse(); + return 0; +} + +int KyraEngine_LoK::o1_savePageToDisk(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_savePageToDisk(%p) ('%s', %d)", (const void *)script, stackPosString(0), stackPos(1)); + _screen->savePageToDisk(stackPosString(0), stackPos(1)); + return 0; +} + +int KyraEngine_LoK::o1_sceneAnimOn(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_sceneAnimOn(%p) (%d)", (const void *)script, stackPos(0)); + _sprites->_anims[stackPos(0)].play = true; + return 0; +} + +int KyraEngine_LoK::o1_sceneAnimOff(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_sceneAnimOff(%p) (%d)", (const void *)script, stackPos(0)); + _sprites->_anims[stackPos(0)].play = false; + return 0; +} + +int KyraEngine_LoK::o1_getElapsedSeconds(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_getElapsedSeconds(%p) ()", (const void *)script); + return _system->getMillis() / 1000; +} + +int KyraEngine_LoK::o1_mouseIsPointer(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_mouseIsPointer(%p) ()", (const void *)script); + if (_itemInHand == -1) + return 1; + return 0; +} + +int KyraEngine_LoK::o1_runSceneAnimUntilDone(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_runSceneAnimUntilDone(%p) (%d)", (const void *)script, stackPos(0)); + _screen->hideMouse(); + _animator->restoreAllObjectBackgrounds(); + _sprites->_anims[stackPos(0)].play = true; + _animator->sprites()[stackPos(0)].active = 1; + _animator->flagAllObjectsForBkgdChange(); + _animator->preserveAnyChangedBackgrounds(); + while (_sprites->_anims[stackPos(0)].play) { + _sprites->updateSceneAnims(); + _animator->updateAllObjectShapes(); + delay(10); + } + _animator->restoreAllObjectBackgrounds(); + _screen->showMouse(); + return 0; +} + +int KyraEngine_LoK::o1_fadeSpecialPalette(EMCState *script) { + if (_flags.platform == Common::kPlatformAmiga) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_fadeSpecialPalette(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); + if (_currentCharacter->sceneId != 45) { + if (stackPos(0) == 13) { + memcpy(_screen->getPalette(0), _screen->getPalette(0) + 384*3, 32*3); + _screen->setScreenPalette(_screen->getPalette(0)); + } + } else { + warning("KyraEngine_LoK::o1_fadeSpecialPalette not implemented"); + } + } else { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_fadeSpecialPalette(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); + _screen->fadeSpecialPalette(stackPos(0), stackPos(1), stackPos(2), stackPos(3)); + } + return 0; +} + +int KyraEngine_LoK::o1_phaseInSameScene(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_phaseInSameScene(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + transcendScenes(stackPos(0), stackPos(1)); + return 0; +} + +int KyraEngine_LoK::o1_setScenePhasingFlag(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_setScenePhasingFlag(%p) ()", (const void *)script); + _scenePhasingFlag = 1; + return 1; +} + +int KyraEngine_LoK::o1_resetScenePhasingFlag(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_resetScenePhasingFlag(%p) ()", (const void *)script); + _scenePhasingFlag = 0; + return 0; +} + +int KyraEngine_LoK::o1_queryScenePhasingFlag(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_queryScenePhasingFlag(%p) ()", (const void *)script); + return _scenePhasingFlag; +} + +int KyraEngine_LoK::o1_sceneToDirection(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_sceneToDirection(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + assert(stackPos(0) < _roomTableSize); + Room *curRoom = &_roomTable[stackPos(0)]; + uint16 returnValue = 0xFFFF; + switch (stackPos(1)) { + case 0: + returnValue = curRoom->northExit; + break; + + case 2: + returnValue = curRoom->eastExit; + break; + + case 4: + returnValue = curRoom->southExit; + break; + + case 6: + returnValue = curRoom->westExit; + break; + + default: + break; + } + if (returnValue == 0xFFFF) + return -1; + return returnValue; +} + +int KyraEngine_LoK::o1_setBirthstoneGem(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_setBirthstoneGem(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + int index = stackPos(0); + if (index < 4 && index >= 0) { + _birthstoneGemTable[index] = stackPos(1); + return 1; + } + return 0; +} + +int KyraEngine_LoK::o1_placeItemInGenericMapScene(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_placeItemInGenericMapScene(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + placeItemInGenericMapScene(stackPos(0), stackPos(1)); + return 0; +} + +int KyraEngine_LoK::o1_setBrandonStatusBit(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_setBrandonStatusBit(%p) (%d)", (const void *)script, stackPos(0)); + _brandonStatusBit |= stackPos(0); + return 0; +} + +int KyraEngine_LoK::o1_delaySecs(EMCState *script) { + if (_flags.isTalkie && speechEnabled()) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_voiceDelay(%p) (%d)", (const void *)script, stackPos(0)); + if (stackPos(0) == 0) { + snd_voiceWaitForFinish(true); + } else if (stackPos(0) < 0) { + uint32 time = ABS(stackPos(0)) * _tickLength; + delay(time, true); + } + } else { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_delaySecs(%p) (%d)", (const void *)script, stackPos(0)); + if (stackPos(0) >= 0 && !_skipFlag) + delay(stackPos(0)*1000, true); + } + + _skipFlag = false; + return 0; +} + +int KyraEngine_LoK::o1_getCharacterScene(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_getCharacterScene(%p) (%d)", (const void *)script, stackPos(0)); + return _characterList[stackPos(0)].sceneId; +} + +int KyraEngine_LoK::o1_runNPCSubscript(EMCState *script) { + warning("STUB: o1_runNPCSubscript"); + return 0; +} + +int KyraEngine_LoK::o1_magicOutMouseItem(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_magicOutMouseItem(%p) (%d)", (const void *)script, stackPos(0)); + magicOutMouseItem(stackPos(0), -1); + return 0; +} + +int KyraEngine_LoK::o1_internalAnimOn(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_internalAnimOn(%p) (%d)", (const void *)script, stackPos(0)); + _animator->sprites()[stackPos(0)].active = 1; + return 0; +} + +int KyraEngine_LoK::o1_forceBrandonToNormal(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_forceBrandonToNormal(%p) ()", (const void *)script); + checkAmuletAnimFlags(); + return 0; +} + +int KyraEngine_LoK::o1_poisonDeathNow(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_poisonDeathNow(%p) ()", (const void *)script); + seq_poisonDeathNow(1); + return 0; +} + +int KyraEngine_LoK::o1_setScaleMode(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_setScaleMode(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); + int len = stackPos(0); + int setValue1 = stackPos(1); + int start2 = stackPos(2); + int setValue2 = stackPos(3); + for (int i = 0; i < len; ++i) + _scaleTable[i] = setValue1; + int temp = setValue2 - setValue1; + int temp2 = start2 - len; + for (int i = len, offset = 0; i < start2; ++i, ++offset) + _scaleTable[i] = (offset * temp) / temp2 + setValue1; + for (int i = start2; i < 145; ++i) + _scaleTable[i] = setValue2; + _scaleMode = 1; + return _scaleMode; +} + +int KyraEngine_LoK::o1_openWSAFile(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_openWSAFile(%p) ('%s', %d, %d, %d)", (const void *)script, stackPosString(0), stackPos(1), stackPos(2), stackPos(3)); + + const char *filename = stackPosString(0); + int wsaIndex = stackPos(1); + + _movieObjects[wsaIndex]->open(filename, (stackPos(3) != 0) ? 1 : 0, 0); + assert(_movieObjects[wsaIndex]->opened()); + + return 0; +} + +int KyraEngine_LoK::o1_closeWSAFile(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_closeWSAFile(%p) (%d)", (const void *)script, stackPos(0)); + + int wsaIndex = stackPos(0); + if (_movieObjects[wsaIndex]) + _movieObjects[wsaIndex]->close(); + + return 0; +} + +int KyraEngine_LoK::o1_runWSAFromBeginningToEnd(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_runWSAFromBeginningToEnd(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); + + _screen->hideMouse(); + + bool running = true; + + int xpos = stackPos(0); + int ypos = stackPos(1); + int waitTime = stackPos(2); + int wsaIndex = stackPos(3); + int worldUpdate = stackPos(4); + int wsaFrame = 0; + + _movieObjects[wsaIndex]->setX(xpos); + _movieObjects[wsaIndex]->setY(ypos); + _movieObjects[wsaIndex]->setDrawPage(0); + while (running) { + _movieObjects[wsaIndex]->displayFrame(wsaFrame++); + _animator->_updateScreen = true; + if (wsaFrame >= _movieObjects[wsaIndex]->frames()) + running = false; + + uint32 continueTime = waitTime * _tickLength + _system->getMillis(); + while (_system->getMillis() < continueTime) { + if (worldUpdate) { + _sprites->updateSceneAnims(); + _animator->updateAllObjectShapes(); + } else { + _screen->updateScreen(); + } + if (continueTime - _system->getMillis() >= 10) + delay(10); + } + } + + _screen->showMouse(); + + return 0; +} + +int KyraEngine_LoK::o1_displayWSAFrame(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_displayWSAFrame(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); + int frame = stackPos(0); + int xpos = stackPos(1); + int ypos = stackPos(2); + int waitTime = stackPos(3); + int wsaIndex = stackPos(4); + _screen->hideMouse(); + _movieObjects[wsaIndex]->setX(xpos); + _movieObjects[wsaIndex]->setY(ypos); + _movieObjects[wsaIndex]->setDrawPage(0); + _movieObjects[wsaIndex]->displayFrame(frame); + _animator->_updateScreen = true; + uint32 continueTime = waitTime * _tickLength + _system->getMillis(); + while (_system->getMillis() < continueTime) { + _sprites->updateSceneAnims(); + _animator->updateAllObjectShapes(); + if (_skipFlag) + break; + + if (continueTime - _system->getMillis() >= 10) + delay(10); + } + _screen->showMouse(); + return 0; +} + +int KyraEngine_LoK::o1_enterNewScene(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_enterNewScene(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); + enterNewScene(stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); + return 0; +} + +int KyraEngine_LoK::o1_setSpecialEnterXAndY(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_setSpecialEnterXAndY(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + _brandonPosX = stackPos(0); + _brandonPosY = stackPos(1); + if (_brandonPosX + 1 == 0 && _brandonPosY + 1 == 0) + _currentCharacter->currentAnimFrame = 88; + return 0; +} + +int KyraEngine_LoK::o1_runWSAFrames(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_runWSAFrames(%p) (%d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5)); + int xpos = stackPos(0); + int ypos = stackPos(1); + int delayTime = stackPos(2); + int startFrame = stackPos(3); + int endFrame = stackPos(4); + int wsaIndex = stackPos(5); + _screen->hideMouse(); + _movieObjects[wsaIndex]->setX(xpos); + _movieObjects[wsaIndex]->setY(ypos); + _movieObjects[wsaIndex]->setDrawPage(0); + for (; startFrame <= endFrame; ++startFrame) { + uint32 nextRun = _system->getMillis() + delayTime * _tickLength; + _movieObjects[wsaIndex]->displayFrame(startFrame); + _animator->_updateScreen = true; + while (_system->getMillis() < nextRun) { + _sprites->updateSceneAnims(); + _animator->updateAllObjectShapes(); + if (nextRun - _system->getMillis() >= 10) + delay(10); + } + } + _screen->showMouse(); + return 0; +} + +int KyraEngine_LoK::o1_popBrandonIntoScene(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_popBrandonIntoScene(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); + int changeScaleMode = stackPos(3); + int xpos = (int16)(stackPos(0) & 0xFFFC); + int ypos = (int16)(stackPos(1) & 0xFFFE); + int facing = stackPos(2); + _currentCharacter->x1 = _currentCharacter->x2 = xpos; + _currentCharacter->y1 = _currentCharacter->y2 = ypos; + _currentCharacter->facing = facing; + _currentCharacter->currentAnimFrame = 7; + int xOffset = _defaultShapeTable[0].xOffset; + int yOffset = _defaultShapeTable[0].yOffset; + int width = _defaultShapeTable[0].w << 3; + int height = _defaultShapeTable[0].h; + Animator_LoK::AnimObject *curAnim = _animator->actors(); + + if (changeScaleMode) { + curAnim->x1 = _currentCharacter->x1; + curAnim->y1 = _currentCharacter->y1; + _animator->_brandonScaleY = _scaleTable[_currentCharacter->y1]; + _animator->_brandonScaleX = _animator->_brandonScaleY; + + int animWidth = _animator->fetchAnimWidth(curAnim->sceneAnimPtr, _animator->_brandonScaleX) >> 1; + int animHeight = _animator->fetchAnimHeight(curAnim->sceneAnimPtr, _animator->_brandonScaleY); + + animWidth = (xOffset * animWidth) / width; + animHeight = (yOffset * animHeight) / height; + + curAnim->x2 = curAnim->x1 += animWidth; + curAnim->y2 = curAnim->y1 += animHeight; + } else { + curAnim->x2 = curAnim->x1 = _currentCharacter->x1 + xOffset; + curAnim->y2 = curAnim->y1 = _currentCharacter->y1 + yOffset; + } + + int scaleModeBackup = _scaleMode; + if (changeScaleMode) + _scaleMode = 1; + + _animator->animRefreshNPC(0); + _animator->preserveAllBackgrounds(); + _animator->prepDrawAllObjects(); + _animator->copyChangedObjectsForward(0); + + _scaleMode = scaleModeBackup; + + return 0; +} + +int KyraEngine_LoK::o1_restoreAllObjectBackgrounds(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_restoreAllObjectBackgrounds(%p) (%d)", (const void *)script, stackPos(0)); + int disable = stackPos(0); + int activeBackup = 0; + if (disable) { + activeBackup = _animator->actors()->active; + _animator->actors()->active = 0; + } + _animator->restoreAllObjectBackgrounds(); + if (disable) + _animator->actors()->active = activeBackup; + return 0; +} + +int KyraEngine_LoK::o1_setCustomPaletteRange(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_setCustomPaletteRange(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); + memcpy(_screen->getPalette(1) + stackPos(1)*3, _specialPalettes[stackPos(0)], stackPos(2)*3); + return 0; +} + +int KyraEngine_LoK::o1_loadPageFromDisk(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_loadPageFromDisk(%p) ('%s', %d)", (const void *)script, stackPosString(0), stackPos(1)); + _screen->loadPageFromDisk(stackPosString(0), stackPos(1)); + _animator->_updateScreen = true; + return 0; +} + +int KyraEngine_LoK::o1_customPrintTalkString(EMCState *script) { + if (_flags.isTalkie) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_customPrintTalkString(%p) (%d, '%s', %d, %d, %d)", (const void *)script, stackPos(0), stackPosString(1), stackPos(2), stackPos(3), stackPos(4) & 0xFF); + + if (speechEnabled()) { + snd_voiceWaitForFinish(); + snd_playVoiceFile(stackPos(0)); + } + + _skipFlag = false; + if (textEnabled()) + _text->printTalkTextMessage(stackPosString(1), stackPos(2), stackPos(3), stackPos(4) & 0xFF, 0, 2); + } else { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_customPrintTalkString(%p) ('%s', %d, %d, %d)", (const void *)script, stackPosString(0), stackPos(1), stackPos(2), stackPos(3) & 0xFF); + _skipFlag = false; + _text->printTalkTextMessage(stackPosString(0), stackPos(1), stackPos(2), stackPos(3) & 0xFF, 0, 2); + } + _screen->updateScreen(); + return 0; +} + +int KyraEngine_LoK::o1_restoreCustomPrintBackground(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_restoreCustomPrintBackground(%p) ()", (const void *)script); + _text->restoreTalkTextMessageBkgd(2, 0); + return 0; +} + +int KyraEngine_LoK::o1_getCharacterX(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_getCharacterX(%p) (%d)", (const void *)script, stackPos(0)); + return _characterList[stackPos(0)].x1; +} + +int KyraEngine_LoK::o1_getCharacterY(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_getCharacterY(%p) (%d)", (const void *)script, stackPos(0)); + return _characterList[stackPos(0)].y1; +} + +int KyraEngine_LoK::o1_setCharacterFacing(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_setCharacterFacing(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); + int character = stackPos(0); + int facing = stackPos(1); + int newAnimFrame = stackPos(2); + + _animator->restoreAllObjectBackgrounds(); + if (newAnimFrame != -1) + _characterList[character].currentAnimFrame = newAnimFrame; + _characterList[character].facing = facing; + _animator->animRefreshNPC(character); + _animator->preserveAllBackgrounds(); + _animator->prepDrawAllObjects(); + _animator->copyChangedObjectsForward(0); + + return 0; +} + +int KyraEngine_LoK::o1_copyWSARegion(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_copyWSARegion(%p) (%d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5)); + int xpos = stackPos(0); + int ypos = stackPos(1); + int width = stackPos(2); + int height = stackPos(3); + int srcPage = stackPos(4); + int dstPage = stackPos(5); + _screen->copyRegion(xpos, ypos, xpos, ypos, width, height, srcPage, dstPage); + _animator->_updateScreen = true; + return 0; +} + +int KyraEngine_LoK::o1_printText(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_printText(%p) ('%s', %d, %d, 0x%X, 0x%X)", (const void *)script, stackPosString(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); + if (_flags.lang == Common::JA_JPN && stackPos(3) == 7) + _screen->printText(stackPosString(0), stackPos(1), stackPos(2), 0, 0x80); + else + _screen->printText(stackPosString(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); + _screen->updateScreen(); + return 0; +} + +int KyraEngine_LoK::o1_loadSoundFile(EMCState *script) { + warning("STUB: o1_loadSoundFile"); + return 0; +} + +int KyraEngine_LoK::o1_displayWSAFrameOnHidPage(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_displayWSAFrameOnHidPage(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); + int frame = stackPos(0); + int xpos = stackPos(1); + int ypos = stackPos(2); + int waitTime = stackPos(3); + int wsaIndex = stackPos(4); + + _screen->hideMouse(); + uint32 continueTime = waitTime * _tickLength + _system->getMillis(); + _movieObjects[wsaIndex]->setX(xpos); + _movieObjects[wsaIndex]->setY(ypos); + _movieObjects[wsaIndex]->setDrawPage(2); + _movieObjects[wsaIndex]->displayFrame(frame); + _animator->_updateScreen = true; + while (_system->getMillis() < continueTime) { + _sprites->updateSceneAnims(); + _animator->updateAllObjectShapes(); + if (_skipFlag) + break; + + if (continueTime - _system->getMillis() >= 10) + delay(10); + } + _screen->showMouse(); + + return 0; +} + +int KyraEngine_LoK::o1_displayWSASequentialFrames(EMCState *script) { + if (_flags.isTalkie) + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_displayWSASequentialFrames(%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)); + else + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_displayWSASequentialFrames(%p) (%d, %d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6)); + int startFrame = stackPos(0); + int endFrame = stackPos(1); + int xpos = stackPos(2); + int ypos = stackPos(3); + int waitTime = stackPos(4); + int wsaIndex = stackPos(5); + int maxTime = stackPos(6); + + if (_flags.isTalkie) { + int specialTime = stackPos(7); + if (specialTime) { + uint32 voiceTime = snd_getVoicePlayTime(); + if (voiceTime) { + int displayFrames = ABS(endFrame-startFrame)+1; + displayFrames *= maxTime; + assert(displayFrames != 0); + + bool voiceSync = false; + + if (specialTime < 0) { + voiceSync = true; + specialTime = ABS(specialTime); + } + + voiceTime *= specialTime; + voiceTime /= 100; + + if (voiceSync) { + uint32 voicePlayedTime = _sound->voicePlayedTime(_speechFile.c_str()); + if (voicePlayedTime >= voiceTime) + voiceTime = 0; + else + voiceTime -= voicePlayedTime; + } + + waitTime = voiceTime / displayFrames; + waitTime /= _tickLength; + } + } + } + + if (maxTime - 1 <= 0) + maxTime = 1; + + _movieObjects[wsaIndex]->setX(xpos); + _movieObjects[wsaIndex]->setY(ypos); + _movieObjects[wsaIndex]->setDrawPage(0); + + // Workaround for bug #1498221 "KYRA1: Glitches when meeting Zanthia" + // the original didn't do a forced screen update after displaying a wsa frame + // while we have to do it, which make brandon disappear for a short moment, + // what shouldn't happen. So we're not updating the screen for this special + // case too. + if (startFrame == 18 && endFrame == 18 && _currentRoom == 45) { + _movieObjects[wsaIndex]->displayFrame(18); + delay(waitTime * _tickLength); + return 0; + } + + int curTime = 0; + _screen->hideMouse(); + while (curTime < maxTime) { + if (endFrame >= startFrame) { + int frame = startFrame; + while (endFrame >= frame) { + uint32 continueTime = waitTime * _tickLength + _system->getMillis(); + _movieObjects[wsaIndex]->displayFrame(frame); + if (waitTime) + _animator->_updateScreen = true; + while (_system->getMillis() < continueTime) { + _sprites->updateSceneAnims(); + _animator->updateAllObjectShapes(); + if (_skipFlag) + break; + + if (continueTime - _system->getMillis() >= 10) + delay(10); + } + ++frame; + } + } else { + int frame = startFrame; + while (endFrame <= frame) { + uint32 continueTime = waitTime * _tickLength + _system->getMillis(); + _movieObjects[wsaIndex]->displayFrame(frame); + if (waitTime) + _animator->_updateScreen = true; + while (_system->getMillis() < continueTime) { + _sprites->updateSceneAnims(); + _animator->updateAllObjectShapes(); + if (_skipFlag) + break; + + if (continueTime - _system->getMillis() >= 10) + delay(10); + } + --frame; + } + } + + if (_skipFlag) + break; + else + ++curTime; + } + _screen->showMouse(); + + return 0; +} + +int KyraEngine_LoK::o1_refreshCharacter(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_refreshCharacter(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); + int character = stackPos(0); + int animFrame = stackPos(1); + int newFacing = stackPos(2); + int updateShapes = stackPos(3); + _characterList[character].currentAnimFrame = animFrame; + if (newFacing != -1) + _characterList[character].facing = newFacing; + _animator->animRefreshNPC(character); + if (updateShapes) + _animator->updateAllObjectShapes(); + return 0; +} + +int KyraEngine_LoK::o1_internalAnimOff(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_internalAnimOff(%p) (%d)", (const void *)script, stackPos(0)); + _animator->sprites()[stackPos(0)].active = 0; + return 0; +} + +int KyraEngine_LoK::o1_changeCharactersXAndY(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_changeCharactersXAndY(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); + Character *ch = &_characterList[stackPos(0)]; + int16 x = stackPos(1); + int16 y = stackPos(2); + if (x != -1 && y != -1) { + x &= 0xFFFC; + y &= 0xFFFE; + } + _animator->restoreAllObjectBackgrounds(); + ch->x1 = ch->x2 = x; + ch->y1 = ch->y2 = y; + _animator->preserveAllBackgrounds(); + return 0; +} + +int KyraEngine_LoK::o1_clearSceneAnimatorBeacon(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_clearSceneAnimatorBeacon(%p) ()", (const void *)script); + _sprites->_sceneAnimatorBeaconFlag = 0; + return 0; +} + +int KyraEngine_LoK::o1_querySceneAnimatorBeacon(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_querySceneAnimatorBeacon(%p) ()", (const void *)script); + return _sprites->_sceneAnimatorBeaconFlag; +} + +int KyraEngine_LoK::o1_refreshSceneAnimator(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_refreshSceneAnimator(%p) ()", (const void *)script); + _sprites->updateSceneAnims(); + _animator->updateAllObjectShapes(); + return 0; +} + +int KyraEngine_LoK::o1_placeItemInOffScene(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_placeItemInOffScene(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); + int item = stackPos(0); + int xpos = stackPos(1); + int ypos = stackPos(2); + int sceneId = stackPos(3); + + byte freeItem = findFreeItemInScene(sceneId); + if (freeItem != 0xFF) { + assert(sceneId < _roomTableSize); + Room *room = &_roomTable[sceneId]; + + room->itemsTable[freeItem] = item; + room->itemsXPos[freeItem] = xpos; + room->itemsYPos[freeItem] = ypos; + } + return 0; +} + +int KyraEngine_LoK::o1_wipeDownMouseItem(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_wipeDownMouseItem(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); + _screen->hideMouse(); + wipeDownMouseItem(stackPos(1), stackPos(2)); + removeHandItem(); + _screen->showMouse(); + return 0; +} + +int KyraEngine_LoK::o1_placeCharacterInOtherScene(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_placeCharacterInOtherScene(%p) (%d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5)); + int id = stackPos(0); + int sceneId = stackPos(1); + int xpos = (int16)(stackPos(2) & 0xFFFC); + int ypos = (int16)(stackPos(3) & 0xFFFE); + int facing = stackPos(4); + int animFrame = stackPos(5); + + _characterList[id].sceneId = sceneId; + _characterList[id].x1 = _characterList[id].x2 = xpos; + _characterList[id].y1 = _characterList[id].y2 = ypos; + _characterList[id].facing = facing; + _characterList[id].currentAnimFrame = animFrame; + return 0; +} + +int KyraEngine_LoK::o1_getKey(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_getKey(%p) ()", (const void *)script); + waitForEvent(); + return 0; +} + +int KyraEngine_LoK::o1_specificItemInInventory(EMCState *script) { + warning("STUB: o1_specificItemInInventory"); + return 0; +} + +int KyraEngine_LoK::o1_popMobileNPCIntoScene(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_popMobileNPCIntoScene(%p) (%d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), (int16)(stackPos(4) & 0xFFFC), (int8)(stackPos(5) & 0xFE)); + int character = stackPos(0); + int sceneId = stackPos(1); + int animFrame = stackPos(2); + int facing = stackPos(3); + int16 xpos = (int16)(stackPos(4) & 0xFFFC); + int8 ypos = (int16)(stackPos(5) & 0xFFFE); + Character *curChar = &_characterList[character]; + + curChar->sceneId = sceneId; + curChar->currentAnimFrame = animFrame; + curChar->facing = facing; + curChar->x1 = curChar->x2 = xpos; + curChar->y1 = curChar->y2 = ypos; + + _animator->animAddNPC(character); + _animator->updateAllObjectShapes(); + return 0; +} + +int KyraEngine_LoK::o1_mobileCharacterInScene(EMCState *script) { + warning("STUB: o1_mobileCharacterInScene"); + return 0; +} + +int KyraEngine_LoK::o1_hideMobileCharacter(EMCState *script) { + warning("STUB: o1_hideMobileCharacter"); + return 0; +} + +int KyraEngine_LoK::o1_unhideMobileCharacter(EMCState *script) { + warning("STUB: o1_unhideMobileCharacter"); + return 0; +} + +int KyraEngine_LoK::o1_setCharacterLocation(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_setCharacterLocation(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + Character *ch = &_characterList[stackPos(0)]; + Animator_LoK::AnimObject *animObj = &_animator->actors()[stackPos(0)]; + int newScene = stackPos(1); + if (_currentCharacter->sceneId == ch->sceneId) { + if (_currentCharacter->sceneId != newScene) + animObj->active = 0; + } else if (_currentCharacter->sceneId == newScene) { + if (_currentCharacter->sceneId != ch->sceneId) + animObj->active = 1; + } + + ch->sceneId = stackPos(1); + return 0; +} + +int KyraEngine_LoK::o1_walkCharacterToPoint(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_walkCharacterToPoint(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); + int character = stackPos(0); + int toX = stackPos(1); + int toY = stackPos(2); + _pathfinderFlag2 = 1; + uint32 nextFrame; + int findWayReturn = findWay(_characterList[character].x1, _characterList[character].y1, toX, toY, _movFacingTable, 150); + _pathfinderFlag2 = 0; + + if (_lastFindWayRet < findWayReturn) + _lastFindWayRet = findWayReturn; + if (findWayReturn == 0x7D00 || findWayReturn == 0) + return 0; + + int *curPos = _movFacingTable; + bool running = true; + while (running) { + bool forceContinue = false; + switch (*curPos) { + case 0: + _characterList[character].facing = 2; + break; + + case 1: + _characterList[character].facing = 1; + break; + + case 2: + _characterList[character].facing = 0; + break; + + case 3: + _characterList[character].facing = 7; + break; + + case 4: + _characterList[character].facing = 6; + break; + + case 5: + _characterList[character].facing = 5; + break; + + case 6: + _characterList[character].facing = 4; + break; + + case 7: + _characterList[character].facing = 3; + break; + + case 8: + running = 0; + break; + + default: + ++curPos; + forceContinue = true; + break; + } + + if (forceContinue || !running) + continue; + + setCharacterPosition(character, 0); + ++curPos; + + nextFrame = _timer->getDelay(5 + character) * _tickLength + _system->getMillis(); + while (_system->getMillis() < nextFrame) { + _sprites->updateSceneAnims(); + updateMousePointer(); + _timer->update(); + _animator->updateAllObjectShapes(); + updateTextFade(); + if ((nextFrame - _system->getMillis()) >= 10) + delay(10); + } + } + return 0; +} + +int KyraEngine_LoK::o1_specialEventDisplayBrynnsNote(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_specialEventDisplayBrynnsNote(%p) ()", (const void *)script); + _screen->hideMouse(); + _screen->savePageToDisk("HIDPAGE.TMP", 2); + _screen->savePageToDisk("SEENPAGE.TMP", 0); + if (_flags.isTalkie) { + if (_flags.lang == Common::EN_ANY || _flags.lang == Common::IT_ITA) + _screen->loadBitmap("NOTEENG.CPS", 3, 3, 0); + else if (_flags.lang == Common::FR_FRA) + _screen->loadBitmap("NOTEFRE.CPS", 3, 3, 0); + else if (_flags.lang == Common::DE_DEU) + _screen->loadBitmap("NOTEGER.CPS", 3, 3, 0); + } else { + _screen->loadBitmap("NOTE.CPS", 3, 3, 0); + } + _screen->copyRegion(63, 8, 63, 8, 194, 128, 2, 0); + _screen->updateScreen(); + _screen->showMouse(); + _screen->setFont(Screen::FID_6_FNT); + return 0; +} + +int KyraEngine_LoK::o1_specialEventRemoveBrynnsNote(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_specialEventRemoveBrynnsNote(%p) ()", (const void *)script); + _screen->hideMouse(); + _screen->loadPageFromDisk("SEENPAGE.TMP", 0); + _screen->loadPageFromDisk("HIDPAGE.TMP", 2); + _screen->updateScreen(); + _screen->showMouse(); + _screen->setFont(Screen::FID_8_FNT); + return 0; +} + +int KyraEngine_LoK::o1_setLogicPage(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_setLogicPage(%p) (%d)", (const void *)script, stackPos(0)); + _screen->_curPage = stackPos(0); + return stackPos(0); +} + +int KyraEngine_LoK::o1_fatPrint(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_fatPrint(%p) ('%s', %d, %d, %d, %d, %d)", (const void *)script, stackPosString(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5)); + + // Workaround for bug #1582672 ("KYRA1: Text crippled and drawn wrong") + // I'm not sure how the original handles this, since it seems to call + // printText also, maybe it fails somewhere inside... + // TODO: fix the reason for this workaround + if (_currentRoom == 117) + return 0; + _text->printText(stackPosString(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5)); + return 0; +} + +int KyraEngine_LoK::o1_preserveAllObjectBackgrounds(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_preserveAllObjectBackgrounds(%p) ()", (const void *)script); + _animator->preserveAllBackgrounds(); + return 0; +} + +int KyraEngine_LoK::o1_updateSceneAnimations(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_updateSceneAnimations(%p) (%d)", (const void *)script, stackPos(0)); + int times = stackPos(0); + while (times--) { + _sprites->updateSceneAnims(); + _animator->updateAllObjectShapes(); + } + return 0; +} + +int KyraEngine_LoK::o1_sceneAnimationActive(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_sceneAnimationActive(%p) (%d)", (const void *)script, stackPos(0)); + return _sprites->_anims[stackPos(0)].play; +} + +int KyraEngine_LoK::o1_setCharacterMovementDelay(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_setCharacterMovementDelay(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + _timer->setDelay(stackPos(0)+5, stackPos(1)); + return 0; +} + +int KyraEngine_LoK::o1_getCharacterFacing(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_getCharacterFacing(%p) (%d)", (const void *)script, stackPos(0)); + return _characterList[stackPos(0)].facing; +} + +int KyraEngine_LoK::o1_bkgdScrollSceneAndMasksRight(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_bkgdScrollSceneAndMasksRight(%p) (%d)", (const void *)script, stackPos(0)); + _screen->copyBackgroundBlock(stackPos(0), 2, 0); + _screen->copyBackgroundBlock2(stackPos(0)); + // update the whole screen + _screen->copyRegion(7, 7, 7, 7, 305, 129, 3, 0); + // Don't do a screen update here, see bug #1910180 "KYRA1: Screen 'flash'" + // it would cause to draw the screen with a wrong palette and thus look + // strange for the user. Since this opcode should be just called on scene + // initialization anyway, there should be no problem with not updating the + // screen right now. + return 0; +} + +int KyraEngine_LoK::o1_dispelMagicAnimation(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_dispelMagicAnimation(%p) ()", (const void *)script); + seq_dispelMagicAnimation(); + return 0; +} + +int KyraEngine_LoK::o1_findBrightestFireberry(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_findBrightestFireberry(%p) ()", (const void *)script); + if (_currentCharacter->sceneId >= 187 && _currentCharacter->sceneId <= 198) + return 29; + + if (_currentCharacter->sceneId == 133 || _currentCharacter->sceneId == 137 || + _currentCharacter->sceneId == 165 || _currentCharacter->sceneId == 173) + return 29; + + if (_itemInHand == 28) + return 28; + + int brightestFireberry = 107; + if (_itemInHand >= 29 && _itemInHand <= 33) + brightestFireberry = _itemInHand; + for (int i = 0; i < 10; ++i) { + uint8 item = _currentCharacter->inventoryItems[i]; + if (item == 0xFF) + continue; + if (item == 28) + return 28; + if (item >= 29 && item <= 33) { + if (item < brightestFireberry) + brightestFireberry = item; + } + } + assert(_currentCharacter->sceneId < _roomTableSize); + Room *curRoom = &_roomTable[_currentCharacter->sceneId]; + for (int i = 0; i < 12; ++i) { + uint8 item = curRoom->itemsTable[i]; + if (item == 0xFF) + continue; + if (item == 28) + return 28; + if (item >= 29 && item <= 33) { + if (item < brightestFireberry) + brightestFireberry = item; + } + } + if (brightestFireberry == 107) + return -1; + return brightestFireberry; +} + +int KyraEngine_LoK::o1_setFireberryGlowPalette(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_setFireberryGlowPalette(%p) (%d)", (const void *)script, stackPos(0)); + int palIndex = 0; + switch (stackPos(0)) { + case 0x1E: + palIndex = 9; + break; + + case 0x1F: + palIndex = 10; + break; + + case 0x20: + palIndex = 11; + break; + + case 0x21: + case -1: + palIndex = 12; + break; + + default: + palIndex = 8; + break; + } + if (_brandonStatusBit & 2) { + if (_currentCharacter->sceneId != 133 && _currentCharacter->sceneId != 137 && + _currentCharacter->sceneId != 165 && _currentCharacter->sceneId != 173 && + (_currentCharacter->sceneId < 187 || _currentCharacter->sceneId > 198)) { + palIndex = 14; + } + } + const uint8 *palette = _specialPalettes[palIndex]; + memcpy(_screen->getPalette(1) + 684, palette, 44); + return 0; +} + +int KyraEngine_LoK::o1_drinkPotionAnimation(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_drinkPotionAnimation(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); + seq_playDrinkPotionAnim(stackPos(0), stackPos(1), stackPos(2)); + return 0; +} + +int KyraEngine_LoK::o1_makeAmuletAppear(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_makeAmuletAppear(%p) ()", (const void *)script); + WSAMovie_v1 amulet(this); + amulet.open("AMULET.WSA", 1, 0); + amulet.setX(224); + amulet.setY(152); + amulet.setDrawPage(0); + if (amulet.opened()) { + assert(_amuleteAnim); + _screen->hideMouse(); + snd_playSoundEffect(0x70); + uint32 nextTime = 0; + for (int i = 0; _amuleteAnim[i] != 0xFF; ++i) { + nextTime = _system->getMillis() + 5 * _tickLength; + + uint8 code = _amuleteAnim[i]; + if (code == 3 || code == 7) + snd_playSoundEffect(0x71); + + if (code == 5) + snd_playSoundEffect(0x72); + + if (code == 14) + snd_playSoundEffect(0x73); + + amulet.displayFrame(code); + _animator->_updateScreen = true; + + while (_system->getMillis() < nextTime) { + _sprites->updateSceneAnims(); + _animator->updateAllObjectShapes(); + if (nextTime - _system->getMillis() >= 10) + delay(10); + } + } + _screen->showMouse(); + } + setGameFlag(0x2D); + return 0; +} + +int KyraEngine_LoK::o1_drawItemShapeIntoScene(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_drawItemShapeIntoScene(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); + int item = stackPos(0); + int x = stackPos(1); + int y = stackPos(2); + int flags = stackPos(3); + int onlyHidPage = stackPos(4); + + if (flags) + flags = 1; + + if (onlyHidPage) { + _screen->drawShape(2, _shapes[216+item], x, y, 0, flags); + } else { + _screen->hideMouse(); + _animator->restoreAllObjectBackgrounds(); + _screen->drawShape(2, _shapes[216+item], x, y, 0, flags); + _screen->drawShape(0, _shapes[216+item], x, y, 0, flags); + _animator->flagAllObjectsForBkgdChange(); + _animator->preserveAnyChangedBackgrounds(); + _animator->flagAllObjectsForRefresh(); + _animator->updateAllObjectShapes(); + _screen->showMouse(); + } + return 0; +} + +int KyraEngine_LoK::o1_setCharacterCurrentFrame(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_setCharacterCurrentFrame(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + _characterList[stackPos(0)].currentAnimFrame = stackPos(1); + return 0; +} + +int KyraEngine_LoK::o1_waitForConfirmationMouseClick(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_waitForConfirmationMouseClick(%p) ()", (const void *)script); + // if (mouseEnabled) { + while (!_mousePressFlag) { + updateMousePointer(); + _sprites->updateSceneAnims(); + _animator->updateAllObjectShapes(); + delay(10); + } + + while (_mousePressFlag) { + updateMousePointer(); + _sprites->updateSceneAnims(); + _animator->updateAllObjectShapes(); + delay(10); + } + // } + _gui->processButtonList(_buttonList, 0, 0); + _skipFlag = false; + Common::Point mouse = getMousePos(); + script->regs[1] = mouse.x; + script->regs[2] = mouse.y; + return 0; +} + +int KyraEngine_LoK::o1_pageFlip(EMCState *script) { + warning("STUB: o1_pageFlip"); + return 0; +} + +int KyraEngine_LoK::o1_setSceneFile(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_setSceneFile(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + setSceneFile(stackPos(0), stackPos(1)); + return 0; +} + +int KyraEngine_LoK::o1_getItemInMarbleVase(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_getItemInMarbleVase(%p) ()", (const void *)script); + return _marbleVaseItem; +} + +int KyraEngine_LoK::o1_setItemInMarbleVase(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_setItemInMarbleVase(%p) (%d)", (const void *)script, stackPos(0)); + _marbleVaseItem = stackPos(0); + return 0; +} + +int KyraEngine_LoK::o1_addItemToInventory(EMCState *script) { + warning("STUB: o1_addItemToInventory"); + return 0; +} + +int KyraEngine_LoK::o1_intPrint(EMCState *script) { + warning("STUB: o1_intPrint"); + return 0; +} + +int KyraEngine_LoK::o1_shakeScreen(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_shakeScreen(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + int waitTicks = stackPos(1); + int times = stackPos(0); + + for (int i = 0; i < times; ++i) { + _screen->shakeScreen(1); + delay(waitTicks * _tickLength); + } + + return 0; +} + +int KyraEngine_LoK::o1_createAmuletJewel(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_createAmuletJewel(%p) (%d)", (const void *)script, stackPos(0)); + seq_createAmuletJewel(stackPos(0), 0, 0, 0); + return 0; +} + +int KyraEngine_LoK::o1_setSceneAnimCurrXY(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_setSceneAnimCurrXY(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); + _sprites->_anims[stackPos(0)].x = stackPos(1); + _sprites->_anims[stackPos(0)].y = stackPos(2); + return 0; +} + +int KyraEngine_LoK::o1_poisonBrandonAndRemaps(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_poisonBrandonAndRemaps(%p) ()", (const void *)script); + setBrandonPoisonFlags(1); + return 0; +} + +int KyraEngine_LoK::o1_fillFlaskWithWater(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_fillFlaskWithWater(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + seq_fillFlaskWithWater(stackPos(0), stackPos(1)); + return 0; +} + +int KyraEngine_LoK::o1_getCharacterMovementDelay(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_getCharacterMovementDelay(%p) (%d)", (const void *)script, stackPos(0)); + return _timer->getDelay(stackPos(0)+5); +} + +int KyraEngine_LoK::o1_getBirthstoneGem(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_getBirthstoneGem(%p) (%d)", (const void *)script, stackPos(0)); + if (stackPos(0) < 4) + return _birthstoneGemTable[stackPos(0)]; + return 0; +} + +int KyraEngine_LoK::o1_queryBrandonStatusBit(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_queryBrandonStatusBit(%p) (%d)", (const void *)script, stackPos(0)); + if (_brandonStatusBit & stackPos(0)) + return 1; + return 0; +} + +int KyraEngine_LoK::o1_playFluteAnimation(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_playFluteAnimation(%p) ()", (const void *)script); + seq_playFluteAnimation(); + return 0; +} + +int KyraEngine_LoK::o1_playWinterScrollSequence(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_playWinterScrollSequence(%p) (%d)", (const void *)script, stackPos(0)); + if (!stackPos(0)) + seq_winterScroll2(); + else + seq_winterScroll1(); + return 0; +} + +int KyraEngine_LoK::o1_getIdolGem(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_getIdolGem(%p) (%d)", (const void *)script, stackPos(0)); + return _idolGemsTable[stackPos(0)]; +} + +int KyraEngine_LoK::o1_setIdolGem(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_setIdolGem(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + _idolGemsTable[stackPos(0)] = stackPos(1); + return 0; +} + +int KyraEngine_LoK::o1_totalItemsInScene(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_totalItemsInScene(%p) (%d)", (const void *)script, stackPos(0)); + return countItemsInScene(stackPos(0)); +} + +int KyraEngine_LoK::o1_restoreBrandonsMovementDelay(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_restoreBrandonsMovementDelay(%p) ()", (const void *)script); + setWalkspeed(_configWalkspeed); + return 0; +} + +int KyraEngine_LoK::o1_setEntranceMouseCursorTrack(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_setEntranceMouseCursorTrack(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); + _entranceMouseCursorTracks[0] = stackPos(0); + _entranceMouseCursorTracks[1] = stackPos(1); + _entranceMouseCursorTracks[2] = stackPos(0) + stackPos(2) - 1; + _entranceMouseCursorTracks[3] = stackPos(1) + stackPos(3) - 1; + _entranceMouseCursorTracks[4] = stackPos(4); + return 0; +} + +int KyraEngine_LoK::o1_itemAppearsOnGround(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_itemAppearsOnGround(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); + processItemDrop(_currentCharacter->sceneId, stackPos(0), stackPos(1), stackPos(2), 2, 0); + return 0; +} + +int KyraEngine_LoK::o1_setNoDrawShapesFlag(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_setNoDrawShapesFlag(%p) (%d)", (const void *)script, stackPos(0)); + _animator->_noDrawShapesFlag = stackPos(0); + return 0; +} + +int KyraEngine_LoK::o1_fadeEntirePalette(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_fadeEntirePalette(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + int cmd = stackPos(0); + uint8 *fadePal = 0; + + if (_flags.platform == Common::kPlatformAmiga) { + if (cmd == 0) { + fadePal = _screen->getPalette(2); + memset(fadePal, 0, 32*3); + memcpy(_screen->getPalette(4), _screen->getPalette(0), 32*3); + } else if (cmd == 1) { + fadePal = _screen->getPalette(0); + memcpy(_screen->getPalette(0), _screen->getPalette(4), 32*3); + } else if (cmd == 2) { + fadePal = _screen->getPalette(0); + memset(_screen->getPalette(2), 0, 32*3); + } + } else { + if (cmd == 0) { + fadePal = _screen->getPalette(2); + uint8 *screenPal = _screen->getPalette(0); + uint8 *backUpPal = _screen->getPalette(3); + + memcpy(backUpPal, screenPal, sizeof(uint8)*768); + memset(fadePal, 0, sizeof(uint8)*768); + } else if (cmd == 1) { + //fadePal = _screen->getPalette(3); + warning("unimplemented o1_fadeEntirePalette function"); + return 0; + } else if (cmd == 2) { + memset(_screen->getPalette(2), 0, 768); + memcpy(_screen->getPalette(0), _screen->getPalette(1), 768); + fadePal = _screen->getPalette(0); + } + } + + _screen->fadePalette(fadePal, stackPos(1)); + return 0; +} + +int KyraEngine_LoK::o1_itemOnGroundHere(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_itemOnGroundHere(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + assert(stackPos(0) < _roomTableSize); + Room *curRoom = &_roomTable[stackPos(0)]; + for (int i = 0; i < 12; ++i) { + if (curRoom->itemsTable[i] == stackPos(1)) + return 1; + } + return 0; +} + +int KyraEngine_LoK::o1_queryCauldronState(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_queryCauldronState(%p) ()", (const void *)script); + return _cauldronState; +} + +int KyraEngine_LoK::o1_setCauldronState(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_setCauldronState(%p) (%d)", (const void *)script, stackPos(0)); + _cauldronState = stackPos(0); + return _cauldronState; +} + +int KyraEngine_LoK::o1_queryCrystalState(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_queryCrystalState(%p) (%d)", (const void *)script, stackPos(0)); + if (!stackPos(0)) + return _crystalState[0]; + else if (stackPos(0) == 1) + return _crystalState[1]; + return -1; +} + +int KyraEngine_LoK::o1_setCrystalState(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_setCrystalState(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + if (!stackPos(0)) + _crystalState[0] = stackPos(1); + else if (stackPos(0) == 1) + _crystalState[1] = stackPos(1); + return stackPos(1); +} + +int KyraEngine_LoK::o1_setPaletteRange(EMCState *script) { + warning("STUB: o1_setPaletteRange"); + return 0; +} + +int KyraEngine_LoK::o1_shrinkBrandonDown(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_shrinkBrandonDown(%p) (%d)", (const void *)script, stackPos(0)); + int delayTime = stackPos(0); + checkAmuletAnimFlags(); + int scaleValue = _scaleTable[_currentCharacter->y1]; + int scale = 0; + + if (_scaleMode) + scale = scaleValue; + else + scale = 256; + + int scaleModeBackUp = _scaleMode; + _scaleMode = 1; + int scaleEnd = scale >> 1; + for (; scaleEnd <= scale; --scale) { + _scaleTable[_currentCharacter->y1] = scale; + _animator->animRefreshNPC(0); + delayWithTicks(1); + } + delayWithTicks(delayTime); // XXX + _scaleTable[_currentCharacter->y1] = scaleValue; + _scaleMode = scaleModeBackUp; + return 0; +} + +int KyraEngine_LoK::o1_growBrandonUp(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_growBrandonUp(%p) ()", (const void *)script); + int scaleValue = _scaleTable[_currentCharacter->y1]; + int scale = 0; + if (_scaleMode) + scale = scaleValue; + else + scale = 256; + + int scaleModeBackUp = _scaleMode; + _scaleMode = 1; + for (int curScale = scale >> 1; curScale <= scale; ++curScale) { + _scaleTable[_currentCharacter->y1] = curScale; + _animator->animRefreshNPC(0); + delayWithTicks(1); + } + _scaleTable[_currentCharacter->y1] = scaleValue; + _scaleMode = scaleModeBackUp; + return 0; +} + +int KyraEngine_LoK::o1_setBrandonScaleXAndY(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_setBrandonScaleXAndY(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + _animator->_brandonScaleX = stackPos(0); + _animator->_brandonScaleY = stackPos(1); + return 0; +} + +int KyraEngine_LoK::o1_resetScaleMode(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_resetScaleMode(%p) ()", (const void *)script); + _scaleMode = 0; + return 0; +} + +int KyraEngine_LoK::o1_getScaleDepthTableValue(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_getScaleDepthTableValue(%p) (%d)", (const void *)script, stackPos(0)); + assert(stackPos(0) < ARRAYSIZE(_scaleTable)); + return _scaleTable[stackPos(0)]; +} + +int KyraEngine_LoK::o1_setScaleDepthTableValue(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_setScaleDepthTableValue(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + assert(stackPos(0) < ARRAYSIZE(_scaleTable)); + _scaleTable[stackPos(0)] = stackPos(1); + return stackPos(1); +} + +int KyraEngine_LoK::o1_message(EMCState *script) { + if (_flags.isTalkie) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_message(%p) (%d, '%s', %d)", (const void *)script, stackPos(0), stackPosString(1), stackPos(2)); + drawSentenceCommand(stackPosString(1), stackPos(2)); + } else { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_message(%p) ('%s', %d)", (const void *)script, stackPosString(0), stackPos(1)); + drawSentenceCommand(stackPosString(0), stackPos(1)); + } + + return 0; +} + +int KyraEngine_LoK::o1_checkClickOnNPC(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_checkClickOnNPC(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + return checkForNPCScriptRun(stackPos(0), stackPos(1)); +} + +int KyraEngine_LoK::o1_getFoyerItem(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_getFoyerItem(%p) (%d)", (const void *)script, stackPos(0)); + assert(stackPos(0) < ARRAYSIZE(_foyerItemTable)); + return _foyerItemTable[stackPos(0)]; +} + +int KyraEngine_LoK::o1_setFoyerItem(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_setFoyerItem(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + assert(stackPos(0) < ARRAYSIZE(_foyerItemTable)); + _foyerItemTable[stackPos(0)] = stackPos(1); + return stackPos(1); +} + +int KyraEngine_LoK::o1_setNoItemDropRegion(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_setNoItemDropRegion(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); + addToNoDropRects(stackPos(0), stackPos(1), stackPos(2), stackPos(3)); + return 0; +} + +int KyraEngine_LoK::o1_walkMalcolmOn(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_walkMalcolmOn(%p) ()", (const void *)script); + if (!_malcolmFlag) + _malcolmFlag = 1; + return 0; +} + +int KyraEngine_LoK::o1_passiveProtection(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_passiveProtection(%p) ()", (const void *)script); + return 1; +} + +int KyraEngine_LoK::o1_setPlayingLoop(EMCState *script) { + warning("STUB: o1_setPlayingLoop"); + return 0; +} + +int KyraEngine_LoK::o1_brandonToStoneSequence(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_brandonToStoneSequence(%p) ()", (const void *)script); + seq_brandonToStone(); + return 0; +} + +int KyraEngine_LoK::o1_brandonHealingSequence(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_brandonHealingSequence(%p) ()", (const void *)script); + seq_brandonHealing(); + return 0; +} + +int KyraEngine_LoK::o1_protectCommandLine(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_protectCommandLine(%p) (%d)", (const void *)script, stackPos(0)); + return stackPos(0); +} + +int KyraEngine_LoK::o1_pauseMusicSeconds(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_pauseMusicSeconds(%p) ()", (const void *)script); + // if music disabled + // return + delay(stackPos(0)*1000, true); + return 0; +} + +int KyraEngine_LoK::o1_resetMaskRegion(EMCState *script) { + warning("STUB: o1_resetMaskRegion"); + return 0; +} + +int KyraEngine_LoK::o1_setPaletteChangeFlag(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_setPaletteChangeFlag(%p) (%d)", (const void *)script, stackPos(0)); + _paletteChanged = stackPos(0); + return _paletteChanged; +} + +int KyraEngine_LoK::o1_vocUnload(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_vocUnload(%p) ()", (const void *)script); + // this should unload all voc files (not needed) + return 0; +} + +int KyraEngine_LoK::o1_vocLoad(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_vocLoad(%p) (%d)", (const void *)script, stackPos(0)); + // this should load the specified voc file (not needed) + return 0; +} + +int KyraEngine_LoK::o1_dummy(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_dummy(%p) ()", (const void *)script); + return 0; +} + +#pragma mark - + +typedef Common::Functor1Mem<EMCState*, int, KyraEngine_LoK> OpcodeV1; +#define SetOpcodeTable(x) table = &x; +#define Opcode(x) table->push_back(new OpcodeV1(this, &KyraEngine_LoK::x)) +void KyraEngine_LoK::setupOpcodeTable() { + Common::Array<const Opcode *> *table = 0; + + SetOpcodeTable(_opcodes); + // 0x00 + Opcode(o1_magicInMouseItem); + Opcode(o1_characterSays); + Opcode(o1_delay); + Opcode(o1_drawSceneAnimShape); + // 0x04 + Opcode(o1_queryGameFlag); + Opcode(o1_setGameFlag); + Opcode(o1_resetGameFlag); + Opcode(o1_runNPCScript); + // 0x08 + Opcode(o1_setSpecialExitList); + Opcode(o1_blockInWalkableRegion); + Opcode(o1_blockOutWalkableRegion); + Opcode(o1_walkPlayerToPoint); + // 0x0c + Opcode(o1_dropItemInScene); + Opcode(o1_drawAnimShapeIntoScene); + Opcode(o1_setHandItem); + Opcode(o1_savePageToDisk); + // 0x10 + Opcode(o1_sceneAnimOn); + Opcode(o1_sceneAnimOff); + Opcode(o1_getElapsedSeconds); + Opcode(o1_mouseIsPointer); + // 0x14 + Opcode(o1_removeHandItem); + Opcode(o1_runSceneAnimUntilDone); + Opcode(o1_fadeSpecialPalette); + Opcode(o1_playSoundEffect); + // 0x18 + Opcode(o1_playWanderScoreViaMap); + Opcode(o1_phaseInSameScene); + Opcode(o1_setScenePhasingFlag); + Opcode(o1_resetScenePhasingFlag); + // 0x1c + Opcode(o1_queryScenePhasingFlag); + Opcode(o1_sceneToDirection); + Opcode(o1_setBirthstoneGem); + Opcode(o1_placeItemInGenericMapScene); + // 0x20 + Opcode(o1_setBrandonStatusBit); + Opcode(o1_delaySecs); + Opcode(o1_getCharacterScene); + Opcode(o1_runNPCSubscript); + // 0x24 + Opcode(o1_magicOutMouseItem); + Opcode(o1_internalAnimOn); + Opcode(o1_forceBrandonToNormal); + Opcode(o1_poisonDeathNow); + // 0x28 + Opcode(o1_setScaleMode); + Opcode(o1_openWSAFile); + Opcode(o1_closeWSAFile); + Opcode(o1_runWSAFromBeginningToEnd); + // 0x2c + Opcode(o1_displayWSAFrame); + Opcode(o1_enterNewScene); + Opcode(o1_setSpecialEnterXAndY); + Opcode(o1_runWSAFrames); + // 0x30 + Opcode(o1_popBrandonIntoScene); + Opcode(o1_restoreAllObjectBackgrounds); + Opcode(o1_setCustomPaletteRange); + Opcode(o1_loadPageFromDisk); + // 0x34 + Opcode(o1_customPrintTalkString); + Opcode(o1_restoreCustomPrintBackground); + Opcode(o1_hideMouse); + Opcode(o1_showMouse); + // 0x38 + Opcode(o1_getCharacterX); + Opcode(o1_getCharacterY); + Opcode(o1_setCharacterFacing); + Opcode(o1_copyWSARegion); + // 0x3c + Opcode(o1_printText); + Opcode(o1_getRand); + Opcode(o1_loadSoundFile); + Opcode(o1_displayWSAFrameOnHidPage); + // 0x40 + Opcode(o1_displayWSASequentialFrames); + Opcode(o1_refreshCharacter); + Opcode(o1_internalAnimOff); + Opcode(o1_changeCharactersXAndY); + // 0x44 + Opcode(o1_clearSceneAnimatorBeacon); + Opcode(o1_querySceneAnimatorBeacon); + Opcode(o1_refreshSceneAnimator); + Opcode(o1_placeItemInOffScene); + // 0x48 + Opcode(o1_wipeDownMouseItem); + Opcode(o1_placeCharacterInOtherScene); + Opcode(o1_getKey); + Opcode(o1_specificItemInInventory); + // 0x4c + Opcode(o1_popMobileNPCIntoScene); + Opcode(o1_mobileCharacterInScene); + Opcode(o1_hideMobileCharacter); + Opcode(o1_unhideMobileCharacter); + // 0x50 + Opcode(o1_setCharacterLocation); + Opcode(o1_walkCharacterToPoint); + Opcode(o1_specialEventDisplayBrynnsNote); + Opcode(o1_specialEventRemoveBrynnsNote); + // 0x54 + Opcode(o1_setLogicPage); + Opcode(o1_fatPrint); + Opcode(o1_preserveAllObjectBackgrounds); + Opcode(o1_updateSceneAnimations); + // 0x58 + Opcode(o1_sceneAnimationActive); + Opcode(o1_setCharacterMovementDelay); + Opcode(o1_getCharacterFacing); + Opcode(o1_bkgdScrollSceneAndMasksRight); + // 0x5c + Opcode(o1_dispelMagicAnimation); + Opcode(o1_findBrightestFireberry); + Opcode(o1_setFireberryGlowPalette); + Opcode(o1_setDeathHandler); + // 0x60 + Opcode(o1_drinkPotionAnimation); + Opcode(o1_makeAmuletAppear); + Opcode(o1_drawItemShapeIntoScene); + Opcode(o1_setCharacterCurrentFrame); + // 0x64 + Opcode(o1_waitForConfirmationMouseClick); + Opcode(o1_pageFlip); + Opcode(o1_setSceneFile); + Opcode(o1_getItemInMarbleVase); + // 0x68 + Opcode(o1_setItemInMarbleVase); + Opcode(o1_addItemToInventory); + Opcode(o1_intPrint); + Opcode(o1_shakeScreen); + // 0x6c + Opcode(o1_createAmuletJewel); + Opcode(o1_setSceneAnimCurrXY); + Opcode(o1_poisonBrandonAndRemaps); + Opcode(o1_fillFlaskWithWater); + // 0x70 + Opcode(o1_getCharacterMovementDelay); + Opcode(o1_getBirthstoneGem); + Opcode(o1_queryBrandonStatusBit); + Opcode(o1_playFluteAnimation); + // 0x74 + Opcode(o1_playWinterScrollSequence); + Opcode(o1_getIdolGem); + Opcode(o1_setIdolGem); + Opcode(o1_totalItemsInScene); + // 0x78 + Opcode(o1_restoreBrandonsMovementDelay); + Opcode(o1_setMousePos); + Opcode(o1_getMouseState); + Opcode(o1_setEntranceMouseCursorTrack); + // 0x7c + Opcode(o1_itemAppearsOnGround); + Opcode(o1_setNoDrawShapesFlag); + Opcode(o1_fadeEntirePalette); + Opcode(o1_itemOnGroundHere); + // 0x80 + Opcode(o1_queryCauldronState); + Opcode(o1_setCauldronState); + Opcode(o1_queryCrystalState); + Opcode(o1_setCrystalState); + // 0x84 + Opcode(o1_setPaletteRange); + Opcode(o1_shrinkBrandonDown); + Opcode(o1_growBrandonUp); + Opcode(o1_setBrandonScaleXAndY); + // 0x88 + Opcode(o1_resetScaleMode); + Opcode(o1_getScaleDepthTableValue); + Opcode(o1_setScaleDepthTableValue); + Opcode(o1_message); + // 0x8c + Opcode(o1_checkClickOnNPC); + Opcode(o1_getFoyerItem); + Opcode(o1_setFoyerItem); + Opcode(o1_setNoItemDropRegion); + // 0x90 + Opcode(o1_walkMalcolmOn); + Opcode(o1_passiveProtection); + Opcode(o1_setPlayingLoop); + Opcode(o1_brandonToStoneSequence); + // 0x94 + Opcode(o1_brandonHealingSequence); + Opcode(o1_protectCommandLine); + Opcode(o1_pauseMusicSeconds); + Opcode(o1_resetMaskRegion); + // 0x98 + Opcode(o1_setPaletteChangeFlag); + Opcode(o1_fillRect); + Opcode(o1_vocUnload); + Opcode(o1_vocLoad); + // 0x9c + Opcode(o1_dummy); +} +#undef Opcode + +} // end of namespace Kyra + diff --git a/engines/kyra/script_mr.cpp b/engines/kyra/script_mr.cpp index 8746ec83d7..9a059ead2a 100644 --- a/engines/kyra/script_mr.cpp +++ b/engines/kyra/script_mr.cpp @@ -134,6 +134,12 @@ int KyraEngine_MR::o3_hideBadConscience(EMCState *script) { return 0; } +int KyraEngine_MR::o3_showAlbum(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_showAlbum(%p) ()", (const void *)script); + showAlbum(); + return 0; +} + int KyraEngine_MR::o3_setInventorySlot(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_setInventorySlot(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); const int slot = MAX<int16>(0, MIN<int16>(10, stackPos(0))); @@ -551,7 +557,7 @@ int KyraEngine_MR::o3_updateConversations(EMCState *script) { convs[0] = 0; convs[1] = 4; convs[2] = 0; - convs[4] = 1; + convs[3] = 1; break; case 10: @@ -588,6 +594,13 @@ int KyraEngine_MR::o3_updateConversations(EMCState *script) { return 1; } +int KyraEngine_MR::o3_removeItemSlot(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_removeItemSlot(%p) (%d)", (const void *)script, stackPos(0)); + deleteItemAnimEntry(stackPos(0)); + _itemList[stackPos(0)].id = 0xFFFF; + 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); @@ -798,8 +811,8 @@ int KyraEngine_MR::o3_daggerWarning(EMCState *script) { 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)); +int KyraEngine_MR::o3_blockOutWalkableRegion(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3_blockOutWalkableRegion(%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); @@ -1169,7 +1182,7 @@ void KyraEngine_MR::setupOpcodeTable() { Opcode(o3_hideBadConscience); // 0x18 OpcodeUnImpl(); - OpcodeUnImpl(); + Opcode(o3_showAlbum); Opcode(o3_setInventorySlot); Opcode(o3_getInventorySlot); // 0x1c @@ -1186,19 +1199,19 @@ void KyraEngine_MR::setupOpcodeTable() { Opcode(o3_removeInventoryItemInstances); Opcode(o3_countInventoryItemInstances); Opcode(o3_npcChatSequence); - Opcode(o2_queryGameFlag); + Opcode(o1_queryGameFlag); // 0x28 - Opcode(o2_resetGameFlag); - Opcode(o2_setGameFlag); - Opcode(o2_setHandItem); - Opcode(o2_removeHandItem); + Opcode(o1_resetGameFlag); + Opcode(o1_setGameFlag); + Opcode(o1_setHandItem); + Opcode(o1_removeHandItem); // 0x2c - Opcode(o2_handItemSet); - Opcode(o2_hideMouse); + Opcode(o1_getMouseState); + Opcode(o1_hideMouse); Opcode(o2_addSpecialExit); - Opcode(o2_setMousePos); + Opcode(o1_setMousePos); // 0x30 - Opcode(o2_showMouse); + Opcode(o1_showMouse); Opcode(o3_badConscienceChat); Opcode(o3_wipeDownMouseItem); Opcode(o3_dummy); @@ -1220,7 +1233,7 @@ void KyraEngine_MR::setupOpcodeTable() { // 0x40 Opcode(o3_checkInRect); Opcode(o3_updateConversations); - OpcodeUnImpl(); + Opcode(o3_removeItemSlot); Opcode(o3_dummy); // 0x44 Opcode(o3_dummy); @@ -1248,19 +1261,19 @@ void KyraEngine_MR::setupOpcodeTable() { Opcode(o3_setMalcolmPos); Opcode(o3_stopMusic); // 0x58 - Opcode(o2_playWanderScoreViaMap); + Opcode(o1_playWanderScoreViaMap); Opcode(o3_playSoundEffect); Opcode(o3_getScore); Opcode(o3_daggerWarning); // 0x5c - Opcode(o3_blockOutRegion); + Opcode(o3_blockOutWalkableRegion); Opcode(o3_dummy); Opcode(o3_showSceneStringsMessage); OpcodeUnImpl(); // 0x60 - Opcode(o2_getRand); + Opcode(o1_getRand); Opcode(o3_dummy); - Opcode(o2_setDeathHandler); + Opcode(o1_setDeathHandler); Opcode(o3_showGoodConscience); // 0x64 Opcode(o3_goodConscienceChat); @@ -1366,7 +1379,7 @@ void KyraEngine_MR::setupOpcodeTable() { Opcode(o3_dummy); // 0x0a Opcode(o2a_setResetFrame); - Opcode(o2_getRand); + Opcode(o1_getRand); Opcode(o3_getMalcolmShapes); Opcode(o3_dummy); @@ -1374,8 +1387,8 @@ void KyraEngine_MR::setupOpcodeTable() { // 0x00 Opcode(o3d_updateAnim); Opcode(o3d_delay); - Opcode(o2_getRand); - Opcode(o2_queryGameFlag); + Opcode(o1_getRand); + Opcode(o1_queryGameFlag); // 0x04 Opcode(o3_dummy); } diff --git a/engines/kyra/script_tim.cpp b/engines/kyra/script_tim.cpp index 67e076cbf8..4ad6464424 100644 --- a/engines/kyra/script_tim.cpp +++ b/engines/kyra/script_tim.cpp @@ -31,7 +31,7 @@ namespace Kyra { -TIMInterpreter::TIMInterpreter(KyraEngine *vm, OSystem *system) : _vm(vm), _system(system), _currentTim(0) { +TIMInterpreter::TIMInterpreter(KyraEngine_v1 *vm, OSystem *system) : _vm(vm), _system(system), _currentTim(0) { #define COMMAND(x) { &TIMInterpreter::x, #x } #define COMMAND_UNIMPL() { 0, 0 } static CommandEntry commandProcs[] = { @@ -118,7 +118,8 @@ TIM *TIMInterpreter::load(const char *filename, const Common::Array<const TIMOpc for (uint i = 0; i < avtlChunkSize; ++i) tim->avtl[i] = READ_LE_UINT16(tim->avtl + i); - for (int i = 0; i < 10; ++i) + int num = (avtlChunkSize < TIM::kCountFuncs) ? avtlChunkSize : (int)TIM::kCountFuncs; + for (int i = 0; i < num; ++i) tim->func[i].avtl = tim->avtl + tim->avtl[i]; return tim; @@ -128,8 +129,8 @@ void TIMInterpreter::unload(TIM *&tim) const { if (!tim) return; - delete [] tim->text; - delete [] tim->avtl; + delete[] tim->text; + delete[] tim->avtl; delete tim; tim = 0; } @@ -145,7 +146,7 @@ void TIMInterpreter::exec(TIM *tim, bool loop) { } do { - for (_currentFunc = 0; _currentFunc < 10; ++_currentFunc) { + for (_currentFunc = 0; _currentFunc < TIM::kCountFuncs; ++_currentFunc) { TIM::Function &cur = _currentTim->func[_currentFunc]; if (_currentTim->procFunc != -1) @@ -184,6 +185,18 @@ void TIMInterpreter::exec(TIM *tim, bool loop) { } while (loop); } +void TIMInterpreter::refreshTimersAfterPause(uint32 elapsedTime) { + if (!_currentTim) + return; + + for (int i = 0; i < TIM::kCountFuncs; i++) { + if (_currentTim->func[i].lastTime) + _currentTim->func[i].lastTime += elapsedTime; + if (_currentTim->func[i].nextTime) + _currentTim->func[i].nextTime += elapsedTime; + } +} + int TIMInterpreter::execCommand(int cmd, const uint16 *param) { if (cmd < 0 || cmd >= _commandsSize) { warning("Calling unimplemented TIM command %d", cmd); @@ -206,7 +219,7 @@ int TIMInterpreter::cmd_initFunc0(const uint16 *param) { } int TIMInterpreter::cmd_stopCurFunc(const uint16 *param) { - if (_currentFunc < 10) + if (_currentFunc < TIM::kCountFuncs) _currentTim->func[_currentFunc].ip = 0; if (!_currentFunc) _finished = true; @@ -215,7 +228,7 @@ int TIMInterpreter::cmd_stopCurFunc(const uint16 *param) { int TIMInterpreter::cmd_initFunc(const uint16 *param) { uint16 func = *param; - assert(func < 10); + assert(func < TIM::kCountFuncs); if (_currentTim->func[func].avtl) _currentTim->func[func].ip = _currentTim->func[func].avtl; else @@ -225,13 +238,13 @@ int TIMInterpreter::cmd_initFunc(const uint16 *param) { int TIMInterpreter::cmd_stopFunc(const uint16 *param) { uint16 func = *param; - assert(func < 10); + assert(func < TIM::kCountFuncs); _currentTim->func[func].ip = 0; return 1; } int TIMInterpreter::cmd_resetAllRuntimes(const uint16 *param) { - for (int i = 0; i < 10; ++i) { + for (int i = 0; i < TIM::kCountFuncs; ++i) { if (_currentTim->func[i].ip) _currentTim->func[i].nextTime = _system->getMillis(); } @@ -255,7 +268,7 @@ int TIMInterpreter::cmd_execOpcode(const uint16 *param) { int TIMInterpreter::cmd_initFuncNow(const uint16 *param) { uint16 func = *param; - assert(func < 10); + assert(func < TIM::kCountFuncs); _currentTim->func[func].ip = _currentTim->func[func].avtl; _currentTim->func[func].lastTime = _currentTim->func[func].nextTime = _system->getMillis(); return 1; @@ -263,7 +276,7 @@ int TIMInterpreter::cmd_initFuncNow(const uint16 *param) { int TIMInterpreter::cmd_stopFuncNow(const uint16 *param) { uint16 func = *param; - assert(func < 10); + assert(func < TIM::kCountFuncs); _currentTim->func[func].ip = 0; _currentTim->func[func].lastTime = _currentTim->func[func].nextTime = _system->getMillis(); return 1; diff --git a/engines/kyra/script_tim.h b/engines/kyra/script_tim.h index 2ffbf89d65..cd715ff4ef 100644 --- a/engines/kyra/script_tim.h +++ b/engines/kyra/script_tim.h @@ -26,7 +26,7 @@ #ifndef KYRA_SCRIPT_TIM_H #define KYRA_SCRIPT_TIM_H -#include "kyra/kyra.h" +#include "kyra/kyra_v1.h" #include "common/array.h" #include "common/func.h" @@ -40,6 +40,10 @@ struct TIM { int16 procFunc; uint16 procParam; + enum { + kCountFuncs = 10 + }; + struct Function { const uint16 *ip; @@ -47,7 +51,7 @@ struct TIM { uint32 nextTime; const uint16 *avtl; - } func[10]; + } func[kCountFuncs]; uint16 *avtl; uint8 *text; @@ -57,7 +61,7 @@ struct TIM { class TIMInterpreter { public: - TIMInterpreter(KyraEngine *vm, OSystem *system); + TIMInterpreter(KyraEngine_v1 *vm, OSystem *system); TIM *load(const char *filename, const Common::Array<const TIMOpcode*> *opcodes); void unload(TIM *&tim) const; @@ -69,8 +73,9 @@ public: void stopCurFunc() { if (_currentTim) cmd_stopCurFunc(0); } void play(const char *filename); + void refreshTimersAfterPause(uint32 elapsedTime); private: - KyraEngine *_vm; + KyraEngine_v1 *_vm; OSystem *_system; TIM *_currentTim; diff --git a/engines/kyra/script_v1.cpp b/engines/kyra/script_v1.cpp index a258482802..f74c7e3560 100644 --- a/engines/kyra/script_v1.cpp +++ b/engines/kyra/script_v1.cpp @@ -23,74 +23,10 @@ * */ - -#include "common/endian.h" -#include "common/system.h" - #include "kyra/kyra_v1.h" -#include "kyra/script.h" #include "kyra/screen.h" -#include "kyra/sprites.h" -#include "kyra/wsamovie.h" -#include "kyra/animator_v1.h" -#include "kyra/text.h" -#include "kyra/timer.h" namespace Kyra { -int KyraEngine_v1::o1_magicInMouseItem(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_magicInMouseItem(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - magicInMouseItem(stackPos(0), stackPos(1), -1); - return 0; -} - -int KyraEngine_v1::o1_characterSays(EMCState *script) { - _skipFlag = false; - if (_flags.isTalkie) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_characterSays(%p) (%d, '%s', %d, %d)", (const void *)script, stackPos(0), stackPosString(1), stackPos(2), stackPos(3)); - characterSays(stackPos(0), stackPosString(1), stackPos(2), stackPos(3)); - } else { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_characterSays(%p) ('%s', %d, %d)", (const void *)script, stackPosString(0), stackPos(1), stackPos(2)); - const char *string = stackPosString(0); - - if ((_flags.platform == Common::kPlatformFMTowns || _flags.platform == Common::kPlatformPC98) && _flags.lang == Common::JA_JPN) { - static const uint8 townsString1[] = { - 0x83, 0x75, 0x83, 0x89, 0x83, 0x93, 0x83, 0x83, 0x93, 0x81, - 0x41, 0x82, 0xDC, 0x82, 0xBD, 0x97, 0x88, 0x82, 0xBD, 0x82, - 0xCC, 0x82, 0xA9, 0x81, 0x48, 0x00, 0x00, 0x00 - }; - static const uint8 townsString2[] = { - 0x83, 0x75, 0x83, 0x89, 0x83, 0x93, 0x83, 0x5C, 0x83, 0x93, - 0x81, 0x41, 0x82, 0xDC, 0x82, 0xBD, 0x97, 0x88, 0x82, 0xBD, - 0x82, 0xCC, 0x82, 0xA9, 0x81, 0x48, 0x00, 0x00 - }; - - if (strncmp((const char *)townsString1, string, sizeof(townsString1)) == 0) - string = (const char *)townsString2; - } - - characterSays(-1, string, stackPos(1), stackPos(2)); - } - - return 0; -} - -int KyraEngine_v1::o1_pauseTicks(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_pauseTicks(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - if (stackPos(1)) { - warning("STUB: special o1_pauseTicks"); - // delete this after correct implementing - delayWithTicks(stackPos(0)); - } else { - delayWithTicks(stackPos(0)); - } - return 0; -} - -int KyraEngine_v1::o1_drawSceneAnimShape(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_drawSceneAnimShape(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); - _screen->drawShape(stackPos(4), _sprites->_sceneShapes[stackPos(0)], stackPos(1), stackPos(2), 0, (stackPos(3) != 0) ? 1 : 0); - return 0; -} int KyraEngine_v1::o1_queryGameFlag(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_queryGameFlag(%p) (0x%X)", (const void *)script, stackPos(0)); @@ -107,1408 +43,21 @@ int KyraEngine_v1::o1_resetGameFlag(EMCState *script) { return resetGameFlag(stackPos(0)); } -int KyraEngine_v1::o1_runNPCScript(EMCState *script) { - warning("STUB: o1_runNPCScript"); - return 0; -} - -int KyraEngine_v1::o1_setSpecialExitList(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setSpecialExitList(%p) (%d, %d, %d, %d, %d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7), stackPos(8), stackPos(9)); - - for (int i = 0; i < 10; ++i) - _exitList[i] = stackPos(i); - _exitListPtr = _exitList; - - return 0; -} - -int KyraEngine_v1::o1_blockInWalkableRegion(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_blockInWalkableRegion(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); - _screen->blockInRegion(stackPos(0), stackPos(1), stackPos(2)-stackPos(0)+1, stackPos(3)-stackPos(1)+1); - return 0; -} - -int KyraEngine_v1::o1_blockOutWalkableRegion(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_blockOutWalkableRegion(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); - _screen->blockOutRegion(stackPos(0), stackPos(1), stackPos(2)-stackPos(0)+1, stackPos(3)-stackPos(1)+1); - return 0; -} - -int KyraEngine_v1::o1_walkPlayerToPoint(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_walkPlayerToPoint(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); - - int normalTimers = stackPos(2); - if (!normalTimers) { - _timer->disable(19); - _timer->disable(14); - _timer->disable(18); - } - - int reinitScript = handleSceneChange(stackPos(0), stackPos(1), stackPos(2), stackPos(3)); - - if (!normalTimers) { - _timer->enable(19); - _timer->enable(14); - _timer->enable(18); - } - - if (reinitScript) - _emc->init(script, script->dataPtr); - - if (_sceneChangeState) { - _sceneChangeState = 0; - return 1; - } - return 0; -} - -int KyraEngine_v1::o1_dropItemInScene(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_dropItemInScene(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); - int item = stackPos(0); - int xpos = stackPos(1); - int ypos = stackPos(2); - - byte freeItem = findFreeItemInScene(_currentCharacter->sceneId); - if (freeItem != 0xFF) { - int sceneId = _currentCharacter->sceneId; - Room *room = &_roomTable[sceneId]; - room->itemsXPos[freeItem] = xpos; - room->itemsYPos[freeItem] = ypos; - room->itemsTable[freeItem] = item; - - _animator->animAddGameItem(freeItem, sceneId); - _animator->updateAllObjectShapes(); - } else { - if (item == 43) - placeItemInGenericMapScene(item, 0); - else - placeItemInGenericMapScene(item, 1); - } - return 0; -} - -int KyraEngine_v1::o1_drawAnimShapeIntoScene(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_drawAnimShapeIntoScene(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); - _screen->hideMouse(); - _animator->restoreAllObjectBackgrounds(); - int shape = stackPos(0); - int xpos = stackPos(1); - int ypos = stackPos(2); - int flags = (stackPos(3) != 0) ? 1 : 0; - _screen->drawShape(2, _sprites->_sceneShapes[shape], xpos, ypos, 0, flags); - _screen->drawShape(0, _sprites->_sceneShapes[shape], xpos, ypos, 0, flags); - _animator->flagAllObjectsForBkgdChange(); - _animator->preserveAnyChangedBackgrounds(); - _animator->flagAllObjectsForRefresh(); - _animator->updateAllObjectShapes(); - _screen->showMouse(); - return 0; -} - -int KyraEngine_v1::o1_createMouseItem(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_createMouseItem(%p) (%d)", (const void *)script, stackPos(0)); - createMouseItem(stackPos(0)); - return 0; -} - -int KyraEngine_v1::o1_savePageToDisk(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_savePageToDisk(%p) ('%s', %d)", (const void *)script, stackPosString(0), stackPos(1)); - _screen->savePageToDisk(stackPosString(0), stackPos(1)); - return 0; -} - -int KyraEngine_v1::o1_sceneAnimOn(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_sceneAnimOn(%p) (%d)", (const void *)script, stackPos(0)); - _sprites->_anims[stackPos(0)].play = true; - return 0; -} - -int KyraEngine_v1::o1_sceneAnimOff(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_sceneAnimOff(%p) (%d)", (const void *)script, stackPos(0)); - _sprites->_anims[stackPos(0)].play = false; - return 0; -} - -int KyraEngine_v1::o1_getElapsedSeconds(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_getElapsedSeconds(%p) ()", (const void *)script); - return _system->getMillis() / 1000; -} - -int KyraEngine_v1::o1_mouseIsPointer(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_mouseIsPointer(%p) ()", (const void *)script); - if (_itemInHand == -1) - return 1; - return 0; -} - -int KyraEngine_v1::o1_destroyMouseItem(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_destroyMouseItem(%p) ()", (const void *)script); - destroyMouseItem(); - return 0; -} - -int KyraEngine_v1::o1_runSceneAnimUntilDone(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_runSceneAnimUntilDone(%p) (%d)", (const void *)script, stackPos(0)); - _screen->hideMouse(); - _animator->restoreAllObjectBackgrounds(); - _sprites->_anims[stackPos(0)].play = true; - _animator->sprites()[stackPos(0)].active = 1; - _animator->flagAllObjectsForBkgdChange(); - _animator->preserveAnyChangedBackgrounds(); - while (_sprites->_anims[stackPos(0)].play) { - _sprites->updateSceneAnims(); - _animator->updateAllObjectShapes(); - delay(10); - } - _animator->restoreAllObjectBackgrounds(); - _screen->showMouse(); - return 0; -} - -int KyraEngine_v1::o1_fadeSpecialPalette(EMCState *script) { - if (_flags.platform == Common::kPlatformAmiga) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_fadeSpecialPalette(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); - if (_currentCharacter->sceneId != 45) { - if (stackPos(0) == 13) { - memcpy(_screen->getPalette(0), _screen->getPalette(0) + 384*3, 32*3); - _screen->setScreenPalette(_screen->getPalette(0)); - } - } else { - warning("KyraEngine_v1::o1_fadeSpecialPalette not implemented"); - } - } else { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_fadeSpecialPalette(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); - _screen->fadeSpecialPalette(stackPos(0), stackPos(1), stackPos(2), stackPos(3)); - } - return 0; -} - -int KyraEngine_v1::o1_playAdlibSound(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_playAdlibSound(%p) (%d)", (const void *)script, stackPos(0)); - snd_playSoundEffect(stackPos(0)); - return 0; -} - -int KyraEngine_v1::o1_playAdlibScore(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_playAdlibScore(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - snd_playWanderScoreViaMap(stackPos(0), stackPos(1)); - return 0; -} - -int KyraEngine_v1::o1_phaseInSameScene(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_phaseInSameScene(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - transcendScenes(stackPos(0), stackPos(1)); - return 0; -} - -int KyraEngine_v1::o1_setScenePhasingFlag(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setScenePhasingFlag(%p) ()", (const void *)script); - _scenePhasingFlag = 1; - return 1; -} - -int KyraEngine_v1::o1_resetScenePhasingFlag(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_resetScenePhasingFlag(%p) ()", (const void *)script); - _scenePhasingFlag = 0; - return 0; -} - -int KyraEngine_v1::o1_queryScenePhasingFlag(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_queryScenePhasingFlag(%p) ()", (const void *)script); - return _scenePhasingFlag; -} - -int KyraEngine_v1::o1_sceneToDirection(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_sceneToDirection(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - assert(stackPos(0) < _roomTableSize); - Room *curRoom = &_roomTable[stackPos(0)]; - uint16 returnValue = 0xFFFF; - switch (stackPos(1)) { - case 0: - returnValue = curRoom->northExit; - break; - - case 2: - returnValue = curRoom->eastExit; - break; - - case 4: - returnValue = curRoom->southExit; - break; - - case 6: - returnValue = curRoom->westExit; - break; - - default: - break; - } - if (returnValue == 0xFFFF) - return -1; - return returnValue; -} - -int KyraEngine_v1::o1_setBirthstoneGem(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setBirthstoneGem(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - int index = stackPos(0); - if (index < 4 && index >= 0) { - _birthstoneGemTable[index] = stackPos(1); - return 1; - } - return 0; -} - -int KyraEngine_v1::o1_placeItemInGenericMapScene(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_placeItemInGenericMapScene(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - placeItemInGenericMapScene(stackPos(0), stackPos(1)); - return 0; -} - -int KyraEngine_v1::o1_setBrandonStatusBit(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setBrandonStatusBit(%p) (%d)", (const void *)script, stackPos(0)); - _brandonStatusBit |= stackPos(0); - return 0; -} - -int KyraEngine_v1::o1_pauseSeconds(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_pauseSeconds(%p) (%d)", (const void *)script, stackPos(0)); - if (stackPos(0) > 0 && !_skipFlag) - delay(stackPos(0)*1000, true); - _skipFlag = false; - return 0; -} - -int KyraEngine_v1::o1_getCharactersLocation(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_getCharactersLocation(%p) (%d)", (const void *)script, stackPos(0)); - return _characterList[stackPos(0)].sceneId; -} - -int KyraEngine_v1::o1_runNPCSubscript(EMCState *script) { - warning("STUB: o1_runNPCSubscript"); - return 0; -} - -int KyraEngine_v1::o1_magicOutMouseItem(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_magicOutMouseItem(%p) (%d)", (const void *)script, stackPos(0)); - magicOutMouseItem(stackPos(0), -1); - return 0; -} - -int KyraEngine_v1::o1_internalAnimOn(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_internalAnimOn(%p) (%d)", (const void *)script, stackPos(0)); - _animator->sprites()[stackPos(0)].active = 1; - return 0; -} - -int KyraEngine_v1::o1_forceBrandonToNormal(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_forceBrandonToNormal(%p) ()", (const void *)script); - checkAmuletAnimFlags(); - return 0; -} - -int KyraEngine_v1::o1_poisonDeathNow(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_poisonDeathNow(%p) ()", (const void *)script); - seq_poisonDeathNow(1); - return 0; -} - -int KyraEngine_v1::o1_setScaleMode(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setScaleMode(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); - int len = stackPos(0); - int setValue1 = stackPos(1); - int start2 = stackPos(2); - int setValue2 = stackPos(3); - for (int i = 0; i < len; ++i) - _scaleTable[i] = setValue1; - int temp = setValue2 - setValue1; - int temp2 = start2 - len; - for (int i = len, offset = 0; i < start2; ++i, ++offset) - _scaleTable[i] = (offset * temp) / temp2 + setValue1; - for (int i = start2; i < 145; ++i) - _scaleTable[i] = setValue2; - _scaleMode = 1; - return _scaleMode; -} - -int KyraEngine_v1::o1_openWSAFile(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_openWSAFile(%p) ('%s', %d, %d, %d)", (const void *)script, stackPosString(0), stackPos(1), stackPos(2), stackPos(3)); - - const char *filename = stackPosString(0); - int wsaIndex = stackPos(1); - - _movieObjects[wsaIndex]->open(filename, (stackPos(3) != 0) ? 1 : 0, 0); - assert(_movieObjects[wsaIndex]->opened()); - - return 0; -} - -int KyraEngine_v1::o1_closeWSAFile(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_closeWSAFile(%p) (%d)", (const void *)script, stackPos(0)); - - int wsaIndex = stackPos(0); - if (_movieObjects[wsaIndex]) - _movieObjects[wsaIndex]->close(); - - return 0; -} - -int KyraEngine_v1::o1_runWSAFromBeginningToEnd(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_runWSAFromBeginningToEnd(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); - - _screen->hideMouse(); - - bool running = true; - - int xpos = stackPos(0); - int ypos = stackPos(1); - int waitTime = stackPos(2); - int wsaIndex = stackPos(3); - int worldUpdate = stackPos(4); - int wsaFrame = 0; - - _movieObjects[wsaIndex]->setX(xpos); - _movieObjects[wsaIndex]->setY(ypos); - _movieObjects[wsaIndex]->setDrawPage(0); - while (running) { - _movieObjects[wsaIndex]->displayFrame(wsaFrame++); - _animator->_updateScreen = true; - if (wsaFrame >= _movieObjects[wsaIndex]->frames()) - running = false; - - uint32 continueTime = waitTime * _tickLength + _system->getMillis(); - while (_system->getMillis() < continueTime) { - if (worldUpdate) { - _sprites->updateSceneAnims(); - _animator->updateAllObjectShapes(); - } else { - _screen->updateScreen(); - } - if (continueTime - _system->getMillis() >= 10) - delay(10); - } - } - - _screen->showMouse(); - - return 0; -} - -int KyraEngine_v1::o1_displayWSAFrame(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_displayWSAFrame(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); - int frame = stackPos(0); - int xpos = stackPos(1); - int ypos = stackPos(2); - int waitTime = stackPos(3); - int wsaIndex = stackPos(4); - _screen->hideMouse(); - _movieObjects[wsaIndex]->setX(xpos); - _movieObjects[wsaIndex]->setY(ypos); - _movieObjects[wsaIndex]->setDrawPage(0); - _movieObjects[wsaIndex]->displayFrame(frame); - _animator->_updateScreen = true; - uint32 continueTime = waitTime * _tickLength + _system->getMillis(); - while (_system->getMillis() < continueTime) { - _sprites->updateSceneAnims(); - _animator->updateAllObjectShapes(); - if (_skipFlag) - break; - - if (continueTime - _system->getMillis() >= 10) - delay(10); - } - _screen->showMouse(); - return 0; -} - -int KyraEngine_v1::o1_enterNewScene(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_enterNewScene(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); - enterNewScene(stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); - return 0; -} - -int KyraEngine_v1::o1_setSpecialEnterXAndY(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setSpecialEnterXAndY(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - _brandonPosX = stackPos(0); - _brandonPosY = stackPos(1); - if (_brandonPosX + 1 == 0 && _brandonPosY + 1 == 0) - _currentCharacter->currentAnimFrame = 88; - return 0; -} - -int KyraEngine_v1::o1_runWSAFrames(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_runWSAFrames(%p) (%d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5)); - int xpos = stackPos(0); - int ypos = stackPos(1); - int delayTime = stackPos(2); - int startFrame = stackPos(3); - int endFrame = stackPos(4); - int wsaIndex = stackPos(5); - _screen->hideMouse(); - _movieObjects[wsaIndex]->setX(xpos); - _movieObjects[wsaIndex]->setY(ypos); - _movieObjects[wsaIndex]->setDrawPage(0); - for (; startFrame <= endFrame; ++startFrame) { - uint32 nextRun = _system->getMillis() + delayTime * _tickLength; - _movieObjects[wsaIndex]->displayFrame(startFrame); - _animator->_updateScreen = true; - while (_system->getMillis() < nextRun) { - _sprites->updateSceneAnims(); - _animator->updateAllObjectShapes(); - if (nextRun - _system->getMillis() >= 10) - delay(10); - } - } - _screen->showMouse(); - return 0; -} - -int KyraEngine_v1::o1_popBrandonIntoScene(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_popBrandonIntoScene(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); - int changeScaleMode = stackPos(3); - int xpos = (int16)(stackPos(0) & 0xFFFC); - int ypos = (int16)(stackPos(1) & 0xFFFE); - int facing = stackPos(2); - _currentCharacter->x1 = _currentCharacter->x2 = xpos; - _currentCharacter->y1 = _currentCharacter->y2 = ypos; - _currentCharacter->facing = facing; - _currentCharacter->currentAnimFrame = 7; - int xOffset = _defaultShapeTable[0].xOffset; - int yOffset = _defaultShapeTable[0].yOffset; - int width = _defaultShapeTable[0].w << 3; - int height = _defaultShapeTable[0].h; - Animator_v1::AnimObject *curAnim = _animator->actors(); - - if (changeScaleMode) { - curAnim->x1 = _currentCharacter->x1; - curAnim->y1 = _currentCharacter->y1; - _animator->_brandonScaleY = _scaleTable[_currentCharacter->y1]; - _animator->_brandonScaleX = _animator->_brandonScaleY; - - int animWidth = _animator->fetchAnimWidth(curAnim->sceneAnimPtr, _animator->_brandonScaleX) >> 1; - int animHeight = _animator->fetchAnimHeight(curAnim->sceneAnimPtr, _animator->_brandonScaleY); - - animWidth = (xOffset * animWidth) / width; - animHeight = (yOffset * animHeight) / height; - - curAnim->x2 = curAnim->x1 += animWidth; - curAnim->y2 = curAnim->y1 += animHeight; - } else { - curAnim->x2 = curAnim->x1 = _currentCharacter->x1 + xOffset; - curAnim->y2 = curAnim->y1 = _currentCharacter->y1 + yOffset; - } - - int scaleModeBackup = _scaleMode; - if (changeScaleMode) - _scaleMode = 1; - - _animator->animRefreshNPC(0); - _animator->preserveAllBackgrounds(); - _animator->prepDrawAllObjects(); - _animator->copyChangedObjectsForward(0); - - _scaleMode = scaleModeBackup; - - return 0; -} - -int KyraEngine_v1::o1_restoreAllObjectBackgrounds(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_restoreAllObjectBackgrounds(%p) (%d)", (const void *)script, stackPos(0)); - int disable = stackPos(0); - int activeBackup = 0; - if (disable) { - activeBackup = _animator->actors()->active; - _animator->actors()->active = 0; - } - _animator->restoreAllObjectBackgrounds(); - if (disable) - _animator->actors()->active = activeBackup; - return 0; -} - -int KyraEngine_v1::o1_setCustomPaletteRange(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setCustomPaletteRange(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); - memcpy(_screen->getPalette(1) + stackPos(1)*3, _specialPalettes[stackPos(0)], stackPos(2)*3); - return 0; -} - -int KyraEngine_v1::o1_loadPageFromDisk(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_loadPageFromDisk(%p) ('%s', %d)", (const void *)script, stackPosString(0), stackPos(1)); - _screen->loadPageFromDisk(stackPosString(0), stackPos(1)); - _animator->_updateScreen = true; - return 0; -} - -int KyraEngine_v1::o1_customPrintTalkString(EMCState *script) { - if (_flags.isTalkie) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_customPrintTalkString(%p) (%d, '%s', %d, %d, %d)", (const void *)script, stackPos(0), stackPosString(1), stackPos(2), stackPos(3), stackPos(4) & 0xFF); - - if (speechEnabled()) { - snd_voiceWaitForFinish(); - snd_playVoiceFile(stackPos(0)); - } - - _skipFlag = false; - if (textEnabled()) - _text->printTalkTextMessage(stackPosString(1), stackPos(2), stackPos(3), stackPos(4) & 0xFF, 0, 2); - } else { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_customPrintTalkString(%p) ('%s', %d, %d, %d)", (const void *)script, stackPosString(0), stackPos(1), stackPos(2), stackPos(3) & 0xFF); - _skipFlag = false; - _text->printTalkTextMessage(stackPosString(0), stackPos(1), stackPos(2), stackPos(3) & 0xFF, 0, 2); - } - _screen->updateScreen(); - return 0; -} - -int KyraEngine_v1::o1_restoreCustomPrintBackground(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_restoreCustomPrintBackground(%p) ()", (const void *)script); - _text->restoreTalkTextMessageBkgd(2, 0); - return 0; +int KyraEngine_v1::o1_getRand(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_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_v1::o1_hideMouse(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_hideMouse(%p) ()", (const void *)script); - _screen->hideMouse(); + screen()->hideMouse(); return 0; } int KyraEngine_v1::o1_showMouse(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_showMouse(%p) ()", (const void *)script); - _screen->showMouse(); - return 0; -} - -int KyraEngine_v1::o1_getCharacterX(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_getCharacterX(%p) (%d)", (const void *)script, stackPos(0)); - return _characterList[stackPos(0)].x1; -} - -int KyraEngine_v1::o1_getCharacterY(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_getCharacterY(%p) (%d)", (const void *)script, stackPos(0)); - return _characterList[stackPos(0)].y1; -} - -int KyraEngine_v1::o1_changeCharactersFacing(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_changeCharactersFacing(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); - int character = stackPos(0); - int facing = stackPos(1); - int newAnimFrame = stackPos(2); - - _animator->restoreAllObjectBackgrounds(); - if (newAnimFrame != -1) - _characterList[character].currentAnimFrame = newAnimFrame; - _characterList[character].facing = facing; - _animator->animRefreshNPC(character); - _animator->preserveAllBackgrounds(); - _animator->prepDrawAllObjects(); - _animator->copyChangedObjectsForward(0); - - return 0; -} - -int KyraEngine_v1::o1_copyWSARegion(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_copyWSARegion(%p) (%d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5)); - int xpos = stackPos(0); - int ypos = stackPos(1); - int width = stackPos(2); - int height = stackPos(3); - int srcPage = stackPos(4); - int dstPage = stackPos(5); - _screen->copyRegion(xpos, ypos, xpos, ypos, width, height, srcPage, dstPage); - _animator->_updateScreen = true; - return 0; -} - -int KyraEngine_v1::o1_printText(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_printText(%p) ('%s', %d, %d, 0x%X, 0x%X)", (const void *)script, stackPosString(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); - if (_flags.lang == Common::JA_JPN && stackPos(3) == 7) - _screen->printText(stackPosString(0), stackPos(1), stackPos(2), 0, 0x80); - else - _screen->printText(stackPosString(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); - _screen->updateScreen(); - return 0; -} - -int KyraEngine_v1::o1_random(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_random(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - assert(stackPos(0) < stackPos(1)); - return _rnd.getRandomNumberRng(stackPos(0), stackPos(1)); -} - -int KyraEngine_v1::o1_loadSoundFile(EMCState *script) { - warning("STUB: o1_loadSoundFile"); - return 0; -} - -int KyraEngine_v1::o1_displayWSAFrameOnHidPage(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_displayWSAFrameOnHidPage(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); - int frame = stackPos(0); - int xpos = stackPos(1); - int ypos = stackPos(2); - int waitTime = stackPos(3); - int wsaIndex = stackPos(4); - - _screen->hideMouse(); - uint32 continueTime = waitTime * _tickLength + _system->getMillis(); - _movieObjects[wsaIndex]->setX(xpos); - _movieObjects[wsaIndex]->setY(ypos); - _movieObjects[wsaIndex]->setDrawPage(2); - _movieObjects[wsaIndex]->displayFrame(frame); - _animator->_updateScreen = true; - while (_system->getMillis() < continueTime) { - _sprites->updateSceneAnims(); - _animator->updateAllObjectShapes(); - if (_skipFlag) - break; - - if (continueTime - _system->getMillis() >= 10) - delay(10); - } - _screen->showMouse(); - - return 0; -} - -int KyraEngine_v1::o1_displayWSASequentialFrames(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_displayWSASequentialFrames(%p) (%d, %d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6)); - int startFrame = stackPos(0); - int endFrame = stackPos(1); - int xpos = stackPos(2); - int ypos = stackPos(3); - int waitTime = stackPos(4); - int wsaIndex = stackPos(5); - int maxTime = stackPos(6); - if (maxTime - 1 <= 0) - maxTime = 1; - - _movieObjects[wsaIndex]->setX(xpos); - _movieObjects[wsaIndex]->setY(ypos); - _movieObjects[wsaIndex]->setDrawPage(0); - - // Workaround for bug #1498221 "KYRA1: Glitches when meeting Zanthia" - // the original didn't do a forced screen update after displaying a wsa frame - // while we have to do it, which make brandon disappear for a short moment, - // what shouldn't happen. So we're not updating the screen for this special - // case too. - if (startFrame == 18 && endFrame == 18 && _currentRoom == 45) { - _movieObjects[wsaIndex]->displayFrame(18); - delay(waitTime * _tickLength); - return 0; - } - - int curTime = 0; - _screen->hideMouse(); - while (curTime < maxTime) { - if (endFrame >= startFrame) { - int frame = startFrame; - while (endFrame >= frame) { - uint32 continueTime = waitTime * _tickLength + _system->getMillis(); - _movieObjects[wsaIndex]->displayFrame(frame); - _animator->_updateScreen = true; - while (_system->getMillis() < continueTime) { - _sprites->updateSceneAnims(); - _animator->updateAllObjectShapes(); - if (_skipFlag) - break; - - if (continueTime - _system->getMillis() >= 10) - delay(10); - } - ++frame; - } - } else { - int frame = startFrame; - while (endFrame <= frame) { - uint32 continueTime = waitTime * _tickLength + _system->getMillis(); - _movieObjects[wsaIndex]->displayFrame(frame); - _animator->_updateScreen = true; - while (_system->getMillis() < continueTime) { - _sprites->updateSceneAnims(); - _animator->updateAllObjectShapes(); - if (_skipFlag) - break; - - if (continueTime - _system->getMillis() >= 10) - delay(10); - } - --frame; - } - } - - if (_skipFlag) - break; - else - ++curTime; - } - _screen->showMouse(); - - return 0; -} - -int KyraEngine_v1::o1_drawCharacterStanding(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_drawCharacterStanding(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); - int character = stackPos(0); - int animFrame = stackPos(1); - int newFacing = stackPos(2); - int updateShapes = stackPos(3); - _characterList[character].currentAnimFrame = animFrame; - if (newFacing != -1) - _characterList[character].facing = newFacing; - _animator->animRefreshNPC(character); - if (updateShapes) - _animator->updateAllObjectShapes(); - return 0; -} - -int KyraEngine_v1::o1_internalAnimOff(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_internalAnimOff(%p) (%d)", (const void *)script, stackPos(0)); - _animator->sprites()[stackPos(0)].active = 0; - return 0; -} - -int KyraEngine_v1::o1_changeCharactersXAndY(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_changeCharactersXAndY(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); - Character *ch = &_characterList[stackPos(0)]; - int16 x = stackPos(1); - int16 y = stackPos(2); - if (x != -1 && y != -1) { - x &= 0xFFFC; - y &= 0xFFFE; - } - _animator->restoreAllObjectBackgrounds(); - ch->x1 = ch->x2 = x; - ch->y1 = ch->y2 = y; - _animator->preserveAllBackgrounds(); - return 0; -} - -int KyraEngine_v1::o1_clearSceneAnimatorBeacon(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_clearSceneAnimatorBeacon(%p) ()", (const void *)script); - _sprites->_sceneAnimatorBeaconFlag = 0; - return 0; -} - -int KyraEngine_v1::o1_querySceneAnimatorBeacon(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_querySceneAnimatorBeacon(%p) ()", (const void *)script); - return _sprites->_sceneAnimatorBeaconFlag; -} - -int KyraEngine_v1::o1_refreshSceneAnimator(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_refreshSceneAnimator(%p) ()", (const void *)script); - _sprites->updateSceneAnims(); - _animator->updateAllObjectShapes(); - return 0; -} - -int KyraEngine_v1::o1_placeItemInOffScene(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_placeItemInOffScene(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); - int item = stackPos(0); - int xpos = stackPos(1); - int ypos = stackPos(2); - int sceneId = stackPos(3); - - byte freeItem = findFreeItemInScene(sceneId); - if (freeItem != 0xFF) { - assert(sceneId < _roomTableSize); - Room *room = &_roomTable[sceneId]; - - room->itemsTable[freeItem] = item; - room->itemsXPos[freeItem] = xpos; - room->itemsYPos[freeItem] = ypos; - } - return 0; -} - -int KyraEngine_v1::o1_wipeDownMouseItem(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_wipeDownMouseItem(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); - _screen->hideMouse(); - wipeDownMouseItem(stackPos(1), stackPos(2)); - destroyMouseItem(); - _screen->showMouse(); - return 0; -} - -int KyraEngine_v1::o1_placeCharacterInOtherScene(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_placeCharacterInOtherScene(%p) (%d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5)); - int id = stackPos(0); - int sceneId = stackPos(1); - int xpos = (int16)(stackPos(2) & 0xFFFC); - int ypos = (int16)(stackPos(3) & 0xFFFE); - int facing = stackPos(4); - int animFrame = stackPos(5); - - _characterList[id].sceneId = sceneId; - _characterList[id].x1 = _characterList[id].x2 = xpos; - _characterList[id].y1 = _characterList[id].y2 = ypos; - _characterList[id].facing = facing; - _characterList[id].currentAnimFrame = animFrame; - return 0; -} - -int KyraEngine_v1::o1_getKey(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_getKey(%p) ()", (const void *)script); - waitForEvent(); - return 0; -} - -int KyraEngine_v1::o1_specificItemInInventory(EMCState *script) { - warning("STUB: o1_specificItemInInventory"); - return 0; -} - -int KyraEngine_v1::o1_popMobileNPCIntoScene(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_popMobileNPCIntoScene(%p) (%d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), (int16)(stackPos(4) & 0xFFFC), (int8)(stackPos(5) & 0xFE)); - int character = stackPos(0); - int sceneId = stackPos(1); - int animFrame = stackPos(2); - int facing = stackPos(3); - int16 xpos = (int16)(stackPos(4) & 0xFFFC); - int8 ypos = (int16)(stackPos(5) & 0xFFFE); - Character *curChar = &_characterList[character]; - - curChar->sceneId = sceneId; - curChar->currentAnimFrame = animFrame; - curChar->facing = facing; - curChar->x1 = curChar->x2 = xpos; - curChar->y1 = curChar->y2 = ypos; - - _animator->animAddNPC(character); - _animator->updateAllObjectShapes(); - return 0; -} - -int KyraEngine_v1::o1_mobileCharacterInScene(EMCState *script) { - warning("STUB: o1_mobileCharacterInScene"); - return 0; -} - -int KyraEngine_v1::o1_hideMobileCharacter(EMCState *script) { - warning("STUB: o1_hideMobileCharacter"); - return 0; -} - -int KyraEngine_v1::o1_unhideMobileCharacter(EMCState *script) { - warning("STUB: o1_unhideMobileCharacter"); - return 0; -} - -int KyraEngine_v1::o1_setCharactersLocation(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setCharactersLocation(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - Character *ch = &_characterList[stackPos(0)]; - Animator_v1::AnimObject *animObj = &_animator->actors()[stackPos(0)]; - int newScene = stackPos(1); - if (_currentCharacter->sceneId == ch->sceneId) { - if (_currentCharacter->sceneId != newScene) - animObj->active = 0; - } else if (_currentCharacter->sceneId == newScene) { - if (_currentCharacter->sceneId != ch->sceneId) - animObj->active = 1; - } - - ch->sceneId = stackPos(1); - return 0; -} - -int KyraEngine_v1::o1_walkCharacterToPoint(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_walkCharacterToPoint(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); - int character = stackPos(0); - int toX = stackPos(1); - int toY = stackPos(2); - _pathfinderFlag2 = 1; - uint32 nextFrame; - int findWayReturn = findWay(_characterList[character].x1, _characterList[character].y1, toX, toY, _movFacingTable, 150); - _pathfinderFlag2 = 0; - - if (_lastFindWayRet < findWayReturn) - _lastFindWayRet = findWayReturn; - if (findWayReturn == 0x7D00 || findWayReturn == 0) - return 0; - - int *curPos = _movFacingTable; - bool running = true; - while (running) { - bool forceContinue = false; - switch (*curPos) { - case 0: - _characterList[character].facing = 2; - break; - - case 1: - _characterList[character].facing = 1; - break; - - case 2: - _characterList[character].facing = 0; - break; - - case 3: - _characterList[character].facing = 7; - break; - - case 4: - _characterList[character].facing = 6; - break; - - case 5: - _characterList[character].facing = 5; - break; - - case 6: - _characterList[character].facing = 4; - break; - - case 7: - _characterList[character].facing = 3; - break; - - case 8: - running = 0; - break; - - default: - ++curPos; - forceContinue = true; - break; - } - - if (forceContinue || !running) - continue; - - setCharacterPosition(character, 0); - ++curPos; - - nextFrame = _timer->getDelay(5 + character) * _tickLength + _system->getMillis(); - while (_system->getMillis() < nextFrame) { - _sprites->updateSceneAnims(); - updateMousePointer(); - _timer->update(); - _animator->updateAllObjectShapes(); - updateTextFade(); - if ((nextFrame - _system->getMillis()) >= 10) - delay(10); - } - } - return 0; -} - -int KyraEngine_v1::o1_specialEventDisplayBrynnsNote(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_specialEventDisplayBrynnsNote(%p) ()", (const void *)script); - _screen->hideMouse(); - _screen->savePageToDisk("HIDPAGE.TMP", 2); - _screen->savePageToDisk("SEENPAGE.TMP", 0); - if (_flags.isTalkie) { - if (_flags.lang == Common::EN_ANY || _flags.lang == Common::IT_ITA) - _screen->loadBitmap("NOTEENG.CPS", 3, 3, 0); - else if (_flags.lang == Common::FR_FRA) - _screen->loadBitmap("NOTEFRE.CPS", 3, 3, 0); - else if (_flags.lang == Common::DE_DEU) - _screen->loadBitmap("NOTEGER.CPS", 3, 3, 0); - } else { - _screen->loadBitmap("NOTE.CPS", 3, 3, 0); - } - _screen->copyRegion(63, 8, 63, 8, 194, 128, 2, 0); - _screen->updateScreen(); - _screen->showMouse(); - _screen->setFont(Screen::FID_6_FNT); - return 0; -} - -int KyraEngine_v1::o1_specialEventRemoveBrynnsNote(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_specialEventRemoveBrynnsNote(%p) ()", (const void *)script); - _screen->hideMouse(); - _screen->loadPageFromDisk("SEENPAGE.TMP", 0); - _screen->loadPageFromDisk("HIDPAGE.TMP", 2); - _screen->updateScreen(); - _screen->showMouse(); - _screen->setFont(Screen::FID_8_FNT); - return 0; -} - -int KyraEngine_v1::o1_setLogicPage(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setLogicPage(%p) (%d)", (const void *)script, stackPos(0)); - _screen->_curPage = stackPos(0); - return stackPos(0); -} - -int KyraEngine_v1::o1_fatPrint(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_fatPrint(%p) ('%s', %d, %d, %d, %d, %d)", (const void *)script, stackPosString(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5)); - - // Workaround for bug #1582672 ("KYRA1: Text crippled and drawn wrong") - // I'm not sure how the original handles this, since it seems to call - // printText also, maybe it fails somewhere inside... - // TODO: fix the reason for this workaround - if (_currentRoom == 117) - return 0; - _text->printText(stackPosString(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5)); - return 0; -} - -int KyraEngine_v1::o1_preserveAllObjectBackgrounds(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_preserveAllObjectBackgrounds(%p) ()", (const void *)script); - _animator->preserveAllBackgrounds(); - return 0; -} - -int KyraEngine_v1::o1_updateSceneAnimations(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_updateSceneAnimations(%p) (%d)", (const void *)script, stackPos(0)); - int times = stackPos(0); - while (times--) { - _sprites->updateSceneAnims(); - _animator->updateAllObjectShapes(); - } - return 0; -} - -int KyraEngine_v1::o1_sceneAnimationActive(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_sceneAnimationActive(%p) (%d)", (const void *)script, stackPos(0)); - return _sprites->_anims[stackPos(0)].play; -} - -int KyraEngine_v1::o1_setCharactersMovementDelay(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setCharactersMovementDelay(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - _timer->setDelay(stackPos(0)+5, stackPos(1)); - return 0; -} - -int KyraEngine_v1::o1_getCharactersFacing(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_getCharactersFacing(%p) (%d)", (const void *)script, stackPos(0)); - return _characterList[stackPos(0)].facing; -} - -int KyraEngine_v1::o1_bkgdScrollSceneAndMasksRight(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_bkgdScrollSceneAndMasksRight(%p) (%d)", (const void *)script, stackPos(0)); - _screen->copyBackgroundBlock(stackPos(0), 2, 0); - _screen->copyBackgroundBlock2(stackPos(0)); - // update the whole screen - _screen->copyRegion(7, 7, 7, 7, 305, 129, 3, 0); - // Don't do a screen update here, see bug #1910180 "KYRA1: Screen 'flash'" - // it would cause to draw the screen with a wrong palette and thus look - // strange for the user. Since this opcode should be just called on scene - // initialization anyway, there should be no problem with not updating the - // screen right now. - return 0; -} - -int KyraEngine_v1::o1_dispelMagicAnimation(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_dispelMagicAnimation(%p) ()", (const void *)script); - seq_dispelMagicAnimation(); - return 0; -} - -int KyraEngine_v1::o1_findBrightestFireberry(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_findBrightestFireberry(%p) ()", (const void *)script); - if (_currentCharacter->sceneId >= 187 && _currentCharacter->sceneId <= 198) - return 29; - - if (_currentCharacter->sceneId == 133 || _currentCharacter->sceneId == 137 || - _currentCharacter->sceneId == 165 || _currentCharacter->sceneId == 173) - return 29; - - if (_itemInHand == 28) - return 28; - - int brightestFireberry = 107; - if (_itemInHand >= 29 && _itemInHand <= 33) - brightestFireberry = _itemInHand; - for (int i = 0; i < 10; ++i) { - uint8 item = _currentCharacter->inventoryItems[i]; - if (item == 0xFF) - continue; - if (item == 28) - return 28; - if (item >= 29 && item <= 33) { - if (item < brightestFireberry) - brightestFireberry = item; - } - } - assert(_currentCharacter->sceneId < _roomTableSize); - Room *curRoom = &_roomTable[_currentCharacter->sceneId]; - for (int i = 0; i < 12; ++i) { - uint8 item = curRoom->itemsTable[i]; - if (item == 0xFF) - continue; - if (item == 28) - return 28; - if (item >= 29 && item <= 33) { - if (item < brightestFireberry) - brightestFireberry = item; - } - } - if (brightestFireberry == 107) - return -1; - return brightestFireberry; -} - -int KyraEngine_v1::o1_setFireberryGlowPalette(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setFireberryGlowPalette(%p) (%d)", (const void *)script, stackPos(0)); - int palIndex = 0; - switch (stackPos(0)) { - case 0x1E: - palIndex = 9; - break; - - case 0x1F: - palIndex = 10; - break; - - case 0x20: - palIndex = 11; - break; - - case 0x21: - case -1: - palIndex = 12; - break; - - default: - palIndex = 8; - break; - } - if (_brandonStatusBit & 2) { - if (_currentCharacter->sceneId != 133 && _currentCharacter->sceneId != 137 && - _currentCharacter->sceneId != 165 && _currentCharacter->sceneId != 173 && - (_currentCharacter->sceneId < 187 || _currentCharacter->sceneId > 198)) { - palIndex = 14; - } - } - const uint8 *palette = _specialPalettes[palIndex]; - memcpy(_screen->getPalette(1) + 684, palette, 44); - return 0; -} - -int KyraEngine_v1::o1_setDeathHandlerFlag(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setDeathHandlerFlag(%p) (%d)", (const void *)script, stackPos(0)); - _deathHandler = stackPos(0); - return 0; -} - -int KyraEngine_v1::o1_drinkPotionAnimation(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_drinkPotionAnimation(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); - seq_playDrinkPotionAnim(stackPos(0), stackPos(1), stackPos(2)); - return 0; -} - -int KyraEngine_v1::o1_makeAmuletAppear(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_makeAmuletAppear(%p) ()", (const void *)script); - WSAMovieV1 amulet(this); - amulet.open("AMULET.WSA", 1, 0); - amulet.setX(224); - amulet.setY(152); - amulet.setDrawPage(0); - if (amulet.opened()) { - assert(_amuleteAnim); - _screen->hideMouse(); - snd_playSoundEffect(0x70); - uint32 nextTime = 0; - for (int i = 0; _amuleteAnim[i] != 0xFF; ++i) { - nextTime = _system->getMillis() + 5 * _tickLength; - - uint8 code = _amuleteAnim[i]; - if (code == 3 || code == 7) - snd_playSoundEffect(0x71); - - if (code == 5) - snd_playSoundEffect(0x72); - - if (code == 14) - snd_playSoundEffect(0x73); - - amulet.displayFrame(code); - _animator->_updateScreen = true; - - while (_system->getMillis() < nextTime) { - _sprites->updateSceneAnims(); - _animator->updateAllObjectShapes(); - if (nextTime - _system->getMillis() >= 10) - delay(10); - } - } - _screen->showMouse(); - } - setGameFlag(0x2D); - return 0; -} - -int KyraEngine_v1::o1_drawItemShapeIntoScene(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_drawItemShapeIntoScene(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); - int item = stackPos(0); - int x = stackPos(1); - int y = stackPos(2); - int flags = stackPos(3); - int onlyHidPage = stackPos(4); - - if (flags) - flags = 1; - - if (onlyHidPage) { - _screen->drawShape(2, _shapes[216+item], x, y, 0, flags); - } else { - _screen->hideMouse(); - _animator->restoreAllObjectBackgrounds(); - _screen->drawShape(2, _shapes[216+item], x, y, 0, flags); - _screen->drawShape(0, _shapes[216+item], x, y, 0, flags); - _animator->flagAllObjectsForBkgdChange(); - _animator->preserveAnyChangedBackgrounds(); - _animator->flagAllObjectsForRefresh(); - _animator->updateAllObjectShapes(); - _screen->showMouse(); - } - return 0; -} - -int KyraEngine_v1::o1_setCharactersCurrentFrame(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setCharactersCurrentFrame(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - _characterList[stackPos(0)].currentAnimFrame = stackPos(1); - return 0; -} - -int KyraEngine_v1::o1_waitForConfirmationMouseClick(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_waitForConfirmationMouseClick(%p) ()", (const void *)script); - // if (mouseEnabled) { - while (!_mousePressFlag) { - updateMousePointer(); - _sprites->updateSceneAnims(); - _animator->updateAllObjectShapes(); - delay(10); - } - - while (_mousePressFlag) { - updateMousePointer(); - _sprites->updateSceneAnims(); - _animator->updateAllObjectShapes(); - delay(10); - } - // } - _gui->processButtonList(_buttonList, 0); - _skipFlag = false; - Common::Point mouse = getMousePos(); - script->regs[1] = mouse.x; - script->regs[2] = mouse.y; - return 0; -} - -int KyraEngine_v1::o1_pageFlip(EMCState *script) { - warning("STUB: o1_pageFlip"); - return 0; -} - -int KyraEngine_v1::o1_setSceneFile(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setSceneFile(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - setSceneFile(stackPos(0), stackPos(1)); - return 0; -} - -int KyraEngine_v1::o1_getItemInMarbleVase(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_getItemInMarbleVase(%p) ()", (const void *)script); - return _marbleVaseItem; -} - -int KyraEngine_v1::o1_setItemInMarbleVase(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setItemInMarbleVase(%p) (%d)", (const void *)script, stackPos(0)); - _marbleVaseItem = stackPos(0); - return 0; -} - -int KyraEngine_v1::o1_addItemToInventory(EMCState *script) { - warning("STUB: o1_addItemToInventory"); - return 0; -} - -int KyraEngine_v1::o1_intPrint(EMCState *script) { - warning("STUB: o1_intPrint"); - return 0; -} - -int KyraEngine_v1::o1_shakeScreen(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_shakeScreen(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - int waitTicks = stackPos(1); - int times = stackPos(0); - - for (int i = 0; i < times; ++i) { - _screen->shakeScreen(1); - delay(waitTicks * _tickLength); - } - - return 0; -} - -int KyraEngine_v1::o1_createAmuletJewel(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_createAmuletJewel(%p) (%d)", (const void *)script, stackPos(0)); - seq_createAmuletJewel(stackPos(0), 0, 0, 0); - return 0; -} - -int KyraEngine_v1::o1_setSceneAnimCurrXY(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setSceneAnimCurrXY(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); - _sprites->_anims[stackPos(0)].x = stackPos(1); - _sprites->_anims[stackPos(0)].y = stackPos(2); - return 0; -} - -int KyraEngine_v1::o1_poisonBrandonAndRemaps(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_poisonBrandonAndRemaps(%p) ()", (const void *)script); - setBrandonPoisonFlags(1); - return 0; -} - -int KyraEngine_v1::o1_fillFlaskWithWater(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_fillFlaskWithWater(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - seq_fillFlaskWithWater(stackPos(0), stackPos(1)); - return 0; -} - -int KyraEngine_v1::o1_getCharactersMovementDelay(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_getCharactersMovementDelay(%p) (%d)", (const void *)script, stackPos(0)); - return _timer->getDelay(stackPos(0)+5); -} - -int KyraEngine_v1::o1_getBirthstoneGem(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_getBirthstoneGem(%p) (%d)", (const void *)script, stackPos(0)); - if (stackPos(0) < 4) - return _birthstoneGemTable[stackPos(0)]; - return 0; -} - -int KyraEngine_v1::o1_queryBrandonStatusBit(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_queryBrandonStatusBit(%p) (%d)", (const void *)script, stackPos(0)); - if (_brandonStatusBit & stackPos(0)) - return 1; - return 0; -} - -int KyraEngine_v1::o1_playFluteAnimation(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_playFluteAnimation(%p) ()", (const void *)script); - seq_playFluteAnimation(); - return 0; -} - -int KyraEngine_v1::o1_playWinterScrollSequence(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_playWinterScrollSequence(%p) (%d)", (const void *)script, stackPos(0)); - if (!stackPos(0)) - seq_winterScroll2(); - else - seq_winterScroll1(); - return 0; -} - -int KyraEngine_v1::o1_getIdolGem(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_getIdolGem(%p) (%d)", (const void *)script, stackPos(0)); - return _idolGemsTable[stackPos(0)]; -} - -int KyraEngine_v1::o1_setIdolGem(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setIdolGem(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - _idolGemsTable[stackPos(0)] = stackPos(1); - return 0; -} - -int KyraEngine_v1::o1_totalItemsInScene(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_totalItemsInScene(%p) (%d)", (const void *)script, stackPos(0)); - return countItemsInScene(stackPos(0)); -} - -int KyraEngine_v1::o1_restoreBrandonsMovementDelay(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_restoreBrandonsMovementDelay(%p) ()", (const void *)script); - setWalkspeed(_configWalkspeed); + screen()->showMouse(); return 0; } @@ -1518,514 +67,58 @@ int KyraEngine_v1::o1_setMousePos(EMCState *script) { return 0; } -int KyraEngine_v1::o1_getMouseState(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_getMouseState(%p) ()", (const void *)script); - return _mouseState; -} - -int KyraEngine_v1::o1_setEntranceMouseCursorTrack(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setEntranceMouseCursorTrack(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); - _entranceMouseCursorTracks[0] = stackPos(0); - _entranceMouseCursorTracks[1] = stackPos(1); - _entranceMouseCursorTracks[2] = stackPos(0) + stackPos(2) - 1; - _entranceMouseCursorTracks[3] = stackPos(1) + stackPos(3) - 1; - _entranceMouseCursorTracks[4] = stackPos(4); - return 0; -} - -int KyraEngine_v1::o1_itemAppearsOnGround(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_itemAppearsOnGround(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); - processItemDrop(_currentCharacter->sceneId, stackPos(0), stackPos(1), stackPos(2), 2, 0); - return 0; -} - -int KyraEngine_v1::o1_setNoDrawShapesFlag(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setNoDrawShapesFlag(%p) (%d)", (const void *)script, stackPos(0)); - _animator->_noDrawShapesFlag = stackPos(0); - return 0; -} - -int KyraEngine_v1::o1_fadeEntirePalette(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_fadeEntirePalette(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - int cmd = stackPos(0); - uint8 *fadePal = 0; - - if (_flags.platform == Common::kPlatformAmiga) { - if (cmd == 0) { - fadePal = _screen->getPalette(2); - memset(fadePal, 0, 32*3); - memcpy(_screen->getPalette(4), _screen->getPalette(0), 32*3); - } else if (cmd == 1) { - fadePal = _screen->getPalette(0); - memcpy(_screen->getPalette(0), _screen->getPalette(4), 32*3); - } else if (cmd == 2) { - fadePal = _screen->getPalette(0); - memset(_screen->getPalette(2), 0, 32*3); - } - } else { - if (cmd == 0) { - fadePal = _screen->getPalette(2); - uint8 *screenPal = _screen->getPalette(0); - uint8 *backUpPal = _screen->getPalette(3); - - memcpy(backUpPal, screenPal, sizeof(uint8)*768); - memset(fadePal, 0, sizeof(uint8)*768); - } else if (cmd == 1) { - //fadePal = _screen->getPalette(3); - warning("unimplemented o1_fadeEntirePalette function"); - return 0; - } else if (cmd == 2) { - memset(_screen->getPalette(2), 0, 768); - memcpy(_screen->getPalette(0), _screen->getPalette(1), 768); - fadePal = _screen->getPalette(0); - } - } - - _screen->fadePalette(fadePal, stackPos(1)); - return 0; -} - -int KyraEngine_v1::o1_itemOnGroundHere(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_itemOnGroundHere(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - assert(stackPos(0) < _roomTableSize); - Room *curRoom = &_roomTable[stackPos(0)]; - for (int i = 0; i < 12; ++i) { - if (curRoom->itemsTable[i] == stackPos(1)) - return 1; - } - return 0; -} - -int KyraEngine_v1::o1_queryCauldronState(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_queryCauldronState(%p) ()", (const void *)script); - return _cauldronState; -} - -int KyraEngine_v1::o1_setCauldronState(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setCauldronState(%p) (%d)", (const void *)script, stackPos(0)); - _cauldronState = stackPos(0); - return _cauldronState; -} - -int KyraEngine_v1::o1_queryCrystalState(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_queryCrystalState(%p) (%d)", (const void *)script, stackPos(0)); - if (!stackPos(0)) - return _crystalState[0]; - else if (stackPos(0) == 1) - return _crystalState[1]; - return -1; -} - -int KyraEngine_v1::o1_setCrystalState(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setCrystalState(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - if (!stackPos(0)) - _crystalState[0] = stackPos(1); - else if (stackPos(0) == 1) - _crystalState[1] = stackPos(1); - return stackPos(1); -} - -int KyraEngine_v1::o1_setPaletteRange(EMCState *script) { - warning("STUB: o1_setPaletteRange"); - return 0; -} - -int KyraEngine_v1::o1_shrinkBrandonDown(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_shrinkBrandonDown(%p) (%d)", (const void *)script, stackPos(0)); - int delayTime = stackPos(0); - checkAmuletAnimFlags(); - int scaleValue = _scaleTable[_currentCharacter->y1]; - int scale = 0; - - if (_scaleMode) - scale = scaleValue; - else - scale = 256; - - int scaleModeBackUp = _scaleMode; - _scaleMode = 1; - int scaleEnd = scale >> 1; - for (; scaleEnd <= scale; --scale) { - _scaleTable[_currentCharacter->y1] = scale; - _animator->animRefreshNPC(0); - delayWithTicks(1); - } - delayWithTicks(delayTime); // XXX - _scaleTable[_currentCharacter->y1] = scaleValue; - _scaleMode = scaleModeBackUp; - return 0; -} - -int KyraEngine_v1::o1_growBrandonUp(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_growBrandonUp(%p) ()", (const void *)script); - int scaleValue = _scaleTable[_currentCharacter->y1]; - int scale = 0; - if (_scaleMode) - scale = scaleValue; - else - scale = 256; - - int scaleModeBackUp = _scaleMode; - _scaleMode = 1; - for (int curScale = scale >> 1; curScale <= scale; ++curScale) { - _scaleTable[_currentCharacter->y1] = curScale; - _animator->animRefreshNPC(0); - delayWithTicks(1); - } - _scaleTable[_currentCharacter->y1] = scaleValue; - _scaleMode = scaleModeBackUp; +int KyraEngine_v1::o1_setHandItem(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setHandItem(%p) (%d)", (const void *)script, stackPos(0)); + setHandItem(stackPos(0)); return 0; } -int KyraEngine_v1::o1_setBrandonScaleXAndY(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setBrandonScaleXAndY(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - _animator->_brandonScaleX = stackPos(0); - _animator->_brandonScaleY = stackPos(1); +int KyraEngine_v1::o1_removeHandItem(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_removeHandItem(%p) ()", (const void *)script); + removeHandItem(); return 0; } -int KyraEngine_v1::o1_resetScaleMode(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_resetScaleMode(%p) ()", (const void *)script); - _scaleMode = 0; - return 0; -} - -int KyraEngine_v1::o1_getScaleDepthTableValue(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_getScaleDepthTableValue(%p) (%d)", (const void *)script, stackPos(0)); - assert(stackPos(0) < ARRAYSIZE(_scaleTable)); - return _scaleTable[stackPos(0)]; -} - -int KyraEngine_v1::o1_setScaleDepthTableValue(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setScaleDepthTableValue(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - assert(stackPos(0) < ARRAYSIZE(_scaleTable)); - _scaleTable[stackPos(0)] = stackPos(1); - return stackPos(1); -} - -int KyraEngine_v1::o1_message(EMCState *script) { - if (_flags.isTalkie) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_message(%p) (%d, '%s', %d)", (const void *)script, stackPos(0), stackPosString(1), stackPos(2)); - drawSentenceCommand(stackPosString(1), stackPos(2)); - } else { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_message(%p) ('%s', %d)", (const void *)script, stackPosString(0), stackPos(1)); - drawSentenceCommand(stackPosString(0), stackPos(1)); - } - - return 0; -} - -int KyraEngine_v1::o1_checkClickOnNPC(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_checkClickOnNPC(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - return checkForNPCScriptRun(stackPos(0), stackPos(1)); -} - -int KyraEngine_v1::o1_getFoyerItem(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_getFoyerItem(%p) (%d)", (const void *)script, stackPos(0)); - assert(stackPos(0) < ARRAYSIZE(_foyerItemTable)); - return _foyerItemTable[stackPos(0)]; -} - -int KyraEngine_v1::o1_setFoyerItem(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setFoyerItem(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - assert(stackPos(0) < ARRAYSIZE(_foyerItemTable)); - _foyerItemTable[stackPos(0)] = stackPos(1); - return stackPos(1); -} - -int KyraEngine_v1::o1_setNoItemDropRegion(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setNoItemDropRegion(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); - addToNoDropRects(stackPos(0), stackPos(1), stackPos(2), stackPos(3)); - return 0; -} - -int KyraEngine_v1::o1_walkMalcolmOn(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_walkMalcolmOn(%p) ()", (const void *)script); - if (!_malcolmFlag) - _malcolmFlag = 1; - return 0; -} - -int KyraEngine_v1::o1_passiveProtection(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_passiveProtection(%p) ()", (const void *)script); - return 1; -} - -int KyraEngine_v1::o1_setPlayingLoop(EMCState *script) { - warning("STUB: o1_setPlayingLoop"); - return 0; -} - -int KyraEngine_v1::o1_brandonToStoneSequence(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_brandonToStoneSequence(%p) ()", (const void *)script); - seq_brandonToStone(); - return 0; -} - -int KyraEngine_v1::o1_brandonHealingSequence(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_brandonHealingSequence(%p) ()", (const void *)script); - seq_brandonHealing(); - return 0; -} - -int KyraEngine_v1::o1_protectCommandLine(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_protectCommandLine(%p) (%d)", (const void *)script, stackPos(0)); - return stackPos(0); +int KyraEngine_v1::o1_getMouseState(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_getMouseState(%p) ()", (const void *)script); + return _mouseState; } -int KyraEngine_v1::o1_pauseMusicSeconds(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_pauseMusicSeconds(%p) ()", (const void *)script); - // if music disabled - // return - o1_pauseSeconds(script); +int KyraEngine_v1::o1_setDeathHandler(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setDeathHandler(%p) (%d)", (const void *)script, stackPos(0)); + _deathHandler = stackPos(0); return 0; } -int KyraEngine_v1::o1_resetMaskRegion(EMCState *script) { - warning("STUB: o1_resetMaskRegion"); +int KyraEngine_v1::o1_playWanderScoreViaMap(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_playWanderScoreViaMap(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + snd_playWanderScoreViaMap(stackPos(0), stackPos(1)); return 0; } -int KyraEngine_v1::o1_setPaletteChangeFlag(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setPaletteChangeFlag(%p) (%d)", (const void *)script, stackPos(0)); - _paletteChanged = stackPos(0); - return _paletteChanged; -} - int KyraEngine_v1::o1_fillRect(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_fillRect(%p) (%d, %d, %d, %d, %d, 0x%X)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5)); - int videoPageBackup = _screen->_curPage; - _screen->_curPage = stackPos(0); - _screen->fillRect(stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5)); - _screen->_curPage = videoPageBackup; + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_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(3), stackPos(4), stackPos(5), stackPos(0)); return 0; } -int KyraEngine_v1::o1_vocUnload(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_vocUnload(%p) ()", (const void *)script); - // this should unload all voc files (not needed) +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_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) +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_dummy(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_dummy(%p) ()", (const void *)script); +int KyraEngine_v1::o1_playSoundEffect(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_playSoundEffect(%p) (%d)", (const void *)script, stackPos(0)); + snd_playSoundEffect(stackPos(0)); return 0; } -#pragma mark - - -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() { - Common::Array<const Opcode *> *table = 0; - - SetOpcodeTable(_opcodes); - // 0x00 - Opcode(o1_magicInMouseItem); - Opcode(o1_characterSays); - Opcode(o1_pauseTicks); - Opcode(o1_drawSceneAnimShape); - // 0x04 - Opcode(o1_queryGameFlag); - Opcode(o1_setGameFlag); - Opcode(o1_resetGameFlag); - Opcode(o1_runNPCScript); - // 0x08 - Opcode(o1_setSpecialExitList); - Opcode(o1_blockInWalkableRegion); - Opcode(o1_blockOutWalkableRegion); - Opcode(o1_walkPlayerToPoint); - // 0x0c - Opcode(o1_dropItemInScene); - Opcode(o1_drawAnimShapeIntoScene); - Opcode(o1_createMouseItem); - Opcode(o1_savePageToDisk); - // 0x10 - Opcode(o1_sceneAnimOn); - Opcode(o1_sceneAnimOff); - Opcode(o1_getElapsedSeconds); - Opcode(o1_mouseIsPointer); - // 0x14 - Opcode(o1_destroyMouseItem); - Opcode(o1_runSceneAnimUntilDone); - Opcode(o1_fadeSpecialPalette); - Opcode(o1_playAdlibSound); - // 0x18 - Opcode(o1_playAdlibScore); - Opcode(o1_phaseInSameScene); - Opcode(o1_setScenePhasingFlag); - Opcode(o1_resetScenePhasingFlag); - // 0x1c - Opcode(o1_queryScenePhasingFlag); - Opcode(o1_sceneToDirection); - Opcode(o1_setBirthstoneGem); - Opcode(o1_placeItemInGenericMapScene); - // 0x20 - Opcode(o1_setBrandonStatusBit); - Opcode(o1_pauseSeconds); - Opcode(o1_getCharactersLocation); - Opcode(o1_runNPCSubscript); - // 0x24 - Opcode(o1_magicOutMouseItem); - Opcode(o1_internalAnimOn); - Opcode(o1_forceBrandonToNormal); - Opcode(o1_poisonDeathNow); - // 0x28 - Opcode(o1_setScaleMode); - Opcode(o1_openWSAFile); - Opcode(o1_closeWSAFile); - Opcode(o1_runWSAFromBeginningToEnd); - // 0x2c - Opcode(o1_displayWSAFrame); - Opcode(o1_enterNewScene); - Opcode(o1_setSpecialEnterXAndY); - Opcode(o1_runWSAFrames); - // 0x30 - Opcode(o1_popBrandonIntoScene); - Opcode(o1_restoreAllObjectBackgrounds); - Opcode(o1_setCustomPaletteRange); - Opcode(o1_loadPageFromDisk); - // 0x34 - Opcode(o1_customPrintTalkString); - Opcode(o1_restoreCustomPrintBackground); - Opcode(o1_hideMouse); - Opcode(o1_showMouse); - // 0x38 - Opcode(o1_getCharacterX); - Opcode(o1_getCharacterY); - Opcode(o1_changeCharactersFacing); - Opcode(o1_copyWSARegion); - // 0x3c - Opcode(o1_printText); - Opcode(o1_random); - Opcode(o1_loadSoundFile); - Opcode(o1_displayWSAFrameOnHidPage); - // 0x40 - Opcode(o1_displayWSASequentialFrames); - Opcode(o1_drawCharacterStanding); - Opcode(o1_internalAnimOff); - Opcode(o1_changeCharactersXAndY); - // 0x44 - Opcode(o1_clearSceneAnimatorBeacon); - Opcode(o1_querySceneAnimatorBeacon); - Opcode(o1_refreshSceneAnimator); - Opcode(o1_placeItemInOffScene); - // 0x48 - Opcode(o1_wipeDownMouseItem); - Opcode(o1_placeCharacterInOtherScene); - Opcode(o1_getKey); - Opcode(o1_specificItemInInventory); - // 0x4c - Opcode(o1_popMobileNPCIntoScene); - Opcode(o1_mobileCharacterInScene); - Opcode(o1_hideMobileCharacter); - Opcode(o1_unhideMobileCharacter); - // 0x50 - Opcode(o1_setCharactersLocation); - Opcode(o1_walkCharacterToPoint); - Opcode(o1_specialEventDisplayBrynnsNote); - Opcode(o1_specialEventRemoveBrynnsNote); - // 0x54 - Opcode(o1_setLogicPage); - Opcode(o1_fatPrint); - Opcode(o1_preserveAllObjectBackgrounds); - Opcode(o1_updateSceneAnimations); - // 0x58 - Opcode(o1_sceneAnimationActive); - Opcode(o1_setCharactersMovementDelay); - Opcode(o1_getCharactersFacing); - Opcode(o1_bkgdScrollSceneAndMasksRight); - // 0x5c - Opcode(o1_dispelMagicAnimation); - Opcode(o1_findBrightestFireberry); - Opcode(o1_setFireberryGlowPalette); - Opcode(o1_setDeathHandlerFlag); - // 0x60 - Opcode(o1_drinkPotionAnimation); - Opcode(o1_makeAmuletAppear); - Opcode(o1_drawItemShapeIntoScene); - Opcode(o1_setCharactersCurrentFrame); - // 0x64 - Opcode(o1_waitForConfirmationMouseClick); - Opcode(o1_pageFlip); - Opcode(o1_setSceneFile); - Opcode(o1_getItemInMarbleVase); - // 0x68 - Opcode(o1_setItemInMarbleVase); - Opcode(o1_addItemToInventory); - Opcode(o1_intPrint); - Opcode(o1_shakeScreen); - // 0x6c - Opcode(o1_createAmuletJewel); - Opcode(o1_setSceneAnimCurrXY); - Opcode(o1_poisonBrandonAndRemaps); - Opcode(o1_fillFlaskWithWater); - // 0x70 - Opcode(o1_getCharactersMovementDelay); - Opcode(o1_getBirthstoneGem); - Opcode(o1_queryBrandonStatusBit); - Opcode(o1_playFluteAnimation); - // 0x74 - Opcode(o1_playWinterScrollSequence); - Opcode(o1_getIdolGem); - Opcode(o1_setIdolGem); - Opcode(o1_totalItemsInScene); - // 0x78 - Opcode(o1_restoreBrandonsMovementDelay); - Opcode(o1_setMousePos); - Opcode(o1_getMouseState); - Opcode(o1_setEntranceMouseCursorTrack); - // 0x7c - Opcode(o1_itemAppearsOnGround); - Opcode(o1_setNoDrawShapesFlag); - Opcode(o1_fadeEntirePalette); - Opcode(o1_itemOnGroundHere); - // 0x80 - Opcode(o1_queryCauldronState); - Opcode(o1_setCauldronState); - Opcode(o1_queryCrystalState); - Opcode(o1_setCrystalState); - // 0x84 - Opcode(o1_setPaletteRange); - Opcode(o1_shrinkBrandonDown); - Opcode(o1_growBrandonUp); - Opcode(o1_setBrandonScaleXAndY); - // 0x88 - Opcode(o1_resetScaleMode); - Opcode(o1_getScaleDepthTableValue); - Opcode(o1_setScaleDepthTableValue); - Opcode(o1_message); - // 0x8c - Opcode(o1_checkClickOnNPC); - Opcode(o1_getFoyerItem); - Opcode(o1_setFoyerItem); - Opcode(o1_setNoItemDropRegion); - // 0x90 - Opcode(o1_walkMalcolmOn); - Opcode(o1_passiveProtection); - Opcode(o1_setPlayingLoop); - Opcode(o1_brandonToStoneSequence); - // 0x94 - Opcode(o1_brandonHealingSequence); - Opcode(o1_protectCommandLine); - Opcode(o1_pauseMusicSeconds); - Opcode(o1_resetMaskRegion); - // 0x98 - Opcode(o1_setPaletteChangeFlag); - Opcode(o1_fillRect); - Opcode(o1_vocUnload); - Opcode(o1_vocLoad); - // 0x9c - Opcode(o1_dummy); -} -#undef Opcode - } // end of namespace Kyra diff --git a/engines/kyra/script_v2.cpp b/engines/kyra/script_v2.cpp index fcfb34561f..2af4fda727 100644 --- a/engines/kyra/script_v2.cpp +++ b/engines/kyra/script_v2.cpp @@ -103,44 +103,6 @@ int KyraEngine_v2::o2_defineItem(EMCState *script) { return freeItem; } -int KyraEngine_v2::o2_queryGameFlag(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_queryGameFlag(%p) (%d)", (const void *)script, stackPos(0)); - return queryGameFlag(stackPos(0)); -} - -int KyraEngine_v2::o2_resetGameFlag(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_resetGameFlag(%p) (%d)", (const void *)script, stackPos(0)); - return resetGameFlag(stackPos(0)); -} - -int KyraEngine_v2::o2_setGameFlag(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_setGameFlag(%p) (%d)", (const void *)script, stackPos(0)); - return setGameFlag(stackPos(0)); -} - -int KyraEngine_v2::o2_setHandItem(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_setHandItem(%p) (%d)", (const void *)script, stackPos(0)); - setHandItem(stackPos(0)); - return 0; -} - -int KyraEngine_v2::o2_removeHandItem(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_removeHandItem(%p) ()", (const void *)script); - removeHandItem(); - return 0; -} - -int KyraEngine_v2::o2_handItemSet(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_handItemSet(%p) ()", (const void *)script); - return _handItemSet; -} - -int KyraEngine_v2::o2_hideMouse(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_hideMouse(%p) ()", (const void *)script); - screen()->hideMouse(); - return 0; -} - int KyraEngine_v2::o2_addSpecialExit(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_addSpecialExit(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); @@ -155,18 +117,6 @@ int KyraEngine_v2::o2_addSpecialExit(EMCState *script) { return 0; } -int KyraEngine_v2::o2_setMousePos(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_setMousePos(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - setMousePos(stackPos(0), stackPos(1)); - return 0; -} - -int KyraEngine_v2::o2_showMouse(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_showMouse(%p) ()", (const void *)script); - screen()->showMouse(); - return 0; -} - int KyraEngine_v2::o2_delay(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_delay(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); if (stackPos(1)) { @@ -206,24 +156,6 @@ int KyraEngine_v2::o2_getShapeFlag1(EMCState *script) { return screen()->getShapeFlag1(stackPos(0), stackPos(1)); } -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_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_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_waitForConfirmationClick(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_waitForConfirmationClick(%p) (%d)", (const void *)script, stackPos(0)); resetSkipFlag(); diff --git a/engines/kyra/seqplayer.cpp b/engines/kyra/seqplayer.cpp index ddd8beb5dc..73d69ef10c 100644 --- a/engines/kyra/seqplayer.cpp +++ b/engines/kyra/seqplayer.cpp @@ -40,7 +40,7 @@ namespace Kyra { -SeqPlayer::SeqPlayer(KyraEngine_v1 *vm, OSystem *system) { +SeqPlayer::SeqPlayer(KyraEngine_LoK *vm, OSystem *system) { _vm = vm; _system = system; @@ -110,7 +110,7 @@ void SeqPlayer::makeHandShapes() { } else { for (int i = 0; i < ARRAYSIZE(_handShapes); ++i) { if (_handShapes[i]) - delete [] _handShapes[i]; + delete[] _handShapes[i]; _handShapes[i] = setPanPages(3, i); assert(_handShapes[i]); } @@ -120,7 +120,7 @@ void SeqPlayer::makeHandShapes() { void SeqPlayer::freeHandShapes() { debugC(9, kDebugLevelSequence, "SeqPlayer::freeHandShapes()"); for (int i = 0; i < ARRAYSIZE(_handShapes); ++i) { - delete [] _handShapes[i]; + delete[] _handShapes[i]; _handShapes[i] = 0; } } @@ -262,7 +262,7 @@ void SeqPlayer::s1_loadPalette() { uint8 *srcData; srcData = _res->fileData(_vm->seqCOLTable()[colNum], &fileSize); memcpy(_screen->_currentPalette, srcData, fileSize); - delete [] srcData; + delete[] srcData; } } @@ -667,7 +667,7 @@ bool SeqPlayer::playSequence(const uint8 *seqData, bool skipSeq) { _screen->updateScreen(); } - delete [] _specialBuffer; + delete[] _specialBuffer; _specialBuffer = 0; return seqSkippedFlag; } diff --git a/engines/kyra/seqplayer.h b/engines/kyra/seqplayer.h index ce7f4648df..7e1b06d955 100644 --- a/engines/kyra/seqplayer.h +++ b/engines/kyra/seqplayer.h @@ -26,13 +26,13 @@ #ifndef KYRA_SEQPLAYER_H #define KYRA_SEQPLAYER_H -#include "kyra/kyra_v1.h" +#include "kyra/kyra_lok.h" namespace Kyra { class SeqPlayer { public: - SeqPlayer(KyraEngine_v1 *vm, OSystem *system); + SeqPlayer(KyraEngine_LoK *vm, OSystem *system); ~SeqPlayer(); void setCopyViewOffs(bool offs) { @@ -46,7 +46,7 @@ public: uint8 *setPanPages(int pageNum, int shape); protected: - KyraEngine_v1 *_vm; + KyraEngine_LoK *_vm; OSystem *_system; Screen *_screen; Sound *_sound; diff --git a/engines/kyra/sequences_hof.cpp b/engines/kyra/sequences_hof.cpp index 1c74f48990..169c319347 100644 --- a/engines/kyra/sequences_hof.cpp +++ b/engines/kyra/sequences_hof.cpp @@ -23,7 +23,7 @@ * */ -#include "kyra/kyra.h" +#include "kyra/kyra_v1.h" #include "kyra/kyra_hof.h" #include "kyra/screen.h" #include "kyra/wsamovie.h" @@ -231,7 +231,7 @@ void KyraEngine_HoF::seq_playSequences(int startSeq, int endSeq) { _seqFrameDelay = cseq.frameDelay; _seqEndTime = _system->getMillis() + _seqFrameDelay * _tickLength; while (!((skipFlag() && allowSkip) || _quitFlag || (_abortIntroFlag && allowSkip) || _menuChoice)) { - uint32 starttime = _system->getMillis(); + _seqSubFrameStartTime = _system->getMillis(); seq_processWSAs(); if (cb) (this->*cb)(0, 0, 0, 0); @@ -246,8 +246,8 @@ void KyraEngine_HoF::seq_playSequences(int startSeq, int endSeq) { if (now >= _seqEndTime && !_seqSubframePlaying) break; - uint32 tdiff = _seqEndTime - starttime; - int32 dly = _tickLength - (now - starttime); + uint32 tdiff = _seqEndTime - _seqSubFrameStartTime; + int32 dly = _tickLength - (now - _seqSubFrameStartTime); if (dly > 0) delay(MIN<uint32>(dly, tdiff)); } @@ -263,7 +263,7 @@ void KyraEngine_HoF::seq_playSequences(int startSeq, int endSeq) { _seqEndTime = _system->getMillis() + dl; while (!((skipFlag() && allowSkip) || _quitFlag || (_abortIntroFlag && allowSkip) || _menuChoice)) { - uint32 starttime = _system->getMillis(); + _seqSubFrameStartTime = _system->getMillis(); seq_processWSAs(); _screen->copyPage(2, 0); @@ -275,8 +275,8 @@ void KyraEngine_HoF::seq_playSequences(int startSeq, int endSeq) { break; } - uint32 tdiff = _seqEndTime - starttime; - int32 dly = _tickLength - (now - starttime); + uint32 tdiff = _seqEndTime - _seqSubFrameStartTime; + int32 dly = _tickLength - (now - _seqSubFrameStartTime); if (dly > 0) delay(MIN<uint32>(dly, tdiff)); } @@ -284,13 +284,12 @@ void KyraEngine_HoF::seq_playSequences(int startSeq, int endSeq) { seq_sequenceCommand(cseq.finalCommand); seq_resetAllTextEntries(); - if (_flags.isDemo && !_flags.isTalkie) { - if (seqNum == kSequenceDemoFisher) { - _abortIntroFlag = false; - resetSkipFlag(); - seqNum = kSequenceDemoVirgin; - } - } else { + if (_abortIntroFlag || skipFlag()) { + _sound->haltTrack(); + _sound->voiceStop(); + } + + if (!_flags.isDemo || _flags.isTalkie) { if ((seqNum != kSequenceTitle && seqNum < kSequenceZanfaun && (_abortIntroFlag || skipFlag())) || seqNum == kSequenceZanfaun) { _abortIntroFlag = false; @@ -301,6 +300,8 @@ void KyraEngine_HoF::seq_playSequences(int startSeq, int endSeq) { _eventList.clear(); seqNum = kSequenceFirates; } + } else if (seqNum == kSequenceDemoFisher && !(_abortIntroFlag || skipFlag())) { + seqNum = kSequenceDemoVirgin; } if (_menuChoice) { @@ -314,8 +315,13 @@ void KyraEngine_HoF::seq_playSequences(int startSeq, int endSeq) { } } + if (_flags.isDemo && !_flags.isTalkie) { + _eventList.clear(); + _screen->fadeToBlack(); + } + if (!_menuChoice) - delay(1000); + delay(1200); _screen->setCurPage(oldPage); _screen->showMouse(); @@ -330,7 +336,7 @@ void KyraEngine_HoF::seq_playSequences(int startSeq, int endSeq) { seq_uninit(); } -int KyraEngine_HoF::seq_introWestwood(WSAMovieV2 *wsaObj, int x, int y, int frm) { +int KyraEngine_HoF::seq_introWestwood(WSAMovie_v2 *wsaObj, int x, int y, int frm) { debugC(9, kDebugLevelMain, "KyraEngine_HoF::seq_introWestwood(%p, %i, %i, %i)", (const void*)wsaObj, x, y, frm); if (frm == -2) { @@ -343,7 +349,7 @@ int KyraEngine_HoF::seq_introWestwood(WSAMovieV2 *wsaObj, int x, int y, int frm) return 0; } -int KyraEngine_HoF::seq_introTitle(WSAMovieV2 *wsaObj, int x, int y, int frm) { +int KyraEngine_HoF::seq_introTitle(WSAMovie_v2 *wsaObj, int x, int y, int frm) { debugC(9, kDebugLevelMain, "KyraEngine_HoF::seq_introTitle(%p, %i, %i, %i)", (const void*)wsaObj, x, y, frm); if (frm == 1) { @@ -365,18 +371,19 @@ int KyraEngine_HoF::seq_introTitle(WSAMovieV2 *wsaObj, int x, int y, int frm) { return 0; } -int KyraEngine_HoF::seq_introOverview(WSAMovieV2 *wsaObj, int x, int y, int frm) { +int KyraEngine_HoF::seq_introOverview(WSAMovie_v2 *wsaObj, int x, int y, int frm) { debugC(9, kDebugLevelMain, "KyraEngine_HoF::seq_introOverview(%p, %i, %i, %i)", (const void*)wsaObj, x, y, frm); uint8 *tmpPal = &(_screen->getPalette(3)[0x101]); memset(tmpPal, 0, 256); - uint32 endtime = 0, now = 0; + _seqSubFrameEndTimeInternal = 0; + uint32 now = 0; switch (_seqFrameCounter) { case 0: _seqSubframePlaying = true; _sound->playTrack(4); - endtime = _system->getMillis() + 60 * _tickLength; + _seqSubFrameEndTimeInternal = _system->getMillis() + 60 * _tickLength; _seqTextColor[1] = _screen->findLeastDifferentColor(_seqTextColorPresets, _screen->getPalette(0) + 3, 255) & 0xff; memset(_seqTextColorMap, _seqTextColor[1], 16); @@ -385,8 +392,8 @@ int KyraEngine_HoF::seq_introOverview(WSAMovieV2 *wsaObj, int x, int y, int frm) _screen->setTextColorMap(_seqTextColorMap); now = _system->getMillis(); - if (endtime > now) - delay(endtime - now); + if (_seqSubFrameEndTimeInternal > now) + delay(_seqSubFrameEndTimeInternal - now); break; case 1: @@ -465,7 +472,7 @@ int KyraEngine_HoF::seq_introOverview(WSAMovieV2 *wsaObj, int x, int y, int frm) return 0; } -int KyraEngine_HoF::seq_introLibrary(WSAMovieV2 *wsaObj, int x, int y, int frm) { +int KyraEngine_HoF::seq_introLibrary(WSAMovie_v2 *wsaObj, int x, int y, int frm) { debugC(9, kDebugLevelMain, "KyraEngine_HoF::seq_introLibrary(%p, %i, %i, %i)", (const void*)wsaObj, x, y, frm); switch (_seqFrameCounter) { @@ -541,7 +548,7 @@ int KyraEngine_HoF::seq_introLibrary(WSAMovieV2 *wsaObj, int x, int y, int frm) } -int KyraEngine_HoF::seq_introHand(WSAMovieV2 *wsaObj, int x, int y, int frm) { +int KyraEngine_HoF::seq_introHand(WSAMovie_v2 *wsaObj, int x, int y, int frm) { debugC(9, kDebugLevelMain, "KyraEngine_HoF::seq_introHand(%p, %i, %i, %i)", (const void*)wsaObj, x, y, frm); switch (_seqFrameCounter) { @@ -625,7 +632,7 @@ int KyraEngine_HoF::seq_introHand(WSAMovieV2 *wsaObj, int x, int y, int frm) { return 0; } -int KyraEngine_HoF::seq_introPoint(WSAMovieV2 *wsaObj, int x, int y, int frm) { +int KyraEngine_HoF::seq_introPoint(WSAMovie_v2 *wsaObj, int x, int y, int frm) { if (frm == -2) { seq_waitForTextsTimeout(); _seqEndTime = 0; @@ -658,7 +665,7 @@ int KyraEngine_HoF::seq_introPoint(WSAMovieV2 *wsaObj, int x, int y, int frm) { return 0; } -int KyraEngine_HoF::seq_introZanfaun(WSAMovieV2 *wsaObj, int x, int y, int frm) { +int KyraEngine_HoF::seq_introZanfaun(WSAMovie_v2 *wsaObj, int x, int y, int frm) { if (frm == -2) { seq_waitForTextsTimeout(); _seqEndTime = 0; @@ -747,7 +754,7 @@ int KyraEngine_HoF::seq_introZanfaun(WSAMovieV2 *wsaObj, int x, int y, int frm) return 0; } -int KyraEngine_HoF::seq_introOver1(WSAMovieV2 *wsaObj, int x, int y, int frm) { +int KyraEngine_HoF::seq_introOver1(WSAMovie_v2 *wsaObj, int x, int y, int frm) { if (frm == 2) seq_waitForTextsTimeout(); else if (frm == 3) @@ -756,13 +763,13 @@ int KyraEngine_HoF::seq_introOver1(WSAMovieV2 *wsaObj, int x, int y, int frm) { } -int KyraEngine_HoF::seq_introOver2(WSAMovieV2 *wsaObj, int x, int y, int frm) { +int KyraEngine_HoF::seq_introOver2(WSAMovie_v2 *wsaObj, int x, int y, int frm) { if (frm == 1) seq_playTalkText(12); return frm; } -int KyraEngine_HoF::seq_introForest(WSAMovieV2 *wsaObj, int x, int y, int frm) { +int KyraEngine_HoF::seq_introForest(WSAMovie_v2 *wsaObj, int x, int y, int frm) { if (frm == 11) seq_waitForTextsTimeout(); else if (frm == 12) @@ -771,7 +778,7 @@ int KyraEngine_HoF::seq_introForest(WSAMovieV2 *wsaObj, int x, int y, int frm) { return frm; } -int KyraEngine_HoF::seq_introDragon(WSAMovieV2 *wsaObj, int x, int y, int frm) { +int KyraEngine_HoF::seq_introDragon(WSAMovie_v2 *wsaObj, int x, int y, int frm) { if (frm == 11) seq_waitForTextsTimeout(); else if (frm == 3) @@ -779,17 +786,17 @@ int KyraEngine_HoF::seq_introDragon(WSAMovieV2 *wsaObj, int x, int y, int frm) { return frm; } -int KyraEngine_HoF::seq_introDarm(WSAMovieV2 *wsaObj, int x, int y, int frm) { +int KyraEngine_HoF::seq_introDarm(WSAMovie_v2 *wsaObj, int x, int y, int frm) { //NULLSUB (at least in fm-towns version) return frm; } -int KyraEngine_HoF::seq_introLibrary2(WSAMovieV2 *wsaObj, int x, int y, int frm) { +int KyraEngine_HoF::seq_introLibrary2(WSAMovie_v2 *wsaObj, int x, int y, int frm) { //NULLSUB (at least in fm-towns version) return frm; } -int KyraEngine_HoF::seq_introMarco(WSAMovieV2 *wsaObj, int x, int y, int frm) { +int KyraEngine_HoF::seq_introMarco(WSAMovie_v2 *wsaObj, int x, int y, int frm) { if (frm == 36) { seq_waitForTextsTimeout(); _seqEndTime = 0; @@ -797,35 +804,35 @@ int KyraEngine_HoF::seq_introMarco(WSAMovieV2 *wsaObj, int x, int y, int frm) { return frm; } -int KyraEngine_HoF::seq_introHand1a(WSAMovieV2 *wsaObj, int x, int y, int frm) { +int KyraEngine_HoF::seq_introHand1a(WSAMovie_v2 *wsaObj, int x, int y, int frm) { //NULLSUB (at least in fm-towns version) return frm; } -int KyraEngine_HoF::seq_introHand1b(WSAMovieV2 *wsaObj, int x, int y, int frm) { +int KyraEngine_HoF::seq_introHand1b(WSAMovie_v2 *wsaObj, int x, int y, int frm) { if (frm == 15) frm = 12; return frm; } -int KyraEngine_HoF::seq_introHand1c(WSAMovieV2 *wsaObj, int x, int y, int frm) { +int KyraEngine_HoF::seq_introHand1c(WSAMovie_v2 *wsaObj, int x, int y, int frm) { if (frm == 8) frm = 4; return frm; } -int KyraEngine_HoF::seq_introHand2(WSAMovieV2 *wsaObj, int x, int y, int frm) { +int KyraEngine_HoF::seq_introHand2(WSAMovie_v2 *wsaObj, int x, int y, int frm) { //NULLSUB (at least in fm-towns version) return frm; } -int KyraEngine_HoF::seq_introHand3(WSAMovieV2 *wsaObj, int x, int y, int frm) { +int KyraEngine_HoF::seq_introHand3(WSAMovie_v2 *wsaObj, int x, int y, int frm) { //NULLSUB (at least in fm-towns version) return frm; } -int KyraEngine_HoF::seq_finaleFunters(WSAMovieV2 *wsaObj, int x, int y, int frm) { - uint32 endtime = 0; +int KyraEngine_HoF::seq_finaleFunters(WSAMovie_v2 *wsaObj, int x, int y, int frm) { + _seqSubFrameEndTimeInternal = 0; int chatX = 0; int chatY = 0; int chatW = 0; @@ -846,12 +853,12 @@ int KyraEngine_HoF::seq_finaleFunters(WSAMovieV2 *wsaObj, int x, int y, int frm) _seqTextColor[0] = _seqTextColorMap[1] = 0xff; _screen->setTextColorMap(_seqTextColorMap); - endtime = _system->getMillis() + 480 * _tickLength; + _seqSubFrameEndTimeInternal = _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); + delay(_seqSubFrameEndTimeInternal - _system->getMillis()); _seqTextColor[0] = 1; if (_flags.isTalkie) { @@ -908,8 +915,8 @@ int KyraEngine_HoF::seq_finaleFunters(WSAMovieV2 *wsaObj, int x, int y, int frm) return 0; } -int KyraEngine_HoF::seq_finaleFerb(WSAMovieV2 *wsaObj, int x, int y, int frm) { - uint32 endtime = 0; +int KyraEngine_HoF::seq_finaleFerb(WSAMovie_v2 *wsaObj, int x, int y, int frm) { + _seqSubFrameEndTimeInternal = 0; int chatX = 0; int chatY = 0; int chatW = 0; @@ -920,7 +927,7 @@ int KyraEngine_HoF::seq_finaleFerb(WSAMovieV2 *wsaObj, int x, int y, int frm) { switch (frm) { case -2: seq_sequenceCommand(9); - endtime = _system->getMillis() + 480 * _tickLength; + _seqSubFrameEndTimeInternal = _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); @@ -929,7 +936,7 @@ int KyraEngine_HoF::seq_finaleFerb(WSAMovieV2 *wsaObj, int x, int y, int frm) { 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()); + delay(_seqSubFrameEndTimeInternal - _system->getMillis()); _seqEndTime = 0; break; @@ -992,8 +999,8 @@ int KyraEngine_HoF::seq_finaleFerb(WSAMovieV2 *wsaObj, int x, int y, int frm) { return 0; } -int KyraEngine_HoF::seq_finaleFish(WSAMovieV2 *wsaObj, int x, int y, int frm) { - uint32 endtime = 0; +int KyraEngine_HoF::seq_finaleFish(WSAMovie_v2 *wsaObj, int x, int y, int frm) { + _seqSubFrameEndTimeInternal = 0; int chatX = 0; int chatY = 0; int chatW = 0; @@ -1002,7 +1009,7 @@ int KyraEngine_HoF::seq_finaleFish(WSAMovieV2 *wsaObj, int x, int y, int frm) { switch (frm) { case -2: seq_sequenceCommand(9); - endtime = _system->getMillis() + 480 * _tickLength; + _seqSubFrameEndTimeInternal = _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]); @@ -1011,7 +1018,7 @@ int KyraEngine_HoF::seq_finaleFish(WSAMovieV2 *wsaObj, int x, int y, int frm) { 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()); + delay(_seqSubFrameEndTimeInternal - _system->getMillis()); _seqEndTime = 0; break; @@ -1069,8 +1076,8 @@ int KyraEngine_HoF::seq_finaleFish(WSAMovieV2 *wsaObj, int x, int y, int frm) { return 0; } -int KyraEngine_HoF::seq_finaleFheep(WSAMovieV2 *wsaObj, int x, int y, int frm) { - uint32 endtime = 0; +int KyraEngine_HoF::seq_finaleFheep(WSAMovie_v2 *wsaObj, int x, int y, int frm) { + _seqSubFrameEndTimeInternal = 0; int chatX = 0; int chatY = 0; int chatW = 0; @@ -1084,7 +1091,7 @@ int KyraEngine_HoF::seq_finaleFheep(WSAMovieV2 *wsaObj, int x, int y, int frm) { _screen->copyPage(2, 0); _screen->updateScreen(); seq_sequenceCommand(9); - endtime = _system->getMillis() + 480 * _tickLength; + _seqSubFrameEndTimeInternal = _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]); @@ -1101,7 +1108,7 @@ int KyraEngine_HoF::seq_finaleFheep(WSAMovieV2 *wsaObj, int x, int y, int frm) { seq_printCreditsString(63, 240, 150, _seqTextColorMap, _seqTextColor[0]); seq_printCreditsString(64, 240, 160, _seqTextColorMap, _seqTextColor[0]); - delay(endtime - _system->getMillis()); + delay(_seqSubFrameEndTimeInternal - _system->getMillis()); _seqEndTime = 0; break; @@ -1151,8 +1158,8 @@ int KyraEngine_HoF::seq_finaleFheep(WSAMovieV2 *wsaObj, int x, int y, int frm) { return 0; } -int KyraEngine_HoF::seq_finaleFarmer(WSAMovieV2 *wsaObj, int x, int y, int frm) { - uint32 endtime = 0; +int KyraEngine_HoF::seq_finaleFarmer(WSAMovie_v2 *wsaObj, int x, int y, int frm) { + _seqSubFrameEndTimeInternal = 0; int chatX = 0; int chatY = 0; int chatW = 0; @@ -1164,7 +1171,7 @@ int KyraEngine_HoF::seq_finaleFarmer(WSAMovieV2 *wsaObj, int x, int y, int frm) _screen->copyPage(2, 0); _screen->updateScreen(); seq_sequenceCommand(9); - endtime = _system->getMillis() + 480 * _tickLength; + _seqSubFrameEndTimeInternal = _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]); @@ -1177,7 +1184,7 @@ int KyraEngine_HoF::seq_finaleFarmer(WSAMovieV2 *wsaObj, int x, int y, int frm) 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()); + delay(_seqSubFrameEndTimeInternal - _system->getMillis()); _seqEndTime = 0; break; @@ -1221,8 +1228,8 @@ int KyraEngine_HoF::seq_finaleFarmer(WSAMovieV2 *wsaObj, int x, int y, int frm) return 0; } -int KyraEngine_HoF::seq_finaleFuards(WSAMovieV2 *wsaObj, int x, int y, int frm) { - uint32 endtime = 0; +int KyraEngine_HoF::seq_finaleFuards(WSAMovie_v2 *wsaObj, int x, int y, int frm) { + _seqSubFrameEndTimeInternal = 0; int chatX = 0; int chatY = 0; int chatW = 0; @@ -1235,7 +1242,7 @@ int KyraEngine_HoF::seq_finaleFuards(WSAMovieV2 *wsaObj, int x, int y, int frm) switch (frm) { case -2: seq_sequenceCommand(9); - endtime = _system->getMillis() + 480 * _tickLength; + _seqSubFrameEndTimeInternal = _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]); @@ -1250,7 +1257,7 @@ int KyraEngine_HoF::seq_finaleFuards(WSAMovieV2 *wsaObj, int x, int y, int frm) 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()); + delay(_seqSubFrameEndTimeInternal - _system->getMillis()); _seqEndTime = 0; break; @@ -1321,8 +1328,8 @@ int KyraEngine_HoF::seq_finaleFuards(WSAMovieV2 *wsaObj, int x, int y, int frm) return 0; } -int KyraEngine_HoF::seq_finaleFirates(WSAMovieV2 *wsaObj, int x, int y, int frm) { - uint32 endtime = 0; +int KyraEngine_HoF::seq_finaleFirates(WSAMovie_v2 *wsaObj, int x, int y, int frm) { + _seqSubFrameEndTimeInternal = 0; int chatX = 0; int chatY = 0; int chatW = 0; @@ -1334,7 +1341,7 @@ int KyraEngine_HoF::seq_finaleFirates(WSAMovieV2 *wsaObj, int x, int y, int frm) _screen->copyPage(2, 0); _screen->updateScreen(); seq_sequenceCommand(9); - endtime = _system->getMillis() + 480 * _tickLength; + _seqSubFrameEndTimeInternal = _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]); @@ -1344,7 +1351,7 @@ int KyraEngine_HoF::seq_finaleFirates(WSAMovieV2 *wsaObj, int x, int y, int frm) 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()); + delay(_seqSubFrameEndTimeInternal - _system->getMillis()); _seqEndTime = 0; break; @@ -1413,7 +1420,7 @@ int KyraEngine_HoF::seq_finaleFirates(WSAMovieV2 *wsaObj, int x, int y, int frm) return 0; } -int KyraEngine_HoF::seq_finaleFrash(WSAMovieV2 *wsaObj, int x, int y, int frm) { +int KyraEngine_HoF::seq_finaleFrash(WSAMovie_v2 *wsaObj, int x, int y, int frm) { int tmp = 0; switch (frm) { @@ -1535,13 +1542,13 @@ void KyraEngine_HoF::seq_finaleActorScreen() { seq_displayScrollText(dataPtr, &d, 2, 6, 5, 1, Screen::FID_GOLDFONT_FNT, Screen::FID_GOLDFONT_FNT, 0, talkieCreditsSpecial); delay(120); - delete [] dataPtr; + 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) { +int KyraEngine_HoF::seq_finaleFiggle(WSAMovie_v2 *wsaObj, int x, int y, int frm) { if (_seqFrameCounter == 10) _seqEndTime = 0; if (_seqFrameCounter == 10 || _seqFrameCounter == 5 || _seqFrameCounter == 7) @@ -1551,18 +1558,18 @@ int KyraEngine_HoF::seq_finaleFiggle(WSAMovieV2 *wsaObj, int x, int y, int frm) return frm; } -int KyraEngine_HoF::seq_demoVirgin(WSAMovieV2 *wsaObj, int x, int y, int frm) { +int KyraEngine_HoF::seq_demoVirgin(WSAMovie_v2 *wsaObj, int x, int y, int frm) { if (!frm) delay(50 * _tickLength); return 0; } -int KyraEngine_HoF::seq_demoWestwood(WSAMovieV2 *wsaObj, int x, int y, int frm) { +int KyraEngine_HoF::seq_demoWestwood(WSAMovie_v2 *wsaObj, int x, int y, int frm) { if (!frm) _sound->playTrack(2); return 0; } -int KyraEngine_HoF::seq_demoTitle(WSAMovieV2 *wsaObj, int x, int y, int frm) { +int KyraEngine_HoF::seq_demoTitle(WSAMovie_v2 *wsaObj, int x, int y, int frm) { if (!frm) { _sound->playTrack(3); } else if (frm == 25) { @@ -1573,7 +1580,7 @@ int KyraEngine_HoF::seq_demoTitle(WSAMovieV2 *wsaObj, int x, int y, int frm) { return 0; } -int KyraEngine_HoF::seq_demoHill(WSAMovieV2 *wsaObj, int x, int y, int frm) { +int KyraEngine_HoF::seq_demoHill(WSAMovie_v2 *wsaObj, int x, int y, int frm) { if (!frm) { _sound->playTrack(4); } else if (frm == 25) { @@ -1593,7 +1600,7 @@ int KyraEngine_HoF::seq_demoHill(WSAMovieV2 *wsaObj, int x, int y, int frm) { return 0; } -int KyraEngine_HoF::seq_demoOuthome(WSAMovieV2 *wsaObj, int x, int y, int frm) { +int KyraEngine_HoF::seq_demoOuthome(WSAMovie_v2 *wsaObj, int x, int y, int frm) { switch (frm) { case 12: seq_playTalkText(4); @@ -1634,7 +1641,7 @@ int KyraEngine_HoF::seq_demoOuthome(WSAMovieV2 *wsaObj, int x, int y, int frm) { return 0; } -int KyraEngine_HoF::seq_demoWharf(WSAMovieV2 *wsaObj, int x, int y, int frm) { +int KyraEngine_HoF::seq_demoWharf(WSAMovie_v2 *wsaObj, int x, int y, int frm) { if (!_seqFrameCounter) seq_loadNestedSequence(0, kSequenceDemoWharf2); @@ -1675,7 +1682,7 @@ int KyraEngine_HoF::seq_demoWharf(WSAMovieV2 *wsaObj, int x, int y, int frm) { return 0; } -int KyraEngine_HoF::seq_demoDinob(WSAMovieV2 *wsaObj, int x, int y, int frm) { +int KyraEngine_HoF::seq_demoDinob(WSAMovie_v2 *wsaObj, int x, int y, int frm) { if (frm == 0) { if (!(_seqFrameCounter/8)) { seq_loadNestedSequence(0, kSequenceDemoDinob2); @@ -1696,7 +1703,7 @@ int KyraEngine_HoF::seq_demoDinob(WSAMovieV2 *wsaObj, int x, int y, int frm) { return 0; } -int KyraEngine_HoF::seq_demoFisher(WSAMovieV2 *wsaObj, int x, int y, int frm) { +int KyraEngine_HoF::seq_demoFisher(WSAMovie_v2 *wsaObj, int x, int y, int frm) { if (((_system->getMillis() - _seqStartTime) / (5 * _tickLength)) > 0) { _seqStartTime = _system->getMillis(); if (!_seqFrameCounter) { @@ -1738,14 +1745,14 @@ int KyraEngine_HoF::seq_demoFisher(WSAMovieV2 *wsaObj, int x, int y, int frm) { return 0; } -int KyraEngine_HoF::seq_demoWharf2(WSAMovieV2 *wsaObj, int x, int y, int frm) { +int KyraEngine_HoF::seq_demoWharf2(WSAMovie_v2 *wsaObj, int x, int y, int frm) { if (frm == 69) _seqWsaCurrentFrame = 8; return frm; } -int KyraEngine_HoF::seq_demoDinob2(WSAMovieV2 *wsaObj, int x, int y, int frm) { +int KyraEngine_HoF::seq_demoDinob2(WSAMovie_v2 *wsaObj, int x, int y, int frm) { switch (frm) { case 19: seq_playTalkText(13); @@ -1775,17 +1782,17 @@ int KyraEngine_HoF::seq_demoDinob2(WSAMovieV2 *wsaObj, int x, int y, int frm) { return frm; } -int KyraEngine_HoF::seq_demoWater(WSAMovieV2 *wsaObj, int x, int y, int frm) { +int KyraEngine_HoF::seq_demoWater(WSAMovie_v2 *wsaObj, int x, int y, int frm) { if (frm == 1) seq_playTalkText(11); return frm; } -int KyraEngine_HoF::seq_demoBail(WSAMovieV2 *wsaObj, int x, int y, int frm) { +int KyraEngine_HoF::seq_demoBail(WSAMovie_v2 *wsaObj, int x, int y, int frm) { return frm; } -int KyraEngine_HoF::seq_demoDig(WSAMovieV2 *wsaObj, int x, int y, int frm) { +int KyraEngine_HoF::seq_demoDig(WSAMovie_v2 *wsaObj, int x, int y, int frm) { return frm; } @@ -1806,7 +1813,7 @@ uint32 KyraEngine_HoF::seq_activeTextsTimeLeft() { } void KyraEngine_HoF::seq_processWSAs() { - for (int i = 0; i < 8; i++) { + for (int i = 0; i < 8; i++) { if (_activeWSA[i].flags != -1) { if (seq_processNextSubFrame(i)) seq_resetActiveWSA(i); @@ -2045,7 +2052,7 @@ void KyraEngine_HoF::seq_loadNestedSequence(int wsaNum, int seqNum) { NestedSequence s = _sequences->seqn[seqNum]; if (!_activeWSA[wsaNum].movie) { - _activeWSA[wsaNum].movie = new WSAMovieV2(this, _screen); + _activeWSA[wsaNum].movie = new WSAMovie_v2(this, _screen); assert(_activeWSA[wsaNum].movie); } @@ -2325,17 +2332,20 @@ void KyraEngine_HoF::seq_printCreditsString(uint16 strIndex, int x, int y, const _seqTextColor[0] = seqTextColor0; } -void KyraEngine_HoF::seq_playWsaSyncDialogue(uint16 strIndex, uint16 vocIndex, int textColor, int x, int y, int width, WSAMovieV2 *wsa, int firstframe, int lastframe, int wsaXpos, int wsaYpos) { +void KyraEngine_HoF::seq_playWsaSyncDialogue(uint16 strIndex, uint16 vocIndex, int textColor, int x, int y, int width, WSAMovie_v2 *wsa, int firstframe, int lastframe, int wsaXpos, int wsaYpos) { int dur = int(strlen(_sequenceStrings[strIndex])) * (_flags.isTalkie ? 7 : 15); int entry = textEnabled() ? seq_setTextEntry(strIndex, x, y, dur, width) : strIndex; _activeText[entry].textcolor = textColor; - uint32 chatTimeout = _system->getMillis() + dur * _tickLength; + _seqWsaChatTimeout = _system->getMillis() + dur * _tickLength; int curframe = firstframe; - if (vocIndex && speechEnabled()) + if (vocIndex && speechEnabled()) { + while (_sound->voiceIsPlaying() && !skipFlag()) + delay(4); seq_playTalkText(vocIndex); + } - while (_system->getMillis() < chatTimeout && !(_abortIntroFlag || skipFlag())) { + while (_system->getMillis() < _seqWsaChatTimeout && !(_abortIntroFlag || skipFlag())) { if (lastframe < 0) { int t = ABS(lastframe); if (t < curframe) @@ -2345,7 +2355,7 @@ void KyraEngine_HoF::seq_playWsaSyncDialogue(uint16 strIndex, uint16 vocIndex, i if (ABS(lastframe) < curframe) curframe = firstframe; - uint32 frameTimeout = _seqEndTime = _system->getMillis() + _seqFrameDelay * _tickLength; + _seqWsaChatFrameTimeout = _seqEndTime = _system->getMillis() + _seqFrameDelay * _tickLength; if (wsa) { wsa->setDrawPage(2); wsa->setX(wsaXpos); @@ -2358,8 +2368,8 @@ void KyraEngine_HoF::seq_playWsaSyncDialogue(uint16 strIndex, uint16 vocIndex, i seq_processText(); uint32 tm = _system->getMillis(); - if (frameTimeout > tm && chatTimeout > tm) - delay(MIN(frameTimeout - tm, chatTimeout - tm)); + if (_seqWsaChatFrameTimeout > tm && _seqWsaChatTimeout > tm) + delay(MIN(_seqWsaChatFrameTimeout - tm, _seqWsaChatTimeout - tm)); if (speechEnabled() && !textEnabled() && !snd_voiceIsPlaying()) break; @@ -2372,11 +2382,8 @@ void KyraEngine_HoF::seq_playWsaSyncDialogue(uint16 strIndex, uint16 vocIndex, i if (_abortIntroFlag || skipFlag()) _sound->voiceStop(); - if (lastframe < 0) { - int t = ABS(lastframe); - if (t < curframe) - curframe = t; - } + if (ABS(lastframe) < curframe) + curframe = ABS(lastframe); if (curframe == firstframe) curframe++; @@ -2390,27 +2397,46 @@ void KyraEngine_HoF::seq_displayScrollText(uint8 *data, const ScreenDim *d, int if (!data) return; - static const char mark[] = { 5, 13, 0}; + 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]; + struct ScrollTextData { + int16 x; + int16 y; + uint8 *text; + byte unk1; + byte height; + byte adjust; + + ScrollTextData() { + x = 0; // 0 11 + y = 0; // 2 13 + text = 0; // 4 15 + unk1 = 0; // 8 19 + height = 0; // 9 20 + adjust = 0; // 10 21 + } + }; + + ScrollTextData *textData = new ScrollTextData[36]; uint8 *ptr = data; - int strTblIndex = 0; bool loop = true; int cnt = 0; while (loop) { - uint32 endTime = _system->getMillis() + speed * _tickLength; + _seqSubFrameEndTimeInternal = _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; + uint16 cH; + + if (cnt) + cH = textData[cnt].y + textData[cnt].height + (textData[cnt].height >> 3); + else + cH = d->h; char *str = (char*)ptr; @@ -2418,12 +2444,15 @@ void KyraEngine_HoF::seq_displayScrollText(uint8 *data, const ScreenDim *d, int if (!ptr) ptr = (uint8*)strchr(str, 0); - tmp[m + 19] = *ptr; + textData[cnt + 1].unk1 = *ptr; *ptr = 0; - if (tmp[m + 19]) + if (textData[cnt + 1].unk1) ptr++; - tmp[m + 21] = (*str == 3 || *str == 4) ? tmp[m + 21] = *str++ : 0; + if (*str == 3 || *str == 4) + textData[cnt + 1].adjust = *str++; + else + textData[cnt + 1].adjust = 0; _screen->setFont(fid1); @@ -2434,18 +2463,25 @@ void KyraEngine_HoF::seq_displayScrollText(uint8 *data, const ScreenDim *d, int str++; } - tmp[m + 20] = _screen->getFontHeight(); + textData[cnt + 1].height = _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)); + switch (textData[cnt + 1].adjust) { + case 3: + textData[cnt + 1].x = 157 - _screen->getTextWidth(str); + break; + case 4: + textData[cnt + 1].x = 161; + break; + default: + textData[cnt + 1].x = (((d->w << 3) - _screen->getTextWidth(str)) >> 1) + 1; + break; + } - if (tmp[m + 8] == 5) - cH -= (tmp[m + 9] + (tmp[m + 9] >> 3)); + if (textData[cnt].unk1 == 5) + cH -= (textData[cnt].height + (textData[cnt].height >> 3)); - WRITE_LE_UINT16(&tmp[m + 13], cH); - WRITE_LE_UINT32(&tmp[m + 15], strTblIndex); - tmpStringTable[strTblIndex] = (uint8*) str; - strTblIndex = (strTblIndex + 1) % 35; + textData[cnt + 1].y = cH; + textData[cnt + 1].text = (uint8*) str; cnt++; } @@ -2455,11 +2491,10 @@ void KyraEngine_HoF::seq_displayScrollText(uint8 *data, const ScreenDim *d, int bool palCycle = 0; while (cnt2 < cnt) { - int m = cnt2 * 11; - const char *str = (const char*)tmpStringTable[READ_LE_UINT32(&tmp[m + 15])]; + const char *str = (const char*)textData[cnt2 + 1].text; const char *str2 = str; - uint16 cW = READ_LE_UINT16(&tmp[m + 11]) - 10; - uint16 cH = READ_LE_UINT16(&tmp[m + 13]); + int16 cW = textData[cnt2 + 1].x - 10; + int16 cH = textData[cnt2 + 1].y; int x = (d->sx << 3) + cW; int y = d->sy + cH; int col1 = 255; @@ -2467,7 +2502,7 @@ void KyraEngine_HoF::seq_displayScrollText(uint8 *data, const ScreenDim *d, int if (cH < d->h) { _screen->setCurPage(tempPage2); _screen->setFont(fid1); - if (tmp[m + 20] != _screen->getFontHeight()) + if (textData[cnt2 + 1].height != _screen->getFontHeight()) _screen->setFont(fid2); if (specialData) { @@ -2498,18 +2533,18 @@ void KyraEngine_HoF::seq_displayScrollText(uint8 *data, const ScreenDim *d, int _screen->setCurPage(0); } - WRITE_LE_UINT16(&tmp[m + 13], READ_LE_UINT16(&tmp[m + 13]) - step); + textData[cnt2 + 1].y -= 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]; + if (textData[1].y < -10) { + textData[1].text += strlen((char*)textData[1].text); + textData[1].text[0] = textData[1].unk1; cnt--; - memcpy(&tmp[11], &tmp[22], cnt * 11); + memcpy(&textData[1], &textData[2], cnt * sizeof(ScrollTextData)); } if (palCycle) { @@ -2519,9 +2554,9 @@ void KyraEngine_HoF::seq_displayScrollText(uint8 *data, const ScreenDim *d, int _screen->setScreenPalette(_screen->_currentPalette); } - delayUntil(endTime); + delayUntil(_seqSubFrameEndTimeInternal); - if ((cnt < 36) && ((d->sy + d->h) > (READ_LE_UINT16(&tmp[cnt * 11 + 2]) + tmp[cnt * 11 + 9])) && !skipFlag()) { + if ((cnt < 36) && ((d->sy + d->h) > (textData[cnt].y + textData[cnt].height)) && !skipFlag()) { resetSkipFlag(); delay(_tickLength * 500); cnt = 0; @@ -2537,8 +2572,7 @@ void KyraEngine_HoF::seq_displayScrollText(uint8 *data, const ScreenDim *d, int _abortIntroFlag= false; resetSkipFlag(); - delete [] tmp; - delete [] tmpStringTable; + delete[] textData; } void KyraEngine_HoF::seq_scrollPage() { @@ -2571,7 +2605,7 @@ void KyraEngine_HoF::seq_scrollPage() { } void KyraEngine_HoF::seq_showStarcraftLogo() { - WSAMovieV2 *ci = new WSAMovieV2(this, _screen); + WSAMovie_v2 *ci = new WSAMovie_v2(this, _screen); assert(ci); _screen->clearPage(2); _res->loadPakFile("INTROGEN.PAK"); @@ -2589,20 +2623,20 @@ void KyraEngine_HoF::seq_showStarcraftLogo() { _screen->copyPage(2, 0); _screen->fadeFromBlack(); for (int i = 1; i < endframe; i++) { - uint32 endTime = _system->getMillis() + 50; + _seqEndTime = _system->getMillis() + 50; if (skipFlag()) break; ci->displayFrame(i, 0); _screen->copyPage(2, 0); _screen->updateScreen(); - delay(endTime - _system->getMillis()); + delay(_seqEndTime - _system->getMillis()); } if(!skipFlag()) { - uint32 endTime = _system->getMillis() + 50; + _seqEndTime = _system->getMillis() + 50; ci->displayFrame(0, 0); _screen->copyPage(2, 0); _screen->updateScreen(); - delay(endTime - _system->getMillis()); + delay(_seqEndTime - _system->getMillis()); } _screen->fadeToBlack(); _screen->showMouse(); @@ -2613,7 +2647,7 @@ void KyraEngine_HoF::seq_showStarcraftLogo() { void KyraEngine_HoF::seq_init() { _seqProcessedString = new char[200]; - _seqWsa = new WSAMovieV2(this, _screen); + _seqWsa = new WSAMovie_v2(this, _screen); _activeWSA = new ActiveWSA[8]; _activeText = new ActiveText[10]; @@ -2623,12 +2657,12 @@ void KyraEngine_HoF::seq_init() { int numShp = -1; if (_flags.isDemo && !_flags.isTalkie) { - _demoAnimData = _staticres->loadHofShapeAnimDataV1(k2SeqplayShapeAnimData, _itemAnimDataSize); + _demoAnimData = _staticres->loadShapeAnimData_v1(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; + delete[] shp; do { numShp++; @@ -2647,26 +2681,24 @@ void KyraEngine_HoF::seq_init() { } void KyraEngine_HoF::seq_uninit() { - delete [] _seqProcessedString; + delete[] _seqProcessedString; _seqProcessedString = NULL; - delete [] _activeWSA; + delete[] _activeWSA; _activeWSA = NULL; - delete [] _activeText; + delete[] _activeText; _activeText = NULL; delete _seqWsa; _seqWsa = NULL; - delete [] _animShapeFiledata; + delete[] _animShapeFiledata; _animShapeFiledata = 0; if (_flags.isDemo && !_flags.isTalkie) _staticres->unloadId(k2SeqplayShapeAnimData); - _gameShapes.clear(); - delete _menu; _menu = 0; } @@ -2772,7 +2804,7 @@ void KyraEngine_HoF::seq_makeBookAppear() { } closeInvWsa(); - delete [] rect; + delete[] rect; _invWsa.running = false; _screen->showMouse(); @@ -2780,3 +2812,4 @@ void KyraEngine_HoF::seq_makeBookAppear() { } // end of namespace Kyra + diff --git a/engines/kyra/sequences_v1.cpp b/engines/kyra/sequences_lok.cpp index 01906d2529..b30568c7e2 100644 --- a/engines/kyra/sequences_v1.cpp +++ b/engines/kyra/sequences_lok.cpp @@ -23,14 +23,14 @@ * */ -#include "kyra/kyra.h" +#include "kyra/kyra_lok.h" #include "kyra/seqplayer.h" -#include "kyra/screen_v1.h" +#include "kyra/screen_lok.h" #include "kyra/resource.h" #include "kyra/sound.h" #include "kyra/sprites.h" #include "kyra/wsamovie.h" -#include "kyra/animator_v1.h" +#include "kyra/animator_lok.h" #include "kyra/text.h" #include "kyra/timer.h" @@ -40,8 +40,8 @@ namespace Kyra { -void KyraEngine_v1::seq_demo() { - debugC(9, kDebugLevelMain, "KyraEngine_v1::seq_demo()"); +void KyraEngine_LoK::seq_demo() { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::seq_demo()"); snd_playTheme(0, 2); @@ -90,18 +90,18 @@ void KyraEngine_v1::seq_demo() { _sound->haltTrack(); } -void KyraEngine_v1::seq_intro() { - debugC(9, kDebugLevelMain, "KyraEngine_v1::seq_intro()"); +void KyraEngine_LoK::seq_intro() { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::seq_intro()"); if (_flags.isTalkie) _res->loadPakFile("INTRO.VRM"); static const IntroProc introProcTable[] = { - &KyraEngine_v1::seq_introLogos, - &KyraEngine_v1::seq_introStory, - &KyraEngine_v1::seq_introMalcolmTree, - &KyraEngine_v1::seq_introKallakWriting, - &KyraEngine_v1::seq_introKallakMalcolm + &KyraEngine_LoK::seq_introLogos, + &KyraEngine_LoK::seq_introStory, + &KyraEngine_LoK::seq_introMalcolmTree, + &KyraEngine_LoK::seq_introKallakWriting, + &KyraEngine_LoK::seq_introKallakMalcolm }; Common::InSaveFile *in; @@ -130,8 +130,8 @@ void KyraEngine_v1::seq_intro() { _res->unloadPakFile("INTRO.VRM"); } -void KyraEngine_v1::seq_introLogos() { - debugC(9, kDebugLevelMain, "KyraEngine_v1::seq_introLogos()"); +void KyraEngine_LoK::seq_introLogos() { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::seq_introLogos()"); if (_flags.platform == Common::kPlatformFMTowns || _flags.platform == Common::kPlatformPC98) { _screen->loadBitmap("LOGO.CPS", 3, 3, _screen->_currentPalette); @@ -176,7 +176,7 @@ void KyraEngine_v1::seq_introLogos() { _screen->setScreenPalette(_screen->_currentPalette); } - if (_seq->playSequence(_seq_KyrandiaLogo, _skipFlag) && !seq_skipSequence() || _quitFlag) { + if ((_seq->playSequence(_seq_KyrandiaLogo, _skipFlag) && !seq_skipSequence()) || _quitFlag) { _screen->fadeToBlack(); _screen->clearPage(0); return; @@ -232,8 +232,8 @@ void KyraEngine_v1::seq_introLogos() { _seq->playSequence(_seq_Forest, true); } -void KyraEngine_v1::seq_introStory() { - debugC(9, kDebugLevelMain, "KyraEngine_v1::seq_introStory()"); +void KyraEngine_LoK::seq_introStory() { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::seq_introStory()"); _screen->clearPage(3); _screen->clearPage(0); @@ -279,15 +279,15 @@ void KyraEngine_v1::seq_introStory() { delay(360 * _tickLength); } -void KyraEngine_v1::seq_introMalcolmTree() { - debugC(9, kDebugLevelMain, "KyraEngine_v1::seq_introMalcolmTree()"); +void KyraEngine_LoK::seq_introMalcolmTree() { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::seq_introMalcolmTree()"); _screen->_curPage = 0; _screen->clearPage(3); _seq->playSequence(_seq_MalcolmTree, true); } -void KyraEngine_v1::seq_introKallakWriting() { - debugC(9, kDebugLevelMain, "KyraEngine_v1::seq_introKallakWriting()"); +void KyraEngine_LoK::seq_introKallakWriting() { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::seq_introKallakWriting()"); _seq->makeHandShapes(); _screen->setAnimBlockPtr(5060); _screen->_charWidth = -2; @@ -295,13 +295,13 @@ void KyraEngine_v1::seq_introKallakWriting() { _seq->playSequence(_seq_KallakWriting, true); } -void KyraEngine_v1::seq_introKallakMalcolm() { - debugC(9, kDebugLevelMain, "KyraEngine_v1::seq_introKallakMalcolm()"); +void KyraEngine_LoK::seq_introKallakMalcolm() { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::seq_introKallakMalcolm()"); _screen->clearPage(3); _seq->playSequence(_seq_KallakMalcolm, true); } -void KyraEngine_v1::seq_createAmuletJewel(int jewel, int page, int noSound, int drawOnly) { +void KyraEngine_LoK::seq_createAmuletJewel(int jewel, int page, int noSound, int drawOnly) { debugC(9, kDebugLevelMain, "seq_createAmuletJewel(%d, %d, %d, %d)", jewel, page, noSound, drawOnly); static const uint16 specialJewelTable[] = { 0x167, 0x162, 0x15D, 0x158, 0x153, 0xFFFF @@ -361,7 +361,7 @@ void KyraEngine_v1::seq_createAmuletJewel(int jewel, int page, int noSound, int setGameFlag(0x55+jewel); } -void KyraEngine_v1::seq_brandonHealing() { +void KyraEngine_LoK::seq_brandonHealing() { debugC(9, kDebugLevelMain, "seq_brandonHealing()"); if (!(_deathHandler & 8)) return; @@ -392,7 +392,7 @@ void KyraEngine_v1::seq_brandonHealing() { _screen->showMouse(); } -void KyraEngine_v1::seq_brandonHealing2() { +void KyraEngine_LoK::seq_brandonHealing2() { debugC(9, kDebugLevelMain, "seq_brandonHealing2()"); _screen->hideMouse(); checkAmuletAnimFlags(); @@ -416,7 +416,7 @@ void KyraEngine_v1::seq_brandonHealing2() { characterSays(2011, _poisonGone[1], 0, -2); } -void KyraEngine_v1::seq_poisonDeathNow(int now) { +void KyraEngine_LoK::seq_poisonDeathNow(int now) { debugC(9, kDebugLevelMain, "seq_poisonDeathNow(%d)", now); if (!(_brandonStatusBit & 1)) return; @@ -437,7 +437,7 @@ void KyraEngine_v1::seq_poisonDeathNow(int now) { } } -void KyraEngine_v1::seq_poisonDeathNowAnim() { +void KyraEngine_LoK::seq_poisonDeathNowAnim() { debugC(9, kDebugLevelMain, "seq_poisonDeathNowAnim()"); _screen->hideMouse(); checkAmuletAnimFlags(); @@ -478,7 +478,7 @@ void KyraEngine_v1::seq_poisonDeathNowAnim() { _screen->showMouse(); } -void KyraEngine_v1::seq_playFluteAnimation() { +void KyraEngine_LoK::seq_playFluteAnimation() { debugC(9, kDebugLevelMain, "seq_playFluteAnimation()"); _screen->hideMouse(); checkAmuletAnimFlags(); @@ -532,7 +532,7 @@ void KyraEngine_v1::seq_playFluteAnimation() { } } -void KyraEngine_v1::seq_winterScroll1() { +void KyraEngine_LoK::seq_winterScroll1() { debugC(9, kDebugLevelMain, "seq_winterScroll1()"); _screen->hideMouse(); checkAmuletAnimFlags(); @@ -613,7 +613,7 @@ void KyraEngine_v1::seq_winterScroll1() { _screen->showMouse(); } -void KyraEngine_v1::seq_winterScroll2() { +void KyraEngine_LoK::seq_winterScroll2() { debugC(9, kDebugLevelMain, "seq_winterScroll2()"); _screen->hideMouse(); checkAmuletAnimFlags(); @@ -642,7 +642,7 @@ void KyraEngine_v1::seq_winterScroll2() { _screen->showMouse(); } -void KyraEngine_v1::seq_makeBrandonInv() { +void KyraEngine_LoK::seq_makeBrandonInv() { debugC(9, kDebugLevelMain, "seq_makeBrandonInv()"); if (_deathHandler == 8) return; @@ -668,7 +668,7 @@ void KyraEngine_v1::seq_makeBrandonInv() { _screen->showMouse(); } -void KyraEngine_v1::seq_makeBrandonNormal() { +void KyraEngine_LoK::seq_makeBrandonNormal() { debugC(9, kDebugLevelMain, "seq_makeBrandonNormal()"); _screen->hideMouse(); _brandonStatusBit |= 0x40; @@ -684,7 +684,7 @@ void KyraEngine_v1::seq_makeBrandonNormal() { _screen->showMouse(); } -void KyraEngine_v1::seq_makeBrandonNormal2() { +void KyraEngine_LoK::seq_makeBrandonNormal2() { debugC(9, kDebugLevelMain, "seq_makeBrandonNormal2()"); _screen->hideMouse(); assert(_brandonToWispTable); @@ -710,7 +710,7 @@ void KyraEngine_v1::seq_makeBrandonNormal2() { _screen->showMouse(); } -void KyraEngine_v1::seq_makeBrandonWisp() { +void KyraEngine_LoK::seq_makeBrandonWisp() { debugC(9, kDebugLevelMain, "seq_makeBrandonWisp()"); if (_deathHandler == 8) return; @@ -752,7 +752,7 @@ void KyraEngine_v1::seq_makeBrandonWisp() { _screen->showMouse(); } -void KyraEngine_v1::seq_dispelMagicAnimation() { +void KyraEngine_LoK::seq_dispelMagicAnimation() { debugC(9, kDebugLevelMain, "seq_dispelMagicAnimation()"); if (_deathHandler == 8) return; @@ -794,7 +794,7 @@ void KyraEngine_v1::seq_dispelMagicAnimation() { _screen->showMouse(); } -void KyraEngine_v1::seq_fillFlaskWithWater(int item, int type) { +void KyraEngine_LoK::seq_fillFlaskWithWater(int item, int type) { debugC(9, kDebugLevelMain, "seq_fillFlaskWithWater(%d, %d)", item, type); int newItem = -1; static const uint8 flaskTable1[] = { 0x46, 0x48, 0x4A, 0x4C }; @@ -827,8 +827,8 @@ void KyraEngine_v1::seq_fillFlaskWithWater(int item, int type) { characterSays(voiceEntries[type], _fullFlask[type], 0, -2); } -void KyraEngine_v1::seq_playDrinkPotionAnim(int item, int unk2, int flags) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::seq_playDrinkPotionAnim(%d, %d, %d)", item, unk2, flags); +void KyraEngine_LoK::seq_playDrinkPotionAnim(int item, int unk2, int flags) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::seq_playDrinkPotionAnim(%d, %d, %d)", item, unk2, flags); uint8 red, green, blue; switch (item) { @@ -919,8 +919,8 @@ void KyraEngine_v1::seq_playDrinkPotionAnim(int item, int unk2, int flags) { _screen->showMouse(); } -int KyraEngine_v1::seq_playEnd() { - debugC(9, kDebugLevelMain, "KyraEngine_v1::seq_playEnd()"); +int KyraEngine_LoK::seq_playEnd() { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::seq_playEnd()"); if (_endSequenceSkipFlag) return 0; @@ -931,13 +931,13 @@ int KyraEngine_v1::seq_playEnd() { if (_endSequenceNeedLoading) { snd_playWanderScoreViaMap(50, 1); setupPanPages(); - _finalA = new WSAMovieV1(this); + _finalA = new WSAMovie_v1(this); assert(_finalA); _finalA->open("finala.wsa", 1, 0); - _finalB = new WSAMovieV1(this); + _finalB = new WSAMovie_v1(this); assert(_finalB); _finalB->open("finalb.wsa", 1, 0); - _finalC = new WSAMovieV1(this); + _finalC = new WSAMovie_v1(this); assert(_finalC); _endSequenceNeedLoading = 0; _finalC->open("finalc.wsa", 1, 0); @@ -981,7 +981,7 @@ int KyraEngine_v1::seq_playEnd() { _screen->setScreenPalette(_screen->_currentPalette); _screen->shuffleScreen(8, 8, 304, 128, 2, 0, 1, 0); uint32 nextTime = _system->getMillis() + 120 * _tickLength; - _finalA = new WSAMovieV1(this); + _finalA = new WSAMovie_v1(this); assert(_finalA); _finalA->open("finald.wsa", 1, 0); _finalA->setX(8); _finalA->setY(8); @@ -1012,8 +1012,8 @@ int KyraEngine_v1::seq_playEnd() { return 0; } -void KyraEngine_v1::seq_brandonToStone() { - debugC(9, kDebugLevelMain, "KyraEngine_v1::seq_brandonToStone()"); +void KyraEngine_LoK::seq_brandonToStone() { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::seq_brandonToStone()"); _screen->hideMouse(); assert(_brandonStoneTable); setupShapes123(_brandonStoneTable, 14, 0); @@ -1028,8 +1028,8 @@ void KyraEngine_v1::seq_brandonToStone() { _screen->showMouse(); } -void KyraEngine_v1::seq_playEnding() { - debugC(9, kDebugLevelMain, "KyraEngine_v1::seq_playEnding()"); +void KyraEngine_LoK::seq_playEnding() { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::seq_playEnding()"); if (_quitFlag) return; _screen->hideMouse(); @@ -1052,8 +1052,8 @@ void KyraEngine_v1::seq_playEnding() { seq_playCredits(); } -void KyraEngine_v1::seq_playCredits() { - debugC(9, kDebugLevelMain, "KyraEngine_v1::seq_playCredits()"); +void KyraEngine_LoK::seq_playCredits() { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::seq_playCredits()"); static const uint8 colorMap[] = { 0, 0, 0xC, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; static const char stringTerms[] = { 0x5, 0xd, 0x0}; static const int numStrings = 250; @@ -1091,12 +1091,12 @@ void KyraEngine_v1::seq_playCredits() { if (_flags.platform == Common::kPlatformFMTowns || _flags.platform == Common::kPlatformPC98) { int sizeTmp = 0; - const uint8 *bufferTmp = _staticres->loadRawData(kCreditsStrings, sizeTmp); + const uint8 *bufferTmp = _staticres->loadRawData(k1CreditsStrings, sizeTmp); buffer = new uint8[sizeTmp]; assert(buffer); memcpy(buffer, bufferTmp, sizeTmp); size = sizeTmp; - _staticres->unloadId(kCreditsStrings); + _staticres->unloadId(k1CreditsStrings); } else { buffer = _res->fileData("CREDITS.TXT", &size); assert(buffer); @@ -1202,20 +1202,20 @@ void KyraEngine_v1::seq_playCredits() { _system->delayMillis(nextLoop - now); } - delete [] buffer; + delete[] buffer; _screen->fadeToBlack(); _screen->clearCurPage(); _screen->showMouse(); } -bool KyraEngine_v1::seq_skipSequence() const { - debugC(9, kDebugLevelMain, "KyraEngine_v1::seq_skipSequence()"); +bool KyraEngine_LoK::seq_skipSequence() const { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::seq_skipSequence()"); return _quitFlag || _abortIntroFlag; } -int KyraEngine_v1::handleMalcolmFlag() { - debugC(9, kDebugLevelMain, "KyraEngine_v1::handleMalcolmFlag()"); +int KyraEngine_LoK::handleMalcolmFlag() { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::handleMalcolmFlag()"); static uint16 frame = 0; static uint32 timer1 = 0; static uint32 timer2 = 0; @@ -1383,8 +1383,8 @@ int KyraEngine_v1::handleMalcolmFlag() { return 0; } -int KyraEngine_v1::handleBeadState() { - debugC(9, kDebugLevelMain, "KyraEngine_v1::handleBeadState()"); +int KyraEngine_LoK::handleBeadState() { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::handleBeadState()"); static uint32 timer1 = 0; static uint32 timer2 = 0; static BeadState beadState1 = { -1, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; @@ -1603,8 +1603,8 @@ int KyraEngine_v1::handleBeadState() { return 0; } -void KyraEngine_v1::initBeadState(int x, int y, int x2, int y2, int unk, BeadState *ptr) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::initBeadState(%d, %d, %d, %d, %d, %p)", x, y, x2, y2, unk, (const void *)ptr); +void KyraEngine_LoK::initBeadState(int x, int y, int x2, int y2, int unk, BeadState *ptr) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::initBeadState(%d, %d, %d, %d, %d, %p)", x, y, x2, y2, unk, (const void *)ptr); ptr->unk9 = unk; int xDiff = x2 - x; int yDiff = y2 - y; @@ -1637,8 +1637,8 @@ void KyraEngine_v1::initBeadState(int x, int y, int x2, int y2, int unk, BeadSta ptr->unk8 = unk2; } -int KyraEngine_v1::processBead(int x, int y, int &x2, int &y2, BeadState *ptr) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::processBead(%d, %d, %p, %p, %p)", x, y, (const void *)&x2, (const void *)&y2, (const void *)ptr); +int KyraEngine_LoK::processBead(int x, int y, int &x2, int &y2, BeadState *ptr) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::processBead(%d, %d, %p, %p, %p)", x, y, (const void *)&x2, (const void *)&y2, (const void *)ptr); if (x == ptr->dstX && y == ptr->dstY) return 1; @@ -1674,21 +1674,21 @@ int KyraEngine_v1::processBead(int x, int y, int &x2, int &y2, BeadState *ptr) { return 0; } -void KyraEngine_v1::setupPanPages() { - debugC(9, kDebugLevelMain, "KyraEngine_v1::setupPanPages()"); +void KyraEngine_LoK::setupPanPages() { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::setupPanPages()"); _screen->savePageToDisk("BKGD.PG", 2); _screen->loadBitmap("BEAD.CPS", 3, 3, 0); if (_flags.platform == Common::kPlatformMacintosh || _flags.platform == Common::kPlatformAmiga) { int pageBackUp = _screen->_curPage; _screen->_curPage = 2; - delete [] _panPagesTable[19]; + delete[] _panPagesTable[19]; _panPagesTable[19] = _screen->encodeShape(0, 0, 16, 9, 0); assert(_panPagesTable[19]); int curX = 16; for (int i = 0; i < 19; ++i) { - delete [] _panPagesTable[i]; + delete[] _panPagesTable[i]; _panPagesTable[i] = _screen->encodeShape(curX, 0, 8, 5, 0); assert(_panPagesTable[i]); curX += 8; @@ -1697,7 +1697,7 @@ void KyraEngine_v1::setupPanPages() { _screen->_curPage = pageBackUp; } else { for (int i = 0; i <= 19; ++i) { - delete [] _panPagesTable[i]; + delete[] _panPagesTable[i]; _panPagesTable[i] = _seq->setPanPages(3, i); assert(_panPagesTable[i]); } @@ -1705,18 +1705,18 @@ void KyraEngine_v1::setupPanPages() { _screen->loadPageFromDisk("BKGD.PG", 2); } -void KyraEngine_v1::freePanPages() { - debugC(9, kDebugLevelMain, "KyraEngine_v1::freePanPages()"); +void KyraEngine_LoK::freePanPages() { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::freePanPages()"); delete _endSequenceBackUpRect; _endSequenceBackUpRect = 0; for (int i = 0; i <= 19; ++i) { - delete [] _panPagesTable[i]; + delete[] _panPagesTable[i]; _panPagesTable[i] = 0; } } -void KyraEngine_v1::closeFinalWsa() { - debugC(9, kDebugLevelMain, "KyraEngine_v1::closeFinalWsa()"); +void KyraEngine_LoK::closeFinalWsa() { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::closeFinalWsa()"); delete _finalA; _finalA = 0; delete _finalB; @@ -1727,7 +1727,7 @@ void KyraEngine_v1::closeFinalWsa() { _endSequenceNeedLoading = 1; } -void KyraEngine_v1::updateKyragemFading() { +void KyraEngine_LoK::updateKyragemFading() { static const uint8 kyraGemPalette[0x28] = { 0x3F, 0x3B, 0x38, 0x34, 0x32, 0x2F, 0x2C, 0x29, 0x25, 0x22, 0x1F, 0x1C, 0x19, 0x16, 0x12, 0x0F, 0x0C, 0x0A, 0x06, 0x03, @@ -1797,8 +1797,8 @@ void KyraEngine_v1::updateKyragemFading() { _kyragemFadingState.timerCount = _system->getMillis() + 120 * _tickLength; } -void KyraEngine_v1::drawJewelPress(int jewel, int drawSpecial) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::drawJewelPress(%d, %d)", jewel, drawSpecial); +void KyraEngine_LoK::drawJewelPress(int jewel, int drawSpecial) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::drawJewelPress(%d, %d)", jewel, drawSpecial); _screen->hideMouse(); int shape = 0; @@ -1822,8 +1822,8 @@ void KyraEngine_v1::drawJewelPress(int jewel, int drawSpecial) { _screen->showMouse(); } -void KyraEngine_v1::drawJewelsFadeOutStart() { - debugC(9, kDebugLevelMain, "KyraEngine_v1::drawJewelsFadeOutStart()"); +void KyraEngine_LoK::drawJewelsFadeOutStart() { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::drawJewelsFadeOutStart()"); static const uint16 jewelTable1[] = { 0x164, 0x15F, 0x15A, 0x155, 0x150, 0xFFFF }; static const uint16 jewelTable2[] = { 0x163, 0x15E, 0x159, 0x154, 0x14F, 0xFFFF }; static const uint16 jewelTable3[] = { 0x166, 0x160, 0x15C, 0x157, 0x152, 0xFFFF }; @@ -1842,8 +1842,8 @@ void KyraEngine_v1::drawJewelsFadeOutStart() { } } -void KyraEngine_v1::drawJewelsFadeOutEnd(int jewel) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::drawJewelsFadeOutEnd(%d)", jewel); +void KyraEngine_LoK::drawJewelsFadeOutEnd(int jewel) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::drawJewelsFadeOutEnd(%d)", jewel); static const uint16 jewelTable[] = { 0x153, 0x158, 0x15D, 0x162, 0x148, 0xFFFF }; int newDelay = 0; diff --git a/engines/kyra/sequences_mr.cpp b/engines/kyra/sequences_mr.cpp index 8c826e2048..f41ed9c2f3 100644 --- a/engines/kyra/sequences_mr.cpp +++ b/engines/kyra/sequences_mr.cpp @@ -241,7 +241,7 @@ 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; + delete[] filedata; setNextIdleAnimTimer(); } diff --git a/engines/kyra/sequences_v2.cpp b/engines/kyra/sequences_v2.cpp index aef510a616..cc4b8528a4 100644 --- a/engines/kyra/sequences_v2.cpp +++ b/engines/kyra/sequences_v2.cpp @@ -102,17 +102,14 @@ void KyraEngine_v2::processAnimationScript(int allowSkip, int resetChar) { uint32 delayEnd = _system->getMillis() + _animDelayTime * _tickLength; - while ((!skipFlag() || !allowSkip) && _system->getMillis() < delayEnd) { - if (_chatText) - updateWithText(); - else - update(); + while ((!skipFlag() || !allowSkip) && _system->getMillis() < delayEnd) + delay(10, true); - delay(10); - } - - if (skipFlag()) + if (skipFlag()) { resetSkipFlag(); + if (allowSkip) + break; + } } if (resetChar) { diff --git a/engines/kyra/sound.cpp b/engines/kyra/sound.cpp index 887e9c7267..f56c43aabd 100644 --- a/engines/kyra/sound.cpp +++ b/engines/kyra/sound.cpp @@ -40,7 +40,7 @@ namespace Kyra { -Sound::Sound(KyraEngine *vm, Audio::Mixer *mixer) +Sound::Sound(KyraEngine_v1 *vm, Audio::Mixer *mixer) : _vm(vm), _mixer(mixer), _soundChannels(), _musicEnabled(1), _sfxEnabled(true), _soundDataList(0) { } @@ -50,9 +50,9 @@ Sound::~Sound() { bool Sound::voiceFileIsPresent(const char *file) { char filenamebuffer[25]; - for (int i = 0; _supportedCodes[i].fileext; ++i) { + for (int i = 0; _supportedCodecs[i].fileext; ++i) { strcpy(filenamebuffer, file); - strcat(filenamebuffer, _supportedCodes[i].fileext); + strcat(filenamebuffer, _supportedCodecs[i].fileext); if (_vm->resource()->getFileSize(filenamebuffer) > 0) return true; } @@ -66,51 +66,48 @@ bool Sound::voiceFileIsPresent(const char *file) { return false; } -bool Sound::voicePlay(const char *file, bool isSfx) { - uint32 fileSize = 0; - byte *fileData = 0; - bool found = false; +int32 Sound::voicePlay(const char *file, bool isSfx) { char filenamebuffer[25]; int h = 0; while (_mixer->isSoundHandleActive(_soundChannels[h].channelHandle) && h < kNumChannelHandles) h++; if (h >= kNumChannelHandles) - return false; + return 0; Audio::AudioStream *audioStream = 0; - for (int i = 0; _supportedCodes[i].fileext; ++i) { + for (int i = 0; _supportedCodecs[i].fileext; ++i) { strcpy(filenamebuffer, file); - strcat(filenamebuffer, _supportedCodes[i].fileext); + strcat(filenamebuffer, _supportedCodecs[i].fileext); Common::SeekableReadStream *stream = _vm->resource()->getFileStream(filenamebuffer); if (!stream) continue; - audioStream = _supportedCodes[i].streamFunc(stream, true, 0, 0, 1); - found = true; + audioStream = _supportedCodecs[i].streamFunc(stream, true, 0, 0, 1); break; } - if (!found) { + if (!audioStream) { strcpy(filenamebuffer, file); strcat(filenamebuffer, ".VOC"); - fileData = _vm->resource()->fileData(filenamebuffer, &fileSize); + uint32 fileSize = 0; + byte *fileData = _vm->resource()->fileData(filenamebuffer, &fileSize); if (!fileData) - return false; + return 0; Common::MemoryReadStream vocStream(fileData, fileSize); audioStream = Audio::makeVOCStream(vocStream); + + delete[] fileData; + fileSize = 0; } _soundChannels[h].file = file; _mixer->playInputStream(isSfx ? Audio::Mixer::kSFXSoundType : Audio::Mixer::kSpeechSoundType, &_soundChannels[h].channelHandle, audioStream); - delete [] fileData; - fileSize = 0; - - return true; + return audioStream->getTotalPlayTime(); } void Sound::voiceStop(const char *file) { @@ -143,9 +140,21 @@ bool Sound::voiceIsPlaying(const char *file) { return res; } +uint32 Sound::voicePlayedTime(const char *file) { + if (!file) + return 0; + + for (int i = 0; i < kNumChannelHandles; ++i) { + if (_soundChannels[i].file == file) + return _mixer->getSoundElapsedTime(_soundChannels[i].channelHandle); + } + + return 0; +} + #pragma mark - -SoundMidiPC::SoundMidiPC(KyraEngine *vm, Audio::Mixer *mixer, MidiDriver *driver) : Sound(vm, mixer) { +SoundMidiPC::SoundMidiPC(KyraEngine_v1 *vm, Audio::Mixer *mixer, MidiDriver *driver) : Sound(vm, mixer) { _driver = driver; _passThrough = false; @@ -320,7 +329,7 @@ void SoundMidiPC::metaEvent(byte type, byte *data, uint16 length) { struct DeleterArray { void operator ()(byte *ptr) { - delete [] ptr; + delete[] ptr; } }; @@ -467,8 +476,8 @@ void SoundMidiPC::beginFadeOut() { #pragma mark - -void KyraEngine::snd_playTheme(int file, int track) { - debugC(9, kDebugLevelMain | kDebugLevelSound, "KyraEngine::snd_playTheme(%d, %d)", file, track); +void KyraEngine_v1::snd_playTheme(int file, int track) { + debugC(9, kDebugLevelMain | kDebugLevelSound, "KyraEngine_v1::snd_playTheme(%d, %d)", file, track); if (_curMusicTheme == file) return; @@ -478,13 +487,13 @@ void KyraEngine::snd_playTheme(int file, int track) { _sound->playTrack(track); } -void KyraEngine::snd_playSoundEffect(int track, int volume) { - debugC(9, kDebugLevelMain | kDebugLevelSound, "KyraEngine::snd_playSoundEffect(%d, %d)", track, volume); +void KyraEngine_v1::snd_playSoundEffect(int track, int volume) { + debugC(9, kDebugLevelMain | kDebugLevelSound, "KyraEngine_v1::snd_playSoundEffect(%d, %d)", track, volume); _sound->playSoundEffect(track); } -void KyraEngine::snd_playWanderScoreViaMap(int command, int restart) { - debugC(9, kDebugLevelMain | kDebugLevelSound, "KyraEngine::snd_playWanderScoreViaMap(%d, %d)", command, restart); +void KyraEngine_v1::snd_playWanderScoreViaMap(int command, int restart) { + debugC(9, kDebugLevelMain | kDebugLevelSound, "KyraEngine_v1::snd_playWanderScoreViaMap(%d, %d)", command, restart); if (restart) _lastMusicCommand = -1; @@ -527,19 +536,22 @@ void KyraEngine::snd_playWanderScoreViaMap(int command, int restart) { _lastMusicCommand = command; } -void KyraEngine::snd_stopVoice() { - debugC(9, kDebugLevelMain | kDebugLevelSound, "KyraEngine::snd_stopVoice()"); - _sound->voiceStop(_speechFile.empty() ? 0 : _speechFile.c_str()); +void KyraEngine_v1::snd_stopVoice() { + debugC(9, kDebugLevelMain | kDebugLevelSound, "KyraEngine_v1::snd_stopVoice()"); + if (!_speechFile.empty()) { + _sound->voiceStop(_speechFile.c_str()); + _speechFile.clear(); + } } -bool KyraEngine::snd_voiceIsPlaying() { - debugC(9, kDebugLevelMain | kDebugLevelSound, "KyraEngine::snd_voiceIsPlaying()"); - return _sound->voiceIsPlaying(_speechFile.empty() ? 0 : _speechFile.c_str()); +bool KyraEngine_v1::snd_voiceIsPlaying() { + debugC(9, kDebugLevelMain | kDebugLevelSound, "KyraEngine_v1::snd_voiceIsPlaying()"); + return _speechFile.empty() ? false : _sound->voiceIsPlaying(_speechFile.c_str()); } // static res -const Sound::SpeechCodecs Sound::_supportedCodes[] = { +const Sound::SpeechCodecs Sound::_supportedCodecs[] = { #ifdef USE_FLAC { ".VOF", Audio::makeFlacStream }, #endif // USE_FLAC diff --git a/engines/kyra/sound.h b/engines/kyra/sound.h index 85648f6b7e..1baeb3064a 100644 --- a/engines/kyra/sound.h +++ b/engines/kyra/sound.h @@ -18,7 +18,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * - * LPGL License + * LGPL License * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -42,7 +42,7 @@ #ifndef KYRA_SOUND_H #define KYRA_SOUND_H -#include "kyra/kyra.h" +#include "kyra/kyra_v1.h" #include "common/scummsys.h" #include "common/file.h" @@ -61,12 +61,12 @@ namespace Kyra { /** * Analog audio output device API for Kyrandia games. - * It countains functionallity to play music tracks, + * It contains functionality to play music tracks, * sound effects and voices. */ class Sound { public: - Sound(KyraEngine *vm, Audio::Mixer *mixer); + Sound(KyraEngine_v1 *vm, Audio::Mixer *mixer); virtual ~Sound(); enum kType { @@ -92,7 +92,7 @@ public: virtual void process() {} /** - * Updates internal volume settings according to ConfigManager + * Updates internal volume settings according to ConfigManager. */ virtual void updateVolumeSettings() {} @@ -105,7 +105,7 @@ public: virtual void setSoundList(const AudioDataStruct *list) { _soundDataList = list; } /** - * Checks if a given sound file is present + * Checks if a given sound file is present. * * @param track track number * @return true if available, false otherwise @@ -126,19 +126,19 @@ public: virtual void playTrack(uint8 track) = 0; /** - * Stop playback of the current track + * Stop playback of the current track. */ virtual void haltTrack() = 0; /** - * Plays the specified sound effect + * Plays the specified sound effect. * * @param track sound effect id */ virtual void playSoundEffect(uint8 track) = 0; /** - * Checks if the sound driver plays any sound + * Checks if the sound driver plays any sound. * * @return true if playing, false otherwise */ @@ -174,9 +174,9 @@ public: * * @param file file to be played * @param isSfx marks file as sfx instead of voice - * @return channel the voice file is played on + * @return playtime of the voice file (-1 marks unknown playtime) */ - virtual bool voicePlay(const char *file, bool isSfx = false); + virtual int32 voicePlay(const char *file, bool isSfx = false); /** * Checks if a voice is being played. @@ -186,13 +186,20 @@ public: bool voiceIsPlaying(const char *file = 0); /** + * Checks how long a voice has been playing + * + * @return time in milliseconds + */ + uint32 voicePlayedTime(const char *file); + + /** * Stops playback of the current voice. */ void voiceStop(const char *file = 0); protected: const char *fileListEntry(int file) const { return (_soundDataList != 0 && file >= 0 && file < _soundDataList->_fileListLen) ? _soundDataList->_fileList[file] : ""; } const void *cdaData() const { return _soundDataList != 0 ? _soundDataList->_cdaTracks : 0; } - const int cdaTrackNum() const { return _soundDataList != 0 ? _soundDataList->_cdaNumTracks : 0; } + int cdaTrackNum() const { return _soundDataList != 0 ? _soundDataList->_cdaNumTracks : 0; } enum { kNumChannelHandles = 4 @@ -209,7 +216,7 @@ protected: int _currentTheme; - KyraEngine *_vm; + KyraEngine_v1 *_vm; Audio::Mixer *_mixer; private: @@ -225,7 +232,7 @@ private: uint numLoops); }; - static const SpeechCodecs _supportedCodes[]; + static const SpeechCodecs _supportedCodecs[]; }; class AdlibDriver; @@ -243,7 +250,7 @@ class AdlibDriver; */ class SoundAdlibPC : public Sound { public: - SoundAdlibPC(KyraEngine *vm, Audio::Mixer *mixer); + SoundAdlibPC(KyraEngine_v1 *vm, Audio::Mixer *mixer); ~SoundAdlibPC(); kType getMusicType() const { return kAdlib; } @@ -298,7 +305,7 @@ private: */ class SoundMidiPC : public MidiDriver, public Sound { public: - SoundMidiPC(KyraEngine *vm, Audio::Mixer *mixer, MidiDriver *driver); + SoundMidiPC(KyraEngine_v1 *vm, Audio::Mixer *mixer, MidiDriver *driver); ~SoundMidiPC(); kType getMusicType() const { return isMT32() ? kMidiMT32 : kMidiGM; } @@ -378,7 +385,7 @@ private: class SoundTowns_EuphonyDriver; class SoundTowns : public MidiDriver, public Sound { public: - SoundTowns(KyraEngine *vm, Audio::Mixer *mixer); + SoundTowns(KyraEngine_v1 *vm, Audio::Mixer *mixer); ~SoundTowns(); kType getMusicType() const { return kTowns; } @@ -435,7 +442,7 @@ private: //class SoundTowns_v2_TwnDriver; class SoundTowns_v2 : public Sound { public: - SoundTowns_v2(KyraEngine *vm, Audio::Mixer *mixer); + SoundTowns_v2(KyraEngine_v1 *vm, Audio::Mixer *mixer); ~SoundTowns_v2(); kType getMusicType() const { return kTowns; } @@ -449,7 +456,7 @@ public: void haltTrack(); void beginFadeOut(); - bool voicePlay(const char *file, bool isSfx = false); + int32 voicePlay(const char *file, bool isSfx = false); void playSoundEffect(uint8) {} private: @@ -463,7 +470,7 @@ private: class MixedSoundDriver : public Sound { public: - MixedSoundDriver(KyraEngine *vm, Audio::Mixer *mixer, Sound *music, Sound *sfx) : Sound(vm, mixer), _music(music), _sfx(sfx) {} + MixedSoundDriver(KyraEngine_v1 *vm, Audio::Mixer *mixer, Sound *music, Sound *sfx) : Sound(vm, mixer), _music(music), _sfx(sfx) {} ~MixedSoundDriver() { delete _music; delete _sfx; } kType getMusicType() const { return _music->getMusicType(); } @@ -491,6 +498,8 @@ private: // Digital Audio class AUDStream; +class KyraAudioStream; +class KyraEngine_MR; /** * Digital audio output device. @@ -499,7 +508,7 @@ class AUDStream; */ class SoundDigital { public: - SoundDigital(KyraEngine *vm, Audio::Mixer *mixer); + SoundDigital(KyraEngine_MR *vm, Audio::Mixer *mixer); ~SoundDigital(); bool init() { return true; } @@ -535,7 +544,7 @@ public: void stopSound(int channel); /** - * Stops playback of all sounds + * Stops playback of all sounds. */ void stopAllSounds(); @@ -548,7 +557,7 @@ public: */ void beginFadeOut(int channel, int ticks); private: - KyraEngine *_vm; + KyraEngine_MR *_vm; Audio::Mixer *_mixer; struct Sound { @@ -556,8 +565,20 @@ private: char filename[16]; uint8 priority; - AUDStream *stream; + KyraAudioStream *stream; } _sounds[4]; + + struct AudioCodecs { + const char *fileext; + Audio::AudioStream *(*streamFunc)( + Common::SeekableReadStream *stream, + bool disposeAfterUse, + uint32 startTime, + uint32 duration, + uint numLoops); + }; + + static const AudioCodecs _supportedCodecs[]; }; } // end of namespace Kyra diff --git a/engines/kyra/sound_adlib.cpp b/engines/kyra/sound_adlib.cpp index fa5a978665..68a2f0be9c 100644 --- a/engines/kyra/sound_adlib.cpp +++ b/engines/kyra/sound_adlib.cpp @@ -18,7 +18,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * - * LPGL License + * LGPL License * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -507,7 +507,7 @@ int AdlibDriver::snd_deinitDriver(va_list &list) { int AdlibDriver::snd_setSoundData(va_list &list) { if (_soundData) { - delete [] _soundData; + delete[] _soundData; _soundData = 0; } _soundData = va_arg(list, uint8*); @@ -2210,7 +2210,7 @@ const int SoundAdlibPC::_kyra1SoundTriggers[] = { const int SoundAdlibPC::_kyra1NumSoundTriggers = ARRAYSIZE(SoundAdlibPC::_kyra1SoundTriggers); -SoundAdlibPC::SoundAdlibPC(KyraEngine *vm, Audio::Mixer *mixer) +SoundAdlibPC::SoundAdlibPC(KyraEngine_v1 *vm, Audio::Mixer *mixer) : Sound(vm, mixer), _driver(0), _trackEntries(), _soundDataPtr(0) { memset(_trackEntries, 0, sizeof(_trackEntries)); _v2 = (_vm->gameFlags().gameID == GI_KYRA2); @@ -2232,7 +2232,7 @@ SoundAdlibPC::SoundAdlibPC(KyraEngine *vm, Audio::Mixer *mixer) SoundAdlibPC::~SoundAdlibPC() { delete _driver; - delete [] _soundDataPtr; + delete[] _soundDataPtr; } bool SoundAdlibPC::init() { @@ -2382,7 +2382,7 @@ void SoundAdlibPC::loadSoundFile(uint file) { memcpy(_soundDataPtr, p, soundDataSize*sizeof(uint8)); - delete [] file_data; + delete[] file_data; file_data = p = 0; file_size = 0; diff --git a/engines/kyra/sound_digital.cpp b/engines/kyra/sound_digital.cpp index f8c6fbdb04..20f3a7f9f9 100644 --- a/engines/kyra/sound_digital.cpp +++ b/engines/kyra/sound_digital.cpp @@ -25,11 +25,83 @@ #include "kyra/sound.h" #include "kyra/resource.h" +#include "kyra/kyra_mr.h" #include "sound/audiostream.h" +#include "sound/mp3.h" +#include "sound/vorbis.h" +#include "sound/flac.h" + namespace Kyra { +class KyraAudioStream : public Audio::AudioStream { +public: + KyraAudioStream(Audio::AudioStream *impl) : _impl(impl), _rate(impl->getRate()), _fadeSamples(0), _fadeCount(0), _fading(0), _endOfData(false) {} + ~KyraAudioStream() { delete _impl; _impl = 0; } + + int readBuffer(int16 *buffer, const int numSamples); + bool isStereo() const { return _impl->isStereo(); } + bool endOfData() const { return _impl->endOfData() | _endOfData; } + int getRate() const { return _rate; } + int32 getTotalPlayTime() const { return _impl->getTotalPlayTime(); } + + void setRate(int newRate) { _rate = newRate; } + void beginFadeOut(uint32 millis); +private: + Audio::AudioStream *_impl; + + int _rate; + + int32 _fadeSamples; + int32 _fadeCount; + int _fading; + + bool _endOfData; +}; + +void KyraAudioStream::beginFadeOut(uint32 millis) { + _fadeSamples = (millis * getRate()) / 1000; + if (_fading == 0) + _fadeCount = _fadeSamples; + _fading = -1; +} + +int KyraAudioStream::readBuffer(int16 *buffer, const int numSamples) { + int samplesRead = _impl->readBuffer(buffer, numSamples); + + if (_fading) { + int samplesProcessed = 0; + for (; samplesProcessed < samplesRead; ++samplesProcessed) { + // To help avoid overflows for long fade times, we divide both + // _fadeSamples and _fadeCount when calculating the new sample. + + int32 div = _fadeSamples / 256; + if (_fading) { + *buffer = (*buffer * (_fadeCount / 256)) / div; + ++buffer; + + _fadeCount += _fading; + + if (_fadeCount < 0) { + _fadeCount = 0; + _endOfData = true; + } else if (_fadeCount > _fadeSamples) { + _fadeCount = _fadeSamples; + _fading = 0; + } + } + } + + if (_endOfData) { + memset(buffer, 0, (samplesRead - samplesProcessed) * sizeof(int16)); + samplesRead = samplesProcessed; + } + } + + return samplesRead; +} + // Thanks to Torbjorn Andersson (eriktorbjorn) for his aud player on which // this code is based on @@ -46,9 +118,6 @@ public: bool endOfData() const { return _endOfData; } int getRate() const { return _rate; } - - void beginFadeIn(uint32 millis); - void beginFadeOut(uint32 millis); private: Common::SeekableReadStream *_stream; bool _loop; @@ -67,10 +136,6 @@ private: byte *_inBuffer; uint _inBufferSize; - int32 _fadeSamples; - int32 _fadeCount; - int _fading; - int readChunk(int16 *buffer, const int maxSamples); static const int8 WSTable2Bit[]; @@ -91,9 +156,6 @@ AUDStream::AUDStream(Common::SeekableReadStream *stream, bool loop) : _stream(st _totalSize = _stream->readUint32LE(); _loop = loop; - _fadeSamples = 0; - _fading = 0; - // TODO?: add checks int flags = _stream->readByte(); // flags int type = _stream->readByte(); // type @@ -107,25 +169,11 @@ AUDStream::AUDStream(Common::SeekableReadStream *stream, bool loop) : _stream(st } AUDStream::~AUDStream() { - delete [] _outBuffer; - delete [] _inBuffer; + delete[] _outBuffer; + delete[] _inBuffer; delete _stream; } -void AUDStream::beginFadeIn(uint32 millis) { - _fadeSamples = (millis * getRate()) / 1000; - if (_fading == 0) - _fadeCount = 0; - _fading = 1; -} - -void AUDStream::beginFadeOut(uint32 millis) { - _fadeSamples = (millis * getRate()) / 1000; - if (_fading == 0) - _fadeCount = _fadeSamples; - _fading = -1; -} - int AUDStream::readBuffer(int16 *buffer, const int numSamples) { int samplesRead = 0, samplesLeft = numSamples; @@ -174,7 +222,7 @@ int AUDStream::readChunk(int16 *buffer, const int maxSamples) { if (size == outSize) { if (outSize > _outBufferSize) { _outBufferSize = outSize; - delete [] _outBuffer; + delete[] _outBuffer; _outBuffer = new uint8[_outBufferSize]; assert(_outBuffer); } @@ -187,14 +235,14 @@ int AUDStream::readChunk(int16 *buffer, const int maxSamples) { if (outSize > _outBufferSize) { _outBufferSize = outSize; - delete [] _outBuffer; + delete[] _outBuffer; _outBuffer = new uint8[_outBufferSize]; assert(_outBuffer); } if (size > _inBufferSize) { _inBufferSize = size; - delete [] _inBuffer; + delete[] _inBuffer; _inBuffer = new uint8[_inBufferSize]; assert(_inBuffer); } @@ -286,40 +334,19 @@ int AUDStream::readChunk(int16 *buffer, const int maxSamples) { samplesProcessed += samples; _bytesLeft -= samples; - // To help avoid overflows for long fade times, we divide both - // _fadeSamples and _fadeCount when calculating the new sample. - - int32 div = _fadeSamples / 256; - while (samples--) { int16 sample = (_outBuffer[_outBufferOffset++] << 8) ^ 0x8000; - if (_fading) { - sample = (sample * (_fadeCount / 256)) / div; - _fadeCount += _fading; - - if (_fadeCount < 0) { - _fadeCount = 0; - _endOfData = true; - } else if (_fadeCount > _fadeSamples) { - _fadeCount = _fadeSamples; - _fading = 0; - } - } - *buffer++ = sample; } } - if (_fading < 0 && _fadeCount == 0) - _fading = 0; - return samplesProcessed; } #pragma mark - -SoundDigital::SoundDigital(KyraEngine *vm, Audio::Mixer *mixer) : _vm(vm), _mixer(mixer), _sounds() { +SoundDigital::SoundDigital(KyraEngine_MR *vm, Audio::Mixer *mixer) : _vm(vm), _mixer(mixer), _sounds() { for (uint i = 0; i < ARRAYSIZE(_sounds); ++i) _sounds[i].stream = 0; } @@ -365,7 +392,19 @@ int SoundDigital::playSound(const char *filename, uint8 priority, Audio::Mixer:: } } - Common::SeekableReadStream *stream = _vm->resource()->getFileStream(filename); + Common::SeekableReadStream *stream = 0; + int usedCodec = -1; + for (int i = 0; _supportedCodecs[i].fileext; ++i) { + Common::String file = filename; + file += _supportedCodecs[i].fileext; + + if (!_vm->resource()->exists(file.c_str())) + continue; + + stream = _vm->resource()->getFileStream(file); + usedCodec = i; + } + if (!stream) { warning("Couldn't find soundfile '%s'", filename); return -1; @@ -373,7 +412,13 @@ int SoundDigital::playSound(const char *filename, uint8 priority, Audio::Mixer:: strncpy(use->filename, filename, sizeof(use->filename)); use->priority = priority; - use->stream = new AUDStream(stream, loop); + Audio::AudioStream *audioStream = _supportedCodecs[usedCodec].streamFunc(stream, true, 0, 0, loop ? 0 : 1); + if (!audioStream) { + warning("Couldn't create audio stream for file '%s'", filename); + return -1; + } + use->stream = new KyraAudioStream(audioStream); + assert(use->stream); if (use->stream->endOfData()) { delete use->stream; use->stream = 0; @@ -384,6 +429,9 @@ int SoundDigital::playSound(const char *filename, uint8 priority, Audio::Mixer:: if (volume > 255) volume = 255; volume = (volume * Audio::Mixer::kMaxChannelVolume) / 255; + + if (type == Audio::Mixer::kSpeechSoundType && _vm->heliumMode()) + use->stream->setRate(32765); _mixer->playInputStream(type, &use->handle, use->stream, -1, volume); @@ -423,5 +471,30 @@ void SoundDigital::beginFadeOut(int channel, int ticks) { _sounds[channel].stream->beginFadeOut(ticks * _vm->tickLength()); } +// static res + +namespace { + +Audio::AudioStream *makeAUDStream(Common::SeekableReadStream *stream, bool disposeAfterUse, uint32 startTime, uint32 duration, uint numLoops) { + return new AUDStream(stream, numLoops == 0 ? true : false); +} + +} // end of anonymous namespace + +const SoundDigital::AudioCodecs SoundDigital::_supportedCodecs[] = { +#ifdef USE_FLAC + { ".FLA", Audio::makeFlacStream }, +#endif // USE_FLAC +#ifdef USE_VORBIS + { ".OGG", Audio::makeVorbisStream }, +#endif // USE_VORBIS +#ifdef USE_MAD + { ".MP3", Audio::makeMP3Stream }, +#endif // USE_MAD + { ".AUD", makeAUDStream }, + { 0, 0 } +}; + + } // end of namespace Kyra diff --git a/engines/kyra/sound_v1.cpp b/engines/kyra/sound_lok.cpp index 8293eb7508..8a1d16a6b1 100644 --- a/engines/kyra/sound_v1.cpp +++ b/engines/kyra/sound_lok.cpp @@ -24,22 +24,22 @@ */ #include "kyra/sound.h" -#include "kyra/kyra_v1.h" +#include "kyra/kyra_lok.h" namespace Kyra { -void KyraEngine_v1::snd_playSoundEffect(int track, int volume) { - debugC(9, kDebugLevelMain | kDebugLevelSound, "KyraEngine_v1::snd_playSoundEffect(%d, %d)", track, volume); +void KyraEngine_LoK::snd_playSoundEffect(int track, int volume) { + debugC(9, kDebugLevelMain | kDebugLevelSound, "KyraEngine_LoK::snd_playSoundEffect(%d, %d)", track, volume); if ((_flags.platform == Common::kPlatformFMTowns || _flags.platform == Common::kPlatformPC98) && track == 49) { snd_playWanderScoreViaMap(56, 1); return; } - KyraEngine::snd_playSoundEffect(track); + KyraEngine_v1::snd_playSoundEffect(track); } -void KyraEngine_v1::snd_playWanderScoreViaMap(int command, int restart) { - debugC(9, kDebugLevelMain | kDebugLevelSound, "KyraEngine_v1::snd_playWanderScoreViaMap(%d, %d)", command, restart); +void KyraEngine_LoK::snd_playWanderScoreViaMap(int command, int restart) { + debugC(9, kDebugLevelMain | kDebugLevelSound, "KyraEngine_LoK::snd_playWanderScoreViaMap(%d, %d)", command, restart); if (restart) _lastMusicCommand = -1; @@ -57,21 +57,21 @@ void KyraEngine_v1::snd_playWanderScoreViaMap(int command, int restart) { _sound->haltTrack(); } } else { - KyraEngine::snd_playWanderScoreViaMap(command, restart); + KyraEngine_v1::snd_playWanderScoreViaMap(command, restart); } } -void KyraEngine_v1::snd_playVoiceFile(int id) { - debugC(9, kDebugLevelMain | kDebugLevelSound, "KyraEngine_v1::snd_playVoiceFile(%d)", id); +void KyraEngine_LoK::snd_playVoiceFile(int id) { + debugC(9, kDebugLevelMain | kDebugLevelSound, "KyraEngine_LoK::snd_playVoiceFile(%d)", id); char vocFile[9]; assert(id >= 0 && id < 9999); sprintf(vocFile, "%03d", id); _speechFile = vocFile; - _sound->voicePlay(vocFile); + _speechPlayTime = _sound->voicePlay(vocFile); } -void KyraEngine_v1::snd_voiceWaitForFinish(bool ingame) { - debugC(9, kDebugLevelMain | kDebugLevelSound, "KyraEngine_v1::snd_voiceWaitForFinish(%d)", ingame); +void KyraEngine_LoK::snd_voiceWaitForFinish(bool ingame) { + debugC(9, kDebugLevelMain | kDebugLevelSound, "KyraEngine_LoK::snd_voiceWaitForFinish(%d)", ingame); while (_sound->voiceIsPlaying() && !_skipFlag) { if (ingame) delay(10, true); @@ -80,4 +80,11 @@ void KyraEngine_v1::snd_voiceWaitForFinish(bool ingame) { } } +uint32 KyraEngine_LoK::snd_getVoicePlayTime() { + debugC(9, kDebugLevelMain | kDebugLevelSound, "KyraEngine_LoK::snd_getVoicePlayTime()"); + if (!snd_voiceIsPlaying()) + return 0; + return (_speechPlayTime != -1 ? _speechPlayTime : 0); +} + } // end of namespace Kyra diff --git a/engines/kyra/sound_towns.cpp b/engines/kyra/sound_towns.cpp index 9ac865c157..4265533507 100644 --- a/engines/kyra/sound_towns.cpp +++ b/engines/kyra/sound_towns.cpp @@ -599,18 +599,18 @@ SoundTowns_EuphonyDriver::~SoundTowns_EuphonyDriver() { MidiDriver_YM2612::removeLookupTables(); if (_fmInstruments) { - delete [] _fmInstruments; + delete[] _fmInstruments; _fmInstruments = 0; } if (_waveInstruments) { - delete [] _waveInstruments; + delete[] _waveInstruments; _waveInstruments = 0; } for (int i = 0; i < 10; i++) { if (_waveSounds[i]) { - delete [] _waveSounds[i]; + delete[] _waveSounds[i]; _waveSounds[i] = 0; } } @@ -709,14 +709,14 @@ void SoundTowns_EuphonyDriver::send(byte chan, uint32 b) { void SoundTowns_EuphonyDriver::loadFmInstruments(const byte *instr) { if (_fmInstruments) - delete [] _fmInstruments; + delete[] _fmInstruments; _fmInstruments = new uint8[0x1800]; memcpy(_fmInstruments, instr, 0x1800); } void SoundTowns_EuphonyDriver::loadWaveInstruments(const byte *instr) { if (_waveInstruments) - delete [] _waveInstruments; + delete[] _waveInstruments; _waveInstruments = new uint8[0x1000]; memcpy(_waveInstruments, instr, 0x1000); @@ -724,7 +724,7 @@ void SoundTowns_EuphonyDriver::loadWaveInstruments(const byte *instr) { for (uint8 i = 0; i < 10; i++) { if (_waveSounds[i]) - delete [] _waveSounds[i]; + delete[] _waveSounds[i]; uint32 numsamples = READ_LE_UINT32(pos + 0x0C); _waveSounds[i] = new int8[numsamples + 0x20]; memcpy(_waveSounds[i], pos, 0x20); @@ -1010,7 +1010,7 @@ SoundTowns_EuphonyTrackQueue * SoundTowns_EuphonyTrackQueue::reset() { void SoundTowns_EuphonyTrackQueue::loadDataToCurrentPosition(uint8 * trackdata, uint32 size, bool loop) { if (_trackData) - delete [] _trackData; + delete[] _trackData; _trackData = new uint8[0xC58A]; memset(_trackData, 0, 0xC58A); Screen::decodeFrame4(trackdata, _trackData, size); @@ -1051,13 +1051,13 @@ void SoundTowns_EuphonyTrackQueue::release() { _used = _fchan = _wchan = 0; if (_trackData) { - delete [] _trackData; + delete[] _trackData; _trackData = 0; } while (i) { if (i->_trackData) { - delete [] i->_trackData; + delete[] i->_trackData; i->_trackData = 0; } i = i->_next; @@ -1084,7 +1084,7 @@ void SoundTowns_EuphonyTrackQueue::initDriver() { _driver->send(0x79B0); } -SoundTowns::SoundTowns(KyraEngine *vm, Audio::Mixer *mixer) +SoundTowns::SoundTowns(KyraEngine_v1 *vm, Audio::Mixer *mixer) : Sound(vm, mixer), _lastTrack(-1), _currentSFX(0), _sfxFileData(0), _sfxFileIndex((uint)-1), _sfxWDTable(0), _sfxBTTable(0), _parser(0) { @@ -1097,7 +1097,7 @@ SoundTowns::SoundTowns(KyraEngine *vm, Audio::Mixer *mixer) SoundTowns::~SoundTowns() { AudioCD.stop(); haltTrack(); - delete [] _sfxFileData; + delete[] _sfxFileData; Common::StackLock lock(_mutex); _driver->setTimerCallback(0, 0); @@ -1109,8 +1109,8 @@ SoundTowns::~SoundTowns() { bool SoundTowns::init() { _vm->checkCD(); int unused = 0; - _sfxWDTable = _vm->staticres()->loadRawData(kKyra1TownsSFXwdTable, unused); - _sfxBTTable = _vm->staticres()->loadRawData(kKyra1TownsSFXbtTable, unused); + _sfxWDTable = _vm->staticres()->loadRawData(k1TownsSFXwdTable, unused); + _sfxBTTable = _vm->staticres()->loadRawData(k1TownsSFXbtTable, unused); return loadInstruments(); } @@ -1164,7 +1164,7 @@ void SoundTowns::loadSoundFile(uint file) { if (_sfxFileIndex == file) return; _sfxFileIndex = file; - delete [] _sfxFileData; + delete[] _sfxFileData; _sfxFileData = _vm->resource()->fileData(fileListEntry(file), 0); } @@ -1293,7 +1293,7 @@ bool SoundTowns::loadInstruments() { _driver->queue()->loadDataToCurrentPosition(twm + 0x0CA0, 0xC58A); _driver->loadWaveInstruments(_driver->queue()->trackData() + 8); - delete [] twm; + delete[] twm; _driver->queue()->release(); return true; @@ -1301,6 +1301,7 @@ bool SoundTowns::loadInstruments() { void SoundTowns::playEuphonyTrack(uint32 offset, int loop) { uint8 * twm = _vm->resource()->fileData("twmusic.pak", 0); + Common::StackLock lock(_mutex); if (!_parser) { _parser = new MidiParser_EuD(_driver->queue()); @@ -1311,7 +1312,7 @@ void SoundTowns::playEuphonyTrack(uint32 offset, int loop) { _parser->property(MidiParser::mpAutoLoop, loop); _parser->loadMusic(twm + 0x4b70 + offset, 0xC58A); - delete [] twm; + delete[] twm; } void SoundTowns::onTimer(void * data) { @@ -1357,7 +1358,7 @@ float SoundTowns::semitoneAndSampleRate_to_sampleStep(int8 semiTone, int8 semiTo // KYRA 2 -SoundTowns_v2::SoundTowns_v2(KyraEngine *vm, Audio::Mixer *mixer) +SoundTowns_v2::SoundTowns_v2(KyraEngine_v1 *vm, Audio::Mixer *mixer) : Sound(vm, mixer), _lastTrack(-1), _currentSFX(0), /*_driver(0),*/ _twnTrackData(0) { } @@ -1366,7 +1367,7 @@ SoundTowns_v2::~SoundTowns_v2() { /*if (_driver) delete _driver;*/ if (_twnTrackData) - delete [] _twnTrackData; + delete[] _twnTrackData; } bool SoundTowns_v2::init() { @@ -1416,7 +1417,7 @@ void SoundTowns_v2::playTrack(uint8 track) { char musicfile[13]; sprintf(musicfile, fileListEntry(0), track); if (_twnTrackData) - delete [] _twnTrackData; + delete[] _twnTrackData; _twnTrackData = _vm->resource()->fileData(musicfile, 0); //_driver->loadData(_twnTrackData); } @@ -1431,7 +1432,7 @@ void SoundTowns_v2::haltTrack() { //_driver->reset(); } -bool SoundTowns_v2::voicePlay(const char *file, bool) { +int32 SoundTowns_v2::voicePlay(const char *file, bool) { static const uint16 rates[] = { 0x10E1, 0x0CA9, 0x0870, 0x0654, 0x0438, 0x032A, 0x021C, 0x0194 }; int h = 0; @@ -1439,10 +1440,13 @@ bool SoundTowns_v2::voicePlay(const char *file, bool) { while (_mixer->isSoundHandleActive(_soundChannels[h].channelHandle) && h < kNumChannelHandles) h++; if (h >= kNumChannelHandles) - return false; + return 0; } - uint8 * data = _vm->resource()->fileData(file, 0); + char filename [13]; + sprintf(filename, "%s.PCM", file); + + uint8 * data = _vm->resource()->fileData(filename, 0); uint8 * src = data; uint16 sfxRate = rates[READ_LE_UINT16(src)]; @@ -1492,8 +1496,8 @@ bool SoundTowns_v2::voicePlay(const char *file, bool) { _soundChannels[h].file = file; _mixer->playInputStream(Audio::Mixer::kSFXSoundType, &_soundChannels[h].channelHandle, _currentSFX); - delete [] data; - return true; + delete[] data; + return 1; } void SoundTowns_v2::beginFadeOut() { diff --git a/engines/kyra/sprites.cpp b/engines/kyra/sprites.cpp index b54192abae..34c2986f25 100644 --- a/engines/kyra/sprites.cpp +++ b/engines/kyra/sprites.cpp @@ -30,14 +30,14 @@ #include "common/system.h" #include "common/events.h" #include "kyra/screen.h" -#include "kyra/kyra_v1.h" +#include "kyra/kyra_lok.h" #include "kyra/sprites.h" #include "kyra/resource.h" -#include "kyra/animator_v1.h" +#include "kyra/animator_lok.h" namespace Kyra { -Sprites::Sprites(KyraEngine_v1 *vm, OSystem *system) { +Sprites::Sprites(KyraEngine_LoK *vm, OSystem *system) { _vm = vm; _res = vm->resource(); _screen = vm->screen(); @@ -52,11 +52,11 @@ Sprites::Sprites(KyraEngine_v1 *vm, OSystem *system) { } Sprites::~Sprites() { - delete [] _dat; + delete[] _dat; freeSceneShapes(); for (int i = 0; i < MAX_NUM_ANIMS; i++) { if (_anims[i].background) - delete [] _anims[i].background; + delete[] _anims[i].background; } } @@ -66,7 +66,7 @@ void Sprites::setupSceneAnims() { for (int i = 0; i < MAX_NUM_ANIMS; i++) { if (_anims[i].background) { - delete [] _anims[i].background; + delete[] _anims[i].background; _anims[i].background = 0; } @@ -140,7 +140,7 @@ void Sprites::updateSceneAnims() { uint16 sound; for (int i = 0; i < MAX_NUM_ANIMS; i++) { - if (_anims[i].script == 0 || !_anims[i].play || _anims[i].nextRun != 0 && _anims[i].nextRun > currTime) + if (_anims[i].script == 0 || !_anims[i].play || (_anims[i].nextRun != 0 && _anims[i].nextRun > currTime)) continue; data = _anims[i].curPos; @@ -515,7 +515,7 @@ void Sprites::loadDat(const char *filename, SceneExits &exits) { void Sprites::freeSceneShapes() { debugC(9, kDebugLevelSprites, "Sprites::freeSceneShapes()"); for (int i = 0; i < ARRAYSIZE(_sceneShapes); i++ ) { - delete [] _sceneShapes[i]; + delete[] _sceneShapes[i]; _sceneShapes[i] = 0; } } @@ -554,7 +554,7 @@ void Sprites::loadSceneShapes() { void Sprites::refreshSceneAnimObject(uint8 animNum, uint8 shapeNum, uint16 x, uint16 y, bool flipX, bool unkFlag) { debugC(9, kDebugLevelSprites, "Sprites::refreshSceneAnimObject(%i, %i, %i, %i, %i, %i", animNum, shapeNum, x, y, flipX, unkFlag); - Animator_v1::AnimObject &anim = _vm->animator()->sprites()[animNum]; + Animator_LoK::AnimObject &anim = _vm->animator()->sprites()[animNum]; anim.refreshFlag = 1; anim.bkgdChangeFlag = 1; diff --git a/engines/kyra/sprites.h b/engines/kyra/sprites.h index 3304458fda..212bfc7428 100644 --- a/engines/kyra/sprites.h +++ b/engines/kyra/sprites.h @@ -26,7 +26,7 @@ #ifndef KYRA_SPRITES_H #define KYRA_SPRITES_H -#include "kyra/kyra_v1.h" +#include "kyra/kyra_lok.h" namespace Kyra { @@ -63,11 +63,11 @@ struct Anim { bool disable; }; -class KyraEngine_v1; +class KyraEngine_LoK; class Sprites { public: - Sprites(KyraEngine_v1 *vm, OSystem *system); + Sprites(KyraEngine_LoK *vm, OSystem *system); ~Sprites(); void updateSceneAnims(); @@ -86,7 +86,7 @@ public: protected: void freeSceneShapes(); - KyraEngine_v1 *_vm; + KyraEngine_LoK *_vm; Resource *_res; OSystem *_system; Screen *_screen; diff --git a/engines/kyra/staticres.cpp b/engines/kyra/staticres.cpp index 16d7ca4d9b..abdf115c1e 100644 --- a/engines/kyra/staticres.cpp +++ b/engines/kyra/staticres.cpp @@ -26,24 +26,23 @@ #include "common/endian.h" #include "common/md5.h" -#include "kyra/kyra.h" #include "kyra/kyra_v1.h" +#include "kyra/kyra_lok.h" +#include "kyra/kyra_v2.h" #include "kyra/kyra_hof.h" #include "kyra/kyra_mr.h" #include "kyra/screen.h" -#include "kyra/screen_v1.h" +#include "kyra/screen_lok.h" #include "kyra/screen_hof.h" #include "kyra/screen_mr.h" #include "kyra/resource.h" -#include "kyra/gui_v1.h" +#include "kyra/gui_lok.h" #include "kyra/gui_hof.h" #include "kyra/gui_mr.h" -#include "gui/message.h" - namespace Kyra { -#define RESFILE_VERSION 24 +#define RESFILE_VERSION 28 bool StaticResource::checkKyraDat() { Common::File kyraDat; @@ -143,8 +142,8 @@ bool StaticResource::init() { { kPaletteTable, proc(loadPaletteTable), proc(freePaletteTable) }, { k2SeqData, proc(loadHofSequenceData), proc(freeHofSequenceData) }, - { k2ShpAnimDataV1, proc(loadHofShapeAnimDataV1), proc(freeHofShapeAnimDataV1) }, - { k2ShpAnimDataV2, proc(loadHofShapeAnimDataV2), proc(freeHofShapeAnimDataV2) }, + { k2ShpAnimDataV1, proc(loadShapeAnimData_v1), proc(freeHofShapeAnimDataV1) }, + { k2ShpAnimDataV2, proc(loadShapeAnimData_v2), proc(freeHofShapeAnimDataV2) }, { 0, 0, 0 } }; @@ -154,85 +153,85 @@ bool StaticResource::init() { // Kyrandia 1 Filenames static const FilenameTable kyra1StaticRes[] = { // INTRO / OUTRO sequences - { kForestSeq, kRawData, "FOREST.SEQ" }, - { kKallakWritingSeq, kRawData, "KALLAK-WRITING.SEQ" }, - { kKyrandiaLogoSeq, kRawData, "KYRANDIA-LOGO.SEQ" }, - { kKallakMalcolmSeq, kRawData, "KALLAK-MALCOLM.SEQ" }, - { kMalcolmTreeSeq, kRawData, "MALCOLM-TREE.SEQ" }, - { kWestwoodLogoSeq, kRawData, "WESTWOOD-LOGO.SEQ" }, - { kDemo1Seq, kRawData, "DEMO1.SEQ" }, - { kDemo2Seq, kRawData, "DEMO2.SEQ" }, - { kDemo3Seq, kRawData, "DEMO3.SEQ" }, - { kDemo4Seq, kRawData, "DEMO4.SEQ" }, - { kOutroReunionSeq, kRawData, "REUNION.SEQ" }, + { k1ForestSeq, kRawData, "FOREST.SEQ" }, + { k1KallakWritingSeq, kRawData, "KALLAK-WRITING.SEQ" }, + { k1KyrandiaLogoSeq, kRawData, "KYRANDIA-LOGO.SEQ" }, + { k1KallakMalcolmSeq, kRawData, "KALLAK-MALCOLM.SEQ" }, + { k1MalcolmTreeSeq, kRawData, "MALCOLM-TREE.SEQ" }, + { k1WestwoodLogoSeq, kRawData, "WESTWOOD-LOGO.SEQ" }, + { k1Demo1Seq, kRawData, "DEMO1.SEQ" }, + { k1Demo2Seq, kRawData, "DEMO2.SEQ" }, + { k1Demo3Seq, kRawData, "DEMO3.SEQ" }, + { k1Demo4Seq, kRawData, "DEMO4.SEQ" }, + { k1OutroReunionSeq, kRawData, "REUNION.SEQ" }, // INTRO / OUTRO strings - { kIntroCPSStrings, kStringList, "INTRO-CPS.TXT" }, - { kIntroCOLStrings, kStringList, "INTRO-COL.TXT" }, - { kIntroWSAStrings, kStringList, "INTRO-WSA.TXT" }, - { kIntroStrings, kLanguageList, "INTRO-STRINGS." }, - { kOutroHomeString, kLanguageList, "HOME." }, + { k1IntroCPSStrings, kStringList, "INTRO-CPS.TXT" }, + { k1IntroCOLStrings, kStringList, "INTRO-COL.TXT" }, + { k1IntroWSAStrings, kStringList, "INTRO-WSA.TXT" }, + { k1IntroStrings, kLanguageList, "INTRO-STRINGS." }, + { k1OutroHomeString, kLanguageList, "HOME." }, // INGAME strings - { kItemNames, kLanguageList, "ITEMLIST." }, - { kTakenStrings, kLanguageList, "TAKEN." }, - { kPlacedStrings, kLanguageList, "PLACED." }, - { kDroppedStrings, kLanguageList, "DROPPED." }, - { kNoDropStrings, kLanguageList, "NODROP." }, - { kPutDownString, kLanguageList, "PUTDOWN." }, - { kWaitAmuletString, kLanguageList, "WAITAMUL." }, - { kBlackJewelString, kLanguageList, "BLACKJEWEL." }, - { kPoisonGoneString, kLanguageList, "POISONGONE." }, - { kHealingTipString, kLanguageList, "HEALINGTIP." }, - { kThePoisonStrings, kLanguageList, "THEPOISON." }, - { kFluteStrings, kLanguageList, "FLUTE." }, - { kWispJewelStrings, kLanguageList, "WISPJEWEL." }, - { kMagicJewelStrings, kLanguageList, "MAGICJEWEL." }, - { kFlaskFullString, kLanguageList, "FLASKFULL." }, - { kFullFlaskString, kLanguageList, "FULLFLASK." }, - { kVeryCleverString, kLanguageList, "VERYCLEVER." }, - { kNewGameString, kLanguageList, "NEWGAME." }, + { k1ItemNames, kLanguageList, "ITEMLIST." }, + { k1TakenStrings, kLanguageList, "TAKEN." }, + { k1PlacedStrings, kLanguageList, "PLACED." }, + { k1DroppedStrings, kLanguageList, "DROPPED." }, + { k1NoDropStrings, kLanguageList, "NODROP." }, + { k1PutDownString, kLanguageList, "PUTDOWN." }, + { k1WaitAmuletString, kLanguageList, "WAITAMUL." }, + { k1BlackJewelString, kLanguageList, "BLACKJEWEL." }, + { k1PoisonGoneString, kLanguageList, "POISONGONE." }, + { k1HealingTipString, kLanguageList, "HEALINGTIP." }, + { k1ThePoisonStrings, kLanguageList, "THEPOISON." }, + { k1FluteStrings, kLanguageList, "FLUTE." }, + { k1WispJewelStrings, kLanguageList, "WISPJEWEL." }, + { k1MagicJewelStrings, kLanguageList, "MAGICJEWEL." }, + { k1FlaskFullString, kLanguageList, "FLASKFULL." }, + { k1FullFlaskString, kLanguageList, "FULLFLASK." }, + { k1VeryCleverString, kLanguageList, "VERYCLEVER." }, + { k1NewGameString, kLanguageList, "NEWGAME." }, // GUI strings table - { kGUIStrings, kLanguageList, "GUISTRINGS." }, - { kConfigStrings, kLanguageList, "CONFIGSTRINGS." }, + { k1GUIStrings, kLanguageList, "GUISTRINGS." }, + { k1ConfigStrings, kLanguageList, "CONFIGSTRINGS." }, // ROOM table/filenames - { Kyra::kRoomList, StaticResource::kRoomList, "ROOM-TABLE.ROOM" }, - { kRoomFilenames, kStringList, "ROOM-FILENAMES.TXT" }, + { k1RoomList, kRoomList, "ROOM-TABLE.ROOM" }, + { k1RoomFilenames, kStringList, "ROOM-FILENAMES.TXT" }, // SHAPE tables - { kDefaultShapes, kShapeList, "SHAPES-DEFAULT.SHP" }, - { kHealing1Shapes, kShapeList, "HEALING.SHP" }, - { kHealing2Shapes, kShapeList, "HEALING2.SHP" }, - { kPoisonDeathShapes, kShapeList, "POISONDEATH.SHP" }, - { kFluteShapes, kShapeList, "FLUTE.SHP" }, - { kWinter1Shapes, kShapeList, "WINTER1.SHP" }, - { kWinter2Shapes, kShapeList, "WINTER2.SHP" }, - { kWinter3Shapes, kShapeList, "WINTER3.SHP" }, - { kDrinkShapes, kShapeList, "DRINK.SHP" }, - { kWispShapes, kShapeList, "WISP.SHP" }, - { kMagicAnimShapes, kShapeList, "MAGICANIM.SHP" }, - { kBranStoneShapes, kShapeList, "BRANSTONE.SHP" }, + { k1DefaultShapes, kShapeList, "SHAPES-DEFAULT.SHP" }, + { k1Healing1Shapes, kShapeList, "HEALING.SHP" }, + { k1Healing2Shapes, kShapeList, "HEALING2.SHP" }, + { k1PoisonDeathShapes, kShapeList, "POISONDEATH.SHP" }, + { k1FluteShapes, kShapeList, "FLUTE.SHP" }, + { k1Winter1Shapes, kShapeList, "WINTER1.SHP" }, + { k1Winter2Shapes, kShapeList, "WINTER2.SHP" }, + { k1Winter3Shapes, kShapeList, "WINTER3.SHP" }, + { k1DrinkShapes, kShapeList, "DRINK.SHP" }, + { k1WispShapes, kShapeList, "WISP.SHP" }, + { k1MagicAnimShapes, kShapeList, "MAGICANIM.SHP" }, + { k1BranStoneShapes, kShapeList, "BRANSTONE.SHP" }, // IMAGE filename table - { kCharacterImageFilenames, kStringList, "CHAR-IMAGE.TXT" }, + { k1CharacterImageFilenames, kStringList, "CHAR-IMAGE.TXT" }, // AMULET anim - { kAmuleteAnimSeq, kRawData, "AMULETEANIM.SEQ" }, + { k1AmuleteAnimSeq, kRawData, "AMULETEANIM.SEQ" }, // PALETTE table - { kPaletteList, kPaletteTable, "1 33 PALTABLE" }, + { k1PaletteList, kPaletteTable, "1 33 PALTABLE" }, // AUDIO files - { kAudioTracks, kStringList, "TRACKS.TXT" }, - { kAudioTracksIntro, kStringList, "TRACKSINT.TXT" }, + { k1AudioTracks, kStringList, "TRACKS.TXT" }, + { k1AudioTracksIntro, kStringList, "TRACKSINT.TXT" }, // FM-TOWNS specific - { kKyra1TownsSFXwdTable, kRawData, "SFXWDTABLE" }, - { kKyra1TownsSFXbtTable, kRawData, "SFXBTTABLE" }, - { kKyra1TownsCDATable, kRawData, "CDATABLE" }, - { kCreditsStrings, kRawData, "CREDITS" }, + { k1TownsSFXwdTable, kRawData, "SFXWDTABLE" }, + { k1TownsSFXbtTable, kRawData, "SFXBTTABLE" }, + { k1TownsCDATable, kRawData, "CDATABLE" }, + { k1CreditsStrings, kRawData, "CREDITS" }, { 0, 0, 0 } }; @@ -261,7 +260,20 @@ bool StaticResource::init() { { k2IngameTalkObjIndex, kRawData, "I_TALKOBJECTS.MAP" }, { k2IngameTimJpStrings, kStringList, "I_TIMJPSTR.TXT" }, { k2IngameShapeAnimData, k2ShpAnimDataV2, "I_INVANIM.SHP" }, - { k2IngameTlkDemoStrings, kLanguageList, "I_TLKDEMO.TXT." }, + { k2IngameTlkDemoStrings, kLanguageList, "I_TLKDEMO.TXT." }, + + { 0, 0, 0 } + }; + + static const FilenameTable kyra3StaticRes[] = { + { k3MainMenuStrings, kStringList, "MAINMENU.TXT" }, + { k3MusicFiles, kStringList, "SCORE.TRA" }, + { k3ScoreTable, kRawData, "SCORE.MAP" }, + { k3SfxFiles, kStringList, "SFXFILES.TRA" }, + { k3SfxMap, kRawData, "SFXINDEX.MAP" }, + { k3ItemAnimData, k2ShpAnimDataV2, "INVANIM.SHP" }, + { k3ItemMagicTable, kRawData, "ITEMMAGIC.MAP" }, + { k3ItemStringMap, kRawData, "ITEMSTRINGS.MAP" }, { 0, 0, 0 } }; @@ -273,23 +285,26 @@ bool StaticResource::init() { _builtIn = 0; _filenameTable = kyra2StaticRes; } else if (_vm->game() == GI_KYRA3) { - return true; + _builtIn = 0; + _filenameTable = kyra3StaticRes; } else { error("unknown game ID"); } + char errorBuffer[100]; int tempSize = 0; uint8 *temp = getFile("INDEX", tempSize); if (!temp) { - warning("No matching INDEX file found ('%s')", getFilename("INDEX")); - outputError(); + snprintf(errorBuffer, sizeof(errorBuffer), "is missing an '%s' entry", getFilename("INDEX")); + outputError(errorBuffer); return false; } if (tempSize != 3*4) { - delete [] temp; - warning("'%s' has illegal filesize %d", getFilename("INDEX"), tempSize); - outputError(); + delete[] temp; + + snprintf(errorBuffer, sizeof(errorBuffer), "has incorrect header size for entry '%s'", getFilename("INDEX")); + outputError(errorBuffer); return false; } @@ -297,32 +312,29 @@ bool StaticResource::init() { uint32 gameID = READ_BE_UINT32((temp+4)); uint32 featuresValue = READ_BE_UINT32((temp+8)); - delete [] temp; + delete[] temp; temp = 0; if (version != RESFILE_VERSION) { - warning("Invalid KYRA.DAT file version (%u, required %d)", version, RESFILE_VERSION); - outputError(); + snprintf(errorBuffer, sizeof(errorBuffer), "has invalid version %d required, you got %d", RESFILE_VERSION, version); + outputError(errorBuffer); return false; } if (gameID != _vm->game()) { - warning("Invalid game id (%u)", gameID); - outputError(); + outputError("does not include support for your game"); return false; } uint32 gameFeatures = createFeatures(_vm->gameFlags()); if ((featuresValue & GAME_FLAGS) != gameFeatures) { - warning("Your data file has a different game flags (0x%.08X has the data and your version has 0x%.08X)", (featuresValue & GAME_FLAGS), gameFeatures); - outputError(); + outputError("does not include support for your game version"); return false; } // load all tables for now if (!prefetchId(-1)) { - warning("Couldn't load all needed resources from 'KYRA.DAT'"); - outputError(); + outputError("is lacking entries for your game version"); return false; } return true; @@ -332,11 +344,10 @@ void StaticResource::deinit() { unloadId(-1); } -void StaticResource::outputError() { - Common::String errorMessage = "Your '" + StaticResource::staticDataFilename() + "' file is outdated, reget it from the ScummVM website"; - ::GUI::MessageDialog errorMsg(errorMessage); - errorMsg.runModal(); - error(errorMessage.c_str()); +void StaticResource::outputError(const Common::String &error) { + Common::String errorMessage = "Your '" + StaticResource::staticDataFilename() + "' file " + error + ", reget a correct version from the ScummVM website"; + _vm->GUIErrorMessage(errorMessage); + ::error(errorMessage.c_str()); } const char * const*StaticResource::loadStrings(int id, int &strings) { @@ -366,11 +377,11 @@ const HofSeqData *StaticResource::loadHofSequenceData(int id, int &entries) { return (const HofSeqData*)getData(id, k2SeqData, entries); } -const ItemAnimData_v1 *StaticResource::loadHofShapeAnimDataV1(int id, int &entries) { +const ItemAnimData_v1 *StaticResource::loadShapeAnimData_v1(int id, int &entries) { return (const ItemAnimData_v1*)getData(id, k2ShpAnimDataV1, entries); } -const ItemAnimData_v2 *StaticResource::loadHofShapeAnimDataV2(int id, int &entries) { +const ItemAnimData_v2 *StaticResource::loadShapeAnimData_v2(int id, int &entries) { return (const ItemAnimData_v2*)getData(id, k2ShpAnimDataV2, entries); } @@ -545,7 +556,7 @@ bool StaticResource::loadStringTable(const char *filename, void *&ptr, int &size curPos += strLen+1; } - delete [] filePtr; + delete[] filePtr; ptr = output; return true; @@ -579,7 +590,7 @@ bool StaticResource::loadShapeTable(const char *filename, void *&ptr, int &size) loadTo[i].yOffset = *src++; } - delete [] filePtr; + delete[] filePtr; ptr = loadTo; return true; @@ -609,7 +620,7 @@ bool StaticResource::loadRoomTable(const char *filename, void *&ptr, int &size) memset(loadTo[i].needInit, 0, sizeof(loadTo[i].needInit)); } - delete [] filePtr; + delete[] filePtr; ptr = loadTo; return true; @@ -642,7 +653,7 @@ bool StaticResource::loadPaletteTable(const char *filename, void *&ptr, int &siz snprintf(name, 64, "%s%d.PAL", file, i); table[(start != 0) ? (i-start) : i] = (char*)getFile(name, size); if (!table[(start != 0) ? (i-start) : i]) { - delete [] table; + delete[] table; return false; } } @@ -743,7 +754,7 @@ bool StaticResource::loadHofSequenceData(const char *filename, void *&ptr, int & } } - delete [] filePtr; + delete[] filePtr; HofSeqData *loadTo = new HofSeqData; assert(loadTo); @@ -758,7 +769,7 @@ bool StaticResource::loadHofSequenceData(const char *filename, void *&ptr, int & return true; } -bool StaticResource::loadHofShapeAnimDataV1(const char *filename, void *&ptr, int &size) { +bool StaticResource::loadShapeAnimData_v1(const char *filename, void *&ptr, int &size) { int filesize; uint8 *filePtr = getFile(filename, filesize); uint8 *src = filePtr; @@ -783,13 +794,13 @@ bool StaticResource::loadHofShapeAnimDataV1(const char *filename, void *&ptr, in loadTo[i].frames = tmp_f; } - delete [] filePtr; + delete[] filePtr; ptr = loadTo; return true; } -bool StaticResource::loadHofShapeAnimDataV2(const char *filename, void *&ptr, int &size) { +bool StaticResource::loadShapeAnimData_v2(const char *filename, void *&ptr, int &size) { int filesize; uint8 *filePtr = getFile(filename, filesize); uint8 *src = filePtr; @@ -815,7 +826,7 @@ bool StaticResource::loadHofShapeAnimDataV2(const char *filename, void *&ptr, in loadTo[i].frames = tmp_f; } - delete [] filePtr; + delete[] filePtr; ptr = loadTo; return true; @@ -823,7 +834,7 @@ bool StaticResource::loadHofShapeAnimDataV2(const char *filename, void *&ptr, in void StaticResource::freeRawData(void *&ptr, int &size) { uint8 *data = (uint8*)ptr; - delete [] data; + delete[] data; ptr = 0; size = 0; } @@ -831,21 +842,22 @@ void StaticResource::freeRawData(void *&ptr, int &size) { void StaticResource::freeStringTable(void *&ptr, int &size) { char **data = (char**)ptr; while (size--) - delete [] data[size]; + delete[] data[size]; + delete[] data; ptr = 0; size = 0; } void StaticResource::freeShapeTable(void *&ptr, int &size) { Shape *data = (Shape*)ptr; - delete [] data; + delete[] data; ptr = 0; size = 0; } void StaticResource::freeRoomTable(void *&ptr, int &size) { Room *data = (Room*)ptr; - delete [] data; + delete[] data; ptr = 0; size = 0; } @@ -854,16 +866,16 @@ void StaticResource::freeHofSequenceData(void *&ptr, int &size) { HofSeqData *h = (HofSeqData*) ptr; for (int i = 0; i < h->numSeq; i++) { - delete [] h->seq[i].wsaFile; - delete [] h->seq[i].cpsFile; + delete[] h->seq[i].wsaFile; + delete[] h->seq[i].cpsFile; } - delete [] h->seq; + delete[] h->seq; for (int i = 0; i < h->numSeqn; i++) { - delete [] h->seqn[i].wsaFile; - delete [] h->seqn[i].wsaControl; + delete[] h->seqn[i].wsaFile; + delete[] h->seqn[i].wsaControl; } - delete [] h->seqn; + delete[] h->seqn; delete h; ptr = 0; @@ -873,8 +885,8 @@ void StaticResource::freeHofSequenceData(void *&ptr, int &size) { void StaticResource::freeHofShapeAnimDataV1(void *&ptr, int &size) { ItemAnimData_v1 *d= (ItemAnimData_v1*) ptr; for (int i = 0; i < size; i++) - delete [] d[i].frames; - delete [] d; + delete[] d[i].frames; + delete[] d; ptr = 0; size = 0; } @@ -882,8 +894,8 @@ void StaticResource::freeHofShapeAnimDataV1(void *&ptr, int &size) { void StaticResource::freeHofShapeAnimDataV2(void *&ptr, int &size) { ItemAnimData_v2 *d= (ItemAnimData_v2*) ptr; for (int i = 0; i < size; i++) - delete [] d[i].frames; - delete [] d; + delete[] d[i].frames; + delete[] d; ptr = 0; size = 0; } @@ -891,7 +903,7 @@ void StaticResource::freeHofShapeAnimDataV2(void *&ptr, int &size) { void StaticResource::freePaletteTable(void *&ptr, int &size) { uint8 **data = (uint8**)ptr; while (size--) - delete [] data[size]; + delete[] data[size]; ptr = 0; size = 0; } @@ -903,8 +915,10 @@ const char *StaticResource::getFilename(const char *name) { if (_vm->gameFlags().gameID == GI_KYRA2) filename += ".K2"; + else if (_vm->gameFlags().gameID == GI_KYRA3) + filename += ".K3"; - if (_vm->gameFlags().isTalkie) + if (_vm->gameFlags().isTalkie && _vm->gameFlags().gameID != GI_KYRA3) filename += ".CD"; else if (_vm->gameFlags().isDemo) filename += ".DEM"; @@ -925,76 +939,76 @@ uint8 *StaticResource::getFile(const char *name, int &size) { #pragma mark - -void KyraEngine_v1::initStaticResource() { +void KyraEngine_LoK::initStaticResource() { int temp = 0; - _seq_Forest = _staticres->loadRawData(kForestSeq, temp); - _seq_KallakWriting = _staticres->loadRawData(kKallakWritingSeq, temp); - _seq_KyrandiaLogo = _staticres->loadRawData(kKyrandiaLogoSeq, temp); - _seq_KallakMalcolm = _staticres->loadRawData(kKallakMalcolmSeq, temp); - _seq_MalcolmTree = _staticres->loadRawData(kMalcolmTreeSeq, temp); - _seq_WestwoodLogo = _staticres->loadRawData(kWestwoodLogoSeq, temp); - _seq_Demo1 = _staticres->loadRawData(kDemo1Seq, temp); - _seq_Demo2 = _staticres->loadRawData(kDemo2Seq, temp); - _seq_Demo3 = _staticres->loadRawData(kDemo3Seq, temp); - _seq_Demo4 = _staticres->loadRawData(kDemo4Seq, temp); - _seq_Reunion = _staticres->loadRawData(kOutroReunionSeq, temp); - - _seq_WSATable = _staticres->loadStrings(kIntroWSAStrings, _seq_WSATable_Size); - _seq_CPSTable = _staticres->loadStrings(kIntroCPSStrings, _seq_CPSTable_Size); - _seq_COLTable = _staticres->loadStrings(kIntroCOLStrings, _seq_COLTable_Size); - _seq_textsTable = _staticres->loadStrings(kIntroStrings, _seq_textsTable_Size); - - _itemList = _staticres->loadStrings(kItemNames, _itemList_Size); - _takenList = _staticres->loadStrings(kTakenStrings, _takenList_Size); - _placedList = _staticres->loadStrings(kPlacedStrings, _placedList_Size); - _droppedList = _staticres->loadStrings(kDroppedStrings, _droppedList_Size); - _noDropList = _staticres->loadStrings(kNoDropStrings, _noDropList_Size); - _putDownFirst = _staticres->loadStrings(kPutDownString, _putDownFirst_Size); - _waitForAmulet = _staticres->loadStrings(kWaitAmuletString, _waitForAmulet_Size); - _blackJewel = _staticres->loadStrings(kBlackJewelString, _blackJewel_Size); - _poisonGone = _staticres->loadStrings(kPoisonGoneString, _poisonGone_Size); - _healingTip = _staticres->loadStrings(kHealingTipString, _healingTip_Size); - _thePoison = _staticres->loadStrings(kThePoisonStrings, _thePoison_Size); - _fluteString = _staticres->loadStrings(kFluteStrings, _fluteString_Size); - _wispJewelStrings = _staticres->loadStrings(kWispJewelStrings, _wispJewelStrings_Size); - _magicJewelString = _staticres->loadStrings(kMagicJewelStrings, _magicJewelString_Size); - _flaskFull = _staticres->loadStrings(kFlaskFullString, _flaskFull_Size); - _fullFlask = _staticres->loadStrings(kFullFlaskString, _fullFlask_Size); - _veryClever = _staticres->loadStrings(kVeryCleverString, _veryClever_Size); - _homeString = _staticres->loadStrings(kOutroHomeString, _homeString_Size); - _newGameString = _staticres->loadStrings(kNewGameString, _newGameString_Size); - - _healingShapeTable = _staticres->loadShapeTable(kHealing1Shapes, _healingShapeTableSize); - _healingShape2Table = _staticres->loadShapeTable(kHealing2Shapes, _healingShape2TableSize); - _posionDeathShapeTable = _staticres->loadShapeTable(kPoisonDeathShapes, _posionDeathShapeTableSize); - _fluteAnimShapeTable = _staticres->loadShapeTable(kFluteShapes, _fluteAnimShapeTableSize); - _winterScrollTable = _staticres->loadShapeTable(kWinter1Shapes, _winterScrollTableSize); - _winterScroll1Table = _staticres->loadShapeTable(kWinter2Shapes, _winterScroll1TableSize); - _winterScroll2Table = _staticres->loadShapeTable(kWinter3Shapes, _winterScroll2TableSize); - _drinkAnimationTable = _staticres->loadShapeTable(kDrinkShapes, _drinkAnimationTableSize); - _brandonToWispTable = _staticres->loadShapeTable(kWispShapes, _brandonToWispTableSize); - _magicAnimationTable = _staticres->loadShapeTable(kMagicAnimShapes, _magicAnimationTableSize); - _brandonStoneTable = _staticres->loadShapeTable(kBranStoneShapes, _brandonStoneTableSize); - - _characterImageTable = _staticres->loadStrings(kCharacterImageFilenames, _characterImageTableSize); - - _roomFilenameTable = _staticres->loadStrings(kRoomFilenames, _roomFilenameTableSize); - - _amuleteAnim = _staticres->loadRawData(kAmuleteAnimSeq, temp); - - _specialPalettes = _staticres->loadPaletteTable(kPaletteList, temp); - - _guiStrings = _staticres->loadStrings(kGUIStrings, _guiStringsSize); - _configStrings = _staticres->loadStrings(kConfigStrings, _configStringsSize); - - _soundFiles = _staticres->loadStrings(kAudioTracks, _soundFilesSize); - _soundFilesIntro = _staticres->loadStrings(kAudioTracksIntro, _soundFilesIntroSize); - _cdaTrackTable = (const int32*) _staticres->loadRawData(kKyra1TownsCDATable, _cdaTrackTableSize); + _seq_Forest = _staticres->loadRawData(k1ForestSeq, temp); + _seq_KallakWriting = _staticres->loadRawData(k1KallakWritingSeq, temp); + _seq_KyrandiaLogo = _staticres->loadRawData(k1KyrandiaLogoSeq, temp); + _seq_KallakMalcolm = _staticres->loadRawData(k1KallakMalcolmSeq, temp); + _seq_MalcolmTree = _staticres->loadRawData(k1MalcolmTreeSeq, temp); + _seq_WestwoodLogo = _staticres->loadRawData(k1WestwoodLogoSeq, temp); + _seq_Demo1 = _staticres->loadRawData(k1Demo1Seq, temp); + _seq_Demo2 = _staticres->loadRawData(k1Demo2Seq, temp); + _seq_Demo3 = _staticres->loadRawData(k1Demo3Seq, temp); + _seq_Demo4 = _staticres->loadRawData(k1Demo4Seq, temp); + _seq_Reunion = _staticres->loadRawData(k1OutroReunionSeq, temp); + + _seq_WSATable = _staticres->loadStrings(k1IntroWSAStrings, _seq_WSATable_Size); + _seq_CPSTable = _staticres->loadStrings(k1IntroCPSStrings, _seq_CPSTable_Size); + _seq_COLTable = _staticres->loadStrings(k1IntroCOLStrings, _seq_COLTable_Size); + _seq_textsTable = _staticres->loadStrings(k1IntroStrings, _seq_textsTable_Size); + + _itemList = _staticres->loadStrings(k1ItemNames, _itemList_Size); + _takenList = _staticres->loadStrings(k1TakenStrings, _takenList_Size); + _placedList = _staticres->loadStrings(k1PlacedStrings, _placedList_Size); + _droppedList = _staticres->loadStrings(k1DroppedStrings, _droppedList_Size); + _noDropList = _staticres->loadStrings(k1NoDropStrings, _noDropList_Size); + _putDownFirst = _staticres->loadStrings(k1PutDownString, _putDownFirst_Size); + _waitForAmulet = _staticres->loadStrings(k1WaitAmuletString, _waitForAmulet_Size); + _blackJewel = _staticres->loadStrings(k1BlackJewelString, _blackJewel_Size); + _poisonGone = _staticres->loadStrings(k1PoisonGoneString, _poisonGone_Size); + _healingTip = _staticres->loadStrings(k1HealingTipString, _healingTip_Size); + _thePoison = _staticres->loadStrings(k1ThePoisonStrings, _thePoison_Size); + _fluteString = _staticres->loadStrings(k1FluteStrings, _fluteString_Size); + _wispJewelStrings = _staticres->loadStrings(k1WispJewelStrings, _wispJewelStrings_Size); + _magicJewelString = _staticres->loadStrings(k1MagicJewelStrings, _magicJewelString_Size); + _flaskFull = _staticres->loadStrings(k1FlaskFullString, _flaskFull_Size); + _fullFlask = _staticres->loadStrings(k1FullFlaskString, _fullFlask_Size); + _veryClever = _staticres->loadStrings(k1VeryCleverString, _veryClever_Size); + _homeString = _staticres->loadStrings(k1OutroHomeString, _homeString_Size); + _newGameString = _staticres->loadStrings(k1NewGameString, _newGameString_Size); + + _healingShapeTable = _staticres->loadShapeTable(k1Healing1Shapes, _healingShapeTableSize); + _healingShape2Table = _staticres->loadShapeTable(k1Healing2Shapes, _healingShape2TableSize); + _posionDeathShapeTable = _staticres->loadShapeTable(k1PoisonDeathShapes, _posionDeathShapeTableSize); + _fluteAnimShapeTable = _staticres->loadShapeTable(k1FluteShapes, _fluteAnimShapeTableSize); + _winterScrollTable = _staticres->loadShapeTable(k1Winter1Shapes, _winterScrollTableSize); + _winterScroll1Table = _staticres->loadShapeTable(k1Winter2Shapes, _winterScroll1TableSize); + _winterScroll2Table = _staticres->loadShapeTable(k1Winter3Shapes, _winterScroll2TableSize); + _drinkAnimationTable = _staticres->loadShapeTable(k1DrinkShapes, _drinkAnimationTableSize); + _brandonToWispTable = _staticres->loadShapeTable(k1WispShapes, _brandonToWispTableSize); + _magicAnimationTable = _staticres->loadShapeTable(k1MagicAnimShapes, _magicAnimationTableSize); + _brandonStoneTable = _staticres->loadShapeTable(k1BranStoneShapes, _brandonStoneTableSize); + + _characterImageTable = _staticres->loadStrings(k1CharacterImageFilenames, _characterImageTableSize); + + _roomFilenameTable = _staticres->loadStrings(k1RoomFilenames, _roomFilenameTableSize); + + _amuleteAnim = _staticres->loadRawData(k1AmuleteAnimSeq, temp); + + _specialPalettes = _staticres->loadPaletteTable(k1PaletteList, temp); + + _guiStrings = _staticres->loadStrings(k1GUIStrings, _guiStringsSize); + _configStrings = _staticres->loadStrings(k1ConfigStrings, _configStringsSize); + + _soundFiles = _staticres->loadStrings(k1AudioTracks, _soundFilesSize); + _soundFilesIntro = _staticres->loadStrings(k1AudioTracksIntro, _soundFilesIntroSize); + _cdaTrackTable = (const int32*) _staticres->loadRawData(k1TownsCDATable, _cdaTrackTableSize); // copied static res // room list - const Room *tempRoomList = _staticres->loadRoomTable(kRoomList, _roomTableSize); + const Room *tempRoomList = _staticres->loadRoomTable(k1RoomList, _roomTableSize); if (_roomTableSize > 0) { _roomTable = new Room[_roomTableSize]; @@ -1003,11 +1017,11 @@ void KyraEngine_v1::initStaticResource() { memcpy(_roomTable, tempRoomList, _roomTableSize*sizeof(Room)); tempRoomList = 0; - _staticres->unloadId(kRoomList); + _staticres->unloadId(k1RoomList); } // default shape table - const Shape *tempShapeTable = _staticres->loadShapeTable(kDefaultShapes, _defaultShapeTableSize); + const Shape *tempShapeTable = _staticres->loadShapeTable(k1DefaultShapes, _defaultShapeTableSize); if (_defaultShapeTableSize > 0) { _defaultShapeTable = new Shape[_defaultShapeTableSize]; @@ -1016,7 +1030,7 @@ void KyraEngine_v1::initStaticResource() { memcpy(_defaultShapeTable, tempShapeTable, _defaultShapeTableSize*sizeof(Shape)); tempShapeTable = 0; - _staticres->unloadId(kDefaultShapes); + _staticres->unloadId(k1DefaultShapes); } // audio data tables @@ -1034,7 +1048,7 @@ void KyraEngine_v1::initStaticResource() { _soundData = (_flags.platform == Common::kPlatformPC) ? soundData_PC : soundData_TOWNS; } -void KyraEngine_v1::loadMouseShapes() { +void KyraEngine_LoK::loadMouseShapes() { _screen->loadBitmap("MOUSE.CPS", 3, 3, 0); _screen->_curPage = 2; _shapes[0] = _screen->encodeShape(0, 0, 8, 10, 0); @@ -1050,7 +1064,7 @@ void KyraEngine_v1::loadMouseShapes() { _screen->setShapePages(5, 3); } -void KyraEngine_v1::loadCharacterShapes() { +void KyraEngine_LoK::loadCharacterShapes() { int curImage = 0xFF; int videoPage = _screen->_curPage; _screen->_curPage = 2; @@ -1071,7 +1085,7 @@ void KyraEngine_v1::loadCharacterShapes() { _screen->_curPage = videoPage; } -void KyraEngine_v1::loadSpecialEffectShapes() { +void KyraEngine_LoK::loadSpecialEffectShapes() { _screen->loadBitmap("EFFECTS.CPS", 3, 3, 0); _screen->_curPage = 2; @@ -1089,7 +1103,7 @@ void KyraEngine_v1::loadSpecialEffectShapes() { _shapes[currShape] = _screen->encodeShape((currShape-201) * 16, 106, 16, 16, 1); } -void KyraEngine_v1::loadItems() { +void KyraEngine_LoK::loadItems() { int shape; _screen->loadBitmap("JEWELS3.CPS", 3, 3, 0); @@ -1143,7 +1157,7 @@ void KyraEngine_v1::loadItems() { delete[] fileData; } -void KyraEngine_v1::loadButtonShapes() { +void KyraEngine_LoK::loadButtonShapes() { _screen->loadBitmap("BUTTONS2.CPS", 3, 3, 0); _screen->_curPage = 2; _gui->_scrollUpButton.data0ShapePtr = _screen->encodeShape(0, 0, 24, 14, 1); @@ -1155,7 +1169,7 @@ void KyraEngine_v1::loadButtonShapes() { _screen->_curPage = 0; } -void KyraEngine_v1::loadMainScreen(int page) { +void KyraEngine_LoK::loadMainScreen(int page) { _screen->clearPage(page); if (_flags.lang == Common::EN_ANY && !_flags.isTalkie && (_flags.platform == Common::kPlatformPC || _flags.platform == Common::kPlatformAmiga)) @@ -1186,43 +1200,37 @@ void KyraEngine_HoF::initStaticResource() { _ingamePakList = _staticres->loadStrings(k2IngamePakFiles, _ingamePakListSize); _sequenceStrings = _staticres->loadStrings(k2SeqplayStrings, _sequenceStringsSize); _ingameSoundList = _staticres->loadStrings(k2IngameSfxFiles, _ingameSoundListSize); - _ingameSoundIndex = (const uint16*) _staticres->loadRawData(k2IngameSfxIndex, _ingameSoundIndexSize); + _ingameSoundIndex = (const uint16 *)_staticres->loadRawData(k2IngameSfxIndex, _ingameSoundIndexSize); _musicFileListIntro = _staticres->loadStrings(k2SeqplayIntroTracks, _musicFileListIntroSize); _musicFileListIngame = _staticres->loadStrings(k2IngameTracks, _musicFileListIngameSize); _musicFileListFinale = _staticres->loadStrings(k2SeqplayFinaleTracks, _musicFileListFinaleSize); _cdaTrackTableIntro = _staticres->loadRawData(k2SeqplayIntroCDA, _cdaTrackTableIntroSize); _cdaTrackTableIngame = _staticres->loadRawData(k2IngameCDA, _cdaTrackTableIngameSize); _cdaTrackTableFinale = _staticres->loadRawData(k2SeqplayFinaleCDA, _cdaTrackTableFinaleSize); - _ingameTalkObjIndex = (const uint16*) _staticres->loadRawData(k2IngameTalkObjIndex, _ingameTalkObjIndexSize); + _ingameTalkObjIndex = (const uint16 *)_staticres->loadRawData(k2IngameTalkObjIndex, _ingameTalkObjIndexSize); _ingameTimJpStr = _staticres->loadStrings(k2IngameTimJpStrings, _ingameTimJpStrSize); - _itemAnimData = _staticres->loadHofShapeAnimDataV2(k2IngameShapeAnimData, _itemAnimDataSize); + _itemAnimData = _staticres->loadShapeAnimData_v2(k2IngameShapeAnimData, _itemAnimDataSize); - // replace sequence talkie files with localized versions and cut off .voc - // suffix from voc files so as to allow compression specific file extensions - const char* const* seqSoundList = _staticres->loadStrings(k2SeqplaySfxFiles, _sequenceSoundListSize); - const char* const* tlkfiles = _staticres->loadStrings(k2SeqplayTlkFiles, tmpSize); - char ** tmpSndLst = new char*[_sequenceSoundListSize]; + // replace sequence talkie files with localized versions + const char *const *seqSoundList = _staticres->loadStrings(k2SeqplaySfxFiles, _sequenceSoundListSize); + const char *const *tlkfiles = _staticres->loadStrings(k2SeqplayTlkFiles, tmpSize); + char **tmpSndLst = new char*[_sequenceSoundListSize]; for (int i = 0; i < _sequenceSoundListSize; i++) { - int len = strlen(seqSoundList[i]); + const int len = strlen(seqSoundList[i]); tmpSndLst[i] = new char[len + 1]; tmpSndLst[i][0] = 0; - if (_flags.platform == Common::kPlatformPC) - len -= 4; - - if (tlkfiles) { + if (tlkfiles && len > 1) { for (int ii = 0; ii < tmpSize; ii++) { - if (!scumm_stricmp(&seqSoundList[i][1], &tlkfiles[ii][1])) - strcpy(tmpSndLst[i], tlkfiles[ii]); + if (strlen(tlkfiles[ii]) > 1 && !scumm_stricmp(&seqSoundList[i][1], &tlkfiles[ii][1])) + strcpy(tmpSndLst[i], tlkfiles[ii]); } } if (tmpSndLst[i][0] == 0) strcpy(tmpSndLst[i], seqSoundList[i]); - - tmpSndLst[i][len] = 0; } tlkfiles = seqSoundList = 0; @@ -1269,7 +1277,7 @@ void KyraEngine_HoF::initStaticResource() { &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 + &KyraEngine_HoF::seq_introHand2, &KyraEngine_HoF::seq_introHand3, 0 }; static const SeqProc hofDemoSequenceCallbacks[] = { @@ -1289,7 +1297,19 @@ void KyraEngine_HoF::initStaticResource() { _callbackN = (_flags.isDemo && !_flags.isTalkie) ? hofDemoNestedSequenceCallbacks : hofNestedSequenceCallbacks; } -const ScreenDim Screen_v1::_screenDimTable[] = { +void KyraEngine_MR::initStaticResource() { + int tmp = 0; + _mainMenuStrings = _staticres->loadStrings(k3MainMenuStrings, _mainMenuStringsSize); + _soundList = _staticres->loadStrings(k3MusicFiles, _soundListSize); + _scoreTable = _staticres->loadRawData(k3ScoreTable, _scoreTableSize); + _sfxFileList = _staticres->loadStrings(k3SfxFiles, _sfxFileListSize); + _sfxFileMap = _staticres->loadRawData(k3SfxMap, _sfxFileMapSize); + _itemAnimData = _staticres->loadShapeAnimData_v2(k3ItemAnimData, tmp); + _itemMagicTable = _staticres->loadRawData(k3ItemMagicTable, tmp); + _itemStringMap = _staticres->loadRawData(k3ItemStringMap, _itemStringMapSize); +} + +const ScreenDim Screen_LoK::_screenDimTable[] = { { 0x00, 0x00, 0x28, 0xC8, 0x0F, 0x0C, 0x00, 0x00 }, { 0x08, 0x48, 0x18, 0x38, 0x0F, 0x0C, 0x00, 0x00 }, { 0x01, 0x08, 0x26, 0x80, 0x0F, 0x0C, 0x00, 0x00 }, @@ -1303,7 +1323,7 @@ const ScreenDim Screen_v1::_screenDimTable[] = { { 0x03, 0x28, 0x22, 0x46, 0x0F, 0x0D, 0x00, 0x00 } }; -const int Screen_v1::_screenDimTableCount = ARRAYSIZE(Screen_v1::_screenDimTable); +const int Screen_LoK::_screenDimTableCount = ARRAYSIZE(Screen_LoK::_screenDimTable); const ScreenDim Screen_HoF::_screenDimTable[] = { { 0x00, 0x00, 0x28, 0xC8, 0xC7, 0xCF, 0x00, 0x00 }, @@ -1331,31 +1351,31 @@ const ScreenDim Screen_MR::_screenDimTable[] = { const int Screen_MR::_screenDimTableCount = ARRAYSIZE(Screen_MR::_screenDimTable); -const int8 KyraEngine::_addXPosTable[] = { +const int8 KyraEngine_v1::_addXPosTable[] = { 4, 4, 0, -4, -4, -4, 0, 4 }; -const int8 KyraEngine::_addYPosTable[] = { +const int8 KyraEngine_v1::_addYPosTable[] = { 0, -2, -2, -2, 0, 2, 2, 2 }; -const int8 KyraEngine_v1::_charXPosTable[] = { +const int8 KyraEngine_v1::_charAddXPosTable[] = { 0, 4, 4, 4, 0, -4, -4, -4 }; -const int8 KyraEngine_v1::_charYPosTable[] = { +const int8 KyraEngine_v1::_charAddYPosTable[] = { -2, -2, 0, 2, 2, 2, 0, -2 }; -const uint16 KyraEngine_v1::_itemPosX[] = { +const uint16 KyraEngine_LoK::_itemPosX[] = { 95, 115, 135, 155, 175, 95, 115, 135, 155, 175 }; -const uint8 KyraEngine_v1::_itemPosY[] = { +const uint8 KyraEngine_LoK::_itemPosY[] = { 160, 160, 160, 160, 160, 181, 181, 181, 181, 181 }; -void GUI_v1::initStaticResource() { +void GUI_LoK::initStaticResource() { GUI_V1_BUTTON(_scrollUpButton, 0x12, 1, 1, 1, 0x483, 0, 0, 0, 0x18, 0x0f, 0); GUI_V1_BUTTON(_scrollDownButton, 0x13, 1, 1, 1, 0x483, 0, 0, 0, 0x18, 0x0f, 0); @@ -1366,13 +1386,13 @@ void GUI_v1::initStaticResource() { GUI_V1_BUTTON(_menuButtonData[4], 0x10, 1, 1, 1, 0x487, 0, 0, 0, 0, 0, 0); GUI_V1_BUTTON(_menuButtonData[5], 0x11, 1, 1, 1, 0x487, 0, 0, 0, 0, 0, 0); - delete [] _menu; + delete[] _menu; _menu = new Menu[6]; assert(_menu); - Button::Callback quitPlayingFunctor = BUTTON_FUNCTOR(GUI_v1, this, &GUI_v1::quitPlaying); - Button::Callback loadGameMenuFunctor = BUTTON_FUNCTOR(GUI_v1, this, &GUI_v1::loadGameMenu); - Button::Callback cancelSubMenuFunctor = BUTTON_FUNCTOR(GUI_v1, this, &GUI_v1::cancelSubMenu); + Button::Callback quitPlayingFunctor = BUTTON_FUNCTOR(GUI_LoK, this, &GUI_LoK::quitPlaying); + Button::Callback loadGameMenuFunctor = BUTTON_FUNCTOR(GUI_LoK, this, &GUI_LoK::loadGameMenu); + Button::Callback cancelSubMenuFunctor = BUTTON_FUNCTOR(GUI_LoK, this, &GUI_LoK::cancelSubMenu); GUI_V1_MENU(_menu[0], -1, -1, 0x100, 0x8B, 248, 249, 250, 0, 251, -1, 8, 0, 5, -1, -1, -1, -1); GUI_V1_MENU_ITEM(_menu[0].item[0], 1, 0, 0, 0, -1, -1, 0x1E, 0xDC, 0x0F, 252, 253, -1, 0, 248, 249, 250, -1, 0, 0, 0, 0, 0); @@ -1381,16 +1401,16 @@ void GUI_v1::initStaticResource() { GUI_V1_MENU_ITEM(_menu[0].item[3], 1, 0, 0, 0, -1, -1, 0x51, 0xDC, 0x0F, 252, 253, -1, 0, 248, 249, 250, -1, 0, 0, 0, 0, 0); GUI_V1_MENU_ITEM(_menu[0].item[4], 1, 0, 0, 0, -1, 0, 0x6E, 0xDC, 0x0F, 252, 253, -1, 255, 248, 249, 250, -1, 0, 0, 0, 0, 0); _menu[0].item[0].callback = loadGameMenuFunctor; - _menu[0].item[1].callback = BUTTON_FUNCTOR(GUI_v1, this, &GUI_v1::saveGameMenu); - _menu[0].item[2].callback = BUTTON_FUNCTOR(GUI_v1, this, &GUI_v1::gameControlsMenu); + _menu[0].item[1].callback = BUTTON_FUNCTOR(GUI_LoK, this, &GUI_LoK::saveGameMenu); + _menu[0].item[2].callback = BUTTON_FUNCTOR(GUI_LoK, this, &GUI_LoK::gameControlsMenu); _menu[0].item[3].callback = quitPlayingFunctor; - _menu[0].item[4].callback = BUTTON_FUNCTOR(GUI_v1, this, &GUI_v1::resumeGame); + _menu[0].item[4].callback = BUTTON_FUNCTOR(GUI_LoK, this, &GUI_LoK::resumeGame); GUI_V1_MENU(_menu[1], -1, -1, 0x140, 0x38, 248, 249, 250, 0, 254,-1, 8, 0, 2, -1, -1, -1, -1); GUI_V1_MENU_ITEM(_menu[1].item[0], 1, 0, 0, 0, 0x18, 0, 0x1E, 0x48, 0x0F, 252, 253, -1, 255, 248, 249, 250, -1, 0, 0, 0, 0, 0); GUI_V1_MENU_ITEM(_menu[1].item[1], 1, 0, 0, 0, 0xD8, 0, 0x1E, 0x48, 0x0F, 252, 253, -1, 255, 248, 249, 250, -1, 0, 0, 0, 0, 0); - _menu[1].item[0].callback = BUTTON_FUNCTOR(GUI_v1, this, &GUI_v1::quitConfirmYes); - _menu[1].item[1].callback = BUTTON_FUNCTOR(GUI_v1, this, &GUI_v1::quitConfirmNo); + _menu[1].item[0].callback = BUTTON_FUNCTOR(GUI_LoK, this, &GUI_LoK::quitConfirmYes); + _menu[1].item[1].callback = BUTTON_FUNCTOR(GUI_LoK, this, &GUI_LoK::quitConfirmNo); GUI_V1_MENU(_menu[2], -1, -1, 0x120, 0xA0, 248, 249, 250, 0, 251, -1, 8, 0, 6, 132, 22, 132, 124); GUI_V1_MENU_ITEM(_menu[2].item[0], 1, 0, 0, 0, -1, 255, 0x27, 0x100, 0x0F, 252, 253, 5, 0, 248, 249, 250, -1, 0, 0, 0, 0, 0); @@ -1404,7 +1424,7 @@ void GUI_v1::initStaticResource() { GUI_V1_MENU(_menu[3], -1, -1, 288, 67, 248, 249, 250, 0, 251, -1, 8, 0, 2, -1, -1, -1, -1); GUI_V1_MENU_ITEM(_menu[3].item[0], 1, 0, 0, 0, 24, 0, 44, 85, 15, 252, 253, -1, 255, 248, 249, 250, -1, 0, 0, 0, 0, 0); GUI_V1_MENU_ITEM(_menu[3].item[1], 1, 0, 0, 0, 179, 0, 44, 85, 15, 252, 253, -1, 255, 248, 249, 250, -1, 0, 0, 0, 0, 0); - _menu[3].item[0].callback = BUTTON_FUNCTOR(GUI_v1, this, &GUI_v1::savegameConfirm); + _menu[3].item[0].callback = BUTTON_FUNCTOR(GUI_LoK, this, &GUI_LoK::savegameConfirm); _menu[3].item[1].callback = cancelSubMenuFunctor; GUI_V1_MENU(_menu[4], -1, -1, 0xD0, 0x4C, 248, 249, 250, 0, 251, -1, 8, 0, 2, -1, -1, -1, -1); @@ -1420,16 +1440,16 @@ void GUI_v1::initStaticResource() { GUI_V1_MENU_ITEM(_menu[5].item[3], 1, 0, 0, 0, 0xA5, 0, 0x51, 0x80, 0x0F, 252, 253, 5, 0, 248, 249, 250, -1, 0, 0x10, 0x53, 0, 0); GUI_V1_MENU_ITEM(_menu[5].item[4], 1, 0, 0, 0, 0xA5, 0, 0x62, 0x80, 0x0F, 252, 253, 5, 0, 248, 249, 250, -1, 0, 0x10, 0x65, 0, 0); GUI_V1_MENU_ITEM(_menu[5].item[5], 1, 0, 0, 0, -1, 0, 0x7F, 0x6C, 0x0F, 252, 253, -1, 255, 248, 249, 250, -1, -0, 0, 0, 0, 0); - _menu[5].item[0].callback = BUTTON_FUNCTOR(GUI_v1, this, &GUI_v1::controlsChangeMusic); - _menu[5].item[1].callback = BUTTON_FUNCTOR(GUI_v1, this, &GUI_v1::controlsChangeSounds); - _menu[5].item[2].callback = BUTTON_FUNCTOR(GUI_v1, this, &GUI_v1::controlsChangeWalk); - _menu[5].item[4].callback = BUTTON_FUNCTOR(GUI_v1, this, &GUI_v1::controlsChangeText); - _menu[5].item[5].callback = BUTTON_FUNCTOR(GUI_v1, this, &GUI_v1::controlsApply); + _menu[5].item[0].callback = BUTTON_FUNCTOR(GUI_LoK, this, &GUI_LoK::controlsChangeMusic); + _menu[5].item[1].callback = BUTTON_FUNCTOR(GUI_LoK, this, &GUI_LoK::controlsChangeSounds); + _menu[5].item[2].callback = BUTTON_FUNCTOR(GUI_LoK, this, &GUI_LoK::controlsChangeWalk); + _menu[5].item[4].callback = BUTTON_FUNCTOR(GUI_LoK, this, &GUI_LoK::controlsChangeText); + _menu[5].item[5].callback = BUTTON_FUNCTOR(GUI_LoK, this, &GUI_LoK::controlsApply); } -void KyraEngine_v1::setupButtonData() { - delete [] _buttonData; - delete [] _buttonDataListPtr; +void KyraEngine_LoK::setupButtonData() { + delete[] _buttonData; + delete[] _buttonDataListPtr; _buttonData = new Button[15]; assert(_buttonData); @@ -1437,9 +1457,9 @@ void KyraEngine_v1::setupButtonData() { assert(_buttonDataListPtr); GUI_V1_BUTTON(_buttonData[1], 0x01, 1, 1, 1, 0x0487, 0, 0x009, 0xA4, 0x36, 0x1E, 0); - _buttonData[1].buttonCallback = BUTTON_FUNCTOR(GUI_v1, _gui, &GUI_v1::buttonMenuCallback); + _buttonData[1].buttonCallback = BUTTON_FUNCTOR(GUI_LoK, _gui, &GUI_LoK::buttonMenuCallback); - Button::Callback inventoryFunctor = BUTTON_FUNCTOR(KyraEngine_v1, this, &KyraEngine_v1::buttonInventoryCallback); + Button::Callback inventoryFunctor = BUTTON_FUNCTOR(KyraEngine_LoK, this, &KyraEngine_LoK::buttonInventoryCallback); for (int i = 2; i <= 10; ++i) _buttonData[i].buttonCallback = inventoryFunctor; _buttonData[0].buttonCallback = inventoryFunctor; @@ -1454,7 +1474,7 @@ void KyraEngine_v1::setupButtonData() { GUI_V1_BUTTON(_buttonData[9], 0x0A, 0, 0, 0, 0x0400, 0, 0x099, 0xB3, 0x13, 0x14, 0); GUI_V1_BUTTON(_buttonData[10], 0x0B, 0, 0, 0, 0x0400, 0, 0x0AD, 0xB3, 0x13, 0x14, 0); - Button::Callback amuletFunctor = BUTTON_FUNCTOR(KyraEngine_v1, this, &KyraEngine_v1::buttonAmuletCallback); + Button::Callback amuletFunctor = BUTTON_FUNCTOR(KyraEngine_LoK, this, &KyraEngine_LoK::buttonAmuletCallback); GUI_V1_BUTTON(_buttonData[11], 0x15, 1, 1, 1, 0x0487, 0, 0x0FD, 0x9C, 0x1A, 0x12, 0); GUI_V1_BUTTON(_buttonData[12], 0x16, 1, 1, 1, 0x0487, 0, 0x0E7, 0xAA, 0x1A, 0x12, 0); GUI_V1_BUTTON(_buttonData[13], 0x17, 1, 1, 1, 0x0487, 0, 0x0FD, 0xB5, 0x1A, 0x12, 0); @@ -1467,29 +1487,29 @@ void KyraEngine_v1::setupButtonData() { _buttonDataListPtr[14] = 0; } -const uint8 KyraEngine_v1::_magicMouseItemStartFrame[] = { +const uint8 KyraEngine_LoK::_magicMouseItemStartFrame[] = { 0xAD, 0xB7, 0xBE, 0x00 }; -const uint8 KyraEngine_v1::_magicMouseItemEndFrame[] = { +const uint8 KyraEngine_LoK::_magicMouseItemEndFrame[] = { 0xB1, 0xB9, 0xC2, 0x00 }; -const uint8 KyraEngine_v1::_magicMouseItemStartFrame2[] = { +const uint8 KyraEngine_LoK::_magicMouseItemStartFrame2[] = { 0xB2, 0xBA, 0xC3, 0x00 }; -const uint8 KyraEngine_v1::_magicMouseItemEndFrame2[] = { +const uint8 KyraEngine_LoK::_magicMouseItemEndFrame2[] = { 0xB6, 0xBD, 0xC8, 0x00 }; -const uint16 KyraEngine_v1::_amuletX[] = { 231, 275, 253, 253 }; -const uint16 KyraEngine_v1::_amuletY[] = { 170, 170, 159, 181 }; +const uint16 KyraEngine_LoK::_amuletX[] = { 231, 275, 253, 253 }; +const uint16 KyraEngine_LoK::_amuletY[] = { 170, 170, 159, 181 }; -const uint16 KyraEngine_v1::_amuletX2[] = { 0x000, 0x0FD, 0x0E7, 0x0FD, 0x113, 0x000 }; -const uint16 KyraEngine_v1::_amuletY2[] = { 0x000, 0x09F, 0x0AA, 0x0B5, 0x0AA, 0x000 }; +const uint16 KyraEngine_LoK::_amuletX2[] = { 0x000, 0x0FD, 0x0E7, 0x0FD, 0x113, 0x000 }; +const uint16 KyraEngine_LoK::_amuletY2[] = { 0x000, 0x09F, 0x0AA, 0x0B5, 0x0AA, 0x000 }; -const int8 KyraEngine_v1::_dosTrackMap[] = { +const int8 KyraEngine_LoK::_dosTrackMap[] = { -1, 0, -1, 1, 0, 3, 0, 2, 0, 4, 1, 2, 1, 3, 1, 4, 1, 92, 1, 6, 1, 7, 2, 2, @@ -1506,18 +1526,10 @@ const int8 KyraEngine_v1::_dosTrackMap[] = { 8, 4, 8, 5, 6, 11, 5, 11 }; -const int KyraEngine_v1::_dosTrackMapSize = ARRAYSIZE(KyraEngine_v1::_dosTrackMap); +const int KyraEngine_LoK::_dosTrackMapSize = ARRAYSIZE(KyraEngine_LoK::_dosTrackMap); // kyra engine v2 static data -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 }; @@ -1530,16 +1542,16 @@ const char *KyraEngine_HoF::_languageExtension[] = { "ENG", "FRE", "GER",/*, - "ITA", Italian and Spanish was never included + "ITA", Italian and Spanish were never included "SPA"*/ - "JPN" + "JPN", }; const char *KyraEngine_HoF::_scriptLangExt[] = { "EMC", "FMC", "GMC",/*, - "IMC", Italian and Spanish was never included + "IMC", Italian and Spanish were never included "SMC"*/ "JMC" }; @@ -1611,7 +1623,7 @@ const int8 KyraEngine_HoF::_dosTrackMap[] = { const int KyraEngine_HoF::_dosTrackMapSize = ARRAYSIZE(KyraEngine_HoF::_dosTrackMap); void KyraEngine_HoF::initInventoryButtonList() { - delete [] _inventoryButtons; + delete[] _inventoryButtons; _inventoryButtons = new Button[15]; assert(_inventoryButtons); @@ -1655,19 +1667,15 @@ 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); - for (int i = 0; i < 4; ++i) { + 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, 0xC7, 0xCF, 0xC7, 0xCF, 0xC7, 0xCF, 0); - } - for (int i = 0; i < 4; ++i) { + 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, 0xC7, 0xCF, 0xC7, 0xCF, 0xC7, 0xCF, 0); - } - for (int i = 0; i < 4; ++i) { + 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, 0xC7, 0xCF, 0xC7, 0xCF, 0xC7, 0xCF, 0); - } - for (uint i = 0; i < ARRAYSIZE(_menuButtons); ++i) { + for (uint i = 0; i < ARRAYSIZE(_menuButtons); ++i) 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_HoF, this, &GUI_HoF::clickLoadSlot); Button::Callback clickSaveSlotFunctor = BUTTON_FUNCTOR(GUI_HoF, this, &GUI_HoF::clickSaveSlot); @@ -1932,74 +1940,11 @@ const uint8 KyraEngine_HoF::_rainbowRoomData[] = { // kyra 3 static res -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", - "CLOWN1.AUD", - "DARM2.AUD", - "FALL1M.AUD", - "FALL2.AUD", - "FISH1.AUD", - "FISHWNDR.AUD", - "HERMAN1.AUD", - "JAIL1.AUD", - "JUNGLE1.AUD", - "KATHY1.AUD", - "NICESINE.AUD", - "PEGASUS1.AUD", - "PIRATE1.AUD", - "PIRATE2.AUD", - "PIRATE3.AUD", - "POP3.AUD", - "PORT1.AUD", - "QUEEN1.AUD", - "RUINS1.AUD", - "SNAKES1.AUD", - "SPRING1.AUD", - "STATUE1.AUD", - "STATUE2.AUD", - "TITLE1.AUD", - "UNDER1.AUD", - "WALKCHP1.AUD", - "YANK1.AUD", - "ZAN2.AUD", - "GROOVE2.AUD", - "GROOVE3.AUD", - "KING1.AUD", - "KING2.AUD", - "GROOVE1.AUD", - "JAIL2.AUD", - "SPIRIT1.AUD", - "SPRING1A.AUD", - "POP1.AUD", - "POP2.AUD", - "SQUIRL1.AUD" -}; - -const int KyraEngine_MR::_soundListSize = ARRAYSIZE(KyraEngine_MR::_soundList); - const char *KyraEngine_MR::_languageExtension[] = { "TRE", "TRF", "TRG"/*, - "TRI", Italian and Spanish was never included + "TRI", Italian and Spanish were never included "TRS"*/ }; @@ -2026,316 +1971,6 @@ const uint8 KyraEngine_MR::_characterFrameTable[] = { 0x36, 0x35, 0x35, 0x33, 0x32, 0x32, 0x34, 0x34 }; -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, - 0x46, 0x00, 0xA9, 0x00, 0x33, 0x00, 0x65, 0x00, - 0x9B, 0x00, 0x17, 0x00, 0xBB, 0x00, 0x64, 0x00, - 0x55, 0x00, 0xD5, 0x00, 0x66, 0x00, 0xB9, 0x00, - 0x9A, 0x00, 0xFF, 0x00, 0xCC, 0x00, 0x67, 0x00, - 0x2E, 0x00, 0xA1, 0x00, 0xD0, 0x00, 0x63, 0x00, - 0x89, 0x00, 0xBE, 0x00, 0x80, 0x00, 0x1D, 0x00, - 0x02, 0x00, 0x28, 0x00, 0x91, 0x00, 0x29, 0x00, - 0xCE, 0x00, 0x8F, 0x00, 0x49, 0x00, 0x2B, 0x00, - 0x2D, 0x00, 0x2C, 0x00, 0x3E, 0x00, 0x22, 0x00, - 0x80, 0x00, 0x9C, 0x00, 0x2E, 0x00, 0x04, 0x00, - 0x47, 0x00, 0xA8, 0x00, 0x51, 0x00, 0x52, 0x00, - 0x80, 0x00, 0x48, 0x00, 0x38, 0x0A, 0x0C, 0x00, - 0xD8, 0x00, 0xD1, 0x00, 0xD2, 0x00, 0xD3, 0x00, - 0xD1, 0x00, 0x6A, 0x00, 0x8A, 0x00, 0xC0, 0x00, - 0xC1, 0x00, 0xC2, 0x00, 0x9F, 0x00, 0xA3, 0x00, - 0x90, 0x00, 0xB6, 0x00, 0x37, 0x00, 0x71, 0x00, - 0x13, 0x00, 0x50, 0x00, 0x5A, 0x00, 0x6E, 0x00, - 0x70, 0x00, 0x11, 0x00, 0x16, 0x00, 0x14, 0x00, - 0x43, 0x00, 0xCD, 0x00, 0xAA, 0x00, 0x15, 0x00, - 0x83, 0x00, 0x19, 0x00, 0xB3, 0x00, 0x6F, 0x00, - 0x26, 0x00, 0xC8, 0x00, 0xA7, 0x00, 0x98, 0x00, - 0x87, 0x00, 0xC7, 0x00, 0xA2, 0x00, 0xB0, 0x00, - 0x12, 0x00, 0xD7, 0x00, 0x56, 0x00, 0x45, 0x00, - 0x4B, 0x00, 0xAF, 0x00, 0x3B, 0x00, 0x6C, 0x00, - 0x8E, 0x00, 0x39, 0x00, 0x38, 0x00, 0x92, 0x00, - 0x4B, 0x00, 0xD0, 0x00, 0x4A, 0x00, 0x9D, 0x00, - 0x7F, 0x00, 0x6D, 0x00, 0xFF, 0x00, 0xFF, 0x00, - 0x3D, 0x00, 0x72, 0x00, 0x40, 0x00, 0x66, 0x00, - 0x01, 0x00, 0xA5, 0x00, 0x00, 0x00, 0x3C, 0x00, - 0xAC, 0x00, 0x38, 0x00, 0x8B, 0x00, 0xDF, 0x00, - 0x0E, 0x00, 0x54, 0x00, 0xFF, 0x00, 0xFF, 0x00, - 0x94, 0x00, 0xAB, 0x00, 0x76, 0x00, 0x58, 0x00, - 0x6B, 0x00, 0x27, 0x00, 0xFF, 0x00, 0x77, 0x00, - 0xA6, 0x00, 0x63, 0x00, 0x9E, 0x00, 0xDE, 0x00, - 0x84, 0x00, 0x85, 0x00, 0x86, 0x00, 0x3F, 0x00, - 0xCC, 0x00, 0xCC, 0x00, 0xCC, 0x00, 0x93, 0x00, - 0x9D, 0x00, 0x75, 0x00, 0x75, 0x00, 0x75, 0x00, - 0x75, 0x00, 0x3A, 0x00, 0xFF, 0x00, 0xFF, 0x00, - 0xFF, 0x00, 0xAE, 0x00, 0x8C, 0x00, 0x20, 0x00, - 0xFF, 0x00, 0x32, 0x00, 0x32, 0x00, 0xFF, 0x00, - 0x4D, 0x00, 0xD9, 0x00, 0x88, 0x00, 0x4D, 0x00, - 0x4D, 0x00, 0x4D, 0x00, 0x4D, 0x00, 0xA0, 0x00, - 0x4C, 0x00, 0x8C, 0x00, 0x4C, 0x00, 0x4C, 0x00, - 0x8C, 0x00, 0x8C, 0x00, 0x5C, 0x00, 0x5D, 0x00, - 0x60, 0x00, 0x5F, 0x00, 0xC5, 0x00, 0xBF, 0x00, - 0xFF, 0x00, 0x4F, 0x00, 0x16, 0x00, 0x59, 0x00, - 0xFF, 0x00, 0x24, 0x00, 0xA4, 0x00, 0xCF, 0x00, - 0xFF, 0x00, 0x47, 0x00, 0x95, 0x00, 0x96, 0x00, - 0x7B, 0x00, 0xBD, 0x00, 0xFF, 0x00, 0x34, 0x00, - 0x35, 0x00, 0x36, 0x00, 0xDE, 0x00, 0xFF, 0x00, - 0x4B, 0x00, 0xD6, 0x00, 0xFF, 0x00, 0x61, 0x00, - 0x62, 0x00, 0xFF, 0x00, 0x78, 0x00, 0xFF, 0x00, - 0x44, 0x00, 0xB4, 0x00, 0xB5, 0x00, 0x42, 0x00, - 0x27, 0x00, 0xA2, 0x00, 0x27, 0x00, 0x5D, 0x00, - 0x7A, 0x00, 0x89, 0x00, 0x1A, 0x00, 0x0E, 0x00, - 0x82, 0x00, 0xFF, 0x00, 0x79, 0x00, 0x2A, 0x00, - 0x81, 0x00, 0xFF, 0x00, 0x74, 0x00, 0x4E, 0x00, - 0xB1, 0x00, 0x1B, 0x00, 0x2F, 0x00, 0xBA, 0x00, - 0xBB, 0x00, 0xBC, 0x00, 0xDA, 0x00, 0xDB, 0x00, - 0x18, 0x00, 0x5E, 0x00, 0x0D, 0x0A, 0x88, 0x00, - 0x1E, 0x00, 0x1F, 0x00, 0x20, 0x00, 0x21, 0x00, - 0x69, 0x00, 0x1C, 0x00, 0x7C, 0x00, 0x30, 0x00, - 0xC3, 0x00, 0xC4, 0x00, 0xAD, 0x00, 0x25, 0x00, - 0x53, 0x00, 0xB7, 0x00, 0xB8, 0x00, 0xDC, 0x00, - 0x8D, 0x00, 0xCB, 0x00, 0xD4, 0x00, 0xB2, 0x00, - 0xDD, 0x00, 0x57, 0x00, 0x41, 0x00, 0x10, 0x00, - 0x4C, 0x00, 0xC9, 0x00, 0xFF, 0x00, 0xFF, 0x00, - 0x7D, 0x00, 0x7E, 0x00, 0xCA, 0x00, 0x03, 0x00, - 0x04, 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, - 0x08, 0x00, 0x09, 0x00, 0x0A, 0x00, 0x0B, 0x00, - 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, - 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, - 0x23, 0x00, 0x97, 0x00, 0x73, 0x00 -}; - -const int KyraEngine_MR::_sfxFileMapSize = ARRAYSIZE(KyraEngine_MR::_sfxFileMap); - -const char *KyraEngine_MR::_sfxFileList[] = { - "ALARM1", - "ARMOIRE1", - "ARROW1", - "AUDLAFF1", - "AUDLAFF2", - "AUDLAFF3", - "AUDLAFF4", - "AUDLAFF5", - "AUDLAFF6", - "AUDLAFF7", - "AUDLAFF8", - "AUDLAFF9", - "BARK22A", - "BEAM1", - "BEDSQK1", - "BEDSQK2", - "BIGCLOK1", - "BIGDOR2", - "BIRD4", - "BIRD122", - "BIRD222", - "BIRD322", - "BLAST22D", - "BLINK1", - "BOATMIX1", - "BODYFAL1", - "BOTLBLOW", - "BOUNCE3", - "BOUNCE5", - "BOW2", - "BUBL1", - "BUBL2", - "BUBL3", - "BUBL4", - "BUTTON1", - "BUTTON2", - "CANNON1", - "CASHREG1", - "CATHY1", - "CHAIN1", - "CHATTER1", - "CHATTER2", - "CHEESE1", - "CHICHIC2", - "CHIPLAF1", - "CHIPROR1", - "CLANG1", - "CLDOOR1", - "CLEAT1", - "CLOTHES1", - "COIN2", - "COUNTER1", - "CREAK1", - "CREAK2", - "CREAK3", - "CRIKT22A", - "CRMAD1", - "CRNORM1", - "CRUMBLE1", - "CRUNCH1", - "CRYSTAL1", - "DFLY1", - "DIAL1", - "DIGDIRT1", - "DIZZY1", - "DODO1", - "DOORBELL", - "DOORCL1", - "DOOROP1", - "DRIP1", - "DROPITM1", - "EAT22A", - "EATNUT1", - "ELEC1", - "EXPLODE2", - "FALL1", - "FALLM2", - "FALLM3", - "FESTRE1", - "FISHLAF2", - "FLAG22A", - "FLAG22B", - "FLAG22C", - "FLPOOF1", - "FOLDER1", - "FROG1", - "FROGJMP1", - "FSHBUBL1", - "FUNNEL1", - "FUSE1", - "GATE22A", - "GEM1", - "GEMFIRE1", - "GEMLIT1", - "GEMPUT1", - "GEMRAIN1", - "GEMWND1", - "GIRLLAF1", - "GIRLLAF2", - "GLASBRK1", - "GLOWY1", - "GOODK33", - "GROWTWIG", - "GUNTHER3", - "H2ODROP2", - "H2OFALL1", - "HAMMER1", - "HAYFALL2", - "HERMMAG1", - "HIPRES1", - "HITHED22", - "HOWL1", - "HUM1", - "HYPNO1", - "HYPNO2", - "IMPACT1", - "JOHAN1", - "JUNGAMB2", - "KISS1", - "KISS2", - "KNIFE", - "KNIFHIT1", - "KNIFSTAB", - "KNOCK", - "LAND1", - "LEVIBAB1", - "LEVIMAN1", - "LID", - "MACHMIX1", - "MALCFALL", - "MALCYAWN", - "MJUMP1", - "MOO1", - "MOO2", - "MOO3", - "MORPH1", - "MORPH2", - "MORPH3", - "MORPH4", - "MOTHS1", - "MSPLASH1", - "MTLSLAM1", - "MUDBATH1", - "NAIL1", - "NEIGH1", - "NETCATCH", - "NETMAL1", - "NETRIP1", - "OPDOOR1", - "OWL1", - "OWL2", - "PEDAL3", - "PEGWING1", - "PICKUP1", - "PLUCK3", - "POLGULP1", - "POOF1", - "PORTAL1", - "POURH2O1", - "PRIMOR1", - "PUMP1", - "PUNCTRE1", - "RATTLE1", - "REV2", - "RING", - "ROAR3", - "ROWBOAT1", - "RUCKUS1", - "RUMBLE1", - "SCOLD1", - "SCRATCH1", - "SHOVEL1", - "SHOWER2", - "SLOTPUL1", - "SNAKKILL", - "SNAP1", - "SNIFF1", - "SNIFF2", - "SNIFFM1", - "SNIP22B", - "SNORIN1", - "SNOROUT1", - "SNORT1", - "SPITBAL1", - "SPITBAL2", - "SPLASH1", - "SQUEAK1", - "SQUEAK2", - "SQUEAK3", - "STATUE", - "STAMPED1", - "STARS1", - "STONE1", - "STONE2", - "STONE3", - "STRETCH1", - "STRETCH2", - "SUNRISE1", - "SWALLOW1", - "SWALLOW2", - "SWAV22B", - "TELBEL1", - "TELBEL2", - "TENNIS1", - "THROW1", - "THUMP1", - "TOILET1", - "TRAPDOR1", - "TRICKLE", - "TROLGRNT", - "TROLYEL1", - "TROLYEL2", - "TUBEDOR1", - "TWIGSNAP", - "UMBRLA1", - "UNLOK22A", - "VACUUM", - "WAVELT1", - "WHIP1", - "WHIP2", - "WOODHIT1", - "YAWN1", - "ZING", - "ZIPPER1" -}; - -const int KyraEngine_MR::_sfxFileListSize = ARRAYSIZE(KyraEngine_MR::_sfxFileList); - const uint8 KyraEngine_MR::_badConscienceFrameTable[] = { 0x13, 0x13, 0x13, 0x18, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x10, 0x13, 0x13, 0x13, 0x13, @@ -2376,28 +2011,6 @@ const uint8 KyraEngine_MR::_trashItemList[] = { 0x39, 0x40, 0x3E, 0x3D, 0x3C, 0x3F, 0xFF }; -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, - 0x10, 0x22, 0x21, 0x0F, 0x22, 0x10, 0x0F, 0x21, - 0xFF, 0xFF, 0xFF, 0xFF -}; - -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, - 2, 0, 2, 2, 0, 0, 0, 0, - 0, 0, 1, 2, 0, 2, 0, 2, - 0, 0, 2, 0, 0, 0, 0, 1, - 1, 0, 2, 2, 0, 0, 2, 0, - 0, 2, 0, 2, 2, 0, 0, 2, - 0, 0, 0, 0, 2, 0, 0, 2 -}; - -const uint KyraEngine_MR::_itemStringMapSize = ARRAYSIZE(KyraEngine_MR::_itemStringMap); - const uint8 KyraEngine_MR::_itemStringPickUp[] = { 0x4, 0x7, 0x0, 0xA }; @@ -2410,36 +2023,6 @@ 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]; @@ -2483,19 +2066,15 @@ 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) { + 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) { + 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) { + 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) { + 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); @@ -2523,6 +2102,7 @@ void GUI_MR::initStaticData() { 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); + _audioOptions.item[3].callback = BUTTON_FUNCTOR(GUI_MR, this, &GUI_MR::toggleHeliumMode); 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) @@ -2592,5 +2172,15 @@ void GUI_MR::initStaticData() { _deathMenu.item[i].enabled = false; } +const int8 KyraEngine_MR::_albumWSAX[] = { + 0, 77, -50, 99, -61, 82, -58, 85, + -64, 80, -63, 88, -63, 88, -64, 0 +}; + +const int8 KyraEngine_MR::_albumWSAY[] = { + 0, -1, 3, 0, -1, 0, -2, 0, + -1, -2, 2, 2, -6, -6, -6, 0 +}; + } // End of namespace Kyra diff --git a/engines/kyra/text.cpp b/engines/kyra/text.cpp index 980b762b23..f8eb10a85e 100644 --- a/engines/kyra/text.cpp +++ b/engines/kyra/text.cpp @@ -25,7 +25,7 @@ -#include "kyra/kyra.h" +#include "kyra/kyra_v1.h" #include "kyra/screen.h" #include "kyra/text.h" @@ -35,7 +35,7 @@ namespace Kyra { -TextDisplayer::TextDisplayer(KyraEngine *vm, Screen *screen) { +TextDisplayer::TextDisplayer(KyraEngine_v1 *vm, Screen *screen) { _screen = screen; _vm = vm; @@ -210,7 +210,7 @@ void TextDisplayer::printTalkTextMessage(const char *text, int x, int y, uint8 c calcWidestLineBounds(x1, x2, w, x); _talkCoords.x = x1; _talkCoords.w = w + 2; - _screen->copyRegion(_talkCoords.x, _talkMessageY, _talkCoords.x, _talkCoords.y, _talkCoords.w, _talkMessageH, srcPage, dstPage); + _screen->copyRegion(_talkCoords.x, _talkMessageY, _talkCoords.x, _talkCoords.y, _talkCoords.w, _talkMessageH, srcPage, dstPage, Screen::CR_NO_P_CHECK); int curPage = _screen->_curPage; _screen->_curPage = srcPage; for (int i = 0; i < lineCount; ++i) { diff --git a/engines/kyra/text.h b/engines/kyra/text.h index 5ae37e32ef..d45e5f9242 100644 --- a/engines/kyra/text.h +++ b/engines/kyra/text.h @@ -31,11 +31,11 @@ #include "kyra/screen.h" namespace Kyra { -class KyraEngine; +class KyraEngine_v1; class TextDisplayer { public: - TextDisplayer(KyraEngine *vm, Screen *screen); + TextDisplayer(KyraEngine_v1 *vm, Screen *screen); virtual ~TextDisplayer() {} int maxSubstringLen() const { return TALK_SUBSTRING_LEN; } @@ -60,7 +60,7 @@ public: bool printed() const { return _talkMessagePrinted; } protected: Screen *_screen; - KyraEngine *_vm; + KyraEngine_v1 *_vm; struct TalkCoords { uint16 y, x, w; diff --git a/engines/kyra/text_hof.cpp b/engines/kyra/text_hof.cpp index dd1796dd02..dd587c5112 100644 --- a/engines/kyra/text_hof.cpp +++ b/engines/kyra/text_hof.cpp @@ -107,8 +107,7 @@ char *TextDisplayer_HoF::preprocessString(const char *str) { int textWidth = _screen->getTextWidth(p); _screen->_charWidth = 0; - // longer text strings for German versions - int maxTextWidth = (_vm->language() == 2 ? 240 : 176); + int maxTextWidth = (_vm->language() == 0) ? 176 : 240; if (textWidth > maxTextWidth) { if (textWidth > (maxTextWidth*2)) { @@ -452,7 +451,7 @@ void KyraEngine_HoF::updateDlgBuffer() { filename[11] = suffix[_lang]; if (_dlgBuffer) - delete [] _dlgBuffer; + delete[] _dlgBuffer; _dlgBuffer = _res->fileData(filename, 0); } @@ -649,7 +648,7 @@ void KyraEngine_HoF::npcChatSequence(const char *str, int objectId, int vocHigh, } while (((textEnabled() && _chatEndTime > _system->getMillis()) || (speechEnabled() && snd_voiceIsPlaying())) && !(_quitFlag || skipFlag())) { - if (!speechEnabled() && chatAnimEndTime > _system->getMillis() || speechEnabled() && snd_voiceIsPlaying()) { + if ((!speechEnabled() && chatAnimEndTime > _system->getMillis()) || (speechEnabled() && snd_voiceIsPlaying())) { _tim->resetFinishedFlag(); while (!_tim->finished() && !skipFlag() && !_quitFlag) { if (_currentTalkSections.TLKTim) diff --git a/engines/kyra/text_hof.h b/engines/kyra/text_hof.h index ef1f481c19..3da6e081f0 100644 --- a/engines/kyra/text_hof.h +++ b/engines/kyra/text_hof.h @@ -23,8 +23,8 @@ * */ -#ifndef KYRA_TEXT_V2_H -#define KYRA_TEXT_V2_H +#ifndef KYRA_TEXT_HOF_H +#define KYRA_TEXT_HOF_H #include "kyra/text.h" diff --git a/engines/kyra/text_v1.cpp b/engines/kyra/text_lok.cpp index 5534992c6a..f6b0407a75 100644 --- a/engines/kyra/text_v1.cpp +++ b/engines/kyra/text_lok.cpp @@ -23,17 +23,17 @@ * */ -#include "kyra/kyra_v1.h" -#include "kyra/screen_v1.h" +#include "kyra/kyra_lok.h" +#include "kyra/screen_lok.h" #include "kyra/text.h" -#include "kyra/animator_v1.h" +#include "kyra/animator_lok.h" #include "kyra/sprites.h" #include "kyra/timer.h" namespace Kyra { -void KyraEngine_v1::waitForChatToFinish(int vocFile, int16 chatDuration, const char *chatStr, uint8 charNum) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::waitForChatToFinish(%i, %s, %i)", chatDuration, chatStr, charNum); +void KyraEngine_LoK::waitForChatToFinish(int vocFile, int16 chatDuration, const char *chatStr, uint8 charNum) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::waitForChatToFinish(%i, %s, %i)", chatDuration, chatStr, charNum); bool hasUpdatedNPCs = false; bool runLoop = true; bool drawText = textEnabled(); @@ -62,10 +62,8 @@ void KyraEngine_v1::waitForChatToFinish(int vocFile, int16 chatDuration, const c if (chatDuration != -1) chatDuration *= _tickLength; - if (vocFile != -1) { - snd_voiceWaitForFinish(); + if (vocFile != -1) snd_playVoiceFile(vocFile); - } _timer->disable(14); _timer->disable(18); @@ -154,7 +152,7 @@ void KyraEngine_v1::waitForChatToFinish(int vocFile, int16 chatDuration, const c //clearKyrandiaButtonIO(); } -void KyraEngine_v1::endCharacterChat(int8 charNum, int16 convoInitialized) { +void KyraEngine_LoK::endCharacterChat(int8 charNum, int16 convoInitialized) { _charSayUnk3 = -1; if (charNum > 4 && charNum < 11) { @@ -171,7 +169,7 @@ void KyraEngine_v1::endCharacterChat(int8 charNum, int16 convoInitialized) { } } -void KyraEngine_v1::restoreChatPartnerAnimFrame(int8 charNum) { +void KyraEngine_LoK::restoreChatPartnerAnimFrame(int8 charNum) { _talkingCharNum = -1; if (charNum > 0 && charNum < 5) { @@ -186,7 +184,7 @@ void KyraEngine_v1::restoreChatPartnerAnimFrame(int8 charNum) { _animator->updateAllObjectShapes(); } -void KyraEngine_v1::backupChatPartnerAnimFrame(int8 charNum) { +void KyraEngine_LoK::backupChatPartnerAnimFrame(int8 charNum) { _talkingCharNum = 0; if (charNum < 5 && charNum > 0) @@ -202,7 +200,7 @@ void KyraEngine_v1::backupChatPartnerAnimFrame(int8 charNum) { _animator->updateAllObjectShapes(); } -int8 KyraEngine_v1::getChatPartnerNum() { +int8 KyraEngine_LoK::getChatPartnerNum() { uint8 sceneTable[] = {0x2, 0x5, 0x2D, 0x7, 0x1B, 0x8, 0x22, 0x9, 0x30, 0x0A}; int pos = 0; int partner = -1; @@ -224,7 +222,7 @@ int8 KyraEngine_v1::getChatPartnerNum() { return partner; } -int KyraEngine_v1::initCharacterChat(int8 charNum) { +int KyraEngine_LoK::initCharacterChat(int8 charNum) { int returnValue = 0; if (_talkingCharNum == -1) { @@ -258,8 +256,8 @@ int KyraEngine_v1::initCharacterChat(int8 charNum) { return returnValue; } -void KyraEngine_v1::characterSays(int vocFile, const char *chatStr, int8 charNum, int8 chatDuration) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::characterSays('%s', %i, %d)", chatStr, charNum, chatDuration); +void KyraEngine_LoK::characterSays(int vocFile, const char *chatStr, int8 charNum, int8 chatDuration) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::characterSays('%s', %i, %d)", chatStr, charNum, chatDuration); uint8 startAnimFrames[] = { 0x10, 0x32, 0x56, 0x0, 0x0, 0x0 }; uint16 chatTicks; @@ -269,6 +267,8 @@ void KyraEngine_v1::characterSays(int vocFile, const char *chatStr, int8 charNum if (_currentCharacter->sceneId == 210) return; + snd_voiceWaitForFinish(true); + convoInitialized = initCharacterChat(charNum); chatPartnerNum = getChatPartnerNum(); @@ -338,8 +338,8 @@ void KyraEngine_v1::characterSays(int vocFile, const char *chatStr, int8 charNum endCharacterChat(charNum, convoInitialized); } -void KyraEngine_v1::drawSentenceCommand(const char *sentence, int color) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::drawSentenceCommand('%s', %i)", sentence, color); +void KyraEngine_LoK::drawSentenceCommand(const char *sentence, int color) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::drawSentenceCommand('%s', %i)", sentence, color); _screen->hideMouse(); _screen->fillRect(8, 143, 311, 152, 12); @@ -358,8 +358,8 @@ void KyraEngine_v1::drawSentenceCommand(const char *sentence, int color) { _fadeText = false; } -void KyraEngine_v1::updateSentenceCommand(const char *str1, const char *str2, int color) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::updateSentenceCommand('%s', '%s', %i)", str1, str2, color); +void KyraEngine_LoK::updateSentenceCommand(const char *str1, const char *str2, int color) { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::updateSentenceCommand('%s', '%s', %i)", str1, str2, color); char sentenceCommand[500]; strncpy(sentenceCommand, str1, 500); if (str2) @@ -369,8 +369,8 @@ void KyraEngine_v1::updateSentenceCommand(const char *str1, const char *str2, in _screen->updateScreen(); } -void KyraEngine_v1::updateTextFade() { - debugC(9, kDebugLevelMain, "KyraEngine_v1::updateTextFade()"); +void KyraEngine_LoK::updateTextFade() { + debugC(9, kDebugLevelMain, "KyraEngine_LoK::updateTextFade()"); if (!_fadeText) return; diff --git a/engines/kyra/text_mr.cpp b/engines/kyra/text_mr.cpp index 35f91c1ccc..16c56da099 100644 --- a/engines/kyra/text_mr.cpp +++ b/engines/kyra/text_mr.cpp @@ -55,25 +55,26 @@ char *TextDisplayer_MR::preprocessString(const char *str) { int count = 0, offs = 0; if (textWidth > (3*maxTextWidth)) { count = getCharLength(p, textWidth/4); - offs = dropCRIntoString(p, getCharLength(p, maxTextWidth), count); + offs = dropCRIntoString(p, count, getCharLength(p, maxTextWidth)); p += count + offs; - } - + // No update of textWidth here + } + if (textWidth > (2*maxTextWidth)) { count = getCharLength(p, textWidth/3); - offs = dropCRIntoString(p, getCharLength(p, maxTextWidth), count); + offs = dropCRIntoString(p, count, getCharLength(p, maxTextWidth)); p += count + offs; textWidth = _screen->getTextWidth(p); } count = getCharLength(p, textWidth/2); - offs = dropCRIntoString(p, getCharLength(p, maxTextWidth), count); + offs = dropCRIntoString(p, count, getCharLength(p, maxTextWidth)); p += count + offs; textWidth = _screen->getTextWidth(p); if (textWidth > maxTextWidth) { count = getCharLength(p, textWidth/2); - offs = dropCRIntoString(p, getCharLength(p, maxTextWidth), count); + offs = dropCRIntoString(p, count, getCharLength(p, maxTextWidth)); } } @@ -131,6 +132,12 @@ int TextDisplayer_MR::dropCRIntoString(char *str, int minOffs, int maxOffs) { void TextDisplayer_MR::printText(const char *str, int x, int y, uint8 c0, uint8 c1, uint8 c2, Screen::FontId font) { debugC(9, kDebugLevelMain, "TextDisplayer_MR::printText('%s', %d, %d, %d, %d, %d)", str, x, y, c0, c1, c2); + if (_vm->_albumChatActive) { + c0 = 0xEE; + c1 = 0xE3; + c2 = 0x00; + } + uint8 colorMap[] = { 0, 255, 240, 240 }; colorMap[3] = c1; _screen->setTextColor(colorMap, 0, 3); @@ -226,7 +233,7 @@ void KyraEngine_MR::objectChat(const char *str, int object, int vocHigh, int voc "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" + "MTA00S.EMC", "MTA00Q.EMC", "MTA00E.EMC", "MTA00T.EMC" }; int chat = talkScriptTable[chatType + _mainCharacter.facing * 4]; @@ -496,6 +503,134 @@ void KyraEngine_MR::goodConscienceChatWaitToFinish() { } } +void KyraEngine_MR::albumChat(const char *str, int vocHigh, int vocLow) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::albumChat('%s', %d, %d)", str, vocHigh, vocLow); + + _talkObjectList[1].x = 190; + _talkObjectList[1].y = 188; + + _chatVocHigh = _chatVocLow = -1; + _albumChatActive = true; + albumChatInit(str, 1, vocHigh, vocLow); + _albumChatActive = false; + + _chatText = str; + _chatObject = 1; + _screen->hideMouse(); + albumChatWaitToFinish(); + _screen->showMouse(); + + _chatText = 0; + _chatObject = -1; +} + +void KyraEngine_MR::albumChatInit(const char *str, int object, int vocHigh, int vocLow) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::albumChatInit('%s', %d, %d, %d)", str, object, vocHigh, vocLow); + Common::String realString; + + while (*str) { + if (str[0] == '\\' && str[1] == 'r') { + realString += '\r'; + ++str; + } else { + realString += *str; + } + + ++str; + } + + str = realString.c_str(); + + str = _text->preprocessString(str); + int lineNum = _text->buildMessageSubstrings(str); + + int xPos = 0, yPos = 0; + + if (!object) { + int scale = getScale(_mainCharacter.x1, _mainCharacter.y1); + yPos = _mainCharacter.y1 - ((_mainCharacter.height * scale) >> 8) - 8; + xPos = _mainCharacter.x1; + } else { + yPos = _talkObjectList[object].y; + xPos = _talkObjectList[object].x; + } + + yPos -= lineNum * 10; + yPos = MAX(yPos, 0); + _text->_talkMessageY = yPos; + _text->_talkMessageH = lineNum*10; + + int width = _text->getWidestLineWidth(lineNum); + _text->calcWidestLineBounds(xPos, yPos, width, xPos); + _text->_talkCoords.x = xPos; + _text->_talkCoords.w = width + 2; + + _screen->hideMouse(); + + if (textEnabled()) { + objectChatPrintText(str, object); + _chatEndTime = _system->getMillis() + chatCalcDuration(str) * _tickLength; + } else { + _chatEndTime = _system->getMillis(); + } + + if (speechEnabled()) { + _chatVocHigh = vocHigh; + _chatVocLow = vocLow; + } else { + _chatVocHigh = _chatVocLow = -1; + } + + _screen->showMouse(); +} + +void KyraEngine_MR::albumChatWaitToFinish() { + debugC(9, kDebugLevelMain, "KyraEngine_MR::albumChatWaitToFinish()"); + if (_chatVocHigh) { + playVoice(_chatVocHigh, _chatVocLow); + _chatVocHigh = _chatVocLow = -1; + } + + bool running = true; + const uint32 endTime = _chatEndTime; + resetSkipFlag(); + + uint32 nextFrame = 0; + int frame = 12; + while (running && !_quitFlag) { + if (nextFrame < _system->getMillis()) { + ++frame; + if (frame > 22) + frame = 13; + + _album.wsa->setX(-100); + _album.wsa->setY(90); + _album.wsa->setDrawPage(2); + + albumRestoreRect(); + _album.wsa->displayFrame(frame, 0x4000); + albumUpdateRect(); + + nextFrame = _system->getMillis() + _rnd.getRandomNumberRng(4, 8) * _tickLength; + } + + if (_album.nextPage != 14) + albumUpdateAnims(); + else + _screen->updateScreen(); + + const uint32 curTime = _system->getMillis(); + if ((textEnabled() && !speechEnabled() && curTime > endTime) || (speechEnabled() && !snd_voiceIsPlaying()) || skipFlag()) { + snd_stopVoice(); + resetSkipFlag(); + nextFrame = curTime; + running = false; + } + + delay(10); + } +} + void KyraEngine_MR::malcolmSceneStartupChat() { debugC(9, kDebugLevelMain, "KyraEngine_MR::malcolmSceneStartupChat()"); diff --git a/engines/kyra/timer.cpp b/engines/kyra/timer.cpp index 1f25f88c97..777871d65a 100644 --- a/engines/kyra/timer.cpp +++ b/engines/kyra/timer.cpp @@ -23,7 +23,7 @@ * */ -#include "kyra/kyra.h" +#include "kyra/kyra_v1.h" #include "kyra/timer.h" #include "common/func.h" @@ -34,7 +34,7 @@ namespace Kyra { namespace { struct TimerResync : public Common::UnaryFunction<TimerEntry&, void> { uint32 _tickLength, _curTime; - TimerResync(KyraEngine *vm, uint32 curTime) : _tickLength(vm->tickLength()), _curTime(curTime) {} + TimerResync(KyraEngine_v1 *vm, uint32 curTime) : _tickLength(vm->tickLength()), _curTime(curTime) {} void operator()(TimerEntry &entry) const { if (entry.lastUpdate < 0) { @@ -62,10 +62,32 @@ struct TimerEqual : public Common::UnaryFunction<const TimerEntry&, bool> { }; } // end of anonymous namespace +void TimerManager::pause(bool p) { + if (p) { + ++_isPaused; + + if (_isPaused == 1) { + _isPaused = true; + _pauseStart = _system->getMillis(); + } + } else if (!p && _isPaused > 0) { + --_isPaused; + + if (_isPaused == 0) { + const uint32 pausedTime = _system->getMillis() - _pauseStart; + _nextRun += pausedTime; + + for (Iterator pos = _timers.begin(); pos != _timers.end(); ++pos) { + pos->lastUpdate += pausedTime; + pos->nextRun += pausedTime; + } + } + } +} + void TimerManager::reset() { - for (Iterator pos = _timers.begin(); pos != _timers.end(); ++pos) { + for (Iterator pos = _timers.begin(); pos != _timers.end(); ++pos) delete pos->func; - } _timers.clear(); } @@ -93,7 +115,7 @@ void TimerManager::addTimer(uint8 id, TimerFunc *func, int countdown, bool enabl void TimerManager::update() { debugC(9, kDebugLevelTimer, "TimerManager::update()"); - if (_system->getMillis() < _nextRun) + if (_system->getMillis() < _nextRun || _isPaused) return; _nextRun += 99999; @@ -121,8 +143,10 @@ void TimerManager::update() { void TimerManager::resync() { debugC(9, kDebugLevelTimer, "TimerManager::resync()"); + const uint32 curTime = _isPaused ? _pauseStart : _system->getMillis(); + _nextRun = 0; // force rerun - Common::for_each(_timers.begin(), _timers.end(), TimerResync(_vm, _system->getMillis())); + Common::for_each(_timers.begin(), _timers.end(), TimerResync(_vm, curTime)); } void TimerManager::resetNextRun() { @@ -225,7 +249,9 @@ void TimerManager::disable(uint8 id) { } void TimerManager::loadDataFromFile(Common::SeekableReadStream &file, int version) { - debugC(9, kDebugLevelTimer, "TimerManager::loadDataFromFile(%p, %d)", (const void*)&file, version); + debugC(9, kDebugLevelTimer, "TimerManager::loadDataFromFile(%p, %d)", (const void *)&file, version); + + const uint32 loadTime = _isPaused ? _pauseStart : _system->getMillis(); if (version <= 7) { _nextRun = 0; @@ -240,12 +266,11 @@ void TimerManager::loadDataFromFile(Common::SeekableReadStream &file, int versio timer->countdown = countdown; if (nextRun) { - timer->nextRun = nextRun + _system->getMillis(); + timer->nextRun = nextRun + loadTime; timer->lastUpdate = timer->nextRun - countdown * _vm->tickLength(); } else { - uint32 curTime = _system->getMillis(); - timer->nextRun = curTime; - timer->lastUpdate = curTime - countdown * _vm->tickLength(); + timer->nextRun = loadTime; + timer->lastUpdate = loadTime - countdown * _vm->tickLength(); } } else { warning("Loading timer data for non existing timer %d", i); @@ -272,14 +297,16 @@ void TimerManager::loadDataFromFile(Common::SeekableReadStream &file, int versio } void TimerManager::saveDataToFile(Common::WriteStream &file) const { - debugC(9, kDebugLevelTimer, "TimerManager::saveDataToFile(%p)", (const void*)&file); + debugC(9, kDebugLevelTimer, "TimerManager::saveDataToFile(%p)", (const void *)&file); + + const uint32 saveTime = _isPaused ? _pauseStart : _system->getMillis(); file.writeByte(count()); for (CIterator pos = _timers.begin(); pos != _timers.end(); ++pos) { file.writeByte(pos->id); file.writeByte(pos->enabled); file.writeSint32BE(pos->countdown); - file.writeSint32BE(pos->lastUpdate - _system->getMillis()); + file.writeSint32BE(pos->lastUpdate - saveTime); } } diff --git a/engines/kyra/timer.h b/engines/kyra/timer.h index 0991f0a1b1..691bac3fb5 100644 --- a/engines/kyra/timer.h +++ b/engines/kyra/timer.h @@ -26,7 +26,7 @@ #ifndef KYRA_TIMER_H #define KYRA_TIMER_H -#include "kyra/kyra.h" +#include "kyra/kyra_v1.h" #include "common/list.h" #include "common/stream.h" @@ -49,9 +49,11 @@ struct TimerEntry { class TimerManager { public: - TimerManager(KyraEngine *vm, OSystem *sys) : _vm(vm), _system(sys), _timers(), _nextRun(0) {} + TimerManager(KyraEngine_v1 *vm, OSystem *sys) : _vm(vm), _system(sys), _timers(), _nextRun(0), _isPaused(0), _pauseStart(0) {} ~TimerManager() { reset(); } + void pause(bool p); + void reset(); void addTimer(uint8 id, TimerFunc *func, int countdown, bool enabled); @@ -77,15 +79,26 @@ public: private: void resync(); - KyraEngine *_vm; + KyraEngine_v1 *_vm; OSystem *_system; Common::List<TimerEntry> _timers; uint32 _nextRun; + uint _isPaused; + uint32 _pauseStart; + typedef Common::List<TimerEntry>::iterator Iterator; typedef Common::List<TimerEntry>::const_iterator CIterator; }; +class PauseTimer { +public: + PauseTimer(TimerManager &timer) : _timer(timer) { _timer.pause(true); } + ~PauseTimer() { _timer.pause(false); } +private: + TimerManager &_timer; +}; + } // end of namespace Kyra #endif diff --git a/engines/kyra/timer_v1.cpp b/engines/kyra/timer_lok.cpp index f5e7c52ba1..69b93b54c3 100644 --- a/engines/kyra/timer_v1.cpp +++ b/engines/kyra/timer_lok.cpp @@ -23,20 +23,20 @@ * */ -#include "kyra/kyra.h" #include "kyra/kyra_v1.h" +#include "kyra/kyra_lok.h" #include "kyra/screen.h" -#include "kyra/animator_v1.h" +#include "kyra/animator_lok.h" #include "kyra/timer.h" #include "common/system.h" namespace Kyra { -#define TimerV1(x) new Common::Functor1Mem<int, void, KyraEngine_v1>(this, &KyraEngine_v1::x) +#define TimerV1(x) new Common::Functor1Mem<int, void, KyraEngine_LoK>(this, &KyraEngine_LoK::x) -void KyraEngine_v1::setupTimers() { - debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v1::setupTimers()"); +void KyraEngine_LoK::setupTimers() { + debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_LoK::setupTimers()"); for (int i = 0; i <= 4; ++i) _timer->addTimer(i, 0, -1, 1); @@ -73,8 +73,8 @@ void KyraEngine_v1::setupTimers() { _timer->addTimer(33, TimerV1(updateAnimFlag2), 3, 1); } -void KyraEngine_v1::timerUpdateHeadAnims(int timerNum) { - debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v1::timerUpdateHeadAnims(%i)", timerNum); +void KyraEngine_LoK::timerUpdateHeadAnims(int timerNum) { + debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_LoK::timerUpdateHeadAnims(%i)", timerNum); static int8 currentFrame = 0; static const int8 frameTable[] = {4, 5, 4, 5, 4, 5, 0, 1, 4, 5, 4, 4, 6, 4, 8, 1, 9, 4, -1}; @@ -92,8 +92,8 @@ void KyraEngine_v1::timerUpdateHeadAnims(int timerNum) { _animator->animRefreshNPC(_talkingCharNum); } -void KyraEngine_v1::timerSetFlags1(int timerNum) { - debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v1::timerSetFlags(%i)", timerNum); +void KyraEngine_LoK::timerSetFlags1(int timerNum) { + debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_LoK::timerSetFlags(%i)", timerNum); if (_currentCharacter->sceneId == 0x1C) return; @@ -111,65 +111,65 @@ void KyraEngine_v1::timerSetFlags1(int timerNum) { } } -void KyraEngine_v1::timerFadeText(int timerNum) { - debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v1::timerFadeText(%i)", timerNum); +void KyraEngine_LoK::timerFadeText(int timerNum) { + debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_LoK::timerFadeText(%i)", timerNum); _fadeText = true; } -void KyraEngine_v1::updateAnimFlag1(int timerNum) { - debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v1::updateAnimFlag1(%d)", timerNum); +void KyraEngine_LoK::updateAnimFlag1(int timerNum) { + debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_LoK::updateAnimFlag1(%d)", timerNum); if (_brandonStatusBit & 2) { _brandonStatusBit0x02Flag = 1; } } -void KyraEngine_v1::updateAnimFlag2(int timerNum) { - debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v1::updateAnimFlag2(%d)", timerNum); +void KyraEngine_LoK::updateAnimFlag2(int timerNum) { + debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_LoK::updateAnimFlag2(%d)", timerNum); if (_brandonStatusBit & 0x20) { _brandonStatusBit0x20Flag = 1; } } -void KyraEngine_v1::setTextFadeTimerCountdown(int16 countdown) { - debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v1::setTextFadeTimerCountdown(%i)", countdown); +void KyraEngine_LoK::setTextFadeTimerCountdown(int16 countdown) { + debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_LoK::setTextFadeTimerCountdown(%i)", countdown); if (countdown == -1) countdown = 32000; _timer->setCountdown(31, countdown*60); } -void KyraEngine_v1::timerSetFlags2(int timerNum) { - debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v1::timerSetFlags2(%i)", timerNum); +void KyraEngine_LoK::timerSetFlags2(int timerNum) { + debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_LoK::timerSetFlags2(%i)", timerNum); if (!((uint32*)(_flagsTable+0x2D))[timerNum]) ((uint32*)(_flagsTable+0x2D))[timerNum] = 1; } -void KyraEngine_v1::timerCheckAnimFlag1(int timerNum) { - debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v1::timerCheckAnimFlag1(%i)", timerNum); +void KyraEngine_LoK::timerCheckAnimFlag1(int timerNum) { + debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_LoK::timerCheckAnimFlag1(%i)", timerNum); if (_brandonStatusBit & 0x20) { checkAmuletAnimFlags(); _timer->setCountdown(18, -1); } } -void KyraEngine_v1::timerCheckAnimFlag2(int timerNum) { - debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v1::timerCheckAnimFlag2(%i)", timerNum); +void KyraEngine_LoK::timerCheckAnimFlag2(int timerNum) { + debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_LoK::timerCheckAnimFlag2(%i)", timerNum); if (_brandonStatusBit & 0x2) { checkAmuletAnimFlags(); _timer->setCountdown(14, -1); } } -void KyraEngine_v1::timerRedrawAmulet(int timerNum) { - debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v1::timerRedrawAmulet(%i)", timerNum); +void KyraEngine_LoK::timerRedrawAmulet(int timerNum) { + debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_LoK::timerRedrawAmulet(%i)", timerNum); if (queryGameFlag(0xF1)) { drawAmulet(); _timer->setCountdown(19, -1); } } -void KyraEngine_v1::setWalkspeed(uint8 newSpeed) { - debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v1::setWalkspeed(%i)", newSpeed); +void KyraEngine_LoK::setWalkspeed(uint8 newSpeed) { + debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_LoK::setWalkspeed(%i)", newSpeed); static const uint8 speeds[] = { 11, 9, 6, 5, 3 }; assert(newSpeed < ARRAYSIZE(speeds)); diff --git a/engines/kyra/timer_mr.cpp b/engines/kyra/timer_mr.cpp index 53865ba0e3..37a910ccf2 100644 --- a/engines/kyra/timer_mr.cpp +++ b/engines/kyra/timer_mr.cpp @@ -64,7 +64,25 @@ void KyraEngine_MR::timerRunSceneScript7(int arg) { void KyraEngine_MR::timerFleaDeath(int arg) { debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_MR::timerFleaDeath(%d)", arg); - warning("STUB timerFleaDeath"); + _timer->setCountdown(4, 5400); + saveGame(getSavegameFilename(999), "SECOND CHANCE SAVE GAME"); + _screen->hideMouse(); + _timer->disable(4); + runAnimationScript("FLEADTH1.EMC", 0, 0, 1, 1); + runAnimationScript("FLEADTH2.EMC", 0, 0, 1, 0); + showBadConscience(); + delay(60, true); + const char *str1 = (const char *)getTableEntry(_cCodeFile, 130); + const char *str2 = (const char *)getTableEntry(_cCodeFile, 131); + if (str1 && str2) { + badConscienceChat(str1, 204, 130); + badConscienceChat(str2, 204, 131); + } + delay(60, true); + hideBadConscience(); + runAnimationScript("FLEADTH3.EMC", 0, 0, 0, 1); + _deathHandler = 9; + _screen->showMouse(); } void KyraEngine_MR::setWalkspeed(uint8 speed) { diff --git a/engines/kyra/vqa.cpp b/engines/kyra/vqa.cpp index db7cad941b..3d18f27c7e 100644 --- a/engines/kyra/vqa.cpp +++ b/engines/kyra/vqa.cpp @@ -42,7 +42,7 @@ namespace Kyra { -VQAMovie::VQAMovie(KyraEngine *vm, OSystem *system) { +VQAMovie::VQAMovie(KyraEngine_v1 *vm, OSystem *system) { _system = system; _vm = vm; _opened = false; @@ -69,7 +69,7 @@ void *VQAMovie::allocBuffer(int num, uint32 size) { * We could use realloc() here, but we don't actually need the * old contents of the buffer. */ - delete [] _buffers[num].data; + delete[] _buffers[num].data; _buffers[num].data = new uint8[size]; _buffers[num].size = size; } @@ -81,7 +81,7 @@ void *VQAMovie::allocBuffer(int num, uint32 size) { void VQAMovie::freeBuffers() { for (int i = 0; i < ARRAYSIZE(_buffers); i++) { - delete [] _buffers[i].data; + delete[] _buffers[i].data; _buffers[i].data = NULL; _buffers[i].size = 0; } @@ -356,15 +356,14 @@ bool VQAMovie::open(const char *filename) { void VQAMovie::close() { debugC(9, kDebugLevelMovie, "VQAMovie::close()"); if (_opened) { - delete [] _frameInfo; - delete [] _frame; - delete [] _codeBook; - delete [] _partialCodeBook; - delete [] _vectorPointers; + delete[] _frameInfo; + delete[] _frame; + delete[] _codeBook; + delete[] _partialCodeBook; + delete[] _vectorPointers; - if (_vm->_mixer->isSoundHandleActive(_sound)) { + if (_vm->_mixer->isSoundHandleActive(_sound)) _vm->_mixer->stopHandle(_sound); - } _frameInfo = NULL; _frame = NULL; @@ -655,11 +654,10 @@ void VQAMovie::play() { while (1) { uint32 elapsedTime; - if (_vm->_mixer->isSoundHandleActive(_sound)) { + if (_vm->_mixer->isSoundHandleActive(_sound)) elapsedTime = _vm->_mixer->getSoundElapsedTime(_sound); - } else { + else elapsedTime = _system->getMillis() - startTick; - } if (elapsedTime >= (i * 1000) / _header.frameRate) break; diff --git a/engines/kyra/vqa.h b/engines/kyra/vqa.h index 35f7d78004..f600f008b7 100644 --- a/engines/kyra/vqa.h +++ b/engines/kyra/vqa.h @@ -30,11 +30,11 @@ class OSystem; namespace Kyra { -class KyraEngine; +class KyraEngine_v1; class VQAMovie { public: - VQAMovie(KyraEngine *vm, OSystem *system); + VQAMovie(KyraEngine_v1 *vm, OSystem *system); ~VQAMovie(); bool opened() { return _opened; } @@ -54,7 +54,7 @@ public: protected: OSystem *_system; - KyraEngine *_vm; + KyraEngine_v1 *_vm; bool _opened; int _x, _y; diff --git a/engines/kyra/wsamovie.cpp b/engines/kyra/wsamovie.cpp index 764327d701..110755c3ba 100644 --- a/engines/kyra/wsamovie.cpp +++ b/engines/kyra/wsamovie.cpp @@ -27,7 +27,7 @@ #include "common/endian.h" #include "common/system.h" -#include "kyra/kyra.h" +#include "kyra/kyra_v1.h" #include "kyra/kyra_v2.h" #include "kyra/screen.h" #include "kyra/screen_v2.h" @@ -35,11 +35,11 @@ #include "kyra/resource.h" namespace Kyra { -WSAMovieV1::WSAMovieV1(KyraEngine *vm) : Movie(vm) {} -WSAMovieV1::~WSAMovieV1() { close(); } +WSAMovie_v1::WSAMovie_v1(KyraEngine_v1 *vm) : Movie(vm) {} +WSAMovie_v1::~WSAMovie_v1() { close(); } -int WSAMovieV1::open(const char *filename, int offscreenDecode, uint8 *palBuf) { - debugC(9, kDebugLevelMovie, "WSAMovieV1::open('%s', %d, %p)", filename, offscreenDecode, (const void *)palBuf); +int WSAMovie_v1::open(const char *filename, int offscreenDecode, uint8 *palBuf) { + debugC(9, kDebugLevelMovie, "WSAMovie_v1::open('%s', %d, %p)", filename, offscreenDecode, (const void *)palBuf); close(); uint32 flags = 0; @@ -117,25 +117,25 @@ int WSAMovieV1::open(const char *filename, int offscreenDecode, uint8 *palBuf) { if (firstFrame) Screen::decodeFrame4(_frameData, _deltaBuffer, _deltaBufferSize); - delete [] p; + delete[] p; _opened = true; return _numFrames; } -void WSAMovieV1::close() { - debugC(9, kDebugLevelMovie, "WSAMovieV1::close()"); +void WSAMovie_v1::close() { + debugC(9, kDebugLevelMovie, "WSAMovie_v1::close()"); if (_opened) { - delete [] _deltaBuffer; - delete [] _offscreenBuffer; - delete [] _frameOffsTable; - delete [] _frameData; + delete[] _deltaBuffer; + delete[] _offscreenBuffer; + delete[] _frameOffsTable; + delete[] _frameData; _opened = false; } } -void WSAMovieV1::displayFrame(int frameNum, ...) { - debugC(9, kDebugLevelMovie, "WSAMovieV1::displayFrame(%d, ...)", frameNum); +void WSAMovie_v1::displayFrame(int frameNum, ...) { + debugC(9, kDebugLevelMovie, "WSAMovie_v1::displayFrame(%d, ...)", frameNum); if (frameNum >= _numFrames || !_opened) return; @@ -198,8 +198,8 @@ void WSAMovieV1::displayFrame(int frameNum, ...) { _vm->screen()->copyBlockToPage(_drawPage, _x, _y, _width, _height, _offscreenBuffer); } -void WSAMovieV1::processFrame(int frameNum, uint8 *dst) { - debugC(9, kDebugLevelMovie, "WSAMovieV1::processFrame(%d, %p)", frameNum, (const void *)dst); +void WSAMovie_v1::processFrame(int frameNum, uint8 *dst) { + debugC(9, kDebugLevelMovie, "WSAMovie_v1::processFrame(%d, %p)", frameNum, (const void *)dst); if (!_opened) return; assert(frameNum <= _numFrames); @@ -213,11 +213,11 @@ void WSAMovieV1::processFrame(int frameNum, uint8 *dst) { #pragma mark - -WSAMovieAmiga::WSAMovieAmiga(KyraEngine *vm) : WSAMovieV1(vm), _buffer(0) {} +WSAMovieAmiga::WSAMovieAmiga(KyraEngine_v1 *vm) : WSAMovie_v1(vm), _buffer(0) {} int WSAMovieAmiga::open(const char *filename, int offscreenDecode, uint8 *palBuf) { debugC(9, kDebugLevelMovie, "WSAMovieAmiga::open('%s', %d, %p)", filename, offscreenDecode, (const void *)palBuf); - int res = WSAMovieV1::open(filename, offscreenDecode, palBuf); + int res = WSAMovie_v1::open(filename, offscreenDecode, palBuf); if (!res) return 0; @@ -230,10 +230,10 @@ int WSAMovieAmiga::open(const char *filename, int offscreenDecode, uint8 *palBuf void WSAMovieAmiga::close() { debugC(9, kDebugLevelMovie, "WSAMovieAmiga::close()"); if (_opened) { - delete [] _buffer; + delete[] _buffer; _buffer = 0; } - WSAMovieV1::close(); + WSAMovie_v1::close(); } void WSAMovieAmiga::displayFrame(int frameNum, ...) { @@ -342,10 +342,10 @@ void WSAMovieAmiga::processFrame(int frameNum, uint8 *dst) { #pragma mark - -WSAMovieV2::WSAMovieV2(KyraEngine *vm, Screen_v2 *screen) : WSAMovieV1(vm), _screen(screen), _xAdd(0), _yAdd(0) {} +WSAMovie_v2::WSAMovie_v2(KyraEngine_v1 *vm, Screen_v2 *screen) : WSAMovie_v1(vm), _screen(screen), _xAdd(0), _yAdd(0) {} -int WSAMovieV2::open(const char *filename, int unk1, uint8 *palBuf) { - debugC(9, kDebugLevelMovie, "WSAMovieV2::open('%s', %d, %p)", filename, unk1, (const void *)palBuf); +int WSAMovie_v2::open(const char *filename, int unk1, uint8 *palBuf) { + debugC(9, kDebugLevelMovie, "WSAMovie_v2::open('%s', %d, %p)", filename, unk1, (const void *)palBuf); close(); uint32 flags = 0; @@ -423,14 +423,14 @@ int WSAMovieV2::open(const char *filename, int unk1, uint8 *palBuf) { if (firstFrame) Screen::decodeFrame4(_frameData, _deltaBuffer, _deltaBufferSize); - delete [] p; + delete[] p; _opened = true; return _numFrames; } -void WSAMovieV2::displayFrame(int frameNum, ...) { - debugC(9, kDebugLevelMovie, "WSAMovieV2::displayFrame(%d, ...)", frameNum); +void WSAMovie_v2::displayFrame(int frameNum, ...) { + debugC(9, kDebugLevelMovie, "WSAMovie_v2::displayFrame(%d, ...)", frameNum); if (frameNum >= _numFrames || frameNum < 0 || !_opened) return; diff --git a/engines/kyra/wsamovie.h b/engines/kyra/wsamovie.h index d1f3465c07..36cd75b1ab 100644 --- a/engines/kyra/wsamovie.h +++ b/engines/kyra/wsamovie.h @@ -32,12 +32,12 @@ class SoundHandle; } // end of namespace Audio namespace Kyra { -class KyraEngine; +class KyraEngine_v1; class Screen_v2; class Movie { public: - Movie(KyraEngine *vm) : _vm(vm), _opened(false), _x(-1), _y(-1), _drawPage(-1) {} + Movie(KyraEngine_v1 *vm) : _vm(vm), _opened(false), _x(-1), _y(-1), _drawPage(-1) {} virtual ~Movie() {} virtual bool opened() { return _opened; } @@ -53,17 +53,17 @@ public: virtual void setY(int y) { _y = y; } virtual void setDrawPage(int page) { _drawPage = page; } protected: - KyraEngine *_vm; + KyraEngine_v1 *_vm; bool _opened; int _x, _y; int _drawPage; }; -class WSAMovieV1 : public Movie { +class WSAMovie_v1 : public Movie { public: - WSAMovieV1(KyraEngine *vm); - virtual ~WSAMovieV1(); + WSAMovie_v1(KyraEngine_v1 *vm); + virtual ~WSAMovie_v1(); virtual int open(const char *filename, int offscreen, uint8 *palette); virtual void close(); @@ -94,9 +94,9 @@ protected: uint8 *_frameData; }; -class WSAMovieAmiga : public WSAMovieV1 { +class WSAMovieAmiga : public WSAMovie_v1 { public: - WSAMovieAmiga(KyraEngine *vm); + WSAMovieAmiga(KyraEngine_v1 *vm); int open(const char *filename, int offscreen, uint8 *palette); void close(); @@ -107,9 +107,9 @@ private: uint8 *_buffer; }; -class WSAMovieV2 : public WSAMovieV1 { +class WSAMovie_v2 : public WSAMovie_v1 { public: - WSAMovieV2(KyraEngine *vm, Screen_v2 *scren); + WSAMovie_v2(KyraEngine_v1 *vm, Screen_v2 *scren); int open(const char *filename, int unk1, uint8 *palette); |