home *** CD-ROM | disk | FTP | other *** search
/ Chip 2002 February / chip_20022115.iso / amiga / chipgame / scummvm_aga.lha / ScummVM_AGA / src / script_v1.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2002-01-05  |  42.9 KB  |  1,987 lines

  1. /* ScummVM - Scumm Interpreter
  2.  * Copyright (C) 2001  Ludvig Strigeus
  3.  *
  4.  * This program is free software; you can redistribute it and/or
  5.  * modify it under the terms of the GNU General Public License
  6.  * as published by the Free Software Foundation; either version 2
  7.  * of the License, or (at your option) any later version.
  8.  
  9.  * This program is distributed in the hope that it will be useful,
  10.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.  * GNU General Public License for more details.
  13.  
  14.  * You should have received a copy of the GNU General Public License
  15.  * along with this program; if not, write to the Free Software
  16.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  17.  *
  18.  * $Header: /cvsroot/scummvm/scummvm/script_v1.cpp,v 1.9 2001/11/09 18:54:14 strigeus Exp $
  19.  *
  20.  */
  21.  
  22.  
  23. #include "stdafx.h"
  24. #include "scumm.h"
  25.  
  26. void Scumm::setupOpcodes() {
  27.     static const OpcodeProc opcode_list[] = {
  28.     /* 00 */
  29.     &Scumm::o5_stopObjectCode,
  30.     &Scumm::o5_putActor,
  31.     &Scumm::o5_startMusic,
  32.     &Scumm::o5_getActorRoom,
  33.     /* 04 */
  34.     &Scumm::o5_isGreaterEqual,
  35.     &Scumm::o5_drawObject,
  36.     &Scumm::o5_getActorElevation,
  37.     &Scumm::o5_setState,
  38.     /* 08 */
  39.     &Scumm::o5_isNotEqual,
  40.     &Scumm::o5_faceActor,
  41.     &Scumm::o5_startScript,
  42.     &Scumm::o5_getVerbEntrypoint,
  43.     /* 0C */
  44.     &Scumm::o5_resourceRoutines,
  45.     &Scumm::o5_walkActorToActor,
  46.     &Scumm::o5_putActorAtObject,
  47.     &Scumm::o5_getObjectState,
  48.     /* 10 */
  49.     &Scumm::o5_getObjectOwner,
  50.     &Scumm::o5_animateActor,
  51.     &Scumm::o5_panCameraTo,
  52.     &Scumm::o5_actorSet,
  53.     /* 14 */
  54.     &Scumm::o5_print,
  55.     &Scumm::o5_actorFromPos,
  56.     &Scumm::o5_getRandomNr,
  57.     &Scumm::o5_and,
  58.     /* 18 */
  59.     &Scumm::o5_jumpRelative,
  60.     &Scumm::o5_doSentence,
  61.     &Scumm::o5_move,
  62.     &Scumm::o5_multiply,
  63.     /* 1C */
  64.     &Scumm::o5_startSound,
  65.     &Scumm::o5_ifClassOfIs,
  66.     &Scumm::o5_walkActorTo,
  67.     &Scumm::o5_isActorInBox,
  68.     /* 20 */
  69.     &Scumm::o5_stopMusic,
  70.     &Scumm::o5_putActor,
  71.     &Scumm::o5_getAnimCounter,
  72.     &Scumm::o5_getActorY,
  73.     /* 24 */
  74.     &Scumm::o5_loadRoomWithEgo,
  75.     &Scumm::o5_pickupObject,
  76.     &Scumm::o5_setVarRange,
  77.     &Scumm::o5_stringOps,
  78.     /* 28 */
  79.     &Scumm::o5_equalZero,
  80.     &Scumm::o5_setOwnerOf,
  81.     &Scumm::o5_startScript,
  82.     &Scumm::o5_delayVariable,
  83.     /* 2C */
  84.     &Scumm::o5_cursorCommand,
  85.     &Scumm::o5_putActorInRoom,
  86.     &Scumm::o5_delay,
  87.     &Scumm::o5_badOpcode,
  88.     /* 30 */
  89.     &Scumm::o5_matrixOps,
  90.     &Scumm::o5_getInventoryCount,
  91.     &Scumm::o5_setCameraAt,
  92.     &Scumm::o5_roomOps,
  93.     /* 34 */
  94.     &Scumm::o5_getDist,
  95.     &Scumm::o5_findObject,
  96.     &Scumm::o5_walkActorToObject,
  97.     &Scumm::o5_startObject,
  98.     /* 38 */
  99.     &Scumm::o5_lessOrEqual,
  100.     &Scumm::o5_doSentence,
  101.     &Scumm::o5_subtract,
  102.     &Scumm::o5_getActorScale,
  103.     /* 3C */
  104.     &Scumm::o5_stopSound,
  105.     &Scumm::o5_findInventory,
  106.     &Scumm::o5_walkActorTo,
  107.     &Scumm::o5_drawBox,
  108.     /* 40 */
  109.     &Scumm::o5_cutscene,
  110.     &Scumm::o5_putActor,
  111.     &Scumm::o5_chainScript,
  112.     &Scumm::o5_getActorX,
  113.     /* 44 */
  114.     &Scumm::o5_isLess,
  115.     &Scumm::o5_badOpcode,
  116.     &Scumm::o5_increment,
  117.     &Scumm::o5_setState,
  118.     /* 48 */
  119.     &Scumm::o5_isEqual,
  120.     &Scumm::o5_faceActor,
  121.     &Scumm::o5_startScript,
  122.     &Scumm::o5_getVerbEntrypoint,
  123.     /* 4C */
  124.     &Scumm::o5_soundKludge,
  125.     &Scumm::o5_walkActorToActor,
  126.     &Scumm::o5_putActorAtObject,
  127.     &Scumm::o5_badOpcode,
  128.     /* 50 */
  129.     &Scumm::o5_badOpcode,
  130.     &Scumm::o5_animateActor,
  131.     &Scumm::o5_actorFollowCamera,
  132.     &Scumm::o5_actorSet,
  133.     /* 54 */
  134.     &Scumm::o5_setObjectName,
  135.     &Scumm::o5_actorFromPos,
  136.     &Scumm::o5_getActorMoving,
  137.     &Scumm::o5_or,
  138.     /* 58 */
  139.     &Scumm::o5_overRide,
  140.     &Scumm::o5_doSentence,
  141.     &Scumm::o5_add,
  142.     &Scumm::o5_divide,
  143.     /* 5C */
  144.     &Scumm::o5_badOpcode,
  145.     &Scumm::o5_actorSetClass,
  146.     &Scumm::o5_walkActorTo,
  147.     &Scumm::o5_isActorInBox,
  148.     /* 60 */
  149.     &Scumm::o5_freezeScripts,
  150.     &Scumm::o5_putActor,
  151.     &Scumm::o5_stopScript,
  152.     &Scumm::o5_getActorFacing,
  153.     /* 64 */
  154.     &Scumm::o5_loadRoomWithEgo,
  155.     &Scumm::o5_pickupObject,
  156.     &Scumm::o5_getClosestObjActor,
  157.     &Scumm::o5_dummy,
  158.     /* 68 */
  159.     &Scumm::o5_getScriptRunning,
  160.     &Scumm::o5_setOwnerOf,
  161.     &Scumm::o5_startScript,
  162.     &Scumm::o5_debug,
  163.     /* 6C */
  164.     &Scumm::o5_getActorWidth,
  165.     &Scumm::o5_putActorInRoom,
  166.     &Scumm::o5_stopObjectScript,
  167.     &Scumm::o5_badOpcode,
  168.     /* 70 */
  169.     &Scumm::o5_lights,
  170.     &Scumm::o5_getActorCostume,
  171.     &Scumm::o5_loadRoom,
  172.     &Scumm::o5_roomOps,
  173.     /* 74 */
  174.     &Scumm::o5_getDist,
  175.     &Scumm::o5_findObject,
  176.     &Scumm::o5_walkActorToObject,
  177.     &Scumm::o5_startObject,
  178.     /* 78 */
  179.     &Scumm::o5_isGreater, /* less? */
  180.     &Scumm::o5_doSentence,
  181.     &Scumm::o5_verbOps,
  182.     &Scumm::o5_getActorWalkBox,
  183.     /* 7C */
  184.     &Scumm::o5_isSoundRunning,
  185.     &Scumm::o5_findInventory,
  186.     &Scumm::o5_walkActorTo,
  187.     &Scumm::o5_drawBox,
  188.     /* 80 */
  189.     &Scumm::o5_breakHere,
  190.     &Scumm::o5_putActor,
  191.     &Scumm::o5_startMusic,
  192.     &Scumm::o5_getActorRoom,
  193.     /* 84 */
  194.     &Scumm::o5_isGreaterEqual, /* less equal? */
  195.     &Scumm::o5_drawObject,
  196.     &Scumm::o5_getActorElevation,
  197.     &Scumm::o5_setState,
  198.     /* 88 */
  199.     &Scumm::o5_isNotEqual,
  200.     &Scumm::o5_faceActor,
  201.     &Scumm::o5_startScript,
  202.     &Scumm::o5_getVerbEntrypoint,
  203.     /* 8C */
  204.     &Scumm::o5_resourceRoutines,
  205.     &Scumm::o5_walkActorToActor,
  206.     &Scumm::o5_putActorAtObject,
  207.     &Scumm::o5_getObjectState,
  208.     /* 90 */
  209.     &Scumm::o5_getObjectOwner,
  210.     &Scumm::o5_animateActor,
  211.     &Scumm::o5_panCameraTo,
  212.     &Scumm::o5_actorSet,
  213.     /* 94 */
  214.     &Scumm::o5_print,
  215.     &Scumm::o5_actorFromPos,
  216.     &Scumm::o5_getRandomNr,
  217.     &Scumm::o5_and,
  218.     /* 98 */
  219.     &Scumm::o5_quitPauseRestart,
  220.     &Scumm::o5_doSentence,
  221.     &Scumm::o5_move,
  222.     &Scumm::o5_multiply,
  223.     /* 9C */
  224.     &Scumm::o5_startSound,
  225.     &Scumm::o5_ifClassOfIs,
  226.     &Scumm::o5_walkActorTo,
  227.     &Scumm::o5_isActorInBox,
  228.     /* A0 */
  229.     &Scumm::o5_stopObjectCode,
  230.     &Scumm::o5_putActor,
  231.     &Scumm::o5_getAnimCounter,
  232.     &Scumm::o5_getActorY,
  233.     /* A4 */
  234.     &Scumm::o5_loadRoomWithEgo,
  235.     &Scumm::o5_pickupObject,
  236.     &Scumm::o5_setVarRange,
  237.     &Scumm::o5_dummy,
  238.     /* A8 */
  239.     &Scumm::o5_notEqualZero,
  240.     &Scumm::o5_setOwnerOf,
  241.     &Scumm::o5_startScript,
  242.     &Scumm::o5_saveRestoreVerbs,
  243.     /* AC */
  244.     &Scumm::o5_expression,
  245.     &Scumm::o5_putActorInRoom,
  246.     &Scumm::o5_wait,
  247.     &Scumm::o5_badOpcode,
  248.     /* B0 */
  249.     &Scumm::o5_matrixOps,
  250.     &Scumm::o5_getInventoryCount,
  251.     &Scumm::o5_setCameraAt,
  252.     &Scumm::o5_roomOps,
  253.     /* B4 */
  254.     &Scumm::o5_getDist,
  255.     &Scumm::o5_findObject,
  256.     &Scumm::o5_walkActorToObject,
  257.     &Scumm::o5_startObject,
  258.     /* B8 */
  259.     &Scumm::o5_lessOrEqual,
  260.     &Scumm::o5_doSentence,
  261.     &Scumm::o5_subtract,
  262.     &Scumm::o5_getActorScale,
  263.     /* BC */
  264.     &Scumm::o5_stopSound,
  265.     &Scumm::o5_findInventory,
  266.     &Scumm::o5_walkActorTo,
  267.     &Scumm::o5_drawBox,
  268.     /* C0 */
  269.     &Scumm::o5_endCutscene,
  270.     &Scumm::o5_putActor,
  271.     &Scumm::o5_chainScript,
  272.     &Scumm::o5_getActorX,
  273.     /* C4 */
  274.     &Scumm::o5_isLess,
  275.     &Scumm::o5_badOpcode,
  276.     &Scumm::o5_decrement,
  277.     &Scumm::o5_setState,
  278.     /* C8 */
  279.     &Scumm::o5_isEqual,
  280.     &Scumm::o5_faceActor,
  281.     &Scumm::o5_startScript,
  282.     &Scumm::o5_getVerbEntrypoint,
  283.     /* CC */
  284.     &Scumm::o5_pseudoRoom,
  285.     &Scumm::o5_walkActorToActor,
  286.     &Scumm::o5_putActorAtObject,
  287.     &Scumm::o5_badOpcode,
  288.     /* D0 */
  289.     &Scumm::o5_badOpcode,
  290.     &Scumm::o5_animateActor,
  291.     &Scumm::o5_actorFollowCamera,
  292.     &Scumm::o5_actorSet,
  293.     /* D4 */
  294.     &Scumm::o5_setObjectName,
  295.     &Scumm::o5_actorFromPos,
  296.     &Scumm::o5_getActorMoving,
  297.     &Scumm::o5_or,
  298.     /* D8 */
  299.     &Scumm::o5_printEgo,
  300.     &Scumm::o5_doSentence,
  301.     &Scumm::o5_add,
  302.     &Scumm::o5_divide,
  303.     /* DC */
  304.     &Scumm::o5_badOpcode,
  305.     &Scumm::o5_actorSetClass,
  306.     &Scumm::o5_walkActorTo,
  307.     &Scumm::o5_isActorInBox,
  308.     /* E0 */
  309.     &Scumm::o5_freezeScripts,
  310.     &Scumm::o5_putActor,
  311.     &Scumm::o5_stopScript,
  312.     &Scumm::o5_getActorFacing,
  313.     /* E4 */
  314.     &Scumm::o5_loadRoomWithEgo,
  315.     &Scumm::o5_pickupObject,
  316.     &Scumm::o5_getClosestObjActor,
  317.     &Scumm::o5_dummy,
  318.     /* E8 */
  319.     &Scumm::o5_getScriptRunning,
  320.     &Scumm::o5_setOwnerOf,
  321.     &Scumm::o5_startScript,
  322.     &Scumm::o5_debug,
  323.     /* EC */
  324.     &Scumm::o5_getActorWidth,
  325.     &Scumm::o5_putActorInRoom,
  326.     &Scumm::o5_stopObjectScript,
  327.     &Scumm::o5_badOpcode,
  328.     /* F0 */
  329.     &Scumm::o5_lights,
  330.     &Scumm::o5_getActorCostume,
  331.     &Scumm::o5_loadRoom,
  332.     &Scumm::o5_roomOps,
  333.     /* F4 */
  334.     &Scumm::o5_getDist,
  335.     &Scumm::o5_findObject,
  336.     &Scumm::o5_walkActorToObject,
  337.     &Scumm::o5_startObject,
  338.     /* F8 */
  339.     &Scumm::o5_isGreater,
  340.     &Scumm::o5_doSentence,
  341.     &Scumm::o5_verbOps,
  342.     &Scumm::o5_getActorWalkBox,
  343.     /* FC */
  344.     &Scumm::o5_isSoundRunning,
  345.     &Scumm::o5_findInventory,
  346.     &Scumm::o5_walkActorTo,
  347.     &Scumm::o5_drawBox
  348.     };
  349.  
  350.     _opcodes = opcode_list;
  351. }
  352.  
  353. void Scumm::o5_actorFollowCamera() {
  354.     actorFollowCamera(getVarOrDirectByte(0x80));
  355. }
  356.  
  357. void Scumm::o5_actorFromPos() {
  358.     int x,y;
  359.     getResultPos();
  360.     x = getVarOrDirectWord(0x80);
  361.     y = getVarOrDirectWord(0x40);
  362.     setResult(getActorFromPos(x,y));
  363. }
  364.  
  365. void Scumm::o5_actorSet() {
  366.     int act = getVarOrDirectByte(0x80);
  367.     Actor *a = derefActorSafe(act, "actorSet");
  368.     int i,j;
  369.  
  370.     while ( (_opcode = fetchScriptByte()) != 0xFF) {
  371.         switch(_opcode&0x1F) {
  372.         case 1: /* costume */
  373.             setActorCostume(a, getVarOrDirectByte(0x80));
  374.             break;
  375.         case 2: /* walkspeed */
  376.             i = getVarOrDirectByte(0x80);
  377.             j = getVarOrDirectByte(0x40);
  378.             setActorWalkSpeed(a, i, j);
  379.             break;
  380.         case 3: /* sound */
  381.             a->sound[0] = getVarOrDirectByte(0x80);
  382.             break;
  383.         case 4: /* walkanim */
  384.             a->walkFrame = getVarOrDirectByte(0x80);
  385.             break;
  386.         case 5: /* talkanim */
  387.             a->talkFrame1 = getVarOrDirectByte(0x80);
  388.             a->talkFrame2 = getVarOrDirectByte(0x40);
  389.             break;
  390.         case 6: /* standanim */
  391.             a->standFrame = getVarOrDirectByte(0x80);
  392.             break;
  393.         case 7: /* ignore */
  394.             getVarOrDirectByte(0x80);
  395.             getVarOrDirectByte(0x40);
  396.             getVarOrDirectByte(0x20);
  397.             break;
  398.         case 8: /* init */
  399.             initActor(a, 0);
  400.             break;
  401.         case 9: /* elevation */
  402.             a->elevation = getVarOrDirectWord(0x80);
  403.             a->needRedraw = true;
  404.             a->needBgReset = true;
  405.             break;
  406.         case 10: /* defaultanims */
  407.             a->initFrame = 1;
  408.             a->walkFrame = 2;
  409.             a->standFrame = 3;
  410.             a->talkFrame1 = 4;
  411.             a->talkFrame2 = 5;
  412.             break;
  413.         case 11: /* palette */
  414.             i = getVarOrDirectByte(0x80);
  415.             j = getVarOrDirectByte(0x40);
  416.             checkRange(31, 0, i, "Illegal palet slot %d");
  417.             a->palette[i] = j;
  418.             a->needRedraw = true;
  419.             break;
  420.         case 12: /* talk color */
  421.             a->talkColor = getVarOrDirectByte(0x80);
  422.             break;
  423.         case 13: /* name */
  424.             loadPtrToResource(9, a->number, NULL);
  425.             break;
  426.         case 14: /* initanim */
  427.             a->initFrame = getVarOrDirectByte(0x80);
  428.             break;
  429.         case 15: /* unk */
  430.             error("o5_actorset:unk not implemented");
  431.             break;
  432.         case 16: /* width */
  433.             a->width = getVarOrDirectByte(0x80);
  434.             break;
  435.         case 17: /* scale */
  436.             a->scalex = getVarOrDirectByte(0x80);
  437.             a->scaley = getVarOrDirectByte(0x40);
  438.             a->needRedraw = true;
  439.             a->needBgReset = true;
  440.             break;
  441.         case 18: /* neverzclip */
  442.             a->neverZClip = 0;
  443.             break;
  444.         case 19: /* setzclip */
  445.             a->neverZClip = getVarOrDirectByte(0x80);
  446.             break;
  447.         case 20: /* ignoreboxes */
  448.             a->ignoreBoxes = 1;
  449.             a->neverZClip = 0;
  450. FixRoom:
  451.             if (a->room==_currentRoom)
  452.                 putActor(a, a->x, a->y, a->room);
  453.             break;
  454.         case 21: /* followboxes */
  455.             a->ignoreBoxes = 0;
  456.             a->neverZClip = 0;
  457.             goto FixRoom;
  458.  
  459.         case 22: /* animspeed */
  460.             a->animSpeed = getVarOrDirectByte(0x80);
  461.             a->animProgress = 0;
  462.             break;
  463.         case 23: /* unk2 */
  464.             a->data8 = getVarOrDirectByte(0x80); /* unused */
  465.             break;
  466.         default:
  467.             error("o5_actorSet: default case");
  468.         }
  469.     }
  470. }
  471.  
  472. void Scumm::o5_actorSetClass() {
  473.     int act = getVarOrDirectWord(0x80);
  474.     int i;
  475.  
  476.     while ( (_opcode=fetchScriptByte()) != 0xFF) {
  477.         i = getVarOrDirectWord(0x80);
  478.         if (i==0) {
  479.             _classData[act] = 0;
  480.             continue;
  481.         }
  482.         if (i&0x80)
  483.             putClass(act, i, 1);
  484.         else
  485.             putClass(act, i, 0);
  486.     }
  487. }
  488.  
  489. void Scumm::o5_add() {
  490.     int a;
  491.     getResultPos();
  492.     a = getVarOrDirectWord(0x80);
  493.     setResult(readVar(_resultVarNumber) + a);
  494. }
  495.  
  496. void Scumm::o5_and() {
  497.     int a;
  498.     getResultPos();
  499.     a = getVarOrDirectWord(0x80);
  500.     setResult(readVar(_resultVarNumber) & a);
  501. }
  502.  
  503. void Scumm::o5_animateActor() {
  504.     int act, anim;
  505.  
  506.     act = getVarOrDirectByte(0x80);
  507.     anim = getVarOrDirectByte(0x40);
  508.     animateActor(act,anim);
  509. }
  510.  
  511. void Scumm::o5_badOpcode() {
  512.     error("Scumm opcode %d illegal", _opcode);
  513. }
  514.  
  515. void Scumm::o5_breakHere() {
  516.     updateScriptPtr();
  517.     _currentScript = 0xFF;
  518. }
  519.  
  520. void Scumm::o5_chainScript() {
  521.     int16 vars[16];
  522.     int data;
  523.     int cur;
  524.  
  525.     data = getVarOrDirectByte(0x80);
  526.  
  527.     getWordVararg(vars);
  528.  
  529.     cur = _currentScript;
  530.  
  531.     if (vm.slot[cur].cutsceneOverride != 0) {
  532.         error("Script %d chaining with active cutscene/override");
  533.     }
  534.  
  535.     vm.slot[cur].number = 0;
  536.     vm.slot[cur].status = 0;
  537.     _currentScript = 0xFF;
  538.  
  539.     runScript(data, vm.slot[cur].unk1, vm.slot[cur].unk2, vars);
  540. }
  541.  
  542. void Scumm::o5_cursorCommand() {
  543.     int i,j,k;
  544.     int16 table[16];
  545.  
  546.     switch((_opcode=fetchScriptByte())&0x1F) {
  547.     case 1: /* cursor show */
  548.         _cursorState = 1;
  549.         verbMouseOver(0);
  550.         break;
  551.     case 2: /* cursor hide */
  552.         _cursorState = 0;
  553.         verbMouseOver(0);
  554.         break;
  555.     case 3: /* userput on */
  556.         _userPut = 1;
  557.         break;
  558.     case 4: /* userput off */
  559.         _userPut = 0;
  560.         break;
  561.     case 5: /* cursor soft on */
  562.         _cursorState++;
  563.         if (_cursorState > 1) {
  564.             error("Cursor state greater than 1 in script");
  565.         }
  566.         verbMouseOver(0);
  567.         break;
  568.     case 6: /* cursor soft off */
  569.         _cursorState--;
  570.         verbMouseOver(0);
  571.         break;
  572.     case 7: /* userput soft on */
  573.         _userPut++;
  574.         break;
  575.     case 8: /* userput soft off */
  576.         _userPut--;
  577.         break;
  578.     case 10: /* set cursor img */
  579.         i = getVarOrDirectByte(0x80);
  580.         j = getVarOrDirectByte(0x40);
  581.         setCursorImg(i, j);
  582.         break;
  583.     case 11: /* set cursor hotspot */
  584.         i = getVarOrDirectByte(0x80);
  585.         j = getVarOrDirectByte(0x40);
  586.         k = getVarOrDirectByte(0x20);
  587.         setCursorHotspot(i, j, k);
  588.         break;
  589.  
  590.     case 12: /* init cursor */
  591.         setCursor(getVarOrDirectByte(0x80));
  592.         break;
  593.     case 13: /* init charset */
  594.         initCharset(getVarOrDirectByte(0x80));
  595.         break;
  596.     case 14: /* unk */
  597.         getWordVararg(table);
  598.         for (i=0; i<16; i++)
  599.             charset._colorMap[i] = _charsetData[string[1].t_charset][i] = table[i];
  600.         break;
  601.     }
  602.  
  603.     _vars[VAR_CURSORSTATE] = _cursorState;
  604.     _vars[VAR_USERPUT] = _userPut;
  605. }
  606.  
  607. void Scumm::o5_cutscene() {
  608.     int16 args[16];
  609.     getWordVararg(args);
  610.     cutscene(args);
  611. }
  612.  
  613. void Scumm::o5_endCutscene() {
  614.     endCutscene();
  615. }
  616.  
  617. void Scumm::o5_debug() {
  618.     getVarOrDirectWord(0x80);
  619. }
  620.  
  621. void Scumm::o5_decrement() {
  622.     getResultPos();
  623.     setResult(readVar(_resultVarNumber)-1);
  624. }
  625.  
  626. void Scumm::o5_delay() {
  627.     int delay = fetchScriptByte();
  628.     delay |= fetchScriptByte()<<8;
  629.     delay |= fetchScriptByte()<<16;
  630.     vm.slot[_currentScript].delay = delay;
  631.     vm.slot[_currentScript].status = 1;
  632.     o5_breakHere();
  633. }
  634.  
  635. void Scumm::o5_delayVariable() {
  636.     vm.slot[_currentScript].delay = readVar(fetchScriptWord());
  637.     vm.slot[_currentScript].status = 1;
  638.     o5_breakHere();
  639. }
  640.  
  641. void Scumm::o5_divide() {
  642.     int a;
  643.     getResultPos();
  644.     a = getVarOrDirectWord(0x80);
  645.     if(a==0) {
  646.         error("Divide by zero");
  647.         setResult(0);
  648.     } else 
  649.         setResult(readVar(_resultVarNumber) / a);
  650. }
  651.  
  652. void Scumm::o5_doSentence() {
  653.     int a,b;
  654.     SentenceTab *st;
  655.  
  656.     _sentenceIndex++;
  657.  
  658.     a = getVarOrDirectByte(0x80);
  659.     if (a==0xFE) {
  660.         _sentenceIndex = 0xFF;
  661.         stopScriptNr(_vars[VAR_SENTENCE_SCRIPT]);
  662.         clearClickedStatus();
  663.         return;
  664.     }
  665.  
  666.     st = &sentence[_sentenceIndex];
  667.  
  668.     st->unk5 = a;
  669.     st->unk4 = getVarOrDirectWord(0x40);
  670.     b = st->unk3 = getVarOrDirectWord(0x20);
  671.     if (b==0) {
  672.         st->unk2 = 0;
  673.     } else {
  674.         st->unk2 = 1;
  675.     }
  676.     st->unk = 0;
  677. }
  678.  
  679. void Scumm::o5_drawBox() {
  680.     int x,y,x2,y2,color;
  681.  
  682.     x = getVarOrDirectWord(0x80);
  683.     y = getVarOrDirectWord(0x40);
  684.  
  685.     _opcode = fetchScriptByte();
  686.     x2 = getVarOrDirectWord(0x80);
  687.     y2 = getVarOrDirectWord(0x40);
  688.     color = getVarOrDirectByte(0x20);
  689.  
  690.     drawBox(x, y, x2, y2, color);
  691. }
  692.  
  693. void Scumm::o5_drawObject() {
  694.     int state,obj,index,i;
  695.     ObjectData *od;
  696.     byte x,y,w,h;
  697.  
  698.     state = 1;
  699.     _xPos = _yPos = 255;
  700.     obj = getVarOrDirectWord(0x80);
  701.  
  702.     switch((_opcode = fetchScriptByte())&0x1F) {
  703.     case 1: /* draw at */
  704.         _xPos = getVarOrDirectWord(0x80);
  705.         _yPos = getVarOrDirectWord(0x40);
  706.         break;
  707.     case 2: /* set state */
  708.         state = getVarOrDirectWord(0x80);
  709.         break;
  710.     case 0x1F: /* neither */
  711.         break;
  712.     default:
  713.         error("o5_drawObject: default case");
  714.     }
  715.  
  716.     index = getObjectIndex(obj);
  717.     if (index==-1)
  718.         return;
  719.     od = &_objs[index];
  720.     if (_xPos!=0xFF) {
  721.         od->walk_x += (_xPos - od->x_pos)<<3;
  722.         od->x_pos = _xPos;
  723.         od->walk_y += (_yPos - od->y_pos)<<3;
  724.         od->y_pos = _yPos;
  725.     }
  726.     addObjectToDrawQue(index);
  727.  
  728.     x = od->x_pos;
  729.     y = od->y_pos;
  730.     w = od->numstrips;
  731.     h = od->height;
  732.  
  733.     i = _numObjectsInRoom;
  734.     do {
  735.         if (_objs[i].x_pos == x && _objs[i].y_pos == y
  736.             && _objs[i].numstrips == w && _objs[i].height==h) 
  737.             putState(_objs[i].obj_nr, 0);
  738.     } while (--i);
  739.  
  740.     putState(obj, state);
  741. }
  742.  
  743. void Scumm::o5_dummy() {
  744.     /* nothing */
  745. }
  746.  
  747.  
  748. void Scumm::o5_expression() {
  749.     int dst, i;
  750.  
  751.     _scummStackPos = 0;
  752.     getResultPos();
  753.     dst = _resultVarNumber;
  754.  
  755.     while ((_opcode = fetchScriptByte())!=0xFF) {
  756.         switch(_opcode&0x1F) {
  757.         case 1: /* varordirect */
  758.             push(getVarOrDirectWord(0x80));
  759.             break;
  760.         case 2: /* add */
  761.             i = pop();
  762.             push(i + pop());
  763.             break;
  764.         case 3: /* sub */
  765.             i = pop();
  766.             push(pop() - i);
  767.             break;
  768.         case 4: /* mul */
  769.             i = pop();
  770.             push(i * pop());
  771.             break;
  772.         case 5: /* div */
  773.             i = pop();
  774.             if (i==0)
  775.                 error("Divide by zero");
  776.             push(pop() / i);
  777.             break;
  778.         case 6: /* normal opcode */
  779.             _opcode = fetchScriptByte();
  780.             (this->*(getOpcode(_opcode)))();
  781.             push(_vars[0]);
  782.             break;
  783.         }
  784.     }
  785.  
  786.     _resultVarNumber = dst;
  787.     setResult(pop());
  788. }
  789.  
  790. void Scumm::o5_faceActor() {
  791.     int act, obj;
  792.     act = getVarOrDirectByte(0x80);
  793.     obj = getVarOrDirectWord(0x40);
  794.     faceActorToObj(act, obj);
  795. }
  796.  
  797. void Scumm::o5_findInventory() {
  798.     int t;
  799.     getResultPos();
  800.     t = getVarOrDirectByte(0x80);
  801.     setResult(findInventory(t,getVarOrDirectByte(0x40)));
  802. }
  803.  
  804. void Scumm::o5_findObject() {
  805.     int t;
  806.     getResultPos();
  807.     t = getVarOrDirectWord(0x80);
  808.     setResult(findObject(t, getVarOrDirectWord(0x40)));
  809. }
  810.  
  811. void Scumm::o5_freezeScripts() {
  812.     int scr = getVarOrDirectByte(0x80);
  813.  
  814.     if (scr!=0)
  815.         freezeScripts(scr);
  816.     else
  817.         unfreezeScripts();
  818. }
  819.  
  820. void Scumm::o5_getActorCostume() {
  821.     getResultPos();
  822.     setResult(derefActorSafe(getVarOrDirectByte(0x80),"o5_getActorCostume")->costume);
  823. }
  824.  
  825. void Scumm::o5_getActorElevation() {
  826.     getResultPos();
  827.     setResult(derefActorSafe(getVarOrDirectByte(0x80),"o5_getActorElevation")->elevation);
  828. }
  829.  
  830. void Scumm::o5_getActorFacing() {
  831.     getResultPos();
  832.     setResult(derefActorSafe(getVarOrDirectByte(0x80),"o5_getActorFacing")->facing);
  833. }
  834.  
  835. void Scumm::o5_getActorMoving() {
  836.     getResultPos();
  837.     setResult(derefActorSafe(getVarOrDirectByte(0x80),"o5_getActorMoving")->moving);
  838. }
  839.  
  840. void Scumm::o5_getActorRoom() {
  841.     getResultPos();
  842.     setResult(derefActorSafe(getVarOrDirectByte(0x80),"o5_getActorRoom")->room);
  843. }
  844.  
  845. void Scumm::o5_getActorScale() {
  846.     getResultPos();
  847.     setResult(derefActorSafe(getVarOrDirectByte(0x80),"o5_getActorScale")->scalex);
  848. }
  849.  
  850. void Scumm::o5_getActorWalkBox() {
  851.     getResultPos();
  852.     setResult(derefActorSafe(getVarOrDirectByte(0x80),"o5_getActorWalkbox")->walkbox);
  853. }
  854.  
  855. void Scumm::o5_getActorWidth() {
  856.     getResultPos();
  857.     setResult(derefActorSafe(getVarOrDirectByte(0x80),"o5_getActorWidth")->width);
  858. }
  859.  
  860. void Scumm::o5_getActorX() {
  861.     getResultPos();
  862.     setResult(getObjX(getVarOrDirectWord(0x80)));
  863. }
  864.  
  865. void Scumm::o5_getActorY() {
  866.     getResultPos();
  867.     setResult(getObjY(getVarOrDirectWord(0x80)));
  868. }
  869.  
  870. void Scumm::o5_getAnimCounter() {
  871.     getResultPos();
  872.     setResult(derefActorSafe(getVarOrDirectByte(0x80),"o5_getActorAnimCounter")->cost.animCounter1);
  873. }
  874.  
  875. void Scumm::o5_getClosestObjActor() {
  876.     int obj;
  877.     int act;
  878.     int closobj=-1, closnum=-1;
  879.     int dist;
  880.  
  881.     getResultPos();
  882.  
  883.     act = getVarOrDirectWord(0x80);
  884.     obj = _vars[VAR_V5_OBJECT_HI];
  885.  
  886.     do {
  887.         dist = getObjActToObjActDist(obj,act);
  888.         if (dist < closnum) {
  889.             closnum = dist;
  890.             closobj = obj;
  891.         }
  892.     } while (--obj >= _vars[VAR_V5_OBJECT_LO]);
  893.  
  894.     setResult(closnum);
  895. }
  896.  
  897. void Scumm::o5_getDist() {
  898.     int o1,o2;
  899.     getResultPos();
  900.     o1 = getVarOrDirectWord(0x80);
  901.     o2 = getVarOrDirectWord(0x40);
  902.     setResult(getObjActToObjActDist(o1,o2));
  903. }
  904.  
  905. void Scumm::o5_getInventoryCount() {
  906.     getResultPos();
  907.     setResult(getInventoryCount(getVarOrDirectByte(0x80)));
  908. }
  909.  
  910. void Scumm::o5_getObjectOwner() {
  911.     getResultPos();
  912.     setResult(getOwner(getVarOrDirectWord(0x80)));
  913. }
  914.  
  915. void Scumm::o5_getObjectState() {
  916.     getResultPos();
  917.     setResult(getState(getVarOrDirectWord(0x80)));
  918. }
  919.  
  920. void Scumm::o5_getRandomNr() {
  921.     getResultPos();
  922.     setResult(getRandomNumber(getVarOrDirectByte(0x80)+1));
  923. }
  924.  
  925. void Scumm::o5_getScriptRunning() {
  926.     getResultPos();
  927.     setResult(getScriptRunning(getVarOrDirectByte(0x80)));
  928. }
  929.  
  930. void Scumm::o5_getVerbEntrypoint() {
  931.     int a,b;
  932.     getResultPos();
  933.     a = getVarOrDirectWord(0x80);
  934.     b = getVarOrDirectWord(0x40);
  935.     setResult(getVerbEntrypoint(a, b));
  936. }
  937.  
  938. void Scumm::o5_ifClassOfIs() {
  939.     int act,cls;
  940.     bool cond = true, b;
  941.  
  942.     act = getVarOrDirectWord(0x80);
  943.     while ( (_opcode = fetchScriptByte()) != 0xFF) {
  944.         cls = getVarOrDirectWord(0x80);
  945.         b = getClass(act, cls);
  946.  
  947.         if (cls&0x80 && !b || !(cls&0x80) && b)
  948.             cond = false;
  949.     }
  950.     if (cond)
  951.         ignoreScriptWord();
  952.     else
  953.         o5_jumpRelative();
  954. }
  955.  
  956. void Scumm::o5_increment() {
  957.     getResultPos();
  958.     setResult(readVar(_resultVarNumber)+1);
  959. }
  960.  
  961. void Scumm::o5_isActorInBox() {
  962.     int box;
  963.     Actor *a;
  964.  
  965.     a = derefActorSafe(getVarOrDirectByte(0x80), "o5_isActorInBox");
  966.     box = getVarOrDirectByte(0x40);
  967.  
  968.     if (!checkXYInBoxBounds(box, a->x, a->y))
  969.         o5_jumpRelative();
  970.     else
  971.         ignoreScriptWord();
  972. }
  973.  
  974. void Scumm::o5_isEqual() {
  975.     int16 a = readVar(fetchScriptWord());
  976.     int16 b = getVarOrDirectWord(0x80);
  977.     if (b == a) ignoreScriptWord();
  978.     else o5_jumpRelative();
  979.  
  980. }
  981.  
  982. void Scumm::o5_isGreater() {
  983.     int16 a = readVar(fetchScriptWord());
  984.     int16 b = getVarOrDirectWord(0x80);
  985.     if (b > a) ignoreScriptWord();
  986.     else o5_jumpRelative();
  987. }
  988.  
  989. void Scumm::o5_isGreaterEqual() {
  990.     int16 a = readVar(fetchScriptWord());
  991.     int16 b = getVarOrDirectWord(0x80);
  992.     if (b >= a) ignoreScriptWord();
  993.     else o5_jumpRelative();
  994. }
  995.  
  996. void Scumm::o5_isLess() {
  997.     int16 a = readVar(fetchScriptWord());
  998.     int16 b = getVarOrDirectWord(0x80);
  999.     if (b < a) ignoreScriptWord();
  1000.     else o5_jumpRelative();
  1001. }
  1002.  
  1003. void Scumm::o5_lessOrEqual() {
  1004.     int16 a = readVar(fetchScriptWord());
  1005.     int16 b = getVarOrDirectWord(0x80);
  1006.     if (b <= a) ignoreScriptWord();
  1007.     else o5_jumpRelative();
  1008. }
  1009.  
  1010. void Scumm::o5_isNotEqual() {
  1011.     int16 a = readVar(fetchScriptWord());
  1012.     int16 b = getVarOrDirectWord(0x80);
  1013.     if (b != a) ignoreScriptWord();
  1014.     else o5_jumpRelative();
  1015. }
  1016.  
  1017. void Scumm::o5_notEqualZero() {
  1018.     int a = readVar(fetchScriptWord());
  1019.     if (a != 0) ignoreScriptWord();
  1020.     else o5_jumpRelative();
  1021. }
  1022.  
  1023. void Scumm::o5_equalZero() {
  1024.     int a = readVar(fetchScriptWord());
  1025.     if (a == 0) ignoreScriptWord();
  1026.     else o5_jumpRelative();
  1027. }
  1028.  
  1029. void Scumm::o5_isSoundRunning() {
  1030.     int snd;
  1031.     getResultPos();
  1032.     snd = getVarOrDirectByte(0x80);
  1033.     if (snd)
  1034.         snd = isSoundRunning(snd);
  1035.     setResult(snd);
  1036. }
  1037.  
  1038. void Scumm::o5_jumpRelative() {
  1039.     _scriptPointer += (int16)fetchScriptWord();
  1040. }
  1041.  
  1042. void Scumm::o5_lights() {
  1043.     int a,b,c;
  1044.  
  1045.     a = getVarOrDirectByte(0x80);
  1046.     b = fetchScriptByte();
  1047.     c = fetchScriptByte();
  1048.  
  1049.     if (c==0)
  1050.         _vars[VAR_V5_DRAWFLAGS] = a;
  1051.     else if (c==1) {
  1052.         warning("o5_lights: lights not implemented");
  1053.     }
  1054.     _fullRedraw=1;
  1055. }
  1056.  
  1057. void Scumm::o5_loadRoom() {
  1058.     int room = getVarOrDirectByte(0x80);
  1059.     startScene(room, 0, 0);
  1060.     _fullRedraw = 1;
  1061. }
  1062.  
  1063. void Scumm::o5_loadRoomWithEgo() {
  1064.     int obj, room, x,y;
  1065.     Actor *a;
  1066.  
  1067.     obj = getVarOrDirectWord(0x80);
  1068.     room = getVarOrDirectByte(0x40);
  1069.  
  1070.     a = derefActorSafe(_vars[VAR_EGO], "o5_loadRoomWithEgo");
  1071.  
  1072.     /* Warning: uses _xPos, _yPos from a previous update of those */
  1073.     putActor(a, _xPos, _yPos, room);
  1074.  
  1075.     x = (int16)fetchScriptWord();
  1076.     y = (int16)fetchScriptWord();
  1077.  
  1078.     _egoPositioned = false;
  1079.  
  1080.     _vars[VAR_WALKTO_OBJ] = obj;
  1081.  
  1082.     startScene(a->room, a, obj);
  1083.  
  1084.     _vars[VAR_WALKTO_OBJ] = 0;
  1085.     camera._destPos = camera._curPos = a->x;
  1086.     setCameraFollows(a);
  1087.     _fullRedraw=1;
  1088.  
  1089.     if (x != -1) {
  1090.         startWalkActor(a, x, y, 0xFF);
  1091.     }
  1092. }
  1093.  
  1094. void Scumm::o5_matrixOps() {
  1095.     int a,b;
  1096.  
  1097.     _opcode = fetchScriptByte();
  1098.     switch(_opcode & 0x1F) {
  1099.     case 1:
  1100.         a = getVarOrDirectByte(0x80);
  1101.         b = getVarOrDirectByte(0x40);
  1102.         setBoxFlags(a,b);
  1103.         break;
  1104.     case 2:
  1105.         a = getVarOrDirectByte(0x80);
  1106.         b = getVarOrDirectByte(0x40);
  1107.         setBoxScale(a,b);
  1108.         break;
  1109.     case 3:
  1110.         a = getVarOrDirectByte(0x80);
  1111.         b = getVarOrDirectByte(0x40);
  1112.         setBoxScale(a,(b-1)|0x8000);
  1113.         break;
  1114.     case 4:
  1115.         createBoxMatrix();
  1116.         break;
  1117.     }
  1118. }
  1119.  
  1120. void Scumm::o5_move() {
  1121.     getResultPos();
  1122.     setResult(getVarOrDirectWord(0x80));
  1123. }
  1124.  
  1125. void Scumm::o5_multiply() {
  1126.     int a;
  1127.     getResultPos();
  1128.     a = getVarOrDirectWord(0x80);
  1129.     setResult(readVar(_resultVarNumber) * a);
  1130. }
  1131.  
  1132.  
  1133. void Scumm::o5_or() {
  1134.     int a;
  1135.     getResultPos();
  1136.     a = getVarOrDirectWord(0x80);
  1137.     setResult(readVar(_resultVarNumber) | a);
  1138. }
  1139.  
  1140. void Scumm::o5_overRide() {
  1141.     if(fetchScriptByte()!=0)
  1142.         beginOverride();
  1143.     else
  1144.         endOverride();
  1145. }
  1146.  
  1147. void Scumm::o5_panCameraTo() {
  1148.     panCameraTo(getVarOrDirectWord(0x80));
  1149. }
  1150.  
  1151. void Scumm::o5_pickupObject() {
  1152.     int obj, room;
  1153.  
  1154.     obj = getVarOrDirectWord(0x80);
  1155.     room = getVarOrDirectByte(0x40);
  1156.     if (room==0)
  1157.         room = _roomResource;
  1158.     addObjectToInventory(obj, room);
  1159.     putOwner(obj, _vars[VAR_EGO]);
  1160.     putClass(obj, 32, 1);
  1161.     putState(obj, 1);
  1162.     removeObjectFromRoom(obj);
  1163.     clearDrawObjectQueue();
  1164.     runHook(1);
  1165. }
  1166.  
  1167. void Scumm::o5_print() {
  1168.     _actorToPrintStrFor = getVarOrDirectByte(0x80);
  1169.     decodeParseString();
  1170. }
  1171.  
  1172. void Scumm::o5_printEgo() {
  1173.     _actorToPrintStrFor = _vars[VAR_EGO];
  1174.     decodeParseString();
  1175. }
  1176.  
  1177. void Scumm::o5_pseudoRoom() {
  1178.     int i = fetchScriptByte(), j;
  1179.     while ((j = fetchScriptByte()) != 0) {
  1180.         if (j >= 0x80) {
  1181.             _resourceMapper[j&0x7F] = i;
  1182.         }
  1183.     }
  1184. }
  1185.  
  1186. void Scumm::o5_putActor() {
  1187.     int x,y;
  1188.     Actor *a;
  1189.  
  1190.     a = derefActorSafe(getVarOrDirectByte(0x80), "o5_putActor");
  1191.     x = getVarOrDirectWord(0x40);
  1192.     y = getVarOrDirectWord(0x20);
  1193.     
  1194.     putActor(a, x, y, a->room);
  1195. }
  1196.  
  1197.  
  1198. void Scumm::o5_putActorAtObject() {
  1199.     int obj;
  1200.     Actor *a;
  1201.  
  1202.     a = derefActorSafe(getVarOrDirectByte(0x80), "o5_putActorAtObject");
  1203.     obj = getVarOrDirectWord(0x40);
  1204.     if (whereIsObject(obj)!=-1)
  1205.         getObjectXYPos(obj);
  1206.     else {
  1207.         _xPos = 240;
  1208.         _yPos = 120;
  1209.     }
  1210.     putActor(a, _xPos, _yPos, a->room);
  1211. }
  1212.  
  1213. void Scumm::o5_putActorInRoom() {
  1214.     int room;
  1215.     Actor *a;
  1216.  
  1217.     a = derefActorSafe(getVarOrDirectByte(0x80), "o5_putActorInRoom");
  1218.     room = getVarOrDirectByte(0x40);
  1219.     if (a->visible && _currentRoom!=room && _vars[VAR_TALK_ACTOR]==a->number) {
  1220.         clearMsgQueue();
  1221.     }
  1222.     a->room = room;
  1223.     if (!room)
  1224.         putActor(a, 0, 0, 0);
  1225. }
  1226.  
  1227. void Scumm::o5_quitPauseRestart() {
  1228.     switch(fetchScriptByte()) {
  1229.     case 1:
  1230.         pauseGame(0);
  1231.         break;
  1232.     case 3:
  1233.         shutDown(0);
  1234.         break;
  1235.     }
  1236. }
  1237.  
  1238. void Scumm::o5_resourceRoutines() {
  1239.     int res;
  1240.  
  1241.     _opcode = fetchScriptByte();
  1242.     if (_opcode != 17)
  1243.         res = getVarOrDirectByte(0x80);
  1244.     switch(_opcode&0x1F) {
  1245.     case 1: /* load script */
  1246.         ensureResourceLoaded(rtScript, res);
  1247.         break;
  1248.     case 2: /* load sound */
  1249.         ensureResourceLoaded(rtSound, res);
  1250.         break;
  1251.     case 3: /* load costume */
  1252.         ensureResourceLoaded(rtCostume, res);
  1253.         break;
  1254.     case 4: /* load room */
  1255.         ensureResourceLoaded(rtRoom, res);
  1256.         break;
  1257.     case 5: /* nuke script */
  1258.         setResourceCounter(rtScript, res, 0x7F);
  1259.         break;
  1260.     case 6: /* nuke sound */
  1261.         setResourceCounter(rtSound, res, 0x7F);
  1262.         break;
  1263.     case 7: /* nuke costume */
  1264.         setResourceCounter(rtCostume, res, 0x7F);
  1265.         break;
  1266.     case 8: /* nuke room */
  1267.         setResourceCounter(rtRoom, res, 0x7F);
  1268.         break;
  1269.     case 9:  /* lock script */
  1270.         if (res >= _numGlobalScripts)
  1271.             break;
  1272.         lock(rtScript,res);
  1273.         break;
  1274.     case 10:/* lock sound */
  1275.         lock(rtSound,res);
  1276.         break;
  1277.     case 11:/* lock costume */
  1278.         lock(rtCostume,res);
  1279.         break;
  1280.     case 12:/* lock room */
  1281.         if (res > 0x7F)
  1282.             res = _resourceMapper[res&0x7F];
  1283.         lock(rtRoom,res);
  1284.         break;
  1285.     case 13:/* unlock script */
  1286.         if (res >= _numGlobalScripts)
  1287.             break;
  1288.         unlock(rtScript,res);
  1289.         break;
  1290.     case 14:/* unlock sound */
  1291.         unlock(rtSound,res);
  1292.         break;
  1293.     case 15:/* unlock costume */
  1294.         unlock(rtCostume,res);
  1295.         break;
  1296.     case 16:/* unlock room */
  1297.         if (res > 0x7F)
  1298.             res = _resourceMapper[res&0x7F];
  1299.         unlock(rtRoom,res);
  1300.         break;
  1301.     case 17:/* clear heap */
  1302.         heapClear(0);
  1303.         unkHeapProc2(0,0);
  1304.         break;
  1305.     case 18:/* load charset */
  1306.         loadCharset(res);
  1307.         break;
  1308.     case 19:/* nuke charset */
  1309.         nukeCharset(res);
  1310.         break;
  1311.     case 20:/* load fl object */
  1312.         loadFlObject(getVarOrDirectWord(0x40), res);
  1313.         break;
  1314.     }
  1315. }
  1316.  
  1317. void Scumm::o5_roomOps() {
  1318.     int a,b,c,d,e;
  1319.  
  1320.     _opcode = fetchScriptByte();
  1321.  
  1322.     switch(_opcode & 0x1F) {
  1323.     case 1: /* room scroll */
  1324.         a = getVarOrDirectWord(0x80);
  1325.         b = getVarOrDirectWord(0x40);
  1326.         if (a < 160) a=160;
  1327.         if (a > ((_scrWidthIn8Unit-20)<<3)) a=((_scrWidthIn8Unit-20)<<3);
  1328.         if (b < 160) b=160;
  1329.         if (b > ((_scrWidthIn8Unit-20)<<3)) b=((_scrWidthIn8Unit-20)<<3);
  1330.         _vars[VAR_CAMERA_MIN] = a;
  1331.         _vars[VAR_CAMERA_MAX] = b;
  1332.         break;
  1333.     case 2: /* room color */
  1334.         error("room-color is no longer a valid command");
  1335.         break;
  1336.  
  1337.     case 3: /* set screen */
  1338.         a = getVarOrDirectWord(0x80);
  1339.         b = getVarOrDirectWord(0x40);
  1340.         initScreens(0,a,320,b);
  1341.         break;
  1342.     case 4: /* set palette color */
  1343.         a = getVarOrDirectWord(0x80);
  1344.         b = getVarOrDirectWord(0x40);
  1345.         c = getVarOrDirectWord(0x20);
  1346.         _opcode = fetchScriptByte();
  1347.         d = getVarOrDirectByte(0x80);
  1348.         setPalColor(d, a, b, c); /* index, r, g, b */
  1349.         break;
  1350.     case 5: /* shake on */
  1351.         setShake(1);
  1352.         break;
  1353.     case 6: /* shake off */
  1354.         setShake(0);
  1355.         break;
  1356.     case 8: /* room scale? */
  1357.         a = getVarOrDirectByte(0x80);
  1358.         b = getVarOrDirectByte(0x40);
  1359.         c = getVarOrDirectByte(0x20);
  1360.         darkenPalette(b, c, a, a, a);
  1361.         break;
  1362.     case 9: /* ? */
  1363.         _saveLoadFlag = getVarOrDirectByte(0x80);
  1364.         _saveLoadSlot = getVarOrDirectByte(0x40);
  1365.         _saveLoadSlot = 99; /* use this slot */
  1366.         _saveLoadCompatible = true;
  1367.         break;
  1368.     case 10: /* ? */
  1369.         a = getVarOrDirectWord(0x80);
  1370.         if (a) {
  1371.             _switchRoomEffect = (byte)(a);
  1372.             _switchRoomEffect2 = (byte)(a>>8);
  1373.         } else {
  1374.             screenEffect(_newEffect);
  1375.         }
  1376.         break;
  1377.     case 11: /* ? */
  1378.         a = getVarOrDirectWord(0x80);
  1379.         b = getVarOrDirectWord(0x40);
  1380.         c = getVarOrDirectWord(0x20);
  1381.         _opcode = fetchScriptByte();
  1382.         d = getVarOrDirectByte(0x80);
  1383.         e = getVarOrDirectByte(0x40);
  1384.         darkenPalette(d, e, a, b, c);
  1385.         break;
  1386.     case 12: /* ? */
  1387.         a = getVarOrDirectWord(0x80);
  1388.         b = getVarOrDirectWord(0x40);
  1389.         c = getVarOrDirectWord(0x20);
  1390.         _opcode = fetchScriptByte();
  1391.         d = getVarOrDirectByte(0x80);
  1392.         e = getVarOrDirectByte(0x40);
  1393.         unkRoomFunc3(d, e, a, b, c);
  1394.         break;
  1395.  
  1396.     case 13: { /* save-string */
  1397.         char buf[256],*s;
  1398.         a = getVarOrDirectByte(0x80);
  1399.         s = buf;
  1400.         while (*s++=fetchScriptByte());
  1401.         warning("roomops:13 save-string(%d,\"%s\") not implemented", a, buf);
  1402.         break;
  1403.         }
  1404.     case 14: /* load-string */
  1405.         char buf[256],*s;
  1406.         a = getVarOrDirectByte(0x80);
  1407.         s = buf;
  1408.         while (*s++=fetchScriptByte());
  1409.         warning("roomops:14 load-string(%d,\"%s\") not implemented", a, buf);
  1410.         break;
  1411.     case 15: /* palmanip? */
  1412.         a = getVarOrDirectByte(0x80);
  1413.         _opcode = fetchScriptByte();
  1414.         b = getVarOrDirectByte(0x80);
  1415.         c = getVarOrDirectByte(0x40);
  1416.         _opcode = fetchScriptByte();
  1417.         d = getVarOrDirectByte(0x80);
  1418.         unkRoomFunc4(b, c, a, d, 1);
  1419.         break;
  1420.  
  1421.     case 16: /* ? */
  1422.         a = getVarOrDirectByte(0x80);
  1423.         b = getVarOrDirectByte(0x40);
  1424.         checkRange(16, 1, a, "o5_roomOps: 16: color cycle out of range (%d)");
  1425.         _colorCycle[a-1].delay = (b!=0) ? 0x4000 / (b*0x4C) : 0;
  1426.         break;
  1427.     }
  1428. }
  1429.  
  1430. void Scumm::o5_saveRestoreVerbs() {
  1431.     int a,b,c,slot, slot2;
  1432.  
  1433.     _opcode = fetchScriptByte();
  1434.     
  1435.     a = getVarOrDirectByte(0x80);
  1436.     b = getVarOrDirectByte(0x40);
  1437.     c = getVarOrDirectByte(0x20);
  1438.  
  1439.     switch(_opcode) {
  1440.     case 1: /* hide verbs */
  1441.         while (a<=b) {
  1442.             slot = getVerbSlot(a,0);
  1443.             if (slot && _verbs[slot].saveid==0) {
  1444.                 _verbs[slot].saveid = c;
  1445.                 drawVerb(slot, 0);
  1446.                 verbMouseOver(0);
  1447.             }
  1448.             a++;
  1449.         }
  1450.         break;
  1451.     case 2: /* show verbs */
  1452.         while (a<=b) {
  1453.             slot = getVerbSlot(a, c);
  1454.             if (slot) {
  1455.                 slot2 = getVerbSlot(a,0);
  1456.                 if (slot2)
  1457.                     killVerb(slot2);
  1458.                 slot = getVerbSlot(a,c);
  1459.                 _verbs[slot].saveid = 0;
  1460.                 drawVerb(slot, 0);
  1461.                 verbMouseOver(0);
  1462.             }
  1463.             a++;
  1464.         }
  1465.         break;
  1466.     case 3: /* kill verbs */
  1467.         while (a<=b) {
  1468.             slot = getVerbSlot(a,c);
  1469.             if (slot)
  1470.                 killVerb(slot);
  1471.             a++;
  1472.         }
  1473.         break;
  1474.     default:
  1475.         error("o5_saveRestoreVerbs: invalid opcode");
  1476.     }
  1477. }
  1478.  
  1479. void Scumm::o5_setCameraAt() {
  1480.     setCameraAtEx(getVarOrDirectWord(0x80));
  1481. }
  1482.  
  1483. void Scumm::o5_setObjectName() {
  1484.     int act = getVarOrDirectWord(0x80);
  1485.     int size;
  1486.     int a;
  1487.     int i;
  1488.  
  1489.     if (act <= _vars[VAR_NUM_ACTOR])
  1490.         error("Can't set actor %d name with new-name-of", act);
  1491.  
  1492.     if (!getObjectAddress(act))
  1493.         error("Can't set name of object %d", act);
  1494.  
  1495.     size = READ_BE_UINT32_UNALIGNED(getObjOrActorName(act) - 4)-9;
  1496.     i = 0;
  1497.  
  1498.     while ((a = fetchScriptByte()) != 0) {
  1499.          getObjOrActorName(act)[i++] = a;
  1500.  
  1501.         if (a==0xFF) {
  1502.             getObjOrActorName(act)[i++] = fetchScriptByte();
  1503.             getObjOrActorName(act)[i++] = fetchScriptByte();
  1504.             getObjOrActorName(act)[i++] = fetchScriptByte();
  1505.         }
  1506.  
  1507.         if (i > size)
  1508.             error("New name of object %d too long", act);
  1509.     }
  1510.  
  1511.     getObjOrActorName(act)[i] = 0;
  1512.     runHook(0);
  1513. }
  1514.  
  1515. void Scumm::o5_setOwnerOf() {
  1516.     int obj, owner;
  1517.  
  1518.     obj = getVarOrDirectWord(0x80);
  1519.     owner = getVarOrDirectByte(0x40);
  1520.  
  1521.     setOwnerOf(obj, owner);
  1522. }
  1523.  
  1524. void Scumm::o5_setState() {
  1525.     int obj, state;
  1526.     obj = getVarOrDirectWord(0x80);
  1527.     state = getVarOrDirectByte(0x40);
  1528.     putState(obj, state);
  1529.     removeObjectFromRoom(obj);
  1530.     if (_BgNeedsRedraw)
  1531.         clearDrawObjectQueue();
  1532. }
  1533.  
  1534. void Scumm::o5_setVarRange() {
  1535.     int a,b;
  1536.  
  1537.     getResultPos();
  1538.     a=fetchScriptByte();
  1539.     do {
  1540.         if (_opcode&0x80)
  1541.             b=fetchScriptWord();
  1542.         else
  1543.             b=fetchScriptByte();
  1544.         
  1545.         setResult(b);
  1546.         _resultVarNumber++;
  1547.     } while (--a);
  1548. }
  1549.  
  1550. void Scumm::o5_soundKludge() {
  1551.     int16 items[15];
  1552.     int i;
  1553.     
  1554.     for (i=0; i<15; i++)
  1555.         items[i] = 0;
  1556.  
  1557.     getWordVararg(items);
  1558.  
  1559.     soundKludge(items);
  1560. }
  1561.  
  1562. void Scumm::o5_startMusic() {
  1563.     addSoundToQueue(getVarOrDirectByte(0x80));
  1564. }
  1565.  
  1566. void Scumm::o5_startObject() {
  1567.     int obj, script;
  1568.     int16 data[16];
  1569.  
  1570.     obj = getVarOrDirectWord(0x80);
  1571.     script = getVarOrDirectByte(0x40);
  1572.  
  1573.     getWordVararg(data);
  1574.     runVerbCode(obj, script, 0, 0, data);
  1575. }
  1576.  
  1577. void Scumm::o5_startScript() {
  1578.     int op,script;
  1579.     int16 data[16];
  1580.     int a,b;
  1581.     
  1582.     op = _opcode;
  1583.     script = getVarOrDirectByte(0x80);
  1584.  
  1585.     getWordVararg(data);
  1586.  
  1587.     a = b = 0;
  1588.     if (op&0x40) b=1;
  1589.     if (op&0x20) a=1;
  1590.  
  1591.     runScript(script, a, b, data);
  1592. }
  1593.  
  1594. void Scumm::o5_startSound() {
  1595.     addSoundToQueue(getVarOrDirectByte(0x80));
  1596. }
  1597.  
  1598. void Scumm::o5_stopMusic() {
  1599.     stopAllSounds();
  1600. }
  1601.  
  1602. void Scumm::o5_stopObjectCode() {
  1603.     stopObjectCode();
  1604. }
  1605.  
  1606. void Scumm::o5_stopObjectScript() {
  1607.     stopObjectScript(getVarOrDirectWord(0x80));
  1608. }
  1609.  
  1610. void Scumm::o5_stopScript() {
  1611.     int script;
  1612.  
  1613.     script = getVarOrDirectByte(0x80);
  1614.     if (script==0)
  1615.         stopObjectCode();
  1616.     else
  1617.         stopScriptNr(script);
  1618. }
  1619.  
  1620. void Scumm::o5_stopSound() {
  1621.     stopSound(getVarOrDirectByte(0x80));
  1622. }
  1623.  
  1624. void Scumm::o5_stringOps() {
  1625.     int a,b,c,i;
  1626.     byte *ptr;
  1627.  
  1628.     _opcode = fetchScriptByte();
  1629.     switch(_opcode&0x1F) {
  1630.     case 1: /* loadstring */
  1631.         loadPtrToResource(7, getVarOrDirectByte(0x80), NULL);
  1632.         break;
  1633.     case 2: /* copystring */
  1634.         a = getVarOrDirectByte(0x80);
  1635.         b = getVarOrDirectByte(0x40);
  1636.         nukeResource(rtString, a);
  1637.         ptr = getResourceAddress(rtString, b);
  1638.         if (ptr) loadPtrToResource(rtString, a, ptr);
  1639.         break;
  1640.     case 3: /* set string char */
  1641.         a = getVarOrDirectByte(0x80);
  1642.         b = getVarOrDirectByte(0x40);
  1643.         ptr = getResourceAddress(7, a);
  1644.         if (ptr==NULL) error("String %d does not exist", a);
  1645.         c = getVarOrDirectByte(0x20);
  1646.         ptr[b] = c;
  1647.         break;
  1648.  
  1649.     case 4: /* get string char */
  1650.         getResultPos();
  1651.         a = getVarOrDirectByte(0x80);
  1652.         b = getVarOrDirectByte(0x40);
  1653.         ptr = getResourceAddress(rtString, a);
  1654.         if (ptr==NULL) error("String %d does not exist", a);
  1655.         setResult(ptr[b]);
  1656.         break;
  1657.         
  1658.     case 5: /* create empty string */
  1659.         a = getVarOrDirectByte(0x80);
  1660.         b = getVarOrDirectByte(0x40);
  1661.         nukeResource(rtString, a);
  1662.         if (b) {
  1663.             ptr = createResource(rtString, a, b);
  1664.             if (ptr) {
  1665.                 for(i=0; i<b; i++)
  1666.                     ptr[i] = 0;
  1667.             }
  1668.         }
  1669.         break;
  1670.     }
  1671. }
  1672.  
  1673. void Scumm::o5_subtract() {
  1674.     int a;
  1675.     getResultPos();
  1676.     a = getVarOrDirectWord(0x80);
  1677.     setResult(readVar(_resultVarNumber) - a);
  1678. }
  1679.  
  1680. void Scumm::o5_verbOps() {
  1681.     int verb,slot;
  1682.     VerbSlot *vs;
  1683.     int a,b;
  1684.     byte *ptr;
  1685.  
  1686.     verb = getVarOrDirectByte(0x80);
  1687.  
  1688.     slot = getVerbSlot(verb,0);
  1689.     checkRange(_maxVerbs-1, 0, slot, "Illegal new verb slot %d");
  1690.  
  1691.     vs = &_verbs[slot];
  1692.     vs->verbid = verb;
  1693.  
  1694.     while ((_opcode=fetchScriptByte()) != 0xFF) {
  1695.         switch(_opcode&0x1F) {
  1696.         case 1: /* load image */
  1697.             a = getVarOrDirectWord(0x80);
  1698.             if (verb) {
  1699.                 setVerbObject(_roomResource, a, verb);
  1700.                 vs->type = 1;
  1701.             }
  1702.             break;
  1703.         case 2: /* load from code */
  1704.             loadPtrToResource(rtVerb, slot, NULL);
  1705.             if (slot==0)
  1706.                 nukeResource(rtVerb, slot);
  1707.             vs->type = 0;
  1708.             vs->imgindex = 0;
  1709.             break;
  1710.         case 3: /* color */
  1711.             vs->color = getVarOrDirectByte(0x80);
  1712.             break;
  1713.         case 4: /* set hi color */
  1714.             vs->hicolor = getVarOrDirectByte(0x80);
  1715.             break;
  1716.         case 5: /* set xy */
  1717.             vs->x = getVarOrDirectWord(0x80);
  1718.             vs->y = getVarOrDirectWord(0x40);
  1719.             break;
  1720.         case 6: /* set on */
  1721.             vs->curmode=1;
  1722.             break;
  1723.         case 7: /* set off */
  1724.             vs->curmode=0;
  1725.             break;
  1726.         case 8: /* delete */
  1727.             killVerb(slot);
  1728.             break;
  1729.         case 9: /* new */
  1730.             slot = getVerbSlot(verb, 0);
  1731.             if (slot==0) {
  1732.                 for (slot=1; slot<_maxVerbs; slot++) {
  1733.                     if(_verbs[slot].verbid==0)
  1734.                         break;
  1735.                 }
  1736.                 if (slot==_maxVerbs)
  1737.                     error("Too many verbs");
  1738.             }
  1739.             vs = &_verbs[slot];
  1740.             vs->verbid = verb;
  1741.             vs->color = 2;
  1742.             vs->hicolor = 0;
  1743.             vs->dimcolor = 8;
  1744.             vs->type = 0;
  1745.             vs->charset_nr = string[0].t_charset;
  1746.             vs->curmode = 0;
  1747.             vs->saveid = 0;
  1748.             vs->key = 0;
  1749.             vs->center = 0;
  1750.             vs->imgindex = 0;
  1751.             break;
  1752.  
  1753.         case 16: /* set dim color */
  1754.             vs->dimcolor = getVarOrDirectByte(0x80);
  1755.             break;
  1756.         case 17: /* dim */
  1757.             vs->curmode = 2;
  1758.             break;
  1759.         case 18: /* set key */
  1760.             vs->key = getVarOrDirectByte(0x80);
  1761.             break;
  1762.         case 19: /* set center */
  1763.             vs->center = 1;
  1764.             break;
  1765.         case 20: /* set to string */
  1766.             ptr = getResourceAddress(rtString, getVarOrDirectWord(0x80));
  1767.             if (!ptr)
  1768.                 nukeResource(rtVerb, slot);
  1769.             else {
  1770.                 loadPtrToResource(rtVerb, slot, ptr);
  1771.             }
  1772.             if (slot==0)
  1773.                 nukeResource(rtVerb, slot);
  1774.             vs->type = 0;
  1775.             vs->imgindex = 0;
  1776.             break;
  1777.         case 22: /* assign object */
  1778.             a = getVarOrDirectWord(0x80);
  1779.             b = getVarOrDirectByte(0x40);
  1780.             if (slot && vs->imgindex!=a) {
  1781.                 setVerbObject(b, a, slot);
  1782.                 vs->type = 1;
  1783.                 vs->imgindex = a;
  1784.             }
  1785.             break;
  1786.         case 23: /* set back color */
  1787.             vs->bkcolor = getVarOrDirectByte(0x80);
  1788.             break;
  1789.         }
  1790.     }
  1791.     drawVerb(slot, 0);
  1792.     verbMouseOver(0);
  1793. }
  1794.  
  1795. void Scumm::o5_wait() {
  1796.     byte *oldaddr;
  1797.  
  1798.     oldaddr = _scriptPointer - 1;
  1799.     
  1800.     _opcode = fetchScriptByte();
  1801.     switch(_opcode&0x1F) {
  1802.     case 1: /* wait for actor */
  1803.         if (derefActorSafe(getVarOrDirectByte(0x80), "o5_wait")->moving)
  1804.             break;
  1805.         return;
  1806.     case 2: /* wait for message */
  1807.         if (_vars[VAR_HAVE_MSG])
  1808.             break;
  1809.         return;
  1810.     case 3: /* wait for camera */
  1811.         if (camera._curPos>>3 != camera._destPos>>3)
  1812.             break;
  1813.         return;
  1814.     case 4: /* wait for sentence */
  1815.         if (_sentenceIndex!=0xFF) {
  1816.             if (sentence[_sentenceIndex].unk &&
  1817.                 !isScriptInUse(_vars[VAR_SENTENCE_SCRIPT]) )
  1818.                 return;
  1819.             break;
  1820.         }
  1821.         if (!isScriptInUse(_vars[VAR_SENTENCE_SCRIPT]))
  1822.             return;
  1823.         break;
  1824.     default:
  1825.         error("o5_wait: default case");
  1826.         return;
  1827.     }
  1828.  
  1829.     _scriptPointer = oldaddr;
  1830.     o5_breakHere();
  1831. }
  1832.  
  1833. void Scumm::o5_walkActorTo() {
  1834.     int x, y;
  1835.     Actor *a;
  1836.     a = derefActorSafe(getVarOrDirectByte(0x80), "o5_walkActorTo");
  1837.     x = getVarOrDirectWord(0x40);
  1838.     y = getVarOrDirectWord(0x20);
  1839.     startWalkActor(a, x, y, 0xFF);
  1840. }
  1841.  
  1842. void Scumm::o5_walkActorToActor() {
  1843.     int b,x,y;
  1844.     Actor *a, *a2;
  1845.  
  1846.     a = derefActorSafe(getVarOrDirectByte(0x80), "o5_walkActorToActor");
  1847.     if (a->room != _currentRoom) {
  1848.         getVarOrDirectByte(0x40);
  1849.         fetchScriptByte();
  1850.         return;
  1851.     }
  1852.  
  1853.     a2 = derefActorSafe(getVarOrDirectByte(0x40), "o5_walkActorToActor(2)");
  1854.     if (a2->room != _currentRoom) {
  1855.         fetchScriptByte();
  1856.         return;
  1857.     }
  1858.     b = fetchScriptByte(); /* distance from actor */
  1859.     if (b==0xFF) {
  1860.         b = a2->scalex * a->width / 0xFF;
  1861.         b = b + b/2;
  1862.     }
  1863.     x = a2->x;
  1864.     y = a2->y;
  1865.     if (x < a->x)
  1866.         x += b;
  1867.     else
  1868.         x -= b;
  1869.     
  1870.     startWalkActor(a, x, y, 0xFF);
  1871. }
  1872.  
  1873. void Scumm::o5_walkActorToObject() {
  1874.     int obj;
  1875.     Actor *a;
  1876.  
  1877.     a = derefActorSafe(getVarOrDirectByte(0x80), "o5_walkActorToObject");
  1878.     obj = getVarOrDirectWord(0x40);
  1879.     if (whereIsObject(obj)!=-1) {
  1880.         getObjectXYPos(obj);
  1881.         startWalkActor(a, _xPos, _yPos, _dir);
  1882.     }
  1883. }
  1884.  
  1885. int Scumm::getWordVararg(int16 *ptr) {
  1886.     int i;
  1887.     for (i=0; i<16; i++)
  1888.         ptr[i] = 0;
  1889.  
  1890.     i = 0;
  1891.     while ((_opcode = fetchScriptByte()) != 0xFF) {
  1892.         ptr[i++] = getVarOrDirectWord(0x80);
  1893.     }
  1894.     return i;
  1895. }
  1896.  
  1897. int Scumm::getVarOrDirectWord(byte mask) {
  1898.     if (_opcode&mask)
  1899.         return readVar(fetchScriptWord());
  1900.     return (int16)fetchScriptWord();
  1901. }
  1902.  
  1903. int Scumm::getVarOrDirectByte(byte mask) {
  1904.     if (_opcode&mask)
  1905.         return readVar(fetchScriptWord());
  1906.     return fetchScriptByte();
  1907. }
  1908.  
  1909. void Scumm::decodeParseString() {
  1910.     int textSlot;
  1911.  
  1912.     switch(_actorToPrintStrFor) {
  1913.     case 252:
  1914.         textSlot = 3;
  1915.         break;
  1916.     case 253:
  1917.         textSlot = 2;
  1918.         break;
  1919.     case 254:
  1920.         textSlot = 1;
  1921.         break;
  1922.     default:
  1923.         textSlot = 0;
  1924.     }
  1925.  
  1926.     string[textSlot].xpos = string[textSlot].t_xpos;
  1927.     string[textSlot].ypos = string[textSlot].t_ypos;
  1928.     string[textSlot].center = string[textSlot].t_center;
  1929.     string[textSlot].overhead = string[textSlot].t_overhead;
  1930.     string[textSlot].right = string[textSlot].t_right;
  1931.     string[textSlot].color = string[textSlot].t_color;
  1932.     string[textSlot].charset = string[textSlot].t_charset;
  1933.  
  1934.     while((_opcode=fetchScriptByte()) != 0xFF) {
  1935.         switch(_opcode&0xF) {
  1936.         case 0: /* set string xy */
  1937.             string[textSlot].xpos = getVarOrDirectWord(0x80);
  1938.             string[textSlot].ypos = getVarOrDirectWord(0x40);
  1939.             string[textSlot].overhead = false;
  1940.             break;
  1941.         case 1: /* color */
  1942.             string[textSlot].color = getVarOrDirectByte(0x80);
  1943.             break;
  1944.         case 2: /* right */
  1945.             string[textSlot].right = getVarOrDirectWord(0x80);
  1946.             break;
  1947.         case 4:    /* center*/
  1948.             string[textSlot].center = true;
  1949.             string[textSlot].overhead = false;
  1950.             break;
  1951.         case 6: /* left */
  1952.             string[textSlot].center = false;
  1953.             string[textSlot].overhead = false;
  1954.             break;
  1955.         case 7: /* overhead */
  1956.             string[textSlot].overhead = true;
  1957.             break;
  1958.         case 8: /* ignore */
  1959.             getVarOrDirectWord(0x80);
  1960.             getVarOrDirectWord(0x40);
  1961.             break;
  1962.         case 15:
  1963.             _messagePtr = _scriptPointer;
  1964.             switch(textSlot) {
  1965.             case 0: actorTalk(); break;
  1966.             case 1: drawString(1); break;
  1967.             case 2: unkMessage1(); break;
  1968.             case 3: unkMessage2(); break;
  1969.             }
  1970.             _scriptPointer = _messagePtr;
  1971.             return;
  1972.         default:
  1973.             return;
  1974.         }
  1975.     }
  1976.  
  1977.     string[textSlot].t_xpos = string[textSlot].xpos;
  1978.     string[textSlot].t_ypos = string[textSlot].ypos;
  1979.     string[textSlot].t_center = string[textSlot].center;
  1980.     string[textSlot].t_overhead = string[textSlot].overhead;
  1981.     string[textSlot].t_right = string[textSlot].right;
  1982.     string[textSlot].t_color = string[textSlot].color;
  1983.     string[textSlot].t_charset = string[textSlot].charset;
  1984. }
  1985.  
  1986.  
  1987.