diff options
author | Ludvig Strigeus | 2001-10-16 10:01:48 +0000 |
---|---|---|
committer | Ludvig Strigeus | 2001-10-16 10:01:48 +0000 |
commit | 794163c1a334e9f99f7cdd70ab2c70fd7bd04737 (patch) | |
tree | b40304976533e40b7f557018d95c844a15612c63 /script_v1.cpp | |
parent | 862192dbebd24f32e24f051b5a88f1bb6d801be8 (diff) | |
download | scummvm-rg350-794163c1a334e9f99f7cdd70ab2c70fd7bd04737.tar.gz scummvm-rg350-794163c1a334e9f99f7cdd70ab2c70fd7bd04737.tar.bz2 scummvm-rg350-794163c1a334e9f99f7cdd70ab2c70fd7bd04737.zip |
preliminary DOTT support
svn-id: r3433
Diffstat (limited to 'script_v1.cpp')
-rw-r--r-- | script_v1.cpp | 1986 |
1 files changed, 1986 insertions, 0 deletions
diff --git a/script_v1.cpp b/script_v1.cpp new file mode 100644 index 0000000000..dde9cbb908 --- /dev/null +++ b/script_v1.cpp @@ -0,0 +1,1986 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2001 Ludvig Strigeus + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * Change Log: + * $Log$ + * Revision 1.1 2001/10/16 10:01:47 strigeus + * preliminary DOTT support + * + */ + + +#include "stdafx.h" +#include "scumm.h" + +#if !defined(DOTT) + +void Scumm::setupOpcodes() { + static const OpcodeProc opcode_list[] = { + /* 00 */ + &Scumm::o_stopObjectCode, + &Scumm::o_putActor, + &Scumm::o_startMusic, + &Scumm::o_getActorRoom, + /* 04 */ + &Scumm::o_isGreaterEqual, + &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 + }; + + _opcodes = opcode_list; +} + +void Scumm::o_actorFollowCamera() { + actorFollowCamera(getVarOrDirectByte(0x80)); +} + +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[0] = 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 = 5; + break; + case 11: /* palette */ + i = getVarOrDirectByte(0x80); + j = getVarOrDirectByte(0x40); + checkRange(31, 0, i, "Illegal palet slot %d"); + a->palette[i] = j; + a->needRedraw = true; + 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); + a->needRedraw = true; + a->needBgReset = true; + 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); + a->animProgress = 0; + 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); +} + +void Scumm::o_and() { + int a; + getResultPos(); + a = getVarOrDirectWord(0x80); + setResult(readVar(_resultVarNumber) & a); +} + +void Scumm::o_animateActor() { + int act, anim; + + act = getVarOrDirectByte(0x80); + anim = getVarOrDirectByte(0x40); + animateActor(act,anim); +} + +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"); + } + verbMouseOver(0); + break; + case 6: /* cursor soft off */ + _cursorState--; + verbMouseOver(0); + 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[string[1].t_charset][i] = table[i]; + break; + } + + _vars[VAR_CURSORSTATE] = _cursorState; + _vars[VAR_USERPUT] = _userPut; +} + +void Scumm::o_cutscene() { + int16 args[16]; + getWordVararg(args); + cutscene(args); +} + +void Scumm::o_endCutscene() { + endCutscene(); +} + +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; + SentenceTab *st; + + _sentenceIndex++; + + a = getVarOrDirectByte(0x80); + if (a==0xFE) { + _sentenceIndex = 0xFF; + stopScriptNr(_vars[VAR_SENTENCE_SCRIPT]); + clearClickedStatus(); + return; + } + + st = &sentence[_sentenceIndex]; + + st->unk5 = a; + st->unk4 = getVarOrDirectWord(0x40); + b = st->unk3 = getVarOrDirectWord(0x20); + if (b==0) { + st->unk2 = 0; + } else { + st->unk2 = 1; + } + st->unk = 0; +} + +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::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 */ + push(getVarOrDirectWord(0x80)); + break; + case 2: /* add */ + i = pop(); + push(i + pop()); + break; + case 3: /* sub */ + i = pop(); + push(pop() - i); + break; + case 4: /* mul */ + i = pop(); + push(i * pop()); + break; + case 5: /* div */ + i = pop(); + if (i==0) + error("Divide by zero"); + push(pop() / i); + break; + case 6: /* normal opcode */ + _opcode = fetchScriptByte(); + (this->*(getOpcode(_opcode)))(); + push(_vars[0]); + break; + } + } + + _resultVarNumber = dst; + setResult(pop()); +} + +void Scumm::o_faceActor() { + int act, obj; + act = getVarOrDirectByte(0x80); + obj = getVarOrDirectWord(0x40); + faceActorToObj(act, obj); +} + +void Scumm::o_findInventory() { + int t; + getResultPos(); + t = getVarOrDirectByte(0x80); + setResult(findInventory(t,getVarOrDirectByte(0x40))); +} + +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() { + getResultPos(); + setResult(getObjX(getVarOrDirectWord(0x80))); +} + +void Scumm::o_getActorY() { + getResultPos(); + setResult(getObjY(getVarOrDirectWord(0x80))); +} + +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 = _vars[VAR_OBJECT_HI]; + + do { + dist = getObjActToObjActDist(obj,act); + if (dist < closnum) { + closnum = dist; + closobj = obj; + } + } while (--obj >= _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() { + getResultPos(); + setResult(getInventoryCount(getVarOrDirectByte(0x80))); +} + +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)+1)); +} + +void Scumm::o_getScriptRunning() { + getResultPos(); + setResult(getScriptRunning(getVarOrDirectByte(0x80))); +} + +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 || !(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) + snd = unkSoundProc23(snd); + setResult(snd); +} + +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) + _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(_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; + + _vars[VAR_WALKTO_OBJ] = obj; + + startScene(a->room, a, obj); + + _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() { + if(fetchScriptByte()!=0) + beginOverride(); + else + endOverride(); +} + +void Scumm::o_panCameraTo() { + panCameraTo(getVarOrDirectWord(0x80)); +} + +void Scumm::o_pickupObject() { + int obj, room; + + obj = getVarOrDirectWord(0x80); + room = getVarOrDirectByte(0x40); + if (room==0) + room = _roomResource; + addObjectToInventory(obj, room); + putOwner(obj, _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 = _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 && _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 >= _numGlobalScripts) + 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 >= _numGlobalScripts) + 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); + _vars[VAR_CAMERA_MIN] = a; + _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() { + setCameraAtEx(getVarOrDirectWord(0x80)); +} + +void Scumm::o_setObjectName() { + int act = getVarOrDirectWord(0x80); + int size; + int a; + int i; + + if (act <= _vars[VAR_NUM_ACTOR]) + 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; + + obj = getVarOrDirectWord(0x80); + owner = getVarOrDirectByte(0x40); + + setOwnerOf(obj, owner); +} + +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; + + for (i=0; i<15; i++) + items[i] = 0; + + getWordVararg(items); + + soundKludge(items); + +} + +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 = string[0].t_charset; + 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 (_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 (sentence[_sentenceIndex].unk && + !isScriptLoaded(_vars[VAR_SENTENCE_SCRIPT]) ) + return; + break; + } + if (!isScriptLoaded(_vars[VAR_SENTENCE_SCRIPT])) + return; + break; + default: + error("o_wait: default case"); + 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); + } +} + +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; +} + +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(); +} + +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; + } + + string[textSlot].xpos = string[textSlot].t_xpos; + string[textSlot].ypos = string[textSlot].t_ypos; + string[textSlot].center = string[textSlot].t_center; + string[textSlot].overhead = string[textSlot].t_overhead; + string[textSlot].right = string[textSlot].t_right; + string[textSlot].color = string[textSlot].t_color; + string[textSlot].charset = string[textSlot].t_charset; + + while((_opcode=fetchScriptByte()) != 0xFF) { + switch(_opcode&0xF) { + case 0: /* set string xy */ + string[textSlot].xpos = getVarOrDirectWord(0x80); + string[textSlot].ypos = getVarOrDirectWord(0x40); + string[textSlot].overhead = 0; + break; + case 1: /* color */ + string[textSlot].color = getVarOrDirectByte(0x80); + break; + case 2: /* right */ + string[textSlot].right = getVarOrDirectWord(0x80); + break; + case 4: /* center*/ + string[textSlot].center = 1; + string[textSlot].overhead = 0; + break; + case 6: /* left */ + string[textSlot].center = 0; + string[textSlot].overhead = 0; + break; + case 7: /* overhead */ + string[textSlot].overhead = 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; + } + } + + string[textSlot].t_xpos = string[textSlot].xpos; + string[textSlot].t_ypos = string[textSlot].ypos; + string[textSlot].t_center = string[textSlot].center; + string[textSlot].t_overhead = string[textSlot].overhead; + string[textSlot].t_right = string[textSlot].right; + string[textSlot].t_color = string[textSlot].color; + string[textSlot].t_charset = string[textSlot].charset; +} + + +#endif
\ No newline at end of file |