diff options
Diffstat (limited to 'engines')
38 files changed, 5312 insertions, 1063 deletions
diff --git a/engines/kyra/animator_v2.cpp b/engines/kyra/animator_v2.cpp new file mode 100644 index 0000000000..179bdd140d --- /dev/null +++ b/engines/kyra/animator_v2.cpp @@ -0,0 +1,313 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "kyra/kyra_v2.h" +#include "kyra/wsamovie.h" + +namespace Kyra { + +void KyraEngine_v2::clearAnimObjects() { + memset(_animObjects, 0, sizeof(_animObjects)); + + _animObjects[0].index = 0; + _animObjects[0].type = 0; + _animObjects[0].enabled = 1; + _animObjects[0].flags = 0x800; + _animObjects[0].width = 32; + _animObjects[0].height = 49; + _animObjects[0].width2 = 4; + _animObjects[0].height2 = 10; + + for (int i = 1; i < 11; ++i) { + _animObjects[i].index = i; + _animObjects[i].type = 2; + } + + for (int i = 11; i <= 40; ++i) { + _animObjects[i].index = i; + _animObjects[i].type = 1; + _animObjects[i].flags = 0x800; + _animObjects[i].width = 16; + _animObjects[i].height = 16; + } +} + +KyraEngine_v2::AnimObj *KyraEngine_v2::initAnimList(AnimObj *list, AnimObj *entry) { + entry->nextObject = list; + return entry; +} + +KyraEngine_v2::AnimObj *KyraEngine_v2::addToAnimListSorted(AnimObj *list, AnimObj *add) { + if (add->yPos1 <= list->yPos1) { + add->nextObject = list; + return add; + } + + AnimObj *cur = list; + AnimObj *prev = list; + while (add->yPos1 > cur->yPos1) { + AnimObj *temp = cur->nextObject; + if (!temp) + break; + prev = cur; + cur = temp; + } + + if (add->yPos1 <= cur->yPos1) { + prev->nextObject = add; + add->nextObject = cur; + } else { + cur->nextObject = add; + add->nextObject = 0; + } + return list; +} + +KyraEngine_v2::AnimObj *KyraEngine_v2::deleteAnimListEntry(AnimObj *list, AnimObj *entry) { + if (!list) + return 0; + + AnimObj *old = 0; + AnimObj *cur = list; + + while (true) { + if (cur == entry) + break; + if (!cur->nextObject) + break; + old = cur; + cur = cur->nextObject; + } + + if (cur == list) { + if (!cur->nextObject) + return 0; + cur = cur->nextObject; + return cur; + } + + if (!cur->nextObject) { + if (!old) + return 0; + old->nextObject = 0; + return list; + } + + if (cur != entry) + return list; + + old->nextObject = entry->nextObject; + return list; +} + +void KyraEngine_v2::drawAnimObjects() { + for (AnimObj *curObject = _animList; curObject; curObject = curObject->nextObject) { + if (!curObject->enabled) + continue; + + int x = curObject->xPos2 - (_screen->getScreenDim(2)->sx << 3); + int y = curObject->yPos2 - _screen->getScreenDim(2)->sy; + int layer = 7; + + if (curObject->flags & 0x800) { + if (curObject->animFlags) + layer = 0; + else + layer = getDrawLayer(curObject->xPos1, curObject->yPos1); + } + curObject->flags |= 0x800; + + if (curObject->index) + drawSceneAnimObject(curObject, x, y, layer); + else + drawCharacterAnimObject(curObject, x, y, layer); + } +} + +void KyraEngine_v2::refreshAnimObjects(int force) { + for (AnimObj *curObject = _animList; curObject; curObject = curObject->nextObject) { + if (!curObject->enabled) + continue; + if (!curObject->needRefresh && !force) + continue; + + int x = curObject->xPos2 - curObject->width2; + if (x < 0) + x = 0; + if (x >= 320) + x = 319; + int y = curObject->yPos2 - curObject->height2; + if (y < 0) + y = 0; + if (y >= 143) + y = 142; + + int width = curObject->width + curObject->width2 + 8; + int height = curObject->height + curObject->height2*2; + if (width + x > 320) + width -= width + x - 322; + if (height + y > 143) + height -= height + y - 144; + + _screen->hideMouse(); + _screen->copyRegion(x, y, x, y, width, height, 2, 0, Screen::CR_CLIPPED); + _screen->showMouse(); + + curObject->needRefresh = false; + } +} + +void KyraEngine_v2::refreshAnimObjectsIfNeed() { + for (AnimObj *curEntry = _animList; curEntry; curEntry = curEntry->nextObject) { + if (curEntry->enabled && curEntry->needRefresh) { + restorePage3(); + drawAnimObjects(); + refreshAnimObjects(0); + _screen->updateScreen(); + return; + } + } +} + +void KyraEngine_v2::updateCharacterAnim(int) { + Character *c = &_mainCharacter; + AnimObj *animState = _animObjects; + + animState->needRefresh = 1; + animState->unk8 = 1; + + if (c->facing >= 1 && c->facing <= 3) + animState->flags |= 1; + else if (c->facing >= 5 && c->facing <= 7) + animState->flags &= ~1; + + animState->xPos2 = animState->xPos1 = c->x1; + animState->yPos2 = animState->yPos1 = c->y1; + animState->shapePtr = _defaultShapeTable[c->animFrame]; + animState->shapeIndex1 = animState->shapeIndex2 = c->animFrame; + + int xAdd = _shapeDescTable[c->animFrame-9].xAdd; + int yAdd = _shapeDescTable[c->animFrame-9].yAdd; + + _charScaleX = _charScaleY = getScale(c->x1, c->y1); + + animState->xPos2 += (xAdd * _charScaleX) >> 8; + animState->yPos2 += (yAdd * _charScaleY) >> 8; + animState->width2 = 8; + animState->height2 = 10; + + _animList = deleteAnimListEntry(_animList, animState); + if (_animList) + _animList = addToAnimListSorted(_animList, animState); + else + _animList = initAnimList(_animList, animState); + + updateCharPal(1); +} + +void KyraEngine_v2::updateSceneAnim(int anim, int newFrame) { + AnimObj *animObject = &_animObjects[1+anim]; + if (!animObject->enabled) + return; + + animObject->needRefresh = 1; + animObject->unk8 = 1; + animObject->flags = 0; + + if (_sceneAnims[anim].flags & 2) + animObject->flags |= 0x800; + else + animObject->flags &= ~0x800; + + if (_sceneAnims[anim].flags & 4) + animObject->flags |= 1; + else + animObject->flags &= ~1; + + if (_sceneAnims[anim].flags & 0x20) { + animObject->shapePtr = _sceneShapeTable[newFrame]; + animObject->shapeIndex2 = 0xFFFF; + animObject->shapeIndex3 = 0xFFFF; + animObject->animNum = 0xFFFF; + } else { + animObject->shapePtr = 0; + animObject->shapeIndex3 = newFrame; + animObject->animNum = anim; + } + + animObject->xPos1 = _sceneAnims[anim].x; + animObject->yPos1 = _sceneAnims[anim].y; + animObject->xPos2 = _sceneAnims[anim].x2; + animObject->yPos2 = _sceneAnims[anim].y2; + + if (_sceneAnims[anim].flags & 2) { + _animList = deleteAnimListEntry(_animList, animObject); + if (!_animList) + _animList = initAnimList(_animList, animObject); + else + _animList = addToAnimListSorted(_animList, animObject); + } +} + +void KyraEngine_v2::drawSceneAnimObject(AnimObj *obj, int x, int y, int layer) { + if (obj->type == 1) { + if (obj->shapeIndex1 == 0xFFFF) + return; + int scale = getScale(obj->xPos1, obj->yPos1); + _screen->drawShape(2, getShapePtr(obj->shapeIndex1), x, y, 2, obj->flags | 4, layer, scale, scale); + return; + } + + if (obj->shapePtr) { + _screen->drawShape(2, obj->shapePtr, x, y, 2, obj->flags, layer); + } else { + if (obj->shapeIndex3 == 0xFFFF || obj->animNum == 0xFFFF) + return; + + int flags = 0x4000; + if (obj->flags & 0x800) + flags |= 0x8000; + + if (_sceneAnims[obj->animNum].wsaFlag) { + x = y = 0; + } else { + x = obj->xPos2; + y = obj->yPos2; + } + + _sceneAnimMovie[obj->animNum]->setX(x); + _sceneAnimMovie[obj->animNum]->setY(y); + _sceneAnimMovie[obj->animNum]->setDrawPage(2); + _sceneAnimMovie[obj->animNum]->displayFrame(obj->shapeIndex3, int(flags | layer), 0, 0); + } +} + +void KyraEngine_v2::drawCharacterAnimObject(AnimObj *obj, int x, int y, int layer) { + if (_drawNoShapeFlag || obj->shapeIndex1 == 0xFFFF) + return; + _screen->drawShape(2, getShapePtr(obj->shapeIndex1), x, y, 2, obj->flags | 4, layer, _charScaleX, _charScaleY); +} + +} // end of namespace Kyra diff --git a/engines/kyra/debugger.cpp b/engines/kyra/debugger.cpp index 0a1974c3f4..152dc21c61 100644 --- a/engines/kyra/debugger.cpp +++ b/engines/kyra/debugger.cpp @@ -29,6 +29,7 @@ #include "kyra/debugger.h" #include "kyra/kyra_v1.h" #include "kyra/screen.h" +#include "kyra/timer.h" namespace Kyra { @@ -141,8 +142,8 @@ bool Debugger_v1::cmd_queryFlag(int argc, const char **argv) { } bool Debugger_v1::cmd_listTimers(int argc, const char **argv) { - for (int i = 0; i < ARRAYSIZE(_vm->_timers); i++) - DebugPrintf("Timer %-2i: Active: %-3s Countdown: %-6i\n", i, _vm->_timers[i].active ? "Yes" : "No", _vm->_timers[i].countdown); + for (int i = 0; i < _vm->timer()->count(); i++) + DebugPrintf("Timer %-2i: Active: %-3s Countdown: %-6i\n", i, _vm->timer()->isEnabled(i) ? "Yes" : "No", _vm->timer()->getDelay(i)); return true; } @@ -151,8 +152,8 @@ bool Debugger_v1::cmd_setTimerCountdown(int argc, const char **argv) { if (argc > 2) { uint timer = atoi(argv[1]); uint countdown = atoi(argv[2]); - _vm->setTimerCountdown(timer, countdown); - DebugPrintf("Timer %i now has countdown %i\n", timer, _vm->_timers[timer].countdown); + _vm->timer()->setCountdown(timer, countdown); + DebugPrintf("Timer %i now has countdown %i\n", timer, _vm->timer()->getDelay(timer)); } else { DebugPrintf("Syntax: settimercountdown <timer> <countdown>\n"); } diff --git a/engines/kyra/gui_v1.cpp b/engines/kyra/gui_v1.cpp index 2452185c24..b7692cc97d 100644 --- a/engines/kyra/gui_v1.cpp +++ b/engines/kyra/gui_v1.cpp @@ -1469,5 +1469,38 @@ void KyraEngine_v1::gui_restorePalette() { _screen->fadePalette(_screen->_currentPalette, 2); } +#pragma mark - + +void KyraEngine_v1::drawAmulet() { + debugC(9, kDebugLevelMain, "KyraEngine_v1::drawAmulet()"); + static const int16 amuletTable1[] = {0x167, 0x162, 0x15D, 0x158, 0x153, 0x150, 0x155, 0x15A, 0x15F, 0x164, 0x145, -1}; + static const int16 amuletTable3[] = {0x167, 0x162, 0x15D, 0x158, 0x153, 0x14F, 0x154, 0x159, 0x15E, 0x163, 0x144, -1}; + static const int16 amuletTable2[] = {0x167, 0x162, 0x15D, 0x158, 0x153, 0x152, 0x157, 0x15C, 0x161, 0x166, 0x147, -1}; + static const int16 amuletTable4[] = {0x167, 0x162, 0x15D, 0x158, 0x153, 0x151, 0x156, 0x15B, 0x160, 0x165, 0x146, -1}; + + resetGameFlag(0xF1); + _screen->hideMouse(); + + int i = 0; + while (amuletTable1[i] != -1) { + if (queryGameFlag(87)) + _screen->drawShape(0, _shapes[amuletTable1[i]], _amuletX[0], _amuletY[0], 0, 0); + + if (queryGameFlag(89)) + _screen->drawShape(0, _shapes[amuletTable2[i]], _amuletX[1], _amuletY[1], 0, 0); + + if (queryGameFlag(86)) + _screen->drawShape(0, _shapes[amuletTable3[i]], _amuletX[2], _amuletY[2], 0, 0); + + if (queryGameFlag(88)) + _screen->drawShape(0, _shapes[amuletTable4[i]], _amuletX[3], _amuletY[3], 0, 0); + + _screen->updateScreen(); + delayWithTicks(3); + i++; + } + _screen->showMouse(); +} + } // end of namespace Kyra diff --git a/engines/kyra/gui_v2.cpp b/engines/kyra/gui_v2.cpp index f24bf295a8..838d347f8f 100644 --- a/engines/kyra/gui_v2.cpp +++ b/engines/kyra/gui_v2.cpp @@ -11,7 +11,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License @@ -63,7 +63,10 @@ int KyraEngine_v2::gui_handleMainMenu() { int charWidthBackUp = _screen->_charWidth; _screen->_charWidth = -2; - _screen->setScreenDim(3); + if (_flags.gameID == GI_KYRA2) + _screen->setScreenDim(11); + else + _screen->setScreenDim(3); int backUpX = _screen->_curDim->sx; int backUpY = _screen->_curDim->sy; int backUpWidth = _screen->_curDim->w; diff --git a/engines/kyra/items_v2.cpp b/engines/kyra/items_v2.cpp new file mode 100644 index 0000000000..fd4c7a5fab --- /dev/null +++ b/engines/kyra/items_v2.cpp @@ -0,0 +1,56 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "kyra/kyra_v2.h" + +namespace Kyra { + +int KyraEngine_v2::findFreeItem() { + for (int i = 0; i < 30; ++i) { + if (_itemList[i].id == 0xFFFF) + return i; + } + return -1; +} + +int KyraEngine_v2::findItem(uint16 sceneId, int id) { + for (int i = 0; i < 30; ++i) { + if (_itemList[i].id == id && _itemList[i].sceneId == sceneId) + return i; + } + return -1; +} + +void KyraEngine_v2::resetItemList() { + for (int i = 0; i < 30; ++i) { + _itemList[i].id = 0xFFFF; + _itemList[i].sceneId = 0xFFFF; + _itemList[i].x = 0; + _itemList[i].y = 0; + _itemList[i].unk7 = 0; + } +} + +} // end of namespace Kyra diff --git a/engines/kyra/kyra.cpp b/engines/kyra/kyra.cpp index c7e167f600..1d8d7440f0 100644 --- a/engines/kyra/kyra.cpp +++ b/engines/kyra/kyra.cpp @@ -35,16 +35,23 @@ #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) { - _screen = 0; _res = 0; _sound = 0; _text = 0; _staticres = 0; + _timer = 0; + _scriptInterpreter = 0; + + _flags = flags; + _gameSpeed = 60; + _tickLength = (uint8)(1000.0 / _gameSpeed); _quitFlag = false; @@ -63,6 +70,7 @@ KyraEngine::KyraEngine(OSystem *system, const GameFlags &flags) 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"); } int KyraEngine::init() { @@ -115,12 +123,18 @@ int KyraEngine::init() { _res = new Resource(this); assert(_res); - _text = new TextDisplayer(this, _screen); + _text = new TextDisplayer(this, this->screen()); assert(_text); _staticres = new StaticResource(this); assert(_staticres); if (!_staticres->init()) error("_staticres->init() failed"); + _timer = new TimerManager(this, _system); + assert(_timer); + _scriptInterpreter = new ScriptHelper(this); + assert(_scriptInterpreter); + + setupOpcodeTable(); _lang = 0; Common::Language lang = Common::parseLanguage(ConfMan.get("language")); @@ -155,6 +169,8 @@ KyraEngine::~KyraEngine() { delete _res; delete _sound; delete _text; + delete _timer; + delete _scriptInterpreter; } void KyraEngine::quitGame() { diff --git a/engines/kyra/kyra.h b/engines/kyra/kyra.h index 7d795abd7c..8ed546d1ce 100644 --- a/engines/kyra/kyra.h +++ b/engines/kyra/kyra.h @@ -31,9 +31,9 @@ #include "common/array.h" #include "common/events.h" -namespace Kyra { +#include "kyra/util.h" -struct Opcode; +namespace Kyra { struct GameFlags { Common::Language lang; @@ -59,16 +59,17 @@ enum { // 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 o1_* functions + kDebugLevelScriptFuncs = 1 << 0, // prints debug output of o#_* functions kDebugLevelScript = 1 << 1, // prints debug output of "ScriptHelper" 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*" functions && "TextDisplayer" 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 + kDebugLevelMovie = 1 << 9, // prints debug output of movie specific funtions + kDebugLevelTimer = 1 << 10 // prints debug output of "TimerManager" functions }; class Screen; @@ -77,6 +78,8 @@ class Sound; class Movie; class TextDisplayer; class StaticResource; +class TimerManager; +class ScriptHelper; class KyraEngine : public Engine { public: @@ -94,6 +97,7 @@ public: TextDisplayer *text() { return _text; } Sound *sound() { return _sound; } StaticResource *staticres() { return _staticres; } + TimerManager *timer() { return _timer; } uint32 tickLength() const { return _tickLength; } @@ -123,14 +127,16 @@ protected: // intern Resource *_res; - Screen *_screen; Sound *_sound; TextDisplayer *_text; StaticResource *_staticres; + TimerManager *_timer; + ScriptHelper *_scriptInterpreter; // game speed bool _skipFlag; uint16 _tickLength; + uint16 _gameSpeed; // detection GameFlags _flags; @@ -145,6 +151,18 @@ protected: // input Common::Point getMousePos() const; + + // 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[]; }; } // End of namespace Kyra diff --git a/engines/kyra/kyra_v1.cpp b/engines/kyra/kyra_v1.cpp index 404e62403a..45ee42b0d3 100644 --- a/engines/kyra/kyra_v1.cpp +++ b/engines/kyra/kyra_v1.cpp @@ -42,6 +42,7 @@ #include "kyra/animator_v1.h" #include "kyra/text.h" #include "kyra/debugger.h" +#include "kyra/timer.h" namespace Kyra { @@ -80,7 +81,6 @@ KyraEngine_v1::KyraEngine_v1(OSystem *system, const GameFlags &flags) _sprites = 0; _animator = 0; _seq = 0; - _scriptInterpreter = 0; _npcScriptData = 0; _scriptMain = 0; _scriptClickData = 0; @@ -124,8 +124,7 @@ KyraEngine_v1::~KyraEngine_v1() { delete _sprites; delete _animator; delete _seq; - delete _scriptInterpreter; - + delete _npcScriptData; delete _scriptMain; @@ -181,18 +180,18 @@ int KyraEngine_v1::init() { initStaticResource(); - if (!_sound->init()) - error("Couldn't init sound"); - if (_flags.platform == Common::kPlatformFMTowns) _sound->setSoundFileList(_soundFilesTowns, _soundFilesTownsCount); else _sound->setSoundFileList(_soundFiles, _soundFilesCount); + + if (!_sound->init()) + error("Couldn't init sound"); _sound->setVolume(255); _sound->loadSoundFile(0); - setupOpcodeTable(); + setupTimers(); setupButtonData(); setupMenu(); @@ -210,9 +209,6 @@ int KyraEngine_v1::init() { _characterList[0].facing = 3; _characterList[0].currentAnimFrame = 7; - _scriptInterpreter = new ScriptHelper(this); - assert(_scriptInterpreter); - _npcScriptData = new ScriptData; memset(_npcScriptData, 0, sizeof(ScriptData)); assert(_npcScriptData); @@ -263,7 +259,6 @@ int KyraEngine_v1::init() { _pathfinderFlag = _pathfinderFlag2 = 0; _lastFindWayRet = 0; _sceneChangeState = _loopFlag2 = 0; - _timerNextRun = 0; _movFacingTable = new int[150]; assert(_movFacingTable); @@ -309,9 +304,6 @@ int KyraEngine_v1::init() { _menuDirectlyToLoad = false; _lastMusicCommand = 0; - - _gameSpeed = 60; - _tickLength = (uint8)(1000.0 / _gameSpeed); return 0; } @@ -456,7 +448,7 @@ void KyraEngine_v1::mainLoop() { processButtonList(_buttonList); updateMousePointer(); - updateGameTimers(); + _timer->update(); updateTextFade(); _handleInput = true; @@ -470,7 +462,7 @@ void KyraEngine_v1::mainLoop() { void KyraEngine_v1::delayUntil(uint32 timestamp, bool updateTimers, bool update, bool isMainLoop) { while (_system->getMillis() < timestamp && !_quitFlag) { if (updateTimers) - updateGameTimers(); + _timer->update(); if (timestamp - _system->getMillis() >= 10) delay(10, update, isMainLoop); @@ -1003,6 +995,21 @@ void KyraEngine_v1::runNpcScript(int func) { _scriptInterpreter->runScript(_npcScript); } +void KyraEngine_v1::checkAmuletAnimFlags() { + debugC(9, kDebugLevelMain, "KyraEngine_v1::checkSpecialAnimFlags()"); + + if (_brandonStatusBit & 2) { + seq_makeBrandonNormal2(); + _timer->setCountdown(19, 300); + } + + if (_brandonStatusBit & 0x20) { + seq_makeBrandonNormal(); + _timer->setCountdown(19, 300); + } +} + +typedef Functor1Mem<ScriptState*, int, KyraEngine_v1> OpcodeV1; #define Opcode(x) OpcodeV1(this, &KyraEngine_v1::x) void KyraEngine_v1::setupOpcodeTable() { static const OpcodeV1 opcodeTable[] = { @@ -1201,6 +1208,7 @@ void KyraEngine_v1::setupOpcodeTable() { Opcode(o1_fillRect), Opcode(o1_vocUnload), Opcode(o1_vocLoad), + // 0x9c Opcode(o1_dummy) }; diff --git a/engines/kyra/kyra_v1.h b/engines/kyra/kyra_v1.h index 1bd8f48971..6e5ba98d3c 100644 --- a/engines/kyra/kyra_v1.h +++ b/engines/kyra/kyra_v1.h @@ -36,7 +36,6 @@ class Movie; class SoundDigital; class SeqPlayer; class Sprites; -class ScriptHelper; class Debugger; class ScreenAnimator; class TextDisplayer; @@ -105,13 +104,6 @@ struct BeadState { int16 tableIndex; }; -struct Timer { - uint8 active; - int32 countdown; - uint32 nextRun; - void (KyraEngine_v1::*func)(int timerNum); -}; - struct Button { Button *nextButton; uint16 specialValue; @@ -294,14 +286,6 @@ public: bool speechEnabled(); bool textEnabled(); - void updateGameTimers(); - void clearNextEventTickCount(); - void setTimerCountdown(uint8 timer, int32 countdown); - void setTimerDelay(uint8 timer, int32 countdown); - int16 getTimerDelay(uint8 timer); - void enableTimer(uint8 timer); - void disableTimer(uint8 timer); - void saveGame(const char *fileName, const char *saveName); void loadGame(const char *fileName); @@ -336,11 +320,7 @@ protected: // -> pathfinder 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); - void changePosTowardsFacing(int &x, int &y, int facing); bool lineIsPassable(int x, int y); - int getMoveTableSize(int *moveTable); // -> item handling // --> misc @@ -397,7 +377,6 @@ protected: void setCharacterPositionWithUpdate(int character); int setCharacterPosition(int character, int *facingTable); void setCharacterPositionHelper(int character, int *facingTable); - int getOppositeFacingDirection(int dir); void setCharactersPositions(int character); // -> brandon @@ -459,7 +438,7 @@ protected: void freePanPages(); void closeFinalWsa(); - void setTimer19(); + //void setTimer19(); void setupTimers(); void timerUpdateHeadAnims(int timerNum); void timerSetFlags1(int timerNum); @@ -535,7 +514,6 @@ protected: int8 _mouseWheel; uint8 *_itemBkgBackUp[2]; uint8 *_shapes[373]; - uint16 _gameSpeed; int8 _itemInHand; int _mouseState; bool _handleInput; @@ -632,7 +610,6 @@ protected: SeqPlayer *_seq; Sprites *_sprites; Screen_v1 *_screen; - ScriptHelper *_scriptInterpreter; Debugger *_debugger; ScriptState *_scriptMain; @@ -790,18 +767,13 @@ protected: const uint8 * const*_specialPalettes; - Timer _timers[34]; - uint32 _timerNextRun; - static const char *_soundFiles[]; static const int _soundFilesCount; static const char *_soundFilesTowns[]; static const int _soundFilesTownsCount; static const int8 _charXPosTable[]; - static const int8 _addXPosTable[]; static const int8 _charYPosTable[]; - static const int8 _addYPosTable[]; // positions of the inventory static const uint16 _itemPosX[]; @@ -829,7 +801,6 @@ protected: static const uint16 _amuletX2[]; static const uint16 _amuletY2[]; protected: - typedef OpcodeImpl<KyraEngine_v1> OpcodeV1; void setupOpcodeTable(); // Opcodes diff --git a/engines/kyra/kyra_v2.cpp b/engines/kyra/kyra_v2.cpp index 2f52d8919d..7a9d631c25 100644 --- a/engines/kyra/kyra_v2.cpp +++ b/engines/kyra/kyra_v2.cpp @@ -29,14 +29,38 @@ #include "kyra/resource.h" #include "kyra/wsamovie.h" #include "kyra/sound.h" +#include "kyra/script.h" +#include "kyra/text.h" +#include "kyra/timer.h" #include "common/system.h" namespace Kyra { KyraEngine_v2::KyraEngine_v2(OSystem *system, const GameFlags &flags) : KyraEngine(system, flags) { - memset(_gameShapes, 0, sizeof(_gameShapes)); + memset(_defaultShapeTable, 0, sizeof(_defaultShapeTable)); _mouseSHPBuf = 0; + + _gamePlayBuffer = 0; + _cCodeBuffer = _optionsBuffer = _chapterBuffer = 0; + + _overwriteSceneFacing = false; + _mainCharX = _mainCharY = -1; + _drawNoShapeFlag = false; + _charPalEntry = 0; + _itemInHand = -1; + _unkSceneScreenFlag1 = false; + _noScriptEnter = true; + _currentChapter = 0; + _newChapterFile = 1; + _handItemSet = -1; + _lastProcessedSceneScript = 0; + _specialSceneScriptRunFlag = false; + memset(_animObjects, 0, sizeof(_animObjects)); + _unkHandleSceneChangeFlag = false; + _pathfinderFlag = 0; + + memset(&_sceneScriptData, 0, sizeof(_sceneScriptData)); } KyraEngine_v2::~KyraEngine_v2() { @@ -55,13 +79,14 @@ int KyraEngine_v2::init() { error("_screen->init() failed"); KyraEngine::init(); + + setupTimers(); - if (_res->getFileSize("6.FNT")) - _screen->loadFont(Screen::FID_6_FNT, "6.FNT"); - if (_res->getFileSize("8FAT.FNT")) - _screen->loadFont(Screen::FID_8_FNT, "8FAT.FNT"); - _screen->loadFont(Screen::FID_GOLDFONT_FNT, "GOLDFONT.FNT"); - _screen->setAnimBlockPtr(3500); + _screen->loadFont(_screen->FID_6_FNT, "6.FNT"); + _screen->loadFont(_screen->FID_8_FNT, "8FAT.FNT"); + _screen->loadFont(_screen->FID_GOLDFONT_FNT, "GOLDFONT.FNT"); + _screen->loadFont(_screen->FID_BOOKFONT_FNT, "BOOKFONT.FNT"); + _screen->setAnimBlockPtr(3504); _screen->setScreenDim(0); assert(_introStringsSize == 21); @@ -76,11 +101,11 @@ int KyraEngine_v2::init() { assert(_mouseSHPBuf); for (int i = 0; i < 2; i++) { - _gameShapes[i] = _screen->getPtrToShape(_mouseSHPBuf, i); - assert(_gameShapes[i]); + _defaultShapeTable[i] = _screen->getPtrToShape(_mouseSHPBuf, i); + assert(_defaultShapeTable[i]); } - _screen->setMouseCursor(0, 0, _gameShapes[0]); + _screen->setMouseCursor(0, 0, _defaultShapeTable[0]); return 0; } @@ -105,14 +130,14 @@ int KyraEngine_v2::go() { _res->unloadPakFile("OUTFARM.PAK"); _res->unloadPakFile("FLYTRAP.PAK"); - seq_playSequences(kSequenceVirgin, kSequenceWestwood); + //seq_playSequences(kSequenceVirgin, kSequenceWestwood); mainMenu(); return 0; } void KyraEngine_v2::mainMenu() { - bool running = true; + /*bool running = true; while (running && !_quitFlag) { seq_playSequences(kSequenceTitle); @@ -120,6 +145,11 @@ void KyraEngine_v2::mainMenu() { switch (gui_handleMainMenu()) { case 0: + _screen->showMouse();*/ + startup(); + runLoop(); + cleanup(); + /*running = false; break; case 1: seq_playSequences(kSequenceOverview, kSequenceZanFaun); @@ -133,7 +163,1130 @@ void KyraEngine_v2::mainMenu() { break; } _screen->hideMouse(); - } + }*/ +} + +void KyraEngine_v2::startup() { + _screen->_curPage = 0; + delete [] _mouseSHPBuf; + _mouseSHPBuf = 0; + + memset(_defaultShapeTable, 0, sizeof(_defaultShapeTable)); + memset(_sceneShapeTable, 0, sizeof(_sceneShapeTable)); + _gamePlayBuffer = new uint8[46080]; + _unkBuf500Bytes = new uint8[500]; + + loadMouseShapes(); + loadItemShapes(); + + _screen->setMouseCursor(0, 0, getShapePtr(0)); + + _screenBuffer = new uint8[64000]; + + loadCCodeBuffer("C_CODE.XXX"); + loadOptionsBuffer("OPTIONS.XXX"); + loadChapterBuffer(_newChapterFile); + + _unkBuf200kByte = new uint8[200000]; + + showMessageFromCCode(265, 150, 0); + + // XXX + + showMessageFromCCode(0, 0, 207); + + // XXX + + _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); + memset(_wsaSlots, 0, sizeof(_wsaSlots)); + for (int i = 0; i < ARRAYSIZE(_wsaSlots); ++i) + _wsaSlots[i] = new WSAMovieV2(this); + + _maskPage = 0;//_screen->getPagePtr(5); + _screen->_curPage = 0; + + _objectList = new Object[72]; + memset(_objectList, 0, sizeof(Object)*72); + _shapeDescTable = new ShapeDesc[55]; + memset(_shapeDescTable, 0, sizeof(ShapeDesc)*55); + + for (int i = 9; i <= 32; ++i) { + _shapeDescTable[i-9].unk5 = 30; + _shapeDescTable[i-9].unk7 = 55; + _shapeDescTable[i-9].xAdd = -15; + _shapeDescTable[i-9].yAdd = -50; + } + + for (int i = 19; i <= 24; ++i) { + _shapeDescTable[i-9].unk7 = 53; + _shapeDescTable[i-9].yAdd = -51; + } + + _gfxBackUpRect = new uint8[_screen->getRectSize(32, 32)]; + _itemList = new Item[30]; + resetItemList(); + //loadButtonShapes(); + _loadedZTable = 1; + loadZShapes(_loadedZTable); + loadInventoryShapes(); + + _res->loadFileToBuf("PALETTE.COL", _screen->_currentPalette, 0x300); + _screen->loadBitmap("_PLAYFLD.CPS", 3, 3, 0); + _screen->copyPage(3, 0); + _screen->showMouse(); + _screen->hideMouse(); + + clearAnimObjects(); + + // XXX + + _sceneList = new SceneDesc[86]; + runStartScript(1, 0); + loadNPCScript(); + + // XXX + + enterNewScene(_mainCharacter.sceneId, _mainCharacter.facing, 0, 0, 1); + _screen->showMouse(); + + //sub_20EE8(1); + //setNextIdleAnimTimer(); + //XXX + _timer->setDelay(0, 5); +} + +void KyraEngine_v2::runLoop() { + _screen->updateScreen(); + + _quitFlag = false; + while (!_quitFlag) { + //XXX + int inputFlag = checkInput(0/*dword_324C5*/); + update(); + if (inputFlag == 198 || inputFlag == 199) { + _unk3 = _handItemSet; + Common::Point mouse = getMousePos(); + handleInput(mouse.x, mouse.y); + } + //XXX + } +} + +void KyraEngine_v2::handleInput(int x, int y) { + //setNextIdleAnimTimer(); + if (_unk5) { + _unk5 = 0; + return; + } + + if (!_screen->isMouseVisible()) + return; + + if (_unk3 == -2) { + //snd_playSfx(13); + return; + } + + //setNextIdleAnimTimer(); + + if (x <= 6 || x >= 312 || y <= 6 || y >= 135) { + bool exitOk = false; + assert(_unk3 + 6 >= 0); + switch (_unk3 + 6) { + case 0: + if (_sceneExit1 != 0xFFFF) + exitOk = true; + break; + + case 1: + if (_sceneExit2 != 0xFFFF) + exitOk = true; + break; + + case 2: + if (_sceneExit3 != 0xFFFF) + exitOk = true; + break; + + case 3: + if (_sceneExit4 != 0xFFFF) + exitOk = true; + break; + + default: + break; + } + + if (exitOk) { + inputSceneChange(x, y, 1, 1); + return; + } + } + + if (checkCharCollision(x, y) >= 0 && _unk3 >= -1) { + runSceneScript2(); + return; + } else { + //XXX + } + + //XXX + + inputSceneChange(x, y, 1, 1); +} + +int KyraEngine_v2::update() { + refreshAnimObjectsIfNeed(); + updateMouse(); + updateSpecialSceneScripts(); + _timer->update(); + //sub_274C0(); + //updateInvWsa(); + //sub_1574C(); + //XXX + _screen->updateScreen(); + return 0; +} + +void KyraEngine_v2::updateMouse() { + int shapeIndex = 0; + int type = 0; + int xOffset = 0, yOffset = 0; + Common::Point mouse = getMousePos(); + + if (mouse.y <= 145) { + if (mouse.x <= 6) { + if (_sceneExit4 != 0xFFFF) { + type = -3; + shapeIndex = 4; + xOffset = 1; + yOffset = 5; + } else { + type = -2; + } + } else if (mouse.x >= 312) { + if (_sceneExit2 != 0xFFFF) { + type = -5; + shapeIndex = 2; + xOffset = 7; + yOffset = 5; + } else { + type = -2; + } + } else if (mouse.y >= 135) { + if (_sceneExit3 != 0xFFFF) { + type = -4; + shapeIndex = 3; + xOffset = 5; + yOffset = 10; + } else { + type = -2; + } + } else if (mouse.y <= 6) { + if (_sceneExit1 != 0xFFFF) { + type = -6; + shapeIndex = 1; + xOffset = 5; + yOffset = 1; + } else { + type = -2; + } + } + } + + for (int i = 0; i < _specialExitCount; ++i) { + if (checkSpecialSceneExit(i, mouse.x, mouse.y)) { + switch (_specialExitTable[20+i]) { + case 0: + type = -6; + shapeIndex = 1; + xOffset = 5; + yOffset = 1; + break; + + case 2: + type = -5; + shapeIndex = 2; + xOffset = 7; + yOffset = 5; + break; + + case 4: + type = -4; + shapeIndex = 3; + xOffset = 5; + yOffset = 7; + break; + + case 6: + type = -3; + shapeIndex = 4; + xOffset = 1; + yOffset = 5; + break; + + default: + break; + } + } + } + + if (type == -2) { + shapeIndex = 5; + xOffset = 5; + yOffset = 9; + } + + if (type != 0 && _handItemSet != type) { + _handItemSet = type; + _screen->hideMouse(); + _screen->setMouseCursor(xOffset, yOffset, getShapePtr(shapeIndex)); + _screen->showMouse(); + } + + if (type == 0 && _handItemSet != _itemInHand) { + if ((mouse.y > 145) || (mouse.x > 6 && mouse.x < 312 && mouse.y > 6 && mouse.y < 135)) { + _handItemSet = _itemInHand; + _screen->hideMouse(); + if (_itemInHand == -1) + _screen->setMouseCursor(0, 0, getShapePtr(0)); + else + _screen->setMouseCursor(8, 15, getShapePtr(_itemInHand+64)); + _screen->showMouse(); + } + } +} + +int KyraEngine_v2::checkInput(void *p) { + Common::Event event; + int keys = 0; + while (_eventMan->pollEvent(event)) { + switch (event.type) { + case Common::EVENT_KEYDOWN: + if (event.kbd.keycode == Common::KEYCODE_RETURN) + keys = 199; + break; + + case Common::EVENT_LBUTTONUP: + keys = 198; + break; + + case Common::EVENT_QUIT: + _quitFlag = true; + break; + + default: + break; + } + + //if ( _debugger->isAttached()) + // _debugger->onFrame(); + } + + _system->delayMillis(10); + return keys; +} + +void KyraEngine_v2::cleanup() { + delete [] _gamePlayBuffer; + delete [] _unkBuf500Bytes; + delete [] _screenBuffer; + delete [] _unkBuf200kByte; + + for (int i = 0; i < ARRAYSIZE(_defaultShapeTable); ++i) + delete [] _defaultShapeTable[i]; + freeSceneShapePtrs(); + + delete [] _cCodeBuffer; + delete [] _optionsBuffer; + delete [] _chapterBuffer; + + delete [] _objectList; + delete [] _shapeDescTable; + + delete [] _gfxBackUpRect; + + delete [] _sceneList; + + for (int i = 0; i < ARRAYSIZE(_sceneAnimMovie); ++i) + delete _sceneAnimMovie[i]; + for (int i = 0; i < ARRAYSIZE(_wsaSlots); ++i) + delete _wsaSlots[i]; +} + +#pragma mark - Localization + +void KyraEngine_v2::loadCCodeBuffer(const char *file) { + char tempString[13]; + strcpy(tempString, file); + changeFileExtension(tempString); + + delete [] _cCodeBuffer; + _cCodeBuffer = _res->fileData(tempString, 0); +} + +void KyraEngine_v2::loadOptionsBuffer(const char *file) { + char tempString[13]; + strcpy(tempString, file); + changeFileExtension(tempString); + + delete [] _optionsBuffer; + _optionsBuffer = _res->fileData(tempString, 0); +} + +void KyraEngine_v2::loadChapterBuffer(int chapter) { + char tempString[14]; + + static const char *chapterFilenames[] = { + "CH1.XXX", "CH2.XXX", "CH3.XXX", "CH4.XXX", "CH5.XXX" + }; + + assert(chapter >= 1 && chapter <= ARRAYSIZE(chapterFilenames)); + strcpy(tempString, chapterFilenames[chapter-1]); + changeFileExtension(tempString); + + delete [] _chapterBuffer; + _chapterBuffer = _res->fileData(tempString, 0); + _currentChapter = chapter; +} + +void KyraEngine_v2::changeFileExtension(char *buffer) { + while (*buffer != '.') ++buffer; + + ++buffer; + strcpy(buffer, _languageExtension[_lang]); +} + +const uint8 *KyraEngine_v2::getTableEntry(const uint8 *buffer, int id) { + return buffer + READ_LE_UINT16(buffer + (id<<1)); +} + +const char *KyraEngine_v2::getTableString(int id, const uint8 *buffer, int decode) { + const char *string = (const char*)getTableEntry(buffer, id); + + if (decode) { + decodeString1(string, _internStringBuf); + decodeString2(_internStringBuf, _internStringBuf); + string = _internStringBuf; + } + + return string; +} + +const char *KyraEngine_v2::getChapterString(int id) { + if (_currentChapter != _newChapterFile) + loadChapterBuffer(_newChapterFile); + + return getTableString(id, _chapterBuffer, 1); +} + +int KyraEngine_v2::decodeString1(const char *src, char *dst) { + static const uint8 decodeTable1[] = { + 0x20, 0x65, 0x74, 0x61, 0x69, 0x6E, 0x6F, 0x73, 0x72, 0x6C, 0x68, + 0x63, 0x64, 0x75, 0x70, 0x6D + }; + + static const uint8 decodeTable2[] = { + 0x74, 0x61, 0x73, 0x69, 0x6F, 0x20, 0x77, 0x62, 0x20, 0x72, 0x6E, + 0x73, 0x64, 0x61, 0x6C, 0x6D, 0x68, 0x20, 0x69, 0x65, 0x6F, 0x72, + 0x61, 0x73, 0x6E, 0x72, 0x74, 0x6C, 0x63, 0x20, 0x73, 0x79, 0x6E, + 0x73, 0x74, 0x63, 0x6C, 0x6F, 0x65, 0x72, 0x20, 0x64, 0x74, 0x67, + 0x65, 0x73, 0x69, 0x6F, 0x6E, 0x72, 0x20, 0x75, 0x66, 0x6D, 0x73, + 0x77, 0x20, 0x74, 0x65, 0x70, 0x2E, 0x69, 0x63, 0x61, 0x65, 0x20, + 0x6F, 0x69, 0x61, 0x64, 0x75, 0x72, 0x20, 0x6C, 0x61, 0x65, 0x69, + 0x79, 0x6F, 0x64, 0x65, 0x69, 0x61, 0x20, 0x6F, 0x74, 0x72, 0x75, + 0x65, 0x74, 0x6F, 0x61, 0x6B, 0x68, 0x6C, 0x72, 0x20, 0x65, 0x69, + 0x75, 0x2C, 0x2E, 0x6F, 0x61, 0x6E, 0x73, 0x72, 0x63, 0x74, 0x6C, + 0x61, 0x69, 0x6C, 0x65, 0x6F, 0x69, 0x72, 0x61, 0x74, 0x70, 0x65, + 0x61, 0x6F, 0x69, 0x70, 0x20, 0x62, 0x6D + }; + + int size = 0; + uint cChar = 0; + while ((cChar = *src++) != 0) { + if (cChar & 0x80) { + cChar &= 0x7F; + int index = (cChar & 0x78) >> 3; + *dst++ = decodeTable1[index]; + ++size; + assert(cChar < sizeof(decodeTable2)); + cChar = decodeTable2[cChar]; + } + + *dst++ = cChar; + ++size; + } + + *dst++ = 0; + return size; +} + +void KyraEngine_v2::decodeString2(const char *src, char *dst) { + if (!src || !dst) + return; + + char out = 0; + while ((out = *src) != 0) { + if (*src == 0x1B) { + ++src; + out = *src + 0x7F; + } + *dst++ = out; + ++src; + } + + *dst = 0; +} + +#pragma mark - + +void KyraEngine_v2::showMessageFromCCode(int id, int16 palIndex, int) { + const char *string = getTableString(id, _cCodeBuffer, 1); + showMessage(string, palIndex); +} + +void KyraEngine_v2::showMessage(const char *string, int16 palIndex) { + _shownMessage = string; + _screen->hideMouse(); + _screen->fillRect(0, 190, 319, 199, 0xCF); + + if (string) { + if (palIndex != -1 || _msgUnk1) { + palIndex *= 3; + memcpy(_messagePal, _screen->_currentPalette + palIndex, 3); + memmove(_screen->_currentPalette + 765, _screen->_currentPalette + palIndex, 3); + _screen->setScreenPalette(_screen->_currentPalette); + } + + int x = _text->getCenterStringX(string, 0, 320); + _text->printText(string, x, 190, 255, 207, 0); + + setTimer1DelaySecs(7); + } + + _msgUnk1 = 0; + _screen->showMouse(); +} + +void KyraEngine_v2::showChapterMessage(int id, int16 palIndex) { + showMessage(getChapterString(id), palIndex); +} + +void KyraEngine_v2::loadMouseShapes() { + _screen->loadBitmap("_MOUSE.CSH", 3, 3, 0); + + for (int i = 0; i <= 8; ++i) { + _defaultShapeTable[i] = _screen->makeShapeCopy(_screen->getCPagePtr(3), i); + assert(_defaultShapeTable[i]); + } +} + +void KyraEngine_v2::loadItemShapes() { + _screen->loadBitmap("_ITEMS.CSH", 3, 3, 0); + + for (int i = 64; i <= 239; ++i) { + _defaultShapeTable[i] = _screen->makeShapeCopy(_screen->getCPagePtr(3), i-64); + assert(_defaultShapeTable[i]); + } + + _res->loadFileToBuf("_ITEMHT.DAT", _itemHtDat, sizeof(_itemHtDat)); + assert(_res->getFileSize("_ITEMHT.DAT") == sizeof(_itemHtDat)); + + _screen->_curPage = 0; +} + +void KyraEngine_v2::loadZShapes(int shapes) { + char file[10]; + strcpy(file, "_ZX.SHP"); + + _loadedZTable = shapes; + file[2] = '0' + shapes; + + uint8 *data = _res->fileData(file, 0); + for (int i = 9; i <= 32; ++i) { + delete [] _defaultShapeTable[i]; + _defaultShapeTable[i] = _screen->makeShapeCopy(data, i-9); + } + delete [] data; + + _loadedZTable = shapes; +} + +void KyraEngine_v2::loadInventoryShapes() { + int curPageBackUp = _screen->_curPage; + _screen->_curPage = 2; + + _screen->loadBitmap("_PLAYALL.CPS", 3, 3, 0); + + for (int i = 0; i < 10; ++i) + _defaultShapeTable[240+i] = _screen->encodeShape(_inventoryX[i], _inventoryY[i], 16, 16, 0); + + _screen->_curPage = curPageBackUp; +} + +void KyraEngine_v2::runStartScript(int script, int unk1) { + char filename[14]; + strcpy(filename, "_START0X.EMC"); + filename[7] = script + '0'; + + ScriptData scriptData; + ScriptState scriptState; + + _scriptInterpreter->loadScript(filename, &scriptData, &_opcodes); + _scriptInterpreter->initScript(&scriptState, &scriptData); + scriptState.regs[6] = unk1; + _scriptInterpreter->startScript(&scriptState, 0); + while (_scriptInterpreter->validScript(&scriptState)) + _scriptInterpreter->runScript(&scriptState); + _scriptInterpreter->unloadScript(&scriptData); +} + +void KyraEngine_v2::loadNPCScript() { + char filename[12]; + strcpy(filename, "_NPC.EMC"); + + switch (_lang) { + case 0: + filename[5] = 'E'; + break; + + case 1: + filename[5] = 'F'; + break; + + case 2: + filename[5] = 'G'; + break; + + default: + break; + }; + + _scriptInterpreter->loadScript(filename, &_npcScriptData, &_opcodes); +} + +void KyraEngine_v2::resetScaleTable() { + for (int i = 0; i < ARRAYSIZE(_scaleTable); ++i) + _scaleTable[i] = 0x100; +} + +void KyraEngine_v2::setScaleTableItem(int item, int data) { + if (item >= 1 || item <= 15) + _scaleTable[item-1] = (data << 8) / 100; +} + +int KyraEngine_v2::getScale(int x, int y) { + return _scaleTable[_screen->getLayer(x, y) - 1]; +} + +void KyraEngine_v2::setDrawLayerTableEntry(int entry, int data) { + if (entry >= 1 || entry <= 15) + _drawLayerTable[entry-1] = data; +} + +int KyraEngine_v2::getDrawLayer(int x, int y) { + int layer = _screen->getLayer(x, y); + layer = _drawLayerTable[layer-1]; + if (layer < 0) + layer = 0; + else if (layer >= 7) + layer = 6; + return layer; +} + +void KyraEngine_v2::restorePage3() { + _screen->copyBlockToPage(2, 0, 0, 320, 144, _gamePlayBuffer); +} + +void KyraEngine_v2::updateCharPal(int unk1) { + static bool unkVar1 = false; + + if (!_useCharPal) + return; + + int layer = _screen->getLayer(_mainCharacter.x1, _mainCharacter.y1); + int palEntry = _charPalTable[layer]; + + if (palEntry != _charPalEntry && unk1) { + const uint8 *src = &_scenePal[(palEntry << 4) * 3]; + uint8 *ptr = _screen->getPalette(0) + 336; + for (int i = 0; i < 48; ++i) { + *ptr -= (*ptr - *src) >> 1; + ++ptr; + ++src; + } + _screen->setScreenPalette(_screen->getPalette(0)); + unkVar1 = true; + _charPalEntry = palEntry; + } else if (unkVar1 && !unk1) { + memcpy(_screen->getPalette(0) + 336, &_scenePal[(palEntry << 4) * 3], 48); + _screen->setScreenPalette(_screen->getPalette(0)); + unkVar1 = false; + } +} + +int KyraEngine_v2::inputSceneChange(int x, int y, int unk1, int unk2) { + bool refreshNPC = false; + uint16 curScene = _mainCharacter.sceneId; + _pathfinderFlag = 15; + + if (!_unkHandleSceneChangeFlag) { + if (_unk3 == -3) { + if (_sceneList[curScene].exit4 != 0xFFFF) { + x = 4; + y = _sceneEnterY4; + _pathfinderFlag = 7; + } + } else if (_unk3 == -5) { + if (_sceneList[curScene].exit2 != 0xFFFF) { + x = 316; + y = _sceneEnterY2; + _pathfinderFlag = 7; + } + } else if (_unk3 == -6) { + if (_sceneList[curScene].exit1 != 0xFFFF) { + x = _sceneEnterX1; + y = _sceneEnterY1 - 2; + _pathfinderFlag = 14; + } + } else if (_unk3 == -4) { + if (_sceneList[curScene].exit3 != 0xFFFF) { + x = _sceneEnterX3; + y = 147; + _pathfinderFlag = 11; + } + } + } + + if (_pathfinderFlag) { + if (findItem(curScene, 13) >= 0 && _unk3 <= -3) { + //XXX + _pathfinderFlag = 0; + return 0; + } else if (_itemInHand == 72) { + //XXX + _pathfinderFlag = 0; + return 0; + } else if (findItem(curScene, 72) >= 0 && _unk3 <= -3) { + //XXX + _pathfinderFlag = 0; + return 0; + } else if (0/*XXX*/) { + //XXX + _pathfinderFlag = 0; + return 0; + } + } + + if (ABS(_mainCharacter.x1 - x) < 4 || ABS(_mainCharacter.y1 - y) < 2) + return 0; + + int curX = _mainCharacter.x1 & ~3; + int curY = _mainCharacter.y1 & ~1; + int dstX = x & ~3; + int dstY = y & ~1; + + int wayLength = findWay(curX, curY, dstX, dstY, _movFacingTable, 600); + _pathfinderFlag = 0; + _timer->disable(5); + + if (wayLength != 0 && wayLength != 0x7D00) + refreshNPC = trySceneChange(_movFacingTable, unk1, unk2); + + //XXX + + if (refreshNPC) + enterNewSceneUnk2(0); + + _pathfinderFlag = 0; + return refreshNPC; +} + +bool KyraEngine_v2::checkSpecialSceneExit(int num, int x, int y) { + if (_specialExitTable[0+num] > x || _specialExitTable[5+num] > y || + _specialExitTable[10+num] < x || _specialExitTable[15+num] < y) + return 0; + return 1; +} + +void KyraEngine_v2::moveCharacter(int facing, int x, int y) { + _mainCharacter.facing = facing; + x &= ~3; + y &= ~1; + + _screen->hideMouse(); + switch (facing) { + case 0: + while (y < _mainCharacter.y1) + updateCharPosWithUpdate(); + break; + + case 2: + while (_mainCharacter.x1 < x) + updateCharPosWithUpdate(); + break; + + case 4: + while (y > _mainCharacter.y1) + updateCharPosWithUpdate(); + break; + + case 6: + while (_mainCharacter.x1 > x) + updateCharPosWithUpdate(); + break; + + default: + break; + } + + _screen->showMouse(); +} + +int KyraEngine_v2::updateCharPos(int *table) { + static uint32 nextUpdate = 0; + static const int updateX[] = { 0, 4, 4, 4, 0, -4, -4, -4 }; + static const int updateY[] = { -2, -2, 0, 2, 2, 2, 0, -2 }; + + if (_system->getMillis() < nextUpdate) + return 0; + + int facing = _mainCharacter.facing; + _mainCharacter.x1 += updateX[facing]; + _mainCharacter.y1 += updateY[facing]; + updateCharAnimFrame(0, table); + nextUpdate = _system->getMillis() + _timer->getDelay(0) * _tickLength; + return 1; +} + +void KyraEngine_v2::updateCharPosWithUpdate() { + updateCharPos(0); + update(); +} + +void KyraEngine_v2::updateCharAnimFrame(int charId, int *table) { + static int unkTable1[] = { 0, 0 }; + static const int unkTable2[] = { 17, 0 }; + static const int unkTable3[] = { 10, 0 }; + static const int unkTable4[] = { 24, 0 }; + static const int unkTable5[] = { 19, 0 }; + static const int unkTable6[] = { 21, 0 }; + static const int unkTable7[] = { 31, 0 }; + static const int unkTable8[] = { 26, 0 }; + + Character *character = &_mainCharacter; + ++character->animFrame; + int facing = character->facing; + + if (table) { + if (table[0] != table[-1] && table[-1] == table[1]) { + facing = getOppositeFacingDirection(table[-1]); + table[0] = table[-1]; + } + } + + if (!facing) { + ++unkTable1[charId]; + } else if (facing == 4) { + ++unkTable1[charId+1]; + } else if (facing == 7 || facing == 1 || facing == 5 || facing == 3) { + if (facing == 7 || facing == 1) { + if (unkTable1[charId] > 2) + facing = 0; + } else { + if (unkTable1[charId+1] > 2) + facing = 4; + } + + unkTable1[charId] = 0; + unkTable1[charId+1] = 0; + } + + if (facing == 0) { + if (character->animFrame < unkTable8[charId]) + character->animFrame = unkTable8[charId]; + + if (character->animFrame > unkTable7[charId]) + character->animFrame = unkTable8[charId]; + } else if (facing == 4) { + if (character->animFrame < unkTable5[charId]) + character->animFrame = unkTable5[charId]; + + if (character->animFrame > unkTable4[charId]) + character->animFrame = unkTable5[charId]; + } else { + if (character->animFrame > unkTable5[charId]) + character->animFrame = unkTable6[charId]; + + if (character->animFrame == unkTable2[charId]) + character->animFrame = unkTable3[charId]; + + if (character->animFrame > unkTable2[charId]) + character->animFrame = unkTable3[charId] + 2; + } + + updateCharacterAnim(charId); +} + +int KyraEngine_v2::checkCharCollision(int x, int y) { + int scale1 = 0, scale2 = 0, scale3 = 0; + int x1 = 0, x2 = 0, y1 = 0, y2 = 0; + scale1 = getScale(_mainCharacter.x1, _mainCharacter.y1); + scale2 = (scale1 * 24) >> 8; + scale3 = (scale1 * 48) >> 8; + + x1 = _mainCharacter.x1 - (scale2 >> 1); + x2 = _mainCharacter.x1 + (scale2 >> 1); + y1 = _mainCharacter.y1 - scale3; + y2 = _mainCharacter.y1; + + if (x >= x1 && x <= x2 && y >= y1 && y <= y2) + return 0; + + return -1; +} + +#pragma mark - + +typedef Functor1Mem<ScriptState*, int, KyraEngine_v2> OpcodeV2; +#define Opcode(x) OpcodeV2(this, &KyraEngine_v2::x) +#define OpcodeUnImpl() OpcodeV2(this, 0) +void KyraEngine_v2::setupOpcodeTable() { + static const OpcodeV2 opcodeTable[] = { + // 0x00 + Opcode(o2_setCharacterFacingRefresh), + OpcodeUnImpl(), + Opcode(o2_defineObject), + Opcode(o2_refreshCharacter), + // 0x04 + Opcode(o2_getCharacterX), + Opcode(o2_getCharacterY), + Opcode(o2_getCharacterFacing), + OpcodeUnImpl(), + // 0x08 + Opcode(o2_setSceneComment), + OpcodeUnImpl(), + OpcodeUnImpl(), + OpcodeUnImpl(), + // 0x0c + OpcodeUnImpl(), + OpcodeUnImpl(), + OpcodeUnImpl(), + OpcodeUnImpl(), + // 0x10 + OpcodeUnImpl(), + Opcode(o2_showChapterMessage), + OpcodeUnImpl(), + OpcodeUnImpl(), + // 0x14 + Opcode(o2_wsaClose), + OpcodeUnImpl(), + OpcodeUnImpl(), + Opcode(o2_displayWsaFrame), + // 0x18 + Opcode(o2_displayWsaSequentialFrames), + Opcode(o2_wsaOpen), + OpcodeUnImpl(), + OpcodeUnImpl(), + // 0x1c + OpcodeUnImpl(), + OpcodeUnImpl(), + OpcodeUnImpl(), + OpcodeUnImpl(), + // 0x20 + OpcodeUnImpl(), + OpcodeUnImpl(), + OpcodeUnImpl(), + Opcode(o2_defineItem), + // 0x24 + OpcodeUnImpl(), + OpcodeUnImpl(), + OpcodeUnImpl(), + Opcode(o2_queryGameFlag), + // 0x28 + Opcode(o2_resetGameFlag), + Opcode(o2_setGameFlag), + OpcodeUnImpl(), + OpcodeUnImpl(), + // 0x2c + OpcodeUnImpl(), + Opcode(o2_hideMouse), + Opcode(o2_addSpecialExit), + OpcodeUnImpl(), + // 0x30 + Opcode(o2_showMouse), + OpcodeUnImpl(), + OpcodeUnImpl(), + OpcodeUnImpl(), + // 0x34 + OpcodeUnImpl(), + OpcodeUnImpl(), + OpcodeUnImpl(), + OpcodeUnImpl(), + // 0x38 + Opcode(o2_dummy), + OpcodeUnImpl(), + Opcode(o2_setScaleTableItem), + Opcode(o2_setDrawLayerTableItem), + // 0x3c + OpcodeUnImpl(), + OpcodeUnImpl(), + OpcodeUnImpl(), + Opcode(o2_drawSceneShapeOnPage), + // 0x40 + OpcodeUnImpl(), + OpcodeUnImpl(), + Opcode(o2_dummy), + OpcodeUnImpl(), + // 0x44 + OpcodeUnImpl(), + Opcode(o2_restoreBackBuffer), + OpcodeUnImpl(), + OpcodeUnImpl(), + // 0x48 + OpcodeUnImpl(), + OpcodeUnImpl(), + OpcodeUnImpl(), + OpcodeUnImpl(), + // 0x4c + OpcodeUnImpl(), + OpcodeUnImpl(), + Opcode(o2_dummy), + Opcode(o2_dummy), + // 0x50 + OpcodeUnImpl(), + OpcodeUnImpl(), + OpcodeUnImpl(), + OpcodeUnImpl(), + // 0x54 + OpcodeUnImpl(), + OpcodeUnImpl(), + OpcodeUnImpl(), + OpcodeUnImpl(), + // 0x58 + OpcodeUnImpl(), + OpcodeUnImpl(), + OpcodeUnImpl(), + OpcodeUnImpl(), + // 0x5c + OpcodeUnImpl(), + OpcodeUnImpl(), + OpcodeUnImpl(), + OpcodeUnImpl(), + // 0x60 + Opcode(o2_getRand), + OpcodeUnImpl(), + OpcodeUnImpl(), + OpcodeUnImpl(), + // 0x64 + OpcodeUnImpl(), + OpcodeUnImpl(), + OpcodeUnImpl(), + OpcodeUnImpl(), + // 0x68 + OpcodeUnImpl(), + OpcodeUnImpl(), + OpcodeUnImpl(), + OpcodeUnImpl(), + // 0x6c + Opcode(o2_encodeShape), + Opcode(o2_defineRoomEntrance), + OpcodeUnImpl(), + Opcode(o2_setSpecialSceneScriptRunTime), + // 0x70 + Opcode(o2_defineSceneAnim), + Opcode(o2_updateSceneAnim), + Opcode(o2_updateSceneAnim), + OpcodeUnImpl(), + // 0x74 + OpcodeUnImpl(), + OpcodeUnImpl(), + OpcodeUnImpl(), + OpcodeUnImpl(), + // 0x78 + OpcodeUnImpl(), + Opcode(o2_defineRoom), + OpcodeUnImpl(), + OpcodeUnImpl(), + // 0x7c + OpcodeUnImpl(), + Opcode(o2_dummy), + Opcode(o2_dummy), + OpcodeUnImpl(), + // 0x80 + OpcodeUnImpl(), + OpcodeUnImpl(), + OpcodeUnImpl(), + OpcodeUnImpl(), + // 0x84 + OpcodeUnImpl(), + OpcodeUnImpl(), + OpcodeUnImpl(), + OpcodeUnImpl(), + // 0x88 + OpcodeUnImpl(), + OpcodeUnImpl(), + OpcodeUnImpl(), + OpcodeUnImpl(), + // 0x8c + OpcodeUnImpl(), + OpcodeUnImpl(), + OpcodeUnImpl(), + Opcode(o2_setSpecialSceneScriptState), + // 0x90 + Opcode(o2_clearSpecialSceneScriptState), + Opcode(o2_querySpecialSceneScriptState), + OpcodeUnImpl(), + OpcodeUnImpl(), + // 0x94 + OpcodeUnImpl(), + OpcodeUnImpl(), + Opcode(o2_wsaClose), + OpcodeUnImpl(), + // 0x98 + OpcodeUnImpl(), + OpcodeUnImpl(), + OpcodeUnImpl(), + OpcodeUnImpl(), + // 0x9c + OpcodeUnImpl(), + OpcodeUnImpl(), + OpcodeUnImpl(), + OpcodeUnImpl(), + // 0xa0 + OpcodeUnImpl(), + OpcodeUnImpl(), + OpcodeUnImpl(), + OpcodeUnImpl(), + // 0xa4 + OpcodeUnImpl(), + OpcodeUnImpl(), + OpcodeUnImpl(), + OpcodeUnImpl(), + // 0xa8 + OpcodeUnImpl(), + OpcodeUnImpl(), + OpcodeUnImpl(), + OpcodeUnImpl(), + // 0xac + OpcodeUnImpl(), + OpcodeUnImpl(), + Opcode(o2_dummy), + Opcode(o2_dummy), + }; + + for (int i = 0; i < ARRAYSIZE(opcodeTable); ++i) + _opcodes.push_back(&opcodeTable[i]); } } // end of namespace Kyra diff --git a/engines/kyra/kyra_v2.h b/engines/kyra/kyra_v2.h index df73118376..fb8fd2c454 100644 --- a/engines/kyra/kyra_v2.h +++ b/engines/kyra/kyra_v2.h @@ -27,6 +27,7 @@ #define KYRA_KYRA_V2_H #include "kyra/kyra.h" +#include "kyra/script.h" #include "kyra/screen_v2.h" namespace Kyra { @@ -87,7 +88,7 @@ public: ~KyraEngine_v2(); virtual Screen *screen() { return _screen; } - Screen *screen_v2() { return _screen; } + Screen_v2 *screen_v2() { return _screen; } Movie *createWSAMovie(); protected: @@ -103,8 +104,7 @@ protected: void gui_printString(const char *string, int x, int y, int col1, int col2, int flags, ...); - void setupOpcodeTable() {} - + // intro void seq_playSequences(int startSeq, int endSeq = -1); int seq_introWestwood(int seqNum); int seq_introTitle(int seqNum); @@ -136,7 +136,6 @@ protected: ActiveWSA *_activeWSA; ActiveChat *_activeChat; - uint8 *_gameShapes[50]; uint8 *_mouseSHPBuf; static const char *_introSoundList[]; @@ -145,6 +144,351 @@ protected: static const int _introStringsSize; int _introStringsDuration[21]; + +protected: + // game initialization + void startup(); + void runLoop(); + void cleanup(); + + void setupTimers(); + void setupOpcodeTable(); + + void loadMouseShapes(); + void loadItemShapes(); + + // run + int update(); + void updateMouse(); + + int checkInput(void *p); + void handleInput(int x, int y); + + int inputSceneChange(int x, int y, int unk1, int unk2); + + // gfx/animation specific + uint8 *_gamePlayBuffer; + void restorePage3(); + + uint8 *_screenBuffer; + uint8 *_maskPage; + uint8 *_gfxBackUpRect; + + uint8 *getShapePtr(int index) { return _defaultShapeTable[index]; } + uint8 *_defaultShapeTable[250]; + uint8 *_sceneShapeTable[50]; + + WSAMovieV2 *_wsaSlots[10]; + + void freeSceneShapePtrs(); + + struct ShapeDesc { + uint8 unk0, unk1, unk2, unk3, unk4; + uint16 unk5, unk7; + int16 xAdd, yAdd; + }; + + ShapeDesc *_shapeDescTable; + + struct SceneAnim { + uint16 flags; + int16 x, y; + int16 x2, y2; + int16 width, height; + uint16 unkE; + uint16 specialSize; + uint16 unk12; + int16 shapeIndex; + uint16 wsaFlag; + char filename[14]; + }; + + SceneAnim _sceneAnims[10]; + WSAMovieV2 *_sceneAnimMovie[10]; + bool _specialSceneScriptState[10]; + ScriptState _sceneSpecialScripts[10]; + uint32 _sceneSpecialScriptsTimer[10]; + int _lastProcessedSceneScript; + bool _specialSceneScriptRunFlag; + + void updateSpecialSceneScripts(); + void freeSceneAnims(); + + int _loadedZTable; + void loadZShapes(int shapes); + void loadInventoryShapes(); + + void resetScaleTable(); + void setScaleTableItem(int item, int data); + int getScale(int x, int y); + uint16 _scaleTable[15]; + + void setDrawLayerTableEntry(int entry, int data); + int getDrawLayer(int x, int y); + int _drawLayerTable[15]; + + // animator + struct AnimObj { + uint16 index; + uint16 type; + uint16 enabled; + uint16 needRefresh; + uint16 unk8; + uint16 animFlags; + uint16 flags; + int16 xPos1, yPos1; + uint8 *shapePtr; + uint16 shapeIndex1; + uint16 animNum; + uint16 shapeIndex3; + uint16 shapeIndex2; + uint16 unk1E; + uint8 unk20; + uint8 unk21; + uint8 unk22; + uint8 unk23; + int16 xPos2, yPos2; + int16 xPos3, yPos3; + int16 width, height; + int16 width2, height2; + AnimObj *nextObject; + }; + + AnimObj _animObjects[42]; + void clearAnimObjects(); + + AnimObj *_animList; + bool _drawNoShapeFlag; + AnimObj *initAnimList(AnimObj *list, AnimObj *entry); + AnimObj *addToAnimListSorted(AnimObj *list, AnimObj *entry); + AnimObj *deleteAnimListEntry(AnimObj *list, AnimObj *entry); + + void drawAnimObjects(); + void drawSceneAnimObject(AnimObj *obj, int x, int y, int drawLayer); + void drawCharacterAnimObject(AnimObj *obj, int x, int y, int drawLayer); + + void refreshAnimObjects(int force); + void refreshAnimObjectsIfNeed(); + + void updateCharacterAnim(int); + void updateSceneAnim(int anim, int newFrame); + + // scene + struct SceneDesc { + char filename[10]; + uint16 exit1, exit2, exit3, exit4; + uint8 flags; + uint8 sound; + }; + + SceneDesc *_sceneList; + const char *_sceneCommentString; + uint16 _sceneExit1, _sceneExit2, _sceneExit3, _sceneExit4; + int _sceneEnterX1, _sceneEnterY1, _sceneEnterX2, _sceneEnterY2, + _sceneEnterX3, _sceneEnterY3, _sceneEnterX4, _sceneEnterY4; + int _specialExitCount; + uint16 _specialExitTable[25]; + bool checkSpecialSceneExit(int num, int x, int y); + uint8 _scenePal[688]; + bool _overwriteSceneFacing; + + void enterNewScene(uint16 newScene, int facing, int unk1, int unk2, int unk3); + void enterNewSceneUnk1(int facing, int unk1, int unk2); + void enterNewSceneUnk2(int unk1); + void unloadScene(); + + void loadScenePal(); + void loadSceneMsc(); + + void startSceneScript(int unk1); + void runSceneScript2(); + void runSceneScript4(int unk1); + void runSceneScript7(); + + void initSceneAnims(int unk1); + void initSceneScreen(int unk1); + + int trySceneChange(int *moveTable, int unk1, int updateChar); + int checkSceneChange(); + + // pathfinder + int _movFacingTable[600]; + int findWay(int curX, int curY, int dstX, int dstY, int *moveTable, int moveTableSize); + bool lineIsPassable(int x, int y); + bool directLinePassable(int x, int y, int toX, int toY); + + int pathfinderUnk1(int *moveTable); + int pathfinderUnk2(int index, int v1, int v2); + int pathfinderUnk3(int tableLen, int x, int y); + int pathfinderUnk4(int index, int v); + void pathfinderUnk5(int *moveTable, int unk1, int x, int y, int moveTableSize); + + int _pathfinderUnkTable1[400]; + int _pathfinderUnkTable2[200]; + + // item + uint8 _itemHtDat[176]; + + struct Item { + uint16 id; + uint16 sceneId; + int16 x; + int8 y; + uint16 unk7; + }; + Item *_itemList; + + int findFreeItem(); + int findItem(uint16 sceneId, int id); + void resetItemList(); + + int _itemInHand; + int _handItemSet; + + // inventroy + static int _inventoryX[]; + static int _inventoryY[]; + + // localization + void loadCCodeBuffer(const char *file); + void loadOptionsBuffer(const char *file); + void loadChapterBuffer(int chapter); + uint8 *_optionsBuffer; + uint8 *_cCodeBuffer; + + uint8 *_chapterBuffer; + int _currentChapter; + int _newChapterFile; + + const uint8 *getTableEntry(const uint8 *buffer, int id); + const char *getTableString(int id, const uint8 *buffer, int decode); + const char *getChapterString(int id); + int decodeString1(const char *src, char *dst); + void decodeString2(const char *src, char *dst); + + void changeFileExtension(char *buffer); + + char _internStringBuf[200]; + static const char *_languageExtension[]; + static const char *_scriptLangExt[]; + + // character + struct Character { + uint16 sceneId; + uint16 unk2; + uint8 height; + uint8 facing; + uint16 animFrame; + uint8 unk8; + uint8 unk9; + uint8 unkA; + uint16 inventory[20]; + int16 x1, y1; + int16 x2, y2; + }; + + Character _mainCharacter; + bool _useCharPal; + int _charPalEntry; + uint8 _charPalTable[16]; + void updateCharPal(int unk1); + + void moveCharacter(int facing, int x, int y); + int updateCharPos(int *table); + void updateCharPosWithUpdate(); + void updateCharAnimFrame(int num, int *table); + + int checkCharCollision(int x, int y); + + int _mainCharX, _mainCharY; + int _charScaleX, _charScaleY; + + static int _characterFrameTable[]; + + // text + void showMessageFromCCode(int id, int16 palIndex, int); + void showMessage(const char *string, int16 palIndex); + void showChapterMessage(int id, int16 palIndex); + + const char *_shownMessage; + + byte _messagePal[3]; + int _msgUnk1; + + // timer + void timerFunc2(int); + void timerFunc3(int); + void timerFunc4(int); + void timerFunc5(int); + void timerFunc6(int); + + void setTimer1DelaySecs(int secs); + + // opcodes + int o2_setCharacterFacingRefresh(ScriptState *script); + int o2_defineObject(ScriptState *script); + int o2_refreshCharacter(ScriptState *script); + int o2_getCharacterX(ScriptState *script); + int o2_getCharacterY(ScriptState *script); + int o2_getCharacterFacing(ScriptState *script); + int o2_setSceneComment(ScriptState *script); + int o2_showChapterMessage(ScriptState *script); + int o2_wsaClose(ScriptState *script); + int o2_displayWsaFrame(ScriptState *script); + int o2_displayWsaSequentialFrames(ScriptState *script); + int o2_wsaOpen(ScriptState *script); + int o2_defineItem(ScriptState *script); + int o2_queryGameFlag(ScriptState *script); + int o2_resetGameFlag(ScriptState *script); + int o2_setGameFlag(ScriptState *script); + int o2_hideMouse(ScriptState *script); + int o2_addSpecialExit(ScriptState *script); + int o2_showMouse(ScriptState *script); + int o2_setScaleTableItem(ScriptState *script); + int o2_setDrawLayerTableItem(ScriptState *script); + int o2_drawSceneShapeOnPage(ScriptState *script); + int o2_restoreBackBuffer(ScriptState *script); + int o2_getRand(ScriptState *script); + int o2_encodeShape(ScriptState *script); + int o2_defineRoomEntrance(ScriptState *script); + int o2_setSpecialSceneScriptRunTime(ScriptState *script); + int o2_defineSceneAnim(ScriptState *script); + int o2_updateSceneAnim(ScriptState *script); + int o2_defineRoom(ScriptState *script); + int o2_setSpecialSceneScriptState(ScriptState *script); + int o2_clearSpecialSceneScriptState(ScriptState *script); + int o2_querySpecialSceneScriptState(ScriptState *script); + int o2_dummy(ScriptState *script); + + // script + void runStartScript(int script, int unk1); + void loadNPCScript(); + + bool _noScriptEnter; + + ScriptData _npcScriptData; + + ScriptData _sceneScriptData; + ScriptState _sceneScriptState; + + // pathfinder + int _pathfinderFlag; + + // unk + struct Object { + char filename[13]; + uint8 scriptId; + int16 x, y; + int8 unk12; + }; + Object *_objectList; + + uint8 *_unkBuf500Bytes; + uint8 *_unkBuf200kByte; + bool _unkFlag1; + int _unk3, _unk4, _unk5; + bool _unkSceneScreenFlag1; + bool _unkHandleSceneChangeFlag; }; } // end of namespace Kyra diff --git a/engines/kyra/kyra_v3.cpp b/engines/kyra/kyra_v3.cpp index b49635ab2d..9aa4b1f4da 100644 --- a/engines/kyra/kyra_v3.cpp +++ b/engines/kyra/kyra_v3.cpp @@ -290,14 +290,14 @@ void KyraEngine_v3::stopMusicTrack() { int KyraEngine_v3::musicUpdate(int forceRestart) { debugC(9, kDebugLevelMain, "KyraEngine::unkUpdate(%d)", forceRestart); - static uint32 timer = 0; + static uint32 mTimer = 0; static uint16 lock = 0; - if (ABS<int>(_system->getMillis() - timer) > (int)(0x0F * _tickLength)) { - timer = _system->getMillis(); + if (ABS<int>(_system->getMillis() - mTimer) > (int)(0x0F * _tickLength)) { + mTimer = _system->getMillis(); } - if (_system->getMillis() < timer && !forceRestart) { + if (_system->getMillis() < mTimer && !forceRestart) { return 1; } @@ -311,7 +311,7 @@ int KyraEngine_v3::musicUpdate(int forceRestart) { } } lock = 0; - timer = _system->getMillis() + 0x0F * _tickLength; + mTimer = _system->getMillis() + 0x0F * _tickLength; } return 1; diff --git a/engines/kyra/module.mk b/engines/kyra/module.mk index 0ddcc1bf7f..0517c393a1 100644 --- a/engines/kyra/module.mk +++ b/engines/kyra/module.mk @@ -2,22 +2,27 @@ MODULE := engines/kyra MODULE_OBJS := \ animator_v1.o \ + animator_v2.o \ debugger.o \ detection.o \ gui_v1.o \ gui_v2.o \ items_v1.o \ + items_v2.o \ kyra.o \ kyra_v1.o \ kyra_v2.o \ kyra_v3.o \ resource.o \ saveload_v1.o \ + scene.o \ scene_v1.o \ + scene_v2.o \ screen.o \ screen_v1.o \ screen_v2.o \ script_v1.o \ + script_v2.o \ script.o \ seqplayer.o \ sequences_v1.o \ @@ -31,7 +36,9 @@ MODULE_OBJS := \ staticres.o \ text.o \ text_v1.o \ + timer.o \ timer_v1.o \ + timer_v2.o \ vqa.o \ wsamovie.o diff --git a/engines/kyra/resource.cpp b/engines/kyra/resource.cpp index 3ff8dd984c..fa333bf8bd 100644 --- a/engines/kyra/resource.cpp +++ b/engines/kyra/resource.cpp @@ -42,11 +42,11 @@ namespace Kyra { namespace { -struct ResFilenameEqual : public Common::BinaryFunction<ResourceFile*, uint, bool> { +struct ResFilenameEqual : public Common::UnaryFunction<ResourceFile*, bool> { uint _filename; ResFilenameEqual(uint file) : _filename(file) {} - bool operator()(ResourceFile *f) { + bool operator()(const ResourceFile *f) { return f->filename() == _filename; } }; diff --git a/engines/kyra/resource.h b/engines/kyra/resource.h index 19855ed9c9..139a7fa72c 100644 --- a/engines/kyra/resource.h +++ b/engines/kyra/resource.h @@ -122,9 +122,8 @@ public: uint32 getFileSize(const char *file) const; uint8* fileData(const char *file, uint32 *size) const; - // it gives back a file handle (used for the speech player) - // it could be that the needed file is embedded in the returned - // handle + // gives back a file handle + // it is possible that the needed file is embedded in the returned handle bool getFileHandle(const char *file, uint32 *size, Common::File &filehandle); bool loadFileToBuf(const char *file, void *buf, uint32 maxSize); diff --git a/engines/kyra/saveload_v1.cpp b/engines/kyra/saveload_v1.cpp index d28a0b3f8b..c2ceee1d3b 100644 --- a/engines/kyra/saveload_v1.cpp +++ b/engines/kyra/saveload_v1.cpp @@ -33,8 +33,9 @@ #include "kyra/screen.h" #include "kyra/resource.h" #include "kyra/sound.h" +#include "kyra/timer.h" -#define CURRENT_VERSION 7 +#define CURRENT_VERSION 8 // TODO: our current savefiles still use the old // flag system to check the version, we should @@ -147,14 +148,7 @@ void KyraEngine_v1::loadGame(const char *fileName) { _poisonDeathCounter = in->readByte(); _animator->_brandonDrawFrame = in->readUint16BE(); - for (int i = 0; i < 32; i++) { - _timers[i].active = in->readByte(); - _timers[i].countdown = in->readSint32BE(); - _timers[i].nextRun = in->readUint32BE(); - if (_timers[i].nextRun != 0) - _timers[i].nextRun += _system->getMillis(); - } - _timerNextRun = 0; + _timer->loadDataFromFile(in, version); memset(_flagsTable, 0, sizeof(_flagsTable)); uint32 flagsSize = in->readUint32BE(); @@ -206,7 +200,7 @@ void KyraEngine_v1::loadGame(const char *fileName) { if (version >= 7) { _curSfxFile = in->readByte(); - // In the first version there this entry was introduced, + // In the first version when this entry was introduced, // it wasn't made sure that _curSfxFile was initialized // so if it's out of bounds we just set it to 0. if (_curSfxFile >= _soundFilesTownsCount || _curSfxFile < 0) @@ -323,14 +317,7 @@ void KyraEngine_v1::saveGame(const char *fileName, const char *saveName) { out->writeByte(_poisonDeathCounter); out->writeUint16BE(_animator->_brandonDrawFrame); - for (int i = 0; i < 32; i++) { - out->writeByte(_timers[i].active); - out->writeSint32BE(_timers[i].countdown); - if (_system->getMillis() >= _timers[i].nextRun) - out->writeUint32BE(0); - else - out->writeUint32BE(_timers[i].nextRun - _system->getMillis()); - } + _timer->saveDataToFile(out); out->writeUint32BE(sizeof(_flagsTable)); out->write(_flagsTable, sizeof(_flagsTable)); diff --git a/engines/kyra/scene.cpp b/engines/kyra/scene.cpp new file mode 100644 index 0000000000..bf85ab1474 --- /dev/null +++ b/engines/kyra/scene.cpp @@ -0,0 +1,383 @@ +/* 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_v1.cpp b/engines/kyra/scene_v1.cpp index e01bb98e18..3754d5e2ab 100644 --- a/engines/kyra/scene_v1.cpp +++ b/engines/kyra/scene_v1.cpp @@ -33,6 +33,7 @@ #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" @@ -230,15 +231,15 @@ void KyraEngine_v1::moveCharacterToPos(int character, int facing, int xpos, int _screen->hideMouse(); xpos = (int16)(xpos & 0xFFFC); ypos = (int16)(ypos & 0xFFFE); - disableTimer(19); - disableTimer(14); - disableTimer(18); + _timer->disable(19); + _timer->disable(14); + _timer->disable(18); uint32 nextFrame = 0; switch (facing) { case 0: while (ypos < ch->y1) { - nextFrame = getTimerDelay(5 + character) * _tickLength + _system->getMillis(); + nextFrame = _timer->getDelay(5 + character) * _tickLength + _system->getMillis(); setCharacterPositionWithUpdate(character); delayUntil(nextFrame, true); } @@ -246,7 +247,7 @@ void KyraEngine_v1::moveCharacterToPos(int character, int facing, int xpos, int case 2: while (ch->x1 < xpos) { - nextFrame = getTimerDelay(5 + character) * _tickLength + _system->getMillis(); + nextFrame = _timer->getDelay(5 + character) * _tickLength + _system->getMillis(); setCharacterPositionWithUpdate(character); delayUntil(nextFrame, true); } @@ -254,7 +255,7 @@ void KyraEngine_v1::moveCharacterToPos(int character, int facing, int xpos, int case 4: while (ypos > ch->y1) { - nextFrame = getTimerDelay(5 + character) * _tickLength + _system->getMillis(); + nextFrame = _timer->getDelay(5 + character) * _tickLength + _system->getMillis(); setCharacterPositionWithUpdate(character); delayUntil(nextFrame, true); } @@ -262,7 +263,7 @@ void KyraEngine_v1::moveCharacterToPos(int character, int facing, int xpos, int case 6: while (ch->x1 > xpos) { - nextFrame = getTimerDelay(5 + character) * _tickLength + _system->getMillis(); + nextFrame = _timer->getDelay(5 + character) * _tickLength + _system->getMillis(); setCharacterPositionWithUpdate(character); delayUntil(nextFrame, true); } @@ -272,9 +273,9 @@ void KyraEngine_v1::moveCharacterToPos(int character, int facing, int xpos, int break; } - enableTimer(19); - enableTimer(14); - enableTimer(18); + _timer->enable(19); + _timer->enable(14); + _timer->enable(18); _screen->showMouse(); } @@ -282,7 +283,7 @@ void KyraEngine_v1::setCharacterPositionWithUpdate(int character) { debugC(9, kDebugLevelMain, "KyraEngine_v1::setCharacterPositionWithUpdate(%d)", character); setCharacterPosition(character, 0); _sprites->updateSceneAnims(); - updateGameTimers(); + _timer->update(); _animator->updateAllObjectShapes(); updateTextFade(); @@ -391,29 +392,6 @@ void KyraEngine_v1::setCharacterPositionHelper(int character, int *facingTable) _animator->animRefreshNPC(character); } -int KyraEngine_v1::getOppositeFacingDirection(int dir) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::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_v1::loadSceneMsc() { assert(_currentCharacter->sceneId < _roomTableSize); int tableId = _roomTable[_currentCharacter->sceneId].nameIndex; @@ -998,9 +976,9 @@ int KyraEngine_v1::processSceneChange(int *table, int unk1, int frameReset) { if (temp) ++table; - nextFrame = getTimerDelay(5) * _tickLength + _system->getMillis(); + nextFrame = _timer->getDelay(5) * _tickLength + _system->getMillis(); while (_system->getMillis() < nextFrame) { - updateGameTimers(); + _timer->update(); if (_currentCharacter->sceneId == 210) { updateKyragemFading(); @@ -1188,237 +1166,10 @@ void KyraEngine_v1::setCharactersPositions(int character) { 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; - - if (x == toY && y == toY) { - moveTable[0] = 8; - return 0; - } - - int curX = x; - int curY = y; - int lastUsedEntry = 0; - int tempValue = 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; + KyraEngine::findWay(x, y, toX, toY, moveTable, moveTableSize); return getMoveTableSize(moveTable); } -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; - } - // 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_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 - }; - - 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]; -} - -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]; -} - bool KyraEngine_v1::lineIsPassable(int x, int y) { debugC(9, kDebugLevelMain, "KyraEngine_v1::lineIsPassable(%d, %d)", x, y); if (queryGameFlag(0xEF)) { @@ -1478,100 +1229,7 @@ bool KyraEngine_v1::lineIsPassable(int x, int y) { return true; } -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; - - 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; -} +#pragma mark - void KyraEngine_v1::setupSceneResource(int sceneId) { debugC(9, kDebugLevelMain, "KyraEngine_v1::setupSceneResource(%d)", sceneId); diff --git a/engines/kyra/scene_v2.cpp b/engines/kyra/scene_v2.cpp new file mode 100644 index 0000000000..fbda1f8455 --- /dev/null +++ b/engines/kyra/scene_v2.cpp @@ -0,0 +1,865 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "kyra/kyra_v2.h" +#include "kyra/screen_v2.h" +#include "kyra/wsamovie.h" + +#include "common/func.h" + +namespace Kyra { + +void KyraEngine_v2::enterNewScene(uint16 newScene, int facing, int unk1, int unk2, int unk3) { + // XXX + _screen->hideMouse(); + + if (!unk3) { + //updateSpecialItems(); + //displayInvWsaLastFrame(); + } + + if (unk1) { + int x = _mainCharacter.x1; + int y = _mainCharacter.y1; + + switch (facing) { + case 0: + y -= 6; + break; + + case 2: + x = 335; + break; + + case 4: + y = 147; + break; + + case 6: + x = -16; + break; + + default: + break; + } + + moveCharacter(facing, x, y); + } + + //XXX sound + + _unkFlag1 = false; + + if (!unk3) { + _scriptInterpreter->initScript(&_sceneScriptState, &_sceneScriptData); + _scriptInterpreter->startScript(&_sceneScriptState, 5); + while (_scriptInterpreter->validScript(&_sceneScriptState)) + _scriptInterpreter->runScript(&_sceneScriptState); + } + + Common::for_each(_wsaSlots, _wsaSlots+ARRAYSIZE(_wsaSlots), Common::mem_fun(&WSAMovieV2::close)); + _specialExitCount = 0; + memset(_specialExitTable, -1, sizeof(_specialExitTable)); + + _mainCharacter.sceneId = newScene; + _sceneList[newScene].flags &= ~1; + loadScenePal(); + unloadScene(); + loadSceneMsc(); + + SceneDesc &scene = _sceneList[newScene]; + _sceneExit1 = scene.exit1; + _sceneExit2 = scene.exit2; + _sceneExit3 = scene.exit3; + _sceneExit4 = scene.exit4; + + //XXX sound + + startSceneScript(unk3); + + if (_overwriteSceneFacing) { + facing = _mainCharacter.facing; + _overwriteSceneFacing = false; + } + + enterNewSceneUnk1(facing, unk2, unk3); + + setTimer1DelaySecs(-1); + _sceneScriptState.regs[3] = 1; + enterNewSceneUnk2(unk3); + _screen->showMouse(); + _unk5 = 0; + //setNextIdleAnimTimer(); +} + +void KyraEngine_v2::enterNewSceneUnk1(int facing, int unk1, int unk2) { + int x = 0, y = 0; + int x2 = 0, y2 = 0; + bool needProc = true; + + if (_mainCharX == -1 && _mainCharY == -1) { + switch (facing+1) { + case 1: case 2: case 8: + x2 = _sceneEnterX3; + y2 = _sceneEnterY3; + break; + + case 3: + x2 = _sceneEnterX4; + y2 = _sceneEnterY4; + break; + + case 4: case 5: case 6: + x2 = _sceneEnterX1; + y2 = _sceneEnterY1; + break; + + case 7: + x2 = _sceneEnterX2; + y2 = _sceneEnterY2; + break; + + default: + x2 = y2 = -1; + break; + } + + if (x2 >= 316) + x2 = 312; + if (y2 >= 141) + y2 = 139; + if (x2 <= 4) + x2 = 8; + } + + if (_mainCharX >= 0) { + x = x2 = _mainCharX; + needProc = false; + } + + if (_mainCharY >= 0) { + y = y2 = _mainCharY; + needProc = false; + } + + _mainCharX = _mainCharY = -1; + + if (unk1 && needProc) { + x = x2; + y = y2; + + switch (facing) { + case 0: + y2 = 147; + break; + + case 2: + x2 = -16; + break; + + case 4: + y2 = y - 4; + break; + + case 6: + x2 = 335; + break; + + default: + break; + } + } + + x2 &= ~3; + x &= ~3; + y2 &= ~1; + y &= ~1; + + _mainCharacter.facing = facing; + _mainCharacter.x1 = _mainCharacter.x2 = x2; + _mainCharacter.y1 = _mainCharacter.y2 = y2; + initSceneAnims(unk2); + + if (!unk2) { + //XXX sound + } + + if (unk1 && !unk2 && _mainCharacter.animFrame != 32) + moveCharacter(facing, x, y); +} + +void KyraEngine_v2::enterNewSceneUnk2(int unk1) { + _unk3 = -1; + + if (_mainCharX == -1 && _mainCharY == -1 && _mainCharacter.sceneId != 61 && + !queryGameFlag(0x1F1) && !queryGameFlag(0x192) && !queryGameFlag(0x193) && + _mainCharacter.sceneId != 70 && !queryGameFlag(0x159) && _mainCharacter.sceneId != 37) { + _mainCharacter.animFrame = _characterFrameTable[_mainCharacter.facing]; + updateCharacterAnim(0); + refreshAnimObjectsIfNeed(); + } + + if (!unk1) { + runSceneScript4(0); + //XXX sub_27158 + } + + _unk4 = 0; + _unk3 = -1; +} + +int KyraEngine_v2::trySceneChange(int *moveTable, int unk1, int updateChar) { + bool running = true; + bool unkFlag = false; + int8 updateType = -1; + int changedScene = 0; + const int *moveTableStart = moveTable; + _unk4 = 0; + while (running) { + if (*moveTable >= 0 && *moveTable <= 7) { + _mainCharacter.facing = getOppositeFacingDirection(*moveTable); + unkFlag = true; + } else { + if (*moveTable == 8) { + running = false; + } else { + ++moveTable; + unkFlag = false; + } + } + + if (checkSceneChange()) { + running = false; + changedScene = 1; + } + + if (unk1) { + //XXX + } + + if (!unkFlag || !running) + continue; + + int ret = 0; + if (moveTable == moveTableStart || moveTable[1] == 8) + ret = updateCharPos(0); + else + ret = updateCharPos(moveTable); + + if (ret) + ++moveTable; + + ++updateType; + if (!updateType) { + update(); + } else if (updateType == 1) { + refreshAnimObjectsIfNeed(); + updateType = -1; + } + } + + if (updateChar) + _mainCharacter.animFrame = _characterFrameTable[_mainCharacter.facing]; + + updateCharacterAnim(0); + refreshAnimObjectsIfNeed(); + + if (!changedScene && !_unk4) { + //XXX + } + return changedScene; +} + +int KyraEngine_v2::checkSceneChange() { + SceneDesc &curScene = _sceneList[_mainCharacter.sceneId]; + int charX = _mainCharacter.x1, charY = _mainCharacter.y1; + int facing = 0; + int process = 0; + + if (_screen->getLayer(charX, charY) == 1 && _unk3 == -6) { + facing = 0; + process = 1; + } else if (charX >= 316 && _unk3 == -5) { + facing = 2; + process = 1; + } else if (charY >= 142 && _unk3 == -4) { + facing = 4; + process = 1; + } else if (charX <= 4 && _unk3 == -3) { + facing = 6; + process = 1; + } + + if (!process) + return 0; + + uint16 newScene = 0xFFFF; + switch (facing) { + case 0: + newScene = curScene.exit1; + break; + + case 2: + newScene = curScene.exit2; + break; + + case 4: + newScene = curScene.exit3; + break; + + case 6: + newScene = curScene.exit4; + break; + + default: + newScene = _mainCharacter.sceneId; + break; + } + + if (newScene == 0xFFFF) + return 0; + + enterNewScene(newScene, facing, 1, 1, 0); + return 1; +} + +void KyraEngine_v2::unloadScene() { + _scriptInterpreter->unloadScript(&_sceneScriptData); + freeSceneShapePtrs(); + freeSceneAnims(); +} + +void KyraEngine_v2::loadScenePal() { + uint16 sceneId = _mainCharacter.sceneId; + memcpy(_screen->getPalette(1), _screen->getPalette(0), 768); + + char filename[14]; + strcpy(filename, _sceneList[sceneId].filename); + strcat(filename, ".COL"); + _screen->loadBitmap(filename, 3, 3, 0); + memcpy(_screen->getPalette(1), _screen->getCPagePtr(3), 384); + memset(_screen->getPalette(1), 0, 3); + memcpy(_scenePal, _screen->getCPagePtr(3)+336, 432); +} + +void KyraEngine_v2::loadSceneMsc() { + uint16 sceneId = _mainCharacter.sceneId; + char filename[14]; + strcpy(filename, _sceneList[sceneId].filename); + strcat(filename, ".MSC"); + _screen->loadBitmap(filename, 3, 5, 0); +} + +void KyraEngine_v2::startSceneScript(int unk1) { + uint16 sceneId = _mainCharacter.sceneId; + char filename[14]; + + strcpy(filename, _sceneList[sceneId].filename); + if (sceneId == 68 && (queryGameFlag(0x1BC) || queryGameFlag(0x1DC))) + strcpy(filename, "DOORX"); + strcat(filename, ".CPS"); + + _screen->loadBitmap(filename, 3, 3, 0); + resetScaleTable(); + _useCharPal = false; + memset(_charPalTable, 0, sizeof(_charPalTable)); + //XXX _unkTable33 + memset(_specialSceneScriptState, 0, sizeof(_specialSceneScriptState)); + + _sceneEnterX1 = 160; + _sceneEnterY1 = 0; + _sceneEnterX2 = 296; + _sceneEnterY2 = 72; + _sceneEnterX3 = 160; + _sceneEnterY3 = 128; + _sceneEnterX4 = 24; + _sceneEnterY4 = 72; + + _sceneCommentString = "Undefined scene comment string!"; + _scriptInterpreter->initScript(&_sceneScriptState, &_sceneScriptData); + + strcpy(filename, _sceneList[sceneId].filename); + strcat(filename, "."); + strcat(filename, _scriptLangExt[_lang]); + + assert(_res->getFileSize(filename)); + _scriptInterpreter->loadScript(filename, &_sceneScriptData, &_opcodes); + runSceneScript7(); + + _scriptInterpreter->startScript(&_sceneScriptState, 0); + _sceneScriptState.regs[0] = sceneId; + _sceneScriptState.regs[5] = unk1; + while (_scriptInterpreter->validScript(&_sceneScriptState)) + _scriptInterpreter->runScript(&_sceneScriptState); + + memcpy(_gamePlayBuffer, _screen->getCPagePtr(3), 46080); + + for (int i = 0; i < 10; ++i) { + _scriptInterpreter->initScript(&_sceneSpecialScripts[i], &_sceneScriptData); + _scriptInterpreter->startScript(&_sceneSpecialScripts[i], i+8); + _sceneSpecialScriptsTimer[i] = 0; + } + + _sceneEnterX1 &= ~3; + _sceneEnterX2 &= ~3; + _sceneEnterX3 &= ~3; + _sceneEnterX4 &= ~3; + _sceneEnterY1 &= ~1; + _sceneEnterY2 &= ~1; + _sceneEnterY3 &= ~1; + _sceneEnterY4 &= ~1; +} + +void KyraEngine_v2::runSceneScript2() { + _scriptInterpreter->initScript(&_sceneScriptState, &_sceneScriptData); + _sceneScriptState.regs[4] = _itemInHand; + _scriptInterpreter->startScript(&_sceneScriptState, 2); + + while (_scriptInterpreter->validScript(&_sceneScriptState)) + _scriptInterpreter->runScript(&_sceneScriptState); +} + +void KyraEngine_v2::runSceneScript4(int unk1) { + _sceneScriptState.regs[4] = _itemInHand; + _sceneScriptState.regs[5] = unk1; + + _scriptInterpreter->startScript(&_sceneScriptState, 4); + while (_scriptInterpreter->validScript(&_sceneScriptState)) + _scriptInterpreter->runScript(&_sceneScriptState); +} + +void KyraEngine_v2::runSceneScript7() { + int oldPage = _screen->_curPage; + _screen->_curPage = 2; + + _scriptInterpreter->startScript(&_sceneScriptState, 7); + while (_scriptInterpreter->validScript(&_sceneScriptState)) + _scriptInterpreter->runScript(&_sceneScriptState); + + _screen->_curPage = oldPage; +} + +void KyraEngine_v2::initSceneAnims(int unk1) { + for (int i = 0; i < ARRAYSIZE(_animObjects); ++i) + _animObjects[i].enabled = 0; + + bool animInit = false; + + AnimObj *animState = &_animObjects[0]; + + if (_mainCharacter.animFrame != 32) + _mainCharacter.animFrame = _characterFrameTable[_mainCharacter.facing]; + + animState->enabled = 1; + animState->xPos1 = _mainCharacter.x1; + animState->yPos1 = _mainCharacter.y1; + animState->shapePtr = _defaultShapeTable[_mainCharacter.animFrame]; + animState->shapeIndex1 = animState->shapeIndex2 = _mainCharacter.animFrame; + + int frame = _mainCharacter.animFrame - 9; + int shapeX = _shapeDescTable[frame].xAdd; + int shapeY = _shapeDescTable[frame].yAdd; + + animState->xPos2 = _mainCharacter.x1; + animState->yPos2 = _mainCharacter.y1; + + _charScaleX = _charScaleY = getScale(_mainCharacter.x1, _mainCharacter.y1); + + int shapeXScaled = (shapeX * _charScaleX) >> 8; + int shapeYScaled = (shapeY * _charScaleY) >> 8; + + animState->xPos2 += shapeXScaled; + animState->yPos2 += shapeYScaled; + animState->xPos3 = animState->xPos2; + animState->yPos3 = animState->yPos2; + animState->needRefresh = 1; + animState->unk8 = 1; + + _animList = 0; + + AnimObj *charAnimState = animState; + + for (int i = 0; i < 10; ++i) { + animState = &_animObjects[i+1]; + animState->enabled = 0; + animState->needRefresh = 0; + animState->unk8 = 0; + + if (_sceneAnims[i].flags & 1) { + animState->enabled = 1; + animState->needRefresh = 1; + animState->unk8 = 1; + } + + animState->animFlags = _sceneAnims[i].flags & 8; + + if (_sceneAnims[i].flags & 2) + animState->flags = 0x800; + else + animState->flags = 0; + + if (_sceneAnims[i].flags & 4) + animState->flags |= 1; + + animState->xPos1 = _sceneAnims[i].x; + animState->yPos1 = _sceneAnims[i].y; + + if (_sceneAnims[i].flags & 0x20) + animState->shapePtr = _sceneShapeTable[_sceneAnims[i].shapeIndex]; + else + animState->shapePtr = 0; + + if (_sceneAnims[i].flags & 0x40) { + animState->shapeIndex3 = _sceneAnims[i].shapeIndex; + animState->animNum = i; + } else { + animState->shapeIndex3 = 0xFFFF; + animState->animNum = 0xFFFF; + } + + animState->shapeIndex2 = 0xFFFF; + + animState->xPos3 = animState->xPos2 = _sceneAnims[i].x2; + animState->yPos3 = animState->yPos2 = _sceneAnims[i].y2; + animState->width = _sceneAnims[i].width; + animState->height = _sceneAnims[i].height; + animState->width2 = animState->height2 = _sceneAnims[i].specialSize; + + if (_sceneAnims[i].flags & 1) { + if (animInit) { + _animList = addToAnimListSorted(_animList, animState); + } else { + _animList = initAnimList(_animList, animState); + animInit = true; + } + } + } + + if (animInit) { + _animList = addToAnimListSorted(_animList, charAnimState); + } else { + _animList = initAnimList(_animList, charAnimState); + animInit = true; + } + + for (int i = 0; i < 30; ++i) { + animState = &_animObjects[i+11]; + + uint16 shapeIndex = _itemList[i].id; + if (shapeIndex == 0xFFFF || _itemList[i].sceneId != _mainCharacter.sceneId) { + animState->enabled = 0; + animState->needRefresh = 0; + animState->unk8 = 0; + } else { + animState->xPos1 = _itemList[i].x; + animState->yPos1 = _itemList[i].y; + animState->shapePtr = _defaultShapeTable[64+shapeIndex]; + animState->shapeIndex1 = animState->shapeIndex2 = shapeIndex+64; + + animState->xPos2 = _itemList[i].x; + animState->yPos2 = _itemList[i].y; + int objectScale = getScale(animState->xPos2, animState->yPos2); + + const uint8 *shape = getShapePtr(animState->shapeIndex1); + animState->xPos2 -= (_screen->getShapeScaledWidth(shape, objectScale) >> 1); + animState->yPos2 -= (_screen->getShapeScaledHeight(shape, objectScale) >> 1); + animState->xPos3 = animState->xPos2; + animState->yPos3 = animState->yPos2; + + animState->enabled = 1; + animState->needRefresh = 1; + animState->unk8 = 1; + + if (animInit) { + _animList = addToAnimListSorted(_animList, animState); + } else { + _animList = initAnimList(_animList, animState); + animInit = true; + } + } + } + + _animObjects[0].unk8 = 1; + _animObjects[0].needRefresh = 1; + + for (int i = 1; i < 41; ++i) { + if (_animObjects[i].enabled) { + _animObjects[i].needRefresh = 1; + _animObjects[i].unk8 = 1; + } + } + + restorePage3(); + drawAnimObjects(); + _screen->hideMouse(); + initSceneScreen(unk1); + _screen->showMouse(); + refreshAnimObjects(0); +} + +void KyraEngine_v2::initSceneScreen(int unk1) { + if (_unkSceneScreenFlag1) { + _screen->copyRegion(0, 0, 0, 0, 320, 144, 2, 0); + return; + } + + if (_noScriptEnter) { + memset(_screen->getPalette(0), 0, 384); + _screen->setScreenPalette(_screen->getPalette(0)); + } + + _screen->copyRegion(0, 0, 0, 0, 320, 144, 2, 0); + + if (_noScriptEnter) + memcpy(_screen->getPalette(0), _screen->getPalette(1), 384); + + updateCharPal(0); + + _scriptInterpreter->startScript(&_sceneScriptState, 3); + _sceneScriptState.regs[5] = unk1; + while (_scriptInterpreter->validScript(&_sceneScriptState)) + _scriptInterpreter->runScript(&_sceneScriptState); +} + +void KyraEngine_v2::updateSpecialSceneScripts() { + uint32 nextTime = _system->getMillis() + _tickLength; + const int startScript = _lastProcessedSceneScript; + + while (_system->getMillis() <= nextTime) { + if (_sceneSpecialScriptsTimer[_lastProcessedSceneScript] <= _system->getMillis() && + !_specialSceneScriptState[_lastProcessedSceneScript]) { + _specialSceneScriptRunFlag = true; + + while (_specialSceneScriptRunFlag && _sceneSpecialScriptsTimer[_lastProcessedSceneScript] <= _system->getMillis()) + _specialSceneScriptRunFlag = _scriptInterpreter->runScript(&_sceneSpecialScripts[_lastProcessedSceneScript]) != 0; + } + + if (!_scriptInterpreter->validScript(&_sceneSpecialScripts[_lastProcessedSceneScript])) { + _scriptInterpreter->startScript(&_sceneSpecialScripts[_lastProcessedSceneScript], 8+_lastProcessedSceneScript); + _specialSceneScriptRunFlag = false; + } + + ++_lastProcessedSceneScript; + if (_lastProcessedSceneScript >= 10) + _lastProcessedSceneScript = 0; + + if (_lastProcessedSceneScript == startScript) + return; + } +} + +void KyraEngine_v2::freeSceneShapePtrs() { + for (int i = 0; i < ARRAYSIZE(_sceneShapeTable); ++i) + delete [] _sceneShapeTable[i]; + memset(_sceneShapeTable, 0, sizeof(_sceneShapeTable)); +} + +void KyraEngine_v2::freeSceneAnims() { + Common::for_each(_sceneAnimMovie, _sceneAnimMovie+ARRAYSIZE(_sceneAnimMovie), Common::mem_fun(&WSAMovieV2::close)); +} + +#pragma mark - +#pragma mark - Pathfinder +#pragma mark - + +int KyraEngine_v2::findWay(int x, int y, int toX, int toY, int *moveTable, int moveTableSize) { + debugC(9, kDebugLevelMain, "KyraEngine_v2::findWay(%d, %d, %d, %d, %p, %d)", x, y, toX, toY, (const void *)moveTable, moveTableSize); + x &= ~3; toX &= ~3; + y &= ~1; toY &= ~1; + int size = KyraEngine::findWay(x, y, toX, toY, moveTable, moveTableSize); + /*if (size) { + int temp = pathfinderUnk1(moveTable); + temp = pathfinderUnk3(temp, x, y); + pathfinderUnk5(moveTable, temp, x, y, moveTableSize); + }*/ + return getMoveTableSize(moveTable); +} + +bool KyraEngine_v2::lineIsPassable(int x, int y) { + debugC(9, kDebugLevelMain, "KyraEngine_v2::lineIsPassable(%d, %d)", x, y); + static int unkTable[] = { 1, 1, 1, 1, 1, 2, 4, 6, 8 }; + + if (_pathfinderFlag & 2) { + if (x >= 320) + return false; + } + + if (_pathfinderFlag & 4) { + if (y >= 144) + return false; + } + + if (_pathfinderFlag & 8) { + if (x < 0) + return false; + } + + if (y > 143) + return false; + + int unk1 = unkTable[getScale(x, y) >> 5]; + + if (y < 0) + y = 0; + x -= unk1 >> 1; + if (x < 0) + x = 0; + int x2 = x + unk1; + if (x2 > 320) + x2 = 320; + + for (;x < x2; ++x) + if (!_screen->getShapeFlag1(x, y)) + return false; + + return true; +} + +bool KyraEngine_v2::directLinePassable(int x, int y, int toX, int toY) { + while (x != toX && y != toY) { + int facing = getFacingFromPointToPoint(x, y, toX, toY); + x += _addXPosTable[facing]; + y += _addYPosTable[facing]; + if (!_screen->getShapeFlag1(x, y)) + return false; + } + return true; +} + +int KyraEngine_v2::pathfinderUnk1(int *moveTable) { + bool breakLoop = false; + int *moveTableCur = moveTable; + int oldEntry = *moveTableCur, curEntry = *moveTableCur; + int oldX = 0, newX = 0, oldY = 0, newY = 0; + int lastEntry = 0; + lastEntry = pathfinderUnk2(lastEntry, 0, 0); + + while (*moveTableCur != 8) { + oldEntry = curEntry; + + while (true) { + curEntry = *moveTableCur; + if (curEntry >= 0 && curEntry <= 7) + break; + + if (curEntry == 8) { + breakLoop = true; + break; + } else { + ++moveTableCur; + } + } + + if (breakLoop) + break; + + oldX = newX; + oldY = newY; + + newX += _addXPosTable[curEntry]; + newY += _addYPosTable[curEntry]; + + int temp = ABS(curEntry - oldEntry); + if (temp > 4) { + temp = 8 - temp; + } + + if (temp > 1 || oldEntry != curEntry) + lastEntry = pathfinderUnk2(lastEntry, oldX, oldY); + + ++moveTableCur; + } + + lastEntry = pathfinderUnk2(lastEntry, newX, newY); + _pathfinderUnkTable1[lastEntry*2+0] = -1; + _pathfinderUnkTable1[lastEntry*2+1] = -1; + return lastEntry; +} + +int KyraEngine_v2::pathfinderUnk2(int index, int v1, int v2) { + _pathfinderUnkTable1[index<<1] = v1; + _pathfinderUnkTable1[(index<<1)+1] = v2; + ++index; + if (index >= 199) + --index; + return index; +} + +int KyraEngine_v2::pathfinderUnk3(int tableLen, int x, int y) { + int x1 = 0, y1 = 0; + int x2 = 0, y2 = 0; + int lastEntry = 0; + int index2 = tableLen-1, index1 = 0; + while (index2 > index1) { + x1 = _pathfinderUnkTable1[index1*2+0] + x; + y1 = _pathfinderUnkTable1[index1*2+1] + y; + x2 = _pathfinderUnkTable1[index2*2+0] + x; + y2 = _pathfinderUnkTable1[index2*2+0] + x; + + if (directLinePassable(x1, y1, x2, y2)) { + lastEntry = pathfinderUnk4(lastEntry, index2); + if (tableLen-1 == index2) + break; + index1 = index2; + index2 = tableLen-1; + } else if (index1+1 == index2) { + lastEntry = pathfinderUnk4(lastEntry, index2); + index1 = index2; + index2 = tableLen-1; + } else { + --index2; + } + } + return lastEntry; +} + +int KyraEngine_v2::pathfinderUnk4(int index, int v) { + _pathfinderUnkTable2[index] = v; + ++index; + if (index >= 199) + --index; + return index; +} + +void KyraEngine_v2::pathfinderUnk5(int *moveTable, int tableLen, int x, int y, int moveTableSize) { + int x1 = 0, y1 = 0; + int x2 = 0, y2 = 0; + int index1 = 0, index2 = 0; + int sizeLeft = moveTableSize; + for (int i = 0; i < tableLen; ++i) { + index2 = _pathfinderUnkTable2[i]; + x1 = _pathfinderUnkTable1[index1*2+0] + x; + y1 = _pathfinderUnkTable1[index1*2+1] + y; + x2 = _pathfinderUnkTable1[index2*2+0] + x; + y2 = _pathfinderUnkTable1[index2*2+0] + x; + + int wayLen = findWay(x1, y1, x2, y2, moveTable, sizeLeft); + moveTable += wayLen; + sizeLeft -= wayLen; // unlike the original we want to be sure that the size left is correct + index1 = index2; + } +} + +} // end of namespace Kyra diff --git a/engines/kyra/screen.cpp b/engines/kyra/screen.cpp index 0e01801369..a7e9c90824 100644 --- a/engines/kyra/screen.cpp +++ b/engines/kyra/screen.cpp @@ -355,33 +355,6 @@ void Screen::fadeToBlack(int delay) { fadePalette(blackPal, delay); } -void Screen::k2IntroFadeToGrey(int delay) { - debugC(9, kDebugLevelScreen, "Screen::k2IntroFadeToGrey()"); - - for (int i = 0; i <= 50; ++i) { - if (i <= 8 || i >= 30) { - _currentPalette[3 * i + 0] = (_currentPalette[3 * i + 0] + - _currentPalette[3 * i + 1] + - _currentPalette[3 * i + 2]) / 3; - _currentPalette[3 * i + 1] = _currentPalette[3 * i + 0]; - _currentPalette[3 * i + 2] = _currentPalette[3 * i + 0]; - } - } - - // color 71 is the same in both the overview and closeup scenes - // Converting it to greyscale makes the trees in the closeup look dull - for (int i = 71; i < 200; ++i) { - _currentPalette[3 * i + 0] = (_currentPalette[3 * i + 0] + - _currentPalette[3 * i + 1] + - _currentPalette[3 * i + 2]) / 3; - _currentPalette[3 * i + 1] = _currentPalette[3 * i + 0]; - _currentPalette[3 * i + 2] = _currentPalette[3 * i + 0]; - } - fadePalette(_currentPalette, delay); - // Make the font color white again - setPaletteIndex(254, 254, 254, 254); -} - void Screen::fadePalette(const uint8 *palData, int delay) { debugC(9, kDebugLevelScreen, "Screen::fadePalette(%p, %d)", (const void *)palData, delay); updateScreen(); @@ -1057,13 +1030,8 @@ void Screen::drawCharANSI(uint8 c, int x, int y) { void Screen::setScreenDim(int dim) { debugC(9, kDebugLevelScreen, "Screen::setScreenDim(%d)", dim); - if (_vm->game() == GI_KYRA1) { - assert(dim < _screenDimTableCount); - _curDim = &_screenDimTable[dim]; - } else { - assert(dim < _screenDimTableCountK3); - _curDim = &_screenDimTableK3[dim]; - } + assert(dim < _screenDimTableCount); + _curDim = &_screenDimTable[dim]; // XXX } @@ -2680,38 +2648,6 @@ void Screen::loadPalette(const byte *data, uint8 *palData, int bytes) { } } -// kyra3 specific - -const uint8 *Screen::getPtrToShape(const uint8 *shpFile, int shape) { - debugC(9, kDebugLevelScreen, "KyraEngine::getPtrToShape(%p, %d)", (const void *)shpFile, shape); - uint16 shapes = READ_LE_UINT16(shpFile); - - if (shapes <= shape) - return 0; - - uint32 offset = READ_LE_UINT32(shpFile + (shape << 2) + 2); - - return shpFile + offset + 2; -} - -uint8 *Screen::getPtrToShape(uint8 *shpFile, int shape) { - debugC(9, kDebugLevelScreen, "KyraEngine::getPtrToShape(%p, %d)", (void *)shpFile, shape); - uint16 shapes = READ_LE_UINT16(shpFile); - - if (shapes <= shape) - return 0; - - uint32 offset = READ_LE_UINT32(shpFile + (shape << 2) + 2); - - return shpFile + offset + 2; -} - -uint16 Screen::getShapeSize(const uint8 *shp) { - debugC(9, kDebugLevelScreen, "KyraEngine::getShapeSize(%p)", (const void *)shp); - - return READ_LE_UINT16(shp+6); -} - // dirty rect handling void Screen::addDirtyRect(int x, int y, int w, int h) { diff --git a/engines/kyra/screen.h b/engines/kyra/screen.h index 355407a330..b1a1eb7b1a 100644 --- a/engines/kyra/screen.h +++ b/engines/kyra/screen.h @@ -133,8 +133,6 @@ public: void fadeFromBlack(int delay=0x54); void fadeToBlack(int delay=0x54); - void k2IntroFadeToGrey(int delay=0x54); - void fadePalette(const uint8 *palData, int delay); void setPaletteIndex(uint8 index, uint8 red, uint8 green, uint8 blue); @@ -162,7 +160,7 @@ public: void setTextColorMap(const uint8 *cmap); void setTextColor(const uint8 *cmap, int a, int b); - void setScreenDim(int dim); + virtual void setScreenDim(int dim); // shape handling uint8 *encodeShape(int x, int y, int w, int h, int flags); @@ -170,7 +168,7 @@ public: int setNewShapeHeight(uint8 *shape, int height); int resetShapeHeight(uint8 *shape); - void drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int sd, int flags, ...); + virtual void drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int sd, int flags, ...); // mouse handling void hideMouse(); @@ -178,7 +176,7 @@ public: void setMouseCursor(int x, int y, byte *shape); // rect handling - int getRectSize(int w, int h); + virtual int getRectSize(int w, int h); void rectClip(int &x, int &y, int w, int h); @@ -208,6 +206,7 @@ public: void copyBackgroundBlock(int x, int page, int flag); void copyBackgroundBlock2(int x); + // kyra1 specific? int getDrawLayer(int x, int y); int getDrawLayer2(int x, int y, int height); @@ -232,15 +231,6 @@ public: static void convertAmigaGfx(uint8 *data, int w, int h, bool offscreen = true); static void convertAmigaMsc(uint8 *data); - // maybe subclass screen for kyra3 - static const ScreenDim _screenDimTableK3[]; - static const int _screenDimTableCountK3; - - uint8 *getPtrToShape(uint8 *shpFile, int shape); - const uint8 *getPtrToShape(const uint8 *shpFile, int shape); - - uint16 getShapeSize(const uint8 *shp); - protected: uint8 *getPagePtr(int pageNum); void updateDirtyRects(); diff --git a/engines/kyra/screen_v2.cpp b/engines/kyra/screen_v2.cpp index 3e98cdbe5b..3ad69818c6 100644 --- a/engines/kyra/screen_v2.cpp +++ b/engines/kyra/screen_v2.cpp @@ -11,7 +11,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License @@ -24,6 +24,7 @@ */ #include "common/stdafx.h" +#include "common/endian.h" #include "kyra/kyra_v2.h" #include "kyra/screen_v2.h" @@ -38,4 +39,523 @@ Screen_v2::Screen_v2(KyraEngine_v2 *vm, OSystem *system) Screen_v2::~Screen_v2() { } +void Screen_v2::setScreenDim(int dim) { + debugC(9, kDebugLevelScreen, "Screen_v2::setScreenDim(%d)", dim); + if (_vm->game() == GI_KYRA2) { + assert(dim < _screenDimTableCount); + _curDim = &_screenDimTable[dim]; + } else { + assert(dim < _screenDimTableCountK3); + _curDim = &_screenDimTableK3[dim]; + } +} + +const ScreenDim *Screen_v2::getScreenDim(int dim) { + debugC(9, kDebugLevelScreen, "Screen_v2::getScreenDim(%d)", dim); + if (_vm->game() == GI_KYRA2) { + assert(dim < _screenDimTableCount); + return &_screenDimTable[dim]; + } else { + assert(dim < _screenDimTableCountK3); + return &_screenDimTableK3[dim]; + } +} + +void Screen_v2::k2IntroFadeToGrey(int delay) { + debugC(9, kDebugLevelScreen, "Screen_v2::k2IntroFadeToGrey(%d)", delay); + + for (int i = 0; i <= 50; ++i) { + if (i <= 8 || i >= 30) { + _currentPalette[3 * i + 0] = (_currentPalette[3 * i + 0] + + _currentPalette[3 * i + 1] + + _currentPalette[3 * i + 2]) / 3; + _currentPalette[3 * i + 1] = _currentPalette[3 * i + 0]; + _currentPalette[3 * i + 2] = _currentPalette[3 * i + 0]; + } + } + + // color 71 is the same in both the overview and closeup scenes + // Converting it to greyscale makes the trees in the closeup look dull + for (int i = 71; i < 200; ++i) { + _currentPalette[3 * i + 0] = (_currentPalette[3 * i + 0] + + _currentPalette[3 * i + 1] + + _currentPalette[3 * i + 2]) / 3; + _currentPalette[3 * i + 1] = _currentPalette[3 * i + 0]; + _currentPalette[3 * i + 2] = _currentPalette[3 * i + 0]; + } + fadePalette(_currentPalette, delay); + // Make the font color white again + setPaletteIndex(254, 254, 254, 254); +} + +void Screen_v2::copyWsaRect(int x, int y, int w, int h, int dimState, int plotFunc, const uint8 *src, + int unk1, const uint8 *unkPtr1, const uint8 *unkPtr2) { + uint8 *dstPtr = getPagePtr(_curPage); + uint8 *origDst = dstPtr; + + const ScreenDim *dim = getScreenDim(dimState); + int dimX1 = dim->sx << 3; + int dimX2 = dim->w << 3; + dimX2 += dimX1; + + int dimY1 = dim->sy; + int dimY2 = dim->h; + dimY2 += dimY1; + + int temp = y - dimY1; + if (temp < 0) { + if ((temp += h) <= 0) + return; + else { + SWAP(temp, h); + y += temp - h; + src += (temp - h) * w; + } + } + + temp = dimY2 - y; + if (temp <= 0) + return; + + if (temp < h) + h = temp; + + int srcOffset = 0; + temp = x - dimX1; + if (temp < 0) { + temp = -temp; + srcOffset = temp; + x += temp; + w -= temp; + } + + int srcAdd = 0; + + temp = dimX2 - x; + if (temp <= 0) + return; + + if (temp < w) { + SWAP(w, temp); + temp -= w; + srcAdd = temp; + } + + dstPtr += y * SCREEN_W + x; + uint8 *dst = dstPtr; + + if (_curPage == 0 || _curPage == 1) + addDirtyRect(x, y, w, h); + + clearOverlayRect(_curPage, x, y, w, h); + + temp = h; + while (h--) { + src += srcOffset; + int cW = w; + + switch (plotFunc) { + case 0: + memcpy(dst, src, cW); + dst += cW; src += cW; + break; + + case 1: + while (cW--) { + uint8 d = *src++; + uint8 t = unkPtr1[d]; + if (t != 0xFF) + d = unkPtr2[*dst + (t << 8)]; + *dst++ = d; + } + break; + + case 4: + while (cW--) { + uint8 d = *src++; + if (d) + *dst = d; + ++dst; + } + break; + + case 5: + while (cW--) { + uint8 d = *src++; + if (d) { + uint8 t = unkPtr1[d]; + if (t != 0xFF) + d = unkPtr2[*dst + (t << 8)]; + *dst = d; + } + ++dst; + } + break; + + case 8: + case 9: + while (cW--) { + uint8 d = *src++; + uint8 t = _shapePages[0][dst - origDst] & 7; + if (unk1 < t) + d = _shapePages[1][dst - origDst]; + *dst++ = d; + } + break; + + case 12: + case 13: + while (cW--) { + uint8 d = *src++; + if (d) { + uint8 t = _shapePages[0][dst - origDst] & 7; + if (unk1 < t) + d = _shapePages[1][dst - origDst]; + *dst++ = d; + } else { + d = _shapePages[1][dst - origDst]; + *dst++ = d; + } + } + break; + + default: + break; + } + + dst = (dstPtr += SCREEN_W); + src += srcAdd; + } +} + +const uint8 *Screen_v2::getPtrToShape(const uint8 *shpFile, int shape) { + debugC(9, kDebugLevelScreen, "Screen_v2::getPtrToShape(%p, %d)", (const void *)shpFile, shape); + uint16 shapes = READ_LE_UINT16(shpFile); + + if (shapes <= shape) + return 0; + + uint32 offset = READ_LE_UINT32(shpFile + (shape << 2) + 2); + + return shpFile + offset + 2; +} + +uint8 *Screen_v2::getPtrToShape(uint8 *shpFile, int shape) { + debugC(9, kDebugLevelScreen, "Screen_v2::getPtrToShape(%p, %d)", (void *)shpFile, shape); + uint16 shapes = READ_LE_UINT16(shpFile); + + if (shapes <= shape) + return 0; + + uint32 offset = READ_LE_UINT32(shpFile + (shape << 2) + 2); + + return shpFile + offset + 2; +} + +int Screen_v2::getShapeScaledWidth(const uint8 *shpFile, int scale) { + int width = READ_LE_UINT16(shpFile+3); + return (width * scale) >> 8; +} + +int Screen_v2::getShapeScaledHeight(const uint8 *shpFile, int scale) { + int height = shpFile[2]; + return (height * scale) >> 8; +} + +uint16 Screen_v2::getShapeSize(const uint8 *shp) { + debugC(9, kDebugLevelScreen, "Screen_v2::getShapeSize(%p)", (const void *)shp); + + return READ_LE_UINT16(shp+6); +} + +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); + int size = getShapeSize(shape); + + uint8 *copy = new uint8[size]; + assert(copy); + memcpy(copy, shape, size); + + return copy; +} + +void Screen_v2::drawShape(uint8 page, const uint8 *shape, int x, int y, int sd, int flags, ...) { + if (!shape) + return; + + if (*shape & 1) + flags |= 0x400; + + va_list args; + va_start(args, flags); + + static int drawShapeVar1 = 0; + static int drawShapeVar2[] = { + 1, 3, 2, 5, 4, 3, 2, 1 + }; + static int drawShapeVar3 = 1; + static int drawShapeVar4 = 0; + static int drawShapeVar5 = 0; + + uint8 *table = 0; + int tableLoopCount = 0; + int drawLayer = 0; + const uint8 *table2 = 0; + uint8 *table3 = 0; + uint8 *table4 = 0; + + if (flags & 0x8000) { + table2 = va_arg(args, uint8*); + } + if (flags & 0x100) { + table = va_arg(args, uint8*); + tableLoopCount = va_arg(args, int); + if (!tableLoopCount) + flags &= 0xFFFFFEFF; + } + if (flags & 0x1000) { + table3 = va_arg(args, uint8*); + table4 = va_arg(args, uint8*); + } + if (flags & 0x200) { + drawShapeVar1 += 1; + drawShapeVar1 &= 7; + drawShapeVar3 = drawShapeVar2[drawShapeVar1]; + drawShapeVar4 = 0; + drawShapeVar5 = 256; + } + if (flags & 0x4000) { + drawShapeVar5 = va_arg(args, int); + } + if (flags & 0x800) { + drawLayer = va_arg(args, int); + } + int scale_w, scale_h; + if (flags & 0x04) { + scale_w = va_arg(args, int); + scale_h = va_arg(args, int); + } else { + scale_w = 0x100; + scale_h = 0x100; + } + + int ppc = (flags >> 8) & 0x3F; + + const uint8 *src = shape; + uint16 shapeFlags = READ_LE_UINT16(src); src += 2; + + int shapeHeight = *src++; + int scaledShapeHeight = (shapeHeight * scale_h) >> 8; + if (scaledShapeHeight == 0) { + va_end(args); + return; + } + + int shapeWidth = READ_LE_UINT16(src); src += 2; + int scaledShapeWidth = (shapeWidth * scale_w) >> 8; + if (scaledShapeWidth == 0) { + va_end(args); + return; + } + + if (flags & 0x20) { + x -= scaledShapeWidth >> 1; + y -= scaledShapeHeight >> 1; + } + + src += 3; + + uint16 frameSize = READ_LE_UINT16(src); src += 2; + int colorTableColors = 0x10; + + if (shapeFlags & 4) + colorTableColors = *src++; + + if (!(flags & 0x8000) && (shapeFlags & 1)) + table2 = src; + + if ((shapeFlags & 1) || (flags & 0x400)) + src += colorTableColors; + + if (!(shapeFlags & 2)) { + decodeFrame4(src, _animBlockPtr, frameSize); + src = _animBlockPtr; + } + + int shapeSize = shapeWidth * shapeHeight; + if (_decodeShapeBufferSize < shapeSize) { + delete [] _decodeShapeBuffer; + _decodeShapeBuffer = new uint8[shapeSize]; + _decodeShapeBufferSize = shapeSize; + } + if (!_decodeShapeBuffer) { + _decodeShapeBufferSize = 0; + va_end(args); + return; + } + memset(_decodeShapeBuffer, 0, _decodeShapeBufferSize); + uint8 *decodedShapeFrame = _decodeShapeBuffer; + + for (int j = 0; j < shapeHeight; ++j) { + uint8 *dsbNextLine = decodedShapeFrame + shapeWidth; + int count = shapeWidth; + while (count > 0) { + uint8 code = *src++; + if (code != 0) { + *decodedShapeFrame++ = code; + --count; + } else { + code = *src++; + decodedShapeFrame += code; + count -= code; + } + } + decodedShapeFrame = dsbNextLine; + } + + uint16 sx1 = getScreenDim(sd)->sx << 3; + uint16 sy1 = getScreenDim(sd)->sy; + uint16 sx2 = sx1 + getScreenDim(sd)->w << 3; + uint16 sy2 = sy1 + getScreenDim(sd)->h; + if (flags & 0x10) { + x += sx1; + y += sy1; + } + + int x1, x2; + if (x >= 0) { + x1 = 0; + if (x + scaledShapeWidth < sx2) { + x2 = scaledShapeWidth; + } else { + x2 = sx2 - x; + } + } else { + x2 = scaledShapeWidth; + x1 = -x; + x = 0; + if (x2 > sx2) { + x2 = sx2; + } + } + + int y1, y2; + if (y >= 0) { + y1 = 0; + if (y + scaledShapeHeight < sy2) { + y2 = scaledShapeHeight; + } else { + y2 = sy2 - y; + } + } else { + y2 = scaledShapeHeight; + y1 = -y; + y = 0; + if (y2 > sy2) { + y2 = sy2; + } + } + + uint8 *dst = getPagePtr(page) + y * 320 + x; + uint8 *dstStart = getPagePtr(page); + + int scaleYTable[200]; + for (y = y1; y < y2; ++y) { + scaleYTable[y] = (y << 8) / scale_h; + } + int scaleXTable[320]; + for (x = x1; x < x2; ++x) { + scaleXTable[x] = (x << 8) / scale_w; + } + + const uint8 *shapeBuffer = _decodeShapeBuffer; + if (flags & 0x02) { + shapeBuffer += shapeWidth * (shapeHeight - 1); + } + if (flags & 0x01) { + shapeBuffer += shapeWidth - 1; + } + + for (y = y1; y < y2; ++y) { + uint8 *dstNextLine = dst + 320; + int j = scaleYTable[y]; + if (flags & 0x02) { + j = -j; + } + for (x = x1; x < x2; ++x) { + int xpos = scaleXTable[x]; + if (flags & 0x01) + xpos = -xpos; + uint8 color = shapeBuffer[j * shapeWidth + xpos]; + if (color != 0) { + switch (ppc) { + case 0: + *dst = color; + break; + + case 4: + *dst = table2[color]; + break; + + case 8: { + int layer = _shapePages[0][dst - dstStart] & 7; + if (drawLayer > layer) + color = _shapePages[1][dst - dstStart]; + *dst = color; + } break; + + case 12: { + int layer = _shapePages[0][dst - dstStart] & 7; + if (drawLayer < layer) + color = _shapePages[1][dst - dstStart]; + else + color = table2[color]; + *dst = color; + } break; + + default: + warning("unhandled ppc: %d", ppc); + break; + } + } + ++dst; + } + dst = dstNextLine; + } + va_end(args); +} + +int Screen_v2::getRectSize(int w, int h) { + if (w > 320 || h > 200) + return 0; + return w*h; +} + +int Screen_v2::getLayer(int x, int y) { + if (x < 0) + x = 0; + else if (x >= 320) + x = 319; + if (y < 0) + y = 0; + else if (y >= 144) + y = 143; + + uint8 pixel = *(getCPagePtr(5) + y * 320 + x); + pixel &= 0x7F; + pixel >>= 3; + + if (pixel < 1) + pixel = 1; + else if (pixel > 15) + pixel = 15; + return pixel; +} + +bool Screen_v2::isMouseVisible() const { + return _mouseLockCount == 0; +} + } // end of namespace Kyra diff --git a/engines/kyra/screen_v2.h b/engines/kyra/screen_v2.h index e45d44d3ff..7912d6b999 100644 --- a/engines/kyra/screen_v2.h +++ b/engines/kyra/screen_v2.h @@ -11,7 +11,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License @@ -36,8 +36,47 @@ class Screen_v2 : public Screen { public: Screen_v2(KyraEngine_v2 *vm, OSystem *system); virtual ~Screen_v2(); + + virtual void setScreenDim(int dim); + const ScreenDim *getScreenDim(int dim); + + // palette handling + void k2IntroFadeToGrey(int delay=0x54); + + // screen page handling + void copyWsaRect(int x, int y, int w, int h, int dimState, int plotFunc, const uint8 *src, + int unk1, const uint8 *unkPtr1, const uint8 *unkPtr2); + + // shape handling + uint8 *getPtrToShape(uint8 *shpFile, int shape); + const uint8 *getPtrToShape(const uint8 *shpFile, int shape); + + int getShapeScaledWidth(const uint8 *shpFile, int scale); + int getShapeScaledHeight(const uint8 *shpFile, int scale); + + uint16 getShapeSize(const uint8 *shp); + + uint8 *makeShapeCopy(const uint8 *src, int index); + + void drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int sd, int flags, ...); + + // rect handling + virtual int getRectSize(int w, int h); + + // layer handling + int getLayer(int x, int y); + + // mouse handling + bool isMouseVisible() const; private: KyraEngine_v2 *_vm; + + static const ScreenDim _screenDimTable[]; + static const int _screenDimTableCount; + + // maybe subclass screen for kyra3 + static const ScreenDim _screenDimTableK3[]; + static const int _screenDimTableCountK3; }; } // End of namespace Kyra diff --git a/engines/kyra/script.cpp b/engines/kyra/script.cpp index b43cd3b471..739e92feda 100644 --- a/engines/kyra/script.cpp +++ b/engines/kyra/script.cpp @@ -40,64 +40,62 @@ namespace Kyra { ScriptHelper::ScriptHelper(KyraEngine *vm) : _vm(vm) { #define COMMAND(x) { &ScriptHelper::x, #x } - // now we create a list of all Command/Opcode procs and so static CommandEntry commandProcs[] = { // 0x00 - COMMAND(c1_jmpTo), - COMMAND(c1_setRetValue), - COMMAND(c1_pushRetOrPos), - COMMAND(c1_push), + COMMAND(cmd_jmpTo), + COMMAND(cmd_setRetValue), + COMMAND(cmd_pushRetOrPos), + COMMAND(cmd_push), // 0x04 - COMMAND(c1_push), - COMMAND(c1_pushReg), - COMMAND(c1_pushBPNeg), - COMMAND(c1_pushBPAdd), + COMMAND(cmd_push), + COMMAND(cmd_pushReg), + COMMAND(cmd_pushBPNeg), + COMMAND(cmd_pushBPAdd), // 0x08 - COMMAND(c1_popRetOrPos), - COMMAND(c1_popReg), - COMMAND(c1_popBPNeg), - COMMAND(c1_popBPAdd), + COMMAND(cmd_popRetOrPos), + COMMAND(cmd_popReg), + COMMAND(cmd_popBPNeg), + COMMAND(cmd_popBPAdd), // 0x0C - COMMAND(c1_addSP), - COMMAND(c1_subSP), - COMMAND(c1_execOpcode), - COMMAND(c1_ifNotJmp), + COMMAND(cmd_addSP), + COMMAND(cmd_subSP), + COMMAND(cmd_execOpcode), + COMMAND(cmd_ifNotJmp), // 0x10 - COMMAND(c1_negate), - COMMAND(c1_eval), - COMMAND(c1_setRetAndJmp) + COMMAND(cmd_negate), + COMMAND(cmd_eval), + COMMAND(cmd_setRetAndJmp) }; _commands = commandProcs; #undef COMMAND } bool ScriptHelper::loadScript(const char *filename, ScriptData *scriptData, const Common::Array<const Opcode*> *opcodes) { - uint32 size = 0; - uint8 *data = _vm->resource()->fileData(filename, &size); - const byte *curData = data; + ScriptFileParser file(filename, _vm->resource()); + if (!file) { + error("Couldn't open script file '%s'", filename); + return false; + } - uint32 formBlockSize = getFORMBlockSize(curData); + uint32 formBlockSize = file.getFORMBlockSize(); if (formBlockSize == (uint32)-1) { - delete [] data; error("No FORM chunk found in file: '%s'", filename); return false; } - uint32 chunkSize = getIFFBlockSize(data, curData, size, TEXT_CHUNK); + uint32 chunkSize = file.getIFFBlockSize(TEXT_CHUNK); if (chunkSize != (uint32)-1) { scriptData->text = new byte[chunkSize]; - if (!loadIFFBlock(data, curData, size, TEXT_CHUNK, scriptData->text, chunkSize)) { - delete [] data; + if (!file.loadIFFBlock(TEXT_CHUNK, scriptData->text, chunkSize)) { unloadScript(scriptData); error("Couldn't load TEXT chunk from file: '%s'", filename); return false; } } - chunkSize = getIFFBlockSize(data, curData, size, ORDR_CHUNK); + chunkSize = file.getIFFBlockSize(ORDR_CHUNK); if (chunkSize == (uint32)-1) { - delete [] data; unloadScript(scriptData); error("No ORDR chunk found in file: '%s'", filename); return false; @@ -106,8 +104,7 @@ bool ScriptHelper::loadScript(const char *filename, ScriptData *scriptData, cons scriptData->ordr = new uint16[chunkSize]; - if (!loadIFFBlock(data, curData, size, ORDR_CHUNK, scriptData->ordr, chunkSize << 1)) { - delete [] data; + if (!file.loadIFFBlock(ORDR_CHUNK, scriptData->ordr, chunkSize << 1)) { unloadScript(scriptData); error("Couldn't load ORDR chunk from file: '%s'", filename); return false; @@ -116,9 +113,8 @@ bool ScriptHelper::loadScript(const char *filename, ScriptData *scriptData, cons while (chunkSize--) scriptData->ordr[chunkSize] = READ_BE_UINT16(&scriptData->ordr[chunkSize]); - chunkSize = getIFFBlockSize(data, curData, size, DATA_CHUNK); + chunkSize = file.getIFFBlockSize(DATA_CHUNK); if (chunkSize == (uint32)-1) { - delete [] data; unloadScript(scriptData); error("No DATA chunk found in file: '%s'", filename); return false; @@ -127,8 +123,7 @@ bool ScriptHelper::loadScript(const char *filename, ScriptData *scriptData, cons scriptData->data = new uint16[chunkSize]; - if (!loadIFFBlock(data, curData, size, DATA_CHUNK, scriptData->data, chunkSize << 1)) { - delete [] data; + if (!file.loadIFFBlock(DATA_CHUNK, scriptData->data, chunkSize << 1)) { unloadScript(scriptData); error("Couldn't load DATA chunk from file: '%s'", filename); return false; @@ -139,8 +134,7 @@ bool ScriptHelper::loadScript(const char *filename, ScriptData *scriptData, cons scriptData->data[chunkSize] = READ_BE_UINT16(&scriptData->data[chunkSize]); scriptData->opcodes = opcodes; - - delete [] data; + return true; } @@ -172,10 +166,14 @@ bool ScriptHelper::startScript(ScriptState *script, int function) { if (functionOffset == 0xFFFF) return false; - if (_vm->gameFlags().platform == Common::kPlatformFMTowns) + if (_vm->game() == GI_KYRA1) { + if (_vm->gameFlags().platform == Common::kPlatformFMTowns) + script->ip = &script->dataPtr->data[functionOffset+1]; + else + script->ip = &script->dataPtr->data[functionOffset]; + } else { script->ip = &script->dataPtr->data[functionOffset+1]; - else - script->ip = &script->dataPtr->data[functionOffset]; + } return true; } @@ -217,37 +215,51 @@ bool ScriptHelper::runScript(ScriptState *script) { return _continue; } -uint32 ScriptHelper::getFORMBlockSize(const byte *&data) const { - static const uint32 chunkName = FORM_CHUNK; +#pragma mark - +#pragma mark - ScriptFileParser implementation +#pragma mark - + +void ScriptFileParser::setFile(const char *filename, Resource *res) { + destroy(); + + if (!res->getFileHandle(filename, &_endOffset, _scriptFile)) + return; + _startOffset = _scriptFile.pos(); + _endOffset += _startOffset; +} + +void ScriptFileParser::destroy() { + _scriptFile.close(); + _startOffset = _endOffset = 0; +} + +uint32 ScriptFileParser::getFORMBlockSize() { + uint32 oldOffset = _scriptFile.pos(); + + uint32 data = _scriptFile.readUint32LE(); - if (READ_LE_UINT32(data) != chunkName) + if (data != FORM_CHUNK) { + _scriptFile.seek(oldOffset); return (uint32)-1; + } - data += 4; - uint32 retValue = READ_BE_UINT32(data); data += 4; - return retValue; + data = _scriptFile.readUint32BE(); + return data; } -uint32 ScriptHelper::getIFFBlockSize(const byte *start, const byte *&data, uint32 maxSize, const uint32 chunkName) const { +uint32 ScriptFileParser::getIFFBlockSize(const uint32 chunkName) { uint32 size = (uint32)-1; - bool special = false; - if (data == (start + maxSize)) - data = start + 0x0C; + _scriptFile.seek(_startOffset + 0x0C); - while (data < (start + maxSize)) { - uint32 chunk = READ_LE_UINT32(data); data += 4; - uint32 size_temp = READ_BE_UINT32(data); data += 4; + while (_scriptFile.pos() < _endOffset) { + uint32 chunk = _scriptFile.readUint32LE(); + uint32 size_temp = _scriptFile.readUint32BE(); + if (chunk != chunkName) { - if (special) { - data += (size_temp + 1) & 0xFFFFFFFE; - } else { - data = start + 0x0C; - special = true; - } + _scriptFile.seek((size_temp + 1) & (~1), SEEK_CUR); + assert(_scriptFile.pos() <= _endOffset); } else { - // kill our data - data = start; size = size_temp; break; } @@ -256,32 +268,21 @@ uint32 ScriptHelper::getIFFBlockSize(const byte *start, const byte *&data, uint3 return size; } -bool ScriptHelper::loadIFFBlock(const byte *start, const byte *&data, uint32 maxSize, const uint32 chunkName, void *loadTo, uint32 ptrSize) const { - bool special = false; - - if (data == (start + maxSize)) - data = start + 0x0C; +bool ScriptFileParser::loadIFFBlock(const uint32 chunkName, void *loadTo, uint32 ptrSize) { + _scriptFile.seek(_startOffset + 0x0C); + + while (_scriptFile.pos() < _endOffset) { + uint32 chunk = _scriptFile.readUint32LE(); + uint32 chunkSize = _scriptFile.readUint32BE(); - while (data < (start + maxSize)) { - uint32 chunk = READ_LE_UINT32(data); data += 4; - uint32 chunkSize = READ_BE_UINT32(data); data += 4; if (chunk != chunkName) { - if (special) { - data += (chunkSize + 1) & 0xFFFFFFFE; - } else { - data = start + 0x0C; - special = true; - } + _scriptFile.seek((chunkSize + 1) & (~1), SEEK_CUR); + assert(_scriptFile.pos() <= _endOffset); } else { uint32 loadSize = 0; - if (chunkSize < ptrSize) - loadSize = chunkSize; - else - loadSize = ptrSize; - memcpy(loadTo, data, loadSize); - chunkSize = (chunkSize + 1) & 0xFFFFFFFE; - if (chunkSize > loadSize) - data += (chunkSize - loadSize); + + loadSize = MIN(ptrSize, chunkSize); + _scriptFile.read(loadTo, loadSize); return true; } } @@ -293,15 +294,15 @@ bool ScriptHelper::loadIFFBlock(const byte *start, const byte *&data, uint32 max #pragma mark - Command implementations #pragma mark - -void ScriptHelper::c1_jmpTo(ScriptState* script) { +void ScriptHelper::cmd_jmpTo(ScriptState* script) { script->ip = script->dataPtr->data + _parameter; } -void ScriptHelper::c1_setRetValue(ScriptState* script) { +void ScriptHelper::cmd_setRetValue(ScriptState* script) { script->retValue = _parameter; } -void ScriptHelper::c1_pushRetOrPos(ScriptState* script) { +void ScriptHelper::cmd_pushRetOrPos(ScriptState* script) { switch (_parameter) { case 0: script->stack[--script->sp] = script->retValue; @@ -320,23 +321,23 @@ void ScriptHelper::c1_pushRetOrPos(ScriptState* script) { } } -void ScriptHelper::c1_push(ScriptState* script) { +void ScriptHelper::cmd_push(ScriptState* script) { script->stack[--script->sp] = _parameter; } -void ScriptHelper::c1_pushReg(ScriptState* script) { +void ScriptHelper::cmd_pushReg(ScriptState* script) { script->stack[--script->sp] = script->regs[_parameter]; } -void ScriptHelper::c1_pushBPNeg(ScriptState* script) { +void ScriptHelper::cmd_pushBPNeg(ScriptState* script) { script->stack[--script->sp] = script->stack[(-(int32)(_parameter + 2)) + script->bp]; } -void ScriptHelper::c1_pushBPAdd(ScriptState* script) { +void ScriptHelper::cmd_pushBPAdd(ScriptState* script) { script->stack[--script->sp] = script->stack[(_parameter - 1) + script->bp]; } -void ScriptHelper::c1_popRetOrPos(ScriptState* script) { +void ScriptHelper::cmd_popRetOrPos(ScriptState* script) { switch (_parameter) { case 0: script->retValue = script->stack[script->sp++]; @@ -359,48 +360,48 @@ void ScriptHelper::c1_popRetOrPos(ScriptState* script) { } } -void ScriptHelper::c1_popReg(ScriptState* script) { +void ScriptHelper::cmd_popReg(ScriptState* script) { script->regs[_parameter] = script->stack[script->sp++]; } -void ScriptHelper::c1_popBPNeg(ScriptState* script) { +void ScriptHelper::cmd_popBPNeg(ScriptState* script) { script->stack[(-(int32)(_parameter + 2)) + script->bp] = script->stack[script->sp++]; } -void ScriptHelper::c1_popBPAdd(ScriptState* script) { +void ScriptHelper::cmd_popBPAdd(ScriptState* script) { script->stack[(_parameter - 1) + script->bp] = script->stack[script->sp++]; } -void ScriptHelper::c1_addSP(ScriptState* script) { +void ScriptHelper::cmd_addSP(ScriptState* script) { script->sp += _parameter; } -void ScriptHelper::c1_subSP(ScriptState* script) { +void ScriptHelper::cmd_subSP(ScriptState* script) { script->sp -= _parameter; } -void ScriptHelper::c1_execOpcode(ScriptState* script) { +void ScriptHelper::cmd_execOpcode(ScriptState* script) { uint8 opcode = _parameter; assert(script->dataPtr->opcodes); assert(opcode < script->dataPtr->opcodes->size()); - if ((*script->dataPtr->opcodes)[opcode]) { + if ((*script->dataPtr->opcodes)[opcode] && *(*script->dataPtr->opcodes)[opcode]) { script->retValue = (*(*script->dataPtr->opcodes)[opcode])(script); } else { script->retValue = 0; - warning("calling unimplemented opcode(0x%.02X)", opcode); + warning("calling unimplemented opcode(0x%.02X/%d)", opcode, opcode); } } -void ScriptHelper::c1_ifNotJmp(ScriptState* script) { +void ScriptHelper::cmd_ifNotJmp(ScriptState* script) { if (!script->stack[script->sp++]) { _parameter &= 0x7FFF; script->ip = script->dataPtr->data + _parameter; } } -void ScriptHelper::c1_negate(ScriptState* script) { +void ScriptHelper::cmd_negate(ScriptState* script) { int16 value = script->stack[script->sp]; switch (_parameter) { case 0: @@ -424,7 +425,7 @@ void ScriptHelper::c1_negate(ScriptState* script) { } } -void ScriptHelper::c1_eval(ScriptState* script) { +void ScriptHelper::cmd_eval(ScriptState* script) { int16 ret = 0; bool error = false; @@ -542,7 +543,7 @@ void ScriptHelper::c1_eval(ScriptState* script) { } } -void ScriptHelper::c1_setRetAndJmp(ScriptState* script) { +void ScriptHelper::cmd_setRetAndJmp(ScriptState* script) { if (script->sp >= 60) { _continue = false; script->ip = 0; diff --git a/engines/kyra/script.h b/engines/kyra/script.h index 5e43039110..3396712a24 100644 --- a/engines/kyra/script.h +++ b/engines/kyra/script.h @@ -27,33 +27,11 @@ #define KYRA_SCRIPT_H #include "kyra/kyra.h" +#include "kyra/util.h" -namespace Kyra { - -struct ScriptState; - -struct Opcode { - virtual ~Opcode() {} - - virtual operator bool() const = 0; - - virtual int operator()(ScriptState*) const = 0; -}; +#include "common/file.h" -template<class T> -struct OpcodeImpl : public Opcode { - T *vm; - typedef int (T::*Callback)(ScriptState*); - Callback callback; - - OpcodeImpl(T *v, Callback c) : Opcode(), vm(v), callback(c) {} - - operator bool() const { return callback != 0; } - - int operator()(ScriptState *state) const { - return (vm->*callback)(state); - } -}; +namespace Kyra { struct ScriptData { byte *text; @@ -74,6 +52,31 @@ struct ScriptState { int16 stack[61]; // VM stack }; +#define stackPos(x) script->stack[script->sp+x] +#define stackPosString(x) (const char*)&script->dataPtr->text[READ_BE_UINT16(&((uint16 *)script->dataPtr->text)[stackPos(x)])] + +class ScriptFileParser { +public: + ScriptFileParser() : _scriptFile(), _startOffset(0), _endOffset(0) {} + ScriptFileParser(const char *filename, Resource *res) : _scriptFile(), _startOffset(0), _endOffset(0) { setFile(filename, res); } + ~ScriptFileParser() { destroy(); } + + // 'script' must be allocated with new! + void setFile(const char *filename, Resource *res); + + operator bool() const { return (_startOffset != _endOffset) && _scriptFile.isOpen(); } + + uint32 getFORMBlockSize(); + uint32 getIFFBlockSize(const uint32 chunk); + bool loadIFFBlock(const uint32 chunk, void *loadTo, uint32 ptrSize); +private: + void destroy(); + + Common::File _scriptFile; + uint32 _startOffset; + uint32 _endOffset; +}; + class ScriptHelper { public: ScriptHelper(KyraEngine *vm); @@ -88,10 +91,6 @@ public: bool runScript(ScriptState *script); protected: - uint32 getFORMBlockSize(const byte *&data) const; - uint32 getIFFBlockSize(const byte *start, const byte *&data, uint32 maxSize, const uint32 chunk) const; - bool loadIFFBlock(const byte *start, const byte *&data, uint32 maxSize, const uint32 chunk, void *loadTo, uint32 ptrSize) const; - KyraEngine *_vm; int16 _parameter; bool _continue; @@ -104,25 +103,24 @@ protected: const CommandEntry *_commands; private: - void c1_jmpTo(ScriptState*); - void c1_setRetValue(ScriptState*); - void c1_pushRetOrPos(ScriptState*); - void c1_push(ScriptState*); - //void c1_push(); same as 03 - void c1_pushReg(ScriptState*); - void c1_pushBPNeg(ScriptState*); - void c1_pushBPAdd(ScriptState*); - void c1_popRetOrPos(ScriptState*); - void c1_popReg(ScriptState*); - void c1_popBPNeg(ScriptState*); - void c1_popBPAdd(ScriptState*); - void c1_addSP(ScriptState*); - void c1_subSP(ScriptState*); - void c1_execOpcode(ScriptState*); - void c1_ifNotJmp(ScriptState*); - void c1_negate(ScriptState*); - void c1_eval(ScriptState*); - void c1_setRetAndJmp(ScriptState*); + void cmd_jmpTo(ScriptState*); + void cmd_setRetValue(ScriptState*); + void cmd_pushRetOrPos(ScriptState*); + void cmd_push(ScriptState*); + void cmd_pushReg(ScriptState*); + void cmd_pushBPNeg(ScriptState*); + void cmd_pushBPAdd(ScriptState*); + void cmd_popRetOrPos(ScriptState*); + void cmd_popReg(ScriptState*); + void cmd_popBPNeg(ScriptState*); + void cmd_popBPAdd(ScriptState*); + void cmd_addSP(ScriptState*); + void cmd_subSP(ScriptState*); + void cmd_execOpcode(ScriptState*); + void cmd_ifNotJmp(ScriptState*); + void cmd_negate(ScriptState*); + void cmd_eval(ScriptState*); + void cmd_setRetAndJmp(ScriptState*); }; } // end of namespace Kyra diff --git a/engines/kyra/script_v1.cpp b/engines/kyra/script_v1.cpp index 14edf5fff8..bd776e2046 100644 --- a/engines/kyra/script_v1.cpp +++ b/engines/kyra/script_v1.cpp @@ -25,6 +25,8 @@ #include "common/stdafx.h" #include "common/endian.h" +#include "common/system.h" + #include "kyra/kyra_v1.h" #include "kyra/script.h" #include "kyra/screen.h" @@ -32,14 +34,11 @@ #include "kyra/wsamovie.h" #include "kyra/animator_v1.h" #include "kyra/text.h" -#include "common/system.h" +#include "kyra/timer.h" namespace Kyra { -#define stackPos(x) script->stack[script->sp+x] -#define stackPosString(x) (const char*)&script->dataPtr->text[READ_BE_UINT16(&((uint16 *)script->dataPtr->text)[stackPos(x)])] - int KyraEngine_v1::o1_magicInMouseItem(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_magicInMouseItem(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1magicInMouseItem(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); magicInMouseItem(stackPos(0), stackPos(1), -1); return 0; } @@ -47,10 +46,10 @@ int KyraEngine_v1::o1_magicInMouseItem(ScriptState *script) { int KyraEngine_v1::o1_characterSays(ScriptState *script) { _skipFlag = false; if (_flags.isTalkie) { - debugC(3, kDebugLevelScriptFuncs, "o1_characterSays(%p) (%d, '%s', %d, %d)", (const void *)script, stackPos(0), stackPosString(1), stackPos(2), stackPos(3)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1characterSays(%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, "o1_characterSays(%p) ('%s', %d, %d)", (const void *)script, stackPosString(0), stackPos(1), stackPos(2)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1characterSays(%p) ('%s', %d, %d)", (const void *)script, stackPosString(0), stackPos(1), stackPos(2)); const char *string = stackPosString(0); if (_flags.platform == Common::kPlatformFMTowns && _flags.lang == Common::JA_JPN) { @@ -76,7 +75,7 @@ int KyraEngine_v1::o1_characterSays(ScriptState *script) { } int KyraEngine_v1::o1_pauseTicks(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_pauseTicks(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1pauseTicks(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); if (stackPos(1)) { warning("STUB: special o1_pauseTicks"); // delete this after correct implementing @@ -88,23 +87,23 @@ int KyraEngine_v1::o1_pauseTicks(ScriptState *script) { } int KyraEngine_v1::o1_drawSceneAnimShape(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_drawSceneAnimShape(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1drawSceneAnimShape(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); _screen->drawShape(stackPos(4), _sprites->_sceneShapes[stackPos(0)], stackPos(1), stackPos(2), 0, (stackPos(3) != 0) ? 1 : 0); return 0; } int KyraEngine_v1::o1_queryGameFlag(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_queryGameFlag(%p) (0x%X)", (const void *)script, stackPos(0)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1queryGameFlag(%p) (0x%X)", (const void *)script, stackPos(0)); return queryGameFlag(stackPos(0)); } int KyraEngine_v1::o1_setGameFlag(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_setGameFlag(%p) (0x%X)", (const void *)script, stackPos(0)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1setGameFlag(%p) (0x%X)", (const void *)script, stackPos(0)); return setGameFlag(stackPos(0)); } int KyraEngine_v1::o1_resetGameFlag(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_resetGameFlag(%p) (0x%X)", (const void *)script, stackPos(0)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1resetGameFlag(%p) (0x%X)", (const void *)script, stackPos(0)); return resetGameFlag(stackPos(0)); } @@ -114,7 +113,7 @@ int KyraEngine_v1::o1_runNPCScript(ScriptState *script) { } int KyraEngine_v1::o1_setSpecialExitList(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "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)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1setSpecialExitList(%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); @@ -124,33 +123,33 @@ int KyraEngine_v1::o1_setSpecialExitList(ScriptState *script) { } int KyraEngine_v1::o1_blockInWalkableRegion(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_blockInWalkableRegion(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1blockInWalkableRegion(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); _screen->blockInRegion(stackPos(0), stackPos(1), stackPos(2)-stackPos(0)+1, stackPos(3)-stackPos(1)+1); return 0; } int KyraEngine_v1::o1_blockOutWalkableRegion(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_blockOutWalkableRegion(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1blockOutWalkableRegion(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); _screen->blockOutRegion(stackPos(0), stackPos(1), stackPos(2)-stackPos(0)+1, stackPos(3)-stackPos(1)+1); return 0; } int KyraEngine_v1::o1_walkPlayerToPoint(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_walkPlayerToPoint(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1walkPlayerToPoint(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); int normalTimers = stackPos(2); if (!normalTimers) { - disableTimer(19); - disableTimer(14); - disableTimer(18); + _timer->disable(19); + _timer->disable(14); + _timer->disable(18); } int reinitScript = handleSceneChange(stackPos(0), stackPos(1), stackPos(2), stackPos(3)); if (!normalTimers) { - enableTimer(19); - enableTimer(14); - enableTimer(18); + _timer->enable(19); + _timer->enable(14); + _timer->enable(18); } if (reinitScript) @@ -164,7 +163,7 @@ int KyraEngine_v1::o1_walkPlayerToPoint(ScriptState *script) { } int KyraEngine_v1::o1_dropItemInScene(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_dropItemInScene(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1dropItemInScene(%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); @@ -189,7 +188,7 @@ int KyraEngine_v1::o1_dropItemInScene(ScriptState *script) { } int KyraEngine_v1::o1_drawAnimShapeIntoScene(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_drawAnimShapeIntoScene(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1drawAnimShapeIntoScene(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); _screen->hideMouse(); _animator->restoreAllObjectBackgrounds(); int shape = stackPos(0); @@ -207,49 +206,49 @@ int KyraEngine_v1::o1_drawAnimShapeIntoScene(ScriptState *script) { } int KyraEngine_v1::o1_createMouseItem(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_createMouseItem(%p) (%d)", (const void *)script, stackPos(0)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1createMouseItem(%p) (%d)", (const void *)script, stackPos(0)); createMouseItem(stackPos(0)); return 0; } int KyraEngine_v1::o1_savePageToDisk(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_savePageToDisk(%p) ('%s', %d)", (const void *)script, stackPosString(0), stackPos(1)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1savePageToDisk(%p) ('%s', %d)", (const void *)script, stackPosString(0), stackPos(1)); _screen->savePageToDisk(stackPosString(0), stackPos(1)); return 0; } int KyraEngine_v1::o1_sceneAnimOn(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_sceneAnimOn(%p) (%d)", (const void *)script, stackPos(0)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1sceneAnimOn(%p) (%d)", (const void *)script, stackPos(0)); _sprites->_anims[stackPos(0)].play = true; return 0; } int KyraEngine_v1::o1_sceneAnimOff(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_sceneAnimOff(%p) (%d)", (const void *)script, stackPos(0)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1sceneAnimOff(%p) (%d)", (const void *)script, stackPos(0)); _sprites->_anims[stackPos(0)].play = false; return 0; } int KyraEngine_v1::o1_getElapsedSeconds(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_getElapsedSeconds(%p) ()", (const void *)script); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1getElapsedSeconds(%p) ()", (const void *)script); return _system->getMillis() / 1000; } int KyraEngine_v1::o1_mouseIsPointer(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_mouseIsPointer(%p) ()", (const void *)script); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1mouseIsPointer(%p) ()", (const void *)script); if (_itemInHand == -1) return 1; return 0; } int KyraEngine_v1::o1_destroyMouseItem(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_destroyMouseItem(%p) ()", (const void *)script); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1destroyMouseItem(%p) ()", (const void *)script); destroyMouseItem(); return 0; } int KyraEngine_v1::o1_runSceneAnimUntilDone(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_runSceneAnimUntilDone(%p) (%d)", (const void *)script, stackPos(0)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1runSceneAnimUntilDone(%p) (%d)", (const void *)script, stackPos(0)); _screen->hideMouse(); _animator->restoreAllObjectBackgrounds(); _sprites->_anims[stackPos(0)].play = true; @@ -268,59 +267,59 @@ int KyraEngine_v1::o1_runSceneAnimUntilDone(ScriptState *script) { int KyraEngine_v1::o1_fadeSpecialPalette(ScriptState *script) { if (_flags.platform == Common::kPlatformAmiga) { - debugC(3, kDebugLevelScriptFuncs, "o1_fadeSpecialPalette(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1fadeSpecialPalette(%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("o1_fadeSpecialPalette not implemented"); + warning("KyraEngine_v1::o1fadeSpecialPalette not implemented"); } } else { - debugC(3, kDebugLevelScriptFuncs, "o1_fadeSpecialPalette(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1fadeSpecialPalette(%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(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_playAdlibSound(%p) (%d)", (const void *)script, stackPos(0)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1playAdlibSound(%p) (%d)", (const void *)script, stackPos(0)); snd_playSoundEffect(stackPos(0)); return 0; } int KyraEngine_v1::o1_playAdlibScore(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_playAdlibScore(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1playAdlibScore(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); snd_playWanderScoreViaMap(stackPos(0), stackPos(1)); return 0; } int KyraEngine_v1::o1_phaseInSameScene(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_phaseInSameScene(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1phaseInSameScene(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); transcendScenes(stackPos(0), stackPos(1)); return 0; } int KyraEngine_v1::o1_setScenePhasingFlag(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_setScenePhasingFlag(%p) ()", (const void *)script); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1setScenePhasingFlag(%p) ()", (const void *)script); _scenePhasingFlag = 1; return 1; } int KyraEngine_v1::o1_resetScenePhasingFlag(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_resetScenePhasingFlag(%p) ()", (const void *)script); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1resetScenePhasingFlag(%p) ()", (const void *)script); _scenePhasingFlag = 0; return 0; } int KyraEngine_v1::o1_queryScenePhasingFlag(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_queryScenePhasingFlag(%p) ()", (const void *)script); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1queryScenePhasingFlag(%p) ()", (const void *)script); return _scenePhasingFlag; } int KyraEngine_v1::o1_sceneToDirection(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_sceneToDirection(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1sceneToDirection(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); assert(stackPos(0) < _roomTableSize); Room *curRoom = &_roomTable[stackPos(0)]; uint16 returnValue = 0xFFFF; @@ -350,7 +349,7 @@ int KyraEngine_v1::o1_sceneToDirection(ScriptState *script) { } int KyraEngine_v1::o1_setBirthstoneGem(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_setBirthstoneGem(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1setBirthstoneGem(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); int index = stackPos(0); if (index < 4 && index >= 0) { _birthstoneGemTable[index] = stackPos(1); @@ -360,19 +359,19 @@ int KyraEngine_v1::o1_setBirthstoneGem(ScriptState *script) { } int KyraEngine_v1::o1_placeItemInGenericMapScene(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_placeItemInGenericMapScene(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1placeItemInGenericMapScene(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); placeItemInGenericMapScene(stackPos(0), stackPos(1)); return 0; } int KyraEngine_v1::o1_setBrandonStatusBit(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_setBrandonStatusBit(%p) (%d)", (const void *)script, stackPos(0)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1setBrandonStatusBit(%p) (%d)", (const void *)script, stackPos(0)); _brandonStatusBit |= stackPos(0); return 0; } int KyraEngine_v1::o1_pauseSeconds(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_pauseSeconds(%p) (%d)", (const void *)script, stackPos(0)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1pauseSeconds(%p) (%d)", (const void *)script, stackPos(0)); if (stackPos(0) > 0 && !_skipFlag) delay(stackPos(0)*1000, true); _skipFlag = false; @@ -380,7 +379,7 @@ int KyraEngine_v1::o1_pauseSeconds(ScriptState *script) { } int KyraEngine_v1::o1_getCharactersLocation(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_getCharactersLocation(%p) (%d)", (const void *)script, stackPos(0)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1getCharactersLocation(%p) (%d)", (const void *)script, stackPos(0)); return _characterList[stackPos(0)].sceneId; } @@ -390,31 +389,31 @@ int KyraEngine_v1::o1_runNPCSubscript(ScriptState *script) { } int KyraEngine_v1::o1_magicOutMouseItem(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_magicOutMouseItem(%p) (%d)", (const void *)script, stackPos(0)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1magicOutMouseItem(%p) (%d)", (const void *)script, stackPos(0)); magicOutMouseItem(stackPos(0), -1); return 0; } int KyraEngine_v1::o1_internalAnimOn(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_internalAnimOn(%p) (%d)", (const void *)script, stackPos(0)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1internalAnimOn(%p) (%d)", (const void *)script, stackPos(0)); _animator->sprites()[stackPos(0)].active = 1; return 0; } int KyraEngine_v1::o1_forceBrandonToNormal(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_forceBrandonToNormal(%p) ()", (const void *)script); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1forceBrandonToNormal(%p) ()", (const void *)script); checkAmuletAnimFlags(); return 0; } int KyraEngine_v1::o1_poisonDeathNow(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_poisonDeathNow(%p) ()", (const void *)script); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1poisonDeathNow(%p) ()", (const void *)script); seq_poisonDeathNow(1); return 0; } int KyraEngine_v1::o1_setScaleMode(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_setScaleMode(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1setScaleMode(%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); @@ -432,7 +431,7 @@ int KyraEngine_v1::o1_setScaleMode(ScriptState *script) { } int KyraEngine_v1::o1_openWSAFile(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_openWSAFile(%p) ('%s', %d, %d, %d)", (const void *)script, stackPosString(0), stackPos(1), stackPos(2), stackPos(3)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1openWSAFile(%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); @@ -444,7 +443,7 @@ int KyraEngine_v1::o1_openWSAFile(ScriptState *script) { } int KyraEngine_v1::o1_closeWSAFile(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_closeWSAFile(%p) (%d)", (const void *)script, stackPos(0)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1closeWSAFile(%p) (%d)", (const void *)script, stackPos(0)); int wsaIndex = stackPos(0); if (_movieObjects[wsaIndex]) @@ -454,7 +453,7 @@ int KyraEngine_v1::o1_closeWSAFile(ScriptState *script) { } int KyraEngine_v1::o1_runWSAFromBeginningToEnd(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_runWSAFromBeginningToEnd(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1runWSAFromBeginningToEnd(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); _screen->hideMouse(); @@ -495,7 +494,7 @@ int KyraEngine_v1::o1_runWSAFromBeginningToEnd(ScriptState *script) { } int KyraEngine_v1::o1_displayWSAFrame(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_displayWSAFrame(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1displayWSAFrame(%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); @@ -522,13 +521,13 @@ int KyraEngine_v1::o1_displayWSAFrame(ScriptState *script) { } int KyraEngine_v1::o1_enterNewScene(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_enterNewScene(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1enterNewScene(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); enterNewScene(stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); return 0; } int KyraEngine_v1::o1_setSpecialEnterXAndY(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_setSpecialEnterXAndY(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1setSpecialEnterXAndY(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); _brandonPosX = stackPos(0); _brandonPosY = stackPos(1); if (_brandonPosX + 1 == 0 && _brandonPosY + 1 == 0) @@ -537,7 +536,7 @@ int KyraEngine_v1::o1_setSpecialEnterXAndY(ScriptState *script) { } int KyraEngine_v1::o1_runWSAFrames(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_runWSAFrames(%p) (%d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1runWSAFrames(%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); @@ -564,7 +563,7 @@ int KyraEngine_v1::o1_runWSAFrames(ScriptState *script) { } int KyraEngine_v1::o1_popBrandonIntoScene(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_popBrandonIntoScene(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1popBrandonIntoScene(%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); @@ -613,7 +612,7 @@ int KyraEngine_v1::o1_popBrandonIntoScene(ScriptState *script) { } int KyraEngine_v1::o1_restoreAllObjectBackgrounds(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_restoreAllObjectBackgrounds(%p) (%d)", (const void *)script, stackPos(0)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1restoreAllObjectBackgrounds(%p) (%d)", (const void *)script, stackPos(0)); int disable = stackPos(0); int activeBackup = 0; if (disable) { @@ -627,13 +626,13 @@ int KyraEngine_v1::o1_restoreAllObjectBackgrounds(ScriptState *script) { } int KyraEngine_v1::o1_setCustomPaletteRange(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_setCustomPaletteRange(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1setCustomPaletteRange(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); memcpy(_screen->getPalette(1) + stackPos(1)*3, _specialPalettes[stackPos(0)], stackPos(2)*3); return 0; } int KyraEngine_v1::o1_loadPageFromDisk(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_loadPageFromDisk(%p) ('%s', %d)", (const void *)script, stackPosString(0), stackPos(1)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1loadPageFromDisk(%p) ('%s', %d)", (const void *)script, stackPosString(0), stackPos(1)); _screen->loadPageFromDisk(stackPosString(0), stackPos(1)); _animator->_updateScreen = true; return 0; @@ -641,7 +640,7 @@ int KyraEngine_v1::o1_loadPageFromDisk(ScriptState *script) { int KyraEngine_v1::o1_customPrintTalkString(ScriptState *script) { if (_flags.isTalkie) { - debugC(3, kDebugLevelScriptFuncs, "o1_customPrintTalkString(%p) (%d, '%s', %d, %d, %d)", (const void *)script, stackPos(0), stackPosString(1), stackPos(2), stackPos(3), stackPos(4) & 0xFF); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1customPrintTalkString(%p) (%d, '%s', %d, %d, %d)", (const void *)script, stackPos(0), stackPosString(1), stackPos(2), stackPos(3), stackPos(4) & 0xFF); if (speechEnabled()) { snd_voiceWaitForFinish(); @@ -651,7 +650,7 @@ int KyraEngine_v1::o1_customPrintTalkString(ScriptState *script) { if (textEnabled()) _text->printTalkTextMessage(stackPosString(1), stackPos(2), stackPos(3), stackPos(4) & 0xFF, 0, 2); } else { - debugC(3, kDebugLevelScriptFuncs, "o1_customPrintTalkString(%p) ('%s', %d, %d, %d)", (const void *)script, stackPosString(0), stackPos(1), stackPos(2), stackPos(3) & 0xFF); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1customPrintTalkString(%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); } @@ -660,7 +659,7 @@ int KyraEngine_v1::o1_customPrintTalkString(ScriptState *script) { } int KyraEngine_v1::o1_restoreCustomPrintBackground(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_restoreCustomPrintBackground(%p) ()", (const void *)script); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1restoreCustomPrintBackground(%p) ()", (const void *)script); snd_voiceWaitForFinish(); snd_stopVoice(); _text->restoreTalkTextMessageBkgd(2, 0); @@ -668,29 +667,29 @@ int KyraEngine_v1::o1_restoreCustomPrintBackground(ScriptState *script) { } int KyraEngine_v1::o1_hideMouse(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_hideMouse(%p) ()", (const void *)script); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1hideMouse(%p) ()", (const void *)script); _screen->hideMouse(); return 0; } int KyraEngine_v1::o1_showMouse(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_showMouse(%p) ()", (const void *)script); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1showMouse(%p) ()", (const void *)script); _screen->showMouse(); return 0; } int KyraEngine_v1::o1_getCharacterX(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_getCharacterX(%p) (%d)", (const void *)script, stackPos(0)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1getCharacterX(%p) (%d)", (const void *)script, stackPos(0)); return _characterList[stackPos(0)].x1; } int KyraEngine_v1::o1_getCharacterY(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_getCharacterY(%p) (%d)", (const void *)script, stackPos(0)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1getCharacterY(%p) (%d)", (const void *)script, stackPos(0)); return _characterList[stackPos(0)].y1; } int KyraEngine_v1::o1_changeCharactersFacing(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_changeCharactersFacing(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1changeCharactersFacing(%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); @@ -708,7 +707,7 @@ int KyraEngine_v1::o1_changeCharactersFacing(ScriptState *script) { } int KyraEngine_v1::o1_copyWSARegion(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_copyWSARegion(%p) (%d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1copyWSARegion(%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); @@ -721,7 +720,7 @@ int KyraEngine_v1::o1_copyWSARegion(ScriptState *script) { } int KyraEngine_v1::o1_printText(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_printText(%p) ('%s', %d, %d, 0x%X, 0x%X)", (const void *)script, stackPosString(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1printText(%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 @@ -731,7 +730,7 @@ int KyraEngine_v1::o1_printText(ScriptState *script) { } int KyraEngine_v1::o1_random(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_random(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1random(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); assert(stackPos(0) < stackPos(1)); return _rnd.getRandomNumberRng(stackPos(0), stackPos(1)); } @@ -742,7 +741,7 @@ int KyraEngine_v1::o1_loadSoundFile(ScriptState *script) { } int KyraEngine_v1::o1_displayWSAFrameOnHidPage(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_displayWSAFrameOnHidPage(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1displayWSAFrameOnHidPage(%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); @@ -771,7 +770,7 @@ int KyraEngine_v1::o1_displayWSAFrameOnHidPage(ScriptState *script) { } int KyraEngine_v1::o1_displayWSASequentialFrames(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "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)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1displayWSASequentialFrames(%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); @@ -847,7 +846,7 @@ int KyraEngine_v1::o1_displayWSASequentialFrames(ScriptState *script) { } int KyraEngine_v1::o1_drawCharacterStanding(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_drawCharacterStanding(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1drawCharacterStanding(%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); @@ -862,13 +861,13 @@ int KyraEngine_v1::o1_drawCharacterStanding(ScriptState *script) { } int KyraEngine_v1::o1_internalAnimOff(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_internalAnimOff(%p) (%d)", (const void *)script, stackPos(0)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1internalAnimOff(%p) (%d)", (const void *)script, stackPos(0)); _animator->sprites()[stackPos(0)].active = 0; return 0; } int KyraEngine_v1::o1_changeCharactersXAndY(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_changeCharactersXAndY(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1changeCharactersXAndY(%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); @@ -884,25 +883,25 @@ int KyraEngine_v1::o1_changeCharactersXAndY(ScriptState *script) { } int KyraEngine_v1::o1_clearSceneAnimatorBeacon(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_clearSceneAnimatorBeacon(%p) ()", (const void *)script); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1clearSceneAnimatorBeacon(%p) ()", (const void *)script); _sprites->_sceneAnimatorBeaconFlag = 0; return 0; } int KyraEngine_v1::o1_querySceneAnimatorBeacon(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_querySceneAnimatorBeacon(%p) ()", (const void *)script); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1querySceneAnimatorBeacon(%p) ()", (const void *)script); return _sprites->_sceneAnimatorBeaconFlag; } int KyraEngine_v1::o1_refreshSceneAnimator(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_refreshSceneAnimator(%p) ()", (const void *)script); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1refreshSceneAnimator(%p) ()", (const void *)script); _sprites->updateSceneAnims(); _animator->updateAllObjectShapes(); return 0; } int KyraEngine_v1::o1_placeItemInOffScene(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_placeItemInOffScene(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1placeItemInOffScene(%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); @@ -921,7 +920,7 @@ int KyraEngine_v1::o1_placeItemInOffScene(ScriptState *script) { } int KyraEngine_v1::o1_wipeDownMouseItem(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_wipeDownMouseItem(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1wipeDownMouseItem(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); _screen->hideMouse(); wipeDownMouseItem(stackPos(1), stackPos(2)); destroyMouseItem(); @@ -930,7 +929,7 @@ int KyraEngine_v1::o1_wipeDownMouseItem(ScriptState *script) { } int KyraEngine_v1::o1_placeCharacterInOtherScene(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_placeCharacterInOtherScene(%p) (%d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1placeCharacterInOtherScene(%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); @@ -947,7 +946,7 @@ int KyraEngine_v1::o1_placeCharacterInOtherScene(ScriptState *script) { } int KyraEngine_v1::o1_getKey(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_getKey(%p) ()", (const void *)script); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1getKey(%p) ()", (const void *)script); waitForEvent(); return 0; } @@ -958,7 +957,7 @@ int KyraEngine_v1::o1_specificItemInInventory(ScriptState *script) { } int KyraEngine_v1::o1_popMobileNPCIntoScene(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "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)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1popMobileNPCIntoScene(%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); @@ -994,7 +993,7 @@ int KyraEngine_v1::o1_unhideMobileCharacter(ScriptState *script) { } int KyraEngine_v1::o1_setCharactersLocation(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_setCharactersLocation(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1setCharactersLocation(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); Character *ch = &_characterList[stackPos(0)]; AnimObject *animObj = &_animator->actors()[stackPos(0)]; int newScene = stackPos(1); @@ -1011,7 +1010,7 @@ int KyraEngine_v1::o1_setCharactersLocation(ScriptState *script) { } int KyraEngine_v1::o1_walkCharacterToPoint(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_walkCharacterToPoint(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1walkCharacterToPoint(%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); @@ -1078,11 +1077,11 @@ int KyraEngine_v1::o1_walkCharacterToPoint(ScriptState *script) { setCharacterPosition(character, 0); ++curPos; - nextFrame = getTimerDelay(5 + character) * _tickLength + _system->getMillis(); + nextFrame = _timer->getDelay(5 + character) * _tickLength + _system->getMillis(); while (_system->getMillis() < nextFrame) { _sprites->updateSceneAnims(); updateMousePointer(); - updateGameTimers(); + _timer->update(); _animator->updateAllObjectShapes(); updateTextFade(); if ((nextFrame - _system->getMillis()) >= 10) @@ -1093,7 +1092,7 @@ int KyraEngine_v1::o1_walkCharacterToPoint(ScriptState *script) { } int KyraEngine_v1::o1_specialEventDisplayBrynnsNote(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_specialEventDisplayBrynnsNote(%p) ()", (const void *)script); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1specialEventDisplayBrynnsNote(%p) ()", (const void *)script); _screen->hideMouse(); _screen->savePageToDisk("HIDPAGE.TMP", 2); _screen->savePageToDisk("SEENPAGE.TMP", 0); @@ -1115,7 +1114,7 @@ int KyraEngine_v1::o1_specialEventDisplayBrynnsNote(ScriptState *script) { } int KyraEngine_v1::o1_specialEventRemoveBrynnsNote(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_specialEventRemoveBrynnsNote(%p) ()", (const void *)script); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1specialEventRemoveBrynnsNote(%p) ()", (const void *)script); _screen->hideMouse(); _screen->loadPageFromDisk("SEENPAGE.TMP", 0); _screen->loadPageFromDisk("HIDPAGE.TMP", 2); @@ -1126,13 +1125,13 @@ int KyraEngine_v1::o1_specialEventRemoveBrynnsNote(ScriptState *script) { } int KyraEngine_v1::o1_setLogicPage(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_setLogicPage(%p) (%d)", (const void *)script, stackPos(0)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1setLogicPage(%p) (%d)", (const void *)script, stackPos(0)); _screen->_curPage = stackPos(0); return stackPos(0); } int KyraEngine_v1::o1_fatPrint(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_fatPrint(%p) ('%s', %d, %d, %d, %d, %d)", (const void *)script, stackPosString(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1fatPrint(%p) ('%s', %d, %d, %d, %d, %d)", (const void *)script, stackPosString(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5)); // Workround for bug #1582672 ("KYRA1: Text crippled and drawn wrong") // I'm not sure how the original handels this, since it seems to call @@ -1145,13 +1144,13 @@ int KyraEngine_v1::o1_fatPrint(ScriptState *script) { } int KyraEngine_v1::o1_preserveAllObjectBackgrounds(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_preserveAllObjectBackgrounds(%p) ()", (const void *)script); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1preserveAllObjectBackgrounds(%p) ()", (const void *)script); _animator->preserveAllBackgrounds(); return 0; } int KyraEngine_v1::o1_updateSceneAnimations(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_updateSceneAnimations(%p) (%d)", (const void *)script, stackPos(0)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1updateSceneAnimations(%p) (%d)", (const void *)script, stackPos(0)); int times = stackPos(0); while (times--) { _sprites->updateSceneAnims(); @@ -1161,23 +1160,23 @@ int KyraEngine_v1::o1_updateSceneAnimations(ScriptState *script) { } int KyraEngine_v1::o1_sceneAnimationActive(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_sceneAnimationActive(%p) (%d)", (const void *)script, stackPos(0)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1sceneAnimationActive(%p) (%d)", (const void *)script, stackPos(0)); return _sprites->_anims[stackPos(0)].play; } int KyraEngine_v1::o1_setCharactersMovementDelay(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_setCharactersMovementDelay(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - setTimerDelay(stackPos(0)+5, stackPos(1)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1setCharactersMovementDelay(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + _timer->setDelay(stackPos(0)+5, stackPos(1)); return 0; } int KyraEngine_v1::o1_getCharactersFacing(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_getCharactersFacing(%p) (%d)", (const void *)script, stackPos(0)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1getCharactersFacing(%p) (%d)", (const void *)script, stackPos(0)); return _characterList[stackPos(0)].facing; } int KyraEngine_v1::o1_bkgdScrollSceneAndMasksRight(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_bkgdScrollSceneAndMasksRight(%p) (%d)", (const void *)script, stackPos(0)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1bkgdScrollSceneAndMasksRight(%p) (%d)", (const void *)script, stackPos(0)); _screen->copyBackgroundBlock(stackPos(0), 2, 0); _screen->copyBackgroundBlock2(stackPos(0)); // update the whole screen @@ -1187,13 +1186,13 @@ int KyraEngine_v1::o1_bkgdScrollSceneAndMasksRight(ScriptState *script) { } int KyraEngine_v1::o1_dispelMagicAnimation(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_dispelMagicAnimation(%p) ()", (const void *)script); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1dispelMagicAnimation(%p) ()", (const void *)script); seq_dispelMagicAnimation(); return 0; } int KyraEngine_v1::o1_findBrightestFireberry(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_findBrightestFireberry(%p) ()", (const void *)script); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1findBrightestFireberry(%p) ()", (const void *)script); if (_currentCharacter->sceneId >= 187 && _currentCharacter->sceneId <= 198) return 29; @@ -1237,7 +1236,7 @@ int KyraEngine_v1::o1_findBrightestFireberry(ScriptState *script) { } int KyraEngine_v1::o1_setFireberryGlowPalette(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_setFireberryGlowPalette(%p) (%d)", (const void *)script, stackPos(0)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1setFireberryGlowPalette(%p) (%d)", (const void *)script, stackPos(0)); int palIndex = 0; switch (stackPos(0)) { case 0x1E: @@ -1274,19 +1273,19 @@ int KyraEngine_v1::o1_setFireberryGlowPalette(ScriptState *script) { } int KyraEngine_v1::o1_setDeathHandlerFlag(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_setDeathHandlerFlag(%p) (%d)", (const void *)script, stackPos(0)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1setDeathHandlerFlag(%p) (%d)", (const void *)script, stackPos(0)); _deathHandler = stackPos(0); return 0; } int KyraEngine_v1::o1_drinkPotionAnimation(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_drinkPotionAnimation(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1drinkPotionAnimation(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); seq_playDrinkPotionAnim(stackPos(0), stackPos(1), stackPos(2)); return 0; } int KyraEngine_v1::o1_makeAmuletAppear(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_makeAmuletAppear(%p) ()", (const void *)script); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1makeAmuletAppear(%p) ()", (const void *)script); WSAMovieV1 amulet(this); amulet.open("AMULET.WSA", 1, 0); amulet.setX(224); @@ -1327,7 +1326,7 @@ int KyraEngine_v1::o1_makeAmuletAppear(ScriptState *script) { } int KyraEngine_v1::o1_drawItemShapeIntoScene(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_drawItemShapeIntoScene(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1drawItemShapeIntoScene(%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); @@ -1354,13 +1353,13 @@ int KyraEngine_v1::o1_drawItemShapeIntoScene(ScriptState *script) { } int KyraEngine_v1::o1_setCharactersCurrentFrame(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_setCharactersCurrentFrame(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1setCharactersCurrentFrame(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); _characterList[stackPos(0)].currentAnimFrame = stackPos(1); return 0; } int KyraEngine_v1::o1_waitForConfirmationMouseClick(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_waitForConfirmationMouseClick(%p) ()", (const void *)script); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1waitForConfirmationMouseClick(%p) ()", (const void *)script); // if (mouseEnabled) { while (!_mousePressFlag) { updateMousePointer(); @@ -1390,18 +1389,18 @@ int KyraEngine_v1::o1_pageFlip(ScriptState *script) { } int KyraEngine_v1::o1_setSceneFile(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_setSceneFile(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1setSceneFile(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); setSceneFile(stackPos(0), stackPos(1)); return 0; } int KyraEngine_v1::o1_getItemInMarbleVase(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_getItemInMarbleVase(%p) ()", (const void *)script); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1getItemInMarbleVase(%p) ()", (const void *)script); return _marbleVaseItem; } int KyraEngine_v1::o1_setItemInMarbleVase(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_setItemInMarbleVase(%p) (%d)", (const void *)script, stackPos(0)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1setItemInMarbleVase(%p) (%d)", (const void *)script, stackPos(0)); _marbleVaseItem = stackPos(0); return 0; } @@ -1417,7 +1416,7 @@ int KyraEngine_v1::o1_intPrint(ScriptState *script) { } int KyraEngine_v1::o1_shakeScreen(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_shakeScreen(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1shakeScreen(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); int waitTicks = stackPos(1); int times = stackPos(0); @@ -1430,57 +1429,57 @@ int KyraEngine_v1::o1_shakeScreen(ScriptState *script) { } int KyraEngine_v1::o1_createAmuletJewel(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_createAmuletJewel(%p) (%d)", (const void *)script, stackPos(0)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1createAmuletJewel(%p) (%d)", (const void *)script, stackPos(0)); seq_createAmuletJewel(stackPos(0), 0, 0, 0); return 0; } int KyraEngine_v1::o1_setSceneAnimCurrXY(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_setSceneAnimCurrXY(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1setSceneAnimCurrXY(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); _sprites->_anims[stackPos(0)].x = stackPos(1); _sprites->_anims[stackPos(0)].y = stackPos(2); return 0; } int KyraEngine_v1::o1_poisonBrandonAndRemaps(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_poisonBrandonAndRemaps(%p) ()", (const void *)script); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1poisonBrandonAndRemaps(%p) ()", (const void *)script); setBrandonPoisonFlags(1); return 0; } int KyraEngine_v1::o1_fillFlaskWithWater(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_fillFlaskWithWater(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1fillFlaskWithWater(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); seq_fillFlaskWithWater(stackPos(0), stackPos(1)); return 0; } int KyraEngine_v1::o1_getCharactersMovementDelay(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_getCharactersMovementDelay(%p) (%d)", (const void *)script, stackPos(0)); - return getTimerDelay(stackPos(0)+5); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1getCharactersMovementDelay(%p) (%d)", (const void *)script, stackPos(0)); + return _timer->getDelay(stackPos(0)+5); } int KyraEngine_v1::o1_getBirthstoneGem(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_getBirthstoneGem(%p) (%d)", (const void *)script, stackPos(0)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1getBirthstoneGem(%p) (%d)", (const void *)script, stackPos(0)); if (stackPos(0) < 4) return _birthstoneGemTable[stackPos(0)]; return 0; } int KyraEngine_v1::o1_queryBrandonStatusBit(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_queryBrandonStatusBit(%p) (%d)", (const void *)script, stackPos(0)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1queryBrandonStatusBit(%p) (%d)", (const void *)script, stackPos(0)); if (_brandonStatusBit & stackPos(0)) return 1; return 0; } int KyraEngine_v1::o1_playFluteAnimation(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_playFluteAnimation(%p) ()", (const void *)script); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1playFluteAnimation(%p) ()", (const void *)script); seq_playFluteAnimation(); return 0; } int KyraEngine_v1::o1_playWinterScrollSequence(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_playWinterScrollSequence(%p) (%d)", (const void *)script, stackPos(0)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1playWinterScrollSequence(%p) (%d)", (const void *)script, stackPos(0)); if (!stackPos(0)) seq_winterScroll2(); else @@ -1489,40 +1488,40 @@ int KyraEngine_v1::o1_playWinterScrollSequence(ScriptState *script) { } int KyraEngine_v1::o1_getIdolGem(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_getIdolGem(%p) (%d)", (const void *)script, stackPos(0)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1getIdolGem(%p) (%d)", (const void *)script, stackPos(0)); return _idolGemsTable[stackPos(0)]; } int KyraEngine_v1::o1_setIdolGem(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_setIdolGem(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1setIdolGem(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); _idolGemsTable[stackPos(0)] = stackPos(1); return 0; } int KyraEngine_v1::o1_totalItemsInScene(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_totalItemsInScene(%p) (%d)", (const void *)script, stackPos(0)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1totalItemsInScene(%p) (%d)", (const void *)script, stackPos(0)); return countItemsInScene(stackPos(0)); } int KyraEngine_v1::o1_restoreBrandonsMovementDelay(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_restoreBrandonsMovementDelay(%p) ()", (const void *)script); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1restoreBrandonsMovementDelay(%p) ()", (const void *)script); setWalkspeed(_configWalkspeed); return 0; } int KyraEngine_v1::o1_setMousePos(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_setMousePos(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1setMousePos(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); _system->warpMouse(stackPos(0), stackPos(1)); return 0; } int KyraEngine_v1::o1_getMouseState(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_getMouseState(%p) ()", (const void *)script); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1getMouseState(%p) ()", (const void *)script); return _mouseState; } int KyraEngine_v1::o1_setEntranceMouseCursorTrack(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_setEntranceMouseCursorTrack(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1setEntranceMouseCursorTrack(%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; @@ -1532,19 +1531,19 @@ int KyraEngine_v1::o1_setEntranceMouseCursorTrack(ScriptState *script) { } int KyraEngine_v1::o1_itemAppearsOnGround(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_itemAppearsOnGround(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1itemAppearsOnGround(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); processItemDrop(_currentCharacter->sceneId, stackPos(0), stackPos(1), stackPos(2), 2, 0); return 0; } int KyraEngine_v1::o1_setNoDrawShapesFlag(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_setNoDrawShapesFlag(%p) (%d)", (const void *)script, stackPos(0)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1setNoDrawShapesFlag(%p) (%d)", (const void *)script, stackPos(0)); _animator->_noDrawShapesFlag = stackPos(0); return 0; } int KyraEngine_v1::o1_fadeEntirePalette(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_fadeEntirePalette(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1fadeEntirePalette(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); int cmd = stackPos(0); uint8 *fadePal = 0; @@ -1584,7 +1583,7 @@ int KyraEngine_v1::o1_fadeEntirePalette(ScriptState *script) { } int KyraEngine_v1::o1_itemOnGroundHere(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_itemOnGroundHere(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1itemOnGroundHere(%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) { @@ -1595,18 +1594,18 @@ int KyraEngine_v1::o1_itemOnGroundHere(ScriptState *script) { } int KyraEngine_v1::o1_queryCauldronState(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_queryCauldronState(%p) ()", (const void *)script); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1queryCauldronState(%p) ()", (const void *)script); return _cauldronState; } int KyraEngine_v1::o1_setCauldronState(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_setCauldronState(%p) (%d)", (const void *)script, stackPos(0)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1setCauldronState(%p) (%d)", (const void *)script, stackPos(0)); _cauldronState = stackPos(0); return _cauldronState; } int KyraEngine_v1::o1_queryCrystalState(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_queryCrystalState(%p) (%d)", (const void *)script, stackPos(0)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1queryCrystalState(%p) (%d)", (const void *)script, stackPos(0)); if (!stackPos(0)) return _crystalState[0]; else if (stackPos(0) == 1) @@ -1615,7 +1614,7 @@ int KyraEngine_v1::o1_queryCrystalState(ScriptState *script) { } int KyraEngine_v1::o1_setCrystalState(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_setCrystalState(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1setCrystalState(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); if (!stackPos(0)) _crystalState[0] = stackPos(1); else if (stackPos(0) == 1) @@ -1629,7 +1628,7 @@ int KyraEngine_v1::o1_setPaletteRange(ScriptState *script) { } int KyraEngine_v1::o1_shrinkBrandonDown(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_shrinkBrandonDown(%p) (%d)", (const void *)script, stackPos(0)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1shrinkBrandonDown(%p) (%d)", (const void *)script, stackPos(0)); int delayTime = stackPos(0); checkAmuletAnimFlags(); int scaleValue = _scaleTable[_currentCharacter->y1]; @@ -1655,7 +1654,7 @@ int KyraEngine_v1::o1_shrinkBrandonDown(ScriptState *script) { } int KyraEngine_v1::o1_growBrandonUp(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_growBrandonUp(%p) ()", (const void *)script); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1growBrandonUp(%p) ()", (const void *)script); int scaleValue = _scaleTable[_currentCharacter->y1]; int scale = 0; if (_scaleMode) @@ -1676,26 +1675,26 @@ int KyraEngine_v1::o1_growBrandonUp(ScriptState *script) { } int KyraEngine_v1::o1_setBrandonScaleXAndY(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_setBrandonScaleXAndY(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1setBrandonScaleXAndY(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); _animator->_brandonScaleX = stackPos(0); _animator->_brandonScaleY = stackPos(1); return 0; } int KyraEngine_v1::o1_resetScaleMode(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_resetScaleMode(%p) ()", (const void *)script); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1resetScaleMode(%p) ()", (const void *)script); _scaleMode = 0; return 0; } int KyraEngine_v1::o1_getScaleDepthTableValue(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_getScaleDepthTableValue(%p) (%d)", (const void *)script, stackPos(0)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1getScaleDepthTableValue(%p) (%d)", (const void *)script, stackPos(0)); assert(stackPos(0) < ARRAYSIZE(_scaleTable)); return _scaleTable[stackPos(0)]; } int KyraEngine_v1::o1_setScaleDepthTableValue(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_setScaleDepthTableValue(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1setScaleDepthTableValue(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); assert(stackPos(0) < ARRAYSIZE(_scaleTable)); _scaleTable[stackPos(0)] = stackPos(1); return stackPos(1); @@ -1703,10 +1702,10 @@ int KyraEngine_v1::o1_setScaleDepthTableValue(ScriptState *script) { int KyraEngine_v1::o1_message(ScriptState *script) { if (_flags.isTalkie) { - debugC(3, kDebugLevelScriptFuncs, "o1_message(%p) (%d, '%s', %d)", (const void *)script, stackPos(0), stackPosString(1), stackPos(2)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1message(%p) (%d, '%s', %d)", (const void *)script, stackPos(0), stackPosString(1), stackPos(2)); drawSentenceCommand(stackPosString(1), stackPos(2)); } else { - debugC(3, kDebugLevelScriptFuncs, "o1_message(%p) ('%s', %d)", (const void *)script, stackPosString(0), stackPos(1)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1message(%p) ('%s', %d)", (const void *)script, stackPosString(0), stackPos(1)); drawSentenceCommand(stackPosString(0), stackPos(1)); } @@ -1714,38 +1713,38 @@ int KyraEngine_v1::o1_message(ScriptState *script) { } int KyraEngine_v1::o1_checkClickOnNPC(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_checkClickOnNPC(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1checkClickOnNPC(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); return checkForNPCScriptRun(stackPos(0), stackPos(1)); } int KyraEngine_v1::o1_getFoyerItem(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_getFoyerItem(%p) (%d)", (const void *)script, stackPos(0)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1getFoyerItem(%p) (%d)", (const void *)script, stackPos(0)); assert(stackPos(0) < ARRAYSIZE(_foyerItemTable)); return _foyerItemTable[stackPos(0)]; } int KyraEngine_v1::o1_setFoyerItem(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_setFoyerItem(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1setFoyerItem(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); assert(stackPos(0) < ARRAYSIZE(_foyerItemTable)); _foyerItemTable[stackPos(0)] = stackPos(1); return stackPos(1); } int KyraEngine_v1::o1_setNoItemDropRegion(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_setNoItemDropRegion(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1setNoItemDropRegion(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); addToNoDropRects(stackPos(0), stackPos(1), stackPos(2), stackPos(3)); return 0; } int KyraEngine_v1::o1_walkMalcolmOn(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_walkMalcolmOn(%p) ()", (const void *)script); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1walkMalcolmOn(%p) ()", (const void *)script); if (!_malcolmFlag) _malcolmFlag = 1; return 0; } int KyraEngine_v1::o1_passiveProtection(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_passiveProtection(%p) ()", (const void *)script); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1passiveProtection(%p) ()", (const void *)script); return 1; } @@ -1755,24 +1754,24 @@ int KyraEngine_v1::o1_setPlayingLoop(ScriptState *script) { } int KyraEngine_v1::o1_brandonToStoneSequence(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_brandonToStoneSequence(%p) ()", (const void *)script); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1brandonToStoneSequence(%p) ()", (const void *)script); seq_brandonToStone(); return 0; } int KyraEngine_v1::o1_brandonHealingSequence(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_brandonHealingSequence(%p) ()", (const void *)script); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1brandonHealingSequence(%p) ()", (const void *)script); seq_brandonHealing(); return 0; } int KyraEngine_v1::o1_protectCommandLine(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_protectCommandLine(%p) (%d)", (const void *)script, stackPos(0)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1protectCommandLine(%p) (%d)", (const void *)script, stackPos(0)); return stackPos(0); } int KyraEngine_v1::o1_pauseMusicSeconds(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_pauseMusicSeconds(%p) ()", (const void *)script); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1pauseMusicSeconds(%p) ()", (const void *)script); // if music disabled // return o1_pauseSeconds(script); @@ -1785,13 +1784,13 @@ int KyraEngine_v1::o1_resetMaskRegion(ScriptState *script) { } int KyraEngine_v1::o1_setPaletteChangeFlag(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_setPaletteChangeFlag(%p) (%d)", (const void *)script, stackPos(0)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1setPaletteChangeFlag(%p) (%d)", (const void *)script, stackPos(0)); _paletteChanged = stackPos(0); return _paletteChanged; } int KyraEngine_v1::o1_fillRect(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "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)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1fillRect(%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)); @@ -1800,19 +1799,19 @@ int KyraEngine_v1::o1_fillRect(ScriptState *script) { } int KyraEngine_v1::o1_vocUnload(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_vocUnload(%p) ()", (const void *)script); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1vocUnload(%p) ()", (const void *)script); // this should unload all voc files (not needed) return 0; } int KyraEngine_v1::o1_vocLoad(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_vocLoad(%p) (%d)", (const void *)script, stackPos(0)); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1vocLoad(%p) (%d)", (const void *)script, stackPos(0)); // this should load the specified voc file (not needed) return 0; } int KyraEngine_v1::o1_dummy(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "o1_dummy(%p) ()", (const void *)script); + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1dummy(%p) ()", (const void *)script); return 0; } diff --git a/engines/kyra/script_v2.cpp b/engines/kyra/script_v2.cpp new file mode 100644 index 0000000000..ce1cd99e03 --- /dev/null +++ b/engines/kyra/script_v2.cpp @@ -0,0 +1,430 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "kyra/kyra_v2.h" +#include "kyra/wsamovie.h" + +#include "common/endian.h" + +namespace Kyra { + +int KyraEngine_v2::o2_setCharacterFacingRefresh(ScriptState *script) { + debugC(3, kDebugLevelScriptFuncs, "o2_setCharacterFacingRefresh(%p) (-, %d, %d)", (const void *)script, stackPos(1), stackPos(2)); + int animFrame = stackPos(2); + if (animFrame >= 0) + _mainCharacter.animFrame = animFrame; + _mainCharacter.facing = stackPos(1); + updateCharacterAnim(0); + refreshAnimObjectsIfNeed(); + return 0; +} + +int KyraEngine_v2::o2_defineObject(ScriptState *script) { + debugC(3, kDebugLevelScriptFuncs, "o2_defineObject(%p) (%d, '%s', %d, %d, %d, %d)", (const void *)script, + stackPos(0), stackPosString(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5)); + Object *object = &_objectList[stackPos(0)]; + strcpy(object->filename, stackPosString(1)); + object->scriptId = stackPos(2); + object->x = stackPos(3); + object->y = stackPos(4); + object->unk12 = stackPos(5); + return 0; +} + +int KyraEngine_v2::o2_refreshCharacter(ScriptState *script) { + debugC(3, kDebugLevelScriptFuncs, "o2_refreshCharacter(%p) (-, %d, %d, %d)", (const void *)script, stackPos(1), stackPos(2), stackPos(3)); + int unk = stackPos(1); + int facing = stackPos(2); + int refresh = stackPos(3); + if (facing >= 0) + _mainCharacter.facing = facing; + if (unk >= 0 && unk != 32) + _mainCharacter.animFrame = _characterFrameTable[_mainCharacter.facing]; + updateCharacterAnim(0); + if (refresh) + refreshAnimObjectsIfNeed(); + return 0; +} + +int KyraEngine_v2::o2_getCharacterX(ScriptState *script) { + debugC(3, kDebugLevelScriptFuncs, "o2_getCharacterX(%p) ()", (const void *)script); + return _mainCharacter.x1; +} + +int KyraEngine_v2::o2_getCharacterY(ScriptState *script) { + debugC(3, kDebugLevelScriptFuncs, "o2_getCharacterY(%p) ()", (const void *)script); + return _mainCharacter.y1; +} + +int KyraEngine_v2::o2_getCharacterFacing(ScriptState *script) { + debugC(3, kDebugLevelScriptFuncs, "o2_getCharacterFacing(%p) ()", (const void *)script); + return _mainCharacter.facing; +} + +int KyraEngine_v2::o2_setSceneComment(ScriptState *script) { + debugC(3, kDebugLevelScriptFuncs, "o2_setSceneComment(%p) ('%s')", (const void *)script, stackPosString(0)); + _sceneCommentString = stackPosString(0); + return 0; +} + +int KyraEngine_v2::o2_showChapterMessage(ScriptState *script) { + debugC(3, kDebugLevelScriptFuncs, "o2_showChapterMessage(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + showChapterMessage(stackPos(0), stackPos(1)); + return 0; +} + +int KyraEngine_v2::o2_wsaClose(ScriptState *script) { + debugC(3, kDebugLevelScriptFuncs, "o2_wsaClose(%p) (%d)", (const void *)script, stackPos(0)); + assert(stackPos(0) >= 0 && stackPos(0) < ARRAYSIZE(_wsaSlots)); + _wsaSlots[stackPos(0)]->close(); + return 0; +} + +int KyraEngine_v2::o2_displayWsaFrame(ScriptState *script) { + debugC(3, kDebugLevelScriptFuncs, "o2_displayWsaFrame(%p) (%d, %d, %d, %d, %d, %d, %d, %d, %d)", (const void *)script, + stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7), stackPos(8)); + int frame = stackPos(0); + int x = stackPos(1); + int y = stackPos(2); + int waitTime = stackPos(3); + int slot = stackPos(4); + int copyParam = stackPos(5); + int doUpdate = stackPos(6); + int dstPage = stackPos(7); + int backUp = stackPos(8); + + _screen->hideMouse(); + uint32 endTime = _system->getMillis() + waitTime * _tickLength; + _wsaSlots[slot]->setX(x); + _wsaSlots[slot]->setY(y); + _wsaSlots[slot]->setDrawPage(dstPage); + _wsaSlots[slot]->displayFrame(frame, copyParam | 0xC000); + _screen->updateScreen(); + + if (backUp) + memcpy(_gamePlayBuffer, _screen->getCPagePtr(3), 46080); + + while (_system->getMillis() < endTime) { + if (doUpdate) + update(); + + if (endTime - _system->getMillis() >= 10) + delay(10); + } + _screen->showMouse(); + return 0; +} + +int KyraEngine_v2::o2_displayWsaSequentialFrames(ScriptState *script) { + debugC(3, kDebugLevelScriptFuncs, "o2_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)); + int startFrame = stackPos(0); + int endFrame = stackPos(1); + int x = stackPos(2); + int y = stackPos(3); + int waitTime = stackPos(4); + int slot = stackPos(5); + int maxTimes = stackPos(6); + int copyFlags = stackPos(7); + + if (maxTimes > 1) + maxTimes = 1; + + _wsaSlots[slot]->setX(x); + _wsaSlots[slot]->setY(y); + _wsaSlots[slot]->setDrawPage(0); + + _screen->hideMouse(); + int curTime = 0; + while (curTime < maxTimes) { + if (startFrame < endFrame) { + for (int i = startFrame; i <= endFrame; ++i) { + uint32 endTime = _system->getMillis() + waitTime * _tickLength; + _wsaSlots[slot]->displayFrame(i, 0xC000 | copyFlags); + _screen->updateScreen(); + + do { + update(); + + if (endTime - _system->getMillis() >= 10) + delay(10); + } while (_system->getMillis() < endTime); + } + } else { + for (int i = startFrame; i >= endFrame; --i) { + uint32 endTime = _system->getMillis() + waitTime * _tickLength; + _wsaSlots[slot]->displayFrame(i, 0xC000 | copyFlags); + _screen->updateScreen(); + + do { + update(); + + if (endTime - _system->getMillis() >= 10) + delay(10); + } while (_system->getMillis() < endTime); + } + } + + ++curTime; + } + _screen->showMouse(); + return 0; +} + +int KyraEngine_v2::o2_wsaOpen(ScriptState *script) { + debugC(3, kDebugLevelScriptFuncs, "o2_wsaOpen(%p) ('%s', %d)", (const void *)script, stackPosString(0), stackPos(1)); + assert(stackPos(1) >= 0 && stackPos(1) < ARRAYSIZE(_wsaSlots)); + _wsaSlots[stackPos(1)]->open(stackPosString(0), 1, 0); + return 0; +} + +int KyraEngine_v2::o2_defineItem(ScriptState *script) { + debugC(3, kDebugLevelScriptFuncs, "o2_defineItem(%p) (%d, %d, %d, %d)", (const void *)script, + stackPos(0), stackPos(1), stackPos(2), stackPos(3)); + int freeItem = findFreeItem(); + + if (freeItem >= 0) { + _itemList[freeItem].id = stackPos(0); + _itemList[freeItem].x = stackPos(1); + _itemList[freeItem].y = stackPos(2); + _itemList[freeItem].sceneId = stackPos(3); + } + + return freeItem; +} + +int KyraEngine_v2::o2_queryGameFlag(ScriptState *script) { + debugC(3, kDebugLevelScriptFuncs, "o2_queryGameFlag(%p) (%d)", (const void *)script, stackPos(0)); + return queryGameFlag(stackPos(0)); +} + +int KyraEngine_v2::o2_resetGameFlag(ScriptState *script) { + debugC(3, kDebugLevelScriptFuncs, "o2_resetGameFlag(%p) (%d)", (const void *)script, stackPos(0)); + return resetGameFlag(stackPos(0)); +} + +int KyraEngine_v2::o2_setGameFlag(ScriptState *script) { + debugC(3, kDebugLevelScriptFuncs, "o2_setGameFlag(%p) (%d)", (const void *)script, stackPos(0)); + return setGameFlag(stackPos(0)); +} + +int KyraEngine_v2::o2_hideMouse(ScriptState *script) { + debugC(3, kDebugLevelScriptFuncs, "o2_hideMouse(%p) ()", (const void *)script); + _screen->hideMouse(); + return 0; +} + +int KyraEngine_v2::o2_addSpecialExit(ScriptState *script) { + debugC(3, kDebugLevelScriptFuncs, "o2_addSpecialExit(%p) (%d, %d, %d, %d, %d)", (const void *)script, + stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); + if (_specialExitCount < 5) { + _specialExitTable[_specialExitCount+0] = stackPos(0); + _specialExitTable[_specialExitCount+5] = stackPos(1); + _specialExitTable[_specialExitCount+10] = stackPos(2); + _specialExitTable[_specialExitCount+15] = stackPos(3); + _specialExitTable[_specialExitCount+20] = stackPos(4); + ++_specialExitCount; + } + return 0; +} + +int KyraEngine_v2::o2_showMouse(ScriptState *script) { + debugC(3, kDebugLevelScriptFuncs, "o2_showMouse(%p) ()", (const void *)script); + _screen->showMouse(); + return 0; +} + +int KyraEngine_v2::o2_setScaleTableItem(ScriptState *script) { + debugC(3, kDebugLevelScriptFuncs, "o2_setScaleTableItem(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + setScaleTableItem(stackPos(0), stackPos(1)); + return 0; +} + +int KyraEngine_v2::o2_setDrawLayerTableItem(ScriptState *script) { + debugC(3, kDebugLevelScriptFuncs, "o2_setDrawLayerTableItem(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + setDrawLayerTableEntry(stackPos(0), stackPos(1)); + return 0; +} + +int KyraEngine_v2::o2_drawSceneShapeOnPage(ScriptState *script) { + debugC(3, kDebugLevelScriptFuncs, "o2_drawSceneShapeOnPage(%p) (%d, %d, %d, %d, %d)", (const void *)script, + stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); + int shape = stackPos(0); + int x = stackPos(1); + int y = stackPos(2); + int flag = stackPos(3); + int drawPage = stackPos(4); + _screen->drawShape(drawPage, _sceneShapeTable[shape], x, y, 2, flag ? 1 : 0); + return 0; +} + +int KyraEngine_v2::o2_restoreBackBuffer(ScriptState *script) { + debugC(3, kDebugLevelScriptFuncs, "o2_restoreBackBuffer(%p) (%d, %d)", (const void *)script, stackPos(0)); + int disable = stackPos(0); + int oldState = 0; + if (disable) { + oldState = _animObjects[0].enabled; + _animObjects[0].enabled = 0; + } + restorePage3(); + if (disable) + _animObjects[0].enabled = oldState; + return 0; +} + +int KyraEngine_v2::o2_getRand(ScriptState *script) { + debugC(3, kDebugLevelScriptFuncs, "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_encodeShape(ScriptState *script) { + debugC(3, kDebugLevelScriptFuncs, "o2_encodeShape(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), + stackPos(2), stackPos(3), stackPos(4)); + _sceneShapeTable[stackPos(0)] = _screen->encodeShape(stackPos(1), stackPos(2), stackPos(3), stackPos(4), 2); + return 0; +} + +int KyraEngine_v2::o2_defineRoomEntrance(ScriptState *script) { + debugC(3, kDebugLevelScriptFuncs, "o2_defineRoomEntrance(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); + switch (stackPos(0)) { + case 0: + _sceneEnterX1 = stackPos(1); + _sceneEnterY1 = stackPos(2); + break; + + case 1: + _sceneEnterX2 = stackPos(1); + _sceneEnterY2 = stackPos(2); + break; + + case 2: + _sceneEnterX3 = stackPos(1); + _sceneEnterY3 = stackPos(2); + break; + + case 3: + _sceneEnterX4 = stackPos(1); + _sceneEnterY4 = stackPos(2); + break; + + default: + break; + } + return 0; +} + +int KyraEngine_v2::o2_setSpecialSceneScriptRunTime(ScriptState *script) { + debugC(3, kDebugLevelScriptFuncs, "o2_setSpecialSceneScriptRunTime(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + assert(stackPos(0) >= 0 && stackPos(0) < 10); + _sceneSpecialScriptsTimer[stackPos(0)] = _system->getMillis() + stackPos(1) * _tickLength; + return 0; +} + +int KyraEngine_v2::o2_defineSceneAnim(ScriptState *script) { + debugC(3, kDebugLevelScriptFuncs, "o2_defineSceneAnim(%p) (%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, '%s')", (const void *)script, + stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7), stackPos(8), + stackPos(9), stackPos(10), stackPos(11), stackPosString(12)); + int animId = stackPos(0); + SceneAnim &anim = _sceneAnims[animId]; + anim.flags = stackPos(1); + anim.x = stackPos(2); + anim.y = stackPos(3); + anim.x2 = stackPos(4); + anim.y2 = stackPos(5); + anim.width = stackPos(6); + anim.height = stackPos(7); + anim.unkE = stackPos(8); + anim.specialSize = stackPos(9); + anim.unk12 = stackPos(10); + anim.shapeIndex = stackPos(11); + if (stackPosString(12) != 0) + strcpy(anim.filename, stackPosString(12)); + + if (anim.flags & 0x40) { + if (!_sceneAnimMovie[animId]->open(anim.filename, 1, 0)) + error("couldn't load '%s'", anim.filename); + + if (_sceneAnimMovie[animId]->xAdd() || _sceneAnimMovie[animId]->yAdd()) + anim.wsaFlag = 1; + else + anim.wsaFlag = 0; + } + + return 0; +} + +int KyraEngine_v2::o2_updateSceneAnim(ScriptState *script) { + debugC(3, kDebugLevelScriptFuncs, "o2_updateSceneAnim(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + updateSceneAnim(stackPos(0), stackPos(1)); + _specialSceneScriptRunFlag = false; + return 0; +} + +int KyraEngine_v2::o2_defineRoom(ScriptState *script) { + debugC(3, kDebugLevelScriptFuncs, "o2_defineRoom(%p) (%d, '%s', %d, %d, %d, %d, %d, %d)", (const void *)script, + stackPos(0), stackPosString(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7)); + SceneDesc *scene = &_sceneList[stackPos(0)]; + strcpy(scene->filename, stackPosString(1)); + scene->exit1 = stackPos(2); + scene->exit2 = stackPos(3); + scene->exit3 = stackPos(4); + scene->exit4 = stackPos(5); + scene->flags = stackPos(6); + scene->sound = stackPos(7); + + if (_mainCharacter.sceneId == stackPos(0)) { + _sceneExit1 = scene->exit1; + _sceneExit2 = scene->exit2; + _sceneExit3 = scene->exit3; + _sceneExit4 = scene->exit4; + } + + return 0; +} + +int KyraEngine_v2::o2_setSpecialSceneScriptState(ScriptState *script) { + debugC(3, kDebugLevelScriptFuncs, "o2_setSpecialSceneScriptState(%p) (%d)", (const void *)script, stackPos(0)); + _specialSceneScriptState[stackPos(0)] = 1; + return 1; +} + +int KyraEngine_v2::o2_clearSpecialSceneScriptState(ScriptState *script) { + debugC(3, kDebugLevelScriptFuncs, "o2_clearSpecialSceneScriptState(%p) (%d)", (const void *)script, stackPos(0)); + _specialSceneScriptState[stackPos(0)] = 0; + return 0; +} + +int KyraEngine_v2::o2_querySpecialSceneScriptState(ScriptState *script) { + debugC(3, kDebugLevelScriptFuncs, "o2_querySpecialSceneScriptState(%p) (%d)", (const void *)script, stackPos(0)); + return _specialSceneScriptState[stackPos(0)]; +} + +int KyraEngine_v2::o2_dummy(ScriptState *script) { + debugC(3, kDebugLevelScriptFuncs, "o2_dummy(%p) ()", (const void *)script); + return 0; +} + +} // end of namespace Kyra diff --git a/engines/kyra/sequences_v1.cpp b/engines/kyra/sequences_v1.cpp index 55c294fb1c..3bba3406a8 100644 --- a/engines/kyra/sequences_v1.cpp +++ b/engines/kyra/sequences_v1.cpp @@ -32,6 +32,7 @@ #include "kyra/wsamovie.h" #include "kyra/animator_v1.h" #include "kyra/text.h" +#include "kyra/timer.h" #include "common/events.h" #include "common/system.h" @@ -654,7 +655,7 @@ void KyraEngine_v1::seq_makeBrandonInv() { _screen->hideMouse(); checkAmuletAnimFlags(); _brandonStatusBit |= 0x20; - setTimerCountdown(18, 2700); + _timer->setCountdown(18, 2700); _brandonStatusBit |= 0x40; snd_playSoundEffect(0x77); _brandonInvFlag = 0; @@ -732,9 +733,9 @@ void KyraEngine_v1::seq_makeBrandonWisp() { _brandonStatusBit |= 2; if (_currentCharacter->sceneId >= 109 && _currentCharacter->sceneId <= 198) - setTimerCountdown(14, 18000); + _timer->setCountdown(14, 18000); else - setTimerCountdown(14, 7200); + _timer->setCountdown(14, 7200); _animator->_brandonDrawFrame = 113; _brandonStatusBit0x02Flag = 1; @@ -1858,7 +1859,7 @@ void KyraEngine_v1::drawJewelsFadeOutEnd(int jewel) { } setGameFlag(0xF1); - setTimerCountdown(19, newDelay); + _timer->setCountdown(19, newDelay); _screen->hideMouse(); for (int i = 0; jewelTable[i] != 0xFFFF; ++i) { uint16 shape = jewelTable[i]; diff --git a/engines/kyra/sequences_v2.cpp b/engines/kyra/sequences_v2.cpp index afda1091e6..1c098bf887 100644 --- a/engines/kyra/sequences_v2.cpp +++ b/engines/kyra/sequences_v2.cpp @@ -569,6 +569,7 @@ void KyraEngine_v2::seq_loadWSA(int wsaNum, const char *filename, int frameDelay _activeWSA[wsaNum].movie = new WSAMovieV2(this); assert(_activeWSA[wsaNum].movie); _activeWSA[wsaNum].endFrame = _activeWSA[wsaNum].movie->open(filename, 0, _screen->_currentPalette); + _activeWSA[wsaNum].movie->flagOldOff(true); assert(_activeWSA[wsaNum].movie->opened()); _activeWSA[wsaNum].currentFrame = 0; _activeWSA[wsaNum].frameDelay = frameDelay; diff --git a/engines/kyra/staticres.cpp b/engines/kyra/staticres.cpp index 68e5401481..3cf8648aa8 100644 --- a/engines/kyra/staticres.cpp +++ b/engines/kyra/staticres.cpp @@ -868,16 +868,41 @@ const ScreenDim Screen::_screenDimTable[] = { { 0x03, 0x28, 0x22, 0x46, 0x0F, 0x0D, 0x00, 0x00 } }; -const int Screen::_screenDimTableCount = ARRAYSIZE(_screenDimTable); +const int Screen::_screenDimTableCount = ARRAYSIZE(Screen::_screenDimTable); + +const ScreenDim Screen_v2::_screenDimTable[] = { + { 0x00, 0x00, 0x28, 0xC8, 0xC7, 0xCF, 0x00, 0x00 }, + { 0x08, 0x48, 0x18, 0x38, 0xC7, 0xCF, 0x00, 0x00 }, + { 0x00, 0x00, 0x28, 0x90, 0xC7, 0xCF, 0x00, 0x00 }, + { 0x00, 0xC2, 0x28, 0x06, 0xC7, 0xCF, 0x00, 0x00 }, + { 0x00, 0x90, 0x28, 0x38, 0x96, 0xCF, 0x00, 0x00 }, + { 0x01, 0x94, 0x26, 0x30, 0x96, 0x1B, 0x00, 0x00 }, + { 0x00, 0x90, 0x28, 0x38, 0xC7, 0xCC, 0x00, 0x00 }, + { 0x01, 0x96, 0x26, 0x32, 0xC7, 0xCC, 0x00, 0x00 }, + { 0x00, 0x00, 0x28, 0x88, 0xC7, 0xCF, 0x00, 0x00 }, + { 0x00, 0x08, 0x28, 0xB8, 0xC7, 0xCF, 0x00, 0x00 }, + { 0x01, 0x28, 0x26, 0x46, 0xC7, 0xCC, 0x00, 0x00 }, + { 0x0A, 0x96, 0x14, 0x30, 0x19, 0xF0, 0x00, 0x00 } // menu, just present for current menu code +}; + +const int Screen_v2::_screenDimTableCount = ARRAYSIZE(Screen_v2::_screenDimTable); -const ScreenDim Screen::_screenDimTableK3[] = { +const ScreenDim Screen_v2::_screenDimTableK3[] = { { 0x00, 0x00, 0x28, 0xC8, 0xFF, 0xF0, 0x00, 0x00 }, { 0x08, 0x48, 0x18, 0x38, 0xFF, 0xF0, 0x00, 0x00 }, { 0x00, 0x00, 0x28, 0xBC, 0xFF, 0xF0, 0x00, 0x00 }, { 0x0A, 0x96, 0x14, 0x30, 0x19, 0xF0, 0x00, 0x00 } }; -const int Screen::_screenDimTableCountK3 = ARRAYSIZE(_screenDimTableK3); +const int Screen_v2::_screenDimTableCountK3 = ARRAYSIZE(Screen_v2::_screenDimTableK3); + +const int8 KyraEngine::_addXPosTable[] = { + 4, 4, 0, -4, -4, -4, 0, 4 +}; + +const int8 KyraEngine::_addYPosTable[] = { + 0, -2, -2, -2, 0, 2, 2, 2 +}; const char *KyraEngine_v1::_soundFiles[] = { "INTRO", @@ -909,18 +934,10 @@ const int8 KyraEngine_v1::_charXPosTable[] = { 0, 4, 4, 4, 0, -4, -4, -4 }; -const int8 KyraEngine_v1::_addXPosTable[] = { - 4, 4, 0, -4, -4, -4, 0, 4 -}; - const int8 KyraEngine_v1::_charYPosTable[] = { -2, -2, 0, 2, 2, 2, 0, -2 }; -const int8 KyraEngine_v1::_addYPosTable[] = { - 0, -2, -2, -2, 0, 2, 2, 2 -}; - const uint16 KyraEngine_v1::_itemPosX[] = { 95, 115, 135, 155, 175, 95, 115, 135, 155, 175 }; @@ -1196,6 +1213,34 @@ const char *KyraEngine_v2::_introSoundList[] = { const int KyraEngine_v2::_introSoundListSize = ARRAYSIZE(KyraEngine_v2::_introSoundList); +const char *KyraEngine_v2::_languageExtension[] = { + "ENG", + "FRE", + "GER"/*, + "ITA", Italian and Spanish was never included + "SPA"*/ +}; + +const char *KyraEngine_v2::_scriptLangExt[] = { + "EMC", + "FMC", + "GMC"/*, + "IMC", Italian and Spanish was never included + "SMC"*/ +}; + +int KyraEngine_v2::_characterFrameTable[] = { + 0x19, 0x09, 0x09, 0x12, 0x12, 0x12, 0x09, 0x09 +}; + +int KyraEngine_v2::_inventoryX[] = { + 0x4F, 0x63, 0x77, 0x8B, 0x9F, 0x4F, 0x63, 0x77, 0x8B, 0x9F +}; + +int KyraEngine_v2::_inventoryY[] = { + 0x95, 0x95, 0x95, 0x95, 0x95, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA +}; + // kyra 3 static res const char *KyraEngine_v3::_soundList[] = { diff --git a/engines/kyra/text_v1.cpp b/engines/kyra/text_v1.cpp index 3ca986adf8..c04aa2105f 100644 --- a/engines/kyra/text_v1.cpp +++ b/engines/kyra/text_v1.cpp @@ -28,6 +28,7 @@ #include "kyra/text.h" #include "kyra/animator_v1.h" #include "kyra/sprites.h" +#include "kyra/timer.h" namespace Kyra { @@ -66,9 +67,9 @@ void KyraEngine_v1::waitForChatToFinish(int vocFile, int16 chatDuration, const c snd_playVoiceFile(vocFile); } - disableTimer(14); - disableTimer(18); - disableTimer(19); + _timer->disable(14); + _timer->disable(18); + _timer->disable(19); uint32 timeAtStart = _system->getMillis(); uint32 loopStart; @@ -80,7 +81,7 @@ void KyraEngine_v1::waitForChatToFinish(int vocFile, int16 chatDuration, const c if (_system->getMillis() > timeToEnd && !hasUpdatedNPCs) { hasUpdatedNPCs = true; - disableTimer(15); + _timer->disable(15); _currHeadShape = 4; _animator->animRefreshNPC(0); _animator->animRefreshNPC(_talkingCharNum); @@ -92,7 +93,7 @@ void KyraEngine_v1::waitForChatToFinish(int vocFile, int16 chatDuration, const c } } - updateGameTimers(); + _timer->update(); _sprites->updateSceneAnims(); _animator->restoreAllObjectBackgrounds(); _animator->preserveAnyChangedBackgrounds(); @@ -146,10 +147,10 @@ void KyraEngine_v1::waitForChatToFinish(int vocFile, int16 chatDuration, const c snd_voiceWaitForFinish(); snd_stopVoice(); - enableTimer(14); - enableTimer(15); - enableTimer(18); - enableTimer(19); + _timer->enable(14); + _timer->enable(15); + _timer->enable(18); + _timer->enable(19); //clearKyrandiaButtonIO(); } @@ -374,7 +375,7 @@ void KyraEngine_v1::updateTextFade() { return; bool finished = false; - for (int i = 0; i < 3; i++) + for (int i = 0; i < 3; i++) { if (_currSentenceColor[i] > 4) _currSentenceColor[i] -= 4; else @@ -382,7 +383,8 @@ void KyraEngine_v1::updateTextFade() { _currSentenceColor[i] = 0; finished = true; } - + } + _screen->_currentPalette[765] = _currSentenceColor[0]; _screen->_currentPalette[766] = _currSentenceColor[1]; _screen->_currentPalette[767] = _currSentenceColor[2]; diff --git a/engines/kyra/timer.cpp b/engines/kyra/timer.cpp new file mode 100644 index 0000000000..dff191cbe0 --- /dev/null +++ b/engines/kyra/timer.cpp @@ -0,0 +1,251 @@ +/* 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/timer.h" + +#include "common/func.h" +#include "common/savefile.h" + +namespace Kyra { + +namespace { +struct TimerResync : public Common::UnaryFunction<TimerEntry&, void> { + uint32 _tickLength, _curTime; + TimerResync(KyraEngine *vm, uint32 curTime) : _tickLength(vm->tickLength()), _curTime(curTime) {} + + void operator()(TimerEntry &entry) const { + if (entry.lastUpdate < 0) { + if ((entry.lastUpdate + _curTime) <= 0) + entry.nextRun = 0; + else + entry.nextRun = _curTime + entry.lastUpdate + entry.countdown * _tickLength; + } else { + uint32 nextRun = entry.lastUpdate + entry.countdown * _tickLength; + if (_curTime < nextRun) + nextRun = 0; + entry.nextRun = nextRun; + } + } +}; + +struct TimerEqual : public Common::UnaryFunction<const TimerEntry&, bool> { + uint8 _id; + + TimerEqual(uint8 id) : _id(id) {} + + bool operator()(const TimerEntry &entry) const { + return entry.id == _id; + } +}; +} // end of anonymous namespace + +void TimerManager::reset() { + for (Iterator pos = _timers.begin(); pos != _timers.end(); ++pos) { + delete pos->func; + } + + _timers.clear(); +} + +void TimerManager::addTimer(uint8 id, TimerFunc *func, int countdown, bool enabled) { + debugC(9, kDebugLevelTimer, "TimerManager::addTimer(%d, %p, %d, %d)", id, (const void*)func, countdown, enabled); + + TimerEntry newTimer; + + newTimer.id = id; + newTimer.countdown = countdown; + newTimer.enabled = enabled ? 1 : 0; + newTimer.lastUpdate = newTimer.nextRun = 0; + newTimer.func = func; + + _timers.push_back(newTimer); +} + +void TimerManager::update() { + debugC(9, kDebugLevelTimer, "TimerManager::update()"); + + if (_system->getMillis() < _nextRun) + return; + + _nextRun += 99999; + + for (Iterator pos = _timers.begin(); pos != _timers.end(); ++pos) { + if (pos->enabled && pos->countdown >= 0 && pos->nextRun <= _system->getMillis()) { + if (pos->func && *pos->func) + (*pos->func)(pos->id); + + uint32 curTime = _system->getMillis(); + pos->lastUpdate = curTime; + pos->nextRun = curTime + pos->countdown * _vm->tickLength(); + + _nextRun = MIN(_nextRun, pos->nextRun); + } + } +} + +void TimerManager::resync() { + debugC(9, kDebugLevelTimer, "TimerManager::resync()"); + + _nextRun = 0; // force rerun + Common::for_each(_timers.begin(), _timers.end(), TimerResync(_vm, _system->getMillis())); +} + +void TimerManager::resetNextRun() { + debugC(9, kDebugLevelTimer, "TimerManager::resetNextRun()"); + _nextRun = 0; +} + +void TimerManager::setCountdown(uint8 id, int32 countdown) { + debugC(9, kDebugLevelTimer, "TimerManager::setCountdown(%d, %d)", id, countdown); + + Iterator timer = Common::find_if(_timers.begin(), _timers.end(), TimerEqual(id)); + if (timer != _timers.end()) { + timer->countdown = countdown; + + if (countdown >= 0) { + uint32 curTime = _system->getMillis(); + timer->lastUpdate = curTime; + timer->nextRun = curTime + countdown * _vm->tickLength(); + + _nextRun = MIN(_nextRun, timer->nextRun); + } + } else { + warning("TimerManager::setCountdown: No timer %d", id); + } +} + +void TimerManager::setDelay(uint8 id, int32 countdown) { + debugC(9, kDebugLevelTimer, "TimerManager::setDelay(%d, %d)", id, countdown); + + Iterator timer = Common::find_if(_timers.begin(), _timers.end(), TimerEqual(id)); + if (timer != _timers.end()) + timer->countdown = countdown; + else + warning("TimerManager::setDelay: No timer %d", id); +} + +int32 TimerManager::getDelay(uint8 id) const { + debugC(9, kDebugLevelTimer, "TimerManager::getDelay(%d)", id); + + CIterator timer = Common::find_if(_timers.begin(), _timers.end(), TimerEqual(id)); + if (timer != _timers.end()) + return timer->countdown; + + warning("TimerManager::getDelay: No timer %d", id); + return -1; +} + +bool TimerManager::isEnabled(uint8 id) const { + debugC(9, kDebugLevelTimer, "TimerManager::isEnabled(%d)", id); + + CIterator timer = Common::find_if(_timers.begin(), _timers.end(), TimerEqual(id)); + if (timer != _timers.end()) + return (timer->enabled == 1); + + warning("TimerManager::isEnabled: No timer %d", id); + return false; +} + +void TimerManager::enable(uint8 id) { + debugC(9, kDebugLevelTimer, "TimerManager::enable(%d)", id); + + Iterator timer = Common::find_if(_timers.begin(), _timers.end(), TimerEqual(id)); + if (timer != _timers.end()) + timer->enabled = 1; + else + warning("TimerManager::enable: No timer %d", id); +} + +void TimerManager::disable(uint8 id) { + debugC(9, kDebugLevelTimer, "TimerManager::disable(%d)", id); + + Iterator timer = Common::find_if(_timers.begin(), _timers.end(), TimerEqual(id)); + if (timer != _timers.end()) + timer->enabled = 0; + else + warning("TimerManager::disable: No timer %d", id); +} + +void TimerManager::loadDataFromFile(Common::InSaveFile *file, int version) { + debugC(9, kDebugLevelTimer, "TimerManager::loadDataFromFile(%p, %d)", (const void*)file, version); + + if (version <= 7) { + _nextRun = 0; + for (int i = 0; i < 32; ++i) { + uint8 enabled = file->readByte(); + int32 countdown = file->readSint32BE(); + uint32 nextRun = file->readUint32BE(); + + Iterator timer = Common::find_if(_timers.begin(), _timers.end(), TimerEqual(i)); + if (timer != _timers.end()) { + timer->enabled = enabled; + timer->countdown = countdown; + + if (nextRun) { + timer->nextRun = nextRun + _system->getMillis(); + timer->lastUpdate = timer->nextRun - countdown * _vm->tickLength(); + } else { + uint32 curTime = _system->getMillis(); + timer->nextRun = curTime; + timer->lastUpdate = curTime - countdown * _vm->tickLength(); + } + } else { + warning("Loading timer data for non existing timer %d", i); + } + } + } else { + int entries = file->readByte(); + for (int i = 0; i < entries; ++i) { + uint8 id = file->readByte(); + + Iterator timer = Common::find_if(_timers.begin(), _timers.end(), TimerEqual(id)); + if (timer != _timers.end()) { + timer->enabled = file->readByte(); + timer->countdown = file->readSint32BE(); + timer->lastUpdate = file->readSint32BE(); + } else { + warning("Loading timer data for non existing timer %d", id); + file->seek(7, SEEK_CUR); + } + } + + resync(); + } +} + +void TimerManager::saveDataToFile(Common::OutSaveFile *file) const { + debugC(9, kDebugLevelTimer, "TimerManager::saveDataToFile(%p)", (const void*)file); + + 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()); + } +} + +} // end of namespace Kyra diff --git a/engines/kyra/timer.h b/engines/kyra/timer.h new file mode 100644 index 0000000000..1edeb92a42 --- /dev/null +++ b/engines/kyra/timer.h @@ -0,0 +1,93 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#ifndef KYRA_TIMER_H +#define KYRA_TIMER_H + +#include "kyra/kyra.h" +#include "kyra/util.h" + +#include "common/list.h" + +namespace Common { +class InSaveFile; +class OutSaveFile; +} // end of namespace Common + +namespace Kyra { + +typedef Functor1<int, void> TimerFunc; + +struct TimerEntry { + uint8 id; + int32 countdown; + int8 enabled; + + int32 lastUpdate; + uint32 nextRun; + + TimerFunc *func; +}; + +class TimerManager { +public: + TimerManager(KyraEngine *vm, OSystem *sys) : _vm(vm), _system(sys), _timers(), _nextRun(0) {} + ~TimerManager() { reset(); } + + void reset(); + + void addTimer(uint8 id, TimerFunc *func, int countdown, bool enabled); + + int count() const { return _timers.size(); } + + void update(); + + void resetNextRun(); + + void setCountdown(uint8 id, int32 countdown); + void setDelay(uint8 id, int32 countdown); + int32 getDelay(uint8 id) const; + + bool isEnabled(uint8 id) const; + void enable(uint8 id); + void disable(uint8 id); + + void resync(); + + void loadDataFromFile(Common::InSaveFile *file, int version); + void saveDataToFile(Common::OutSaveFile *file) const; +private: + KyraEngine *_vm; + OSystem *_system; + Common::List<TimerEntry> _timers; + uint32 _nextRun; + + typedef Common::List<TimerEntry>::iterator Iterator; + typedef Common::List<TimerEntry>::const_iterator CIterator; +}; + +} // end of namespace Kyra + +#endif diff --git a/engines/kyra/timer_v1.cpp b/engines/kyra/timer_v1.cpp index 0b5184fe5a..55dab4413f 100644 --- a/engines/kyra/timer_v1.cpp +++ b/engines/kyra/timer_v1.cpp @@ -11,7 +11,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License @@ -23,126 +23,58 @@ * */ +#include "kyra/kyra.h" #include "kyra/kyra_v1.h" #include "kyra/screen.h" #include "kyra/animator_v1.h" +#include "kyra/timer.h" #include "common/system.h" namespace Kyra { -void KyraEngine_v1::setupTimers() { - debugC(9, kDebugLevelMain, "KyraEngine_v1::setupTimers()"); - memset(_timers, 0, sizeof(_timers)); - - for (int i = 0; i < 34; i++) - _timers[i].active = 1; - - _timers[0].func = _timers[1].func = _timers[2].func = _timers[3].func = _timers[4].func = 0; //Unused. - _timers[5].func = _timers[6].func = _timers[7].func = _timers[8].func = _timers[9].func = 0; //_nullsub51; - _timers[10].func = _timers[11].func = _timers[12].func = _timers[13].func = 0; //_nullsub50; - _timers[14].func = &KyraEngine_v1::timerCheckAnimFlag2; //_nullsub52; - _timers[15].func = &KyraEngine_v1::timerUpdateHeadAnims; //_nullsub48; - _timers[16].func = &KyraEngine_v1::timerSetFlags1; //_nullsub47; - _timers[17].func = 0; //sub_15120; - _timers[18].func = &KyraEngine_v1::timerCheckAnimFlag1; //_nullsub53; - _timers[19].func = &KyraEngine_v1::timerRedrawAmulet; //_nullsub54; - _timers[20].func = 0; //offset _timerDummy1 - _timers[21].func = 0; //sub_1517C; - _timers[22].func = 0; //offset _timerDummy2 - _timers[23].func = 0; //offset _timerDummy3, - _timers[24].func = 0; //_nullsub45; - _timers[25].func = 0; //offset _timerDummy4 - _timers[26].func = 0; //_nullsub46; - _timers[27].func = 0; //offset _timerDummy5, - _timers[28].func = 0; //offset _timerDummy6 - _timers[29].func = 0; //offset _timerDummy7, - _timers[30].func = 0; //offset _timerDummy8, - _timers[31].func = &KyraEngine_v1::timerFadeText; //sub_151F8; - _timers[32].func = &KyraEngine_v1::updateAnimFlag1; //_nullsub61; - _timers[33].func = &KyraEngine_v1::updateAnimFlag2; //_nullsub62; - - _timers[0].countdown = _timers[1].countdown = _timers[2].countdown = _timers[3].countdown = _timers[4].countdown = -1; - _timers[5].countdown = 5; - _timers[6].countdown = 7; - _timers[7].countdown = 8; - _timers[8].countdown = 9; - _timers[9].countdown = 7; - _timers[10].countdown = _timers[11].countdown = _timers[12].countdown = _timers[13].countdown = 420; - _timers[14].countdown = 600; - _timers[15].countdown = 11; - _timers[16].countdown = _timers[17].countdown = 7200; - _timers[18].countdown = _timers[19].countdown = 600; - _timers[20].countdown = 7200; - _timers[21].countdown = 18000; - _timers[22].countdown = 7200; - _timers[23].countdown = _timers[24].countdown = _timers[25].countdown = _timers[26].countdown = _timers[27].countdown = 10800; - _timers[28].countdown = 21600; - _timers[29].countdown = 7200; - _timers[30].countdown = 10800; - _timers[31].countdown = -1; - _timers[32].countdown = 9; - _timers[33].countdown = 3; -} - -void KyraEngine_v1::updateGameTimers() { - debugC(9, kDebugLevelMain, "KyraEngine_v1::updateGameTimers()"); - - if (_system->getMillis() < _timerNextRun) - return; - - _timerNextRun += 99999; - - for (int i = 0; i < 34; i++) { - if (_timers[i].active && _timers[i].countdown > -1) { - if (_timers[i].nextRun <=_system->getMillis()) { - if (i > 4 && _timers[i].func) - (*this.*_timers[i].func)(i); - - _timers[i].nextRun = _system->getMillis() + _timers[i].countdown * _tickLength; - } - } - if (_timers[i].nextRun < _timerNextRun) - _timerNextRun = _timers[i].nextRun; - } -} - -void KyraEngine_v1::clearNextEventTickCount() { - debugC(9, kDebugLevelMain, "KyraEngine_v1::clearNextEventTickCount()"); - _timerNextRun = 0; -} - -void KyraEngine_v1::setTimerDelay(uint8 timer, int32 countdown) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::setTimerDelay(%i, %d)", timer, countdown); - _timers[timer].countdown = countdown; -} -int16 KyraEngine_v1::getTimerDelay(uint8 timer) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::getTimerDelay(%i)", timer); - return _timers[timer].countdown; -} +#define TimerV1(x) new Functor1Mem<int, void, KyraEngine_v1>(this, &KyraEngine_v1::x) -void KyraEngine_v1::setTimerCountdown(uint8 timer, int32 countdown) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::setTimerCountdown(%i, %i)", timer, countdown); - _timers[timer].countdown = countdown; - _timers[timer].nextRun = _system->getMillis() + countdown * _tickLength; +void KyraEngine_v1::setupTimers() { + debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v1::setupTimers()"); - uint32 nextRun = _system->getMillis() + countdown * _tickLength; - if (nextRun < _timerNextRun) - _timerNextRun = nextRun; -} + for (int i = 0; i <= 4; ++i) + _timer->addTimer(i, 0, -1, 1); -void KyraEngine_v1::enableTimer(uint8 timer) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::enableTimer(%i)", timer); - _timers[timer].active = 1; -} + _timer->addTimer(5, 0, 5, 1); + _timer->addTimer(6, 0, 7, 1); + _timer->addTimer(7, 0, 8, 1); + _timer->addTimer(8, 0, 9, 1); + _timer->addTimer(9, 0, 7, 1); + + for (int i = 10; i <= 13; ++i) + _timer->addTimer(i, 0, 420, 1); + + _timer->addTimer(14, TimerV1(timerCheckAnimFlag2), 600, 1); + _timer->addTimer(15, TimerV1(timerUpdateHeadAnims), 11, 1); + _timer->addTimer(16, TimerV1(timerSetFlags1), 7200, 1); + _timer->addTimer(17, 0 /*sub_15120*/, 7200, 1); + _timer->addTimer(18, TimerV1(timerCheckAnimFlag1), 600, 1); + _timer->addTimer(19, TimerV1(timerRedrawAmulet), 600, 1); + + _timer->addTimer(20, 0, 7200, 1); + _timer->addTimer(21, 0/*sub_1517C*/, 18000, 1); + _timer->addTimer(22, 0, 7200, 1); + + for (int i = 23; i <= 27; ++i) + _timer->addTimer(i, 0, 10800, 1); -void KyraEngine_v1::disableTimer(uint8 timer) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::disableTimer(%i)", timer); - _timers[timer].active = 0; + _timer->addTimer(28, 0, 21600, 1); + _timer->addTimer(29, 0, 7200, 1); + _timer->addTimer(30, 0, 10800, 1); + + _timer->addTimer(31, TimerV1(timerFadeText), -1, 1); + _timer->addTimer(32, TimerV1(updateAnimFlag1), 9, 1); + _timer->addTimer(33, TimerV1(updateAnimFlag2), 3, 1); } void KyraEngine_v1::timerUpdateHeadAnims(int timerNum) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::timerUpdateHeadAnims(%i)", timerNum); + debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v1::timerUpdateHeadAnims(%i)", timerNum); static int8 currentFrame = 0; static const int8 frameTable[] = {4, 5, 4, 5, 4, 5, 0, 1, 4, 5, 4, 4, 6, 4, 8, 1, 9, 4, -1}; @@ -161,7 +93,7 @@ void KyraEngine_v1::timerUpdateHeadAnims(int timerNum) { } void KyraEngine_v1::timerSetFlags1(int timerNum) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::timerSetFlags(%i)", timerNum); + debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v1::timerSetFlags(%i)", timerNum); if (_currentCharacter->sceneId == 0x1C) return; @@ -180,112 +112,68 @@ void KyraEngine_v1::timerSetFlags1(int timerNum) { } void KyraEngine_v1::timerFadeText(int timerNum) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::timerFadeText(%i)", timerNum); + debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v1::timerFadeText(%i)", timerNum); _fadeText = true; } void KyraEngine_v1::updateAnimFlag1(int timerNum) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::updateAnimFlag1(%d)", timerNum); + debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v1::updateAnimFlag1(%d)", timerNum); if (_brandonStatusBit & 2) { _brandonStatusBit0x02Flag = 1; } } void KyraEngine_v1::updateAnimFlag2(int timerNum) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::updateAnimFlag2(%d)", timerNum); + debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v1::updateAnimFlag2(%d)", timerNum); if (_brandonStatusBit & 0x20) { _brandonStatusBit0x20Flag = 1; } } void KyraEngine_v1::setTextFadeTimerCountdown(int16 countdown) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::setTextFadeTimerCountdown(%i)", countdown); - //if (countdown == -1) - //countdown = 32000; + debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v1::setTextFadeTimerCountdown(%i)", countdown); + if (countdown == -1) + countdown = 32000; - setTimerCountdown(31, countdown*60); + _timer->setCountdown(31, countdown*60); } void KyraEngine_v1::timerSetFlags2(int timerNum) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::timerSetFlags2(%i)", timerNum); + debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v1::timerSetFlags2(%i)", timerNum); if (!((uint32*)(_flagsTable+0x2D))[timerNum]) ((uint32*)(_flagsTable+0x2D))[timerNum] = 1; } void KyraEngine_v1::timerCheckAnimFlag1(int timerNum) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::timerCheckAnimFlag1(%i)", timerNum); + debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v1::timerCheckAnimFlag1(%i)", timerNum); if (_brandonStatusBit & 0x20) { checkAmuletAnimFlags(); - setTimerCountdown(18, -1); + _timer->setCountdown(18, -1); } } void KyraEngine_v1::timerCheckAnimFlag2(int timerNum) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::timerCheckAnimFlag1(%i)", timerNum); + debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v1::timerCheckAnimFlag2(%i)", timerNum); if (_brandonStatusBit & 0x2) { checkAmuletAnimFlags(); - setTimerCountdown(14, -1); - } -} - -void KyraEngine_v1::checkAmuletAnimFlags() { - debugC(9, kDebugLevelMain, "KyraEngine_v1::checkSpecialAnimFlags()"); - if (_brandonStatusBit & 2) { - seq_makeBrandonNormal2(); - setTimerCountdown(19, 300); - } - - if (_brandonStatusBit & 0x20) { - seq_makeBrandonNormal(); - setTimerCountdown(19, 300); + _timer->setCountdown(14, -1); } } void KyraEngine_v1::timerRedrawAmulet(int timerNum) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::timerRedrawAmulet(%i)", timerNum); + debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v1::timerRedrawAmulet(%i)", timerNum); if (queryGameFlag(0xF1)) { drawAmulet(); - setTimerCountdown(19, -1); - } -} - -void KyraEngine_v1::drawAmulet() { - debugC(9, kDebugLevelMain, "KyraEngine_v1::drawAmulet()"); - static const int16 amuletTable1[] = {0x167, 0x162, 0x15D, 0x158, 0x153, 0x150, 0x155, 0x15A, 0x15F, 0x164, 0x145, -1}; - static const int16 amuletTable3[] = {0x167, 0x162, 0x15D, 0x158, 0x153, 0x14F, 0x154, 0x159, 0x15E, 0x163, 0x144, -1}; - static const int16 amuletTable2[] = {0x167, 0x162, 0x15D, 0x158, 0x153, 0x152, 0x157, 0x15C, 0x161, 0x166, 0x147, -1}; - static const int16 amuletTable4[] = {0x167, 0x162, 0x15D, 0x158, 0x153, 0x151, 0x156, 0x15B, 0x160, 0x165, 0x146, -1}; - - resetGameFlag(0xF1); - _screen->hideMouse(); - - int i = 0; - while (amuletTable1[i] != -1) { - if (queryGameFlag(87)) - _screen->drawShape(0, _shapes[amuletTable1[i]], _amuletX[0], _amuletY[0], 0, 0); - - if (queryGameFlag(89)) - _screen->drawShape(0, _shapes[amuletTable2[i]], _amuletX[1], _amuletY[1], 0, 0); - - if (queryGameFlag(86)) - _screen->drawShape(0, _shapes[amuletTable3[i]], _amuletX[2], _amuletY[2], 0, 0); - - if (queryGameFlag(88)) - _screen->drawShape(0, _shapes[amuletTable4[i]], _amuletX[3], _amuletY[3], 0, 0); - - _screen->updateScreen(); - delayWithTicks(3); - i++; + _timer->setCountdown(19, -1); } - _screen->showMouse(); } void KyraEngine_v1::setWalkspeed(uint8 newSpeed) { - debugC(9, kDebugLevelMain, "KyraEngine_v1::setWalkspeed(%i)", newSpeed); + debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v1::setWalkspeed(%i)", newSpeed); static const uint8 speeds[] = {11, 9, 6, 5, 3}; assert(newSpeed < ARRAYSIZE(speeds)); - setTimerDelay(5, speeds[newSpeed]); + _timer->setDelay(5, speeds[newSpeed]); } } // end of namespace Kyra diff --git a/engines/kyra/timer_v2.cpp b/engines/kyra/timer_v2.cpp new file mode 100644 index 0000000000..2db90f6ecc --- /dev/null +++ b/engines/kyra/timer_v2.cpp @@ -0,0 +1,80 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "kyra/kyra_v2.h" +#include "kyra/timer.h" + +namespace Kyra { + +#define TimerV2(x) new Functor1Mem<int, void, KyraEngine_v2>(this, &KyraEngine_v2::x) + +void KyraEngine_v2::setupTimers() { + debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v2::setupTimers()"); + + _timer->addTimer(0, 0, 5, 1); + _timer->addTimer(1, TimerV2(timerFunc2), -1, 1); + _timer->addTimer(2, TimerV2(timerFunc3), 1, 1); + _timer->addTimer(3, TimerV2(timerFunc4), 1, 0); + _timer->addTimer(4, TimerV2(timerFunc5), 1, 0); + _timer->addTimer(5, TimerV2(timerFunc6), 1, 0); +} + +void KyraEngine_v2::timerFunc2(int arg) { + debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v2::timerFunc2(%d)", arg); + if (_shownMessage) + _msgUnk1 = 1; +} + +void KyraEngine_v2::timerFunc3(int arg) { + debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v2::timerFunc3(%d)", arg); + // XXX +} + +void KyraEngine_v2::timerFunc4(int arg) { + debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v2::timerFunc4(%d)", arg); + _timer->disable(3); + setGameFlag(0xD8); +} + +void KyraEngine_v2::timerFunc5(int arg) { + debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v2::timerFunc5(%d)", arg); + // XXX +} + +void KyraEngine_v2::timerFunc6(int arg) { + debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v2::timerFunc6(%d)", arg); + // XXX +} + +void KyraEngine_v2::setTimer1DelaySecs(int secs) { + debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v2::setTimer1DelaySecs(%d)", secs); + + if (secs == -1) + secs = 32000; + + _timer->setCountdown(1, secs * 60); +} + +} // end of namespace Kyra diff --git a/engines/kyra/util.h b/engines/kyra/util.h new file mode 100644 index 0000000000..edb2ca454a --- /dev/null +++ b/engines/kyra/util.h @@ -0,0 +1,61 @@ +/* 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_UTIL_H +#define KYRA_UTIL_H + +#include "common/func.h" + +namespace Kyra { + +template<class Arg, class Res> +struct Functor1 : public Common::UnaryFunction<Arg, Res> { + virtual operator bool() const = 0; + virtual Res operator()(Arg) const = 0; +}; + +template<class Arg, class Res, class T> +class Functor1Mem : public Functor1<Arg, Res> { +public: + typedef Res (T::*FuncType)(Arg); + + Functor1Mem(T *t, const FuncType &func) : _t(t), _func(func) {} + + operator bool() const { return _func != 0; } + Res operator()(Arg v1) const { + return (_t->*_func)(v1); + } +private: + mutable T *_t; + Res (T::*_func)(Arg); +}; + +struct ScriptState; + +typedef Functor1<ScriptState*, int> Opcode; + +} // end of namespace Kyra + +#endif diff --git a/engines/kyra/wsamovie.cpp b/engines/kyra/wsamovie.cpp index f0119101fd..7e9ec9b78b 100644 --- a/engines/kyra/wsamovie.cpp +++ b/engines/kyra/wsamovie.cpp @@ -28,10 +28,11 @@ #include "common/system.h" #include "kyra/kyra.h" +#include "kyra/kyra_v2.h" #include "kyra/screen.h" +#include "kyra/screen_v2.h" #include "kyra/wsamovie.h" - namespace Kyra { WSAMovieV1::WSAMovieV1(KyraEngine *vm) : Movie(vm) {} WSAMovieV1::~WSAMovieV1() { close(); } @@ -132,8 +133,8 @@ void WSAMovieV1::close() { } } -void WSAMovieV1::displayFrame(int frameNum) { - debugC(9, kDebugLevelMovie, "WSAMovieV1::displayFrame(%d)", frameNum); +void WSAMovieV1::displayFrame(int frameNum, ...) { + debugC(9, kDebugLevelMovie, "WSAMovieV1::displayFrame(%d, ...)", frameNum); if (frameNum >= _numFrames || !_opened) return; @@ -234,7 +235,7 @@ void WSAMovieAmiga::close() { WSAMovieV1::close(); } -void WSAMovieAmiga::displayFrame(int frameNum) { +void WSAMovieAmiga::displayFrame(int frameNum, ...) { debugC(9, kDebugLevelMovie, "WSAMovieAmiga::displayFrame(%d)", frameNum); if (frameNum >= _numFrames || !_opened) return; @@ -340,7 +341,7 @@ void WSAMovieAmiga::processFrame(int frameNum, uint8 *dst) { #pragma mark - -WSAMovieV2::WSAMovieV2(KyraEngine *vm) : WSAMovieV1(vm), _xAdd(0), _yAdd(0) {} +WSAMovieV2::WSAMovieV2(KyraEngine_v2 *vm) : WSAMovieV1(vm), _vm(vm), _xAdd(0), _yAdd(0), _oldOff(false) {} int WSAMovieV2::open(const char *filename, int unk1, uint8 *palBuf) { debugC(9, kDebugLevelMovie, "WSAMovieV2::open('%s', %d, %p)", filename, unk1, (const void *)palBuf); @@ -419,5 +420,95 @@ int WSAMovieV2::open(const char *filename, int unk1, uint8 *palBuf) { return _numFrames; } +void WSAMovieV2::displayFrame(int frameNum, ...) { + debugC(9, kDebugLevelMovie, "WSAMovieV2::displayFrame(%d, ...)", frameNum); + if (frameNum >= _numFrames || !_opened) + return; + + uint8 *dst = 0; + if (_flags & WF_OFFSCREEN_DECODE) + dst = _offscreenBuffer; + else + dst = _vm->screen()->getPageRect(_drawPage, _x, _y, _width, _height); + + if (_currentFrame == _numFrames) { + if (!(_flags & WF_NO_FIRST_FRAME)) { + if (_flags & WF_OFFSCREEN_DECODE) + Screen::decodeFrameDelta(dst, _deltaBuffer); + else + Screen::decodeFrameDeltaPage(dst, _deltaBuffer, _width, (_flags & WF_XOR) == 0); + } + _currentFrame = 0; + } + + // try to reduce the number of needed frame operations + int diffCount = ABS(_currentFrame - frameNum); + int frameStep = 1; + int frameCount; + if (_currentFrame < frameNum) { + frameCount = _numFrames - frameNum + _currentFrame; + if (diffCount > frameCount) + frameStep = -1; + else + frameCount = diffCount; + } else { + frameCount = _numFrames - _currentFrame + frameNum; + if (frameCount >= diffCount) { + frameStep = -1; + frameCount = diffCount; + } + } + + // process + if (frameStep > 0) { + uint16 cf = _currentFrame; + while (frameCount--) { + cf += frameStep; + processFrame(cf, dst); + if (cf == _numFrames) + cf = 0; + } + } else { + uint16 cf = _currentFrame; + while (frameCount--) { + if (cf == 0) + cf = _numFrames; + processFrame(cf, dst); + cf += frameStep; + } + } + + // display + _currentFrame = frameNum; + if (_flags & WF_OFFSCREEN_DECODE) { + if (_oldOff) { + // Kyrandia 1 offscreen buffer -> screen copy method of Kyrandia 1, needs to be present + // for our intro code that doesn't supply all the needed parameters for the Kyrandia 2 method + _vm->screen()->copyBlockToPage(_drawPage, _x, _y, _width, _height, _offscreenBuffer); + } else { + // This is the offscreen buffer -> screen copy method of Kyrandia 2 as it's implemented + // in the original, we use this in game + Screen_v2 *screen = _vm->screen_v2(); + int pageBackUp = screen->_curPage; + screen->_curPage = _drawPage; + + va_list args; + va_start(args, frameNum); + + int copyParam = va_arg(args, int); + int plotFunc = (copyParam & 0xFF00) >> 12; + int unk1 = copyParam & 0xFF; + + const uint8 *unkPtr1 = va_arg(args, const uint8*); + const uint8 *unkPtr2 = va_arg(args, const uint8*); + va_end(args); + + screen->copyWsaRect(_x, _y, _width, _height, 0, plotFunc, _offscreenBuffer, unk1, unkPtr1, unkPtr2); + + screen->_curPage = pageBackUp; + } + } +} + } // end of namespace Kyra diff --git a/engines/kyra/wsamovie.h b/engines/kyra/wsamovie.h index a3af9f16b7..0e93bd2a93 100644 --- a/engines/kyra/wsamovie.h +++ b/engines/kyra/wsamovie.h @@ -35,6 +35,7 @@ class SoundHandle; namespace Kyra { class KyraEngine; +class KyraEngine_v2; class Movie { public: @@ -48,7 +49,7 @@ public: virtual int frames() = 0; - virtual void displayFrame(int frameNum) = 0; + virtual void displayFrame(int frameNum, ...) = 0; virtual void setX(int x) { _x = x; } virtual void setY(int y) { _y = y; } @@ -71,7 +72,7 @@ public: virtual int frames() { return _opened ? _numFrames : -1; } - virtual void displayFrame(int frameNum); + virtual void displayFrame(int frameNum, ...); enum WSAFlags { WF_OFFSCREEN_DECODE = 0x10, @@ -101,7 +102,7 @@ public: int open(const char *filename, int offscreen, uint8 *palette); void close(); - void displayFrame(int frameNum); + void displayFrame(int frameNum, ...); private: void processFrame(int frameNum, uint8 *dst); @@ -110,9 +111,11 @@ private: class WSAMovieV2 : public WSAMovieV1 { public: - WSAMovieV2(KyraEngine *vm); + WSAMovieV2(KyraEngine_v2 *vm); int open(const char *filename, int unk1, uint8 *palette); + + virtual void displayFrame(int frameNum, ...); void setX(int x) { _x = x + _xAdd; } void setY(int y) { _y = y + _yAdd; } @@ -122,10 +125,15 @@ public: int width() const { return _width; } int height() const { return _height; } -protected: + // HACK for our intro code + void flagOldOff(bool enabled) { _oldOff = enabled; } +protected: + KyraEngine_v2 *_vm; + int16 _xAdd; int16 _yAdd; + bool _oldOff; // old offscreen copy, HACK for our intro code }; } // end of namespace Kyra |