aboutsummaryrefslogtreecommitdiff
path: root/saga
diff options
context:
space:
mode:
authorAndrew Kurushin2005-06-05 16:53:53 +0000
committerAndrew Kurushin2005-06-05 16:53:53 +0000
commit6128bb05e3108671d3a687acef17904a8460c5a7 (patch)
treeedbdf98a9919eaf5de6b657debc416a96c778743 /saga
parentf163b4f71abba9a871a301c85b21bdf306bf6070 (diff)
downloadscummvm-rg350-6128bb05e3108671d3a687acef17904a8460c5a7.tar.gz
scummvm-rg350-6128bb05e3108671d3a687acef17904a8460c5a7.tar.bz2
scummvm-rg350-6128bb05e3108671d3a687acef17904a8460c5a7.zip
implements sfScriptClimb, sfThrowActor, sfChangeActorScene
so tunnel may be passed now svn-id: r18358
Diffstat (limited to 'saga')
-rw-r--r--saga/actor.cpp48
-rw-r--r--saga/actor.h16
-rw-r--r--saga/saga.h10
-rw-r--r--saga/saveload.cpp32
-rw-r--r--saga/script.h6
-rw-r--r--saga/sfuncs.cpp92
6 files changed, 151 insertions, 53 deletions
diff --git a/saga/actor.cpp b/saga/actor.cpp
index 1bd3a3310f..b040be665b 100644
--- a/saga/actor.cpp
+++ b/saga/actor.cpp
@@ -427,6 +427,7 @@ void Actor::realLocation(Location &location, uint16 objectId, uint16 walkFlags)
int distance;
ActorData *actor;
ObjectData *obj;
+ debug (8, "Actor::realLocation objectId=%i", objectId);
if (walkFlags & kWalkUseAngle) {
if (_vm->_scene->getFlags() & kSceneFlagISO) {
angle = (location.x + 2) & 15;
@@ -460,7 +461,7 @@ void Actor::realLocation(Location &location, uint16 objectId, uint16 walkFlags)
void Actor::actorFaceTowardsPoint(uint16 actorId, const Location &toLocation) {
ActorData *actor;
Location delta;
-
+ debug (8, "Actor::actorFaceTowardsPoint actorId=%i", actorId);
actor = getActor(actorId);
toLocation.delta(actor->location, delta);
@@ -802,6 +803,7 @@ void Actor::handleActions(int msec, bool setup) {
ActorFrameRange *frameRange;
int state;
int speed;
+ int32 framesLeft;
Location delta;
Location addDelta;
int hitZoneIndex;
@@ -1099,15 +1101,49 @@ void Actor::handleActions(int msec, bool setup) {
break;
case kActionFall:
- debug(9,"kActionFall not implemented");
-
- //todo: do it
+ if (actor->actionCycle > 0) {
+ framesLeft = actor->actionCycle--;
+ actor->finalTarget.delta(actor->location, delta);
+ delta.x /= framesLeft;
+ delta.y /= framesLeft;
+ actor->location.addXY(delta);
+ actor->fallVelocity += actor->fallAcceleration;
+ actor->fallPosition += actor->fallVelocity;
+ actor->location.z = actor->fallPosition >> 4;
+ } else {
+ actor->location = actor->finalTarget;
+ actor->currentAction = kActionFreeze;
+ _vm->_script->wakeUpActorThread(kWaitTypeWalk, actor);
+ }
break;
case kActionClimb:
- debug(9,"kActionClimb not implemented");
+ actor->cycleDelay++;
+ if (actor->cycleDelay & 3) {
+ break;
+ }
+
+ if (actor->location.z >= actor->finalTarget.z + ACTOR_CLIMB_SPEED) {
+ actor->location.z -= ACTOR_CLIMB_SPEED;
+ actor->actionCycle--;
+ } else {
+ if (actor->location.z <= actor->finalTarget.z - ACTOR_CLIMB_SPEED) {
+ actor->location.z += ACTOR_CLIMB_SPEED;
+ actor->actionCycle++;
+ } else {
+ actor->location.z = actor->finalTarget.z;
+ actor->currentAction = kActionFreeze;
+ _vm->_script->wakeUpActorThread(kWaitTypeWalk, actor);
+ }
+ }
+
+ frameRange = getActorFrameRange(actor->id, actor->cycleFrameSequence);
- //todo: do it
+ if (actor->actionCycle < 0) {
+ actor->actionCycle = frameRange->frameCount - 1;
+ }
+ actor->cycleWrap(frameRange->frameCount);
+ actor->frameNumber = frameRange->frameIndex + actor->actionCycle;
break;
}
diff --git a/saga/actor.h b/saga/actor.h
index ba63c1dfb2..00f950bd23 100644
--- a/saga/actor.h
+++ b/saga/actor.h
@@ -49,6 +49,8 @@ class HitZone;
#define ACTOR_LMULT 4
+#define ACTOR_CLIMB_SPEED 8
+
#define ACTOR_COLLISION_WIDTH 32
#define ACTOR_COLLISION_HEIGHT 8
@@ -287,6 +289,10 @@ public:
uint8 cycleTimeCount;
uint8 cycleFlags;
+ int16 fallVelocity;
+ int16 fallAcceleration;
+ int16 fallPosition;
+
int32 frameNumber; // current frame number
int32 tileDirectionsAlloced;
@@ -315,6 +321,9 @@ public:
out->writeByte(cycleDelay);
out->writeByte(cycleTimeCount);
out->writeByte(cycleFlags);
+ out->writeSint16LE(fallVelocity);
+ out->writeSint16LE(fallAcceleration);
+ out->writeSint16LE(fallPosition);
out->writeSint32LE(frameNumber);
out->writeSint32LE(tileDirectionsAlloced);
@@ -349,6 +358,13 @@ public:
cycleDelay = in->readByte();
cycleTimeCount = in->readByte();
cycleFlags = in->readByte();
+ if (_vm->getCurrentLoadVersion() > 1) {
+ fallVelocity = in->readSint16LE();
+ fallAcceleration = in->readSint16LE();
+ fallPosition = in->readSint16LE();
+ } else {
+ fallVelocity = fallAcceleration = fallPosition = 0;
+ }
frameNumber = in->readSint32LE();
diff --git a/saga/saga.h b/saga/saga.h
index c3aa5061bf..64a3c82725 100644
--- a/saga/saga.h
+++ b/saga/saga.h
@@ -463,6 +463,12 @@ struct SaveFileData {
uint slotNumber;
};
+struct SaveGameHeader {
+ uint32 type;
+ uint32 size;
+ uint32 version;
+ char name[SAVE_TITLE_SIZE];
+};
inline int ticksToMSec(int tick) {
return tick * 1000 / kScriptTimeTicksPerSecond;
@@ -512,6 +518,9 @@ public:
void save(const char *fileName, const char *saveName);
void load(const char *fileName);
+ uint32 getCurrentLoadVersion() {
+ return _saveHeader.version;
+ }
void fillSaveList();
char *calcSaveFileName(uint slotNumber);
@@ -605,6 +614,7 @@ public:
uint _saveFilesCount;
SaveFileData _saveFiles[MAX_SAVES];
bool _saveMarks[MAX_SAVES];
+ SaveGameHeader _saveHeader;
Point _mousePos;
bool _leftMouseButtonPressed;
diff --git a/saga/saveload.cpp b/saga/saveload.cpp
index 8a3e5befe4..c19550a4ac 100644
--- a/saga/saveload.cpp
+++ b/saga/saveload.cpp
@@ -37,17 +37,10 @@
#include "saga/scene.h"
#include "saga/render.h"
-#define CURRENT_SAGA_VER 1
+#define CURRENT_SAGA_VER 2
namespace Saga {
-struct SaveGameHeader {
- uint32 type;
- uint32 size;
- uint32 version;
- char name[SAVE_TITLE_SIZE];
-};
-
static SaveFileData emptySlot = {
"[New Save Game]", 0
};
@@ -114,7 +107,6 @@ uint SagaEngine::getNewSaveSlotNumber() {
void SagaEngine::fillSaveList() {
int i;
Common::InSaveFile *in;
- SaveGameHeader header;
char *name;
name = calcSaveFileName(MAX_SAVES);
@@ -137,12 +129,12 @@ void SagaEngine::fillSaveList() {
if (_saveMarks[i]) {
name = calcSaveFileName(i);
if ((in = _saveFileMan->openForLoading(name)) != NULL) {
- in->read(&header, sizeof(header));
+ in->read(&_saveHeader, sizeof(_saveHeader));
- if (header.type != MKID('SAGA')) {
+ if (_saveHeader.type != MKID('SAGA')) {
error("SagaEngine::load wrong format");
}
- strcpy(_saveFiles[_saveFilesCount].name, header.name);
+ strcpy(_saveFiles[_saveFilesCount].name, _saveHeader.name);
_saveFiles[_saveFilesCount].slotNumber = i;
delete in;
_saveFilesCount++;
@@ -163,18 +155,17 @@ void SagaEngine::fillSaveList() {
void SagaEngine::save(const char *fileName, const char *saveName) {
Common::OutSaveFile *out;
- SaveGameHeader header;
if (!(out = _saveFileMan->openForSaving(fileName))) {
return;
}
- header.type = MKID('SAGA');
- header.size = 0;
- header.version = CURRENT_SAGA_VER;
- strcpy(header.name, saveName);
+ _saveHeader.type = MKID('SAGA');
+ _saveHeader.size = 0;
+ _saveHeader.version = CURRENT_SAGA_VER;
+ strcpy(_saveHeader.name, saveName);
- out->write(&header, sizeof(header));
+ out->write(&_saveHeader, sizeof(_saveHeader));
// Surrounding scene
out->writeSint32LE(_scene->getOutsetSceneNumber());
@@ -201,15 +192,14 @@ void SagaEngine::load(const char *fileName) {
int commonBufferSize;
int sceneNumber, insetSceneNumber;
int mapx, mapy;
- SaveGameHeader header;
if (!(in = _saveFileMan->openForLoading(fileName))) {
return;
}
- in->read(&header, sizeof(header));
+ in->read(&_saveHeader, sizeof(_saveHeader));
- if (header.type != MKID('SAGA')) {
+ if (_saveHeader.type != MKID('SAGA')) {
error("SagaEngine::load wrong format");
}
diff --git a/saga/script.h b/saga/script.h
index 04fd328101..44c438e143 100644
--- a/saga/script.h
+++ b/saga/script.h
@@ -514,11 +514,11 @@ private:
void sfPlacardOff(SCRIPTFUNC_PARAMS);
void sfSetProtagState(SCRIPTFUNC_PARAMS);
void sfResumeBgdAnim(SCRIPTFUNC_PARAMS);
- void SF_throwActor(SCRIPTFUNC_PARAMS);
+ void sfThrowActor(SCRIPTFUNC_PARAMS);
void sfWaitWalk(SCRIPTFUNC_PARAMS);
void sfScriptSceneID(SCRIPTFUNC_PARAMS);
- void SF_changeActorScene(SCRIPTFUNC_PARAMS);
- void SF_climb(SCRIPTFUNC_PARAMS);
+ void sfChangeActorScene(SCRIPTFUNC_PARAMS);
+ void sfScriptClimb(SCRIPTFUNC_PARAMS);
void sfSetDoorState(SCRIPTFUNC_PARAMS);
void SF_setActorZ(SCRIPTFUNC_PARAMS);
void SF_text(SCRIPTFUNC_PARAMS);
diff --git a/saga/sfuncs.cpp b/saga/sfuncs.cpp
index c05f4f002e..4e1f671bfb 100644
--- a/saga/sfuncs.cpp
+++ b/saga/sfuncs.cpp
@@ -103,11 +103,11 @@ void Script::setupScriptFuncList(void) {
OPCODE(sfPlacardOff),
OPCODE(sfSetProtagState),
OPCODE(sfResumeBgdAnim),
- OPCODE(SF_throwActor),
+ OPCODE(sfThrowActor),
OPCODE(sfWaitWalk),
OPCODE(sfScriptSceneID),
- OPCODE(SF_changeActorScene),
- OPCODE(SF_climb),
+ OPCODE(sfChangeActorScene),
+ OPCODE(sfScriptClimb),
OPCODE(sfSetDoorState),
OPCODE(SF_setActorZ),
OPCODE(SF_text),
@@ -889,7 +889,7 @@ void Script::sfScriptWalk(SCRIPTFUNC_PARAMS) {
// Param4: cycle delay
void Script::sfCycleFrames(SCRIPTFUNC_PARAMS) {
int16 actorId;
- int flags;
+ int16 flags;
int cycleFrameSequence;
int cycleDelay;
ActorData *actor;
@@ -1360,17 +1360,39 @@ void Script::sfResumeBgdAnim(SCRIPTFUNC_PARAMS) {
}
// Script function #52 (0x34)
-void Script::SF_throwActor(SCRIPTFUNC_PARAMS) {
- int param1, param2, param3, param4, param5, param6;
+// Param1: actor id
+// Param2: x
+// Param3: y
+// Param4: unknown
+// Param5: actionCycle
+// Param6: flags
+void Script::sfThrowActor(SCRIPTFUNC_PARAMS) {
+ int16 actorId;
+ ActorData *actor;
+ int16 flags;
+ int32 actionCycle;
+ Location location;
- param1 = thread->pop();
- param2 = thread->pop();
- param3 = thread->pop();
- param4 = thread->pop();
- param5 = thread->pop();
- param6 = thread->pop();
+ actorId = thread->pop();
+ location.x = thread->pop();
+ location.y = thread->pop();
+ thread->pop();
+ actionCycle = thread->pop();
+ flags = thread->pop();
- warning("STUB: SF_throwActor(%d, %d, %d, %d, %d, %d)", param1, param2, param3, param4, param5, param6);
+ actor = _vm->_actor->getActor(actorId);
+ location.z = actor->location.z;
+ actor->currentAction = kActionFall;
+ actor->actionCycle = actionCycle;
+ actor->fallAcceleration = -20;
+ actor->fallVelocity = - (actor->fallAcceleration * actor->actionCycle) / 2;
+ actor->fallPosition = actor->location.z << 4;
+
+ actor->finalTarget = location;
+ actor->actionCycle--;
+ if (!(flags & kWalkAsync)) {
+ thread->waitWalk(actor);
+ }
}
// Script function #53 (0x35)
@@ -1396,21 +1418,45 @@ void Script::sfScriptSceneID(SCRIPTFUNC_PARAMS) {
}
// Script function #55 (0x37)
-void Script::SF_changeActorScene(SCRIPTFUNC_PARAMS) {
- int param1 = thread->pop();
- int param2 = thread->pop();
+// Param1: actor id
+// Param2: scene number
+void Script::sfChangeActorScene(SCRIPTFUNC_PARAMS) {
+ int16 actorId;
+ int32 sceneNumber;
+ ActorData *actor;
- error("STUB: SF_changeActorScene(%d, %d)", param1, param2);
+ actorId = thread->pop();
+ sceneNumber = thread->pop();
+ actor = _vm->_actor->getActor(actorId);
+ actor->sceneNumber = sceneNumber;
}
// Script function #56 (0x38)
-void Script::SF_climb(SCRIPTFUNC_PARAMS) {
- int param1 = thread->pop();
- int param2 = thread->pop();
- int param3 = thread->pop();
- int param4 = thread->pop();
+// Param1: actor id
+// Param2: z
+// Param3: frame seq
+// Param4: flags
+void Script::sfScriptClimb(SCRIPTFUNC_PARAMS) {
+ int16 actorId;
+ int16 z;
+ ActorData *actor;
+ uint16 flags;
+ int cycleFrameSequence;
- error("STUB: SF_climb(%d, %d, %d, %d)", param1, param2, param3, param4);
+ actorId = thread->pop();
+ z = thread->pop();
+ cycleFrameSequence = thread->pop();
+ flags = thread->pop();
+
+ actor = _vm->_actor->getActor(actorId);
+ actor->finalTarget.z = z;
+ actor->flags &= ~kFollower;
+ actor->actionCycle = 1;
+ actor->cycleFrameSequence = cycleFrameSequence;
+ actor->currentAction = kActionClimb;
+ if (!(flags & kWalkAsync)) {
+ thread->waitWalk(actor);
+ }
}
// Script function #57 (0x39)