diff options
author | Andrew Kurushin | 2005-01-15 20:12:49 +0000 |
---|---|---|
committer | Andrew Kurushin | 2005-01-15 20:12:49 +0000 |
commit | 2f20dd57c2da6507a65811ce14cadb4bef1012ff (patch) | |
tree | 43f755456057d2d04cfd74881857754db06d9c06 /saga | |
parent | 139f57a29d27a1c148563a7c8f729f7c3b3e4f3e (diff) | |
download | scummvm-rg350-2f20dd57c2da6507a65811ce14cadb4bef1012ff.tar.gz scummvm-rg350-2f20dd57c2da6507a65811ce14cadb4bef1012ff.tar.bz2 scummvm-rg350-2f20dd57c2da6507a65811ce14cadb4bef1012ff.zip |
some work in progress on verb stuff:
- many structers and fields renamed to proper names
- added missing functions
svn-id: r16562
Diffstat (limited to 'saga')
-rw-r--r-- | saga/actor.cpp | 122 | ||||
-rw-r--r-- | saga/actor.h | 36 | ||||
-rw-r--r-- | saga/actordata.cpp | 2 | ||||
-rw-r--r-- | saga/actordata.h | 6 | ||||
-rw-r--r-- | saga/events.cpp | 8 | ||||
-rw-r--r-- | saga/ihnm_introproc.cpp | 8 | ||||
-rw-r--r-- | saga/interface.cpp | 51 | ||||
-rw-r--r-- | saga/interface.h | 18 | ||||
-rw-r--r-- | saga/objectdata.cpp | 4 | ||||
-rw-r--r-- | saga/objectdata.h | 7 | ||||
-rw-r--r-- | saga/objectmap.cpp | 2 | ||||
-rw-r--r-- | saga/objectmap.h | 5 | ||||
-rw-r--r-- | saga/resnames.h | 5 | ||||
-rw-r--r-- | saga/saga.cpp | 47 | ||||
-rw-r--r-- | saga/saga.h | 5 | ||||
-rw-r--r-- | saga/scene.cpp | 34 | ||||
-rw-r--r-- | saga/scene.h | 18 | ||||
-rw-r--r-- | saga/script.cpp | 223 | ||||
-rw-r--r-- | saga/script.h | 54 | ||||
-rw-r--r-- | saga/sdebug.cpp | 8 | ||||
-rw-r--r-- | saga/sfuncs.cpp | 12 | ||||
-rw-r--r-- | saga/sthread.cpp | 106 | ||||
-rw-r--r-- | saga/xref.txt | 6 |
23 files changed, 536 insertions, 251 deletions
diff --git a/saga/actor.cpp b/saga/actor.cpp index 8ca4abe275..8f4d450800 100644 --- a/saga/actor.cpp +++ b/saga/actor.cpp @@ -135,7 +135,8 @@ Actor::Actor(SagaEngine *vm) : _vm(vm) { size_t stringsLength; ActorData *actor; debug(9, "Actor::Actor()"); - + + _actors = NULL; if (_vm->getGameType() == GType_IHNM) { warning("Actors aren't implemented for IHNM yet"); return; @@ -180,32 +181,37 @@ Actor::Actor(SagaEngine *vm) : _vm(vm) { _vm->loadStrings(_actorsStrings, stringsPointer, stringsLength); RSC_FreeResource(stringsPointer); - for (i = 0; i < ACTORCOUNT; i++) { - actor = &_actors[i]; - actor->actorId = actorIndexToId(i); - actor->index = i; - debug(9, "init actorId=%d index=%d", actor->actorId, actor->index); - actor->nameIndex = ActorTable[i].nameIndex; - actor->spriteListResourceId = ActorTable[i].spriteListResourceId; - actor->frameListResourceId = ActorTable[i].frameListResourceId; - actor->speechColor = ActorTable[i].speechColor; - actor->sceneNumber = ActorTable[i].sceneIndex; - actor->flags = ActorTable[i].flags; - actor->currentAction = ActorTable[i].currentAction; - actor->facingDirection = ActorTable[i].facingDirection; - actor->actionDirection = ActorTable[i].actionDirection; - actor->frameNumber = 0; - actor->targetObject = ID_NOTHING; - actor->actorFlags = 0; - - 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) { - warning("Disabling actorId=%d index=%d", actor->actorId, actor->index); - } + if (_vm->getGameType() == GType_ITE) { + _actorsCount = ITE_ACTORCOUNT; + _actors = (ActorData **)malloc(_actorsCount * sizeof(ActorData *)); + for (i = 0; i < _actorsCount; i++) { + actor = _actors[i] = new ActorData(); + actor->actorId = actorIndexToId(i); + actor->index = i; + debug(9, "init actorId=%d index=%d", actor->actorId, actor->index); + actor->nameIndex = ITE_ActorTable[i].nameIndex; + actor->scriptEntrypointNumber = ITE_ActorTable[i].scriptEntrypointNumber; + actor->spriteListResourceId = ITE_ActorTable[i].spriteListResourceId; + actor->frameListResourceId = ITE_ActorTable[i].frameListResourceId; + actor->speechColor = ITE_ActorTable[i].speechColor; + actor->sceneNumber = ITE_ActorTable[i].sceneIndex; + actor->flags = ITE_ActorTable[i].flags; + actor->currentAction = ITE_ActorTable[i].currentAction; + actor->facingDirection = ITE_ActorTable[i].facingDirection; + actor->actionDirection = ITE_ActorTable[i].actionDirection; + actor->frameNumber = 0; + actor->targetObject = ID_NOTHING; + actor->actorFlags = 0; + + actor->location.x = ITE_ActorTable[i].x; + actor->location.y = ITE_ActorTable[i].y; + actor->location.z = ITE_ActorTable[i].z; + + actor->disabled = !loadActorResources(actor); + if (actor->disabled) { + warning("Disabling actorId=%d index=%d", actor->actorId, actor->index); + } + } } } @@ -225,11 +231,11 @@ Actor::~Actor() { free(_pathCell); _actorsStrings.freeMem(); //release resources - for (i = 0; i < ACTORCOUNT; i++) { - actor = &_actors[i]; - free(actor->frames); - actor->spriteList.freeMem(); + for (i = 0; i < _actorsCount; i++) { + actor = _actors[i]; + delete actor; } + free(_actors); } bool Actor::loadActorResources(ActorData *actor) { @@ -304,7 +310,7 @@ bool Actor::loadActorResources(ActorData *actor) { return true; } -void Actor::realLocation(ActorLocation &location, uint16 objectId, uint16 walkFlags) { +void Actor::realLocation(Location &location, uint16 objectId, uint16 walkFlags) { int angle; int distance; ActorData *actor; @@ -332,9 +338,9 @@ void Actor::realLocation(ActorLocation &location, uint16 objectId, uint16 walkFl } } -void Actor::actorFaceTowardsPoint(uint16 actorId, const ActorLocation &toLocation) { +void Actor::actorFaceTowardsPoint(uint16 actorId, const Location &toLocation) { ActorData *actor; - ActorLocation delta; + Location delta; actor = getActor(actorId); @@ -382,7 +388,7 @@ ActorData *Actor::getActor(uint16 actorId) { return _protagonist; } - actor = &_actors[actorIdToIndex(actorId)]; + actor = _actors[actorIdToIndex(actorId)]; if (actor->disabled) warning("Actor::getActor disabled actorId 0x%X", actorId); @@ -390,7 +396,7 @@ ActorData *Actor::getActor(uint16 actorId) { return actor; } -bool Actor::validFollowerLocation(const ActorLocation &location) { +bool Actor::validFollowerLocation(const Location &location) { Point point; location.toScreenPointXY(point); @@ -406,8 +412,8 @@ void Actor::updateActorsScene() { int i, j; int followerDirection; ActorData *actor; - ActorLocation tempLocation; - ActorLocation possibleLocation; + Location tempLocation; + Location possibleLocation; Point delta; if (_vm->getGameType() == GType_IHNM) { @@ -418,8 +424,8 @@ void Actor::updateActorsScene() { _activeSpeech.stringsCount = 0; _protagonist = NULL; - for (i = 0; i < ACTORCOUNT; i++) { - actor = &_actors[i]; + for (i = 0; i < _actorsCount; i++) { + actor = _actors[i]; if (actor->flags & (kProtagonist | kFollower)) { actor->sceneNumber = _vm->_scene->currentSceneNumber(); if (actor->flags & kProtagonist) { @@ -452,8 +458,8 @@ void Actor::updateActorsScene() { followerDirection = _protagonist->facingDirection + 3; calcActorScreenPosition(_protagonist); - for (i = 0; i < ACTORCOUNT; i++) { - actor = &_actors[i]; + for (i = 0; i < _actorsCount; i++) { + actor = _actors[i]; if (actor->flags & (kFollower)) { actor->facingDirection = actor->actionDirection = _protagonist->facingDirection; actor->currentAction = kActionWait; @@ -630,11 +636,11 @@ void Actor::handleActions(int msec, bool setup) { ActorFrameRange *frameRange; int state; int speed; - ActorLocation delta; - ActorLocation addDelta; + Location delta; + Location addDelta; - for (i = 0; i < ACTORCOUNT; i++) { - actor = &_actors[i]; + for (i = 0; i < _actorsCount; i++) { + actor = _actors[i]; if (actor->disabled) continue; if (actor->sceneNumber != _vm->_scene->currentSceneNumber()) continue; @@ -876,7 +882,7 @@ int Actor::direct(int msec) { // FIXME: HACK. This should be turned into cycle event. _lastTickMsec += msec; - if (_lastTickMsec > ticksToMSec(5)) { // fixme + if (_lastTickMsec > ticksToMSec(2)) { // fixme _lastTickMsec = 0; //process actions handleActions(msec, false); @@ -922,8 +928,8 @@ void Actor::createDrawOrderList() { ActorData *actor; _drawOrderList.clear(); - for (i = 0; i < ACTORCOUNT; i++) { - actor = &_actors[i]; + for (i = 0; i < _actorsCount; i++) { + actor = _actors[i]; if (actor->disabled) continue; if (actor->sceneNumber != _vm->_scene->currentSceneNumber()) continue; @@ -1009,9 +1015,9 @@ int Actor::drawActors() { } bool Actor::followProtagonist(ActorData *actor) { - ActorLocation protagonistLocation; - ActorLocation newLocation; - ActorLocation delta; + Location protagonistLocation; + Location newLocation; + Location delta; int protagonistBGMaskType; Point prefer1; Point prefer2; @@ -1132,7 +1138,7 @@ bool Actor::actorEndWalk(uint16 actorId, bool recurse) { return walkMore; } -bool Actor::actorWalkTo(uint16 actorId, const ActorLocation &toLocation) { +bool Actor::actorWalkTo(uint16 actorId, const Location &toLocation) { ActorData *actor; ActorData *anotherActor; int i; @@ -1207,8 +1213,8 @@ bool Actor::actorWalkTo(uint16 actorId, const ActorLocation &toLocation) { _barrierCount = 0; - for (i = 0; (i < ACTORCOUNT) && (_barrierCount < ACTOR_BARRIERS_MAX); i++) { - anotherActor = &_actors[i]; + for (i = 0; (i < _actorsCount) && (_barrierCount < ACTOR_BARRIERS_MAX); i++) { + anotherActor = _actors[i]; if (anotherActor->disabled) continue; if (anotherActor->sceneNumber != _vm->_scene->currentSceneNumber()) continue; if (anotherActor == actor ) continue; @@ -1298,8 +1304,8 @@ bool Actor::actorWalkTo(uint16 actorId, const ActorLocation &toLocation) { return false; } else { if (actor->flags & kProtagonist) { - _actors[1].actorFlags &= ~kActorNoFollow; - _actors[2].actorFlags &= ~kActorNoFollow; + _actors[1]->actorFlags &= ~kActorNoFollow; // TODO: mark all actors with kFollower flag, not only 1 and 2 + _actors[2]->actorFlags &= ~kActorNoFollow; } actor->currentAction = (actor->walkStepsCount >= ACTOR_MAX_STEPS_COUNT) ? kActionWalkToLink : kActionWalkToPoint; actor->walkFrameSequence = kFrameWalk; @@ -1903,7 +1909,7 @@ void Actor::drawPathTest() { void Actor::cmdActorWalkTo(int argc, const char **argv) { uint16 actorId = (uint16) atoi(argv[1]); - ActorLocation location; + Location location; Point movePoint; movePoint.x = atoi(argv[2]); diff --git a/saga/actor.h b/saga/actor.h index 955e78b541..8430c45643 100644 --- a/saga/actor.h +++ b/saga/actor.h @@ -134,22 +134,22 @@ struct ActorFrameSequence { ActorFrameRange directions[ACTOR_DIRECTIONS_COUNT]; }; -struct ActorLocation { - int x; // Actor's logical coordinates +struct Location { + int x; // logical coordinates int y; // int z; // - ActorLocation() { + Location() { x = y = z = 0; } - int distance(const ActorLocation &location) const { + int distance(const Location &location) const { return MAX(ABS(x - location.x), ABS(y - location.y)); } - void delta(const ActorLocation &location, ActorLocation &result) const { + void delta(const Location &location, Location &result) const { result.x = x - location.x; result.y = y - location.y; result.z = z - location.z; } - void add(const ActorLocation &location) { + void add(const Location &location) { x += location.x; y += location.y; z += location.z; @@ -176,10 +176,10 @@ struct ActorData { int nameIndex; // Actor's index in actor name string list byte speechColor; // Actor dialogue color uint16 flags; // Actor initial flags - + int scriptEntrypointNumber; // Actor script entrypoint number int sceneNumber; // scene of actor - ActorLocation location; // Actor's logical coordinates + Location location; // Actor's logical coordinates Point screenPosition; // Actor's screen coordinates int screenDepth; // @@ -211,8 +211,8 @@ struct ActorData { int walkStepIndex; Point *walkStepsPoints; - ActorLocation finalTarget; - ActorLocation partialTarget; + Location finalTarget; + Location partialTarget; int walkFrameSequence; void cycleWrap(int cycleLimit) { @@ -235,7 +235,9 @@ struct ActorData { memset(&spriteList, 0, sizeof(spriteList)); } ~ActorData() { + free(frames); free(walkStepsPoints); + spriteList.freeMem(); } }; @@ -271,7 +273,7 @@ public: void cmdActorWalkTo(int argc, const char **argv); - bool validActorId(uint16 id) { return (id == 1) || ((id >= 0x2000) && (id < (0x2000 | ACTORCOUNT))); } + bool validActorId(uint16 id) { return (id == 1) || ((id >= 0x2000) && (id < (0x2000 | _actorsCount))); } int actorIdToIndex(uint16 id) { return (id == 1 ) ? 0 : (id & ~0x2000); } uint16 actorIndexToId(int index) { return (index == 0 ) ? 1 : (index | 0x2000); } @@ -281,13 +283,14 @@ public: void drawPathTest(); + uint16 testHit(const Point& mousePointer){ return ID_NOTHING;}; //TODO: do it const char * getActorName(uint16 actorId); bool actorEndWalk(uint16 actorId, bool recurse); - bool actorWalkTo(uint16 actorId, const ActorLocation &toLocation); + bool actorWalkTo(uint16 actorId, const Location &toLocation); ActorData *getActor(uint16 actorId); ActorFrameRange *getActorFrameRange(uint16 actorId, int frameType); - void realLocation(ActorLocation &location, uint16 objectId, uint16 walkFlags); - void actorFaceTowardsPoint(uint16 actorId, const ActorLocation &toLocation); + void realLocation(Location &location, uint16 objectId, uint16 walkFlags); + void actorFaceTowardsPoint(uint16 actorId, const Location &toLocation); void actorFaceTowardsObject(uint16 actorId, uint16 objectId); // speech @@ -337,13 +340,14 @@ private: void removeNodes(); void nodeToPath(); void removePathPoints(); - bool validFollowerLocation(const ActorLocation &location); + bool validFollowerLocation(const Location &location); int _lastTickMsec; SagaEngine *_vm; RSCFILE_CONTEXT *_actorContext; ActorOrderList _drawOrderList; - ActorData _actors[ACTORCOUNT]; + int _actorsCount; + ActorData **_actors; SpeechData _activeSpeech; StringsTable _actorsStrings; diff --git a/saga/actordata.cpp b/saga/actordata.cpp index fb07e79407..1532b90904 100644 --- a/saga/actordata.cpp +++ b/saga/actordata.cpp @@ -27,7 +27,7 @@ namespace Saga { -ActorTableData ActorTable[ACTORCOUNT] = { +ActorTableData ITE_ActorTable[ITE_ACTORCOUNT] = { // Original used so called permanent actors for first three and that was designed by // EXTENDED object flag. They contained frames in more than one resource. We use // different technique here see "Apppending to sprite list" in loadActorResources() diff --git a/saga/actordata.h b/saga/actordata.h index b86635c23b..46bd997e1f 100644 --- a/saga/actordata.h +++ b/saga/actordata.h @@ -49,16 +49,16 @@ struct ActorTableData { int16 z; int32 spriteListResourceId; int32 frameListResourceId; - byte scriptResourceId; + byte scriptEntrypointNumber; byte speechColor; byte currentAction; byte facingDirection; byte actionDirection; }; -#define ACTORCOUNT 181 +#define ITE_ACTORCOUNT 181 -extern ActorTableData ActorTable[ACTORCOUNT]; +extern ActorTableData ITE_ActorTable[ITE_ACTORCOUNT]; } // End of namespace Saga diff --git a/saga/events.cpp b/saga/events.cpp index a8e43139b7..c3cf7cde05 100644 --- a/saga/events.cpp +++ b/saga/events.cpp @@ -258,7 +258,7 @@ int Events::handleImmediate(EVENT *event) { int Events::handleOneShot(EVENT *event) { SURFACE *back_buf; - SCRIPT_THREAD *sthread; + ScriptThread *sthread; Rect rect; static SCENE_BGINFO bginfo; @@ -397,7 +397,7 @@ int Events::handleOneShot(EVENT *event) { case EVENT_EXEC_NONBLOCKING: debug(0, "Starting start script #%d", event->param); - sthread = _vm->_script->SThreadCreate(); + sthread = _vm->_script->createThread(); if (sthread == NULL) { _vm->_console->DebugPrintf("Thread creation failed.\n"); break; @@ -408,10 +408,10 @@ int Events::handleOneShot(EVENT *event) { sthread->threadVars[kVarWithObject] = TO_LE_16(event->param4); sthread->threadVars[kVarActor] = TO_LE_16(event->param5); - _vm->_script->SThreadExecute(sthread, event->param); + _vm->_script->executeThread(sthread, event->param); if (event->op == EVENT_EXEC_BLOCKING) - _vm->_script->SThreadCompleteThread(); + _vm->_script->completeThread(); break; case EVENT_THREAD_WAKE: diff --git a/saga/ihnm_introproc.cpp b/saga/ihnm_introproc.cpp index 643f570927..2706bc795b 100644 --- a/saga/ihnm_introproc.cpp +++ b/saga/ihnm_introproc.cpp @@ -41,7 +41,7 @@ SCENE_RESLIST IHNM_IntroMovie1RL[] = { {31, SAGA_ANIM_1, 0, 0} }; -SCENE_DESC IHNM_IntroMovie1Desc = { +SceneDescription IHNM_IntroMovie1Desc = { 0, 0, 0, 0, 0, 0, 0, 0, IHNM_IntroMovie1RL, ARRAYSIZE(IHNM_IntroMovie1RL) @@ -52,7 +52,7 @@ SCENE_RESLIST IHNM_IntroMovie2RL[] = { {33, SAGA_ANIM_1, 0, 0} }; -SCENE_DESC IHNM_IntroMovie2Desc = { +SceneDescription IHNM_IntroMovie2Desc = { 0, 0, 0, 0, 0, 0, 0, 0, IHNM_IntroMovie2RL, ARRAYSIZE(IHNM_IntroMovie2RL) @@ -63,7 +63,7 @@ SCENE_RESLIST IHNM_IntroMovie3RL[] = { {35, SAGA_ANIM_1, 0, 0} }; -SCENE_DESC IHNM_IntroMovie3Desc = { +SceneDescription IHNM_IntroMovie3Desc = { 0, 0, 0, 0, 0, 0, 0, 0, IHNM_IntroMovie3RL, ARRAYSIZE(IHNM_IntroMovie3RL) @@ -74,7 +74,7 @@ SCENE_RESLIST IHNM_IntroMovie4RL[] = { {1226, SAGA_ANIM_1, 0, 0} }; -SCENE_DESC IHNM_IntroMovie4Desc = { +SceneDescription IHNM_IntroMovie4Desc = { 0, 0, 0, 0, 0, 0, 0, 0, IHNM_IntroMovie4RL, ARRAYSIZE(IHNM_IntroMovie4RL) diff --git a/saga/interface.cpp b/saga/interface.cpp index d1ba561f40..d64c1a2aa4 100644 --- a/saga/interface.cpp +++ b/saga/interface.cpp @@ -67,7 +67,7 @@ Interface::Interface(SagaEngine *vm) : _vm(vm), _initialized(false) { return; } - _iThread = _vm->_script->SThreadCreate(); + _iThread = _vm->_script->createThread(); if (_iThread == NULL) { error("Interface::Interface(): Error creating script thread for game interface module"); } @@ -347,7 +347,7 @@ int Interface::draw() { return SUCCESS; } -int Interface::update(const Point& imousePointer, int updateFlag) { +int Interface::update(const Point& mousePoint, int updateFlag) { SURFACE *backBuffer; @@ -358,31 +358,33 @@ int Interface::update(const Point& imousePointer, int updateFlag) { backBuffer = _vm->_gfx->getBackBuffer(); - if (_panelMode == kPanelMain) { // FIXME: HACK - // Update playfield space ( only if cursor is inside ) - if (imousePointer.y < _vm->getSceneHeight()) { - // Mouse is in playfield space - if (updateFlag == UPDATE_MOUSEMOVE) { - handlePlayfieldUpdate(backBuffer, imousePointer); + if (_panelMode == kPanelMain) { + if (updateFlag == UPDATE_MOUSEMOVE) { + + if (mousePoint.y < _vm->getSceneHeight()) { + //handlePlayfieldUpdate(backBuffer, imousePointer); + _vm->_script->whichObject(mousePoint); } else { - if (updateFlag == UPDATE_MOUSECLICK) { - handlePlayfieldClick(backBuffer, imousePointer); + if (_lastMousePoint.y < _vm->getSceneHeight()) { + _vm->_script->setNonPlayfieldVerb(); } + handleCommandUpdate(backBuffer, mousePoint); } + } else { - // Update command space - if (updateFlag == UPDATE_MOUSEMOVE) { - handleCommandUpdate(backBuffer, imousePointer); - } else { - if (updateFlag == UPDATE_MOUSECLICK) { - handleCommandClick(backBuffer, imousePointer); + + if (updateFlag == UPDATE_MOUSECLICK) { + if (mousePoint.y < _vm->getSceneHeight()) { + handlePlayfieldClick(backBuffer, mousePoint); + } else { + handleCommandClick(backBuffer, mousePoint); } } } } drawStatusBar(backBuffer); - + _lastMousePoint = mousePoint; return SUCCESS; } @@ -415,21 +417,21 @@ int Interface::drawStatusBar(SURFACE *ds) { return SUCCESS; } -void Interface::handleCommandClick(SURFACE *ds, const Point& imousePointer) { +void Interface::handleCommandClick(SURFACE *ds, const Point& mousePoint) { PanelButton *panelButton; - panelButton = verbHitTest(imousePointer); + panelButton = verbHitTest(mousePoint); if (panelButton) { _vm->_script->setVerb(panelButton->id); return; } } -void Interface::handleCommandUpdate(SURFACE *ds, const Point& imousePointer) { +void Interface::handleCommandUpdate(SURFACE *ds, const Point& mousePoint) { PanelButton *panelButton; - panelButton = verbHitTest(imousePointer); + panelButton = verbHitTest(mousePoint); if (_mainPanel.currentButton != panelButton) { if (_mainPanel.currentButton) { drawVerb(_mainPanel.currentButton->id, 0); @@ -458,7 +460,7 @@ int Interface::handlePlayfieldClick(SURFACE *ds, const Point& imousePt) { uint16 object_flags = 0; // int script_num; - ActorLocation location; + Location location; objectNum = _vm->_scene->_objectMap->hitTest(imousePt); @@ -529,7 +531,7 @@ int Interface::handlePlayfieldUpdate(SURFACE *ds, const Point& imousePt) { */ } -PanelButton *Interface::verbHitTest(const Point& imousePointer) { +PanelButton *Interface::verbHitTest(const Point& mousePoint) { PanelButton *panelButton; Rect rect; int i; @@ -540,7 +542,7 @@ PanelButton *Interface::verbHitTest(const Point& imousePointer) { rect.right = rect.left + panelButton->width; rect.top = _mainPanel.y + panelButton->yOffset; rect.bottom = rect.top + panelButton->height; - if (rect.contains(imousePointer)) + if (rect.contains(mousePoint)) return panelButton; } } @@ -643,6 +645,7 @@ int Interface::inventoryTest(const Point& imousePt, int *ibutton) { return FAILURE; } + void Interface::drawVerb(int verb, int state) { SURFACE *backBuffer; PanelButton * panelButton; diff --git a/saga/interface.h b/saga/interface.h index e481998de9..d9030c3bd7 100644 --- a/saga/interface.h +++ b/saga/interface.h @@ -96,19 +96,18 @@ public: int activate(); int deactivate(); + bool isActive() { return _active; } int setMode(int mode, bool force = false); int getMode(void) const { return _panelMode; } void rememberMode(); void restoreMode(); - void lockMode() { _lockedMode = _panelMode; } - void unlockMode() { _panelMode = _lockedMode; } bool isInMainMode() { return _inMainMode; } int setStatusText(const char *new_txt); int loadScenePortraits(int resourceId); int setLeftPortrait(int portrait); int setRightPortrait(int portrait); int draw(); - int update(const Point& imousePointer, int updateFlag); + int update(const Point& mousePoint, int updateFlag); int drawStatusBar(SURFACE *ds); void drawVerb(int verb, int state); @@ -120,12 +119,15 @@ public: private: int inventoryTest(const Point& imousePt, int *ibutton); - PanelButton *verbHitTest(const Point& imousePointer); - void handleCommandUpdate(SURFACE *ds, const Point& imousePointer); - void handleCommandClick(SURFACE *ds, const Point& imousePointer); + PanelButton *verbHitTest(const Point& mousePoint); + void handleCommandUpdate(SURFACE *ds, const Point& mousePoint); + void handleCommandClick(SURFACE *ds, const Point& mousePoint); int handlePlayfieldUpdate(SURFACE *ds, const Point& imousePt); int handlePlayfieldClick(SURFACE *ds, const Point& imousePt); + void lockMode() { _lockedMode = _panelMode; } + void unlockMode() { _panelMode = _lockedMode; } + void drawPanelButtonText(SURFACE *ds, InterfacePanel *panel, PanelButton *panelButton, int textColor, int textShadowColor); public: void converseClear(void); @@ -152,7 +154,7 @@ private: InterfacePanel _conversePanel; SpriteList _defPortraits; SpriteList _scenePortraits; - SCRIPT_THREAD *_iThread; + ScriptThread *_iThread; PanelButton *_verbTypeToPanelButton[kVerbTypesMax]; bool _active; @@ -164,6 +166,8 @@ private: int _leftPortrait; int _rightPortrait; + Point _lastMousePoint; + uint16 *_inventory; int _inventorySize; byte _inventoryCount; diff --git a/saga/objectdata.cpp b/saga/objectdata.cpp index a98ca9587d..5ca1215617 100644 --- a/saga/objectdata.cpp +++ b/saga/objectdata.cpp @@ -27,10 +27,6 @@ namespace Saga { -enum { - kObjUseWith = 0x01, - kObjNotFlat = 0x02 -}; OBJECTTABLE ObjectTable[OBJECTCOUNT] = { { 8, 49, 1256, 760, 0, 9, 5, kObjNotFlat }, // Magic Hat diff --git a/saga/objectdata.h b/saga/objectdata.h index c0990c044a..9a2f1c8457 100644 --- a/saga/objectdata.h +++ b/saga/objectdata.h @@ -28,12 +28,17 @@ namespace Saga { +enum { + kObjUseWith = 0x01, + kObjNotFlat = 0x02 +}; + struct OBJECTTABLE { byte nameIndex; int32 sceneIndex; int16 x, y, z; int32 spritelistRn; - byte scriptRn; + byte scriptEntrypointNumber; uint16 interactBits; }; diff --git a/saga/objectmap.cpp b/saga/objectmap.cpp index 6623042dbe..c8c43068db 100644 --- a/saga/objectmap.cpp +++ b/saga/objectmap.cpp @@ -43,7 +43,7 @@ HitZone::HitZone(MemoryReadStreamEndian *readStream) { _flags = readStream->readByte(); _clickAreasCount = readStream->readByte(); - _defaultVerb = readStream->readByte(); + _rightButtonVerb = readStream->readByte(); readStream->readByte(); // pad _nameNumber = readStream->readUint16(); _scriptNumber = readStream->readUint16(); diff --git a/saga/objectmap.h b/saga/objectmap.h index 05b7a59189..ffe3cbbf9a 100644 --- a/saga/objectmap.h +++ b/saga/objectmap.h @@ -49,13 +49,16 @@ public: int getEntranceNumber() const { return _scriptNumber; } + int getRightButtonVerb() const { + return _rightButtonVerb; + } void draw(SURFACE *ds, int color); bool hitTest(const Point &testPoint); private: int _flags; // HitZoneFlags int _clickAreasCount; - int _defaultVerb; + int _rightButtonVerb; int _nameNumber; int _scriptNumber; diff --git a/saga/resnames.h b/saga/resnames.h index a0aead8fa8..9767b906b5 100644 --- a/saga/resnames.h +++ b/saga/resnames.h @@ -115,6 +115,11 @@ namespace Saga { //TODO: fill it #define RID_SCENE1_VOICE_138 186 +#define RID_BOAR_VOICE_000 239 +#define RID_BOAR_VOICE_002 241 +#define RID_BOAR_VOICE_005 244 +#define RID_BOAR_VOICE_006 245 +#define RID_BOAR_VOICE_007 246 // MUSIC #define MUSIC_1 9 diff --git a/saga/saga.cpp b/saga/saga.cpp index e9b8a8c5db..1d934a2752 100644 --- a/saga/saga.cpp +++ b/saga/saga.cpp @@ -357,6 +357,27 @@ const char *SagaEngine::getObjectName(uint16 objectId) { return NULL; } +int SagaEngine::getObjectScriptEntrypointNumber(uint16 objectId) { + ActorData *actor; + switch (objectIdType(objectId)) { + case kGameObjectActor: + actor = _vm->_actor->getActor(objectId); + return actor->scriptEntrypointNumber; + break; + } + //todo: object name & etc + return 0; +} + +int SagaEngine::getObjectFlags(uint16 objectId) { + ActorData *actor; + if (objectIdType(objectId) == kGameObjectActor) { + actor = _vm->_actor->getActor(objectId); + return actor->flags; + } + return 0; +} + const char *SagaEngine::getTextString(int textStringId) { const char *string; int lang = _vm->getFeatures() & GF_LANG_DE ? 1 : 0; @@ -368,4 +389,30 @@ const char *SagaEngine::getTextString(int textStringId) { return string; } +void SagaEngine::getExcuseInfo(int verb, const char *&textString, int &soundResourceId) { + textString = NULL; // TODO: i18n it ! + switch (verb) { + case kVerbPickUp: + textString = "I can't pick that up."; + soundResourceId = RID_BOAR_VOICE_007; + break; + case kVerbLookAt: + textString = "I see nothing special about it."; + soundResourceId = RID_BOAR_VOICE_006; + break; + case kVerbOpen: + textString = "There's no place to open it."; + soundResourceId = RID_BOAR_VOICE_000; + break; + case kVerbClose: + textString = "There's no opening to close."; + soundResourceId = RID_BOAR_VOICE_002; + break; + case kVerbUse: + textString = "I don't know how to do that."; + soundResourceId = RID_BOAR_VOICE_005; + break; + } +} + } // End of namespace Saga diff --git a/saga/saga.h b/saga/saga.h index be0bc3f0e2..02922eb709 100644 --- a/saga/saga.h +++ b/saga/saga.h @@ -433,8 +433,10 @@ public: byte **output_buf, size_t *output_buf_len, int *w, int *h); const byte *getImagePal(const byte *image_data, size_t image_size); void loadStrings(StringsTable &stringsTable, const byte *stringsPointer, size_t stringsLength); - const char *getObjectName(uint16 objectId); + const char *getObjectName(uint16 objectId); + int getObjectScriptEntrypointNumber(uint16 objectId); + int getObjectFlags(uint16 objectId); public: TEXTLIST *textCreateList(); void textDestroyList(TEXTLIST *textlist); @@ -491,6 +493,7 @@ public: const GameDisplayInfo & getDisplayInfo() { return _gameDisplayInfo; } const char *getTextString(int textStringId); + void getExcuseInfo(int verb, const char *&textString, int &soundResourceId); private: int loadGame(int gameNumber); }; diff --git a/saga/scene.cpp b/saga/scene.cpp index 7f73ba814a..c5ff11199b 100644 --- a/saga/scene.cpp +++ b/saga/scene.cpp @@ -191,7 +191,7 @@ int Scene::startScene() { scene_qdat = queueIterator.operator->(); assert(scene_qdat != NULL); - loadScene(scene_qdat->scene_n, scene_qdat->load_flag, scene_qdat->scene_proc, scene_qdat->scene_desc, scene_qdat->fadeType); + loadScene(scene_qdat->scene_n, scene_qdat->load_flag, scene_qdat->scene_proc, scene_qdat->sceneDescription, scene_qdat->fadeType); return SUCCESS; } @@ -230,7 +230,7 @@ int Scene::nextScene() { scene_qdat = queueIterator.operator->(); assert(scene_qdat != NULL); - loadScene(scene_qdat->scene_n, scene_qdat->load_flag, scene_qdat->scene_proc, scene_qdat->scene_desc, scene_qdat->fadeType); + loadScene(scene_qdat->scene_n, scene_qdat->load_flag, scene_qdat->scene_proc, scene_qdat->sceneDescription, scene_qdat->fadeType); return SUCCESS; } @@ -277,7 +277,7 @@ int Scene::skipScene() { _sceneQueue.erase(_sceneQueue.begin(), queueIterator); endScene(); - loadScene(skip_qdat->scene_n, skip_qdat->load_flag, skip_qdat->scene_proc, skip_qdat->scene_desc, skip_qdat->fadeType); + loadScene(skip_qdat->scene_n, skip_qdat->load_flag, skip_qdat->scene_proc, skip_qdat->sceneDescription, skip_qdat->fadeType); } // Search for a scene to skip to @@ -504,7 +504,7 @@ int Scene::getSceneLUT(int scene_num) { return _sceneLUT[scene_num]; } -int Scene::loadScene(int scene_num, int load_flag, SCENE_PROC scene_proc, SCENE_DESC *scene_desc_param, int fadeType) { +int Scene::loadScene(int scene_num, int load_flag, SCENE_PROC scene_proc, SceneDescription *scene_desc_param, int fadeType) { SCENE_INFO scene_info; uint32 res_number = 0; int result; @@ -580,8 +580,8 @@ int Scene::loadScene(int scene_num, int load_flag, SCENE_PROC scene_proc, SCENE_ } // Load scene script data - if (_desc.scriptNum > 0) { - if (_vm->_script->loadScript(_desc.scriptNum) != SUCCESS) { + if (_desc.scriptModuleNumber > 0) { + if (_vm->_script->loadScript(_desc.scriptModuleNumber) != SUCCESS) { warning("Scene::loadScene(): Error loading scene script"); return FAILURE; } @@ -635,12 +635,12 @@ int Scene::loadScene(int scene_num, int load_flag, SCENE_PROC scene_proc, SCENE_ q_event = _vm->_events->chain(q_event, &event); // Start the scene pre script, but stay with black palette - if (_desc.startScriptNum > 0) { + if (_desc.startScriptEntrypointNumber > 0) { event.type = ONESHOT_EVENT; event.code = SCRIPT_EVENT; event.op = EVENT_EXEC_BLOCKING; event.time = 0; - event.param = _desc.startScriptNum; + event.param = _desc.startScriptEntrypointNumber; event.param2 = 0; // Action event.param3 = _sceneNumber; // Object event.param4 = 0; // With Object - TODO: should be 'entrance' @@ -695,9 +695,9 @@ int Scene::loadSceneDescriptor(uint32 res_number) { _desc.resListRN = readS.readSint16(); _desc.endSlope = readS.readSint16(); _desc.beginSlope = readS.readSint16(); - _desc.scriptNum = readS.readUint16(); - _desc.sceneScriptNum = readS.readUint16(); - _desc.startScriptNum = readS.readUint16(); + _desc.scriptModuleNumber = readS.readUint16(); + _desc.sceneScriptEntrypointNumber = readS.readUint16(); + _desc.startScriptEntrypointNumber = readS.readUint16(); _desc.musicRN = readS.readSint16(); RSC_FreeResource(scene_desc_data); @@ -930,7 +930,7 @@ int Scene::endScene() { _sceneProc(SCENE_END, &scene_info, this); - if (_desc.scriptNum > 0) { + if (_desc.scriptModuleNumber > 0) { _vm->_script->freeScript(); } @@ -1002,9 +1002,9 @@ void Scene::cmdSceneInfo() { _vm->_console->DebugPrintf(fmt, "Resource list R#:", _desc.resListRN); _vm->_console->DebugPrintf(fmt, "End slope:", _desc.endSlope); _vm->_console->DebugPrintf(fmt, "Begin slope:", _desc.beginSlope); - _vm->_console->DebugPrintf(fmt, "Script resource:", _desc.scriptNum); - _vm->_console->DebugPrintf(fmt, "Scene script:", _desc.sceneScriptNum); - _vm->_console->DebugPrintf(fmt, "Start script:", _desc.startScriptNum); + _vm->_console->DebugPrintf(fmt, "scriptModuleNumber:", _desc.scriptModuleNumber); + _vm->_console->DebugPrintf(fmt, "sceneScriptEntrypointNumber:", _desc.sceneScriptEntrypointNumber); + _vm->_console->DebugPrintf(fmt, "startScriptEntrypointNumber:", _desc.startScriptEntrypointNumber); _vm->_console->DebugPrintf(fmt, "Music R#", _desc.musicRN); } @@ -1084,12 +1084,12 @@ int Scene::defaultScene(int param, SCENE_INFO *scene_info) { _vm->_events->chain(q_event, &event); // Start the scene main script - if (_desc.sceneScriptNum > 0) { + if (_desc.sceneScriptEntrypointNumber > 0) { event.type = ONESHOT_EVENT; event.code = SCRIPT_EVENT; event.op = EVENT_EXEC_NONBLOCKING; event.time = 0; - event.param = _desc.sceneScriptNum; + event.param = _desc.sceneScriptEntrypointNumber; event.param2 = 0; // Action event.param3 = _sceneNumber; // Object event.param4 = 0; // With Object - TODO: should be 'entrance' diff --git a/saga/scene.h b/saga/scene.h index c518b52008..4f95a1082d 100644 --- a/saga/scene.h +++ b/saga/scene.h @@ -99,14 +99,14 @@ struct SCENE_RESLIST { #define SAGA_SCENE_DESC_LEN 16 -struct SCENE_DESC { +struct SceneDescription { int16 flags; int16 resListRN; int16 endSlope; int16 beginSlope; - uint16 scriptNum; - uint16 sceneScriptNum; - uint16 startScriptNum; + uint16 scriptModuleNumber; + uint16 sceneScriptEntrypointNumber; + uint16 startScriptEntrypointNumber; int16 musicRN; SCENE_RESLIST *resList; size_t resListCnt; @@ -139,7 +139,7 @@ enum SCENE_FADE_TYPES { struct SCENE_QUEUE { uint32 scene_n; - SCENE_DESC *scene_desc; + SceneDescription* sceneDescription; int load_flag; SCENE_PROC *scene_proc; int scene_skiptarget; @@ -203,7 +203,8 @@ class Scene { int endScene(); int queueScene(SCENE_QUEUE *scene_queue); int draw(SURFACE *); - int getFlags() { return _desc.flags; } + int getFlags() const { return _desc.flags; } + int getScriptModuleNumber() const { return _desc.scriptModuleNumber; } bool isInDemo() { return !_inGame; } void getBGMaskInfo(int &width, int &height, byte *&buffer, size_t &bufferLength); @@ -232,8 +233,7 @@ class Scene { int currentSceneNumber() { return _sceneNumber; } private: - int loadScene(int scene, int load_flag, SCENE_PROC scene_proc, SCENE_DESC *, - int fadeIn); + int loadScene(int scene, int load_flag, SCENE_PROC scene_proc, SceneDescription *, int fadeIn); int loadSceneDescriptor(uint32 res_number); int loadSceneResourceList(uint32 res_number); int processSceneResources(); @@ -253,7 +253,7 @@ class Scene { int _sceneResNum; bool _inGame; bool _loadDesc; - SCENE_DESC _desc; + SceneDescription _desc; int _resListEntries; SCENE_RESLIST *_resList; int _animEntries; diff --git a/saga/script.cpp b/saga/script.cpp index f880dd2fd4..3fa26f5128 100644 --- a/saga/script.cpp +++ b/saga/script.cpp @@ -31,6 +31,12 @@ #include "saga/script.h" #include "saga/stream.h" #include "saga/interface.h" +#include "saga/actordata.h" +#include "saga/scene.h" +#include "saga/events.h" +#include "saga/actor.h" +#include "saga/objectdata.h" +#include "saga/objectmap.h" namespace Saga { @@ -61,6 +67,7 @@ Script::Script() { _stickyVerb = kVerbWalkTo; _leftButtonVerb = kVerbNone; _rightButtonVerb = kVerbNone; + _pointerObject = 0; _dataBuf[0].data = _dataBuf[1].data = (ScriptDataWord *)calloc(SCRIPT_DATABUF_LEN, sizeof(ScriptDataWord));; _dataBuf[0].length = _dataBuf[1].length = SCRIPT_DATABUF_LEN; @@ -256,7 +263,7 @@ int Script::getBit(int bufNumber, ScriptDataWord bitNumber, int *bitState) { } // Loads a script; including script bytecode and dialogue list -int Script::loadScript(int script_num) { +int Script::loadScript(int scriptModuleNumber) { ScriptData *script_data; byte *bytecode_p; size_t bytecode_len; @@ -270,8 +277,8 @@ int Script::loadScript(int script_num) { int result; // Validate script number - if ((script_num < 0) || (script_num > _scriptLUTMax)) { - warning("Script::loadScript(): Invalid script number"); + if ((scriptModuleNumber < 0) || (scriptModuleNumber > _scriptLUTMax)) { + warning("Script::loadScript(): Invalid script module number"); return FAILURE; } @@ -279,7 +286,7 @@ int Script::loadScript(int script_num) { freeScript(); // Initialize script data structure - debug(0, "Loading script data for script #%d", script_num); + debug(0, "Loading script data for script module #%d", scriptModuleNumber); script_data = (ScriptData *)malloc(sizeof(*script_data)); if (script_data == NULL) { @@ -293,7 +300,7 @@ int Script::loadScript(int script_num) { script_data->voice = NULL; // Load script bytecode - scriptl_rn = _scriptLUT[script_num].script_rn; + scriptl_rn = _scriptLUT[scriptModuleNumber].script_rn; result = RSC_LoadResource(_scriptContext, scriptl_rn, &bytecode_p, &bytecode_len); if (result != SUCCESS) { @@ -309,7 +316,7 @@ int Script::loadScript(int script_num) { } // Load script strings list - stringsResourceId = _scriptLUT[script_num].diag_list_rn; + stringsResourceId = _scriptLUT[scriptModuleNumber].diag_list_rn; // Load strings list resource result = RSC_LoadResource(_scriptContext, stringsResourceId, &stringsPointer, &stringsLength); @@ -323,7 +330,7 @@ int Script::loadScript(int script_num) { // Load voice resource lookup table if (_voiceLUTPresent) { - voicelut_rn = _scriptLUT[script_num].voice_lut_rn; + voicelut_rn = _scriptLUT[scriptModuleNumber].voice_lut_rn; // Load voice LUT resource result = RSC_LoadResource(_scriptContext, voicelut_rn, &voicelut_p, &voicelut_len); @@ -492,7 +499,7 @@ VOICE_LUT *Script::loadVoiceLUT(const byte *voicelut_p, size_t voicelut_len, Scr return voice_lut; } -void Script::scriptError(SCRIPT_THREAD *thread, const char *format, ...) { +void Script::scriptError(ScriptThread *thread, const char *format, ...) { char buf[STRINGBUFLEN]; va_list argptr; @@ -501,8 +508,8 @@ void Script::scriptError(SCRIPT_THREAD *thread, const char *format, ...) { va_end (argptr); thread->flags |= kTFlagAborted; - debug(0, "Script::scriptError %X: %s", thread->i_offset, buf); - _vm->_console->DebugPrintf("Script::scriptError %X: %s", thread->i_offset, buf); + debug(0, "Script::scriptError %X: %s", thread->instructionOffset, buf); + _vm->_console->DebugPrintf("Script::scriptError %X: %s", thread->instructionOffset, buf); } void Script::scriptInfo() { @@ -536,7 +543,7 @@ void Script::scriptExec(int argc, const char **argv) { if (_dbg_thread == NULL) { _vm->_console->DebugPrintf("Creating debug thread...\n"); - _dbg_thread = SThreadCreate(); + _dbg_thread = createThread(); if (_dbg_thread == NULL) { _vm->_console->DebugPrintf("Thread creation failed.\n"); return; @@ -548,7 +555,7 @@ void Script::scriptExec(int argc, const char **argv) { return; } - SThreadExecute(_dbg_thread, ep_num); + executeThread(_dbg_thread, ep_num); } // verb @@ -641,6 +648,198 @@ void Script::setRightButtonVerb(int verb) { } void Script::doVerb() { + int scriptEntrypointNumber = 0; + int scriptModuleNumber = 0; + int objectType; + EVENT event; + const char *excuseText; + int excuseSampleResourceId; + + objectType = objectIdType(_pendingObject[0]); + + if (_pendingVerb == kVerbGive) { + scriptEntrypointNumber = _vm->getObjectScriptEntrypointNumber(_pendingObject[1]); + if (_vm->getObjectFlags(_pendingObject[1]) & (kFollower|kProtagonist|kExtended)) { + scriptModuleNumber = 0; + } else { + scriptModuleNumber = _vm->_scene->getScriptModuleNumber(); + } + } else { + if (_pendingVerb == kVerbUse) { + if ((objectIdType(_pendingObject[1]) > kGameObjectNone) && (objectType < objectIdType(_pendingObject[1]))) { + SWAP(_pendingObject[0], _pendingObject[1]); + objectType = objectIdType(_pendingObject[0]); + } + } + + if (objectType == kGameObjectHitZone) { + scriptModuleNumber = _vm->_scene->getScriptModuleNumber(); + //TODO: check HitZone Exit + } else { + if (objectType & (kGameObjectActor | kGameObjectObject)) { + scriptEntrypointNumber = _vm->getObjectScriptEntrypointNumber(_pendingObject[0]); + + if ((objectType == kGameObjectActor) && !(_vm->getObjectFlags(_pendingObject[0]) & (kFollower|kProtagonist|kExtended))) { + scriptModuleNumber = _vm->_scene->getScriptModuleNumber(); + } else { + scriptModuleNumber = 0; + } + } + } + } + + if (scriptEntrypointNumber > 0) { + if (scriptModuleNumber != _vm->_scene->getScriptModuleNumber()) { + warning("scriptModuleNumber != _vm->_scene->getScriptModuleNumber()"); + } + + event.type = ONESHOT_EVENT; + event.code = SCRIPT_EVENT; + event.op = EVENT_EXEC_NONBLOCKING; + event.time = 0; + event.param = scriptEntrypointNumber; + event.param2 = _pendingVerb; // Action + event.param3 = _pendingObject[0]; // Object + event.param4 = _pendingObject[1]; // With Object + event.param5 = (objectType == kGameObjectActor) ? _pendingObject[0] : ID_PROTAG; // Actor + + _vm->_events->queue(&event); + + } else { + _vm->getExcuseInfo(_pendingVerb, excuseText, excuseSampleResourceId); + if (excuseText) + _vm->_actor->actorSpeech(ID_PROTAG, &excuseText, 1, excuseSampleResourceId, 0); + } + + if ((_currentVerb == kVerbWalkTo) || (_currentVerb == kVerbLookAt)) { + _stickyVerb = _currentVerb; + } + + _pendingVerb = kVerbNone; + _currentObject[0] = _currentObject[1] = ID_NOTHING; + setLeftButtonVerb(_stickyVerb); + + setPointerVerb(); +} + +void Script::setPointerVerb() { + Point mousePoint; + mousePoint = _vm->getMousePos(); + if (_vm->_interface->isActive()) { + _pointerObject = ID_PROTAG; + whichObject(mousePoint); + } +} + +void Script::whichObject(const Point& mousePointer) { + uint16 objectId; + int16 objectFlags; + int newRightButtonVerb; + uint16 newObjectId; + ActorData *actor; + Location pickLocation; + int hitZoneId; + HitZone * hitZone; + + objectId = ID_NOTHING; + objectFlags = 0; + _leftButtonVerb = _currentVerb; + newRightButtonVerb = kVerbNone; + + if (_vm->_actor->_protagonist->currentAction == kActionWalkDir) { + } else { + newObjectId = _vm->_actor->testHit(mousePointer); + + if (newObjectId != ID_NOTHING) { + if (objectIdType(newObjectId) == kGameObjectObject) { + objectId = newObjectId; + objectFlags = 0; + newRightButtonVerb = kVerbLookAt; + + if ((_currentVerb == kVerbTalkTo) || ((_currentVerb == kVerbGive) && _firstObjectSet)) { + objectId = ID_NOTHING; + newObjectId = ID_NOTHING; + } + } else { + actor = _vm->_actor->getActor(newObjectId); + objectId = newObjectId; + objectFlags = kObjUseWith; + newRightButtonVerb = kVerbTalkTo; + + if ((_currentVerb == kVerbPickUp) || + (_currentVerb == kVerbOpen) || + (_currentVerb == kVerbClose) || + ((_currentVerb == kVerbGive) && !_firstObjectSet) || + ((_currentVerb == kVerbUse) && !(actor->flags & kFollower))) { + objectId = ID_NOTHING; + newObjectId = ID_NOTHING; + } + } + } + + if (newObjectId == ID_NOTHING) { +/* struct HitZone far *newZone = NULL; + UWORD zone;*/ + + + if (_vm->_scene->getFlags() & kSceneFlagISO) { + //todo: it + } else { + pickLocation.x = mousePointer.x; + pickLocation.y = mousePointer.y; + pickLocation.z = 0; + } + + hitZoneId = _vm->_scene->_objectMap->hitTest(mousePointer); + + if ((hitZoneId != -1) && 0) { //TODO: do it + //hitZone = _vm->_scene->_objectMap->getZone(hitZoneId); + //objectId = hitZone->objectId; + objectFlags = 0; + newRightButtonVerb = hitZone->getRightButtonVerb() & 0x7f; + + if (newRightButtonVerb == kVerbWalkOnly) { + if (_firstObjectSet) { + objectId = ID_NOTHING; + } else { + newRightButtonVerb = _leftButtonVerb = kVerbWalkTo; + } + } else { + if (_firstObjectSet) { + objectId = ID_NOTHING; + } else { + newRightButtonVerb = _leftButtonVerb = kVerbLookAt; + } + } + + if (newRightButtonVerb >= kVerbOptions) { + newRightButtonVerb = kVerbNone; + } + + if ((_currentVerb == kVerbTalkTo) || ((_currentVerb == kVerbGive) && !_firstObjectSet)) { + objectId = ID_NOTHING; + newObjectId = ID_NOTHING; + } + + if ((_leftButtonVerb == kVerbUse) && (hitZone->getRightButtonVerb() & 0x80)) { + objectFlags = kObjUseWith; + } + } + } + } + + if (objectId != _pointerObject) { + _pointerObject = objectId; + _currentObject[_firstObjectSet ? 1 : 0] = objectId; + _currentObjectFlags[_firstObjectSet ? 1 : 0] = objectFlags; + if (_pendingVerb == kVerbNone) { + showVerb(); + } + } + + if (newRightButtonVerb != _rightButtonVerb) { + setRightButtonVerb(newRightButtonVerb); + } } // console wrappers diff --git a/saga/script.h b/saga/script.h index 94f49c33bd..9236a7e131 100644 --- a/saga/script.h +++ b/saga/script.h @@ -127,15 +127,15 @@ enum WalkFlags { kWalkFace = (1<<5) }; -struct SCRIPT_THREAD { +struct ScriptThread { int flags; // ThreadFlags int waitType; // ThreadWaitTypes void *threadObj; // which object we're handling uint sleepTime; - int ep_num; // Entrypoint number - unsigned long ep_offset; // Entrypoint offset - unsigned long i_offset; // Instruction offset + int entrypointNumber; // Entrypoint number + unsigned long entrypointOffset; // Entrypoint offset + unsigned long instructionOffset; // Instruction offset // The scripts are allowed to access the stack like any other memory // area. It's therefore probably quite important that our stacks work @@ -183,10 +183,12 @@ struct SCRIPT_THREAD { sleepTime = aSleepTime; } - SCRIPT_THREAD() { memset(this, 0, sizeof(*this)); } + ScriptThread() { + memset(this, 0, sizeof(*this)); + } }; -typedef SortedList<SCRIPT_THREAD> ScriptThreadList; +typedef SortedList<ScriptThread> ScriptThreadList; struct PROC_TBLENTRY { size_t name_offset; @@ -224,7 +226,7 @@ struct ScriptDataBuf { int length; }; -#define SCRIPTFUNC_PARAMS SCRIPT_THREAD *thread, int nArgs +#define SCRIPTFUNC_PARAMS ScriptThread *thread, int nArgs class Script { public: @@ -251,11 +253,19 @@ public: void doVerb(); void showVerb(); void setVerb(int verb); - void setLeftButtonVerb(int verb); - void setRightButtonVerb(int verb); int getCurrentVerb() const { return _currentVerb; } + void setPointerVerb(); + void whichObject(const Point& mousePointer); + + void setLeftButtonVerb(int verb); int getLeftButtonVerb() const { return _leftButtonVerb; } + void setRightButtonVerb(int verb); int getRightButtonVerb() const { return _rightButtonVerb; } + void setNonPlayfieldVerb() { + setRightButtonVerb(kVerbNone); + _pointerObject = ID_NOTHING; + _currentObject[_firstObjectSet ? 1 : 0] = ID_NOTHING; + } void scriptInfo(); void scriptExec(int argc, const char **argv); @@ -276,13 +286,15 @@ protected: bool _firstObjectSet; bool _secondObjectNeeded; uint16 _currentObject[2]; + int16 _currentObjectFlags[2]; uint16 _pendingObject[2]; int _currentVerb; int _stickyVerb; int _leftButtonVerb; int _rightButtonVerb; int _pendingVerb; - + + uint16 _pointerObject; public: bool _skipSpeeches; @@ -290,27 +302,27 @@ public: int _dbg_singlestep; int _dbg_dostep; - SCRIPT_THREAD *_dbg_thread; + ScriptThread *_dbg_thread; TEXTLIST_ENTRY *_dbg_txtentry; public: - SCRIPT_THREAD *SThreadCreate(); - int SThreadExecute(SCRIPT_THREAD *thread, int ep_num); + ScriptThread *createThread(); + int executeThread(ScriptThread *thread, int entrypointNumber); int executeThreads(uint msec); int SThreadDebugStep(); - void SThreadCompleteThread(void); + void completeThread(void); void wakeUpActorThread(int waitType, void *threadObj); void wakeUpThreads(int waitType); void wakeUpThreadsDelayed(int waitType, int sleepTime); private: - void setFramePtr(SCRIPT_THREAD *thread, int newPtr); - unsigned char *SThreadGetReadPtr(SCRIPT_THREAD *thread); + void setFramePtr(ScriptThread *thread, int newPtr); + unsigned char *SThreadGetReadPtr(ScriptThread *thread); unsigned long SThreadGetReadOffset(const byte *read_p); - size_t SThreadGetReadLen(SCRIPT_THREAD *thread); - void runThread(SCRIPT_THREAD *thread, int instr_limit); - int SThreadSetEntrypoint(SCRIPT_THREAD *thread, int ep_num); + size_t SThreadGetReadLen(ScriptThread *thread); + void runThread(ScriptThread *thread, int instr_limit); + void setThreadEntrypoint(ScriptThread *thread, int entrypointNumber); private: typedef int (Script::*ScriptFunctionType)(SCRIPTFUNC_PARAMS); @@ -322,8 +334,8 @@ private: const ScriptFunctionDescription *_scriptFunctionsList; void setupScriptFuncList(void); - void scriptError(SCRIPT_THREAD *thread, const char *format, ...); - int SDebugPrintInstr(SCRIPT_THREAD *thread); + void scriptError(ScriptThread *thread, const char *format, ...); + int SDebugPrintInstr(ScriptThread *thread); int SF_putString(SCRIPTFUNC_PARAMS); int sfWait(SCRIPTFUNC_PARAMS); diff --git a/saga/sdebug.cpp b/saga/sdebug.cpp index e0b35d370c..9816e0bb7a 100644 --- a/saga/sdebug.cpp +++ b/saga/sdebug.cpp @@ -37,7 +37,7 @@ namespace Saga { #define SD_DISPLAY_LEN 128 #define SD_ADDTXT(x) strncat(disp_buf, x, SD_DISPLAY_LEN); -int Script::SDebugPrintInstr(SCRIPT_THREAD *thread) { +int Script::SDebugPrintInstr(ScriptThread *thread) { TEXTLIST_ENTRY tl_e; char tmp_buf[80] = { 0 }; static char disp_buf[SD_DISPLAY_LEN] = { 0 }; @@ -66,11 +66,11 @@ int Script::SDebugPrintInstr(SCRIPT_THREAD *thread) { tl_e.display = 1; MemoryReadStream readS(currentScript()->bytecode->bytecode_p - + thread->i_offset, + + thread->instructionOffset, currentScript()->bytecode->bytecode_len - - thread->i_offset); + - thread->instructionOffset); in_char = readS.readByte(); - sprintf(tmp_buf, "%04lX | %02X | ", thread->i_offset, in_char); + sprintf(tmp_buf, "%04lX | %02X | ", thread->instructionOffset, in_char); strncat(disp_buf, tmp_buf, SD_DISPLAY_LEN); switch (in_char) { diff --git a/saga/sfuncs.cpp b/saga/sfuncs.cpp index 1952f15dcc..e068156555 100644 --- a/saga/sfuncs.cpp +++ b/saga/sfuncs.cpp @@ -209,7 +209,7 @@ int Script::SF_mainMode(SCRIPTFUNC_PARAMS) { // Param3: actor y int Script::sfScriptWalkTo(SCRIPTFUNC_PARAMS) { uint16 actorId; - ActorLocation actorLocation; + Location actorLocation; ActorData *actor; actorId = getSWord(thread->pop()); @@ -566,7 +566,7 @@ int Script::sfStartBgdAnimSpeed(SCRIPTFUNC_PARAMS) { // Param3: actor y int Script::sfScriptWalkToAsync(SCRIPTFUNC_PARAMS) { uint16 actorId; - ActorLocation actorLocation; + Location actorLocation; ActorData *actor; actorId = getSWord(thread->pop()); @@ -619,7 +619,7 @@ int Script::sfSetActorState(SCRIPTFUNC_PARAMS) { // Param3: actor pos y int Script::scriptMoveTo(SCRIPTFUNC_PARAMS) { uint16 actorId; - ActorLocation actorLocation; + Location actorLocation; ActorData *actor; actorId = getSWord(thread->pop()); @@ -688,7 +688,7 @@ int Script::sfSwapActors(SCRIPTFUNC_PARAMS) { uint16 actorId2; ActorData *actor1; ActorData *actor2; - ActorLocation location; + Location location; actorId1 = getSWord(thread->pop()); actorId2 = getSWord(thread->pop()); @@ -751,7 +751,7 @@ int Script::sfSimulSpeech(SCRIPTFUNC_PARAMS) { // Param4: actor walk flag int Script::sfScriptWalk(SCRIPTFUNC_PARAMS) { uint16 actorId; - ActorLocation actorLocation; + Location actorLocation; ActorData *actor; uint16 walkFlags; @@ -917,7 +917,7 @@ int Script::SF_scriptSpecialWalk(SCRIPTFUNC_PARAMS) { // Param6: actor frame number int Script::sfPlaceActor(SCRIPTFUNC_PARAMS) { uint16 actorId; - ActorLocation actorLocation; + Location actorLocation; int actorDirection; int frameType; int frameOffset; diff --git a/saga/sthread.cpp b/saga/sthread.cpp index e4b1f8f5d3..eae548cf07 100644 --- a/saga/sthread.cpp +++ b/saga/sthread.cpp @@ -37,34 +37,34 @@ namespace Saga { -void Script::setFramePtr(SCRIPT_THREAD *thread, int newPtr) { +void Script::setFramePtr(ScriptThread *thread, int newPtr) { thread->framePtr = newPtr; dataBuffer(3)->length = ARRAYSIZE(thread->stackBuf) - thread->framePtr; dataBuffer(3)->data = (ScriptDataWord *) &(thread->stackBuf[newPtr]); } -SCRIPT_THREAD *Script::SThreadCreate() { - SCRIPT_THREAD *new_thread; +ScriptThread *Script::createThread() { + ScriptThread *newThread; if (!isInitialized()) { return NULL; } - new_thread = _threadList.pushFront().operator->(); + newThread = _threadList.pushFront().operator->(); - new_thread->stackPtr = ARRAYSIZE(new_thread->stackBuf) - 1; - setFramePtr(new_thread, new_thread->stackPtr); + newThread->stackPtr = ARRAYSIZE(newThread->stackBuf) - 1; + setFramePtr(newThread, newThread->stackPtr); - new_thread->flags = kTFlagWaiting; - new_thread->waitType = kWaitTypePause; + newThread->flags = kTFlagWaiting; + newThread->waitType = kWaitTypePause; - dataBuffer(4)->length = ARRAYSIZE(new_thread->threadVars); - dataBuffer(4)->data = new_thread->threadVars; - return new_thread; + dataBuffer(4)->length = ARRAYSIZE(newThread->threadVars); + dataBuffer(4)->data = newThread->threadVars; + return newThread; } void Script::wakeUpActorThread(int waitType, void *threadObj) { - SCRIPT_THREAD *thread; + ScriptThread *thread; ScriptThreadList::iterator threadIterator; for (threadIterator = _threadList.begin(); threadIterator != _threadList.end(); ++threadIterator) { @@ -76,7 +76,7 @@ void Script::wakeUpActorThread(int waitType, void *threadObj) { } void Script::wakeUpThreads(int waitType) { - SCRIPT_THREAD *thread; + ScriptThread *thread; ScriptThreadList::iterator threadIterator; for (threadIterator = _threadList.begin(); threadIterator != _threadList.end(); ++threadIterator) { @@ -88,7 +88,7 @@ void Script::wakeUpThreads(int waitType) { } void Script::wakeUpThreadsDelayed(int waitType, int sleepTime) { - SCRIPT_THREAD *thread; + ScriptThread *thread; ScriptThreadList::iterator threadIterator; for (threadIterator = _threadList.begin(); threadIterator != _threadList.end(); ++threadIterator) { @@ -101,7 +101,7 @@ void Script::wakeUpThreadsDelayed(int waitType, int sleepTime) { } int Script::executeThreads(uint msec) { - SCRIPT_THREAD *thread; + ScriptThread *thread; ScriptThreadList::iterator threadIterator; if (!isInitialized()) { @@ -114,8 +114,8 @@ int Script::executeThreads(uint msec) { thread = threadIterator.operator->(); if (thread->flags & (kTFlagFinished | kTFlagAborted)) { - //if (thread->flags & kTFlagFinished) // FIXME. Missing function - + if (thread->flags & kTFlagFinished) + setPointerVerb(); threadIterator = _threadList.erase(threadIterator); continue; @@ -152,12 +152,12 @@ int Script::executeThreads(uint msec) { return SUCCESS; } -void Script::SThreadCompleteThread(void) { +void Script::completeThread(void) { for (int i = 0; i < 40 && !_threadList.isEmpty() ; i++) executeThreads(0); } -int Script::SThreadSetEntrypoint(SCRIPT_THREAD *thread, int ep_num) { +void Script::setThreadEntrypoint(ScriptThread *thread, int entrypointNumber) { SCRIPT_BYTECODE *bytecode; int max_entrypoint; @@ -166,26 +166,24 @@ int Script::SThreadSetEntrypoint(SCRIPT_THREAD *thread, int ep_num) { bytecode = currentScript()->bytecode; max_entrypoint = bytecode->n_entrypoints; - if ((ep_num < 0) || (ep_num >= max_entrypoint)) { - return FAILURE; + if ((entrypointNumber < 0) || (entrypointNumber >= max_entrypoint)) { + error("Script::setThreadEntrypoint wrong entrypointNumber"); } - thread->ep_num = ep_num; - thread->ep_offset = bytecode->entrypoints[ep_num].offset; - - return SUCCESS; + thread->entrypointNumber = entrypointNumber; + thread->entrypointOffset = bytecode->entrypoints[entrypointNumber].offset; } -int Script::SThreadExecute(SCRIPT_THREAD *thread, int ep_num) { +int Script::executeThread(ScriptThread *thread, int entrypointNumber) { assert(isInitialized()); if ((currentScript() == NULL) || (!currentScript()->loaded)) { return FAILURE; } - SThreadSetEntrypoint(thread, ep_num); + setThreadEntrypoint(thread, entrypointNumber); - thread->i_offset = thread->ep_offset; + thread->instructionOffset = thread->entrypointOffset; thread->flags = kTFlagNone; return SUCCESS; @@ -193,16 +191,16 @@ int Script::SThreadExecute(SCRIPT_THREAD *thread, int ep_num) { -unsigned char *Script::SThreadGetReadPtr(SCRIPT_THREAD *thread) { - return currentScript()->bytecode->bytecode_p + thread->i_offset; +unsigned char *Script::SThreadGetReadPtr(ScriptThread *thread) { + return currentScript()->bytecode->bytecode_p + thread->instructionOffset; } unsigned long Script::SThreadGetReadOffset(const byte *read_p) { return (unsigned long)(read_p - (unsigned char *)currentScript()->bytecode->bytecode_p); } -size_t Script::SThreadGetReadLen(SCRIPT_THREAD *thread) { - return currentScript()->bytecode->bytecode_len - thread->i_offset; +size_t Script::SThreadGetReadLen(ScriptThread *thread) { + return currentScript()->bytecode->bytecode_len - thread->instructionOffset; } @@ -216,7 +214,7 @@ int Script::SThreadDebugStep() { return SUCCESS; } -void Script::runThread(SCRIPT_THREAD *thread, int instr_limit) { +void Script::runThread(ScriptThread *thread, int instr_limit) { int instr_count; uint32 saved_offset; ScriptDataWord param1; @@ -251,23 +249,23 @@ void Script::runThread(SCRIPT_THREAD *thread, int instr_limit) { dataBuffer(2)->length = currentScript()->bytecode->bytecode_len / sizeof(ScriptDataWord); dataBuffer(2)->data = (ScriptDataWord *) currentScript()->bytecode->bytecode_p; - scriptS.seek(thread->i_offset); + scriptS.seek(thread->instructionOffset); for (instr_count = 0; instr_count < instr_limit; instr_count++) { if (thread->flags & (kTFlagAsleep)) break; - saved_offset = thread->i_offset; + saved_offset = thread->instructionOffset; operandChar = scriptS.readByte(); // debug print (opCode name etc) should be placed here // SDebugPrintInstr(thread) -// debug(2, "Executing thread offset: %lu (%x) stack: %d", thread->i_offset, operandChar, thread->stackSize()); +// debug(2, "Executing thread offset: %lu (%x) stack: %d", thread->instructionOffset, operandChar, thread->stackSize()); switch (operandChar) { case 0x01: // nextblock // Some sort of "jump to the start of the next memory // page" instruction, I think. - thread->i_offset = 1024 * ((thread->i_offset / 1024) + 1); + thread->instructionOffset = 1024 * ((thread->instructionOffset / 1024) + 1); break; // STACK INSTRUCTIONS @@ -356,7 +354,7 @@ void Script::runThread(SCRIPT_THREAD *thread, int instr_limit) { // counter as a pointer here. But I don't think // we will have to do that. thread->push(data); - thread->i_offset = (unsigned long)param1; + thread->instructionOffset = (unsigned long)param1; } break; case opCcall: // Call function @@ -377,7 +375,7 @@ void Script::runThread(SCRIPT_THREAD *thread, int instr_limit) { scriptFunction = _scriptFunctionsList[functionNumber].scriptFunction; scriptFunctionReturnValue = (this->*scriptFunction)(thread, argumentsCount); if (scriptFunctionReturnValue != SUCCESS) { - _vm->_console->DebugPrintf(S_WARN_PREFIX "%X: Script function %d failed.\n", thread->i_offset, scriptFunctionReturnValue); + _vm->_console->DebugPrintf(S_WARN_PREFIX "%X: Script function %d failed.\n", thread->instructionOffset, scriptFunctionReturnValue); } if (functionNumber == 16) { // SF_gotoScene @@ -408,7 +406,7 @@ void Script::runThread(SCRIPT_THREAD *thread, int instr_limit) { thread->flags |= kTFlagFinished; return; } else { - thread->i_offset = thread->pop(); + thread->instructionOffset = thread->pop(); /* int n_args = */ thread->pop(); if (operandChar == opReturn) thread->push(scriptRetVal); @@ -420,14 +418,14 @@ void Script::runThread(SCRIPT_THREAD *thread, int instr_limit) { // (JMP): Unconditional jump case 0x1D: param1 = scriptS.readUint16LE(); - thread->i_offset = (unsigned long)param1; + thread->instructionOffset = (unsigned long)param1; break; // (JNZP): Jump if nonzero + POP case 0x1E: param1 = scriptS.readUint16LE(); data = thread->pop(); if (data) { - thread->i_offset = (unsigned long)param1; + thread->instructionOffset = (unsigned long)param1; } break; // (JZP): Jump if zero + POP @@ -435,7 +433,7 @@ void Script::runThread(SCRIPT_THREAD *thread, int instr_limit) { param1 = scriptS.readUint16LE(); data = thread->pop(); if (!data) { - thread->i_offset = (unsigned long)param1; + thread->instructionOffset = (unsigned long)param1; } break; // (JNZ): Jump if nonzero @@ -443,7 +441,7 @@ void Script::runThread(SCRIPT_THREAD *thread, int instr_limit) { param1 = scriptS.readUint16LE(); data = thread->stackTop(); if (data) { - thread->i_offset = (unsigned long)param1; + thread->instructionOffset = (unsigned long)param1; } break; // (JZ): Jump if zero @@ -451,7 +449,7 @@ void Script::runThread(SCRIPT_THREAD *thread, int instr_limit) { param1 = scriptS.readUint16LE(); data = thread->stackTop(); if (!data) { - thread->i_offset = (unsigned long)param1; + thread->instructionOffset = (unsigned long)param1; } break; // (SWCH): Switch @@ -470,7 +468,7 @@ void Script::runThread(SCRIPT_THREAD *thread, int instr_limit) { switch_jmp = scriptS.readUint16LE(); // Found the specified case if (data == (ScriptDataWord) switch_num) { - thread->i_offset = switch_jmp; + thread->instructionOffset = switch_jmp; case_found = 1; break; } @@ -479,7 +477,7 @@ void Script::runThread(SCRIPT_THREAD *thread, int instr_limit) { // Jump to default case if (!case_found) { default_jmp = scriptS.readUint16LE(); - thread->i_offset = default_jmp; + thread->instructionOffset = default_jmp; } } break; @@ -497,7 +495,7 @@ void Script::runThread(SCRIPT_THREAD *thread, int instr_limit) { uint16 offset = scriptS.readUint16LE(); if (branch_probability > probability) { - thread->i_offset = offset; + thread->instructionOffset = offset; break; } @@ -770,7 +768,7 @@ void Script::runThread(SCRIPT_THREAD *thread, int instr_limit) { if (!(speechFlags & kSpeakAsync)) { thread->wait(kWaitTypeSpeech); - thread->i_offset = scriptS.pos(); + thread->instructionOffset = scriptS.pos(); return; } } @@ -803,7 +801,7 @@ void Script::runThread(SCRIPT_THREAD *thread, int instr_limit) { scriptS.readUint16LE(); scriptS.readUint16LE(); iparam1 = (long)scriptS.readByte(); - thread->i_offset += iparam1; + thread->instructionOffset += iparam1; break; // End instruction list @@ -814,14 +812,14 @@ void Script::runThread(SCRIPT_THREAD *thread, int instr_limit) { } // Set instruction offset only if a previous instruction didn't branch - if (saved_offset == thread->i_offset) { - thread->i_offset = scriptS.pos(); + if (saved_offset == thread->instructionOffset) { + thread->instructionOffset = scriptS.pos(); } else { - if (thread->i_offset >= scriptS.size()) { + if (thread->instructionOffset >= scriptS.size()) { scriptError(thread, "Out of range script execution"); return; } else { - scriptS.seek(thread->i_offset); + scriptS.seek(thread->instructionOffset); } } diff --git a/saga/xref.txt b/saga/xref.txt index de66d6fd9a..33ce644d5d 100644 --- a/saga/xref.txt +++ b/saga/xref.txt @@ -60,9 +60,9 @@ Scene.c resInfo->loadList _desc.resListRN resInfo->horizon _desc.endSlope resInfo->nearFigureLimit _desc.beginSlope - resInfo->scriptModule _desc.scriptNum - resInfo->entryScript _desc.sceneScriptNum - resInfo->preScript _desc.startScriptNum + resInfo->scriptModule _desc.scriptModuleNumber + resInfo->entryScript _desc.sceneScriptEntrypointNumber + resInfo->preScript _desc.startScriptEntrypointNumber resInfo->backgroundMusic _desc.musicRN thisScene->ID currentSceneNumber() |