diff options
author | Andrew Kurushin | 2004-12-22 21:04:50 +0000 |
---|---|---|
committer | Andrew Kurushin | 2004-12-22 21:04:50 +0000 |
commit | 3d9784f94d3bc6c425d3180e59d322ab715e6306 (patch) | |
tree | 1313b3b88f8a6f9341a72c4fc178dad582f924c5 | |
parent | ab4734dcf60d8f06786cbdd382a7a83ca962103a (diff) | |
download | scummvm-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
-rw-r--r-- | saga/actor.cpp | 290 | ||||
-rw-r--r-- | saga/actor.h | 139 | ||||
-rw-r--r-- | saga/actordata.cpp | 3 | ||||
-rw-r--r-- | saga/actordata.h | 9 | ||||
-rw-r--r-- | saga/console.cpp | 16 | ||||
-rw-r--r-- | saga/game.cpp | 16 | ||||
-rw-r--r-- | saga/interface.cpp | 19 | ||||
-rw-r--r-- | saga/ite_introproc.cpp | 46 | ||||
-rw-r--r-- | saga/resnames.h | 129 | ||||
-rw-r--r-- | saga/saga.cpp | 5 | ||||
-rw-r--r-- | saga/saga.h | 4 | ||||
-rw-r--r-- | saga/scene.cpp | 1 | ||||
-rw-r--r-- | saga/script.cpp | 96 | ||||
-rw-r--r-- | saga/script.h | 82 | ||||
-rw-r--r-- | saga/sfuncs.cpp | 511 | ||||
-rw-r--r-- | saga/sthread.cpp | 111 |
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) { |