Open main menu

SCUMM/V5 opcodes

< SCUMM
Revision as of 01:35, 8 April 2009 by Jestar jokin (talk | contribs) (→‎actorOps ($13): add sub-opcode for shadow mode)

SCUMM V5 opcodes

The following conventions are used in the encoding descriptions.

Term Description
opcode The instruction's opcode, with the appropriate bits set according to the parameters.
aux An aux opcode that stores parameter bits and no other information.
result A result pointer. (A standard word pointer, always a LE word.)
sub-opcode An aux opcode that indicates a specific function to perform (e.g. the "wait" instruction has sub-opcodes to "wait for message", "wait for actor" etc), as well as storing parameter bits if necessary
var A var pointer. Same as above, but is not written to. Because this is always a var, the opcode is not affected like with normal parameter/pointers.
value[8] An 8-bit constant (a byte).
value[16] A 16-bit constant (a word LE).
value[p8] An 8-bit parameter. This may be encoded as a word LE if it's a pointer, or a byte if it's a constant.
value[p16] A 16-bit parameter. This is always encoded as a word LE, and may be a pointer or constant.
value[v16] A variable number of word LE parameters. These are encoded as a sequence of aux[8] param[p16]; param; aux contains the parameter bit to describe param. A byte of $FF terminates the sequence. (actually always shown as "value[v16]...")
value[o] The offset word for parameter value. This is only encoded if needed, but always at the position indicated. If not specified, the offset word occurs immediately after the parameter.
value[c] An ASCII character. Because some instructions use null-terminated strings and some use $FF, the exact format of a string is described in the instruction. Almost always appears as "value[c]..."
term... One or more terms.

Of course, due to the non-orthogonality of the opcodes, there are lots of exceptions.


actorFollowCamera ($52)

Encoding

opcode actor[p8]

Operation

Sets the camera to follow the given actor?


actorFromPos ($15)

Encoding

opcode result x[p16] y[p16]

Operation

Returns the actor located at the given co-ordinates.


actorOps ($13)

parameters depend on auxiliary opcode; terminated by $FF

Encoding

opcode actor[p8] sub-opcode... $FF

sub-opcodes:

$00 arg1[p8]
$01 costume[p8]
$02 xspeed[p8] yspeed[p8]
$03 sound[p8]
$04 walkframe[p8]
$05 starttalk[p8] endtalk[p8]
$06 standframe[p8]
$07 arg1[p8] arg2[p8] arg3[p8]
$08
$09 elevation[p16]
$0A
$0B index[p8] value[p8]
$0C colour[p8]
$0D name[c]... $00
$0E initframe[p8]
$10 width[p8]
$11 xscale[p8] yscale[p8]
$12
$13 zplane[p8]
$14
$15 animspeed[p8]
$16 mode[p8]
$17 shadow[p8]

Operation

Miscellaneous actions on actors.

Opcode Meaning Description
$00 dummy A dummy case, does nothing (in ScummVM).
$01 SO_COSTUME Sets the actor's costume.
$02 SO_STEP_DIST Sets the actor's walking speed for x and y.
$03 SO_SOUND Associates a sound with the actor (footsteps?)
$04 SO_WALK_ANIMATION Sets the current frame of the walking animation.
$05 SO_TALK_ANIMATION Sets the start and stop frames of the talking animation.
$06 SO_STAND_ANIMATION Sets the current frame of the standing animation.
$07 SO_ANIMATION Unknown; seems to be unused in ScummVM.
$08 SO_DEFAULT Initializes actor.
$09 SO_ELEVATION Sets the actor's elevation to the given value.
$0A SO_ANIMATION_DEFAULT Initializes the actor's animation frames.
Init frame = 1
Walk frame = 2
Stand frame = 3
Talk start frame = 4
Talk stop frame = 5
$0B SO_PALETTE Sets the colour at the given index to a new value (another entry in the colour lookup table/CLUT). Index must be between 0 and 31 (the number of colours in a costume).
$0C SO_TALK_COLOR Sets the actor's talk colour.
$0D SO_ACTOR_NAME Sets the actor's name to the given null-terminated string.
$0E SO_INIT_ANIMATION Sets the current frame of the initial animation.
$10 SO_ACTOR_WIDTH Sets the actor's width.
$11 SO_ACTOR_SCALE Sets the actor's X and Y scales.
$12 SO_NEVER_ZCLIP Turns off all Z-clipping for the actor.
$13 SO_ALWAYS_ZCLIP Forces the actor's Z-clipping for the given Z-plane?
$14 SO_IGNORE_BOXES Ignores boxes, turns off Z-clipping, and puts actor somewhere if the actor is in the current room?
$15 SO_FOLLOW_BOXES Follows boxes, turns off Z-clipping, and puts actor somewhere if the actor is in the current room?
$16 SO_ANIMATION_SPEED Sets the animatino speed
$17 SO_SHADOW Sets the shadow mode.

Variants

In SCUMM V4, sub-opcode $11 (SO_ACTOR_SCALE) only takes one parameter, so X and Y scaling is done at a 1:1 ratio.

actorSetClass ($5D)

Encoding

opcode object[p16] classes[v16]...

Operation

Makes object inherit from all of the given classes. A class of "0" will clear all of the object's existing class data.


add ($5A)

Encoding

opcode result value[p16]

Operation

result := result + value

The variable pointed to by result is read, value is added to it, and the result written back.


and ($17)

one parameter, uses result

Encoding

opcode result value[p16]

Operation

result := result and value

The variable pointed to by result is read, logically ANDed with value, and the result written back.


animateActor ($11)

Encoding

opcode actor[p8] anim[p8]

Operation

Starts the given animation for the given actor.


breakHere ($80)

no parameters

Encoding

opcode

Operation

Deschedules the currently running thread. Execution continues at the next instruction when the thread's next timeslot comes around.


chainScript ($42)

one parameter plus varargs

Encoding

opcode script[p8] args[v16]...

Operation

Replaces the currently running script with another one. The current script is terminated immediately and the new script (determined by the given script ID), is executed in the same thread. The new script has its local variables initialised to the list args. Uninitialised variables have undefined values.


cursorCommand ($2C)

parameters depend on auxiliary opcode

Encoding

opcode sub-opcode

sub-opcode can be any of the following:

