SCUMM: changed handling of _activeInventory/_activeActor to _activeObject(2)/_activeObject(2)Type

Note: the transition is not completed yet. The code compiles but is probably not runnable as not every occurrence of _activeInventory has been properly replaced.
The usage of _v0ObjectIndex and _v0ObjectInInventory should be revised too and both variables should be replaced by another mechanism (maybe by using a single variable "obj = (type << 8) | id").

- moved v0 only vars _activeInventory, _activeObject, _activeVerb from  ScummEngine_v2 to ScummEngine_v0
- removed _activeActor, _activeInvExecute, _activeObject2Inv and _activeInventory. They are handled by _activeObject/_activeObjectType and _activeObject2/_activeObject2Type now.
- removed _activeObject(2)Index as they only bloat the code without any benefit (?)
- merge prep-name tables from ScummEngine_v2::drawPreposition() and ScummEngine_v0::drawSentenceWord() by introducing ScummEngine_v2::drawPreposition()
- rename ObjectData.flags -> obj_type (quick-fix only, needs review! Maybe obj_nr and obj_type can be merged into one var: obj_nr = (obj_type << 8) | obj_nr)
- o_unknown2 is negation of o_ifActiveObject (o_ifNotEqualActiveObject2)
- renamed o_ifActiveObject -> o_ifEqualActiveObject2 as it acts only on _activeObject2
- renamed ScummEngine_v0::drawSentenceWord() -> ScummEngine_v0::getObjectName()
This commit is contained in:
Tobias Gunkel 2012-01-03 22:10:50 +01:00
parent c9ae5f3838
commit a79f224c23
9 changed files with 207 additions and 303 deletions

View file

