diff options
author | Paul Gilbert | 2010-07-06 11:33:09 +0000 |
---|---|---|
committer | Paul Gilbert | 2010-07-06 11:33:09 +0000 |
commit | c89fe5f6d56b6d6e11b7d642e85633bc86098ce8 (patch) | |
tree | 47c8ae8910e1bbbf654f60e68caa93ed750d3bdc | |
parent | 3f7dc9e0e2e4d043b2234b7b66981e16eb8a84b1 (diff) | |
download | scummvm-rg350-c89fe5f6d56b6d6e11b7d642e85633bc86098ce8.tar.gz scummvm-rg350-c89fe5f6d56b6d6e11b7d642e85633bc86098ce8.tar.bz2 scummvm-rg350-c89fe5f6d56b6d6e11b7d642e85633bc86098ce8.zip |
Added support for idle character animations
svn-id: r50723
-rw-r--r-- | engines/m4/assets.cpp | 4 | ||||
-rw-r--r-- | engines/m4/assets.h | 4 | ||||
-rw-r--r-- | engines/m4/m4.cpp | 2 | ||||
-rw-r--r-- | engines/m4/mads_player.cpp | 190 | ||||
-rw-r--r-- | engines/m4/mads_player.h | 11 | ||||
-rw-r--r-- | engines/m4/mads_scene.cpp | 8 | ||||
-rw-r--r-- | engines/m4/mads_views.cpp | 13 | ||||
-rw-r--r-- | engines/m4/mads_views.h | 3 |
8 files changed, 205 insertions, 30 deletions
diff --git a/engines/m4/assets.cpp b/engines/m4/assets.cpp index 9cfb7afc4c..23122eb960 100644 --- a/engines/m4/assets.cpp +++ b/engines/m4/assets.cpp @@ -632,9 +632,9 @@ int32 AssetManager::getSpriteFrameCount(int32 hash) { //-------------------------------------------------------------------------- MadsSpriteSetCharInfo::MadsSpriteSetCharInfo(Common::SeekableReadStream *s) { - _frameNumber = s->readByte(); + _totalFrames = s->readByte(); s->skip(1); - _hasIdling = s->readUint16LE() != 0; + _numEntries = s->readUint16LE(); for (int i = 0; i < 16; ++i) _frameList[i] = s->readUint16LE(); diff --git a/engines/m4/assets.h b/engines/m4/assets.h index e9902d8aa6..3ae7fb2e22 100644 --- a/engines/m4/assets.h +++ b/engines/m4/assets.h @@ -106,8 +106,8 @@ class MadsSpriteSetCharInfo { public: MadsSpriteSetCharInfo(Common::SeekableReadStream *s); - int _frameNumber; - int _hasIdling; + int _totalFrames; + int _numEntries; int _frameList2[16]; int _frameList[16]; int _ticksList[16]; diff --git a/engines/m4/m4.cpp b/engines/m4/m4.cpp index f5c6d260a9..a999a6bd5a 100644 --- a/engines/m4/m4.cpp +++ b/engines/m4/m4.cpp @@ -538,6 +538,8 @@ Common::Error MadsEngine::run() { //printf("%s\n----------\n", _globals->loadMessage(i)); if (getGameType() == GType_RexNebular) { + MadsGameLogic::initialiseGlobals(); + _scene = NULL; loadMenu(MAIN_MENU); } else { diff --git a/engines/m4/mads_player.cpp b/engines/m4/mads_player.cpp index 57cb9eefd3..bb7a1b406d 100644 --- a/engines/m4/mads_player.cpp +++ b/engines/m4/mads_player.cpp @@ -38,6 +38,9 @@ MadsPlayer::MadsPlayer() { _direction = 0; _direction2 = 0; _forceRefresh = true; + _stepEnabled = true; + _ticksAmount = 3; + _priorTimer = 0; _visible = true; _priorVisible = false; _visible3 = false; @@ -53,7 +56,7 @@ MadsPlayer::MadsPlayer() { _frameNum = 0; _frameOffset = 0; _unk1 = 0; - _newFrame = 0; + _frameCount = 0; _frameListIndex = 0; _actionIndex = 0; resetActionList(); @@ -154,7 +157,7 @@ void MadsPlayer::update() { if (equal) // Undo the prior expiry of the player sprite - slot.spriteType = SPRITE_ZERO; + s2.spriteType = SPRITE_ZERO; else slotIndex = -1; } @@ -175,13 +178,13 @@ void MadsPlayer::update() { } /** - * Idling animation for player + * Updates the animation frame for the player */ -void MadsPlayer::idle() { +void MadsPlayer::updateFrame() { SpriteAsset &spriteSet = _madsVm->scene()->_spriteSlots.getSprite(_spriteListIdx + _spriteListIdx2); assert(spriteSet._charInfo); - if (!spriteSet._charInfo->_hasIdling) { + if (!spriteSet._charInfo->_numEntries) { _frameNum = 1; } else { _frameListIndex = _actionList[_actionIndex]; @@ -204,7 +207,7 @@ void MadsPlayer::idle() { if (frameIndex == 0) setTicksAmount(); else - _madsVm->scene()->_ticksAmount = spriteSet._charInfo->_ticksList[frameIndex]; + _madsVm->_player._ticksAmount = spriteSet._charInfo->_ticksList[frameIndex]; } } @@ -223,19 +226,103 @@ void MadsPlayer::setupFrame() { _unk1 = MAX(spriteSet._charInfo->_unk1, 100); setTicksAmount(); - _newFrame = spriteSet._charInfo->_frameNumber; - if (_newFrame == 0) - _newFrame = spriteSet.getCount(); + _frameCount = spriteSet._charInfo->_totalFrames; + if (_frameCount == 0) + _frameCount = spriteSet.getCount(); _yScale = spriteSet._charInfo->_yScale; - if ((_frameNum <= 0) || (_frameNum > _newFrame)) + if ((_frameNum <= 0) || (_frameNum > _frameCount)) _frameNum = 1; _forceRefresh = true; } void MadsPlayer::step() { + if (_visible && _stepEnabled && !_moving && (_direction == _direction2) && (_madsVm->_currentTimer >= GET_GLOBAL32(2))) { + if (_actionIndex == 0) { + int randVal = _vm->_random->getRandomNumber(29999); + + if (GET_GLOBAL(0) == SEX_MALE) { + switch (_direction) { + case 1: + case 3: + case 7: + case 9: + if (randVal < 200) { + queueAction(-1, 0); + queueAction(1, 0); + } + break; + + case 2: + if (randVal < 500) { + for (int i = 0; i < 10; ++i) + queueAction((randVal < 250) ? 1 : 2, 0); + } else if (randVal < 750) { + for (int i = 0; i < 5; ++i) + queueAction(1, 0); + queueAction(0, 0); + for (int i = 0; i < 5; ++i) + queueAction(2, 0); + } + break; + + case 4: + case 6: + if (randVal < 500) { + for (int i = 0; i < 10; ++i) + queueAction(1, 0); + } + break; + + case 5: + case 8: + if (randVal < 200) { + queueAction(-1, 0); + queueAction(1, 0); + } + break; + } + } + } + + SET_GLOBAL32(2, GET_GLOBAL32(2) + 6); + } + + if (GET_GLOBAL(138) == 1) { + uint32 diff = _madsVm->_currentTimer - GET_GLOBAL32(142); + if (diff > 60) { + SET_GLOBAL32(144, GET_GLOBAL32(144) + 1); + } else { + SET_GLOBAL32(144, GET_GLOBAL32(144) + diff); + } + + SET_GLOBAL32(142, _madsVm->_currentTimer); + } +} + +void MadsPlayer::nextFrame() { + if (_madsVm->_currentTimer >= (_priorTimer + _ticksAmount)) { + _priorTimer = _madsVm->_currentTimer; + + if (_moving) + move(); + else + idle(); + + // Post update logic + if (_moving) { + ++_frameNum; + if (_frameNum > _frameCount) + _frameNum = 1; + _forceRefresh = true; + } else if (!_forceRefresh) { + idle(); + } + // Final update + update(); + } } int MadsPlayer::getScale(int yp) { @@ -262,9 +349,9 @@ int MadsPlayer::getSpriteSlot() { void MadsPlayer::setTicksAmount() { SpriteAsset &spriteSet = _madsVm->scene()->_spriteSlots.getSprite(_spriteListIdx + _spriteListIdx2); assert(spriteSet._charInfo); - _madsVm->scene()->_ticksAmount = spriteSet._charInfo->_ticksAmount; - if (_madsVm->scene()->_ticksAmount == 0) - _madsVm->scene()->_ticksAmount = 6; + _madsVm->_player._ticksAmount = spriteSet._charInfo->_ticksAmount; + if (_madsVm->_player._ticksAmount == 0) + _madsVm->_player._ticksAmount = 6; } void MadsPlayer::resetActionList() { @@ -279,7 +366,7 @@ int MadsPlayer::queueAction(int action1, int action2) { SpriteAsset &spriteSet = _madsVm->scene()->_spriteSlots.getSprite(_spriteListIdx + _spriteListIdx2); assert(spriteSet._charInfo); - if ((spriteSet._charInfo->_hasIdling) && (_actionIndex < 11)) { + if ((action1 < spriteSet._charInfo->_numEntries) && (_actionIndex < 11)) { ++_actionIndex; _actionList[_actionIndex] = action1; _actionList2[_actionIndex] = action2; @@ -289,4 +376,79 @@ int MadsPlayer::queueAction(int action1, int action2) { return true; } +void MadsPlayer::idle() { + if (_direction != _direction2) { + // The direction has changed, so reset for new direction + dirChanged(); + return; + } + + SpriteAsset &spriteSet = _madsVm->scene()->_spriteSlots.getSprite(_spriteListIdx + _spriteListIdx2); + assert(spriteSet._charInfo); + if (spriteSet._charInfo->_numEntries == 0) + // No entries, so exit immediately + return; + + int frameIndex = ABS(_frameListIndex); + int direction = (_frameListIndex < 0) ? -1 : 1; + + if (frameIndex >= spriteSet._charInfo->_numEntries) + // Reset back to the start of the list + _frameListIndex = 0; + else { + _frameNum += direction; + _forceRefresh = true; + + if (spriteSet._charInfo->_frameList2[frameIndex] < _frameNum) { + _unk3 = _unk2; + updateFrame(); + } + if (spriteSet._charInfo->_frameList[frameIndex] < _frameNum) { + _unk3 = _unk2; + updateFrame(); + } + } +} + +void MadsPlayer::move() { + // TODO: Handle player movement +} + +void MadsPlayer::dirChanged() { + int dirIndex = 0, dirIndex2 = 0; + int newDir = 0, newDir2 = 0; + + if (_direction != _direction2) { + // Find the index for the given direction in the player direction list + int tempDir = _direction; + do { + ++dirIndex; + newDir += tempDir; + tempDir = _directionListIndexes[tempDir + 10]; + } while (tempDir != _direction2); + } + + + if (_direction != _direction2) { + // Find the index for the given direction in the player direction list + int tempDir = _direction; + do { + ++dirIndex2; + newDir2 += tempDir; + tempDir = _directionListIndexes[tempDir + 10]; + } while (tempDir != _direction2); + } + + int diff = dirIndex - dirIndex2; + if (diff == 0) + diff = newDir - newDir2; + + _direction = (diff >= 0) ? _directionListIndexes[_direction] : _directionListIndexes[_direction + 10]; + setupFrame(); + if ((_direction == _direction2) && !_moving) + updateFrame(); + + _priorTimer += 1; +} + } // End of namespace M4 diff --git a/engines/m4/mads_player.h b/engines/m4/mads_player.h index 7285796309..7db45cae43 100644 --- a/engines/m4/mads_player.h +++ b/engines/m4/mads_player.h @@ -39,13 +39,19 @@ private: void setTicksAmount(); void resetActionList(); int queueAction(int v0, int v1); + void idle(); + void move(); + void dirChanged(); public: char _spritesPrefix[16]; int _spriteSetCount; bool _spriteSetsPresent[8]; Common::Point _playerPos; Common::Point _destPos; + uint32 _priorTimer; + uint _ticksAmount; int16 _direction, _direction2; + bool _stepEnabled; bool _visible, _priorVisible; bool _visible3; bool _forceRefresh; @@ -57,7 +63,7 @@ public: uint16 _frameOffset, _frameNum; bool _moving; int _unk1; - int _newFrame; + int _frameCount; int _frameListIndex; int _actionIndex; int _actionList[12]; @@ -71,9 +77,10 @@ public: bool loadSprites(const char *prefix); void update(); - void idle(); + void updateFrame(); void setupFrame(); void step(); + void nextFrame(); }; } // End of namespace M4 diff --git a/engines/m4/mads_scene.cpp b/engines/m4/mads_scene.cpp index 66883dd13c..3e838fc1c0 100644 --- a/engines/m4/mads_scene.cpp +++ b/engines/m4/mads_scene.cpp @@ -167,7 +167,7 @@ void MadsScene::loadScene(int sceneNumber) { _madsVm->_player._destPos = _madsVm->_player._destPos; _madsVm->_player._direction2 = _madsVm->_player._direction; _madsVm->_player.setupFrame(); - _madsVm->_player.idle(); + _madsVm->_player.updateFrame(); // Purge resources _vm->res()->purge(); @@ -337,9 +337,15 @@ void MadsScene::updateState() { // Step through the scene _sceneLogic.sceneStep(); + _madsVm->_player.step(); + _madsVm->_player._unk3 = 0; + if (_abortTimersMode == ABORTMODE_1) _abortTimers = 0; + // Handle updating the player frame + _madsVm->_player.nextFrame(); + if ((_activeAnimation) && !_abortTimers) { _activeAnimation->update(); if (((MadsAnimation *) _activeAnimation)->freeFlag()) { diff --git a/engines/m4/mads_views.cpp b/engines/m4/mads_views.cpp index 580f54b1c0..d7e6435b14 100644 --- a/engines/m4/mads_views.cpp +++ b/engines/m4/mads_views.cpp @@ -426,15 +426,15 @@ int MadsKernelMessageList::add(const Common::Point &pt, uint fontColour, uint8 f for (int i = 0; i < 3; ++i) rec.actionNouns[i] = _madsVm->globals()->actionNouns[i]; - if (flags & KMSG_OWNER_TIMEOUT) - rec.frameTimer = _owner._ticksAmount + _owner._newTimeout; + if (flags & KMSG_PLAYER_TIMEOUT) + rec.frameTimer = _madsVm->_player._ticksAmount + _madsVm->_player._priorTimer; return idx; } int MadsKernelMessageList::addQuote(int quoteId, int abortTimers, uint32 timeout) { const char *quoteStr = _madsVm->globals()->getQuote(quoteId); - return add(Common::Point(0, 0), 0x1110, KMSG_OWNER_TIMEOUT | KMSG_CENTER_ALIGN, abortTimers, timeout, quoteStr); + return add(Common::Point(0, 0), 0x1110, KMSG_PLAYER_TIMEOUT | KMSG_CENTER_ALIGN, abortTimers, timeout, quoteStr); } void MadsKernelMessageList::scrollMessage(int msgIndex, int numTicks, bool quoted) { @@ -450,8 +450,8 @@ void MadsKernelMessageList::scrollMessage(int msgIndex, int numTicks, bool quote _entries[msgIndex].asciiChar = *msgP; _entries[msgIndex].asciiChar2 = *(msgP + 1); - if (_entries[msgIndex].flags & KMSG_OWNER_TIMEOUT) - _entries[msgIndex].frameTimer2 = _owner._ticksAmount + _owner._newTimeout; + if (_entries[msgIndex].flags & KMSG_PLAYER_TIMEOUT) + _entries[msgIndex].frameTimer2 = _madsVm->_player._ticksAmount + _madsVm->_player._priorTimer; _entries[msgIndex].frameTimer = _entries[msgIndex].frameTimer2; } @@ -545,7 +545,7 @@ void MadsKernelMessageList::processText(int msgIndex) { } } - if (msg.flags & KMSG_OWNER_TIMEOUT) { + if (msg.flags & KMSG_PLAYER_TIMEOUT) { if (word_8469E != 0) { // TODO: Figure out various flags } else { @@ -1211,7 +1211,6 @@ MadsView::MadsView(View *view): _view(view), _dynamicHotspots(*this), _sequenceL _kernelMessages(*this), _spriteSlots(*this), _dirtyAreas(*this), _textDisplay(*this) { _textSpacing = -1; - _ticksAmount = 3; _newTimeout = 0; _abortTimers = 0; _abortTimers2 = 0; diff --git a/engines/m4/mads_views.h b/engines/m4/mads_views.h index ead6ae94bf..0604ae1ee1 100644 --- a/engines/m4/mads_views.h +++ b/engines/m4/mads_views.h @@ -149,7 +149,7 @@ public: #define TIMED_TEXT_SIZE 10 #define INDEFINITE_TIMEOUT 9999999 -enum KernelMessageFlags {KMSG_QUOTED = 1, KMSG_OWNER_TIMEOUT = 2, KMSG_SEQ_ENTRY = 4, KMSG_SCROLL = 8, KMSG_RIGHT_ALIGN = 0x10, +enum KernelMessageFlags {KMSG_QUOTED = 1, KMSG_PLAYER_TIMEOUT = 2, KMSG_SEQ_ENTRY = 4, KMSG_SCROLL = 8, KMSG_RIGHT_ALIGN = 0x10, KMSG_CENTER_ALIGN = 0x20, KMSG_EXPIRE = 0x40, KMSG_ACTIVE = 0x80}; class MadsKernelMessageEntry { @@ -395,7 +395,6 @@ public: MadsDirtyAreas _dirtyAreas; int _textSpacing; - int _ticksAmount; uint32 _newTimeout; int _abortTimers; int8 _abortTimers2; |