aboutsummaryrefslogtreecommitdiff
path: root/engines/scumm/script_v0.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/scumm/script_v0.cpp')
-rw-r--r--engines/scumm/script_v0.cpp540
1 files changed, 257 insertions, 283 deletions
diff --git a/engines/scumm/script_v0.cpp b/engines/scumm/script_v0.cpp
index e2d3f40e8e..45901186cd 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 {
@@ -50,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 */
@@ -59,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);
@@ -79,9 +80,9 @@ 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(0x26, o_getClosestActor);
OPCODE(0x27, o2_getActorY);
/* 28 */
OPCODE(0x28, o5_equalZero);
@@ -91,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);
@@ -101,7 +102,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);
@@ -144,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);
@@ -154,14 +155,14 @@ 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);
/* 64 */
- OPCODE(0x64, o_ifActiveObject);
+ 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);
@@ -177,11 +178,11 @@ 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);
- OPCODE(0x76, o2_walkActorToObject);
+ OPCODE(0x75, o_printEgo);
+ OPCODE(0x76, o_walkActorToObject);
OPCODE(0x77, o2_clearState04);
/* 78 */
OPCODE(0x78, o2_isGreater);
@@ -239,7 +240,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);
@@ -251,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);
@@ -261,7 +262,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);
@@ -314,12 +315,12 @@ 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);
/* E4 */
- OPCODE(0xe4, o_ifActiveObject);
+ OPCODE(0xe4, o_ifEqualActiveObject2);
OPCODE(0xe5, o_loadRoomWithEgo);
OPCODE(0xe6, o_stopCurrentScript);
OPCODE(0xe7, o5_getActorFacing);
@@ -337,11 +338,11 @@ 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);
- OPCODE(0xf6, o2_walkActorToObject);
+ OPCODE(0xf6, o_walkActorToObject);
OPCODE(0xf7, o2_setState04);
/* F8 */
OPCODE(0xf8, o2_isGreater);
@@ -365,7 +366,7 @@ uint ScummEngine_v0::fetchScriptWord() {
int ScummEngine_v0::getActiveObject() {
if (_opcode & PARAM_2)
- return _activeObject;
+ return OBJECT_V0_ID(_cmdObject);
return fetchScriptByte();
}
@@ -406,172 +407,121 @@ void ScummEngine_v0::decodeParseString() {
actorTalk(buffer);
}
-void ScummEngine_v0::drawSentenceWord(int object, bool usePrep, bool objInInventory) {
- const byte *temp;
- int sentencePrep = 0;
-
- // If object not in inventory, we except an index
- if (!objInInventory)
- _v0ObjectIndex = true;
- else
- _v0ObjectInInventory = true;
-
- temp = getObjOrActorName(object);
+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);
+}
- _v0ObjectInInventory = false;
- _v0ObjectIndex = false;
+void ScummEngine_v0::flushSentenceLine() {
+ byte string[80];
+ const char *ptr = _sentenceBuf.c_str();
+ int i = 0, len = 0;
- // Append the 'object-name'
- if (temp) {
- _sentenceBuf += " ";
- _sentenceBuf += (const char *)temp;
- }
+ // Maximum length of printable characters
+ int maxChars = 40;
+ while (*ptr) {
+ if (*ptr != '@')
+ len++;
+ if (len > maxChars) {
+ break;
+ }
- // Append the modifier? (With / On / To / In)
- if (!usePrep)
- return;
+ string[i++] = *ptr++;
- if (_verbs[_activeVerb].prep == 0xFF) {
- _v0ObjectInInventory = objInInventory;
- sentencePrep = verbPrep(object);
- } else {
- sentencePrep = _verbs[_activeVerb].prep;
}
+ string[i] = 0;
- 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
- }
+ _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);
+}
- _sentenceBuf += prepositions[lang][sentencePrep];
+void ScummEngine_v0::drawSentenceObject(int object) {
+ const byte *temp;
+ temp = getObjOrActorName(object);
+ if (temp) {
+ _sentenceBuf += " ";
+ _sentenceBuf += (const char *)temp;
}
}
-void ScummEngine_v0::drawSentence() {
- Common::Rect sentenceline;
- bool inventoryFirst = false;
- if (!(_userState & 32))
- return;
+void ScummEngine_v0::drawSentenceLine() {
+ _redrawSentenceLine = false;
- // Current Verb, Walk/Use
- if (getResourceAddress(rtVerb, _activeVerb)) {
- _sentenceBuf = (char *)getResourceAddress(rtVerb, _activeVerb);
- } else {
+ if (!(_userState & USERSTATE_IFACE_SENTENCE))
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);
+ clearSentenceLine();
+
+ if (_activeVerb == kVerbNewKid) {
+ _sentenceBuf = "";
+ for (int i = 0; i < 3; ++i) {
+ const 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;
}
- // Draw the active actor
- if (_activeActor) {
- Actor *a = derefActor(_activeActor, "");
+ // Current Verb
+ if (_activeVerb == kVerbNone)
+ _activeVerb = kVerbWalkTo;
- _sentenceBuf += " ";
- _sentenceBuf += (const char *)a->getActorName();
- }
+ char *verbName = (char *)getResourceAddress(rtVerb, _activeVerb);
+ assert(verbName);
+ _sentenceBuf = verbName;
- _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;
+ if (_activeObject) {
+ // Draw the 1st active object
+ drawSentenceObject(_activeObject);
- byte string[80];
- const char *ptr = _sentenceBuf.c_str();
- int i = 0, len = 0;
+ // Append verb preposition
+ int sentencePrep = activeVerbPrep();
+ if (sentencePrep) {
+ drawPreposition(sentencePrep);
- // Maximum length of printable characters
- int maxChars = 40;
- while (*ptr) {
- if (*ptr != '@')
- len++;
- if (len > maxChars) {
- break;
+ // Draw the 2nd active object
+ if (_activeObject2)
+ drawSentenceObject(_activeObject2);
}
-
- 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() {
- int script;
+ stopScriptCommon(0);
+}
- script = vm.slot[_currentScript].number;
+void ScummEngine_v0::o_walkActorToObject() {
+ int actor = getVarOrDirectByte(PARAM_1);
+ int objId = fetchScriptByte();
+ int obj;
- if (_currentScript != 0 && vm.slot[_currentScript].number == script)
- stopObjectCode();
+ if (_opcode & 0x40)
+ obj = OBJECT_V0(objId, kObjectV0TypeBG);
else
- stopScript(script);
+ obj = OBJECT_V0(objId, kObjectV0TypeFG);
+
+ if (whereIsObject(obj) != WIO_NOT_FOUND) {
+ walkActorToObject(actor, obj);
+ }
}
void ScummEngine_v0::o_loadSound() {
@@ -625,18 +575,16 @@ void ScummEngine_v0::o_loadRoom() {
}
void ScummEngine_v0::o_loadRoomWithEgo() {
- Actor *a;
+ Actor_v0 *a;
int obj, room, x, y, dir;
obj = fetchScriptByte();
room = fetchScriptByte();
- a = derefActor(VAR(VAR_EGO), "o_loadRoomWithEgo");
+ a = (Actor_v0 *)derefActor(VAR(VAR_EGO), "o_loadRoomWithEgo");
//0x634F
- if (((ActorC64 *)a)->_miscflags & 0x40) {
- // TODO: Check if this is the correct function
- // to be calling here
+ if (a->_miscflags & kActorMiscFlagFreeze) {
stopObjectCode();
return;
}
@@ -654,15 +602,14 @@ 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);
_fullRedraw = true;
- resetSentence(false);
+ resetSentence();
if (x >= 0 && y >= 0) {
a->startWalkActor(x, y, -1);
@@ -679,27 +626,39 @@ void ScummEngine_v0::o_unlockRoom() {
_res->unlock(rtRoom, resid);
}
-void ScummEngine_v0::o_cursorCommand() {
- // TODO
- int state = 0;
+void ScummEngine_v0::setMode(byte mode) {
+ int state;
+
+ _currentMode = mode;
- _currentMode = fetchScriptByte();
switch (_currentMode) {
- case 0:
- state = 15;
+ case kModeCutscene:
+ _redrawSentenceLine = false;
+ // Note: do not change freeze state here
+ state = USERSTATE_SET_IFACE |
+ USERSTATE_SET_CURSOR;
break;
- case 1:
- state = 31;
+ case kModeKeypad:
+ _redrawSentenceLine = false;
+ state = USERSTATE_SET_IFACE |
+ USERSTATE_SET_CURSOR | USERSTATE_CURSOR_ON |
+ USERSTATE_SET_FREEZE | USERSTATE_FREEZE_ON;
break;
- case 2:
- break;
- case 3:
- state = 247;
+ case kModeNormal:
+ case kModeNoNewKid:
+ 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);
- debug(0, "o_cursorCommand(%d)", _currentMode);
+}
+
+void ScummEngine_v0::o_setMode() {
+ setMode(fetchScriptByte());
}
void ScummEngine_v0::o_lights() {
@@ -724,24 +683,31 @@ void ScummEngine_v0::o_lights() {
void ScummEngine_v0::o_animateActor() {
int act = getVarOrDirectByte(PARAM_1);
int anim = getVarOrDirectByte(PARAM_2);
- int unk = fetchScriptByte();
-
- debug(0,"o_animateActor: unk %d", unk);
-
- ActorC64 *a = (ActorC64*) derefActor(act, "o_animateActor");
-
- // 0x6993
- if (anim == 0xFE) {
- a->_speaking = 0x80; // Enabled, but not switching
- return;
- }
- // 0x69A3
- if (anim == 0xFD) {
- a->_speaking = 0x00;
- return;
+ int8 repeat = (int8) fetchScriptByte();
+
+ Actor_v0 *a = (Actor_v0*) derefActor(act, "o_animateActor");
+
+ a->_animFrameRepeat = repeat;
+
+ switch (anim) {
+
+ case 0xFE:
+ // 0x6993
+ a->_speaking = 0x80; // Enabled, but not switching
+ return;
+
+ case 0xFD:
+ // 0x69A3
+ a->_speaking = 0x00;
+ return;
+
+ case 0xFF:
+ a->stopActorMoving();
+ return;
}
a->animateActor(anim);
+ a->animateCostume();
}
void ScummEngine_v0::o_getActorMoving() {
@@ -760,7 +726,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);
@@ -776,20 +747,13 @@ void ScummEngine_v0::o_putActorAtObject() {
void ScummEngine_v0::o_pickupObject() {
int obj = fetchScriptByte();
- if (obj == 0) {
- obj = _activeObject;
- }
+ if (!obj)
+ obj = _cmdObject;
- 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));
@@ -800,14 +764,22 @@ void ScummEngine_v0::o_pickupObject() {
}
void ScummEngine_v0::o_setObjectName() {
- int obj = fetchScriptByte();
+ 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);
}
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);
@@ -817,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;
@@ -825,20 +797,24 @@ 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)
- a->setActorCostume(0);
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 : _cmdObject));
+}
+
void ScummEngine_v0::o_getActorBitVar() {
getResultPos();
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));
@@ -867,74 +843,97 @@ 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();
}
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 = _cmdObject2;
+ } else if (b == 0xFE) {
+ obj = _cmdObject;
+ } else {
+ obj = OBJECT_V0(b, (_opcode & 0x80) ? kObjectV0TypeBG : kObjectV0TypeFG);
+ }
- runObjectScript(obj, entry, false, false, NULL);
-}
+ b = fetchScriptByte();
+ if (b == 0xFF) {
+ obj2 = _cmdObject2;
+ } else if (b == 0xFE) {
+ obj2 = _cmdObject;
+ } else {
+ obj2 = OBJECT_V0(b, (_opcode & 0x40) ? kObjectV0TypeBG : kObjectV0TypeFG);
+ }
-void ScummEngine_v0::o_unknown2() {
- byte var1 = fetchScriptByte();
- error("STUB: o_unknown2(%d)", var1);
+ doSentence(verb, obj, obj2);
}
-void ScummEngine_v0::o_ifActiveObject() {
+bool ScummEngine_v0::ifEqualActiveObject2Common(bool checkType) {
byte obj = fetchScriptByte();
+ if (!checkType || (OBJECT_V0_TYPE(_cmdObject2) == kObjectV0TypeFG))
+ return (obj == OBJECT_V0_ID(_cmdObject2));
+ return false;
+}
- jumpRelative(obj == _activeInventory);
+void ScummEngine_v0::o_ifEqualActiveObject2() {
+ bool equal = ifEqualActiveObject2Common((_opcode & 0x80) == 0);
+ jumpRelative(equal);
}
-void ScummEngine_v0::o_getClosestObjActor() {
- int obj;
- int act;
+void ScummEngine_v0::o_ifNotEqualActiveObject2() {
+ bool equal = ifEqualActiveObject2Common((_opcode & 0x80) == 0);
+ jumpRelative(!equal);
+}
+
+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() {
- 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);
+ freezeScripts(0);
+ setMode(kModeCutscene);
_sentenceNum = 0;
- resetSentence(false);
+ resetSentence();
vm.cutScenePtr[0] = 0;
+ vm.cutSceneScript[0] = 0;
}
void ScummEngine_v0::o_endCutscene() {
@@ -944,68 +943,43 @@ 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);
+ // 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;
}
}
-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;
obj = getVarOrDirectWord(PARAM_1);
owner = getVarOrDirectByte(PARAM_2);
- if (obj == 0)
- obj = _activeInventory;
+ if (!obj)
+ obj = _cmdObject;
setOwnerOf(obj, owner);
}
-void ScummEngine_v0::resetSentence(bool walking) {
- _activeVerb = 13;
-
- // 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;
- _activeInventory = 0;
- _activeObject = 0;
- _activeObject2 = 0;
- _activeObjectIndex = 0;
- _activeObject2Index = 0;
- }
+void ScummEngine_v0::resetSentence() {
+ _activeVerb = kVerbWalkTo;
+ _activeObject = 0;
+ _activeObject2 = 0;
- _verbExecuting = false;
- _verbPickup = false;
+ _walkToObjectState = kWalkToObjectStateDone;
+ _redrawSentenceLine = true;
- _activeActor = 0;
- _activeInvExecute = false;
- _activeObject2Inv = false;
- _activeObjectObtained = false;
- _activeObject2Obtained = false;
+ _sentenceNum = 0;
+ _sentenceNestedCount = 0;
}
} // End of namespace Scumm