$01
... $01 through $08 take the same arguments ...
$08
$0A cursornum[p8] charletter[p8]
$0B index[p8] x[p8] y[p8]
$0C cursor[p8]
$0D charset[p8]
$0E colours[v16]...

Operation

Miscellaneous actions on cursors & charsets.

Opcode Meaning Description
$01 SO_CURSOR_ON Turns the cursor on.
$02 SO_CURSOR_OFF Turns the cursor off.
$03 SO_USERPUT_ON Enables user input.
$04 SO_USERPUT_OFF Disables user input.
$05 SO_CURSOR_SOFT_ON Increments the cursor's state?
$06 SO_CURSOR_SOFT_OFF Decrements the cursor's state?
$07 SO_USERPUT_SOFT_ON Increments "user input" counter (when greater than 0, user input is enabled).
$08 SO_USERPUT_SOFT_OFF Decrements "user input" counter (when 0 or less, user input is disabled).
$0A SO_CURSOR_IMAGE Changes the cursor image to a new one, based on image in a character set. Only used in Loom.
$0B SO_CURSOR_HOTSPOT Changes the hotspot of a cursor. Only used in Loom.
$0C SO_CURSOR_SET Changes the current cursor. Must be between 0 and 3 inclusive.
$0D SO_CHARSET_SET Initializes the given character set.
$0E SO_CHARSET_COLORS Initializes the character set data & colours to the given arguments? Must have 16 arguments?

Variants

In SCUMM V3, sub-opcode $0E performs a different function, possibly initializing a character set.


cutScene ($40)

Encoding

opcode args[v16]...

Operation

??? If required, runs a script passing the given arguments. Cutscene data given by the first argument?


debug ($6B)

one parameter, no result

Encoding

opcode param[p16]

Operation

Passes the parameter to the interpreter's debugger. What this does is entirely platform-specific (and may do nothing).


decrement ($C6)

no parameters, uses result

Encoding

opcode result

Operation

result := result - 1

Reads the variable pointed to by result, decrements it, and writes it back.


delay ($2E)

one constant parameter

Encoding

opcode param[24]

Operation

Suspends the current thread for the appropriate number of 1/60ths of a second. Yes, that really is a 24-bit LE constant.


delayVariable ($2E)

one constant parameter

Encoding

opcode var

Operation

var is dereferenced and the current thread suspended for that number of 1/60ths of a second.


divide ($5B)

one parameter, uses result

Encoding

opcode result value[p16]

Operation

result := result / value

The variable pointed to by result is read, divided by value, and the result written back. If value is zero, the result is undefined (and the interpeter may halt with an error).


doSentence ($19)

Encoding

opcode verb[p8] objectA[p16] objectB[p16]

Operation

Performs a verb sentence action, e.g. "Use monkey on hydrant". If verb is $FE, the current sentence script is stopped, status cleared etc.


drawBox ($3F)

two parameters, does not use result, supplementary opcode byte with three more subsequent parameters

Encoding

opcode left[p16] top[p16] auxopcode[8] right[p16] bottom[p16] colour[p8]

Operation

Draws a solid box on the backbuffer from (left, top)-(right, bottom) in the given colour.

The only part of auxopcode that is relevant are the parameter bits. The rest of the opcode is ignored.


drawObject ($05)

Encoding

opcode object[p16] sub-opcode

sub-opcodes:

$01 xpos[p16] ypos[p16]
$02 state[p16]
$1F

Operation

Opcode Meaning Description
$01 Draw At Moves the given object to the given co-ordinates, and adds it to the drawing queue.
$02 Set State Sets the state of the object, adds it to the drawing queue.
$1F Draw Does not change the object's position (or state?), still adds it to the drawing queue.

Variants

Small header games only support the parameters used with sub-opcode $01, e.g:

opcode object[p16] xpos[p16] ypos[p16]


dummy ($A7)

Encoding

opcode

Operation

V5 specific - The KIXX XL release of Monkey Island 2 (Amiga disk) used this opcode as a dummy, in order to remove copy protection and keep level selection.

Variants

In SCUMM V3 and V4, this opcode is used for the saveLoadVars instruction.


endCutScene ($C0)

Encoding

opcode

Operation

Ends the cutscene, performing cleanup if necessary.


equalZero ($28)

jumps

Encoding

opcode var target[16]

Operation

unless (var == 0) goto target

Target is a byte offset (measured from after this instruction), which will be added to the instruction pointer.


expression ($AC)

Encoding

opcode result subopcode... $FF

sub-opcodes:

$01 value[p16]
$02
... $02 through $05 take the same arguments ...
$05
$06 nested-opcode

Operation

Expression mode operates on a stack. Values are pushed on, and operators are applied to the top two items on the stack.

Opcode Meaning Description
$01 Value Pushes a value onto the top of the stack.
$02 Add stack[top - 1] + stack[top]
$03 Subtract stack[top - 1] - stack[top]
$04 Multiply stack[top - 1] * stack[top]
$05 Divide stack[top - 1] / stack[top] (if stack[top] is 0 an error occurs)
$06 Nested Opcode An entire instruction that returns a result, such as getActorScale. This is interpreted like a normal opcode, but the result is pushed onto the expression stack. (The opcode is passed the special "VAR_RESULT" parameter for "result")


faceActor ($09)

Encoding

opcode actor[p8] object[p16]

Operation

Dereferences actor, tells actor to face object (presumably based on X/Y co-ordinates).


findInventory ($3D)

Encoding

opcode result owner[p8] index[p8]

Operation

object := owner.inventory[index]

Searches for all objects owned by owner (an actor or object), and returns the one at the given index (offset).


findObject ($35)

Encoding

opcode result x[p8] y[p8]

Operation

Returns the first "touchable" local object at the given co-ordinates. Will not match on the bottom or right-hand edges of an object.


freezeScripts ($60)

Encoding

opcode flag[p8]

Operation

