aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorTobias Gunkel2012-01-08 23:51:13 +0100
committerTobias Gunkel2012-02-11 08:28:22 +0100
commitde0b5f76749add219a6b667d5d2d69fb8a86d959 (patch)
tree1ad135eecc6a2d91ccec411a7b60acd53499c0a2 /engines
parentd8b435917d5cc00ad2b4817c5eabc828439e36f3 (diff)
downloadscummvm-rg350-de0b5f76749add219a6b667d5d2d69fb8a86d959.tar.gz
scummvm-rg350-de0b5f76749add219a6b667d5d2d69fb8a86d959.tar.bz2
scummvm-rg350-de0b5f76749add219a6b667d5d2d69fb8a86d959.zip
SCUMM: use command stack and SentenceTab in mm c64
- MM C64 uses command stack (SentenceTab, doSentence()) now - _cmdObject... added for current SentenceTab. The _active... variables are only used to build a sentence in the inventory but never by a script. -> many routines are not needed anymore and are removed
Diffstat (limited to 'engines')
-rw-r--r--engines/scumm/object.cpp11
-rw-r--r--engines/scumm/script.cpp136
-rw-r--r--engines/scumm/script_v0.cpp68
-rw-r--r--engines/scumm/script_v2.cpp27
-rw-r--r--engines/scumm/script_v5.cpp65
-rw-r--r--engines/scumm/scumm.cpp14
-rw-r--r--engines/scumm/scumm.h2
-rw-r--r--engines/scumm/scumm_v0.h22
-rw-r--r--engines/scumm/scumm_v2.h2
-rw-r--r--engines/scumm/scumm_v5.h2
-rw-r--r--engines/scumm/verbs.cpp410
11 files changed, 307 insertions, 452 deletions
diff --git a/engines/scumm/object.cpp b/engines/scumm/object.cpp
index 53dc0151d9..49f1777c86 100644
--- a/engines/scumm/object.cpp
+++ b/engines/scumm/object.cpp
@@ -434,8 +434,15 @@ void ScummEngine::getObjectXYPos(int object, int &x, int &y, int &dir) {
y = od.y_pos + (int16)READ_LE_UINT16(&imhd->old.hotspot[state].y);
}
} else if (_game.version <= 2) {
- x = od.walk_x >> V12_X_SHIFT;
- y = od.walk_y >> V12_Y_SHIFT;
+ if (od.actordir) {
+ x = od.walk_x;
+ y = od.walk_y;
+ } else {
+ x = od.x_pos + od.width/2;
+ y = od.y_pos + od.height/2;
+ }
+ x = x >> V12_X_SHIFT;
+ y = y >> V12_Y_SHIFT;
} else {
x = od.walk_x;
y = od.walk_y;
diff --git a/engines/scumm/script.cpp b/engines/scumm/script.cpp
index d04c3c0891..0864022c59 100644
--- a/engines/scumm/script.cpp
+++ b/engines/scumm/script.cpp
@@ -28,6 +28,7 @@
#include "scumm/object.h"
#include "scumm/resource.h"
#include "scumm/util.h"
+#include "scumm/scumm_v0.h"
#include "scumm/scumm_v2.h"
#include "scumm/sound.h"
#include "scumm/verbs.h"
@@ -194,9 +195,14 @@ int ScummEngine::getVerbEntrypoint(int obj, int entry) {
return verboffs + 8 + READ_LE_UINT32(ptr + 1);
} else if (_game.version <= 2) {
do {
- if (!*verbptr)
- return 0;
- if (*verbptr == entry || *verbptr == 0xFF)
+ const int kFallbackEntry = (_game.version == 0 ? 0x0F : 0xFF);
+ if (!*verbptr) {
+ if (_game.version == 0 && entry == kVerbWalkTo)
+ return 13;
+ else
+ return 0;
+ }
+ if (*verbptr == entry || *verbptr == kFallbackEntry)
break;
verbptr += 2;
} while (1);
@@ -1128,6 +1134,130 @@ void ScummEngine::checkAndRunSentenceScript() {
runScript(sentenceScript, 0, 0, localParamList);
}
+void ScummEngine_v0::walkToActorOrObject(int object) {
+ int x, y, dir;
+ ActorC64 *a = (ActorC64 *)derefActor(VAR(VAR_EGO), "walkToObject");
+
+ _walkToObject = object;
+ _walkToObjectIdx = getObjectIndex(object);
+
+ if (OBJECT_V0_TYPE(object) == kObjectTypeActor) {
+ walkActorToActor(VAR(VAR_EGO), OBJECT_V0_NR(object), 4);
+ x = a->getRealPos().x;
+ y = a->getRealPos().y;
+ } else {
+ walkActorToObject(VAR(VAR_EGO), object);
+ getObjectXYPos(object, x, y, dir);
+ }
+
+ VAR(6) = x;
+ VAR(7) = y;
+
+ if (!(a->_miscflags & kActorMiscFlagFreeze)) {
+ // FIXME: walking already started -> should be stopped if condition not true
+ //actorStartWalk();
+ }
+}
+
+void ScummEngine_v0::checkAndRunSentenceScript() {
+ const ScriptSlot *ss;
+
+ if (_walkToObjectIdx) {
+ ActorC64 *a = (ActorC64 *)derefActor(VAR(VAR_EGO), "checkAndRunSentenceScript");
+ if (a->_moving)
+ return;
+ // TODO: change actor facing
+ _walkToObjectIdx = 0;
+ runSentenceScript();
+ return;
+ }
+
+ if (!_sentenceNum || _sentence[_sentenceNum - 1].freezeCount)
+ return;
+
+ //_sentenceNum--;
+ SentenceTab &st = _sentence[_sentenceNum - 1];
+
+ if (st.preposition && st.objectB == st.objectA)
+ return;
+
+ // FIXME: should this be executed?
+ //_currentScript = 0xFF;
+
+ int obj1Nr = OBJECT_V0_NR(st.objectA);
+ int obj1Type = OBJECT_V0_TYPE(st.objectA);
+ int obj2Nr = OBJECT_V0_NR(st.objectB);
+ int obj2Type = OBJECT_V0_TYPE(st.objectB);
+ assert(obj1Nr);
+
+ // If two objects are involved, at least one must be in the actors inventory
+ if (obj2Nr &&
+ (obj1Type != kObjectTypeFG || _objectOwnerTable[obj1Nr] != VAR(VAR_EGO)) &&
+ (obj2Type != kObjectTypeFG || _objectOwnerTable[obj2Nr] != VAR(VAR_EGO)))
+ {
+ if (getVerbEntrypoint(st.objectA, kVerbPickUp))
+ doSentence(kVerbPickUp, st.objectA, 0);
+ else if (getVerbEntrypoint(st.objectB, kVerbPickUp))
+ doSentence(kVerbPickUp, st.objectB, 0);
+ else
+ _sentenceNum--;
+ return;
+ }
+
+ _cmdVerb = st.verb;
+ _cmdObjectNr = obj1Nr;
+ _cmdObjectType = obj1Type;
+ _cmdObject2Nr = obj2Nr;
+ _cmdObject2Type = obj2Type;
+ _sentenceNum--;
+
+ // TODO: check sentenceNum
+
+ if (whereIsObject(st.objectA) != WIO_INVENTORY) {
+ if (_currentMode != kModeKeypad) {
+ walkToActorOrObject(st.objectA);
+ return;
+ }
+ } else if (st.objectB && whereIsObject(st.objectB) != WIO_INVENTORY) {
+ walkToActorOrObject(st.objectB);
+ return;
+ }
+
+ runSentenceScript();
+ if (_currentMode == kModeKeypad) {
+ _walkToObjectIdx = 0;
+ }
+}
+
+void ScummEngine_v0::runSentenceScript() {
+ int obj = OBJECT_V0(_cmdObjectNr, _cmdObjectType);
+
+ // FIXME: should it really ever return 0xD on WalkTo, seems wrong?
+ if (getVerbEntrypoint(obj, _cmdVerb) != 0) {
+ if (_cmdVerb == kVerbRead && VAR(VAR_CURRENT_LIGHTS) == 0) {
+ //slot = 0xFF;
+ VAR(VAR_ACTIVE_VERB) = _cmdVerb;
+ runScript(3, 0, 0, 0);
+ return;
+ } else {
+ VAR(VAR_ACTIVE_ACTOR) = _cmdObject2Nr;
+ runObjectScript(obj, _cmdVerb, false, false, NULL);
+ return;
+ }
+ } else {
+ if (_cmdVerb == kVerbGive) {
+ if (_cmdObject2Nr < 8)
+ setOwnerOf(obj, _cmdObject2Nr);
+ return;
+ } else if (_cmdVerb == kVerbWalkTo) {
+ //slot = 0xFF;
+ VAR(VAR_ACTIVE_VERB) = _cmdVerb;
+ runScript(3, 0, 0, 0);
+ return;
+ }
+ }
+}
+
void ScummEngine_v2::runInputScript(int clickArea, int val, int mode) {
int args[24];
int verbScript;
diff --git a/engines/scumm/script_v0.cpp b/engines/scumm/script_v0.cpp
index 9b39391246..f4b98a4ba5 100644
--- a/engines/scumm/script_v0.cpp
+++ b/engines/scumm/script_v0.cpp
@@ -177,7 +177,7 @@ void ScummEngine_v0::setupOpcodes() {
OPCODE(0x70, o_lights);
OPCODE(0x71, o_getBitVar);
OPCODE(0x72, o_nop);
- OPCODE(0x73, o5_getObjectOwner);
+ OPCODE(0x73, o_getObjectOwner);
/* 74 */
OPCODE(0x74, o5_getDist);
OPCODE(0x75, o_printEgo_c64);
@@ -337,7 +337,7 @@ void ScummEngine_v0::setupOpcodes() {
OPCODE(0xf0, o_lights);
OPCODE(0xf1, o_getBitVar);
OPCODE(0xf2, o_nop);
- OPCODE(0xf3, o5_getObjectOwner);
+ OPCODE(0xf3, o_getObjectOwner);
/* F4 */
OPCODE(0xf4, o5_getDist);
OPCODE(0xf5, o_stopCurrentScript);
@@ -365,7 +365,7 @@ uint ScummEngine_v0::fetchScriptWord() {
int ScummEngine_v0::getActiveObject() {
if (_opcode & PARAM_2)
- return _activeObjectNr;
+ return _cmdObjectNr;
return fetchScriptByte();
}
@@ -693,7 +693,7 @@ void ScummEngine_v0::o_putActorAtObject() {
void ScummEngine_v0::o_pickupObject() {
int objNr = fetchScriptByte();
- int obj = OBJECT_V0((objNr ? objNr : _activeObjectNr), 0);
+ int obj = OBJECT_V0((objNr ? objNr : _cmdObjectNr), 0);
/* Don't take an object twice */
if (whereIsObject(obj) == WIO_INVENTORY)
@@ -742,6 +742,12 @@ void ScummEngine_v0::o_setActorBitVar() {
debug(0, "o_setActorBitVar(%d, %d, %d)", act, mask, mod);
}
+void ScummEngine_v0::o_getObjectOwner() {
+ getResultPos();
+ int obj = getVarOrDirectWord(PARAM_1);
+ setResult(getOwner(obj ? obj : _cmdObjectNr));
+}
+
void ScummEngine_v0::o_getActorBitVar() {
getResultPos();
byte act = getVarOrDirectByte(PARAM_1);
@@ -787,17 +793,35 @@ void ScummEngine_v0::o_printEgo_c64() {
}
void ScummEngine_v0::o_doSentence() {
- byte entry = fetchScriptByte();
- byte obj = fetchScriptByte();
- fetchScriptByte();
+ byte verb = fetchScriptByte();
+ int obj, obj2;
+ byte b;
+
+ b = fetchScriptByte();
+ if (b == 0xFF) {
+ obj = OBJECT_V0(_cmdObject2Nr, _cmdObject2Type);
+ } else if (b == 0xFE) {
+ obj = OBJECT_V0(_cmdObjectNr, _cmdObjectType);
+ } else {
+ obj = OBJECT_V0(b, (_opcode & 0x80) ? 1 : 0);
+ }
- runObjectScript(obj, entry, false, false, NULL);
+ b = fetchScriptByte();
+ if (b == 0xFF) {
+ obj2 = OBJECT_V0(_cmdObject2Nr, _cmdObject2Type);
+ } else if (b == 0xFE) {
+ obj2 = OBJECT_V0(_cmdObjectNr, _cmdObjectType);
+ } else {
+ obj2 = OBJECT_V0(b, (_opcode & 0x40) ? 1 : 0);
+ }
+
+ doSentence(verb, obj, obj2);
}
-bool ScummEngine_v0::ifEqualActiveObject2Common(bool inventoryObject) {
+bool ScummEngine_v0::ifEqualActiveObject2Common(bool ignoreType) {
byte obj = fetchScriptByte();
- if (!inventoryObject || (_activeObject2Type == kObjectTypeFG))
- return (obj == _activeObject2Nr);
+ if (!ignoreType || (_cmdObject2Type == kObjectTypeFG))
+ return (obj == _cmdObject2Nr);
return false;
}
@@ -894,7 +918,7 @@ void ScummEngine_v0::o_setOwnerOf() {
owner = getVarOrDirectByte(PARAM_2);
if (obj == 0)
- obj = _activeObjectNr;
+ obj = _cmdObjectNr;
// FIXME: the original interpreter seems to set the owner of
// an item to remove (new owner 0) to 13 (purple tentacle).
@@ -909,21 +933,11 @@ void ScummEngine_v0::o_setOwnerOf() {
void ScummEngine_v0::resetSentence(bool walking) {
_activeVerb = kVerbWalkTo;
-
- // If the actor is walking, or the screen is a keypad (no sentence verbs/objects are drawn)
- // Then reset all active objects (stops the radio crash, bug #3077966)
- if (!walking || !(_userState & 32)) {
- _activeObjectNr = 0;
- _activeObjectType = kObjectTypeBG;
- _activeObject2Nr = 0;
- _activeObject2Type = kObjectTypeBG;
- }
-
- _verbExecuting = false;
- _verbPickup = false;
-
- _activeObjectObtained = false;
- _activeObject2Obtained = false;
+ _activeObjectNr = 0;
+ _activeObjectType = kObjectTypeBG;
+ _activeObject2Nr = 0;
+ _activeObject2Type = kObjectTypeBG;
+ _walkToObjectIdx = 0;
}
} // End of namespace Scumm
diff --git a/engines/scumm/script_v2.cpp b/engines/scumm/script_v2.cpp
index 1ea3257c17..6f6138d411 100644
--- a/engines/scumm/script_v2.cpp
+++ b/engines/scumm/script_v2.cpp
@@ -1219,20 +1219,23 @@ void ScummEngine_v2::o2_panCameraTo() {
panCameraTo(getVarOrDirectByte(PARAM_1) * V12_X_MULTIPLIER, 0);
}
-void ScummEngine_v2::o2_walkActorToObject() {
- int obj;
- Actor *a;
+void ScummEngine_v2::walkActorToObject(int actor, int obj) {
+ int x, y, dir;
+ getObjectXYPos(obj, x, y, dir);
- a = derefActor(getVarOrDirectByte(PARAM_1), "o2_walkActorToObject");
- obj = getVarOrDirectWord(PARAM_2);
- if (whereIsObject(obj) != WIO_NOT_FOUND) {
- int x, y, dir;
- getObjectXYPos(obj, x, y, dir);
- AdjustBoxResult r = a->adjustXYToBeInBox(x, y);
- x = r.x;
- y = r.y;
+ Actor *a = derefActor(actor, "walkActorToObject");
+ AdjustBoxResult r = a->adjustXYToBeInBox(x, y);
+ x = r.x;
+ y = r.y;
+
+ a->startWalkActor(x, y, dir);
+}
- a->startWalkActor(x, y, dir);
+void ScummEngine_v2::o2_walkActorToObject() {
+ int actor = getVarOrDirectByte(PARAM_1);
+ int obj = getVarOrDirectWord(PARAM_2);
+ if (whereIsObject(obj) != WIO_NOT_FOUND) {
+ walkActorToObject(actor, obj);
}
}
diff --git a/engines/scumm/script_v5.cpp b/engines/scumm/script_v5.cpp
index 6426b75e1e..1d68e86942 100644
--- a/engines/scumm/script_v5.cpp
+++ b/engines/scumm/script_v5.cpp
@@ -2464,8 +2464,43 @@ void ScummEngine_v5::o5_walkActorTo() {
a->startWalkActor(x, y, -1);
}
+void ScummEngine_v5::walkActorToActor(int actor, int toActor, int dist) {
+ Actor *a = derefActor(actor, "walkActorToActor");
+ Actor *to = derefActor(toActor, "walkActorToActor(2)");
+
+ if (_game.version <= 2) {
+ dist *= V12_X_MULTIPLIER;
+ } else if (dist == 0xFF) {
+ dist = a->_scalex * a->_width / 0xFF;
+ dist += (to->_scalex * to->_width / 0xFF) / 2;
+ }
+ int x = to->getPos().x;
+ int y = to->getPos().y;
+ if (x < a->getPos().x)
+ x += dist;
+ else
+ x -= dist;
+
+ if (_game.version <= 2) {
+ x /= V12_X_MULTIPLIER;
+ y /= V12_Y_MULTIPLIER;
+ }
+ if (_game.version <= 3) {
+ AdjustBoxResult abr = a->adjustXYToBeInBox(x, y);
+ x = abr.x;
+ y = abr.y;
+ }
+ a->startWalkActor(x, y, -1);
+
+ // WORKAROUND: See bug #2971126 for details on why this is here.
+ if (_game.version == 0) {
+ // FIXME(TOBIAS): is this still needed?
+ // (updateScriptPtr/_currentScript might now be called automatically)
+ o5_breakHere();
+ }
+}
+
void ScummEngine_v5::o5_walkActorToActor() {
- int x, y;
Actor *a, *a2;
int nr = getVarOrDirectByte(PARAM_1);
int nr2 = getVarOrDirectByte(PARAM_2);
@@ -2499,33 +2534,7 @@ void ScummEngine_v5::o5_walkActorToActor() {
if (!a2->isInCurrentRoom())
return;
- if (_game.version <= 2) {
- dist *= V12_X_MULTIPLIER;
- } else if (dist == 0xFF) {
- dist = a->_scalex * a->_width / 0xFF;
- dist += (a2->_scalex * a2->_width / 0xFF) / 2;
- }
- x = a2->getPos().x;
- y = a2->getPos().y;
- if (x < a->getPos().x)
- x += dist;
- else
- x -= dist;
-
- if (_game.version <= 2) {
- x /= V12_X_MULTIPLIER;
- y /= V12_Y_MULTIPLIER;
- }
- if (_game.version <= 3) {
- AdjustBoxResult abr = a->adjustXYToBeInBox(x, y);
- x = abr.x;
- y = abr.y;
- }
- a->startWalkActor(x, y, -1);
-
- // WORKAROUND: See bug #2971126 for details on why this is here.
- if (_game.version == 0)
- o5_breakHere();
+ walkActorToActor(nr, nr2, dist);
}
void ScummEngine_v5::o5_walkActorToObject() {
diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp
index 8b2e2ef88e..e6ec2b0dab 100644
--- a/engines/scumm/scumm.cpp
+++ b/engines/scumm/scumm.cpp
@@ -712,17 +712,19 @@ ScummEngine_v2::ScummEngine_v2(OSystem *syst, const DetectorResult &dr)
ScummEngine_v0::ScummEngine_v0(OSystem *syst, const DetectorResult &dr)
: ScummEngine_v2(syst, dr) {
- _verbExecuting = false;
- _verbPickup = false;
_currentMode = 0;
_activeVerb = kVerbNone;
_activeObjectNr = 0;
+ _activeObjectType = 0;
_activeObject2Nr = 0;
- _activeObjectType = kObjectTypeBG;
- _activeObject2Type = kObjectTypeBG;
- _activeObjectObtained = false;
- _activeObject2Obtained = false;
+ _activeObject2Type = 0;
+
+ _cmdVerb = kVerbNone;
+ _cmdObjectNr = 0;
+ _cmdObjectType = 0;
+ _cmdObject2Nr = 0;
+ _cmdObject2Type = 0;
VAR_ACTIVE_ACTOR = 0xFF;
VAR_IS_SOUND_RUNNING = 0xFF;
diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h
index f004176da1..fadc3902c0 100644
--- a/engines/scumm/scumm.h
+++ b/engines/scumm/scumm.h
@@ -642,7 +642,7 @@ protected:
void updateScriptPtr();
virtual void runInventoryScript(int i);
void inventoryScriptIndy3Mac();
- void checkAndRunSentenceScript();
+ virtual void checkAndRunSentenceScript();
void runExitScript();
void runEntryScript();
void runAllScripts();
diff --git a/engines/scumm/scumm_v0.h b/engines/scumm/scumm_v0.h
index 9b38b108e2..031a73acf9 100644
--- a/engines/scumm/scumm_v0.h
+++ b/engines/scumm/scumm_v0.h
@@ -54,8 +54,6 @@ protected:
protected:
byte _currentMode;
- bool _verbExecuting; // is a verb executing
- bool _verbPickup; // are we picking up an object during a verb execute
int _activeVerb;
int _activeObjectNr; // 1st Object Number
@@ -63,8 +61,14 @@ protected:
int _activeObject2Nr; // 2nd Object Number
int _activeObject2Type; // 2nd Object Type (0: inventory (or room), 1: room, 2: actor)
- bool _activeObjectObtained; // collected _activeobject?
- bool _activeObject2Obtained; // collected _activeObject2?
+ int _cmdVerb;
+ int _cmdObjectNr;
+ int _cmdObjectType;
+ int _cmdObject2Nr;
+ int _cmdObject2Type;
+
+ int _walkToObject;
+ int _walkToObjectIdx;
public:
ScummEngine_v0(OSystem *syst, const DetectorResult &dr);
@@ -83,17 +87,16 @@ protected:
virtual void processInput();
- virtual void runObject(int obj, int entry);
virtual void saveOrLoad(Serializer *s);
// V0 MM Verb commands
int getVerbPrepId();
int activeVerbPrep();
- bool verbMove(int object);
- bool verbMoveToActor(int actor);
- bool verbObtain(int object);
- bool verbExec();
+ void walkToActorOrObject(int object);
+ void verbExec();
+ virtual void runSentenceScript();
+ virtual void checkAndRunSentenceScript();
virtual void checkExecVerbs();
virtual void handleMouseOver(bool updateInventory);
int verbPrepIdType(int verbid);
@@ -138,6 +141,7 @@ protected:
void o_unlockScript();
void o_decrement();
void o_nop();
+ void o_getObjectOwner();
void o_getActorBitVar();
void o_setActorBitVar();
void o_getBitVar();
diff --git a/engines/scumm/scumm_v2.h b/engines/scumm/scumm_v2.h
index b9cd8a3921..b407fd3f8a 100644
--- a/engines/scumm/scumm_v2.h
+++ b/engines/scumm/scumm_v2.h
@@ -99,7 +99,7 @@ protected:
void drawPreposition(int index);
- virtual void setActiveInventory(int object);
+ void walkActorToObject(int actor, int obj);
/* Version 2 script opcodes */
void o2_actorFromPos();
diff --git a/engines/scumm/scumm_v5.h b/engines/scumm/scumm_v5.h
index b8a61c1677..0eef04b8de 100644
--- a/engines/scumm/scumm_v5.h
+++ b/engines/scumm/scumm_v5.h
@@ -87,6 +87,8 @@ protected:
void drawFlashlight();
+ void walkActorToActor(int actor, int toActor, int dist);
+
/**
* Fetch the next script word, then if cond is *false*, perform a relative jump.
* So this corresponds to a "jne" jump instruction.
diff --git a/engines/scumm/verbs.cpp b/engines/scumm/verbs.cpp
index 016248c530..376e075daa 100644
--- a/engines/scumm/verbs.cpp
+++ b/engines/scumm/verbs.cpp
@@ -366,10 +366,6 @@ void ScummEngine_v2::checkV2MouseOver(Common::Point pos) {
}
}
-void ScummEngine_v2::setActiveInventory(int object) {
- runInputScript(kInventoryClickArea, object, 0);
-}
-
int ScummEngine_v2::checkV2Inventory(int x, int y) {
int inventoryArea = (_game.platform == Common::kPlatformNES) ? 48: 32;
int object = 0;
@@ -717,142 +713,6 @@ void ScummEngine_v2::checkExecVerbs() {
}
}
-void ScummEngine_v0::runObject(int obj, int entry) {
- if (getVerbEntrypoint(obj, entry) == 0) {
- // If nothing was found, attempt to find the 'WHAT-IS' verb script
- // (which is not really the what-is script, as this verb never actually executes
- // it merely seems to be some type of fallback)
- if (getVerbEntrypoint(obj, 0x0F) != 0) {
- entry = 0x0F;
- }
- }
-
- if (getVerbEntrypoint(obj, entry) != 0) {
- runObjectScript(obj, entry, false, false, NULL);
- } else if (entry != 13 && entry != 15) {
- if (_activeVerb == kVerbGive) {
- // For some reasons, certain objects don't have a "give" script
- if (VAR(VAR_ACTIVE_ACTOR) > 0 && VAR(VAR_ACTIVE_ACTOR) < 8) {
- if (OBJECT_V0_TYPE(obj) == kObjectTypeFG) {
- assert(false);
- setOwnerOf(obj, VAR(VAR_ACTIVE_ACTOR));
- }
- }
- } else {
- VAR(VAR_ACTIVE_VERB) = entry;
- runScript(3, 0, 0, 0);
- }
- }
-}
-
-bool ScummEngine_v0::verbMoveToActor(int actor) {
- Actor *a = derefActor(VAR(VAR_EGO), "verbMoveToActor");
- Actor *a2 = derefActor(actor, "verbMoveToActor");
- int dist = getDist(a->getRealPos().x, a->getRealPos().y, a2->getRealPos().x, a2->getRealPos().y);
-
- if (!a->_moving && dist > 4) {
- a->startWalkActor(a2->getRealPos().x, a2->getRealPos().y, -1);
- } else {
- if (dist <= 4) {
- a->stopActorMoving();
- return false;
- }
- }
-
- return true;
-}
-
-bool ScummEngine_v0::verbMove(int object) {
- int x, y, dir;
- Actor *a = derefActor(VAR(VAR_EGO), "verbMove");
-
- if (_currentMode != kModeNormal && _currentMode != kModeNoNewKid)
- return false;
-
- getObjectXYPos(object, x, y, dir);
-
- // Detect distance from target object
- int dist = getDist(a->getRealPos().x, a->getRealPos().y, x, y);
-
- if (a->_moving)
- return true;
-
- if (dist > 5) {
- a->startWalkActor(x, y, dir);
- VAR(6) = x;
- VAR(7) = y;
- return true;
- } else {
- // Finished walk, are we picking up the item?
- if (_verbPickup) {
- int oldActive = OBJECT_V0(_activeObjectNr, _activeObjectType);
-
- _activeObjectNr = OBJECT_V0_NR(object);
- _activeObjectType = OBJECT_V0_TYPE(object);
-
- // Execute pickup
- runObject(object, 14);
-
- _activeObjectNr = OBJECT_V0_NR(oldActive);
- _activeObjectType = OBJECT_V0_TYPE(oldActive);
-
- // Finished picking up
- _verbPickup = false;
- }
- }
-
- return false;
-}
-
-bool ScummEngine_v0::verbObtain(int obj) {
- bool didPickup = false;
- int prep;
- int where;
-
- if (!obj)
- return false;
-
- where = whereIsObject(obj);
-
- // Object in inventory ?
- if (where != WIO_INVENTORY) {
- prep = activeVerbPrep();
-
- if (prep == kVerbPrepIn || prep == kVerbPrepTo) {
- if (_activeVerb != kVerbWalkTo && _activeVerb != kVerbPickUp) {
- _verbPickup = true;
- didPickup = true;
- }
- } else {
- _verbPickup = false;
- }
-
- // Ignore verbs?
- ActorC64 *a = (ActorC64 *)derefActor(VAR(VAR_EGO), "verbObtain");
- if (a->_miscflags & kActorMiscFlagFreeze) {
- resetSentence(false);
- return false;
- }
-
- //attempt move to object
- if (verbMove(obj))
- return true;
-
- if (didPickup && (prep == kVerbPrepIn || prep == kVerbPrepTo))
- if (_activeVerb != kVerbWalkTo && _activeVerb != kVerbPickUp) {
-// TODO(TOBIAS)
-#if 0
- if (whereIsObject(obj) == WIO_INVENTORY)
- _activeInventory = obj;
- else
- resetSentence(false);
-#endif
- }
- }
-
- return false;
-}
-
int ScummEngine_v0::getVerbPrepId() {
if (_verbs[_activeVerb].prep != 0xFF) {
return _verbs[_activeVerb].prep;
@@ -869,150 +729,44 @@ int ScummEngine_v0::activeVerbPrep() {
return getVerbPrepId();
}
-bool ScummEngine_v0::verbExec() {
- int entry = (_currentMode != kModeCutscene && _currentMode != kModeKeypad) ? _activeVerb : kVerbWhatIs;
-
- if (_activeObjectNr && getObjectIndex(OBJECT_V0(_activeObjectNr, _activeObjectType)) == -1) {
- resetSentence(false);
- return false;
- }
-
- // Lets try walk to the object
- if (_activeObjectNr && !_activeObjectObtained && _currentMode != kModeCutscene) {
- if (verbObtain(OBJECT_V0(_activeObjectNr, _activeObjectType)))
- return true;
-
- _activeObjectObtained = true;
- }
-
- // Attempt to obtain/reach object2
- if (_activeObject2Nr && !_activeObject2Obtained && _currentMode != kModeCutscene) {
- if (verbObtain(OBJECT_V0(_activeObject2Nr, _activeObject2Type)))
- return true;
-
- _activeObject2Obtained = true;
- }
-
- // Give-To
- if (_activeVerb == kVerbGive && _activeObjectNr && _activeObject2Nr && _activeObject2Type == kObjectTypeActor) {
- // FIXME: Actors need to turn and face each other
- if (verbMoveToActor(_activeObject2Nr)) {
- // Ignore verbs?
- Actor *a = derefActor(VAR(VAR_EGO), "verbExec");
- if (((ActorC64 *)a)->_miscflags & kActorMiscFlagFreeze) {
- resetSentence(false);
- return false;
- }
-
- return true;
- }
- VAR(VAR_ACTIVE_ACTOR) = _activeObject2Nr;
- runObject(OBJECT_V0(_activeObjectNr, _activeObjectType), 3);
-
- resetSentence(false);
- return false;
- }
-
- // Where we performing an action on an actor?
- if (_activeObject2Nr && _activeObject2Type == kObjectTypeActor) {
- runObject(OBJECT_V0(_activeObject2Nr, _activeObject2Type), entry);
- _verbExecuting = false;
-
- resetSentence(false);
- return false;
- }
-
- // If we've finished walking (now near target), execute the action
- if (_activeObjectNr && activeVerbPrep() == kVerbPrepWith) {
- runObject(OBJECT_V0(_activeObjectNr, _activeObjectType), entry);
- _verbExecuting = false;
-
- if ((_currentMode == kModeNormal || _currentMode == kModeNoNewKid) && _activeVerb == kVerbWalkTo)
- return false;
-
- resetSentence(false);
- return false;
- }
-
- // We acted on an inventory item
- if (_activeVerb != kVerbGive) {
- runObject(OBJECT_V0(_activeObjectNr/*2*/, _activeObjectType/*2*/), _activeVerb);
-
- _verbExecuting = false;
-
- if (_currentMode == kModeNormal && _activeVerb == kVerbWalkTo) {
- resetSentence(true);
- return false;
+void ScummEngine_v0::verbExec() {
+ if (_activeVerb == kVerbWhatIs)
+ return;
+
+ if (_activeVerb != kVerbWalkTo || _activeObjectNr != 0) {
+ doSentence(_activeVerb,
+ OBJECT_V0(_activeObjectNr, _activeObjectType),
+ OBJECT_V0(_activeObject2Nr, _activeObject2Type));
+ if (_activeVerb != kVerbWalkTo) {
+ _activeVerb = kVerbWalkTo;
+ _activeObjectNr = 0;
}
-
- resetSentence(false);
- return false;
- }
-
- if (_activeObjectNr) {
- runObject(OBJECT_V0(_activeObjectNr, _activeObjectType), entry);
- }
-
- _verbExecuting = false;
-
- if (_activeVerb == kVerbWalkTo) {
- resetSentence(true);
- return false;
+ _walkToObjectIdx = 0;
+ return;
}
- resetSentence(false);
+ ActorC64 *a = (ActorC64 *)derefActor(VAR(VAR_EGO), "verbExec");
+ int x = _virtualMouse.x / V12_X_MULTIPLIER;
+ int y = _virtualMouse.y / V12_Y_MULTIPLIER;
+ //actorSetPosInBox();
- return false;
-}
+ // 0xB31
+ VAR(6) = x;
+ VAR(7) = y;
-#if 0
-verbExec() {
- cmdStackMaxLeft = 6;
- cmdStackPos = 0xFF;
- if (verbSelectedID == 15) // WHAT IS
- return;
-
- if (verbSelectedID != 13 || objectSelectedID != 0) {
- cmdStackPos++;
- cmdVerbID[cmdStackPos] = verbSelectedID;
- cmdObjectID[cmdStackPos] = objectSelectedID;
- cmdObjectType[cmdStackPos] = objectSelectedType;
- cmdVerbPrepID[cmdStackPos] = verbPrepID;
- cmdObject2ID[cmdStackPos] = objectSelected2ID;
- cmdObject2Type[cmdStackPos] = objectSelected2Type;
-
- if (verbSelectedID != 13) { // WALK TO
- verbSelectedID = 13;
- objectSelectedID = 0;
- verbPrepID = 0;
- }
- scriptUpdateSkip = 0;
+ if (a->_miscflags & kActorMiscFlagFreeze)
return;
- }
-
- currentActor = scriptVARS[0];
- roomActor = gActorInRoom[currentActor];
- tmpX = cursorX();
- tmpY = cursorY();
- actorSetPosInBox();
-
- scriptVARS[6] = tmpX;
- scriptVARS[7] = tmpY;
-
- if (gActor_miscFlags[scriptVARS[0]] & 0x40) {
- rActor_scriptWalkToX[roomActor] = tmpX;
- rActor_scriptWalkToX[roomActor] = tmpY;
- walk_1C4A();
- }
+
+ a->stopActorMoving();
+ a->startWalkActor(VAR(6), VAR(7), -1);
}
-#endif
void ScummEngine_v0::checkExecVerbs() {
ActorC64 *a = (ActorC64 *)derefActor(VAR(VAR_EGO), "checkExecVerbs");
VirtScreen *zone = findVirtScreen(_mouse.y);
- int scriptUpdateSkip;
int sentenceLineChanged = false;
+ bool execute = false;
/*
if (_userPut <= 0 || _mouseAndKeyboardStat == 0)
@@ -1024,7 +778,6 @@ void ScummEngine_v0::checkExecVerbs() {
int over = findVerbAtPos(_mouse.x, _mouse.y);
if (over && _activeVerb != over) {
_activeVerb = over;
- //_activeVerbPrep = 0;
_activeObjectNr = 0;
_activeObjectType = 0;
_activeObject2Nr = 0;
@@ -1045,7 +798,7 @@ void ScummEngine_v0::checkExecVerbs() {
}
if (_mouseAndKeyboardStat < MBS_MAX_KEY) {
- // TODO: Check keypresses
+ // TODO: check keypresses
} else if ((_mouseAndKeyboardStat & MBS_MOUSE_MASK) || _activeVerb == kVerbWhatIs) {
if (zone->number == kVerbVirtScreen && _mouse.y <= zone->topline + 8) {
// TODO: handle click into sentence line
@@ -1081,130 +834,61 @@ void ScummEngine_v0::checkExecVerbs() {
_activeObject2Type = 0;
}
} else {
- //_activeVerbPrep:
- // 0: no activeObject or activeObject but no prep
- // > 0: activeObject + prep
if (activeVerbPrep() == kVerbPrepNone) {
if (id == _activeObjectNr && type == _activeObjectType) {
- _verbExecuting = true;
+ execute = true;
} else {
_activeObjectNr = id;
_activeObjectType = type;
}
- //sentenceLineChanged = true;
if (_currentMode == kModeKeypad)
- _verbExecuting = true;
+ execute = true;
} else {
if (id == _activeObject2Nr && type == _activeObject2Type)
- _verbExecuting = true;
+ execute = true;
if (!(id == _activeObjectNr && type == _activeObjectType)) {
_activeObject2Nr = id;
_activeObject2Type = type;
if (_currentMode == kModeKeypad)
- _verbExecuting = true;
+ execute = true;
}
}
}
sentenceLineChanged = true;
- if (_activeVerb == kVerbWalkTo) {
- scriptUpdateSkip = 0;
- _verbExecuting = true;
+ if (_activeVerb == kVerbWalkTo && zone->number == kMainVirtScreen) {
+ _walkToObjectIdx = 0;
+ execute = true;
}
}
}
}
- if (sentenceLineChanged)
+ if (sentenceLineChanged) {
drawSentence();
+ sentenceLineChanged = false;
+ }
+
+ if (!execute || !_activeVerb)
+ return;
if (_activeVerb == kVerbNewKid) {
- // TODO
if (_currentMode == kModeNormal) {
- // get kid
+ // TODO: get clicked kid
_activeVerb = kVerbWalkTo;
- resetSentence(false);
+ drawSentence();
//switchActor(_verbs[over].verbid - 1);
}
_activeVerb = kVerbWalkTo;
}
- if (_activeVerb == kVerbWalkTo) {
- //exec();
- }
-
- /*
- if (_activeVerbPrep == 0) {
- int prep = activeVerbPrep();
- if (prep == kVerbPrepNone)
- ; //exec();
- else {
- _activeVerbPrep = prep;
- ; // draw()
- }
- } else {
- if (_activeObject2 == 0)
- ; //drawSentence();
- else
- ; // exec();
+ if (_activeVerb == kVerbWalkTo)
+ verbExec();
+ else if (_activeObjectNr) {
+ // execute if we have a 1st object and either have or do not need a 2nd
+ if (activeVerbPrep() == kVerbPrepNone || _activeObject2Nr)
+ verbExec();
}
- */
-
-#if 0
- // Is a verb currently executing
- if (_verbExecuting) {
- // Check if mouse click
- if (_mouseAndKeyboardStat & MBS_MOUSE_MASK) {
- int over = findVerbAtPos(_mouse.x, _mouse.y);
- int act = getActorFromPos(_virtualMouse.x, _virtualMouse.y);
- byte type;
- int obj = findObject(_virtualMouse.x, _virtualMouse.y, &type);
-
- if (over && over != _activeVerb) {
- _activeVerb = over;
- _verbExecuting = false;
- return;
- }
-
- if (!obj && !act && !over) {
- resetSentence(false);
- } else {
- a->stopActorMoving();
- }
- } else {
-
- if (_verbExecuting && !verbExec())
- return;
- }
- }
-
- ...
-
- // Clicked on nothing, walk here?
- if (!over && !act && _activeVerb == kVerbWalkTo && !obj && _currentMode != kMode_0) {
- // Clear all selected
- resetSentence(false);
-
- // 0xB31
- VAR(6) = _virtualMouse.x / V12_X_MULTIPLIER;
- VAR(7) = _virtualMouse.y / V12_Y_MULTIPLIER;
-
- if (zone->number == kMainVirtScreen) {
- // Ignore verbs?
- if (a->_miscflags & kActorMiscFlagFreeze) {
- resetSentence(false);
- return;
- }
- a->stopActorMoving();
- a->startWalkActor(VAR(6), VAR(7), -1);
- _verbExecuting = true;
- }
- return;
- }
- _verbExecuting = true;
-
- } // mouse k/b action
-#endif
}
void ScummEngine::verbMouseOver(int verb) {