Skip to content

Commit

Permalink
PRINCE: Background animations update. O_PUTBACKANIM(), O_REMBACKANIM(…
Browse files Browse the repository at this point in the history
…), O_ANIMUPDATEON(), O_ANIMUPDATEOFF()
  • Loading branch information
lukaslw committed Jul 4, 2014
1 parent 9d26704 commit a838b34
Show file tree
Hide file tree
Showing 4 changed files with 144 additions and 99 deletions.
175 changes: 96 additions & 79 deletions engines/prince/prince.cpp
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
}
}
}
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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) {
Expand Down
2 changes: 2 additions & 0 deletions engines/prince/prince.h
Expand Up @@ -300,6 +300,7 @@ class PrinceEngine : public Engine {
Script *_script;

static const int kMaxNormAnims = 64;
static const int kMaxBackAnims = 64;

Common::Array<AnimListItem> _animList;
Common::Array<BackgroundAnim> _backAnimList;
Expand All @@ -308,6 +309,7 @@ class PrinceEngine : public Engine {

void freeNormAnim(int slot);
void freeAllNormAnims();
void removeSingleBackAnim(int slot);

Common::RandomSource _randomSource;

Expand Down
61 changes: 43 additions & 18 deletions engines/prince/script.cpp
Expand Up @@ -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;
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;
}
}
Expand Down Expand Up @@ -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);
}

Expand Down Expand Up @@ -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;
}
}
}
}
Expand Down Expand Up @@ -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() {
Expand All @@ -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);
}

Expand All @@ -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;
Expand Down
5 changes: 3 additions & 2 deletions engines/prince/script.h
Expand Up @@ -137,8 +137,9 @@ class Script {
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);
Expand Down

0 comments on commit a838b34

Please sign in to comment.