SHERLOCK: SS: Fix sprites when multiple animations are active

This commit is contained in:
Paul Gilbert 2015-10-11 10:58:54 -04:00
parent 4e6cdf71fb
commit 1d0c07006c
2 changed files with 49 additions and 39 deletions

View File

@ -40,6 +40,11 @@ const int FS_TRANS[8] = {
/*----------------------------------------------------------------*/
ScalpelScene::~ScalpelScene() {
for (uint idx = 0; idx < _canimShapes.size(); ++idx)
delete _canimShapes[idx];
}
bool ScalpelScene::loadScene(const Common::String &filename) {
ScalpelMap &map = *(ScalpelMap *)_vm->_map;
bool result = Scene::loadScene(filename);
@ -454,12 +459,14 @@ void ScalpelScene::doBgAnim() {
if (o._type == INVALID) {
// Anim shape was invalidated by checkEndOfSequence, so at this point we can remove it
delete _canimShapes[idx];
_canimShapes.remove_at(idx);
} else if (o._type == REMOVE) {
if (_goToScene == -1)
screen.slamArea(o._position.x, o._position.y, o._delta.x, o._delta.y);
// Shape for an animation is no longer needed, so remove it completely
delete _canimShapes[idx];
_canimShapes.remove_at(idx);
} else if (o._type == ACTIVE_BG_SHAPE) {
screen.flushImage(o._imageFrame, o._position,
@ -496,7 +503,7 @@ int ScalpelScene::startCAnim(int cAnimNum, int playRate) {
int tpDir, walkDir;
int tFrames = 0;
int gotoCode = -1;
Object cObj;
Object *cObj;
// Validation
if (cAnimNum >= (int)_cAnim.size())
@ -534,32 +541,33 @@ int ScalpelScene::startCAnim(int cAnimNum, int playRate) {
return 1;
// Add new anim shape entry for displaying the animation
_canimShapes.push_back(&cObj);
cObj = new Object();
_canimShapes.push_back(cObj);
// Copy the canimation into the bgShapes type canimation structure so it can be played
cObj._allow = cAnimNum + 1; // Keep track of the parent structure
cObj._name = _cAnim[cAnimNum]._name; // Copy name
cObj->_allow = cAnimNum + 1; // Keep track of the parent structure
cObj->_name = _cAnim[cAnimNum]._name; // Copy name
// Remove any attempt to draw object frame
if (cAnim._type == NO_SHAPE && cAnim._sequences[0] < 100)
cAnim._sequences[0] = 0;
cObj._sequences = cAnim._sequences;
cObj._images = nullptr;
cObj._position = cAnim._position;
cObj._delta = Common::Point(0, 0);
cObj._type = cAnim._type;
cObj._flags = cAnim._flags;
cObj->_sequences = cAnim._sequences;
cObj->_images = nullptr;
cObj->_position = cAnim._position;
cObj->_delta = Common::Point(0, 0);
cObj->_type = cAnim._type;
cObj->_flags = cAnim._flags;
cObj._maxFrames = 0;
cObj._frameNumber = -1;
cObj._sequenceNumber = cAnimNum;
cObj._oldPosition = Common::Point(0, 0);
cObj._oldSize = Common::Point(0, 0);
cObj._goto = Common::Point(0, 0);
cObj._status = 0;
cObj._misc = 0;
cObj._imageFrame = nullptr;
cObj->_maxFrames = 0;
cObj->_frameNumber = -1;
cObj->_sequenceNumber = cAnimNum;
cObj->_oldPosition = Common::Point(0, 0);
cObj->_oldSize = Common::Point(0, 0);
cObj->_goto = Common::Point(0, 0);
cObj->_status = 0;
cObj->_misc = 0;
cObj->_imageFrame = nullptr;
if (cAnim._name.size() > 0 && cAnim._type != NO_SHAPE) {
if (tpPos.x != -1)
@ -584,25 +592,25 @@ int ScalpelScene::startCAnim(int cAnimNum, int playRate) {
// Now load the resource as an image
if (!IS_3DO) {
cObj._images = new ImageFile(fname);
cObj->_images = new ImageFile(fname);
} else {
cObj._images = new ImageFile3DO(fname, kImageFile3DOType_RoomFormat);
cObj->_images = new ImageFile3DO(fname, kImageFile3DOType_RoomFormat);
}
cObj._imageFrame = &(*cObj._images)[0];
cObj._maxFrames = cObj._images->size();
cObj->_imageFrame = &(*cObj->_images)[0];
cObj->_maxFrames = cObj->_images->size();
int frames = 0;
if (playRate < 0) {
// Reverse direction
// Count number of frames
while (frames < MAX_FRAME && cObj._sequences[frames])
while (frames < MAX_FRAME && cObj->_sequences[frames])
++frames;
} else {
// Forward direction
BaseObject::_countCAnimFrames = true;
while (cObj._type == ACTIVE_BG_SHAPE) {
cObj.checkObject();
while (cObj->_type == ACTIVE_BG_SHAPE) {
cObj->checkObject();
++frames;
if (frames >= 1000)
@ -614,10 +622,10 @@ int ScalpelScene::startCAnim(int cAnimNum, int playRate) {
BaseObject::_countCAnimFrames = false;
cObj._type = cAnim._type;
cObj._frameNumber = -1;
cObj._position = cAnim._position;
cObj._delta = Common::Point(0, 0);
cObj->_type = cAnim._type;
cObj->_frameNumber = -1;
cObj->_position = cAnim._position;
cObj->_delta = Common::Point(0, 0);
}
// Return if animation has no frames in it
@ -631,7 +639,7 @@ int ScalpelScene::startCAnim(int cAnimNum, int playRate) {
if (playRate < 0) {
// Play in reverse
dir = -2;
cObj._frameNumber = frames - 3;
cObj->_frameNumber = frames - 3;
} else {
dir = 0;
}
@ -648,14 +656,14 @@ int ScalpelScene::startCAnim(int cAnimNum, int playRate) {
// Repeat same frame
int temp = repeat;
while (--temp > 0) {
cObj._frameNumber--;
cObj->_frameNumber--;
doBgAnim();
if (_vm->shouldQuit())
return 0;
}
cObj._frameNumber += dir;
cObj->_frameNumber += dir;
}
people[HOLMES]._type = CHARACTER;
@ -670,15 +678,15 @@ int ScalpelScene::startCAnim(int cAnimNum, int playRate) {
if (playRate < 0)
// Reverse direction - set to end sequence
cObj._frameNumber = tFrames - 1;
cObj->_frameNumber = tFrames - 1;
if (cObj._frameNumber <= 26)
gotoCode = cObj._sequences[cObj._frameNumber + 3];
if (cObj->_frameNumber <= 26)
gotoCode = cObj->_sequences[cObj->_frameNumber + 3];
// Unless anim shape has already been removed, set it to REMOVE
// Unless anim shape has already been removed, do a final check to allow it to become REMOVEd
for (uint idx = 0; idx < _canimShapes.size(); ++idx) {
if (_canimShapes[idx] == &cObj) {
cObj.checkObject();
if (_canimShapes[idx] == cObj) {
cObj->checkObject();
break;
}
}

View File

@ -75,6 +75,8 @@ protected:
public:
ScalpelScene(SherlockEngine *vm) : Scene(vm) {}
virtual ~ScalpelScene();
/**
* Draw all objects and characters.
*/