aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTobias Gunkel2012-01-07 16:08:55 +0100
committerTobias Gunkel2012-02-11 08:28:14 +0100
commit1c32000a004cc184a8744e2467035a4c7ba2f3a5 (patch)
tree0be70cec22cace4d981817558ce15534f308c25c
parentc69a52853ccc42f3891ce4212fa281dbea65c3ea (diff)
downloadscummvm-rg350-1c32000a004cc184a8744e2467035a4c7ba2f3a5.tar.gz
scummvm-rg350-1c32000a004cc184a8744e2467035a4c7ba2f3a5.tar.bz2
scummvm-rg350-1c32000a004cc184a8744e2467035a4c7ba2f3a5.zip
SCUMM: start handling object type and id correctly in mm c64
- removed complicated and unnecessary _v0ObjectIndex, _v0ObjectInInventory, _v0ObjectFlag vars - started to merge object id and type into one object value (type<<8|id) - verb preposition ids do not dependent on language -> remove from VerbSettings Note: - objects with type=0 are foreground objects. They have a state, an owner and a bg overlay image. - objects with type=1 are bg objects. They do not have a state or owner and are already contained in the bg image. The do not have an entry in objectState/OwnerTable
-rw-r--r--engines/scumm/object.cpp74
-rw-r--r--engines/scumm/object.h8
-rw-r--r--engines/scumm/script.cpp2
-rw-r--r--engines/scumm/script_v0.cpp65
-rw-r--r--engines/scumm/script_v2.cpp2
-rw-r--r--engines/scumm/scumm.cpp11
-rw-r--r--engines/scumm/scumm.h7
-rw-r--r--engines/scumm/scumm_v0.h29
-rw-r--r--engines/scumm/verbs.cpp542
9 files changed, 360 insertions, 380 deletions
diff --git a/engines/scumm/object.cpp b/engines/scumm/object.cpp
index a9e2a76345..53dc0151d9 100644
--- a/engines/scumm/object.cpp
+++ b/engines/scumm/object.cpp
@@ -178,10 +178,7 @@ void ScummEngine::clearOwnerOf(int obj) {
// Alternatively, scan the inventory to see if the object is in there...
for (i = 0; i < _numInventory; i++) {
if (_inventory[i] == obj) {
- if (_game.version == 0)
- assert(WIO_INVENTORY == whereIsObjectInventory(obj));
- else
- assert(WIO_INVENTORY == whereIsObject(obj));
+ assert(WIO_INVENTORY == whereIsObject(obj));
// Found the object! Nuke it from the inventory.
_res->nukeResource(rtInventory, i);
@@ -310,52 +307,50 @@ int ScummEngine::getObjectRoom(int obj) const {
int ScummEngine::getObjectIndex(int object) const {
int i;
+ int nr = (_game.version != 0) ? object : OBJECT_V0_NR(object);
- if (object < 1)
+ if (nr < 1)
return -1;
for (i = (_numLocalObjects-1); i > 0; i--) {
- if (_game.version == 0 )
- if( _objs[i].obj_type != _v0ObjectFlag )
- continue;
+ if (_game.version == 0 && _objs[i].obj_type != OBJECT_V0_TYPE(object))
+ continue;
- if (_objs[i].obj_nr == object)
+ if (_objs[i].obj_nr == nr)
return i;
}
return -1;
}
-int ScummEngine::whereIsObjectInventory(int object) {
- int res = 0;
- _v0ObjectInInventory = true;
- res = whereIsObject(object);
- _v0ObjectInInventory = false;
-
- return res;
-}
-
int ScummEngine::whereIsObject(int object) const {
int i;
- if (object >= _numGlobalObjects)
+ // Note: in MMC64 bg objects are greater _numGlobalObjects
+ if (_game.version != 0 && object >= _numGlobalObjects)
return WIO_NOT_FOUND;
if (object < 1)
return WIO_NOT_FOUND;
- if ((_objectOwnerTable[object] != OF_OWNER_ROOM && _game.version != 0) || _v0ObjectInInventory) {
+ if ((_game.version != 0 || OBJECT_V0_TYPE(object) == 0) &&
+ _objectOwnerTable[object] != OF_OWNER_ROOM)
+ {
for (i = 0; i < _numInventory; i++)
if (_inventory[i] == object)
return WIO_INVENTORY;
return WIO_NOT_FOUND;
}
- for (i = (_numLocalObjects-1); i > 0; i--)
- if ((_objs[i].obj_nr == object && !_v0ObjectIndex) || (_v0ObjectIndex && i == object)) {
+ for (i = (_numLocalObjects-1); i > 0; i--) {
+ int nr = (_game.version != 0) ? object : OBJECT_V0_NR(object);
+ if (_objs[i].obj_nr == nr) {
+ if (_game.version == 0 && _objs[i].obj_type != OBJECT_V0_TYPE(object))
+ continue;
if (_objs[i].fl_object_index)
return WIO_FLOBJECT;
return WIO_ROOM;
}
+ }
return WIO_NOT_FOUND;
}
@@ -396,7 +391,7 @@ int ScummEngine::getObjectOrActorXY(int object, int &x, int &y) {
* Returns X, Y and direction in angles
*/
void ScummEngine::getObjectXYPos(int object, int &x, int &y, int &dir) {
- int idx = (_v0ObjectIndex) ? object : getObjectIndex(object);
+ int idx = getObjectIndex(object);
assert(idx >= 0);
ObjectData &od = _objs[idx];
int state;
@@ -497,6 +492,7 @@ int ScummEngine::findObject(int x, int y) {
byte a;
const int mask = (_game.version <= 2) ? kObjectState_08 : 0xF;
+ // FIXME(TOBIAS): <= _numLocalObjects?
for (i = 1; i < _numLocalObjects; i++) {
if ((_objs[i].obj_nr < 1) || getClass(_objs[i].obj_nr, kObjectClassUntouchable))
continue;
@@ -522,11 +518,8 @@ int ScummEngine::findObject(int x, int y) {
#endif
if (_objs[i].x_pos <= x && _objs[i].width + _objs[i].x_pos > x &&
_objs[i].y_pos <= y && _objs[i].height + _objs[i].y_pos > y) {
- // MMC64: Set the object search flag
if (_game.version == 0)
- _v0ObjectFlag = _objs[i].obj_type;
- if (_game.version == 0 && _v0ObjectIndex)
- return i;
+ return OBJECT_V0(_objs[i].obj_nr, _objs[i].obj_type);
else
return _objs[i].obj_nr;
}
@@ -1165,7 +1158,7 @@ const byte *ScummEngine::getObjOrActorName(int obj) {
}
}
- objptr = getOBCDFromObject(obj);
+ objptr = getOBCDFromObject(obj, true);
if (objptr == NULL)
return NULL;
@@ -1218,15 +1211,14 @@ void ScummEngine::setObjectName(int obj) {
uint32 ScummEngine::getOBCDOffs(int object) const {
int i;
- if ((_objectOwnerTable[object] != OF_OWNER_ROOM && (_game.version != 0)) || _v0ObjectInInventory)
+ if ((_game.version != 0 || OBJECT_V0_TYPE(object) == 0) &&
+ _objectOwnerTable[object] != OF_OWNER_ROOM)
return 0;
- // V0 MM Return by Index
- if (_v0ObjectIndex)
- return _objs[object].OBCDoffset;
-
for (i = (_numLocalObjects-1); i > 0; i--) {
if (_objs[i].obj_nr == object) {
+ if (_game.version == 0 && _objs[i].obj_type != OBJECT_V0_TYPE(object))
+ continue;
if (_objs[i].fl_object_index != 0)
return 8;
return _objs[i].OBCDoffset;
@@ -1235,21 +1227,25 @@ uint32 ScummEngine::getOBCDOffs(int object) const {
return 0;
}
-byte *ScummEngine::getOBCDFromObject(int obj) {
- bool useInventory = _v0ObjectInInventory;
+byte *ScummEngine::getOBCDFromObject(int obj, bool v0CheckInventory) {
int i;
byte *ptr;
- _v0ObjectInInventory = false;
-
- if ((_objectOwnerTable[obj] != OF_OWNER_ROOM && (_game.version != 0)) || useInventory) {
+ if ((_game.version != 0 || OBJECT_V0_TYPE(obj) == 0) &&
+ _objectOwnerTable[obj] != OF_OWNER_ROOM)
+ {
+ if (_game.version == 0 && !v0CheckInventory)
+ return 0;
for (i = 0; i < _numInventory; i++) {
if (_inventory[i] == obj)
return getResourceAddress(rtInventory, i);
}
} else {
for (i = (_numLocalObjects-1); i > 0; --i) {
- if ((_objs[i].obj_nr == obj && !_v0ObjectIndex) || (_v0ObjectIndex && i == obj)) {
+ int nr = (_game.version != 0) ? obj : OBJECT_V0_NR(obj);
+ if (_objs[i].obj_nr == nr) {
+ if (_game.version == 0 && _objs[i].obj_type != OBJECT_V0_TYPE(obj))
+ continue;
if (_objs[i].fl_object_index) {
assert(_objs[i].OBCDoffset == 8);
ptr = getResourceAddress(rtFlObject, _objs[i].fl_object_index);
diff --git a/engines/scumm/object.h b/engines/scumm/object.h
index edbff38355..7e4a5b57ab 100644
--- a/engines/scumm/object.h
+++ b/engines/scumm/object.h
@@ -24,6 +24,14 @@
namespace Scumm {
+static inline int OBJECT_V0(int id, byte type) {
+ assert(id < 255);
+ return (type << 8 | id);
+}
+#define OBJECT_V0_NR(obj) (obj & 0xFF)
+#define OBJECT_V0_TYPE(obj) ((obj >> 8) & 0xFF)
+
+
enum ObjectClass {
kObjectClassNeverClip = 20,
kObjectClassAlwaysClip = 21,
diff --git a/engines/scumm/script.cpp b/engines/scumm/script.cpp
index 37ea3a9a9f..d04c3c0891 100644
--- a/engines/scumm/script.cpp
+++ b/engines/scumm/script.cpp
@@ -131,8 +131,6 @@ void ScummEngine::runObjectScript(int object, int entry, bool freezeResistant, b
initializeLocals(slot, vars);
- // V0 Ensure we don't try and access objects via index inside the script
- _v0ObjectIndex = false;
runScriptNested(slot);
}
diff --git a/engines/scumm/script_v0.cpp b/engines/scumm/script_v0.cpp
index 2bbde617ad..14df89b28d 100644
--- a/engines/scumm/script_v0.cpp
+++ b/engines/scumm/script_v0.cpp
@@ -365,7 +365,7 @@ uint ScummEngine_v0::fetchScriptWord() {
int ScummEngine_v0::getActiveObject() {
if (_opcode & PARAM_2)
- return _activeObject;
+ return _activeObjectNr;
return fetchScriptByte();
}
@@ -406,22 +406,9 @@ void ScummEngine_v0::decodeParseString() {
actorTalk(buffer);
}
-const byte *ScummEngine_v0::getObjectName(int object, int type) {
- const byte *temp;
-
- if (type == kObjectTypeInventory)
- _v0ObjectInInventory = true;
-
- temp = getObjOrActorName(object);
-
- _v0ObjectInInventory = false;
-
- return temp;
-}
-
void ScummEngine_v0::drawSentenceObject(int object, int type) {
const byte *temp;
- temp = getObjectName(object, type);
+ temp = getObjOrActorName(OBJECT_V0(object, type));
if (temp) {
_sentenceBuf += " ";
_sentenceBuf += (const char *)temp;
@@ -443,25 +430,25 @@ void ScummEngine_v0::drawSentence() {
return;
}
- if (_activeObject) {
+ if (_activeObjectNr) {
// Draw the 1st active object
- drawSentenceObject(_activeObject, _activeObjectType);
+ drawSentenceObject(_activeObjectNr, _activeObjectType);
// Append verb preposition
- int sentencePrep = verbPrep();
+ int sentencePrep = activeVerbPrep();
if (sentencePrep) {
drawPreposition(sentencePrep);
// Draw the 2nd active object
- if (_activeObject2) {
+ if (_activeObject2Nr) {
// 2nd Object is an actor
if (_activeObject2Type == kObjectTypeActor) {
- Actor *a = derefActor(_activeObject2, "");
+ Actor *a = derefActor(_activeObject2Nr, "");
_sentenceBuf += " ";
_sentenceBuf += (const char *)a->getActorName();
// 2nd Object is an inventory or room object
} else {
- drawSentenceObject(_activeObject2, _activeObject2Type);
+ drawSentenceObject(_activeObject2Nr, _activeObject2Type);
}
}
}
@@ -705,26 +692,13 @@ void ScummEngine_v0::o_putActorAtObject() {
}
void ScummEngine_v0::o_pickupObject() {
- int obj = fetchScriptByte();
- if (obj == 0) {
- if (_activeObject) {
- obj = _activeObject;
- } else {
- // might happen if an inventory item was picked again
- return;
- }
- }
+ int objNr = fetchScriptByte();
+ int obj = OBJECT_V0((objNr ? objNr : _activeObjectNr), 0);
- if (obj < 1) {
- error("pickupObject received invalid index %d (script %d)", obj, vm.slot[_currentScript].number);
- }
-
- if (getObjectIndex(obj) == -1)
+ /* Don't take an object twice */
+ if (whereIsObject(obj) == WIO_INVENTORY)
return;
- if (whereIsObjectInventory(_activeObject2) == WIO_INVENTORY) /* Don't take an */
- return; /* object twice */
-
addObjectToInventory(obj, _roomResource);
markObjectRectAsDirty(obj);
putOwner(obj, VAR(VAR_EGO));
@@ -822,8 +796,8 @@ void ScummEngine_v0::o_doSentence() {
bool ScummEngine_v0::ifEqualActiveObject2Common(bool inventoryObject) {
byte obj = fetchScriptByte();
- if (!inventoryObject || (_activeObject2Type == kObjectTypeInventory))
- return (obj == _activeObject2);
+ if (!inventoryObject || (_activeObject2Type == kObjectTypeFG))
+ return (obj == _activeObject2Nr);
return false;
}
@@ -920,7 +894,7 @@ void ScummEngine_v0::o_setOwnerOf() {
owner = getVarOrDirectByte(PARAM_2);
if (obj == 0)
- obj = _activeObject;
+ obj = _activeObjectNr;
// FIXME: the original interpreter seems to set the owner of
// an item to remove (new owner 0) to 13 (purple tentacle).
@@ -939,16 +913,15 @@ void ScummEngine_v0::resetSentence(bool walking) {
// 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)) {
- _v0ObjectFlag = 0;
- _activeObject = 0;
- _activeObject2 = 0;
+ _activeObjectNr = 0;
+ _activeObjectType = kObjectTypeBG;
+ _activeObject2Nr = 0;
+ _activeObject2Type = kObjectTypeBG;
}
_verbExecuting = false;
_verbPickup = false;
- _activeObjectType = kObjectTypeRoom;
- _activeObject2Type = kObjectTypeRoom;
_activeObjectObtained = false;
_activeObject2Obtained = false;
}
diff --git a/engines/scumm/script_v2.cpp b/engines/scumm/script_v2.cpp
index 003bafa27e..1ea3257c17 100644
--- a/engines/scumm/script_v2.cpp
+++ b/engines/scumm/script_v2.cpp
@@ -1223,8 +1223,6 @@ void ScummEngine_v2::o2_walkActorToObject() {
int obj;
Actor *a;
- _v0ObjectFlag = 0;
-
a = derefActor(getVarOrDirectByte(PARAM_1), "o2_walkActorToObject");
obj = getVarOrDirectWord(PARAM_2);
if (whereIsObject(obj) != WIO_NOT_FOUND) {
diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp
index d3dc702395..423ad79b00 100644
--- a/engines/scumm/scumm.cpp
+++ b/engines/scumm/scumm.cpp
@@ -151,9 +151,6 @@ ScummEngine::ScummEngine(OSystem *syst, const DetectorResult &dr)
_fileHandle = 0;
// Init all vars
- _v0ObjectIndex = false;
- _v0ObjectInInventory = false;
- _v0ObjectFlag = 0;
_imuse = NULL;
_imuseDigital = NULL;
_musicEngine = NULL;
@@ -720,10 +717,10 @@ ScummEngine_v0::ScummEngine_v0(OSystem *syst, const DetectorResult &dr)
_currentMode = 0;
_activeVerb = 0;
- _activeObject = 0;
- _activeObject2 = 0;
- _activeObjectType = kObjectTypeRoom;
- _activeObject2Type = kObjectTypeRoom;
+ _activeObjectNr = 0;
+ _activeObject2Nr = 0;
+ _activeObjectType = kObjectTypeBG;
+ _activeObject2Type = kObjectTypeBG;
_activeObjectObtained = false;
_activeObject2Obtained = false;
diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h
index d9237b2b30..f004176da1 100644
--- a/engines/scumm/scumm.h
+++ b/engines/scumm/scumm.h
@@ -502,10 +502,6 @@ protected:
int32 *_scummVars;
byte *_bitVars;
- bool _v0ObjectIndex; // V0 Use object index, instead of object number
- bool _v0ObjectInInventory; // V0 Use object number from inventory
- byte _v0ObjectFlag;
-
/* Global resource tables */
int _numVariables, _numBitVariables, _numLocalObjects;
int _numGlobalObjects, _numArray, _numVerbs, _numFlObject;
@@ -799,7 +795,6 @@ protected:
int getObjNewDir(int obj);
int getObjectIndex(int object) const;
int getObjectImageCount(int object);
- int whereIsObjectInventory(int object);
int whereIsObject(int object) const;
int findObject(int x, int y);
void findObjectInRoom(FindObjectInRoom *fo, byte findWhat, uint object, uint room);
@@ -820,7 +815,7 @@ protected:
virtual void clearDrawQueues();
uint32 getOBCDOffs(int object) const;
- byte *getOBCDFromObject(int obj);
+ byte *getOBCDFromObject(int obj, bool v0CheckInventory = true);
const byte *getOBIMFromObjectData(const ObjectData &od);
const byte *getObjectImage(const byte *ptr, int state);
virtual int getObjectIdFromOBIM(const byte *obim);
diff --git a/engines/scumm/scumm_v0.h b/engines/scumm/scumm_v0.h
index d9629948fe..0bb4d1a4a9 100644
--- a/engines/scumm/scumm_v0.h
+++ b/engines/scumm/scumm_v0.h
@@ -33,9 +33,16 @@ namespace Scumm {
class ScummEngine_v0 : public ScummEngine_v2 {
protected:
enum ObjectType {
- kObjectTypeInventory = 0,
- kObjectTypeRoom = 1,
- kObjectTypeActor = 2
+ kObjectTypeFG = 0, // foreground object
+ // - with owner/state, might (but has not to) be pickupable
+ // -> with entry in _objectOwner/StateTable
+ // -> all objects in _inventory have this type
+ // - image can be exchanged (background overlay)
+ kObjectTypeBG = 1, // background object
+ // - without owner/state, not pickupable (room only)
+ // -> without entry in _objectOwner/StateTable
+ // - image cannot be exchanged (part of background image)
+ kObjectTypeActor = 2 // object is an actor
};
protected:
@@ -44,10 +51,10 @@ protected:
bool _verbPickup; // are we picking up an object during a verb execute
int _activeVerb;
- int _activeObject; // 1st Object Number
- int _activeObjectType; // 1st Object Type (0: inventory, 1: room)
- int _activeObject2; // 2nd Object Number
- int _activeObject2Type; // 2nd Object Type (0: inventory, 1: room, 2: actor)
+ int _activeObjectNr; // 1st Object Number
+ int _activeObjectType; // 1st Object Type (0: inventory (or room), 1: room)
+ 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?
@@ -73,20 +80,20 @@ protected:
virtual void saveOrLoad(Serializer *s);
// V0 MM Verb commands
- int verbPrep();
+ int getVerbPrepId();
+ int activeVerbPrep();
bool verbMove(int object, bool invObject);
bool verbMoveToActor(int actor);
- bool verbObtain(int object, int objType);
+ bool verbObtain(int object);
bool verbExecutes(int object, bool inventory = false);
bool verbExec();
virtual void checkExecVerbs();
virtual void handleMouseOver(bool updateInventory);
+ int verbPrepIdType(int verbid);
void resetVerbs();
void setNewKidVerbs();
- const byte *getObjectName(int object, int type);
-
void drawSentenceObject(int object, int type);
void drawSentence();
diff --git a/engines/scumm/verbs.cpp b/engines/scumm/verbs.cpp
index dc4a47a231..467b587b63 100644
--- a/engines/scumm/verbs.cpp
+++ b/engines/scumm/verbs.cpp
@@ -37,51 +37,82 @@ enum {
kSentenceLine = 6
};
+enum VerbsV0 {
+ kVerbNone = 0,
+ kVerbOpen = 1,
+ kVerbClose = 2,
+ kVerbGive = 3,
+ kVerbTurnOn = 4,
+ kVerbTurnOff = 5,
+ kVerbFix = 6,
+ kVerbNewKid = 7,
+ kVerbUnlock = 8,
+ kVerbPush = 9,
+ kVerbPull = 10,
+ kVerbUse = 11,
+ kVerbRead = 12,
+ kVerbWalkTo = 13,
+ kVerbPickUp = 14,
+ kVerbWhatIs = 15
+};
+
struct VerbSettings {
int id;
int x_pos;
int y_pos;
- int prep;
const char *name;
};
static const VerbSettings v0VerbTable_English[] = {
- { 1, 8, 0, 0, "Open"},
- { 2, 8, 1, 0, "Close"},
- { 3, 0, 2, 4, "Give"},
- { 4, 32, 0, 0, "Turn on"},
- { 5, 32, 1, 0, "Turn off"},
- { 6, 32, 2, 2, "Fix"},
- { 7, 24, 0, 0, "New Kid"},
- { 8, 24, 1, 2, "Unlock"},
- { 9, 0, 0, 0, "Push"},
- {10, 0, 1, 0, "Pull"},
- {11, 24, 2, 255, "Use"},
- {12, 8, 2, 0, "Read"},
- {13, 15, 0, 0, "Walk to"},
- {14, 15, 1, 0, "Pick up"},
- {15, 15, 2, 0, "What is"}
+ {kVerbOpen, 8, 0, "Open"},
+ {kVerbClose, 8, 1, "Close"},
+ {kVerbGive, 0, 2, "Give"},
+ {kVerbTurnOn, 32, 0, "Turn on"},
+ {kVerbTurnOff, 32, 1, "Turn off"},
+ {kVerbFix, 32, 2, "Fix"},
+ {kVerbNewKid, 24, 0, "New Kid"},
+ {kVerbUnlock, 24, 1, "Unlock"},
+ {kVerbPush, 0, 0, "Push"},
+ {kVerbPull, 0, 1, "Pull"},
+ {kVerbUse, 24, 2, "Use"},
+ {kVerbRead, 8, 2, "Read"},
+ {kVerbWalkTo, 15, 0, "Walk to"},
+ {kVerbPickUp, 15, 1, "Pick up"},
+ {kVerbWhatIs, 15, 2, "What is"}
};
// FIXME: Replace * with the correct character
static const VerbSettings v0VerbTable_German[] = {
- { 1, 7, 0, 0, "$ffne"},
- { 2, 13, 1, 0, "Schlie*e"},
- { 3, 0, 2, 4, "Gebe"},
- { 4, 37, 1, 0, "Ein"},
- { 5, 37, 0, 0, "Aus"},
- { 6, 23, 1, 2, "Repariere"},
- { 7, 34, 2, 0, "Person"},
- { 8, 23, 0, 2, "Schlie*e auf"},
- { 9, 0, 0, 0, "Dr<cke"},
- {10, 0, 1, 0, "Ziehe"},
- {11, 23, 2, 255, "Benutz"},
- {12, 7, 2, 0, "Lese"},
- {13, 13, 0, 0, "Gehe zu"},
- {14, 7, 1, 0, "Nimm"},
- {15, 13, 2, 0, "Was ist"}
+ {kVerbOpen, 7, 0, "$ffne"},
+ {kVerbClose, 13, 1, "Schlie*e"},
+ {kVerbGive, 0, 2, "Gebe"},
+ {kVerbTurnOn, 37, 1, "Ein"},
+ {kVerbTurnOff, 37, 0, "Aus"},
+ {kVerbFix, 23, 1, "Repariere"},
+ {kVerbNewKid, 34, 2, "Person"},
+ {kVerbUnlock, 23, 0, "Schlie*e auf"},
+ {kVerbPush, 0, 0, "Dr<cke"},
+ {kVerbPull, 0, 1, "Ziehe"},
+ {kVerbUse, 23, 2, "Benutz"},
+ {kVerbRead, 7, 2, "Lese"},
+ {kVerbWalkTo, 13, 0, "Gehe zu"},
+ {kVerbPickUp, 7, 1, "Nimm"},
+ {kVerbWhatIs, 13, 2, "Was ist"}
};
+int ScummEngine_v0::verbPrepIdType(int verbid) {
+ switch (verbid) {
+ case kVerbUse: // depends on object1
+ return 0xFF;
+ case kVerbGive:
+ return 4;
+ case kVerbUnlock: case kVerbFix:
+ return 2;
+ default:
+ return 0;
+ }
+}
+
void ScummEngine_v0::resetVerbs() {
VirtScreen *virt = &_virtscr[kVerbVirtScreen];
VerbSlot *vs;
@@ -112,7 +143,7 @@ void ScummEngine_v0::resetVerbs() {
vs->key = 0;
vs->center = 0;
vs->imgindex = 0;
- vs->prep = vtable[i - 1].prep;
+ vs->prep = verbPrepIdType(vtable[i - 1].id);
vs->curRect.left = vtable[i - 1].x_pos * 8;
vs->curRect.top = vtable[i - 1].y_pos * 8 + virt->topline + 8;
loadPtrToResource(rtVerb, i, (const byte*)vtable[i - 1].name);
@@ -433,9 +464,7 @@ void ScummEngine_v2::redrawV2Inventory() {
_string[1].right = _mouseOverBoxesV2[i].rect.right - 1;
_string[1].color = _mouseOverBoxesV2[i].color;
- _v0ObjectInInventory = true;
const byte *tmp = getObjOrActorName(obj);
- _v0ObjectInInventory = false;
assert(tmp);
// Prevent inventory entries from overflowing by truncating the text
@@ -518,7 +547,7 @@ void ScummEngine_v2::handleMouseOver(bool updateInventory) {
}
void ScummEngine_v0::handleMouseOver(bool updateInventory) {
- drawSentence();
+ //drawSentence();
ScummEngine_v2::handleMouseOver(updateInventory);
}
@@ -713,8 +742,6 @@ void ScummEngine_v2::checkExecVerbs() {
}
void ScummEngine_v0::runObject(int obj, int entry) {
- bool prev = _v0ObjectInInventory;
-
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
@@ -724,23 +751,20 @@ void ScummEngine_v0::runObject(int obj, int entry) {
}
}
- _v0ObjectInInventory = prev;
-
if (getVerbEntrypoint(obj, entry) != 0) {
- _v0ObjectInInventory = prev;
runObjectScript(obj, entry, false, false, NULL);
} else if (entry != 13 && entry != 15) {
- if (_activeVerb != 3) {
+ 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);
-
- // For some reasons, certain objects don't have a "give" script
- } else if (VAR(VAR_ACTIVE_ACTOR) > 0 && VAR(VAR_ACTIVE_ACTOR) < 8) {
- // TODO
- /*
- if (_activeInventory)
- setOwnerOf(_activeInventory, VAR(VAR_ACTIVE_ACTOR));
- */
}
}
}
@@ -785,13 +809,16 @@ bool ScummEngine_v0::verbMove(int object, bool invObject) {
} else {
// Finished walk, are we picking up the item?
if (_verbPickup) {
- int oldActive = _activeObject;
- _activeObject = object;
+ int oldActive = OBJECT_V0(_activeObjectNr, _activeObjectType);
+
+ _activeObjectNr = OBJECT_V0_NR(object);
+ _activeObjectType = OBJECT_V0_TYPE(object);
// Execute pickup
runObject(object, 14);
- _activeObject = oldActive;
+ _activeObjectNr = OBJECT_V0_NR(oldActive);
+ _activeObjectType = OBJECT_V0_TYPE(oldActive);
// Finished picking up
_verbPickup = false;
@@ -801,7 +828,7 @@ bool ScummEngine_v0::verbMove(int object, bool invObject) {
return false;
}
-bool ScummEngine_v0::verbObtain(int obj, int objType) {
+bool ScummEngine_v0::verbObtain(int obj) {
bool didPickup = false;
int prep;
int where;
@@ -809,11 +836,11 @@ bool ScummEngine_v0::verbObtain(int obj, int objType) {
if (!obj)
return false;
- where = whereIsObjectInventory(obj);
+ where = whereIsObject(obj);
// Object in inventory ?
if (where != WIO_INVENTORY) {
- prep = verbPrep();
+ prep = activeVerbPrep();
if (prep == 1 || prep == 4) {
if (_activeVerb != 13 && _activeVerb != 14) {
@@ -837,79 +864,63 @@ bool ScummEngine_v0::verbObtain(int obj, int objType) {
if (didPickup && (prep == 1 || prep == 4))
if (_activeVerb != 13 && _activeVerb != 14) {
- // TODO
- /*
- _v0ObjectInInventory = true;
-
+// TODO(TOBIAS)
+#if 0
if (whereIsObject(obj) == WIO_INVENTORY)
_activeInventory = obj;
else
resetSentence(false);
-
- _v0ObjectInInventory = false;
- */
+#endif
}
}
return false;
}
-int ScummEngine_v0::verbPrep() {
+int ScummEngine_v0::getVerbPrepId() {
if (_verbs[_activeVerb].prep != 0xFF) {
return _verbs[_activeVerb].prep;
} else {
- if (!_v0ObjectInInventory)
- _v0ObjectIndex = true;
- else
- _v0ObjectIndex = false;
-
- byte *ptr = getOBCDFromObject(_activeObject);
- _v0ObjectIndex = false;
+ byte *ptr = getOBCDFromObject(OBJECT_V0(_activeObjectNr, _activeObjectType), true);
assert(ptr);
return (*(ptr + 11) >> 5);
}
}
-bool ScummEngine_v0::verbExecutes(int object, bool inventory) {
- _v0ObjectInInventory = inventory;
- int prep = verbPrep();
-
- if (prep == 2 || prep == 0) {
- return true;
- }
-
- return false;
+int ScummEngine_v0::activeVerbPrep() {
+ if (!_activeVerb || !_activeObjectNr)
+ return 0;
+ return getVerbPrepId();
}
bool ScummEngine_v0::verbExec() {
int entry = (_currentMode != 0 && _currentMode != 1) ? _activeVerb : 15;
- if (_activeObject && getObjectIndex(_activeObject) == -1) {
+ if (_activeObjectNr && getObjectIndex(OBJECT_V0(_activeObjectNr, _activeObjectType)) == -1) {
resetSentence(false);
return false;
}
// Lets try walk to the object
- if (_activeObject && !_activeObjectObtained && _currentMode != 0) {
- if (verbObtain(_activeObject, _activeObjectType))
+ if (_activeObjectNr && !_activeObjectObtained && _currentMode != 0) {
+ if (verbObtain(OBJECT_V0(_activeObjectNr, _activeObjectType)))
return true;
_activeObjectObtained = true;
}
// Attempt to obtain/reach object2
- if (_activeObject2 && !_activeObject2Obtained && _currentMode != 0) {
- _v0ObjectInInventory = false;
- if (verbObtain(_activeObject2, _activeObject2Type))
+ if (_activeObject2Nr && !_activeObject2Obtained && _currentMode != 0) {
+ if (verbObtain(OBJECT_V0(_activeObject2Nr, _activeObject2Type)))
return true;
_activeObject2Obtained = true;
}
// Give-To
- if (_activeVerb == 3 && _activeObject && _activeObject2 && _activeObject2Type == kObjectTypeActor) {
+ if (_activeVerb == 3 && _activeObjectNr && _activeObject2Nr && _activeObject2Type == kObjectTypeActor) {
// FIXME: Actors need to turn and face each other
- if (verbMoveToActor(_activeObject2)) {
+ if (verbMoveToActor(_activeObject2Nr)) {
// Ignore verbs?
Actor *a = derefActor(VAR(VAR_EGO), "verbExec");
if (((ActorC64 *)a)->_miscflags & 0x40) {
@@ -919,18 +930,16 @@ bool ScummEngine_v0::verbExec() {
return true;
}
- _v0ObjectInInventory = true;
- VAR(VAR_ACTIVE_ACTOR) = _activeObject2;
- runObject(_activeObject , 3);
- _v0ObjectInInventory = false;
+ VAR(VAR_ACTIVE_ACTOR) = _activeObject2Nr;
+ runObject(OBJECT_V0(_activeObjectNr, _activeObjectType), 3);
resetSentence(false);
return false;
}
// Where we performing an action on an actor?
- if (_activeObject2 && _activeObject2Type == kObjectTypeActor) {
- runObject(_activeObject2, entry);
+ if (_activeObject2Nr && _activeObject2Type == kObjectTypeActor) {
+ runObject(OBJECT_V0(_activeObject2Nr, _activeObject2Type), entry);
_verbExecuting = false;
resetSentence(false);
@@ -938,8 +947,8 @@ bool ScummEngine_v0::verbExec() {
}
// If we've finished walking (now near target), execute the action
- if (_activeObject && verbPrep() == 2) {
- runObject(_activeObject, entry);
+ if (_activeObjectNr && activeVerbPrep() == 2) {
+ runObject(OBJECT_V0(_activeObjectNr, _activeObjectType), entry);
_verbExecuting = false;
if ((_currentMode == 3 || _currentMode == 2) && _activeVerb == 13)
@@ -950,9 +959,8 @@ bool ScummEngine_v0::verbExec() {
}
// We acted on an inventory item
- if (/*_activeInventory && verbExecutes(_activeInventory, true) &&*/ _activeVerb != 3) {
- _v0ObjectInInventory = true;
- runObject(_activeObject/*2*/, _activeVerb);
+ if (_activeVerb != 3) {
+ runObject(OBJECT_V0(_activeObjectNr/*2*/, _activeObjectType/*2*/), _activeVerb);
_verbExecuting = false;
@@ -965,36 +973,8 @@ bool ScummEngine_v0::verbExec() {
return false;
}
- // Item not in inventory is executed
- if (_activeObject) {
- runObject(_activeObject, entry);
- } else if (/*_activeInventory*/false) {
-#if 0
- // Not sure this is the correct way to do this,
- // however its working for most situations - segra
- if (verbExecutes(_activeInventory, true) == false) {
- if (_activeObject2 && _activeObject2Type == kObjectTypeInventory && verbExecutes(_activeObject2, true)) {
- _v0ObjectInInventory = true;
-
- _activeObject = _activeInventory;
- _activeInventory = _activeObject2;
-
- runObject(_activeObject, _activeVerb);
- } else {
- _v0ObjectInInventory = true;
-
- if (_activeObject2) {
- _activeObject = _activeObject2;
-
- runObject(_activeObject, _activeVerb);
- } else
- runObject(_activeInventory, _activeVerb);
- }
- } else {
- _v0ObjectInInventory = true;
- runObject(_activeInventory, _activeVerb);
- }
-#endif
+ if (_activeObjectNr) {
+ runObject(OBJECT_V0(_activeObjectNr, _activeObjectType), entry);
}
_verbExecuting = false;
@@ -1009,17 +989,182 @@ bool ScummEngine_v0::verbExec() {
return false;
}
+#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;
+ 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();
+ }
+}
+#endif
+
void ScummEngine_v0::checkExecVerbs() {
ActorC64 *a = (ActorC64 *)derefActor(VAR(VAR_EGO), "checkExecVerbs");
VirtScreen *zone = findVirtScreen(_mouse.y);
+ int scriptUpdateSkip;
+ int sentenceLineChanged = false;
+
+ /*
+ if (_userPut <= 0 || _mouseAndKeyboardStat == 0)
+ return;
+ */
+
+ // Check if mouse click
+ if (_mouseAndKeyboardStat & MBS_MOUSE_MASK) {
+ int over = findVerbAtPos(_mouse.x, _mouse.y);
+ if (over && _activeVerb != over) {
+ _activeVerb = over;
+ //_activeVerbPrep = 0;
+ _activeObjectNr = 0;
+ _activeObjectType = 0;
+ _activeObject2Nr = 0;
+ _activeObject2Type = 0;
+ sentenceLineChanged = true;
+ }
+ }
+
+ if (a->_miscflags & 0x80) {
+ if (_activeVerb != kVerbNewKid) {
+ _activeVerb = kVerbNone;
+ }
+ }
+
+ // mode 1: kid selection, 3: normal
+ if (_currentMode != 0) {
+ if (_currentMode == 1) {
+ // kid selection or dial pad
+ _activeVerb = kVerbPush;
+ }
+
+ if ((_mouseAndKeyboardStat & MBS_MOUSE_MASK) || _activeVerb == kVerbWhatIs) {
+ int id;
+ byte type;
+ if (_activeVerb == kVerbGive && _activeObjectNr) {
+ id = getActorFromPos(_virtualMouse.x, _virtualMouse.y);
+ type = kObjectTypeActor;
+ } else {
+ int obj = findObject(_virtualMouse.x, _virtualMouse.y);
+ id = OBJECT_V0_NR(obj);
+ type = OBJECT_V0_TYPE(obj);
+ debug("found 0x%03x", obj);
+ }
+ if (!id) {
+ if (_activeVerb == kVerbWalkTo) {
+ _activeObjectNr = 0;
+ _activeObject2Nr = 0;
+ }
+ } else {
+ //_activeVerbPrep:
+ // 0: no activeObject or activeObject but no prep
+ // > 0: activeObject + prep
+ if (activeVerbPrep() == 0) {
+ if (id == _activeObjectNr && type == _activeObjectType) {
+ _verbExecuting = true;
+ } else {
+ _activeObjectNr = id;
+ _activeObjectType = type;
+ }
+ //sentenceLineChanged = true;
+ if (_currentMode == 1)
+ _verbExecuting = true;
+ } else {
+ if (id == _activeObject2Nr && type == _activeObject2Type)
+ _verbExecuting = true;
+ if (!(id == _activeObjectNr && type == _activeObjectType)) {
+ _activeObject2Nr = id;
+ _activeObject2Type = type;
+ if (_currentMode == 1)
+ _verbExecuting = true;
+ }
+ }
+ }
+
+ sentenceLineChanged = true;
+ if (_activeVerb == kVerbWalkTo) {
+ scriptUpdateSkip = 0;
+ _verbExecuting = true;
+ }
+ }
+ }
+
+ if (sentenceLineChanged)
+ drawSentence();
+
+ if (_activeVerb == kVerbNewKid) {
+ // TODO
+ if (_currentMode == 3) {
+ // get kid
+ _activeVerb = kVerbWalkTo;
+ resetSentence(false);
+ //switchActor(_verbs[over].verbid - 1);
+ }
+ _activeVerb = kVerbWalkTo;
+ }
+
+ if (_activeVerb == kVerbWalkTo) {
+ //exec();
+ }
+
+ /*
+ if (_activeVerbPrep == 0) {
+ int prep = activeVerbPrep();
+ if (prep == 0)
+ ; //exec();
+ else {
+ _activeVerbPrep = prep;
+ ; // draw()
+ }
+ } else {
+ if (_activeObject2 == 0)
+ ; //drawSentence();
+ else
+ ; // exec();
+ }
+ */
+
+#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);
- int obj = findObject(_virtualMouse.x, _virtualMouse.y);
+ byte type;
+ int obj = findObject(_virtualMouse.x, _virtualMouse.y, &type);
if (over && over != _activeVerb) {
_activeVerb = over;
@@ -1039,17 +1184,6 @@ void ScummEngine_v0::checkExecVerbs() {
}
}
- // What-Is selected, any object we hover over is selected, on mouse press we set to WalkTo
- if (_activeVerb == 15) {
- int obj = findObject(_virtualMouse.x, _virtualMouse.y);
- _activeObject = obj;
-
- if ((_mouseAndKeyboardStat & MBS_MOUSE_MASK))
- _activeVerb = 13; // Walk-To
-
- return;
- }
-
if (_userPut <= 0 || _mouseAndKeyboardStat == 0)
return;
@@ -1060,78 +1194,19 @@ void ScummEngine_v0::checkExecVerbs() {
if (zone->number == kVerbVirtScreen && _mouse.y <= zone->topline + 8) {
// TODO
} else if (zone->number == kVerbVirtScreen && _mouse.y > zone->topline + 32) {
-#if 0
- int prevInventory = _activeInventory;
-#endif
int invOff = _inventoryOffset;
- // GIVE: actor must be selected (not possible via inventory)
- if ((_activeVerb == 3) && _activeObject)
- return;
-
// Click into V2 inventory
checkV2Inventory(_mouse.x, _mouse.y);
// Did the Inventory position changed (arrows pressed, do nothing)
if (invOff != _inventoryOffset)
return;
-
-#if 0
- // No inventory selected?
- if (!_activeInventory)
- return;
-
- // Did we just change the selected inventory item?
- if (prevInventory && prevInventory != _activeInventory && _activeInventory != _activeObject2) {
- // Setup object2
- _activeObject = 0;
- _activeObject2Type = kObjectTypeInventory;
- _activeObject2 = _activeInventory;
- _activeInventory = prevInventory;
- return;
- }
-
- // is the new selected inventory the same as the last selected?, reset to previous if it is
- if (_activeInventory == _activeObject2)
- _activeInventory = prevInventory;
-
- // Inventory Selected changed
- if (prevInventory != _activeInventory)
- if (!_activeObject2 || prevInventory != _activeObject2)
- return;
-#endif
-
- if (_activeVerb == 11 && !(_activeObject || !_activeObject2))
- return;
} else {
int over = findVerbAtPos(_mouse.x, _mouse.y);
int act = getActorFromPos(_virtualMouse.x, _virtualMouse.y);
int obj = findObject(_virtualMouse.x, _virtualMouse.y);
- if (a->_miscflags & 0x80) {
- if (_activeVerb != 7 && over != 7) {
- _activeVerb = 0;
- over = 0;
- }
- }
-
- // Handle New Kid verb options
- if (_activeVerb == 7 || over == 7) {
- // Disable New-Kid (in the secret lab)
- if (_currentMode == 2 || _currentMode == 0)
- return;
-
- if (_activeVerb == 7 && over) {
- _activeVerb = 13;
- switchActor(_verbs[over].verbid - 1);
- return;
- }
-
- setNewKidVerbs();
- _activeVerb = 7;
-
- return;
- }
// Clicked on nothing, walk here?
if (!over && !act && _activeVerb == 13 && !obj && _currentMode != 0) {
@@ -1154,77 +1229,10 @@ void ScummEngine_v0::checkExecVerbs() {
}
return;
}
-
- // No new verb, use previous
- if (over == 0)
- over = _activeVerb;
-
- // No verb selected, use walk-to
- if (!_activeVerb)
- _activeVerb = over = 13; // Walk-To
-
- // New verb selected
- if (_activeVerb != over) {
- _activeVerb = over;
- if (_activeVerb == 13) {
- resetSentence(false);
- }
- return;
- }
-
- // Only allowing targetting actors if its the GIVE verb
- if (_activeVerb == 3) {
- if (_activeObject) {
- // Once selected the object cannot be changed
- obj = 0;
-
- // Different actor selected?
- if (act) {
- if (_activeObject2 != act || _activeObject2Type != kObjectTypeActor) {
- _activeObject2 = act;
- _activeObject2Type = kObjectTypeActor;
- return;
- }
- } else {
- return;
- }
- } else {
- // An object has to be selected first
- act = 0;
- if (!obj)
- return;
- }
- }
-
- if (obj && obj != _activeObject) {
- // USE / UNLOCK
- if (_activeVerb == 11 || _activeVerb == 8) {
- if (obj != _activeObject && obj != _activeObject2) {
- if (!_activeObject) {
- _activeObject = obj;
- return;
- } else {
- if (_activeObject2 != obj) {
- _activeObject2 = obj;
- return;
- }
- }
- }
- } else {
- a->stopActorMoving();
-
- _activeObject = obj;
- if (_activeVerb != 13)
- return;
-
- //return;
- }
- }
- }
-
_verbExecuting = true;
} // mouse k/b action
+#endif
}
void ScummEngine::verbMouseOver(int verb) {