Freezes all scripts (by setting the high bit on each script's status). If flag is >= $80, all freeze resistent scripts will also be frozen. If flag is 0, all scripts are unfrozen. Freezing effects are cumulative - i.e. if script A is frozen twice, and unfrozen once, it will still be frozen until it is unfrozen a second time. A script's frozen status is indicated by the high bit.


getActorCostume ($71)

Encoding

opcode result actor[p8]

Operation

Returns the actor's current costume.


getActorElevation ($06)

Encoding

opcode result actor[p8]

Operation

Returns the actor's current elevation.


getActorFacing ($63)

Encoding

opcode result actor[p8]

Operation

Returns the current direction the actor is facing.


getActorMoving ($56)

Encoding

opcode result actor[p8]

Operation

Returns the actor's moving status (0 or 1).


getActorRoom ($03)

Encoding

opcode result actor[p8]

Operation

Returns the room the actor currently occupies?


getActorScale ($3B)

Encoding

opcode result actor[p8]

Operation

Returns the actor's current scale.

Variants

In Indy3, this opcode is used for waitForActor.


getActorWalkBox ($7B)

Encoding

opcode result actor[p8]

Operation

Returns the actor's walkbox.


getActorWidth ($6C)

Encoding

opcode result actor[p8]

Operation

Returns the actor's width.


getActorX ($43)

Encoding

opcode result actor[p16]

Operation

Returns the actor's current X co-ordinate.


getActorY ($23)

Encoding

opcode result actor[p16]

Operation

Returns the actor's current Y co-ordinate.


getAnimCounter ($22)

Encoding

opcode result actor[p8]

Operation

Returns the actor's animation counter.

Variants

This opcode is used for saveLoadGame in SCUMM V3.


getClosestObjActor ($66)

Encoding

opcode result actor[p16]

Operation

Returns the object closest to the actor. Items that are more than 255 units (pixels in newer games, characters in older games) away from the actor will not be detected.


getDist ($34)

Encoding

opcode result objA[p16] objB[p16]

Operation

Returns the distance between two actors/objects (objA and objB).


getInventoryCount ($31)

Encoding

opcode result actor[p8]

Operation

Returns the number of items in an actor's inventory?


getObjectOwner ($10)

Encoding

opcode result object[p16]

Operation

Returns the owner of an object.


getObjectState ($0F)

Encoding

opcode result object[p16]

Operation

Returns the state of the object.

Variants

In small header games, the encoding becomes:

opcode object[p16] state[p8] target[16]

operation becomes

unless (getState(object) == state) goto target


getRandomNumber ($16)

Encoding

opcode result seed[p8]

Operation

Returns a new random number based on the given seed.


getScriptRunning ($68)

Encoding

opcode result script[p8]

Operation

Returns 1 if the given script is running, 0 if it's not.


getStringWidth ($67)

Encoding

opcode result strptr[p8]

Operation

Gets the length of the string pointed to by strptr (either a variable or direct byte), stores the returned value in result.


getVerbEntryPoint ($0B)

Encoding

opcode result object[p16] verb[p16]

Operation

Returns the entry point for the response code/script for when the given verb is applied to the given object? i.e. gets the start of the script to run for the specific user interaction.


ifClassOfIs ($1D)

jumps

Encoding

opcode value[p16] args[p16]... $FF target[16]

Operation

unless (value.class is one of [args.class]) goto target

Compares the value's class with all classes given in args.

Target is a byte offset (measured from after this instruction), which will be added to the instruction pointer.


ifNotState ($2F)

Encoding

opcode object[p16] state[p8] target[16]

Operation

unless (stateOf(object) != state) goto target


ifState ($4F)

Encoding

opcode object[p16] state[p8] target[16]

Operation

unless (stateOf(object) == state) goto target


increment ($46)

no parameters, uses result

Encoding

opcode result

Operation

result := result + 1

Reads the variable pointed to by result, increments it, and writes it back.


isActorInBox ($1F)

Encoding

opcode actor[p8] box[p8] target[16]

Operation

Unless the actor's co-ordinates are within the bounds of the given box, jump to target.

Target is a byte offset (measured from after this instruction), which will be added to the instruction pointer.


isEqual ($48)

Encoding

opcode var value[p16] target[16]

Operation

unless (value == var) goto target

Target is a byte offset (measured from after this instruction), which will be added to the instruction pointer.


isGreater ($78)

Encoding

opcode var value[p16] target[16]

Operation

unless (value > var) goto target

Target is a byte offset (measured from after this instruction), which will be added to the instruction pointer.


isGreaterEqual ($04)

Encoding

opcode var value[p16] target[16]

Operation

unless (value >= var) goto target

Target is a byte offset (measured from after this instruction), which will be added to the instruction pointer.


isLess ($44)

Encoding

opcode var value[p16] target[16]

Operation

unless (value < var) goto target

Target is a byte offset (measured from after this instruction), which will be added to the instruction pointer.


isNotEqual ($08)

Encoding

opcode var value[p16] target[16]

Operation

unless (value != var) goto target

Target is a byte offset (measured from after this instruction), which will be added to the instruction pointer.


isSoundRunning ($7C)

Encoding

opcode result sound[p8]

Operation

Returns 1 if sound is running, returns 0 if sound is not running or if the given sound is 0.


jumpRelative ($18)

jumps

Encoding

opcode target[16]

Operation

PC := PC + target

The inline constant target is read as a signed word and added to the program counter after the instruction has been read. Therefore, if target is zero, the instruction will do nothing; if target is -3, an infinite loop will result.


lessOrEqual ($38)

jumps

Encoding

opcode var value[p16] target[16]

Operation

unless (value <= var) goto target

Target is a byte offset (measured from after this instruction), which will be added to the instruction pointer.


lights ($70)

Encoding

opcode arg1[p8] arg2[8] arg3[8]

Operation

If arg3 is 0, the "current lights" variable is set to arg1. If arg3 is 1, the size of the "flashlight" light is determined by arg1 and arg2, for width and height in stripes (which are equivalent to 8 pixels each; see SCUMM/Technical Reference/Image resources).


loadRoom ($72)

Encoding

opcode room[p8]

Operation

Loads the given room into memory.


loadRoomWithEgo ($24)

Encoding

opcode object[p16] room[p8] x[16] y[16]

Operation

Places the Ego actor in room at object's position. If x is not -1, Ego will start moving towards the given x and y co-ordinates. If object is not in the given room an error will occur. (I think...)


matrixOp ($30)

Encoding

opcode sub-opcode

sub-opcodes:

$01 box[p8] val[p8]
$02 box[p8] val[p8]
$03 box[p8] val[p8]
$04

Operation

This instruction manipulates boxes.

Opcode Meaning Description
$01 setBoxFlags Sets the box's flags to the given value.
$02 setBoxScale Sets the box's scale.
$03 setBoxScale Sets the box's scale to ((val - 1) OR $8000).
$04 createBoxMatrix Initializes the matrix of boxes, by determining the distances and shortest paths between boxes.

Variants

SCUMM V3 only has the one instruction, which behaves like setBoxFlags:

opcode box[p8] val[8]


move ($1A)

Encoding

opcode result value[p16]

Operation

result := value

Value is moved into result.


multiply ($1B)

Encoding

opcode result value[p16]

Operation

result := result * value

The variable pointed to by result is read, multiplied by value, and written back.


notEqualZero ($A8)

Encoding

opcode var target[16]

Operation

unless (var != 0) goto target

Target is a byte offset (measured from after this instruction), which will be added to the instruction pointer.


oldRoomEffect ($5C)

Encoding

opcode sub-opcode

sub-opcodes:

$03 effect[p16]

Operation

Performs like sub-opcode SO_ROOM_FADE of the roomOps instruction (fade in if effect != 0, otherwise fade out).

Variants

FM-Towns SCUMM V3 performs a different effect, not fully implemented in ScummVM. At the moment ScummVM just forces a redraw of the screen background.


or ($57)

one parameter, uses result

Encoding

opcode result value[p16]

Operation

result := result or value

The variable pointed to by result is read, logically ORed with value, and the result written back.


override ($58)

Encoding

opcode sub-opcode

sub-opcodes:

$00
$01 $18 target[16]

Operation

If the sub-opcode is 0, marks the end of an override section. If the sub-opcode is not 0, marks the beginning of an override section. Overrides are used by cutscenes; if a cutscene is skipped (if the user presses the ESC key), the script will jump by the given target (offset from this instruction).


panCameraTo ($12)

Encoding

opcode x[p16]

Operation

Starts the camera panning to the given x co-ordinate.


pickupObject ($25)

Encoding

opcode object[p16] room[p8]

Operation

Adds the given object (located in the given room) to the Ego actor's inventory.

Variants

In SCUMM V3 and V4, this opcode is used for drawObject.


pickupObjectOld ($50)

Encoding

opcode object[p16]

Operation

Adds the given object (located in the given room) to the Ego actor's inventory. If object < 1, an error is raised. If the object is not found or the object is already in the inventory, this function ends gracefully.


print ($14)

Encoding

opcode actor[p8] sub-opcode

sub-opcodes

$00 xpos[p16] ypos[p16]
$01 colour[p8]
$02 right[p16]
$03 width[p16] height[p16]
$04
$06
$07
$08 offset[p16] delay[p16]
$15 string[c]... $FF

Operation

Sets text properties and displays dialogue.

Opcode Meaning Description
$00 SO_AT Sets the position of the text that follows.
$01 SO_COLOR Sets the colour of the text.
$02 SO_CLIPPED Clips the text's right-hand side (for wrapping?).
$03 SO_ERASE Erases characters (not used in ScummVM).
$04 SO_CENTER Centres the text.
$06 SO_LEFT Left-aligns the text.
$07 SO_OVERHEAD Overhead-aligns the text.
$15 SO_TEXTSTRING Prints the text string that follows. Terminated by $FF.

Variants

In SCUMM V3, text function $06 sets the height of the text:

$06 height[p16]

In Loom CD (SCUMM V4), there is an additional text function $08 (SO_SAY_VOICE), which plays a portion of the CD audio track.

$08 offset[p16] delay[p16]


printEgo ($D8)

Encoding

opcode sub-opcode

Operation

Exactly the same as print, except the actor is implicitly Ego. See the entry for "print" for further explanation.


pseudoRoom ($CC)

Encoding

opcode val[8] res[8]... $00

Operation

forall (res) {
 if (res >= $80) {
  _resourceMapper[res & $7F] := val
 }
}

What does this actually do? We may never know.

putActor ($01)

Encoding

opcode actor[p8] x[p16] y[p16]

Operation

Puts the actor at the given co-ordinates.


putActorAtObject ($0E)

Encoding

opcode actor[p8] object[p16]

Operation

Puts the actor at the given object's position. If the object can not be found, a default position is returned (the centre of the screen in ScummVM).


putActorInRoom ($2D)

Encoding

opcode actor[p8] room[p8]

Operation

Puts the actor in the given room.


resourceRoutines ($0C)

Encoding

opcode sub-opcode

sub-opcodes:

$01 resID[p8]
... $01 through $13 take the same arguments ...
$13 resID[p8]
$14 room[p8] object[p16]

Operation

resID is unique only within the resource type (e.g. script 11 will not conflict with sound 11).

Opcode Meaning Description
$01 SO_LOAD_SCRIPT Loads the given script into memory.
$02 SO_LOAD_SOUND Loads the given sound into memory.
$03 SO_LOAD_COSTUME Loads the given costume into memory.
$04 SO_LOAD_ROOM Loads the given room into memory.
$05 SO_NUKE_SCRIPT Obliterates the given script from memory.
$06 SO_NUKE_SOUND Obliterates the given sound from memory.
$07 SO_NUKE_COSTUME Obliterates the given costume from memory.
$08 SO_NUKE_ROOM Obliterates the given room from memory.
$09 SO_LOCK_SCRIPT Locks the given script.
$0A SO_LOCK_SOUND Locks the given sound.
$0B SO_LOCK_COSTUME Locks the given costume.
$0C SO_LOCK_ROOM Locks the given room.
$0D SO_UNLOCK_SCRIPT Unlocks the given script.
$0E SO_UNLOCK_SOUND Unlocks the given sound.
$0F SO_UNLOCK_COSTUME Unlocks the given costume.
$10 SO_UNLOCK_ROOM Unlocks the given room.
$11 SO_CLEAR_HEAP Clears the heap.
$12 SO_LOAD_CHARSET Loads the given character set into memory.
$13 SO_NUKE_CHARSET Obliterates the given character set from memory.
$14 SO_LOAD_OBJECT Loads the given object from the given room resource.

Variants

FM-Towns games add the following sub-opcodes (these are not confirmed nor implemented in ScummVM):

Opcode Meaning Description
$20 Unknown Does nothing, not used in-game.
$21 Unknown Does nothing, not used in-game.
$23 CD Volume Possibly changes the volume of CD tracks (Loom CD). Takes 1 byte.
$24 Sound Volume Sets the loudness of a sound resource. Used in Indy3 and Zak. Takes 2 bytes (left/right volumes?).
$25 Sound Pitch Sets the pitch of a sound resource. Used in Indy3 and Zak. Takes 1 byte (pitch = "foo" - "center" semitones. Center is at $32 in the sound resource.)


roomOps ($33)

Encoding

opcode sub-opcode

sub-opcodes:

$01 minX[p16] maxX[p16]
$03 b[p16] h[p16]
$04 red[p16] green[p16] blue[p16] aux index[p8]
$05
$06
$07 scale1[p8] y1[p8] aux scale2[p8] y2[p8] aux slot[p8]
$08 scale[p8] startcolour[p8] endcolour[p8]
$09 loadflag[p8] loadslot[p8]
$0A effect[p16]
$0B redscale[p16] bluescale[p16] greenscale[p16] aux startcolour[p8] endcolour[p8]
$0C redscale[p16] bluescale[p16] greenscale[p16] aux startcolour[p8] endcolour[p8]
$0D resID[p8] filename[c]... $00
$0E resID[p8] filename[c]... $00
$0F resID[p8] aux start[p8] end[p8] aux time[p8]
$10 colindex[p8] delay[p8]

Operation

Opcode Meaning Description
$01 SO_ROOM_SCROLL Clamps the given arguments so scrolling does not extend past the width of the room or screen.
$03 SO_ROOM_SCREEN Initialises a screen.
$04 SO_ROOM_PALETTE Adjusts the room's palette.
$05 SO_ROOM_SHAKE_ON Starts the room shaking.
$06 SO_ROOM_SHAKE_OFF Ends the room shaking.
$07 SO_ROOM_SCALE Sets the room's y scales? (slot is 1 greater than actual slot?)
$08 SO_ROOM_INTENSITY Lightens/darkens the room's palette.
$09 SO_ROOM_SAVEGAME Saves temporary state of the room/game?
$0A SO_ROOM_FADE If effect is 0, fades in the room. Otherwise, fades out with the given effect (taken from the high byte of effect).
1 = iris effect
2 = box wipe (upper-left to bottom-right)
3 = box wipe (upper-right to bottem-left)
4 = inverse box wipe.
$0B SO_RGB_ROOM_INTENSITY Lightens/darkens the room's palette, with different scales for red, green and blue.
$0C SO_ROOM_SHADOW Lightens/darkens the shadow palette, with different scales for red, green, and blue.
$0D SO_SAVE_STRING Saves a string resource to the given file?
$0E SO_LOAD_STRING Loads a string resource from a given file?
$0F SO_ROOM_TRANSFORM Manipulates palettes, strings?
$10 SO_CYCLE_SPEED Starts colour cycling with delay? colIndex is between 0 and 16

Variants

SCUMM V3 (non-PC Engine) encodes the arguments before the sub-opcode:

opcode arg1[p16] arg2[p16] sub-opcode

Small header games include an extra sub-opcode, $02 (SO_ROOM_COLOR), which adjusts the room's palette:

opcode $02 colour[p16] index[p16]
... or for V3 games ...
opcode colour[p16] index[p16] $02

In small header games, sub-opcode $04 (SO_ROOM_PALETTE) affects the shadow palette, and only accepts two arguments, a "room colour slot" (palette entry? between 0 and 256) and an index:

opcode $04 colour[p16] index[p16]
... or for V3 games ...
opcode colour[p16] index[p16] $04

In FM-Towns games, sub-opcode $0A performs a different function and has its own sub-opcodes (some unknown and all not yet implemented in ScummVM):

opcode $0A sub-opcode
Opcode Meaning Description
$08 compose kMainVirtScreen over a screen buffer
$09 call 0x110:0x20 _ax=0x601 _edx=2
$0A call 0x110:0x20 _ax=0x601 _edx=3
$0B clear screen 0x1C:0x45000 sizeof(640 * 320)
$0C call 0x110:0x20 _ax=0x601 _edx=0
$0D call 0x110:0x20 _ax=0x601 _edx=1
$10 enable clearing of a screen buffer in drawBitmap()
$11 disable clearing of a screen buffer in drawBitmap()
$12 clear a screen buffer
$13 enable palette operations (palManipulate(), cyclePalette() etc.)
$14 disable palette operations
$15 disable clearing of screen 0x1C:0x5000 sizeof(640 * 320) in initScreens()
$16 enable clearing of screen 0x1C:0x5000 sizeof(640 * 320) in initScreens()
$1E Unknown


saveRestoreVerbs ($AB)

Encoding

opcode aux start[p8] end[p8] mode[p8] sub-opcode

sub-opcodes:

$01
$02
$03

Operation

Opcode Meaning Description
$01 SO_SAVE_VERBS For all verbs between start and end, sets the "saveid" to mode.
$02 SO_RESTORE_VERBS For all verbs between start and end and matching mode, kills any existing verb, sets the saveid to 0 and generally inits the verb.
$03 SO_DELETE_VERBS For all verbs between start and end and matching mode, kills any existing verb.


setCameraAt ($32)

Encoding

opcode x[p16]

Operation

Sets the camera's x position.


setObjectName ($54)

Encoding

opcode object[p16] name[c]... $00

Operation

Sets the given object's name.


setOwnerOf ($29)

Encoding

opcode object[p16] owner[p8]

Operation

Sets the owner of the object.


setState ($07)

Encoding

opcode object[p16] state[p8]

Operation

Sets the state of the object.


setVarRange ($26)

non-standard encoding

Encoding

opcode result number[8] values[8]...

or

opcode result number[8] values[16]...

Operation

for (i = 0; i < number; i++) {
 *result + i := values[i];
}

This sets a number of variables to the given parameters. The starting variable is given as "result", and the number of variables to modify is given as "number". This is followed by the same number of values, which will be put into the variable locations. The values are constants, and can be either 16-bit, if the highest bit of the opcode is set, i.e. $A6; or 8-bit, if the highest bit of the opcode is not set, i.e. $26. Note that all values are affected by the opcode's high bit; you can't mix 8 and 16-bit values.

descumm example:

setVarRange(Var[178],9,[0,0,0,0,0,0,0,0,0]);

This sets variables 178 to 186 (inclusive) to 0.


soundKludge ($4C)

Encoding

opcode items[v16]...

Operation

If the first item is -1, the existing sound queue is processed. Otherwise, the list of items is added to the queue.

Variants

In SCUMM V3 (small header) games, this opcode is used for the WaitForSentence instruction.


startMusic ($01)

Encoding

opcode music[p8]

Operation

Adds the music in to the queue to be played.

Variants

In FM-Towns (SCUMM V3) games, this instruction performs different functions (some kind of Audio CD status query function; some partially implemented in ScummVM):

opcode result sub-opcode
Opcode Meaning Description
$00 Is Playing Returns true if a CD audio track is currently playing.
$FC Unpause CD Unpauses the CD audio track.
$FD Pause CD Pauses the CD audio track.
$FE Get CD Sound Returns the current CD sound.
$FF CD Volume Might return the the current CD volume in FM-Towns Loom.
other Track Length Returns the track length in seconds.


startObject ($37)

Encoding

opcode object[p16] script[p8] args[v16]...

Operation

Starts the object's script (OBCD blocks), passing the given arguments.


startScript ($0A)

one parameter plus varargs, extra encoding in opcode

Encoding

opcode script[p8] args[v16]...

Operation

Spawns a new thread running the code in script script. The new script has its local variables initialised to the list args. Uninitialised variables have undefined values.

The opcode carries extra information:

7 6 5 4 0
P1 R F $0A

P1 = standard parameter bit
R = indicates that the script is recursive
F = indicates that the script is freeze resistant (a call to freezeScripts will skip this script, unless the "force freeze" bit of the freezeScripts opcode is set).


startSound ($1C)

Encoding

opcode sound[p8]

Operation

Adds the given sound to the sound queue to be played.


stopMusic ($20)

Encoding

opcode

Operation

Stops all sounds.


stopObjectCode ($00)

Encoding

opcode

Operation

Marks the calling script as dead, to be later pruned from the thread pool. Cleans up residual arrays.


stopObjectScript ($6E)

Encoding

opcode script[p16]

Operation

Marks the given object script as dead, to be later pruned from the thread pool. Cleans up residual arrays.


stopScript ($62)

Encoding

opcode script[p8]

Operation

Marks the given script as dead, to be later pruned from the thread pool. Cleans up residual arrays.


stopSound ($3C)

Encoding

opcode sound[p8]

Operation

Stops the given sound.


stringOps ($27)

parameters depend on sub-opcode

Encoding

opcode sub-opcode

sub-opcodes:

$01 stringID[p8] string[c]... $00
$02 destID[p8] srcID[p8]
$03 stringID[p8] index[p8] char[c]
$04 result stringID[p8] index[p8]
$05 stringID[p8] size[p8]

Operation

Miscellaneous actions on strings (Arrays, referred to by resource number).

Opcode Meaning Description
$01 Load String Loads the inline null-terminated string into the resource slot given by stringID.
$02 Copy String Creates a duplicate of the string at resource slot srcID into destID. The old string at destID is lost.
$03 Write Character Writes char at the given index (offset) of the string resource located at slot stringID. Out of bounds accesses cause undefined behaviour.
$04 Read Character Reads a byte (character) at the given index (offset) of the string resource located at slot stringID, and writes it to result. Out of bounds accesses cause undefined behaviour.
$05 New String Allocates or frees a string (Array), located at resource slot stringID. The string is initialised to size; if size is zero, the string is freed.


subtract ($3A)

Encoding

opcode result value[p16]

Operation

result := result - value

The variable pointed to by result is read, value is subtracted from it, and the result written back.


systemOps ($98)

Encoding

opcode sub-opcode

sub-opcodes:

$01
$02
$03

Operation

Opcode Meaning Description
$01 SO_RESTART Restarts the game.
$02 SO_PAUSE Pauses/unpauses the game.
$03 SO_QUIT Quits the game.


verbOps ($7A)

Encoding

opcode verbID[p8] sub-opcode... $FF

sub-opcodes:

$01 object[p16]
$02 name[c]... $00
$03 colour[p8]
$04 hicolour[p8]
$05 left[p16] top[p16]
$06
$07
$08
$09
$10 colour[p8]
$11
$12 key[p8]
$13
$14 stringID[p16]
$16 object[p16] room[p8]
$17 colour[p8]

Operation

Opcode Meaning Description
$01 SO_VERB_IMAGE Assigns an object (image) to a verb.
$02 SO_VERB_NAME Assigns the in-line name to the verb slot.
$03 SO_VERB_COLOR Sets the colour of the verb.
$04 SO_VERB_HICOLOR Sets the high colour of the verb.
$05 SO_VERB_AT Sets the verb's top-left co-ordinates.
$06 SO_VERB_ON Makes this verb active.
$07 SO_VERB_OFF Makes this verb inactive.
$08 SO_VERB_DELETE Kills this verb.
$09 SO_VERB_NEW Creates a verb in the slot for the given verbID. If the slot is 0 (verb doesn't already exist), will add it to the next unusued slot; if this exceeds the global maximum number of verbs an error will be raised.
$10 SO_VERB_DIMCOLOR Sets the dim colour of the verb.
$11 SO_VERB_DIM Dims this verb.
$12 SO_VERB_KEY Sets the key code (maybe ASCII char?) associated with this verb.
$13 SO_VERB_CENTER Centres the verb?
$14 SO_VERB_NAME_STR Loads the given string resource into the verb's slot. If either the string resource or verb slot is not found (0), the verb resource is nuked.
$16 Assign Object Assigns an object from the given room to the verb (if the object's image index is not already assigned to the given object).
$17 Set Back Colour Sets the background colour of the verb?


wait ($AE)

Encoding

opcode sub-opcode

sub-opcodes:

$01 actor[p8]
$02 
$03
$04

Operation

Opcode Meaning Description
$01 SO_WAIT_FOR_ACTOR If the given actor is moving, breaks and resumes at this instruction again.
$02 SO_WAIT_FOR_MESSAGE If the global variable VAR_HAVE_MSG (Var[3]) is not zero, breaks and resumes at this instruction again.
$03 SO_WAIT_FOR_CAMERA If the camera has not reached its destination x position, breaks and resumes at this instruction again.
$04 SO_WAIT_FOR_SENTENCE If there is a sentence present?, breaks and resumes at this instruction again

Variants

In Indy3 (non-Macintosh), this opcode only acts as SO_WAIT_FOR_MESSAGE and omits the sub-opcode.

opcode


walkActorTo ($1E)

Encoding

opcode actor[p8] x[p16] y[p16]

Operation

Sets the actor to begin walking to the given position.


walkActorToActor ($0D)

Encoding

opcode walker[p8] walkee[p8] distance[8]

Operation

Walks walker towards walkee's position by the given distance. Walker and walkee are both actors.


walkActorToObject ($36)

Encoding

opcode actor[p8] object[p16]

Operation

Sets the actor to begin walking to the given object's position.

Variables

A number of variables are reserved for use by the SPUTM/SCUMM engine. Here is a list of known variables and their corresponding numbers, taken from the ScummVM source code.

VAR_RESULT = 0; // descumm claims var 0 is the result var (for expressions)
VAR_KEYPRESS = 0; // script_v5_.cpp claims var 0 is for keypresses...
VAR_EGO = 1;
VAR_CAMERA_POS_X = 2;
VAR_HAVE_MSG = 3;
VAR_ROOM = 4;
VAR_OVERRIDE = 5;
VAR_MACHINE_SPEED = 6;
VAR_ME = 7;
VAR_NUM_ACTOR = 8;
VAR_CURRENT_LIGHTS = 9;
VAR_CURRENTDRIVE = 10;
VAR_TMR_1 = 11;
VAR_TMR_2 = 12;
VAR_TMR_3 = 13;
VAR_MUSIC_TIMER = 14;
VAR_ACTOR_RANGE_MIN = 15;
VAR_ACTOR_RANGE_MAX = 16;
VAR_CAMERA_MIN_X = 17;
VAR_CAMERA_MAX_X = 18;
VAR_TIMER_NEXT = 19;
VAR_VIRT_MOUSE_X = 20;
VAR_VIRT_MOUSE_Y = 21;
VAR_ROOM_RESOURCE = 22;
VAR_LAST_SOUND = 23;
VAR_CUTSCENEEXIT_KEY = 24;
VAR_TALK_ACTOR = 25;
VAR_CAMERA_FAST_X = 26;
VAR_SCROLL_SCRIPT = 27;
VAR_ENTRY_SCRIPT = 28;
VAR_ENTRY_SCRIPT2 = 29;
VAR_EXIT_SCRIPT = 30;
VAR_EXIT_SCRIPT2 = 31;
VAR_VERB_SCRIPT = 32;
VAR_SENTENCE_SCRIPT = 33;
VAR_INVENTORY_SCRIPT = 34;
VAR_CUTSCENE_START_SCRIPT = 35;
VAR_CUTSCENE_END_SCRIPT = 36;
VAR_CHARINC = 37;
VAR_WALKTO_OBJ = 38;
VAR_DEBUGMODE = 39;
VAR_HEAPSPACE = 40;
VAR_RESTART_KEY = 42;
VAR_PAUSE_KEY = 43;
VAR_MOUSE_X = 44;
VAR_MOUSE_Y = 45;
VAR_TIMER = 46;
VAR_TIMER_TOTAL = 47;
VAR_SOUNDCARD = 48;
VAR_VIDEOMODE = 49;
VAR_MAINMENU_KEY = 50;
VAR_FIXEDDISK = 51;
VAR_CURSORSTATE = 52;
VAR_USERPUT = 53;
VAR_V5_TALK_STRING_Y = 54;
VAR_SOUNDRESULT = 56;
VAR_TALKSTOP_KEY = 57;
VAR_FADE_DELAY = 59;
VAR_NOSUBTITLES = 60;
VAR_SOUNDPARAM = 64;
VAR_SOUNDPARAM2 = 65;
VAR_SOUNDPARAM3 = 66;
VAR_INPUTMODE = 67; // 1 is keyboard, 2 is joystick, 3 is mouse
VAR_MEMORY_PERFORMANCE = 68;
VAR_VIDEO_PERFORMANCE = 69;
VAR_ROOM_FLAG = 70;
VAR_GAME_LOADED = 71;
VAR_NEW_ROOM = 72;

Table of Parameters

This table shows a summary of the opcodes and their parameters in a concise fashion. Further information that could be added: the opcode values, equivalent output from descumm.

Argument types:

  • V = variable
  • B = byte constant
  • W = word constant
  • P8 = variable or byte
  • P16 = variable or word
  • L = list
  • J = jump (used by almost all boolean expressions, comparisons) (equivalent to W)
  • D = delay; 24-bit constant (only used by delay instruction, strangely enough)
  • A0 = ASCII string, null-terminated
  • A1 = ASCII string, $FF terminated
  • FF = the hex value $FF, used for terminating some lists, strings etc.
  • SO = sub-opcode, variants listed underneath as "opcode$sub-opcode"
  • NS = non-standard encoding that cannot be sufficiently expressed in this table
  • + = one or more of the preceding argument (parameter bits usually don't matter)
  • None = does not take that argument argument


Instruction Returns a Value Arg 1 Arg 2 Arg 3
actorFollowCamera False P8 None None
actorFromPos True P16 P16 None
actorOps False P8 SO+ FF
actorOps$00 False P8 None None
actorOps$01 False P8 None None
actorOps$02 False P8 P8 None
actorOps$03 False P8 None None
actorOps$04 False P8 None None
actorOps$05 False P8 P8 None
actorOps$06 False P8 None None
actorOps$07 False P8 P8 P8
actorOps$08 False None None None
actorOps$09 False P16 None None
actorOps$0A False None None None
actorOps$0B False P8 P8 None
actorOps$0C False P8 None None
actorOps$0D False A0 None None
actorOps$0E False P8 None None
actorOps$10 False P8 None None
actorOps$11 False P8 P8 None
actorOps$12 False None None None
actorOps$13 False P8 None None
actorOps$14 False None None None
actorOps$15 False P8 None None
actorOps$16 False P8 None None
actorSetClass False P16 L None
add True P16 None None
and True P16 None None
animateActor False P8 P8 None
breakHere False None None None
chainScript False P8 L None
cursorCommand False SO None None
cursorCommand$01 False None None None
cursorCommand$02 False None None None
cursorCommand$03 False None None None
cursorCommand$04 False None None None
cursorCommand$05 False None None None
cursorCommand$06 False None None None
cursorCommand$07 False None None None
cursorCommand$08 False None None None
cursorCommand$0A False P8 P8 None
cursorCommand$0B False P8 P8 P8
cursorCommand$0C False P8 None None
cursorCommand$0D False P8 None None
cursorCommand$0E False L None None
cutscene False L None None
debug False P16 None None
decrement True None None None
delay False D None None
delayVariable False V None None
divide True P16 None None
doSentence False P8 P16 P16
drawBox False P16 P16 NS
drawObject False P16 SO None
drawObject$01 False P16 P16 None
drawObject$02 False P16 None None
drawObject$1F False None None None
dummy False None None None
endCutscene False None None None
equalZero False V J None
expression True SO+ FF None
expression$01 False P16 None None
expression$02 False None None None
expression$03 False None None None
expression$04 False None None None
expression$05 False None None None
expression$06 False NS None None
faceActor False P8 P16 None
findInventory True P8 P8 None
findObject True P8 P8 None
freezeScripts False P8 None None
getActorCostume True P8 None None
getActorElevation True P8 None None
getActorFacing True P8 None None
getActorMoving True P8 None None
getActorRoom True P8 None None
getActorScale True P8 None None
getActorWalkBox True P8 None None
getActorWidth True P8 None None
getActorX True P16 None None
getActorY True P16 None None
getAnimCounter True P8 None None
getClosestObjActor True P16 None None
getDist True P16 P16 None
getInventoryCount True P8 None None
getObjectOwner True P16 None None
getObjectState True P16 None None
getRandomNumberr True P8 None None
getScriptRunning True P8 None None
getStringWidth True P8 None None
getVerbEntryPoint True P16 P16 None
ifClassOfIs False P16 NS J
ifNotState False P16 P8 J
ifState False P16 P8 J
increment True None None None
isActorInBox False P8 P8 J
isEqual False V P16 J
isGreater False V P16 J
isGreaterEqual False V P16 J
isLess False V P16 J
isNotEqual False V P16 J
isSoundRunning True P8 None None
jumpRelative False J None None
lessOrEqual False V P16 J
lights False P8 B B
loadRoom False P8 None None
loadRoomWithEgo False P16 P8 NS
matrixOp False SO None None
matrixOp$01 False P8 P8 None
matrixOp$02 False P8 P8 None
matrixOp$03 False P8 P8 None
matrixOp$04 False None None None
move True P16 None None
multiply True P16 None None
notEqualZero False V J None
oldRoomEffect False SO None None
oldRoomEffect$03 False P16 None None
or True P16 None None
override False SO None None
override$00 False None None None
override$01 False NS J None
panCameraTo False P16 None None
pickupObject False P16 P8 None
pickupObjectOld False P16 None None
print False P8 SO None
print$00 False P16 P16 None
print$01 False P8 None None
print$02 False P16 None None
print$03 False P16 P16 None
print$04 False None None None
print$06 False None None None
print$07 False None None None
print$08 False P16 P16 None
print$15 False A1 None None
printEgo False None None None
printEgo$00 False P16 P16 None
printEgo$01 False P8 None None
printEgo$02 False P16 None None
printEgo$03 False P16 P16 None
printEgo$04 False None None None
printEgo$06 False None None None
printEgo$07 False None None None
printEgo$08 False P16 P16 None
printEgo$15 False A1 None None
pseudoRoom False B NS NS
putActor False P8 P16 P16
putActorAtObject False P8 P16 None
putActorInRoom False P8 P8 None
resourceRoutines False SO None None
resourcesRoutines$01 False P8 None None
resourcesRoutines$02 False P8 None None
resourcesRoutines$03 False P8 None None
resourcesRoutines$04 False P8 None None
resourcesRoutines$05 False P8 None None
resourcesRoutines$06 False P8 None None
resourcesRoutines$07 False P8 None None
resourcesRoutines$08 False P8 None None
resourcesRoutines$09 False P8 None None
resourcesRoutines$0A False P8 None None
resourcesRoutines$0B False P8 None None
resourcesRoutines$0C False P8 None None
resourcesRoutines$0D False P8 None None
resourcesRoutines$0E False P8 None None
resourcesRoutines$0F False P8 None None
resourcesRoutines$10 False P8 None None
resourcesRoutines$11 False P8 None None
resourcesRoutines$12 False P8 None None
resourcesRoutines$13 False P8 None None
resourcesRoutines$14 False P8 P16 None
roomOps False SO None None
roomOps$01 False P16 P16 None
roomOps$03 False P16 P16 None
roomOps$04 False P16 P16 NS
roomOps$05 False None None None
roomOps$06 False None None None
roomOps$07 False P8 P8 NS
roomOps$08 False P8 P8 P8
roomOps$09 False P8 P8 None
roomOps$0A False P16 None None
roomOps$0B False P16 P16 NS
roomOps$0C False P16 P16 NS
roomOps$0D False P8 NS NS
roomOps$0E False P8 NS NS
roomOps$0F False P8 NS NS
roomOps$10 False P8 P8 None
saveRestoreVerbs False NS NS NS
saveRestoreVerbs$01 False None None None
saveRestoreVerbs$02 False None None None
saveRestoreVerbs$03 False None None None
setCameraAt False P16 None None
setObjectName False P16 A None
setOwnerOf False P16 P8 None
setState False P16 P8 None
setVarRange True B NS NS
soundKludge False L None None
startMusic False P8 None None
startObject False P16 P8 L
startScript False P8 L None
startSound False P8 None None
stopMusic False None None None
stopObjectCode False None None None
stopObjectScript False P16 None None
stopScript False P8 None None
stopSound False P8 None None
stringOps False SO None None
stringOps$01 False P8 A0 None
stringOps$02 False P8 P8 None
stringOps$03 False P8 P8 B
stringOps$04 True P8 P8 None
stringOps$05 False P8 P8 None
subtract True P16 None None
systemOps False SO None None
systemOps$01 False None None None
systemOps$02 False None None None
systemOps$03 False None None None
verbOps False P8 SO+ FF
verbOps$01 False P16 None None
verbOps$02 False A0 None None
verbOps$03 False P8 None None
verbOps$04 False P8 None None
verbOps$05 False P16 P16 None
verbOps$06 False None None None
verbOps$07 False None None None
verbOps$08 False None None None
verbOps$09 False None None None
verbOps$10 False P8 None None
verbOps$11 False None None None
verbOps$12 False P8 None None
verbOps$13 False None None None
verbOps$14 False P16 None None
verbOps$16 False P16 P8 None
verbOps$17 False P8 None None
wait False SO None None
wait$01 False P8 None None
wait$02 False None None None
wait$03 False None None None
wait$04 False None None None
walkActorTo False P8 P16 P16
walkActorToActor False P8 P8 B
walkActorToObject False P8 P16 None