aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/kyra/animator_v3.cpp100
-rw-r--r--engines/kyra/kyra_v2.cpp10
-rw-r--r--engines/kyra/kyra_v3.cpp79
-rw-r--r--engines/kyra/kyra_v3.h24
-rw-r--r--engines/kyra/scene_v3.cpp4
-rw-r--r--engines/kyra/script_v3.cpp14
-rw-r--r--engines/kyra/text_v3.cpp4
-rw-r--r--engines/kyra/timer_v3.cpp5
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