diff options
author | Johannes Schickel | 2008-04-23 19:24:02 +0000 |
---|---|---|
committer | Johannes Schickel | 2008-04-23 19:24:02 +0000 |
commit | 69bdd29976738b246247adfdc399295cf006b943 (patch) | |
tree | 55a1860775a9d978fd4449f86d30fa661a6bcf7e | |
parent | 1267ed09db3fa264822d321112a46957adc52875 (diff) | |
download | scummvm-rg350-69bdd29976738b246247adfdc399295cf006b943.tar.gz scummvm-rg350-69bdd29976738b246247adfdc399295cf006b943.tar.bz2 scummvm-rg350-69bdd29976738b246247adfdc399295cf006b943.zip |
- Implemented idle animation/talk handling in kyra3
- Implemented opcodes: 110: o3_runTemporaryScript
- fixed idle animation handling in kyra2
svn-id: r31673
-rw-r--r-- | engines/kyra/animator_v3.cpp | 100 | ||||
-rw-r--r-- | engines/kyra/kyra_v2.cpp | 10 | ||||
-rw-r--r-- | engines/kyra/kyra_v3.cpp | 79 | ||||
-rw-r--r-- | engines/kyra/kyra_v3.h | 24 | ||||
-rw-r--r-- | engines/kyra/scene_v3.cpp | 4 | ||||
-rw-r--r-- | engines/kyra/script_v3.cpp | 14 | ||||
-rw-r--r-- | engines/kyra/text_v3.cpp | 4 | ||||
-rw-r--r-- | engines/kyra/timer_v3.cpp | 5 |
8 files changed, 226 insertions, 14 deletions
diff --git a/engines/kyra/animator_v3.cpp b/engines/kyra/animator_v3.cpp index 67b6e2ac2e..31212e631a 100644 --- a/engines/kyra/animator_v3.cpp +++ b/engines/kyra/animator_v3.cpp @@ -505,5 +505,105 @@ void KyraEngine_v3::resetCharacterAnimDim() { _charBackUpWidth = _charBackUpHeight = -1; } +void KyraEngine_v3::showIdleAnim() { + debugC(9, kDebugLevelMain | kDebugLevelAnimator, "KyraEngine_v3::showIdleAnim()"); + + if (_mainCharacter.sceneId == 20 || _mainCharacter.sceneId == 21 + || _mainCharacter.sceneId == 12 || _mainCharacter.sceneId == 11) + return; + + if (_mainCharacter.animFrame == 87) + return; + + if (!_nextIdleType && !talkObjectsInCurScene()) { + malcolmRandomChat(); + } else { + static const char *facingTable[] = { + "A", "R", "R", "FR", "FX", "FL", "L", "L" + }; + + char filename[14]; + snprintf(filename, 14, "MI0%s%.02d.EMC", facingTable[_mainCharacter.facing], _malcolmShapes); + + if (_res->exists(filename)) + runTemporaryScript(filename, 1, 1, 1, 1); + } + + _nextIdleType = !_nextIdleType; +} + +int KyraEngine_v3::initNewShapes(uint8 *filedata) { + debugC(9, kDebugLevelAnimator, "KyraEngine_v3::initNewShapes(%p)", (const void*)filedata); + const int lastEntry = MIN(_newShapeLastEntry, 41); + for (int i = 0; i < lastEntry; ++i) + _gameShapes[9+i] = _screen->getPtrToShape(filedata, i); + return lastEntry; +} + +void KyraEngine_v3::processNewShapes(int allowSkip, int resetChar) { + debugC(9, kDebugLevelAnimator, "KyraEngine_v3::processNewShapes(%d, %d)", allowSkip, resetChar); + setCharacterAnimDim(_newShapeWidth, _newShapeHeight); + + _scriptInterpreter->initScript(&_temporaryScriptState, &_temporaryScriptData); + _scriptInterpreter->startScript(&_temporaryScriptState, 1); + + resetSkipFlag(); + + while (_scriptInterpreter->validScript(&_temporaryScriptState)) { + _temporaryScriptExecBit = false; + while (_scriptInterpreter->validScript(&_temporaryScriptState) && !_temporaryScriptExecBit) + _scriptInterpreter->runScript(&_temporaryScriptState); + + if (_newShapeAnimFrame < 0) + continue; + + _mainCharacter.animFrame = _newShapeAnimFrame + 9; + updateCharacterAnim(0); + if (_chatText) + updateWithText(); + else + update(); + + uint32 delayEnd = _system->getMillis() + _newShapeDelay * _tickLength; + + while ((!skipFlag() || !allowSkip) && _system->getMillis() < delayEnd) { + if (_chatText) + updateWithText(); + else + update(); + + delay(10); + } + + if (skipFlag()) + resetSkipFlag(); + } + + if (resetChar) { + if (_newShapeFlag >= 0) { + _mainCharacter.animFrame = _newShapeFlag + 9; + updateCharacterAnim(0); + if (_chatText) + updateWithText(); + else + update(); + } + + _mainCharacter.animFrame = _characterFrameTable[_mainCharacter.facing]; + updateCharacterAnim(0); + } + + _newShapeFlag = -1; + resetCharacterAnimDim(); +} + +void KyraEngine_v3::resetNewShapes(int count, uint8 *filedata) { + debugC(9, kDebugLevelAnimator, "KyraEngine_v3::resetNewShapes(%d, %p)", count, (const void*)filedata); + for (int i = 0; i < count; ++i) + _gameShapes[9+i] = 0; + delete [] filedata; + setNextIdleAnimTimer(); +} + } // end of namespace Kyra diff --git a/engines/kyra/kyra_v2.cpp b/engines/kyra/kyra_v2.cpp index 93dfc73109..1d61a12b8b 100644 --- a/engines/kyra/kyra_v2.cpp +++ b/engines/kyra/kyra_v2.cpp @@ -1268,8 +1268,12 @@ void KyraEngine_v2::runTemporaryScript(const char *filename, int unk1, int unk2, uint8 *fileData = 0; if (newShapes) { + if (_newShapeFiledata) { + resetNewShapes(_newShapeCount, _newShapeFiledata); + _newShapeFiledata = 0; + _newShapeCount = 0; + } _newShapeFiledata = _res->fileData(_newShapeFilename, 0); - assert(_newShapeFiledata); } fileData = _newShapeFiledata; @@ -1660,7 +1664,7 @@ void KyraEngine_v2::processNewShapes(int unk1, int unk2) { uint32 delayEnd = _system->getMillis() + _newShapeDelay * _tickLength; - while ((!skipFlag() || unk1) && _system->getMillis() < delayEnd) { + while ((!skipFlag() || !unk1) && _system->getMillis() < delayEnd) { if (_chatText) updateWithText(); else @@ -1687,8 +1691,6 @@ void KyraEngine_v2::processNewShapes(int unk1, int unk2) { updateCharacterAnim(0); } - resetSkipFlag(); - _newShapeFlag = -1; resetCharacterAnimDim(); } diff --git a/engines/kyra/kyra_v3.cpp b/engines/kyra/kyra_v3.cpp index 08b006568d..4e490f2711 100644 --- a/engines/kyra/kyra_v3.cpp +++ b/engines/kyra/kyra_v3.cpp @@ -121,6 +121,10 @@ KyraEngine_v3::KyraEngine_v3(OSystem *system, const GameFlags &flags) : KyraEngi memset(&_dialogScriptState, 0, sizeof(_dialogScriptState)); _dialogScriptFuncStart = _dialogScriptFuncProc = _dialogScriptFuncEnd = 0; _malcolmsSpirit = 1; + _nextIdleAnim = 0; + _nextIdleType = false; + _newShapeFlag = -1; + _newShapeFiledata = 0; } KyraEngine_v3::~KyraEngine_v3() { @@ -177,6 +181,7 @@ KyraEngine_v3::~KyraEngine_v3() { delete _cnvFile; delete _dlgBuffer; delete [] _stringBuffer; + delete [] _newShapeFiledata; } int KyraEngine_v3::init() { @@ -568,7 +573,7 @@ void KyraEngine_v3::startup() { _talkObjectList = new TalkObject[88]; memset(_talkObjectList, 0, sizeof(TalkObject)*88); for (int i = 0; i < 88; ++i) - _talkObjectList[i].unk14 = -1; + _talkObjectList[i].sceneId = 0xFF; musicUpdate(0); updateMalcolmShapes(); @@ -1008,7 +1013,10 @@ void KyraEngine_v3::runLoop() { _runFlag = true; while (_runFlag && !_quitFlag) { //XXX deathHandler - //XXX + + if (_system->getMillis() >= _nextIdleAnim) + showIdleAnim(); + int inputFlag = checkInput(0/*_mainButtonList*/); removeInputTop(); @@ -1029,7 +1037,7 @@ void KyraEngine_v3::handleInput(int x, int y) { debugC(9, kDebugLevelMain, "KyraEngine_v3::handleInput(%d, %d)", x, y); if (_inventoryState) return; - //setNextIdleAnimTimer(); + setNextIdleAnimTimer(); if (_unk5) { _unk5 = 0; @@ -1044,7 +1052,7 @@ void KyraEngine_v3::handleInput(int x, int y) { return; } - //setNextIdleAnimTimer(); + setNextIdleAnimTimer(); int skip = 0; @@ -1535,6 +1543,69 @@ void KyraEngine_v3::getTableEntry(Common::SeekableReadStream *stream, int id, ch #pragma mark - +bool KyraEngine_v3::talkObjectsInCurScene() { + debugC(9, kDebugLevelMain, "KyraEngine_v3::talkObjectsInCurScene()"); + + for (int i = 0; i < 88; ++i) { + if (_talkObjectList[i].sceneId == _mainCharacter.sceneId) + return true; + } + + return false; +} + +#pragma mark - + +void KyraEngine_v3::runTemporaryScript(const char *filename, int allowSkip, int resetChar, int newShapes, int shapeUnload) { + debugC(9, kDebugLevelMain, "KyraEngine_v3::runTemporaryScript('%s', %d, %d, %d, %d)", filename, allowSkip, resetChar, newShapes, shapeUnload); + memset(&_temporaryScriptData, 0, sizeof(_temporaryScriptData)); + memset(&_temporaryScriptState, 0, sizeof(_temporaryScriptState)); + + if (!_scriptInterpreter->loadScript(filename, &_temporaryScriptData, &_opcodesTemporary)) + error("Couldn't load temporary script '%s'", filename); + + _scriptInterpreter->initScript(&_temporaryScriptState, &_temporaryScriptData); + _scriptInterpreter->startScript(&_temporaryScriptState, 0); + + _newShapeFlag = -1; + + while (_scriptInterpreter->validScript(&_temporaryScriptState)) + _scriptInterpreter->runScript(&_temporaryScriptState); + + uint8 *fileData = 0; + + if (newShapes) { + if (_newShapeFiledata) { + resetNewShapes(_newShapeCount, _newShapeFiledata); + _newShapeFiledata = 0; + _newShapeCount = 0; + } + _newShapeFiledata = _res->fileData(_newShapeFilename, 0); + } + + fileData = _newShapeFiledata; + + if (!fileData) { + _scriptInterpreter->unloadScript(&_temporaryScriptData); + return; + } + + if (newShapes) + _newShapeCount = initNewShapes(fileData); + + processNewShapes(allowSkip, resetChar); + + if (shapeUnload) { + resetNewShapes(_newShapeCount, fileData); + _newShapeCount = 0; + _newShapeFiledata = 0; + } + + _scriptInterpreter->unloadScript(&_temporaryScriptData); +} + +#pragma mark - + Movie *KyraEngine_v3::createWSAMovie() { WSAMovieV2 *movie = new WSAMovieV2(this, _screen); assert(movie); diff --git a/engines/kyra/kyra_v3.h b/engines/kyra/kyra_v3.h index 2b4e9c478e..daba7a7d56 100644 --- a/engines/kyra/kyra_v3.h +++ b/engines/kyra/kyra_v3.h @@ -160,6 +160,9 @@ private: void timerRunSceneScript7(int arg); void timerFleaDeath(int arg); + uint32 _nextIdleAnim; + void setNextIdleAnimTimer(); + // pathfinder int *_moveFacingTable; int _pathfinderFlag; @@ -230,6 +233,9 @@ private: void setCharacterAnimDim(int w, int h); void resetCharacterAnimDim(); + bool _nextIdleType; + void showIdleAnim(); + // interface uint8 *_interface; uint8 *_interfaceCommandLine; @@ -463,11 +469,13 @@ private: int8 sceneScript; int16 x, y; uint8 color; - int8 unk14; + uint8 sceneId; }; TalkObject *_talkObjectList; + bool talkObjectsInCurScene(); + // chat int _vocHigh; @@ -546,6 +554,11 @@ private: int o3t_defineNewShapes(ScriptState *script); int o3t_setCurrentFrame(ScriptState *script); + ScriptData _temporaryScriptData; + ScriptState _temporaryScriptState; + + void runTemporaryScript(const char *filename, int allowSkip, int resetChar, int newShapes, int shapeUnload); + // special shape code char _newShapeFilename[13]; int _newShapeLastEntry; @@ -555,6 +568,14 @@ private: int _newShapeAnimFrame; int _newShapeDelay; + int _newShapeFlag; + uint8 *_newShapeFiledata; + int _newShapeCount; + + int initNewShapes(uint8 *filedata); + void processNewShapes(int allowSkip, int resetChar); + void resetNewShapes(int count, uint8 *filedata); + // unk uint8 *_costPalBuffer; uint8 *_screenBuffer; @@ -623,6 +644,7 @@ private: int o3_blockOutRegion(ScriptState *script); int o3_getRand(ScriptState *script); int o3_defineRoomEntrance(ScriptState *script); + int o3_runTemporaryScript(ScriptState *script); int o3_setSpecialSceneScriptRunTime(ScriptState *script); int o3_defineSceneAnim(ScriptState *script); int o3_updateSceneAnim(ScriptState *script); diff --git a/engines/kyra/scene_v3.cpp b/engines/kyra/scene_v3.cpp index 3e2864375c..fabed9dfb9 100644 --- a/engines/kyra/scene_v3.cpp +++ b/engines/kyra/scene_v3.cpp @@ -158,7 +158,9 @@ void KyraEngine_v3::enterNewScene(uint16 sceneId, int facing, int unk1, int unk2 } else { if (!--_enterNewSceneLock) _unk5 = 0; - //XXX + + setNextIdleAnimTimer(); + if (_itemInHand <= 0) { _itemInHand = -1; _handItemSet = -1; diff --git a/engines/kyra/script_v3.cpp b/engines/kyra/script_v3.cpp index f74a9f2417..b5261f16a1 100644 --- a/engines/kyra/script_v3.cpp +++ b/engines/kyra/script_v3.cpp @@ -63,7 +63,7 @@ int KyraEngine_v3::o3_defineObject(ScriptState *script) { obj.x = stackPos(4); obj.y = stackPos(5); obj.color = stackPos(6); - obj.unk14 = stackPos(7); + obj.sceneId = stackPos(7); return 0; } @@ -675,6 +675,16 @@ int KyraEngine_v3::o3_defineRoomEntrance(ScriptState *script) { return 0; } +int KyraEngine_v3::o3_runTemporaryScript(ScriptState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_runTemporaryScript(%p) ('%s', %d, %d, %d)", (const void *)script, + stackPosString(0), stackPos(1), stackPos(2), stackPos(3)); + const int newShapes = stackPos(1); + const int unloadShapes = stackPos(2); + const int allowSkip = stackPos(3); + runTemporaryScript(stackPosString(0), allowSkip, (unloadShapes != 0) ? 1 : 0, newShapes, unloadShapes); + return 0; +} + int KyraEngine_v3::o3_setSpecialSceneScriptRunTime(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_setSpecialSceneScriptRunTime(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); assert(stackPos(0) >= 0 && stackPos(0) < 10); @@ -1120,7 +1130,7 @@ void KyraEngine_v3::setupOpcodeTable() { // 0x6c Opcode(o3_dummy); Opcode(o3_defineRoomEntrance); - OpcodeUnImpl(); + Opcode(o3_runTemporaryScript); Opcode(o3_setSpecialSceneScriptRunTime); // 0x70 Opcode(o3_defineSceneAnim); diff --git a/engines/kyra/text_v3.cpp b/engines/kyra/text_v3.cpp index 984adc4cb8..3b8c69177f 100644 --- a/engines/kyra/text_v3.cpp +++ b/engines/kyra/text_v3.cpp @@ -236,7 +236,7 @@ void KyraEngine_v3::objectChat(const char *str, int object, int vocHigh, int voc updateCharacterAnim(0); _chatText = 0; _chatObject = -1; - //setNextIdleAnimTimer(); + setNextIdleAnimTimer(); } void KyraEngine_v3::objectChatInit(const char *str, int object, int vocHigh, int vocLow) { @@ -385,7 +385,7 @@ void KyraEngine_v3::badConscienceChat(const char *str, int vocHigh, int vocLow) if (!_badConscienceShown) return; - //setNextIdleAnimTimer(); + setNextIdleAnimTimer(); _chatVocHigh = _chatVocLow = -1; objectChatInit(str, 1, vocHigh, vocLow); _chatText = str; diff --git a/engines/kyra/timer_v3.cpp b/engines/kyra/timer_v3.cpp index 2211fc6337..4ce73ceaec 100644 --- a/engines/kyra/timer_v3.cpp +++ b/engines/kyra/timer_v3.cpp @@ -84,4 +84,9 @@ void KyraEngine_v3::setCommandLineRestoreTimer(int secs) { _timer->setCountdown(0, secs*60); } +void KyraEngine_v3::setNextIdleAnimTimer() { + debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v3::setNextIdleAnimTimer()"); + _nextIdleAnim = _system->getMillis() + _rnd.getRandomNumberRng(10, 15) * 1000; +} + } // end of namespace Kyra |