aboutsummaryrefslogtreecommitdiff
path: root/saga
diff options
context:
space:
mode:
authorAndrew Kurushin2004-12-22 21:04:50 +0000
committerAndrew Kurushin2004-12-22 21:04:50 +0000
commit3d9784f94d3bc6c425d3180e59d322ab715e6306 (patch)
tree1313b3b88f8a6f9341a72c4fc178dad582f924c5 /saga
parentab4734dcf60d8f06786cbdd382a7a83ca962103a (diff)
downloadscummvm-rg350-3d9784f94d3bc6c425d3180e59d322ab715e6306.tar.gz
scummvm-rg350-3d9784f94d3bc6c425d3180e59d322ab715e6306.tar.bz2
scummvm-rg350-3d9784f94d3bc6c425d3180e59d322ab715e6306.zip
- rewriten actors action handling (now uses all original flags etc)
- added some script functions (swapactors...) - many things were renamed according scummvm covention - resource id definintions should begin with "RID_" prefix - intro temporary broken - work in progress todo: - walking hanling also should be rewriten - timings for speech and actor cycling should be more accurate svn-id: r16263
Diffstat (limited to 'saga')
-rw-r--r--saga/actor.cpp290
-rw-r--r--saga/actor.h139
-rw-r--r--saga/actordata.cpp3
-rw-r--r--saga/actordata.h9
-rw-r--r--saga/console.cpp16
-rw-r--r--saga/game.cpp16
-rw-r--r--saga/interface.cpp19
-rw-r--r--saga/ite_introproc.cpp46
-rw-r--r--saga/resnames.h129
-rw-r--r--saga/saga.cpp5
-rw-r--r--saga/saga.h4
-rw-r--r--saga/scene.cpp1
-rw-r--r--saga/script.cpp96
-rw-r--r--saga/script.h82
-rw-r--r--saga/sfuncs.cpp511
-rw-r--r--saga/sthread.cpp111
16 files changed, 959 insertions, 518 deletions
diff --git a/saga/actor.cpp b/saga/actor.cpp
index fc2336f415..f80b3a7bcd 100644
--- a/saga/actor.cpp
+++ b/saga/actor.cpp
@@ -44,9 +44,9 @@
namespace Saga {
static int actorCompare(const ActorDataPointer& actor1, const ActorDataPointer& actor2) {
- if (actor1->actorY == actor2->actorY) {
+ if (actor1->location.y == actor2->location.y) {
return 0;
- } else if (actor1->actorY < actor2->actorY) {
+ } else if (actor1->location.y < actor2->location.y) {
return -1;
} else {
return 1;
@@ -59,11 +59,25 @@ ACTIONTIMES ActionTDeltas[] = {
{ ACTION_SPEAK, 200 }
};
+// Lookup table to convert 8 cardinal directions to 4
+int ActorDirectectionsLUT[8] = {
+ ACTOR_DIRECTION_BACK, // kDirUp
+ ACTOR_DIRECTION_RIGHT, // kkDirUpRight
+ ACTOR_DIRECTION_RIGHT, // kDirRight
+ ACTOR_DIRECTION_RIGHT, // kDirDownRight
+ ACTOR_DIRECTION_FORWARD,// kDirDown
+ ACTOR_DIRECTION_LEFT, // kDirDownLeft
+ ACTOR_DIRECTION_LEFT, // kDirLeft
+ ACTOR_DIRECTION_LEFT, // kDirUpLeft
+};
+
Actor::Actor(SagaEngine *vm) : _vm(vm) {
int i;
ActorData *actor;
debug(9, "Actor::Actor()");
+ _centerActor = _protagonist = NULL;
+
// Get actor resource file context
_actorContext = _vm->getFileContext(GAME_RESOURCEFILE, 0);
if (_actorContext == NULL) {
@@ -80,15 +94,16 @@ Actor::Actor(SagaEngine *vm) : _vm(vm) {
actor->frameListResourceId = ActorTable[i].frameListResourceId;
actor->speechColor = ActorTable[i].speechColor;
actor->sceneNumber = ActorTable[i].sceneIndex;
-
actor->flags = ActorTable[i].flags;
- actor->orient = ACTOR_DEFAULT_ORIENT;
- actor->def_action = 0;
- actor->def_action_flags = 0;
- actor->action = 0;
- actor->action_flags = 0;
- actor->action_time = 0;
- actor->action_frame = 0;
+ actor->currentAction = ActorTable[i].currentAction;
+ actor->facingDirection = ActorTable[i].facingDirection;
+ actor->actionDirection = ActorTable[i].actionDirection;
+ actor->frameNumber = 0;
+ actor->targetObject = ID_NOTHING;
+
+ actor->location.x = ActorTable[i].x;
+ actor->location.y = ActorTable[i].y;
+ actor->location.z = ActorTable[i].z;
actor->disabled = !loadActorResources(actor);
if (actor->disabled) {
@@ -114,7 +129,7 @@ bool Actor::loadActorResources(ActorData * actor) {
byte *resourcePointer;
size_t resourceLength;
int framesCount;
- ActorFrame *framesPointer;
+ ActorFrameSequence *framesPointer;
int lastFrame;
int i, orient;
int result;
@@ -129,7 +144,7 @@ bool Actor::loadActorResources(ActorData * actor) {
framesCount = resourceLength / 16;
debug(9, "Frame resource contains %d frames", framesCount);
- framesPointer = (ActorFrame *)malloc(sizeof(ActorFrame) * framesCount);
+ framesPointer = (ActorFrameSequence *)malloc(sizeof(ActorFrameSequence) * framesCount);
if (framesPointer == NULL) {
error("Couldn't allocate memory for sprite frames");
}
@@ -139,12 +154,12 @@ bool Actor::loadActorResources(ActorData * actor) {
lastFrame = 0;
for (i = 0; i < framesCount; i++) {
- for (orient = 0; orient < ACTOR_ORIENTATION_COUNT; orient++) {
+ for (orient = 0; orient < ACTOR_DIRECTIONS_COUNT; orient++) {
// Load all four orientations
- framesPointer[i].dir[orient].frameIndex = readS.readUint16();
- framesPointer[i].dir[orient].frameCount = readS.readUint16();
- if (framesPointer[i].dir[orient].frameIndex > lastFrame) {
- lastFrame = framesPointer[i].dir[orient].frameIndex;
+ framesPointer[i].directions[orient].frameIndex = readS.readUint16();
+ framesPointer[i].directions[orient].frameCount = readS.readUint16();
+ if (framesPointer[i].directions[orient].frameIndex > lastFrame) {
+ lastFrame = framesPointer[i].directions[orient].frameIndex;
}
}
}
@@ -191,13 +206,40 @@ ActorData *Actor::getActor(uint16 actorId) {
void Actor::updateActorsScene() {
int i;
ActorData *actor;
+
+ _activeSpeech.stringsCount = 0;
for (i = 0; i < ACTORCOUNT; i++) {
- actor = &_actors[i];
+ actor = &_actors[i];
if (actor->flags & (kProtagonist | kFollower)) {
actor->sceneNumber = _vm->_scene->currentSceneNumber();
+ if (actor->flags & kProtagonist) {
+// actor->finalTarget = a->obj.loc;
+ _centerActor = _protagonist = actor;
+ }
+
}
+ if (actor->sceneNumber == _vm->_scene->currentSceneNumber())
+ actor->actionCycle = (rand() & 7) * 4;
}
+
+ handleActions(0, true);
+}
+
+ActorFrameRange *Actor::getActorFrameRange(uint16 actorId, int frameType) {
+ ActorData *actor;
+
+ actor = getActor(actorId);
+ if (actor->disabled)
+ error("Actor::getActorFrameRange Wrong actorId 0x%X", actorId);
+
+ if (frameType >= actor->framesCount)
+ error("Actor::getActorFrameRange Wrong frameType 0x%X actorId 0x%X", frameType, actorId);
+
+ if ((actor->facingDirection < kDirUp) || (actor->facingDirection > kDirUpLeft))
+ error("Actor::getActorFrameRange Wrong direction 0x%X actorId 0x%X", actor->facingDirection, actorId);
+
+ return &actor->frames[frameType].directions[actor->facingDirection];
}
void Actor::handleSpeech(int msec) {
@@ -283,9 +325,158 @@ void Actor::handleSpeech(int msec) {
_vm->_script->wakeUpThreadsDelayed(kWaitTypeSpeech, ticksToMSec(kScriptTimeTicksPerSecond / 3));
}
-int Actor::direct(int msec) {
+void Actor::handleActions(int msec, bool setup) {
int i;
ActorData *actor;
+ ActorFrameRange *frameRange;
+ int state;
+
+ for (i = 0; i < ACTORCOUNT; i++) {
+ actor = &_actors[i];
+ if (actor->disabled) continue;
+ if (actor->sceneNumber != _vm->_scene->currentSceneNumber()) continue;
+
+ //todo: dragon stuff
+
+ switch(actor->currentAction) {
+ case kActionWait: {
+ if (!setup && (actor->flags & kFollower)) {
+ //todo: followProtagonist
+ if (actor->currentAction != kActionWait)
+ break;
+ }
+
+ if (actor->targetObject != ID_NOTHING) {
+ //todo: facetowardsobject
+ }
+
+ if (actor->flags & kCycle) {
+ frameRange = getActorFrameRange( actor->actorId, kFrameStand);
+ if (frameRange->frameCount > 0) {
+ actor->actionCycle = (++actor->actionCycle) % frameRange->frameCount;
+ } else {
+ actor->actionCycle = 0;
+ }
+ actor->frameNumber = frameRange->frameIndex + actor->actionCycle;
+ break;
+ }
+
+ if ((actor->actionCycle & 3) == 0) {
+ actor->cycleWrap(100);
+
+ frameRange = getActorFrameRange( actor->actorId, kFrameWait);
+ if ((frameRange->frameCount < 1 || actor->actionCycle > 33))
+ frameRange = getActorFrameRange( actor->actorId, kFrameStand);
+
+ if (frameRange->frameCount) {
+ actor->frameNumber = frameRange->frameIndex + (uint16)rand() % frameRange->frameCount;
+ } else {
+ actor->frameNumber = frameRange->frameIndex;
+ }
+ }
+ actor->actionCycle++;
+ } break;
+ case kActionWalkToPoint:
+ case kActionWalkToLink: {
+ //todo: do it
+ debug(9,"kActionWalk* not implemented");
+ } break;
+ case kActionWalkDir: {
+ debug(9,"kActionWalkDir not implemented");
+ //todo: do it
+ } break;
+ case kActionSpeak: {
+ actor->actionCycle++;
+ actor->cycleWrap(64);
+
+ frameRange = getActorFrameRange( actor->actorId, kFrameGesture);
+ if (actor->actionCycle >= frameRange->frameCount) {
+ if (actor->actionCycle & 1) break;
+ frameRange = getActorFrameRange( actor->actorId, kFrameSpeak);
+ state = (uint16)rand() % (frameRange->frameCount + 1);
+
+ if (state == 0) {
+ frameRange = getActorFrameRange( actor->actorId, kFrameStand);
+ } else {
+ state--;
+ }
+ } else {
+ state = actor->actionCycle;
+ }
+
+ actor->frameNumber = frameRange->frameIndex + state;
+ } break;
+
+ case kActionAccept:
+ case kActionStoop:
+ break;
+
+ case kActionCycleFrames:
+ case kActionPongFrames: {
+ if (actor->cycleTimeCount > 0) {
+ actor->cycleTimeCount--;
+ break;
+ }
+
+ actor->cycleTimeCount = actor->cycleDelay;
+ actor->actionCycle++;
+
+ frameRange = getActorFrameRange( actor->actorId, actor->cycleFrameNumber);
+
+ if (actor->currentAction == kActionPongFrames) {
+ if (actor->actionCycle >= frameRange->frameCount * 2 - 2) {
+ if (actor->actorFlags & kActorContinuous) {
+ actor->actionCycle = 0;
+ } else {
+ actor->currentAction = kActionFreeze;
+ break;
+ }
+ }
+
+ state = actor->actionCycle;
+ if (state >= frameRange->frameCount) {
+ state = frameRange->frameCount * 2 - 2 - state;
+ }
+ } else {
+ if (actor->actionCycle >= frameRange->frameCount) {
+ if (actor->actorFlags & kActorContinuous) {
+ actor->actionCycle = 0;
+ } else {
+ actor->currentAction = kActionFreeze;
+ break;
+ }
+ }
+ state = actor->actionCycle;
+ }
+
+ if (frameRange->frameCount && (actor->actorFlags & kActorRandom)) {
+ state = rand() % frameRange->frameCount;
+ }
+
+ if (actor->actorFlags & kActorBackwards) {
+ actor->frameNumber = frameRange->frameIndex + frameRange->frameCount - 1 - state;
+ } else {
+ actor->frameNumber = frameRange->frameIndex + state;
+ }
+ } break;
+ case kActionFall: {
+ debug(9,"kActionFall not implemented");
+
+ //todo: do it
+ } break;
+ case kActionClimb: {
+ debug(9,"kActionClimb not implemented");
+
+ //todo: do it
+ } break;
+ }
+ }
+
+}
+
+int Actor::direct(int msec) {
+/* int i;
+ ActorData *actor;
ActorIntentList::iterator actorIntentIterator;
ACTORINTENT *a_intent;
@@ -351,6 +542,9 @@ int Actor::direct(int msec) {
}
}
}
+*/
+//process actions
+ handleActions(msec, false);
//process speech
handleSpeech(msec);
@@ -370,7 +564,7 @@ void Actor::createDrawOrderList() {
_drawOrderList.pushBack(actor, actorCompare);
- middle = ITE_STATUS_Y - actor->actorY / ACTOR_LMULT,
+ middle = ITE_STATUS_Y - actor->location.y / ACTOR_LMULT,
_vm->_scene->getSlopes(beginSlope, endSlope);
@@ -388,19 +582,16 @@ void Actor::createDrawOrderList() {
}
}
- actor->screenPosition.x = (actor->actorX / ACTOR_LMULT);
- actor->screenPosition.y = (actor->actorY / ACTOR_LMULT) - actor->actorZ;
+ actor->screenPosition.x = (actor->location.x / ACTOR_LMULT);
+ actor->screenPosition.y = (actor->location.y / ACTOR_LMULT) - actor->location.z;
}
}
int Actor::drawActors() {
ActorOrderList::iterator actorDrawOrderIterator;
ActorData *actor;
-
-
- int o_idx; //Orientation index
- int sprite_num;
-
+ int frameNumber;
+ SPRITELIST *spriteList;
SURFACE *back_buf;
@@ -410,19 +601,25 @@ int Actor::drawActors() {
for (actorDrawOrderIterator = _drawOrderList.begin(); actorDrawOrderIterator != _drawOrderList.end(); ++actorDrawOrderIterator) {
actor = actorDrawOrderIterator.operator*();
- if (actor->framesCount == 0) {
- warning("actor->framesCount == 0 actorId 0x%X", actor->actorId);
- continue;
- }
- o_idx = ActorOrientationLUT[actor->orient];
- sprite_num = actor->frames[actor->action].dir[o_idx].frameIndex;
- sprite_num += actor->action_frame;
- if (actor->spriteList->sprite_count <= sprite_num) {
- warning("(actor->spriteList->sprite_count <= sprite_num) actorId 0x%X", actor->actorId);
+ if (_vm->_scene->currentSceneNumber() == RID_ITE_OVERMAP_SCENE) {
+ if (!(actor->flags & kProtagonist)){
+ warning("not protagonist");
+ continue;
+ }
+ frameNumber = 8;
+ spriteList = _vm->_mainSprites;
+ } else {
+ frameNumber = actor->frameNumber;
+ spriteList = actor->spriteList;
+ }
+
+ if ((frameNumber < 0) || (spriteList->sprite_count <= frameNumber)) {
+ warning("Actor::drawActors frameNumber invalid for actorId 0x%X", actor->actorId);
continue;
}
- _vm->_sprite->drawOccluded(back_buf, actor->spriteList, sprite_num, actor->screenPosition, actor->screenScale, actor->screenDepth);
+
+ _vm->_sprite->drawOccluded(back_buf, spriteList, frameNumber, actor->screenPosition, actor->screenScale, actor->screenDepth);
}
// draw speeches
@@ -470,7 +667,7 @@ int Actor::drawActors() {
return SUCCESS;
}
-
+/*
void Actor::setOrientation(uint16 actorId, int orient) {
ActorData *actor;
@@ -540,7 +737,7 @@ void Actor::walkTo(uint16 actorId, const Point *walk_pt, uint16 flags, SEMAPHORE
_vm->_script->SThreadHoldSem(sem);
}
}
-
+*/
int Actor::setPathNode(WALKINTENT *walk_int, const Point &src_pt, Point *dst_pt, SEMAPHORE *sem) {
WALKNODE new_node;
@@ -556,7 +753,7 @@ int Actor::setPathNode(WALKINTENT *walk_int, const Point &src_pt, Point *dst_pt,
return SUCCESS;
}
-
+/*
int Actor::handleWalkIntent(ActorData *actor, WALKINTENT *a_walkint, int *complete_p, int delta_time) {
WalkNodeList::iterator walkNodeIterator;
WalkNodeList::iterator nextWalkNodeIterator;
@@ -722,7 +919,7 @@ void Actor::moveRelative(uint16 actorId, const Point &movePoint) {
actor->actorX += movePoint.x;
actor->actorY += movePoint.y;
}
-
+*/
void Actor::StoA(Point &actorPoint, const Point &screenPoint) {
actorPoint.x = (screenPoint.x * ACTOR_LMULT);
actorPoint.y = (screenPoint.y * ACTOR_LMULT);
@@ -768,10 +965,11 @@ void Actor::nonActorSpeech(const char **strings, int stringsCount, int speechFla
void Actor::simulSpeech(const char *string, uint16 *actorIds, int actorIdsCount, int speechFlags) {
int i;
-
+
for (i = 0; i < actorIdsCount; i++) {
_activeSpeech.actorIds[i] = actorIds[i];
}
+ _activeSpeech.actorsCount = actorIdsCount;
_activeSpeech.strings[0] = string;
_activeSpeech.stringsCount = 1;
_activeSpeech.speechFlags = speechFlags;
@@ -797,6 +995,7 @@ void Actor::abortSpeech() {
_activeSpeech.playingTime = 0;
}
+/*
// Console wrappers - must be safe to run
// TODO - checkup ALL arguments, cause wrong arguments may fall function with "error"
@@ -841,7 +1040,6 @@ void Actor::CF_actor_seto(int argc, const char **argv) {
return;
}
- setOrientation(actorId, orient);
}
void Actor::CF_actor_setact(int argc, const char **argv) {
@@ -856,7 +1054,7 @@ void Actor::CF_actor_setact(int argc, const char **argv) {
}
//TODO action_n check
-/* if ((action_n < 0) || (action_n >= actor->action_ct)) {
+ if ((action_n < 0) || (action_n >= actor->action_ct)) {
_vm->_console->DebugPrintf("Invalid action number.\n");
return;
}
@@ -866,8 +1064,8 @@ void Actor::CF_actor_setact(int argc, const char **argv) {
actor->act_tbl[action_n].dir[1].frame_count,
actor->act_tbl[action_n].dir[2].frame_count,
actor->act_tbl[action_n].dir[3].frame_count);
-*/
+
setAction(actorId, action_n, ACTION_LOOP);
}
-
+*/
} // End of namespace Saga
diff --git a/saga/actor.h b/saga/actor.h
index 61f57662df..8bdf921812 100644
--- a/saga/actor.h
+++ b/saga/actor.h
@@ -43,11 +43,18 @@ namespace Saga {
#define ACTOR_LMULT 4
-#define ACTOR_ORIENTATION_COUNT 4
+#define ACTOR_DIRECTIONS_COUNT 4 // for ActorFrameSequence
+#define ACTOR_DIRECTION_RIGHT 0
+#define ACTOR_DIRECTION_LEFT 1
+#define ACTOR_DIRECTION_BACK 2
+#define ACTOR_DIRECTION_FORWARD 3
-#define ACTOR_SPEECH_STRING_MAX 16
+#define ACTOR_SPEECH_STRING_MAX 16 // speech const
#define ACTOR_SPEECH_ACTORS_MAX 8
+#define ID_NOTHING 0
+#define ID_PROTAG 1
+
#define IS_VALID_ACTOR_INDEX(index) ((index >= 0) && (index < ACTORCOUNT))
#define IS_VALID_ACTOR_ID(id) ((id == 1) || (id >= 0x2000) && (id < (0x2000 | ACTORCOUNT)))
#define ACTOR_ID_TO_INDEX(id) ((((uint16)id) == 1 ) ? 0 : (int)(((uint16)id) & ~0x2000))
@@ -76,6 +83,44 @@ enum SpeechFlags {
kSpeakSlow = 4
};
+enum ActorDirections {
+ kDirUp = 0,
+ kDirUpRight = 1,
+ kDirRight = 2,
+ kDirDownRight = 3,
+ kDirDown = 4,
+ kDirDownLeft = 5,
+ kDirLeft = 6,
+ kDirUpLeft = 7
+};
+
+enum ActorFrameTypes {
+ kFrameStand = 0,
+ kFrameWalk = 1,
+ kFrameSpeak = 2,
+ kFrameGive = 3,
+ kFrameGesture = 4,
+ kFrameWait = 5,
+ kFramePickUp = 6,
+ kFrameLook = 7
+//...some special
+};
+
+enum ActorFlagsEx {
+ kActorNoCollide = (1 << 0),
+ kActorNoFollow = (1 << 1),
+ kActorCollided = (1 << 2),
+ kActorBackwards = (1 << 3),
+ kActorContinuous = (1 << 4),
+ kActorFinalFace = (1 << 5),
+ kActorFinishLeft = ((1 << 5) | (kDirLeft << 6)),
+ kActorFinishRight = ((1 << 5) | (kDirRight << 6)),
+ kActorFinishUp = ((1 << 5) | (kDirUp << 6)),
+ kActorFinishDown = ((1 << 5) | (kDirDown << 6)),
+ kActorFacing = (0xf << 5),
+ kActorRandom = (1 << 10)
+};
+
enum ACTOR_INTENTS {
INTENT_NONE = 0,
INTENT_PATH = 1
@@ -109,13 +154,13 @@ enum ACTOR_ACTIONFLAGS {
ACTION_LOOP = 0x01
};
-struct ActorOrientation {
+struct ActorFrameRange {
int frameIndex;
int frameCount;
};
-struct ActorFrame {
- ActorOrientation dir[ACTOR_ORIENTATION_COUNT];
+struct ActorFrameSequence {
+ ActorFrameRange directions[ACTOR_DIRECTIONS_COUNT];
};
struct WALKNODE {
@@ -159,9 +204,6 @@ struct WALKINTENT {
}
};
-
-
-
struct ACTORINTENT {
int a_itype;
uint16 a_iflags;
@@ -178,7 +220,11 @@ struct ACTORINTENT {
typedef Common::List<ACTORINTENT> ActorIntentList;
-
+struct ActorLocation {
+ int x; // Actor's logical coordinates
+ int y; //
+ int z; //
+};
struct ActorData {
bool disabled; // Actor disabled in init section
int index; // Actor index
@@ -189,9 +235,7 @@ struct ActorData {
int sceneNumber; // scene of actor
- int actorX; // Actor's logical coordinates
- int actorY; //
- int actorZ; //
+ ActorLocation location; // Actor's logical coordinates
Point screenPosition; // Actor's screen coordinates
int screenDepth; //
@@ -203,62 +247,73 @@ struct ActorData {
int actionDirection;
int actionCycle;
int frameNumber; // current actor frame number
+ uint16 targetObject;
+ int cycleFrameNumber;
+ uint8 cycleDelay;
+ uint8 cycleTimeCount;
+ uint8 cycleFlags;
+
SPRITELIST *spriteList; // Actor's sprite list data
int spriteListResourceId; // Actor's sprite list resource id
- ActorFrame *frames; // Actor's frames
+ ActorFrameSequence *frames; // Actor's frames
int framesCount; // Actor's frames count
int frameListResourceId; // Actor's frame list resource id
-
+///old stuff
int idle_time;
int orient;
int speaking;
-
-
- // The actor intent list describes what the actor intends to do;
- // multiple intents can be queued. The actor must complete an
- // intent before moving on to the next; thus actor movements, esp
- // as described from scripts, can be serialized
-
ActorIntentList a_intentlist;
-
- // WALKPATH path;
-
int def_action;
uint16 def_action_flags;
-
int action;
uint16 action_flags;
int action_frame;
int action_time;
-
+/// end old stuff
+
+ void cycleWrap(int cycleLimit) {
+ if (actionCycle >= cycleLimit)
+ actionCycle = 0;
+ }
ActorData() {
disabled = false;
index = 0;
actorId = 0;
+
nameIndex = 0;
speechColor = 0;
+
frames = NULL;
framesCount = 0;
frameListResourceId = 0;
+
spriteList = NULL;
spriteListResourceId = 0;
+
flags = 0;
sceneNumber = 0;
- actorX = 0;
- actorY = 0;
- actorZ = 0;
+ location.x = 0;
+ location.y = 0;
+ location.z = 0;
screenDepth = 0;
actorFlags = 0;
currentAction = 0;
facingDirection = 0;
actionDirection = 0;
+ actionCycle = 0;
+ targetObject = ID_NOTHING;
+
+ cycleFrameNumber = 0;
+ cycleDelay = 0;
+ cycleTimeCount = 0;
+ cycleFlags = 0;
idle_time = 0;
orient = 0;
@@ -301,30 +356,31 @@ struct SpeechData {
class Actor {
public:
+ ActorData *_centerActor;
+ ActorData *_protagonist;
+
Actor(SagaEngine *vm);
~Actor();
-
+/*
void CF_actor_move(int argc, const char **argv);
void CF_actor_moverel(int argc, const char **argv);
void CF_actor_seto(int argc, const char **argv);
void CF_actor_setact(int argc, const char **argv);
-
+*/
int direct(int msec);
int drawActors();
void updateActorsScene(); // calls from scene loading to update Actors info
void StoA(Point &actorPoint, const Point &screenPoint);
- void move(uint16 actorId, const Point &movePoint);
- void moveRelative(uint16 actorId, const Point &movePoint);
+ void move(uint16 actorId, const Point &movePoint){}
+ void moveRelative(uint16 actorId, const Point &movePoint){}
- void walkTo(uint16 actorId, const Point *walk_pt, uint16 flags, SEMAPHORE *sem);
-
-
-
- void setOrientation(uint16 actorId, int orient);
- void setAction(uint16 actorId, int action_n, uint16 action_flags);
- void setDefaultAction(uint16 actorId, int action_n, uint16 action_flags);
+ void walkTo(uint16 actorId, const Point *walk_pt, uint16 flags, SEMAPHORE *sem) {}
+
+ ActorData *getActor(uint16 actorId);
+// action
+ ActorFrameRange *getActorFrameRange(uint16 actorId, int frameType);
// speech
void actorSpeech(uint16 actorId, const char **strings, int stringsCount, uint16 sampleResourceId, int speechFlags);
@@ -342,14 +398,13 @@ public:
private:
int handleWalkIntent(ActorData *actor, WALKINTENT *a_walk_int, int *complete_p, int msec);
- int handleSpeakIntent(ActorData *actor, ACTORINTENT *a_aintent, int *complete_p, int msec);
int setPathNode(WALKINTENT *walk_int, const Point &src_pt, Point *dst_pt, SEMAPHORE *sem);
- ActorData *getActor(uint16 actorId);
bool loadActorResources(ActorData * actor);
void createDrawOrderList();
void handleSpeech(int msec);
+ void handleActions(int msec, bool setup);
SagaEngine *_vm;
RSCFILE_CONTEXT *_actorContext;
diff --git a/saga/actordata.cpp b/saga/actordata.cpp
index 896f126ff1..1e4a443a24 100644
--- a/saga/actordata.cpp
+++ b/saga/actordata.cpp
@@ -27,9 +27,6 @@
namespace Saga {
-// Lookup table to convert 8 cardinal directions to 4
-int ActorOrientationLUT[] = { 2, 0, 0, 0, 3, 1, 1, 1 };
-
ActorTableData ActorTable[ACTORCOUNT] = {
// flags name scene x y z spr frm scp col
// -------------- --- ---- ---- ----- ---- ---- ---- --- ---- --- -- --
diff --git a/saga/actordata.h b/saga/actordata.h
index 77cc64e7d6..e9b70eab6b 100644
--- a/saga/actordata.h
+++ b/saga/actordata.h
@@ -28,7 +28,7 @@
namespace Saga {
-enum {
+enum ActorFlags {
kProtagonist = 0x01, // Actor is protagonist
kFollower = 0x02, // Actor is follower
kCycle = 0x04, // Actor stand has a cycle
@@ -51,14 +51,13 @@ struct ActorTableData {
int32 frameListResourceId;
byte scriptResourceId;
byte speechColor;
- byte action;
- byte facing_dir;
- byte action_dir;
+ byte currentAction;
+ byte facingDirection;
+ byte actionDirection;
};
#define ACTORCOUNT 181
-extern int ActorOrientationLUT[];
extern ActorTableData ActorTable[ACTORCOUNT];
} // End of namespace Saga
diff --git a/saga/console.cpp b/saga/console.cpp
index b5ada851e1..903a91cd0b 100644
--- a/saga/console.cpp
+++ b/saga/console.cpp
@@ -151,34 +151,34 @@ bool Console::Cmd_Help(int argc, const char **argv) {
}
bool Console::Cmd_ActorMove(int argc, const char **argv) {
- if (argc != 4)
+/* if (argc != 4)
DebugPrintf("Usage: %s <Actor id> <lx> <ly>\n", argv[0]);
else
- _vm->_actor->CF_actor_move(argc, argv);
+ _vm->_actor->CF_actor_move(argc, argv);*/
return true;
}
bool Console::Cmd_ActorMoveRel(int argc, const char **argv) {
- if (argc != 4)
+/* if (argc != 4)
DebugPrintf("Usage: %s <Actor id> <lx> <ly>\n", argv[0]);
else
- _vm->_actor->CF_actor_moverel(argc, argv);
+ _vm->_actor->CF_actor_moverel(argc, argv);*/
return true;
}
bool Console::Cmd_ActorSetO(int argc, const char **argv) {
- if (argc != 3)
+/* if (argc != 3)
DebugPrintf("Usage: %s <Actor id> <Orientation>\n", argv[0]);
else
- _vm->_actor->CF_actor_seto(argc, argv);
+ _vm->_actor->CF_actor_seto(argc, argv);*/
return true;
}
bool Console::Cmd_ActorSetAct(int argc, const char **argv) {
- if (argc != 3)
+/* if (argc != 3)
DebugPrintf("Usage: %s <Actor id> <Action #>\n", argv[0]);
else
- _vm->_actor->CF_actor_setact(argc, argv);
+ _vm->_actor->CF_actor_setact(argc, argv);*/
return true;
}
diff --git a/saga/game.cpp b/saga/game.cpp
index 572274adc6..729e300647 100644
--- a/saga/game.cpp
+++ b/saga/game.cpp
@@ -115,10 +115,10 @@ static GAME_FONTDESC ITEDISK_GameFonts[] = {
};
static GAME_RESOURCEDESC ITE_Resources = {
- ITE_SCENE_LUT, // Scene lookup table RN
- ITE_SCRIPT_LUT, // Script lookup table RN
- ITE_COMMAND_PANEL,
- ITE_DIALOGUE_PANEL
+ RID_ITE_SCENE_LUT, // Scene lookup table RN
+ RID_ITE_SCRIPT_LUT, // Script lookup table RN
+ RID_ITE_COMMAND_PANEL,
+ RID_ITE_DIALOGUE_PANEL
};
static GAME_SOUNDINFO ITE_GameSound = {
@@ -181,10 +181,10 @@ static GAME_FONTDESC IHNMCD_GameFonts[] = {
};
static GAME_RESOURCEDESC IHNM_Resources = {
- IHNM_SCENE_LUT, // Scene lookup table RN
- IHNM_SCRIPT_LUT, // Script lookup table RN
- IHNM_COMMAND_PANEL,
- IHNM_DIALOGUE_PANEL
+ RID_IHNM_SCENE_LUT, // Scene lookup table RN
+ RID_IHNM_SCRIPT_LUT, // Script lookup table RN
+ RID_IHNM_COMMAND_PANEL,
+ RID_IHNM_DIALOGUE_PANEL
};
static GAME_SOUNDINFO IHNM_GameSound = {
diff --git a/saga/interface.cpp b/saga/interface.cpp
index ad58a17b08..a2f42d2318 100644
--- a/saga/interface.cpp
+++ b/saga/interface.cpp
@@ -36,7 +36,6 @@
#include "saga/sprite.h"
#include "saga/interface.h"
-#include "saga/sdata.h"
namespace Saga {
@@ -214,9 +213,9 @@ Interface::Interface(SagaEngine *vm) : _vm(vm), _initialized(false) {
return;
}
- _vm->_sprite->loadList(ITE_COMMAND_BUTTONSPRITES, &_cPanel.sprites);
+ _vm->_sprite->loadList(RID_ITE_COMMAND_BUTTONSPRITES, &_cPanel.sprites);
- _vm->_sprite->loadList(ITE_DEFAULT_PORTRAITS, &_defPortraits);
+ _vm->_sprite->loadList(RID_ITE_DEFAULT_PORTRAITS, &_defPortraits);
_vm->decodeBGImage(_cPanel.res, _cPanel.res_len, &_cPanel.img,
&_cPanel.img_len, &_cPanel.img_w, &_cPanel.img_h);
@@ -356,13 +355,13 @@ int Interface::draw() {
lportrait.x = xbase + _iDesc.lportrait_x;
lportrait.y = ybase + _iDesc.lportrait_y;
- _vm->_sprite->draw(back_buf, _defPortraits, _leftPortrait, lportrait, 1);
+ _vm->_sprite->draw(back_buf, _defPortraits, _leftPortrait, lportrait, 256);
if (_panelMode == kPanelDialogue && _iDesc.rportrait_x >= 0) {
rportrait.x = xbase + _iDesc.rportrait_x;
rportrait.y = ybase + _iDesc.rportrait_y;
- _vm->_sprite->draw(back_buf, _scenePortraits, _rightPortrait, rportrait, 1);
+ _vm->_sprite->draw(back_buf, _scenePortraits, _rightPortrait, rportrait, 256);
}
drawInventory();
@@ -480,7 +479,7 @@ int Interface::handleCommandClick(SURFACE *ds, const Point& imousePt) {
button.y = y_base + _cPanel.buttons[set_button].y1;
_vm->_sprite->draw(ds, _cPanel.sprites, _cPanel.buttons[set_button].
- active_sprite - 1, button, 1);
+ active_sprite - 1, button, 256);
}
if (_cPanel.buttons[old_set_button].flags & BUTTON_BITMAP) {
@@ -488,7 +487,7 @@ int Interface::handleCommandClick(SURFACE *ds, const Point& imousePt) {
button.y = y_base + _cPanel.buttons[old_set_button].y1;
_vm->_sprite->draw(ds, _cPanel.sprites, _cPanel.buttons[old_set_button].
- inactive_sprite - 1, button, 1);
+ inactive_sprite - 1, button, 256);
}
}
@@ -548,7 +547,7 @@ int Interface::handleCommandUpdate(SURFACE *ds, const Point& imousePt) {
if ((i == _cPanel.set_button) && (_cPanel.buttons[i].flags & BUTTON_BITMAP)) {
_vm->_sprite->draw(ds, _cPanel.sprites, _cPanel.buttons[i].active_sprite - 1,
- button, 1);
+ button, 256);
}
}
@@ -576,7 +575,7 @@ int Interface::handlePlayfieldClick(SURFACE *ds, const Point& imousePt) {
if (object_flags & OBJECT_EXIT) { // FIXME. This is wrong
if ((script_num = _vm->_scene->_objectMap->getEPNum(objectNum)) != -1) {
// Set active verb in script module
- _vm->_sdata->putWord(4, 4, I_VerbData[_activeVerb].s_verb);
+ _vm->_script->putWord(4, 4, I_VerbData[_activeVerb].s_verb);
// Execute object script if present
if (script_num != 0) {
@@ -708,7 +707,7 @@ void Interface::drawInventory() {
_vm->_sprite->draw(back_buf, _vm->_mainSprites,
ObjectTable[_inventory[i]].spritelistRn,
- drawPoint, 1);
+ drawPoint, 256);
if (++col >= _iDesc.inv_columns) {
if (++row >= _iDesc.inv_rows) {
diff --git a/saga/ite_introproc.cpp b/saga/ite_introproc.cpp
index 9a6dc9ea05..8af18ac39f 100644
--- a/saga/ite_introproc.cpp
+++ b/saga/ite_introproc.cpp
@@ -42,82 +42,82 @@ namespace Saga {
static INTRO_DIALOGUE IntroDiag[] = {
{
- CAVE_VOICE_0, "intro1a",
+ RID_CAVE_VOICE_0, "intro1a",
"We see the sky, we see the land, we see the water, "
"and we wonder: Are we the only ones?"
},
{
- CAVE_VOICE_1, "intro2a",
+ RID_CAVE_VOICE_1, "intro2a",
"Long before we came to exist, the humans ruled "
"the Earth."
},
{
- CAVE_VOICE_2, "intro3a",
+ RID_CAVE_VOICE_2, "intro3a",
"They made marvelous things, and moved whole " "mountains."
},
{
- CAVE_VOICE_3, "intro4a",
+ RID_CAVE_VOICE_3, "intro4a",
"They knew the Secret of Flight, the Secret of "
"Happiness, and other secrets beyond our imagining."
},
{
- CAVE_VOICE_4, "intro1b",
+ RID_CAVE_VOICE_4, "intro1b",
"The humans also knew the Secret of Life, "
"and they used it to give us the Four Great Gifts:"
},
{
- CAVE_VOICE_5, "intro2b",
+ RID_CAVE_VOICE_5, "intro2b",
"Thinking minds, feeling hearts, speaking "
"mouths, and reaching hands."
},
{
- CAVE_VOICE_6, "intro3b",
+ RID_CAVE_VOICE_6, "intro3b",
"We are their children."
},
{
- CAVE_VOICE_7, "intro1c",
+ RID_CAVE_VOICE_7, "intro1c",
"They taught us how to use our hands, and how " "to speak."
},
{
- CAVE_VOICE_8, "intro2c",
+ RID_CAVE_VOICE_8, "intro2c",
"They showed us the joy of using our minds."
},
{
- CAVE_VOICE_9, "intro3c",
+ RID_CAVE_VOICE_9, "intro3c",
"They loved us, and when we were ready, they "
"surely would have given us the Secret of Happiness."
},
{
- CAVE_VOICE_10, "intro1d",
+ RID_CAVE_VOICE_10, "intro1d",
"And now we see the sky, the land, and the water "
"that we are heirs to, and we wonder: why did "
"they leave?"
},
{
- CAVE_VOICE_11, "intro2d",
+ RID_CAVE_VOICE_11, "intro2d",
"Do they live still, in the stars? In the oceans "
"depths? In the wind?"
},
{
- CAVE_VOICE_12, "intro3d",
+ RID_CAVE_VOICE_12, "intro3d",
"We wonder, was their fate good or evil?"
},
{
- CAVE_VOICE_13, "intro4d",
+ RID_CAVE_VOICE_13, "intro4d",
"And will we also share the same fate one day?"
},
};
SCENE_QUEUE ITE_IntroList[] = {
- {ITE_INTRO_ANIM_SCENE, NULL, BY_RESOURCE, Scene::SC_ITEIntroAnimProc, 0, SCENE_NOFADE},
- {ITE_CAVE_SCENE_1, NULL, BY_RESOURCE, Scene::SC_ITEIntroCave1Proc, 0, SCENE_FADE_NO_INTERFACE},
- {ITE_CAVE_SCENE_2, NULL, BY_RESOURCE, Scene::SC_ITEIntroCave2Proc, 0, SCENE_NOFADE},
- {ITE_CAVE_SCENE_3, NULL, BY_RESOURCE, Scene::SC_ITEIntroCave3Proc, 0, SCENE_NOFADE},
- {ITE_CAVE_SCENE_4, NULL, BY_RESOURCE, Scene::SC_ITEIntroCave4Proc, 0, SCENE_NOFADE},
- {ITE_VALLEY_SCENE, NULL, BY_RESOURCE, Scene::SC_ITEIntroValleyProc, 0, SCENE_FADE_NO_INTERFACE},
- {ITE_TREEHOUSE_SCENE, NULL, BY_RESOURCE, Scene::SC_ITEIntroTreeHouseProc, 0, SCENE_NOFADE},
- {ITE_FAIREPATH_SCENE, NULL, BY_RESOURCE, Scene::SC_ITEIntroFairePathProc, 0, SCENE_NOFADE},
- {ITE_FAIRETENT_SCENE, NULL, BY_RESOURCE, Scene::SC_ITEIntroFaireTentProc, 0, SCENE_NOFADE}
+ {RID_ITE_INTRO_ANIM_SCENE, NULL, BY_RESOURCE, Scene::SC_ITEIntroAnimProc, 0, SCENE_NOFADE},
+ {RID_ITE_CAVE_SCENE_1, NULL, BY_RESOURCE, Scene::SC_ITEIntroCave1Proc, 0, SCENE_FADE_NO_INTERFACE},
+ {RID_ITE_CAVE_SCENE_2, NULL, BY_RESOURCE, Scene::SC_ITEIntroCave2Proc, 0, SCENE_NOFADE},
+ {RID_ITE_CAVE_SCENE_3, NULL, BY_RESOURCE, Scene::SC_ITEIntroCave3Proc, 0, SCENE_NOFADE},
+ {RID_ITE_CAVE_SCENE_4, NULL, BY_RESOURCE, Scene::SC_ITEIntroCave4Proc, 0, SCENE_NOFADE},
+ {RID_ITE_VALLEY_SCENE, NULL, BY_RESOURCE, Scene::SC_ITEIntroValleyProc, 0, SCENE_FADE_NO_INTERFACE},
+ {RID_ITE_TREEHOUSE_SCENE, NULL, BY_RESOURCE, Scene::SC_ITEIntroTreeHouseProc, 0, SCENE_NOFADE},
+ {RID_ITE_FAIREPATH_SCENE, NULL, BY_RESOURCE, Scene::SC_ITEIntroFairePathProc, 0, SCENE_NOFADE},
+ {RID_ITE_FAIRETENT_SCENE, NULL, BY_RESOURCE, Scene::SC_ITEIntroFaireTentProc, 0, SCENE_NOFADE}
};
int Scene::ITEStartProc() {
diff --git a/saga/resnames.h b/saga/resnames.h
index c6b9b5977f..c56b722032 100644
--- a/saga/resnames.h
+++ b/saga/resnames.h
@@ -28,85 +28,88 @@
namespace Saga {
+// Prefix RID_ means Resource Id
+
// Lookup tables
-#define ITE_SCENE_LUT 1806
-#define ITE_SCRIPT_LUT 216
+#define RID_ITE_SCENE_LUT 1806
+#define RID_ITE_SCRIPT_LUT 216
- // Hmmm.... as far as I see origginal uses now commented values, but they're wrong
-#define IHNM_SCENE_LUT 1272 // 286
-#define IHNM_SCRIPT_LUT 0 // 18
+ // Hmmm.... as far as I see original uses now commented values, but they're wrong
+#define RID_IHNM_SCENE_LUT 1272 // 286
+#define RID_IHNM_SCRIPT_LUT 0 // 18
// SCENES
#define ITE_DEFAULT_SCENE 32
// FONTS
-#define RN_MEDIUM_FONT 0
-#define RN_BIG_FONT 1
-#define RN_SMALL_FONT 2
+#define RID_MEDIUM_FONT 0
+#define RID_BIG_FONT 1
+#define RID_SMALL_FONT 2
// INTERFACE IMAGES
-#define ITE_COMMAND_PANEL 3
-#define ITE_DIALOGUE_PANEL 4
+#define RID_ITE_COMMAND_PANEL 3
+#define RID_ITE_DIALOGUE_PANEL 4
-#define IHNM_COMMAND_PANEL 9
-#define IHNM_DIALOGUE_PANEL 10
+#define RID_IHNM_COMMAND_PANEL 9
+#define RID_IHNM_DIALOGUE_PANEL 10
-#define ITE_SETUP_PANEL 5
-#define ITE_MAIN_SPRITES 6
-#define ITE_COMMAND_BUTTONSPRITES 7
-#define ITE_DEFAULT_PORTRAITS 125
+#define RID_ITE_SETUP_PANEL 5
+#define RID_ITE_MAIN_SPRITES 6
+#define RID_ITE_COMMAND_BUTTONSPRITES 7
+#define RID_ITE_DEFAULT_PORTRAITS 125
// ITE Scene resource numbers
-#define ITE_INTRO_ANIM_SCENE 1538
-#define ITE_CAVE_SCENE_1 1542
-#define ITE_CAVE_SCENE_2 1545
-#define ITE_CAVE_SCENE_3 1548
-#define ITE_CAVE_SCENE_4 1551
-
-#define ITE_VALLEY_SCENE 1556
-#define ITE_TREEHOUSE_SCENE 1560
-#define ITE_FAIREPATH_SCENE 1564
-#define ITE_FAIRETENT_SCENE 1567
-
-#define ITE_INTRO_ANIM_STARTFRAME 1529
-
-#define INTRO_ANIM_1 1530
-#define INTRO_ANIM_2 1531
-#define INTRO_ANIM_3 1532
-#define INTRO_ANIM_4 1533
-#define INTRO_ANIM_5 1534
-#define INTRO_ANIM_6 1535
-#define INTRO_ANIM_7 1536
-
-#define CAVE_IMG_1 1540
-#define CAVE_IMG_2 1543
-#define CAVE_IMG_3 1546
-#define CAVE_IMG_4 1549
-
-#define INTRO_IMG_1 1552
-#define INTRO_IMG_2 1557
-#define INTRO_IMG_3 1561
-#define INTRO_IMG_4 1565
+#define RID_ITE_OVERMAP_SCENE 226
+#define RID_ITE_INTRO_ANIM_SCENE 1538
+#define RID_ITE_CAVE_SCENE_1 1542
+#define RID_ITE_CAVE_SCENE_2 1545
+#define RID_ITE_CAVE_SCENE_3 1548
+#define RID_ITE_CAVE_SCENE_4 1551
+
+#define RID_ITE_VALLEY_SCENE 1556
+#define RID_ITE_TREEHOUSE_SCENE 1560
+#define RID_ITE_FAIREPATH_SCENE 1564
+#define RID_ITE_FAIRETENT_SCENE 1567
+
+#define RID_ITE_INTRO_ANIM_STARTFRAME 1529
+
+#define RID_ITE_INTRO_ANIM_1 1530
+#define RID_ITE_INTRO_ANIM_2 1531
+#define RID_ITE_INTRO_ANIM_3 1532
+#define RID_ITE_INTRO_ANIM_4 1533
+#define RID_ITE_INTRO_ANIM_5 1534
+#define RID_ITE_INTRO_ANIM_6 1535
+#define RID_ITE_INTRO_ANIM_7 1536
+
+#define RID_ITE_CAVE_IMG_1 1540
+#define RID_ITE_CAVE_IMG_2 1543
+#define RID_ITE_CAVE_IMG_3 1546
+#define RID_ITE_CAVE_IMG_4 1549
+
+#define RID_ITE_INTRO_IMG_1 1552
+#define RID_ITE_INTRO_IMG_2 1557
+#define RID_ITE_INTRO_IMG_3 1561
+#define RID_ITE_INTRO_IMG_4 1565
// ITE_VOICES
-#define CAVE_VOICE_0 0
-#define CAVE_VOICE_1 1
-#define CAVE_VOICE_2 2
-#define CAVE_VOICE_3 3
-#define CAVE_VOICE_4 4
-#define CAVE_VOICE_5 5
-#define CAVE_VOICE_6 6
-#define CAVE_VOICE_7 7
-#define CAVE_VOICE_8 8
-#define CAVE_VOICE_9 9
-#define CAVE_VOICE_10 10
-#define CAVE_VOICE_11 11
-#define CAVE_VOICE_12 12
-#define CAVE_VOICE_13 13
-
-#define SCENE1_VOICE_009 57
+#define RID_CAVE_VOICE_0 0
+#define RID_CAVE_VOICE_1 1
+#define RID_CAVE_VOICE_2 2
+#define RID_CAVE_VOICE_3 3
+#define RID_CAVE_VOICE_4 4
+#define RID_CAVE_VOICE_5 5
+#define RID_CAVE_VOICE_6 6
+#define RID_CAVE_VOICE_7 7
+#define RID_CAVE_VOICE_8 8
+#define RID_CAVE_VOICE_9 9
+#define RID_CAVE_VOICE_10 10
+#define RID_CAVE_VOICE_11 11
+#define RID_CAVE_VOICE_12 12
+#define RID_CAVE_VOICE_13 13
+
+#define RID_SCENE1_VOICE_009 57
//TODO: fill it
-#define SCENE1_VOICE_138 186
+#define RID_SCENE1_VOICE_138 186
// MUSIC
diff --git a/saga/saga.cpp b/saga/saga.cpp
index 25680a7383..c22e38eb19 100644
--- a/saga/saga.cpp
+++ b/saga/saga.cpp
@@ -45,7 +45,6 @@
#include "saga/isomap.h"
#include "saga/script.h"
#include "saga/scene.h"
-#include "saga/sdata.h"
#include "saga/sndres.h"
#include "saga/sprite.h"
#include "saga/sound.h"
@@ -151,7 +150,6 @@ int SagaEngine::init(GameDetector &detector) {
_sprite = new Sprite(this);
_anim = new Anim(this);
_script = new Script();
- _sdata = new SData();
_interface = new Interface(this); // requires script module
_actor = new Actor(this);
_palanim = new PalAnim(this);
@@ -218,7 +216,7 @@ int SagaEngine::go() {
_previousTicks = _system->getMillis();
- _sprite->loadList(ITE_MAIN_SPRITES, &_mainSprites);
+ _sprite->loadList(RID_ITE_MAIN_SPRITES, &_mainSprites);
// Begin Main Engine Loop
@@ -270,7 +268,6 @@ void SagaEngine::shutdown() {
delete _render;
delete _isoMap;
delete _sndRes;
- delete _sdata;
// Shutdown system modules */
delete _music;
delete _sound;
diff --git a/saga/saga.h b/saga/saga.h
index 9c6aa7b8da..88a87ce6dd 100644
--- a/saga/saga.h
+++ b/saga/saga.h
@@ -49,7 +49,6 @@ class Anim;
class Render;
class IsoMap;
class Gfx;
-class SData;
class Script;
class Actor;
class Font;
@@ -217,7 +216,6 @@ public:
Render *_render;
IsoMap *_isoMap;
Gfx *_gfx;
- SData *_sdata;
Script *_script;
Actor *_actor;
Font *_font;
@@ -263,7 +261,7 @@ public:
int processInput(void);
Point getMousePos();
-private:
+ private:
Point _mousePos;
public:
diff --git a/saga/scene.cpp b/saga/scene.cpp
index 8d9e8cff51..8793bc57cf 100644
--- a/saga/scene.cpp
+++ b/saga/scene.cpp
@@ -409,6 +409,7 @@ int Scene::loadScene(int scene_num, int load_flag, SCENE_PROC scene_proc, SCENE_
_sceneMode = 0;
_loadDesc = true;
+ _sceneNumber = -1;
switch (load_flag) {
case BY_RESOURCE:
diff --git a/saga/script.cpp b/saga/script.cpp
index dc178d9a41..9b6395beaf 100644
--- a/saga/script.cpp
+++ b/saga/script.cpp
@@ -52,7 +52,14 @@ Script::Script() {
_currentScript = 0;
_abortEnabled = true;
_skipSpeeches = false;
- memset(_dataBuf, 0, sizeof(_dataBuf));
+
+ _dataBuf[0].data = _dataBuf[1].data = (ScriptDataWord *)calloc(SCRIPT_DATABUF_LEN, sizeof(ScriptDataWord));;
+ _dataBuf[0].length = _dataBuf[1].length = SCRIPT_DATABUF_LEN;
+
+ for (i = 2; i < SCRIPT_DATABUF_NUM; i++) {
+ _dataBuf[i].length = 0;
+ _dataBuf[i].data = NULL;
+ }
gr_desc = _vm->getResourceInfo();
@@ -138,9 +145,96 @@ Script::~Script() {
// Free script lookup table
free(_scriptLUT);
+ free(_dataBuf[0].data);
+
_initialized = false;
}
+int Script::getWord(int bufNumber, int wordNumber, ScriptDataWord *data) {
+ if ((bufNumber < 0) || (bufNumber >= SCRIPT_DATABUF_NUM)) {
+ return FAILURE;
+ }
+
+ if ((wordNumber < 0) || (wordNumber >= _dataBuf[bufNumber].length)) {
+ return FAILURE;
+ }
+
+ if (data == NULL) {
+ return FAILURE;
+ }
+
+ *data = _dataBuf[bufNumber].data[wordNumber];
+
+ return SUCCESS;
+}
+
+int Script::putWord(int bufNumber, int wordNumber, ScriptDataWord data) {
+ if ((bufNumber < 0) || (bufNumber >= SCRIPT_DATABUF_NUM)) {
+ return FAILURE;
+ }
+
+ if ((wordNumber < 0) || (wordNumber >= _dataBuf[bufNumber].length)) {
+ return FAILURE;
+ }
+
+ _dataBuf[bufNumber].data[wordNumber] = data;
+
+ return SUCCESS;
+}
+
+int Script::setBit(int bufNumber, ScriptDataWord bitNumber, int bitState) {
+ int wordNumber;
+ int bitPos;
+
+ ScriptDataWord bitPattern = 0x01;
+
+ if ((bufNumber < 0) || (bufNumber >= SCRIPT_DATABUF_NUM)) {
+ return FAILURE;
+ }
+
+ if (bitNumber >= (unsigned long)_dataBuf[bufNumber].length * (sizeof(ScriptDataWord) * CHAR_BIT)) {
+ return FAILURE;
+ }
+
+ wordNumber = bitNumber / (sizeof(ScriptDataWord) * CHAR_BIT);
+ bitPos = bitNumber % (sizeof(ScriptDataWord) * CHAR_BIT);
+
+ bitPattern <<= ((sizeof(ScriptDataWord) * CHAR_BIT) - (bitPos + 1));
+
+ if (bitState) {
+ _dataBuf[bufNumber].data[wordNumber] |= bitPattern;
+ } else {
+ _dataBuf[bufNumber].data[wordNumber] &= ~bitPattern;
+ }
+
+ return SUCCESS;
+}
+
+int Script::getBit(int bufNumber, ScriptDataWord bitNumber, int *bitState) {
+ int wordNumber;
+ int bitPos;
+
+ ScriptDataWord bitPattern = 0x01;
+
+ if ((bufNumber < 0) || (bufNumber >= SCRIPT_DATABUF_NUM)) {
+ return FAILURE;
+ }
+
+ if (bitNumber >= (unsigned long)_dataBuf[bufNumber].length * (sizeof(ScriptDataWord) * CHAR_BIT)) {
+ return FAILURE;
+ }
+
+ wordNumber = bitNumber / (sizeof(ScriptDataWord) * CHAR_BIT);
+ bitPos = bitNumber % (sizeof(ScriptDataWord) * CHAR_BIT);
+
+ bitPattern <<= ((sizeof(ScriptDataWord) * CHAR_BIT) - (bitPos + 1));
+
+
+ *bitState = (_dataBuf[bufNumber].data[wordNumber] & bitPattern) ? 1 : 0;
+
+ return SUCCESS;
+}
+
// Loads a script; including script bytecode and dialogue list
int Script::loadScript(int script_num) {
SCRIPTDATA *script_data;
diff --git a/saga/script.h b/saga/script.h
index 0019c6a5a8..78c42779bf 100644
--- a/saga/script.h
+++ b/saga/script.h
@@ -47,9 +47,9 @@ namespace Saga {
#define S_ERROR_PREFIX "SError: "
#define S_WARN_PREFIX "SWarning: "
-#define SFUNC_NUM 78
+#define SCRIPT_FUNCTION_MAX 78
-typedef unsigned int SDataWord_T;
+typedef unsigned int ScriptDataWord;
enum SCRIPT_VERBS {
S_VERB_WALKTO = 0,
@@ -95,9 +95,20 @@ enum ThreadWaitTypes {
};
enum OpCodes {
+
+//...
+ opCcall = 0x18,
+ opCcallV = 0x19,
+//...
opSpeak = 0x53
};
+enum CycleFlags {
+ kCyclePong = (1 << 0),
+ kCycleOnce = (1 << 1),
+ kCycleRandom = (1 << 2),
+ kCycleReverse = (1 << 3)
+};
struct SCRIPT_THREAD {
int flags; // ThreadFlags
int waitType; // ThreadWaitTypes
@@ -113,16 +124,16 @@ struct SCRIPT_THREAD {
// area. It's therefore probably quite important that our stacks work
// the same as in the original interpreter.
- SDataWord_T stackBuf[64];
+ ScriptDataWord stackBuf[64];
int stackPtr;
int framePtr;
- SDataWord_T threadVars[4];
+ ScriptDataWord threadVars[4];
- SDataWord_T retVal;
+ ScriptDataWord retVal;
- SDataWord_T stackTop() {
+ ScriptDataWord stackTop() {
return stackBuf[stackPtr];
}
@@ -130,12 +141,12 @@ struct SCRIPT_THREAD {
return ARRAYSIZE(stackBuf) - stackPtr - 1;
}
- void push(SDataWord_T n) {
+ void push(ScriptDataWord n) {
assert(stackPtr > 0);
stackBuf[--stackPtr] = n;
}
- SDataWord_T pop() {
+ ScriptDataWord pop() {
assert(stackPtr < ARRAYSIZE(stackBuf));
return stackBuf[stackPtr++];
}
@@ -186,9 +197,9 @@ struct SCRIPT_LUT_ENTRY {
int voice_lut_rn;
};
-struct SCRIPT_DATABUF {
- SDataWord_T *data;
- int len;
+struct ScriptDataBuf {
+ ScriptDataWord *data;
+ int length;
};
#define SCRIPTFUNC_PARAMS SCRIPT_THREAD *thread, int nArgs
@@ -210,8 +221,11 @@ public:
bool isInitialized() const { return _initialized; }
bool isVoiceLUTPresent() const { return _voiceLUTPresent; }
SCRIPTDATA *currentScript() { return _currentScript; }
- void setBuffer(int idx, SCRIPT_DATABUF *ptr) { _dataBuf[idx] = ptr; }
- SCRIPT_DATABUF *dataBuffer(int idx) { return _dataBuf[idx]; }
+ ScriptDataBuf *dataBuffer(int idx) { return &_dataBuf[idx]; }
+ int getWord(int bufNumber, int wordNumber, ScriptDataWord *data);
+ int putWord(int bufNumber, int wordNumber, ScriptDataWord data);
+ int setBit(int bufNumber, ScriptDataWord bitNumber, int bitState);
+ int getBit(int bufNumber, ScriptDataWord bitNumber, int *bitState);
const char *getString(int index);
void scriptInfo();
@@ -225,7 +239,7 @@ protected:
int _scriptLUTMax;
uint16 _scriptLUTEntryLen;
SCRIPTDATA *_currentScript;
- SCRIPT_DATABUF *_dataBuf[SCRIPT_DATABUF_NUM];
+ ScriptDataBuf _dataBuf[SCRIPT_DATABUF_NUM];
ScriptThreadList _threadList;
@@ -260,29 +274,29 @@ private:
int SThreadSetEntrypoint(SCRIPT_THREAD *thread, int ep_num);
private:
- typedef int (Script::*SFunc_T)(SCRIPTFUNC_PARAMS);
+ typedef int (Script::*ScriptFunctionType)(SCRIPTFUNC_PARAMS);
- const SFunc_T *_SFuncList;
+ const ScriptFunctionType *_scriptFunctionsList;
void setupScriptFuncList(void);
int SDebugPrintInstr(SCRIPT_THREAD *thread);
int SF_putString(SCRIPTFUNC_PARAMS);
- int SF_sleep(SCRIPTFUNC_PARAMS);
+ int sfWait(SCRIPTFUNC_PARAMS);
int SF_takeObject(SCRIPTFUNC_PARAMS);
int SF_objectIsCarried(SCRIPTFUNC_PARAMS);
int SF_setStatusText(SCRIPTFUNC_PARAMS);
int SF_commandMode(SCRIPTFUNC_PARAMS);
int SF_actorWalkTo(SCRIPTFUNC_PARAMS);
int SF_doAction(SCRIPTFUNC_PARAMS);
- int SF_setFacing(SCRIPTFUNC_PARAMS);
+ int sfSetActorFacing(SCRIPTFUNC_PARAMS);
int SF_startBgdAnim(SCRIPTFUNC_PARAMS);
int SF_stopBgdAnim(SCRIPTFUNC_PARAMS);
int SF_freezeInterface(SCRIPTFUNC_PARAMS);
int SF_dialogMode(SCRIPTFUNC_PARAMS);
int SF_killActorThreads(SCRIPTFUNC_PARAMS);
int SF_faceTowards(SCRIPTFUNC_PARAMS);
- int SF_setFollower(SCRIPTFUNC_PARAMS);
+ int sfSetFollower(SCRIPTFUNC_PARAMS);
int SF_gotoScene(SCRIPTFUNC_PARAMS);
int SF_setObjImage(SCRIPTFUNC_PARAMS);
int SF_setObjName(SCRIPTFUNC_PARAMS);
@@ -297,20 +311,20 @@ private:
int SF_actorWalkToAsync(SCRIPTFUNC_PARAMS);
int SF_enableZone(SCRIPTFUNC_PARAMS);
int SF_setActorState(SCRIPTFUNC_PARAMS);
- int SF_moveTo(SCRIPTFUNC_PARAMS);
+ int scriptMoveTo(SCRIPTFUNC_PARAMS);
int SF_sceneEq(SCRIPTFUNC_PARAMS);
int SF_dropObject(SCRIPTFUNC_PARAMS);
int SF_finishBgdAnim(SCRIPTFUNC_PARAMS);
- int SF_swapActors(SCRIPTFUNC_PARAMS);
- int SF_simulSpeech(SCRIPTFUNC_PARAMS);
+ int sfSwapActors(SCRIPTFUNC_PARAMS);
+ int sfSimulSpeech(SCRIPTFUNC_PARAMS);
int SF_actorWalk(SCRIPTFUNC_PARAMS);
- int SF_cycleActorFrames(SCRIPTFUNC_PARAMS);
- int SF_setFrame(SCRIPTFUNC_PARAMS);
+ int sfCycleFrames(SCRIPTFUNC_PARAMS);
+ int sfSetFrame(SCRIPTFUNC_PARAMS);
int SF_setRightPortrait(SCRIPTFUNC_PARAMS);
int SF_setLeftPortrait(SCRIPTFUNC_PARAMS);
int SF_linkAnim(SCRIPTFUNC_PARAMS);
int SF_scriptSpecialWalk(SCRIPTFUNC_PARAMS);
- int SF_placeActor(SCRIPTFUNC_PARAMS);
+ int sfPlaceActor(SCRIPTFUNC_PARAMS);
int SF_checkUserInterrupt(SCRIPTFUNC_PARAMS);
int SF_walkRelative(SCRIPTFUNC_PARAMS);
int SF_moveRelative(SCRIPTFUNC_PARAMS);
@@ -347,6 +361,24 @@ private:
int SF_playVoice(SCRIPTFUNC_PARAMS);
};
+inline int getSWord(ScriptDataWord word) {
+ uint16 uInt = word;
+ int sInt;
+
+ if (uInt & 0x8000U) {
+ sInt = (int)(uInt - 0x8000U) - 0x7FFF - 1;
+ } else {
+ sInt = uInt;
+ }
+
+ return sInt;
+}
+
+inline uint getUWord(ScriptDataWord word) {
+ return (uint16) word;
+}
+
+
} // End of namespace Saga
#endif
diff --git a/saga/sfuncs.cpp b/saga/sfuncs.cpp
index 2636214677..ad1604e472 100644
--- a/saga/sfuncs.cpp
+++ b/saga/sfuncs.cpp
@@ -36,7 +36,6 @@
#include "saga/sndres.h"
#include "saga/script.h"
-#include "saga/sdata.h"
#include "saga/scene.h"
@@ -45,23 +44,23 @@ namespace Saga {
#define OPCODE(x) &Script::x
void Script::setupScriptFuncList(void) {
- static const SFunc_T SFuncList[SFUNC_NUM] = {
+ static const ScriptFunctionType scriptFunctionsList[SCRIPT_FUNCTION_MAX] = {
OPCODE(SF_putString),
- OPCODE(SF_sleep),
+ OPCODE(sfWait),
OPCODE(SF_takeObject),
OPCODE(SF_objectIsCarried),
OPCODE(SF_setStatusText),
OPCODE(SF_commandMode),
OPCODE(SF_actorWalkTo),
OPCODE(SF_doAction),
- OPCODE(SF_setFacing),
+ OPCODE(sfSetActorFacing),
OPCODE(SF_startBgdAnim),
OPCODE(SF_stopBgdAnim),
OPCODE(SF_freezeInterface),
OPCODE(SF_dialogMode),
OPCODE(SF_killActorThreads),
OPCODE(SF_faceTowards),
- OPCODE(SF_setFollower),
+ OPCODE(sfSetFollower),
OPCODE(SF_gotoScene),
OPCODE(SF_setObjImage),
OPCODE(SF_setObjName),
@@ -76,20 +75,20 @@ void Script::setupScriptFuncList(void) {
OPCODE(SF_actorWalkToAsync),
OPCODE(SF_enableZone),
OPCODE(SF_setActorState),
- OPCODE(SF_moveTo),
+ OPCODE(scriptMoveTo),
OPCODE(SF_sceneEq),
OPCODE(SF_dropObject),
OPCODE(SF_finishBgdAnim),
- OPCODE(SF_swapActors),
- OPCODE(SF_simulSpeech),
+ OPCODE(sfSwapActors),
+ OPCODE(sfSimulSpeech),
OPCODE(SF_actorWalk),
- OPCODE(SF_cycleActorFrames),
- OPCODE(SF_setFrame),
+ OPCODE(sfCycleFrames),
+ OPCODE(sfSetFrame),
OPCODE(SF_setRightPortrait),
OPCODE(SF_setLeftPortrait),
OPCODE(SF_linkAnim),
OPCODE(SF_scriptSpecialWalk),
- OPCODE(SF_placeActor),
+ OPCODE(sfPlaceActor),
OPCODE(SF_checkUserInterrupt),
OPCODE(SF_walkRelative),
OPCODE(SF_moveRelative),
@@ -125,27 +124,25 @@ void Script::setupScriptFuncList(void) {
OPCODE(SF_fadeMusic),
OPCODE(SF_playVoice)
};
- _SFuncList = SFuncList;
+ _scriptFunctionsList = scriptFunctionsList;
}
// Script function #0 (0x00)
// Print a debugging message
int Script::SF_putString(SCRIPTFUNC_PARAMS) {
- SDataWord_T param = thread->pop();
+ ScriptDataWord param = thread->pop();
_vm->_console->DebugPrintf(getString(param));
return SUCCESS;
}
// Script function #1 (0x01) blocking
-// Suspends thread execution for the specified time period
-int Script::SF_sleep(SCRIPTFUNC_PARAMS) {
- SDataWord_T time_param;
- long time;
+// Param1: time in ticks
+int Script::sfWait(SCRIPTFUNC_PARAMS) {
+ int time;
+ time = getUWord(thread->pop());
if (!_skipSpeeches) {
- time_param = thread->pop();
- time = _vm->_sdata->readWordU(time_param);
thread->wait(kWaitTypeDelay); // put thread to sleep
thread->sleepTime = ticksToMSec(time);
}
@@ -154,7 +151,7 @@ int Script::SF_sleep(SCRIPTFUNC_PARAMS) {
// Script function #2 (0x02)
int Script::SF_takeObject(SCRIPTFUNC_PARAMS) {
- SDataWord_T param = thread->pop();
+ ScriptDataWord param = thread->pop();
int index = param & 0x1FFF;
if (index >= ARRAYSIZE(ObjectTable)) {
@@ -172,7 +169,7 @@ int Script::SF_takeObject(SCRIPTFUNC_PARAMS) {
// Script function #3 (0x03)
// Check if an object is carried.
int Script::SF_objectIsCarried(SCRIPTFUNC_PARAMS) {
- SDataWord_T param = thread->pop();
+ ScriptDataWord param = thread->pop();
int index = param & 0x1FFF;
if (index >= ARRAYSIZE(ObjectTable)) {
@@ -188,7 +185,7 @@ int Script::SF_objectIsCarried(SCRIPTFUNC_PARAMS) {
// Set the command display to the specified text string
// Param1: dialogue index of string
int Script::SF_setStatusText(SCRIPTFUNC_PARAMS) {
- SDataWord_T param = thread->pop();
+ ScriptDataWord param = thread->pop();
return _vm->_interface->setStatusText(getString(param));
}
@@ -204,9 +201,9 @@ int Script::SF_commandMode(SCRIPTFUNC_PARAMS) {
// Param2: actor destination x
// Param3: actor destination y
int Script::SF_actorWalkTo(SCRIPTFUNC_PARAMS) {
- SDataWord_T actor_parm;
- SDataWord_T x_parm;
- SDataWord_T y_parm;
+ ScriptDataWord actor_parm;
+ ScriptDataWord x_parm;
+ ScriptDataWord y_parm;
uint16 actorId;
Point pt;
@@ -214,10 +211,10 @@ int Script::SF_actorWalkTo(SCRIPTFUNC_PARAMS) {
x_parm = thread->pop();
y_parm = thread->pop();
- actorId = _vm->_sdata->readWordS(actor_parm);
+ actorId = getSWord(actor_parm);
- pt.x = _vm->_sdata->readWordS(x_parm);
- pt.y = _vm->_sdata->readWordS(y_parm);
+ pt.x = getSWord(x_parm);
+ pt.y = getSWord(y_parm);
_vm->_actor->walkTo(actorId, &pt, 0, &thread->sem);
@@ -226,10 +223,10 @@ int Script::SF_actorWalkTo(SCRIPTFUNC_PARAMS) {
// Script function #7 (0x07)
int Script::SF_doAction(SCRIPTFUNC_PARAMS) {
- SDataWord_T actor_parm = thread->pop();
- SDataWord_T action_parm = thread->pop();
- SDataWord_T obj_parm = thread->pop();
- SDataWord_T withobj_parm = thread->pop();
+ ScriptDataWord actor_parm = thread->pop();
+ ScriptDataWord action_parm = thread->pop();
+ ScriptDataWord obj_parm = thread->pop();
+ ScriptDataWord withobj_parm = thread->pop();
// The parameters correspond with the thread variables.
@@ -238,29 +235,26 @@ int Script::SF_doAction(SCRIPTFUNC_PARAMS) {
}
// Script function #8 (0x08) nonblocking
-// Sets the orientation of the specified actor.
// Param1: actor id
// Param2: actor orientation
-int Script::SF_setFacing(SCRIPTFUNC_PARAMS) {
- SDataWord_T actor_parm;
- SDataWord_T orient_parm;
+int Script::sfSetActorFacing(SCRIPTFUNC_PARAMS) {
uint16 actorId;
- int orientation;
+ int actorDirection;
+ ActorData *actor;
- actor_parm = thread->pop();
- orient_parm = thread->pop();
+ actorId = getSWord(thread->pop());
+ actorDirection = getSWord(thread->pop());
- actorId = _vm->_sdata->readWordS(actor_parm);
- orientation = _vm->_sdata->readWordS(orient_parm);
+ actor = _vm->_actor->getActor(actorId);
+ actor->facingDirection = actor->actionDirection = actorDirection;
- _vm->_actor->setOrientation(actorId, orientation);
return SUCCESS;
}
// Script function #9 (0x09)
int Script::SF_startBgdAnim(SCRIPTFUNC_PARAMS) {
- SDataWord_T param1 = thread->pop();
- SDataWord_T param2 = thread->pop();
+ ScriptDataWord param1 = thread->pop();
+ ScriptDataWord param2 = thread->pop();
debug(1, "stub: SF_startBgdAnim(%d, %d)", param1, param2);
return SUCCESS;
@@ -268,7 +262,7 @@ int Script::SF_startBgdAnim(SCRIPTFUNC_PARAMS) {
// Script function #10 (0x0A)
int Script::SF_stopBgdAnim(SCRIPTFUNC_PARAMS) {
- SDataWord_T param = thread->pop();
+ ScriptDataWord param = thread->pop();
debug(1, "stub: SF_stopBgdAnim(%d)", param);
return SUCCESS;
@@ -280,7 +274,7 @@ int Script::SF_stopBgdAnim(SCRIPTFUNC_PARAMS) {
// reenabled.
// Param1: boolean
int Script::SF_freezeInterface(SCRIPTFUNC_PARAMS) {
- SDataWord_T b_param;
+ ScriptDataWord b_param;
b_param = thread->pop();
@@ -310,26 +304,41 @@ int Script::SF_killActorThreads(SCRIPTFUNC_PARAMS) {
// Script function #14 (0x0E)
int Script::SF_faceTowards(SCRIPTFUNC_PARAMS) {
- SDataWord_T param1 = thread->pop();
- SDataWord_T param2 = thread->pop();
+ ScriptDataWord param1 = thread->pop();
+ ScriptDataWord param2 = thread->pop();
debug(1, "stub: SF_faceTowards(%d, %d)", param1, param2);
return SUCCESS;
}
// Script function #15 (0x0F)
-int Script::SF_setFollower(SCRIPTFUNC_PARAMS) {
- SDataWord_T param1 = thread->pop();
- SDataWord_T param2 = thread->pop();
+// Param1: actor id
+// Param2: target object
+int Script::sfSetFollower(SCRIPTFUNC_PARAMS) {
+ uint16 actorId;
+ uint16 targetObject;
+
+ ActorData *actor;
- debug(1, "stub: SF_setFollower(%d, %d)", param1, param2);
+ actorId = getSWord(thread->pop());
+ targetObject = getSWord(thread->pop());
+
+ actor = _vm->_actor->getActor(actorId);
+ actor->targetObject = targetObject;
+ if (targetObject != ID_NOTHING) {
+ actor->flags |= kFollower;
+ actor->actorFlags &= ~kActorNoFollow;
+ } else {
+ actor->flags &= ~kFollower;
+ }
+
return SUCCESS;
}
// Script function #16 (0x10)
int Script::SF_gotoScene(SCRIPTFUNC_PARAMS) {
- SDataWord_T param1 = thread->pop();
- SDataWord_T param2 = thread->pop();
+ ScriptDataWord param1 = thread->pop();
+ ScriptDataWord param2 = thread->pop();
debug(1, "stub: SF_gotoScene(%d, %d)", param1, param2);
return SUCCESS;
@@ -337,8 +346,8 @@ int Script::SF_gotoScene(SCRIPTFUNC_PARAMS) {
// Script function #17 (0x11)
int Script::SF_setObjImage(SCRIPTFUNC_PARAMS) {
- SDataWord_T obj_param = thread->pop();
- SDataWord_T sprite_param = thread->pop();
+ ScriptDataWord obj_param = thread->pop();
+ ScriptDataWord sprite_param = thread->pop();
int index = obj_param & 0x1FFF;
@@ -354,8 +363,8 @@ int Script::SF_setObjImage(SCRIPTFUNC_PARAMS) {
// Script function #18 (0x12)
int Script::SF_setObjName(SCRIPTFUNC_PARAMS) {
- SDataWord_T obj_param = thread->pop();
- SDataWord_T name_param = thread->pop();
+ ScriptDataWord obj_param = thread->pop();
+ ScriptDataWord name_param = thread->pop();
int index = obj_param & 0x1FFF;
@@ -369,7 +378,7 @@ int Script::SF_setObjName(SCRIPTFUNC_PARAMS) {
// Script function #19 (0x13)
int Script::SF_getObjImage(SCRIPTFUNC_PARAMS) {
- SDataWord_T param = thread->pop();
+ ScriptDataWord param = thread->pop();
int index = param & 0x1FFF;
if (index >= ARRAYSIZE(ObjectTable)) {
@@ -410,8 +419,8 @@ int Script::SF_closeDoor(SCRIPTFUNC_PARAMS) {
// Script function #23 (0x17)
int Script::SF_setBgdAnimSpeed(SCRIPTFUNC_PARAMS) {
- SDataWord_T param1 = thread->pop();
- SDataWord_T param2 = thread->pop();
+ ScriptDataWord param1 = thread->pop();
+ ScriptDataWord param2 = thread->pop();
debug(1, "stub: SF_setBgdAnimSpeed(%d, %d)", param1, param2);
return SUCCESS;
@@ -428,7 +437,7 @@ int Script::SF_cycleColors(SCRIPTFUNC_PARAMS) {
// Script function #25 (0x19)
int Script::SF_centerActor(SCRIPTFUNC_PARAMS) {
- SDataWord_T param = thread->pop();
+ ScriptDataWord param = thread->pop();
debug(1, "stub: SF_centerActor(%d)", param);
return SUCCESS;
@@ -441,9 +450,9 @@ int Script::SF_centerActor(SCRIPTFUNC_PARAMS) {
// Param3: animation id
int Script::SF_startAnim(SCRIPTFUNC_PARAMS) {
// FIXME: implementation is wrong. Should link animation
- SDataWord_T timer_parm;
- SDataWord_T frame_parm;
- SDataWord_T anim_id_parm;
+ ScriptDataWord timer_parm;
+ ScriptDataWord frame_parm;
+ ScriptDataWord anim_id_parm;
int frame_count;
int anim_id;
@@ -451,8 +460,8 @@ int Script::SF_startAnim(SCRIPTFUNC_PARAMS) {
frame_parm = thread->pop();
timer_parm = thread->pop();
- frame_count = _vm->_sdata->readWordS(frame_parm);
- anim_id = _vm->_sdata->readWordS(anim_id_parm);
+ frame_count = getSWord(frame_parm);
+ anim_id = getSWord(anim_id_parm);
if (_vm->_anim->play(anim_id, 0) != SUCCESS) {
_vm->_console->DebugPrintf(S_WARN_PREFIX "SF.26: Anim::play() failed. Anim id: %u\n", anim_id);
@@ -468,9 +477,9 @@ int Script::SF_startAnim(SCRIPTFUNC_PARAMS) {
// Param2: actor destination x
// Param3: actor destination y
int Script::SF_actorWalkToAsync(SCRIPTFUNC_PARAMS) {
- SDataWord_T actor_parm;
- SDataWord_T x_parm;
- SDataWord_T y_parm;
+ ScriptDataWord actor_parm;
+ ScriptDataWord x_parm;
+ ScriptDataWord y_parm;
uint16 actorId;
Point pt;
@@ -479,10 +488,10 @@ int Script::SF_actorWalkToAsync(SCRIPTFUNC_PARAMS) {
x_parm = thread->pop();
y_parm = thread->pop();
- actorId = _vm->_sdata->readWordS(actor_parm);
+ actorId = getSWord(actor_parm);
- pt.x = _vm->_sdata->readWordS(x_parm);
- pt.y = _vm->_sdata->readWordS(y_parm);
+ pt.x = getSWord(x_parm);
+ pt.y = getSWord(y_parm);
_vm->_actor->walkTo(actorId, &pt, 0, NULL);
return SUCCESS;
@@ -499,42 +508,37 @@ int Script::SF_enableZone(SCRIPTFUNC_PARAMS) {
// Script function #29 (0x1D)
int Script::SF_setActorState(SCRIPTFUNC_PARAMS) {
- SDataWord_T param1 = thread->pop();
- SDataWord_T param2 = thread->pop();
+ ScriptDataWord param1 = thread->pop();
+ ScriptDataWord param2 = thread->pop();
debug(1, "stub: SF_setActorState(%d, %d)", param1, param2);
return SUCCESS;
}
// Script function #30 (0x1E) nonblocking
-// Positions an actor at the specified location; actor is created if the
-// actor does not already exist.
// Param1: actor id
// Param2: actor pos x
// Param3: actor pos y
-int Script::SF_moveTo(SCRIPTFUNC_PARAMS) {
- SDataWord_T actor_parm;
- SDataWord_T x_parm;
- SDataWord_T y_parm;
+int Script::scriptMoveTo(SCRIPTFUNC_PARAMS) {
uint16 actorId;
- Point pt;
+ ActorLocation actorLocation;
+ ActorData *actor;
- actor_parm = thread->pop();
- x_parm = thread->pop();
- y_parm = thread->pop();
+ actorId = getSWord(thread->pop());
+ actorLocation.x = getSWord(thread->pop());
+ actorLocation.y = getSWord(thread->pop());
- actorId = _vm->_sdata->readWordS(actor_parm);
- pt.x = _vm->_sdata->readWordS(x_parm);
- pt.y = _vm->_sdata->readWordS(y_parm);
+ actor = _vm->_actor->getActor(actorId);
- _vm->_actor->move(actorId, pt);
+ actor->location.x = actorLocation.x;
+ actor->location.y = actorLocation.y;
return SUCCESS;
}
// Script function #31 (0x21)
int Script::SF_sceneEq(SCRIPTFUNC_PARAMS) {
- SDataWord_T param = thread->pop();
+ ScriptDataWord param = thread->pop();
if (_vm->_scene->getSceneLUT(param) == _vm->_scene->currentSceneNumber())
thread->retVal = 1;
@@ -545,10 +549,10 @@ int Script::SF_sceneEq(SCRIPTFUNC_PARAMS) {
// Script function #32 (0x20)
int Script::SF_dropObject(SCRIPTFUNC_PARAMS) {
- SDataWord_T obj_param = thread->pop();
- SDataWord_T sprite_param = thread->pop();
- SDataWord_T x_param = thread->pop();
- SDataWord_T y_param = thread->pop();
+ ScriptDataWord obj_param = thread->pop();
+ ScriptDataWord sprite_param = thread->pop();
+ ScriptDataWord x_param = thread->pop();
+ ScriptDataWord y_param = thread->pop();
int index = obj_param & 0x1FFF;
@@ -570,27 +574,73 @@ int Script::SF_dropObject(SCRIPTFUNC_PARAMS) {
// Script function #33 (0x21)
int Script::SF_finishBgdAnim(SCRIPTFUNC_PARAMS) {
- SDataWord_T param = thread->pop();
+ ScriptDataWord param = thread->pop();
debug(1, "stub: SF_finishBgdAnim(%d)", param);
return SUCCESS;
}
// Script function #34 (0x22)
-int Script::SF_swapActors(SCRIPTFUNC_PARAMS) {
- SDataWord_T param1 = thread->pop();
- SDataWord_T param2 = thread->pop();
+// Param1: actor id 1
+// Param2: actor id 2
+int Script::sfSwapActors(SCRIPTFUNC_PARAMS) {
+ uint16 actorId1;
+ uint16 actorId2;
+ ActorData *actor1;
+ ActorData *actor2;
+ ActorLocation location;
+
+ actorId1 = getSWord(thread->pop());
+ actorId2 = getSWord(thread->pop());
+
+ actor1 = _vm->_actor->getActor(actorId1);
+ actor2 = _vm->_actor->getActor(actorId2);
+ location = actor1->location;
+ actor1->location = actor2->location;
+ actor2->location = location;
+
+
+ if (actor1->flags & kProtagonist) {
+ actor1->flags &= ~kProtagonist;
+ actor2->flags |= kProtagonist;
+ _vm->_actor->_protagonist = _vm->_actor->_centerActor = actor2;
+ } else {
+ if (actor2->flags & kProtagonist) {
+ actor2->flags &= ~kProtagonist;
+ actor1->flags |= kProtagonist;
+ _vm->_actor->_protagonist = _vm->_actor->_centerActor = actor1;
+ }
+ }
+
- debug(1, "stub: SF_swapActors(%d, %d)", param1, param2);
return SUCCESS;
}
// Script function #35 (0x23)
-int Script::SF_simulSpeech(SCRIPTFUNC_PARAMS) {
- for (int i = 0; i < nArgs; i++)
- thread->pop();
+// Param1: string rid
+// Param2: actorscount
+// Param3: actor id1
+///....
+// Param3: actor idN
+int Script::sfSimulSpeech(SCRIPTFUNC_PARAMS) {
+ ScriptDataWord stringId;
+ int actorsCount;
+ int i;
+ uint16 actorsIds[ACTOR_SPEECH_ACTORS_MAX];
+ const char *string;
+
+ stringId = thread->pop();
+ actorsCount = getSWord(thread->pop());
+
+ if (actorsCount > ACTOR_SPEECH_ACTORS_MAX)
+ error("sfSimulSpeech actorsCount=0x%X exceed ACTOR_SPEECH_ACTORS_MAX", actorsCount);
+
+ for (i = 0; i < actorsCount; i++)
+ actorsIds[i] = getSWord(thread->pop());
+
+ string = getString(stringId);
- debug(1, "stub: SF_simulSpeech(), %d args", nArgs);
+ _vm->_actor->simulSpeech(string, actorsIds, actorsCount, 0);
return SUCCESS;
}
@@ -602,10 +652,10 @@ int Script::SF_simulSpeech(SCRIPTFUNC_PARAMS) {
// Param4: flags telling how to walk
int Script::SF_actorWalk(SCRIPTFUNC_PARAMS) {
// INCOMPLETE
- SDataWord_T actor_parm;
- SDataWord_T x_parm;
- SDataWord_T y_parm;
- SDataWord_T flags_parm;
+ ScriptDataWord actor_parm;
+ ScriptDataWord x_parm;
+ ScriptDataWord y_parm;
+ ScriptDataWord flags_parm;
uint16 actorId;
Point pt;
@@ -614,10 +664,10 @@ int Script::SF_actorWalk(SCRIPTFUNC_PARAMS) {
y_parm = thread->pop();
flags_parm = thread->pop();
- actorId = _vm->_sdata->readWordS(actor_parm);
+ actorId = getSWord(actor_parm);
- pt.x = _vm->_sdata->readWordS(x_parm);
- pt.y = _vm->_sdata->readWordS(y_parm);
+ pt.x = getSWord(x_parm);
+ pt.y = getSWord(y_parm);
#if 1
_vm->_actor->walkTo(actorId, &pt, 0, NULL);
@@ -629,56 +679,76 @@ int Script::SF_actorWalk(SCRIPTFUNC_PARAMS) {
}
// Script function #37 (0x25) nonblocking
-// Sets an actor to the specified action state
// Param1: actor id
// Param2: flags telling how to cycle the frames
-// Param3: actor action state
-// Param4: some kind of delay/speed thing?
-int Script::SF_cycleActorFrames(SCRIPTFUNC_PARAMS) {
- // INCOMPLETE
- SDataWord_T actor_parm;
- SDataWord_T flags_parm;
- SDataWord_T delay_parm;
- SDataWord_T action_parm;
+// Param3: cycle frame number
+// Param4: cycle delay
+int Script::sfCycleFrames(SCRIPTFUNC_PARAMS) {
uint16 actorId;
- int action;
- //uint16 flags;
+ int flags;
+ int cycleFrameNumber;
+ int cycleDelay;
+ ActorData *actor;
- actor_parm = thread->pop();
- flags_parm = thread->pop();
- action_parm = thread->pop();
- delay_parm = thread->pop();
- actorId = _vm->_sdata->readWordS(actor_parm);
- action = _vm->_sdata->readWordS(action_parm);
+ actorId = getSWord(thread->pop());
+ flags = getUWord(thread->pop());
+ cycleFrameNumber = getUWord(thread->pop());
+ cycleDelay = getUWord(thread->pop());
+
+ actor = _vm->_actor->getActor(actorId);
+
+ if (flags & kCyclePong) {
+ actor->currentAction = kActionPongFrames;
+ } else {
+ actor->currentAction = kActionCycleFrames;
+ }
+
+ actor->actorFlags &= ~(kActorContinuous | kActorRandom | kActorBackwards);
+
+ if (!(flags & kCycleOnce)) {
+ actor->actorFlags |= kActorContinuous;
+ }
+ if (flags & kCycleRandom) {
+ actor->actorFlags |= kActorRandom;
+ }
+ if (flags & kCycleReverse) {
+ actor->actorFlags |= kActorBackwards;
+ }
- _vm->_actor->setAction(actorId, action, ACTION_NONE);
+ actor->cycleFrameNumber = cycleFrameNumber;
+ actor->cycleTimeCount = 0;
+ actor->cycleDelay = cycleDelay;
+ actor->actionCycle = 0;
return SUCCESS;
}
// Script function #38 (0x26) nonblocking
-// Sets an actor to the specified action state
// Param1: actor id
-// Param2: actor action state
-// Param3: which frame of the action to use
-int Script::SF_setFrame(SCRIPTFUNC_PARAMS) {
- // INCOMPLETE
+// Param2: frame type
+// Param3: frame offset
+int Script::sfSetFrame(SCRIPTFUNC_PARAMS) {
+ uint16 actorId;
+ int frameType;
+ int frameOffset;
+ ActorData *actor;
+ ActorFrameRange *frameRange;
- SDataWord_T actorParam;
- SDataWord_T actionParam;
- SDataWord_T frameParam;
+ actorId = getSWord(thread->pop());
+ frameType = getSWord(thread->pop());
+ frameOffset = getSWord(thread->pop());
- uint16 actorId;
- int action;
+ actor = _vm->_actor->getActor(actorId);
- actorParam = thread->pop();
- actionParam = thread->pop();
- frameParam = thread->pop();
+ frameRange = _vm->_actor->getActorFrameRange(actorId, frameType);
- actorId = _vm->_sdata->readWordS(actorParam);
- action = _vm->_sdata->readWordS(actionParam);
+ if (frameRange->frameCount <= frameOffset)
+ error("Wrong frameOffset 0x%X", frameOffset);
+ actor->frameNumber = frameRange->frameIndex + frameOffset;
- _vm->_actor->setAction(actorId, action, ACTION_NONE);
+ if (actor->currentAction != kActionFall) {
+ actor->currentAction = kActionFreeze;
+ }
return SUCCESS;
}
@@ -686,7 +756,7 @@ int Script::SF_setFrame(SCRIPTFUNC_PARAMS) {
// Script function #39 (0x27)
// Sets the right-hand portrait
int Script::SF_setRightPortrait(SCRIPTFUNC_PARAMS) {
- SDataWord_T param = thread->pop();
+ ScriptDataWord param = thread->pop();
return _vm->_interface->setRightPortrait(param);
}
@@ -694,7 +764,7 @@ int Script::SF_setRightPortrait(SCRIPTFUNC_PARAMS) {
// Script function #40 (0x28)
// Sets the left-hand portrait
int Script::SF_setLeftPortrait(SCRIPTFUNC_PARAMS) {
- SDataWord_T param = thread->pop();
+ ScriptDataWord param = thread->pop();
return _vm->_interface->setLeftPortrait(param);
}
@@ -707,10 +777,10 @@ int Script::SF_setLeftPortrait(SCRIPTFUNC_PARAMS) {
// Param3: animation id link target
// Param4: animation id link source
int Script::SF_linkAnim(SCRIPTFUNC_PARAMS) {
- SDataWord_T timer_parm;
- SDataWord_T tframes_parm;
- SDataWord_T anim1_parm;
- SDataWord_T anim2_parm;
+ ScriptDataWord timer_parm;
+ ScriptDataWord tframes_parm;
+ ScriptDataWord anim1_parm;
+ ScriptDataWord anim2_parm;
int tframes;
uint16 anim_id1;
uint16 anim_id2;
@@ -719,9 +789,9 @@ int Script::SF_linkAnim(SCRIPTFUNC_PARAMS) {
anim2_parm = thread->pop();
tframes_parm = thread->pop();
timer_parm = thread->pop();
- tframes = _vm->_sdata->readWordS(tframes_parm);
- anim_id1 = _vm->_sdata->readWordU(anim1_parm);
- anim_id2 = _vm->_sdata->readWordU(anim2_parm);
+ tframes = getSWord(tframes_parm);
+ anim_id1 = getUWord(anim1_parm);
+ anim_id2 = getUWord(anim2_parm);
if (_vm->_anim->link(anim_id1, anim_id2) != SUCCESS) {
_vm->_console->DebugPrintf(S_WARN_PREFIX "SF.41: Anim::link() failed. (%u->%u)\n", anim_id1, anim_id2);
@@ -733,54 +803,55 @@ int Script::SF_linkAnim(SCRIPTFUNC_PARAMS) {
// Script function #42 (0x2A)
int Script::SF_scriptSpecialWalk(SCRIPTFUNC_PARAMS) {
- SDataWord_T param1 = thread->pop();
- SDataWord_T param2 = thread->pop();
- SDataWord_T param3 = thread->pop();
- SDataWord_T param4 = thread->pop();
+ ScriptDataWord param1 = thread->pop();
+ ScriptDataWord param2 = thread->pop();
+ ScriptDataWord param3 = thread->pop();
+ ScriptDataWord param4 = thread->pop();
debug(1, "stub: SF_scriptSpecialWalk(%d, %d, %d, %d)", param1, param2, param3, param4);
return SUCCESS;
}
// Script function #43 (0x2B) nonblocking
-// Positions an actor at the specified location; actor is created if the
-// actor does not already exist.
// Param1: actor id
-// Param2: actor pos x
-// Param3: actor pos y
-// Param4: ?
+// Param2: actor x
+// Param3: actor y
+// Param4: actor direction
// Param5: actor action
-// Param6: ?
-int Script::SF_placeActor(SCRIPTFUNC_PARAMS) {
- // INCOMPLETE
- SDataWord_T actor_parm;
- SDataWord_T x_parm;
- SDataWord_T y_parm;
- SDataWord_T orient_parm;
- SDataWord_T action_parm;
- SDataWord_T frame_parm;
+// Param6: actor frame number
+int Script::sfPlaceActor(SCRIPTFUNC_PARAMS) {
uint16 actorId;
- int action_state;
- Point pt;
-
- actor_parm = thread->pop();
- x_parm = thread->pop();
- y_parm = thread->pop();
- orient_parm = thread->pop();
- action_parm = thread->pop();
- frame_parm = thread->pop();
-
- actorId = _vm->_sdata->readWordS(actor_parm);
- pt.x = _vm->_sdata->readWordS(x_parm);
- pt.y = _vm->_sdata->readWordS(y_parm);
- action_state = _vm->_sdata->readWordS(action_parm);
+ ActorLocation actorLocation;
+ int actorDirection;
+ int frameType;
+ int frameOffset;
+ ActorData *actor;
+ ActorFrameRange *frameRange;
+
+ actorId = getSWord(thread->pop());
+ actorLocation.x = getSWord(thread->pop());
+ actorLocation.y = getSWord(thread->pop());
+ actorDirection = getSWord(thread->pop());
+ frameType = getSWord(thread->pop());
+ frameOffset = getSWord(thread->pop());
+
+ actor = _vm->_actor->getActor(actorId);
+ actor->location.x = actorLocation.x;
+ actor->location.y = actorLocation.y;
+ actor->facingDirection = actor->actionDirection = actorDirection;
+ if (frameType >= 0) {
+ frameRange = _vm->_actor->getActorFrameRange(actorId, frameType);
+
+ if (frameRange->frameCount <= frameOffset)
+ error("Wrong frameOffset 0x%X", frameOffset);
- _vm->_actor->move(actorId, pt);
+ actor->frameNumber = frameRange->frameIndex + frameOffset;
+ actor->currentAction = kActionFreeze;
+ } else {
+ actor->currentAction = kActionWait;
+ }
- if (action_state < 0)
- action_state = ACTION_IDLE;
- _vm->_actor->setDefaultAction(actorId, action_state, ACTION_NONE);
- _vm->_actor->setAction(actorId, action_state, ACTION_NONE);
+ actor->targetObject = ID_NOTHING;
return SUCCESS;
}
@@ -797,11 +868,11 @@ int Script::SF_checkUserInterrupt(SCRIPTFUNC_PARAMS) {
// Script function #45 (0x2D)
int Script::SF_walkRelative(SCRIPTFUNC_PARAMS) {
- SDataWord_T param1 = thread->pop();
- SDataWord_T param2 = thread->pop();
- SDataWord_T param3 = thread->pop();
- SDataWord_T param4 = thread->pop();
- SDataWord_T param5 = thread->pop();
+ ScriptDataWord param1 = thread->pop();
+ ScriptDataWord param2 = thread->pop();
+ ScriptDataWord param3 = thread->pop();
+ ScriptDataWord param4 = thread->pop();
+ ScriptDataWord param5 = thread->pop();
debug(1, "stub: SF_walkRelative(%d, %d, %d, %d, %d)", param1, param2, param3, param4, param5);
return SUCCESS;
@@ -809,11 +880,11 @@ int Script::SF_walkRelative(SCRIPTFUNC_PARAMS) {
// Script function #46 (0x2E)
int Script::SF_moveRelative(SCRIPTFUNC_PARAMS) {
- SDataWord_T param1 = thread->pop();
- SDataWord_T param2 = thread->pop();
- SDataWord_T param3 = thread->pop();
- SDataWord_T param4 = thread->pop();
- SDataWord_T param5 = thread->pop();
+ ScriptDataWord param1 = thread->pop();
+ ScriptDataWord param2 = thread->pop();
+ ScriptDataWord param3 = thread->pop();
+ ScriptDataWord param4 = thread->pop();
+ ScriptDataWord param5 = thread->pop();
debug(1, "stub: SF_moveRelative(%d, %d, %d, %d, %d)", param1, param2, param3, param4, param5);
return SUCCESS;
@@ -860,12 +931,12 @@ int Script::SF_resumeBgdAnim(SCRIPTFUNC_PARAMS) {
// Script function #52 (0x34)
int Script::SF_throwActor(SCRIPTFUNC_PARAMS) {
- SDataWord_T param1 = thread->pop();
- SDataWord_T param2 = thread->pop();
- SDataWord_T param3 = thread->pop();
- SDataWord_T param4 = thread->pop();
- SDataWord_T param5 = thread->pop();
- SDataWord_T param6 = thread->pop();
+ ScriptDataWord param1 = thread->pop();
+ ScriptDataWord param2 = thread->pop();
+ ScriptDataWord param3 = thread->pop();
+ ScriptDataWord param4 = thread->pop();
+ ScriptDataWord param5 = thread->pop();
+ ScriptDataWord param6 = thread->pop();
debug(1, "stub: SF_throwActor(%d, %d, %d, %d, %d, %d)", param1, param2, param3, param4, param5, param6);
return SUCCESS;
@@ -873,7 +944,7 @@ int Script::SF_throwActor(SCRIPTFUNC_PARAMS) {
// Script function #53 (0x35)
int Script::SF_waitWalk(SCRIPTFUNC_PARAMS) {
- SDataWord_T param = thread->pop();
+ ScriptDataWord param = thread->pop();
debug(1, "stub: SF_waitWalk(%d)", param);
return SUCCESS;
@@ -887,8 +958,8 @@ int Script::SF_sceneID(SCRIPTFUNC_PARAMS) {
// Script function #55 (0x37)
int Script::SF_changeActorScene(SCRIPTFUNC_PARAMS) {
- SDataWord_T param1 = thread->pop();
- SDataWord_T param2 = thread->pop();
+ ScriptDataWord param1 = thread->pop();
+ ScriptDataWord param2 = thread->pop();
debug(1, "stub: SF_changeActorScene(%d, %d)", param1, param2);
return SUCCESS;
@@ -896,10 +967,10 @@ int Script::SF_changeActorScene(SCRIPTFUNC_PARAMS) {
// Script function #56 (0x38)
int Script::SF_climb(SCRIPTFUNC_PARAMS) {
- SDataWord_T param1 = thread->pop();
- SDataWord_T param2 = thread->pop();
- SDataWord_T param3 = thread->pop();
- SDataWord_T param4 = thread->pop();
+ ScriptDataWord param1 = thread->pop();
+ ScriptDataWord param2 = thread->pop();
+ ScriptDataWord param3 = thread->pop();
+ ScriptDataWord param4 = thread->pop();
debug(1, "stub: SF_climb(%d, %d, %d, %d)", param1, param2, param3, param4);
return SUCCESS;
@@ -916,8 +987,8 @@ int Script::SF_setDoorState(SCRIPTFUNC_PARAMS) {
// Script function #58 (0x3A)
int Script::SF_setActorZ(SCRIPTFUNC_PARAMS) {
- SDataWord_T param1 = thread->pop();
- SDataWord_T param2 = thread->pop();
+ ScriptDataWord param1 = thread->pop();
+ ScriptDataWord param2 = thread->pop();
debug(1, "stub: SF_setActorZ(%d, %d)", param1, param2);
return SUCCESS;
@@ -934,7 +1005,7 @@ int Script::SF_text(SCRIPTFUNC_PARAMS) {
// Script function #60 (0x3C)
int Script::SF_getActorX(SCRIPTFUNC_PARAMS) {
- SDataWord_T param = thread->pop();
+ ScriptDataWord param = thread->pop();
debug(1, "stub: SF_getActorX(%d)", param);
return SUCCESS;
@@ -942,7 +1013,7 @@ int Script::SF_getActorX(SCRIPTFUNC_PARAMS) {
// Script function #61 (0x3D)
int Script::SF_getActorY(SCRIPTFUNC_PARAMS) {
- SDataWord_T param = thread->pop();
+ ScriptDataWord param = thread->pop();
debug(1, "stub: SF_getActorY(%d)", param);
return SUCCESS;
@@ -959,7 +1030,7 @@ int Script::SF_eraseDelta(SCRIPTFUNC_PARAMS) {
// Script function #63 (0x3F)
int Script::SF_playMusic(SCRIPTFUNC_PARAMS) {
- SDataWord_T param = thread->pop() + 9;
+ ScriptDataWord param = thread->pop() + 9;
if (param >= 9 && param <= 34)
_vm->_music->play(param);
@@ -1099,7 +1170,7 @@ static struct {
// Script function #70 (0x46)
int Script::SF_playSound(SCRIPTFUNC_PARAMS) {
- SDataWord_T param = thread->pop() - 13;
+ ScriptDataWord param = thread->pop() - 13;
if (/* param >= 0 && */ param < ARRAYSIZE(sfxTable))
_vm->_sndRes->playSound(sfxTable[param].res, sfxTable[param].vol, false);
@@ -1147,7 +1218,7 @@ int Script::SF_protectResult(SCRIPTFUNC_PARAMS) {
// Script function #75 (0x4d)
int Script::SF_rand(SCRIPTFUNC_PARAMS) {
- SDataWord_T param = thread->pop();
+ ScriptDataWord param = thread->pop();
thread->retVal = (_vm->_rnd.getRandomNumber(param));
diff --git a/saga/sthread.cpp b/saga/sthread.cpp
index 8a00b0c7ec..98e3d6c547 100644
--- a/saga/sthread.cpp
+++ b/saga/sthread.cpp
@@ -30,7 +30,6 @@
#include "saga/script.h"
-#include "saga/sdata.h"
#include "saga/stream.h"
#include "saga/scene.h"
#include "saga/resnames.h"
@@ -39,8 +38,8 @@ namespace Saga {
void Script::setFramePtr(SCRIPT_THREAD *thread, int newPtr) {
thread->framePtr = newPtr;
- dataBuffer(3)->len = ARRAYSIZE(thread->stackBuf) - thread->framePtr;
- dataBuffer(3)->data = (SDataWord_T *) &(thread->stackBuf[newPtr]);
+ dataBuffer(3)->length = ARRAYSIZE(thread->stackBuf) - thread->framePtr;
+ dataBuffer(3)->data = (ScriptDataWord *) &(thread->stackBuf[newPtr]);
}
SCRIPT_THREAD *Script::SThreadCreate() {
@@ -58,7 +57,7 @@ SCRIPT_THREAD *Script::SThreadCreate() {
new_thread->flags = kTFlagWaiting;
new_thread->waitType = kWaitTypePause;
- dataBuffer(4)->len = ARRAYSIZE(new_thread->threadVars);
+ dataBuffer(4)->length = ARRAYSIZE(new_thread->threadVars);
dataBuffer(4)->data = new_thread->threadVars;
return new_thread;
@@ -218,14 +217,14 @@ int Script::SThreadDebugStep() {
int Script::SThreadRun(SCRIPT_THREAD *thread, int instr_limit) {
int instr_count;
uint32 saved_offset;
- SDataWord_T param1;
- SDataWord_T param2;
+ ScriptDataWord param1;
+ ScriptDataWord param2;
long iparam1;
long iparam2;
long iresult;
- SDataWord_T data;
- SDataWord_T scriptRetVal = 0;
+ ScriptDataWord data;
+ ScriptDataWord scriptRetVal = 0;
int debug_print = 0;
int n_buf;
int bitstate;
@@ -247,8 +246,8 @@ int Script::SThreadRun(SCRIPT_THREAD *thread, int instr_limit) {
MemoryReadStream/*Endian*/ scriptS(currentScript()->bytecode->bytecode_p, currentScript()->bytecode->bytecode_len/*, IS_BIG_ENDIAN*/);
- dataBuffer(2)->len = currentScript()->bytecode->bytecode_len / sizeof(SDataWord_T);
- dataBuffer(2)->data = (SDataWord_T *) currentScript()->bytecode->bytecode_p;
+ dataBuffer(2)->length = currentScript()->bytecode->bytecode_len / sizeof(ScriptDataWord);
+ dataBuffer(2)->data = (ScriptDataWord *) currentScript()->bytecode->bytecode_p;
scriptS.seek(thread->i_offset);
@@ -285,7 +284,7 @@ int Script::SThreadRun(SCRIPT_THREAD *thread, int instr_limit) {
break;
case 0x06: // Push word (PUSH)
case 0x08: // Push word (PSHD) (dialogue string index)
- param1 = (SDataWord_T)scriptS.readUint16LE();
+ param1 = (ScriptDataWord)scriptS.readUint16LE();
thread->push(param1);
break;
@@ -293,49 +292,49 @@ int Script::SThreadRun(SCRIPT_THREAD *thread, int instr_limit) {
case 0x0B: // Test flag (TSTF)
n_buf = scriptS.readByte();
- param1 = (SDataWord_T)scriptS.readUint16LE();
- _vm->_sdata->getBit(n_buf, param1, &bitstate);
+ param1 = (ScriptDataWord)scriptS.readUint16LE();
+ getBit(n_buf, param1, &bitstate);
thread->push(bitstate);
break;
case 0x0C: // Get word (GETW)
n_buf = scriptS.readByte();
param1 = scriptS.readUint16LE();
- _vm->_sdata->getWord(n_buf, param1, &data);
+ getWord(n_buf, param1, &data);
thread->push(data);
break;
case 0x0F: // Modify flag (MODF)
n_buf = scriptS.readByte();
- param1 = (SDataWord_T)scriptS.readUint16LE();
- bitstate = _vm->_sdata->readWordU(param1);
+ param1 = (ScriptDataWord)scriptS.readUint16LE();
+ bitstate = getUWord(param1);
data = thread->stackTop();
if (bitstate) {
- _vm->_sdata->setBit(n_buf, data, 1);
+ setBit(n_buf, data, 1);
} else {
- _vm->_sdata->setBit(n_buf, data, 0);
+ setBit(n_buf, data, 0);
}
break;
case 0x10: // Put word (PUTW)
n_buf = scriptS.readByte();
- param1 = (SDataWord_T)scriptS.readUint16LE();
+ param1 = (ScriptDataWord)scriptS.readUint16LE();
data = thread->stackTop();
- _vm->_sdata->putWord(n_buf, param1, data);
+ putWord(n_buf, param1, data);
break;
case 0x13: // Modify flag and pop (MDFP)
n_buf = scriptS.readByte();
- param1 = (SDataWord_T)scriptS.readUint16LE();
+ param1 = (ScriptDataWord)scriptS.readUint16LE();
param1 = thread->pop();
- bitstate = _vm->_sdata->readWordU(param1);
+ bitstate = getUWord(param1);
if (bitstate) {
- _vm->_sdata->setBit(n_buf, param1, 1);
+ setBit(n_buf, param1, 1);
} else {
- _vm->_sdata->setBit(n_buf, param1, 0);
+ setBit(n_buf, param1, 0);
}
break;
case 0x14: // Put word and pop (PTWP)
n_buf = scriptS.readByte();
- param1 = (SDataWord_T)scriptS.readUint16LE();
+ param1 = (ScriptDataWord)scriptS.readUint16LE();
data = thread->stackTop();
- _vm->_sdata->putWord(n_buf, param1, data);
+ putWord(n_buf, param1, data);
break;
// CONTROL INSTRUCTIONS
@@ -349,7 +348,7 @@ int Script::SThreadRun(SCRIPT_THREAD *thread, int instr_limit) {
temp = scriptS.readByte();
if (temp != 2)
error("Calling dynamically generated script? Wow");
- param1 = (SDataWord_T)scriptS.readUint16LE();
+ param1 = (ScriptDataWord)scriptS.readUint16LE();
data = scriptS.pos();
thread->push(n_args);
// NOTE: The original pushes the program
@@ -359,29 +358,30 @@ int Script::SThreadRun(SCRIPT_THREAD *thread, int instr_limit) {
thread->i_offset = (unsigned long)param1;
}
break;
- case 0x18: // (CALL): Call function
- case 0x19: // (CALL_V): Call function and discard return value
+ case opCcall: // (CALL): Call function
+ case opCcallV: // (CALL_V): Call function and discard return value
{
- int n_args;
- uint16 func_num;
- int sfuncRetVal;
- SFunc_T sfunc;
-
- n_args = scriptS.readByte();
- func_num = scriptS.readUint16LE();
- if (func_num >= SFUNC_NUM) {
- _vm->_console->DebugPrintf(S_ERROR_PREFIX "Invalid script function number: (%X)\n", func_num);
+ int argumentsCount;
+ uint16 functionNumber;
+ int scriptFunctionReturnValue;
+ ScriptFunctionType scriptFunction;
+
+ argumentsCount = scriptS.readByte();
+ functionNumber = scriptS.readUint16LE();
+ debug(9, "opCCall* 0x%X", functionNumber);
+ if (functionNumber >= SCRIPT_FUNCTION_MAX) {
+ _vm->_console->DebugPrintf(S_ERROR_PREFIX "Invalid script function number: (%X)\n", functionNumber);
thread->flags |= kTFlagAborted;
break;
}
- sfunc = _SFuncList[func_num];
- sfuncRetVal = (this->*sfunc)(thread, n_args);
- if (sfuncRetVal != SUCCESS) {
- _vm->_console->DebugPrintf(S_WARN_PREFIX "%X: Script function %d failed.\n", thread->i_offset, func_num);
+ scriptFunction = _scriptFunctionsList[functionNumber];
+ scriptFunctionReturnValue = (this->*scriptFunction)(thread, argumentsCount);
+ if (scriptFunctionReturnValue != SUCCESS) {
+ _vm->_console->DebugPrintf(S_WARN_PREFIX "%X: Script function %d failed.\n", thread->i_offset, scriptFunctionReturnValue);
}
- if (func_num == 16) { // SF_gotoScene
+ if (functionNumber == 16) { // SF_gotoScene
instr_count = instr_limit; // break the loop
break;
}
@@ -470,7 +470,7 @@ int Script::SThreadRun(SCRIPT_THREAD *thread, int instr_limit) {
switch_num = scriptS.readUint16LE();
switch_jmp = scriptS.readUint16LE();
// Found the specified case
- if (data == (SDataWord_T) switch_num) {
+ if (data == (ScriptDataWord) switch_num) {
thread->i_offset = switch_jmp;
case_found = 1;
break;
@@ -566,7 +566,7 @@ int Script::SThreadRun(SCRIPT_THREAD *thread, int instr_limit) {
iparam2 = (long)param2;
iparam1 = (long)param1;
iresult = iparam1 + iparam2;
- thread->push((SDataWord_T) iresult);
+ thread->push((ScriptDataWord) iresult);
break;
// (SUB): Subtraction
case 0x2D:
@@ -575,7 +575,7 @@ int Script::SThreadRun(SCRIPT_THREAD *thread, int instr_limit) {
iparam2 = (long)param2;
iparam1 = (long)param1;
iresult = iparam1 - iparam2;
- thread->push((SDataWord_T) iresult);
+ thread->push((ScriptDataWord) iresult);
break;
// (MULT): Integer multiplication
case 0x2E:
@@ -584,7 +584,7 @@ int Script::SThreadRun(SCRIPT_THREAD *thread, int instr_limit) {
iparam2 = (long)param2;
iparam1 = (long)param1;
iresult = iparam1 * iparam2;
- thread->push((SDataWord_T) iresult);
+ thread->push((ScriptDataWord) iresult);
break;
// (DIV): Integer division
case 0x2F:
@@ -593,7 +593,7 @@ int Script::SThreadRun(SCRIPT_THREAD *thread, int instr_limit) {
iparam2 = (long)param2;
iparam1 = (long)param1;
iresult = iparam1 / iparam2;
- thread->push((SDataWord_T) iresult);
+ thread->push((ScriptDataWord) iresult);
break;
// (MOD) Modulus
case 0x30:
@@ -602,7 +602,7 @@ int Script::SThreadRun(SCRIPT_THREAD *thread, int instr_limit) {
iparam2 = (long)param2;
iparam1 = (long)param1;
iresult = iparam1 % iparam2;
- thread->push((SDataWord_T) iresult);
+ thread->push((ScriptDataWord) iresult);
break;
// (EQU) Test equality
case 0x33:
@@ -728,10 +728,7 @@ int Script::SThreadRun(SCRIPT_THREAD *thread, int instr_limit) {
break;
// GAME INSTRUCTIONS
-
- // (opSpeak): Play Character Speech
- case opSpeak:
- {
+ case opSpeak: { // (opSpeak): Play Character Speech
int stringsCount;
uint16 actorId;
int speechFlags;
@@ -752,7 +749,7 @@ int Script::SThreadRun(SCRIPT_THREAD *thread, int instr_limit) {
if (stringsCount == 0)
error("opSpeak stringsCount == 0");
- if (stringsCount >= ACTOR_SPEECH_STRING_MAX)
+ if (stringsCount > ACTOR_SPEECH_STRING_MAX)
error("opSpeak stringsCount=0x%X exceed ACTOR_SPEECH_STRING_MAX", stringsCount);
data = first = thread->stackTop();
@@ -763,8 +760,8 @@ int Script::SThreadRun(SCRIPT_THREAD *thread, int instr_limit) {
// now data contains last string index
if (_vm->_gameId == GID_ITE_DISK_G) { // special ITE dos
- if ((_vm->_scene->currentSceneNumber() == ITE_DEFAULT_SCENE) && (data >= 288) && (data <= (SCENE1_VOICE_138 - SCENE1_VOICE_009 + 288))) {
- sampleResourceId = SCENE1_VOICE_009 + data - 288;
+ if ((_vm->_scene->currentSceneNumber() == ITE_DEFAULT_SCENE) && (data >= 288) && (data <= (RID_SCENE1_VOICE_138 - RID_SCENE1_VOICE_009 + 288))) {
+ sampleResourceId = RID_SCENE1_VOICE_009 + data - 288;
}
} else {
if (isVoiceLUTPresent()) {
@@ -792,7 +789,7 @@ int Script::SThreadRun(SCRIPT_THREAD *thread, int instr_limit) {
// (DLGO): Add a dialogue option to interface
case 0x56:
{
- SDataWord_T param3 = 0;
+ ScriptDataWord param3 = 0;
param1 = scriptS.readByte();
param2 = scriptS.readByte();
if (param2 & 1) {