diff options
author | lukaslw | 2014-07-04 19:10:22 +0200 |
---|---|---|
committer | lukaslw | 2014-07-04 19:10:22 +0200 |
commit | a838b34b4dc9968c06ab1ebf27efad85d54216a0 (patch) | |
tree | c57108348286ab24841d3fe9ab65e3a861d09fe0 | |
parent | 9d2670416ce81abeca04cb64512f7c5ebc918281 (diff) | |
download | scummvm-rg350-a838b34b4dc9968c06ab1ebf27efad85d54216a0.tar.gz scummvm-rg350-a838b34b4dc9968c06ab1ebf27efad85d54216a0.tar.bz2 scummvm-rg350-a838b34b4dc9968c06ab1ebf27efad85d54216a0.zip |
PRINCE: Background animations update. O_PUTBACKANIM(), O_REMBACKANIM(), O_ANIMUPDATEON(), O_ANIMUPDATEOFF()
-rw-r--r-- | engines/prince/prince.cpp | 175 | ||||
-rw-r--r-- | engines/prince/prince.h | 2 | ||||
-rw-r--r-- | engines/prince/script.cpp | 61 | ||||
-rw-r--r-- | engines/prince/script.h | 5 |
4 files changed, 144 insertions, 99 deletions
diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 0430a967c1..10f90288c0 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -288,6 +288,12 @@ void PrinceEngine::init() { _mainHero->loadAnimSet(1); _secondHero->loadAnimSet(3); + BackgroundAnim tempBackAnim; + tempBackAnim._seq._currRelative = 0; + for (int i = 0; i < kMaxBackAnims; i++) { + _backAnimList.push_back(tempBackAnim); + } + Anim tempAnim; tempAnim._animData = nullptr; tempAnim._shadowData = nullptr; @@ -867,20 +873,22 @@ int PrinceEngine::checkMob(Graphics::Surface *screen, Common::Array<Mob> &mobLis case 2: case 5: //check_ba_mob - if (mob._mask < _backAnimList.size()) { + if (!_backAnimList[mob._mask].backAnims.empty()) { int currentAnim = _backAnimList[mob._mask]._seq._currRelative; Anim &backAnim = _backAnimList[mob._mask].backAnims[currentAnim]; - if (!backAnim._state) { - Common::Rect backAnimRect(backAnim._currX, backAnim._currY, backAnim._currX + backAnim._currW, backAnim._currY + backAnim._currH); - if (backAnimRect.contains(mousePosCamera)) { - int phase = backAnim._showFrame; - int phaseFrameIndex = backAnim._animData->getPhaseFrameIndex(phase); - Graphics::Surface *backAnimSurface = backAnim._animData->getFrame(phaseFrameIndex); - byte pixel = *(byte *)backAnimSurface->getBasePtr(mousePosCamera.x - backAnim._currX, mousePosCamera.y - backAnim._currY); - backAnimSurface->free(); - delete backAnimSurface; - if (pixel != 255) { - break; + if (backAnim._animData != nullptr) { + if (!backAnim._state) { + Common::Rect backAnimRect(backAnim._currX, backAnim._currY, backAnim._currX + backAnim._currW, backAnim._currY + backAnim._currH); + if (backAnimRect.contains(mousePosCamera)) { + int phase = backAnim._showFrame; + int phaseFrameIndex = backAnim._animData->getPhaseFrameIndex(phase); + Graphics::Surface *backAnimSurface = backAnim._animData->getFrame(phaseFrameIndex); + byte pixel = *(byte *)backAnimSurface->getBasePtr(mousePosCamera.x - backAnim._currX, mousePosCamera.y - backAnim._currY); + backAnimSurface->free(); + delete backAnimSurface; + if (pixel != 255) { + break; + } } } } @@ -1264,7 +1272,7 @@ void PrinceEngine::showNormAnims() { Anim &anim = _normAnimList[i]; if (anim._animData != nullptr) { if (!anim._state) { - if (anim._frame == anim._lastFrame - 1) { // TODO - check if correct + if (anim._frame == anim._lastFrame - 1) { if (anim._loopType) { if (anim._loopType == 1) { anim._frame = anim._loopFrame; @@ -1303,88 +1311,97 @@ void PrinceEngine::setBackAnim(Anim &backAnim) { } void PrinceEngine::showBackAnims() { - for (uint i = 0; i < _backAnimList.size(); i++) { + for (uint i = 0; i < kMaxBackAnims; i++) { BAS &seq = _backAnimList[i]._seq; int activeSubAnim = seq._currRelative; - - if (!_backAnimList[i].backAnims[activeSubAnim]._state) { - seq._counter++; - if (seq._type == 2) { - if (!seq._currRelative) { - if (seq._counter >= seq._data) { - if (seq._anims > 2) { - seq._currRelative = _randomSource.getRandomNumber(seq._anims - 2) + 1; - activeSubAnim = seq._currRelative; - seq._current = _backAnimList[i].backAnims[activeSubAnim]._basaData._num; + if (!_backAnimList[i].backAnims.empty()) { + if (_backAnimList[i].backAnims[activeSubAnim]._animData != nullptr) { + if (!_backAnimList[i].backAnims[activeSubAnim]._state) { + seq._counter++; + if (seq._type == 2) { + if (!seq._currRelative) { + if (seq._counter >= seq._data) { + if (seq._anims > 2) { + seq._currRelative = _randomSource.getRandomNumber(seq._anims - 2) + 1; + activeSubAnim = seq._currRelative; + seq._current = _backAnimList[i].backAnims[activeSubAnim]._basaData._num; + } + setBackAnim(_backAnimList[i].backAnims[activeSubAnim]); + seq._counter = 0; + } } - setBackAnim(_backAnimList[i].backAnims[activeSubAnim]); - seq._counter = 0; } - } - } - if (seq._type == 3) { - if (!seq._currRelative) { - if (seq._counter < seq._data2) { - continue; - } else { - setBackAnim(_backAnimList[i].backAnims[activeSubAnim]); + if (seq._type == 3) { + if (!seq._currRelative) { + if (seq._counter < seq._data2) { + continue; + } else { + setBackAnim(_backAnimList[i].backAnims[activeSubAnim]); + } + } } - } - } - if (_backAnimList[i].backAnims[activeSubAnim]._frame == _backAnimList[i].backAnims[activeSubAnim]._lastFrame - 1) { - _backAnimList[i].backAnims[activeSubAnim]._frame = _backAnimList[i].backAnims[activeSubAnim]._loopFrame; - switch (seq._type) { - case 1: - if (seq._anims > 1) { - int rnd; - do { - rnd = _randomSource.getRandomNumber(seq._anims - 1); - } while (rnd == seq._currRelative); - seq._currRelative = rnd; - seq._current = _backAnimList[i].backAnims[rnd]._basaData._num; - activeSubAnim = rnd; - setBackAnim(_backAnimList[i].backAnims[activeSubAnim]); - seq._counter = 0; - } - break; - case 2: - if (seq._currRelative) { - seq._currRelative = 0; - seq._current = _backAnimList[i].backAnims[0]._basaData._num; - activeSubAnim = 0; - setBackAnim(_backAnimList[i].backAnims[activeSubAnim]); - seq._counter = 0; + if (_backAnimList[i].backAnims[activeSubAnim]._frame == _backAnimList[i].backAnims[activeSubAnim]._lastFrame - 1) { + _backAnimList[i].backAnims[activeSubAnim]._frame = _backAnimList[i].backAnims[activeSubAnim]._loopFrame; + switch (seq._type) { + case 1: + if (seq._anims > 1) { + int rnd; + do { + rnd = _randomSource.getRandomNumber(seq._anims - 1); + } while (rnd == seq._currRelative); + seq._currRelative = rnd; + seq._current = _backAnimList[i].backAnims[rnd]._basaData._num; + activeSubAnim = rnd; + setBackAnim(_backAnimList[i].backAnims[activeSubAnim]); + seq._counter = 0; + } + break; + case 2: + if (seq._currRelative) { + seq._currRelative = 0; + seq._current = _backAnimList[i].backAnims[0]._basaData._num; + activeSubAnim = 0; + setBackAnim(_backAnimList[i].backAnims[activeSubAnim]); + seq._counter = 0; + } + break; + case 3: + seq._currRelative = 0; + seq._current = _backAnimList[i].backAnims[0]._basaData._num; + seq._counter = 0; + seq._data2 = _randomSource.getRandomNumber(seq._data - 1); + continue; // for bug in original game + break; + } + } else { + _backAnimList[i].backAnims[activeSubAnim]._frame++; } - break; - case 3: - seq._currRelative = 0; - seq._current = _backAnimList[i].backAnims[0]._basaData._num; - seq._counter = 0; - seq._data2 = _randomSource.getRandomNumber(seq._data - 1); - continue; // for bug in original game - break; + _backAnimList[i].backAnims[activeSubAnim]._showFrame = _backAnimList[i].backAnims[activeSubAnim]._frame; + showAnim(_backAnimList[i].backAnims[activeSubAnim]); } - } else { - _backAnimList[i].backAnims[activeSubAnim]._frame++; } - _backAnimList[i].backAnims[activeSubAnim]._showFrame = _backAnimList[i].backAnims[activeSubAnim]._frame; - showAnim(_backAnimList[i].backAnims[activeSubAnim]); } } } -void PrinceEngine::clearBackAnimList() { - for (uint i = 0; i < _backAnimList.size(); i++) { - int anims = _backAnimList[i]._seq._anims != 0 ? _backAnimList[i]._seq._anims : 1; +void PrinceEngine::removeSingleBackAnim(int slot) { + if (!_backAnimList[slot].backAnims.empty()) { + int anims = _backAnimList[slot]._seq._anims != 0 ? _backAnimList[slot]._seq._anims : 1; for (int j = 0; j < anims; j++) { - delete _backAnimList[i].backAnims[j]._animData; - delete _backAnimList[i].backAnims[j]._shadowData; + delete _backAnimList[slot].backAnims[j]._animData; + delete _backAnimList[slot].backAnims[j]._shadowData; } - _backAnimList[i].backAnims.clear(); + _backAnimList[slot].backAnims.clear(); + _backAnimList[slot]._seq._currRelative = 0; + } +} + +void PrinceEngine::clearBackAnimList() { + for (int i = 0; i < kMaxBackAnims; i++) { + removeSingleBackAnim(i); } - _backAnimList.clear(); } void PrinceEngine::initZoomIn(int slot) { @@ -2559,7 +2576,7 @@ void PrinceEngine::doTalkAnim(int animNumber, int slot, AnimType animType) { } } } else if (animType == kBackgroundAnimation) { - if ((uint)animNumber < _backAnimList.size()) { + if (!_backAnimList[animNumber].backAnims.empty()) { int currAnim = _backAnimList[animNumber]._seq._currRelative; Anim &backAnim = _backAnimList[animNumber].backAnims[currAnim]; if (backAnim._animData != nullptr) { diff --git a/engines/prince/prince.h b/engines/prince/prince.h index b095da1fc0..060f78f681 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -300,6 +300,7 @@ public: Script *_script; static const int kMaxNormAnims = 64; + static const int kMaxBackAnims = 64; Common::Array<AnimListItem> _animList; Common::Array<BackgroundAnim> _backAnimList; @@ -308,6 +309,7 @@ public: void freeNormAnim(int slot); void freeAllNormAnims(); + void removeSingleBackAnim(int slot); Common::RandomSource _randomSource; diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 8615b1ef9b..ab435f2cb1 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -257,6 +257,10 @@ int32 Script::getOptionStandardOffset(int option) { } } +void Script::setBackAnimId(int offset, int animId) { + WRITE_UINT32(&_data[offset], animId); +} + int Script::scanMobEvents(int mobMask, int dataEventOffset) { debug("mobMask: %d", mobMask); int i = 0; @@ -296,7 +300,7 @@ int Script::scanMobEventsWithItem(int mobMask, int dataEventOffset, int itemMask return -1; } -void Script::installSingleBackAnim(Common::Array<BackgroundAnim> &_backanimList, int offset) { +void Script::installSingleBackAnim(Common::Array<BackgroundAnim> &backAnimList, int slot, int offset) { BackgroundAnim newBackgroundAnim; @@ -371,13 +375,13 @@ void Script::installSingleBackAnim(Common::Array<BackgroundAnim> &_backanimList, newBackgroundAnim.backAnims[0]._lastFrame = end; } - _backanimList.push_back(newBackgroundAnim); + backAnimList[slot] = newBackgroundAnim; } } -void Script::installBackAnims(Common::Array<BackgroundAnim> &backanimList, int offset) { - for (uint i = 0; i < 64; i++) { - installSingleBackAnim(backanimList, offset); +void Script::installBackAnims(Common::Array<BackgroundAnim> &backAnimList, int offset) { + for (uint i = 0; i < _vm->kMaxBackAnims; i++) { + installSingleBackAnim(backAnimList, i, offset); offset += 4; } } @@ -676,12 +680,28 @@ void Interpreter::O_PUTBACKANIM() { uint16 roomId = readScriptFlagValue(); uint16 slot = readScriptFlagValue(); int32 animId = readScript<uint32>(); + Room *room = new Room(); + room->loadRoom(_script->getRoomOffset(roomId)); + int offset = room->_backAnim + slot * 4; + _vm->_script->setBackAnimId(offset, animId); + if (_vm->_locationNr == roomId) { + _vm->_script->installBackAnims(_vm->_backAnimList, offset); + } + delete room; debugInterpreter("O_PUTBACKANIM roomId %d, slot %d, animId %d", roomId, slot, animId); } void Interpreter::O_REMBACKANIM() { uint16 roomId = readScriptFlagValue(); uint16 slot = readScriptFlagValue(); + if (_vm->_locationNr == roomId) { + _vm->removeSingleBackAnim(slot); + } + Room *room = new Room(); + room->loadRoom(_script->getRoomOffset(roomId)); + int offset = room->_backAnim + slot * 4; + _vm->_script->setBackAnimId(offset, 0); + delete room; debugInterpreter("O_REMBACKANIM roomId %d, slot %d", roomId, slot); } @@ -1495,14 +1515,17 @@ void Interpreter::O_BACKANIMRANGE() { } _result = 1; - if (slotId < _vm->_backAnimList.size()) { - if (animId == 0xFFFF || _vm->_backAnimList[slotId]._seq._current == animId) { - int currAnim = _vm->_backAnimList[slotId]._seq._currRelative; - Anim &backAnim = _vm->_backAnimList[slotId].backAnims[currAnim]; - if (!backAnim._state) { - if (backAnim._frame >= low) { - if (backAnim._frame <= high) { - _result = 0; + if (!_vm->_backAnimList[slotId].backAnims.empty()) { + int currAnim = _vm->_backAnimList[slotId]._seq._currRelative; + if (_vm->_backAnimList[slotId].backAnims[currAnim]._animData != nullptr) { + if (animId == 0xFFFF || _vm->_backAnimList[slotId]._seq._current == animId) { + int currAnim = _vm->_backAnimList[slotId]._seq._currRelative; + Anim &backAnim = _vm->_backAnimList[slotId].backAnims[currAnim]; + if (!backAnim._state) { + if (backAnim._frame >= low) { + if (backAnim._frame <= high) { + _result = 0; + } } } } @@ -1574,19 +1597,22 @@ void Interpreter::O_STOPHERO() { } void Interpreter::O_ANIMUPDATEOFF() { - uint16 slotId = readScript<uint16>(); + uint16 slotId = readScriptFlagValue(); + _vm->_normAnimList[slotId]._state = 1; debugInterpreter("O_ANIMUPDATEOFF slotId %d", slotId); } void Interpreter::O_ANIMUPDATEON() { uint16 slotId = readScriptFlagValue(); + _vm->_normAnimList[slotId]._state = 0; debugInterpreter("O_ANIMUPDATEON slotId %d", slotId); } void Interpreter::O_FREECURSOR() { + _vm->changeCursor(0); + _vm->_currentPointerNumber = 1; + // free memory here? debugInterpreter("O_FREECURSOR"); - // Change cursor to 0 - // free inv cursor 1 } void Interpreter::O_ADDINVQUIET() { @@ -1601,7 +1627,6 @@ void Interpreter::O_RUNHERO() { uint16 x = readScriptFlagValue(); uint16 y = readScriptFlagValue(); uint16 dir = readScriptFlagValue(); - debugInterpreter("O_RUNHERO heroId %d, x %d, y %d, dir %d", heroId, x, y, dir); } @@ -1627,7 +1652,7 @@ void Interpreter::O_CHECKFLCFRAME() { debugInterpreter("O_CHECKFLCFRAME frame number %d", frameNr); if (_vm->_flicPlayer.getCurFrame() != frameNr) { - // Move instruction pointer before current instruciton + // Move instruction pointer before current instruction // must do this check once again till it's false _currentInstruction -= 2; _opcodeNF = 1; diff --git a/engines/prince/script.h b/engines/prince/script.h index 99a6af3427..278a8c858e 100644 --- a/engines/prince/script.h +++ b/engines/prince/script.h @@ -137,8 +137,9 @@ public: int32 getShadowScale(int locationNr); uint8 *getRoomOffset(int locationNr); int32 getOptionStandardOffset(int option); - void installBackAnims(Common::Array<BackgroundAnim> &_backanimList, int offset); - void installSingleBackAnim(Common::Array<BackgroundAnim> &_backanimList, int offset); + void setBackAnimId(int offset, int animId); + void installBackAnims(Common::Array<BackgroundAnim> &backAnimList, int offset); + void installSingleBackAnim(Common::Array<BackgroundAnim> &backAnimList, int slot, int offset); bool loadAllMasks(Common::Array<Mask> &maskList, int offset); int scanMobEvents(int mobMask, int dataEventOffset); |