PRINCE: Background animations update. O_PUTBACKANIM(), O_REMBACKANIM(), O_ANIMUPDATEON(), O_ANIMUPDATEOFF()
This commit is contained in:
parent
9d2670416c
commit
a838b34b4d
4 changed files with 145 additions and 100 deletions
|
@ -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;
|
||||
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;
|
||||
}
|
||||
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 {
|
||||
setBackAnim(_backAnimList[i].backAnims[activeSubAnim]);
|
||||
_backAnimList[i].backAnims[activeSubAnim]._frame++;
|
||||
}
|
||||
_backAnimList[i].backAnims[activeSubAnim]._showFrame = _backAnimList[i].backAnims[activeSubAnim]._frame;
|
||||
showAnim(_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;
|
||||
}
|
||||
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++;
|
||||
}
|
||||
_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) {
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue