aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Kurushin2007-06-09 22:45:03 +0000
committerAndrew Kurushin2007-06-09 22:45:03 +0000
commit86f6aaf206fadd6970b300c953a525804d7d84df (patch)
tree4380ae0ff814888eeab842abf204c8665c37ec9d
parentd2bc07cfdf016346055ab60ec1524a31f13dbc22 (diff)
downloadscummvm-rg350-86f6aaf206fadd6970b300c953a525804d7d84df.tar.gz
scummvm-rg350-86f6aaf206fadd6970b300c953a525804d7d84df.tar.bz2
scummvm-rg350-86f6aaf206fadd6970b300c953a525804d7d84df.zip
fix IHNM protagonist state loading routine. now Ellen's animations are showing well
svn-id: r27263
-rw-r--r--engines/saga/actor.cpp230
-rw-r--r--engines/saga/actor.h14
2 files changed, 190 insertions, 54 deletions
diff --git a/engines/saga/actor.cpp b/engines/saga/actor.cpp
index 32311da03d..1ba881f565 100644
--- a/engines/saga/actor.cpp
+++ b/engines/saga/actor.cpp
@@ -243,7 +243,7 @@ Actor::Actor(SagaEngine *vm) : _vm(vm) {
_debugPointsAlloced = _debugPointsCount = 0;
#endif
- _protagStates = 0;
+ _protagStates = NULL;
_protagStatesCount = 0;
_pathNodeList = _newPathNodeList = NULL;
@@ -356,52 +356,65 @@ Actor::~Actor() {
free(_pathCell);
_actorsStrings.freeMem();
//release resources
+ freeProtagStates();
freeActorList();
freeObjList();
}
-bool Actor::loadActorResources(ActorData *actor) {
+void Actor::freeProtagStates() {
+ int i;
+ for (i = 0; i < _protagStatesCount; i++) {
+ free(_protagStates[i]._frames);
+ }
+ free(_protagStates);
+ _protagStates = NULL;
+ _protagStatesCount = 0;
+}
+
+void Actor::loadFrameList(int frameListResourceId, ActorFrameSequence *&framesPointer, int &framesCount) {
byte *resourcePointer;
size_t resourceLength;
- int framesCount;
- ActorFrameSequence *framesPointer;
- bool gotSomething = false;
- if (actor->_frameListResourceId) {
- debug(9, "Loading frame resource id %d", actor->_frameListResourceId);
- _vm->_resource->loadResource(_actorContext, actor->_frameListResourceId, resourcePointer, resourceLength);
+ debug(9, "Loading frame resource id %d", frameListResourceId);
+ _vm->_resource->loadResource(_actorContext, frameListResourceId, resourcePointer, resourceLength);
- framesCount = resourceLength / 16;
- debug(9, "Frame resource contains %d frames (res length is %d)", framesCount, (int)resourceLength);
+ framesCount = resourceLength / 16;
+ debug(9, "Frame resource contains %d frames (res length is %d)", framesCount, (int)resourceLength);
- framesPointer = (ActorFrameSequence *)malloc(sizeof(ActorFrameSequence) * framesCount);
- if (framesPointer == NULL && framesCount != 0) {
- memoryError("Actor::loadActorResources");
- }
+ framesPointer = (ActorFrameSequence *)malloc(sizeof(ActorFrameSequence) * framesCount);
+ if (framesPointer == NULL && framesCount != 0) {
+ memoryError("Actor::loadFrameList");
+ }
- MemoryReadStreamEndian readS(resourcePointer, resourceLength, _actorContext->isBigEndian);
+ MemoryReadStreamEndian readS(resourcePointer, resourceLength, _actorContext->isBigEndian);
- for (int i = 0; i < framesCount; i++) {
- debug(9, "frameType %d", i);
- for (int orient = 0; orient < ACTOR_DIRECTIONS_COUNT; orient++) {
- // Load all four orientations
- framesPointer[i].directions[orient].frameIndex = readS.readUint16();
- if (_vm->getGameType() == GType_ITE) {
- framesPointer[i].directions[orient].frameCount = readS.readSint16();
- } else {
- framesPointer[i].directions[orient].frameCount = readS.readByte();
- readS.readByte();
- }
- if (framesPointer[i].directions[orient].frameCount < 0)
- warning("frameCount < 0 (%d)", framesPointer[i].directions[orient].frameCount);
- debug(9, "frameIndex %d frameCount %d", framesPointer[i].directions[orient].frameIndex, framesPointer[i].directions[orient].frameCount);
+ for (int i = 0; i < framesCount; i++) {
+ debug(9, "frameType %d", i);
+ for (int orient = 0; orient < ACTOR_DIRECTIONS_COUNT; orient++) {
+ // Load all four orientations
+ framesPointer[i].directions[orient].frameIndex = readS.readUint16();
+ if (_vm->getGameType() == GType_ITE) {
+ framesPointer[i].directions[orient].frameCount = readS.readSint16();
+ } else {
+ framesPointer[i].directions[orient].frameCount = readS.readByte();
+ readS.readByte();
}
+ if (framesPointer[i].directions[orient].frameCount < 0)
+ warning("frameCount < 0 (%d)", framesPointer[i].directions[orient].frameCount);
+ debug(9, "frameIndex %d frameCount %d", framesPointer[i].directions[orient].frameIndex, framesPointer[i].directions[orient].frameCount);
}
+ }
+
+ free(resourcePointer);
+}
+
+bool Actor::loadActorResources(ActorData *actor) {
+ bool gotSomething = false;
- free(resourcePointer);
+ if (actor->_frameListResourceId) {
+ loadFrameList(actor->_frameListResourceId, actor->_frames, actor->_framesCount);
- actor->_frames = framesPointer;
- actor->_framesCount = framesCount;
+ actor->_shareFrames = false;
gotSomething = true;
} else {
@@ -470,6 +483,7 @@ void Actor::loadActorList(int protagonistIdx, int actorCount, int actorsResource
int movementSpeed;
int walkStepIndex;
int walkStepCount;
+ int stateResourceId;
freeActorList();
@@ -567,28 +581,34 @@ void Actor::loadActorList(int protagonistIdx, int actorCount, int actorsResource
_protagState = 0;
if (protagStatesResourceID) {
- free(_protagStates);
+ if (!_protagonist->_shareFrames)
+ free(_protagonist->_frames);
+ freeProtagStates();
- _protagStates = (ActorFrameSequence *)malloc(sizeof(ActorFrameSequence) * protagStatesCount);
+ _protagStates = (ProtagStateData *)malloc(sizeof(ProtagStateData) * protagStatesCount);
- byte *resourcePointer;
- size_t resourceLength;
+ byte *idsResourcePointer;
+ size_t idsResourceLength;
_vm->_resource->loadResource(_actorContext, protagStatesResourceID,
- resourcePointer, resourceLength);
+ idsResourcePointer, idsResourceLength);
+ if (idsResourceLength < (size_t)protagStatesCount * 4) {
+ error("Wrong protagonist states resource");
+ }
- MemoryReadStream statesS(resourcePointer, resourceLength);
+ MemoryReadStream statesIds(idsResourcePointer, idsResourceLength);
for (i = 0; i < protagStatesCount; i++) {
- for (j = 0; j < ACTOR_DIRECTIONS_COUNT; j++) {
- _protagStates[i].directions[j].frameIndex = statesS.readUint16LE();
- _protagStates[i].directions[j].frameCount = statesS.readUint16LE();
- }
+ stateResourceId = statesIds.readUint32LE();
+
+ loadFrameList(stateResourceId, _protagStates[i]._frames, _protagStates[i]._framesCount);
}
- free(resourcePointer);
+ free(idsResourcePointer);
- _protagonist->_frames = &_protagStates[_protagState];
+ _protagonist->_frames = _protagStates[_protagState]._frames;
+ _protagonist->_framesCount = _protagStates[_protagState]._framesCount;
+ _protagonist->_shareFrames = true;
}
_protagStatesCount = protagStatesCount;
@@ -823,8 +843,14 @@ bool Actor::validFollowerLocation(const Location &location) {
void Actor::setProtagState(int state) {
_protagState = state;
- if (_vm->getGameType() == GType_IHNM)
- _protagonist->_frames = &_protagStates[state];
+ if (_vm->getGameType() == GType_IHNM) {
+ if (!_protagonist->_shareFrames)
+ free(_protagonist->_frames);
+
+ _protagonist->_frames = _protagStates[state]._frames;
+ _protagonist->_framesCount = _protagStates[state]._framesCount;
+ _protagonist->_shareFrames = true;
+ }
}
void Actor::updateActorsScene(int actorsEntrance) {
@@ -1024,19 +1050,117 @@ ActorFrameRange *Actor::getActorFrameRange(uint16 actorId, int frameType) {
if ((actor->_facingDirection < kDirUp) || (actor->_facingDirection > kDirUpLeft))
error("Actor::getActorFrameRange Wrong direction 0x%X actorId 0x%X", actor->_facingDirection, actorId);
- if (frameType >= actor->_framesCount) {
+ if (_vm->getGameType() == GType_ITE) {
+ if (frameType >= actor->_framesCount) {
+ warning("Actor::getActorFrameRange Wrong frameType 0x%X (%d) actorId 0x%X", frameType, actor->_framesCount, actorId);
+ return &def;
+ }
+
+
+ fourDirection = actorDirectectionsLUT[actor->_facingDirection];
+ return &actor->_frames[frameType].directions[fourDirection];
+ }
+
+ if (_vm->getGameType() == GType_IHNM) {
// It is normal for some actors to have no frames for a given frameType
// These are mainly actors with no frames at all (e.g. narrators or immovable actors)
// Examples are AM and the boy when he is talking to Benny via the computer screen.
// Both of them are invisible and immovable
// There is no point to keep throwing warnings about this, the original checks for
// a valid framecount too
- //warning("Actor::getActorFrameRange Wrong frameType 0x%X (%d) actorId 0x%X", frameType, actor->_framesCount, actorId);
- return &def;
+ if (0 == actor->_framesCount) {
+ return &def;
+ }
+ if (frameType >= actor->_framesCount) {
+ frameType = actor->_framesCount - 1;
+ }
+ if (frameType < 0) {
+ frameType = 0;
+ }
+
+ fourDirection = actorDirectectionsLUT[actor->_facingDirection];
+ return &actor->_frames[frameType].directions[fourDirection];
}
+ return NULL;
+ /*
+ } else {
+ if (0 == actor->_framesCount) {
+ return &def;
+ }
+
+ //TEST
+ if (actor->_id == 0x2000) {
+ if (actor->_framesCount <= _currentFrameIndex) {
+ _currentFrameIndex = 0;
+ }
+ fr = actor->_frames[_currentFrameIndex].directions;
+ return fr;
+ }
+ //TEST
+ if (frameType >= actor->_framesCount) {
+ frameType = actor->_framesCount - 1;
+ }
+ if (frameType < 0) {
+ frameType = 0;
+ }
- fourDirection = actorDirectectionsLUT[actor->_facingDirection];
- return &actor->_frames[frameType].directions[fourDirection];
+ if (frameType == kFrameIHNMWalk ) {
+ switch (actor->_facingDirection) {
+ case kDirUpRight:
+ if (frameType > 0)
+ fr = &actor->_frames[frameType - 1].directions[ACTOR_DIRECTION_RIGHT];
+ else
+ fr = &def;
+ if (!fr->frameCount)
+ fr = &actor->_frames[frameType].directions[ACTOR_DIRECTION_RIGHT];
+ break;
+ case kDirDownRight:
+ if (frameType > 0)
+ fr = &actor->_frames[frameType - 1].directions[ACTOR_DIRECTION_FORWARD];
+ else
+ fr = &def;
+ if (!fr->frameCount)
+ fr = &actor->_frames[frameType].directions[ACTOR_DIRECTION_RIGHT];
+ break;
+ case kDirUpLeft:
+ if (frameType > 0)
+ fr = &actor->_frames[frameType - 1].directions[ACTOR_DIRECTION_LEFT];
+ else
+ fr = &def;
+ if (!fr->frameCount)
+ fr = &actor->_frames[frameType].directions[ACTOR_DIRECTION_LEFT];
+ break;
+ case kDirDownLeft:
+ if (frameType > 0)
+ fr = &actor->_frames[frameType - 1].directions[ACTOR_DIRECTION_BACK];
+ else
+ fr = &def;
+ if (!fr->frameCount)
+ fr = &actor->_frames[frameType].directions[ACTOR_DIRECTION_LEFT];
+ break;
+ case kDirRight:
+ fr = &actor->_frames[frameType].directions[ACTOR_DIRECTION_RIGHT];
+ break;
+ case kDirLeft:
+ fr = &actor->_frames[frameType].directions[ACTOR_DIRECTION_LEFT];
+ break;
+ case kDirUp:
+ fr = &actor->_frames[frameType].directions[ACTOR_DIRECTION_BACK];
+ break;
+ case kDirDown:
+ fr = &actor->_frames[frameType].directions[ACTOR_DIRECTION_FORWARD];
+ break;
+ }
+ return fr;
+ }
+ else {
+ if (frameType >= actor->_framesCount) {
+ error("Actor::getActorFrameRange Wrong frameType 0x%X (%d) actorId 0x%X", frameType, actor->_framesCount, actorId);
+ }
+ fourDirection = actorDirectectionsLUT[actor->_facingDirection];
+ return &actor->_frames[frameType].directions[fourDirection];
+ }
+ }*/
}
void Actor::handleSpeech(int msec) {
@@ -1709,6 +1833,10 @@ bool Actor::getSpriteParams(CommonObjectData *commonObjectData, int &frameNumber
frameNumber = commonObjectData->_spriteListResourceId;
}
+ if (spriteList->spriteCount == 0) {
+ return false;
+ }
+
if ((frameNumber < 0) || (spriteList->spriteCount <= frameNumber)) {
debug(1, "Actor::getSpriteParams frameNumber invalid for %s id 0x%X (%d)",
validObjId(commonObjectData->_id) ? "object" : "actor",
diff --git a/engines/saga/actor.h b/engines/saga/actor.h
index d4d7a0957d..3296246cba 100644
--- a/engines/saga/actor.h
+++ b/engines/saga/actor.h
@@ -303,6 +303,7 @@ public:
//constant
SpriteList _spriteList; // sprite list data
+ bool _shareFrames;
ActorFrameSequence *_frames; // Actor's frames
int _framesCount; // Actor's frames count
int _frameListResourceId; // Actor's frame list resource id
@@ -474,13 +475,18 @@ public:
memset(this, 0, sizeof(*this));
}
~ActorData() {
- free(_frames);
+ if (!_shareFrames)
+ free(_frames);
free(_tileDirections);
free(_walkStepsPoints);
freeSpriteList();
}
};
+struct ProtagStateData {
+ ActorFrameSequence *_frames; // Actor's frames
+ int _framesCount; // Actor's frames count
+};
struct SpeechData {
@@ -592,6 +598,8 @@ public:
void setProtagState(int state);
int getProtagState() { return _protagState; }
+ void freeProtagStates();
+
void freeActorList();
void loadActorList(int protagonistIdx, int actorCount, int actorsResourceID,
int protagStatesCount, int protagStatesResourceID);
@@ -606,7 +614,7 @@ public:
protected:
friend class Script;
bool loadActorResources(ActorData *actor);
-
+ void loadFrameList(int frameListResourceId, ActorFrameSequence *&framesPointer, int &framesCount);
private:
void stepZoneAction(ActorData *actor, const HitZone *hitZone, bool exit, bool stopped);
void loadActorSpriteList(ActorData *actor);
@@ -682,7 +690,7 @@ protected:
bool _dragonHunt;
private:
- ActorFrameSequence *_protagStates;
+ ProtagStateData *_protagStates;
int _protagStatesCount;
//path stuff