From 2acd5a823984eccd341b4528523016f9cd539999 Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Mon, 26 Dec 2011 13:54:53 +0100 Subject: SCUMM: Fix sound playback if fast-mode is on Sounds are played that fast in fast-mode that the queue gets stuck. This is just a workaround and only fixes the symptoms. Check the queue handling for a correct fix. --- engines/scumm/actor.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'engines/scumm') diff --git a/engines/scumm/actor.cpp b/engines/scumm/actor.cpp index eb23c30ebe..4a92d6d81a 100644 --- a/engines/scumm/actor.cpp +++ b/engines/scumm/actor.cpp @@ -1355,7 +1355,10 @@ void ScummEngine::playActorSounds() { } else { sound = _actors[i]->_sound[0]; } - _sound->addSoundToQueue(sound); + // fast mode will flood the queue with walk sounds + if (!_fastMode) { + _sound->addSoundToQueue(sound); + } for (j = 1; j < _numActors; j++) { _actors[j]->_cost.soundCounter = 0; } -- cgit v1.2.3 From 05f853edd7e1b80d25678ccd38c23ab3c171adab Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Mon, 26 Dec 2011 20:58:03 +0100 Subject: SCUMM: Fix meteor actor index - Now the correct actor name is shown with "give ... to meteor". Formerly the name was "". - Add actor names that do not have a string assigned --- engines/scumm/actor.cpp | 44 +++++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 21 deletions(-) (limited to 'engines/scumm') diff --git a/engines/scumm/actor.cpp b/engines/scumm/actor.cpp index 4a92d6d81a..70e051edfd 100644 --- a/engines/scumm/actor.cpp +++ b/engines/scumm/actor.cpp @@ -1323,23 +1323,23 @@ static const byte v0ActorSounds[24] = { 0x06, // Bernard 0x06, // Wendy 0x00, // Jeff - 0x46, // ??? + 0x46, // Radiation Suit 0x06, // Dr Fred 0x06, // Nurse Edna 0x06, // Weird Ed 0x06, // Dead Cousin Ted 0xFF, // Purple Tentacle 0xFF, // Green Tentacle - 0x06, // Meteor - 0xC0, // Plant - 0x06, // ??? - 0x06, // ??? - 0x00, // ??? - 0xC0, // ??? - 0xC0, // ??? - 0x00, // ??? - 0x06, // Sandy - 0x06, // ??? + 0x06, // Meteor police + 0xC0, // Meteor + 0x06, // Mark Eteer + 0x06, // Talkshow Host + 0x00, // Plant + 0xC0, // Meteor Radiation + 0xC0, // Edsel (small, outro) + 0x00, // Meteor (small, intro) + 0x06, // Sandy (Lab) + 0x06, // Sandy (Cut-Scene) }; /* Used in Scumm v5 only. Play sounds associated with actors */ @@ -2298,22 +2298,23 @@ static const char *const v0ActorNames_English[25] = { "Bernard", "Wendy", "Jeff", - "", + "", // Radiation Suit "Dr Fred", "Nurse Edna", "Weird Ed", "Dead Cousin Ted", "Purple Tentacle", "Green Tentacle", + "", // Meteor Police "Meteor", - "", - "", - "", + "", // Mark Eteer + "", // Talkshow Host "Plant", - "", - "", - "", - "Sandy" + "", // Meteor Radiation + "", // Edsel (small, outro) + "", // Meteor (small, intro) + "Sandy", // (Lab) + "", // Sandy (Cut-Scene) }; static const char *const v0ActorNames_German[25] = { @@ -2331,15 +2332,16 @@ static const char *const v0ActorNames_German[25] = { "Ted", "Lila Tentakel", "Gr_miscflags & 0x80) { if (_activeVerb != 7 && over != 7) { _activeVerb = 0; @@ -1208,14 +1205,27 @@ void ScummEngine_v0::checkExecVerbs() { return; } - // Only allowing targetting actors if its the GIVE/USE verb - if (_activeVerb == 3 || _activeVerb == 11) { - // Different actor selected? - if (act) { - if (_activeActor != act) { - _activeActor = act; + // Only allowing targetting actors if its the GIVE verb + if (_activeVerb == 3) { + if (_activeObject || _activeInventory) { + // Once selected the object cannot be changed + obj = 0; + objIdx = 0; + + // Different actor selected? + if (act) { + if (_activeActor != act) { + _activeActor = act; + return; + } + } else { return; } + } else { + // An object has to be selected first + act = 0; + if (!obj) + return; } } @@ -1224,9 +1234,12 @@ void ScummEngine_v0::checkExecVerbs() { if (_activeInventory) _activeInvExecute = true; - // USE + // USE / UNLOCK if (_activeVerb == 11 || _activeVerb == 8) { - if (obj != _activeObject || obj != _activeObject2) { + if (obj != _activeObject && obj != _activeObject2) { + if (_activeObject || _activeInventory) { + //verbPrep( + } if (!_activeObject || _activeInventory) { _activeObject = obj; _activeObjectIndex = objIdx; -- cgit v1.2.3 From c9ae5f383807c1f40088fc042d470bf8ba74f1da Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Tue, 27 Dec 2011 08:47:00 +0100 Subject: SCUMM: Fix pickupObject() --- engines/scumm/script_v0.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'engines/scumm') diff --git a/engines/scumm/script_v0.cpp b/engines/scumm/script_v0.cpp index 71dfbc6a82..cc59e608fd 100644 --- a/engines/scumm/script_v0.cpp +++ b/engines/scumm/script_v0.cpp @@ -777,7 +777,12 @@ void ScummEngine_v0::o_putActorAtObject() { void ScummEngine_v0::o_pickupObject() { int obj = fetchScriptByte(); if (obj == 0) { - obj = _activeObject; + if (_activeObject) { + obj = _activeObject; + } else { + // might happen if an inventory item was picked again + return; + } } if (obj < 1) { -- cgit v1.2.3 From a79f224c23f1b0fa4d9850a032e0adc0d72619f7 Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Tue, 3 Jan 2012 22:10:50 +0100 Subject: 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() --- engines/scumm/object.cpp | 22 ++--- engines/scumm/object.h | 7 +- engines/scumm/saveload.cpp | 2 +- engines/scumm/script_v0.cpp | 161 +++++++++++------------------------- engines/scumm/script_v2.cpp | 68 ++++++++------- engines/scumm/scumm.cpp | 12 +-- engines/scumm/scumm_v0.h | 37 +++++---- engines/scumm/scumm_v2.h | 8 +- engines/scumm/verbs.cpp | 197 ++++++++++++++++++-------------------------- 9 files changed, 209 insertions(+), 305 deletions(-) (limited to 'engines/scumm') diff --git a/engines/scumm/object.cpp b/engines/scumm/object.cpp index da238dc517..a9e2a76345 100644 --- a/engines/scumm/object.cpp +++ b/engines/scumm/object.cpp @@ -316,7 +316,7 @@ int ScummEngine::getObjectIndex(int object) const { for (i = (_numLocalObjects-1); i > 0; i--) { if (_game.version == 0 ) - if( _objs[i].flags != _v0ObjectFlag ) + if( _objs[i].obj_type != _v0ObjectFlag ) continue; if (_objs[i].obj_nr == object) @@ -492,14 +492,6 @@ int ScummEngine::getObjActToObjActDist(int a, int b) { 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 i, b; byte a; @@ -510,7 +502,7 @@ int ScummEngine::findObject(int x, int y) { continue; if (_game.version == 0) { - if (_objs[i].flags == 0 && _objs[i].state & kObjectStateUntouchable) + if (_objs[i].obj_type == 0 && _objs[i].state & kObjectStateUntouchable) continue; } else { 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) { // MMC64: Set the object search flag if (_game.version == 0) - _v0ObjectFlag = _objs[i].flags; + _v0ObjectFlag = _objs[i].obj_type; if (_game.version == 0 && _v0ObjectIndex) return i; else @@ -844,7 +836,7 @@ void ScummEngine_v3old::resetRoomObjects() { char buf[32]; sprintf(buf, "roomobj-%d-", _roomResource); 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); } @@ -912,7 +904,7 @@ void ScummEngine_v0::resetRoomObject(ObjectData *od, const byte *room, const byt ptr -= 2; od->obj_nr = *(ptr + 6); - od->flags = *(ptr + 7); + od->obj_type = *(ptr + 7); od->x_pos = *(ptr + 8) * 8; od->y_pos = ((*(ptr + 9)) & 0x7F) * 8; @@ -1072,8 +1064,8 @@ void ScummEngine::updateObjectStates() { int i; ObjectData *od = &_objs[1]; for (i = 1; i < _numLocalObjects; i++, od++) { - // V0 MM, Room objects with Flag == 1 are objects with 'no-state' (room specific objects, non-pickup) - if (_game.version == 0 && od->flags == 1) + // V0 MM, objects with type == 1 are room objects (room specific objects, non-pickup) + if (_game.version == 0 && od->obj_type == 1) continue; if (od->obj_nr > 0) diff --git a/engines/scumm/object.h b/engines/scumm/object.h index cdf8b09e6f..edbff38355 100644 --- a/engines/scumm/object.h +++ b/engines/scumm/object.h @@ -62,7 +62,12 @@ struct ObjectData { byte parentstate; byte state; 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 diff --git a/engines/scumm/saveload.cpp b/engines/scumm/saveload.cpp index 38dbd8270a..17135623e2 100644 --- a/engines/scumm/saveload.cpp +++ b/engines/scumm/saveload.cpp @@ -822,7 +822,7 @@ void ScummEngine::saveOrLoad(Serializer *s) { MKLINE(ObjectData, parent, sleByte, VER(8)), MKLINE(ObjectData, state, sleByte, VER(8)), MKLINE(ObjectData, fl_object_index, sleByte, VER(8)), - MKLINE(ObjectData, flags, sleByte, VER(46)), + MKLINE(ObjectData, extra, sleByte, VER(46)), MKEND() }; diff --git a/engines/scumm/script_v0.cpp b/engines/scumm/script_v0.cpp index cc59e608fd..07923dea6a 100644 --- a/engines/scumm/script_v0.cpp +++ b/engines/scumm/script_v0.cpp @@ -79,7 +79,7 @@ void ScummEngine_v0::setupOpcodes() { OPCODE(0x22, o4_saveLoadGame); OPCODE(0x23, o_stopCurrentScript); /* 24 */ - OPCODE(0x24, o_unknown2); + OPCODE(0x24, o_ifNotEqualActiveObject2); OPCODE(0x25, o5_loadRoom); OPCODE(0x26, o_getClosestObjActor); OPCODE(0x27, o2_getActorY); @@ -159,7 +159,7 @@ void ScummEngine_v0::setupOpcodes() { OPCODE(0x62, o2_stopScript); OPCODE(0x63, o_stopCurrentScript); /* 64 */ - OPCODE(0x64, o_ifActiveObject); + OPCODE(0x64, o_ifEqualActiveObject2); OPCODE(0x65, o_stopCurrentScript); OPCODE(0x66, o_getClosestObjActor); OPCODE(0x67, o5_getActorFacing); @@ -239,7 +239,7 @@ void ScummEngine_v0::setupOpcodes() { OPCODE(0xa2, o4_saveLoadGame); OPCODE(0xa3, o_stopCurrentScript); /* A4 */ - OPCODE(0xa4, o_unknown2); + OPCODE(0xa4, o_ifNotEqualActiveObject2); OPCODE(0xa5, o5_loadRoom); OPCODE(0xa6, o_stopCurrentScript); OPCODE(0xa7, o2_getActorY); @@ -319,7 +319,7 @@ void ScummEngine_v0::setupOpcodes() { OPCODE(0xe2, o2_stopScript); OPCODE(0xe3, o_stopCurrentScript); /* E4 */ - OPCODE(0xe4, o_ifActiveObject); + OPCODE(0xe4, o_ifEqualActiveObject2); OPCODE(0xe5, o_loadRoomWithEgo); OPCODE(0xe6, o_stopCurrentScript); OPCODE(0xe7, o5_getActorFacing); @@ -406,130 +406,67 @@ void ScummEngine_v0::decodeParseString() { actorTalk(buffer); } -void ScummEngine_v0::drawSentenceWord(int object, bool usePrep, bool objInInventory) { +const byte *ScummEngine_v0::getObjectName(int object, int type) { const byte *temp; - int sentencePrep = 0; - // If object not in inventory, we except an index - if (!objInInventory) - _v0ObjectIndex = true; - else + if (type == kObjectTypeInventory) _v0ObjectInInventory = true; temp = getObjOrActorName(object); _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) { _sentenceBuf += " "; _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() { Common::Rect sentenceline; - bool inventoryFirst = false; if (!(_userState & 32)) return; - // Current Verb, Walk/Use + // Current Verb + if (_activeVerb == 0) + _activeVerb = 13; if (getResourceAddress(rtVerb, _activeVerb)) { _sentenceBuf = (char *)getResourceAddress(rtVerb, _activeVerb); } else { return; } - // If using inventory first, draw it first - if (_activeInvExecute && _activeInventory) { - drawSentenceWord(_activeInventory, true, true); - } else { - // Not using inventory, use selected object - if (_activeObject) - drawSentenceWord(_activeObjectIndex, true, false); - else - inventoryFirst = true; - } - - - // Draw the inventory? - if (_activeInventory > 0 && _activeObject2 == 0) { - // Only if inventory isnt first (it will already be drawn by now) - if (!_activeInvExecute) { - drawSentenceWord(_activeInventory, inventoryFirst, true); - } else { - // Draw the active object, which could be inventory based, or room based - if (_activeObject && !_activeObjectIndex) { - drawSentenceWord(_activeObject, inventoryFirst, true); - } else // Room based - 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); + if (_activeObject) { + // Draw the 1st active object + drawSentenceObject(_activeObject, _activeObjectType); + + // Append verb preposition + int sentencePrep = verbPrep(); + if (sentencePrep) { + drawPreposition(sentencePrep); + + // Draw the 2nd active object + if (_activeObject2) { + // 2nd Object is an actor + if (_activeObject2Type == kObjectTypeActor) { + Actor *a = derefActor(_activeObject2, ""); + _sentenceBuf += " "; + _sentenceBuf += (const char *)a->getActorName(); + // 2nd Object is an inventory or room object + } else { + drawSentenceObject(_activeObject2, _activeObject2Type); + } + } } } - // Draw the active actor - if (_activeActor) { - Actor *a = derefActor(_activeActor, ""); - - _sentenceBuf += " "; - _sentenceBuf += (const char *)a->getActorName(); - } - _string[2].charset = 1; _string[2].ypos = _virtscr[kVerbVirtScreen].topline; _string[2].xpos = 0; @@ -890,15 +827,21 @@ void ScummEngine_v0::o_doSentence() { runObjectScript(obj, entry, false, false, NULL); } -void ScummEngine_v0::o_unknown2() { - byte var1 = fetchScriptByte(); - error("STUB: o_unknown2(%d)", var1); +bool ScummEngine_v0::ifEqualActiveObject2Common(bool inventoryObject) { + byte obj = fetchScriptByte(); + if (!inventoryObject || (_activeObject2Type == kObjectTypeInventory)) + return (obj == _activeObject2); + return false; } -void ScummEngine_v0::o_ifActiveObject() { - byte obj = fetchScriptByte(); +void ScummEngine_v0::o_ifEqualActiveObject2() { + 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() { @@ -1004,19 +947,15 @@ void ScummEngine_v0::resetSentence(bool walking) { // Then reset all active objects (stops the radio crash, bug #3077966) if (!walking || !(_userState & 32)) { _v0ObjectFlag = 0; - _activeInventory = 0; _activeObject = 0; _activeObject2 = 0; - _activeObjectIndex = 0; - _activeObject2Index = 0; } _verbExecuting = false; _verbPickup = false; - _activeActor = 0; - _activeInvExecute = false; - _activeObject2Inv = false; + _activeObjectType = kObjectTypeRoom; + _activeObject2Type = kObjectTypeRoom; _activeObjectObtained = false; _activeObject2Obtained = false; } diff --git a/engines/scumm/script_v2.cpp b/engines/scumm/script_v2.cpp index edb046d571..76f6b02eb7 100644 --- a/engines/scumm/script_v2.cpp +++ b/engines/scumm/script_v2.cpp @@ -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() { Common::Rect sentenceline; const byte *temp; @@ -986,38 +1021,7 @@ void ScummEngine_v2::o2_drawSentence() { } if (0 < VAR(VAR_SENTENCE_PREPOSITION) && VAR(VAR_SENTENCE_PREPOSITION) <= 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. - 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)]; + drawPreposition(VAR(VAR_SENTENCE_PREPOSITION)); } if (VAR(VAR_SENTENCE_OBJECT2) > 0) { diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp index d3cc218cd3..d3dc702395 100644 --- a/engines/scumm/scumm.cpp +++ b/engines/scumm/scumm.cpp @@ -701,10 +701,6 @@ ScummEngine_v2::ScummEngine_v2(OSystem *syst, const DetectorResult &dr) _inventoryOffset = 0; - _activeInventory = 0; - _activeObject = 0; - _activeVerb = 0; - VAR_SENTENCE_VERB = 0xFF; VAR_SENTENCE_OBJECT1 = 0xFF; VAR_SENTENCE_OBJECT2 = 0xFF; @@ -723,11 +719,11 @@ ScummEngine_v0::ScummEngine_v0(OSystem *syst, const DetectorResult &dr) _verbPickup = false; _currentMode = 0; + _activeVerb = 0; + _activeObject = 0; _activeObject2 = 0; - _activeObjectIndex = 0; - _activeObject2Index = 0; - _activeInvExecute = false; - _activeObject2Inv = false; + _activeObjectType = kObjectTypeRoom; + _activeObject2Type = kObjectTypeRoom; _activeObjectObtained = false; _activeObject2Obtained = false; diff --git a/engines/scumm/scumm_v0.h b/engines/scumm/scumm_v0.h index af481df0e0..d9629948fe 100644 --- a/engines/scumm/scumm_v0.h +++ b/engines/scumm/scumm_v0.h @@ -31,22 +31,27 @@ namespace Scumm { * Engine for Apple II and Commodore 64 versions of Maniac Mansion */ class ScummEngine_v0 : public ScummEngine_v2 { +protected: + enum ObjectType { + kObjectTypeInventory = 0, + kObjectTypeRoom = 1, + kObjectTypeActor = 2 + }; + protected: byte _currentMode; bool _verbExecuting; // is a verb executing 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 _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 _activeObject2Obtained; // collected _activeObject2? - int _activeObjectIndex; - int _activeObject2Index; - public: ScummEngine_v0(OSystem *syst, const DetectorResult &dr); @@ -68,21 +73,21 @@ protected: virtual void saveOrLoad(Serializer *s); // V0 MM Verb commands - int verbPrep(int object); - bool verbMove(int object, int objectIndex, bool invObject); + int verbPrep(); + bool verbMove(int object, bool invObject); bool verbMoveToActor(int actor); - bool verbObtain(int object, int objIndex); + bool verbObtain(int object, int objType); bool verbExecutes(int object, bool inventory = false); bool verbExec(); - int findObjectIndex(int x, int y); - virtual void checkExecVerbs(); virtual void handleMouseOver(bool updateInventory); void resetVerbs(); 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 switchActor(int slot); @@ -96,6 +101,10 @@ protected: virtual bool areBoxesNeighbors(int box1nr, int box2nr); + virtual void setActiveInventory(int object); + + bool ifEqualActiveObject2Common(bool ignoreType); + /* Version C64 script opcodes */ void o_stopCurrentScript(); void o_loadSound(); @@ -123,8 +132,8 @@ protected: void o_getBitVar(); void o_setBitVar(); void o_doSentence(); - void o_unknown2(); - void o_ifActiveObject(); + void o_ifEqualActiveObject2(); + void o_ifNotEqualActiveObject2(); void o_getClosestObjActor(); void o_printEgo_c64(); void o_print_c64(); diff --git a/engines/scumm/scumm_v2.h b/engines/scumm/scumm_v2.h index 47c5fa2626..1f41283852 100644 --- a/engines/scumm/scumm_v2.h +++ b/engines/scumm/scumm_v2.h @@ -44,10 +44,6 @@ protected: Common::String _sentenceBuf; uint16 _inventoryOffset; - int _activeInventory; - int _activeObject; - int _activeVerb; - public: ScummEngine_v2(OSystem *syst, const DetectorResult &dr); @@ -100,6 +96,10 @@ protected: virtual void setBuiltinCursor(int index); + void drawPreposition(int index); + + virtual void setActiveInventory(int object); + /* Version 2 script opcodes */ void o2_actorFromPos(); void o2_actorOps(); diff --git a/engines/scumm/verbs.cpp b/engines/scumm/verbs.cpp index 3398cca05c..1bb0c0a34d 100644 --- a/engines/scumm/verbs.cpp +++ b/engines/scumm/verbs.cpp @@ -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) { int inventoryArea = (_game.platform == Common::kPlatformNES) ? 48: 32; int object = 0; @@ -385,15 +394,8 @@ void ScummEngine_v2::checkV2Inventory(int x, int y) { return; object = findInventory(_scummVars[VAR_EGO], object + 1 + _inventoryOffset); - - if (object > 0) { - if (_game.version == 0) { - _activeInventory = object; - - } else { - runInputScript(kInventoryClickArea, object, 0); - } - } + if (object > 0) + setActiveInventory(object); } void ScummEngine_v2::redrawV2Inventory() { @@ -674,15 +676,8 @@ void ScummEngine_v2::checkExecVerbs() { if (object != -1) { object = findInventory(_scummVars[VAR_EGO], object + 1 + _inventoryOffset); - - if (object > 0) { - if (_game.version == 0) { - _activeInventory = object; - - } else { - runInputScript(kInventoryClickArea, object, 0); - } - } + if (object > 0) + setActiveInventory(object); return; } @@ -741,8 +736,11 @@ void ScummEngine_v0::runObject(int obj, int entry) { // 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)); + */ } } } @@ -764,16 +762,14 @@ bool ScummEngine_v0::verbMoveToActor(int actor) { return true; } -bool ScummEngine_v0::verbMove(int object, int objectIndex, bool invObject) { +bool ScummEngine_v0::verbMove(int object, bool invObject) { int x, y, dir; Actor *a = derefActor(VAR(VAR_EGO), "verbMove"); if (_currentMode != 3 && _currentMode != 2) return false; - _v0ObjectIndex = true; - getObjectXYPos(objectIndex, x, y, dir); - _v0ObjectIndex = false; + getObjectXYPos(object, x, y, dir); // Detect distance from target object 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 { // Finished walk, are we picking up the item? if (_verbPickup) { - int oldActive = _activeObject, oldIndex = _activeObjectIndex; + int oldActive = _activeObject; _activeObject = object; - _activeObjectIndex = objectIndex; - _v0ObjectIndex = true; // Execute pickup - runObject(objectIndex, 14); - _v0ObjectIndex = false; + runObject(object, 14); _activeObject = oldActive; - _activeObjectIndex = oldIndex; // Finished picking up _verbPickup = false; @@ -809,18 +801,19 @@ bool ScummEngine_v0::verbMove(int object, int objectIndex, bool invObject) { return false; } -bool ScummEngine_v0::verbObtain(int obj, int objIndex) { +bool ScummEngine_v0::verbObtain(int obj, int objType) { bool didPickup = false; + int prep; + int where; - int prep, where = whereIsObjectInventory(obj); - - if (objIndex == 0) + if (!obj) return false; + where = whereIsObjectInventory(obj); + // Object in inventory ? if (where != WIO_INVENTORY) { - _v0ObjectIndex = true; - prep = verbPrep(objIndex); + prep = verbPrep(); if (prep == 1 || prep == 4) { if (_activeVerb != 13 && _activeVerb != 14) { @@ -839,11 +832,13 @@ bool ScummEngine_v0::verbObtain(int obj, int objIndex) { } //attempt move to object - if (verbMove(obj, objIndex, false)) + if (verbMove(obj, false)) return true; if (didPickup && (prep == 1 || prep == 4)) if (_activeVerb != 13 && _activeVerb != 14) { + // TODO + /* _v0ObjectInInventory = true; if (whereIsObject(obj) == WIO_INVENTORY) @@ -852,27 +847,32 @@ bool ScummEngine_v0::verbObtain(int obj, int objIndex) { resetSentence(false); _v0ObjectInInventory = false; + */ } } return false; } -int ScummEngine_v0::verbPrep(int object) { - if (!_v0ObjectInInventory) - _v0ObjectIndex = true; - else - _v0ObjectIndex = false; +int ScummEngine_v0::verbPrep() { + if (_verbs[_activeVerb].prep != 0xFF) { + return _verbs[_activeVerb].prep; + } else { + if (!_v0ObjectInInventory) + _v0ObjectIndex = true; + else + _v0ObjectIndex = false; - byte *ptr = getOBCDFromObject(object); - _v0ObjectIndex = false; - assert(ptr); - return (*(ptr + 11) >> 5); + byte *ptr = getOBCDFromObject(_activeObject); + _v0ObjectIndex = false; + assert(ptr); + return (*(ptr + 11) >> 5); + } } bool ScummEngine_v0::verbExecutes(int object, bool inventory) { _v0ObjectInInventory = inventory; - int prep = verbPrep(object); + int prep = verbPrep(); if (prep == 2 || prep == 0) { return true; @@ -885,44 +885,34 @@ bool ScummEngine_v0::verbExec() { int prep = 0; int entry = (_currentMode != 0 && _currentMode != 1) ? _activeVerb : 15; - if ((!_activeInvExecute && _activeObject && getObjectIndex(_activeObject) == -1)) { + if (_activeObject && getObjectIndex(_activeObject) == -1) { resetSentence(false); return false; } // Lets try walk to the object - if (_activeObject && _activeObjectIndex && !_activeObjectObtained && _currentMode != 0) { - prep = verbPrep(_activeObjectIndex); + if (_activeObject && !_activeObjectObtained && _currentMode != 0) { + prep = verbPrep(); - if (verbObtain(_activeObject, _activeObjectIndex)) + if (verbObtain(_activeObject, _activeObjectType)) return true; _activeObjectObtained = true; } // Attempt to obtain/reach object2 - if (_activeObject2 && _activeObject2Index && !_activeObject2Obtained && _currentMode != 0) { - prep = verbPrep(_activeObject2Index); - + if (_activeObject2 && !_activeObject2Obtained && _currentMode != 0) { _v0ObjectInInventory = false; - if (verbObtain(_activeObject2, _activeObject2Index)) + if (verbObtain(_activeObject2, _activeObject2Type)) return true; - if (prep != 1 && prep != 4) { - _activeInventory = _activeObject; - _activeObject = _activeObject2; - _activeObjectIndex = _activeObject2Index; - _activeObject2 = 0; - _activeObject2Index = 0; - } - _activeObject2Obtained = true; } // Give-To - if (_activeVerb == 3 && _activeInventory && _activeActor) { + if (_activeVerb == 3 && _activeObject && _activeObject2 && _activeObject2Type == kObjectTypeActor) { // FIXME: Actors need to turn and face each other - if (verbMoveToActor(_activeActor)) { + if (verbMoveToActor(_activeObject2)) { // Ignore verbs? Actor *a = derefActor(VAR(VAR_EGO), "verbExec"); if (((ActorC64 *)a)->_miscflags & 0x40) { @@ -933,8 +923,8 @@ bool ScummEngine_v0::verbExec() { return true; } _v0ObjectInInventory = true; - VAR(VAR_ACTIVE_ACTOR) = _activeActor; - runObject(_activeInventory , 3); + VAR(VAR_ACTIVE_ACTOR) = _activeObject2; + runObject(_activeObject , 3); _v0ObjectInInventory = false; resetSentence(false); @@ -942,10 +932,8 @@ bool ScummEngine_v0::verbExec() { } // Where we performing an action on an actor? - if (_activeActor) { - _v0ObjectIndex = true; - runObject(_activeActor, entry); - _v0ObjectIndex = false; + if (_activeObject2 && _activeObject2Type == kObjectTypeActor) { + runObject(_activeObject2, entry); _verbExecuting = false; resetSentence(false); @@ -953,10 +941,8 @@ bool ScummEngine_v0::verbExec() { } // If we've finished walking (now near target), execute the action - if (_activeObject && _activeObjectIndex && verbPrep(_activeObjectIndex) == 2) { - _v0ObjectIndex = true; - runObject(_activeObjectIndex, entry); - _v0ObjectIndex = false; + if (_activeObject && verbPrep() == 2) { + runObject(_activeObject, entry); _verbExecuting = false; if ((_currentMode == 3 || _currentMode == 2) && _activeVerb == 13) @@ -967,10 +953,9 @@ bool ScummEngine_v0::verbExec() { } // We acted on an inventory item - if (_activeInventory && verbExecutes(_activeInventory, true) && _activeVerb != 3) { + if (/*_activeInventory && verbExecutes(_activeInventory, true) &&*/ _activeVerb != 3) { _v0ObjectInInventory = true; - _activeObject = _activeInventory; - runObject(_activeInventory, _activeVerb); + runObject(_activeObject/*2*/, _activeVerb); _verbExecuting = false; @@ -985,14 +970,13 @@ bool ScummEngine_v0::verbExec() { // Item not in inventory is executed if (_activeObject) { - _v0ObjectIndex = true; - runObject(_activeObjectIndex, entry); - _v0ObjectIndex = false; - } else if (_activeInventory) { + 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 && _activeObject2Inv && verbExecutes(_activeObject2, true)) { + if (_activeObject2 && _activeObject2Type == kObjectTypeInventory && verbExecutes(_activeObject2, true)) { _v0ObjectInInventory = true; _activeObject = _activeInventory; @@ -1013,6 +997,7 @@ bool ScummEngine_v0::verbExec() { _v0ObjectInInventory = true; runObject(_activeInventory, _activeVerb); } +#endif } _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 if (_activeVerb == 15) { int obj = findObject(_virtualMouse.x, _virtualMouse.y); - int objIdx = findObjectIndex(_virtualMouse.x, _virtualMouse.y); _activeObject = obj; - _activeObjectIndex = objIdx; if ((_mouseAndKeyboardStat & MBS_MOUSE_MASK)) _activeVerb = 13; // Walk-To @@ -1080,11 +1063,13 @@ 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 || _activeInventory)) + if ((_activeVerb == 3) && _activeObject) return; // Click into V2 inventory @@ -1094,31 +1079,16 @@ void ScummEngine_v0::checkExecVerbs() { 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) { - _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 _activeObject = 0; - _activeInvExecute = true; - _activeObject2Inv = true; + _activeObject2Type = kObjectTypeInventory; _activeObject2 = _activeInventory; _activeInventory = prevInventory; return; @@ -1132,14 +1102,14 @@ void ScummEngine_v0::checkExecVerbs() { if (prevInventory != _activeInventory) if (!_activeObject2 || prevInventory != _activeObject2) return; +#endif - if (_activeVerb == 11 && !(((_activeObject || _activeInventory)) || !_activeObject2)) + 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); - int objIdx = findObjectIndex(_virtualMouse.x, _virtualMouse.y); if (a->_miscflags & 0x80) { if (_activeVerb != 7 && over != 7) { @@ -1207,15 +1177,15 @@ void ScummEngine_v0::checkExecVerbs() { // Only allowing targetting actors if its the GIVE verb if (_activeVerb == 3) { - if (_activeObject || _activeInventory) { + if (_activeObject) { // Once selected the object cannot be changed obj = 0; - objIdx = 0; // Different actor selected? if (act) { - if (_activeActor != act) { - _activeActor = act; + if (_activeObject2 != act || _activeObject2Type != kObjectTypeActor) { + _activeObject2 = act; + _activeObject2Type = kObjectTypeActor; return; } } else { @@ -1230,24 +1200,15 @@ void ScummEngine_v0::checkExecVerbs() { } if (obj && obj != _activeObject) { - if (!_activeObject) - if (_activeInventory) - _activeInvExecute = true; - // USE / UNLOCK if (_activeVerb == 11 || _activeVerb == 8) { if (obj != _activeObject && obj != _activeObject2) { - if (_activeObject || _activeInventory) { - //verbPrep( - } - if (!_activeObject || _activeInventory) { + if (!_activeObject) { _activeObject = obj; - _activeObjectIndex = objIdx; return; } else { if (_activeObject2 != obj) { _activeObject2 = obj; - _activeObject2Index = objIdx; return; } } @@ -1256,8 +1217,6 @@ void ScummEngine_v0::checkExecVerbs() { a->stopActorMoving(); _activeObject = obj; - _activeObjectIndex = objIdx; - if (_activeVerb != 13) return; -- cgit v1.2.3 From a709a4231937fef823352cffb7146a94d9f8cccf Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Tue, 3 Jan 2012 22:58:25 +0100 Subject: SCUMM: fix ScummEngine_v0::o_stopCurrentScript() --- engines/scumm/script_v0.cpp | 9 +-------- engines/scumm/script_v2.cpp | 10 +++++----- engines/scumm/scumm_v2.h | 1 + 3 files changed, 7 insertions(+), 13 deletions(-) (limited to 'engines/scumm') diff --git a/engines/scumm/script_v0.cpp b/engines/scumm/script_v0.cpp index 07923dea6a..2bbde617ad 100644 --- a/engines/scumm/script_v0.cpp +++ b/engines/scumm/script_v0.cpp @@ -501,14 +501,7 @@ void ScummEngine_v0::drawSentence() { } void ScummEngine_v0::o_stopCurrentScript() { - int script; - - script = vm.slot[_currentScript].number; - - if (_currentScript != 0 && vm.slot[_currentScript].number == script) - stopObjectCode(); - else - stopScript(script); + stopScriptCommon(0); } void ScummEngine_v0::o_loadSound() { diff --git a/engines/scumm/script_v2.cpp b/engines/scumm/script_v2.cpp index 76f6b02eb7..003bafa27e 100644 --- a/engines/scumm/script_v2.cpp +++ b/engines/scumm/script_v2.cpp @@ -1190,11 +1190,7 @@ void ScummEngine_v2::o2_startScript() { runScript(script, 0, 0, 0); } -void ScummEngine_v2::o2_stopScript() { - int script; - - script = getVarOrDirectByte(PARAM_1); - +void ScummEngine_v2::stopScriptCommon(int script) { if (_game.id == GID_MANIAC && _roomResource == 26 && vm.slot[_currentScript].number == 10001) { // FIXME: Nasty hack for bug #915575 // Don't let the exit script for room 26 stop the script (116), when @@ -1215,6 +1211,10 @@ void ScummEngine_v2::o2_stopScript() { stopScript(script); } +void ScummEngine_v2::o2_stopScript() { + stopScriptCommon(getVarOrDirectByte(PARAM_1)); +} + void ScummEngine_v2::o2_panCameraTo() { panCameraTo(getVarOrDirectByte(PARAM_1) * V12_X_MULTIPLIER, 0); } diff --git a/engines/scumm/scumm_v2.h b/engines/scumm/scumm_v2.h index 1f41283852..a4da4fb2dc 100644 --- a/engines/scumm/scumm_v2.h +++ b/engines/scumm/scumm_v2.h @@ -85,6 +85,7 @@ protected: void ifNotStateCommon(byte type); void setStateCommon(byte type); void clearStateCommon(byte type); + void stopScriptCommon(int script); virtual void resetSentence(bool walking); void setUserState(byte state); -- cgit v1.2.3 From c69a52853ccc42f3891ce4212fa281dbea65c3ea Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Wed, 4 Jan 2012 16:18:18 +0100 Subject: SCUMM: remove unneeded verbPrep() calls --- engines/scumm/verbs.cpp | 3 --- 1 file changed, 3 deletions(-) (limited to 'engines/scumm') diff --git a/engines/scumm/verbs.cpp b/engines/scumm/verbs.cpp index 1bb0c0a34d..dc4a47a231 100644 --- a/engines/scumm/verbs.cpp +++ b/engines/scumm/verbs.cpp @@ -882,7 +882,6 @@ bool ScummEngine_v0::verbExecutes(int object, bool inventory) { } bool ScummEngine_v0::verbExec() { - int prep = 0; int entry = (_currentMode != 0 && _currentMode != 1) ? _activeVerb : 15; if (_activeObject && getObjectIndex(_activeObject) == -1) { @@ -892,8 +891,6 @@ bool ScummEngine_v0::verbExec() { // Lets try walk to the object if (_activeObject && !_activeObjectObtained && _currentMode != 0) { - prep = verbPrep(); - if (verbObtain(_activeObject, _activeObjectType)) return true; -- cgit v1.2.3 From 1c32000a004cc184a8744e2467035a4c7ba2f3a5 Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Sat, 7 Jan 2012 16:08:55 +0100 Subject: 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 --- engines/scumm/object.cpp | 74 +++--- engines/scumm/object.h | 8 + engines/scumm/script.cpp | 2 - engines/scumm/script_v0.cpp | 65 ++---- engines/scumm/script_v2.cpp | 2 - engines/scumm/scumm.cpp | 11 +- engines/scumm/scumm.h | 7 +- engines/scumm/scumm_v0.h | 29 ++- engines/scumm/verbs.cpp | 542 ++++++++++++++++++++++---------------------- 9 files changed, 360 insertions(+), 380 deletions(-) (limited to 'engines/scumm') 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, "Drkey = 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) { -- cgit v1.2.3 From 6b5abf69190b47dc7c0da63fa08a717adbfc0cdd Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Sat, 7 Jan 2012 17:37:04 +0100 Subject: SCUMM: selecting inventory objects and inventory scrolling works again --- engines/scumm/scumm_v0.h | 2 - engines/scumm/scumm_v2.h | 2 +- engines/scumm/verbs.cpp | 139 ++++++++++++++++++++++------------------------- 3 files changed, 66 insertions(+), 77 deletions(-) (limited to 'engines/scumm') diff --git a/engines/scumm/scumm_v0.h b/engines/scumm/scumm_v0.h index 0bb4d1a4a9..460843cfc2 100644 --- a/engines/scumm/scumm_v0.h +++ b/engines/scumm/scumm_v0.h @@ -108,8 +108,6 @@ protected: virtual bool areBoxesNeighbors(int box1nr, int box2nr); - virtual void setActiveInventory(int object); - bool ifEqualActiveObject2Common(bool ignoreType); /* Version C64 script opcodes */ diff --git a/engines/scumm/scumm_v2.h b/engines/scumm/scumm_v2.h index a4da4fb2dc..b9cd8a3921 100644 --- a/engines/scumm/scumm_v2.h +++ b/engines/scumm/scumm_v2.h @@ -50,7 +50,7 @@ public: virtual void resetScumm(); void checkV2MouseOver(Common::Point pos); - void checkV2Inventory(int x, int y); + int checkV2Inventory(int x, int y); void redrawV2Inventory(); protected: diff --git a/engines/scumm/verbs.cpp b/engines/scumm/verbs.cpp index 467b587b63..291985892a 100644 --- a/engines/scumm/verbs.cpp +++ b/engines/scumm/verbs.cpp @@ -389,19 +389,14 @@ 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) { +int ScummEngine_v2::checkV2Inventory(int x, int y) { int inventoryArea = (_game.platform == Common::kPlatformNES) ? 48: 32; int object = 0; y -= _virtscr[kVerbVirtScreen].topline; if ((y < inventoryArea) || !(_mouseAndKeyboardStat & MBS_LEFT_CLICK)) - return; + return 0; if (_mouseOverBoxesV2[kInventoryUpArrow].rect.contains(x, y)) { if (_inventoryOffset >= 2) { @@ -422,11 +417,9 @@ void ScummEngine_v2::checkV2Inventory(int x, int y) { } if (object >= 4) - return; + return 0; - object = findInventory(_scummVars[VAR_EGO], object + 1 + _inventoryOffset); - if (object > 0) - setActiveInventory(object); + return findInventory(_scummVars[VAR_EGO], object + 1 + _inventoryOffset); } void ScummEngine_v2::redrawV2Inventory() { @@ -706,7 +699,7 @@ void ScummEngine_v2::checkExecVerbs() { if (object != -1) { object = findInventory(_scummVars[VAR_EGO], object + 1 + _inventoryOffset); if (object > 0) - setActiveInventory(object); + runInputScript(kInventoryClickArea, object, 0); return; } @@ -727,7 +720,9 @@ void ScummEngine_v2::checkExecVerbs() { runInputScript(kSentenceClickArea, 0, 0); } else if (zone->number == kVerbVirtScreen && _mouse.y > zone->topline + inventoryArea) { // Click into V2 inventory - checkV2Inventory(_mouse.x, _mouse.y); + int object = checkV2Inventory(_mouse.x, _mouse.y); + if (object > 0) + runInputScript(kInventoryClickArea, object, 0); } else { over = findVerbAtPos(_mouse.x, _mouse.y); if (over != 0) { @@ -1070,53 +1065,71 @@ void ScummEngine_v0::checkExecVerbs() { _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; - } + if (_mouseAndKeyboardStat < MBS_MAX_KEY) { + // 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 } else { - //_activeVerbPrep: - // 0: no activeObject or activeObject but no prep - // > 0: activeObject + prep - if (activeVerbPrep() == 0) { - if (id == _activeObjectNr && type == _activeObjectType) { - _verbExecuting = true; + int obj = 0; + + if (zone->number == kVerbVirtScreen && _mouse.y > zone->topline + 32) { + // click into inventory + int invOff = _inventoryOffset; + obj = checkV2Inventory(_mouse.x, _mouse.y); + if (invOff != _inventoryOffset) { + // inventory position changed (arrows pressed, do nothing) + return; + } + } else if (zone->number == kMainVirtScreen) { + // click into main screen + if (_activeVerb == kVerbGive && _activeObjectNr) { + obj = OBJECT_V0(getActorFromPos(_virtualMouse.x, _virtualMouse.y), kObjectTypeActor); } else { - _activeObjectNr = id; - _activeObjectType = type; + obj = findObject(_virtualMouse.x, _virtualMouse.y); + } + } + + int id = OBJECT_V0_NR(obj); + int type = OBJECT_V0_TYPE(obj); + debug("found 0x%03x", obj); + + if (!id) { + if (_activeVerb == kVerbWalkTo) { + _activeObjectNr = 0; + _activeObject2Nr = 0; } - //sentenceLineChanged = true; - if (_currentMode == 1) - _verbExecuting = true; } else { - if (id == _activeObject2Nr && type == _activeObject2Type) - _verbExecuting = true; - if (!(id == _activeObjectNr && type == _activeObjectType)) { - _activeObject2Nr = id; - _activeObject2Type = type; + //_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; + sentenceLineChanged = true; + if (_activeVerb == kVerbWalkTo) { + scriptUpdateSkip = 0; + _verbExecuting = true; + } } } } @@ -1184,29 +1197,7 @@ void ScummEngine_v0::checkExecVerbs() { } } - if (_userPut <= 0 || _mouseAndKeyboardStat == 0) - return; - - if (_mouseAndKeyboardStat < MBS_MAX_KEY) { - /* Check keypresses */ - // TODO - } else if (_mouseAndKeyboardStat & MBS_MOUSE_MASK) { - if (zone->number == kVerbVirtScreen && _mouse.y <= zone->topline + 8) { - // TODO - } else if (zone->number == kVerbVirtScreen && _mouse.y > zone->topline + 32) { - int invOff = _inventoryOffset; - - // Click into V2 inventory - checkV2Inventory(_mouse.x, _mouse.y); - - // Did the Inventory position changed (arrows pressed, do nothing) - if (invOff != _inventoryOffset) - return; - } else { - int over = findVerbAtPos(_mouse.x, _mouse.y); - int act = getActorFromPos(_virtualMouse.x, _virtualMouse.y); - int obj = findObject(_virtualMouse.x, _virtualMouse.y); - + ... // Clicked on nothing, walk here? if (!over && !act && _activeVerb == 13 && !obj && _currentMode != 0) { -- cgit v1.2.3 From b01f601d7e8dc0b7885ff058c8596dc2ad6762f4 Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Sat, 7 Jan 2012 18:05:42 +0100 Subject: SCUMM: use constants for c64 actor miscflags --- engines/scumm/actor.h | 13 ++++++++++++- engines/scumm/script_v0.cpp | 10 +++++----- engines/scumm/verbs.cpp | 10 +++++----- 3 files changed, 22 insertions(+), 11 deletions(-) (limited to 'engines/scumm') diff --git a/engines/scumm/actor.h b/engines/scumm/actor.h index 1584d0a78b..d8e3692619 100644 --- a/engines/scumm/actor.h +++ b/engines/scumm/actor.h @@ -335,10 +335,21 @@ protected: virtual void prepareDrawActorCostume(BaseCostumeRenderer *bcr); }; +enum ActorC64MiscFlags { + kActorMiscFlagStrong = 0x01, // Kid is strong (Hunk-O-Matic used) + kActorMiscFlag_02 = 0x02, // ??? + kActorMiscFlag_04 = 0x04, // ??? + kActorMiscFlagEdsEnemy = 0x08, // Kid is not Weird Ed's friend + kActorMiscFlag_10 = 0x10, // ??? + kActorMiscFlag_20 = 0x20, // ??? + kActorMiscFlagFreeze = 0x40, // Stop moving + kActorMiscFlagHide = 0x80, // Hide actor (e.g. dead or wearing radiation suit) +}; + class ActorC64 : public Actor_v2 { public: byte _costCommand, _costFrame; - byte _miscflags; // 0x1: strong, 0x8: Ed's enemy, 0x40: stop moving, 0x80: hide(dead/radiation suit) + byte _miscflags; byte _speaking, _speakingPrev; public: diff --git a/engines/scumm/script_v0.cpp b/engines/scumm/script_v0.cpp index 14df89b28d..0f9fbc6e6f 100644 --- a/engines/scumm/script_v0.cpp +++ b/engines/scumm/script_v0.cpp @@ -542,16 +542,16 @@ void ScummEngine_v0::o_loadRoom() { } void ScummEngine_v0::o_loadRoomWithEgo() { - Actor *a; + ActorC64 *a; int obj, room, x, y, dir; obj = fetchScriptByte(); room = fetchScriptByte(); - a = derefActor(VAR(VAR_EGO), "o_loadRoomWithEgo"); + a = (ActorC64 *)derefActor(VAR(VAR_EGO), "o_loadRoomWithEgo"); //0x634F - if (((ActorC64 *)a)->_miscflags & 0x40) { + if (a->_miscflags & kActorMiscFlagFreeze) { // TODO: Check if this is the correct function // to be calling here stopObjectCode(); @@ -734,9 +734,9 @@ void ScummEngine_v0::o_setActorBitVar() { a->_miscflags &= ~mask; // This flag causes the actor to stop moving (used by script #158, Green Tentacle 'Oomph!') - if (a->_miscflags & 0x40) + if (a->_miscflags & kActorMiscFlagFreeze) a->stopActorMoving(); - if (a->_miscflags & 0x80) + if (a->_miscflags & kActorMiscFlagHide) a->setActorCostume(0); debug(0, "o_setActorBitVar(%d, %d, %d)", act, mask, mod); diff --git a/engines/scumm/verbs.cpp b/engines/scumm/verbs.cpp index 291985892a..3d0abae0a3 100644 --- a/engines/scumm/verbs.cpp +++ b/engines/scumm/verbs.cpp @@ -847,8 +847,8 @@ bool ScummEngine_v0::verbObtain(int obj) { } // Ignore verbs? - Actor *a = derefActor(VAR(VAR_EGO), "verbObtain"); - if (((ActorC64 *)a)->_miscflags & 0x40) { + ActorC64 *a = (ActorC64 *)derefActor(VAR(VAR_EGO), "verbObtain"); + if (a->_miscflags & kActorMiscFlagFreeze) { resetSentence(false); return false; } @@ -918,7 +918,7 @@ bool ScummEngine_v0::verbExec() { if (verbMoveToActor(_activeObject2Nr)) { // Ignore verbs? Actor *a = derefActor(VAR(VAR_EGO), "verbExec"); - if (((ActorC64 *)a)->_miscflags & 0x40) { + if (((ActorC64 *)a)->_miscflags & kActorMiscFlagFreeze) { resetSentence(false); return false; } @@ -1052,7 +1052,7 @@ void ScummEngine_v0::checkExecVerbs() { } } - if (a->_miscflags & 0x80) { + if (a->_miscflags & kActorMiscFlagHide) { if (_activeVerb != kVerbNewKid) { _activeVerb = kVerbNone; } @@ -1210,7 +1210,7 @@ void ScummEngine_v0::checkExecVerbs() { if (zone->number == kMainVirtScreen) { // Ignore verbs? - if (a->_miscflags & 0x40) { + if (a->_miscflags & kActorMiscFlagFreeze) { resetSentence(false); return; } -- cgit v1.2.3 From 706b8cf1c531e15b980a64060a1080e17e854d98 Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Sat, 7 Jan 2012 20:06:26 +0100 Subject: SCUMM: replace verb, prep and currentMode values with symbolic constants --- engines/scumm/script_v0.cpp | 14 ++++----- engines/scumm/scumm.cpp | 2 +- engines/scumm/scumm_v0.h | 7 +++++ engines/scumm/verbs.cpp | 77 +++++++++++++++++---------------------------- engines/scumm/verbs.h | 28 +++++++++++++++++ 5 files changed, 72 insertions(+), 56 deletions(-) (limited to 'engines/scumm') diff --git a/engines/scumm/script_v0.cpp b/engines/scumm/script_v0.cpp index 0f9fbc6e6f..31363ed140 100644 --- a/engines/scumm/script_v0.cpp +++ b/engines/scumm/script_v0.cpp @@ -422,8 +422,8 @@ void ScummEngine_v0::drawSentence() { return; // Current Verb - if (_activeVerb == 0) - _activeVerb = 13; + if (_activeVerb == kVerbNone) + _activeVerb = kVerbWalkTo; if (getResourceAddress(rtVerb, _activeVerb)) { _sentenceBuf = (char *)getResourceAddress(rtVerb, _activeVerb); } else { @@ -602,15 +602,15 @@ void ScummEngine_v0::o_cursorCommand() { _currentMode = fetchScriptByte(); switch (_currentMode) { - case 0: + case kModeCutscene: state = 15; break; - case 1: + case kModeKeypad: state = 31; break; - case 2: + case kModeNoNewKid: break; - case 3: + case kModeNormal: state = 247; break; } @@ -908,7 +908,7 @@ void ScummEngine_v0::o_setOwnerOf() { } void ScummEngine_v0::resetSentence(bool walking) { - _activeVerb = 13; + _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) diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp index 423ad79b00..8b2e2ef88e 100644 --- a/engines/scumm/scumm.cpp +++ b/engines/scumm/scumm.cpp @@ -716,7 +716,7 @@ ScummEngine_v0::ScummEngine_v0(OSystem *syst, const DetectorResult &dr) _verbPickup = false; _currentMode = 0; - _activeVerb = 0; + _activeVerb = kVerbNone; _activeObjectNr = 0; _activeObject2Nr = 0; _activeObjectType = kObjectTypeBG; diff --git a/engines/scumm/scumm_v0.h b/engines/scumm/scumm_v0.h index 460843cfc2..2c8c1c85c5 100644 --- a/engines/scumm/scumm_v0.h +++ b/engines/scumm/scumm_v0.h @@ -32,6 +32,13 @@ namespace Scumm { */ class ScummEngine_v0 : public ScummEngine_v2 { protected: + enum CurrentMode { + kModeCutscene = 0, // cutscene active + kModeKeypad = 1, // kid selection / dial pad / save-load dialog + kModeNoNewKid = 2, // verb "new kid" disabled (e.g. when entering lab) + kModeNormal = 3, // normal playing mode + }; + enum ObjectType { kObjectTypeFG = 0, // foreground object // - with owner/state, might (but has not to) be pickupable diff --git a/engines/scumm/verbs.cpp b/engines/scumm/verbs.cpp index 3d0abae0a3..03acdda1a8 100644 --- a/engines/scumm/verbs.cpp +++ b/engines/scumm/verbs.cpp @@ -37,25 +37,6 @@ 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; @@ -103,13 +84,13 @@ static const VerbSettings v0VerbTable_German[] = { int ScummEngine_v0::verbPrepIdType(int verbid) { switch (verbid) { case kVerbUse: // depends on object1 - return 0xFF; + return kVerbPrepObject; case kVerbGive: - return 4; + return kVerbPrepTo; case kVerbUnlock: case kVerbFix: - return 2; + return kVerbPrepWith; default: - return 0; + return kVerbPrepNone; } } @@ -192,7 +173,7 @@ void ScummEngine_v0::switchActor(int slot) { return; // verbs disabled? or just new kid button? - if (_currentMode == 0 || _currentMode == 1 || _currentMode == 2) + if (_currentMode == kModeCutscene || _currentMode == kModeKeypad || _currentMode == kModeNoNewKid) return; VAR(VAR_EGO) = VAR(97 + slot); @@ -785,7 +766,7 @@ bool ScummEngine_v0::verbMove(int object, bool invObject) { int x, y, dir; Actor *a = derefActor(VAR(VAR_EGO), "verbMove"); - if (_currentMode != 3 && _currentMode != 2) + if (_currentMode != kModeNormal && _currentMode != kModeNoNewKid) return false; getObjectXYPos(object, x, y, dir); @@ -837,8 +818,8 @@ bool ScummEngine_v0::verbObtain(int obj) { if (where != WIO_INVENTORY) { prep = activeVerbPrep(); - if (prep == 1 || prep == 4) { - if (_activeVerb != 13 && _activeVerb != 14) { + if (prep == kVerbPrepIn || prep == kVerbPrepTo) { + if (_activeVerb != kVerbWalkTo && _activeVerb != kVerbPickUp) { _verbPickup = true; didPickup = true; } @@ -857,8 +838,8 @@ bool ScummEngine_v0::verbObtain(int obj) { if (verbMove(obj, false)) return true; - if (didPickup && (prep == 1 || prep == 4)) - if (_activeVerb != 13 && _activeVerb != 14) { + if (didPickup && (prep == kVerbPrepIn || prep == kVerbPrepTo)) + if (_activeVerb != kVerbWalkTo && _activeVerb != kVerbPickUp) { // TODO(TOBIAS) #if 0 if (whereIsObject(obj) == WIO_INVENTORY) @@ -889,7 +870,7 @@ int ScummEngine_v0::activeVerbPrep() { } bool ScummEngine_v0::verbExec() { - int entry = (_currentMode != 0 && _currentMode != 1) ? _activeVerb : 15; + int entry = (_currentMode != kModeCutscene && _currentMode != kModeKeypad) ? _activeVerb : kVerbWhatIs; if (_activeObjectNr && getObjectIndex(OBJECT_V0(_activeObjectNr, _activeObjectType)) == -1) { resetSentence(false); @@ -897,7 +878,7 @@ bool ScummEngine_v0::verbExec() { } // Lets try walk to the object - if (_activeObjectNr && !_activeObjectObtained && _currentMode != 0) { + if (_activeObjectNr && !_activeObjectObtained && _currentMode != kModeCutscene) { if (verbObtain(OBJECT_V0(_activeObjectNr, _activeObjectType))) return true; @@ -905,7 +886,7 @@ bool ScummEngine_v0::verbExec() { } // Attempt to obtain/reach object2 - if (_activeObject2Nr && !_activeObject2Obtained && _currentMode != 0) { + if (_activeObject2Nr && !_activeObject2Obtained && _currentMode != kModeCutscene) { if (verbObtain(OBJECT_V0(_activeObject2Nr, _activeObject2Type))) return true; @@ -913,7 +894,7 @@ bool ScummEngine_v0::verbExec() { } // Give-To - if (_activeVerb == 3 && _activeObjectNr && _activeObject2Nr && _activeObject2Type == kObjectTypeActor) { + if (_activeVerb == kVerbGive && _activeObjectNr && _activeObject2Nr && _activeObject2Type == kObjectTypeActor) { // FIXME: Actors need to turn and face each other if (verbMoveToActor(_activeObject2Nr)) { // Ignore verbs? @@ -942,11 +923,11 @@ bool ScummEngine_v0::verbExec() { } // If we've finished walking (now near target), execute the action - if (_activeObjectNr && activeVerbPrep() == 2) { + if (_activeObjectNr && activeVerbPrep() == kVerbPrepWith) { runObject(OBJECT_V0(_activeObjectNr, _activeObjectType), entry); _verbExecuting = false; - if ((_currentMode == 3 || _currentMode == 2) && _activeVerb == 13) + if ((_currentMode == kModeNormal || _currentMode == kModeNoNewKid) && _activeVerb == kVerbWalkTo) return false; resetSentence(false); @@ -954,12 +935,12 @@ bool ScummEngine_v0::verbExec() { } // We acted on an inventory item - if (_activeVerb != 3) { + if (_activeVerb != kVerbGive) { runObject(OBJECT_V0(_activeObjectNr/*2*/, _activeObjectType/*2*/), _activeVerb); _verbExecuting = false; - if (_currentMode == 3 && _activeVerb == 13) { + if (_currentMode == kModeNormal && _activeVerb == kVerbWalkTo) { resetSentence(true); return false; } @@ -974,7 +955,7 @@ bool ScummEngine_v0::verbExec() { _verbExecuting = false; - if (_activeVerb == 13) { + if (_activeVerb == kVerbWalkTo) { resetSentence(true); return false; } @@ -1058,10 +1039,8 @@ void ScummEngine_v0::checkExecVerbs() { } } - // mode 1: kid selection, 3: normal - if (_currentMode != 0) { - if (_currentMode == 1) { - // kid selection or dial pad + if (_currentMode != kModeCutscene) { + if (_currentMode == kModeKeypad) { _activeVerb = kVerbPush; } @@ -1097,13 +1076,15 @@ void ScummEngine_v0::checkExecVerbs() { if (!id) { if (_activeVerb == kVerbWalkTo) { _activeObjectNr = 0; + _activeObjectType = 0; _activeObject2Nr = 0; + _activeObject2Type = 0; } } else { //_activeVerbPrep: // 0: no activeObject or activeObject but no prep // > 0: activeObject + prep - if (activeVerbPrep() == 0) { + if (activeVerbPrep() == kVerbPrepNone) { if (id == _activeObjectNr && type == _activeObjectType) { _verbExecuting = true; } else { @@ -1111,7 +1092,7 @@ void ScummEngine_v0::checkExecVerbs() { _activeObjectType = type; } //sentenceLineChanged = true; - if (_currentMode == 1) + if (_currentMode == kModeKeypad) _verbExecuting = true; } else { if (id == _activeObject2Nr && type == _activeObject2Type) @@ -1119,7 +1100,7 @@ void ScummEngine_v0::checkExecVerbs() { if (!(id == _activeObjectNr && type == _activeObjectType)) { _activeObject2Nr = id; _activeObject2Type = type; - if (_currentMode == 1) + if (_currentMode == kModeKeypad) _verbExecuting = true; } } @@ -1139,7 +1120,7 @@ void ScummEngine_v0::checkExecVerbs() { if (_activeVerb == kVerbNewKid) { // TODO - if (_currentMode == 3) { + if (_currentMode == kModeNormal) { // get kid _activeVerb = kVerbWalkTo; resetSentence(false); @@ -1155,7 +1136,7 @@ void ScummEngine_v0::checkExecVerbs() { /* if (_activeVerbPrep == 0) { int prep = activeVerbPrep(); - if (prep == 0) + if (prep == kVerbPrepNone) ; //exec(); else { _activeVerbPrep = prep; @@ -1200,7 +1181,7 @@ void ScummEngine_v0::checkExecVerbs() { ... // Clicked on nothing, walk here? - if (!over && !act && _activeVerb == 13 && !obj && _currentMode != 0) { + if (!over && !act && _activeVerb == kVerbWalkTo && !obj && _currentMode != kMode_0) { // Clear all selected resetSentence(false); diff --git a/engines/scumm/verbs.h b/engines/scumm/verbs.h index fb4dc969e2..fce260ea63 100644 --- a/engines/scumm/verbs.h +++ b/engines/scumm/verbs.h @@ -57,6 +57,34 @@ struct VerbSlot { uint16 imgindex; }; +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 +}; + +enum VerbPrepsV0 { + kVerbPrepNone = 0, + kVerbPrepIn = 1, + kVerbPrepWith = 2, + kVerbPrepOn = 3, + kVerbPrepTo = 4, + kVerbPrepObject = 0xFF, // prep depends on object (USE) +}; + } // End of namespace Scumm #endif -- cgit v1.2.3 From d8b435917d5cc00ad2b4817c5eabc828439e36f3 Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Sat, 7 Jan 2012 20:25:01 +0100 Subject: SCUMM: mm c64 cleanup --- engines/scumm/script_v0.cpp | 8 ++++---- engines/scumm/scumm_v0.h | 5 ++--- engines/scumm/verbs.cpp | 4 ++-- 3 files changed, 8 insertions(+), 9 deletions(-) (limited to 'engines/scumm') diff --git a/engines/scumm/script_v0.cpp b/engines/scumm/script_v0.cpp index 31363ed140..9b39391246 100644 --- a/engines/scumm/script_v0.cpp +++ b/engines/scumm/script_v0.cpp @@ -406,9 +406,9 @@ void ScummEngine_v0::decodeParseString() { actorTalk(buffer); } -void ScummEngine_v0::drawSentenceObject(int object, int type) { +void ScummEngine_v0::drawSentenceObject(int object) { const byte *temp; - temp = getObjOrActorName(OBJECT_V0(object, type)); + temp = getObjOrActorName(object); if (temp) { _sentenceBuf += " "; _sentenceBuf += (const char *)temp; @@ -432,7 +432,7 @@ void ScummEngine_v0::drawSentence() { if (_activeObjectNr) { // Draw the 1st active object - drawSentenceObject(_activeObjectNr, _activeObjectType); + drawSentenceObject(OBJECT_V0(_activeObjectNr, _activeObjectType)); // Append verb preposition int sentencePrep = activeVerbPrep(); @@ -448,7 +448,7 @@ void ScummEngine_v0::drawSentence() { _sentenceBuf += (const char *)a->getActorName(); // 2nd Object is an inventory or room object } else { - drawSentenceObject(_activeObject2Nr, _activeObject2Type); + drawSentenceObject(OBJECT_V0(_activeObject2Nr, _activeObject2Type)); } } } diff --git a/engines/scumm/scumm_v0.h b/engines/scumm/scumm_v0.h index 2c8c1c85c5..9b38b108e2 100644 --- a/engines/scumm/scumm_v0.h +++ b/engines/scumm/scumm_v0.h @@ -89,10 +89,9 @@ protected: // V0 MM Verb commands int getVerbPrepId(); int activeVerbPrep(); - bool verbMove(int object, bool invObject); + bool verbMove(int object); bool verbMoveToActor(int actor); bool verbObtain(int object); - bool verbExecutes(int object, bool inventory = false); bool verbExec(); virtual void checkExecVerbs(); @@ -101,7 +100,7 @@ protected: void resetVerbs(); void setNewKidVerbs(); - void drawSentenceObject(int object, int type); + void drawSentenceObject(int object); void drawSentence(); void switchActor(int slot); diff --git a/engines/scumm/verbs.cpp b/engines/scumm/verbs.cpp index 03acdda1a8..016248c530 100644 --- a/engines/scumm/verbs.cpp +++ b/engines/scumm/verbs.cpp @@ -762,7 +762,7 @@ bool ScummEngine_v0::verbMoveToActor(int actor) { return true; } -bool ScummEngine_v0::verbMove(int object, bool invObject) { +bool ScummEngine_v0::verbMove(int object) { int x, y, dir; Actor *a = derefActor(VAR(VAR_EGO), "verbMove"); @@ -835,7 +835,7 @@ bool ScummEngine_v0::verbObtain(int obj) { } //attempt move to object - if (verbMove(obj, false)) + if (verbMove(obj)) return true; if (didPickup && (prep == kVerbPrepIn || prep == kVerbPrepTo)) -- cgit v1.2.3 From de0b5f76749add219a6b667d5d2d69fb8a86d959 Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Sun, 8 Jan 2012 23:51:13 +0100 Subject: 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 --- engines/scumm/object.cpp | 11 +- engines/scumm/script.cpp | 136 ++++++++++++++- engines/scumm/script_v0.cpp | 68 +++++--- engines/scumm/script_v2.cpp | 27 +-- engines/scumm/script_v5.cpp | 65 ++++--- engines/scumm/scumm.cpp | 14 +- engines/scumm/scumm.h | 2 +- engines/scumm/scumm_v0.h | 22 ++- engines/scumm/scumm_v2.h | 2 +- engines/scumm/scumm_v5.h | 2 + engines/scumm/verbs.cpp | 410 +++++--------------------------------------- 11 files changed, 307 insertions(+), 452 deletions(-) (limited to 'engines/scumm') 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) { -- cgit v1.2.3 From c16ef940a1f25846623903d6ce744374228ff104 Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Mon, 9 Jan 2012 20:04:38 +0100 Subject: SCUMM: make START-button in mm c64 kid selection screen work again --- engines/scumm/object.cpp | 2 +- engines/scumm/verbs.cpp | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'engines/scumm') diff --git a/engines/scumm/object.cpp b/engines/scumm/object.cpp index 49f1777c86..670b2cb79c 100644 --- a/engines/scumm/object.cpp +++ b/engines/scumm/object.cpp @@ -1223,7 +1223,7 @@ uint32 ScummEngine::getOBCDOffs(int object) const { return 0; for (i = (_numLocalObjects-1); i > 0; i--) { - if (_objs[i].obj_nr == object) { + if (_objs[i].obj_nr == OBJECT_V0_NR(object)) { if (_game.version == 0 && _objs[i].obj_type != OBJECT_V0_TYPE(object)) continue; if (_objs[i].fl_object_index != 0) diff --git a/engines/scumm/verbs.cpp b/engines/scumm/verbs.cpp index 376e075daa..19ad003da6 100644 --- a/engines/scumm/verbs.cpp +++ b/engines/scumm/verbs.cpp @@ -740,6 +740,7 @@ void ScummEngine_v0::verbExec() { if (_activeVerb != kVerbWalkTo) { _activeVerb = kVerbWalkTo; _activeObjectNr = 0; + _activeObjectType = 0; } _walkToObjectIdx = 0; return; @@ -841,6 +842,7 @@ void ScummEngine_v0::checkExecVerbs() { _activeObjectNr = id; _activeObjectType = type; } + // immediately execute action in keypad/selection mode if (_currentMode == kModeKeypad) execute = true; } else { -- cgit v1.2.3 From b337823bab5994b78f639a7625ff763f061a1c0c Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Mon, 9 Jan 2012 23:21:08 +0100 Subject: SCUMM: fix verb and script handling - getVerbEntrypoint() should not handle walk-to differently (revert 0x0D handling back to original behavior) - VAR_ACTIVE_ACTOR actually is VAR_ACTIVE_OBJECT2 - runSentenceScript(): "if (_cmdVerb == kVerbWalkTo)" must be "if (_cmdVerb != kVerbWalkTo)" --- engines/scumm/script.cpp | 34 ++++++++++++---------------------- engines/scumm/scumm.cpp | 2 +- engines/scumm/scumm_v0.h | 2 +- engines/scumm/vars.cpp | 2 +- 4 files changed, 15 insertions(+), 25 deletions(-) (limited to 'engines/scumm') diff --git a/engines/scumm/script.cpp b/engines/scumm/script.cpp index 0864022c59..e34c81d0d4 100644 --- a/engines/scumm/script.cpp +++ b/engines/scumm/script.cpp @@ -196,12 +196,8 @@ int ScummEngine::getVerbEntrypoint(int obj, int entry) { } else if (_game.version <= 2) { do { const int kFallbackEntry = (_game.version == 0 ? 0x0F : 0xFF); - if (!*verbptr) { - if (_game.version == 0 && entry == kVerbWalkTo) - return 13; - else - return 0; - } + if (!*verbptr) + return 0; if (*verbptr == entry || *verbptr == kFallbackEntry) break; verbptr += 2; @@ -1160,8 +1156,6 @@ void ScummEngine_v0::walkToActorOrObject(int object) { } void ScummEngine_v0::checkAndRunSentenceScript() { - const ScriptSlot *ss; - if (_walkToObjectIdx) { ActorC64 *a = (ActorC64 *)derefActor(VAR(VAR_EGO), "checkAndRunSentenceScript"); if (a->_moving) @@ -1175,7 +1169,6 @@ void ScummEngine_v0::checkAndRunSentenceScript() { if (!_sentenceNum || _sentence[_sentenceNum - 1].freezeCount) return; - //_sentenceNum--; SentenceTab &st = _sentence[_sentenceNum - 1]; if (st.preposition && st.objectB == st.objectA) @@ -1232,30 +1225,27 @@ void ScummEngine_v0::checkAndRunSentenceScript() { 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; + // do not read in the dark + if (!(_cmdVerb == kVerbRead && _currentLights == 0)) { + VAR(VAR_ACTIVE_OBJECT2) = _cmdObject2Nr; runObjectScript(obj, _cmdVerb, false, false, NULL); return; } } else { if (_cmdVerb == kVerbGive) { + // no "give to"-script: give to other kid or ignore if (_cmdObject2Nr < 8) setOwnerOf(obj, _cmdObject2Nr); return; - } else if (_cmdVerb == kVerbWalkTo) { - //slot = 0xFF; - VAR(VAR_ACTIVE_VERB) = _cmdVerb; - runScript(3, 0, 0, 0); - return; } } + + if (_cmdVerb != kVerbWalkTo) { + // perform verb's fallback action + VAR(VAR_ACTIVE_VERB) = _cmdVerb; + runScript(3, 0, 0, 0); + } } void ScummEngine_v2::runInputScript(int clickArea, int val, int mode) { diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp index e6ec2b0dab..2eda5cac80 100644 --- a/engines/scumm/scumm.cpp +++ b/engines/scumm/scumm.cpp @@ -726,7 +726,7 @@ ScummEngine_v0::ScummEngine_v0(OSystem *syst, const DetectorResult &dr) _cmdObject2Nr = 0; _cmdObject2Type = 0; - VAR_ACTIVE_ACTOR = 0xFF; + VAR_ACTIVE_OBJECT2 = 0xFF; VAR_IS_SOUND_RUNNING = 0xFF; VAR_ACTIVE_VERB = 0xFF; } diff --git a/engines/scumm/scumm_v0.h b/engines/scumm/scumm_v0.h index 031a73acf9..3335a15ad2 100644 --- a/engines/scumm/scumm_v0.h +++ b/engines/scumm/scumm_v0.h @@ -159,7 +159,7 @@ protected: void o_beginOverride(); void o_setOwnerOf(); - byte VAR_ACTIVE_ACTOR; + byte VAR_ACTIVE_OBJECT2; byte VAR_IS_SOUND_RUNNING; byte VAR_ACTIVE_VERB; }; diff --git a/engines/scumm/vars.cpp b/engines/scumm/vars.cpp index 26a6a2f3b1..6365a728d2 100644 --- a/engines/scumm/vars.cpp +++ b/engines/scumm/vars.cpp @@ -115,7 +115,7 @@ void ScummEngine_v0::setupScummVars() { VAR_CAMERA_POS_X = 2; VAR_HAVE_MSG = 3; VAR_ROOM = 4; - VAR_ACTIVE_ACTOR = 5; + VAR_ACTIVE_OBJECT2 = 5; VAR_OVERRIDE = 6; VAR_IS_SOUND_RUNNING = 8; VAR_ACTIVE_VERB = 9; -- cgit v1.2.3 From 32945904d5267562975d01f2bae5c56a7c35af93 Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Tue, 10 Jan 2012 19:43:24 +0100 Subject: SCUMM: fix kid selection in v0 The kid names are now displayed in the sentence line (instead of the verb area) as it is done in the original. --- engines/scumm/script_v0.cpp | 92 ++++++++++++++++++++++++++------------------- engines/scumm/scumm_v0.h | 5 ++- engines/scumm/verbs.cpp | 62 ++++++++++-------------------- 3 files changed, 76 insertions(+), 83 deletions(-) (limited to 'engines/scumm') diff --git a/engines/scumm/script_v0.cpp b/engines/scumm/script_v0.cpp index f4b98a4ba5..cd2e8969bb 100644 --- a/engines/scumm/script_v0.cpp +++ b/engines/scumm/script_v0.cpp @@ -406,6 +406,42 @@ void ScummEngine_v0::decodeParseString() { actorTalk(buffer); } +void ScummEngine_v0::clearSentenceLine() { + Common::Rect sentenceline; + sentenceline.top = _virtscr[kVerbVirtScreen].topline; + sentenceline.bottom = _virtscr[kVerbVirtScreen].topline + 8; + sentenceline.left = 0; + sentenceline.right = _virtscr[kVerbVirtScreen].w - 1; + restoreBackground(sentenceline); +} + +void ScummEngine_v0::flushSentenceLine() { + byte string[80]; + const char *ptr = _sentenceBuf.c_str(); + int i = 0, len = 0; + + // Maximum length of printable characters + int maxChars = 40; + while (*ptr) { + if (*ptr != '@') + len++; + if (len > maxChars) { + break; + } + + string[i++] = *ptr++; + + } + string[i] = 0; + + _string[2].charset = 1; + _string[2].ypos = _virtscr[kVerbVirtScreen].topline; + _string[2].xpos = 0; + _string[2].right = _virtscr[kVerbVirtScreen].w - 1; + _string[2].color = 16; + drawString(2, (byte *)string); +} + void ScummEngine_v0::drawSentenceObject(int object) { const byte *temp; temp = getObjOrActorName(object); @@ -415,20 +451,30 @@ void ScummEngine_v0::drawSentenceObject(int object) { } } -void ScummEngine_v0::drawSentence() { - Common::Rect sentenceline; +void ScummEngine_v0::drawSentenceLine() { if (!(_userState & 32)) return; + clearSentenceLine(); + + if (_activeVerb == kVerbNewKid) { + _sentenceBuf = ""; + for (int i = 0; i < 3; ++i) { + Actor *a = derefActor(VAR(97 + i), "drawSentence"); + _sentenceBuf += Common::String::format("%-13s", a->getActorName()); + } + flushSentenceLine(); + return; + } + // Current Verb if (_activeVerb == kVerbNone) _activeVerb = kVerbWalkTo; - if (getResourceAddress(rtVerb, _activeVerb)) { - _sentenceBuf = (char *)getResourceAddress(rtVerb, _activeVerb); - } else { - return; - } + + char *verbName = (char *)getResourceAddress(rtVerb, _activeVerb); + assert(verbName); + _sentenceBuf = verbName; if (_activeObjectNr) { // Draw the 1st active object @@ -454,37 +500,7 @@ void ScummEngine_v0::drawSentence() { } } - _string[2].charset = 1; - _string[2].ypos = _virtscr[kVerbVirtScreen].topline; - _string[2].xpos = 0; - _string[2].right = _virtscr[kVerbVirtScreen].w - 1; - _string[2].color = 16; - - byte string[80]; - const char *ptr = _sentenceBuf.c_str(); - int i = 0, len = 0; - - // Maximum length of printable characters - int maxChars = 40; - while (*ptr) { - if (*ptr != '@') - len++; - if (len > maxChars) { - break; - } - - string[i++] = *ptr++; - - } - string[i] = 0; - - sentenceline.top = _virtscr[kVerbVirtScreen].topline; - sentenceline.bottom = _virtscr[kVerbVirtScreen].topline + 8; - sentenceline.left = 0; - sentenceline.right = _virtscr[kVerbVirtScreen].w - 1; - restoreBackground(sentenceline); - - drawString(2, (byte *)string); + flushSentenceLine(); } void ScummEngine_v0::o_stopCurrentScript() { diff --git a/engines/scumm/scumm_v0.h b/engines/scumm/scumm_v0.h index 3335a15ad2..78449eaa57 100644 --- a/engines/scumm/scumm_v0.h +++ b/engines/scumm/scumm_v0.h @@ -101,10 +101,11 @@ protected: virtual void handleMouseOver(bool updateInventory); int verbPrepIdType(int verbid); void resetVerbs(); - void setNewKidVerbs(); + void clearSentenceLine(); + void flushSentenceLine(); void drawSentenceObject(int object); - void drawSentence(); + void drawSentenceLine(); void switchActor(int slot); diff --git a/engines/scumm/verbs.cpp b/engines/scumm/verbs.cpp index 19ad003da6..e06ee3d949 100644 --- a/engines/scumm/verbs.cpp +++ b/engines/scumm/verbs.cpp @@ -131,37 +131,6 @@ void ScummEngine_v0::resetVerbs() { } } -void ScummEngine_v0::setNewKidVerbs() { - VirtScreen *virt = &_virtscr[kVerbVirtScreen]; - VerbSlot *vs; - int i; - - for (i = 1; i < 16; i++) - killVerb(i); - - for (i = 1; i < 4; i++) { - vs = &_verbs[i]; - vs->verbid = i; - vs->color = 5; - vs->hicolor = 7; - vs->dimcolor = 11; - vs->type = kTextVerbType; - vs->charset_nr = _string[0]._default.charset; - vs->curmode = 1; - vs->saveid = 0; - vs->key = 0; - vs->center = 0; - vs->imgindex = 0; - vs->prep = 0; - vs->curRect.left = (i * 8) * 8; - vs->curRect.top = virt->topline + 8; - - Actor *a = derefActor(VAR(96 + i), "setNewKidVerbs"); - loadPtrToResource(rtVerb, i, (const byte*)a->getActorName()); - } - setUserState(191); -} - void ScummEngine_v0::switchActor(int slot) { resetSentence(false); @@ -802,7 +771,24 @@ void ScummEngine_v0::checkExecVerbs() { // 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 + if (_activeVerb == kVerbNewKid) { + if (_currentMode == kModeNormal) { + int kid; + int lineX = _mouse.x >> V12_X_SHIFT; + if (lineX < 11) + kid = 0; + else if (lineX < 25) + kid = 1; + else + kid = 2; + // TODO: get clicked kid + _activeVerb = kVerbWalkTo; + drawSentenceLine(); + switchActor(kid); + } + _activeVerb = kVerbWalkTo; + return; + } } else { int obj = 0; @@ -867,23 +853,13 @@ void ScummEngine_v0::checkExecVerbs() { } if (sentenceLineChanged) { - drawSentence(); + drawSentenceLine(); sentenceLineChanged = false; } if (!execute || !_activeVerb) return; - if (_activeVerb == kVerbNewKid) { - if (_currentMode == kModeNormal) { - // TODO: get clicked kid - _activeVerb = kVerbWalkTo; - drawSentence(); - //switchActor(_verbs[over].verbid - 1); - } - _activeVerb = kVerbWalkTo; - } - if (_activeVerb == kVerbWalkTo) verbExec(); else if (_activeObjectNr) { -- cgit v1.2.3 From c010da00a425ff4be1619093327c46ab2e6c1381 Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Tue, 10 Jan 2012 20:50:23 +0100 Subject: SCUMM: click into sentence line in v0 now performs the action --- engines/scumm/verbs.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'engines/scumm') diff --git a/engines/scumm/verbs.cpp b/engines/scumm/verbs.cpp index e06ee3d949..cb8148d81b 100644 --- a/engines/scumm/verbs.cpp +++ b/engines/scumm/verbs.cpp @@ -781,13 +781,15 @@ void ScummEngine_v0::checkExecVerbs() { kid = 1; else kid = 2; - // TODO: get clicked kid _activeVerb = kVerbWalkTo; drawSentenceLine(); switchActor(kid); } _activeVerb = kVerbWalkTo; return; + } else if (_activeVerb && _activeVerb != kVerbWalkTo && _activeVerb != kVerbWhatIs) { + if (_activeObjectNr && (!activeVerbPrep() || _activeObject2Nr)) + execute = true; } } else { int obj = 0; -- cgit v1.2.3 From df07d2db297b263142a0505d880e57b17e681a97 Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Tue, 10 Jan 2012 22:11:11 +0100 Subject: SCUMM: fix a regression in v0 Found by segra. --- engines/scumm/object.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'engines/scumm') diff --git a/engines/scumm/object.cpp b/engines/scumm/object.cpp index 670b2cb79c..26597864fd 100644 --- a/engines/scumm/object.cpp +++ b/engines/scumm/object.cpp @@ -1223,7 +1223,8 @@ uint32 ScummEngine::getOBCDOffs(int object) const { return 0; for (i = (_numLocalObjects-1); i > 0; i--) { - if (_objs[i].obj_nr == OBJECT_V0_NR(object)) { + 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 != 0) -- cgit v1.2.3 From 8392d23e6bf740fb336cc98e0bbee8882108503a Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Tue, 10 Jan 2012 23:15:53 +0100 Subject: SCUMM: reset sentence line in v0 if sentence executed --- engines/scumm/script.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'engines/scumm') diff --git a/engines/scumm/script.cpp b/engines/scumm/script.cpp index e34c81d0d4..ded47ad60a 100644 --- a/engines/scumm/script.cpp +++ b/engines/scumm/script.cpp @@ -1225,6 +1225,8 @@ void ScummEngine_v0::checkAndRunSentenceScript() { void ScummEngine_v0::runSentenceScript() { int obj = OBJECT_V0(_cmdObjectNr, _cmdObjectType); + drawSentenceLine(); + if (getVerbEntrypoint(obj, _cmdVerb) != 0) { // do not read in the dark if (!(_cmdVerb == kVerbRead && _currentLights == 0)) { -- cgit v1.2.3 From e14bc5fd6d9df5157c841683e6e02f8d25cd8a2c Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Tue, 10 Jan 2012 23:17:40 +0100 Subject: SCUMM: improve verb and sentence handling - execute sentence if verb was clicked twice - reuse the first object if a new verb is selected (but no preposition is used yet) --- engines/scumm/scumm_v0.h | 1 + engines/scumm/verbs.cpp | 52 ++++++++++++++++++++++++++++++++++-------------- 2 files changed, 38 insertions(+), 15 deletions(-) (limited to 'engines/scumm') diff --git a/engines/scumm/scumm_v0.h b/engines/scumm/scumm_v0.h index 78449eaa57..c2af6d4c5f 100644 --- a/engines/scumm/scumm_v0.h +++ b/engines/scumm/scumm_v0.h @@ -97,6 +97,7 @@ protected: virtual void runSentenceScript(); virtual void checkAndRunSentenceScript(); + bool checkSentenceComplete(); virtual void checkExecVerbs(); virtual void handleMouseOver(bool updateInventory); int verbPrepIdType(int verbid); diff --git a/engines/scumm/verbs.cpp b/engines/scumm/verbs.cpp index cb8148d81b..74ff27c483 100644 --- a/engines/scumm/verbs.cpp +++ b/engines/scumm/verbs.cpp @@ -731,6 +731,14 @@ void ScummEngine_v0::verbExec() { a->startWalkActor(VAR(6), VAR(7), -1); } +bool ScummEngine_v0::checkSentenceComplete() { + if (_activeVerb && _activeVerb != kVerbWalkTo && _activeVerb != kVerbWhatIs) { + if (_activeObjectNr && (!activeVerbPrep() || _activeObject2Nr)) + return true; + } + return false; +} + void ScummEngine_v0::checkExecVerbs() { ActorC64 *a = (ActorC64 *)derefActor(VAR(VAR_EGO), "checkExecVerbs"); VirtScreen *zone = findVirtScreen(_mouse.y); @@ -738,21 +746,28 @@ void ScummEngine_v0::checkExecVerbs() { int sentenceLineChanged = false; bool execute = false; - /* - if (_userPut <= 0 || _mouseAndKeyboardStat == 0) - return; - */ + //if (_userPut <= 0) + // return; - // Check if mouse click if (_mouseAndKeyboardStat & MBS_MOUSE_MASK) { int over = findVerbAtPos(_mouse.x, _mouse.y); - if (over && _activeVerb != over) { - _activeVerb = over; - _activeObjectNr = 0; - _activeObjectType = 0; - _activeObject2Nr = 0; - _activeObject2Type = 0; - sentenceLineChanged = true; + // click region: verbs + if (over) { + if (_activeVerb != over) { // new verb + // keep first object if no preposition is used yet + if (activeVerbPrep()) { + _activeObjectNr = 0; + _activeObjectType = 0; + } + _activeObject2Nr = 0; + _activeObject2Type = 0; + _activeVerb = over; + sentenceLineChanged = true; + } else { + // execute sentence if complete + if (checkSentenceComplete()) + execute = true; + } } } @@ -770,6 +785,7 @@ void ScummEngine_v0::checkExecVerbs() { if (_mouseAndKeyboardStat < MBS_MAX_KEY) { // TODO: check keypresses } else if ((_mouseAndKeyboardStat & MBS_MOUSE_MASK) || _activeVerb == kVerbWhatIs) { + // click region: sentence line if (zone->number == kVerbVirtScreen && _mouse.y <= zone->topline + 8) { if (_activeVerb == kVerbNewKid) { if (_currentMode == kModeNormal) { @@ -787,13 +803,18 @@ void ScummEngine_v0::checkExecVerbs() { } _activeVerb = kVerbWalkTo; return; - } else if (_activeVerb && _activeVerb != kVerbWalkTo && _activeVerb != kVerbWhatIs) { - if (_activeObjectNr && (!activeVerbPrep() || _activeObject2Nr)) + } else { + // execute sentence if complete + if (checkSentenceComplete()) execute = true; } - } else { + // click region: inventory or main screen + } else if ((zone->number == kVerbVirtScreen && _mouse.y > zone->topline + 32) || + (zone->number == kMainVirtScreen)) + { int obj = 0; + // click region: inventory if (zone->number == kVerbVirtScreen && _mouse.y > zone->topline + 32) { // click into inventory int invOff = _inventoryOffset; @@ -802,6 +823,7 @@ void ScummEngine_v0::checkExecVerbs() { // inventory position changed (arrows pressed, do nothing) return; } + // click region: main screen } else if (zone->number == kMainVirtScreen) { // click into main screen if (_activeVerb == kVerbGive && _activeObjectNr) { -- cgit v1.2.3 From e89dd623ef2f44bac2768327da7faeef0e2c6f5b Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Tue, 10 Jan 2012 23:39:13 +0100 Subject: SCUMM: pop stack in v0 if command's object1 and 2 are the same Otherwise the command will never be removed and the stack overflows --- engines/scumm/script.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'engines/scumm') diff --git a/engines/scumm/script.cpp b/engines/scumm/script.cpp index ded47ad60a..eb0f7bf16a 100644 --- a/engines/scumm/script.cpp +++ b/engines/scumm/script.cpp @@ -1171,8 +1171,10 @@ void ScummEngine_v0::checkAndRunSentenceScript() { SentenceTab &st = _sentence[_sentenceNum - 1]; - if (st.preposition && st.objectB == st.objectA) + if (st.preposition && st.objectB == st.objectA) { + _sentenceNum--; return; + } // FIXME: should this be executed? //_currentScript = 0xFF; -- cgit v1.2.3 From 4bc726b9958a26e9ce82d00c8fd4ced35b83b83d Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Tue, 10 Jan 2012 23:40:58 +0100 Subject: SCUMM: reset object2 in v0 correctly This fixes the issue that a kid will not enter the front door after opening it with the key. --- engines/scumm/verbs.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'engines/scumm') diff --git a/engines/scumm/verbs.cpp b/engines/scumm/verbs.cpp index 74ff27c483..e70ae49b34 100644 --- a/engines/scumm/verbs.cpp +++ b/engines/scumm/verbs.cpp @@ -710,6 +710,8 @@ void ScummEngine_v0::verbExec() { _activeVerb = kVerbWalkTo; _activeObjectNr = 0; _activeObjectType = 0; + _activeObject2Nr = 0; + _activeObject2Type = 0; } _walkToObjectIdx = 0; return; -- cgit v1.2.3 From ffcd6004613d42d924d20a42694e870c041dadaa Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Wed, 11 Jan 2012 22:50:35 +0100 Subject: SCUMM: make what-is verb work in v0 again --- engines/scumm/verbs.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'engines/scumm') diff --git a/engines/scumm/verbs.cpp b/engines/scumm/verbs.cpp index e70ae49b34..30d0d02976 100644 --- a/engines/scumm/verbs.cpp +++ b/engines/scumm/verbs.cpp @@ -784,7 +784,7 @@ void ScummEngine_v0::checkExecVerbs() { _activeVerb = kVerbPush; } - if (_mouseAndKeyboardStat < MBS_MAX_KEY) { + if (_mouseAndKeyboardStat > 0 && _mouseAndKeyboardStat < MBS_MAX_KEY) { // TODO: check keypresses } else if ((_mouseAndKeyboardStat & MBS_MOUSE_MASK) || _activeVerb == kVerbWhatIs) { // click region: sentence line -- cgit v1.2.3 From 621017ce65f3c5b346c3b17bd4e6700af13215c6 Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Wed, 11 Jan 2012 22:57:46 +0100 Subject: SCUMM: remove some NOTEs/TODOs - o5_breakHere() seems to be still needed. For example edna does not manage to walk up the ladder if this is not enabled. - numLocalObjects seems to be big enough so that < instead of <= can be used. The original interpreter only uses the local ids 0 .. 44 whereas scummvm has _numLocalObjects set to 200. --- engines/scumm/object.cpp | 1 - engines/scumm/script_v5.cpp | 5 +---- 2 files changed, 1 insertion(+), 5 deletions(-) (limited to 'engines/scumm') diff --git a/engines/scumm/object.cpp b/engines/scumm/object.cpp index 26597864fd..86d9065385 100644 --- a/engines/scumm/object.cpp +++ b/engines/scumm/object.cpp @@ -499,7 +499,6 @@ 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; diff --git a/engines/scumm/script_v5.cpp b/engines/scumm/script_v5.cpp index 1d68e86942..707c3c2397 100644 --- a/engines/scumm/script_v5.cpp +++ b/engines/scumm/script_v5.cpp @@ -2493,11 +2493,8 @@ void ScummEngine_v5::walkActorToActor(int actor, int toActor, int dist) { 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) + if (_game.version == 0) o5_breakHere(); - } } void ScummEngine_v5::o5_walkActorToActor() { -- cgit v1.2.3 From b999fe9e265277dbd8e736edec1478013c86feba Mon Sep 17 00:00:00 2001 From: segrax Date: Sun, 15 Jan 2012 23:23:11 +1100 Subject: SCUMM: Add in support in v0 for the unknown variable to o_animateActor --- engines/scumm/actor.cpp | 57 ++++++++++++++++++++++++++++++++---- engines/scumm/actor.h | 15 ++++++++++ engines/scumm/costume.cpp | 70 +++++++++++++++++++++++++++++++++++---------- engines/scumm/script_v0.cpp | 2 ++ 4 files changed, 124 insertions(+), 20 deletions(-) (limited to 'engines/scumm') diff --git a/engines/scumm/actor.cpp b/engines/scumm/actor.cpp index 70e051edfd..bccf4ef746 100644 --- a/engines/scumm/actor.cpp +++ b/engines/scumm/actor.cpp @@ -859,10 +859,16 @@ void Actor::setDirection(int direction) { // V0 MM if (_vm->_game.version == 0) { - if (_moving) - _vm->_costumeLoader->costumeDecodeData(this, _walkFrame, 0); - else - _vm->_costumeLoader->costumeDecodeData(this, _standFrame, 0); + + if (_moving) + _vm->_costumeLoader->costumeDecodeData(this, _walkFrame, 0); + else + _vm->_costumeLoader->costumeDecodeData(this, _standFrame, 0); + + // 0x2C17 + + ((ActorC64*) this)->_byte_FD0A = 0xFF; + _needRedraw = true; return; } @@ -896,6 +902,9 @@ void Actor::turnToDirection(int newdir) { if (newdir == -1 || _ignoreTurns) return; + if( _vm->_game.version == 0 ) + ((ActorC64*) this)->_byte_FD0A = -1; + if (_vm->_game.version <= 6) { _moving = MF_TURN; _targetFacing = newdir; @@ -1794,7 +1803,6 @@ void Actor::animateActor(int anim) { dir = anim % 1000; } else { - cmd = anim / 4; dir = oldDirToNewDir(anim % 4); @@ -2626,6 +2634,45 @@ void ScummEngine_v71he::queueAuxEntry(int actorNum, int subIndex) { } #endif +void ActorC64::animateActor(int anim) { + Actor::animateActor(anim); + return; + int dir = oldDirToNewDir(anim % 4); + + if( this->isInCurrentRoom() ) { + + this->_costCommandNew = anim; + this->_byte_FD0A = this->_byte_FDE8; + + // 0x273A + /*switch( anim ) { + case 4: + dir = 1; + break; + case 5: + dir = 0; + break; + case 6: + dir = 0x80; + break; + case 7: + dir = 0x81; + break; + + default: + return; + }*/ + + this->setDirection( dir ); + + } else { + + if( anim > 4 ) { + if( anim <= 7 ) + this->setDirection( dir ); + } + } +} void ActorC64::saveLoadWithSerializer(Serializer *ser) { Actor::saveLoadWithSerializer(ser); diff --git a/engines/scumm/actor.h b/engines/scumm/actor.h index d8e3692619..1feb1afaa5 100644 --- a/engines/scumm/actor.h +++ b/engines/scumm/actor.h @@ -348,16 +348,29 @@ enum ActorC64MiscFlags { class ActorC64 : public Actor_v2 { public: + byte _costCommandNew; byte _costCommand, _costFrame; byte _miscflags; byte _speaking, _speakingPrev; + byte _byte_FDE8; + int8 _byte_FD0A; + byte _byte_FCE2[8]; + + public: ActorC64(ScummEngine *scumm, int id) : Actor_v2(scumm, id) { _costCommand = 0; _costFrame = 0; _speaking = 0; _speakingPrev = 0; + _byte_FD0A = 0; + _byte_FDE8 = 0; + + // Reset the limb counter? + for( int i = 0; i < sizeof( _byte_FCE2 ); ++i ) + _byte_FCE2[i] = 0; + } virtual void initActor(int mode) { Actor_v2::initActor(mode); @@ -366,6 +379,8 @@ public: } } + virtual void animateActor(int anim); + // Used by the save/load system: virtual void saveLoadWithSerializer(Serializer *ser); diff --git a/engines/scumm/costume.cpp b/engines/scumm/costume.cpp index eb3cc3262c..0c091c38bf 100644 --- a/engines/scumm/costume.cpp +++ b/engines/scumm/costume.cpp @@ -1298,12 +1298,14 @@ void C64CostumeLoader::frameUpdate(ActorC64 *a, int cmd ) { cmd <<= 3; for (int limb = 0, pos = 0; limb < 8; ++limb, pos = 0) { - // get a limb frames ptr from the costume command + // get the frame number for the beginning of the costume command limbFrames = ((_animCmds + cmd)[limb]); - // Dont change limb if entry is invalid + // Dont change if frame is invalid if (limbFrames == 0xFF) - continue; + continue; + + a->_byte_FCE2[limb] = a->_byte_FD0A; // Has limb frames ptr changed since last update? if (a->_cost.start[limb] == limbFrames) @@ -1337,7 +1339,7 @@ void C64CostumeLoader::frameUpdate(ActorC64 *a, int cmd ) { } // Set ending position of limb frames - a->_cost.end[limb] = pos - 1; + a->_cost.end[limb] = pos; a->_cost.curpos[limb] = 0; } } @@ -1345,18 +1347,27 @@ void C64CostumeLoader::frameUpdate(ActorC64 *a, int cmd ) { // based on 0x2BCA, doesn't match disassembly because 'oldDir' variable // is not the same value as stored in the original interpreter int C64CostumeLoader::dirToDirStop(int oldDir) { + int res = 0; + switch (oldDir) { case 0: - return 4; // Left + res = 4; // Left + break; + case 1: - return 5; // Right + res = 5; // Right + break; + case 2: - return 6; // Face Camera - case 3: - return 7; // Face Away + res = 6; // Face Camera + break; + + default: + res = 7; // Face Away + break; } - // shouldnt' be reached - return 4; + + return res; } void C64CostumeLoader::actorSpeak(ActorC64 *a, int &cmd) { @@ -1378,21 +1389,28 @@ void C64CostumeLoader::costumeDecodeData(Actor *a, int frame, uint usemask) { // Enable/Disable speaking flag if (frame == a->_talkStartFrame) { + if (v0ActorTalkArray[a->_number] & 0x40) return; A->_speaking = 1; return; } + if (frame == a->_talkStopFrame) { + A->_speaking = 0; return; } // Different command for stand frame if (frame == a->_standFrame) + { command = dirToDirStop(dir); + A->_byte_FDE8 = 0xFF; + } + // Update the limb frames frameUpdate(A, command); @@ -1435,11 +1453,33 @@ byte C64CostumeLoader::increaseAnims(Actor *a) { } // increase each frame pos + // 0x2543 for (int limb = 0; limb < 8; ++limb) { - if (a->_cost.curpos[limb] < a->_cost.end[limb]) - a->_cost.curpos[limb]++; - else - a->_cost.curpos[limb] = 0; + + if (++a->_cost.curpos[limb] >= a->_cost.end[limb]) { + + // 0x2541 + if( A->_byte_FCE2[limb] == 0 ) { + + // 0x2556 + --a->_cost.curpos[limb]; + + A->_costCommandNew = 0xFF; + //A->_costCommand = 0xFF; + + // 0x2568 + //A->_limbCommandNew[limb] = 0xFF; + //A->_limbCommand[limb] = 0xFF; + + } else { + if( A->_byte_FCE2[limb] != 0xFF ) + --A->_byte_FCE2[limb]; + + a->_cost.curpos[limb] = 0; + } + } + + } return 1; diff --git a/engines/scumm/script_v0.cpp b/engines/scumm/script_v0.cpp index cd2e8969bb..e3d74fcd90 100644 --- a/engines/scumm/script_v0.cpp +++ b/engines/scumm/script_v0.cpp @@ -663,6 +663,8 @@ void ScummEngine_v0::o_animateActor() { ActorC64 *a = (ActorC64*) derefActor(act, "o_animateActor"); + a->_byte_FDE8 = unk; + // 0x6993 if (anim == 0xFE) { a->_speaking = 0x80; // Enabled, but not switching -- cgit v1.2.3 From 6ca91a2be5e2f2ad981e52a5c21ca97ca3dee48d Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Sun, 15 Jan 2012 19:26:02 +0100 Subject: SCUMM: Fix actor behind man-eating plant issue in v0. Thanks segra for finding how it works in the original interpreter. The plant is handled specially and 0 is used instead of its y-position. --- engines/scumm/actor.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'engines/scumm') diff --git a/engines/scumm/actor.cpp b/engines/scumm/actor.cpp index bccf4ef746..950f580f42 100644 --- a/engines/scumm/actor.cpp +++ b/engines/scumm/actor.cpp @@ -1474,6 +1474,18 @@ void ScummEngine::processActors() { } } } + } else if (_game.version == 0) { + for (int j = 0; j < numactors; ++j) { + for (int i = 0; i < numactors; ++i) { + // Note: the plant is handled different in v0, the y value is not used. + // In v1/2 this is done by the actor's elevation instead. + int sc_actor1 = (_sortedActors[j]->_number == 19 ? 0 : _sortedActors[j]->getPos().y); + int sc_actor2 = (_sortedActors[i]->_number == 19 ? 0 : _sortedActors[i]->getPos().y); + if (sc_actor1 < sc_actor2) { + SWAP(_sortedActors[i], _sortedActors[j]); + } + } + } } else { for (int j = 0; j < numactors; ++j) { for (int i = 0; i < numactors; ++i) { -- cgit v1.2.3 From f2309998ffbcb33a96edac7f2959abc534717827 Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Sun, 15 Jan 2012 20:11:30 +0100 Subject: SCUMM: fix debugger for v0 --- engines/scumm/debugger.cpp | 11 +++++++---- engines/scumm/object.cpp | 11 +++++++++++ engines/scumm/object.h | 12 ++++++++++++ engines/scumm/script.cpp | 6 +++--- engines/scumm/script_v0.cpp | 14 ++++++-------- engines/scumm/scumm.h | 1 + engines/scumm/scumm_v0.h | 13 ------------- engines/scumm/verbs.cpp | 2 +- 8 files changed, 41 insertions(+), 29 deletions(-) (limited to 'engines/scumm') diff --git a/engines/scumm/debugger.cpp b/engines/scumm/debugger.cpp index 54f7fea97b..59018f1269 100644 --- a/engines/scumm/debugger.cpp +++ b/engines/scumm/debugger.cpp @@ -382,7 +382,7 @@ bool ScummDebugger::Cmd_Actor(int argc, const char **argv) { DebugPrintf("Actor[%d].costume = %d\n", actnum, a->_costume); } } else if (!strcmp(argv[2], "name")) { - DebugPrintf("Name of actor %d: %s\n", actnum, _vm->getObjOrActorName(actnum)); + DebugPrintf("Name of actor %d: %s\n", actnum, _vm->getActorName(actnum)); } else if (!strcmp(argv[2], "condmask")) { if (argc > 3) { a->_heCondMask = value; @@ -427,9 +427,11 @@ bool ScummDebugger::Cmd_PrintObjects(int argc, const char **argv) { o = &(_vm->_objs[i]); if (o->obj_nr == 0) continue; + int obj = (_vm->_game.version != 0 ? o->obj_nr : OBJECT_V0(o->obj_nr, o->obj_type)); + int classData = (_vm->_game.version != 0 ? _vm->_classData[o->obj_nr] : 0); DebugPrintf("|%4d|%4d|%4d|%5d|%6d|%5d|%2d|$%08x|\n", - o->obj_nr, o->x_pos, o->y_pos, o->width, o->height, o->state, - o->fl_object_index, _vm->_classData[o->obj_nr]); + obj, o->x_pos, o->y_pos, o->width, o->height, o->state, + o->fl_object_index, classData); } DebugPrintf("\n"); @@ -446,7 +448,8 @@ bool ScummDebugger::Cmd_Object(int argc, const char **argv) { } obj = atoi(argv[1]); - if (obj >= _vm->_numGlobalObjects) { + int obj_nr = (_vm->_game.version != 0 ? obj : OBJECT_V0_NR(obj)); + if (obj_nr >= _vm->_numGlobalObjects) { DebugPrintf("Object %d is out of range (range: 1 - %d)\n", obj, _vm->_numGlobalObjects); return true; } diff --git a/engines/scumm/object.cpp b/engines/scumm/object.cpp index 86d9065385..d3ed086892 100644 --- a/engines/scumm/object.cpp +++ b/engines/scumm/object.cpp @@ -1150,6 +1150,17 @@ void ScummEngine::markObjectRectAsDirty(int obj) { } } +const byte *ScummEngine::getActorName(int id) { + if (_game.version == 0) { + if (id > 0 && id < _numActors) + return derefActor(id, "getActorName")->getActorName(); + else + return NULL; + } else { + return getObjOrActorName(id); + } +} + const byte *ScummEngine::getObjOrActorName(int obj) { byte *objptr; int i; diff --git a/engines/scumm/object.h b/engines/scumm/object.h index 7e4a5b57ab..12956fc4fd 100644 --- a/engines/scumm/object.h +++ b/engines/scumm/object.h @@ -31,6 +31,18 @@ static inline int OBJECT_V0(int id, byte type) { #define OBJECT_V0_NR(obj) (obj & 0xFF) #define OBJECT_V0_TYPE(obj) ((obj >> 8) & 0xFF) +enum ObjectV0Type { + kObjectV0TypeFG = 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) + kObjectV0TypeBG = 1, // background object + // - without owner/state, not pickupable (room only) + // -> without entry in _objectOwner/StateTable + // - image cannot be exchanged (part of background image) + kObjectV0TypeActor = 2 // object is an actor +}; enum ObjectClass { kObjectClassNeverClip = 20, diff --git a/engines/scumm/script.cpp b/engines/scumm/script.cpp index eb0f7bf16a..bc6873edf2 100644 --- a/engines/scumm/script.cpp +++ b/engines/scumm/script.cpp @@ -1137,7 +1137,7 @@ void ScummEngine_v0::walkToActorOrObject(int object) { _walkToObject = object; _walkToObjectIdx = getObjectIndex(object); - if (OBJECT_V0_TYPE(object) == kObjectTypeActor) { + if (OBJECT_V0_TYPE(object) == kObjectV0TypeActor) { walkActorToActor(VAR(VAR_EGO), OBJECT_V0_NR(object), 4); x = a->getRealPos().x; y = a->getRealPos().y; @@ -1187,8 +1187,8 @@ void ScummEngine_v0::checkAndRunSentenceScript() { // 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))) + (obj1Type != kObjectV0TypeFG || _objectOwnerTable[obj1Nr] != VAR(VAR_EGO)) && + (obj2Type != kObjectV0TypeFG || _objectOwnerTable[obj2Nr] != VAR(VAR_EGO))) { if (getVerbEntrypoint(st.objectA, kVerbPickUp)) doSentence(kVerbPickUp, st.objectA, 0); diff --git a/engines/scumm/script_v0.cpp b/engines/scumm/script_v0.cpp index e3d74fcd90..f35230b6e2 100644 --- a/engines/scumm/script_v0.cpp +++ b/engines/scumm/script_v0.cpp @@ -461,8 +461,7 @@ void ScummEngine_v0::drawSentenceLine() { if (_activeVerb == kVerbNewKid) { _sentenceBuf = ""; for (int i = 0; i < 3; ++i) { - Actor *a = derefActor(VAR(97 + i), "drawSentence"); - _sentenceBuf += Common::String::format("%-13s", a->getActorName()); + _sentenceBuf += Common::String::format("%-13s", getActorName(VAR(97 + i))); } flushSentenceLine(); return; @@ -488,10 +487,9 @@ void ScummEngine_v0::drawSentenceLine() { // Draw the 2nd active object if (_activeObject2Nr) { // 2nd Object is an actor - if (_activeObject2Type == kObjectTypeActor) { - Actor *a = derefActor(_activeObject2Nr, ""); + if (_activeObject2Type == kObjectV0TypeActor) { _sentenceBuf += " "; - _sentenceBuf += (const char *)a->getActorName(); + _sentenceBuf += (const char *)getActorName(_activeObject2Nr); // 2nd Object is an inventory or room object } else { drawSentenceObject(OBJECT_V0(_activeObject2Nr, _activeObject2Type)); @@ -838,7 +836,7 @@ void ScummEngine_v0::o_doSentence() { bool ScummEngine_v0::ifEqualActiveObject2Common(bool ignoreType) { byte obj = fetchScriptByte(); - if (!ignoreType || (_cmdObject2Type == kObjectTypeFG)) + if (!ignoreType || (_cmdObject2Type == kObjectV0TypeFG)) return (obj == _cmdObject2Nr); return false; } @@ -952,9 +950,9 @@ void ScummEngine_v0::o_setOwnerOf() { void ScummEngine_v0::resetSentence(bool walking) { _activeVerb = kVerbWalkTo; _activeObjectNr = 0; - _activeObjectType = kObjectTypeBG; + _activeObjectType = kObjectV0TypeBG; _activeObject2Nr = 0; - _activeObject2Type = kObjectTypeBG; + _activeObject2Type = kObjectV0TypeBG; _walkToObjectIdx = 0; } diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h index fadc3902c0..d77ae44d4c 100644 --- a/engines/scumm/scumm.h +++ b/engines/scumm/scumm.h @@ -804,6 +804,7 @@ public: protected: int getObjActToObjActDist(int a, int b); // Not sure how to handle + const byte *getActorName(int id); const byte *getObjOrActorName(int obj); // these three.. void setObjectName(int obj); diff --git a/engines/scumm/scumm_v0.h b/engines/scumm/scumm_v0.h index c2af6d4c5f..4da46b31bf 100644 --- a/engines/scumm/scumm_v0.h +++ b/engines/scumm/scumm_v0.h @@ -39,19 +39,6 @@ protected: kModeNormal = 3, // normal playing mode }; - enum ObjectType { - 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: byte _currentMode; diff --git a/engines/scumm/verbs.cpp b/engines/scumm/verbs.cpp index 30d0d02976..99fdafa5b6 100644 --- a/engines/scumm/verbs.cpp +++ b/engines/scumm/verbs.cpp @@ -829,7 +829,7 @@ void ScummEngine_v0::checkExecVerbs() { } else if (zone->number == kMainVirtScreen) { // click into main screen if (_activeVerb == kVerbGive && _activeObjectNr) { - obj = OBJECT_V0(getActorFromPos(_virtualMouse.x, _virtualMouse.y), kObjectTypeActor); + obj = OBJECT_V0(getActorFromPos(_virtualMouse.x, _virtualMouse.y), kObjectV0TypeActor); } else { obj = findObject(_virtualMouse.x, _virtualMouse.y); } -- cgit v1.2.3 From c138ef67099cd14bedd4e0e79080e31e2b41eddd Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Sun, 15 Jan 2012 21:43:21 +0100 Subject: SCUMM: merge _activeObjectNr/_activeObjectType and _cmdObjectNr/_cmdObjectType --- engines/scumm/debugger.cpp | 3 ++- engines/scumm/object.cpp | 18 ++++--------- engines/scumm/script.cpp | 31 +++++++++------------- engines/scumm/script_v0.cpp | 62 ++++++++++++++++--------------------------- engines/scumm/scumm.cpp | 12 +++------ engines/scumm/scumm.h | 1 - engines/scumm/scumm_v0.h | 18 +++++-------- engines/scumm/verbs.cpp | 64 ++++++++++++++++++--------------------------- 8 files changed, 78 insertions(+), 131 deletions(-) (limited to 'engines/scumm') diff --git a/engines/scumm/debugger.cpp b/engines/scumm/debugger.cpp index 59018f1269..b52dc7997a 100644 --- a/engines/scumm/debugger.cpp +++ b/engines/scumm/debugger.cpp @@ -382,7 +382,8 @@ bool ScummDebugger::Cmd_Actor(int argc, const char **argv) { DebugPrintf("Actor[%d].costume = %d\n", actnum, a->_costume); } } else if (!strcmp(argv[2], "name")) { - DebugPrintf("Name of actor %d: %s\n", actnum, _vm->getActorName(actnum)); + int actor = (_vm->_game.version != 0 ? actnum : OBJECT_V0(actnum, kObjectV0TypeActor)); + DebugPrintf("Name of actor %d: %s\n", actnum, _vm->getObjOrActorName(actor)); } else if (!strcmp(argv[2], "condmask")) { if (argc > 3) { a->_heCondMask = value; diff --git a/engines/scumm/object.cpp b/engines/scumm/object.cpp index d3ed086892..f7a01fd4cc 100644 --- a/engines/scumm/object.cpp +++ b/engines/scumm/object.cpp @@ -1150,23 +1150,15 @@ void ScummEngine::markObjectRectAsDirty(int obj) { } } -const byte *ScummEngine::getActorName(int id) { - if (_game.version == 0) { - if (id > 0 && id < _numActors) - return derefActor(id, "getActorName")->getActorName(); - else - return NULL; - } else { - return getObjOrActorName(id); - } -} - const byte *ScummEngine::getObjOrActorName(int obj) { byte *objptr; int i; - if (obj < _numActors && _game.version >= 1) - return derefActor(obj, "getObjOrActorName")->getActorName(); + if ((_game.version == 0 && OBJECT_V0_TYPE(obj) == kObjectV0TypeActor) || + (_game.version != 0 && obj < _numActors)) { + int actorNr = (_game.version != 0 ? obj : OBJECT_V0_NR(obj)); + return derefActor(actorNr, "getObjOrActorName")->getActorName(); + } for (i = 0; i < _numNewNames; i++) { if (_newNames[i] == obj) { diff --git a/engines/scumm/script.cpp b/engines/scumm/script.cpp index bc6873edf2..3fa89b68fb 100644 --- a/engines/scumm/script.cpp +++ b/engines/scumm/script.cpp @@ -1179,16 +1179,12 @@ void ScummEngine_v0::checkAndRunSentenceScript() { // 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); + assert(st.objectA); // If two objects are involved, at least one must be in the actors inventory - if (obj2Nr && - (obj1Type != kObjectV0TypeFG || _objectOwnerTable[obj1Nr] != VAR(VAR_EGO)) && - (obj2Type != kObjectV0TypeFG || _objectOwnerTable[obj2Nr] != VAR(VAR_EGO))) + if (st.objectB && + (OBJECT_V0_TYPE(st.objectA) != kObjectV0TypeFG || _objectOwnerTable[st.objectA] != VAR(VAR_EGO)) && + (OBJECT_V0_TYPE(st.objectB) != kObjectV0TypeFG || _objectOwnerTable[st.objectB] != VAR(VAR_EGO))) { if (getVerbEntrypoint(st.objectA, kVerbPickUp)) doSentence(kVerbPickUp, st.objectA, 0); @@ -1200,10 +1196,8 @@ void ScummEngine_v0::checkAndRunSentenceScript() { } _cmdVerb = st.verb; - _cmdObjectNr = obj1Nr; - _cmdObjectType = obj1Type; - _cmdObject2Nr = obj2Nr; - _cmdObject2Type = obj2Type; + _cmdObject = st.objectA; + _cmdObject2 = st.objectB; _sentenceNum--; // TODO: check sentenceNum @@ -1225,22 +1219,21 @@ void ScummEngine_v0::checkAndRunSentenceScript() { } void ScummEngine_v0::runSentenceScript() { - int obj = OBJECT_V0(_cmdObjectNr, _cmdObjectType); - drawSentenceLine(); - if (getVerbEntrypoint(obj, _cmdVerb) != 0) { + if (getVerbEntrypoint(_cmdObject, _cmdVerb) != 0) { // do not read in the dark if (!(_cmdVerb == kVerbRead && _currentLights == 0)) { - VAR(VAR_ACTIVE_OBJECT2) = _cmdObject2Nr; - runObjectScript(obj, _cmdVerb, false, false, NULL); + VAR(VAR_ACTIVE_OBJECT2) = OBJECT_V0_NR(_cmdObject2); + runObjectScript(_cmdObject, _cmdVerb, false, false, NULL); return; } } else { if (_cmdVerb == kVerbGive) { // no "give to"-script: give to other kid or ignore - if (_cmdObject2Nr < 8) - setOwnerOf(obj, _cmdObject2Nr); + int actor = OBJECT_V0_NR(_cmdObject2); + if (actor < 8) + setOwnerOf(_cmdObject, actor); return; } } diff --git a/engines/scumm/script_v0.cpp b/engines/scumm/script_v0.cpp index f35230b6e2..a40dd44727 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 _cmdObjectNr; + return OBJECT_V0_NR(_cmdObject); return fetchScriptByte(); } @@ -461,7 +461,8 @@ void ScummEngine_v0::drawSentenceLine() { if (_activeVerb == kVerbNewKid) { _sentenceBuf = ""; for (int i = 0; i < 3; ++i) { - _sentenceBuf += Common::String::format("%-13s", getActorName(VAR(97 + i))); + Actor *a = derefActor(VAR(97 + i), "drawSentenceLine"); + _sentenceBuf += Common::String::format("%-13s", a->getActorName()); } flushSentenceLine(); return; @@ -475,9 +476,9 @@ void ScummEngine_v0::drawSentenceLine() { assert(verbName); _sentenceBuf = verbName; - if (_activeObjectNr) { + if (_activeObject) { // Draw the 1st active object - drawSentenceObject(OBJECT_V0(_activeObjectNr, _activeObjectType)); + drawSentenceObject(_activeObject); // Append verb preposition int sentencePrep = activeVerbPrep(); @@ -485,16 +486,8 @@ void ScummEngine_v0::drawSentenceLine() { drawPreposition(sentencePrep); // Draw the 2nd active object - if (_activeObject2Nr) { - // 2nd Object is an actor - if (_activeObject2Type == kObjectV0TypeActor) { - _sentenceBuf += " "; - _sentenceBuf += (const char *)getActorName(_activeObject2Nr); - // 2nd Object is an inventory or room object - } else { - drawSentenceObject(OBJECT_V0(_activeObject2Nr, _activeObject2Type)); - } - } + if (_activeObject2) + drawSentenceObject(_activeObject2); } } @@ -708,8 +701,9 @@ void ScummEngine_v0::o_putActorAtObject() { } void ScummEngine_v0::o_pickupObject() { - int objNr = fetchScriptByte(); - int obj = OBJECT_V0((objNr ? objNr : _cmdObjectNr), 0); + int obj = fetchScriptByte(); + if (!obj) + obj = _cmdObject; /* Don't take an object twice */ if (whereIsObject(obj) == WIO_INVENTORY) @@ -761,7 +755,7 @@ void ScummEngine_v0::o_setActorBitVar() { void ScummEngine_v0::o_getObjectOwner() { getResultPos(); int obj = getVarOrDirectWord(PARAM_1); - setResult(getOwner(obj ? obj : _cmdObjectNr)); + setResult(getOwner(obj ? obj : _cmdObject)); } void ScummEngine_v0::o_getActorBitVar() { @@ -815,20 +809,20 @@ void ScummEngine_v0::o_doSentence() { b = fetchScriptByte(); if (b == 0xFF) { - obj = OBJECT_V0(_cmdObject2Nr, _cmdObject2Type); + obj = _cmdObject2; } else if (b == 0xFE) { - obj = OBJECT_V0(_cmdObjectNr, _cmdObjectType); + obj = _cmdObject; } else { - obj = OBJECT_V0(b, (_opcode & 0x80) ? 1 : 0); + obj = OBJECT_V0(b, (_opcode & 0x80) ? kObjectV0TypeBG : kObjectV0TypeFG); } b = fetchScriptByte(); if (b == 0xFF) { - obj2 = OBJECT_V0(_cmdObject2Nr, _cmdObject2Type); + obj2 = _cmdObject2; } else if (b == 0xFE) { - obj2 = OBJECT_V0(_cmdObjectNr, _cmdObjectType); + obj2 = _cmdObject; } else { - obj2 = OBJECT_V0(b, (_opcode & 0x40) ? 1 : 0); + obj2 = OBJECT_V0(b, (_opcode & 0x40) ? kObjectV0TypeBG : kObjectV0TypeFG); } doSentence(verb, obj, obj2); @@ -836,8 +830,8 @@ void ScummEngine_v0::o_doSentence() { bool ScummEngine_v0::ifEqualActiveObject2Common(bool ignoreType) { byte obj = fetchScriptByte(); - if (!ignoreType || (_cmdObject2Type == kObjectV0TypeFG)) - return (obj == _cmdObject2Nr); + if (!ignoreType || (OBJECT_V0_TYPE(_cmdObject2) == kObjectV0TypeFG)) + return (obj == OBJECT_V0_NR(_cmdObject2)); return false; } @@ -933,26 +927,16 @@ void ScummEngine_v0::o_setOwnerOf() { obj = getVarOrDirectWord(PARAM_1); owner = getVarOrDirectByte(PARAM_2); - if (obj == 0) - obj = _cmdObjectNr; - - // FIXME: the original interpreter seems to set the owner of - // an item to remove (new owner 0) to 13 (purple tentacle). - // Ignore this behavior for now. - /* - if (owner == 0) - owner = 13; - */ + if (!obj) + obj = _cmdObject; setOwnerOf(obj, owner); } void ScummEngine_v0::resetSentence(bool walking) { _activeVerb = kVerbWalkTo; - _activeObjectNr = 0; - _activeObjectType = kObjectV0TypeBG; - _activeObject2Nr = 0; - _activeObject2Type = kObjectV0TypeBG; + _activeObject = 0; + _activeObject2 = 0; _walkToObjectIdx = 0; } diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp index 2eda5cac80..f2db5ad6ba 100644 --- a/engines/scumm/scumm.cpp +++ b/engines/scumm/scumm.cpp @@ -715,16 +715,12 @@ ScummEngine_v0::ScummEngine_v0(OSystem *syst, const DetectorResult &dr) _currentMode = 0; _activeVerb = kVerbNone; - _activeObjectNr = 0; - _activeObjectType = 0; - _activeObject2Nr = 0; - _activeObject2Type = 0; + _activeObject = 0; + _activeObject2 = 0; _cmdVerb = kVerbNone; - _cmdObjectNr = 0; - _cmdObjectType = 0; - _cmdObject2Nr = 0; - _cmdObject2Type = 0; + _cmdObject = 0; + _cmdObject2 = 0; VAR_ACTIVE_OBJECT2 = 0xFF; VAR_IS_SOUND_RUNNING = 0xFF; diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h index d77ae44d4c..fadc3902c0 100644 --- a/engines/scumm/scumm.h +++ b/engines/scumm/scumm.h @@ -804,7 +804,6 @@ public: protected: int getObjActToObjActDist(int a, int b); // Not sure how to handle - const byte *getActorName(int id); const byte *getObjOrActorName(int obj); // these three.. void setObjectName(int obj); diff --git a/engines/scumm/scumm_v0.h b/engines/scumm/scumm_v0.h index 4da46b31bf..6b49cc0ddf 100644 --- a/engines/scumm/scumm_v0.h +++ b/engines/scumm/scumm_v0.h @@ -42,17 +42,13 @@ protected: protected: byte _currentMode; - int _activeVerb; - 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) - - int _cmdVerb; - int _cmdObjectNr; - int _cmdObjectType; - int _cmdObject2Nr; - int _cmdObject2Type; + int _activeVerb; // selected verb + int _activeObject; // 1st selected object (see OBJECT_V0(nr, type), cannot be an actor) + int _activeObject2; // 2nd selected object or actor (see OBJECT_V0(nr, type)) + + int _cmdVerb; // script verb + int _cmdObject; // 1st script object (see OBJECT_V0(nr, type)) + int _cmdObject2; // 2nd script object or actor (see OBJECT_V0(nr, type)) int _walkToObject; int _walkToObjectIdx; diff --git a/engines/scumm/verbs.cpp b/engines/scumm/verbs.cpp index 99fdafa5b6..dc049816e3 100644 --- a/engines/scumm/verbs.cpp +++ b/engines/scumm/verbs.cpp @@ -686,14 +686,14 @@ int ScummEngine_v0::getVerbPrepId() { if (_verbs[_activeVerb].prep != 0xFF) { return _verbs[_activeVerb].prep; } else { - byte *ptr = getOBCDFromObject(OBJECT_V0(_activeObjectNr, _activeObjectType), true); + byte *ptr = getOBCDFromObject(_activeObject, true); assert(ptr); return (*(ptr + 11) >> 5); } } int ScummEngine_v0::activeVerbPrep() { - if (!_activeVerb || !_activeObjectNr) + if (!_activeVerb || !_activeObject) return 0; return getVerbPrepId(); } @@ -702,16 +702,12 @@ 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 && _activeObject == 0)) { + doSentence(_activeVerb, _activeObject, _activeObject2); if (_activeVerb != kVerbWalkTo) { _activeVerb = kVerbWalkTo; - _activeObjectNr = 0; - _activeObjectType = 0; - _activeObject2Nr = 0; - _activeObject2Type = 0; + _activeObject = 0; + _activeObject2 = 0; } _walkToObjectIdx = 0; return; @@ -735,7 +731,7 @@ void ScummEngine_v0::verbExec() { bool ScummEngine_v0::checkSentenceComplete() { if (_activeVerb && _activeVerb != kVerbWalkTo && _activeVerb != kVerbWhatIs) { - if (_activeObjectNr && (!activeVerbPrep() || _activeObject2Nr)) + if (_activeObject && (!activeVerbPrep() || _activeObject2)) return true; } return false; @@ -757,12 +753,9 @@ void ScummEngine_v0::checkExecVerbs() { if (over) { if (_activeVerb != over) { // new verb // keep first object if no preposition is used yet - if (activeVerbPrep()) { - _activeObjectNr = 0; - _activeObjectType = 0; - } - _activeObject2Nr = 0; - _activeObject2Type = 0; + if (activeVerbPrep()) + _activeObject = 0; + _activeObject2 = 0; _activeVerb = over; sentenceLineChanged = true; } else { @@ -828,41 +821,34 @@ void ScummEngine_v0::checkExecVerbs() { // click region: main screen } else if (zone->number == kMainVirtScreen) { // click into main screen - if (_activeVerb == kVerbGive && _activeObjectNr) { - obj = OBJECT_V0(getActorFromPos(_virtualMouse.x, _virtualMouse.y), kObjectV0TypeActor); + if (_activeVerb == kVerbGive && _activeObject) { + int actor = getActorFromPos(_virtualMouse.x, _virtualMouse.y); + if (actor != 0) + obj = OBJECT_V0(actor, kObjectV0TypeActor); } else { obj = findObject(_virtualMouse.x, _virtualMouse.y); } } - int id = OBJECT_V0_NR(obj); - int type = OBJECT_V0_TYPE(obj); - debug("found 0x%03x", obj); - - if (!id) { + if (!obj) { if (_activeVerb == kVerbWalkTo) { - _activeObjectNr = 0; - _activeObjectType = 0; - _activeObject2Nr = 0; - _activeObject2Type = 0; + _activeObject = 0; + _activeObject2 = 0; } } else { if (activeVerbPrep() == kVerbPrepNone) { - if (id == _activeObjectNr && type == _activeObjectType) { + if (obj == _activeObject) execute = true; - } else { - _activeObjectNr = id; - _activeObjectType = type; - } + else + _activeObject = obj; // immediately execute action in keypad/selection mode if (_currentMode == kModeKeypad) execute = true; } else { - if (id == _activeObject2Nr && type == _activeObject2Type) + if (obj == _activeObject2) execute = true; - if (!(id == _activeObjectNr && type == _activeObjectType)) { - _activeObject2Nr = id; - _activeObject2Type = type; + if (obj != _activeObject) { + _activeObject2 = obj; if (_currentMode == kModeKeypad) execute = true; } @@ -888,9 +874,9 @@ void ScummEngine_v0::checkExecVerbs() { if (_activeVerb == kVerbWalkTo) verbExec(); - else if (_activeObjectNr) { + else if (_activeObject) { // execute if we have a 1st object and either have or do not need a 2nd - if (activeVerbPrep() == kVerbPrepNone || _activeObject2Nr) + if (activeVerbPrep() == kVerbPrepNone || _activeObject2) verbExec(); } } -- cgit v1.2.3 From 8141511e2f6eb01a526d6adf3ecf915c656e280c Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Sun, 15 Jan 2012 23:51:28 +0100 Subject: SCUMM: fix ScummEngine_v0::ifEqualActiveObject2Common() parameter name --- engines/scumm/script_v0.cpp | 4 ++-- engines/scumm/scumm_v0.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'engines/scumm') diff --git a/engines/scumm/script_v0.cpp b/engines/scumm/script_v0.cpp index a40dd44727..ac6ee4b9d6 100644 --- a/engines/scumm/script_v0.cpp +++ b/engines/scumm/script_v0.cpp @@ -828,9 +828,9 @@ void ScummEngine_v0::o_doSentence() { doSentence(verb, obj, obj2); } -bool ScummEngine_v0::ifEqualActiveObject2Common(bool ignoreType) { +bool ScummEngine_v0::ifEqualActiveObject2Common(bool checkType) { byte obj = fetchScriptByte(); - if (!ignoreType || (OBJECT_V0_TYPE(_cmdObject2) == kObjectV0TypeFG)) + if (!checkType || (OBJECT_V0_TYPE(_cmdObject2) == kObjectV0TypeFG)) return (obj == OBJECT_V0_NR(_cmdObject2)); return false; } diff --git a/engines/scumm/scumm_v0.h b/engines/scumm/scumm_v0.h index 6b49cc0ddf..cdae22e983 100644 --- a/engines/scumm/scumm_v0.h +++ b/engines/scumm/scumm_v0.h @@ -102,7 +102,7 @@ protected: virtual bool areBoxesNeighbors(int box1nr, int box2nr); - bool ifEqualActiveObject2Common(bool ignoreType); + bool ifEqualActiveObject2Common(bool checkType); /* Version C64 script opcodes */ void o_stopCurrentScript(); -- cgit v1.2.3 From 347035385e3608c3107db7b9cba0673ce9e03a22 Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Mon, 16 Jan 2012 22:32:46 +0100 Subject: SCUMM: merge object v0 id and type into one object var --- engines/scumm/debugger.cpp | 6 ++--- engines/scumm/object.cpp | 55 ++++++++++++++++----------------------------- engines/scumm/object.h | 11 +++------ engines/scumm/saveload.cpp | 17 +++++++++----- engines/scumm/script.cpp | 6 ++--- engines/scumm/script_v0.cpp | 4 ++-- engines/scumm/scumm_v0.h | 8 +++---- 7 files changed, 44 insertions(+), 63 deletions(-) (limited to 'engines/scumm') diff --git a/engines/scumm/debugger.cpp b/engines/scumm/debugger.cpp index b52dc7997a..5d1396633f 100644 --- a/engines/scumm/debugger.cpp +++ b/engines/scumm/debugger.cpp @@ -428,10 +428,9 @@ bool ScummDebugger::Cmd_PrintObjects(int argc, const char **argv) { o = &(_vm->_objs[i]); if (o->obj_nr == 0) continue; - int obj = (_vm->_game.version != 0 ? o->obj_nr : OBJECT_V0(o->obj_nr, o->obj_type)); int classData = (_vm->_game.version != 0 ? _vm->_classData[o->obj_nr] : 0); DebugPrintf("|%4d|%4d|%4d|%5d|%6d|%5d|%2d|$%08x|\n", - obj, o->x_pos, o->y_pos, o->width, o->height, o->state, + o->obj_nr, o->x_pos, o->y_pos, o->width, o->height, o->state, o->fl_object_index, classData); } DebugPrintf("\n"); @@ -449,8 +448,7 @@ bool ScummDebugger::Cmd_Object(int argc, const char **argv) { } obj = atoi(argv[1]); - int obj_nr = (_vm->_game.version != 0 ? obj : OBJECT_V0_NR(obj)); - if (obj_nr >= _vm->_numGlobalObjects) { + if (_vm->_game.version != 0 && obj >= _vm->_numGlobalObjects) { DebugPrintf("Object %d is out of range (range: 1 - %d)\n", obj, _vm->_numGlobalObjects); return true; } diff --git a/engines/scumm/object.cpp b/engines/scumm/object.cpp index f7a01fd4cc..bf871d7fa5 100644 --- a/engines/scumm/object.cpp +++ b/engines/scumm/object.cpp @@ -203,6 +203,9 @@ void ScummEngine::clearOwnerOf(int obj) { } bool ScummEngine::getClass(int obj, int cls) const { + if (_game.version == 0) + return false; + assertRange(0, obj, _numGlobalObjects - 1, "object"); cls &= 0x7F; assertRange(1, cls, 32, "class"); @@ -230,6 +233,9 @@ bool ScummEngine::getClass(int obj, int cls) const { } void ScummEngine::putClass(int obj, int cls, bool set) { + if (_game.version == 0) + return; + assertRange(0, obj, _numGlobalObjects - 1, "object"); cls &= 0x7F; assertRange(1, cls, 32, "class"); @@ -307,16 +313,12 @@ 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 (nr < 1) + if (object < 1) return -1; for (i = (_numLocalObjects-1); i > 0; i--) { - if (_game.version == 0 && _objs[i].obj_type != OBJECT_V0_TYPE(object)) - continue; - - if (_objs[i].obj_nr == nr) + if (_objs[i].obj_nr == object) return i; } return -1; @@ -342,10 +344,7 @@ int ScummEngine::whereIsObject(int object) const { } 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].obj_nr == object) { if (_objs[i].fl_object_index) return WIO_FLOBJECT; return WIO_ROOM; @@ -503,11 +502,9 @@ int ScummEngine::findObject(int x, int y) { if ((_objs[i].obj_nr < 1) || getClass(_objs[i].obj_nr, kObjectClassUntouchable)) continue; - if (_game.version == 0) { - if (_objs[i].obj_type == 0 && _objs[i].state & kObjectStateUntouchable) - continue; - } else { - if (_game.version <= 2 && _objs[i].state & kObjectStateUntouchable) + if ((_game.version == 0 && OBJECT_V0_TYPE(_objs[i].obj_nr) == kObjectV0TypeFG) || + (_game.version > 0 && _game.version <= 2)) { + if (_objs[i].state & kObjectStateUntouchable) continue; } @@ -523,12 +520,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) { - if (_game.version == 0) - return OBJECT_V0(_objs[i].obj_nr, _objs[i].obj_type); - else - return _objs[i].obj_nr; - } + _objs[i].y_pos <= y && _objs[i].height + _objs[i].y_pos > y) + return _objs[i].obj_nr; break; } } while ((_objs[b].state & mask) == a); @@ -834,9 +827,6 @@ void ScummEngine_v3old::resetRoomObjects() { if (_dumpScripts) { char buf[32]; sprintf(buf, "roomobj-%d-", _roomResource); - if (_game.version == 0) - sprintf(buf + 11, "%d-", od->obj_type); - dumpResource(buf, od->obj_nr, room + od->OBCDoffset); } } @@ -902,8 +892,7 @@ void ScummEngine_v0::resetRoomObject(ObjectData *od, const byte *room, const byt const byte *ptr = room + od->OBCDoffset; ptr -= 2; - od->obj_nr = *(ptr + 6); - od->obj_type = *(ptr + 7); + od->obj_nr = OBJECT_V0(*(ptr + 6), *(ptr + 7)); od->x_pos = *(ptr + 8) * 8; od->y_pos = ((*(ptr + 9)) & 0x7F) * 8; @@ -1064,7 +1053,7 @@ void ScummEngine::updateObjectStates() { ObjectData *od = &_objs[1]; for (i = 1; i < _numLocalObjects; i++, od++) { // V0 MM, objects with type == 1 are room objects (room specific objects, non-pickup) - if (_game.version == 0 && od->obj_type == 1) + if (_game.version == 0 && OBJECT_V0_TYPE(od->obj_nr) == kObjectV0TypeBG) continue; if (od->obj_nr > 0) @@ -1156,7 +1145,7 @@ const byte *ScummEngine::getObjOrActorName(int obj) { if ((_game.version == 0 && OBJECT_V0_TYPE(obj) == kObjectV0TypeActor) || (_game.version != 0 && obj < _numActors)) { - int actorNr = (_game.version != 0 ? obj : OBJECT_V0_NR(obj)); + int actorNr = (_game.version != 0 ? obj : OBJECT_V0_ID(obj)); return derefActor(actorNr, "getObjOrActorName")->getActorName(); } @@ -1225,10 +1214,7 @@ uint32 ScummEngine::getOBCDOffs(int object) const { return 0; 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].obj_nr == object) { if (_objs[i].fl_object_index != 0) return 8; return _objs[i].OBCDoffset; @@ -1252,10 +1238,7 @@ byte *ScummEngine::getOBCDFromObject(int obj, bool v0CheckInventory) { } } else { for (i = (_numLocalObjects-1); i > 0; --i) { - 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].obj_nr == obj) { 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 12956fc4fd..37ccc4eef6 100644 --- a/engines/scumm/object.h +++ b/engines/scumm/object.h @@ -25,10 +25,10 @@ namespace Scumm { static inline int OBJECT_V0(int id, byte type) { - assert(id < 255); + assert(id < 256); return (type << 8 | id); } -#define OBJECT_V0_NR(obj) (obj & 0xFF) +#define OBJECT_V0_ID(obj) (obj & 0xFF) #define OBJECT_V0_TYPE(obj) ((obj >> 8) & 0xFF) enum ObjectV0Type { @@ -82,12 +82,7 @@ struct ObjectData { byte parentstate; byte state; byte fl_object_index; - // extra engine specific data - union { - byte extra; - byte obj_type; // v0 - byte flags; // v8 - }; + byte flags; }; #include "common/pack-start.h" // START STRUCT PACKING diff --git a/engines/scumm/saveload.cpp b/engines/scumm/saveload.cpp index 17135623e2..6c6c4a1a27 100644 --- a/engines/scumm/saveload.cpp +++ b/engines/scumm/saveload.cpp @@ -822,7 +822,7 @@ void ScummEngine::saveOrLoad(Serializer *s) { MKLINE(ObjectData, parent, sleByte, VER(8)), MKLINE(ObjectData, state, sleByte, VER(8)), MKLINE(ObjectData, fl_object_index, sleByte, VER(8)), - MKLINE(ObjectData, extra, sleByte, VER(46)), + MKLINE(ObjectData, flags, sleByte, VER(46)), MKEND() }; @@ -1205,12 +1205,17 @@ void ScummEngine::saveOrLoad(Serializer *s) { // Save/load local objects // s->saveLoadArrayOf(_objs, _numLocalObjects, sizeof(_objs[0]), objectEntries); - if (s->isLoading() && s->getVersion() < VER(13)) { - // Since roughly v13 of the save games, the objs storage has changed a bit - for (i = _numObjectsInRoom; i < _numLocalObjects; i++) { - _objs[i].obj_nr = 0; + if (s->isLoading()) { + if (s->getVersion() < VER(13)) { + // Since roughly v13 of the save games, the objs storage has changed a bit + for (i = _numObjectsInRoom; i < _numLocalObjects; i++) + _objs[i].obj_nr = 0; + } else if (_game.version == 0) { // TODO: handle this correctly + for (i = 0; i < _numLocalObjects; i++) { + if (_objs[i].obj_nr != 0 && _objs[i].flags != 0) + _objs[i].obj_nr = OBJECT_V0(_objs[i].obj_nr, _objs[i].flags); + } } - } diff --git a/engines/scumm/script.cpp b/engines/scumm/script.cpp index 3fa89b68fb..588ebaffb9 100644 --- a/engines/scumm/script.cpp +++ b/engines/scumm/script.cpp @@ -1138,7 +1138,7 @@ void ScummEngine_v0::walkToActorOrObject(int object) { _walkToObjectIdx = getObjectIndex(object); if (OBJECT_V0_TYPE(object) == kObjectV0TypeActor) { - walkActorToActor(VAR(VAR_EGO), OBJECT_V0_NR(object), 4); + walkActorToActor(VAR(VAR_EGO), OBJECT_V0_ID(object), 4); x = a->getRealPos().x; y = a->getRealPos().y; } else { @@ -1224,14 +1224,14 @@ void ScummEngine_v0::runSentenceScript() { if (getVerbEntrypoint(_cmdObject, _cmdVerb) != 0) { // do not read in the dark if (!(_cmdVerb == kVerbRead && _currentLights == 0)) { - VAR(VAR_ACTIVE_OBJECT2) = OBJECT_V0_NR(_cmdObject2); + VAR(VAR_ACTIVE_OBJECT2) = OBJECT_V0_ID(_cmdObject2); runObjectScript(_cmdObject, _cmdVerb, false, false, NULL); return; } } else { if (_cmdVerb == kVerbGive) { // no "give to"-script: give to other kid or ignore - int actor = OBJECT_V0_NR(_cmdObject2); + int actor = OBJECT_V0_ID(_cmdObject2); if (actor < 8) setOwnerOf(_cmdObject, actor); return; diff --git a/engines/scumm/script_v0.cpp b/engines/scumm/script_v0.cpp index ac6ee4b9d6..e2ec40ef52 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 OBJECT_V0_NR(_cmdObject); + return OBJECT_V0_ID(_cmdObject); return fetchScriptByte(); } @@ -831,7 +831,7 @@ void ScummEngine_v0::o_doSentence() { bool ScummEngine_v0::ifEqualActiveObject2Common(bool checkType) { byte obj = fetchScriptByte(); if (!checkType || (OBJECT_V0_TYPE(_cmdObject2) == kObjectV0TypeFG)) - return (obj == OBJECT_V0_NR(_cmdObject2)); + return (obj == OBJECT_V0_ID(_cmdObject2)); return false; } diff --git a/engines/scumm/scumm_v0.h b/engines/scumm/scumm_v0.h index cdae22e983..b6f9027dfa 100644 --- a/engines/scumm/scumm_v0.h +++ b/engines/scumm/scumm_v0.h @@ -43,12 +43,12 @@ protected: byte _currentMode; int _activeVerb; // selected verb - int _activeObject; // 1st selected object (see OBJECT_V0(nr, type), cannot be an actor) - int _activeObject2; // 2nd selected object or actor (see OBJECT_V0(nr, type)) + int _activeObject; // 1st selected object (see OBJECT_V0()) + int _activeObject2; // 2nd selected object or actor (see OBJECT_V0()) int _cmdVerb; // script verb - int _cmdObject; // 1st script object (see OBJECT_V0(nr, type)) - int _cmdObject2; // 2nd script object or actor (see OBJECT_V0(nr, type)) + int _cmdObject; // 1st script object (see OBJECT_V0()) + int _cmdObject2; // 2nd script object or actor (see OBJECT_V0()) int _walkToObject; int _walkToObjectIdx; -- cgit v1.2.3 From cbae5c79b702494dd30abb9504767029fba065ae Mon Sep 17 00:00:00 2001 From: segrax Date: Tue, 17 Jan 2012 20:03:52 +1100 Subject: SCUMM: Change vars to ints, remove unused variable for now --- engines/scumm/actor.cpp | 5 ++--- engines/scumm/actor.h | 5 ++--- engines/scumm/costume.cpp | 2 +- 3 files changed, 5 insertions(+), 7 deletions(-) (limited to 'engines/scumm') diff --git a/engines/scumm/actor.cpp b/engines/scumm/actor.cpp index 950f580f42..e703c55192 100644 --- a/engines/scumm/actor.cpp +++ b/engines/scumm/actor.cpp @@ -866,8 +866,7 @@ void Actor::setDirection(int direction) { _vm->_costumeLoader->costumeDecodeData(this, _standFrame, 0); // 0x2C17 - - ((ActorC64*) this)->_byte_FD0A = 0xFF; + ((ActorC64*) this)->_byte_FD0A = -1; _needRedraw = true; return; @@ -2653,7 +2652,7 @@ void ActorC64::animateActor(int anim) { if( this->isInCurrentRoom() ) { - this->_costCommandNew = anim; + // this->_costCommandNew = anim; this->_byte_FD0A = this->_byte_FDE8; // 0x273A diff --git a/engines/scumm/actor.h b/engines/scumm/actor.h index 1feb1afaa5..a2b36e51ca 100644 --- a/engines/scumm/actor.h +++ b/engines/scumm/actor.h @@ -348,14 +348,13 @@ enum ActorC64MiscFlags { class ActorC64 : public Actor_v2 { public: - byte _costCommandNew; byte _costCommand, _costFrame; byte _miscflags; byte _speaking, _speakingPrev; - byte _byte_FDE8; + int8 _byte_FDE8; int8 _byte_FD0A; - byte _byte_FCE2[8]; + int8 _byte_FCE2[8]; public: diff --git a/engines/scumm/costume.cpp b/engines/scumm/costume.cpp index 0c091c38bf..68eeeea674 100644 --- a/engines/scumm/costume.cpp +++ b/engines/scumm/costume.cpp @@ -1464,7 +1464,7 @@ byte C64CostumeLoader::increaseAnims(Actor *a) { // 0x2556 --a->_cost.curpos[limb]; - A->_costCommandNew = 0xFF; + //A->_costCommandNew = 0xFF; //A->_costCommand = 0xFF; // 0x2568 -- cgit v1.2.3 From 4519e56e5c018459c408e20e7469d35b6ac7ed44 Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Tue, 17 Jan 2012 21:51:39 +0100 Subject: SCUMM: shorten delay for dungeon door closing action Escaping with only one kid should not be possible anymore. --- engines/scumm/script_v2.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'engines/scumm') diff --git a/engines/scumm/script_v2.cpp b/engines/scumm/script_v2.cpp index 6f6138d411..c35ddea64d 100644 --- a/engines/scumm/script_v2.cpp +++ b/engines/scumm/script_v2.cpp @@ -1433,6 +1433,17 @@ void ScummEngine_v2::o2_delay() { delay |= fetchScriptByte() << 16; delay = 0xFFFFFF - delay; + // WORKAROUND: walking speed in the original v0/v1 interpreter + // is sometimes slower (e.g. during scrolling) than in ScummVM. + // Hence, the delay for the door-closing action in the dungeon + // is to long, so a single kid is able to escape -> shorten delay. + int script = vm.slot[_currentScript].number; + if ((_game.version == 0 && script == 132) || + (_game.version == 1 && script == 137)) { + if (delay == 180) + delay = 120; + } + vm.slot[_currentScript].delay = delay; vm.slot[_currentScript].status = ssPaused; o5_breakHere(); -- cgit v1.2.3 From 0bae642453caeef9c6af9c49f043f46eebd0f787 Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Tue, 17 Jan 2012 22:52:59 +0100 Subject: SCUMM: 2nd try to fix dungeon door timing Shorten the timer delay does not work as escaping with a second kid is not possible too. Instead decrease engine speed during script execution. --- engines/scumm/script_v2.cpp | 11 ----------- engines/scumm/scumm.cpp | 8 ++++++++ 2 files changed, 8 insertions(+), 11 deletions(-) (limited to 'engines/scumm') diff --git a/engines/scumm/script_v2.cpp b/engines/scumm/script_v2.cpp index c35ddea64d..6f6138d411 100644 --- a/engines/scumm/script_v2.cpp +++ b/engines/scumm/script_v2.cpp @@ -1433,17 +1433,6 @@ void ScummEngine_v2::o2_delay() { delay |= fetchScriptByte() << 16; delay = 0xFFFFFF - delay; - // WORKAROUND: walking speed in the original v0/v1 interpreter - // is sometimes slower (e.g. during scrolling) than in ScummVM. - // Hence, the delay for the door-closing action in the dungeon - // is to long, so a single kid is able to escape -> shorten delay. - int script = vm.slot[_currentScript].number; - if ((_game.version == 0 && script == 132) || - (_game.version == 1 && script == 137)) { - if (delay == 180) - delay = 120; - } - vm.slot[_currentScript].delay = delay; vm.slot[_currentScript].status = ssPaused; o5_breakHere(); diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp index f2db5ad6ba..61d38dc593 100644 --- a/engines/scumm/scumm.cpp +++ b/engines/scumm/scumm.cpp @@ -1964,6 +1964,14 @@ Common::Error ScummEngine::go() { if (delta < 1) // Ensure we don't get into an endless loop delta = 1; // by not decreasing sleepers. + // WORKAROUND: walking speed in the original v0/v1 interpreter + // is sometimes slower (e.g. during scrolling) than in ScummVM. + // This is important for the door-closing action in the dungeon, + // otherwise (delta < 6) a single kid is able to escape. + if ((_game.version == 0 && isScriptRunning(132)) || + (_game.version == 1 && isScriptRunning(137))) + delta = 6; + // Wait... waitForTimer(delta * 1000 / 60 - diff); -- cgit v1.2.3 From 6d4b710c541a2e7706cb80c8737e6f8caa487277 Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Wed, 18 Jan 2012 00:04:03 +0100 Subject: SCUMM: fix opcode walkToObject in v0 Before Michael did not develop the film correctly --- engines/scumm/script_v0.cpp | 23 +++++++++++++++++++---- engines/scumm/scumm_v0.h | 1 + 2 files changed, 20 insertions(+), 4 deletions(-) (limited to 'engines/scumm') diff --git a/engines/scumm/script_v0.cpp b/engines/scumm/script_v0.cpp index e2ec40ef52..3b81a913b3 100644 --- a/engines/scumm/script_v0.cpp +++ b/engines/scumm/script_v0.cpp @@ -101,7 +101,7 @@ void ScummEngine_v0::setupOpcodes() { /* 34 */ OPCODE(0x34, o5_getDist); OPCODE(0x35, o_stopCurrentScript); - OPCODE(0x36, o2_walkActorToObject); + OPCODE(0x36, o_walkActorToObject); OPCODE(0x37, o2_clearState04); /* 38 */ OPCODE(0x38, o2_isLessEqual); @@ -181,7 +181,7 @@ void ScummEngine_v0::setupOpcodes() { /* 74 */ OPCODE(0x74, o5_getDist); OPCODE(0x75, o_printEgo_c64); - OPCODE(0x76, o2_walkActorToObject); + OPCODE(0x76, o_walkActorToObject); OPCODE(0x77, o2_clearState04); /* 78 */ OPCODE(0x78, o2_isGreater); @@ -261,7 +261,7 @@ void ScummEngine_v0::setupOpcodes() { /* B4 */ OPCODE(0xb4, o5_getDist); OPCODE(0xb5, o_stopCurrentScript); - OPCODE(0xb6, o2_walkActorToObject); + OPCODE(0xb6, o_walkActorToObject); OPCODE(0xb7, o2_setState04); /* B8 */ OPCODE(0xb8, o2_isLessEqual); @@ -341,7 +341,7 @@ void ScummEngine_v0::setupOpcodes() { /* F4 */ OPCODE(0xf4, o5_getDist); OPCODE(0xf5, o_stopCurrentScript); - OPCODE(0xf6, o2_walkActorToObject); + OPCODE(0xf6, o_walkActorToObject); OPCODE(0xf7, o2_setState04); /* F8 */ OPCODE(0xf8, o2_isGreater); @@ -498,6 +498,21 @@ void ScummEngine_v0::o_stopCurrentScript() { stopScriptCommon(0); } +void ScummEngine_v0::o_walkActorToObject() { + int actor = getVarOrDirectByte(PARAM_1); + int objId = fetchScriptByte(); + int obj; + + if (_opcode & 0x40) + obj = OBJECT_V0(objId, kObjectV0TypeBG); + else + obj = OBJECT_V0(objId, kObjectV0TypeFG); + + if (whereIsObject(obj) != WIO_NOT_FOUND) { + walkActorToObject(actor, obj); + } +} + void ScummEngine_v0::o_loadSound() { int resid = fetchScriptByte(); ensureResourceLoaded(rtSound, resid); diff --git a/engines/scumm/scumm_v0.h b/engines/scumm/scumm_v0.h index b6f9027dfa..d70d893f09 100644 --- a/engines/scumm/scumm_v0.h +++ b/engines/scumm/scumm_v0.h @@ -106,6 +106,7 @@ protected: /* Version C64 script opcodes */ void o_stopCurrentScript(); + void o_walkActorToObject(); void o_loadSound(); void o_getActorMoving(); void o_animateActor(); -- cgit v1.2.3 From f2c3675ed1306f82b5cb5d44d541739ff727dfde Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Wed, 18 Jan 2012 20:29:29 +0100 Subject: SCUMM: v0 opcode review - o_setObjectName has a default value - o_putActorAtObject can either operate on a fg or bg object Note: neither the default value nor the bg object opcode (4E) seem to be ever used by any script. So this commit is rather for completeness than for bug-fixing. --- engines/scumm/script_v0.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'engines/scumm') diff --git a/engines/scumm/script_v0.cpp b/engines/scumm/script_v0.cpp index 3b81a913b3..caaf56878f 100644 --- a/engines/scumm/script_v0.cpp +++ b/engines/scumm/script_v0.cpp @@ -701,7 +701,12 @@ void ScummEngine_v0::o_putActorAtObject() { a = derefActor(getVarOrDirectByte(PARAM_1), "o_putActorAtObject"); - obj = fetchScriptByte(); + int objId = fetchScriptByte(); + if (_opcode & 0x40) + obj = OBJECT_V0(objId, kObjectV0TypeBG); + else + obj = OBJECT_V0(objId, kObjectV0TypeFG); + if (whereIsObject(obj) != WIO_NOT_FOUND) { getObjectXYPos(obj, x, y); AdjustBoxResult r = a->adjustXYToBeInBox(x, y); @@ -735,6 +740,8 @@ void ScummEngine_v0::o_pickupObject() { void ScummEngine_v0::o_setObjectName() { int obj = fetchScriptByte(); + if (!obj) + obj = _cmdObject; setObjectName(obj); } -- cgit v1.2.3 From e2d45467bb6f0dc6d35fa33697bb97ae470f05f1 Mon Sep 17 00:00:00 2001 From: segrax Date: Thu, 19 Jan 2012 17:59:56 +1100 Subject: SCUMM: improve unknown variable support, add case 0xff to the animateactor opcode --- engines/scumm/actor.cpp | 8 +++++--- engines/scumm/costume.cpp | 7 +++++-- engines/scumm/script_v0.cpp | 21 +++++++++++++-------- 3 files changed, 23 insertions(+), 13 deletions(-) (limited to 'engines/scumm') diff --git a/engines/scumm/actor.cpp b/engines/scumm/actor.cpp index e703c55192..c4b7c82a57 100644 --- a/engines/scumm/actor.cpp +++ b/engines/scumm/actor.cpp @@ -847,7 +847,7 @@ void Actor::setDirection(int direction) { direction = 90; // Do nothing if actor is already facing in the given direction - if (_facing == direction) + if (_vm->_game.version != 0 && _facing == direction) return; // Normalize the angle @@ -1294,6 +1294,10 @@ void Actor::showActor() { _vm->ensureResourceLoaded(rtCostume, _costume); if (_vm->_game.version == 0) { + + // 0x39DF + ((ActorC64*) this)->_byte_FDE8 = 1; + _cost.reset(); startAnimActor(_standFrame); } else if (_vm->_game.version <= 2) { @@ -2646,8 +2650,6 @@ void ScummEngine_v71he::queueAuxEntry(int actorNum, int subIndex) { #endif void ActorC64::animateActor(int anim) { - Actor::animateActor(anim); - return; int dir = oldDirToNewDir(anim % 4); if( this->isInCurrentRoom() ) { diff --git a/engines/scumm/costume.cpp b/engines/scumm/costume.cpp index 68eeeea674..04e3f5986b 100644 --- a/engines/scumm/costume.cpp +++ b/engines/scumm/costume.cpp @@ -1378,6 +1378,8 @@ void C64CostumeLoader::actorSpeak(ActorC64 *a, int &cmd) { cmd += 0x0C; else cmd += 0x10; + + a->_byte_FDE8 = -1; } void C64CostumeLoader::costumeDecodeData(Actor *a, int frame, uint usemask) { @@ -1408,7 +1410,8 @@ void C64CostumeLoader::costumeDecodeData(Actor *a, int frame, uint usemask) { { command = dirToDirStop(dir); - A->_byte_FDE8 = 0xFF; + //0x2BEB + A->_byte_FDE8 = -1; } // Update the limb frames @@ -1472,7 +1475,7 @@ byte C64CostumeLoader::increaseAnims(Actor *a) { //A->_limbCommand[limb] = 0xFF; } else { - if( A->_byte_FCE2[limb] != 0xFF ) + if( A->_byte_FCE2[limb] != -1 ) --A->_byte_FCE2[limb]; a->_cost.curpos[limb] = 0; diff --git a/engines/scumm/script_v0.cpp b/engines/scumm/script_v0.cpp index caaf56878f..ec3cad009d 100644 --- a/engines/scumm/script_v0.cpp +++ b/engines/scumm/script_v0.cpp @@ -663,24 +663,29 @@ void ScummEngine_v0::o_lights() { void ScummEngine_v0::o_animateActor() { int act = getVarOrDirectByte(PARAM_1); int anim = getVarOrDirectByte(PARAM_2); - int unk = fetchScriptByte(); + int8 unk = (int8) fetchScriptByte(); debug(0,"o_animateActor: unk %d", unk); ActorC64 *a = (ActorC64*) derefActor(act, "o_animateActor"); a->_byte_FDE8 = unk; - - // 0x6993 - if (anim == 0xFE) { + + switch( anim ) { + case 0xFE: + // 0x6993 a->_speaking = 0x80; // Enabled, but not switching return; - } - // 0x69A3 - if (anim == 0xFD) { + + case 0xFD: + // 0x69A3 a->_speaking = 0x00; return; - } + + case 0xFF: + a->stopActorMoving(); + return; + } a->animateActor(anim); } -- cgit v1.2.3 From e331421eae305fe857c1b630d5764e35635eaa7e Mon Sep 17 00:00:00 2001 From: segrax Date: Fri, 20 Jan 2012 07:47:43 +1100 Subject: SCUMM: Save the new variables, move the setting of the unknown variable to after the setDirection call --- engines/scumm/actor.cpp | 12 +++++++----- engines/scumm/saveload.h | 2 +- 2 files changed, 8 insertions(+), 6 deletions(-) (limited to 'engines/scumm') diff --git a/engines/scumm/actor.cpp b/engines/scumm/actor.cpp index c4b7c82a57..17e1f8cd82 100644 --- a/engines/scumm/actor.cpp +++ b/engines/scumm/actor.cpp @@ -865,9 +865,6 @@ void Actor::setDirection(int direction) { else _vm->_costumeLoader->costumeDecodeData(this, _standFrame, 0); - // 0x2C17 - ((ActorC64*) this)->_byte_FD0A = -1; - _needRedraw = true; return; } @@ -901,6 +898,7 @@ void Actor::turnToDirection(int newdir) { if (newdir == -1 || _ignoreTurns) return; + // 0x2C17 if( _vm->_game.version == 0 ) ((ActorC64*) this)->_byte_FD0A = -1; @@ -2655,7 +2653,6 @@ void ActorC64::animateActor(int anim) { if( this->isInCurrentRoom() ) { // this->_costCommandNew = anim; - this->_byte_FD0A = this->_byte_FDE8; // 0x273A /*switch( anim ) { @@ -2675,9 +2672,11 @@ void ActorC64::animateActor(int anim) { default: return; }*/ - + this->setDirection( dir ); + this->_byte_FD0A = this->_byte_FDE8; + } else { if( anim > 4 ) { @@ -2696,6 +2695,9 @@ void ActorC64::saveLoadWithSerializer(Serializer *ser) { MKLINE(ActorC64, _miscflags, sleByte, VER(84)), MKLINE(ActorC64, _speaking, sleByte, VER(84)), MKLINE(ActorC64, _speakingPrev, sleByte, VER(84)), + MKLINE(ActorC64, _byte_FD0A, sleByte, VER(89)), + MKLINE(ActorC64, _byte_FDE8, sleByte, VER(89)), + MKARRAY(ActorC64, _byte_FCE2, sleInt8, 8, VER(89)), MKEND() }; diff --git a/engines/scumm/saveload.h b/engines/scumm/saveload.h index 064bdf1406..898f80f867 100644 --- a/engines/scumm/saveload.h +++ b/engines/scumm/saveload.h @@ -47,7 +47,7 @@ namespace Scumm { * only saves/loads those which are valid for the version of the savegame * which is being loaded/saved currently. */ -#define CURRENT_VER 88 +#define CURRENT_VER 89 /** * An auxillary macro, used to specify savegame versions. We use this instead -- cgit v1.2.3 From a999aa39ba4963b8c31b1db81f73bdc04e9b4772 Mon Sep 17 00:00:00 2001 From: segrax Date: Sat, 21 Jan 2012 17:50:55 +1100 Subject: SCUMM: Re-arrange some things to make it closer to the original --- engines/scumm/actor.cpp | 45 +++++++++++++++++++++++++++------------------ engines/scumm/actor.h | 3 ++- engines/scumm/costume.cpp | 6 +----- engines/scumm/script_v0.cpp | 23 ++++++++++++----------- 4 files changed, 42 insertions(+), 35 deletions(-) (limited to 'engines/scumm') diff --git a/engines/scumm/actor.cpp b/engines/scumm/actor.cpp index 17e1f8cd82..090ad25c9a 100644 --- a/engines/scumm/actor.cpp +++ b/engines/scumm/actor.cpp @@ -319,6 +319,9 @@ int Actor::actorWalkStep() { int distX, distY; int nextFacing; + if( _vm->_game.version == 0 ) + ((ActorC64*) this)->_byte_FD0A = -1; + _needRedraw = true; nextFacing = updateActorDirection(true); @@ -857,18 +860,6 @@ void Actor::setDirection(int direction) { if (_costume == 0) return; - // V0 MM - if (_vm->_game.version == 0) { - - if (_moving) - _vm->_costumeLoader->costumeDecodeData(this, _walkFrame, 0); - else - _vm->_costumeLoader->costumeDecodeData(this, _standFrame, 0); - - _needRedraw = true; - return; - } - // Update the costume for the new direction (and mark the actor for redraw) aMask = 0x8000; for (i = 0; i < 16; i++, aMask >>= 1) { @@ -881,6 +872,27 @@ void Actor::setDirection(int direction) { _needRedraw = true; } +void ActorC64::setDirection(int direction) { + + // Normalize the angle + _facing = normalizeAngle(direction); + + // 0x2C17 + // _byte_FDE8 = -1; + + // If there is no costume set for this actor, we are finished + if (_costume == 0) + return; + + if (_moving) + _vm->_costumeLoader->costumeDecodeData(this, _walkFrame, 0); + else { + _vm->_costumeLoader->costumeDecodeData(this, _standFrame, 0); + } + + _needRedraw = true; +} + void Actor::faceToObject(int obj) { int x2, y2, dir; @@ -898,10 +910,6 @@ void Actor::turnToDirection(int newdir) { if (newdir == -1 || _ignoreTurns) return; - // 0x2C17 - if( _vm->_game.version == 0 ) - ((ActorC64*) this)->_byte_FD0A = -1; - if (_vm->_game.version <= 6) { _moving = MF_TURN; _targetFacing = newdir; @@ -2672,11 +2680,12 @@ void ActorC64::animateActor(int anim) { default: return; }*/ - - this->setDirection( dir ); + this->_byte_FD0A = this->_byte_FDE8; + this->setDirection( dir ); + } else { if( anim > 4 ) { diff --git a/engines/scumm/actor.h b/engines/scumm/actor.h index a2b36e51ca..0b3fcd7143 100644 --- a/engines/scumm/actor.h +++ b/engines/scumm/actor.h @@ -202,7 +202,7 @@ public: void adjustActorPos(); virtual AdjustBoxResult adjustXYToBeInBox(int dstX, int dstY); - void setDirection(int direction); + virtual void setDirection(int direction); void faceToObject(int obj); void turnToDirection(int newdir); virtual void walkActor(); @@ -379,6 +379,7 @@ public: } virtual void animateActor(int anim); + virtual void setDirection(int direction); // Used by the save/load system: virtual void saveLoadWithSerializer(Serializer *ser); diff --git a/engines/scumm/costume.cpp b/engines/scumm/costume.cpp index 04e3f5986b..965cee79a8 100644 --- a/engines/scumm/costume.cpp +++ b/engines/scumm/costume.cpp @@ -1305,6 +1305,7 @@ void C64CostumeLoader::frameUpdate(ActorC64 *a, int cmd ) { if (limbFrames == 0xFF) continue; + // 0x2679 a->_byte_FCE2[limb] = a->_byte_FD0A; // Has limb frames ptr changed since last update? @@ -1407,13 +1408,8 @@ void C64CostumeLoader::costumeDecodeData(Actor *a, int frame, uint usemask) { // Different command for stand frame if (frame == a->_standFrame) - { command = dirToDirStop(dir); - //0x2BEB - A->_byte_FDE8 = -1; - } - // Update the limb frames frameUpdate(A, command); diff --git a/engines/scumm/script_v0.cpp b/engines/scumm/script_v0.cpp index ec3cad009d..e277480aed 100644 --- a/engines/scumm/script_v0.cpp +++ b/engines/scumm/script_v0.cpp @@ -672,19 +672,20 @@ void ScummEngine_v0::o_animateActor() { a->_byte_FDE8 = unk; switch( anim ) { - case 0xFE: - // 0x6993 - a->_speaking = 0x80; // Enabled, but not switching - return; - case 0xFD: - // 0x69A3 - a->_speaking = 0x00; - return; + case 0xFE: + // 0x6993 + a->_speaking = 0x80; // Enabled, but not switching + return; + + case 0xFD: + // 0x69A3 + a->_speaking = 0x00; + return; - case 0xFF: - a->stopActorMoving(); - return; + case 0xFF: + a->stopActorMoving(); + return; } a->animateActor(anim); -- cgit v1.2.3 From 2f1336cdf07b59c560d082a1ce3bb7986a3913df Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Sat, 21 Jan 2012 14:06:19 +0100 Subject: SCUMM: fix blank sentence line in v0 after cutscenes and remove unused parameter of resetSentence() --- engines/scumm/script.cpp | 2 +- engines/scumm/script_v0.cpp | 12 +++++++++--- engines/scumm/scumm_v0.h | 3 ++- engines/scumm/vars.cpp | 2 +- engines/scumm/verbs.cpp | 13 +++++-------- 5 files changed, 18 insertions(+), 14 deletions(-) (limited to 'engines/scumm') diff --git a/engines/scumm/script.cpp b/engines/scumm/script.cpp index 588ebaffb9..6dac647714 100644 --- a/engines/scumm/script.cpp +++ b/engines/scumm/script.cpp @@ -1219,7 +1219,7 @@ void ScummEngine_v0::checkAndRunSentenceScript() { } void ScummEngine_v0::runSentenceScript() { - drawSentenceLine(); + _redrawSentenceLine = true; if (getVerbEntrypoint(_cmdObject, _cmdVerb) != 0) { // do not read in the dark diff --git a/engines/scumm/script_v0.cpp b/engines/scumm/script_v0.cpp index e277480aed..7fce4011e4 100644 --- a/engines/scumm/script_v0.cpp +++ b/engines/scumm/script_v0.cpp @@ -453,6 +453,8 @@ void ScummEngine_v0::drawSentenceObject(int object) { void ScummEngine_v0::drawSentenceLine() { + _redrawSentenceLine = false; + if (!(_userState & 32)) return; @@ -601,7 +603,7 @@ void ScummEngine_v0::o_loadRoomWithEgo() { _fullRedraw = true; - resetSentence(false); + resetSentence(); if (x >= 0 && y >= 0) { a->startWalkActor(x, y, -1); @@ -625,6 +627,7 @@ void ScummEngine_v0::o_cursorCommand() { _currentMode = fetchScriptByte(); switch (_currentMode) { case kModeCutscene: + _redrawSentenceLine = false; state = 15; break; case kModeKeypad: @@ -909,7 +912,7 @@ void ScummEngine_v0::o_cutscene() { setUserState(15); _sentenceNum = 0; - resetSentence(false); + resetSentence(); vm.cutScenePtr[0] = 0; } @@ -930,6 +933,8 @@ void ScummEngine_v0::o_endCutscene() { } else if (vm.cutSceneData[2] != _currentRoom) { startScene(vm.cutSceneData[2], 0, 0); } + + _redrawSentenceLine = true; } void ScummEngine_v0::o_beginOverride() { @@ -961,11 +966,12 @@ void ScummEngine_v0::o_setOwnerOf() { setOwnerOf(obj, owner); } -void ScummEngine_v0::resetSentence(bool walking) { +void ScummEngine_v0::resetSentence() { _activeVerb = kVerbWalkTo; _activeObject = 0; _activeObject2 = 0; _walkToObjectIdx = 0; + _redrawSentenceLine = true; } } // End of namespace Scumm diff --git a/engines/scumm/scumm_v0.h b/engines/scumm/scumm_v0.h index d70d893f09..ae97b57a3e 100644 --- a/engines/scumm/scumm_v0.h +++ b/engines/scumm/scumm_v0.h @@ -52,6 +52,7 @@ protected: int _walkToObject; int _walkToObjectIdx; + bool _redrawSentenceLine; public: ScummEngine_v0(OSystem *syst, const DetectorResult &dr); @@ -98,7 +99,7 @@ protected: virtual int getActiveObject(); - virtual void resetSentence(bool walking); + virtual void resetSentence(); virtual bool areBoxesNeighbors(int box1nr, int box2nr); diff --git a/engines/scumm/vars.cpp b/engines/scumm/vars.cpp index 6365a728d2..6d132c601f 100644 --- a/engines/scumm/vars.cpp +++ b/engines/scumm/vars.cpp @@ -546,7 +546,7 @@ void ScummEngine_v8::setupScummVars() { #endif void ScummEngine_v0::resetScummVars() { - resetSentence(false); + resetSentence(); VAR(VAR_EGO) = 3; diff --git a/engines/scumm/verbs.cpp b/engines/scumm/verbs.cpp index dc049816e3..8888935ea7 100644 --- a/engines/scumm/verbs.cpp +++ b/engines/scumm/verbs.cpp @@ -132,7 +132,7 @@ void ScummEngine_v0::resetVerbs() { } void ScummEngine_v0::switchActor(int slot) { - resetSentence(false); + resetSentence(); if (_currentRoom == 45) return; @@ -741,7 +741,6 @@ void ScummEngine_v0::checkExecVerbs() { ActorC64 *a = (ActorC64 *)derefActor(VAR(VAR_EGO), "checkExecVerbs"); VirtScreen *zone = findVirtScreen(_mouse.y); - int sentenceLineChanged = false; bool execute = false; //if (_userPut <= 0) @@ -757,7 +756,7 @@ void ScummEngine_v0::checkExecVerbs() { _activeObject = 0; _activeObject2 = 0; _activeVerb = over; - sentenceLineChanged = true; + _redrawSentenceLine = true; } else { // execute sentence if complete if (checkSentenceComplete()) @@ -793,7 +792,7 @@ void ScummEngine_v0::checkExecVerbs() { else kid = 2; _activeVerb = kVerbWalkTo; - drawSentenceLine(); + _redrawSentenceLine = true; switchActor(kid); } _activeVerb = kVerbWalkTo; @@ -855,7 +854,7 @@ void ScummEngine_v0::checkExecVerbs() { } } - sentenceLineChanged = true; + _redrawSentenceLine = true; if (_activeVerb == kVerbWalkTo && zone->number == kMainVirtScreen) { _walkToObjectIdx = 0; execute = true; @@ -864,10 +863,8 @@ void ScummEngine_v0::checkExecVerbs() { } } - if (sentenceLineChanged) { + if (_redrawSentenceLine) drawSentenceLine(); - sentenceLineChanged = false; - } if (!execute || !_activeVerb) return; -- cgit v1.2.3 From f22bbc47b460bf7901844649e1e7929f512b9670 Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Sat, 21 Jan 2012 23:05:16 +0100 Subject: SCUMM: fix v0 mode handling and actor switching - handle mode switching correctly - do not freeze scripts in cutscene mode (mode 0), as some scripts are freezed in mode 0 that should not be freezed - kModeNoNewKid (mode 2) needs the same userState as mode 3 - rename o_cursorCommand to o_setMode as it is not really cursor specific - handle actorHiding correctly (do not set costume to 0 as the previous costume cannot be reverted after hiding) - add drawSentence - document meanings for actor misc flags - fix actor names for "new kid" if the radiation suit is used (all kids are set to 0 then with actor 0 name " ") - cleanup actor switching routine - _userPut is not used anymore in v0 --- engines/scumm/actor.cpp | 9 ++++++-- engines/scumm/actor.h | 16 ++++++------- engines/scumm/script_v0.cpp | 55 ++++++++++++++++++++++++--------------------- engines/scumm/scumm_v0.h | 4 +++- engines/scumm/verbs.cpp | 20 +++++------------ 5 files changed, 52 insertions(+), 52 deletions(-) (limited to 'engines/scumm') diff --git a/engines/scumm/actor.cpp b/engines/scumm/actor.cpp index 090ad25c9a..86daaeff2f 100644 --- a/engines/scumm/actor.cpp +++ b/engines/scumm/actor.cpp @@ -1512,12 +1512,17 @@ void ScummEngine::processActors() { for (Actor** ac = _sortedActors; ac != end; ++ac) { Actor* a = *ac; - // V0 MM: 0x057B if (_game.version == 0) { + // 0x057B ActorC64 *A = (ActorC64*) a; - if ((A->_speaking & 1)) + if (A->_speaking & 1) A->_speaking ^= 0xFE; + + // 0x22B5 + if (A->_miscflags & kActorMiscFlagHide) + continue; } + // Draw and animate the actors, except those w/o a costume. // Note: We could 'optimize' this a little bit by only putting // actors with a costume into the _sortedActors array in the diff --git a/engines/scumm/actor.h b/engines/scumm/actor.h index 0b3fcd7143..7e8faa54cc 100644 --- a/engines/scumm/actor.h +++ b/engines/scumm/actor.h @@ -336,14 +336,14 @@ protected: }; enum ActorC64MiscFlags { - kActorMiscFlagStrong = 0x01, // Kid is strong (Hunk-O-Matic used) - kActorMiscFlag_02 = 0x02, // ??? - kActorMiscFlag_04 = 0x04, // ??? - kActorMiscFlagEdsEnemy = 0x08, // Kid is not Weird Ed's friend - kActorMiscFlag_10 = 0x10, // ??? - kActorMiscFlag_20 = 0x20, // ??? - kActorMiscFlagFreeze = 0x40, // Stop moving - kActorMiscFlagHide = 0x80, // Hide actor (e.g. dead or wearing radiation suit) + kActorMiscFlagStrong = 0x01, // Kid is strong (Hunk-O-Matic used) + kActorMiscFlagGTFriend = 0x02, // Kid is green tentacle's friend (recording contract) + kActorMiscFlagWatchedTV = 0x04, // Kid knows publisher's address (watched TV) + kActorMiscFlagEdsEnemy = 0x08, // Kid is not Weird Ed's friend + kActorMiscFlag_10 = 0x10, // ??? + kActorMiscFlag_20 = 0x20, // ??? + kActorMiscFlagFreeze = 0x40, // Stop moving + kActorMiscFlagHide = 0x80, // Kid is invisible (dead or in radiation suit) }; class ActorC64 : public Actor_v2 { diff --git a/engines/scumm/script_v0.cpp b/engines/scumm/script_v0.cpp index 7fce4011e4..b0e3a958e4 100644 --- a/engines/scumm/script_v0.cpp +++ b/engines/scumm/script_v0.cpp @@ -154,7 +154,7 @@ void ScummEngine_v0::setupOpcodes() { OPCODE(0x5e, o2_walkActorTo); OPCODE(0x5f, o2_ifState04); /* 60 */ - OPCODE(0x60, o_cursorCommand); + OPCODE(0x60, o_setMode); OPCODE(0x61, o2_putActor); OPCODE(0x62, o2_stopScript); OPCODE(0x63, o_stopCurrentScript); @@ -314,7 +314,7 @@ void ScummEngine_v0::setupOpcodes() { OPCODE(0xde, o2_walkActorTo); OPCODE(0xdf, o2_ifNotState04); /* E0 */ - OPCODE(0xe0, o_cursorCommand); + OPCODE(0xe0, o_setMode); OPCODE(0xe1, o2_putActor); OPCODE(0xe2, o2_stopScript); OPCODE(0xe3, o_stopCurrentScript); @@ -463,8 +463,16 @@ void ScummEngine_v0::drawSentenceLine() { if (_activeVerb == kVerbNewKid) { _sentenceBuf = ""; for (int i = 0; i < 3; ++i) { - Actor *a = derefActor(VAR(97 + i), "drawSentenceLine"); - _sentenceBuf += Common::String::format("%-13s", a->getActorName()); + char *actorName; + int actorId = VAR(97 + i); + if (actorId == 0) { + // after usage of the radiation suit, kid vars are set to 0 + actorName = " "; + } else { + Actor *a = derefActor(actorId, "drawSentenceLine"); + actorName = (char *)a->getActorName(); + } + _sentenceBuf += Common::String::format("%-13s", actorName); } flushSentenceLine(); return; @@ -620,28 +628,30 @@ void ScummEngine_v0::o_unlockRoom() { _res->unlock(rtRoom, resid); } -void ScummEngine_v0::o_cursorCommand() { - // TODO +void ScummEngine_v0::setMode(byte mode) { int state = 0; - _currentMode = fetchScriptByte(); + _currentMode = mode; + switch (_currentMode) { case kModeCutscene: _redrawSentenceLine = false; - state = 15; + state = 7; break; case kModeKeypad: - state = 31; - break; - case kModeNoNewKid: + state = 23; break; case kModeNormal: + case kModeNoNewKid: state = 247; break; } setUserState(state); - debug(0, "o_cursorCommand(%d)", _currentMode); +} + +void ScummEngine_v0::o_setMode() { + setMode(fetchScriptByte()); } void ScummEngine_v0::o_lights() { @@ -777,8 +787,6 @@ void ScummEngine_v0::o_setActorBitVar() { // This flag causes the actor to stop moving (used by script #158, Green Tentacle 'Oomph!') if (a->_miscflags & kActorMiscFlagFreeze) a->stopActorMoving(); - if (a->_miscflags & kActorMiscFlagHide) - a->setActorCostume(0); debug(0, "o_setActorBitVar(%d, %d, %d)", act, mask, mod); } @@ -904,12 +912,10 @@ void ScummEngine_v0::o_getClosestObjActor() { } void ScummEngine_v0::o_cutscene() { - vm.cutSceneData[0] = _userState | (_userPut ? 16 : 0); + vm.cutSceneData[0] = _currentMode; vm.cutSceneData[2] = _currentRoom; - vm.cutSceneData[3] = camera._mode; - // Hide inventory, freeze scripts, hide cursor - setUserState(15); + setMode(kModeCutscene); _sentenceNum = 0; resetSentence(); @@ -924,17 +930,14 @@ void ScummEngine_v0::o_endCutscene() { vm.cutSceneScript[0] = 0; vm.cutScenePtr[0] = 0; - // Reset user state to values before cutscene - setUserState(vm.cutSceneData[0] | 7); + setMode(vm.cutSceneData[0]); - camera._mode = (byte) vm.cutSceneData[3]; - if (camera._mode == kFollowActorCameraMode) { - actorFollowCamera(VAR(VAR_EGO)); - } else if (vm.cutSceneData[2] != _currentRoom) { + if (_currentMode == kModeKeypad) { startScene(vm.cutSceneData[2], 0, 0); + } else { + actorFollowCamera(VAR(VAR_EGO)); + _redrawSentenceLine = true; } - - _redrawSentenceLine = true; } void ScummEngine_v0::o_beginOverride() { diff --git a/engines/scumm/scumm_v0.h b/engines/scumm/scumm_v0.h index ae97b57a3e..c5c0c0950c 100644 --- a/engines/scumm/scumm_v0.h +++ b/engines/scumm/scumm_v0.h @@ -92,6 +92,8 @@ protected: void drawSentenceObject(int object); void drawSentenceLine(); + void setMode(byte mode); + void switchActor(int slot); virtual int getVarOrDirectWord(byte mask); @@ -122,7 +124,7 @@ protected: void o_lockScript(); void o_loadScript(); void o_lockRoom(); - void o_cursorCommand(); + void o_setMode(); void o_lights(); void o_unlockCostume(); void o_unlockScript(); diff --git a/engines/scumm/verbs.cpp b/engines/scumm/verbs.cpp index 8888935ea7..bb0d8f4ae2 100644 --- a/engines/scumm/verbs.cpp +++ b/engines/scumm/verbs.cpp @@ -134,21 +134,12 @@ void ScummEngine_v0::resetVerbs() { void ScummEngine_v0::switchActor(int slot) { resetSentence(); - if (_currentRoom == 45) - return; - - // radiation suit? don't let the player switch - if (VAR(VAR_EGO) == 8) - return; - - // verbs disabled? or just new kid button? - if (_currentMode == kModeCutscene || _currentMode == kModeKeypad || _currentMode == kModeNoNewKid) + // actor switching only allowed during normal gamplay (not cutscene, ...) + if (_currentMode != kModeNormal) return; VAR(VAR_EGO) = VAR(97 + slot); - resetVerbs(); actorFollowCamera(VAR(VAR_EGO)); - setUserState(247); } void ScummEngine_v2::initV2MouseOver() { @@ -743,9 +734,6 @@ void ScummEngine_v0::checkExecVerbs() { bool execute = false; - //if (_userPut <= 0) - // return; - if (_mouseAndKeyboardStat & MBS_MOUSE_MASK) { int over = findVerbAtPos(_mouse.x, _mouse.y); // click region: verbs @@ -777,7 +765,7 @@ void ScummEngine_v0::checkExecVerbs() { } if (_mouseAndKeyboardStat > 0 && _mouseAndKeyboardStat < MBS_MAX_KEY) { - // TODO: check keypresses + // keys already checked by input handler } else if ((_mouseAndKeyboardStat & MBS_MOUSE_MASK) || _activeVerb == kVerbWhatIs) { // click region: sentence line if (zone->number == kVerbVirtScreen && _mouse.y <= zone->topline + 8) { @@ -793,9 +781,11 @@ void ScummEngine_v0::checkExecVerbs() { kid = 2; _activeVerb = kVerbWalkTo; _redrawSentenceLine = true; + drawSentenceLine(); switchActor(kid); } _activeVerb = kVerbWalkTo; + _redrawSentenceLine = true; return; } else { // execute sentence if complete -- cgit v1.2.3 From 124e8926ba3d81c03f7603ebb6f5b2ed8d949831 Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Sun, 22 Jan 2012 00:01:53 +0100 Subject: SCUMM: do not convert a savegame twice --- engines/scumm/saveload.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'engines/scumm') diff --git a/engines/scumm/saveload.cpp b/engines/scumm/saveload.cpp index 6c6c4a1a27..a1b2fafa86 100644 --- a/engines/scumm/saveload.cpp +++ b/engines/scumm/saveload.cpp @@ -1212,7 +1212,7 @@ void ScummEngine::saveOrLoad(Serializer *s) { _objs[i].obj_nr = 0; } else if (_game.version == 0) { // TODO: handle this correctly for (i = 0; i < _numLocalObjects; i++) { - if (_objs[i].obj_nr != 0 && _objs[i].flags != 0) + if (_objs[i].obj_nr != 0 && OBJECT_V0_TYPE(_objs[i].obj_nr) == 0 && _objs[i].flags != 0) _objs[i].obj_nr = OBJECT_V0(_objs[i].obj_nr, _objs[i].flags); } } -- cgit v1.2.3 From 00dcc63e8f7c59c5e331963e56b03a5f8462745d Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Sun, 22 Jan 2012 01:31:28 +0100 Subject: SCUMM: remove unimplemented und unused method startMusic() in pce and apple2 players --- engines/scumm/player_apple2.h | 1 - engines/scumm/player_pce.h | 1 - 2 files changed, 2 deletions(-) (limited to 'engines/scumm') diff --git a/engines/scumm/player_apple2.h b/engines/scumm/player_apple2.h index 4cbd24b81d..c3e1b7fc60 100644 --- a/engines/scumm/player_apple2.h +++ b/engines/scumm/player_apple2.h @@ -247,7 +247,6 @@ public: _sampleRate = rate; _sampleConverter.setSampleRate(rate); } - void startMusic(int songResIndex); virtual void startSound(int sound); virtual void stopSound(int sound); virtual void stopAllSounds(); diff --git a/engines/scumm/player_pce.h b/engines/scumm/player_pce.h index eb6afd892a..427fb1ace6 100644 --- a/engines/scumm/player_pce.h +++ b/engines/scumm/player_pce.h @@ -76,7 +76,6 @@ public: virtual ~Player_PCE(); virtual void setMusicVolume(int vol) { _maxvol = vol; } - void startMusic(int songResIndex); virtual void startSound(int sound); virtual void stopSound(int sound); virtual void stopAllSounds(); -- cgit v1.2.3 From 7d4ffb1ec068bb149fb20287d955719d3c3f5a0d Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Sun, 22 Jan 2012 01:43:46 +0100 Subject: SCUMM: fix resetAllSounds() in player_sid It actually was stopMusic() before and so stopped only the music and not all sounds. The former implementation is for the o_stopMusic opcode which is not supported directly by ScummVM (it always stops all sounds). It is kept as stopMusic_intern() but is not used anymore. --- engines/scumm/player_sid.cpp | 4 ++-- engines/scumm/player_sid.h | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) (limited to 'engines/scumm') diff --git a/engines/scumm/player_sid.cpp b/engines/scumm/player_sid.cpp index f0f60a3924..ecfaef22c1 100644 --- a/engines/scumm/player_sid.cpp +++ b/engines/scumm/player_sid.cpp @@ -683,7 +683,7 @@ void Player_SID::stopSound_intern(int soundResID) { // $5093 releaseResource(soundResID); } -void Player_SID::stopAllSounds_intern() { // $4CAA +void Player_SID::stopMusic_intern() { // $4CAA statusBits1B = 0; isMusicPlaying = false; @@ -1352,7 +1352,7 @@ void Player_SID::stopSound(int nr) { void Player_SID::stopAllSounds() { Common::StackLock lock(_mutex); - stopAllSounds_intern(); + resetPlayerState(); } int Player_SID::getSoundStatus(int nr) const { diff --git a/engines/scumm/player_sid.h b/engines/scumm/player_sid.h index baeb7bbef0..12e3573575 100644 --- a/engines/scumm/player_sid.h +++ b/engines/scumm/player_sid.h @@ -57,7 +57,6 @@ public: virtual ~Player_SID(); virtual void setMusicVolume(int vol) { _maxvol = vol; } - void startMusic(int songResIndex); virtual void startSound(int sound); virtual void stopSound(int sound); virtual void stopAllSounds(); @@ -95,7 +94,7 @@ private: void initMusic(int songResIndex); // $7de6 int initSound(int soundResID); // $4D0A void stopSound_intern(int soundResID); // $5093 - void stopAllSounds_intern(); // $4CAA + void stopMusic_intern(); // $4CAA void resetSID(); // $48D8 void update(); // $481B -- cgit v1.2.3 From fd4a3501ede75d87c06980b5ac563402da834f25 Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Sun, 22 Jan 2012 01:44:42 +0100 Subject: SCUMM: fix saving of array _byte_FCE2 --- engines/scumm/actor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'engines/scumm') diff --git a/engines/scumm/actor.cpp b/engines/scumm/actor.cpp index 86daaeff2f..3a4f72181b 100644 --- a/engines/scumm/actor.cpp +++ b/engines/scumm/actor.cpp @@ -2711,7 +2711,7 @@ void ActorC64::saveLoadWithSerializer(Serializer *ser) { MKLINE(ActorC64, _speakingPrev, sleByte, VER(84)), MKLINE(ActorC64, _byte_FD0A, sleByte, VER(89)), MKLINE(ActorC64, _byte_FDE8, sleByte, VER(89)), - MKARRAY(ActorC64, _byte_FCE2, sleInt8, 8, VER(89)), + MKARRAY(ActorC64, _byte_FCE2[0], sleInt8, 8, VER(89)), MKEND() }; -- cgit v1.2.3 From 96f8fc6ca9889d30db11b854c95ffd65bb88034d Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Sun, 22 Jan 2012 22:58:10 +0100 Subject: SCUMM: Fix actor ID handling in v0 Some object functions allow actor IDs and object IDs as parameters. They are easily distinguishable in engines > 0 as actor IDs are < _numActors and object IDs are bigger. In v0 this is not the case as there are objects with IDs like 3 and 5 (e.g. the hamster). So object ID handling was unified for v0 and the other engines by introducing objIsActor(), objToActor() and ActorToObj(). --- engines/scumm/debugger.cpp | 4 +-- engines/scumm/object.cpp | 67 +++++++++++++++++++++++++++++---------------- engines/scumm/script_v0.cpp | 21 +++++++------- engines/scumm/script_v2.cpp | 4 +-- engines/scumm/script_v5.cpp | 8 +++++- engines/scumm/scumm.h | 3 ++ engines/scumm/scumm_v0.h | 2 +- 7 files changed, 69 insertions(+), 40 deletions(-) (limited to 'engines/scumm') diff --git a/engines/scumm/debugger.cpp b/engines/scumm/debugger.cpp index 5d1396633f..edcf2e6fea 100644 --- a/engines/scumm/debugger.cpp +++ b/engines/scumm/debugger.cpp @@ -382,8 +382,8 @@ bool ScummDebugger::Cmd_Actor(int argc, const char **argv) { DebugPrintf("Actor[%d].costume = %d\n", actnum, a->_costume); } } else if (!strcmp(argv[2], "name")) { - int actor = (_vm->_game.version != 0 ? actnum : OBJECT_V0(actnum, kObjectV0TypeActor)); - DebugPrintf("Name of actor %d: %s\n", actnum, _vm->getObjOrActorName(actor)); + DebugPrintf("Name of actor %d: %s\n", actnum, + _vm->getObjOrActorName(_vm->actorToObj(actnum))); } else if (!strcmp(argv[2], "condmask")) { if (argc > 3) { a->_heCondMask = value; diff --git a/engines/scumm/object.cpp b/engines/scumm/object.cpp index bf871d7fa5..4ef8707714 100644 --- a/engines/scumm/object.cpp +++ b/engines/scumm/object.cpp @@ -357,8 +357,8 @@ int ScummEngine::whereIsObject(int object) const { int ScummEngine::getObjectOrActorXY(int object, int &x, int &y) { Actor *act; - if (object < _numActors) { - act = derefActorSafe(object, "getObjectOrActorXY"); + if (objIsActor(object)) { + act = derefActorSafe(objToActor(object), "getObjectOrActorXY"); if (act && act->isInCurrentRoom()) { x = act->getRealPos().x; y = act->getRealPos().y; @@ -371,7 +371,7 @@ int ScummEngine::getObjectOrActorXY(int object, int &x, int &y) { case WIO_NOT_FOUND: return -1; case WIO_INVENTORY: - if (_objectOwnerTable[object] < _numActors) { + if (objIsActor(_objectOwnerTable[object])) { act = derefActor(_objectOwnerTable[object], "getObjectOrActorXY(2)"); if (act && act->isInCurrentRoom()) { x = act->getRealPos().x; @@ -463,11 +463,11 @@ int ScummEngine::getObjActToObjActDist(int a, int b) { Actor *acta = NULL; Actor *actb = NULL; - if (a < _numActors) - acta = derefActorSafe(a, "getObjActToObjActDist"); + if (objIsActor(a)) + acta = derefActorSafe(objToActor(a), "getObjActToObjActDist"); - if (b < _numActors) - actb = derefActorSafe(b, "getObjActToObjActDist(2)"); + if (objIsActor(b)) + actb = derefActorSafe(objToActor(b), "getObjActToObjActDist(2)"); if (acta && actb && acta->getRoom() == actb->getRoom() && acta->getRoom() && !acta->isInCurrentRoom()) return 0; @@ -1143,11 +1143,8 @@ const byte *ScummEngine::getObjOrActorName(int obj) { byte *objptr; int i; - if ((_game.version == 0 && OBJECT_V0_TYPE(obj) == kObjectV0TypeActor) || - (_game.version != 0 && obj < _numActors)) { - int actorNr = (_game.version != 0 ? obj : OBJECT_V0_ID(obj)); - return derefActor(actorNr, "getObjOrActorName")->getActorName(); - } + if (objIsActor(obj)) + return derefActor(objToActor(obj), "getObjOrActorName")->getActorName(); for (i = 0; i < _numNewNames; i++) { if (_newNames[i] == obj) { @@ -1183,7 +1180,7 @@ const byte *ScummEngine::getObjOrActorName(int obj) { void ScummEngine::setObjectName(int obj) { int i; - if (obj < _numActors && _game.version != 0) + if (objIsActor(obj)) error("Can't set actor %d name with new-name-of", obj); for (i = 0; i < _numNewNames; i++) { @@ -1491,11 +1488,34 @@ void ScummEngine::findObjectInRoom(FindObjectInRoom *fo, byte findWhat, uint id, } } +bool ScummEngine::objIsActor(int obj) { + // object IDs < _numActors are used in v0 for objects too (e.g. hamster) + if (_game.version == 0) + return OBJECT_V0_TYPE(obj) == kObjectV0TypeActor; + else + return obj < _numActors; +} + +int ScummEngine::objToActor(int obj) { + if (_game.version == 0) + return OBJECT_V0_ID(obj); + else + return obj; +} + +int ScummEngine::actorToObj(int actor) { + if (_game.version == 0) + return OBJECT_V0(actor, kObjectV0TypeActor); + else + return actor; +} + int ScummEngine::getObjX(int obj) { - if (obj < _numActors) { - if (obj < 1) - return 0; /* fix for indy4's map */ - return derefActor(obj, "getObjX")->getRealPos().x; + if (obj < 1) + return 0; /* fix for indy4's map */ + + if (objIsActor(obj)) { + return derefActor(objToActor(obj), "getObjX")->getRealPos().x; } else { if (whereIsObject(obj) == WIO_NOT_FOUND) return -1; @@ -1506,10 +1526,11 @@ int ScummEngine::getObjX(int obj) { } int ScummEngine::getObjY(int obj) { - if (obj < _numActors) { - if (obj < 1) - return 0; /* fix for indy4's map */ - return derefActor(obj, "getObjY")->getRealPos().y; + if (obj < 1) + return 0; /* fix for indy4's map */ + + if (objIsActor(obj)) { + return derefActor(objToActor(obj), "getObjY")->getRealPos().y; } else { if (whereIsObject(obj) == WIO_NOT_FOUND) return -1; @@ -1525,8 +1546,8 @@ int ScummEngine::getObjOldDir(int obj) { int ScummEngine::getObjNewDir(int obj) { int dir; - if (obj < _numActors) { - dir = derefActor(obj, "getObjNewDir")->getFacing(); + if (objIsActor(obj)) { + dir = derefActor(objToActor(obj), "getObjNewDir")->getFacing(); } else { int x, y; getObjectXYPos(obj, x, y, dir); diff --git a/engines/scumm/script_v0.cpp b/engines/scumm/script_v0.cpp index b0e3a958e4..7dc8945595 100644 --- a/engines/scumm/script_v0.cpp +++ b/engines/scumm/script_v0.cpp @@ -81,7 +81,7 @@ void ScummEngine_v0::setupOpcodes() { /* 24 */ OPCODE(0x24, o_ifNotEqualActiveObject2); OPCODE(0x25, o5_loadRoom); - OPCODE(0x26, o_getClosestObjActor); + OPCODE(0x26, o_getClosestActor); OPCODE(0x27, o2_getActorY); /* 28 */ OPCODE(0x28, o5_equalZero); @@ -161,7 +161,7 @@ void ScummEngine_v0::setupOpcodes() { /* 64 */ OPCODE(0x64, o_ifEqualActiveObject2); OPCODE(0x65, o_stopCurrentScript); - OPCODE(0x66, o_getClosestObjActor); + OPCODE(0x66, o_getClosestActor); OPCODE(0x67, o5_getActorFacing); /* 68 */ OPCODE(0x68, o5_isScriptRunning); @@ -884,31 +884,30 @@ void ScummEngine_v0::o_ifNotEqualActiveObject2() { jumpRelative(!equal); } -void ScummEngine_v0::o_getClosestObjActor() { - int obj; - int act; +void ScummEngine_v0::o_getClosestActor() { + int act, check_act; int dist; // This code can't detect any actors farther away than 255 units // (pixels in newer games, characters in older ones.) But this is // perfectly OK, as it is exactly how the original behaved. - int closest_obj = 0xFF, closest_dist = 0xFF; + int closest_act = 0xFF, closest_dist = 0xFF; getResultPos(); act = getVarOrDirectByte(PARAM_1); - obj = (_opcode & PARAM_2) ? 25 : 7; + check_act = (_opcode & PARAM_2) ? 25 : 7; do { - dist = getObjActToObjActDist(act, obj); + dist = getObjActToObjActDist(actorToObj(act), actorToObj(check_act)); if (dist < closest_dist) { closest_dist = dist; - closest_obj = obj; + closest_act = check_act; } - } while (--obj); + } while (--check_act); - setResult(closest_obj); + setResult(closest_act); } void ScummEngine_v0::o_cutscene() { diff --git a/engines/scumm/script_v2.cpp b/engines/scumm/script_v2.cpp index 6f6138d411..59500deaf5 100644 --- a/engines/scumm/script_v2.cpp +++ b/engines/scumm/script_v2.cpp @@ -1315,7 +1315,7 @@ void ScummEngine_v2::o2_getActorX() { getResultPos(); a = getVarOrDirectByte(PARAM_1); - setResult(getObjX(a)); + setResult(getObjX(actorToObj(a))); } void ScummEngine_v2::o2_getActorY() { @@ -1323,7 +1323,7 @@ void ScummEngine_v2::o2_getActorY() { getResultPos(); a = getVarOrDirectByte(PARAM_1); - setResult(getObjY(a)); + setResult(getObjY(actorToObj(a))); } void ScummEngine_v2::o2_isGreater() { diff --git a/engines/scumm/script_v5.cpp b/engines/scumm/script_v5.cpp index 707c3c2397..a5591b701f 100644 --- a/engines/scumm/script_v5.cpp +++ b/engines/scumm/script_v5.cpp @@ -1095,10 +1095,16 @@ void ScummEngine_v5::o5_getClosestObjActor() { void ScummEngine_v5::o5_getDist() { int o1, o2; int r; + getResultPos(); + o1 = getVarOrDirectWord(PARAM_1); o2 = getVarOrDirectWord(PARAM_2); - r = getObjActToObjActDist(o1, o2); + + if (_game.version == 0) // in v0 both parameters are always actor IDs, never objects + r = getObjActToObjActDist(actorToObj(o1), actorToObj(o2)); + else + r = getObjActToObjActDist(o1, o2); // FIXME: MI2 race workaround, see bug #597022. We never quite figured out // what the real cause of this, or if it maybe occurs in the original, too... diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h index fadc3902c0..042a3a5d47 100644 --- a/engines/scumm/scumm.h +++ b/engines/scumm/scumm.h @@ -787,6 +787,9 @@ protected: void setOwnerOf(int obj, int owner); void clearOwnerOf(int obj); int getObjectRoom(int obj) const; + bool objIsActor(int obj); + int objToActor(int obj); + int actorToObj(int actor); int getObjX(int obj); int getObjY(int obj); void getObjectXYPos(int object, int &x, int &y) { int dir; getObjectXYPos(object, x, y, dir); } diff --git a/engines/scumm/scumm_v0.h b/engines/scumm/scumm_v0.h index c5c0c0950c..10ae18ace5 100644 --- a/engines/scumm/scumm_v0.h +++ b/engines/scumm/scumm_v0.h @@ -138,7 +138,7 @@ protected: void o_doSentence(); void o_ifEqualActiveObject2(); void o_ifNotEqualActiveObject2(); - void o_getClosestObjActor(); + void o_getClosestActor(); void o_printEgo_c64(); void o_print_c64(); void o_unlockRoom(); -- cgit v1.2.3 From b31157cee3159ec266e454dec354bd928ee54629 Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Sun, 22 Jan 2012 23:01:59 +0100 Subject: SCUMM: delete some obsolete v0 TODOs --- engines/scumm/script_v0.cpp | 3 --- engines/scumm/verbs.cpp | 1 - 2 files changed, 4 deletions(-) (limited to 'engines/scumm') diff --git a/engines/scumm/script_v0.cpp b/engines/scumm/script_v0.cpp index 7dc8945595..9fd8397596 100644 --- a/engines/scumm/script_v0.cpp +++ b/engines/scumm/script_v0.cpp @@ -584,8 +584,6 @@ void ScummEngine_v0::o_loadRoomWithEgo() { //0x634F if (a->_miscflags & kActorMiscFlagFreeze) { - // TODO: Check if this is the correct function - // to be calling here stopObjectCode(); return; } @@ -767,7 +765,6 @@ void ScummEngine_v0::o_setObjectName() { void ScummEngine_v0::o_nop() { } -// TODO: Maybe translate actor flags in future. void ScummEngine_v0::o_setActorBitVar() { byte act = getVarOrDirectByte(PARAM_1); byte mask = getVarOrDirectByte(PARAM_2); diff --git a/engines/scumm/verbs.cpp b/engines/scumm/verbs.cpp index bb0d8f4ae2..9334f40048 100644 --- a/engines/scumm/verbs.cpp +++ b/engines/scumm/verbs.cpp @@ -62,7 +62,6 @@ static const VerbSettings v0VerbTable_English[] = { {kVerbWhatIs, 15, 2, "What is"} }; -// FIXME: Replace * with the correct character static const VerbSettings v0VerbTable_German[] = { {kVerbOpen, 7, 0, "$ffne"}, {kVerbClose, 13, 1, "Schlie*e"}, -- cgit v1.2.3 From b0201a8df24462b95c786826793e46583349ee1c Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Sun, 22 Jan 2012 23:06:07 +0100 Subject: SCUMM: fix o_setObjectName() The parameter can either be a FG or BG object depending on the opcode. --- engines/scumm/script_v0.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'engines/scumm') diff --git a/engines/scumm/script_v0.cpp b/engines/scumm/script_v0.cpp index 9fd8397596..a04f23aea8 100644 --- a/engines/scumm/script_v0.cpp +++ b/engines/scumm/script_v0.cpp @@ -756,9 +756,16 @@ void ScummEngine_v0::o_pickupObject() { } void ScummEngine_v0::o_setObjectName() { - int obj = fetchScriptByte(); - if (!obj) + int obj; + int objId = fetchScriptByte(); + if (!objId) { obj = _cmdObject; + } else { + if (_opcode & 0x80) + obj = OBJECT_V0(objId, kObjectV0TypeBG); + else + obj = OBJECT_V0(objId, kObjectV0TypeFG); + } setObjectName(obj); } -- cgit v1.2.3 From 1da715719c89e5cb185accf48300ba1d75c63b96 Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Sun, 22 Jan 2012 23:10:46 +0100 Subject: SCUMM: handle actor freeze in walkToActorOrObject() --- engines/scumm/script.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'engines/scumm') diff --git a/engines/scumm/script.cpp b/engines/scumm/script.cpp index 6dac647714..31eef50a6a 100644 --- a/engines/scumm/script.cpp +++ b/engines/scumm/script.cpp @@ -1149,9 +1149,9 @@ void ScummEngine_v0::walkToActorOrObject(int object) { VAR(6) = x; VAR(7) = y; - if (!(a->_miscflags & kActorMiscFlagFreeze)) { - // FIXME: walking already started -> should be stopped if condition not true - //actorStartWalk(); + // actor must not move if frozen + if (a->_miscflags & kActorMiscFlagFreeze) + a->stopActorMoving(); } } -- cgit v1.2.3 From fb684565412c69aeb0d0a9837fc5a76b98cbe285 Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Sun, 22 Jan 2012 23:13:58 +0100 Subject: SCUMM: complete handling of pending walkTo actions for sentence commands in v0 --- engines/scumm/script.cpp | 53 ++++++++++++++++++++++++++++++++++++--------- engines/scumm/script_v0.cpp | 3 ++- engines/scumm/scumm_v0.h | 9 +++++++- engines/scumm/verbs.cpp | 4 ++-- 4 files changed, 55 insertions(+), 14 deletions(-) (limited to 'engines/scumm') diff --git a/engines/scumm/script.cpp b/engines/scumm/script.cpp index 31eef50a6a..cda2b3cd82 100644 --- a/engines/scumm/script.cpp +++ b/engines/scumm/script.cpp @@ -1135,7 +1135,7 @@ void ScummEngine_v0::walkToActorOrObject(int object) { ActorC64 *a = (ActorC64 *)derefActor(VAR(VAR_EGO), "walkToObject"); _walkToObject = object; - _walkToObjectIdx = getObjectIndex(object); + _walkToObjectState = kWalkToObjectStateWalk; if (OBJECT_V0_TYPE(object) == kObjectV0TypeActor) { walkActorToActor(VAR(VAR_EGO), OBJECT_V0_ID(object), 4); @@ -1152,19 +1152,52 @@ void ScummEngine_v0::walkToActorOrObject(int object) { // actor must not move if frozen if (a->_miscflags & kActorMiscFlagFreeze) a->stopActorMoving(); +} + +bool ScummEngine_v0::checkPendingWalkAction() { + // before a sentence script is executed, it might be necessary to walk to + // and pickup objects before. Check if such an action is pending and handle + // it if available. + if (_walkToObjectState == kWalkToObjectStateDone) + return false; + + int actor = VAR(VAR_EGO); + ActorC64 *a = (ActorC64 *)derefActor(actor, "checkAndRunSentenceScript"); + + // wait until walking or turning action is finished + if (a->_moving) + return true; + + // after walking and turning finally execute the script + if (_walkToObjectState == kWalkToObjectStateTurn) { + runSentenceScript(); + // change actor facing + } else if (getObjActToObjActDist(actorToObj(actor), _walkToObject) <= 4) { + if (objIsActor(_walkToObject)) { // walk to actor finished + // make actors turn to each other + a->faceToObject(_walkToObject); + int otherActor = objToActor(_walkToObject); + // ignore the plant + if (otherActor != 19) { + Actor *b = derefActor(otherActor, "checkAndRunSentenceScript(2)"); + b->faceToObject(actorToObj(actor)); + } + } else { // walk to object finished + int x, y, dir; + getObjectXYPos(_walkToObject, x, y, dir); + a->turnToDirection(dir); + } + _walkToObjectState = kWalkToObjectStateTurn; + return true; } + + _walkToObjectState = kWalkToObjectStateDone; + return false; } void ScummEngine_v0::checkAndRunSentenceScript() { - if (_walkToObjectIdx) { - ActorC64 *a = (ActorC64 *)derefActor(VAR(VAR_EGO), "checkAndRunSentenceScript"); - if (a->_moving) - return; - // TODO: change actor facing - _walkToObjectIdx = 0; - runSentenceScript(); + if (checkPendingWalkAction()) return; - } if (!_sentenceNum || _sentence[_sentenceNum - 1].freezeCount) return; @@ -1214,7 +1247,7 @@ void ScummEngine_v0::checkAndRunSentenceScript() { runSentenceScript(); if (_currentMode == kModeKeypad) { - _walkToObjectIdx = 0; + _walkToObjectState = kWalkToObjectStateDone; } } diff --git a/engines/scumm/script_v0.cpp b/engines/scumm/script_v0.cpp index a04f23aea8..4d9a206118 100644 --- a/engines/scumm/script_v0.cpp +++ b/engines/scumm/script_v0.cpp @@ -976,7 +976,8 @@ void ScummEngine_v0::resetSentence() { _activeVerb = kVerbWalkTo; _activeObject = 0; _activeObject2 = 0; - _walkToObjectIdx = 0; + + _walkToObjectState = kWalkToObjectStateDone; _redrawSentenceLine = true; } diff --git a/engines/scumm/scumm_v0.h b/engines/scumm/scumm_v0.h index 10ae18ace5..e25d6f5826 100644 --- a/engines/scumm/scumm_v0.h +++ b/engines/scumm/scumm_v0.h @@ -39,6 +39,12 @@ protected: kModeNormal = 3, // normal playing mode }; + enum WalkToObjectState { + kWalkToObjectStateDone = 0, + kWalkToObjectStateWalk = 1, + kWalkToObjectStateTurn = 2, + }; + protected: byte _currentMode; @@ -51,7 +57,7 @@ protected: int _cmdObject2; // 2nd script object or actor (see OBJECT_V0()) int _walkToObject; - int _walkToObjectIdx; + int _walkToObjectState; bool _redrawSentenceLine; public: @@ -81,6 +87,7 @@ protected: virtual void runSentenceScript(); virtual void checkAndRunSentenceScript(); + bool checkPendingWalkAction(); bool checkSentenceComplete(); virtual void checkExecVerbs(); virtual void handleMouseOver(bool updateInventory); diff --git a/engines/scumm/verbs.cpp b/engines/scumm/verbs.cpp index 9334f40048..91c9cc159a 100644 --- a/engines/scumm/verbs.cpp +++ b/engines/scumm/verbs.cpp @@ -699,7 +699,7 @@ void ScummEngine_v0::verbExec() { _activeObject = 0; _activeObject2 = 0; } - _walkToObjectIdx = 0; + _walkToObjectState = kWalkToObjectStateDone; return; } @@ -845,7 +845,7 @@ void ScummEngine_v0::checkExecVerbs() { _redrawSentenceLine = true; if (_activeVerb == kVerbWalkTo && zone->number == kMainVirtScreen) { - _walkToObjectIdx = 0; + _walkToObjectState = kWalkToObjectStateDone; execute = true; } } -- cgit v1.2.3 From e3f9a09d49aaeb4657862ca734d20279e75c869f Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Sun, 22 Jan 2012 23:20:27 +0100 Subject: SCUMM: keep track of the number of nested script calls for a sentence command in v0 If for instance an object necessary for the sentence command is not reachable or pickupable (try to use faucet (object 55) with jar with water in microwave (object 50), the pick-up script of the jar will tell the actor to pickup object 99 (jar not in microwave)) the actor will try to pick-up the jar infinitely. This is fixed by counting the amount of nested scripts the sentence command has called (directly or indirectly) so far and aborts it if there have been too many. --- engines/scumm/script.cpp | 17 ++++++++++++++--- engines/scumm/script_v0.cpp | 3 +++ engines/scumm/scumm_v0.h | 1 + engines/scumm/verbs.cpp | 3 +++ 4 files changed, 21 insertions(+), 3 deletions(-) (limited to 'engines/scumm') diff --git a/engines/scumm/script.cpp b/engines/scumm/script.cpp index cda2b3cd82..b51452170a 100644 --- a/engines/scumm/script.cpp +++ b/engines/scumm/script.cpp @@ -1209,8 +1209,7 @@ void ScummEngine_v0::checkAndRunSentenceScript() { return; } - // FIXME: should this be executed? - //_currentScript = 0xFF; + _currentScript = 0xFF; assert(st.objectA); @@ -1233,7 +1232,19 @@ void ScummEngine_v0::checkAndRunSentenceScript() { _cmdObject2 = st.objectB; _sentenceNum--; - // TODO: check sentenceNum + // abort sentence execution if the number of nested scripts is too high. + // This might happen for instance if the sentence command depends on an + // object that the actor has to pick-up in a nested doSentence() call. + // If the actor is not able to pick-up the object (e.g. because it is not + // reachable or pickupable) a nested pick-up command is triggered again + // and again, so the actual sentence command will never be executed. + // In this case the sentence command has to be aborted. + _sentenceNestedCount++; + if (_sentenceNestedCount > 6) { + _sentenceNestedCount = 0; + _sentenceNum = 0; + return; + } if (whereIsObject(st.objectA) != WIO_INVENTORY) { if (_currentMode != kModeKeypad) { diff --git a/engines/scumm/script_v0.cpp b/engines/scumm/script_v0.cpp index 4d9a206118..4081123e13 100644 --- a/engines/scumm/script_v0.cpp +++ b/engines/scumm/script_v0.cpp @@ -979,6 +979,9 @@ void ScummEngine_v0::resetSentence() { _walkToObjectState = kWalkToObjectStateDone; _redrawSentenceLine = true; + + _sentenceNum = 0; + _sentenceNestedCount = 0; } } // End of namespace Scumm diff --git a/engines/scumm/scumm_v0.h b/engines/scumm/scumm_v0.h index e25d6f5826..8b13569042 100644 --- a/engines/scumm/scumm_v0.h +++ b/engines/scumm/scumm_v0.h @@ -55,6 +55,7 @@ protected: int _cmdVerb; // script verb int _cmdObject; // 1st script object (see OBJECT_V0()) int _cmdObject2; // 2nd script object or actor (see OBJECT_V0()) + int _sentenceNestedCount; int _walkToObject; int _walkToObjectState; diff --git a/engines/scumm/verbs.cpp b/engines/scumm/verbs.cpp index 91c9cc159a..7a099adae9 100644 --- a/engines/scumm/verbs.cpp +++ b/engines/scumm/verbs.cpp @@ -689,6 +689,9 @@ int ScummEngine_v0::activeVerbPrep() { } void ScummEngine_v0::verbExec() { + _sentenceNum = 0; + _sentenceNestedCount = 0; + if (_activeVerb == kVerbWhatIs) return; -- cgit v1.2.3 From 65fb1f9a09b3460eebaf7d033990fe9e778070f4 Mon Sep 17 00:00:00 2001 From: Robert Crossfield Date: Tue, 24 Jan 2012 23:23:19 +1100 Subject: SCUMM: Fix the animation system, rename the Limb Frame Repeat variable --- engines/scumm/actor.cpp | 259 ++++++++++++++++++++++++++++++++------------ engines/scumm/actor.h | 43 +++++--- engines/scumm/costume.cpp | 234 +++++++++++---------------------------- engines/scumm/costume.h | 2 - engines/scumm/script_v0.cpp | 10 +- 5 files changed, 285 insertions(+), 263 deletions(-) (limited to 'engines/scumm') diff --git a/engines/scumm/actor.cpp b/engines/scumm/actor.cpp index 3a4f72181b..2d0e498f48 100644 --- a/engines/scumm/actor.cpp +++ b/engines/scumm/actor.cpp @@ -42,6 +42,14 @@ namespace Scumm { byte Actor::kInvalidBox = 0; +static const byte v0ActorTalkArray[0x19] = { + 0x00, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x00, 0x46, 0x06, + 0x06, 0x06, 0x06, 0xFF, 0xFF, + 0x06, 0xC0, 0x06, 0x06, 0x00, + 0xC0, 0xC0, 0x00, 0x06, 0x06 +}; + Actor::Actor(ScummEngine *scumm, int id) : _vm(scumm), _number(id) { assert(_vm != 0); @@ -226,11 +234,6 @@ void Actor::stopActorMoving() { if (_walkScript) _vm->stopScript(_walkScript); - // V0 Games will walk on the spot if the actor is stopped mid-walk - // So we must set the stand still frame - if (_vm->_game.version == 0) - startWalkAnim(3, -1); - _moving = 0; } @@ -320,11 +323,12 @@ int Actor::actorWalkStep() { int nextFacing; if( _vm->_game.version == 0 ) - ((ActorC64*) this)->_byte_FD0A = -1; + ((ActorC64*) this)->_AnimFrameRepeat = -1; _needRedraw = true; - nextFacing = updateActorDirection(true); + nextFacing = updateActorDirection(true);; + if (!(_moving & MF_IN_LEG) || _facing != nextFacing) { if (_walkFrame != _frame || _facing != nextFacing) { startWalkAnim(1, nextFacing); @@ -364,6 +368,7 @@ int Actor::actorWalkStep() { _moving &= ~MF_IN_LEG; return 0; } + return 1; } @@ -415,6 +420,9 @@ void Actor::startWalkActor(int destX, int destY, int dir) { } } + if( _vm->_game.version == 0 ) + ((ActorC64*) this)->animateActor(dir); + _walkdata.dest.x = abr.x; _walkdata.dest.y = abr.y; _walkdata.destbox = abr.box; @@ -545,17 +553,18 @@ void Actor_v2::walkActor() { if (_moving & MF_TURN) { new_dir = updateActorDirection(false); - // FIXME: is this correct? + if (_facing != new_dir) { - // Actor never stops walking when an object has been selected without this - if (_vm->_game.version ==0) - _moving = 0; - - setDirection(new_dir); + if( _vm->_game.version != 0 ) + setDirection(new_dir); - } else + } else { _moving = 0; + } + + if( _vm->_game.version == 0 ) + ((ActorC64*)this)->setCmdFromDirection( newDirToOldDir(new_dir) ); return; } @@ -564,6 +573,8 @@ void Actor_v2::walkActor() { if (_moving & MF_IN_LEG) { actorWalkStep(); + if( _vm->_game.version == 0 ) + ((ActorC64*) this)->animateActor( newDirToOldDir( _facing ) ); } else { if (_moving & MF_LAST_LEG) { _moving = 0; @@ -850,7 +861,7 @@ void Actor::setDirection(int direction) { direction = 90; // Do nothing if actor is already facing in the given direction - if (_vm->_game.version != 0 && _facing == direction) + if (_facing == direction) return; // Normalize the angle @@ -872,25 +883,45 @@ void Actor::setDirection(int direction) { _needRedraw = true; } -void ActorC64::setDirection(int direction) { +void ActorC64::setDirection(int cmd) { // Normalize the angle - _facing = normalizeAngle(direction); - - // 0x2C17 - // _byte_FDE8 = -1; + _facing = normalizeAngle( cmd ); // If there is no costume set for this actor, we are finished if (_costume == 0) return; +} - if (_moving) - _vm->_costumeLoader->costumeDecodeData(this, _walkFrame, 0); - else { - _vm->_costumeLoader->costumeDecodeData(this, _standFrame, 0); - } +// based on 0x2BCA, doesn't match disassembly because 'oldDir' variable +// is not the same value as stored in the original interpreter +int ActorC64::setCmdFromDirection(int direction) { + int res = 0; - _needRedraw = true; + switch (direction) { + case 0: + res = 4; // Left + break; + + case 1: + res = 5; // Right + break; + + case 2: + res = 6; // Face Away + break; + + default: + res = 7; // Face Camera + break; + } + + + _AnimFrameRepeat = -1; + animateActor(res); + animateCostume(); + + return res; } void Actor::faceToObject(int obj) { @@ -961,10 +992,12 @@ void Actor::putActor(int dstX, int dstY, int newRoom) { if (_visible) { if (isInCurrentRoom()) { + if (_moving) { stopActorMoving(); startAnimActor(_standFrame); } + adjustActorPos(); } else { #ifdef ENABLE_HE @@ -1228,6 +1261,8 @@ void Actor::adjustActorPos() { if (flags & 7) { turnToDirection(_facing); } + if (_vm->_game.version == 0) + ((ActorC64*)this)->setCmdFromDirection( newDirToOldDir(_facing) ); } } @@ -1300,12 +1335,21 @@ void Actor::showActor() { _vm->ensureResourceLoaded(rtCostume, _costume); if (_vm->_game.version == 0) { + ActorC64 *a = ((ActorC64*) this); + + a->_costCommand = a->_costCommandNew = 0xFF; + + for( int i = 0; i < 8; ++i ) { + a->_limbFrameRepeatNew[i] = 0; + + } // 0x39DF - ((ActorC64*) this)->_byte_FDE8 = 1; + a->_AnimFrameRepeat = 1; _cost.reset(); - startAnimActor(_standFrame); + a->setCmdFromDirection( newDirToOldDir(_facing) ); + } else if (_vm->_game.version <= 2) { _cost.reset(); startAnimActor(_standFrame); @@ -1817,6 +1861,27 @@ void Actor::startAnimActor(int f) { } } +void ActorC64::startAnimActor(int f) { + if (f == _talkStartFrame) { + if (v0ActorTalkArray[_number] & 0x40) + return; + + _speaking = 1; + return; + } + + if (f == _talkStopFrame) { + + _speaking = 0; + return; + } + + if( f == _standFrame ) + setCmdFromDirection( newDirToOldDir(_facing) ); + else + animateActor( newDirToOldDir(_facing) ); +} + void Actor::animateActor(int anim) { int cmd, dir; @@ -1878,6 +1943,65 @@ void Actor::animateCostume() { } } +void ActorC64::limbFrameCheck() { + if (_cost.frame[_limb_current] == 0xFFFF ) + return; + + if (_cost.start[_limb_current] == _cost.frame[_limb_current] ) + return; + + // 0x25A4 + _cost.start[_limb_current] = _cost.frame[_limb_current]; + + _limbFrameRepeat[_limb_current] = _limbFrameRepeatNew[_limb_current]; + + _cost.active[_limb_current] = _cost.frame[_limb_current]; + _cost.curpos[_limb_current] = 0; + + _needRedraw = true; +} + +void ActorC64::animateCostume() { + + // Sound + if (_moving && _vm->_currentRoom != 1 && _vm->_currentRoom != 44) { + if (_cost.soundPos == 0) + _cost.soundCounter++; + + // Is this the correct location? + // 0x073C + if (v0ActorTalkArray[_number] & 0x3F) + _cost.soundPos = (_cost.soundPos + 1) % 3; + } + + _vm->_costumeLoader->loadCostume(_costume); + + speakCheck(); + + for( _limb_current = 0; _limb_current < 8; ++_limb_current ) { + limbFrameCheck(); + + if (_vm->_costumeLoader->increaseAnims(this)) + _needRedraw = true; + } +} + +void ActorC64::speakCheck() { + + if (v0ActorTalkArray[_number] & 0x80) + return; + + int cmd = newDirToOldDir( _facing ); + + if (_speaking & 0x80) + cmd += 0x0C; + else + cmd += 0x10; + + _AnimFrameRepeat = -1; + animateActor( cmd ); +} + #ifdef ENABLE_SCUMM_7_8 void Actor::animateLimb(int limb, int f) { // This methods is very similiar to animateCostume(). @@ -2661,42 +2785,43 @@ void ScummEngine_v71he::queueAuxEntry(int actorNum, int subIndex) { #endif void ActorC64::animateActor(int anim) { - int dir = oldDirToNewDir(anim % 4); - - if( this->isInCurrentRoom() ) { - - // this->_costCommandNew = anim; - - // 0x273A - /*switch( anim ) { - case 4: - dir = 1; - break; - case 5: - dir = 0; - break; - case 6: - dir = 0x80; - break; - case 7: - dir = 0x81; - break; - - default: - return; - }*/ - - - this->_byte_FD0A = this->_byte_FDE8; - - this->setDirection( dir ); - - } else { - - if( anim > 4 ) { - if( anim <= 7 ) - this->setDirection( dir ); - } + int dir = -1; + + switch( anim ) { + case 0x04: + dir = 0; + break; + + case 0x05: + dir = 1; + break; + + case 0x06: + dir = 2; + break; + + case 0x07: + dir = 3; + break; + + default: + break; + } + + if( isInCurrentRoom() ) { + + _costCommandNew = anim; + _vm->_costumeLoader->costumeDecodeData(this, 0, 0); + + if( dir == -1 ) + return; + + setDirection( oldDirToNewDir(dir) ); + + } else { + + if( anim > 4 && anim <= 7 ) + setDirection( oldDirToNewDir(dir) ); } } @@ -2708,10 +2833,8 @@ void ActorC64::saveLoadWithSerializer(Serializer *ser) { MKLINE(ActorC64, _costFrame, sleByte, VER(84)), MKLINE(ActorC64, _miscflags, sleByte, VER(84)), MKLINE(ActorC64, _speaking, sleByte, VER(84)), - MKLINE(ActorC64, _speakingPrev, sleByte, VER(84)), - MKLINE(ActorC64, _byte_FD0A, sleByte, VER(89)), - MKLINE(ActorC64, _byte_FDE8, sleByte, VER(89)), - MKARRAY(ActorC64, _byte_FCE2[0], sleInt8, 8, VER(89)), + MKLINE(ActorC64, _AnimFrameRepeat, sleByte, VER(89)), + MKARRAY(ActorC64, _limbFrameRepeatNew[0], sleInt8, 8, VER(89)), MKEND() }; diff --git a/engines/scumm/actor.h b/engines/scumm/actor.h index 7e8faa54cc..35ff657fa7 100644 --- a/engines/scumm/actor.h +++ b/engines/scumm/actor.h @@ -208,7 +208,7 @@ public: virtual void walkActor(); void drawActorCostume(bool hitTestMode = false); virtual void prepareDrawActorCostume(BaseCostumeRenderer *bcr); - void animateCostume(); + virtual void animateCostume(); virtual void setActorCostume(int c); void animateLimb(int limb, int f); @@ -222,7 +222,7 @@ protected: void startWalkAnim(int cmd, int angle); public: void runActorTalkScript(int f); - void startAnimActor(int frame); + virtual void startAnimActor(int frame); void remapActorPalette(int r_fact, int g_fact, int b_fact, int threshold); void remapActorPaletteColor(int slot, int color); @@ -348,38 +348,47 @@ enum ActorC64MiscFlags { class ActorC64 : public Actor_v2 { public: - byte _costCommand, _costFrame; + byte _costCommandNew, _costCommand, _costFrame; byte _miscflags; - byte _speaking, _speakingPrev; + byte _speaking; - int8 _byte_FDE8; - int8 _byte_FD0A; - int8 _byte_FCE2[8]; - + int8 _AnimFrameRepeat; + int8 _limbFrameRepeatNew[8], _limbFrameRepeat[8]; + + byte _limb_current; + bool _limb_flipped[8]; public: ActorC64(ScummEngine *scumm, int id) : Actor_v2(scumm, id) { - _costCommand = 0; + _costCommand = 0xFF; _costFrame = 0; _speaking = 0; - _speakingPrev = 0; - _byte_FD0A = 0; - _byte_FDE8 = 0; - - // Reset the limb counter? - for( int i = 0; i < sizeof( _byte_FCE2 ); ++i ) - _byte_FCE2[i] = 0; - + _AnimFrameRepeat = 0; + _costCommandNew = 0; + + for( int i = 0; i < 8; ++i ) { + _limbFrameRepeatNew[i] = 0; + _limbFrameRepeat[i] = 0; + _limb_flipped[i] = false; + } } virtual void initActor(int mode) { Actor_v2::initActor(mode); if (mode == -1) { _miscflags = 0; } + } virtual void animateActor(int anim); + virtual void animateCostume(); + + void limbFrameCheck(); + + void speakCheck(); virtual void setDirection(int direction); + int setCmdFromDirection(int direction); + void startAnimActor(int f); // Used by the save/load system: virtual void saveLoadWithSerializer(Serializer *ser); diff --git a/engines/scumm/costume.cpp b/engines/scumm/costume.cpp index 965cee79a8..c7285ead56 100644 --- a/engines/scumm/costume.cpp +++ b/engines/scumm/costume.cpp @@ -72,14 +72,6 @@ static const int v1MMNESLookup[25] = { 0x17, 0x00, 0x01, 0x05, 0x16 }; -static const byte v0ActorTalkArray[0x19] = { - 0x00, 0x06, 0x06, 0x06, 0x06, - 0x06, 0x06, 0x00, 0x46, 0x06, - 0x06, 0x06, 0x06, 0xFF, 0xFF, - 0x06, 0xC0, 0x06, 0x06, 0x00, - 0xC0, 0xC0, 0x00, 0x06, 0x06 -}; - byte ClassicCostumeRenderer::mainRoutine(int xmoveCur, int ymoveCur) { int i, skip = 0; byte drawFlag = 1; @@ -1187,10 +1179,12 @@ static const byte actorColorsMMC64[25] = { } byte C64CostumeRenderer::drawLimb(const Actor *a, int limb) { + ActorC64* A = (ActorC64*) a; + if (limb >= 8) return 0; - if (a->_cost.start[limb] == 0xFFFF) + if (a->_cost.curpos[limb] == 0xFFFF || A->_cost.active[limb] == 0xFFFF ) return 0; if (limb == 0) { @@ -1198,8 +1192,8 @@ byte C64CostumeRenderer::drawLimb(const Actor *a, int limb) { _draw_bottom = 0; } - bool flipped = (a->_cost.start[limb] & 0x80) != 0; - byte frameStart = _loaded._frameOffsets[a->_cost.frame[limb]]; + byte frameB = _loaded._frameOffsets[limb] + a->_cost.active[limb]; + byte frameStart = _loaded._frameOffsets[ frameB ]; byte frame = _loaded._frameOffsets[frameStart + a->_cost.curpos[limb]]; if (frame == 0xFF) return 0; @@ -1231,7 +1225,7 @@ byte C64CostumeRenderer::drawLimb(const Actor *a, int limb) { if (!width || !height) return 0; - int xpos = _actorX + (flipped ? -1 : +1) * (offsetX * 8 - a->_width / 2); + int xpos = _actorX + (A->_limb_flipped[ limb ] ? -1 : +1) * (offsetX * 8 - a->_width / 2); // +1 as we appear to be 1 pixel away from the original interpreter int ypos = _actorY - offsetY + 1; @@ -1241,13 +1235,13 @@ byte C64CostumeRenderer::drawLimb(const Actor *a, int limb) { byte color = data[y * width + x]; byte pcolor; - int destX = xpos + (flipped ? -(x + 1) : x) * 8; + int destX = xpos + (A->_limb_flipped[ limb ] ? -(x + 1) : x) * 8; int destY = ypos + y; if (destY >= 0 && destY < _out.h && destX >= 0 && destX < _out.w) { byte *dst = (byte *)_out.pixels + destY * _out.pitch + destX; byte *mask = _vm->getMaskBuffer(0, destY, _zbuf); - if (flipped) { + if (A->_limb_flipped[ limb ]) { LINE(0, 0); LINE(2, 2); LINE(4, 4); LINE(6, 6); } else { LINE(6, 0); LINE(4, 2); LINE(2, 4); LINE(0, 6); @@ -1258,7 +1252,7 @@ byte C64CostumeRenderer::drawLimb(const Actor *a, int limb) { _draw_top = MIN(_draw_top, ypos); _draw_bottom = MAX(_draw_bottom, ypos + height); - if (flipped) + if (A->_limb_flipped[ limb ]) _vm->markRectAsDirty(kMainVirtScreen, xpos - (width * 8), xpos, ypos, ypos + height, _actorID); else _vm->markRectAsDirty(kMainVirtScreen, xpos, xpos + (width * 8), ypos, ypos + height, _actorID); @@ -1291,195 +1285,93 @@ void C64CostumeLoader::loadCostume(int id) { _maxHeight = 0; } -void C64CostumeLoader::frameUpdate(ActorC64 *a, int cmd ) { - byte limbFrames = 0; - - // Each costume-command has 8 limbs (0x2622) - cmd <<= 3; - - for (int limb = 0, pos = 0; limb < 8; ++limb, pos = 0) { - // get the frame number for the beginning of the costume command - limbFrames = ((_animCmds + cmd)[limb]); - - // Dont change if frame is invalid - if (limbFrames == 0xFF) - continue; - - // 0x2679 - a->_byte_FCE2[limb] = a->_byte_FD0A; - - // Has limb frames ptr changed since last update? - if (a->_cost.start[limb] == limbFrames) - continue; - - // Set new limb command addresses - a->_cost.start[limb] = limbFrames; - a->_cost.frame[limb] = _frameOffsets[limb] + (limbFrames & 0x7f); // limb animation-frames ptr - - // Get first entry of a limbs' frames - byte frameStart = _frameOffsets[ a->_cost.frame[limb]]; - - // Loop each frame in this limb until we reach the end marker - while (pos != 0xFF) { // This is just so we dont overflow - byte frame = _frameOffsets[frameStart + pos]; - - // Each animation-frame until we find end - if (frame == 0xFF) - break; - - byte ptrLow = _baseptr[frame]; - byte ptrHigh = ptrLow + _dataOffsets[4]; - int frameOffset = (_baseptr[ptrHigh] << 8) + _baseptr[ptrLow + 2]; // 0x23EF / 0x2400 - - const byte *data = _baseptr + frameOffset; - - if (data[3] > _maxHeight) - _maxHeight = data[3] + 1; - - ++pos; - } - - // Set ending position of limb frames - a->_cost.end[limb] = pos; - a->_cost.curpos[limb] = 0; - } -} - -// based on 0x2BCA, doesn't match disassembly because 'oldDir' variable -// is not the same value as stored in the original interpreter -int C64CostumeLoader::dirToDirStop(int oldDir) { - int res = 0; - - switch (oldDir) { - case 0: - res = 4; // Left - break; - - case 1: - res = 5; // Right - break; - - case 2: - res = 6; // Face Camera - break; +void C64CostumeLoader::costumeDecodeData(Actor *a, int frame, uint usemask) { + ActorC64 *A = (ActorC64 *)a; - default: - res = 7; // Face Away - break; - } - - return res; -} + loadCostume(a->_costume); -void C64CostumeLoader::actorSpeak(ActorC64 *a, int &cmd) { - if (v0ActorTalkArray[a->_number] & 0x80) + if( A->_costCommandNew == 0xFF || (A->_costCommand == A->_costCommandNew) ) return; - if ((a->_speaking & 0x80)) - cmd += 0x0C; - else - cmd += 0x10; - - a->_byte_FDE8 = -1; -} + A->_costCommand = A->_costCommandNew; -void C64CostumeLoader::costumeDecodeData(Actor *a, int frame, uint usemask) { - ActorC64 *A = (ActorC64 *)a; - int dir = newDirToOldDir(a->getFacing()); - int command = dir; + int cmd = A->_costCommand; + byte limbFrameNumber = 0; - loadCostume(a->_costume); + // Each costume-command has 8 limbs (0x2622) + cmd <<= 3; - // Enable/Disable speaking flag - if (frame == a->_talkStartFrame) { + for (int limb = 0; limb < 8; ++limb) { - if (v0ActorTalkArray[a->_number] & 0x40) - return; + // get the frame number for the beginning of the costume command + limbFrameNumber = ((_animCmds + cmd)[limb]); - A->_speaking = 1; - return; - } + if( limbFrameNumber & 0x80 ) { - if (frame == a->_talkStopFrame) { + // 0x263D + if( limbFrameNumber == 0xFF ) + continue; - A->_speaking = 0; - return; - } + // 0x2643 + a->_cost.frame[limb] = (limbFrameNumber & 0x7f); // limb animation-frames ptr + if( A->_limb_flipped[limb] != true ) + a->_cost.start[limb] = 0xFFFF; - // Different command for stand frame - if (frame == a->_standFrame) - command = dirToDirStop(dir); + A->_limb_flipped[limb] = true; - // Update the limb frames - frameUpdate(A, command); + } else { + //0x2660 + a->_cost.frame[limb] = limbFrameNumber; - // Keep current command/frame mode - A->_costCommand = dir; - A->_costFrame = frame; + if( A->_limb_flipped[limb] != false ) + a->_cost.start[limb] = 0xFFFF; - // Update 'speaking' frames? - if (A->_speaking) { - command = dir; // Incase standing frame was set as cmd - actorSpeak(A, command); + A->_limb_flipped[limb] = false; + } - // Update the limb speak frames - frameUpdate(A, command); + // 0x2679 + A->_limbFrameRepeatNew[limb] = A->_AnimFrameRepeat; } } byte C64CostumeLoader::increaseAnims(Actor *a) { ActorC64 *A = (ActorC64 *)a; + + if( _frameOffsets == 0 ) + return 0; - // check if the actor speak flag has changed since last frame increase - if (A->_speaking != A->_speakingPrev) { - int cmd = A->_costCommand; - A->_speakingPrev = A->_speaking; - - actorSpeak(A, cmd); - - // Update the limb frames - frameUpdate(A, cmd); - } - - if (A->_moving && _vm->_currentRoom != 1 && _vm->_currentRoom != 44) { - if (a->_cost.soundPos == 0) - a->_cost.soundCounter++; - - // Is this the correct location? - // 0x073C - if (v0ActorTalkArray[a->_number] & 0x3F) - a->_cost.soundPos = (a->_cost.soundPos + 1) % 3; - } + uint16 limbPrevious = a->_cost.curpos[A->_limb_current]++; // increase each frame pos // 0x2543 - for (int limb = 0; limb < 8; ++limb) { - - if (++a->_cost.curpos[limb] >= a->_cost.end[limb]) { + byte frameB = _frameOffsets[A->_limb_current] + a->_cost.active[A->_limb_current]; + byte frameStart = _frameOffsets[ frameB ]; + byte frame = _frameOffsets[frameStart + a->_cost.curpos[A->_limb_current]]; - // 0x2541 - if( A->_byte_FCE2[limb] == 0 ) { + if ( frame == 0xFF ) { + // 0x2545 + if( A->_limbFrameRepeat[A->_limb_current] == 0 ) { - // 0x2556 - --a->_cost.curpos[limb]; + // 0x2556 + --A->_cost.curpos[A->_limb_current]; - //A->_costCommandNew = 0xFF; - //A->_costCommand = 0xFF; + A->_costCommandNew = 0xFF; + A->_costCommand = 0xFF; - // 0x2568 - //A->_limbCommandNew[limb] = 0xFF; - //A->_limbCommand[limb] = 0xFF; + // 0x2568 + A->_cost.frame[A->_limb_current] = 0xFFFF; + A->_cost.start[A->_limb_current] = 0xFFFF; - } else { - if( A->_byte_FCE2[limb] != -1 ) - --A->_byte_FCE2[limb]; + } else { + if( A->_limbFrameRepeat[A->_limb_current] != -1 ) + --A->_limbFrameRepeat[A->_limb_current]; - a->_cost.curpos[limb] = 0; - } + a->_cost.curpos[A->_limb_current] = 0; } + } - - } + if( limbPrevious == a->_cost.curpos[A->_limb_current] ) + return 0; return 1; } diff --git a/engines/scumm/costume.h b/engines/scumm/costume.h index 3acf2a1f6c..50e3f1e1b2 100644 --- a/engines/scumm/costume.h +++ b/engines/scumm/costume.h @@ -77,9 +77,7 @@ public: int _maxHeight; protected: - void actorSpeak(ActorC64 *a, int &cmd); int dirToDirStop(int oldDir); - void frameUpdate(ActorC64 *A, int cmd); }; diff --git a/engines/scumm/script_v0.cpp b/engines/scumm/script_v0.cpp index 4081123e13..0bdefd660b 100644 --- a/engines/scumm/script_v0.cpp +++ b/engines/scumm/script_v0.cpp @@ -27,6 +27,7 @@ #include "scumm/resource.h" #include "scumm/scumm_v0.h" #include "scumm/verbs.h" +#include "scumm/util.h" namespace Scumm { @@ -601,8 +602,7 @@ void ScummEngine_v0::o_loadRoomWithEgo() { x = r.x; y = r.y; a->putActor(x, y, _currentRoom); - a->setDirection(dir + 180); - + camera._dest.x = camera._cur.x = a->getPos().x; setCameraAt(a->getPos().x, a->getPos().y); setCameraFollows(a); @@ -674,13 +674,13 @@ void ScummEngine_v0::o_lights() { void ScummEngine_v0::o_animateActor() { int act = getVarOrDirectByte(PARAM_1); int anim = getVarOrDirectByte(PARAM_2); - int8 unk = (int8) fetchScriptByte(); + int8 animFrameRepeat = (int8) fetchScriptByte(); - debug(0,"o_animateActor: unk %d", unk); + debug(0,"o_animateActor: animFrameRepeat %d", animFrameRepeat); ActorC64 *a = (ActorC64*) derefActor(act, "o_animateActor"); - a->_byte_FDE8 = unk; + a->_AnimFrameRepeat = animFrameRepeat; switch( anim ) { -- cgit v1.2.3 From 08e3866395326faee0e64e2e92097f85418980f3 Mon Sep 17 00:00:00 2001 From: Robert Crossfield Date: Wed, 25 Jan 2012 16:18:33 +1100 Subject: SCUMM: Animation Fixes --- engines/scumm/actor.cpp | 65 ++++++++++++++++++++++++++------------------- engines/scumm/actor.h | 7 +++-- engines/scumm/costume.cpp | 7 +++-- engines/scumm/script_v0.cpp | 6 ++--- 4 files changed, 48 insertions(+), 37 deletions(-) (limited to 'engines/scumm') diff --git a/engines/scumm/actor.cpp b/engines/scumm/actor.cpp index 2d0e498f48..89e4133ade 100644 --- a/engines/scumm/actor.cpp +++ b/engines/scumm/actor.cpp @@ -323,11 +323,11 @@ int Actor::actorWalkStep() { int nextFacing; if( _vm->_game.version == 0 ) - ((ActorC64*) this)->_AnimFrameRepeat = -1; + ((ActorC64*) this)->_animFrameRepeat = -1; _needRedraw = true; - nextFacing = updateActorDirection(true);; + nextFacing = updateActorDirection(true); if (!(_moving & MF_IN_LEG) || _facing != nextFacing) { if (_walkFrame != _frame || _facing != nextFacing) { @@ -420,9 +420,6 @@ void Actor::startWalkActor(int destX, int destY, int dir) { } } - if( _vm->_game.version == 0 ) - ((ActorC64*) this)->animateActor(dir); - _walkdata.dest.x = abr.x; _walkdata.dest.y = abr.y; _walkdata.destbox = abr.box; @@ -448,6 +445,7 @@ void Actor::startWalkAnim(int cmd, int angle) { args[2] = angle; _vm->runScript(_walkScript, 1, 0, args); } else { + switch (cmd) { case 1: /* start walk */ setDirection(angle); @@ -564,7 +562,9 @@ void Actor_v2::walkActor() { } if( _vm->_game.version == 0 ) - ((ActorC64*)this)->setCmdFromDirection( newDirToOldDir(new_dir) ); + if( _moving == 0 ) + ((ActorC64*)this)->setCmdFromDirection( newDirToOldDir(new_dir) ); + return; } @@ -573,8 +573,10 @@ void Actor_v2::walkActor() { if (_moving & MF_IN_LEG) { actorWalkStep(); + if( _vm->_game.version == 0 ) ((ActorC64*) this)->animateActor( newDirToOldDir( _facing ) ); + } else { if (_moving & MF_LAST_LEG) { _moving = 0; @@ -884,13 +886,9 @@ void Actor::setDirection(int direction) { } void ActorC64::setDirection(int cmd) { + + setCmdFromDirection( newDirToOldDir( cmd ) ); - // Normalize the angle - _facing = normalizeAngle( cmd ); - - // If there is no costume set for this actor, we are finished - if (_costume == 0) - return; } // based on 0x2BCA, doesn't match disassembly because 'oldDir' variable @@ -916,8 +914,7 @@ int ActorC64::setCmdFromDirection(int direction) { break; } - - _AnimFrameRepeat = -1; + _animFrameRepeat = -1; animateActor(res); animateCostume(); @@ -951,6 +948,9 @@ void Actor::turnToDirection(int newdir) { _targetFacing = newdir; } } + + if (_vm->_game.version == 0) + ((ActorC64*)this)->setCmdFromDirection( newDirToOldDir(newdir) ); } @@ -999,6 +999,7 @@ void Actor::putActor(int dstX, int dstY, int newRoom) { } adjustActorPos(); + } else { #ifdef ENABLE_HE if (_vm->_game.heversion >= 71) @@ -1010,6 +1011,9 @@ void Actor::putActor(int dstX, int dstY, int newRoom) { if (isInCurrentRoom()) showActor(); } + + if( _vm->_game.version == 0 && _costume != 0x13 ) + turnToDirection( oldDirToNewDir(2)); } static bool inBoxQuickReject(const BoxCoords &box, int x, int y, int threshold) { @@ -1261,8 +1265,6 @@ void Actor::adjustActorPos() { if (flags & 7) { turnToDirection(_facing); } - if (_vm->_game.version == 0) - ((ActorC64*)this)->setCmdFromDirection( newDirToOldDir(_facing) ); } } @@ -1335,20 +1337,26 @@ void Actor::showActor() { _vm->ensureResourceLoaded(rtCostume, _costume); if (_vm->_game.version == 0) { + ActorC64 *a = ((ActorC64*) this); a->_costCommand = a->_costCommandNew = 0xFF; for( int i = 0; i < 8; ++i ) { + a->_limbFrameRepeat[i] = 0; a->_limbFrameRepeatNew[i] = 0; - } + _cost.reset(); + // 0x39DF - a->_AnimFrameRepeat = 1; + a->_animFrameRepeat = 1; + a->_speaking = 0; - _cost.reset(); - a->setCmdFromDirection( newDirToOldDir(_facing) ); + if( a->_costume != 0x13 ) + startAnimActor(_standFrame); + _visible = true; + return; } else if (_vm->_game.version <= 2) { _cost.reset(); @@ -1974,8 +1982,6 @@ void ActorC64::animateCostume() { _cost.soundPos = (_cost.soundPos + 1) % 3; } - _vm->_costumeLoader->loadCostume(_costume); - speakCheck(); for( _limb_current = 0; _limb_current < 8; ++_limb_current ) { @@ -1998,7 +2004,7 @@ void ActorC64::speakCheck() { else cmd += 0x10; - _AnimFrameRepeat = -1; + _animFrameRepeat = -1; animateActor( cmd ); } @@ -2788,18 +2794,22 @@ void ActorC64::animateActor(int anim) { int dir = -1; switch( anim ) { + case 0x00: case 0x04: dir = 0; break; + case 0x01: case 0x05: dir = 1; break; + case 0x02: case 0x06: dir = 2; break; + case 0x03: case 0x07: dir = 3; break; @@ -2816,12 +2826,12 @@ void ActorC64::animateActor(int anim) { if( dir == -1 ) return; - setDirection( oldDirToNewDir(dir) ); + _facing = normalizeAngle( oldDirToNewDir(dir) ); } else { if( anim > 4 && anim <= 7 ) - setDirection( oldDirToNewDir(dir) ); + _facing = normalizeAngle( oldDirToNewDir(dir) ); } } @@ -2830,11 +2840,12 @@ void ActorC64::saveLoadWithSerializer(Serializer *ser) { static const SaveLoadEntry actorEntries[] = { MKLINE(ActorC64, _costCommand, sleByte, VER(84)), - MKLINE(ActorC64, _costFrame, sleByte, VER(84)), + MKLINE_OLD(ActorC64, _costFrame, sleByte, VER(84), VER(89)), MKLINE(ActorC64, _miscflags, sleByte, VER(84)), MKLINE(ActorC64, _speaking, sleByte, VER(84)), - MKLINE(ActorC64, _AnimFrameRepeat, sleByte, VER(89)), + MKLINE(ActorC64, _animFrameRepeat, sleByte, VER(89)), MKARRAY(ActorC64, _limbFrameRepeatNew[0], sleInt8, 8, VER(89)), + MKARRAY(ActorC64, _limbFrameRepeat[0], sleInt8, 8, VER(89)), MKEND() }; diff --git a/engines/scumm/actor.h b/engines/scumm/actor.h index 35ff657fa7..a93b75c6e7 100644 --- a/engines/scumm/actor.h +++ b/engines/scumm/actor.h @@ -352,7 +352,7 @@ public: byte _miscflags; byte _speaking; - int8 _AnimFrameRepeat; + int8 _animFrameRepeat; int8 _limbFrameRepeatNew[8], _limbFrameRepeat[8]; byte _limb_current; @@ -361,10 +361,9 @@ public: public: ActorC64(ScummEngine *scumm, int id) : Actor_v2(scumm, id) { _costCommand = 0xFF; - _costFrame = 0; _speaking = 0; - _AnimFrameRepeat = 0; - _costCommandNew = 0; + _animFrameRepeat = 0; + _costCommandNew = 0xFF; for( int i = 0; i < 8; ++i ) { _limbFrameRepeatNew[i] = 0; diff --git a/engines/scumm/costume.cpp b/engines/scumm/costume.cpp index c7285ead56..cfb1e8690f 100644 --- a/engines/scumm/costume.cpp +++ b/engines/scumm/costume.cpp @@ -1288,6 +1288,9 @@ void C64CostumeLoader::loadCostume(int id) { void C64CostumeLoader::costumeDecodeData(Actor *a, int frame, uint usemask) { ActorC64 *A = (ActorC64 *)a; + if( !a->_costume ) + return; + loadCostume(a->_costume); if( A->_costCommandNew == 0xFF || (A->_costCommand == A->_costCommandNew) ) @@ -1330,14 +1333,14 @@ void C64CostumeLoader::costumeDecodeData(Actor *a, int frame, uint usemask) { } // 0x2679 - A->_limbFrameRepeatNew[limb] = A->_AnimFrameRepeat; + A->_limbFrameRepeatNew[limb] = A->_animFrameRepeat; } } byte C64CostumeLoader::increaseAnims(Actor *a) { ActorC64 *A = (ActorC64 *)a; - if( _frameOffsets == 0 ) + if( _frameOffsets == 0 || (a->_cost.active[A->_limb_current] == 0xFFFF) ) return 0; uint16 limbPrevious = a->_cost.curpos[A->_limb_current]++; diff --git a/engines/scumm/script_v0.cpp b/engines/scumm/script_v0.cpp index 0bdefd660b..054d861db4 100644 --- a/engines/scumm/script_v0.cpp +++ b/engines/scumm/script_v0.cpp @@ -674,13 +674,11 @@ void ScummEngine_v0::o_lights() { void ScummEngine_v0::o_animateActor() { int act = getVarOrDirectByte(PARAM_1); int anim = getVarOrDirectByte(PARAM_2); - int8 animFrameRepeat = (int8) fetchScriptByte(); - - debug(0,"o_animateActor: animFrameRepeat %d", animFrameRepeat); + int8 repeat = (int8) fetchScriptByte(); ActorC64 *a = (ActorC64*) derefActor(act, "o_animateActor"); - a->_AnimFrameRepeat = animFrameRepeat; + a->_animFrameRepeat = repeat; switch( anim ) { -- cgit v1.2.3 From 5b4b606a5879ddcbeb43d3c846bdf40f2d864bed Mon Sep 17 00:00:00 2001 From: Robert Crossfield Date: Thu, 26 Jan 2012 18:38:38 +1100 Subject: SCUMM: Remove the setCmdFromDirection function --- engines/scumm/actor.cpp | 21 ++++++--------------- engines/scumm/actor.h | 1 - 2 files changed, 6 insertions(+), 16 deletions(-) (limited to 'engines/scumm') diff --git a/engines/scumm/actor.cpp b/engines/scumm/actor.cpp index 89e4133ade..f5c17078da 100644 --- a/engines/scumm/actor.cpp +++ b/engines/scumm/actor.cpp @@ -563,7 +563,7 @@ void Actor_v2::walkActor() { if( _vm->_game.version == 0 ) if( _moving == 0 ) - ((ActorC64*)this)->setCmdFromDirection( newDirToOldDir(new_dir) ); + setDirection( new_dir ); return; } @@ -885,18 +885,11 @@ void Actor::setDirection(int direction) { _needRedraw = true; } -void ActorC64::setDirection(int cmd) { - - setCmdFromDirection( newDirToOldDir( cmd ) ); - -} - -// based on 0x2BCA, doesn't match disassembly because 'oldDir' variable -// is not the same value as stored in the original interpreter -int ActorC64::setCmdFromDirection(int direction) { +void ActorC64::setDirection(int direction) { + int dir = newDirToOldDir( direction ); int res = 0; - switch (direction) { + switch (dir) { case 0: res = 4; // Left break; @@ -917,8 +910,6 @@ int ActorC64::setCmdFromDirection(int direction) { _animFrameRepeat = -1; animateActor(res); animateCostume(); - - return res; } void Actor::faceToObject(int obj) { @@ -950,7 +941,7 @@ void Actor::turnToDirection(int newdir) { } if (_vm->_game.version == 0) - ((ActorC64*)this)->setCmdFromDirection( newDirToOldDir(newdir) ); + setDirection( newdir ); } @@ -1885,7 +1876,7 @@ void ActorC64::startAnimActor(int f) { } if( f == _standFrame ) - setCmdFromDirection( newDirToOldDir(_facing) ); + setDirection( _facing ); else animateActor( newDirToOldDir(_facing) ); } diff --git a/engines/scumm/actor.h b/engines/scumm/actor.h index a93b75c6e7..d3271f4eaa 100644 --- a/engines/scumm/actor.h +++ b/engines/scumm/actor.h @@ -386,7 +386,6 @@ public: void speakCheck(); virtual void setDirection(int direction); - int setCmdFromDirection(int direction); void startAnimActor(int f); // Used by the save/load system: -- cgit v1.2.3 From cf292001d35b56b4e4741d7519019c57b30d22dd Mon Sep 17 00:00:00 2001 From: Robert Crossfield Date: Thu, 26 Jan 2012 21:37:04 +1100 Subject: SCUMM: Animations fix again, no need for the hack now --- engines/scumm/actor.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'engines/scumm') diff --git a/engines/scumm/actor.cpp b/engines/scumm/actor.cpp index f5c17078da..47b2582242 100644 --- a/engines/scumm/actor.cpp +++ b/engines/scumm/actor.cpp @@ -909,7 +909,8 @@ void ActorC64::setDirection(int direction) { _animFrameRepeat = -1; animateActor(res); - animateCostume(); + if(_moving) + animateCostume(); } void Actor::faceToObject(int obj) { @@ -1344,8 +1345,7 @@ void Actor::showActor() { a->_animFrameRepeat = 1; a->_speaking = 0; - if( a->_costume != 0x13 ) - startAnimActor(_standFrame); + startAnimActor(_standFrame); _visible = true; return; -- cgit v1.2.3 From f99dab78e401608e45da672355ecac468f8e5e1d Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Thu, 26 Jan 2012 18:42:35 +0100 Subject: SCUMM: fix for old savegames --- engines/scumm/actor.cpp | 8 +++++--- engines/scumm/saveload.h | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) (limited to 'engines/scumm') diff --git a/engines/scumm/actor.cpp b/engines/scumm/actor.cpp index 47b2582242..ed517524ff 100644 --- a/engines/scumm/actor.cpp +++ b/engines/scumm/actor.cpp @@ -2834,9 +2834,11 @@ void ActorC64::saveLoadWithSerializer(Serializer *ser) { MKLINE_OLD(ActorC64, _costFrame, sleByte, VER(84), VER(89)), MKLINE(ActorC64, _miscflags, sleByte, VER(84)), MKLINE(ActorC64, _speaking, sleByte, VER(84)), - MKLINE(ActorC64, _animFrameRepeat, sleByte, VER(89)), - MKARRAY(ActorC64, _limbFrameRepeatNew[0], sleInt8, 8, VER(89)), - MKARRAY(ActorC64, _limbFrameRepeat[0], sleInt8, 8, VER(89)), + MK_OBSOLETE(ActorC64, _speakingPrev, sleByte, VER(84), VER(89)), + MK_OBSOLETE(ActorC64, _byte_FD0A, sleByte, VER(89), VER(89)), + MKLINE(ActorC64, _animFrameRepeat, sleByte, VER(89)), + MKARRAY(ActorC64, _limbFrameRepeatNew[0], sleInt8, 8, VER(89)), + MKARRAY(ActorC64, _limbFrameRepeat[0], sleInt8, 8, VER(90)), MKEND() }; diff --git a/engines/scumm/saveload.h b/engines/scumm/saveload.h index 898f80f867..931b56f137 100644 --- a/engines/scumm/saveload.h +++ b/engines/scumm/saveload.h @@ -47,7 +47,7 @@ namespace Scumm { * only saves/loads those which are valid for the version of the savegame * which is being loaded/saved currently. */ -#define CURRENT_VER 89 +#define CURRENT_VER 90 /** * An auxillary macro, used to specify savegame versions. We use this instead -- cgit v1.2.3 From ddd65dfc22333eefccf3a875fcd33c4597426089 Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Thu, 26 Jan 2012 22:39:34 +0100 Subject: SCUMM: fix actor climbing on plant or swimming pool ladder Before, the actor will descend the ladder of the pool and maybe even into the the pool. Another issue fixed by this is the actor climbing onto the plant pot if you give something to it. --- engines/scumm/actor.cpp | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) (limited to 'engines/scumm') diff --git a/engines/scumm/actor.cpp b/engines/scumm/actor.cpp index ed517524ff..19cd0ae2eb 100644 --- a/engines/scumm/actor.cpp +++ b/engines/scumm/actor.cpp @@ -1105,16 +1105,11 @@ static int checkXYInBoxBounds(int boxnum, int x, int y, int &destX, int &destY) // yDist must be divided by 4, as we are using 8x2 pixels // blocks for actor coordinates). int xDist = ABS(x - destX); - int yDist; + int yDist = ABS(y - destY) / 4; int dist; - // MM C64: This fixes the trunk bug (#3070065), as well - // as the fruit bowl, however im not sure if its - // the proper solution or not. - if( g_scumm->_game.version == 0 ) - yDist = ABS(y - destY); - else - yDist = ABS(y - destY) / 4; + if(g_scumm->_game.version == 0) + xDist *= 2; if (xDist < yDist) dist = (xDist >> 1) + yDist; @@ -1133,7 +1128,9 @@ AdjustBoxResult Actor_v2::adjustXYToBeInBox(const int dstX, const int dstY) { int numBoxes = _vm->getNumBoxes() - 1; int bestDist = 0xFF; - for (int box = numBoxes; box >= 0; box--) { + for (int i = 0; i <= numBoxes; i++) { + // MM v0 prioritizes lower boxes, other engines higher boxes + int box = (_vm->_game.version == 0 ? i : numBoxes - i); int foundX, foundY; int flags = _vm->getBoxFlags(box); if ((flags & kBoxInvisible) && !((flags & kBoxPlayerOnly) && !isPlayer())) @@ -1143,7 +1140,6 @@ AdjustBoxResult Actor_v2::adjustXYToBeInBox(const int dstX, const int dstY) { abr.x = foundX; abr.y = foundY; abr.box = box; - break; } if (dist < bestDist) { -- cgit v1.2.3 From 1e8d0664ac704160c3353d998a3b9978245128bd Mon Sep 17 00:00:00 2001 From: Robert Crossfield Date: Fri, 27 Jan 2012 22:05:10 +1100 Subject: SCUMM: Fix Tentacle issue, and possibly some other animation issues --- engines/scumm/actor.cpp | 52 ++++++++++++++++++++++++--------------------- engines/scumm/costume.cpp | 29 +++++++++++++------------ engines/scumm/costume.h | 3 ++- engines/scumm/script_v0.cpp | 1 + 4 files changed, 46 insertions(+), 39 deletions(-) (limited to 'engines/scumm') diff --git a/engines/scumm/actor.cpp b/engines/scumm/actor.cpp index 19cd0ae2eb..c22fc8a438 100644 --- a/engines/scumm/actor.cpp +++ b/engines/scumm/actor.cpp @@ -396,9 +396,14 @@ void Actor::startWalkActor(int destX, int destY, int dir) { } if (_vm->_game.version <= 2) { + abr = adjustXYToBeInBox(abr.x, abr.y); if (_pos.x == abr.x && _pos.y == abr.y && (dir == -1 || _facing == dir)) return; + + if( _vm->_game.version == 0 ) + ((ActorC64*) this)->animateActor( newDirToOldDir( _facing ) ); + } else { if (_ignoreBoxes) { abr.box = kInvalidBox; @@ -554,17 +559,12 @@ void Actor_v2::walkActor() { if (_facing != new_dir) { - if( _vm->_game.version != 0 ) - setDirection(new_dir); + setDirection(new_dir); } else { _moving = 0; } - if( _vm->_game.version == 0 ) - if( _moving == 0 ) - setDirection( new_dir ); - return; } @@ -909,7 +909,7 @@ void ActorC64::setDirection(int direction) { _animFrameRepeat = -1; animateActor(res); - if(_moving) + if(_moving & MF_TURN) animateCostume(); } @@ -936,13 +936,12 @@ void Actor::turnToDirection(int newdir) { } else { _moving &= ~MF_TURN; if (newdir != _facing) { + _moving |= MF_TURN; _targetFacing = newdir; } } - if (_vm->_game.version == 0) - setDirection( newdir ); } @@ -1004,8 +1003,10 @@ void Actor::putActor(int dstX, int dstY, int newRoom) { showActor(); } - if( _vm->_game.version == 0 && _costume != 0x13 ) - turnToDirection( oldDirToNewDir(2)); + if( _vm->_game.version == 0 ) { + _moving = 0; + setDirection( oldDirToNewDir(2)); + } } static bool inBoxQuickReject(const BoxCoords &box, int x, int y, int threshold) { @@ -1874,7 +1875,7 @@ void ActorC64::startAnimActor(int f) { if( f == _standFrame ) setDirection( _facing ); else - animateActor( newDirToOldDir(_facing) ); + animateActor( newDirToOldDir(_targetFacing) ); } void Actor::animateActor(int anim) { @@ -1950,24 +1951,16 @@ void ActorC64::limbFrameCheck() { _limbFrameRepeat[_limb_current] = _limbFrameRepeatNew[_limb_current]; - _cost.active[_limb_current] = _cost.frame[_limb_current]; + _vm->_costumeLoader->loadCostume(_costume); + + // 0x25C3 + _cost.active[_limb_current] = ((C64CostumeLoader*)_vm->_costumeLoader)->getFrame( this ); _cost.curpos[_limb_current] = 0; _needRedraw = true; } void ActorC64::animateCostume() { - - // Sound - if (_moving && _vm->_currentRoom != 1 && _vm->_currentRoom != 44) { - if (_cost.soundPos == 0) - _cost.soundCounter++; - - // Is this the correct location? - // 0x073C - if (v0ActorTalkArray[_number] & 0x3F) - _cost.soundPos = (_cost.soundPos + 1) % 3; - } speakCheck(); @@ -2780,6 +2773,17 @@ void ScummEngine_v71he::queueAuxEntry(int actorNum, int subIndex) { void ActorC64::animateActor(int anim) { int dir = -1; + // Sound + if (_moving && _vm->_currentRoom != 1 && _vm->_currentRoom != 44) { + if (_cost.soundPos == 0) + _cost.soundCounter++; + + // Is this the correct location? + // 0x073C + if (v0ActorTalkArray[_number] & 0x3F) + _cost.soundPos = (_cost.soundPos + 1) % 3; + } + switch( anim ) { case 0x00: case 0x04: diff --git a/engines/scumm/costume.cpp b/engines/scumm/costume.cpp index cfb1e8690f..0ae0aca147 100644 --- a/engines/scumm/costume.cpp +++ b/engines/scumm/costume.cpp @@ -1184,20 +1184,17 @@ byte C64CostumeRenderer::drawLimb(const Actor *a, int limb) { if (limb >= 8) return 0; - if (a->_cost.curpos[limb] == 0xFFFF || A->_cost.active[limb] == 0xFFFF ) - return 0; - if (limb == 0) { _draw_top = 200; _draw_bottom = 0; } - - byte frameB = _loaded._frameOffsets[limb] + a->_cost.active[limb]; - byte frameStart = _loaded._frameOffsets[ frameB ]; - byte frame = _loaded._frameOffsets[frameStart + a->_cost.curpos[limb]]; - if (frame == 0xFF) + + if( a->_cost.curpos[limb] == 0xFFFF ) return 0; + _loaded.loadCostume( a->_costume ); + byte frame = _loaded._frameOffsets[ a->_cost.curpos[limb] + a->_cost.active[limb] ]; + byte ptrLow = _loaded._baseptr[frame]; byte ptrHigh = ptrLow + _loaded._dataOffsets[4]; int frameOffset = (_loaded._baseptr[ptrHigh] << 8) + _loaded._baseptr[ptrLow + 2]; // 0x23EF / 0x2400 @@ -1337,19 +1334,23 @@ void C64CostumeLoader::costumeDecodeData(Actor *a, int frame, uint usemask) { } } +byte C64CostumeLoader::getFrame( ActorC64 *A ) { + + loadCostume(A->_costume); + + return _frameOffsets[ _frameOffsets[A->_limb_current] + A->_cost.start[ A->_limb_current ] ]; +} + byte C64CostumeLoader::increaseAnims(Actor *a) { ActorC64 *A = (ActorC64 *)a; - if( _frameOffsets == 0 || (a->_cost.active[A->_limb_current] == 0xFFFF) ) - return 0; - uint16 limbPrevious = a->_cost.curpos[A->_limb_current]++; + loadCostume(a->_costume); + // increase each frame pos // 0x2543 - byte frameB = _frameOffsets[A->_limb_current] + a->_cost.active[A->_limb_current]; - byte frameStart = _frameOffsets[ frameB ]; - byte frame = _frameOffsets[frameStart + a->_cost.curpos[A->_limb_current]]; + byte frame = _frameOffsets[ a->_cost.curpos[A->_limb_current] + a->_cost.active[A->_limb_current] ]; if ( frame == 0xFF ) { // 0x2545 diff --git a/engines/scumm/costume.h b/engines/scumm/costume.h index 50e3f1e1b2..38e21d586f 100644 --- a/engines/scumm/costume.h +++ b/engines/scumm/costume.h @@ -73,11 +73,12 @@ public: void loadCostume(int id); void costumeDecodeData(Actor *a, int frame, uint usemask); byte increaseAnims(Actor *a); + + byte getFrame( ActorC64 *A ); int _maxHeight; protected: - int dirToDirStop(int oldDir); }; diff --git a/engines/scumm/script_v0.cpp b/engines/scumm/script_v0.cpp index 054d861db4..cf2b7d9a8f 100644 --- a/engines/scumm/script_v0.cpp +++ b/engines/scumm/script_v0.cpp @@ -698,6 +698,7 @@ void ScummEngine_v0::o_animateActor() { } a->animateActor(anim); + a->animateCostume(); } void ScummEngine_v0::o_getActorMoving() { -- cgit v1.2.3 From f299fc295e620a71d5fbb783b549b10807c97b99 Mon Sep 17 00:00:00 2001 From: Robert Crossfield Date: Sat, 28 Jan 2012 00:02:05 +1100 Subject: SCUMM: Fix for V0 objects --- engines/scumm/script.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'engines/scumm') diff --git a/engines/scumm/script.cpp b/engines/scumm/script.cpp index b51452170a..1d2581f915 100644 --- a/engines/scumm/script.cpp +++ b/engines/scumm/script.cpp @@ -1000,7 +1000,7 @@ void ScummEngine::killScriptsAndResources() { for (i = 0; i < _numNewNames; i++) { const int obj = _newNames[i]; if (obj) { - const int owner = getOwner(obj); + const int owner = getOwner( (_game.version != 0 ? obj : OBJECT_V0_ID(obj) ) ); // We can delete custom name resources if either the object is // no longer in use (i.e. not owned by anyone anymore); or if // it is an object which is owned by a room. -- cgit v1.2.3 From 5accf01881424e10e1700bf36c4b8236ed200258 Mon Sep 17 00:00:00 2001 From: Robert Crossfield Date: Sat, 28 Jan 2012 00:25:30 +1100 Subject: SCUMM: Remove unnecessary calls to animateActor --- engines/scumm/actor.cpp | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) (limited to 'engines/scumm') diff --git a/engines/scumm/actor.cpp b/engines/scumm/actor.cpp index c22fc8a438..95b7f90318 100644 --- a/engines/scumm/actor.cpp +++ b/engines/scumm/actor.cpp @@ -401,9 +401,6 @@ void Actor::startWalkActor(int destX, int destY, int dir) { if (_pos.x == abr.x && _pos.y == abr.y && (dir == -1 || _facing == dir)) return; - if( _vm->_game.version == 0 ) - ((ActorC64*) this)->animateActor( newDirToOldDir( _facing ) ); - } else { if (_ignoreBoxes) { abr.box = kInvalidBox; @@ -909,7 +906,7 @@ void ActorC64::setDirection(int direction) { _animFrameRepeat = -1; animateActor(res); - if(_moving & MF_TURN) + if(_moving) animateCostume(); } @@ -1002,11 +999,6 @@ void Actor::putActor(int dstX, int dstY, int newRoom) { if (isInCurrentRoom()) showActor(); } - - if( _vm->_game.version == 0 ) { - _moving = 0; - setDirection( oldDirToNewDir(2)); - } } static bool inBoxQuickReject(const BoxCoords &box, int x, int y, int threshold) { -- cgit v1.2.3 From fb3e431ec63cbdd2edc7e289b0910cfe4aa72510 Mon Sep 17 00:00:00 2001 From: Robert Crossfield Date: Sat, 28 Jan 2012 00:38:19 +1100 Subject: SCUMM: V0 always turns actor towards camera when entering room, remove unnecessary loadcostume --- engines/scumm/actor.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'engines/scumm') diff --git a/engines/scumm/actor.cpp b/engines/scumm/actor.cpp index 95b7f90318..e95b3555eb 100644 --- a/engines/scumm/actor.cpp +++ b/engines/scumm/actor.cpp @@ -999,6 +999,10 @@ void Actor::putActor(int dstX, int dstY, int newRoom) { if (isInCurrentRoom()) showActor(); } + + // V0 always sets the actor to face the camera upon entering a room + if( _vm->_game.version == 0 ) + setDirection( oldDirToNewDir(2)); } static bool inBoxQuickReject(const BoxCoords &box, int x, int y, int threshold) { @@ -1943,8 +1947,6 @@ void ActorC64::limbFrameCheck() { _limbFrameRepeat[_limb_current] = _limbFrameRepeatNew[_limb_current]; - _vm->_costumeLoader->loadCostume(_costume); - // 0x25C3 _cost.active[_limb_current] = ((C64CostumeLoader*)_vm->_costumeLoader)->getFrame( this ); _cost.curpos[_limb_current] = 0; -- cgit v1.2.3 From 1ca0b84b018657d3980b167cc2d8b56d94b4f26a Mon Sep 17 00:00:00 2001 From: Robert Crossfield Date: Sat, 28 Jan 2012 00:48:49 +1100 Subject: SCUMM: Improve comments --- engines/scumm/costume.cpp | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) (limited to 'engines/scumm') diff --git a/engines/scumm/costume.cpp b/engines/scumm/costume.cpp index 0ae0aca147..3bb62c2de5 100644 --- a/engines/scumm/costume.cpp +++ b/engines/scumm/costume.cpp @@ -1189,12 +1189,14 @@ byte C64CostumeRenderer::drawLimb(const Actor *a, int limb) { _draw_bottom = 0; } + // Invalid current position? if( a->_cost.curpos[limb] == 0xFFFF ) return 0; _loaded.loadCostume( a->_costume ); byte frame = _loaded._frameOffsets[ a->_cost.curpos[limb] + a->_cost.active[limb] ]; + // Get the frame ptr byte ptrLow = _loaded._baseptr[frame]; byte ptrHigh = ptrLow + _loaded._dataOffsets[4]; int frameOffset = (_loaded._baseptr[ptrHigh] << 8) + _loaded._baseptr[ptrLow + 2]; // 0x23EF / 0x2400 @@ -1285,11 +1287,9 @@ void C64CostumeLoader::loadCostume(int id) { void C64CostumeLoader::costumeDecodeData(Actor *a, int frame, uint usemask) { ActorC64 *A = (ActorC64 *)a; - if( !a->_costume ) - return; - loadCostume(a->_costume); + // Invalid costume command? if( A->_costCommandNew == 0xFF || (A->_costCommand == A->_costCommandNew) ) return; @@ -1306,13 +1306,14 @@ void C64CostumeLoader::costumeDecodeData(Actor *a, int frame, uint usemask) { // get the frame number for the beginning of the costume command limbFrameNumber = ((_animCmds + cmd)[limb]); + // Is this limb flipped? if( limbFrameNumber & 0x80 ) { - // 0x263D + // Invalid frame? if( limbFrameNumber == 0xFF ) continue; - // 0x2643 + // Store the limb frame number (clear the flipped status) a->_cost.frame[limb] = (limbFrameNumber & 0x7f); // limb animation-frames ptr if( A->_limb_flipped[limb] != true ) a->_cost.start[limb] = 0xFFFF; @@ -1320,7 +1321,7 @@ void C64CostumeLoader::costumeDecodeData(Actor *a, int frame, uint usemask) { A->_limb_flipped[limb] = true; } else { - //0x2660 + //Store the limb frame number a->_cost.frame[limb] = limbFrameNumber; if( A->_limb_flipped[limb] != false ) @@ -1329,7 +1330,7 @@ void C64CostumeLoader::costumeDecodeData(Actor *a, int frame, uint usemask) { A->_limb_flipped[limb] = false; } - // 0x2679 + // Set the repeat value A->_limbFrameRepeatNew[limb] = A->_animFrameRepeat; } } @@ -1338,6 +1339,7 @@ byte C64CostumeLoader::getFrame( ActorC64 *A ) { loadCostume(A->_costume); + // Get the frame number for the current limb / Command return _frameOffsets[ _frameOffsets[A->_limb_current] + A->_cost.start[ A->_limb_current ] ]; } @@ -1348,32 +1350,38 @@ byte C64CostumeLoader::increaseAnims(Actor *a) { loadCostume(a->_costume); - // increase each frame pos // 0x2543 byte frame = _frameOffsets[ a->_cost.curpos[A->_limb_current] + a->_cost.active[A->_limb_current] ]; + // Is this frame invalid? if ( frame == 0xFF ) { - // 0x2545 + + // Repeat timer has reached 0? if( A->_limbFrameRepeat[A->_limb_current] == 0 ) { - // 0x2556 + // Use the previous frame --A->_cost.curpos[A->_limb_current]; + // Reset the comstume command A->_costCommandNew = 0xFF; A->_costCommand = 0xFF; - // 0x2568 + // Set the frame/start to invalid A->_cost.frame[A->_limb_current] = 0xFFFF; A->_cost.start[A->_limb_current] = 0xFFFF; } else { + + // Repeat timer enabled? if( A->_limbFrameRepeat[A->_limb_current] != -1 ) --A->_limbFrameRepeat[A->_limb_current]; + // No, restart at frame 0 a->_cost.curpos[A->_limb_current] = 0; } } + // Limb frame has changed? if( limbPrevious == a->_cost.curpos[A->_limb_current] ) return 0; -- cgit v1.2.3 From 9ba01d020b8a48bed57977a430c532a3237dedd0 Mon Sep 17 00:00:00 2001 From: Robert Crossfield Date: Sat, 28 Jan 2012 01:25:13 +1100 Subject: SCUMM: Fix V0 Sound, and a direction issue (affected walking down the ladder) --- engines/scumm/actor.cpp | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) (limited to 'engines/scumm') diff --git a/engines/scumm/actor.cpp b/engines/scumm/actor.cpp index e95b3555eb..0191439612 100644 --- a/engines/scumm/actor.cpp +++ b/engines/scumm/actor.cpp @@ -1557,8 +1557,18 @@ void ScummEngine::processActors() { // 0x22B5 if (A->_miscflags & kActorMiscFlagHide) continue; - } + // Sound + if (A->_moving && _currentRoom != 1 && _currentRoom != 44) { + if (A->_cost.soundPos == 0) + A->_cost.soundCounter++; + + // Is this the correct location? + // 0x073C + if (v0ActorTalkArray[A->_number] & 0x3F) + A->_cost.soundPos = (A->_cost.soundPos + 1) % 3; + } + } // Draw and animate the actors, except those w/o a costume. // Note: We could 'optimize' this a little bit by only putting // actors with a costume into the _sortedActors array in the @@ -1871,7 +1881,7 @@ void ActorC64::startAnimActor(int f) { if( f == _standFrame ) setDirection( _facing ); else - animateActor( newDirToOldDir(_targetFacing) ); + animateActor( newDirToOldDir(_facing) ); } void Actor::animateActor(int anim) { @@ -2766,17 +2776,6 @@ void ScummEngine_v71he::queueAuxEntry(int actorNum, int subIndex) { void ActorC64::animateActor(int anim) { int dir = -1; - - // Sound - if (_moving && _vm->_currentRoom != 1 && _vm->_currentRoom != 44) { - if (_cost.soundPos == 0) - _cost.soundCounter++; - - // Is this the correct location? - // 0x073C - if (v0ActorTalkArray[_number] & 0x3F) - _cost.soundPos = (_cost.soundPos + 1) % 3; - } switch( anim ) { case 0x00: -- cgit v1.2.3 From c6688cf0d516543a051841116d5175ca8bcee39f Mon Sep 17 00:00:00 2001 From: Robert Crossfield Date: Sat, 28 Jan 2012 09:38:54 +1100 Subject: SCUMM: Remove unused variable, remove old comment --- engines/scumm/costume.cpp | 5 ++--- engines/scumm/costume.h | 2 -- 2 files changed, 2 insertions(+), 5 deletions(-) (limited to 'engines/scumm') diff --git a/engines/scumm/costume.cpp b/engines/scumm/costume.cpp index 3bb62c2de5..e3a2203adc 100644 --- a/engines/scumm/costume.cpp +++ b/engines/scumm/costume.cpp @@ -1280,8 +1280,6 @@ void C64CostumeLoader::loadCostume(int id) { _frameOffsets = _baseptr + READ_LE_UINT16(ptr + 5); _dataOffsets = ptr; _animCmds = _baseptr + READ_LE_UINT16(ptr + 7); - - _maxHeight = 0; } void C64CostumeLoader::costumeDecodeData(Actor *a, int frame, uint usemask) { @@ -1314,7 +1312,8 @@ void C64CostumeLoader::costumeDecodeData(Actor *a, int frame, uint usemask) { continue; // Store the limb frame number (clear the flipped status) - a->_cost.frame[limb] = (limbFrameNumber & 0x7f); // limb animation-frames ptr + a->_cost.frame[limb] = (limbFrameNumber & 0x7f); + if( A->_limb_flipped[limb] != true ) a->_cost.start[limb] = 0xFFFF; diff --git a/engines/scumm/costume.h b/engines/scumm/costume.h index 38e21d586f..4600cc5670 100644 --- a/engines/scumm/costume.h +++ b/engines/scumm/costume.h @@ -76,8 +76,6 @@ public: byte getFrame( ActorC64 *A ); - int _maxHeight; - protected: }; -- cgit v1.2.3 From 08e1e127e9a03b10b83b790458bdfff5130aa510 Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Sat, 28 Jan 2012 21:15:05 +0100 Subject: SCUMM: handle v0 distance check in checkPendingWalkAction() correctly --- engines/scumm/script.cpp | 50 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 34 insertions(+), 16 deletions(-) (limited to 'engines/scumm') diff --git a/engines/scumm/script.cpp b/engines/scumm/script.cpp index 1d2581f915..63f04c1f32 100644 --- a/engines/scumm/script.cpp +++ b/engines/scumm/script.cpp @@ -1162,7 +1162,7 @@ bool ScummEngine_v0::checkPendingWalkAction() { return false; int actor = VAR(VAR_EGO); - ActorC64 *a = (ActorC64 *)derefActor(actor, "checkAndRunSentenceScript"); + ActorC64 *a = (ActorC64 *)derefActor(actor, "checkPendingWalkAction"); // wait until walking or turning action is finished if (a->_moving) @@ -1172,23 +1172,41 @@ bool ScummEngine_v0::checkPendingWalkAction() { if (_walkToObjectState == kWalkToObjectStateTurn) { runSentenceScript(); // change actor facing - } else if (getObjActToObjActDist(actorToObj(actor), _walkToObject) <= 4) { - if (objIsActor(_walkToObject)) { // walk to actor finished - // make actors turn to each other - a->faceToObject(_walkToObject); - int otherActor = objToActor(_walkToObject); - // ignore the plant - if (otherActor != 19) { - Actor *b = derefActor(otherActor, "checkAndRunSentenceScript(2)"); - b->faceToObject(actorToObj(actor)); + } else { + int x, y, distX, distY; + if (objIsActor(_walkToObject)) { + Actor *b = derefActor(objToActor(_walkToObject), "checkPendingWalkAction(2)"); + x = b->getRealPos().x; + y = b->getRealPos().y; + if (x < a->getRealPos().x) + x += 4; + else + x -= 4; + } else { + getObjectXYPos(_walkToObject, x, y); + } + AdjustBoxResult abr = a->adjustXYToBeInBox(x, y); + distX = ABS(a->getRealPos().x - abr.x); + distY = ABS(a->getRealPos().y - abr.y); + + if (distX <= 4 && distY <= 8) { + if (objIsActor(_walkToObject)) { // walk to actor finished + // make actors turn to each other + a->faceToObject(_walkToObject); + int otherActor = objToActor(_walkToObject); + // ignore the plant + if (otherActor != 19) { + Actor *b = derefActor(otherActor, "checkPendingWalkAction(3)"); + b->faceToObject(actorToObj(actor)); + } + } else { // walk to object finished + int x, y, dir; + getObjectXYPos(_walkToObject, x, y, dir); + a->turnToDirection(dir); } - } else { // walk to object finished - int x, y, dir; - getObjectXYPos(_walkToObject, x, y, dir); - a->turnToDirection(dir); + _walkToObjectState = kWalkToObjectStateTurn; + return true; } - _walkToObjectState = kWalkToObjectStateTurn; - return true; } _walkToObjectState = kWalkToObjectStateDone; -- cgit v1.2.3 From 7d409dd15f13f517c083e58d0e5c59ec0776c974 Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Sat, 28 Jan 2012 21:32:41 +0100 Subject: SCUMM: in v0 do not allow an inventory item as 2nd object of a give-to command --- engines/scumm/verbs.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'engines/scumm') diff --git a/engines/scumm/verbs.cpp b/engines/scumm/verbs.cpp index 7a099adae9..4347ad9db9 100644 --- a/engines/scumm/verbs.cpp +++ b/engines/scumm/verbs.cpp @@ -809,6 +809,9 @@ void ScummEngine_v0::checkExecVerbs() { // inventory position changed (arrows pressed, do nothing) return; } + // the second object of a give-to command has to be an actor + if (_activeVerb == kVerbGive && _activeObject) + obj = 0; // click region: main screen } else if (zone->number == kMainVirtScreen) { // click into main screen -- cgit v1.2.3 From cc68a598564285b6f303f90304891f0beef7f1e4 Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Sun, 29 Jan 2012 04:42:02 +0100 Subject: SCUMM: fix diagonal walking in at least MM v0 The comparison "ABS((int)(deltaXFactor >> 16)) > _speedx)" does not work as "deltaXFactor >> 16" will clear the fractional part of deltaXFactor. As a result the deltaXFactor might be bigger than (_speedx<<16) and the actor moves faster than he should. --- engines/scumm/actor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'engines/scumm') diff --git a/engines/scumm/actor.cpp b/engines/scumm/actor.cpp index 0191439612..f0ba79b98d 100644 --- a/engines/scumm/actor.cpp +++ b/engines/scumm/actor.cpp @@ -289,7 +289,7 @@ int Actor::calcMovementFactor(const Common::Point& next) { deltaYFactor = 0; } - if ((uint) ABS((int)(deltaXFactor >> 16)) > _speedx) { + if ((uint) ABS(deltaXFactor) > (_speedx << 16)) { deltaXFactor = _speedx << 16; if (diffX < 0) deltaXFactor = -deltaXFactor; -- cgit v1.2.3 From e33d41035cfbdf81c0178730bec1ed3eb36d7ef7 Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Sun, 29 Jan 2012 06:20:16 +0100 Subject: SCUMM: scumm_vars 14 to 16 are not handled specially in v0 Reading the manuscript will be fixed by this. --- engines/scumm/script_v2.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'engines/scumm') diff --git a/engines/scumm/script_v2.cpp b/engines/scumm/script_v2.cpp index 59500deaf5..983bba0914 100644 --- a/engines/scumm/script_v2.cpp +++ b/engines/scumm/script_v2.cpp @@ -412,7 +412,7 @@ void ScummEngine_v2::decodeParseString() { } int ScummEngine_v2::readVar(uint var) { - if (var >= 14 && var <= 16) + if (_game.version >= 1 && var >= 14 && var <= 16) var = _scummVars[var]; assertRange(0, var, _numVariables - 1, "variable (reading)"); -- cgit v1.2.3 From f5faa4554defa2e220f3b0507c8fefb8f13182c6 Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Sun, 29 Jan 2012 06:35:57 +0100 Subject: SCUMM: isPlayer() is not supported by engine v0 --- engines/scumm/actor.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'engines/scumm') diff --git a/engines/scumm/actor.cpp b/engines/scumm/actor.cpp index f0ba79b98d..c2390ab4b0 100644 --- a/engines/scumm/actor.cpp +++ b/engines/scumm/actor.cpp @@ -2620,6 +2620,8 @@ bool Actor::isPlayer() { } bool Actor_v2::isPlayer() { + // isPlayer() is not supported by v0 + assert(_vm->_game.version != 0); return _vm->VAR(42) <= _number && _number <= _vm->VAR(43); } -- cgit v1.2.3 From d4ddd2ca840fc91cd75cdb4545db30f2f0a78722 Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Sun, 29 Jan 2012 17:03:37 +0100 Subject: SCUMM: introduce constants for _userState for cleaner and easier to understand code --- engines/scumm/script_v0.cpp | 20 +++++++++++++++----- engines/scumm/script_v2.cpp | 27 +++++++++++++++------------ engines/scumm/scumm.h | 13 +++++++++++++ engines/scumm/verbs.cpp | 8 ++++---- 4 files changed, 47 insertions(+), 21 deletions(-) (limited to 'engines/scumm') diff --git a/engines/scumm/script_v0.cpp b/engines/scumm/script_v0.cpp index cf2b7d9a8f..46052cdf49 100644 --- a/engines/scumm/script_v0.cpp +++ b/engines/scumm/script_v0.cpp @@ -456,7 +456,7 @@ void ScummEngine_v0::drawSentenceObject(int object) { void ScummEngine_v0::drawSentenceLine() { _redrawSentenceLine = false; - if (!(_userState & 32)) + if (!(_userState & USERSTATE_IFACE_SENTENCE)) return; clearSentenceLine(); @@ -627,22 +627,32 @@ void ScummEngine_v0::o_unlockRoom() { } void ScummEngine_v0::setMode(byte mode) { - int state = 0; + int state; _currentMode = mode; switch (_currentMode) { case kModeCutscene: _redrawSentenceLine = false; - state = 7; + // Note: do not change freeze state here + state = USERSTATE_SET_IFACE | + USERSTATE_SET_CURSOR | + USERSTATE_SET_FREEZE; break; case kModeKeypad: - state = 23; + _redrawSentenceLine = false; + state = USERSTATE_SET_IFACE | + USERSTATE_SET_CURSOR | USERSTATE_CURSOR_ON | + USERSTATE_SET_FREEZE; break; case kModeNormal: case kModeNoNewKid: - state = 247; + state = USERSTATE_SET_IFACE | USERSTATE_IFACE_ALL | + USERSTATE_SET_CURSOR | USERSTATE_CURSOR_ON | + USERSTATE_SET_FREEZE; break; + default: + error("Invalid mode: %d", mode); } setUserState(state); diff --git a/engines/scumm/script_v2.cpp b/engines/scumm/script_v2.cpp index 983bba0914..2b2bad32a7 100644 --- a/engines/scumm/script_v2.cpp +++ b/engines/scumm/script_v2.cpp @@ -993,7 +993,8 @@ void ScummEngine_v2::o2_drawSentence() { const byte *temp; int slot = getVerbSlot(VAR(VAR_SENTENCE_VERB), 0); - if (!((_userState & 32) || (_game.platform == Common::kPlatformNES && _userState & 0xe0))) + if (!((_userState & USERSTATE_IFACE_SENTENCE) || + (_game.platform == Common::kPlatformNES && (_userState & USERSTATE_IFACE_ALL)))) return; if (getResourceAddress(rtVerb, slot)) @@ -1303,7 +1304,7 @@ void ScummEngine_v2::o2_findObject() { int x = getVarOrDirectByte(PARAM_1) * V12_X_MULTIPLIER; int y = getVarOrDirectByte(PARAM_2) * V12_Y_MULTIPLIER; obj = findObject(x, y); - if (obj == 0 && (_game.platform == Common::kPlatformNES) && (_userState & 0x40)) { + if (obj == 0 && (_game.platform == Common::kPlatformNES) && (_userState & USERSTATE_IFACE_INVENTORY)) { if (_mouseOverBoxV2 >= 0 && _mouseOverBoxV2 < 4) obj = findInventory(VAR(VAR_EGO), _mouseOverBoxV2 + _inventoryOffset + 1); } @@ -1485,7 +1486,9 @@ void ScummEngine_v2::o2_cutscene() { VAR(VAR_CURSORSTATE) = 200; // Hide inventory, freeze scripts, hide cursor - setUserState(15); + setUserState(USERSTATE_SET_IFACE | + USERSTATE_SET_CURSOR | + USERSTATE_SET_FREEZE | USERSTATE_FREEZE_ON); _sentenceNum = 0; stopScript(SENTENCE_SCRIPT); @@ -1504,7 +1507,7 @@ void ScummEngine_v2::o2_endCutscene() { VAR(VAR_CURSORSTATE) = vm.cutSceneData[1]; // Reset user state to values before cutscene - setUserState(vm.cutSceneData[0] | 7); + setUserState(vm.cutSceneData[0] | USERSTATE_SET_IFACE | USERSTATE_SET_CURSOR | USERSTATE_SET_FREEZE); if ((_game.id == GID_MANIAC) && !(_game.platform == Common::kPlatformNES)) { camera._mode = (byte) vm.cutSceneData[3]; @@ -1570,24 +1573,24 @@ void ScummEngine_v2::o2_cursorCommand() { // TODO: Define the magic numbers } void ScummEngine_v2::setUserState(byte state) { - if (state & 4) { // Userface + if (state & USERSTATE_SET_IFACE) { // Userface if (_game.platform == Common::kPlatformNES) - _userState = (_userState & ~0xE0) | (state & 0xE0); + _userState = (_userState & ~USERSTATE_IFACE_ALL) | (state & USERSTATE_IFACE_ALL); else - _userState = state & (32 | 64 | 128); + _userState = state & USERSTATE_IFACE_ALL; } - if (state & 1) { // Freeze - if (state & 8) + if (state & USERSTATE_SET_FREEZE) { // Freeze + if (state & USERSTATE_FREEZE_ON) freezeScripts(0); else unfreezeScripts(); } - if (state & 2) { // Cursor Show/Hide + if (state & USERSTATE_SET_CURSOR) { // Cursor Show/Hide if (_game.platform == Common::kPlatformNES) - _userState = (_userState & ~0x10) | (state & 0x10); - if (state & 16) { + _userState = (_userState & ~USERSTATE_CURSOR_ON) | (state & USERSTATE_CURSOR_ON); + if (state & USERSTATE_CURSOR_ON) { _userPut = 1; _cursor.state = 1; } else { diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h index 042a3a5d47..fa04c5b616 100644 --- a/engines/scumm/scumm.h +++ b/engines/scumm/scumm.h @@ -303,6 +303,19 @@ struct SaveStateMetaInfos { uint32 playtime; }; +enum UserStates { + USERSTATE_SET_FREEZE = 0x01, // freeze scripts if USERSTATE_FREEZE_ON is set, unfreeze otherwise + USERSTATE_SET_CURSOR = 0x02, // shows cursor if USERSTATE_CURSOR_ON is set, hides it otherwise + USERSTATE_SET_IFACE = 0x04, // change user-interface (sentence-line, inventory, verb-area) + USERSTATE_FREEZE_ON = 0x08, // only interpreted if USERSTATE_SET_FREEZE is set + USERSTATE_CURSOR_ON = 0x10, // only interpreted if USERSTATE_SET_CURSOR is set + USERSTATE_IFACE_SENTENCE = 0x20, // only interpreted if USERSTATE_SET_IFACE is set + USERSTATE_IFACE_INVENTORY = 0x40, // only interpreted if USERSTATE_SET_IFACE is set + USERSTATE_IFACE_VERBS = 0x80 // only interpreted if USERSTATE_SET_IFACE is set +}; + +#define USERSTATE_IFACE_ALL (USERSTATE_IFACE_SENTENCE | USERSTATE_IFACE_INVENTORY | USERSTATE_IFACE_VERBS) + /** * A list of resource types. * WARNING: Do not change the order of these, as the savegame format relies diff --git a/engines/scumm/verbs.cpp b/engines/scumm/verbs.cpp index 4347ad9db9..2b9d2342bc 100644 --- a/engines/scumm/verbs.cpp +++ b/engines/scumm/verbs.cpp @@ -272,7 +272,7 @@ void ScummEngine_v2::checkV2MouseOver(Common::Point pos) { int i, x, y, new_box = -1; // Don't do anything unless the inventory is active - if (!(_userState & 64)) { + if (!(_userState & USERSTATE_IFACE_INVENTORY)) { _mouseOverBoxV2 = -1; return; } @@ -368,7 +368,7 @@ void ScummEngine_v2::redrawV2Inventory() { _mouseOverBoxV2 = -1; - if (!(_userState & 64)) // Don't draw inventory unless active + if (!(_userState & USERSTATE_IFACE_INVENTORY)) // Don't draw inventory unless active return; // Clear on all invocations @@ -432,7 +432,7 @@ void ScummEngine_v2::redrawV2Inventory() { } void ScummEngine::redrawVerbs() { - if (_game.version <= 2 && !(_userState & 128)) // Don't draw verbs unless active + if (_game.version <= 2 && !(_userState & USERSTATE_IFACE_VERBS)) // Don't draw verbs unless active return; int i, verb = 0; @@ -875,7 +875,7 @@ void ScummEngine_v0::checkExecVerbs() { void ScummEngine::verbMouseOver(int verb) { // Don't do anything unless verbs are active - if (_game.version <= 2 && !(_userState & 128)) + if (_game.version <= 2 && !(_userState & USERSTATE_IFACE_VERBS)) return; if (_game.id == GID_FT) -- cgit v1.2.3 From 984c2a05e4e4ec643c1135c6b087f6e7faf1997f Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Sun, 29 Jan 2012 17:11:54 +0100 Subject: SCUMM: replace o_beginOverride() with o2_beginOverride() In contrast to the comment in o_beginOverride() VAR(VAR_OVERRIDE) is not set in the disassembly. In addition the cutscene stack-pointer is always 0 as this feature is not used in v0. This makes o_beginOverride() work the same way o2_beginOverride() and so it is not needed anymore. Note that fetchScriptWord() was changed to ScummEngine::fetchScriptWord() in o2_beginOverride() as ScummEngine_v0::fetchScriptWord() only fetches a byte. As we need two bytes here we have to use ScummEngine::fetchScriptWord(). --- engines/scumm/script_v0.cpp | 19 +------------------ engines/scumm/script_v2.cpp | 2 +- engines/scumm/scumm_v0.h | 1 - 3 files changed, 2 insertions(+), 20 deletions(-) (limited to 'engines/scumm') diff --git a/engines/scumm/script_v0.cpp b/engines/scumm/script_v0.cpp index 46052cdf49..a7187237f3 100644 --- a/engines/scumm/script_v0.cpp +++ b/engines/scumm/script_v0.cpp @@ -145,7 +145,7 @@ void ScummEngine_v0::setupOpcodes() { OPCODE(0x56, o_getActorMoving); OPCODE(0x57, o2_clearState08); /* 58 */ - OPCODE(0x58, o_beginOverride); + OPCODE(0x58, o2_beginOverride); OPCODE(0x59, o_stopCurrentScript); OPCODE(0x5a, o2_add); OPCODE(0x5b, o_getActorBitVar); @@ -952,23 +952,6 @@ void ScummEngine_v0::o_endCutscene() { } } -void ScummEngine_v0::o_beginOverride() { - const int idx = vm.cutSceneStackPointer; - assert(0 <= idx && idx < 5); - - vm.cutScenePtr[idx] = _scriptPointer - _scriptOrgPointer; - vm.cutSceneScript[idx] = _currentScript; - - // Skip the jump instruction following the override instruction - // (the jump is responsible for "skipping" cutscenes, and the reason - // why we record the current script position in vm.cutScenePtr). - fetchScriptByte(); - ScummEngine::fetchScriptWord(); - - // This is based on disassembly - VAR(VAR_OVERRIDE) = 0; -} - void ScummEngine_v0::o_setOwnerOf() { int obj, owner; diff --git a/engines/scumm/script_v2.cpp b/engines/scumm/script_v2.cpp index 2b2bad32a7..6857f8635b 100644 --- a/engines/scumm/script_v2.cpp +++ b/engines/scumm/script_v2.cpp @@ -1527,7 +1527,7 @@ void ScummEngine_v2::o2_beginOverride() { // Skip the jump instruction following the override instruction fetchScriptByte(); - fetchScriptWord(); + ScummEngine::fetchScriptWord(); } void ScummEngine_v2::o2_chainScript() { diff --git a/engines/scumm/scumm_v0.h b/engines/scumm/scumm_v0.h index 8b13569042..a5af34b1ff 100644 --- a/engines/scumm/scumm_v0.h +++ b/engines/scumm/scumm_v0.h @@ -153,7 +153,6 @@ protected: void o_unlockSound(); void o_cutscene(); void o_endCutscene(); - void o_beginOverride(); void o_setOwnerOf(); byte VAR_ACTIVE_OBJECT2; -- cgit v1.2.3 From 91bdf9a3f5abff5651679b414de878a890219b44 Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Sun, 29 Jan 2012 17:18:31 +0100 Subject: SCUMM: fix cutscenes by reintroduction of freeze modes --- engines/scumm/script_v0.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'engines/scumm') diff --git a/engines/scumm/script_v0.cpp b/engines/scumm/script_v0.cpp index a7187237f3..faac991193 100644 --- a/engines/scumm/script_v0.cpp +++ b/engines/scumm/script_v0.cpp @@ -636,14 +636,13 @@ void ScummEngine_v0::setMode(byte mode) { _redrawSentenceLine = false; // Note: do not change freeze state here state = USERSTATE_SET_IFACE | - USERSTATE_SET_CURSOR | - USERSTATE_SET_FREEZE; + USERSTATE_SET_CURSOR; break; case kModeKeypad: _redrawSentenceLine = false; state = USERSTATE_SET_IFACE | USERSTATE_SET_CURSOR | USERSTATE_CURSOR_ON | - USERSTATE_SET_FREEZE; + USERSTATE_SET_FREEZE | USERSTATE_FREEZE_ON; break; case kModeNormal: case kModeNoNewKid: @@ -927,12 +926,14 @@ void ScummEngine_v0::o_cutscene() { vm.cutSceneData[0] = _currentMode; vm.cutSceneData[2] = _currentRoom; + freezeScripts(0); setMode(kModeCutscene); _sentenceNum = 0; resetSentence(); vm.cutScenePtr[0] = 0; + vm.cutSceneScript[0] = 0; } void ScummEngine_v0::o_endCutscene() { @@ -946,8 +947,13 @@ void ScummEngine_v0::o_endCutscene() { if (_currentMode == kModeKeypad) { startScene(vm.cutSceneData[2], 0, 0); + // in contrast to the normal keypad behavior we unfreeze scripts here + unfreezeScripts(); } else { + unfreezeScripts(); actorFollowCamera(VAR(VAR_EGO)); + // set mode again to have the freeze mode right + setMode(vm.cutSceneData[0]); _redrawSentenceLine = true; } } -- cgit v1.2.3 From 2b657283d763b23a3263485924c43d5e86aefcc9 Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Sun, 29 Jan 2012 17:26:16 +0100 Subject: SCUMM: forward savegame version is needed due to previous savegame changes) --- engines/scumm/saveload.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'engines/scumm') diff --git a/engines/scumm/saveload.h b/engines/scumm/saveload.h index 931b56f137..a316670e3d 100644 --- a/engines/scumm/saveload.h +++ b/engines/scumm/saveload.h @@ -47,7 +47,7 @@ namespace Scumm { * only saves/loads those which are valid for the version of the savegame * which is being loaded/saved currently. */ -#define CURRENT_VER 90 +#define CURRENT_VER 91 /** * An auxillary macro, used to specify savegame versions. We use this instead -- cgit v1.2.3 From 92908bfc4b461dad5cf5811a0d3c167827ddf3b1 Mon Sep 17 00:00:00 2001 From: Robert Crossfield Date: Mon, 30 Jan 2012 23:33:48 +1100 Subject: SCUMM: Fix ActorStop, V0 needs to set the stop direction --- engines/scumm/actor.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'engines/scumm') diff --git a/engines/scumm/actor.cpp b/engines/scumm/actor.cpp index c2390ab4b0..6f6c1d21db 100644 --- a/engines/scumm/actor.cpp +++ b/engines/scumm/actor.cpp @@ -235,6 +235,8 @@ void Actor::stopActorMoving() { _vm->stopScript(_walkScript); _moving = 0; + if( _vm->_game.version == 0 ) + ((ActorC64*)this)->setDirection( _facing ); } void Actor::setActorWalkSpeed(uint newSpeedX, uint newSpeedY) { -- cgit v1.2.3 From a8008e0a717fd2bb1d697f04c1901397deabe958 Mon Sep 17 00:00:00 2001 From: Robert Crossfield Date: Tue, 31 Jan 2012 07:42:38 +1100 Subject: SCUMM: Fix if there is no costume set --- engines/scumm/costume.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'engines/scumm') diff --git a/engines/scumm/costume.cpp b/engines/scumm/costume.cpp index e3a2203adc..b2ad4b9b33 100644 --- a/engines/scumm/costume.cpp +++ b/engines/scumm/costume.cpp @@ -1285,6 +1285,9 @@ void C64CostumeLoader::loadCostume(int id) { void C64CostumeLoader::costumeDecodeData(Actor *a, int frame, uint usemask) { ActorC64 *A = (ActorC64 *)a; + if(!a->_costume) + return; + loadCostume(a->_costume); // Invalid costume command? -- cgit v1.2.3 From 434aaaf0c0cdbcc8a1ebc0e461f1e31582126f92 Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Sat, 4 Feb 2012 11:18:14 +0100 Subject: SCUMM: fix gcc compiler warnings --- engines/scumm/actor.h | 2 +- engines/scumm/costume.cpp | 2 +- engines/scumm/script.cpp | 4 ++-- engines/scumm/script_v0.cpp | 2 +- engines/scumm/scumm_v0.h | 4 ++-- engines/scumm/verbs.h | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) (limited to 'engines/scumm') diff --git a/engines/scumm/actor.h b/engines/scumm/actor.h index d3271f4eaa..4e251d0e3c 100644 --- a/engines/scumm/actor.h +++ b/engines/scumm/actor.h @@ -343,7 +343,7 @@ enum ActorC64MiscFlags { kActorMiscFlag_10 = 0x10, // ??? kActorMiscFlag_20 = 0x20, // ??? kActorMiscFlagFreeze = 0x40, // Stop moving - kActorMiscFlagHide = 0x80, // Kid is invisible (dead or in radiation suit) + kActorMiscFlagHide = 0x80 // Kid is invisible (dead or in radiation suit) }; class ActorC64 : public Actor_v2 { diff --git a/engines/scumm/costume.cpp b/engines/scumm/costume.cpp index b2ad4b9b33..489c1f46e7 100644 --- a/engines/scumm/costume.cpp +++ b/engines/scumm/costume.cpp @@ -1179,7 +1179,7 @@ static const byte actorColorsMMC64[25] = { } byte C64CostumeRenderer::drawLimb(const Actor *a, int limb) { - ActorC64* A = (ActorC64*) a; + const ActorC64* A = (const ActorC64 *)a; if (limb >= 8) return 0; diff --git a/engines/scumm/script.cpp b/engines/scumm/script.cpp index 63f04c1f32..8880963698 100644 --- a/engines/scumm/script.cpp +++ b/engines/scumm/script.cpp @@ -1200,8 +1200,8 @@ bool ScummEngine_v0::checkPendingWalkAction() { b->faceToObject(actorToObj(actor)); } } else { // walk to object finished - int x, y, dir; - getObjectXYPos(_walkToObject, x, y, dir); + int tmpX, tmpY, dir; + getObjectXYPos(_walkToObject, tmpX, tmpY, dir); a->turnToDirection(dir); } _walkToObjectState = kWalkToObjectStateTurn; diff --git a/engines/scumm/script_v0.cpp b/engines/scumm/script_v0.cpp index faac991193..8de95858f2 100644 --- a/engines/scumm/script_v0.cpp +++ b/engines/scumm/script_v0.cpp @@ -464,7 +464,7 @@ void ScummEngine_v0::drawSentenceLine() { if (_activeVerb == kVerbNewKid) { _sentenceBuf = ""; for (int i = 0; i < 3; ++i) { - char *actorName; + const char *actorName; int actorId = VAR(97 + i); if (actorId == 0) { // after usage of the radiation suit, kid vars are set to 0 diff --git a/engines/scumm/scumm_v0.h b/engines/scumm/scumm_v0.h index a5af34b1ff..a64f108243 100644 --- a/engines/scumm/scumm_v0.h +++ b/engines/scumm/scumm_v0.h @@ -36,13 +36,13 @@ protected: kModeCutscene = 0, // cutscene active kModeKeypad = 1, // kid selection / dial pad / save-load dialog kModeNoNewKid = 2, // verb "new kid" disabled (e.g. when entering lab) - kModeNormal = 3, // normal playing mode + kModeNormal = 3 // normal playing mode }; enum WalkToObjectState { kWalkToObjectStateDone = 0, kWalkToObjectStateWalk = 1, - kWalkToObjectStateTurn = 2, + kWalkToObjectStateTurn = 2 }; protected: diff --git a/engines/scumm/verbs.h b/engines/scumm/verbs.h index fce260ea63..0aa008b4de 100644 --- a/engines/scumm/verbs.h +++ b/engines/scumm/verbs.h @@ -82,7 +82,7 @@ enum VerbPrepsV0 { kVerbPrepWith = 2, kVerbPrepOn = 3, kVerbPrepTo = 4, - kVerbPrepObject = 0xFF, // prep depends on object (USE) + kVerbPrepObject = 0xFF // prep depends on object (USE) }; } // End of namespace Scumm -- cgit v1.2.3 From e14e4ab3b035012781abfbac500e6de88e0ad60b Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Sat, 4 Feb 2012 14:49:44 +0100 Subject: SCUMM: adjust to coding style-guide --- engines/scumm/actor.cpp | 80 ++++++++++++++++++++------------------------- engines/scumm/actor.h | 28 ++++++++-------- engines/scumm/costume.cpp | 70 +++++++++++++++++++-------------------- engines/scumm/costume.h | 2 +- engines/scumm/object.h | 14 ++++---- engines/scumm/script.cpp | 4 +-- engines/scumm/script_v0.cpp | 28 ++++++++-------- engines/scumm/script_v2.cpp | 2 +- engines/scumm/verbs.cpp | 3 +- 9 files changed, 110 insertions(+), 121 deletions(-) (limited to 'engines/scumm') diff --git a/engines/scumm/actor.cpp b/engines/scumm/actor.cpp index 6f6c1d21db..c5d2a2b9fb 100644 --- a/engines/scumm/actor.cpp +++ b/engines/scumm/actor.cpp @@ -235,8 +235,8 @@ void Actor::stopActorMoving() { _vm->stopScript(_walkScript); _moving = 0; - if( _vm->_game.version == 0 ) - ((ActorC64*)this)->setDirection( _facing ); + if(_vm->_game.version == 0) + ((ActorC64 *)this)->setDirection(_facing); } void Actor::setActorWalkSpeed(uint newSpeedX, uint newSpeedY) { @@ -324,13 +324,12 @@ int Actor::actorWalkStep() { int distX, distY; int nextFacing; - if( _vm->_game.version == 0 ) - ((ActorC64*) this)->_animFrameRepeat = -1; + if(_vm->_game.version == 0) + ((ActorC64 *)this)->_animFrameRepeat = -1; _needRedraw = true; nextFacing = updateActorDirection(true); - if (!(_moving & MF_IN_LEG) || _facing != nextFacing) { if (_walkFrame != _frame || _facing != nextFacing) { startWalkAnim(1, nextFacing); @@ -370,7 +369,6 @@ int Actor::actorWalkStep() { _moving &= ~MF_IN_LEG; return 0; } - return 1; } @@ -398,11 +396,9 @@ void Actor::startWalkActor(int destX, int destY, int dir) { } if (_vm->_game.version <= 2) { - abr = adjustXYToBeInBox(abr.x, abr.y); if (_pos.x == abr.x && _pos.y == abr.y && (dir == -1 || _facing == dir)) return; - } else { if (_ignoreBoxes) { abr.box = kInvalidBox; @@ -449,7 +445,6 @@ void Actor::startWalkAnim(int cmd, int angle) { args[2] = angle; _vm->runScript(_walkScript, 1, 0, args); } else { - switch (cmd) { case 1: /* start walk */ setDirection(angle); @@ -573,9 +568,8 @@ void Actor_v2::walkActor() { if (_moving & MF_IN_LEG) { actorWalkStep(); - if( _vm->_game.version == 0 ) - ((ActorC64*) this)->animateActor( newDirToOldDir( _facing ) ); - + if(_vm->_game.version == 0) + ((ActorC64 *)this)->animateActor(newDirToOldDir(_facing)); } else { if (_moving & MF_LAST_LEG) { _moving = 0; @@ -886,24 +880,24 @@ void Actor::setDirection(int direction) { void ActorC64::setDirection(int direction) { int dir = newDirToOldDir( direction ); - int res = 0; + int res = 0; switch (dir) { case 0: res = 4; // Left - break; + break; case 1: res = 5; // Right - break; + break; case 2: res = 6; // Face Away - break; + break; - default: + default: res = 7; // Face Camera - break; + break; } _animFrameRepeat = -1; @@ -935,12 +929,10 @@ void Actor::turnToDirection(int newdir) { } else { _moving &= ~MF_TURN; if (newdir != _facing) { - _moving |= MF_TURN; _targetFacing = newdir; } } - } @@ -982,14 +974,11 @@ void Actor::putActor(int dstX, int dstY, int newRoom) { if (_visible) { if (isInCurrentRoom()) { - if (_moving) { stopActorMoving(); startAnimActor(_standFrame); } - adjustActorPos(); - } else { #ifdef ENABLE_HE if (_vm->_game.heversion >= 71) @@ -1003,8 +992,8 @@ void Actor::putActor(int dstX, int dstY, int newRoom) { } // V0 always sets the actor to face the camera upon entering a room - if( _vm->_game.version == 0 ) - setDirection( oldDirToNewDir(2)); + if(_vm->_game.version == 0) + setDirection(oldDirToNewDir(2)); } static bool inBoxQuickReject(const BoxCoords &box, int x, int y, int threshold) { @@ -1139,6 +1128,7 @@ AdjustBoxResult Actor_v2::adjustXYToBeInBox(const int dstX, const int dstY) { abr.x = foundX; abr.y = foundY; abr.box = box; + break; } if (dist < bestDist) { @@ -1324,20 +1314,19 @@ void Actor::showActor() { _vm->ensureResourceLoaded(rtCostume, _costume); if (_vm->_game.version == 0) { - - ActorC64 *a = ((ActorC64*) this); + ActorC64 *a = ((ActorC64 *)this); a->_costCommand = a->_costCommandNew = 0xFF; - for( int i = 0; i < 8; ++i ) { + for(int i = 0; i < 8; ++i) { a->_limbFrameRepeat[i] = 0; a->_limbFrameRepeatNew[i] = 0; } _cost.reset(); - // 0x39DF - a->_animFrameRepeat = 1; + // 0x39DF + a->_animFrameRepeat = 1; a->_speaking = 0; startAnimActor(_standFrame); @@ -1880,10 +1869,10 @@ void ActorC64::startAnimActor(int f) { return; } - if( f == _standFrame ) - setDirection( _facing ); + if(f == _standFrame) + setDirection(_facing); else - animateActor( newDirToOldDir(_facing) ); + animateActor(newDirToOldDir(_facing)); } void Actor::animateActor(int anim) { @@ -1898,6 +1887,7 @@ void Actor::animateActor(int anim) { dir = anim % 1000; } else { + cmd = anim / 4; dir = oldDirToNewDir(anim % 4); @@ -1970,7 +1960,7 @@ void ActorC64::animateCostume() { speakCheck(); - for( _limb_current = 0; _limb_current < 8; ++_limb_current ) { + for(_limb_current = 0; _limb_current < 8; ++_limb_current) { limbFrameCheck(); if (_vm->_costumeLoader->increaseAnims(this)) @@ -1983,15 +1973,15 @@ void ActorC64::speakCheck() { if (v0ActorTalkArray[_number] & 0x80) return; - int cmd = newDirToOldDir( _facing ); + int cmd = newDirToOldDir(_facing); if (_speaking & 0x80) cmd += 0x0C; else cmd += 0x10; - _animFrameRepeat = -1; - animateActor( cmd ); + _animFrameRepeat = -1; + animateActor(cmd); } #ifdef ENABLE_SCUMM_7_8 @@ -2622,7 +2612,7 @@ bool Actor::isPlayer() { } bool Actor_v2::isPlayer() { - // isPlayer() is not supported by v0 + // isPlayer() is not supported by v0 assert(_vm->_game.version != 0); return _vm->VAR(42) <= _number && _number <= _vm->VAR(43); } @@ -2781,7 +2771,7 @@ void ScummEngine_v71he::queueAuxEntry(int actorNum, int subIndex) { void ActorC64::animateActor(int anim) { int dir = -1; - switch( anim ) { + switch (anim) { case 0x00: case 0x04: dir = 0; @@ -2806,21 +2796,21 @@ void ActorC64::animateActor(int anim) { break; } - if( isInCurrentRoom() ) { + if(isInCurrentRoom()) { _costCommandNew = anim; _vm->_costumeLoader->costumeDecodeData(this, 0, 0); - if( dir == -1 ) + if(dir == -1) return; - _facing = normalizeAngle( oldDirToNewDir(dir) ); + _facing = normalizeAngle(oldDirToNewDir(dir)); } else { - if( anim > 4 && anim <= 7 ) - _facing = normalizeAngle( oldDirToNewDir(dir) ); - } + if(anim > 4 && anim <= 7) + _facing = normalizeAngle(oldDirToNewDir(dir)); + } } void ActorC64::saveLoadWithSerializer(Serializer *ser) { diff --git a/engines/scumm/actor.h b/engines/scumm/actor.h index 4e251d0e3c..c82bd641bd 100644 --- a/engines/scumm/actor.h +++ b/engines/scumm/actor.h @@ -352,41 +352,41 @@ public: byte _miscflags; byte _speaking; - int8 _animFrameRepeat; - int8 _limbFrameRepeatNew[8], _limbFrameRepeat[8]; + int8 _animFrameRepeat; + int8 _limbFrameRepeatNew[8], _limbFrameRepeat[8]; - byte _limb_current; + byte _limb_current; bool _limb_flipped[8]; public: ActorC64(ScummEngine *scumm, int id) : Actor_v2(scumm, id) { - _costCommand = 0xFF; - _speaking = 0; - _animFrameRepeat = 0; - _costCommandNew = 0xFF; + _costCommand = 0xFF; + _speaking = 0; + _animFrameRepeat = 0; + _costCommandNew = 0xFF; - for( int i = 0; i < 8; ++i ) { + for(int i = 0; i < 8; ++i) { _limbFrameRepeatNew[i] = 0; _limbFrameRepeat[i] = 0; _limb_flipped[i] = false; } } + virtual void initActor(int mode) { Actor_v2::initActor(mode); if (mode == -1) { _miscflags = 0; } - } - virtual void animateActor(int anim); + virtual void animateActor(int anim); virtual void animateCostume(); - void limbFrameCheck(); + void limbFrameCheck(); - void speakCheck(); - virtual void setDirection(int direction); - void startAnimActor(int f); + void speakCheck(); + virtual void setDirection(int direction); + void startAnimActor(int f); // Used by the save/load system: virtual void saveLoadWithSerializer(Serializer *ser); diff --git a/engines/scumm/costume.cpp b/engines/scumm/costume.cpp index 489c1f46e7..0b22cf38e2 100644 --- a/engines/scumm/costume.cpp +++ b/engines/scumm/costume.cpp @@ -1190,11 +1190,11 @@ byte C64CostumeRenderer::drawLimb(const Actor *a, int limb) { } // Invalid current position? - if( a->_cost.curpos[limb] == 0xFFFF ) + if(a->_cost.curpos[limb] == 0xFFFF) return 0; - _loaded.loadCostume( a->_costume ); - byte frame = _loaded._frameOffsets[ a->_cost.curpos[limb] + a->_cost.active[limb] ]; + _loaded.loadCostume(a->_costume); + byte frame = _loaded._frameOffsets[a->_cost.curpos[limb] + a->_cost.active[limb]]; // Get the frame ptr byte ptrLow = _loaded._baseptr[frame]; @@ -1224,7 +1224,7 @@ byte C64CostumeRenderer::drawLimb(const Actor *a, int limb) { if (!width || !height) return 0; - int xpos = _actorX + (A->_limb_flipped[ limb ] ? -1 : +1) * (offsetX * 8 - a->_width / 2); + int xpos = _actorX + (A->_limb_flipped[limb] ? -1 : +1) * (offsetX * 8 - a->_width / 2); // +1 as we appear to be 1 pixel away from the original interpreter int ypos = _actorY - offsetY + 1; @@ -1234,13 +1234,13 @@ byte C64CostumeRenderer::drawLimb(const Actor *a, int limb) { byte color = data[y * width + x]; byte pcolor; - int destX = xpos + (A->_limb_flipped[ limb ] ? -(x + 1) : x) * 8; + int destX = xpos + (A->_limb_flipped[limb] ? -(x + 1) : x) * 8; int destY = ypos + y; if (destY >= 0 && destY < _out.h && destX >= 0 && destX < _out.w) { byte *dst = (byte *)_out.pixels + destY * _out.pitch + destX; byte *mask = _vm->getMaskBuffer(0, destY, _zbuf); - if (A->_limb_flipped[ limb ]) { + if (A->_limb_flipped[limb]) { LINE(0, 0); LINE(2, 2); LINE(4, 4); LINE(6, 6); } else { LINE(6, 0); LINE(4, 2); LINE(2, 4); LINE(0, 6); @@ -1251,7 +1251,7 @@ byte C64CostumeRenderer::drawLimb(const Actor *a, int limb) { _draw_top = MIN(_draw_top, ypos); _draw_bottom = MAX(_draw_bottom, ypos + height); - if (A->_limb_flipped[ limb ]) + if (A->_limb_flipped[limb]) _vm->markRectAsDirty(kMainVirtScreen, xpos - (width * 8), xpos, ypos, ypos + height, _actorID); else _vm->markRectAsDirty(kMainVirtScreen, xpos, xpos + (width * 8), ypos, ypos + height, _actorID); @@ -1291,7 +1291,7 @@ void C64CostumeLoader::costumeDecodeData(Actor *a, int frame, uint usemask) { loadCostume(a->_costume); // Invalid costume command? - if( A->_costCommandNew == 0xFF || (A->_costCommand == A->_costCommandNew) ) + if(A->_costCommandNew == 0xFF || (A->_costCommand == A->_costCommandNew)) return; A->_costCommand = A->_costCommandNew; @@ -1308,41 +1308,41 @@ void C64CostumeLoader::costumeDecodeData(Actor *a, int frame, uint usemask) { limbFrameNumber = ((_animCmds + cmd)[limb]); // Is this limb flipped? - if( limbFrameNumber & 0x80 ) { + if(limbFrameNumber & 0x80) { // Invalid frame? - if( limbFrameNumber == 0xFF ) + if(limbFrameNumber == 0xFF) continue; // Store the limb frame number (clear the flipped status) - a->_cost.frame[limb] = (limbFrameNumber & 0x7f); + a->_cost.frame[limb] = (limbFrameNumber & 0x7f); - if( A->_limb_flipped[limb] != true ) + if(A->_limb_flipped[limb] != true) a->_cost.start[limb] = 0xFFFF; A->_limb_flipped[limb] = true; } else { //Store the limb frame number - a->_cost.frame[limb] = limbFrameNumber; + a->_cost.frame[limb] = limbFrameNumber; - if( A->_limb_flipped[limb] != false ) + if(A->_limb_flipped[limb] != false) a->_cost.start[limb] = 0xFFFF; A->_limb_flipped[limb] = false; } // Set the repeat value - A->_limbFrameRepeatNew[limb] = A->_animFrameRepeat; + A->_limbFrameRepeatNew[limb] = A->_animFrameRepeat; } } -byte C64CostumeLoader::getFrame( ActorC64 *A ) { +byte C64CostumeLoader::getFrame(ActorC64 *A) { loadCostume(A->_costume); // Get the frame number for the current limb / Command - return _frameOffsets[ _frameOffsets[A->_limb_current] + A->_cost.start[ A->_limb_current ] ]; + return _frameOffsets[_frameOffsets[A->_limb_current] + A->_cost.start[A->_limb_current]]; } byte C64CostumeLoader::increaseAnims(Actor *a) { @@ -1352,39 +1352,39 @@ byte C64CostumeLoader::increaseAnims(Actor *a) { loadCostume(a->_costume); - // 0x2543 - byte frame = _frameOffsets[ a->_cost.curpos[A->_limb_current] + a->_cost.active[A->_limb_current] ]; + // 0x2543 + byte frame = _frameOffsets[a->_cost.curpos[A->_limb_current] + a->_cost.active[A->_limb_current]]; // Is this frame invalid? - if ( frame == 0xFF ) { + if (frame == 0xFF) { - // Repeat timer has reached 0? - if( A->_limbFrameRepeat[A->_limb_current] == 0 ) { + // Repeat timer has reached 0? + if(A->_limbFrameRepeat[A->_limb_current] == 0) { - // Use the previous frame - --A->_cost.curpos[A->_limb_current]; + // Use the previous frame + --A->_cost.curpos[A->_limb_current]; // Reset the comstume command - A->_costCommandNew = 0xFF; - A->_costCommand = 0xFF; - - // Set the frame/start to invalid + A->_costCommandNew = 0xFF; + A->_costCommand = 0xFF; + + // Set the frame/start to invalid A->_cost.frame[A->_limb_current] = 0xFFFF; A->_cost.start[A->_limb_current] = 0xFFFF; - } else { + } else { // Repeat timer enabled? - if( A->_limbFrameRepeat[A->_limb_current] != -1 ) - --A->_limbFrameRepeat[A->_limb_current]; + if(A->_limbFrameRepeat[A->_limb_current] != -1) + --A->_limbFrameRepeat[A->_limb_current]; // No, restart at frame 0 - a->_cost.curpos[A->_limb_current] = 0; - } - } + a->_cost.curpos[A->_limb_current] = 0; + } + } // Limb frame has changed? - if( limbPrevious == a->_cost.curpos[A->_limb_current] ) + if(limbPrevious == a->_cost.curpos[A->_limb_current]) return 0; return 1; diff --git a/engines/scumm/costume.h b/engines/scumm/costume.h index 4600cc5670..50f23dbacf 100644 --- a/engines/scumm/costume.h +++ b/engines/scumm/costume.h @@ -74,7 +74,7 @@ public: void costumeDecodeData(Actor *a, int frame, uint usemask); byte increaseAnims(Actor *a); - byte getFrame( ActorC64 *A ); + byte getFrame(ActorC64 *A); protected: diff --git a/engines/scumm/object.h b/engines/scumm/object.h index 37ccc4eef6..8212075e43 100644 --- a/engines/scumm/object.h +++ b/engines/scumm/object.h @@ -33,14 +33,14 @@ static inline int OBJECT_V0(int id, byte type) { enum ObjectV0Type { kObjectV0TypeFG = 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) + // - 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) kObjectV0TypeBG = 1, // background object - // - without owner/state, not pickupable (room only) - // -> without entry in _objectOwner/StateTable - // - image cannot be exchanged (part of background image) + // - without owner/state, not pickupable (room only) + // -> without entry in _objectOwner/StateTable + // - image cannot be exchanged (part of background image) kObjectV0TypeActor = 2 // object is an actor }; diff --git a/engines/scumm/script.cpp b/engines/scumm/script.cpp index 8880963698..3bd70d0e24 100644 --- a/engines/scumm/script.cpp +++ b/engines/scumm/script.cpp @@ -1000,7 +1000,7 @@ void ScummEngine::killScriptsAndResources() { for (i = 0; i < _numNewNames; i++) { const int obj = _newNames[i]; if (obj) { - const int owner = getOwner( (_game.version != 0 ? obj : OBJECT_V0_ID(obj) ) ); + const int owner = getOwner((_game.version != 0 ? obj : OBJECT_V0_ID(obj))); // We can delete custom name resources if either the object is // no longer in use (i.e. not owned by anyone anymore); or if // it is an object which is owned by a room. @@ -1234,7 +1234,7 @@ void ScummEngine_v0::checkAndRunSentenceScript() { // If two objects are involved, at least one must be in the actors inventory if (st.objectB && (OBJECT_V0_TYPE(st.objectA) != kObjectV0TypeFG || _objectOwnerTable[st.objectA] != VAR(VAR_EGO)) && - (OBJECT_V0_TYPE(st.objectB) != kObjectV0TypeFG || _objectOwnerTable[st.objectB] != VAR(VAR_EGO))) + (OBJECT_V0_TYPE(st.objectB) != kObjectV0TypeFG || _objectOwnerTable[st.objectB] != VAR(VAR_EGO))) { if (getVerbEntrypoint(st.objectA, kVerbPickUp)) doSentence(kVerbPickUp, st.objectA, 0); diff --git a/engines/scumm/script_v0.cpp b/engines/scumm/script_v0.cpp index 8de95858f2..07be151ce2 100644 --- a/engines/scumm/script_v0.cpp +++ b/engines/scumm/script_v0.cpp @@ -687,24 +687,24 @@ void ScummEngine_v0::o_animateActor() { ActorC64 *a = (ActorC64*) derefActor(act, "o_animateActor"); - a->_animFrameRepeat = repeat; + a->_animFrameRepeat = repeat; - switch( anim ) { + switch (anim) { - case 0xFE: - // 0x6993 - a->_speaking = 0x80; // Enabled, but not switching - return; + case 0xFE: + // 0x6993 + a->_speaking = 0x80; // Enabled, but not switching + return; - case 0xFD: - // 0x69A3 - a->_speaking = 0x00; - return; + case 0xFD: + // 0x69A3 + a->_speaking = 0x00; + return; - case 0xFF: - a->stopActorMoving(); - return; - } + case 0xFF: + a->stopActorMoving(); + return; + } a->animateActor(anim); a->animateCostume(); diff --git a/engines/scumm/script_v2.cpp b/engines/scumm/script_v2.cpp index 6857f8635b..1b8dc965e0 100644 --- a/engines/scumm/script_v2.cpp +++ b/engines/scumm/script_v2.cpp @@ -994,7 +994,7 @@ void ScummEngine_v2::o2_drawSentence() { int slot = getVerbSlot(VAR(VAR_SENTENCE_VERB), 0); if (!((_userState & USERSTATE_IFACE_SENTENCE) || - (_game.platform == Common::kPlatformNES && (_userState & USERSTATE_IFACE_ALL)))) + (_game.platform == Common::kPlatformNES && (_userState & USERSTATE_IFACE_ALL)))) return; if (getResourceAddress(rtVerb, slot)) diff --git a/engines/scumm/verbs.cpp b/engines/scumm/verbs.cpp index 2b9d2342bc..88a1283067 100644 --- a/engines/scumm/verbs.cpp +++ b/engines/scumm/verbs.cpp @@ -476,7 +476,6 @@ void ScummEngine_v2::handleMouseOver(bool updateInventory) { } void ScummEngine_v0::handleMouseOver(bool updateInventory) { - //drawSentence(); ScummEngine_v2::handleMouseOver(updateInventory); } @@ -695,7 +694,7 @@ void ScummEngine_v0::verbExec() { if (_activeVerb == kVerbWhatIs) return; - if (!(_activeVerb == kVerbWalkTo && _activeObject == 0)) { + if (!(_activeVerb == kVerbWalkTo && _activeObject == 0)) { doSentence(_activeVerb, _activeObject, _activeObject2); if (_activeVerb != kVerbWalkTo) { _activeVerb = kVerbWalkTo; -- cgit v1.2.3 From daff6f36ae210bea03bc51f0e5293218f439cd89 Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Sat, 4 Feb 2012 15:40:36 +0100 Subject: SCUMM: _currentLights is v0 only --- engines/scumm/gfx.cpp | 19 +++++++++++-------- engines/scumm/scumm.cpp | 2 +- engines/scumm/scumm.h | 3 +-- engines/scumm/scumm_v0.h | 3 +++ 4 files changed, 16 insertions(+), 11 deletions(-) (limited to 'engines/scumm') diff --git a/engines/scumm/gfx.cpp b/engines/scumm/gfx.cpp index a22aa1802f..a6b8377d2f 100644 --- a/engines/scumm/gfx.cpp +++ b/engines/scumm/gfx.cpp @@ -26,6 +26,7 @@ #include "scumm/he/intern_he.h" #endif #include "scumm/resource.h" +#include "scumm/scumm_v0.h" #include "scumm/scumm_v5.h" #include "scumm/scumm_v6.h" #include "scumm/usage_bits.h" @@ -1487,15 +1488,17 @@ void ScummEngine_v5::drawFlashlight() { _flashlight.isDrawn = true; } -// V0 Maniac doesn't have a ScummVar for VAR_CURRENT_LIGHTS, and just uses -// an internal variable. Emulate this to prevent overwriting script vars... -// And V6 games do not use the "lights" at all. There, the whole screen is -// always visible, and actors are always colored, so we fake the correct -// light value for it. +int ScummEngine_v0::getCurrentLights() const { + // V0 Maniac doesn't have a ScummVar for VAR_CURRENT_LIGHTS, and just uses + // an internal variable. Emulate this to prevent overwriting script vars... + // And V6 games do not use the "lights" at all. There, the whole screen is + // always visible, and actors are always colored, so we fake the correct + // light value for it. + return _currentLights; +} + int ScummEngine::getCurrentLights() const { - if (_game.id == GID_MANIAC && _game.version == 0) - return _currentLights; - else if (_game.version >= 6) + if (_game.version >= 6) return LIGHTMODE_room_lights_on | LIGHTMODE_actor_use_colors; else return VAR(VAR_CURRENT_LIGHTS); diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp index 61d38dc593..d8b02d0881 100644 --- a/engines/scumm/scumm.cpp +++ b/engines/scumm/scumm.cpp @@ -263,7 +263,6 @@ ScummEngine::ScummEngine(OSystem *syst, const DetectorResult &dr) _bytesPerPixel = 1; _doEffect = false; _snapScroll = false; - _currentLights = 0; _shakeEnabled = false; _shakeFrame = 0; _screenStartStrip = 0; @@ -713,6 +712,7 @@ ScummEngine_v0::ScummEngine_v0(OSystem *syst, const DetectorResult &dr) : ScummEngine_v2(syst, dr) { _currentMode = 0; + _currentLights = 0; _activeVerb = kVerbNone; _activeObject = 0; diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h index fa04c5b616..f67536d3ed 100644 --- a/engines/scumm/scumm.h +++ b/engines/scumm/scumm.h @@ -942,8 +942,7 @@ protected: public: bool isLightOn() const; - byte _currentLights; - int getCurrentLights() const; + virtual int getCurrentLights() const; protected: void initScreens(int b, int h); diff --git a/engines/scumm/scumm_v0.h b/engines/scumm/scumm_v0.h index a64f108243..982b62d645 100644 --- a/engines/scumm/scumm_v0.h +++ b/engines/scumm/scumm_v0.h @@ -47,6 +47,7 @@ protected: protected: byte _currentMode; + byte _currentLights; int _activeVerb; // selected verb int _activeObject; // 1st selected object (see OBJECT_V0()) @@ -115,6 +116,8 @@ protected: bool ifEqualActiveObject2Common(bool checkType); + virtual int getCurrentLights() const; + /* Version C64 script opcodes */ void o_stopCurrentScript(); void o_walkActorToObject(); -- cgit v1.2.3 From 5d3e1dd0dc7542057779f192c6865e9501eb8e36 Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Sat, 4 Feb 2012 17:32:26 +0100 Subject: SCUMM: remove the temporary variable _limb_current --- engines/scumm/actor.cpp | 24 +++++++++--------------- engines/scumm/actor.h | 3 +-- engines/scumm/costume.cpp | 40 +++++++++++++++++++++++++--------------- engines/scumm/costume.h | 5 ++--- 4 files changed, 37 insertions(+), 35 deletions(-) (limited to 'engines/scumm') diff --git a/engines/scumm/actor.cpp b/engines/scumm/actor.cpp index c5d2a2b9fb..f58d3fde4e 100644 --- a/engines/scumm/actor.cpp +++ b/engines/scumm/actor.cpp @@ -1937,39 +1937,33 @@ void Actor::animateCostume() { } } -void ActorC64::limbFrameCheck() { - if (_cost.frame[_limb_current] == 0xFFFF ) +void ActorC64::limbFrameCheck(int limb) { + if (_cost.frame[limb] == 0xFFFF) return; - if (_cost.start[_limb_current] == _cost.frame[_limb_current] ) + if (_cost.start[limb] == _cost.frame[limb]) return; // 0x25A4 - _cost.start[_limb_current] = _cost.frame[_limb_current]; + _cost.start[limb] = _cost.frame[limb]; - _limbFrameRepeat[_limb_current] = _limbFrameRepeatNew[_limb_current]; + _limbFrameRepeat[limb] = _limbFrameRepeatNew[limb]; // 0x25C3 - _cost.active[_limb_current] = ((C64CostumeLoader*)_vm->_costumeLoader)->getFrame( this ); - _cost.curpos[_limb_current] = 0; + _cost.active[limb] = ((C64CostumeLoader*)_vm->_costumeLoader)->getFrame(this, limb); + _cost.curpos[limb] = 0; _needRedraw = true; } void ActorC64::animateCostume() { - speakCheck(); - for(_limb_current = 0; _limb_current < 8; ++_limb_current) { - limbFrameCheck(); - - if (_vm->_costumeLoader->increaseAnims(this)) - _needRedraw = true; - } + if (_vm->_costumeLoader->increaseAnims(this)) + _needRedraw = true; } void ActorC64::speakCheck() { - if (v0ActorTalkArray[_number] & 0x80) return; diff --git a/engines/scumm/actor.h b/engines/scumm/actor.h index c82bd641bd..c2ffcf1275 100644 --- a/engines/scumm/actor.h +++ b/engines/scumm/actor.h @@ -355,7 +355,6 @@ public: int8 _animFrameRepeat; int8 _limbFrameRepeatNew[8], _limbFrameRepeat[8]; - byte _limb_current; bool _limb_flipped[8]; public: @@ -382,7 +381,7 @@ public: virtual void animateActor(int anim); virtual void animateCostume(); - void limbFrameCheck(); + void limbFrameCheck(int limb); void speakCheck(); virtual void setDirection(int direction); diff --git a/engines/scumm/costume.cpp b/engines/scumm/costume.cpp index 0b22cf38e2..9fe5296546 100644 --- a/engines/scumm/costume.cpp +++ b/engines/scumm/costume.cpp @@ -1337,54 +1337,64 @@ void C64CostumeLoader::costumeDecodeData(Actor *a, int frame, uint usemask) { } } -byte C64CostumeLoader::getFrame(ActorC64 *A) { - - loadCostume(A->_costume); +byte C64CostumeLoader::getFrame(Actor *a, int limb) { + loadCostume(a->_costume); // Get the frame number for the current limb / Command - return _frameOffsets[_frameOffsets[A->_limb_current] + A->_cost.start[A->_limb_current]]; + return _frameOffsets[_frameOffsets[limb] + a->_cost.start[limb]]; } byte C64CostumeLoader::increaseAnims(Actor *a) { ActorC64 *A = (ActorC64 *)a; - - uint16 limbPrevious = a->_cost.curpos[A->_limb_current]++; + int i; + byte r = 0; + + for(i = 0; i != 8; i++) { + A->limbFrameCheck(i); + r += increaseAnim(a, i); + } + return r; +} + +byte C64CostumeLoader::increaseAnim(Actor *a, int limb) { + ActorC64 *A = (ActorC64 *)a; + const uint16 limbPrevious = a->_cost.curpos[limb]++; loadCostume(a->_costume); // 0x2543 - byte frame = _frameOffsets[a->_cost.curpos[A->_limb_current] + a->_cost.active[A->_limb_current]]; + byte frame = _frameOffsets[a->_cost.curpos[limb] + a->_cost.active[limb]]; // Is this frame invalid? if (frame == 0xFF) { // Repeat timer has reached 0? - if(A->_limbFrameRepeat[A->_limb_current] == 0) { + if(A->_limbFrameRepeat[limb] == 0) { // Use the previous frame - --A->_cost.curpos[A->_limb_current]; + --A->_cost.curpos[limb]; // Reset the comstume command A->_costCommandNew = 0xFF; A->_costCommand = 0xFF; // Set the frame/start to invalid - A->_cost.frame[A->_limb_current] = 0xFFFF; - A->_cost.start[A->_limb_current] = 0xFFFF; + A->_cost.frame[limb] = 0xFFFF; + A->_cost.start[limb] = 0xFFFF; } else { // Repeat timer enabled? - if(A->_limbFrameRepeat[A->_limb_current] != -1) - --A->_limbFrameRepeat[A->_limb_current]; + if(A->_limbFrameRepeat[limb] != -1) + --A->_limbFrameRepeat[limb]; // No, restart at frame 0 - a->_cost.curpos[A->_limb_current] = 0; + a->_cost.curpos[limb] = 0; } } // Limb frame has changed? - if(limbPrevious == a->_cost.curpos[A->_limb_current]) + if(limbPrevious == a->_cost.curpos[limb]) return 0; return 1; diff --git a/engines/scumm/costume.h b/engines/scumm/costume.h index 50f23dbacf..16317cb1c9 100644 --- a/engines/scumm/costume.h +++ b/engines/scumm/costume.h @@ -73,11 +73,10 @@ public: void loadCostume(int id); void costumeDecodeData(Actor *a, int frame, uint usemask); byte increaseAnims(Actor *a); - - byte getFrame(ActorC64 *A); + byte getFrame(Actor *a, int limb); protected: - + byte increaseAnim(Actor *a, int limb); }; class ClassicCostumeRenderer : public BaseCostumeRenderer { -- cgit v1.2.3 From 8d3b27293965ea17a4a34a1258688f9eeb3410d1 Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Sat, 4 Feb 2012 17:35:59 +0100 Subject: SCUMM: save complete v0 state and initialize actors correctly --- engines/scumm/actor.cpp | 19 +++++++++++++++++-- engines/scumm/actor.h | 27 ++++++--------------------- engines/scumm/saveload.cpp | 12 +++++++++++- engines/scumm/saveload.h | 2 +- 4 files changed, 35 insertions(+), 25 deletions(-) (limited to 'engines/scumm') diff --git a/engines/scumm/actor.cpp b/engines/scumm/actor.cpp index f58d3fde4e..59c4110348 100644 --- a/engines/scumm/actor.cpp +++ b/engines/scumm/actor.cpp @@ -175,6 +175,21 @@ void Actor_v2::initActor(int mode) { _talkStopFrame = 4; } +void ActorC64::initActor(int mode) { + Actor_v2::initActor(mode); + + _costCommandNew = 0xFF; + _costCommand = 0xFF; + _miscflags = 0; + _speaking = 0; + + _animFrameRepeat = 0; + for(int i = 0; i < 8; ++i) { + _limbFrameRepeatNew[i] = 0; + _limbFrameRepeat[i] = 0; + _limb_flipped[i] = false; + } +} void Actor::setBox(int box) { _walkbox = box; @@ -2812,11 +2827,11 @@ void ActorC64::saveLoadWithSerializer(Serializer *ser) { static const SaveLoadEntry actorEntries[] = { MKLINE(ActorC64, _costCommand, sleByte, VER(84)), - MKLINE_OLD(ActorC64, _costFrame, sleByte, VER(84), VER(89)), + MK_OBSOLETE(ActorC64, _costFrame, sleByte, VER(84), VER(89)), MKLINE(ActorC64, _miscflags, sleByte, VER(84)), MKLINE(ActorC64, _speaking, sleByte, VER(84)), MK_OBSOLETE(ActorC64, _speakingPrev, sleByte, VER(84), VER(89)), - MK_OBSOLETE(ActorC64, _byte_FD0A, sleByte, VER(89), VER(89)), + MK_OBSOLETE(ActorC64, _limbTemp, sleByte, VER(89), VER(89)), MKLINE(ActorC64, _animFrameRepeat, sleByte, VER(89)), MKARRAY(ActorC64, _limbFrameRepeatNew[0], sleInt8, 8, VER(89)), MKARRAY(ActorC64, _limbFrameRepeat[0], sleInt8, 8, VER(90)), diff --git a/engines/scumm/actor.h b/engines/scumm/actor.h index c2ffcf1275..9e4955c079 100644 --- a/engines/scumm/actor.h +++ b/engines/scumm/actor.h @@ -348,36 +348,21 @@ enum ActorC64MiscFlags { class ActorC64 : public Actor_v2 { public: - byte _costCommandNew, _costCommand, _costFrame; + byte _costCommandNew; + byte _costCommand; byte _miscflags; byte _speaking; int8 _animFrameRepeat; - int8 _limbFrameRepeatNew[8], _limbFrameRepeat[8]; + int8 _limbFrameRepeatNew[8]; + int8 _limbFrameRepeat[8]; bool _limb_flipped[8]; public: - ActorC64(ScummEngine *scumm, int id) : Actor_v2(scumm, id) { - _costCommand = 0xFF; - _speaking = 0; - _animFrameRepeat = 0; - _costCommandNew = 0xFF; - - for(int i = 0; i < 8; ++i) { - _limbFrameRepeatNew[i] = 0; - _limbFrameRepeat[i] = 0; - _limb_flipped[i] = false; - } - } - - virtual void initActor(int mode) { - Actor_v2::initActor(mode); - if (mode == -1) { - _miscflags = 0; - } - } + ActorC64(ScummEngine *scumm, int id) : Actor_v2(scumm, id) {} + virtual void initActor(int mode); virtual void animateActor(int anim); virtual void animateCostume(); diff --git a/engines/scumm/saveload.cpp b/engines/scumm/saveload.cpp index a1b2fafa86..6e54377199 100644 --- a/engines/scumm/saveload.cpp +++ b/engines/scumm/saveload.cpp @@ -1210,10 +1210,12 @@ void ScummEngine::saveOrLoad(Serializer *s) { // Since roughly v13 of the save games, the objs storage has changed a bit for (i = _numObjectsInRoom; i < _numLocalObjects; i++) _objs[i].obj_nr = 0; - } else if (_game.version == 0) { // TODO: handle this correctly + } else if (_game.version == 0 && s->getVersion() < VER(91)) { for (i = 0; i < _numLocalObjects; i++) { + // Merge object id and type (previously stored in flags) if (_objs[i].obj_nr != 0 && OBJECT_V0_TYPE(_objs[i].obj_nr) == 0 && _objs[i].flags != 0) _objs[i].obj_nr = OBJECT_V0(_objs[i].obj_nr, _objs[i].flags); + _objs[i].flags = 0; } } } @@ -1502,6 +1504,14 @@ void ScummEngine_v0::saveOrLoad(Serializer *s) { const SaveLoadEntry v0Entrys[] = { MKLINE(ScummEngine_v0, _currentMode, sleByte, VER(78)), MKLINE(ScummEngine_v0, _currentLights, sleByte, VER(78)), + MKLINE(ScummEngine_v0, _activeVerb, sleByte, VER(92)), + MKLINE(ScummEngine_v0, _activeObject, sleUint16, VER(92)), + MKLINE(ScummEngine_v0, _activeObject2, sleUint16, VER(92)), + MKLINE(ScummEngine_v0, _cmdVerb, sleByte, VER(92)), + MKLINE(ScummEngine_v0, _cmdObject, sleUint16, VER(92)), + MKLINE(ScummEngine_v0, _cmdObject2, sleUint16, VER(92)), + MKLINE(ScummEngine_v0, _walkToObject, sleUint16, VER(92)), + MKLINE(ScummEngine_v0, _walkToObjectState, sleByte, VER(92)), MKEND() }; s->saveLoadEntries(this, v0Entrys); diff --git a/engines/scumm/saveload.h b/engines/scumm/saveload.h index a316670e3d..90feee6dc0 100644 --- a/engines/scumm/saveload.h +++ b/engines/scumm/saveload.h @@ -47,7 +47,7 @@ namespace Scumm { * only saves/loads those which are valid for the version of the savegame * which is being loaded/saved currently. */ -#define CURRENT_VER 91 +#define CURRENT_VER 92 /** * An auxillary macro, used to specify savegame versions. We use this instead -- cgit v1.2.3 From 9dd6105ce62210509207dc61607543b7bcf5639d Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Sat, 4 Feb 2012 18:34:08 +0100 Subject: SCUMM: replace "c64" with "v0" when it applies to both C64 and AppleII v0 versions In addition some routines (e.g. the gfx ones) that are even used in v1. --- engines/scumm/actor.cpp | 52 ++++++++++++++-------------- engines/scumm/actor.h | 6 ++-- engines/scumm/boxes.cpp | 26 +++++++------- engines/scumm/boxes.h | 2 +- engines/scumm/charset-fontdata.cpp | 2 +- engines/scumm/costume.cpp | 28 +++++++-------- engines/scumm/costume.h | 10 +++--- engines/scumm/gfx.cpp | 70 +++++++++++++++++++------------------- engines/scumm/gfx.h | 12 +++---- engines/scumm/object.cpp | 4 +-- engines/scumm/room.cpp | 2 +- engines/scumm/script.cpp | 4 +-- engines/scumm/script_v0.cpp | 24 ++++++------- engines/scumm/script_v2.cpp | 2 +- engines/scumm/scumm.cpp | 8 ++--- engines/scumm/scumm_v0.h | 6 ++-- engines/scumm/verbs.cpp | 4 +-- 17 files changed, 131 insertions(+), 131 deletions(-) (limited to 'engines/scumm') diff --git a/engines/scumm/actor.cpp b/engines/scumm/actor.cpp index 59c4110348..ee655dec33 100644 --- a/engines/scumm/actor.cpp +++ b/engines/scumm/actor.cpp @@ -175,7 +175,7 @@ void Actor_v2::initActor(int mode) { _talkStopFrame = 4; } -void ActorC64::initActor(int mode) { +void Actor_v0::initActor(int mode) { Actor_v2::initActor(mode); _costCommandNew = 0xFF; @@ -251,7 +251,7 @@ void Actor::stopActorMoving() { _moving = 0; if(_vm->_game.version == 0) - ((ActorC64 *)this)->setDirection(_facing); + ((Actor_v0 *)this)->setDirection(_facing); } void Actor::setActorWalkSpeed(uint newSpeedX, uint newSpeedY) { @@ -340,7 +340,7 @@ int Actor::actorWalkStep() { int nextFacing; if(_vm->_game.version == 0) - ((ActorC64 *)this)->_animFrameRepeat = -1; + ((Actor_v0 *)this)->_animFrameRepeat = -1; _needRedraw = true; @@ -584,7 +584,7 @@ void Actor_v2::walkActor() { actorWalkStep(); if(_vm->_game.version == 0) - ((ActorC64 *)this)->animateActor(newDirToOldDir(_facing)); + ((Actor_v0 *)this)->animateActor(newDirToOldDir(_facing)); } else { if (_moving & MF_LAST_LEG) { _moving = 0; @@ -805,7 +805,7 @@ int Actor::remapDirection(int dir, bool is_walking) { return 180; } - // MM C64 stores flags as a part of the mask + // MM v0 stores flags as a part of the mask if (_vm->_game.version == 0) { mask = _vm->getMaskFromBox(_walkbox); // face the wall if climbing/descending a ladder @@ -893,7 +893,7 @@ void Actor::setDirection(int direction) { _needRedraw = true; } -void ActorC64::setDirection(int direction) { +void Actor_v0::setDirection(int direction) { int dir = newDirToOldDir( direction ); int res = 0; @@ -1329,7 +1329,7 @@ void Actor::showActor() { _vm->ensureResourceLoaded(rtCostume, _costume); if (_vm->_game.version == 0) { - ActorC64 *a = ((ActorC64 *)this); + Actor_v0 *a = ((Actor_v0 *)this); a->_costCommand = a->_costCommandNew = 0xFF; @@ -1556,7 +1556,7 @@ void ScummEngine::processActors() { if (_game.version == 0) { // 0x057B - ActorC64 *A = (ActorC64*) a; + Actor_v0 *A = (Actor_v0*) a; if (A->_speaking & 1) A->_speaking ^= 0xFE; @@ -1869,7 +1869,7 @@ void Actor::startAnimActor(int f) { } } -void ActorC64::startAnimActor(int f) { +void Actor_v0::startAnimActor(int f) { if (f == _talkStartFrame) { if (v0ActorTalkArray[_number] & 0x40) return; @@ -1952,7 +1952,7 @@ void Actor::animateCostume() { } } -void ActorC64::limbFrameCheck(int limb) { +void Actor_v0::limbFrameCheck(int limb) { if (_cost.frame[limb] == 0xFFFF) return; @@ -1965,20 +1965,20 @@ void ActorC64::limbFrameCheck(int limb) { _limbFrameRepeat[limb] = _limbFrameRepeatNew[limb]; // 0x25C3 - _cost.active[limb] = ((C64CostumeLoader*)_vm->_costumeLoader)->getFrame(this, limb); + _cost.active[limb] = ((V0CostumeLoader*)_vm->_costumeLoader)->getFrame(this, limb); _cost.curpos[limb] = 0; _needRedraw = true; } -void ActorC64::animateCostume() { +void Actor_v0::animateCostume() { speakCheck(); if (_vm->_costumeLoader->increaseAnims(this)) _needRedraw = true; } -void ActorC64::speakCheck() { +void Actor_v0::speakCheck() { if (v0ActorTalkArray[_number] & 0x80) return; @@ -2146,7 +2146,7 @@ void ScummEngine::setTalkingActor(int i) { VAR(VAR_TALK_ACTOR) = i; } -static const int c64MMActorTalkColor[25] = { +static const int v0MMActorTalkColor[25] = { 1, 7, 2, 14, 8, 15, 3, 7, 7, 15, 1, 13, 1, 4, 5, 5, 4, 3, 1, 5, 1, 1, 1, 1, 7 }; static const int v1MMActorTalkColor[25] = { @@ -2158,7 +2158,7 @@ void ScummEngine::resetV1ActorTalkColor() { for (i = 1; i < _numActors; i++) { if (_game.version == 0) { - _actors[i]->_talkColor = c64MMActorTalkColor[i]; + _actors[i]->_talkColor = v0MMActorTalkColor[i]; } else { _actors[i]->_talkColor = v1MMActorTalkColor[i]; } @@ -2777,7 +2777,7 @@ void ScummEngine_v71he::queueAuxEntry(int actorNum, int subIndex) { } #endif -void ActorC64::animateActor(int anim) { +void Actor_v0::animateActor(int anim) { int dir = -1; switch (anim) { @@ -2822,19 +2822,19 @@ void ActorC64::animateActor(int anim) { } } -void ActorC64::saveLoadWithSerializer(Serializer *ser) { +void Actor_v0::saveLoadWithSerializer(Serializer *ser) { Actor::saveLoadWithSerializer(ser); static const SaveLoadEntry actorEntries[] = { - MKLINE(ActorC64, _costCommand, sleByte, VER(84)), - MK_OBSOLETE(ActorC64, _costFrame, sleByte, VER(84), VER(89)), - MKLINE(ActorC64, _miscflags, sleByte, VER(84)), - MKLINE(ActorC64, _speaking, sleByte, VER(84)), - MK_OBSOLETE(ActorC64, _speakingPrev, sleByte, VER(84), VER(89)), - MK_OBSOLETE(ActorC64, _limbTemp, sleByte, VER(89), VER(89)), - MKLINE(ActorC64, _animFrameRepeat, sleByte, VER(89)), - MKARRAY(ActorC64, _limbFrameRepeatNew[0], sleInt8, 8, VER(89)), - MKARRAY(ActorC64, _limbFrameRepeat[0], sleInt8, 8, VER(90)), + MKLINE(Actor_v0, _costCommand, sleByte, VER(84)), + MK_OBSOLETE(Actor_v0, _costFrame, sleByte, VER(84), VER(89)), + MKLINE(Actor_v0, _miscflags, sleByte, VER(84)), + MKLINE(Actor_v0, _speaking, sleByte, VER(84)), + MK_OBSOLETE(Actor_v0, _speakingPrev, sleByte, VER(84), VER(89)), + MK_OBSOLETE(Actor_v0, _limbTemp, sleByte, VER(89), VER(89)), + MKLINE(Actor_v0, _animFrameRepeat, sleByte, VER(89)), + MKARRAY(Actor_v0, _limbFrameRepeatNew[0], sleInt8, 8, VER(89)), + MKARRAY(Actor_v0, _limbFrameRepeat[0], sleInt8, 8, VER(90)), MKEND() }; diff --git a/engines/scumm/actor.h b/engines/scumm/actor.h index 9e4955c079..69cfbfe398 100644 --- a/engines/scumm/actor.h +++ b/engines/scumm/actor.h @@ -335,7 +335,7 @@ protected: virtual void prepareDrawActorCostume(BaseCostumeRenderer *bcr); }; -enum ActorC64MiscFlags { +enum ActorV0MiscFlags { kActorMiscFlagStrong = 0x01, // Kid is strong (Hunk-O-Matic used) kActorMiscFlagGTFriend = 0x02, // Kid is green tentacle's friend (recording contract) kActorMiscFlagWatchedTV = 0x04, // Kid knows publisher's address (watched TV) @@ -346,7 +346,7 @@ enum ActorC64MiscFlags { kActorMiscFlagHide = 0x80 // Kid is invisible (dead or in radiation suit) }; -class ActorC64 : public Actor_v2 { +class Actor_v0 : public Actor_v2 { public: byte _costCommandNew; byte _costCommand; @@ -360,7 +360,7 @@ public: bool _limb_flipped[8]; public: - ActorC64(ScummEngine *scumm, int id) : Actor_v2(scumm, id) {} + Actor_v0(ScummEngine *scumm, int id) : Actor_v2(scumm, id) {} virtual void initActor(int mode); virtual void animateActor(int anim); diff --git a/engines/scumm/boxes.cpp b/engines/scumm/boxes.cpp index 64d4d7422c..f6d2a18f38 100644 --- a/engines/scumm/boxes.cpp +++ b/engines/scumm/boxes.cpp @@ -42,7 +42,7 @@ struct Box { /* Internal walkbox file format */ byte y1; byte y2; byte mask; - } c64; + } v0; struct { byte uy; @@ -181,7 +181,7 @@ byte ScummEngine::getMaskFromBox(int box) { if (_game.version == 8) return (byte) FROM_LE_32(ptr->v8.mask); else if (_game.version == 0) - return ptr->c64.mask; + return ptr->v0.mask; else if (_game.version <= 2) return ptr->v2.mask; else @@ -479,7 +479,7 @@ Box *ScummEngine::getBoxBaseAddr(int box) { assertRange(0, box, ptr[0] - 1, "box"); if (_game.version == 0) - return (Box *)(ptr + box * SIZEOF_BOX_C64 + 1); + return (Box *)(ptr + box * SIZEOF_BOX_V0 + 1); else if (_game.version <= 2) return (Box *)(ptr + box * SIZEOF_BOX_V2 + 1); else if (_game.version == 3) @@ -602,19 +602,19 @@ BoxCoords ScummEngine::getBoxCoordinates(int boxnum) { SWAP(box->ll, box->lr); } } else if (_game.version == 0) { - box->ul.x = bp->c64.x1; - box->ul.y = bp->c64.y1; - box->ur.x = bp->c64.x2; - box->ur.y = bp->c64.y1; + box->ul.x = bp->v0.x1; + box->ul.y = bp->v0.y1; + box->ur.x = bp->v0.x2; + box->ur.y = bp->v0.y1; - box->ll.x = bp->c64.x1; - box->ll.y = bp->c64.y2; - box->lr.x = bp->c64.x2; - box->lr.y = bp->c64.y2; + box->ll.x = bp->v0.x1; + box->ll.y = bp->v0.y2; + box->lr.x = bp->v0.x2; + box->lr.y = bp->v0.y2; - if ((bp->c64.mask & 0x88) == 0x88) { + if ((bp->v0.mask & 0x88) == 0x88) { // walkbox for (right/left) corner - if (bp->c64.mask & 0x04) + if (bp->v0.mask & 0x04) box->ur = box->ul; else box->ul = box->ur; diff --git a/engines/scumm/boxes.h b/engines/scumm/boxes.h index e554aea1b5..345d6a9d36 100644 --- a/engines/scumm/boxes.h +++ b/engines/scumm/boxes.h @@ -27,7 +27,7 @@ namespace Scumm { -#define SIZEOF_BOX_C64 5 +#define SIZEOF_BOX_V0 5 #define SIZEOF_BOX_V2 8 #define SIZEOF_BOX_V3 18 #define SIZEOF_BOX 20 diff --git a/engines/scumm/charset-fontdata.cpp b/engines/scumm/charset-fontdata.cpp index 29465584f8..16193f5503 100644 --- a/engines/scumm/charset-fontdata.cpp +++ b/engines/scumm/charset-fontdata.cpp @@ -420,7 +420,7 @@ static const byte germanCharsetDataV2[] = { 126, 10, }; -// German C64 MM. +// German v0 MM. static const byte germanCharsetDataV0[] = { 36, 11, 42, 12, diff --git a/engines/scumm/costume.cpp b/engines/scumm/costume.cpp index 9fe5296546..da6c1a2ae4 100644 --- a/engines/scumm/costume.cpp +++ b/engines/scumm/costume.cpp @@ -1163,7 +1163,7 @@ byte NESCostumeLoader::increaseAnim(Actor *a, int slot) { return (a->_cost.curpos[slot] != oldframe); } -static const byte actorColorsMMC64[25] = { +static const byte actorV0Colors[25] = { 0, 7, 2, 6, 9, 1, 3, 7, 7, 1, 1, 9, 1, 4, 5, 5, 4, 1, 0, 5, 4, 2, 2, 7, 7 }; @@ -1178,8 +1178,8 @@ static const byte actorColorsMMC64[25] = { dst[p + 1] = palette[pcolor]; \ } -byte C64CostumeRenderer::drawLimb(const Actor *a, int limb) { - const ActorC64* A = (const ActorC64 *)a; +byte V0CostumeRenderer::drawLimb(const Actor *a, int limb) { + const Actor_v0* A = (const Actor_v0 *)a; if (limb >= 8) return 0; @@ -1207,7 +1207,7 @@ byte C64CostumeRenderer::drawLimb(const Actor *a, int limb) { byte palette[4] = { 0, 0, 0, 0 }; if (_vm->getCurrentLights() & LIGHTMODE_actor_use_colors) { palette[1] = 10; - palette[2] = actorColorsMMC64[_actorID]; + palette[2] = actorV0Colors[_actorID]; } else { palette[2] = 11; palette[3] = 11; @@ -1261,11 +1261,11 @@ byte C64CostumeRenderer::drawLimb(const Actor *a, int limb) { #undef LINE #undef MASK_AT -void C64CostumeRenderer::setCostume(int costume, int shadow) { +void V0CostumeRenderer::setCostume(int costume, int shadow) { _loaded.loadCostume(costume); } -void C64CostumeLoader::loadCostume(int id) { +void V0CostumeLoader::loadCostume(int id) { const byte *ptr = _vm->getResourceAddress(rtCostume, id); _id = id; @@ -1275,15 +1275,15 @@ void C64CostumeLoader::loadCostume(int id) { _numColors = 0; _numAnim = 0; _mirror = 0; - _palette = &actorColorsMMC64[id]; + _palette = &actorV0Colors[id]; _frameOffsets = _baseptr + READ_LE_UINT16(ptr + 5); _dataOffsets = ptr; _animCmds = _baseptr + READ_LE_UINT16(ptr + 7); } -void C64CostumeLoader::costumeDecodeData(Actor *a, int frame, uint usemask) { - ActorC64 *A = (ActorC64 *)a; +void V0CostumeLoader::costumeDecodeData(Actor *a, int frame, uint usemask) { + Actor_v0 *A = (Actor_v0 *)a; if(!a->_costume) return; @@ -1337,15 +1337,15 @@ void C64CostumeLoader::costumeDecodeData(Actor *a, int frame, uint usemask) { } } -byte C64CostumeLoader::getFrame(Actor *a, int limb) { +byte V0CostumeLoader::getFrame(Actor *a, int limb) { loadCostume(a->_costume); // Get the frame number for the current limb / Command return _frameOffsets[_frameOffsets[limb] + a->_cost.start[limb]]; } -byte C64CostumeLoader::increaseAnims(Actor *a) { - ActorC64 *A = (ActorC64 *)a; +byte V0CostumeLoader::increaseAnims(Actor *a) { + Actor_v0 *A = (Actor_v0 *)a; int i; byte r = 0; @@ -1356,8 +1356,8 @@ byte C64CostumeLoader::increaseAnims(Actor *a) { return r; } -byte C64CostumeLoader::increaseAnim(Actor *a, int limb) { - ActorC64 *A = (ActorC64 *)a; +byte V0CostumeLoader::increaseAnim(Actor *a, int limb) { + Actor_v0 *A = (Actor_v0 *)a; const uint16 limbPrevious = a->_cost.curpos[limb]++; loadCostume(a->_costume); diff --git a/engines/scumm/costume.h b/engines/scumm/costume.h index 16317cb1c9..4a21692ddb 100644 --- a/engines/scumm/costume.h +++ b/engines/scumm/costume.h @@ -67,9 +67,9 @@ protected: byte increaseAnim(Actor *a, int slot); }; -class C64CostumeLoader : public ClassicCostumeLoader { +class V0CostumeLoader : public ClassicCostumeLoader { public: - C64CostumeLoader(ScummEngine *vm) : ClassicCostumeLoader(vm) {} + V0CostumeLoader(ScummEngine *vm) : ClassicCostumeLoader(vm) {} void loadCostume(int id); void costumeDecodeData(Actor *a, int frame, uint usemask); byte increaseAnims(Actor *a); @@ -131,12 +131,12 @@ public: }; #endif -class C64CostumeRenderer : public BaseCostumeRenderer { +class V0CostumeRenderer : public BaseCostumeRenderer { protected: - C64CostumeLoader _loaded; + V0CostumeLoader _loaded; public: - C64CostumeRenderer(ScummEngine *vm) : BaseCostumeRenderer(vm), _loaded(vm) {} + V0CostumeRenderer(ScummEngine *vm) : BaseCostumeRenderer(vm), _loaded(vm) {} void setPalette(uint16 *palette) {} void setFacing(const Actor *a) {} diff --git a/engines/scumm/gfx.cpp b/engines/scumm/gfx.cpp index a6b8377d2f..bc6cfc761e 100644 --- a/engines/scumm/gfx.cpp +++ b/engines/scumm/gfx.cpp @@ -240,7 +240,7 @@ GdiPCEngine::~GdiPCEngine() { #endif GdiV1::GdiV1(ScummEngine *vm) : Gdi(vm) { - memset(&_C64, 0, sizeof(_C64)); + memset(&_V1, 0, sizeof(_V1)); } GdiV2::GdiV2(ScummEngine *vm) : Gdi(vm) { @@ -297,17 +297,17 @@ void GdiPCEngine::loadTiles(byte *roomptr) { void GdiV1::roomChanged(byte *roomptr) { for (int i = 0; i < 4; i++){ - _C64.colors[i] = roomptr[6 + i]; + _V1.colors[i] = roomptr[6 + i]; } - decodeC64Gfx(roomptr + READ_LE_UINT16(roomptr + 10), _C64.charMap, 2048); - decodeC64Gfx(roomptr + READ_LE_UINT16(roomptr + 12), _C64.picMap, roomptr[4] * roomptr[5]); - decodeC64Gfx(roomptr + READ_LE_UINT16(roomptr + 14), _C64.colorMap, roomptr[4] * roomptr[5]); - decodeC64Gfx(roomptr + READ_LE_UINT16(roomptr + 16), _C64.maskMap, roomptr[4] * roomptr[5]); + decodeV1Gfx(roomptr + READ_LE_UINT16(roomptr + 10), _V1.charMap, 2048); + decodeV1Gfx(roomptr + READ_LE_UINT16(roomptr + 12), _V1.picMap, roomptr[4] * roomptr[5]); + decodeV1Gfx(roomptr + READ_LE_UINT16(roomptr + 14), _V1.colorMap, roomptr[4] * roomptr[5]); + decodeV1Gfx(roomptr + READ_LE_UINT16(roomptr + 16), _V1.maskMap, roomptr[4] * roomptr[5]); // Read the mask data. The 16bit length value seems to always be 8 too big. // See bug #1837375 for details on this. const byte *maskPtr = roomptr + READ_LE_UINT16(roomptr + 18); - decodeC64Gfx(maskPtr + 2, _C64.maskChar, READ_LE_UINT16(maskPtr) - 8); + decodeV1Gfx(maskPtr + 2, _V1.maskChar, READ_LE_UINT16(maskPtr) - 8); _objectMode = true; } @@ -1541,7 +1541,7 @@ void GdiV1::prepareDrawBitmap(const byte *ptr, VirtScreen *vs, const int x, const int y, const int width, const int height, int stripnr, int numstrip) { if (_objectMode) { - decodeC64Gfx(ptr, _C64.objectMap, (width / 8) * (height / 8) * 3); + decodeV1Gfx(ptr, _V1.objectMap, (width / 8) * (height / 8) * 3); } } @@ -1928,9 +1928,9 @@ bool GdiPCEngine::drawStrip(byte *dstPtr, VirtScreen *vs, int x, int y, const in bool GdiV1::drawStrip(byte *dstPtr, VirtScreen *vs, int x, int y, const int width, const int height, int stripnr, const byte *smap_ptr) { if (_objectMode) - drawStripC64Object(dstPtr, vs->pitch, stripnr, width, height); + drawStripV1Object(dstPtr, vs->pitch, stripnr, width, height); else - drawStripC64Background(dstPtr, vs->pitch, stripnr, height); + drawStripV1Background(dstPtr, vs->pitch, stripnr, height); return false; } @@ -2071,7 +2071,7 @@ void GdiV1::decodeMask(int x, int y, const int width, const int height, int stripnr, int numzbuf, const byte *zplane_list[9], bool transpStrip, byte flag) { byte *mask_ptr = getMaskBuffer(x, y, 1); - drawStripC64Mask(mask_ptr, stripnr, width, height); + drawStripV1Mask(mask_ptr, stripnr, width, height); } void GdiV2::decodeMask(int x, int y, const int width, const int height, @@ -3089,67 +3089,67 @@ void GdiPCEngine::drawStripPCEngineMask(byte *dst, int stripnr, int top, int hei } #endif -void GdiV1::drawStripC64Background(byte *dst, int dstPitch, int stripnr, int height) { +void GdiV1::drawStripV1Background(byte *dst, int dstPitch, int stripnr, int height) { int charIdx; height /= 8; for (int y = 0; y < height; y++) { - _C64.colors[3] = (_C64.colorMap[y + stripnr * height] & 7); + _V1.colors[3] = (_V1.colorMap[y + stripnr * height] & 7); // Check for room color change in V1 zak if (_roomPalette[0] == 255) { - _C64.colors[2] = _roomPalette[2]; - _C64.colors[1] = _roomPalette[1]; + _V1.colors[2] = _roomPalette[2]; + _V1.colors[1] = _roomPalette[1]; } - charIdx = _C64.picMap[y + stripnr * height] * 8; + charIdx = _V1.picMap[y + stripnr * height] * 8; for (int i = 0; i < 8; i++) { - byte c = _C64.charMap[charIdx + i]; - dst[0] = dst[1] = _C64.colors[(c >> 6) & 3]; - dst[2] = dst[3] = _C64.colors[(c >> 4) & 3]; - dst[4] = dst[5] = _C64.colors[(c >> 2) & 3]; - dst[6] = dst[7] = _C64.colors[(c >> 0) & 3]; + byte c = _V1.charMap[charIdx + i]; + dst[0] = dst[1] = _V1.colors[(c >> 6) & 3]; + dst[2] = dst[3] = _V1.colors[(c >> 4) & 3]; + dst[4] = dst[5] = _V1.colors[(c >> 2) & 3]; + dst[6] = dst[7] = _V1.colors[(c >> 0) & 3]; dst += dstPitch; } } } -void GdiV1::drawStripC64Object(byte *dst, int dstPitch, int stripnr, int width, int height) { +void GdiV1::drawStripV1Object(byte *dst, int dstPitch, int stripnr, int width, int height) { int charIdx; height /= 8; width /= 8; for (int y = 0; y < height; y++) { - _C64.colors[3] = (_C64.objectMap[(y + height) * width + stripnr] & 7); - charIdx = _C64.objectMap[y * width + stripnr] * 8; + _V1.colors[3] = (_V1.objectMap[(y + height) * width + stripnr] & 7); + charIdx = _V1.objectMap[y * width + stripnr] * 8; for (int i = 0; i < 8; i++) { - byte c = _C64.charMap[charIdx + i]; - dst[0] = dst[1] = _C64.colors[(c >> 6) & 3]; - dst[2] = dst[3] = _C64.colors[(c >> 4) & 3]; - dst[4] = dst[5] = _C64.colors[(c >> 2) & 3]; - dst[6] = dst[7] = _C64.colors[(c >> 0) & 3]; + byte c = _V1.charMap[charIdx + i]; + dst[0] = dst[1] = _V1.colors[(c >> 6) & 3]; + dst[2] = dst[3] = _V1.colors[(c >> 4) & 3]; + dst[4] = dst[5] = _V1.colors[(c >> 2) & 3]; + dst[6] = dst[7] = _V1.colors[(c >> 0) & 3]; dst += dstPitch; } } } -void GdiV1::drawStripC64Mask(byte *dst, int stripnr, int width, int height) const { +void GdiV1::drawStripV1Mask(byte *dst, int stripnr, int width, int height) const { int maskIdx; height /= 8; width /= 8; for (int y = 0; y < height; y++) { if (_objectMode) - maskIdx = _C64.objectMap[(y + 2 * height) * width + stripnr] * 8; + maskIdx = _V1.objectMap[(y + 2 * height) * width + stripnr] * 8; else - maskIdx = _C64.maskMap[y + stripnr * height] * 8; + maskIdx = _V1.maskMap[y + stripnr * height] * 8; for (int i = 0; i < 8; i++) { - byte c = _C64.maskChar[maskIdx + i]; + byte c = _V1.maskChar[maskIdx + i]; - // V1/C64 masks are inverted compared to what ScummVM expects + // V1/V0 masks are inverted compared to what ScummVM expects *dst = c ^ 0xFF; dst += _numStrips; } } } -void GdiV1::decodeC64Gfx(const byte *src, byte *dst, int size) const { +void GdiV1::decodeV1Gfx(const byte *src, byte *dst, int size) const { int x, z; byte color, run, common[4]; diff --git a/engines/scumm/gfx.h b/engines/scumm/gfx.h index 4b44ddc376..0d81698c50 100644 --- a/engines/scumm/gfx.h +++ b/engines/scumm/gfx.h @@ -375,19 +375,19 @@ public: class GdiV1 : public Gdi { protected: - /** Render settings which are specific to the C64 graphic decoders. */ + /** Render settings which are specific to the v0/v1 graphic decoders. */ struct { byte colors[4]; byte charMap[2048], objectMap[2048], picMap[4096], colorMap[4096]; byte maskMap[4096], maskChar[4096]; - } _C64; + } _V1; protected: - void decodeC64Gfx(const byte *src, byte *dst, int size) const; + void decodeV1Gfx(const byte *src, byte *dst, int size) const; - void drawStripC64Object(byte *dst, int dstPitch, int stripnr, int width, int height); - void drawStripC64Background(byte *dst, int dstPitch, int stripnr, int height); - void drawStripC64Mask(byte *dst, int stripnr, int width, int height) const; + void drawStripV1Object(byte *dst, int dstPitch, int stripnr, int width, int height); + void drawStripV1Background(byte *dst, int dstPitch, int stripnr, int height); + void drawStripV1Mask(byte *dst, int stripnr, int width, int height) const; virtual bool drawStrip(byte *dstPtr, VirtScreen *vs, int x, int y, const int width, const int height, diff --git a/engines/scumm/object.cpp b/engines/scumm/object.cpp index 4ef8707714..e38552c8f3 100644 --- a/engines/scumm/object.cpp +++ b/engines/scumm/object.cpp @@ -327,7 +327,7 @@ int ScummEngine::getObjectIndex(int object) const { int ScummEngine::whereIsObject(int object) const { int i; - // Note: in MMC64 bg objects are greater _numGlobalObjects + // Note: in MM v0 bg objects are greater _numGlobalObjects if (_game.version != 0 && object >= _numGlobalObjects) return WIO_NOT_FOUND; @@ -808,7 +808,7 @@ void ScummEngine_v3old::resetRoomObjects() { else ptr = room + 29; - // Default pointer of objects without image, in C64 verison of Maniac Mansion + // Default pointer of objects without image, in v0 version of Maniac Mansion int defaultPtr = READ_LE_UINT16(ptr + 2 * _numObjectsInRoom); for (i = 0; i < _numObjectsInRoom; i++) { diff --git a/engines/scumm/room.cpp b/engines/scumm/room.cpp index 63cbef8944..9ee8fb93a9 100644 --- a/engines/scumm/room.cpp +++ b/engines/scumm/room.cpp @@ -747,7 +747,7 @@ void ScummEngine_v3old::resetRoomSubBlocks() { } ptr = roomptr + *(roomptr + 0x15); - size = numOfBoxes * SIZEOF_BOX_C64 + 1; + size = numOfBoxes * SIZEOF_BOX_V0 + 1; _res->createResource(rtMatrix, 2, size + 1); getResourceAddress(rtMatrix, 2)[0] = numOfBoxes; diff --git a/engines/scumm/script.cpp b/engines/scumm/script.cpp index 3bd70d0e24..39420ee974 100644 --- a/engines/scumm/script.cpp +++ b/engines/scumm/script.cpp @@ -1132,7 +1132,7 @@ void ScummEngine::checkAndRunSentenceScript() { void ScummEngine_v0::walkToActorOrObject(int object) { int x, y, dir; - ActorC64 *a = (ActorC64 *)derefActor(VAR(VAR_EGO), "walkToObject"); + Actor_v0 *a = (Actor_v0 *)derefActor(VAR(VAR_EGO), "walkToObject"); _walkToObject = object; _walkToObjectState = kWalkToObjectStateWalk; @@ -1162,7 +1162,7 @@ bool ScummEngine_v0::checkPendingWalkAction() { return false; int actor = VAR(VAR_EGO); - ActorC64 *a = (ActorC64 *)derefActor(actor, "checkPendingWalkAction"); + Actor_v0 *a = (Actor_v0 *)derefActor(actor, "checkPendingWalkAction"); // wait until walking or turning action is finished if (a->_moving) diff --git a/engines/scumm/script_v0.cpp b/engines/scumm/script_v0.cpp index 07be151ce2..45901186cd 100644 --- a/engines/scumm/script_v0.cpp +++ b/engines/scumm/script_v0.cpp @@ -51,7 +51,7 @@ void ScummEngine_v0::setupOpcodes() { OPCODE(0x0b, o_setActorBitVar); /* 0C */ OPCODE(0x0c, o_loadSound); - OPCODE(0x0d, o_printEgo_c64); + OPCODE(0x0d, o_printEgo); OPCODE(0x0e, o_putActorAtObject); OPCODE(0x0f, o2_clearState02); /* 10 */ @@ -60,7 +60,7 @@ void ScummEngine_v0::setupOpcodes() { OPCODE(0x12, o2_panCameraTo); OPCODE(0x13, o_lockCostume); /* 14 */ - OPCODE(0x14, o_print_c64); + OPCODE(0x14, o_print); OPCODE(0x15, o5_walkActorToActor); OPCODE(0x16, o5_getRandomNr); OPCODE(0x17, o2_clearState08); @@ -92,7 +92,7 @@ void ScummEngine_v0::setupOpcodes() { /* 2C */ OPCODE(0x2c, o_stopCurrentScript); OPCODE(0x2d, o2_putActorInRoom); - OPCODE(0x2e, o_print_c64); + OPCODE(0x2e, o_print); OPCODE(0x2f, o2_ifState08); /* 30 */ OPCODE(0x30, o_loadCostume); @@ -181,7 +181,7 @@ void ScummEngine_v0::setupOpcodes() { OPCODE(0x73, o_getObjectOwner); /* 74 */ OPCODE(0x74, o5_getDist); - OPCODE(0x75, o_printEgo_c64); + OPCODE(0x75, o_printEgo); OPCODE(0x76, o_walkActorToObject); OPCODE(0x77, o2_clearState04); /* 78 */ @@ -252,7 +252,7 @@ void ScummEngine_v0::setupOpcodes() { /* AC */ OPCODE(0xac, o_stopCurrentScript); OPCODE(0xad, o2_putActorInRoom); - OPCODE(0xae, o_print_c64); + OPCODE(0xae, o_print); OPCODE(0xaf, o2_ifNotState08); /* B0 */ OPCODE(0xb0, o_loadCostume); @@ -575,13 +575,13 @@ void ScummEngine_v0::o_loadRoom() { } void ScummEngine_v0::o_loadRoomWithEgo() { - ActorC64 *a; + Actor_v0 *a; int obj, room, x, y, dir; obj = fetchScriptByte(); room = fetchScriptByte(); - a = (ActorC64 *)derefActor(VAR(VAR_EGO), "o_loadRoomWithEgo"); + a = (Actor_v0 *)derefActor(VAR(VAR_EGO), "o_loadRoomWithEgo"); //0x634F if (a->_miscflags & kActorMiscFlagFreeze) { @@ -685,7 +685,7 @@ void ScummEngine_v0::o_animateActor() { int anim = getVarOrDirectByte(PARAM_2); int8 repeat = (int8) fetchScriptByte(); - ActorC64 *a = (ActorC64*) derefActor(act, "o_animateActor"); + Actor_v0 *a = (Actor_v0*) derefActor(act, "o_animateActor"); a->_animFrameRepeat = repeat; @@ -789,7 +789,7 @@ void ScummEngine_v0::o_setActorBitVar() { if (act >= _numActors) return; - ActorC64 *a = (ActorC64 *)derefActor(act, "o_setActorBitVar"); + Actor_v0 *a = (Actor_v0 *)derefActor(act, "o_setActorBitVar"); if (mod) a->_miscflags |= mask; @@ -814,7 +814,7 @@ void ScummEngine_v0::o_getActorBitVar() { byte act = getVarOrDirectByte(PARAM_1); byte mask = getVarOrDirectByte(PARAM_2); - ActorC64 *a = (ActorC64 *)derefActor(act, "o_getActorBitVar"); + Actor_v0 *a = (Actor_v0 *)derefActor(act, "o_getActorBitVar"); setResult((a->_miscflags & mask) ? 1 : 0); debug(0, "o_getActorBitVar(%d, %d, %d)", act, mask, (a->_miscflags & mask)); @@ -843,12 +843,12 @@ void ScummEngine_v0::o_getBitVar() { debug(0, "o_getBitVar (%d, %d %d)", flag, mask, _bitVars[flag] & (1 << mask)); } -void ScummEngine_v0::o_print_c64() { +void ScummEngine_v0::o_print() { _actorToPrintStrFor = fetchScriptByte(); decodeParseString(); } -void ScummEngine_v0::o_printEgo_c64() { +void ScummEngine_v0::o_printEgo() { _actorToPrintStrFor = (byte)VAR(VAR_EGO); decodeParseString(); } diff --git a/engines/scumm/script_v2.cpp b/engines/scumm/script_v2.cpp index 1b8dc965e0..9c8742cffd 100644 --- a/engines/scumm/script_v2.cpp +++ b/engines/scumm/script_v2.cpp @@ -401,7 +401,7 @@ void ScummEngine_v2::decodeParseString() { _string[textSlot].overhead = false; if (_game.id == GID_MANIAC && _actorToPrintStrFor == 0xFF) { - if (_game.platform == Common::kPlatformC64) { + if (_game.version == 0) { _string[textSlot].color = 14; } else if (_game.features & GF_DEMO) { _string[textSlot].color = (_game.version == 2) ? 15 : 1; diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp index d8b02d0881..fc46f88df4 100644 --- a/engines/scumm/scumm.cpp +++ b/engines/scumm/scumm.cpp @@ -1025,7 +1025,7 @@ Common::Error ScummEngine::init() { // The kGenUnchanged method is only used for 'container files', i.e. files // that contain the real game files bundled together in an archive format. - // This is the case of the NES, C64 and Mac versions of certain games. + // This is the case of the NES, v0 and Mac versions of certain games. // Note: All of these can also occur in 'extracted' form, in which case they // are treated like any other SCUMM game. if (_filenamePattern.genMethod == kGenUnchanged) { @@ -1379,8 +1379,8 @@ void ScummEngine::setupCostumeRenderer() { _costumeRenderer = new AkosRenderer(this); _costumeLoader = new AkosCostumeLoader(this); } else if (_game.version == 0) { - _costumeRenderer = new C64CostumeRenderer(this); - _costumeLoader = new C64CostumeLoader(this); + _costumeRenderer = new V0CostumeRenderer(this); + _costumeLoader = new V0CostumeLoader(this); } else if (_game.platform == Common::kPlatformNES) { _costumeRenderer = new NESCostumeRenderer(this); _costumeLoader = new NESCostumeLoader(this); @@ -1459,7 +1459,7 @@ void ScummEngine::resetScumm() { _sortedActors = new Actor * [_numActors]; for (i = 0; i < _numActors; ++i) { if (_game.version == 0) - _actors[i] = new ActorC64(this, i); + _actors[i] = new Actor_v0(this, i); else if (_game.version <= 2) _actors[i] = new Actor_v2(this, i); else if (_game.version == 3) diff --git a/engines/scumm/scumm_v0.h b/engines/scumm/scumm_v0.h index 982b62d645..1341b9ed15 100644 --- a/engines/scumm/scumm_v0.h +++ b/engines/scumm/scumm_v0.h @@ -118,7 +118,7 @@ protected: virtual int getCurrentLights() const; - /* Version C64 script opcodes */ + /* Version 0 script opcodes */ void o_stopCurrentScript(); void o_walkActorToObject(); void o_loadSound(); @@ -150,8 +150,8 @@ protected: void o_ifEqualActiveObject2(); void o_ifNotEqualActiveObject2(); void o_getClosestActor(); - void o_printEgo_c64(); - void o_print_c64(); + void o_printEgo(); + void o_print(); void o_unlockRoom(); void o_unlockSound(); void o_cutscene(); diff --git a/engines/scumm/verbs.cpp b/engines/scumm/verbs.cpp index 88a1283067..567ca31485 100644 --- a/engines/scumm/verbs.cpp +++ b/engines/scumm/verbs.cpp @@ -705,7 +705,7 @@ void ScummEngine_v0::verbExec() { return; } - ActorC64 *a = (ActorC64 *)derefActor(VAR(VAR_EGO), "verbExec"); + Actor_v0 *a = (Actor_v0 *)derefActor(VAR(VAR_EGO), "verbExec"); int x = _virtualMouse.x / V12_X_MULTIPLIER; int y = _virtualMouse.y / V12_Y_MULTIPLIER; //actorSetPosInBox(); @@ -730,7 +730,7 @@ bool ScummEngine_v0::checkSentenceComplete() { } void ScummEngine_v0::checkExecVerbs() { - ActorC64 *a = (ActorC64 *)derefActor(VAR(VAR_EGO), "checkExecVerbs"); + Actor_v0 *a = (Actor_v0 *)derefActor(VAR(VAR_EGO), "checkExecVerbs"); VirtScreen *zone = findVirtScreen(_mouse.y); bool execute = false; -- cgit v1.2.3 From 163f698cf0f0f9fb66fd5e782c74d64ea598c953 Mon Sep 17 00:00:00 2001 From: Robert Crossfield Date: Sun, 5 Feb 2012 16:35:44 +1100 Subject: SCUMM: Few changes for animations, dont move while turning & not necessary to call animateactor during startanimactor --- engines/scumm/actor.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'engines/scumm') diff --git a/engines/scumm/actor.cpp b/engines/scumm/actor.cpp index ee655dec33..bcacdc3b5a 100644 --- a/engines/scumm/actor.cpp +++ b/engines/scumm/actor.cpp @@ -350,6 +350,10 @@ int Actor::actorWalkStep() { startWalkAnim(1, nextFacing); } _moving |= MF_IN_LEG; + + // V0: Don't move during the turn + if(_vm->_game.version == 0) + return 0; } if (_walkbox != _walkdata.curbox && _vm->checkXYInBoxBounds(_walkdata.curbox, _pos.x, _pos.y)) { @@ -384,6 +388,10 @@ int Actor::actorWalkStep() { _moving &= ~MF_IN_LEG; return 0; } + + if(_vm->_game.version == 0) + ((Actor_v0 *)this)->animateActor(newDirToOldDir(_facing)); + return 1; } @@ -583,8 +591,6 @@ void Actor_v2::walkActor() { if (_moving & MF_IN_LEG) { actorWalkStep(); - if(_vm->_game.version == 0) - ((Actor_v0 *)this)->animateActor(newDirToOldDir(_facing)); } else { if (_moving & MF_LAST_LEG) { _moving = 0; @@ -1886,8 +1892,8 @@ void Actor_v0::startAnimActor(int f) { if(f == _standFrame) setDirection(_facing); - else - animateActor(newDirToOldDir(_facing)); + //else + // animateActor(newDirToOldDir(_facing)); } void Actor::animateActor(int anim) { -- cgit v1.2.3 From 6c40b3f36f152f05313d19d048193541f91bca6b Mon Sep 17 00:00:00 2001 From: Robert Crossfield Date: Sun, 5 Feb 2012 18:53:50 +1100 Subject: SCUMM: Remove old code --- engines/scumm/actor.cpp | 2 -- 1 file changed, 2 deletions(-) (limited to 'engines/scumm') diff --git a/engines/scumm/actor.cpp b/engines/scumm/actor.cpp index bcacdc3b5a..bc336292dc 100644 --- a/engines/scumm/actor.cpp +++ b/engines/scumm/actor.cpp @@ -1892,8 +1892,6 @@ void Actor_v0::startAnimActor(int f) { if(f == _standFrame) setDirection(_facing); - //else - // animateActor(newDirToOldDir(_facing)); } void Actor::animateActor(int anim) { -- cgit v1.2.3 From ef56bd6de2403e8a5f88ef49933207147b497783 Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Sun, 5 Feb 2012 15:40:52 +0100 Subject: SCUMM: add support for diagonal walking between boxes (e.g. used for meteor opening scene) --- engines/scumm/actor.cpp | 93 ++++++++++++++++++++++++++++++++++++++++++++----- engines/scumm/actor.h | 5 ++- 2 files changed, 89 insertions(+), 9 deletions(-) (limited to 'engines/scumm') diff --git a/engines/scumm/actor.cpp b/engines/scumm/actor.cpp index bc336292dc..1ba0eafc06 100644 --- a/engines/scumm/actor.cpp +++ b/engines/scumm/actor.cpp @@ -567,6 +567,90 @@ void Actor::walkActor() { calcMovementFactor(_walkdata.dest); } +bool Actor_v2::checkWalkboxesHaveDirectPath(Common::Point &foundPath) { + // only MM v0 supports walking in direct line between walkboxes. + // MM v1 already does not support it anymore. + return false; +} + +bool Actor_v0::intersectLineSegments(const Common::Point &line1Start, const Common::Point &line1End, + const Common::Point &line2Start, const Common::Point &line2End, Common::Point &result) +{ + const Common::Point v1 = line1End - line1Start; // line1(n1) = line1Start + n1 * v1 + const Common::Point v2 = line2End - line2Start; // line2(n2) = line2Start + n2 * v2 + + double det = v2.x * v1.y - v1.x * v2.y; + if (det == 0) + return false; + + double n1 = ((double)v2.x * (line2Start.y - line1Start.y) - + (double)v2.y * (line2Start.x - line1Start.x)) / det; + double n2 = ((double)v1.x * (line2Start.y - line1Start.y) - + (double)v1.y * (line2Start.x - line1Start.x)) / det; + + // both coefficients have to be in [0, 1], otherwise the intersection is + // not inside of at least one of the two line segments + if (n1 < 0.0 || n1 > 1.0 || n2 < 0.0 || n2 > 1.0) + return false; + + result.x = line1Start.x + (int)(n1 * v1.x); + result.y = line1Start.y + (int)(n1 * v1.y); + return true; +} + +/* + * MM v0 allows the actor to walk in a direct line between boxes to the target + * if actor and target share a horizontal or vertical corridor. + * If such a corridor is found the actor is not forced to go horizontally or + * vertically from one box to the next but can also walk diagonally. + * + * Note: the original v0 interpreter sets the target destination for diagonal + * walking only once and then rechecks whenever the actor reaches a new box if the + * walk destination is still suitable for the current box. + * ScummVM does not perform such a check, so it is possible to leave the walkboxes + * in some cases, for example L-shaped rooms like the swimming pool (actor walks over water) + * or the medical room (actor walks over examination table). + * To solve this we intersect the new walk destination with the actor's walkbox borders, + * so a recheck is done when the actor leaves his box. This is done by the + * intersectLineSegments() routine calls. + */ +bool Actor_v0::checkWalkboxesHaveDirectPath(Common::Point &foundPath) { + BoxCoords boxCoords = _vm->getBoxCoordinates(_walkbox); + BoxCoords curBoxCoords = _vm->getBoxCoordinates(_walkdata.curbox); + + // check if next walkbox is left or right to actor's box + if (boxCoords.ll.x > curBoxCoords.lr.x || boxCoords.lr.x < curBoxCoords.ll.x) { + // determine horizontal corridor gates + int gateUpper = MAX(boxCoords.ul.y, curBoxCoords.ul.y); + int gateLower = MIN(boxCoords.ll.y, curBoxCoords.ll.y); + + // check if actor and target are in the same horizontal corridor between the boxes + if ((_pos.y >= gateUpper && _pos.y <= gateLower) && + (_walkdata.dest.y >= gateUpper && _walkdata.dest.y <= gateLower)) { + if (boxCoords.ll.x > curBoxCoords.lr.x) // next box is left + return intersectLineSegments(_pos, _walkdata.dest, boxCoords.ll, boxCoords.ul, foundPath); + else // next box is right + return intersectLineSegments(_pos, _walkdata.dest, boxCoords.lr, boxCoords.ur, foundPath); + } + // check if next walkbox is above or below actor's box + } else if (boxCoords.ul.y > curBoxCoords.ll.y || boxCoords.ll.y < curBoxCoords.ul.y) { + // determine vertical corridor gates + int gateLeft = MAX(boxCoords.ll.x, curBoxCoords.ll.x); + int gateRight = MIN(boxCoords.lr.x, curBoxCoords.lr.x); + + // check if actor and target are in the same vertical corridor between the boxes + if ((_pos.x >= gateLeft && _pos.x <= gateRight) && + (_walkdata.dest.x >= gateLeft && _walkdata.dest.x <= gateRight)) { + if (boxCoords.ul.y > curBoxCoords.ll.y) // next box is above + return intersectLineSegments(_pos, _walkdata.dest, boxCoords.ul, boxCoords.ur, foundPath); + else // next box is below + return intersectLineSegments(_pos, _walkdata.dest, boxCoords.ll, boxCoords.lr, foundPath); + } + } + + return false; +} + void Actor_v2::walkActor() { Common::Point foundPath, tmp; int new_dir, next_box; @@ -618,14 +702,7 @@ void Actor_v2::walkActor() { _walkdata.curbox = next_box; - // WORKAROUND: The route of the meteor landing in the introduction isn't correct. - // MM V0 in contrast to MM V2 uses two walkboxes instead of just one. Hence a route - // from walkbox 1 to 0 is calculated first. This causes the meteor to fly on a - // horizontal line to walkbox 0 then vertically to the ground. - // To fix this problem, the box-to-box routing has been disabled in room 33. - if (_vm->_game.version == 0 && _vm->_currentRoom == 33) { - foundPath = _walkdata.dest; - } else { + if (!checkWalkboxesHaveDirectPath(foundPath)) { getClosestPtOnBox(_vm->getBoxCoordinates(_walkdata.curbox), _pos.x, _pos.y, tmp.x, tmp.y); getClosestPtOnBox(_vm->getBoxCoordinates(_walkbox), tmp.x, tmp.y, foundPath.x, foundPath.y); } diff --git a/engines/scumm/actor.h b/engines/scumm/actor.h index 69cfbfe398..0ed239d005 100644 --- a/engines/scumm/actor.h +++ b/engines/scumm/actor.h @@ -333,6 +333,7 @@ public: protected: virtual bool isPlayer(); virtual void prepareDrawActorCostume(BaseCostumeRenderer *bcr); + virtual bool checkWalkboxesHaveDirectPath(Common::Point &foundPath); }; enum ActorV0MiscFlags { @@ -376,7 +377,9 @@ public: virtual void saveLoadWithSerializer(Serializer *ser); protected: - + bool intersectLineSegments(const Common::Point &line1Start, const Common::Point &line1End, + const Common::Point &line2Start, const Common::Point &line2End, Common::Point &result); + virtual bool checkWalkboxesHaveDirectPath(Common::Point &foundPath); }; -- cgit v1.2.3 From 0aabf95cb84620f7b5a84b09ceddf5d46d93323c Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Mon, 6 Feb 2012 08:06:48 +0100 Subject: SCUMM: match style-guide, add missing spaces between some "if ()", "for ()" --- engines/scumm/actor.cpp | 26 +++++++++++++------------- engines/scumm/costume.cpp | 22 +++++++++++----------- engines/scumm/player_pce.cpp | 22 +++++++++++----------- 3 files changed, 35 insertions(+), 35 deletions(-) (limited to 'engines/scumm') diff --git a/engines/scumm/actor.cpp b/engines/scumm/actor.cpp index 1ba0eafc06..3989d0f803 100644 --- a/engines/scumm/actor.cpp +++ b/engines/scumm/actor.cpp @@ -184,7 +184,7 @@ void Actor_v0::initActor(int mode) { _speaking = 0; _animFrameRepeat = 0; - for(int i = 0; i < 8; ++i) { + for (int i = 0; i < 8; ++i) { _limbFrameRepeatNew[i] = 0; _limbFrameRepeat[i] = 0; _limb_flipped[i] = false; @@ -250,7 +250,7 @@ void Actor::stopActorMoving() { _vm->stopScript(_walkScript); _moving = 0; - if(_vm->_game.version == 0) + if (_vm->_game.version == 0) ((Actor_v0 *)this)->setDirection(_facing); } @@ -339,7 +339,7 @@ int Actor::actorWalkStep() { int distX, distY; int nextFacing; - if(_vm->_game.version == 0) + if (_vm->_game.version == 0) ((Actor_v0 *)this)->_animFrameRepeat = -1; _needRedraw = true; @@ -352,7 +352,7 @@ int Actor::actorWalkStep() { _moving |= MF_IN_LEG; // V0: Don't move during the turn - if(_vm->_game.version == 0) + if (_vm->_game.version == 0) return 0; } @@ -389,7 +389,7 @@ int Actor::actorWalkStep() { return 0; } - if(_vm->_game.version == 0) + if (_vm->_game.version == 0) ((Actor_v0 *)this)->animateActor(newDirToOldDir(_facing)); return 1; @@ -1000,7 +1000,7 @@ void Actor_v0::setDirection(int direction) { _animFrameRepeat = -1; animateActor(res); - if(_moving) + if (_moving) animateCostume(); } @@ -1090,7 +1090,7 @@ void Actor::putActor(int dstX, int dstY, int newRoom) { } // V0 always sets the actor to face the camera upon entering a room - if(_vm->_game.version == 0) + if (_vm->_game.version == 0) setDirection(oldDirToNewDir(2)); } @@ -1194,7 +1194,7 @@ static int checkXYInBoxBounds(int boxnum, int x, int y, int &destX, int &destY) int yDist = ABS(y - destY) / 4; int dist; - if(g_scumm->_game.version == 0) + if (g_scumm->_game.version == 0) xDist *= 2; if (xDist < yDist) @@ -1416,7 +1416,7 @@ void Actor::showActor() { a->_costCommand = a->_costCommandNew = 0xFF; - for(int i = 0; i < 8; ++i) { + for (int i = 0; i < 8; ++i) { a->_limbFrameRepeat[i] = 0; a->_limbFrameRepeatNew[i] = 0; } @@ -1967,7 +1967,7 @@ void Actor_v0::startAnimActor(int f) { return; } - if(f == _standFrame) + if (f == _standFrame) setDirection(_facing); } @@ -2886,19 +2886,19 @@ void Actor_v0::animateActor(int anim) { break; } - if(isInCurrentRoom()) { + if (isInCurrentRoom()) { _costCommandNew = anim; _vm->_costumeLoader->costumeDecodeData(this, 0, 0); - if(dir == -1) + if (dir == -1) return; _facing = normalizeAngle(oldDirToNewDir(dir)); } else { - if(anim > 4 && anim <= 7) + if (anim > 4 && anim <= 7) _facing = normalizeAngle(oldDirToNewDir(dir)); } } diff --git a/engines/scumm/costume.cpp b/engines/scumm/costume.cpp index da6c1a2ae4..5f0df3566a 100644 --- a/engines/scumm/costume.cpp +++ b/engines/scumm/costume.cpp @@ -1190,7 +1190,7 @@ byte V0CostumeRenderer::drawLimb(const Actor *a, int limb) { } // Invalid current position? - if(a->_cost.curpos[limb] == 0xFFFF) + if (a->_cost.curpos[limb] == 0xFFFF) return 0; _loaded.loadCostume(a->_costume); @@ -1285,13 +1285,13 @@ void V0CostumeLoader::loadCostume(int id) { void V0CostumeLoader::costumeDecodeData(Actor *a, int frame, uint usemask) { Actor_v0 *A = (Actor_v0 *)a; - if(!a->_costume) + if (!a->_costume) return; loadCostume(a->_costume); // Invalid costume command? - if(A->_costCommandNew == 0xFF || (A->_costCommand == A->_costCommandNew)) + if (A->_costCommandNew == 0xFF || (A->_costCommand == A->_costCommandNew)) return; A->_costCommand = A->_costCommandNew; @@ -1308,16 +1308,16 @@ void V0CostumeLoader::costumeDecodeData(Actor *a, int frame, uint usemask) { limbFrameNumber = ((_animCmds + cmd)[limb]); // Is this limb flipped? - if(limbFrameNumber & 0x80) { + if (limbFrameNumber & 0x80) { // Invalid frame? - if(limbFrameNumber == 0xFF) + if (limbFrameNumber == 0xFF) continue; // Store the limb frame number (clear the flipped status) a->_cost.frame[limb] = (limbFrameNumber & 0x7f); - if(A->_limb_flipped[limb] != true) + if (A->_limb_flipped[limb] != true) a->_cost.start[limb] = 0xFFFF; A->_limb_flipped[limb] = true; @@ -1326,7 +1326,7 @@ void V0CostumeLoader::costumeDecodeData(Actor *a, int frame, uint usemask) { //Store the limb frame number a->_cost.frame[limb] = limbFrameNumber; - if(A->_limb_flipped[limb] != false) + if (A->_limb_flipped[limb] != false) a->_cost.start[limb] = 0xFFFF; A->_limb_flipped[limb] = false; @@ -1349,7 +1349,7 @@ byte V0CostumeLoader::increaseAnims(Actor *a) { int i; byte r = 0; - for(i = 0; i != 8; i++) { + for (i = 0; i != 8; i++) { A->limbFrameCheck(i); r += increaseAnim(a, i); } @@ -1369,7 +1369,7 @@ byte V0CostumeLoader::increaseAnim(Actor *a, int limb) { if (frame == 0xFF) { // Repeat timer has reached 0? - if(A->_limbFrameRepeat[limb] == 0) { + if (A->_limbFrameRepeat[limb] == 0) { // Use the previous frame --A->_cost.curpos[limb]; @@ -1385,7 +1385,7 @@ byte V0CostumeLoader::increaseAnim(Actor *a, int limb) { } else { // Repeat timer enabled? - if(A->_limbFrameRepeat[limb] != -1) + if (A->_limbFrameRepeat[limb] != -1) --A->_limbFrameRepeat[limb]; // No, restart at frame 0 @@ -1394,7 +1394,7 @@ byte V0CostumeLoader::increaseAnim(Actor *a, int limb) { } // Limb frame has changed? - if(limbPrevious == a->_cost.curpos[limb]) + if (limbPrevious == a->_cost.curpos[limb]) return 0; return 1; diff --git a/engines/scumm/player_pce.cpp b/engines/scumm/player_pce.cpp index 786971c683..8d886ee008 100644 --- a/engines/scumm/player_pce.cpp +++ b/engines/scumm/player_pce.cpp @@ -269,13 +269,13 @@ void PSG_HuC6280::init() { reset(); // Make waveform frequency table - for(i = 0; i < 4096; i++) { + for (i = 0; i < 4096; i++) { step = ((_clock / _rate) * 4096) / (i+1); _waveFreqTable[(1 + i) & 0xFFF] = (uint32)step; } // Make noise frequency table - for(i = 0; i < 32; i++) { + for (i = 0; i < 32; i++) { step = ((_clock / _rate) * 32) / (i+1); _noiseFreqTable[i] = (uint32)step; } @@ -283,7 +283,7 @@ void PSG_HuC6280::init() { // Make volume table // PSG_HuC6280 has 48dB volume range spread over 32 steps step = 48.0 / 32.0; - for(i = 0; i < 31; i++) { + for (i = 0; i < 31; i++) { _volumeTable[i] = (uint16)level; level /= pow(10.0, step / 20.0); } @@ -323,7 +323,7 @@ void PSG_HuC6280::write(int offset, byte data) { case 0x04: // Channel control (key-on, DDA mode, volume) // 1-to-0 transition of DDA bit resets waveform index - if((chan->control & 0x40) && ((data & 0x40) == 0)) { + if ((chan->control & 0x40) && ((data & 0x40) == 0)) { chan->index = 0; } chan->control = data; @@ -383,9 +383,9 @@ void PSG_HuC6280::update(int16* samples, int sampleCnt) { // Clear buffer memset(samples, 0, 2 * sampleCnt * sizeof(int16)); - for(ch = 0; ch < 6; ch++) { + for (ch = 0; ch < 6; ch++) { // Only look at enabled channels - if(_channel[ch].control & 0x80) { + if (_channel[ch].control & 0x80) { int lal = (_channel[ch].balance >> 4) & 0x0F; int ral = (_channel[ch].balance >> 0) & 0x0F; int al = _channel[ch].control & 0x1F; @@ -395,25 +395,25 @@ void PSG_HuC6280::update(int16* samples, int sampleCnt) { // Calculate volume just as the patent says vll = (0x1F - lal) + (0x1F - al) + (0x1F - lmal); - if(vll > 0x1F) vll = 0x1F; + if (vll > 0x1F) vll = 0x1F; vlr = (0x1F - ral) + (0x1F - al) + (0x1F - rmal); - if(vlr > 0x1F) vlr = 0x1F; + if (vlr > 0x1F) vlr = 0x1F; vll = _volumeTable[vll]; vlr = _volumeTable[vlr]; // Check channel mode - if(_channel[ch].control & 0x40) { + if (_channel[ch].control & 0x40) { /* DDA mode */ - for(i = 0; i < sampleCnt; i++) { + for (i = 0; i < sampleCnt; i++) { samples[2*i] += (int16)(vll * (_channel[ch].dda - 16)); samples[2*i + 1] += (int16)(vlr * (_channel[ch].dda - 16)); } } else { /* Waveform mode */ uint32 step = _waveFreqTable[_channel[ch].frequency]; - for(i = 0; i < sampleCnt; i += 1) { + for (i = 0; i < sampleCnt; i += 1) { int offset; int16 data; offset = (_channel[ch].counter >> 12) & 0x1F; -- cgit v1.2.3 From 4922055063b0a72069ffdbbe9e95c5b11f47bd71 Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Fri, 10 Feb 2012 22:58:59 +0100 Subject: SCUMM: cleanup and separation of objIsActor()/objToActor()/actorToObj() for v0 and other engines --- engines/scumm/actor.cpp | 6 ------ engines/scumm/object.cpp | 33 ++++++++++++++++++--------------- engines/scumm/scumm.h | 6 +++--- engines/scumm/scumm_v0.h | 4 ++++ 4 files changed, 25 insertions(+), 24 deletions(-) (limited to 'engines/scumm') diff --git a/engines/scumm/actor.cpp b/engines/scumm/actor.cpp index 3989d0f803..9e1b91c338 100644 --- a/engines/scumm/actor.cpp +++ b/engines/scumm/actor.cpp @@ -657,15 +657,11 @@ void Actor_v2::walkActor() { if (_moving & MF_TURN) { new_dir = updateActorDirection(false); - if (_facing != new_dir) { - setDirection(new_dir); - } else { _moving = 0; } - return; } @@ -674,7 +670,6 @@ void Actor_v2::walkActor() { if (_moving & MF_IN_LEG) { actorWalkStep(); - } else { if (_moving & MF_LAST_LEG) { _moving = 0; @@ -1423,7 +1418,6 @@ void Actor::showActor() { _cost.reset(); - // 0x39DF a->_animFrameRepeat = 1; a->_speaking = 0; diff --git a/engines/scumm/object.cpp b/engines/scumm/object.cpp index e38552c8f3..399cd91324 100644 --- a/engines/scumm/object.cpp +++ b/engines/scumm/object.cpp @@ -437,8 +437,8 @@ void ScummEngine::getObjectXYPos(int object, int &x, int &y, int &dir) { x = od.walk_x; y = od.walk_y; } else { - x = od.x_pos + od.width/2; - y = od.y_pos + od.height/2; + x = od.x_pos + od.width / 2; + y = od.y_pos + od.height / 2; } x = x >> V12_X_SHIFT; y = y >> V12_Y_SHIFT; @@ -1488,26 +1488,29 @@ void ScummEngine::findObjectInRoom(FindObjectInRoom *fo, byte findWhat, uint id, } } -bool ScummEngine::objIsActor(int obj) { +bool ScummEngine_v0::objIsActor(int obj) { // object IDs < _numActors are used in v0 for objects too (e.g. hamster) - if (_game.version == 0) - return OBJECT_V0_TYPE(obj) == kObjectV0TypeActor; - else - return obj < _numActors; + return OBJECT_V0_TYPE(obj) == kObjectV0TypeActor; +} + +int ScummEngine_v0::objToActor(int obj) { + return OBJECT_V0_ID(obj); +} + +int ScummEngine_v0::actorToObj(int actor) { + return OBJECT_V0(actor, kObjectV0TypeActor); +} + +bool ScummEngine::objIsActor(int obj) { + return obj < _numActors; } int ScummEngine::objToActor(int obj) { - if (_game.version == 0) - return OBJECT_V0_ID(obj); - else - return obj; + return obj; } int ScummEngine::actorToObj(int actor) { - if (_game.version == 0) - return OBJECT_V0(actor, kObjectV0TypeActor); - else - return actor; + return actor; } int ScummEngine::getObjX(int obj) { diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h index f67536d3ed..2f1e536f0a 100644 --- a/engines/scumm/scumm.h +++ b/engines/scumm/scumm.h @@ -800,9 +800,9 @@ protected: void setOwnerOf(int obj, int owner); void clearOwnerOf(int obj); int getObjectRoom(int obj) const; - bool objIsActor(int obj); - int objToActor(int obj); - int actorToObj(int actor); + virtual bool objIsActor(int obj); + virtual int objToActor(int obj); + virtual int actorToObj(int actor); int getObjX(int obj); int getObjY(int obj); void getObjectXYPos(int object, int &x, int &y) { int dir; getObjectXYPos(object, x, y, dir); } diff --git a/engines/scumm/scumm_v0.h b/engines/scumm/scumm_v0.h index 1341b9ed15..144dd701d4 100644 --- a/engines/scumm/scumm_v0.h +++ b/engines/scumm/scumm_v0.h @@ -81,6 +81,10 @@ protected: virtual void saveOrLoad(Serializer *s); + virtual bool objIsActor(int obj); + virtual int objToActor(int obj); + virtual int actorToObj(int actor); + // V0 MM Verb commands int getVerbPrepId(); int activeVerbPrep(); -- cgit v1.2.3 From 67d67ec4f6c867fab9ef5ff6f40c1f6144f0f77f Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Fri, 10 Feb 2012 23:39:07 +0100 Subject: SCUMM: replaced A with a0 to avoid upper-case local vars --- engines/scumm/actor.cpp | 18 ++++++++--------- engines/scumm/costume.cpp | 50 +++++++++++++++++++++++------------------------ 2 files changed, 34 insertions(+), 34 deletions(-) (limited to 'engines/scumm') diff --git a/engines/scumm/actor.cpp b/engines/scumm/actor.cpp index 9e1b91c338..07c439043f 100644 --- a/engines/scumm/actor.cpp +++ b/engines/scumm/actor.cpp @@ -1633,23 +1633,23 @@ void ScummEngine::processActors() { if (_game.version == 0) { // 0x057B - Actor_v0 *A = (Actor_v0*) a; - if (A->_speaking & 1) - A->_speaking ^= 0xFE; + Actor_v0 *a0 = (Actor_v0*) a; + if (a0->_speaking & 1) + a0->_speaking ^= 0xFE; // 0x22B5 - if (A->_miscflags & kActorMiscFlagHide) + if (a0->_miscflags & kActorMiscFlagHide) continue; // Sound - if (A->_moving && _currentRoom != 1 && _currentRoom != 44) { - if (A->_cost.soundPos == 0) - A->_cost.soundCounter++; + if (a0->_moving && _currentRoom != 1 && _currentRoom != 44) { + if (a0->_cost.soundPos == 0) + a0->_cost.soundCounter++; // Is this the correct location? // 0x073C - if (v0ActorTalkArray[A->_number] & 0x3F) - A->_cost.soundPos = (A->_cost.soundPos + 1) % 3; + if (v0ActorTalkArray[a0->_number] & 0x3F) + a0->_cost.soundPos = (a0->_cost.soundPos + 1) % 3; } } // Draw and animate the actors, except those w/o a costume. diff --git a/engines/scumm/costume.cpp b/engines/scumm/costume.cpp index 5f0df3566a..2bbf3b3801 100644 --- a/engines/scumm/costume.cpp +++ b/engines/scumm/costume.cpp @@ -1179,7 +1179,7 @@ static const byte actorV0Colors[25] = { } byte V0CostumeRenderer::drawLimb(const Actor *a, int limb) { - const Actor_v0* A = (const Actor_v0 *)a; + const Actor_v0* a0 = (const Actor_v0 *)a; if (limb >= 8) return 0; @@ -1224,7 +1224,7 @@ byte V0CostumeRenderer::drawLimb(const Actor *a, int limb) { if (!width || !height) return 0; - int xpos = _actorX + (A->_limb_flipped[limb] ? -1 : +1) * (offsetX * 8 - a->_width / 2); + int xpos = _actorX + (a0->_limb_flipped[limb] ? -1 : +1) * (offsetX * 8 - a->_width / 2); // +1 as we appear to be 1 pixel away from the original interpreter int ypos = _actorY - offsetY + 1; @@ -1234,13 +1234,13 @@ byte V0CostumeRenderer::drawLimb(const Actor *a, int limb) { byte color = data[y * width + x]; byte pcolor; - int destX = xpos + (A->_limb_flipped[limb] ? -(x + 1) : x) * 8; + int destX = xpos + (a0->_limb_flipped[limb] ? -(x + 1) : x) * 8; int destY = ypos + y; if (destY >= 0 && destY < _out.h && destX >= 0 && destX < _out.w) { byte *dst = (byte *)_out.pixels + destY * _out.pitch + destX; byte *mask = _vm->getMaskBuffer(0, destY, _zbuf); - if (A->_limb_flipped[limb]) { + if (a0->_limb_flipped[limb]) { LINE(0, 0); LINE(2, 2); LINE(4, 4); LINE(6, 6); } else { LINE(6, 0); LINE(4, 2); LINE(2, 4); LINE(0, 6); @@ -1251,7 +1251,7 @@ byte V0CostumeRenderer::drawLimb(const Actor *a, int limb) { _draw_top = MIN(_draw_top, ypos); _draw_bottom = MAX(_draw_bottom, ypos + height); - if (A->_limb_flipped[limb]) + if (a0->_limb_flipped[limb]) _vm->markRectAsDirty(kMainVirtScreen, xpos - (width * 8), xpos, ypos, ypos + height, _actorID); else _vm->markRectAsDirty(kMainVirtScreen, xpos, xpos + (width * 8), ypos, ypos + height, _actorID); @@ -1283,7 +1283,7 @@ void V0CostumeLoader::loadCostume(int id) { } void V0CostumeLoader::costumeDecodeData(Actor *a, int frame, uint usemask) { - Actor_v0 *A = (Actor_v0 *)a; + Actor_v0 *a0 = (Actor_v0 *)a; if (!a->_costume) return; @@ -1291,12 +1291,12 @@ void V0CostumeLoader::costumeDecodeData(Actor *a, int frame, uint usemask) { loadCostume(a->_costume); // Invalid costume command? - if (A->_costCommandNew == 0xFF || (A->_costCommand == A->_costCommandNew)) + if (a0->_costCommandNew == 0xFF || (a0->_costCommand == a0->_costCommandNew)) return; - A->_costCommand = A->_costCommandNew; + a0->_costCommand = a0->_costCommandNew; - int cmd = A->_costCommand; + int cmd = a0->_costCommand; byte limbFrameNumber = 0; // Each costume-command has 8 limbs (0x2622) @@ -1317,23 +1317,23 @@ void V0CostumeLoader::costumeDecodeData(Actor *a, int frame, uint usemask) { // Store the limb frame number (clear the flipped status) a->_cost.frame[limb] = (limbFrameNumber & 0x7f); - if (A->_limb_flipped[limb] != true) + if (a0->_limb_flipped[limb] != true) a->_cost.start[limb] = 0xFFFF; - A->_limb_flipped[limb] = true; + a0->_limb_flipped[limb] = true; } else { //Store the limb frame number a->_cost.frame[limb] = limbFrameNumber; - if (A->_limb_flipped[limb] != false) + if (a0->_limb_flipped[limb] != false) a->_cost.start[limb] = 0xFFFF; - A->_limb_flipped[limb] = false; + a0->_limb_flipped[limb] = false; } // Set the repeat value - A->_limbFrameRepeatNew[limb] = A->_animFrameRepeat; + a0->_limbFrameRepeatNew[limb] = a0->_animFrameRepeat; } } @@ -1345,19 +1345,19 @@ byte V0CostumeLoader::getFrame(Actor *a, int limb) { } byte V0CostumeLoader::increaseAnims(Actor *a) { - Actor_v0 *A = (Actor_v0 *)a; + Actor_v0 *a0 = (Actor_v0 *)a; int i; byte r = 0; for (i = 0; i != 8; i++) { - A->limbFrameCheck(i); + a0->limbFrameCheck(i); r += increaseAnim(a, i); } return r; } byte V0CostumeLoader::increaseAnim(Actor *a, int limb) { - Actor_v0 *A = (Actor_v0 *)a; + Actor_v0 *a0 = (Actor_v0 *)a; const uint16 limbPrevious = a->_cost.curpos[limb]++; loadCostume(a->_costume); @@ -1369,24 +1369,24 @@ byte V0CostumeLoader::increaseAnim(Actor *a, int limb) { if (frame == 0xFF) { // Repeat timer has reached 0? - if (A->_limbFrameRepeat[limb] == 0) { + if (a0->_limbFrameRepeat[limb] == 0) { // Use the previous frame - --A->_cost.curpos[limb]; + --a0->_cost.curpos[limb]; // Reset the comstume command - A->_costCommandNew = 0xFF; - A->_costCommand = 0xFF; + a0->_costCommandNew = 0xFF; + a0->_costCommand = 0xFF; // Set the frame/start to invalid - A->_cost.frame[limb] = 0xFFFF; - A->_cost.start[limb] = 0xFFFF; + a0->_cost.frame[limb] = 0xFFFF; + a0->_cost.start[limb] = 0xFFFF; } else { // Repeat timer enabled? - if (A->_limbFrameRepeat[limb] != -1) - --A->_limbFrameRepeat[limb]; + if (a0->_limbFrameRepeat[limb] != -1) + --a0->_limbFrameRepeat[limb]; // No, restart at frame 0 a->_cost.curpos[limb] = 0; -- cgit v1.2.3 From 0d5b03d8daffa758a60feaea9a6515a0632cce72 Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Fri, 10 Feb 2012 23:46:32 +0100 Subject: SCUMM: remove unnecessary cast to Actor_v0 --- engines/scumm/actor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'engines/scumm') diff --git a/engines/scumm/actor.cpp b/engines/scumm/actor.cpp index 07c439043f..53496428e3 100644 --- a/engines/scumm/actor.cpp +++ b/engines/scumm/actor.cpp @@ -251,7 +251,7 @@ void Actor::stopActorMoving() { _moving = 0; if (_vm->_game.version == 0) - ((Actor_v0 *)this)->setDirection(_facing); + setDirection(_facing); } void Actor::setActorWalkSpeed(uint newSpeedX, uint newSpeedY) { -- cgit v1.2.3 From 65fc7225bb31e72120dcdf16e91ae377c657548d Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Sat, 11 Feb 2012 00:10:58 +0100 Subject: SCUMM: revert savegame version to 89 Previous versions 89-92 are merged into version 89. --- engines/scumm/actor.cpp | 7 +++---- engines/scumm/saveload.cpp | 18 +++++++++--------- engines/scumm/saveload.h | 2 +- 3 files changed, 13 insertions(+), 14 deletions(-) (limited to 'engines/scumm') diff --git a/engines/scumm/actor.cpp b/engines/scumm/actor.cpp index 53496428e3..dee601b273 100644 --- a/engines/scumm/actor.cpp +++ b/engines/scumm/actor.cpp @@ -2902,14 +2902,13 @@ void Actor_v0::saveLoadWithSerializer(Serializer *ser) { static const SaveLoadEntry actorEntries[] = { MKLINE(Actor_v0, _costCommand, sleByte, VER(84)), - MK_OBSOLETE(Actor_v0, _costFrame, sleByte, VER(84), VER(89)), + MK_OBSOLETE(Actor_v0, _costFrame, sleByte, VER(84), VER(88)), MKLINE(Actor_v0, _miscflags, sleByte, VER(84)), MKLINE(Actor_v0, _speaking, sleByte, VER(84)), - MK_OBSOLETE(Actor_v0, _speakingPrev, sleByte, VER(84), VER(89)), - MK_OBSOLETE(Actor_v0, _limbTemp, sleByte, VER(89), VER(89)), + MK_OBSOLETE(Actor_v0, _speakingPrev, sleByte, VER(84), VER(88)), MKLINE(Actor_v0, _animFrameRepeat, sleByte, VER(89)), MKARRAY(Actor_v0, _limbFrameRepeatNew[0], sleInt8, 8, VER(89)), - MKARRAY(Actor_v0, _limbFrameRepeat[0], sleInt8, 8, VER(90)), + MKARRAY(Actor_v0, _limbFrameRepeat[0], sleInt8, 8, VER(89)), MKEND() }; diff --git a/engines/scumm/saveload.cpp b/engines/scumm/saveload.cpp index 6e54377199..51a291b7f2 100644 --- a/engines/scumm/saveload.cpp +++ b/engines/scumm/saveload.cpp @@ -1210,7 +1210,7 @@ void ScummEngine::saveOrLoad(Serializer *s) { // Since roughly v13 of the save games, the objs storage has changed a bit for (i = _numObjectsInRoom; i < _numLocalObjects; i++) _objs[i].obj_nr = 0; - } else if (_game.version == 0 && s->getVersion() < VER(91)) { + } else if (_game.version == 0 && s->getVersion() < VER(89)) { for (i = 0; i < _numLocalObjects; i++) { // Merge object id and type (previously stored in flags) if (_objs[i].obj_nr != 0 && OBJECT_V0_TYPE(_objs[i].obj_nr) == 0 && _objs[i].flags != 0) @@ -1504,14 +1504,14 @@ void ScummEngine_v0::saveOrLoad(Serializer *s) { const SaveLoadEntry v0Entrys[] = { MKLINE(ScummEngine_v0, _currentMode, sleByte, VER(78)), MKLINE(ScummEngine_v0, _currentLights, sleByte, VER(78)), - MKLINE(ScummEngine_v0, _activeVerb, sleByte, VER(92)), - MKLINE(ScummEngine_v0, _activeObject, sleUint16, VER(92)), - MKLINE(ScummEngine_v0, _activeObject2, sleUint16, VER(92)), - MKLINE(ScummEngine_v0, _cmdVerb, sleByte, VER(92)), - MKLINE(ScummEngine_v0, _cmdObject, sleUint16, VER(92)), - MKLINE(ScummEngine_v0, _cmdObject2, sleUint16, VER(92)), - MKLINE(ScummEngine_v0, _walkToObject, sleUint16, VER(92)), - MKLINE(ScummEngine_v0, _walkToObjectState, sleByte, VER(92)), + MKLINE(ScummEngine_v0, _activeVerb, sleByte, VER(89)), + MKLINE(ScummEngine_v0, _activeObject, sleUint16, VER(89)), + MKLINE(ScummEngine_v0, _activeObject2, sleUint16, VER(89)), + MKLINE(ScummEngine_v0, _cmdVerb, sleByte, VER(89)), + MKLINE(ScummEngine_v0, _cmdObject, sleUint16, VER(89)), + MKLINE(ScummEngine_v0, _cmdObject2, sleUint16, VER(89)), + MKLINE(ScummEngine_v0, _walkToObject, sleUint16, VER(89)), + MKLINE(ScummEngine_v0, _walkToObjectState, sleByte, VER(89)), MKEND() }; s->saveLoadEntries(this, v0Entrys); diff --git a/engines/scumm/saveload.h b/engines/scumm/saveload.h index 90feee6dc0..898f80f867 100644 --- a/engines/scumm/saveload.h +++ b/engines/scumm/saveload.h @@ -47,7 +47,7 @@ namespace Scumm { * only saves/loads those which are valid for the version of the savegame * which is being loaded/saved currently. */ -#define CURRENT_VER 92 +#define CURRENT_VER 89 /** * An auxillary macro, used to specify savegame versions. We use this instead -- cgit v1.2.3