@ -316,7 +316,7 @@ int ScummEngine::getObjectIndex(int object) const {
for (i = (_numLocalObjects-1); i > 0; i--) { for (i = (_numLocalObjects-1); i > 0; i--) {
if (_game.version == 0 ) if (_game.version == 0 )
if( _objs[i].flags != _v0ObjectFlag ) if( _objs[i].obj_type != _v0ObjectFlag )
continue; continue;
if (_objs[i].obj_nr == object) if (_objs[i].obj_nr == object)
@ -492,14 +492,6 @@ int ScummEngine::getObjActToObjActDist(int a, int b) {
return getDist(x, y, x2, y2); return getDist(x, y, x2, y2);
} }
int ScummEngine_v0::findObjectIndex(int x, int y) {
int objIdx;
_v0ObjectIndex = true;
objIdx = findObject(x, y);
_v0ObjectIndex = false;
return objIdx;
}
int ScummEngine::findObject(int x, int y) { int ScummEngine::findObject(int x, int y) {
int i, b; int i, b;
byte a; byte a;
@ -510,7 +502,7 @@ int ScummEngine::findObject(int x, int y) {
continue; continue;
if (_game.version == 0) { if (_game.version == 0) {
if (_objs[i].flags == 0 && _objs[i].state & kObjectStateUntouchable) if (_objs[i].obj_type == 0 && _objs[i].state & kObjectStateUntouchable)
continue; continue;
} else { } else {
if (_game.version <= 2 && _objs[i].state & kObjectStateUntouchable) if (_game.version <= 2 && _objs[i].state & kObjectStateUntouchable)
@ -532,7 +524,7 @@ int ScummEngine::findObject(int x, int y) {
_objs[i].y_pos <= y && _objs[i].height + _objs[i].y_pos > y) { _objs[i].y_pos <= y && _objs[i].height + _objs[i].y_pos > y) {
// MMC64: Set the object search flag // MMC64: Set the object search flag
if (_game.version == 0) if (_game.version == 0)
_v0ObjectFlag = _objs[i].flags; _v0ObjectFlag = _objs[i].obj_type;
if (_game.version == 0 && _v0ObjectIndex) if (_game.version == 0 && _v0ObjectIndex)
return i; return i;
else else
@ -844,7 +836,7 @@ void ScummEngine_v3old::resetRoomObjects() {
char buf[32]; char buf[32];
sprintf(buf, "roomobj-%d-", _roomResource); sprintf(buf, "roomobj-%d-", _roomResource);
if (_game.version == 0) if (_game.version == 0)
sprintf(buf + 11, "%d-", od->flags); sprintf(buf + 11, "%d-", od->obj_type);
dumpResource(buf, od->obj_nr, room + od->OBCDoffset); dumpResource(buf, od->obj_nr, room + od->OBCDoffset);
} }
@ -912,7 +904,7 @@ void ScummEngine_v0::resetRoomObject(ObjectData *od, const byte *room, const byt
ptr -= 2; ptr -= 2;
od->obj_nr = *(ptr + 6); od->obj_nr = *(ptr + 6);
od->flags = *(ptr + 7); od->obj_type = *(ptr + 7);
od->x_pos = *(ptr + 8) * 8; od->x_pos = *(ptr + 8) * 8;
od->y_pos = ((*(ptr + 9)) & 0x7F) * 8; od->y_pos = ((*(ptr + 9)) & 0x7F) * 8;
@ -1072,8 +1064,8 @@ void ScummEngine::updateObjectStates() {
int i; int i;
ObjectData *od = &_objs[1]; ObjectData *od = &_objs[1];
for (i = 1; i < _numLocalObjects; i++, od++) { for (i = 1; i < _numLocalObjects; i++, od++) {
// V0 MM, Room objects with Flag == 1 are objects with 'no-state' (room specific objects, non-pickup) // V0 MM, objects with type == 1 are room objects (room specific objects, non-pickup)
if (_game.version == 0 && od->flags == 1) if (_game.version == 0 && od->obj_type == 1)
continue; continue;
if (od->obj_nr > 0) if (od->obj_nr > 0)

View file

@ -62,7 +62,12 @@ struct ObjectData {
byte parentstate; byte parentstate;
byte state; byte state;
byte fl_object_index; byte fl_object_index;
byte flags; // extra engine specific data
union {
byte extra;
byte obj_type; // v0
byte flags; // v8
};
}; };
#include "common/pack-start.h" // START STRUCT PACKING #include "common/pack-start.h" // START STRUCT PACKING

View file

@ -822,7 +822,7 @@ void ScummEngine::saveOrLoad(Serializer *s) {
MKLINE(ObjectData, parent, sleByte, VER(8)), MKLINE(ObjectData, parent, sleByte, VER(8)),
MKLINE(ObjectData, state, sleByte, VER(8)), MKLINE(ObjectData, state, sleByte, VER(8)),
MKLINE(ObjectData, fl_object_index, sleByte, VER(8)), MKLINE(ObjectData, fl_object_index, sleByte, VER(8)),
MKLINE(ObjectData, flags, sleByte, VER(46)), MKLINE(ObjectData, extra, sleByte, VER(46)),
MKEND() MKEND()
}; };

View file

@ -79,7 +79,7 @@ void ScummEngine_v0::setupOpcodes() {
OPCODE(0x22, o4_saveLoadGame); OPCODE(0x22, o4_saveLoadGame);
OPCODE(0x23, o_stopCurrentScript); OPCODE(0x23, o_stopCurrentScript);
/* 24 */ /* 24 */
OPCODE(0x24, o_unknown2); OPCODE(0x24, o_ifNotEqualActiveObject2);
OPCODE(0x25, o5_loadRoom); OPCODE(0x25, o5_loadRoom);
OPCODE(0x26, o_getClosestObjActor); OPCODE(0x26, o_getClosestObjActor);
OPCODE(0x27, o2_getActorY); OPCODE(0x27, o2_getActorY);
@ -159,7 +159,7 @@ void ScummEngine_v0::setupOpcodes() {
OPCODE(0x62, o2_stopScript); OPCODE(0x62, o2_stopScript);
OPCODE(0x63, o_stopCurrentScript); OPCODE(0x63, o_stopCurrentScript);
/* 64 */ /* 64 */
OPCODE(0x64, o_ifActiveObject); OPCODE(0x64, o_ifEqualActiveObject2);
OPCODE(0x65, o_stopCurrentScript); OPCODE(0x65, o_stopCurrentScript);
OPCODE(0x66, o_getClosestObjActor); OPCODE(0x66, o_getClosestObjActor);
OPCODE(0x67, o5_getActorFacing); OPCODE(0x67, o5_getActorFacing);
@ -239,7 +239,7 @@ void ScummEngine_v0::setupOpcodes() {
OPCODE(0xa2, o4_saveLoadGame); OPCODE(0xa2, o4_saveLoadGame);
OPCODE(0xa3, o_stopCurrentScript); OPCODE(0xa3, o_stopCurrentScript);
/* A4 */ /* A4 */
OPCODE(0xa4, o_unknown2); OPCODE(0xa4, o_ifNotEqualActiveObject2);
OPCODE(0xa5, o5_loadRoom); OPCODE(0xa5, o5_loadRoom);
OPCODE(0xa6, o_stopCurrentScript); OPCODE(0xa6, o_stopCurrentScript);
OPCODE(0xa7, o2_getActorY); OPCODE(0xa7, o2_getActorY);
@ -319,7 +319,7 @@ void ScummEngine_v0::setupOpcodes() {
OPCODE(0xe2, o2_stopScript); OPCODE(0xe2, o2_stopScript);
OPCODE(0xe3, o_stopCurrentScript); OPCODE(0xe3, o_stopCurrentScript);
/* E4 */ /* E4 */
OPCODE(0xe4, o_ifActiveObject); OPCODE(0xe4, o_ifEqualActiveObject2);
OPCODE(0xe5, o_loadRoomWithEgo); OPCODE(0xe5, o_loadRoomWithEgo);
OPCODE(0xe6, o_stopCurrentScript); OPCODE(0xe6, o_stopCurrentScript);
OPCODE(0xe7, o5_getActorFacing); OPCODE(0xe7, o5_getActorFacing);
@ -406,128 +406,65 @@ void ScummEngine_v0::decodeParseString() {
actorTalk(buffer); actorTalk(buffer);
} }
void ScummEngine_v0::drawSentenceWord(int object, bool usePrep, bool objInInventory) { const byte *ScummEngine_v0::getObjectName(int object, int type) {
const byte *temp; const byte *temp;
int sentencePrep = 0;
// If object not in inventory, we except an index if (type == kObjectTypeInventory)
if (!objInInventory)
_v0ObjectIndex = true;
else
_v0ObjectInInventory = true; _v0ObjectInInventory = true;
temp = getObjOrActorName(object); temp = getObjOrActorName(object);
_v0ObjectInInventory = false; _v0ObjectInInventory = false;
_v0ObjectIndex = false;
// Append the 'object-name' return temp;
}
void ScummEngine_v0::drawSentenceObject(int object, int type) {
const byte *temp;
temp = getObjectName(object, type);
if (temp) { if (temp) {
_sentenceBuf += " "; _sentenceBuf += " ";
_sentenceBuf += (const char *)temp; _sentenceBuf += (const char *)temp;
} }
// Append the modifier? (With / On / To / In)
if (!usePrep)
return;
if (_verbs[_activeVerb].prep == 0xFF) {
_v0ObjectInInventory = objInInventory;
sentencePrep = verbPrep(object);
} else {
sentencePrep = _verbs[_activeVerb].prep;
}
if (sentencePrep > 0 && sentencePrep <= 4) {
// The prepositions, like the fonts, were hard code in the engine. Thus
// we have to do that, too, and provde localized versions for all the
// languages MM/Zak are available in.
static const char *const prepositions[][5] = {
{ " ", " in", " with", " on", " to" }, // English
{ " ", " mit", " mit", " mit", " zu" }, // German
{ " ", " dans", " avec", " sur", " <" }, // French
{ " ", " in", " con", " su", " a" }, // Italian
{ " ", " en", " con", " en", " a" }, // Spanish
};
int lang;
switch (_language) {
case Common::DE_DEU:
lang = 1;
break;
case Common::FR_FRA:
lang = 2;
break;
case Common::IT_ITA:
lang = 3;
break;
case Common::ES_ESP:
lang = 4;
break;
default:
lang = 0; // Default to english
}
_sentenceBuf += prepositions[lang][sentencePrep];
}
} }
void ScummEngine_v0::drawSentence() { void ScummEngine_v0::drawSentence() {
Common::Rect sentenceline; Common::Rect sentenceline;
bool inventoryFirst = false;
if (!(_userState & 32)) if (!(_userState & 32))
return; return;
// Current Verb, Walk/Use // Current Verb
if (_activeVerb == 0)
_activeVerb = 13;
if (getResourceAddress(rtVerb, _activeVerb)) { if (getResourceAddress(rtVerb, _activeVerb)) {
_sentenceBuf = (char *)getResourceAddress(rtVerb, _activeVerb); _sentenceBuf = (char *)getResourceAddress(rtVerb, _activeVerb);
} else { } else {
return; return;
} }
// If using inventory first, draw it first if (_activeObject) {
if (_activeInvExecute && _activeInventory) { // Draw the 1st active object
drawSentenceWord(_activeInventory, true, true); drawSentenceObject(_activeObject, _activeObjectType);
} else {
// Not using inventory, use selected object
if (_activeObject)
drawSentenceWord(_activeObjectIndex, true, false);
else
inventoryFirst = true;
}
// Append verb preposition
int sentencePrep = verbPrep();
if (sentencePrep) {
drawPreposition(sentencePrep);
// Draw the inventory? // Draw the 2nd active object
if (_activeInventory > 0 && _activeObject2 == 0) { if (_activeObject2) {
// Only if inventory isnt first (it will already be drawn by now) // 2nd Object is an actor
if (!_activeInvExecute) { if (_activeObject2Type == kObjectTypeActor) {
drawSentenceWord(_activeInventory, inventoryFirst, true); Actor *a = derefActor(_activeObject2, "");
} else { _sentenceBuf += " ";
// Draw the active object, which could be inventory based, or room based _sentenceBuf += (const char *)a->getActorName();
if (_activeObject && !_activeObjectIndex) { // 2nd Object is an inventory or room object
drawSentenceWord(_activeObject, inventoryFirst, true); } else {
} else // Room based drawSentenceObject(_activeObject2, _activeObject2Type);
drawSentenceWord(_activeObjectIndex, inventoryFirst, false); }
}
} }
// Draw the 2nd active object
} else if (_activeObject2) {
// 2nd Object is in inventory
if (_activeObject2Inv) {
_v0ObjectInInventory = true;
drawSentenceWord(_activeObject2, inventoryFirst, true);
} else {
drawSentenceWord(_activeObject2Index, inventoryFirst, false);
}
}
// Draw the active actor
if (_activeActor) {
Actor *a = derefActor(_activeActor, "");
_sentenceBuf += " ";
_sentenceBuf += (const char *)a->getActorName();
} }
_string[2].charset = 1; _string[2].charset = 1;
@ -890,15 +827,21 @@ void ScummEngine_v0::o_doSentence() {
runObjectScript(obj, entry, false, false, NULL); runObjectScript(obj, entry, false, false, NULL);
} }
void ScummEngine_v0::o_unknown2() { bool ScummEngine_v0::ifEqualActiveObject2Common(bool inventoryObject) {
byte var1 = fetchScriptByte(); byte obj = fetchScriptByte();
error("STUB: o_unknown2(%d)", var1); if (!inventoryObject || (_activeObject2Type == kObjectTypeInventory))
return (obj == _activeObject2);
return false;
} }
void ScummEngine_v0::o_ifActiveObject() { void ScummEngine_v0::o_ifEqualActiveObject2() {
byte obj = fetchScriptByte(); bool equal = ifEqualActiveObject2Common((_opcode & 0x80) == 0);
jumpRelative(equal);
}
jumpRelative(obj == _activeInventory); void ScummEngine_v0::o_ifNotEqualActiveObject2() {
bool equal = ifEqualActiveObject2Common((_opcode & 0x80) == 0);
jumpRelative(!equal);
} }
void ScummEngine_v0::o_getClosestObjActor() { void ScummEngine_v0::o_getClosestObjActor() {
@ -1004,19 +947,15 @@ void ScummEngine_v0::resetSentence(bool walking) {
// Then reset all active objects (stops the radio crash, bug #3077966) // Then reset all active objects (stops the radio crash, bug #3077966)
if (!walking || !(_userState & 32)) { if (!walking || !(_userState & 32)) {
_v0ObjectFlag = 0; _v0ObjectFlag = 0;
_activeInventory = 0;
_activeObject = 0; _activeObject = 0;
_activeObject2 = 0; _activeObject2 = 0;
_activeObjectIndex = 0;
_activeObject2Index = 0;
} }
_verbExecuting = false; _verbExecuting = false;
_verbPickup = false; _verbPickup = false;
_activeActor = 0; _activeObjectType = kObjectTypeRoom;
_activeInvExecute = false; _activeObject2Type = kObjectTypeRoom;
_activeObject2Inv = false;
_activeObjectObtained = false; _activeObjectObtained = false;
_activeObject2Obtained = false; _activeObject2Obtained = false;
} }

View file

@ -953,6 +953,41 @@ void ScummEngine_v2::o2_doSentence() {
} }
} }
void ScummEngine_v2::drawPreposition(int index) {
// The prepositions, like the fonts, were hard code in the engine. Thus
// we have to do that, too, and provde localized versions for all the
// languages MM/Zak are available in.
const char *prepositions[][5] = {
{ " ", " in", " with", " on", " to" }, // English
{ " ", " mit", " mit", " mit", " zu" }, // German
{ " ", " dans", " avec", " sur", " <" }, // French
{ " ", " in", " con", " su", " a" }, // Italian
{ " ", " en", " con", " en", " a" }, // Spanish
};
int lang;
switch (_language) {
case Common::DE_DEU:
lang = 1;
break;
case Common::FR_FRA:
lang = 2;
break;
case Common::IT_ITA:
lang = 3;
break;
case Common::ES_ESP:
lang = 4;
break;
default:
lang = 0; // Default to english
}
if (_game.platform == Common::kPlatformNES) {
_sentenceBuf += (const char *)(getResourceAddress(rtCostume, 78) + VAR(VAR_SENTENCE_PREPOSITION) * 8 + 2);
} else
_sentenceBuf += prepositions[lang][index];
}
void ScummEngine_v2::o2_drawSentence() { void ScummEngine_v2::o2_drawSentence() {
Common::Rect sentenceline; Common::Rect sentenceline;
const byte *temp; const byte *temp;
@ -986,38 +1021,7 @@ void ScummEngine_v2::o2_drawSentence() {
} }
if (0 < VAR(VAR_SENTENCE_PREPOSITION) && VAR(VAR_SENTENCE_PREPOSITION) <= 4) { if (0 < VAR(VAR_SENTENCE_PREPOSITION) && VAR(VAR_SENTENCE_PREPOSITION) <= 4) {
// The prepositions, like the fonts, were hard code in the engine. Thus drawPreposition(VAR(VAR_SENTENCE_PREPOSITION));
// we have to do that, too, and provde localized versions for all the
// languages MM/Zak are available in.
const char *prepositions[][5] = {
{ " ", " in", " with", " on", " to" }, // English
{ " ", " mit", " mit", " mit", " zu" }, // German
{ " ", " dans", " avec", " sur", " <" }, // French
{ " ", " in", " con", " su", " a" }, // Italian
{ " ", " en", " con", " en", " a" }, // Spanish
};
int lang;
switch (_language) {
case Common::DE_DEU:
lang = 1;
break;
case Common::FR_FRA:
lang = 2;
break;
case Common::IT_ITA:
lang = 3;
break;
case Common::ES_ESP:
lang = 4;
break;
default:
lang = 0; // Default to english
}
if (_game.platform == Common::kPlatformNES) {
_sentenceBuf += (const char *)(getResourceAddress(rtCostume, 78) + VAR(VAR_SENTENCE_PREPOSITION) * 8 + 2);
} else
_sentenceBuf += prepositions[lang][VAR(VAR_SENTENCE_PREPOSITION)];
} }
if (VAR(VAR_SENTENCE_OBJECT2) > 0) { if (VAR(VAR_SENTENCE_OBJECT2) > 0) {

View file

@ -701,10 +701,6 @@ ScummEngine_v2::ScummEngine_v2(OSystem *syst, const DetectorResult &dr)
_inventoryOffset = 0; _inventoryOffset = 0;
_activeInventory = 0;
_activeObject = 0;
_activeVerb = 0;
VAR_SENTENCE_VERB = 0xFF; VAR_SENTENCE_VERB = 0xFF;
VAR_SENTENCE_OBJECT1 = 0xFF; VAR_SENTENCE_OBJECT1 = 0xFF;
VAR_SENTENCE_OBJECT2 = 0xFF; VAR_SENTENCE_OBJECT2 = 0xFF;
@ -723,11 +719,11 @@ ScummEngine_v0::ScummEngine_v0(OSystem *syst, const DetectorResult &dr)
_verbPickup = false; _verbPickup = false;
_currentMode = 0; _currentMode = 0;
_activeVerb = 0;
_activeObject = 0;
_activeObject2 = 0; _activeObject2 = 0;
_activeObjectIndex = 0; _activeObjectType = kObjectTypeRoom;
_activeObject2Index = 0; _activeObject2Type = kObjectTypeRoom;
_activeInvExecute = false;
_activeObject2Inv = false;
_activeObjectObtained = false; _activeObjectObtained = false;
_activeObject2Obtained = false; _activeObject2Obtained = false;

View file

@ -31,22 +31,27 @@ namespace Scumm {
* Engine for Apple II and Commodore 64 versions of Maniac Mansion * Engine for Apple II and Commodore 64 versions of Maniac Mansion
*/ */
class ScummEngine_v0 : public ScummEngine_v2 { class ScummEngine_v0 : public ScummEngine_v2 {
protected:
enum ObjectType {
kObjectTypeInventory = 0,
kObjectTypeRoom = 1,
kObjectTypeActor = 2
};
protected: protected:
byte _currentMode; byte _currentMode;
bool _verbExecuting; // is a verb executing bool _verbExecuting; // is a verb executing
bool _verbPickup; // are we picking up an object during a verb execute bool _verbPickup; // are we picking up an object during a verb execute
int _activeActor; // Actor Number int _activeVerb;
int _activeObject; // 1st Object Number
int _activeObjectType; // 1st Object Type (0: inventory, 1: room)
int _activeObject2; // 2nd Object Number int _activeObject2; // 2nd Object Number
int _activeObject2Type; // 2nd Object Type (0: inventory, 1: room, 2: actor)
bool _activeInvExecute; // is activeInventory first to be executed
bool _activeObject2Inv; // is activeobject2 in the inventory
bool _activeObjectObtained; // collected _activeobject? bool _activeObjectObtained; // collected _activeobject?
bool _activeObject2Obtained; // collected _activeObject2? bool _activeObject2Obtained; // collected _activeObject2?
int _activeObjectIndex;
int _activeObject2Index;
public: public:
ScummEngine_v0(OSystem *syst, const DetectorResult &dr); ScummEngine_v0(OSystem *syst, const DetectorResult &dr);
@ -68,21 +73,21 @@ protected:
virtual void saveOrLoad(Serializer *s); virtual void saveOrLoad(Serializer *s);
// V0 MM Verb commands // V0 MM Verb commands
int verbPrep(int object); int verbPrep();
bool verbMove(int object, int objectIndex, bool invObject); bool verbMove(int object, bool invObject);
bool verbMoveToActor(int actor); bool verbMoveToActor(int actor);
bool verbObtain(int object, int objIndex); bool verbObtain(int object, int objType);
bool verbExecutes(int object, bool inventory = false); bool verbExecutes(int object, bool inventory = false);
bool verbExec(); bool verbExec();
int findObjectIndex(int x, int y);
virtual void checkExecVerbs(); virtual void checkExecVerbs();
virtual void handleMouseOver(bool updateInventory); virtual void handleMouseOver(bool updateInventory);
void resetVerbs(); void resetVerbs();
void setNewKidVerbs(); void setNewKidVerbs();
void drawSentenceWord(int object, bool usePrep, bool objInInventory); const byte *getObjectName(int object, int type);
void drawSentenceObject(int object, int type);
void drawSentence(); void drawSentence();
void switchActor(int slot); void switchActor(int slot);
@ -96,6 +101,10 @@ protected:
virtual bool areBoxesNeighbors(int box1nr, int box2nr); virtual bool areBoxesNeighbors(int box1nr, int box2nr);
virtual void setActiveInventory(int object);
bool ifEqualActiveObject2Common(bool ignoreType);
/* Version C64 script opcodes */ /* Version C64 script opcodes */
void o_stopCurrentScript(); void o_stopCurrentScript();
void o_loadSound(); void o_loadSound();
@ -123,8 +132,8 @@ protected:
void o_getBitVar(); void o_getBitVar();
void o_setBitVar(); void o_setBitVar();
void o_doSentence(); void o_doSentence();
void o_unknown2(); void o_ifEqualActiveObject2();
void o_ifActiveObject(); void o_ifNotEqualActiveObject2();
void o_getClosestObjActor(); void o_getClosestObjActor();
void o_printEgo_c64(); void o_printEgo_c64();
void o_print_c64(); void o_print_c64();

View file

@ -44,10 +44,6 @@ protected:
Common::String _sentenceBuf; Common::String _sentenceBuf;
uint16 _inventoryOffset; uint16 _inventoryOffset;
int _activeInventory;
int _activeObject;
int _activeVerb;
public: public:
ScummEngine_v2(OSystem *syst, const DetectorResult &dr); ScummEngine_v2(OSystem *syst, const DetectorResult &dr);
@ -100,6 +96,10 @@ protected:
virtual void setBuiltinCursor(int index); virtual void setBuiltinCursor(int index);
void drawPreposition(int index);
virtual void setActiveInventory(int object);
/* Version 2 script opcodes */ /* Version 2 script opcodes */
void o2_actorFromPos(); void o2_actorFromPos();
void o2_actorOps(); void o2_actorOps();

View file

@ -354,6 +354,15 @@ void ScummEngine_v2::checkV2MouseOver(Common::Point pos) {
} }
} }
void ScummEngine_v2::setActiveInventory(int object) {
runInputScript(kInventoryClickArea, object, 0);
}
void ScummEngine_v0::setActiveInventory(int object) {
// TODO
//_activeInventory = object;
}
void ScummEngine_v2::checkV2Inventory(int x, int y) { void ScummEngine_v2::checkV2Inventory(int x, int y) {
int inventoryArea = (_game.platform == Common::kPlatformNES) ? 48: 32; int inventoryArea = (_game.platform == Common::kPlatformNES) ? 48: 32;
int object = 0; int object = 0;
@ -385,15 +394,8 @@ void ScummEngine_v2::checkV2Inventory(int x, int y) {
return; return;
object = findInventory(_scummVars[VAR_EGO], object + 1 + _inventoryOffset); object = findInventory(_scummVars[VAR_EGO], object + 1 + _inventoryOffset);
if (object > 0)
if (object > 0) { setActiveInventory(object);
if (_game.version == 0) {
_activeInventory = object;
} else {
runInputScript(kInventoryClickArea, object, 0);
}
}
} }
void ScummEngine_v2::redrawV2Inventory() { void ScummEngine_v2::redrawV2Inventory() {
@ -674,15 +676,8 @@ void ScummEngine_v2::checkExecVerbs() {
if (object != -1) { if (object != -1) {
object = findInventory(_scummVars[VAR_EGO], object + 1 + _inventoryOffset); object = findInventory(_scummVars[VAR_EGO], object + 1 + _inventoryOffset);
if (object > 0)
if (object > 0) { setActiveInventory(object);
if (_game.version == 0) {
_activeInventory = object;
} else {
runInputScript(kInventoryClickArea, object, 0);
}
}
return; return;
} }
@ -741,8 +736,11 @@ void ScummEngine_v0::runObject(int obj, int entry) {
// For some reasons, certain objects don't have a "give" script // For some reasons, certain objects don't have a "give" script
} else if (VAR(VAR_ACTIVE_ACTOR) > 0 && VAR(VAR_ACTIVE_ACTOR) < 8) { } else if (VAR(VAR_ACTIVE_ACTOR) > 0 && VAR(VAR_ACTIVE_ACTOR) < 8) {
// TODO
/*
if (_activeInventory) if (_activeInventory)
setOwnerOf(_activeInventory, VAR(VAR_ACTIVE_ACTOR)); setOwnerOf(_activeInventory, VAR(VAR_ACTIVE_ACTOR));
*/
} }
} }
} }
@ -764,16 +762,14 @@ bool ScummEngine_v0::verbMoveToActor(int actor) {
return true; return true;
} }
bool ScummEngine_v0::verbMove(int object, int objectIndex, bool invObject) { bool ScummEngine_v0::verbMove(int object, bool invObject) {
int x, y, dir; int x, y, dir;
Actor *a = derefActor(VAR(VAR_EGO), "verbMove"); Actor *a = derefActor(VAR(VAR_EGO), "verbMove");
if (_currentMode != 3 && _currentMode != 2) if (_currentMode != 3 && _currentMode != 2)
return false; return false;
_v0ObjectIndex = true; getObjectXYPos(object, x, y, dir);
getObjectXYPos(objectIndex, x, y, dir);
_v0ObjectIndex = false;
// Detect distance from target object // Detect distance from target object
int dist = getDist(a->getRealPos().x, a->getRealPos().y, x, y); int dist = getDist(a->getRealPos().x, a->getRealPos().y, x, y);
@ -789,17 +785,13 @@ bool ScummEngine_v0::verbMove(int object, int objectIndex, bool invObject) {
} else { } else {
// Finished walk, are we picking up the item? // Finished walk, are we picking up the item?
if (_verbPickup) { if (_verbPickup) {
int oldActive = _activeObject, oldIndex = _activeObjectIndex; int oldActive = _activeObject;
_activeObject = object; _activeObject = object;
_activeObjectIndex = objectIndex;
_v0ObjectIndex = true;
// Execute pickup // Execute pickup
runObject(objectIndex, 14); runObject(object, 14);
_v0ObjectIndex = false;
_activeObject = oldActive; _activeObject = oldActive;
_activeObjectIndex = oldIndex;
// Finished picking up // Finished picking up
_verbPickup = false; _verbPickup = false;
@ -809,18 +801,19 @@ bool ScummEngine_v0::verbMove(int object, int objectIndex, bool invObject) {
return false; return false;
} }
bool ScummEngine_v0::verbObtain(int obj, int objIndex) { bool ScummEngine_v0::verbObtain(int obj, int objType) {
bool didPickup = false; bool didPickup = false;
int prep;
int where;
int prep, where = whereIsObjectInventory(obj); if (!obj)
if (objIndex == 0)
return false; return false;
where = whereIsObjectInventory(obj);
// Object in inventory ? // Object in inventory ?
if (where != WIO_INVENTORY) { if (where != WIO_INVENTORY) {
_v0ObjectIndex = true; prep = verbPrep();
prep = verbPrep(objIndex);
if (prep == 1 || prep == 4) { if (prep == 1 || prep == 4) {
if (_activeVerb != 13 && _activeVerb != 14) { if (_activeVerb != 13 && _activeVerb != 14) {
@ -839,11 +832,13 @@ bool ScummEngine_v0::verbObtain(int obj, int objIndex) {
} }
//attempt move to object //attempt move to object
if (verbMove(obj, objIndex, false)) if (verbMove(obj, false))
return true; return true;
if (didPickup && (prep == 1 || prep == 4)) if (didPickup && (prep == 1 || prep == 4))
if (_activeVerb != 13 && _activeVerb != 14) { if (_activeVerb != 13 && _activeVerb != 14) {
// TODO
/*
_v0ObjectInInventory = true; _v0ObjectInInventory = true;
if (whereIsObject(obj) == WIO_INVENTORY) if (whereIsObject(obj) == WIO_INVENTORY)
@ -852,27 +847,32 @@ bool ScummEngine_v0::verbObtain(int obj, int objIndex) {
resetSentence(false); resetSentence(false);
_v0ObjectInInventory = false; _v0ObjectInInventory = false;
*/
} }
} }
return false; return false;
} }
int ScummEngine_v0::verbPrep(int object) { int ScummEngine_v0::verbPrep() {
if (!_v0ObjectInInventory) if (_verbs[_activeVerb].prep != 0xFF) {
_v0ObjectIndex = true; return _verbs[_activeVerb].prep;
else } else {
_v0ObjectIndex = false; if (!_v0ObjectInInventory)
_v0ObjectIndex = true;
else
_v0ObjectIndex = false;
byte *ptr = getOBCDFromObject(object); byte *ptr = getOBCDFromObject(_activeObject);
_v0ObjectIndex = false; _v0ObjectIndex = false;
assert(ptr); assert(ptr);
return (*(ptr + 11) >> 5); return (*(ptr + 11) >> 5);
}
} }
bool ScummEngine_v0::verbExecutes(int object, bool inventory) { bool ScummEngine_v0::verbExecutes(int object, bool inventory) {
_v0ObjectInInventory = inventory; _v0ObjectInInventory = inventory;
int prep = verbPrep(object); int prep = verbPrep();
if (prep == 2 || prep == 0) { if (prep == 2 || prep == 0) {
return true; return true;
@ -885,44 +885,34 @@ bool ScummEngine_v0::verbExec() {
int prep = 0; int prep = 0;
int entry = (_currentMode != 0 && _currentMode != 1) ? _activeVerb : 15; int entry = (_currentMode != 0 && _currentMode != 1) ? _activeVerb : 15;
if ((!_activeInvExecute && _activeObject && getObjectIndex(_activeObject) == -1)) { if (_activeObject && getObjectIndex(_activeObject) == -1) {
resetSentence(false); resetSentence(false);
return false; return false;
} }
// Lets try walk to the object // Lets try walk to the object
if (_activeObject && _activeObjectIndex && !_activeObjectObtained && _currentMode != 0) { if (_activeObject && !_activeObjectObtained && _currentMode != 0) {
prep = verbPrep(_activeObjectIndex); prep = verbPrep();
if (verbObtain(_activeObject, _activeObjectIndex)) if (verbObtain(_activeObject, _activeObjectType))
return true; return true;
_activeObjectObtained = true; _activeObjectObtained = true;
} }
// Attempt to obtain/reach object2 // Attempt to obtain/reach object2
if (_activeObject2 && _activeObject2Index && !_activeObject2Obtained && _currentMode != 0) { if (_activeObject2 && !_activeObject2Obtained && _currentMode != 0) {
prep = verbPrep(_activeObject2Index);
_v0ObjectInInventory = false; _v0ObjectInInventory = false;
if (verbObtain(_activeObject2, _activeObject2Index)) if (verbObtain(_activeObject2, _activeObject2Type))
return true; return true;
if (prep != 1 && prep != 4) {
_activeInventory = _activeObject;
_activeObject = _activeObject2;
_activeObjectIndex = _activeObject2Index;
_activeObject2 = 0;
_activeObject2Index = 0;
}
_activeObject2Obtained = true; _activeObject2Obtained = true;
} }
// Give-To // Give-To
if (_activeVerb == 3 && _activeInventory && _activeActor) { if (_activeVerb == 3 && _activeObject && _activeObject2 && _activeObject2Type == kObjectTypeActor) {
// FIXME: Actors need to turn and face each other // FIXME: Actors need to turn and face each other
if (verbMoveToActor(_activeActor)) { if (verbMoveToActor(_activeObject2)) {
// Ignore verbs? // Ignore verbs?
Actor *a = derefActor(VAR(VAR_EGO), "verbExec"); Actor *a = derefActor(VAR(VAR_EGO), "verbExec");
if (((ActorC64 *)a)->_miscflags & 0x40) { if (((ActorC64 *)a)->_miscflags & 0x40) {
@ -933,8 +923,8 @@ bool ScummEngine_v0::verbExec() {
return true; return true;
} }
_v0ObjectInInventory = true; _v0ObjectInInventory = true;
VAR(VAR_ACTIVE_ACTOR) = _activeActor; VAR(VAR_ACTIVE_ACTOR) = _activeObject2;
runObject(_activeInventory , 3); runObject(_activeObject , 3);
_v0ObjectInInventory = false; _v0ObjectInInventory = false;
resetSentence(false); resetSentence(false);
@ -942,10 +932,8 @@ bool ScummEngine_v0::verbExec() {
} }
// Where we performing an action on an actor? // Where we performing an action on an actor?
if (_activeActor) { if (_activeObject2 && _activeObject2Type == kObjectTypeActor) {
_v0ObjectIndex = true; runObject(_activeObject2, entry);
runObject(_activeActor, entry);
_v0ObjectIndex = false;
_verbExecuting = false; _verbExecuting = false;
resetSentence(false); resetSentence(false);
@ -953,10 +941,8 @@ bool ScummEngine_v0::verbExec() {
} }
// If we've finished walking (now near target), execute the action // If we've finished walking (now near target), execute the action
if (_activeObject && _activeObjectIndex && verbPrep(_activeObjectIndex) == 2) { if (_activeObject && verbPrep() == 2) {
_v0ObjectIndex = true; runObject(_activeObject, entry);
runObject(_activeObjectIndex, entry);
_v0ObjectIndex = false;
_verbExecuting = false; _verbExecuting = false;
if ((_currentMode == 3 || _currentMode == 2) && _activeVerb == 13) if ((_currentMode == 3 || _currentMode == 2) && _activeVerb == 13)
@ -967,10 +953,9 @@ bool ScummEngine_v0::verbExec() {
} }
// We acted on an inventory item // We acted on an inventory item
if (_activeInventory && verbExecutes(_activeInventory, true) && _activeVerb != 3) { if (/*_activeInventory && verbExecutes(_activeInventory, true) &&*/ _activeVerb != 3) {
_v0ObjectInInventory = true; _v0ObjectInInventory = true;
_activeObject = _activeInventory; runObject(_activeObject/*2*/, _activeVerb);
runObject(_activeInventory, _activeVerb);
_verbExecuting = false; _verbExecuting = false;
@ -985,14 +970,13 @@ bool ScummEngine_v0::verbExec() {
// Item not in inventory is executed // Item not in inventory is executed
if (_activeObject) { if (_activeObject) {
_v0ObjectIndex = true; runObject(_activeObject, entry);
runObject(_activeObjectIndex, entry); } else if (/*_activeInventory*/false) {
_v0ObjectIndex = false; #if 0
} else if (_activeInventory) {
// Not sure this is the correct way to do this, // Not sure this is the correct way to do this,
// however its working for most situations - segra // however its working for most situations - segra
if (verbExecutes(_activeInventory, true) == false) { if (verbExecutes(_activeInventory, true) == false) {
if (_activeObject2 && _activeObject2Inv && verbExecutes(_activeObject2, true)) { if (_activeObject2 && _activeObject2Type == kObjectTypeInventory && verbExecutes(_activeObject2, true)) {
_v0ObjectInInventory = true; _v0ObjectInInventory = true;
_activeObject = _activeInventory; _activeObject = _activeInventory;
@ -1013,6 +997,7 @@ bool ScummEngine_v0::verbExec() {
_v0ObjectInInventory = true; _v0ObjectInInventory = true;
runObject(_activeInventory, _activeVerb); runObject(_activeInventory, _activeVerb);
} }
#endif
} }
_verbExecuting = false; _verbExecuting = false;
@ -1060,9 +1045,7 @@ void ScummEngine_v0::checkExecVerbs() {
// What-Is selected, any object we hover over is selected, on mouse press we set to WalkTo // What-Is selected, any object we hover over is selected, on mouse press we set to WalkTo
if (_activeVerb == 15) { if (_activeVerb == 15) {
int obj = findObject(_virtualMouse.x, _virtualMouse.y); int obj = findObject(_virtualMouse.x, _virtualMouse.y);
int objIdx = findObjectIndex(_virtualMouse.x, _virtualMouse.y);
_activeObject = obj; _activeObject = obj;
_activeObjectIndex = objIdx;
if ((_mouseAndKeyboardStat & MBS_MOUSE_MASK)) if ((_mouseAndKeyboardStat & MBS_MOUSE_MASK))
_activeVerb = 13; // Walk-To _activeVerb = 13; // Walk-To
@ -1080,11 +1063,13 @@ void ScummEngine_v0::checkExecVerbs() {
if (zone->number == kVerbVirtScreen && _mouse.y <= zone->topline + 8) { if (zone->number == kVerbVirtScreen && _mouse.y <= zone->topline + 8) {
// TODO // TODO
} else if (zone->number == kVerbVirtScreen && _mouse.y > zone->topline + 32) { } else if (zone->number == kVerbVirtScreen && _mouse.y > zone->topline + 32) {
#if 0
int prevInventory = _activeInventory; int prevInventory = _activeInventory;
#endif
int invOff = _inventoryOffset; int invOff = _inventoryOffset;
// GIVE: actor must be selected (not possible via inventory) // GIVE: actor must be selected (not possible via inventory)
if ((_activeVerb == 3) && (_activeObject || _activeInventory)) if ((_activeVerb == 3) && _activeObject)
return; return;
// Click into V2 inventory // Click into V2 inventory
@ -1094,31 +1079,16 @@ void ScummEngine_v0::checkExecVerbs() {
if (invOff != _inventoryOffset) if (invOff != _inventoryOffset)
return; return;
#if 0
// No inventory selected? // No inventory selected?
if (!_activeInventory) if (!_activeInventory)
return; return;
// Did we just change the selected inventory item? // Did we just change the selected inventory item?
if (prevInventory && prevInventory != _activeInventory && _activeInventory != _activeObject2) { if (prevInventory && prevInventory != _activeInventory && _activeInventory != _activeObject2) {
_v0ObjectInInventory = true;
int prep = verbPrep(_activeInventory);
_v0ObjectInInventory = true;
int prep2 = verbPrep(prevInventory);
// Should the new inventory object remain as the secondary selected object
// Or should the new inventory object become primary?
if (prep != prep2 || prep != 1) {
if (prep == 1 || prep == 3) {
int tmp = _activeInventory;
_activeInventory = prevInventory;
prevInventory = tmp;
}
}
// Setup object2 // Setup object2
_activeObject = 0; _activeObject = 0;
_activeInvExecute = true; _activeObject2Type = kObjectTypeInventory;
_activeObject2Inv = true;
_activeObject2 = _activeInventory; _activeObject2 = _activeInventory;
_activeInventory = prevInventory; _activeInventory = prevInventory;
return; return;
@ -1132,14 +1102,14 @@ void ScummEngine_v0::checkExecVerbs() {
if (prevInventory != _activeInventory) if (prevInventory != _activeInventory)
if (!_activeObject2 || prevInventory != _activeObject2) if (!_activeObject2 || prevInventory != _activeObject2)
return; return;
#endif
if (_activeVerb == 11 && !(((_activeObject || _activeInventory)) || !_activeObject2)) if (_activeVerb == 11 && !(_activeObject || !_activeObject2))
return; return;
} else { } else {
int over = findVerbAtPos(_mouse.x, _mouse.y); int over = findVerbAtPos(_mouse.x, _mouse.y);
int act = getActorFromPos(_virtualMouse.x, _virtualMouse.y); int act = getActorFromPos(_virtualMouse.x, _virtualMouse.y);
int obj = findObject(_virtualMouse.x, _virtualMouse.y); int obj = findObject(_virtualMouse.x, _virtualMouse.y);
int objIdx = findObjectIndex(_virtualMouse.x, _virtualMouse.y);
if (a->_miscflags & 0x80) { if (a->_miscflags & 0x80) {
if (_activeVerb != 7 && over != 7) { if (_activeVerb != 7 && over != 7) {
@ -1207,15 +1177,15 @@ void ScummEngine_v0::checkExecVerbs() {
// Only allowing targetting actors if its the GIVE verb // Only allowing targetting actors if its the GIVE verb
if (_activeVerb == 3) { if (_activeVerb == 3) {
if (_activeObject || _activeInventory) { if (_activeObject) {
// Once selected the object cannot be changed // Once selected the object cannot be changed
obj = 0; obj = 0;
objIdx = 0;
// Different actor selected? // Different actor selected?
if (act) { if (act) {
if (_activeActor != act) { if (_activeObject2 != act || _activeObject2Type != kObjectTypeActor) {
_activeActor = act; _activeObject2 = act;
_activeObject2Type = kObjectTypeActor;
return; return;
} }
} else { } else {
@ -1230,24 +1200,15 @@ void ScummEngine_v0::checkExecVerbs() {
} }
if (obj && obj != _activeObject) { if (obj && obj != _activeObject) {
if (!_activeObject)
if (_activeInventory)
_activeInvExecute = true;
// USE / UNLOCK // USE / UNLOCK
if (_activeVerb == 11 || _activeVerb == 8) { if (_activeVerb == 11 || _activeVerb == 8) {
if (obj != _activeObject && obj != _activeObject2) { if (obj != _activeObject && obj != _activeObject2) {
if (_activeObject || _activeInventory) { if (!_activeObject) {
//verbPrep(
}
if (!_activeObject || _activeInventory) {
_activeObject = obj; _activeObject = obj;
_activeObjectIndex = objIdx;
return; return;
} else { } else {
if (_activeObject2 != obj) { if (_activeObject2 != obj) {
_activeObject2 = obj; _activeObject2 = obj;
_activeObject2Index = objIdx;
return; return;
} }
} }
@ -1256,8 +1217,6 @@ void ScummEngine_v0::checkExecVerbs() {
a->stopActorMoving(); a->stopActorMoving();
_activeObject = obj; _activeObject = obj;
_activeObjectIndex = objIdx;
if (_activeVerb != 13) if (_activeVerb != 13)
return; return;