aboutsummaryrefslogtreecommitdiff
path: root/script.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'script.cpp')
-rw-r--r--script.cpp2564
1 files changed, 345 insertions, 2219 deletions
diff --git a/script.cpp b/script.cpp
index 698b09c8bf..fbad851263 100644
--- a/script.cpp
+++ b/script.cpp
@@ -17,6 +17,9 @@
*
* Change Log:
* $Log$
+ * Revision 1.3 2001/10/16 10:01:47 strigeus
+ * preliminary DOTT support
+ *
* Revision 1.2 2001/10/11 13:36:25 strigeus
* fixed swapped parameters in o_walkActorToActor
*
@@ -50,12 +53,12 @@ void Scumm::runScript(int script, int a, int b, int16 *lvarptr) {
if (b==0)
stopScriptNr(script);
- if (script < _numGlobalScriptsUsed) {
+ if (script < _numGlobalScripts) {
scriptPtr = getResourceAddress(2, script);
scriptOffs = 8;
scriptType = 2;
} else {
- scriptOffs = _localScriptList[script - _numGlobalScriptsUsed];
+ scriptOffs = _localScriptList[script - _numGlobalScripts];
if (scriptOffs == 0)
error("Local script %d is not in room %d", script, _roomResource);
scriptOffs += 9;
@@ -114,7 +117,7 @@ void Scumm::stopScriptNr(int script) {
do {
if (nest->number == script && (nest->type==2 || nest->type==3)) {
- nest->number = 0xFFFF;
+ nest->number = 0xFF;
nest->slot = 0xFF;
nest->type = 0xFF;
}
@@ -132,15 +135,14 @@ void Scumm::stopObjectScript(int script) {
ss = &vm.slot[1];
for (i=1; i<20; i++,ss++) {
- if (script!=ss->number || ss->type!=1 && ss->type!=0 && ss->type!=4 || ss->status==0)
- continue;
-
- if (ss->cutsceneOverride)
- error("Object %d stopped with active cutscene/override", script);
- ss->number = 0;
- ss->status = 0;
- if (_currentScript == i)
- _currentScript = 0xFF;
+ if (script==ss->number && (ss->type==1 || ss->type==0 || ss->type==4) && ss->status!=0) {
+ if (ss->cutsceneOverride)
+ error("Object %d stopped with active cutscene/override", script);
+ ss->number = 0;
+ ss->status = 0;
+ if (_currentScript == i)
+ _currentScript = 0xFF;
+ }
}
if (_numNestedScripts==0)
@@ -151,7 +153,7 @@ void Scumm::stopObjectScript(int script) {
do {
if (nest->number == script && (nest->type==1 || nest->type==4 || nest->type==0)) {
- nest->number = 0xFFFF;
+ nest->number = 0xFF;
nest->slot = 0xFF;
nest->type = 0xFF;
}
@@ -250,7 +252,7 @@ void Scumm::getScriptBaseAddress() {
case 4: /* flobject script */
index = getObjectIndex(ss->number);
- _scriptOrgPointer = getResourceAddress(13,objs[index].fl_object_index);
+ _scriptOrgPointer = getResourceAddress(13,_objs[index].fl_object_index);
_lastCodePtr = &_baseFLObject[ss->number];
break;
default:
@@ -265,345 +267,17 @@ void Scumm::getScriptEntryPoint() {
_scriptPointer = _scriptOrgPointer + vm.slot[_currentScript].offs;
}
-OpcodeProc FORCEINLINE Scumm::getOpcode(int i) {
- static const OpcodeProc opcode_list[] = {
- /* 00 */
- &Scumm::o_stopObjectCode,
- &Scumm::o_putActor,
- &Scumm::o_startMusic,
- &Scumm::o_getActorRoom,
- /* 04 */
- &Scumm::o_isGreaterEqual, /* hmm, seems to be less or equal */
- &Scumm::o_drawObject,
- &Scumm::o_getActorElevation,
- &Scumm::o_setState,
- /* 08 */
- &Scumm::o_isNotEqual,
- &Scumm::o_faceActor,
- &Scumm::o_startScript,
- &Scumm::o_getVerbEntrypoint,
- /* 0C */
- &Scumm::o_resourceRoutines,
- &Scumm::o_walkActorToActor,
- &Scumm::o_putActorAtObject,
- &Scumm::o_getObjectState,
- /* 10 */
- &Scumm::o_getObjectOwner,
- &Scumm::o_animateActor,
- &Scumm::o_panCameraTo,
- &Scumm::o_actorSet,
- /* 14 */
- &Scumm::o_print,
- &Scumm::o_actorFromPos,
- &Scumm::o_getRandomNr,
- &Scumm::o_and,
- /* 18 */
- &Scumm::o_jumpRelative,
- &Scumm::o_doSentence,
- &Scumm::o_move,
- &Scumm::o_multiply,
- /* 1C */
- &Scumm::o_startSound,
- &Scumm::o_ifClassOfIs,
- &Scumm::o_walkActorTo,
- &Scumm::o_isActorInBox,
- /* 20 */
- &Scumm::o_stopMusic,
- &Scumm::o_putActor,
- &Scumm::o_getAnimCounter,
- &Scumm::o_getActorY,
- /* 24 */
- &Scumm::o_loadRoomWithEgo,
- &Scumm::o_pickupObject,
- &Scumm::o_setVarRange,
- &Scumm::o_stringOps,
- /* 28 */
- &Scumm::o_equalZero,
- &Scumm::o_setOwnerOf,
- &Scumm::o_startScript,
- &Scumm::o_delayVariable,
- /* 2C */
- &Scumm::o_cursorCommand,
- &Scumm::o_putActorInRoom,
- &Scumm::o_delay,
- &Scumm::o_badOpcode,
- /* 30 */
- &Scumm::o_matrixOps,
- &Scumm::o_getInventoryCount,
- &Scumm::o_setCameraAt,
- &Scumm::o_roomOps,
- /* 34 */
- &Scumm::o_getDist,
- &Scumm::o_findObject,
- &Scumm::o_walkActorToObject,
- &Scumm::o_startObject,
- /* 38 */
- &Scumm::o_lessOrEqual,
- &Scumm::o_doSentence,
- &Scumm::o_subtract,
- &Scumm::o_getActorScale,
- /* 3C */
- &Scumm::o_stopSound,
- &Scumm::o_findInventory,
- &Scumm::o_walkActorTo,
- &Scumm::o_drawBox,
- /* 40 */
- &Scumm::o_cutscene,
- &Scumm::o_putActor,
- &Scumm::o_chainScript,
- &Scumm::o_getActorX,
- /* 44 */
- &Scumm::o_isLess,
- &Scumm::o_badOpcode,
- &Scumm::o_increment,
- &Scumm::o_setState,
- /* 48 */
- &Scumm::o_isEqual,
- &Scumm::o_faceActor,
- &Scumm::o_startScript,
- &Scumm::o_getVerbEntrypoint,
- /* 4C */
- &Scumm::o_soundKludge,
- &Scumm::o_walkActorToActor,
- &Scumm::o_putActorAtObject,
- &Scumm::o_badOpcode,
- /* 50 */
- &Scumm::o_badOpcode,
- &Scumm::o_animateActor,
- &Scumm::o_actorFollowCamera,
- &Scumm::o_actorSet,
- /* 54 */
- &Scumm::o_setObjectName,
- &Scumm::o_actorFromPos,
- &Scumm::o_getActorMoving,
- &Scumm::o_or,
- /* 58 */
- &Scumm::o_overRide,
- &Scumm::o_doSentence,
- &Scumm::o_add,
- &Scumm::o_divide,
- /* 5C */
- &Scumm::o_badOpcode,
- &Scumm::o_actorSetClass,
- &Scumm::o_walkActorTo,
- &Scumm::o_isActorInBox,
- /* 60 */
- &Scumm::o_freezeScripts,
- &Scumm::o_putActor,
- &Scumm::o_stopScript,
- &Scumm::o_getActorFacing,
- /* 64 */
- &Scumm::o_loadRoomWithEgo,
- &Scumm::o_pickupObject,
- &Scumm::o_getClosestObjActor,
- &Scumm::o_dummy,
- /* 68 */
- &Scumm::o_getScriptRunning,
- &Scumm::o_setOwnerOf,
- &Scumm::o_startScript,
- &Scumm::o_debug,
- /* 6C */
- &Scumm::o_getActorWidth,
- &Scumm::o_putActorInRoom,
- &Scumm::o_stopObjectScript,
- &Scumm::o_badOpcode,
- /* 70 */
- &Scumm::o_lights,
- &Scumm::o_getActorCostume,
- &Scumm::o_loadRoom,
- &Scumm::o_roomOps,
- /* 74 */
- &Scumm::o_getDist,
- &Scumm::o_findObject,
- &Scumm::o_walkActorToObject,
- &Scumm::o_startObject,
- /* 78 */
- &Scumm::o_isGreater, /* less? */
- &Scumm::o_doSentence,
- &Scumm::o_verbOps,
- &Scumm::o_getActorWalkBox,
- /* 7C */
- &Scumm::o_isSoundRunning,
- &Scumm::o_findInventory,
- &Scumm::o_walkActorTo,
- &Scumm::o_drawBox,
- /* 80 */
- &Scumm::o_breakHere,
- &Scumm::o_putActor,
- &Scumm::o_startMusic,
- &Scumm::o_getActorRoom,
- /* 84 */
- &Scumm::o_isGreaterEqual, /* less equal? */
- &Scumm::o_drawObject,
- &Scumm::o_getActorElevation,
- &Scumm::o_setState,
- /* 88 */
- &Scumm::o_isNotEqual,
- &Scumm::o_faceActor,
- &Scumm::o_startScript,
- &Scumm::o_getVerbEntrypoint,
- /* 8C */
- &Scumm::o_resourceRoutines,
- &Scumm::o_walkActorToActor,
- &Scumm::o_putActorAtObject,
- &Scumm::o_getObjectState,
- /* 90 */
- &Scumm::o_getObjectOwner,
- &Scumm::o_animateActor,
- &Scumm::o_panCameraTo,
- &Scumm::o_actorSet,
- /* 94 */
- &Scumm::o_print,
- &Scumm::o_actorFromPos,
- &Scumm::o_getRandomNr,
- &Scumm::o_and,
- /* 98 */
- &Scumm::o_quitPauseRestart,
- &Scumm::o_doSentence,
- &Scumm::o_move,
- &Scumm::o_multiply,
- /* 9C */
- &Scumm::o_startSound,
- &Scumm::o_ifClassOfIs,
- &Scumm::o_walkActorTo,
- &Scumm::o_isActorInBox,
- /* A0 */
- &Scumm::o_stopObjectCode,
- &Scumm::o_putActor,
- &Scumm::o_getAnimCounter,
- &Scumm::o_getActorY,
- /* A4 */
- &Scumm::o_loadRoomWithEgo,
- &Scumm::o_pickupObject,
- &Scumm::o_setVarRange,
- &Scumm::o_dummy,
- /* A8 */
- &Scumm::o_notEqualZero,
- &Scumm::o_setOwnerOf,
- &Scumm::o_startScript,
- &Scumm::o_saveRestoreVerbs,
- /* AC */
- &Scumm::o_expression,
- &Scumm::o_putActorInRoom,
- &Scumm::o_wait,
- &Scumm::o_badOpcode,
- /* B0 */
- &Scumm::o_matrixOps,
- &Scumm::o_getInventoryCount,
- &Scumm::o_setCameraAt,
- &Scumm::o_roomOps,
- /* B4 */
- &Scumm::o_getDist,
- &Scumm::o_findObject,
- &Scumm::o_walkActorToObject,
- &Scumm::o_startObject,
- /* B8 */
- &Scumm::o_lessOrEqual,
- &Scumm::o_doSentence,
- &Scumm::o_subtract,
- &Scumm::o_getActorScale,
- /* BC */
- &Scumm::o_stopSound,
- &Scumm::o_findInventory,
- &Scumm::o_walkActorTo,
- &Scumm::o_drawBox,
- /* C0 */
- &Scumm::o_endCutscene,
- &Scumm::o_putActor,
- &Scumm::o_chainScript,
- &Scumm::o_getActorX,
- /* C4 */
- &Scumm::o_isLess,
- &Scumm::o_badOpcode,
- &Scumm::o_decrement,
- &Scumm::o_setState,
- /* C8 */
- &Scumm::o_isEqual,
- &Scumm::o_faceActor,
- &Scumm::o_startScript,
- &Scumm::o_getVerbEntrypoint,
- /* CC */
- &Scumm::o_pseudoRoom,
- &Scumm::o_walkActorToActor,
- &Scumm::o_putActorAtObject,
- &Scumm::o_badOpcode,
- /* D0 */
- &Scumm::o_badOpcode,
- &Scumm::o_animateActor,
- &Scumm::o_actorFollowCamera,
- &Scumm::o_actorSet,
- /* D4 */
- &Scumm::o_setObjectName,
- &Scumm::o_actorFromPos,
- &Scumm::o_getActorMoving,
- &Scumm::o_or,
- /* D8 */
- &Scumm::o_printEgo,
- &Scumm::o_doSentence,
- &Scumm::o_add,
- &Scumm::o_divide,
- /* DC */
- &Scumm::o_badOpcode,
- &Scumm::o_actorSetClass,
- &Scumm::o_walkActorTo,
- &Scumm::o_isActorInBox,
- /* E0 */
- &Scumm::o_freezeScripts,
- &Scumm::o_putActor,
- &Scumm::o_stopScript,
- &Scumm::o_getActorFacing,
- /* E4 */
- &Scumm::o_loadRoomWithEgo,
- &Scumm::o_pickupObject,
- &Scumm::o_getClosestObjActor,
- &Scumm::o_dummy,
- /* E8 */
- &Scumm::o_getScriptRunning,
- &Scumm::o_setOwnerOf,
- &Scumm::o_startScript,
- &Scumm::o_debug,
- /* EC */
- &Scumm::o_getActorWidth,
- &Scumm::o_putActorInRoom,
- &Scumm::o_stopObjectScript,
- &Scumm::o_badOpcode,
- /* F0 */
- &Scumm::o_lights,
- &Scumm::o_getActorCostume,
- &Scumm::o_loadRoom,
- &Scumm::o_roomOps,
- /* F4 */
- &Scumm::o_getDist,
- &Scumm::o_findObject,
- &Scumm::o_walkActorToObject,
- &Scumm::o_startObject,
- /* F8 */
- &Scumm::o_isGreater,
- &Scumm::o_doSentence,
- &Scumm::o_verbOps,
- &Scumm::o_getActorWalkBox,
- /* FC */
- &Scumm::o_isSoundRunning,
- &Scumm::o_findInventory,
- &Scumm::o_walkActorTo,
- &Scumm::o_drawBox
- };
-
- return opcode_list[i];
-}
-
-
void Scumm::executeScript() {
OpcodeProc op;
while (_currentScript != 0xFF) {
_opcode = fetchScriptByte();
_scriptPointerStart = _scriptPointer;
vm.slot[_currentScript].didexec = 1;
- debug(9, "%X", _opcode);
+// debug(1, "%X", _opcode);
op = getOpcode(_opcode);
(this->*op)();
}
- checkHeap();
+ CHECK_HEAP
}
byte Scumm::fetchScriptByte() {
@@ -639,18 +313,33 @@ void Scumm::ignoreScriptByte() {
fetchScriptByte();
}
-int Scumm::getVarOrDirectWord(byte mask) {
- if (_opcode&mask)
- return readVar(fetchScriptWord());
- return (int16)fetchScriptWord();
-}
-int Scumm::getVarOrDirectByte(byte mask) {
- if (_opcode&mask)
- return readVar(fetchScriptWord());
- return fetchScriptByte();
+#if defined(DOTT)
+int Scumm::readVar(uint var) {
+ int a;
+
+ if (!(var&0xF000)) {
+ checkRange(_numVariables-1, 0, var, "Variable %d out of range(r)");
+ return _vars[var];
+ }
+
+ if (var&0x8000) {
+ var &= 0x7FFF;
+ checkRange(_numBitVariables-1, 0, var, "Bit variable %d out of range(r)");
+ return (_bitVars[var>>3] & (1<<(var&7))) ? 1 : 0;
+ }
+
+ if (var&0x4000) {
+ var &= 0xFFF;
+ checkRange(0x10, 0, var, "Local variable %d out of range(r)");
+ return vm.localvar[_currentScript * 17 + var];
+ }
+
+ error("Illegal varbits (r)");
}
+#else
+
int Scumm::readVar(uint var) {
int a;
#ifdef BYPASS_COPY_PROT
@@ -658,8 +347,8 @@ int Scumm::readVar(uint var) {
#endif
debug(9, "readvar=%d", var);
if (!(var&0xF000)) {
- checkRange(0x31F, 0, var, "Variable %d out of range(r)");
- return vm.vars[var];
+ checkRange(_numVariables-1, 0, var, "Variable %d out of range(r)");
+ return _vars[var];
}
if (var&0x2000) {
@@ -671,12 +360,12 @@ int Scumm::readVar(uint var) {
}
if (!(var&0xF000))
- return vm.vars[var];
+ return _vars[var];
if (var&0x8000) {
- var &= 0xFFF;
- checkRange(0x7FF, 0, var, "Bit variable %d out of range(r)");
- return (vm.bitvars[var>>3] & (1<<(var&7))) ? 1 : 0;
+ var &= 0x7FFF;
+ checkRange(_numBitVariables-1, 0, var, "Bit variable %d out of range(r)");
+ return (_bitVars[var>>3] & (1<<(var&7))) ? 1 : 0;
}
if (var&0x4000) {
@@ -695,44 +384,24 @@ int Scumm::readVar(uint var) {
error("Illegal varbits (r)");
}
-void Scumm::getResultPos() {
- int a;
-
- _resultVarNumber = fetchScriptWord();
- if (_resultVarNumber&0x2000) {
- a = fetchScriptWord();
- if (a&0x2000) {
- _resultVarNumber += readVar(a&~0x2000);
- } else {
- _resultVarNumber += a&0xFFF;
- }
- _resultVarNumber&=~0x2000;
- }
-
- debug(9, "getResultPos=%d", _resultVarNumber);
-}
+#endif
-void Scumm::setResult(int value) {
- int var = _resultVarNumber;
- debug(9, "setResult %d,%d", var,value);
+void Scumm::writeVar(uint var, int value) {
+ int a;
if (!(var&0xF000)) {
- checkRange(0x31F, 0, var, "Variable %d out of range(w)");
- vm.vars[var] = value;
-
- if (var==518) {
- printf("The answer is %d\n", value);
- }
+ checkRange(_numVariables-1, 0, var, "Variable %d out of range(w)");
+ _vars[var] = value;
return;
}
- if(var&0x8000) {
- var&=0xFFF;
- checkRange(0x7FF, 0, var, "Bit variable %d out of range(w)");
+ if (var&0x8000) {
+ var &= 0x7FFF;
+ checkRange(_numBitVariables-1, 0, var, "Bit variable %d out of range(w)");
if (value)
- vm.bitvars[var>>3] |= (1<<(var&7));
+ _bitVars[var>>3] |= (1<<(var&7));
else
- vm.bitvars[var>>3] &= ~(1<<(var&7));
+ _bitVars[var>>3] &= ~(1<<(var&7));
return;
}
@@ -742,410 +411,29 @@ void Scumm::setResult(int value) {
vm.localvar[_currentScript * 17 + var] = value;
return;
}
- error("Illegal varbits (w)");
-}
-
-void Scumm::o_actorFollowCamera() {
- int a = camera._follows;
-
- setCameraFollows(derefActorSafe(getVarOrDirectByte(0x80), "actorFollowCamera"));
-
- if (camera._follows != a)
- runHook(0);
-
- camera._movingToActor = 0;
-}
-
-void Scumm::o_actorFromPos() {
- int x,y;
- getResultPos();
- x = getVarOrDirectWord(0x80);
- y = getVarOrDirectWord(0x40);
- setResult(getActorFromPos(x,y));
-}
-
-void Scumm::o_actorSet() {
- int act = getVarOrDirectByte(0x80);
- Actor *a = derefActorSafe(act, "actorSet");
- int i,j;
-
- while ( (_opcode = fetchScriptByte()) != 0xFF) {
- switch(_opcode&0x1F) {
- case 1: /* costume */
- setActorCostume(a, getVarOrDirectByte(0x80));
- break;
- case 2: /* walkspeed */
- i = getVarOrDirectByte(0x80);
- j = getVarOrDirectByte(0x40);
- setActorWalkSpeed(a, i, j);
- break;
- case 3: /* sound */
- a->sound = getVarOrDirectByte(0x80);
- break;
- case 4: /* walkanim */
- a->walkFrame = getVarOrDirectByte(0x80);
- break;
- case 5: /* talkanim */
- a->talkFrame1 = getVarOrDirectByte(0x80);
- a->talkFrame2 = getVarOrDirectByte(0x40);
- break;
- case 6: /* standanim */
- a->standFrame = getVarOrDirectByte(0x80);
- break;
- case 7: /* ignore */
- getVarOrDirectByte(0x80);
- getVarOrDirectByte(0x40);
- getVarOrDirectByte(0x20);
- break;
- case 8: /* init */
- initActor(a, 0);
- break;
- case 9: /* elevation */
- a->elevation = getVarOrDirectWord(0x80);
- a->needRedraw = true;
- a->needBgReset = true;
- break;
- case 10: /* defaultanims */
- a->initFrame = 1;
- a->walkFrame = 2;
- a->standFrame = 3;
- a->talkFrame1 = 4;
- a->talkFrame2 = 4;
- break;
- case 11: /* palette */
- i = getVarOrDirectByte(0x80);
- j = getVarOrDirectByte(0x40);
- checkRange(32, 0, i, "Illegal palet slot %d");
- a->palette[i] = j;
- a->needRedraw = 1;
- break;
- case 12: /* talk color */
- a->talkColor = getVarOrDirectByte(0x80);
- break;
- case 13: /* name */
- loadPtrToResource(9, a->number, NULL);
- break;
- case 14: /* initanim */
- a->initFrame = getVarOrDirectByte(0x80);
- break;
- case 15: /* unk */
- error("o_actorset:unk not implemented");
- break;
- case 16: /* width */
- a->width = getVarOrDirectByte(0x80);
- break;
- case 17: /* scale */
- a->scalex = getVarOrDirectByte(0x80);
- a->scaley = getVarOrDirectByte(0x40);
- break;
- case 18: /* neverzclip */
- a->neverZClip = 0;
- break;
- case 19: /* setzclip */
- a->neverZClip = getVarOrDirectByte(0x80);
- break;
- case 20: /* ignoreboxes */
- a->ignoreBoxes = 1;
- a->neverZClip = 0;
-FixRoom:
- if (a->room==_currentRoom)
- putActor(a, a->x, a->y, a->room);
- break;
- case 21: /* followboxes */
- a->ignoreBoxes = 0;
- a->neverZClip = 0;
- goto FixRoom;
-
- case 22: /* animspeed */
- a->animSpeed = getVarOrDirectByte(0x80);
- break;
- case 23: /* unk2 */
- a->data8 = getVarOrDirectByte(0x80); /* unused */
- break;
- default:
- error("o_actorSet: default case");
- }
- }
-}
-
-void Scumm::o_actorSetClass() {
- int act = getVarOrDirectWord(0x80);
- int i;
- while ( (_opcode=fetchScriptByte()) != 0xFF) {
- i = getVarOrDirectWord(0x80);
- if (i==0) {
- _classData[act] = 0;
- continue;
- }
- if (i&0x80)
- putClass(act, i, 1);
- else
- putClass(act, i, 0);
- }
-}
-
-void Scumm::o_add() {
- int a;
- getResultPos();
- a = getVarOrDirectWord(0x80);
- setResult(readVar(_resultVarNumber) + a);
+ error("Illegal varbits (w)");
}
-void Scumm::o_and() {
+void Scumm::getResultPos() {
int a;
- getResultPos();
- a = getVarOrDirectWord(0x80);
- setResult(readVar(_resultVarNumber) & a);
-}
-
-void Scumm::o_animateActor() {
- int anim,shr,dir;
- bool inRoom;
- Actor *a;
-
- a = derefActorSafe(getVarOrDirectByte(0x80), "animateActor");
- anim = getVarOrDirectByte(0x40);
-
- shr = anim>>2;
- dir = anim&3;
-
- inRoom = (a->room == _currentRoom);
-
- if (shr == 0x3F) {
- if (inRoom) {
- startAnimActor(a, a->standFrame, a->facing);
- a->moving = 0;
- }
- return;
- }
-
- if (shr == 0x3E) {
- if (inRoom) {
- startAnimActor(a, 0x3E, dir);
- a->moving &= ~4;
- }
- a->facing = dir;
- return;
- }
- if (shr == 0x3D) {
- if (inRoom) {
- turnToDirection(a, dir);
+ _resultVarNumber = fetchScriptWord();
+ if (_resultVarNumber&0x2000) {
+ a = fetchScriptWord();
+ if (a&0x2000) {
+ _resultVarNumber += readVar(a&~0x2000);
} else {
- a->facing = dir;
- }
- return;
- }
-
- startAnimActor(a, anim, a->facing);
-}
-
-void Scumm::o_badOpcode() {
- error("Scumm opcode %d illegal", _opcode);
-}
-
-void Scumm::o_breakHere() {
- updateScriptPtr();
- _currentScript = 0xFF;
-}
-
-void Scumm::o_chainScript() {
- int16 vars[16];
- int data;
- int cur;
-
- data = getVarOrDirectByte(0x80);
-
- getWordVararg(vars);
-
- cur = _currentScript;
-
- if (vm.slot[cur].cutsceneOverride != 0) {
- error("Script %d chaining with active cutscene/override");
- }
-
- vm.slot[cur].number = 0;
- vm.slot[cur].status = 0;
- _currentScript = 0xFF;
-
- runScript(data, vm.slot[cur].unk1, vm.slot[cur].unk2, vars);
-}
-
-void Scumm::o_cursorCommand() {
- int i,j,k;
- int16 table[16];
-
- switch((_opcode=fetchScriptByte())&0x1F) {
- case 1: /* cursor show */
- _cursorState = 1;
- verbMouseOver(0);
- break;
- case 2: /* cursor hide */
- _cursorState = 0;
- verbMouseOver(0);
- break;
- case 3: /* userput on */
- _userPut = 1;
- break;
- case 4: /* userput off */
- _userPut = 0;
- break;
- case 5: /* cursor soft on */
- _cursorState++;
- if (_cursorState > 1) {
- error("Cursor state greater than 1 in script");
+ _resultVarNumber += a&0xFFF;
}
- break;
- case 6: /* cursor soft off */
- _cursorState--;
- break;
- case 7: /* userput soft on */
- _userPut++;
- break;
- case 8: /* userput soft off */
- _userPut--;
- break;
- case 10: /* set cursor img */
- i = getVarOrDirectByte(0x80);
- j = getVarOrDirectByte(0x40);
- setCursorImg(i, j);
- break;
- case 11: /* set cursor hotspot */
- i = getVarOrDirectByte(0x80);
- j = getVarOrDirectByte(0x40);
- k = getVarOrDirectByte(0x20);
- setCursorHotspot(i, j, k);
- break;
-
- case 12: /* init cursor */
- setCursor(getVarOrDirectByte(0x80));
- break;
- case 13: /* init charset */
- initCharset(getVarOrDirectByte(0x80));
- break;
- case 14: /* unk */
- getWordVararg(table);
- for (i=0; i<16; i++)
- charset._colorMap[i] = _charsetData[textslot.charset[1]][i] = table[i];
- break;
+ _resultVarNumber&=~0x2000;
}
- vm.vars[VAR_CURSORSTATE] = _cursorState;
- vm.vars[VAR_USERPUT] = _userPut;
-}
-
-void Scumm::o_cutscene() {
- int scr = _currentScript;
-
- getWordVararg(_vararg_temp_pos);
-
- vm.slot[scr].cutsceneOverride++;
-
- if (++vm.cutSceneStackPointer > 5)
- error("Cutscene stack overflow");
-
- vm.cutSceneData[vm.cutSceneStackPointer] = _vararg_temp_pos[0];
- vm.cutSceneScript[vm.cutSceneStackPointer] = 0;
- vm.cutScenePtr[vm.cutSceneStackPointer] = 0;
-
- vm.cutSceneScriptIndex = scr;
- if (vm.vars[VAR_CUTSCENE_START_SCRIPT])
- runScript(vm.vars[VAR_CUTSCENE_START_SCRIPT], 0, 0, _vararg_temp_pos);
- vm.cutSceneScriptIndex = 0xFF;
-}
-
-void Scumm::o_endCutscene() {
- ScriptSlot *ss = &vm.slot[_currentScript];
- uint32 *csptr;
-
- ss->cutsceneOverride--;
-
- _vararg_temp_pos[0] = vm.cutSceneData[vm.cutSceneStackPointer];
- vm.vars[VAR_OVERRIDE] = 0;
-
- csptr = &vm.cutScenePtr[vm.cutSceneStackPointer];
- if (*csptr)
- ss->cutsceneOverride--;
-
- vm.cutSceneScript[vm.cutSceneStackPointer] = 0;
- *csptr = 0;
- vm.cutSceneStackPointer--;
-
- if (vm.vars[VAR_CUTSCENE_END_SCRIPT])
- runScript(vm.vars[VAR_CUTSCENE_END_SCRIPT], 0, 0, _vararg_temp_pos);
-}
-
-
-void Scumm::o_debug() {
- getVarOrDirectWord(0x80);
-}
-
-void Scumm::o_decrement() {
- getResultPos();
- setResult(readVar(_resultVarNumber)-1);
-}
-
-void Scumm::o_delay() {
- int delay = fetchScriptByte();
- delay |= fetchScriptByte()<<8;
- delay |= fetchScriptByte()<<16;
- vm.slot[_currentScript].delay = delay;
- vm.slot[_currentScript].status = 1;
- o_breakHere();
-}
-
-void Scumm::o_delayVariable() {
- vm.slot[_currentScript].delay = readVar(fetchScriptWord());
- vm.slot[_currentScript].status = 1;
- o_breakHere();
-}
-
-void Scumm::o_divide() {
- int a;
- getResultPos();
- a = getVarOrDirectWord(0x80);
- if(a==0) {
- error("Divide by zero");
- setResult(0);
- } else
- setResult(readVar(_resultVarNumber) / a);
-}
-
-void Scumm::o_doSentence() {
- int a,b;
- _sentenceIndex++;
-
- a = getVarOrDirectByte(0x80);
- if (a==0xFE) {
- _sentenceIndex = 0xFF;
- stopScriptNr(vm.vars[VAR_SENTENCE_SCRIPT]);
- clearClickedStatus();
- return;
- }
- _sentenceTab5[_sentenceIndex] = a;
- _sentenceTab4[_sentenceIndex] = getVarOrDirectWord(0x40);
- b = _sentenceTab3[_sentenceIndex] = getVarOrDirectWord(0x20);
- if (b==0) {
- _sentenceTab2[_sentenceIndex] = 0;
- } else {
- _sentenceTab2[_sentenceIndex] = 1;
- }
- _sentenceTab[_sentenceIndex] = 0;
+ debug(9, "getResultPos=%d", _resultVarNumber);
}
-void Scumm::o_drawBox() {
- int x,y,x2,y2,color;
-
- x = getVarOrDirectWord(0x80);
- y = getVarOrDirectWord(0x40);
-
- _opcode = fetchScriptByte();
- x2 = getVarOrDirectWord(0x80);
- y2 = getVarOrDirectWord(0x40);
- color = getVarOrDirectByte(0x20);
-
- drawBox(x, y, x2, y2, color);
+void Scumm::setResult(int value) {
+ writeVar(_resultVarNumber, value);
}
void Scumm::drawBox(int x, int y, int x2, int y2, int color) {
@@ -1186,1314 +474,6 @@ void Scumm::drawBox(int x, int y, int x2, int y2, int color) {
}
}
-void Scumm::o_drawObject() {
- int state,obj,index,i;
- ObjectData *od;
- byte x,y,w,h;
-
- state = 1;
- _xPos = _yPos = 255;
- obj = getVarOrDirectWord(0x80);
-
- switch((_opcode = fetchScriptByte())&0x1F) {
- case 1: /* draw at */
- _xPos = getVarOrDirectWord(0x80);
- _yPos = getVarOrDirectWord(0x40);
- break;
- case 2: /* set state */
- state = getVarOrDirectWord(0x80);
- break;
- case 0x1F: /* neither */
- break;
- default:
- error("o_drawObject: default case");
- }
- index = getObjectIndex(obj);
- if (index==-1)
- return;
- od = &objs[index];
- if (_xPos!=0xFF) {
- od->cdhd_10 += (_xPos - od->x_pos)<<3;
- od->x_pos = _xPos;
- od->cdhd_12 += (_yPos - od->y_pos)<<3;
- od->y_pos = _yPos;
- }
- addObjectToDrawQue(index);
-
- x = od->x_pos;
- y = od->y_pos;
- w = od->numstrips;
- h = od->height;
-
- i = _numObjectsInRoom;
- do {
- if (objs[i].x_pos == x && objs[i].y_pos == y
- && objs[i].numstrips == w && objs[i].height==h)
- putState(objs[i].obj_nr, 0);
- } while (--i);
-
- putState(obj, state);
-}
-
-void Scumm::o_dummy() {
- /* nothing */
-}
-
-
-void Scumm::o_expression() {
- int dst, i;
-
- _scummStackPos = 0;
- getResultPos();
- dst = _resultVarNumber;
-
- while ((_opcode = fetchScriptByte())!=0xFF) {
- switch(_opcode&0x1F) {
- case 1: /* varordirect */
- stackPush(getVarOrDirectWord(0x80));
- break;
- case 2: /* add */
- i = stackPop();
- stackPush(i + stackPop());
- break;
- case 3: /* sub */
- i = stackPop();
- stackPush(stackPop() - i);
- break;
- case 4: /* mul */
- i = stackPop();
- stackPush(i * stackPop());
- break;
- case 5: /* div */
- i = stackPop();
- if (i==0)
- error("Divide by zero");
- stackPush(stackPop() / i);
- break;
- case 6: /* normal opcode */
- _opcode = fetchScriptByte();
- (this->*(getOpcode(_opcode)))();
- stackPush(vm.vars[0]);
- break;
- }
- }
-
- _resultVarNumber = dst;
- setResult(stackPop());
-}
-
-void Scumm::o_faceActor() {
- int act, obj;
- int x;
- byte dir;
-
- act = getVarOrDirectByte(0x80);
- obj = getVarOrDirectWord(0x40);
-
- if (getObjectOrActorXY(act)==-1)
- return;
-
- x = _xPos;
-
- if (getObjectOrActorXY(obj)==-1)
- return;
-
- dir = (_xPos > x) ? 1 : 0;
- turnToDirection(derefActorSafe(act, "o_faceActor"), dir);
-}
-
-void Scumm::o_findInventory() {
- int owner, b, count, i, obj;
-
- getResultPos();
- owner = getVarOrDirectByte(0x80);
- b = getVarOrDirectByte(0x40);
- count = 1;
- for (i=0; i!=_maxInventoryItems; i++) {
- obj = _inventory[i];
- if (obj && getOwner(obj)==owner && count++ == b) {
- setResult(obj);
- return;
- }
- }
- setResult(0);
-}
-
-void Scumm::o_findObject() {
- int t;
- getResultPos();
- t = getVarOrDirectWord(0x80);
- setResult(findObject(t, getVarOrDirectWord(0x40)));
-}
-
-void Scumm::o_freezeScripts() {
- int scr = getVarOrDirectByte(0x80);
-
- if (scr!=0)
- freezeScripts(scr);
- else
- unfreezeScripts();
-}
-
-void Scumm::o_getActorCostume() {
- getResultPos();
- setResult(derefActorSafe(getVarOrDirectByte(0x80),"o_getActorCostume")->costume);
-}
-
-void Scumm::o_getActorElevation() {
- getResultPos();
- setResult(derefActorSafe(getVarOrDirectByte(0x80),"o_getActorElevation")->elevation);
-}
-
-void Scumm::o_getActorFacing() {
- getResultPos();
- setResult(derefActorSafe(getVarOrDirectByte(0x80),"o_getActorFacing")->facing);
-}
-
-void Scumm::o_getActorMoving() {
- getResultPos();
- setResult(derefActorSafe(getVarOrDirectByte(0x80),"o_getActorMoving")->moving);
-}
-
-void Scumm::o_getActorRoom() {
- getResultPos();
- setResult(derefActorSafe(getVarOrDirectByte(0x80),"o_getActorRoom")->room);
-}
-
-void Scumm::o_getActorScale() {
- getResultPos();
- setResult(derefActorSafe(getVarOrDirectByte(0x80),"o_getActorScale")->scalex);
-}
-
-void Scumm::o_getActorWalkBox() {
- getResultPos();
- setResult(derefActorSafe(getVarOrDirectByte(0x80),"o_getActorWalkbox")->walkbox);
-}
-
-void Scumm::o_getActorWidth() {
- getResultPos();
- setResult(derefActorSafe(getVarOrDirectByte(0x80),"o_getActorWidth")->width);
-}
-
-void Scumm::o_getActorX() {
- int index;
- getResultPos();
- index = getVarOrDirectWord(0x80);
- if (index <= vm.vars[VAR_NUM_ACTOR]) {
- setResult(derefActorSafe(index,"o_getActorX")->x);
- } else {
- if (whereIsObject(index)==-1)
- setResult(-1);
- else {
- getObjectOrActorXY(index);
- setResult(_xPos);
- }
- }
-}
-
-void Scumm::o_getActorY() {
- int index;
- getResultPos();
- index = getVarOrDirectWord(0x80);
- if (index <= vm.vars[VAR_NUM_ACTOR]) {
- setResult(derefActorSafe(index,"o_getActorY")->y);
- } else {
- if (whereIsObject(index)==-1)
- setResult(-1);
- else {
- getObjectOrActorXY(index);
- setResult(_yPos);
- }
- }
-}
-
-void Scumm::o_getAnimCounter() {
- getResultPos();
- setResult(derefActorSafe(getVarOrDirectByte(0x80),"o_getActorAnimCounter")->cost.animCounter1);
-}
-
-void Scumm::o_getClosestObjActor() {
- int obj;
- int act;
- int closobj=-1, closnum=-1;
- int dist;
-
- getResultPos();
-
- act = getVarOrDirectWord(0x80);
- obj = vm.vars[VAR_OBJECT_HI];
-
- do {
- dist = getObjActToObjActDist(obj,act);
- if (dist < closnum) {
- closnum = dist;
- closobj = obj;
- }
- } while (--obj >= vm.vars[VAR_OBJECT_LO]);
-
- setResult(closnum);
-}
-
-void Scumm::o_getDist() {
- int o1,o2;
- getResultPos();
- o1 = getVarOrDirectWord(0x80);
- o2 = getVarOrDirectWord(0x40);
- setResult(getObjActToObjActDist(o1,o2));
-}
-
-void Scumm::o_getInventoryCount() {
- int owner, count, i, obj;
-
- getResultPos();
-
- owner = getVarOrDirectByte(0x80);
- count = 0;
- for (i=0; i!=_maxInventoryItems; i++) {
- obj = _inventory[i];
- if (obj && getOwner(obj)==owner)
- count++;
- }
- setResult(count);
-}
-
-void Scumm::o_getObjectOwner() {
- getResultPos();
- setResult(getOwner(getVarOrDirectWord(0x80)));
-}
-
-void Scumm::o_getObjectState() {
- getResultPos();
- setResult(getState(getVarOrDirectWord(0x80)));
-}
-
-void Scumm::o_getRandomNr() {
- getResultPos();
- setResult(getRandomNumber(getVarOrDirectByte(0x80)));
-}
-
-void Scumm::o_getScriptRunning() {
- int i;
- ScriptSlot *ss;
- int script;
-
- getResultPos();
- script = getVarOrDirectByte(0x80);
-
- ss = vm.slot;
- for (i=0; i<20; i++,ss++) {
- if (ss->number==script && (ss->type==2 || ss->type==3) && ss->status) {
- setResult(1);
- return;
- }
- }
- setResult(0);
-}
-
-void Scumm::o_getVerbEntrypoint() {
- int a,b;
- getResultPos();
- a = getVarOrDirectWord(0x80);
- b = getVarOrDirectWord(0x40);
- setResult(getVerbEntrypoint(a, b));
-}
-
-void Scumm::o_ifClassOfIs() {
- int act,cls;
- bool cond = true, b;
-
- act = getVarOrDirectWord(0x80);
- while ( (_opcode = fetchScriptByte()) != 0xFF) {
- cls = getVarOrDirectWord(0x80);
- b = getClass(act, cls);
-
- if (cls&0x80 && !b)
- cond = false;
- if (!(cls&0x80) && b)
- cond = false;
- }
- if (cond)
- ignoreScriptWord();
- else
- o_jumpRelative();
-}
-
-void Scumm::o_increment() {
- getResultPos();
- setResult(readVar(_resultVarNumber)+1);
-}
-
-void Scumm::o_isActorInBox() {
- int box;
- Actor *a;
-
- a = derefActorSafe(getVarOrDirectByte(0x80), "o_isActorInBox");
- box = getVarOrDirectByte(0x40);
-
- if (!checkXYInBoxBounds(box, a->x, a->y))
- o_jumpRelative();
- else
- ignoreScriptWord();
-}
-
-void Scumm::o_isEqual() {
- int16 a = readVar(fetchScriptWord());
- int16 b = getVarOrDirectWord(0x80);
- if (b == a) ignoreScriptWord();
- else o_jumpRelative();
-
-}
-
-void Scumm::o_isGreater() {
- int16 a = readVar(fetchScriptWord());
- int16 b = getVarOrDirectWord(0x80);
- if (b > a) ignoreScriptWord();
- else o_jumpRelative();
-}
-
-void Scumm::o_isGreaterEqual() {
- int16 a = readVar(fetchScriptWord());
- int16 b = getVarOrDirectWord(0x80);
- if (b >= a) ignoreScriptWord();
- else o_jumpRelative();
-}
-
-void Scumm::o_isLess() {
- int16 a = readVar(fetchScriptWord());
- int16 b = getVarOrDirectWord(0x80);
- if (b < a) ignoreScriptWord();
- else o_jumpRelative();
-}
-
-void Scumm::o_lessOrEqual() {
- int16 a = readVar(fetchScriptWord());
- int16 b = getVarOrDirectWord(0x80);
- if (b <= a) ignoreScriptWord();
- else o_jumpRelative();
-}
-
-void Scumm::o_isNotEqual() {
- int16 a = readVar(fetchScriptWord());
- int16 b = getVarOrDirectWord(0x80);
- if (b != a) ignoreScriptWord();
- else o_jumpRelative();
-}
-
-void Scumm::o_notEqualZero() {
- int a = readVar(fetchScriptWord());
- if (a != 0) ignoreScriptWord();
- else o_jumpRelative();
-}
-
-void Scumm::o_equalZero() {
- int a = readVar(fetchScriptWord());
- if (a == 0) ignoreScriptWord();
- else o_jumpRelative();
-}
-
-void Scumm::o_isSoundRunning() {
- int snd;
- getResultPos();
- snd = getVarOrDirectByte(0x80);
- if (snd)
- setResult(unkSoundProc23(snd));
- else
- setResult(0);
-}
-
-void Scumm::o_jumpRelative() {
- _scriptPointer += (int16)fetchScriptWord();
-}
-
-void Scumm::o_lights() {
- int a,b,c;
-
- a = getVarOrDirectByte(0x80);
- b = fetchScriptByte();
- c = fetchScriptByte();
- if (c==0)
- vm.vars[VAR_DRAWFLAGS] = a;
- else if (c==1) {
- _lightsValueA = a;
- _lightsValueB = b;
- }
- _fullRedraw=1;
-}
-
-void Scumm::o_loadRoom() {
- int room = getVarOrDirectByte(0x80);
- debug(1,"Loading room %d", room);
- startScene(room, 0, 0);
- _fullRedraw = 1;
-}
-
-void Scumm::o_loadRoomWithEgo() {
- int obj, room, x,y;
- Actor *a;
-
- obj = getVarOrDirectWord(0x80);
- room = getVarOrDirectByte(0x40);
-
- a = derefActorSafe(vm.vars[VAR_UNK_ACTOR], "o_loadRoomWithEgo");
-
- /* Warning: uses _xPos, _yPos from a previous update of those */
- putActor(a, _xPos, _yPos, room);
-
- x = (int16)fetchScriptWord();
- y = (int16)fetchScriptWord();
-
- dseg_3A76 = 0;
-
- vm.vars[VAR_WALKTO_OBJ] = obj;
-
- startScene(a->room, a, obj);
-
- vm.vars[VAR_WALKTO_OBJ] = 0;
- camera._destPos = camera._curPos = a->x;
- setCameraFollows(a);
- _fullRedraw=1;
-
- if (x != -1) {
- startWalkActor(a, x, y, 0xFF);
- }
-}
-
-void Scumm::o_matrixOps() {
- int a,b;
-
- _opcode = fetchScriptByte();
- switch(_opcode & 0x1F) {
- case 1:
- a = getVarOrDirectByte(0x80);
- b = getVarOrDirectByte(0x40);
- setBoxFlags(a,b);
- break;
- case 2:
- a = getVarOrDirectByte(0x80);
- b = getVarOrDirectByte(0x40);
- setBoxScale(a,b);
- break;
- case 3:
- a = getVarOrDirectByte(0x80);
- b = getVarOrDirectByte(0x40);
- setBoxScale(a,(b-1)|0x8000);
- break;
- case 4:
- createBoxMatrix();
- break;
- }
-}
-
-void Scumm::o_move() {
- getResultPos();
- setResult(getVarOrDirectWord(0x80));
-}
-
-void Scumm::o_multiply() {
- int a;
- getResultPos();
- a = getVarOrDirectWord(0x80);
- setResult(readVar(_resultVarNumber) * a);
-}
-
-
-void Scumm::o_or() {
- int a;
- getResultPos();
- a = getVarOrDirectWord(0x80);
- setResult(readVar(_resultVarNumber) | a);
-}
-
-void Scumm::o_overRide() {
- byte b;
- int index;
- uint32 *ptr;
-
- b = fetchScriptByte();
- if(b!=0) {
- index = vm.cutSceneStackPointer;
- ptr = &vm.cutScenePtr[index];
- if (!*ptr) {
- vm.slot[_currentScript].cutsceneOverride++;
- }
- *ptr = _scriptPointer - _scriptOrgPointer;
- vm.cutSceneScript[index] = _currentScript;
-
- ignoreScriptByte();
- ignoreScriptWord();
- } else {
- index = vm.cutSceneStackPointer;
- ptr = &vm.cutScenePtr[index];
- if (*ptr) {
- vm.slot[_currentScript].cutsceneOverride--;
- }
- *ptr = 0;
- vm.cutSceneScript[index] = 0;
- }
- vm.vars[VAR_OVERRIDE] = 0;
-}
-
-void Scumm::o_panCameraTo() {
- CameraData *cd = &camera;
- cd->_destPos = getVarOrDirectWord(0x80);
- cd->_mode = 3;
- cd->_movingToActor = 0;
-}
-
-void Scumm::o_pickupObject() {
- int obj, room;
-
- obj = getVarOrDirectWord(0x80);
- room = getVarOrDirectByte(0x40);
- if (room==0)
- room = _roomResource;
- addObjectToInventory(obj, room);
- putOwner(obj, vm.vars[VAR_UNK_ACTOR]);
- putClass(obj, 32, 1);
- putState(obj, 1);
- removeObjectFromRoom(obj);
- clearDrawObjectQueue();
- runHook(1);
-}
-
-void Scumm::o_print() {
- _actorToPrintStrFor = getVarOrDirectByte(0x80);
- decodeParseString();
-}
-
-void Scumm::o_printEgo() {
- _actorToPrintStrFor = vm.vars[VAR_UNK_ACTOR];
- decodeParseString();
-}
-
-void Scumm::o_pseudoRoom() {
- int i = fetchScriptByte(), j;
- while ((j = fetchScriptByte()) != 0) {
- if (j >= 0x80) {
- _resourceMapper[j&0x7F] = i;
- }
- }
-}
-
-void Scumm::o_putActor() {
- int x,y;
- Actor *a;
-
- a = derefActorSafe(getVarOrDirectByte(0x80), "o_putActor");
- x = getVarOrDirectWord(0x40);
- y = getVarOrDirectWord(0x20);
-
- putActor(a, x, y, a->room);
-}
-
-
-void Scumm::o_putActorAtObject() {
- int obj;
- Actor *a;
-
- a = derefActorSafe(getVarOrDirectByte(0x80), "o_putActorAtObject");
- obj = getVarOrDirectWord(0x40);
- if (whereIsObject(obj)!=-1)
- getObjectXYPos(obj);
- else {
- _xPos = 240;
- _yPos = 120;
- }
- putActor(a, _xPos, _yPos, a->room);
-}
-
-void Scumm::o_putActorInRoom() {
- int room;
- Actor *a;
-
- a = derefActorSafe(getVarOrDirectByte(0x80), "o_putActorInRoom");
- room = getVarOrDirectByte(0x40);
- if (a->visible && _currentRoom!=room && vm.vars[VAR_TALK_ACTOR]==a->number) {
- clearMsgQueue();
- }
- a->room = room;
- if (!room)
- putActor(a, 0, 0, 0);
-}
-
-void Scumm::o_quitPauseRestart() {
- switch(fetchScriptByte()) {
- case 1:
- pauseGame(0);
- break;
- case 3:
- shutDown(0);
- break;
- }
-}
-
-void Scumm::o_resourceRoutines() {
- int res;
-
- _opcode = fetchScriptByte();
- if (_opcode != 17)
- res = getVarOrDirectByte(0x80);
- switch(_opcode&0x1F) {
- case 1: /* load script */
- ensureResourceLoaded(2, res);
- break;
- case 2: /* load sound */
- ensureResourceLoaded(4, res);
- break;
- case 3: /* load costume */
- ensureResourceLoaded(3, res);
- break;
- case 4: /* load room */
- ensureResourceLoaded(1, res);
- break;
- case 5: /* nuke script */
- setResourceFlags(2, res, 0x7F);
- break;
- case 6: /* nuke sound */
- setResourceFlags(4, res, 0x7F);
- break;
- case 7: /* nuke costume */
- setResourceFlags(3, res, 0x7F);
- break;
- case 8: /* nuke room */
- setResourceFlags(1, res, 0x7F);
- break;
- case 9: /* lock script */
- if (res >= _numGlobalScriptsUsed)
- break;
- lock(2,res);
- break;
- case 10:/* lock sound */
- lock(4,res);
- break;
- case 11:/* lock costume */
- lock(3,res);
- break;
- case 12:/* lock room */
- if (res > 0x7F)
- res = _resourceMapper[res&0x7F];
- lock(1,res);
- break;
- case 13:/* unlock script */
- if (res >= _numGlobalScriptsUsed)
- break;
- unlock(2,res);
- break;
- case 14:/* unlock sound */
- unlock(4,res);
- break;
- case 15:/* unlock costume */
- unlock(3,res);
- break;
- case 16:/* unlock room */
- if (res > 0x7F)
- res = _resourceMapper[res&0x7F];
- unlock(1,res);
- break;
- case 17:/* clear heap */
- heapClear(0);
- unkHeapProc2(0,0);
- break;
- case 18:/* load charset */
- loadCharset(res);
- break;
- case 19:/* nuke charset */
- nukeCharset(res);
- break;
- case 20:/* ? */
- unkResProc(getVarOrDirectWord(0x40), res);
- break;
- }
-}
-
-void Scumm::o_roomOps() {
- int a,b,c,d,e;
-
- _opcode = fetchScriptByte();
-
- switch(_opcode & 0x1F) {
- case 1: /* room scroll */
- a = getVarOrDirectWord(0x80);
- b = getVarOrDirectWord(0x40);
- if (a < 160) a=160;
- if (a > ((_scrWidthIn8Unit-20)<<3)) a=((_scrWidthIn8Unit-20)<<3);
- if (b < 160) b=160;
- if (b > ((_scrWidthIn8Unit-20)<<3)) b=((_scrWidthIn8Unit-20)<<3);
- vm.vars[VAR_CAMERA_MIN] = a;
- vm.vars[VAR_CAMERA_MAX] = b;
- break;
- case 2: /* room color */
- error("room-color is no longer a valid command");
- break;
-
- case 3: /* set screen */
- a = getVarOrDirectWord(0x80);
- b = getVarOrDirectWord(0x40);
- initScreens(0,a,320,b);
- break;
- case 4: /* set palette color */
- a = getVarOrDirectWord(0x80);
- b = getVarOrDirectWord(0x40);
- c = getVarOrDirectWord(0x20);
- _opcode = fetchScriptByte();
- d = getVarOrDirectByte(0x80);
- setPalColor(d, a, b, c); /* index, r, g, b */
- break;
- case 5: /* shake on */
- setShake(1);
- break;
- case 6: /* shake off */
- setShake(0);
- break;
- case 8: /* room scale? */
- a = getVarOrDirectByte(0x80);
- b = getVarOrDirectByte(0x40);
- c = getVarOrDirectByte(0x20);
- unkRoomFunc2(b, c, a, a, a);
- break;
- case 9: /* ? */
- _saveLoadFlag = getVarOrDirectByte(0x80);
- _saveLoadData = getVarOrDirectByte(0x40);
- _saveLoadData = 0; /* TODO: weird behaviour */
- break;
- case 10: /* ? */
- a = getVarOrDirectWord(0x80);
- if (a) {
- _switchRoomEffect = (byte)(a);
- _switchRoomEffect2 = (byte)(a>>8);
- } else {
- screenEffect(_newEffect);
- }
- break;
- case 11: /* ? */
- a = getVarOrDirectWord(0x80);
- b = getVarOrDirectWord(0x40);
- c = getVarOrDirectWord(0x20);
- _opcode = fetchScriptByte();
- d = getVarOrDirectByte(0x80);
- e = getVarOrDirectByte(0x40);
- unkRoomFunc2(d, e, a, b, c);
- break;
- case 12: /* ? */
- a = getVarOrDirectWord(0x80);
- b = getVarOrDirectWord(0x40);
- c = getVarOrDirectWord(0x20);
- _opcode = fetchScriptByte();
- d = getVarOrDirectByte(0x80);
- e = getVarOrDirectByte(0x40);
- unkRoomFunc3(d, e, a, b, c);
- break;
-
- case 13: /* ? */
- error("roomops:13 not implemented");
- break;
- case 14: /* ? */
- error("roomops:14 not implemented");
- break;
- case 15: /* palmanip? */
- a = getVarOrDirectByte(0x80);
- _opcode = fetchScriptByte();
- b = getVarOrDirectByte(0x80);
- c = getVarOrDirectByte(0x40);
- _opcode = fetchScriptByte();
- d = getVarOrDirectByte(0x80);
- unkRoomFunc4(b, c, a, d, 1);
- break;
-
- case 16: /* ? */
- a = getVarOrDirectByte(0x80);
- b = getVarOrDirectByte(0x40);
- if (b!=0)
- _colorCycleDelays[a] = 0x4000 / (b*0x4C);
- else
- _colorCycleDelays[a] = 0;
- break;
- }
-}
-
-void Scumm::o_saveRestoreVerbs() {
- int a,b,c,slot, slot2;
-
- _opcode = fetchScriptByte();
-
- a = getVarOrDirectByte(0x80);
- b = getVarOrDirectByte(0x40);
- c = getVarOrDirectByte(0x20);
-
- switch(_opcode) {
- case 1: /* hide verbs */
- while (a<=b) {
- slot = getVerbSlot(a,0);
- if (slot && verbs[slot].saveid==0) {
- verbs[slot].saveid = c;
- drawVerb(slot, 0);
- verbMouseOver(0);
- }
- a++;
- }
- break;
- case 2: /* show verbs */
- while (a<=b) {
- slot = getVerbSlot(a, c);
- if (slot) {
- slot2 = getVerbSlot(a,0);
- if (slot2)
- killVerb(slot2);
- slot = getVerbSlot(a,c);
- verbs[slot].saveid = 0;
- drawVerb(slot, 0);
- verbMouseOver(0);
- }
- a++;
- }
- break;
- case 3: /* kill verbs */
- while (a<=b) {
- slot = getVerbSlot(a,c);
- if (slot)
- killVerb(slot);
- a++;
- }
- break;
- default:
- error("o_saveRestoreVerbs: invalid opcode");
- }
-}
-
-void Scumm::o_setCameraAt() {
- CameraData *cd = &camera;
- cd->_curPos = getVarOrDirectWord(0x80);
- cd->_mode = 1;
- setCameraAt(cd->_curPos);
- cd->_movingToActor = 0;
-}
-
-void Scumm::o_setObjectName() {
- int act = getVarOrDirectWord(0x80);
- int size;
- int a;
- int i;
-
- if (vm.vars[VAR_NUM_ACTOR] >= act)
- error("Can't set actor %d name with new-name-of", act);
-
- if (!getObjectAddress(act))
- error("Can't set name of object %d", act);
-
- size = READ_BE_UINT32_UNALIGNED(getObjOrActorName(act) - 4)-9;
- i = 0;
-
- while ((a = fetchScriptByte()) != 0) {
- getObjOrActorName(act)[i++] = a;
-
- if (a==0xFF) {
- getObjOrActorName(act)[i++] = fetchScriptByte();
- getObjOrActorName(act)[i++] = fetchScriptByte();
- getObjOrActorName(act)[i++] = fetchScriptByte();
- }
-
- if (i > size)
- error("New name of object %d too long", act);
- }
-
- getObjOrActorName(act)[i] = 0;
- runHook(0);
-}
-
-void Scumm::o_setOwnerOf() {
- int obj, owner;
- ScriptSlot *ss;
-
- obj = getVarOrDirectWord(0x80);
- owner = getVarOrDirectByte(0x40);
-
- if (owner==0) {
- clearOwnerOf(obj);
- ss = &vm.slot[_currentScript];
- if (ss->type==0 && _inventory[ss->number]==obj) {
- putOwner(obj, owner);
- runHook(0);
- stopObjectCode();
- return;
- }
- }
- putOwner(obj, owner);
- runHook(0);
-}
-
-void Scumm::o_setState() {
- int obj, state;
- obj = getVarOrDirectWord(0x80);
- state = getVarOrDirectByte(0x40);
- putState(obj, state);
- removeObjectFromRoom(obj);
- if (_BgNeedsRedraw)
- clearDrawObjectQueue();
-}
-
-void Scumm::o_setVarRange() {
- int a,b;
-
- getResultPos();
- a=fetchScriptByte();
- do {
- if (_opcode&0x80)
- b=fetchScriptWord();
- else
- b=fetchScriptByte();
-
- setResult(b);
- _resultVarNumber++;
- } while (--a);
-}
-
-void Scumm::o_soundKludge() {
- int16 items[15];
- int i;
- int16 *ptr;
-
- for (i=0; i<15; i++)
- items[i] = 0;
-
- getWordVararg(items);
- if (items[0]==-1)
- unkSoundProc22();
- else {
- _soundQue[_soundQuePos++] = 8;
-
- ptr = _soundQue + _soundQuePos;
- _soundQuePos += 8;
-
- for (i=0; i<8; i++)
- *ptr++ = items[i];
- if (_soundQuePos > 0x100)
- error("Sound que buffer overflow");
- }
-}
-
-void Scumm::o_startMusic() {
- addSoundToQueue(getVarOrDirectByte(0x80));
-}
-
-void Scumm::o_startObject() {
- int obj, script;
- int16 data[16];
-
- obj = getVarOrDirectWord(0x80);
- script = getVarOrDirectByte(0x40);
-
- getWordVararg(data);
- runVERBCode(obj, script, 0, 0, data);
-}
-
-void Scumm::o_startScript() {
- int op,script;
- int16 data[16];
- int a,b;
-
- op = _opcode;
- script = getVarOrDirectByte(0x80);
-
- getWordVararg(data);
-
- a = b = 0;
- if (op&0x40) b=1;
- if (op&0x20) a=1;
-
- runScript(script, a, b, data);
-}
-
-void Scumm::o_startSound() {
- addSoundToQueue(getVarOrDirectByte(0x80));
-}
-
-void Scumm::o_stopMusic() {
- /* TODO: not implemented */
- warning("o_stopMusic: not implemented");
-}
-
-void Scumm::o_stopObjectCode() {
- stopObjectCode();
-}
-
-void Scumm::o_stopObjectScript() {
- stopObjectScript(getVarOrDirectWord(0x80));
-}
-
-void Scumm::o_stopScript() {
- int script;
-
- script = getVarOrDirectByte(0x80);
- if (script==0)
- stopObjectCode();
- else
- stopScriptNr(script);
-}
-
-void Scumm::o_stopSound() {
- unkSoundProc1(getVarOrDirectByte(0x80));
-}
-
-void Scumm::o_stringOps() {
- int a,b,c,i;
- byte *ptr;
-
- _opcode = fetchScriptByte();
- switch(_opcode&0x1F) {
- case 1: /* loadstring */
- loadPtrToResource(7, getVarOrDirectByte(0x80), NULL);
- break;
- case 2: /* copystring */
- a = getVarOrDirectByte(0x80);
- b = getVarOrDirectByte(0x40);
- nukeResource(7, a);
- ptr = getResourceAddress(7, b);
- if (ptr) loadPtrToResource(7, a, ptr);
- break;
- case 3: /* set string char */
- a = getVarOrDirectByte(0x80);
- b = getVarOrDirectByte(0x40);
- ptr = getResourceAddress(7, a);
- if (ptr==NULL) error("String %d does not exist", a);
- c = getVarOrDirectByte(0x20);
- ptr[b] = c;
- break;
-
- case 4: /* get string char */
- getResultPos();
- a = getVarOrDirectByte(0x80);
- b = getVarOrDirectByte(0x40);
- ptr = getResourceAddress(7, a);
- if (ptr==NULL) error("String %d does not exist", a);
- setResult(ptr[b]);
- break;
-
- case 5: /* create empty string */
- a = getVarOrDirectByte(0x80);
- b = getVarOrDirectByte(0x40);
- nukeResource(7, a);
- if (b) {
- ptr = createResource(7, a, b);
- if (ptr) {
- for(i=0; i<b; i++)
- ptr[i] = 0;
- }
- }
- break;
- }
-}
-
-void Scumm::o_subtract() {
- int a;
- getResultPos();
- a = getVarOrDirectWord(0x80);
- setResult(readVar(_resultVarNumber) - a);
-}
-
-void Scumm::o_verbOps() {
- int verb,slot;
- VerbSlot *vs;
- int a,b;
- byte *ptr;
-
- verb = getVarOrDirectByte(0x80);
-
- slot = getVerbSlot(verb,0);
- checkRange(_maxVerbs-1, 0, slot, "Illegal new verb slot %d");
-
- vs = &verbs[slot];
- vs->verbid = verb;
-
- while ((_opcode=fetchScriptByte()) != 0xFF) {
- switch(_opcode&0x1F) {
- case 1: /* load image */
- a = getVarOrDirectWord(0x80);
- if (verb) {
- setVerbObject(_roomResource, a, verb);
- vs->type = 1;
- }
- break;
- case 2: /* load from code */
- loadPtrToResource(8, slot, NULL);
- if (slot==0)
- nukeResource(8, slot);
- vs->type = 0;
- vs->imgindex = 0;
- break;
- case 3: /* color */
- vs->color = getVarOrDirectByte(0x80);
- break;
- case 4: /* set hi color */
- vs->hicolor = getVarOrDirectByte(0x80);
- break;
- case 5: /* set xy */
- vs->x = getVarOrDirectWord(0x80);
- vs->y = getVarOrDirectWord(0x40);
- break;
- case 6: /* set on */
- vs->curmode=1;
- break;
- case 7: /* set off */
- vs->curmode=0;
- break;
- case 8: /* delete */
- killVerb(slot);
- break;
- case 9: /* new */
- slot = getVerbSlot(verb, 0);
- if (slot==0) {
- for (slot=1; slot<_maxVerbs; slot++) {
- if(verbs[slot].verbid==0)
- break;
- }
- if (slot==_maxVerbs)
- error("Too many verbs");
- }
- vs = &verbs[slot];
- vs->verbid = verb;
- vs->color = 2;
- vs->hicolor = 0;
- vs->dimcolor = 8;
- vs->type = 0;
- vs->charset_nr = textslot.charset[0];
- vs->curmode = 0;
- vs->saveid = 0;
- vs->key = 0;
- vs->center = 0;
- vs->imgindex = 0;
- break;
-
- case 16: /* set dim color */
- vs->dimcolor = getVarOrDirectByte(0x80);
- break;
- case 17: /* dim */
- vs->curmode = 2;
- break;
- case 18: /* set key */
- vs->key = getVarOrDirectByte(0x80);
- break;
- case 19: /* set center */
- vs->center = 1;
- break;
- case 20: /* set to string */
- ptr = getResourceAddress(7, getVarOrDirectWord(0x80));
- if (!ptr)
- nukeResource(8, slot);
- else {
- loadPtrToResource(8, slot, ptr);
- }
- if (slot==0)
- nukeResource(8, slot);
- vs->type = 0;
- vs->imgindex = 0;
- break;
- case 22: /* assign object */
- a = getVarOrDirectWord(0x80);
- b = getVarOrDirectByte(0x40);
- if (slot && vs->imgindex!=a) {
- setVerbObject(b, a, slot);
- vs->type = 1;
- vs->imgindex = a;
- }
- break;
- case 23: /* set back color */
- vs->bkcolor = getVarOrDirectByte(0x80);
- break;
- }
- }
- drawVerb(slot, 0);
- verbMouseOver(0);
-}
-
-void Scumm::o_wait() {
- byte *oldaddr;
-
- oldaddr = _scriptPointer - 1;
-
- _opcode = fetchScriptByte();
- switch(_opcode&0x1F) {
- case 1: /* wait for actor */
- if (derefActorSafe(getVarOrDirectByte(0x80), "o_wait")->moving)
- break;
- return;
- case 2: /* wait for message */
- if (vm.vars[VAR_HAVE_MSG])
- break;
- return;
- case 3: /* wait for camera */
- if (camera._curPos>>3 != camera._destPos>>3)
- break;
- return;
- case 4: /* wait for sentence */
- if (_sentenceIndex!=0xFF) {
- if (_sentenceTab[_sentenceIndex] &&
- !isScriptLoaded(vm.vars[VAR_SENTENCE_SCRIPT]) )
- return;
- break;
- }
- if (!isScriptLoaded(vm.vars[VAR_SENTENCE_SCRIPT]))
- return;
- break;
-
- default:
- return;
- }
-
- _scriptPointer = oldaddr;
- o_breakHere();
-}
-
-void Scumm::o_walkActorTo() {
- int x, y;
- Actor *a;
- a = derefActorSafe(getVarOrDirectByte(0x80), "o_walkActorTo");
- x = getVarOrDirectWord(0x40);
- y = getVarOrDirectWord(0x20);
- startWalkActor(a, x, y, 0xFF);
-}
-
-void Scumm::o_walkActorToActor() {
- int b,x,y;
- Actor *a, *a2;
-
- a = derefActorSafe(getVarOrDirectByte(0x80), "o_walkActorToActor");
- if (a->room != _currentRoom) {
- getVarOrDirectByte(0x40);
- fetchScriptByte();
- return;
- }
-
- a2 = derefActorSafe(getVarOrDirectByte(0x40), "o_walkActorToActor(2)");
- if (a2->room != _currentRoom) {
- fetchScriptByte();
- return;
- }
- b = fetchScriptByte(); /* distance from actor */
- if (b==0xFF) {
- b = a2->scalex * a->width / 0xFF;
- b = b + b/2;
- }
- x = a2->x;
- y = a2->y;
- if (x < a->x)
- x += b;
- else
- x -= b;
-
- startWalkActor(a, x, y, 0xFF);
-}
-
-void Scumm::o_walkActorToObject() {
- int obj;
- Actor *a;
-
- a = derefActorSafe(getVarOrDirectByte(0x80), "o_walkActorToObject");
- obj = getVarOrDirectWord(0x40);
- if (whereIsObject(obj)!=-1) {
- getObjectXYPos(obj);
- startWalkActor(a, _xPos, _yPos, _dir);
- }
-}
void Scumm::stopObjectCode() {
ScriptSlot *ss;
@@ -2501,28 +481,21 @@ void Scumm::stopObjectCode() {
ss = &vm.slot[_currentScript];
if (ss->type!=2 && ss->type!=3) {
- stopObjectScript(ss->number);
+ if (ss->cutsceneOverride)
+ error("Object %d ending with active cutscene/override", ss->number);
+
+ /* I wonder if the removal of this breaks anything.
+ * put ss->number and ss->status at another place if using this
+ * stopObjectScript(ss->number); */
} else {
if (ss->cutsceneOverride)
error("Script %d ending with active cutscene/override", ss->number);
- ss->number = 0;
- ss->status = 0;
}
+ ss->number = 0;
+ ss->status = 0;
_currentScript = 0xFF;
}
-int Scumm::getWordVararg(int16 *ptr) {
- int i;
- for (i=0; i<16; i++)
- ptr[i] = 0;
-
- i = 0;
- while ((_opcode = fetchScriptByte()) != 0xFF) {
- ptr[i++] = getVarOrDirectWord(0x80);
- }
- return i;
-}
-
bool Scumm::isScriptLoaded(int script) {
ScriptSlot *ss;
int i;
@@ -2538,8 +511,8 @@ bool Scumm::isScriptLoaded(int script) {
void Scumm::runHook(int i) {
int16 tmp[16];
tmp[0] = i;
- if (vm.vars[VAR_HOOK_SCRIPT]) {
- runScript(vm.vars[VAR_HOOK_SCRIPT], 0, 0, tmp);
+ if (_vars[VAR_HOOK_SCRIPT]) {
+ runScript(_vars[VAR_HOOK_SCRIPT], 0, 0, tmp);
}
}
@@ -2554,7 +527,7 @@ void Scumm::freezeScripts(int flag) {
}
for (i=0; i<6; i++)
- _sentenceTab[i]++;
+ sentence[i].unk++;
if(vm.cutSceneScriptIndex != 0xFF) {
vm.slot[vm.cutSceneScriptIndex].status&=0x7F;
@@ -2573,8 +546,8 @@ void Scumm::unfreezeScripts() {
}
for (i=0; i<6; i++) {
- if (((int8)--_sentenceTab[i])<0)
- _sentenceTab[i] = 0;
+ if (((int8)--sentence[i].unk)<0)
+ sentence[i].unk = 0;
}
}
@@ -2597,8 +570,8 @@ void Scumm::runAllScripts() {
}
void Scumm::runExitScript() {
- if (vm.vars[VAR_EXIT_SCRIPT])
- runScript(vm.vars[VAR_EXIT_SCRIPT], 0, 0, 0);
+ if (_vars[VAR_EXIT_SCRIPT])
+ runScript(_vars[VAR_EXIT_SCRIPT], 0, 0, 0);
if (_EXCD_offs) {
int slot = getScriptSlot();
vm.slot[slot].status = 2;
@@ -2610,13 +583,13 @@ void Scumm::runExitScript() {
vm.slot[slot].freezeCount = 0;
runScriptNested(slot);
}
- if (vm.vars[VAR_EXIT_SCRIPT2])
- runScript(vm.vars[VAR_EXIT_SCRIPT2], 0, 0, 0);
+ if (_vars[VAR_EXIT_SCRIPT2])
+ runScript(_vars[VAR_EXIT_SCRIPT2], 0, 0, 0);
}
void Scumm::runEntryScript() {
- if (vm.vars[VAR_ENTRY_SCRIPT])
- runScript(vm.vars[VAR_ENTRY_SCRIPT], 0, 0, 0);
+ if (_vars[VAR_ENTRY_SCRIPT])
+ runScript(_vars[VAR_ENTRY_SCRIPT], 0, 0, 0);
if (_ENCD_offs) {
int slot = getScriptSlot();
vm.slot[slot].status = 2;
@@ -2628,8 +601,8 @@ void Scumm::runEntryScript() {
vm.slot[slot].freezeCount = 0;
runScriptNested(slot);
}
- if (vm.vars[VAR_ENTRY_SCRIPT2])
- runScript(vm.vars[VAR_ENTRY_SCRIPT2], 0, 0, 0);
+ if (_vars[VAR_ENTRY_SCRIPT2])
+ runScript(_vars[VAR_ENTRY_SCRIPT2], 0, 0, 0);
}
void Scumm::killScriptsAndResources() {
@@ -2652,8 +625,8 @@ void Scumm::killScriptsAndResources() {
i = 0;
do {
- if (objs[i].fl_object_index)
- nukeResource(0xD, objs[i].fl_object_index);
+ if (_objs[i].fl_object_index)
+ nukeResource(0xD, _objs[i].fl_object_index);
} while (++i <= _numObjectsInRoom);
}
@@ -2662,29 +635,29 @@ void Scumm::checkAndRunVar33() {
ScriptSlot *ss;
memset(_localParamList, 0, sizeof(_localParamList));
- if (isScriptLoaded(vm.vars[VAR_SENTENCE_SCRIPT])) {
+ if (isScriptLoaded(_vars[VAR_SENTENCE_SCRIPT])) {
ss = vm.slot;
for (i=0; i<20; i++,ss++)
- if (ss->number==vm.vars[VAR_SENTENCE_SCRIPT] && ss->status!=0 && ss->freezeCount==0)
+ if (ss->number==_vars[VAR_SENTENCE_SCRIPT] && ss->status!=0 && ss->freezeCount==0)
return;
}
- if (_sentenceIndex > 0x7F || _sentenceTab[_sentenceIndex])
+ if (_sentenceIndex > 0x7F || sentence[_sentenceIndex].unk)
return;
- if (_sentenceTab2[_sentenceIndex] &&
- _sentenceTab3[_sentenceIndex]==_sentenceTab4[_sentenceIndex]) {
+ if (sentence[_sentenceIndex].unk2 &&
+ sentence[_sentenceIndex].unk3==sentence[_sentenceIndex].unk4) {
_sentenceIndex--;
return;
}
- _localParamList[0] = _sentenceTab5[_sentenceIndex];
- _localParamList[1] = _sentenceTab4[_sentenceIndex];
- _localParamList[2] = _sentenceTab3[_sentenceIndex];
+ _localParamList[0] = sentence[_sentenceIndex].unk5;
+ _localParamList[1] = sentence[_sentenceIndex].unk4;
+ _localParamList[2] = sentence[_sentenceIndex].unk3;
_sentenceIndex--;
_currentScript = 0xFF;
- if (vm.vars[VAR_SENTENCE_SCRIPT])
- runScript(vm.vars[VAR_SENTENCE_SCRIPT], 0, 0, _localParamList);
+ if (_vars[VAR_SENTENCE_SCRIPT])
+ runScript(_vars[VAR_SENTENCE_SCRIPT], 0, 0, _localParamList);
}
void Scumm::runInputScript(int a, int cmd, int mode) {
@@ -2692,8 +665,8 @@ void Scumm::runInputScript(int a, int cmd, int mode) {
_localParamList[0] = a;
_localParamList[1] = cmd;
_localParamList[2] = mode;
- if (vm.vars[VAR_VERB_SCRIPT])
- runScript(vm.vars[VAR_VERB_SCRIPT], 0, 0, _localParamList);
+ if (_vars[VAR_VERB_SCRIPT])
+ runScript(_vars[VAR_VERB_SCRIPT], 0, 0, _localParamList);
}
void Scumm::decreaseScriptDelay(int amount) {
@@ -2710,85 +683,9 @@ void Scumm::decreaseScriptDelay(int amount) {
}
}
-void Scumm::decodeParseString() {
- int textSlot;
- switch(_actorToPrintStrFor) {
- case 252:
- textSlot = 3;
- break;
- case 253:
- textSlot = 2;
- break;
- case 254:
- textSlot = 1;
- break;
- default:
- textSlot = 0;
- }
- _stringXpos[textSlot] = textslot.x[textSlot];
- _stringYpos[textSlot] = textslot.y[textSlot];
- _stringCenter[textSlot] = textslot.center[textSlot];
- _stringOverhead[textSlot] = textslot.overhead[textSlot];
- _stringRight[textSlot] = textslot.right[textSlot];
- _stringColor[textSlot] = textslot.color[textSlot];
- _stringCharset[textSlot] = textslot.charset[textSlot];
-
- while((_opcode=fetchScriptByte()) != 0xFF) {
- switch(_opcode&0xF) {
- case 0: /* set string xy */
- _stringXpos[textSlot] = getVarOrDirectWord(0x80);
- _stringYpos[textSlot] = getVarOrDirectWord(0x40);
- _stringOverhead[textSlot] = 0;
- break;
- case 1: /* color */
- _stringColor[textSlot] = getVarOrDirectByte(0x80);
- break;
- case 2: /* right */
- _stringRight[textSlot] = getVarOrDirectWord(0x80);
- break;
- case 4: /* center*/
- _stringCenter[textSlot] = 1;
- _stringOverhead[textSlot] = 0;
- break;
- case 6: /* left */
- _stringCenter[textSlot] = 0;
- _stringOverhead[textSlot] = 0;
- break;
- case 7: /* overhead */
- _stringOverhead[textSlot] = 1;
- break;
- case 8: /* ignore */
- getVarOrDirectWord(0x80);
- getVarOrDirectWord(0x40);
- break;
- case 15:
- _messagePtr = _scriptPointer;
- switch(textSlot) {
- case 0: actorTalk(); break;
- case 1: drawString(1); break;
- case 2: unkMessage1(); break;
- case 3: unkMessage2(); break;
- }
- _scriptPointer = _messagePtr;
- return;
- default:
- return;
- }
- }
-
- textslot.x[textSlot] = _stringXpos[textSlot];
- textslot.y[textSlot] = _stringYpos[textSlot];
- textslot.center[textSlot] = _stringCenter[textSlot];
- textslot.overhead[textSlot] = _stringOverhead[textSlot];
- textslot.right[textSlot] = _stringRight[textSlot];
- textslot.color[textSlot] = _stringColor[textSlot];
- textslot.charset[textSlot] = _stringCharset[textSlot];
-}
-
-
-void Scumm::runVERBCode(int object, int entry, int a, int b, int16 *vars) {
+void Scumm::runVerbCode(int object, int entry, int a, int b, int16 *vars) {
uint32 obcd;
int slot, where, offs,i;
@@ -2817,6 +714,9 @@ void Scumm::runVERBCode(int object, int entry, int a, int b, int16 *vars) {
vm.slot[slot].unk1 = a;
vm.slot[slot].unk2 = b;
vm.slot[slot].freezeCount = 0;
+#if defined(DOTT)
+ vm.slot[slot].newfield = 0;
+#endif
if (!vars) {
for(i=0; i<16; i++)
@@ -2829,16 +729,6 @@ void Scumm::runVERBCode(int object, int entry, int a, int b, int16 *vars) {
runScriptNested(slot);
}
-void Scumm::stackPush(int a) {
- assert(_scummStackPos >=0 && _scummStackPos < sizeof(_scummStack)-1);
- _scummStack[_scummStackPos++] = a;
-}
-
-int Scumm::stackPop() {
- assert(_scummStackPos >0 && _scummStackPos < sizeof(_scummStack));
- return _scummStack[--_scummStackPos];
-}
-
int Scumm::getVerbEntrypoint(int obj, int entry) {
byte *objptr, *verbptr;
int verboffs;
@@ -2866,3 +756,239 @@ int Scumm::getVerbEntrypoint(int obj, int entry) {
return verboffs + READ_LE_UINT16(verbptr+1);
}
+
+void Scumm::push(int a) {
+ assert(_scummStackPos >=0 && _scummStackPos < sizeof(_scummStack)-1);
+ _scummStack[_scummStackPos++] = a;
+}
+
+int Scumm::pop() {
+ assert(_scummStackPos >0 && _scummStackPos < sizeof(_scummStack));
+ return _scummStack[--_scummStackPos];
+}
+
+
+void Scumm::endCutscene() {
+ ScriptSlot *ss = &vm.slot[_currentScript];
+ uint32 *csptr;
+ int16 args[16];
+
+ memset(args, 0, sizeof(args));
+
+ ss->cutsceneOverride--;
+
+ args[0] = vm.cutSceneData[vm.cutSceneStackPointer];
+ _vars[VAR_OVERRIDE] = 0;
+
+ csptr = &vm.cutScenePtr[vm.cutSceneStackPointer];
+ if (*csptr)
+ ss->cutsceneOverride--;
+
+ vm.cutSceneScript[vm.cutSceneStackPointer] = 0;
+ *csptr = 0;
+ vm.cutSceneStackPointer--;
+
+ if (_vars[VAR_CUTSCENE_END_SCRIPT])
+ runScript(_vars[VAR_CUTSCENE_END_SCRIPT], 0, 0, args);
+}
+
+void Scumm::cutscene(int16 *args) {
+ int scr = _currentScript;
+ vm.slot[scr].cutsceneOverride++;
+
+ if (++vm.cutSceneStackPointer > 5)
+ error("Cutscene stack overflow");
+
+ vm.cutSceneData[vm.cutSceneStackPointer] = args[0];
+ vm.cutSceneScript[vm.cutSceneStackPointer] = 0;
+ vm.cutScenePtr[vm.cutSceneStackPointer] = 0;
+
+ vm.cutSceneScriptIndex = scr;
+ if (_vars[VAR_CUTSCENE_START_SCRIPT])
+ runScript(_vars[VAR_CUTSCENE_START_SCRIPT], 0, 0, args);
+ vm.cutSceneScriptIndex = 0xFF;
+}
+
+void Scumm::faceActorToObj(int act, int obj) {
+ int x,dir;
+
+ if (getObjectOrActorXY(act)==-1)
+ return;
+
+ x = _xPos;
+
+ if (getObjectOrActorXY(obj)==-1)
+ return;
+
+ dir = (_xPos > x) ? 1 : 0;
+ turnToDirection(derefActorSafe(act, "faceActorToObj"), dir);
+}
+
+void Scumm::animateActor(int act, int anim) {
+ int shr,dir;
+ bool inRoom;
+ Actor *a;
+
+ a = derefActorSafe(act, "animateActor");
+
+ shr = anim>>2;
+ dir = anim&3;
+
+ inRoom = (a->room == _currentRoom);
+
+ if (shr == 0x3F) {
+ if (inRoom) {
+ startAnimActor(a, a->standFrame, a->facing);
+ a->moving = 0;
+ }
+ return;
+ }
+
+ if (shr == 0x3E) {
+ if (inRoom) {
+ startAnimActor(a, 0x3E, dir);
+ a->moving &= ~4;
+ }
+ a->facing = dir;
+ return;
+ }
+
+ if (shr == 0x3D) {
+ if (inRoom) {
+ turnToDirection(a, dir);
+ } else {
+ a->facing = dir;
+ }
+ return;
+ }
+
+ startAnimActor(a, anim, a->facing);
+}
+
+int Scumm::getScriptRunning(int script) {
+ int i;
+ ScriptSlot *ss = vm.slot;
+ for (i=0; i<20; i++,ss++)
+ if (ss->number==script && (ss->type==2 || ss->type==3) && ss->status)
+ return 1;
+ return 0;
+}
+
+void Scumm::beginOverride() {
+ int index;
+ uint32 *ptr;
+
+ index = vm.cutSceneStackPointer;
+ ptr = &vm.cutScenePtr[index];
+ if (!*ptr) {
+ vm.slot[_currentScript].cutsceneOverride++;
+ }
+ *ptr = _scriptPointer - _scriptOrgPointer;
+ vm.cutSceneScript[index] = _currentScript;
+
+ fetchScriptByte();
+ fetchScriptWord();
+ _vars[VAR_OVERRIDE] = 0;
+}
+
+void Scumm::endOverride() {
+ int index;
+ uint32 *ptr;
+
+ index = vm.cutSceneStackPointer;
+ ptr = &vm.cutScenePtr[index];
+ if (*ptr) {
+ vm.slot[_currentScript].cutsceneOverride--;
+ }
+ *ptr = 0;
+ vm.cutSceneScript[index] = 0;
+ _vars[VAR_OVERRIDE] = 0;
+}
+
+
+#if defined(DOTT)
+int Scumm::defineArray(int array, int type, int dim2, int dim1) {
+ int id;
+ int size;
+ ArrayHeader *ah;
+
+ if (type!=5 && type!=4)
+ type=5;
+
+ nukeArray(array);
+
+ id = getArrayId();
+
+ if (array&0x4000) {
+ _arrays[id] = vm.slot[_currentScript].number;
+ }
+
+ if (array&0x8000) {
+ error("Can't define bit variable as array pointer");
+ }
+
+ writeVar(array, id);
+
+ size = (type==5) ? 16 : 8;
+ size *= dim2+1;
+ size *= dim1+1;
+ size >>= 3;
+
+ ah = (ArrayHeader*)createResource(7, id, size+sizeof(ArrayHeader));
+
+ ah->type = type;
+ ah->dim1_size = dim1+1;
+ ah->dim2_size = dim2+1;
+
+ return id;
+}
+
+void Scumm::nukeArray(int a) {
+ int data;
+
+ data = readVar(a);
+
+ if (data)
+ nukeResource(7, data);
+ _arrays[data] = 0;
+
+ writeVar(a, 0);
+}
+
+int Scumm::getArrayId() {
+ byte **addr = _baseArrays;
+ int i;
+
+ for (i=1; i<_numArray; i++) {
+ if (!addr[i])
+ return i;
+ }
+ error("Out of array pointers, %d max", _numArray);
+}
+
+void Scumm::copyString(byte *dst, byte *src, int len) {
+ if (!src) {
+ while (--len>=0)
+ *dst++ = fetchScriptByte();
+ } else {
+ while (--len>=0)
+ *dst++ = *src++;
+ }
+}
+#endif
+
+int Scumm::getStringLen(byte *ptr) {
+ int len;
+ byte c;
+ if (!ptr)
+ ptr = _scriptPointer;
+ len = 0;
+ do {
+ c = *ptr++;
+ if (!c) break;
+ len++;
+ if (c==0xFF)
+ ptr += 3, len += 3;
+ } while (1);
+ return len+1;
+}