[Scummvm-cvs-logs] CVS: web/docs/specs aary.php,NONE,1.1 char.php,NONE,1.1 glossary.php,NONE,1.1 index.php,NONE,1.1 introduction.php,NONE,1.1 scrp-v5.php,NONE,1.1 scrp-v6.php,NONE,1.1 scrp.php,NONE,1.1 sidebar_specs.php,NONE,1.1 slob.php,NONE,1.1

Jonathan Gray khalek at users.sourceforge.net
Fri Sep 13 07:43:03 CEST 2002


Update of /cvsroot/scummvm/web/docs/specs
In directory usw-pr-cvs1:/tmp/cvs-serv31649

Added Files:
	aary.php char.php glossary.php index.php introduction.php 
	scrp-v5.php scrp-v6.php scrp.php sidebar_specs.php slob.php 
Log Message:
add David Givens scumm docs


--- NEW FILE: aary.php ---
<?

$file_root = "../..";
// load libs
require($file_root."/include/"."incl.php");
require($file_root."/docs/specs/"."sidebar_specs.php");

// start of html
html_header("SCUMM Reference Guide :: AARY Arrays and Strings");
sidebar_specs_start();
    
//display welcome table
echo html_round_frame_start("AARY: Arrays and Strings","98%","",20);
?>

        <p>
          <big><b>AARY: Arrays and Strings</b></big><br>
          <? echo html_line(); ?>
        </p>

<H2>Introduction</H2>

<p>Arrays are used for storing arbitrary blocks of data. They are accessible by
the scripts, and so can be used for storing anything that might be useful;
however, the contents of an array is not stored in the data file and can only
be set at run time. Arrays can be dynamically allocated and freed as desired,
but only a limited number are available. See the section on Arrays in the <a
href="scrp.html">Scripts</A> chapter for more information.

<p>The way Arrays work was redesigned completely between V5 and V6.

<H2>V5 chunk format</H2>

<p>V5 Arrays are not stored in the data file. 32 Arrays are available for
access using the <tt>arrayOps</tt> opcode. V5 Arrays (sometimes also referred
to as Strings) are one-dimensional.

<H2>V6 chunk format</H2>

<p><pre class=box>
 <u>Size</u>    <u>Type</u>             <u>Description</u>
 8       chunk tag        AARY chunk tag
for each array {
 2       word LE          array resource number
 2       word LE          X size minus one
 2       word LE          Y size minus one
 2       word LE          array type
}
 2       word LE          zero
</pre>

<p>The X and Y size fields are set to one less than the actual size;
an entry of 0 means a size of 1. Arrays are always two-dimensional.

<p>The type field can be one of:

<p><table class=list align=center>
<tr><th>Value</th>	<th>Meaning</th></tr>
<tr><td>0</td>		<td>Array of words</td></tr>
<tr><td>1</td>		<td>Array of bytes</td></tr>
</table>
<HR><P STYLE="font-size: smaller; text-align: center">
All material © 2000-2002 David Given, unless where stated otherwise.
</P>

<?
echo html_round_frame_end(" ");

// end of html
echo html_p();
sidebar_end();
html_footer();
?>


--- NEW FILE: char.php ---
<?

$file_root = "../..";
// load libs
require($file_root."/include/"."incl.php");
require($file_root."/docs/specs/"."sidebar_specs.php");

// start of html
html_header("SCUMM Reference Guide :: CHAR Character Sets");
sidebar_specs_start();

//display welcome table
echo html_round_frame_start("CHAR: Character Sets","98%","",20);
?>

        <p>
          <big><b>CHAR: Character Sets</b></big><br>
          <? echo html_line(); ?>
        </p>


<H2>Introduction</H2>

Character sets define the fonts used by SCUMM to draw text, such as dialogue,
on the screen. They are stored in <tt>CHAR</tt> chunks, and
are named resource #6.

<p>SCUMM supports 256 displayable characters in each character set. (Although
the only SCUMM implementation I have access to appears to refuse to
draw the @ character, for some reason.) The character set is more
or less ASCII but may be adapted according to needs; for example,
usually the copyright and trademark symbols are included.

<p> Character glyphs may be 1, 2 or 4 bits per pixel, and can be masked.

<h2>Chunk Format</h2>

<p><pre class=box>
<u>Size</u>    <u>Type</u>             <u>Description</u>
8       chunk tag        CHAR chunk tag
6                        unknown
15      bytes            colour map
1       byte             number of bits per pixel
3                        unknown
1024    256*quad LE      character data offsets
</pre>

<p>The colour map contains the colours each pixel of the character glyph
is drawn as. (I don't know how this works. There are only 15 colours
but 16 possibly pixel values; I think pixel 0 is transparent, pixel
1 is mapped to colour 0, 2 to 1, etc.)

<p>The character data pointers contain the offset, relative to the byte
after the end of the colour map (byte 29), of the character data.
This can be 0 if that particular character is not encoded in the character
set. The character data itself is formatted as follows:

<p><pre class=box>
<u>Size</u>    <u>Type</u>             <u>Description</u>
1       byte             width of character
1       byte             height of character
1       byte             X offset
1       byte             Y offset
many    bytes...         glyph data bitstream
</pre>

The X and Y offsets are added to the screen coordinates of the top-left
corner of the glyph before drawing. This is useful for, say, shadowed
text. Needless to say, glyphs don't all have to be the same size,
although in all the examples I have they are the same height.

<p>The data bitstream encodes the pixels in the glyph in left-to-right,
top-to-bottom order. Multiple pixels are encoded per byte. The pixels
are arranged in big-endian format; so, the first pixel in the stream
is in the top bits of the first data byte; then the bits below that;
and so on. For example, at one bit per pixel:

<p><pre class=box>
Bit position:  7      0 7      0 ...
Words of data: 01234567 89ABCDEF
</pre>

<p>At two bits per pixel:

<p><pre class=box>
Bit position:  7      0 7      0 ...
Words of data: 00112233 44556677
</pre>

<p>And at four bits per pixel:

<p><pre class=box>
Bit position:  7      0 7      1 ...
Words of data: 00001111 22223333
</pre>
<HR><P STYLE="font-size: smaller; text-align: center">
All material © 2000-2002 David Given, unless where stated otherwise.
</P>

<?
echo html_round_frame_end(" ");

// end of html
echo html_p();
sidebar_end();
html_footer();
?>


--- NEW FILE: glossary.php ---
<?

$file_root = "../..";
// load libs
require($file_root."/include/"."incl.php");
require($file_root."/docs/specs/"."sidebar_specs.php");

// start of html
html_header("SCUMM Reference Guide :: Glossary");
sidebar_specs_start();

//display welcome table
echo html_round_frame_start("Glossary","98%","",20);
?>
  
        <p>
          <big><b>Glossary</b></big><br>
          <? echo html_line(); ?>
        </p>  

<dl>
<DT>
archive<DD>A file containing one or more chunks

<dt>chunk
<DD>The basic component of a SCUMM data file. A chunk is a block of data that
starts with a chunk tag; a two or four byte indentifier of the type of data
stored in the chunk, and the length of the chunk.  The rest of the chunk can be
data of any type and may contain child chunks.

<DT>container chunk
<DD>A chunk that contains child chunks. Usually the child chunks follow a
header that may be zero or more bytes long, with no data between them.

<DT>leaf chunk
<DD>A chunk that does not contain any child chunks.

<DT>quad
<DD>A four-byte signed value. SCUMM uses both quad LEs (little endian) and quad
BEs (big endian).

<DT>resource
<DD>A chunk that is important to SCUMM in some way. (Resource and chunk are
mostly interchangeable. Chunk is used to refer to any RIFF file data block,
resource only refers to SCUMM data blocks.)

<DT>resource number
<DD>See <i><a href="#named resource">named resource</a></i>.

<DT>named resource
<DD>A resource that appears in the SCUMM file's index.  Named resources are
identified by a tuple of (class, number). The numbers are small integers
counting up from zero. See <A HREF="resource-classes.html">Resource Classes</A>
for the full list. Named resources are sometimes referred to as objects, but as
these can be easily confused with SCUMM objects it is not recommended.

<DT>string
<DD>Another name for an array.

<DT>word
<DD>A two-byte signed value. SCUMM uses both quad LEs (little endian) and quad
BEs (big endian).

</DL>

<HR><P STYLE="font-size: smaller; text-align: center">
All material © 2000-2002 David Given, unless where stated otherwise.
</P>

<?
echo html_round_frame_end(" ");

// end of html
echo html_p();
sidebar_end();
html_footer();
?>


--- NEW FILE: index.php ---
<?

$file_root = "../..";
// load libs
require($file_root."/include/"."incl.php");
require($file_root."/docs/specs/"."sidebar_specs.php");

// start of html
html_header("The inComplete SCUMM Reference Guide");
sidebar_specs_start();

// add 

//display welcome table
echo html_round_frame_start("The inComplete SCUMM Reference Guide","98%","",20);

?>
        <p>
          <big><b>The inComplete SCUMM Reference Guide</b></big><br>
          <? echo html_line(); ?>
        </p>

        <p>

	<i>being a Partially Complete and Mostly Accurate guide to the SCUMM Engine data file Format for Versions Five and Six (and above)</i>


<HR><P STYLE="font-size: smaller; text-align: center">
All material © 2000-2002 David Given, unless where stated otherwise.
</P>

<?
echo html_round_frame_end(" ");

// end of html
echo html_p();
sidebar_end();
html_footer();
?>

--- NEW FILE: introduction.php ---
<?

$file_root = "../..";
// load libs
require($file_root."/include/"."incl.php");
require($file_root."/docs/specs/"."sidebar_specs.php");

// start of html
html_header("SCUMM Reference Guide :: Introduction");
sidebar_specs_start();

//display welcome table
echo html_round_frame_start("Introduction","98%","",20);

?>

        <p>
          <big><b>Introduction</b></big><br>
          <? echo html_line(); ?>
        </p>

<H2>Changes</h2>

<dl>
<dt>
2002-4-10:
<dd>Added James 'Ender' Brown's information (the engines, the resource tree introduction).

<dt>
2002-3-23:
<dd>Rewrote it in HTML for the new Cowlark web server. LaTeX is good but for an
on-line reference HTML is better.

<dt>
2002-1-30:
<DD>Added Arrays, deciphered a lot of the threading and VM stuff and documented
it, added a bunch of opcodes, assorted tidying.

<DT>2002-1-18:
<DD>Initial version
</dl>

<h2>What is SCUMM?</h2>

SCUMM, the <B>S</B>cript <B>C</B>reation <B>U</B>tility for
<B><EM>M</EM></B><EM>aniac</EM> <B><EM>M</EM></B><EM>ansion</EM>, is an engine
for creating graphics adventure games.

<p>It is well known that the best way to perform some very complex task is to
start out by building a tool to help you with that task. In the same way, two
programmers at LucasArts back in 1988 decided that rather than write a single,
complicated program for their new graphic adventure game, they should instead
build an generic engine that would play any graphic adventure game, if given
the proper data files; this would let them concentrate on the game design,
rather than the details of the programming.

<p>It worked. And so SCUMM was born.

<p>The way the SCUMM engine works is that there is a single executable program,
called the interpreter, that operates on some data files.  The data files
contain images, dialogue, details of object behaviour, and so on. The
interpreter then brings all this to life and handles the details of drawing it
all, animating the characters, processing user input, and all the other details
that a graphic adventure game needs dealt with in order to work properly.
Because the data files contain no executable code, it turns out to be trivial
to port the game to a new platform: just port the interpreter, and use the same
data files. You will get exactly the same game on the new system.

<p class=footnote>A lesson many people have learnt. Infocom, creators of
possibly the finest text adventure games of all time, did a very similar trick
with their Z-machine; you can now get Z-machine interpreters for everything
from a Cray Supercomputer to a Game Boy, all of which will play Infocom's
games, encoded in the data files. See <a href="http://brasslantern.org">Brass
Lentern</a> for more information.

<p>Aric Wilmunder and Ron Gilbert's original SCUMM has been expanded
a bit since 1988, of course. Every time a game required some feature
that SCUMM had not previously supported, the interpreter was extended
and the data file format expanded. The whole system was redesigned
from scratch twice. Even now that LucasArts has finally retired SCUMM
for their latest games, such as <EM>Grim Fandango</EM>, the
interpreter/data file philosophy is still in use and you can see SCUMM
design decisions in the data file format.

<p>This document attempts to document the SCUMM data file format. With
reasonably complete documentation, it becomes possible to do all sorts
of exiting things: like write a free, portable interpreter that will
play and SCUMM game on any platform (such as <a href="http://scummvm.sourceforge.net">ScummVM</a>, written by Ludvig Strigeus and the ScummVM team),
or to create your own SCUMM games from scratch.

<p class=footnote>(In fact your humble author is currently working on a toolkit
to do this, called Skim. This document is, in fact, a side effect of Skim
development.  It can be obtained from <a href="http://www.cowlark.com/scumm.html">my
SCUMM page</a>, but it is not particularly useful in its current state.)

<p>The information obtained here was almost all obtained by other people.  All
I have done is to collate it into one place. Among the many who have been
working on the SCUMM file format, Ludvig Strigeus, Jimmi Thøgerson and Peter
Kelly have performed incredible tasks of reverse-engineering, and I am indebted
to them.

<P class=footnote>Jimmi Thøgerson and Peter Kelly have developed their own
SCUMM file browsing and analysis tool called <a href="http://scummrev.mixnmojo.com">SCUMM
Revisited</a>. If you are at all interested in SCUMM files, this is an
essential tool.

<H2>What versions of SCUMM are there available?</H2>

<p>Many.

<p>SCUMM is a LucasArts in-house standard. The format was never designed
to be public and so would change unpredictably from game to game to
suit the task at hand.

<p>The first LucasArts adventure games used an unknown format that is
now lost with time. We will ignore it because it wasn't really SCUMM
as we know it know, wasn't very good, anyway, and only worked on the
Commodore 64. The first PC versions started with V2 and a variation
of the V1 format.

<p>With <EM>Indiana Jones and the Last Crusade</EM>, LucasArts developed
a modular file format based loosely on the standard IFF format. This
was used several times in various forms until <EM>The Secret of
Monkey Island</EM>, where the SCUMM engine and file format was redesigned
from scratch. The new format was used from then on, and vestiges of
It are still visible in the latest LucasArts games such as <EM>Grim
Fandango</EM>.

<p>The full list of games and versions follows.

<?

$games = array(
		'Maniac Mansion (c64)'                                  => array('1'),
		'Zak McKracken and the Alien Mindbenders (C64)'		=> array('1'),
                'Maniac Mansion'                                        => array('2'),
                'Zak McKracken and the Alien Mindbenders'               => array('2'),
                'Indiana Jones and the Last Crusade'                    => array('2'),
                'Zak McKracken and the Alien Mindbenders (256 - FmTowns)' => array('3'),
                'Indiana Jones and the Last Crusade (256)'              => array('3.0.22'),
                'Loom'                                                  => array('3.5.37'),
                'Loom (alt. version)'                                   => array('3.5.40'),
                'The Secret of Monkey Island (EGA)'                     => array('4.0.67'),
                'The Secret of Monkey Island (VGA Floppy)'              => array('5.0.19'),
                'LOOM (256 color CD version)'                           => array('5.1.42'),
                'Monkey Island 2: LeChuck\'s revenge'                   => array('5.2.2'),
                'The Secret of Monkey Island (VGA CD)'                  => array('5.3.06'),
                'Indiana Jones 4 and the Fate of Atlantis (DEMO)'       => array('5.5.2'),
                'Indiana Jones 4 and the Fate of Atlantis'              => array('5.5.20'),
                'Sam & Max (DEMO)'                                      => array('6.3.0'),
                'Day Of The Tentacle (DEMO)'                            => array('6.3.9'),
                'Day Of The Tentacle'                                   => array('6.4.2'),
                'Sam & Max'                                             => array('6.5.0'),
                'Full Thottle'                                          => array('7.3.5'),
                'The DIG'                                               => array('7.5.0'),
                'Curse of Monkey Island'                                => array('8.1.0')
              );

echo html_frame_start("Game versions","60%",2,1,"color4");
echo html_frame_tr(
                   html_frame_td("Version").
                   html_frame_td("Game", 'align="center"'),
                   "color4"
  
                  );
	$c = 0;
        while (list($name,$array) = each($games))
        {
                if ($c % 2 == 0) { $color = "color2"; } else { $color = "color0"; }
                echo html_frame_tr(
                                    html_frame_td($array[0]).
                                    html_frame_td($name, 'align="center" class="pct'.$array[2].'"'),
                                    $color
                );
                $c++;
        }


echo html_frame_end(" ");
?>
<p>This document will only concern itself with SCUMM versions 5-8.

<h2>What is Skim?</h2>

<p>Skim is a set of tools for manipulating SCUMM files. It will, or at least
will when it's finished, allow existing SCUMM files to be disassembled and new
ones to be constructed.

<p>One of the features of Skim is a linkable object file format, called SLOB.
SLOB files can contain any normal SCUMM resources, plus information about them
to allow several SLOB files to be linked together into a runnable game. See
also the <a href="http://www.cowlark.com/scumm/slob.html">SLOB file format</a>.

<h2>Engines</h2>

<p>The SCUMM virtual machine is made up of a number of sub engines working together. Strictly, the term SCUMM only refers to the scripting language itself. The official term for the virtual machine as a whole is SPUTM --- but getting people to change is probably a lost cause.

<p>Here are all the engines used by the SCUMM virtual machine.

<p><dl>
<dt>SPUTM
<dd>The 'real' name for the engine.

<dt>SCUMM
<dd>The actual scripting language.

<dt>IMUSE
<dd>The MIDI control system, allowing dynamic music.

<dt>SMUSH
<dd>A movie compression format and player.

<dt>INSANE
<dd>The event management system used in V7+ games.

<dt>MMUCAS
<dd>The memory allocation system used in <i>The Curse of Monkey Island</i>. V8 only.
</dl>

<HR><P STYLE="font-size: smaller; text-align: center">
All material © 2000-2002 David Given, unless where stated otherwise.
</P>

<?
echo html_round_frame_end(" ");
          
// end of html
echo html_p();
sidebar_end();
html_footer();
?>


--- NEW FILE: scrp-v5.php ---
<?

$file_root = "../..";
// load libs
require($file_root."/include/"."incl.php");
require($file_root."/docs/specs/"."sidebar_specs.php");

// start of html
html_header("SCUMM Reference Guide :: V5 opcode list");
sidebar_specs_start();

//display welcome table 
echo html_round_frame_start("V5 opcode list","98%","",20);
?>

        <p>
          <big><b>V5 opcode list</b></big><br>
          <? echo html_line(); ?>
        </p>

<p>The following conventions are used in the encoding descriptions.

<p><DL CLASS=tablelike>
<DT><tt>opcode</tt>
<DD>
The instruction's opcode, with the appropriate bits set according to the
parameters.

<DT><tt>result</tt>
<DD>
A result pointer. (A standard word pointer, always a LE word.)

<DT><tt>value[8]</tt>
<DD>
An 8-bit constant (a byte).

<DT><tt>value[16]</tt>
<dd>A 16-bit constant (a word LE).

<DT><tt>value[p8]</tt>
<DD>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.

<DT><tt>value[p16]</tt>
<DD>A 16-bit parameter. This is always encoded as
a word LE.

<DT><tt>value[v16]</tt>
<DD>A variable number of word LE parameters. These are encoded as a sequence of
<tt>aux[8] param[p16]</tt>; <I>param</I>; <I>aux</I> contains the parameter bit
to describe <I>param</I>. A byte of $FF terminates the sequence.

<DT><tt>value[o]</tt>
<DD>The offset word for parameter <I>value</I>. This
is only encoded if needed, but always at the position indicated. If
not specified, the offset word occurs immediately after the parameter.

<DT><tt>(term)</tt>
<DD>An optional term.
</DL>

<!-- actorFollowCamera ---------------------------------------------------- -->

<div class=opcode>
<h2>actorFollowCamera
<h3>$52
</div>

<!-- actorFromPos --------------------------------------------------------- -->

<div class=opcode>
<h2>actorFromPos
<h3>$15
</div>

<!-- actorFollowCamera ---------------------------------------------------- -->

<div class=opcode>
<h2>actorFollowCamera
<h3>$52
</div>

<!-- actorFromPos --------------------------------------------------------- -->

<div class=opcode>
<h2>actorFromPos
<h3>$15
</div>

<!-- actorSet ------------------------------------------------------------- -->

<div class=opcode>
<h2>actorSet
<h3>$13
</div>

<!-- actorSetClass -------------------------------------------------------- -->

<div class=opcode>
<h2>actorSetClass
<h3>$5D
</div>

<!-- add ------------------------------------------------------------------ -->

<div class=opcode>
<h2>add
<h3>$5A; one parameter, uses result
<h4>Encoding</h4>
<h5>opcode result value[p16]
<h4>Operation</h4>
<p class=operation><i>result</i> := <i>result</i> + <i>value</i>
<p>
The variable pointed to by <I>result</I> is read, <I>value</I> is
added to it, and the result written back.
</div>

<!-- and ------------------------------------------------------------------ -->

<div class=opcode>
<h2>and
<h3>$17; one parameter, uses result
<h4>Encoding</h4>
<h5>opcode result value[p16]
<h4>Operation</h4>
<p class=operation><i>result</i> := <i>result</i> and <i>value</i>
<p>
The variable pointed to by <I>result</I> is read, logically ANDed with
<I>value</I>, and the result written back.
</div>

<!-- animateActor --------------------------------------------------------- -->

<div class=opcode>
<h2>animateActor
<h3>$11
</div>

<!-- arrayOp -------------------------------------------------------------- -->

<div class=opcode>
<h2>arrayOp
<h3>$27; parameters depend on auxiliary opcode
<h4>Encoding</h4>
<h5>opcode $01 array[p8]
<h5>opcode $02 dest[p8] src[p8]
<h5>opcode $03 array[p8] index[p8] data[p8]
<h5>opcode $04 result array[p8] index[p8]
<h5>opcode $05 array[p8] size[p8]
<h4>Operation</h4>
<p>Miscellaneous actions on Arrays (referred to by resource number).
<p><table class=list>
<tr><th>Opcode</th><th>Meaning</th><th>Description</th></tr>

<tr><td>$01</td>
<td>load array</td>
<td class=l>
Ensures that the Array is loaded into memory. [I don't know what this does.]
</td></tr>

<tr><td>$02</td>
<td>copy array</td>
<td class=l>
Creates a duplicate of <i>src</i> at resource number <i>dest</i>. The old Array
at <i>dest</i> is lost.
</td></tr>

<tr><td>$02</td>
<td>copy array</td>
<td class=l>
Creates a duplicate of <i>src</i> at resource number <i>dest</i>. The old Array
at <i>dest</i> is lost.
</td></tr>

<tr><td>$03</td>
<td>write entry</td>
<td class=l>
Writes the byte <i>data</i> at offset <i>index</i> of Array <i>array</i>. Out
of bounds accesses cause undefined behaviour.
</td></tr>

<tr><td>$04</td>
<td>read entry</td>
<td class=l>
Sets <i>result</i> to the byte of data at offset <i>index</i> of Array
<i>array<i>. Out of bounds accesses cause undefined behaviour.
</td></tr>

<tr><td>$05</td>
<td>create entry</td>
<td class=l>
Allocates or frees an Array. The Array <i>array</i> is initialised to size <i>size</i>; if <i>size</i> is zero, the Array is freed.
</td></tr>
</table>
</div>

<!-- breakHere ------------------------------------------------------------ -->

<div class=opcode>
<h2>breakHere
<h3>$80; no parameters
<h4>Encoding</h4>
<h5>opcode
<h4>Operation</h4>
Deschedules the currently running thread. Execution continues at the next
instruction when the thread's next timeslot comes around.
</div>

<!-- chainScript ---------------------------------------------------------- -->

<div class=opcode>
<h2>chainScript
<h3>$42; one parameter plus varargs
<h4>Encoding</h4>
<h5>opcode script[p8] args[v16]...
<h4>Operation</h4>
Replaces the currently running script with another one. The current script is
terminated immediately and the new script, resource number <I>script</I>, is
executed in the same thread. The new script has its local variables initialised
to the list <I>args</I>. Uninitialised variables have undefined values.
</div>

<!-- cursorCommand -------------------------------------------------------- -->

<div class=opcode>
<h2>cursorCommand
<h3>$2C
</div>

<!-- cutScene ------------------------------------------------------------- -->

<div class=opcode>
<h2>cutScene
<h3>$40
</div>

<!-- debug ---------------------------------------------------------------- -->

<div class=opcode>
<h2>debug
<h3>$6B; one parameter, no result
<h4>Encoding</h4>
<h5>opcode param[p16]
<h4>Operation</h4>
Passes the parameter to the interpreter's debugger. What this does is entirely
platform-specific (and may do nothing).
</div>

<!-- decrement ------------------------------------------------------------ -->

<div class=opcode>
<h2>decrement
<h3>$C6; no parameters, uses result
<h4>Encoding</h4>
<h5>opcode result
<h4>Operation</h4>
<p><i>result</i> := <i>result</i> - 1
<p>Reads the variable pointed to by <i>result</i>, decrements it, and writes it back.
</div>

<!-- delay ---------------------------------------------------------------- -->

<div class=opcode>
<h2>delay
<h3>$2E; one constant parameter
<h4>Encoding</h4>
<h5>opcode param[24]
<h4>Operation</h4>
<p>Suspends the current thread for the appropriate number of 1/60ths of a second. Yes, that really is a 24-bit LE constant.
</div>

<!-- delayVariable -------------------------------------------------------- -->

<div class=opcode>
<h2>delayVariable
<h3>$2E; one constant parameter
<h4>Encoding</h4>
<h5>opcode pointer[16]
<h4>Operation</h4>
<p><i>pointer</i> is dereferenced and the current thread suspended for that number of 1/60ths of a second. Note that <i>pointer</i> is an inline constant, not a parameter.
</div>

<!-- divide --------------------------------------------------------------- -->

<div class=opcode>
<h2>divide
<h3>$5B; one parameter, uses result
<h4>Encoding</h4>
<h5>opcode result value[p16]
<h4>Operation</h4>
<p class=operation><i>result</i> := <i>result</i> / <i>value</i>
<p>
The variable pointed to by <I>result</I> is read, divided by <I>value</I>, and
the result written back. If <i>value</i> is zero, the result is undefined (and
the interpeter may halt with an error).
</div>

<!-- doSentence ----------------------------------------------------------- -->

<div class=opcode>
<h2>doSentence
<h3>$19
</div>

<!-- drawBox -------------------------------------------------------------- -->

<div class=opcode>
<h2>drawBox
<h3>$3F; two parameters, does not use result, supplementary opcode byte with three more subsequent parameters
<h4>Encoding</h4>
<h5>opcode left[p16] top[p16] auxopcode[8] right[p16] bottom[p16] colour[p8]
<h4>Operation</h4>
<p>Draws a solid box on the backbuffer from (<i>left</i>,
<i>top</i>)-(<i>right</i>, <i>bottom</i>) in the colour <i>colour</i>.

<p>The only part of <i>auxopcode</i> that is relevant are the parameter bits.
The rest of the opcode is ignored.
</div>

<!-- drawObject ----------------------------------------------------------- -->

<div class=opcode>
<h2>drawObject
<h3>$05
</div>

<!-- dummy ---------------------------------------------------------------- -->

<div class=opcode>
<h2>dummy
<h3>$67
</div>

<!-- endCutScene ---------------------------------------------------------- -->

<div class=opcode>
<h2>endCutScene
<h3>$C0
</div>

<!-- equalZero ------------------------------------------------------------ -->

<div class=opcode>
<h2>equalZero
<h3>$28
</div>

<!-- expression ----------------------------------------------------------- -->

<div class=opcode>
<h2>expression
<h3>$AC
</div>

<!-- faceActor ------------------------------------------------------------ -->

<div class=opcode>
<h2>faceActor
<h3>$09
</div>

<!-- findInventory -------------------------------------------------------- -->

<div class=opcode>
<h2>findInventory
<h3>$3D
</div>

<!-- findObject ----------------------------------------------------------- -->

<div class=opcode>
<h2>findObject
<h3>$35
</div>

<!-- freezeScripts -------------------------------------------------------- -->

<div class=opcode>
<h2>freezeScripts
<h3>$60
</div>

<!-- getActorCostume ------------------------------------------------------ -->

<div class=opcode>
<h2>getActorCostume
<h3>$71
</div>

<!-- getActorElevation ---------------------------------------------------- -->

<div class=opcode>
<h2>getActorElevation
<h3>$06
</div>

<!-- getActorFacing ------------------------------------------------------- -->

<div class=opcode>
<h2>getActorFacing
<h3>$63
</div>

<!-- getActorMoving ------------------------------------------------------- -->

<div class=opcode>
<h2>getActorMoving
<h3>$56
</div>

<!-- getActorRoom --------------------------------------------------------- -->

<div class=opcode>
<h2>getActorRoom
<h3>$03
</div>

<!-- getActorScale -------------------------------------------------------- -->

<div class=opcode>
<h2>getActorScale
<h3>$3B
</div>

<!-- getActorWalkBox ------------------------------------------------------ -->

<div class=opcode>
<h2>getActorWalkBox
<h3>$7B
</div>

<!-- getActorWidth -------------------------------------------------------- -->

<div class=opcode>
<h2>getActorWidth
<h3>$6C
</div>

<!-- getActorX ------------------------------------------------------------ -->

<div class=opcode>
<h2>getActorX
<h3>$43
</div>

<!-- getActorY ------------------------------------------------------------ -->

<div class=opcode>
<h2>getActorY
<h3>$23
</div>

<!-- getAnimCounter ------------------------------------------------------- -->

<div class=opcode>
<h2>getAnimCounter
<h3>$22
</div>

<!-- getClosestObjActor --------------------------------------------------- -->

<div class=opcode>
<h2>getClosestObjActor
<h3>$66
</div>

<!-- getDist -------------------------------------------------------------- -->

<div class=opcode>
<h2>getDist
<h3>$34
</div>

<!-- getInventoryCount ---------------------------------------------------- -->

<div class=opcode>
<h2>getInventoryCount
<h3>$31
</div>

<!-- getObjectOwner ------------------------------------------------------- -->

<div class=opcode>
<h2>getObjectOwner
<h3>$10
</div>

<!-- getObjectState ------------------------------------------------------- -->

<div class=opcode>
<h2>getObjectState
<h3>$0F
</div>

<!-- getRandomNumber ------------------------------------------------------ -->

<div class=opcode>
<h2>getRandomNumber
<h3>$16
</div>

<!-- getScriptRunning ----------------------------------------------------- -->

<div class=opcode>
<h2>getScriptRunning
<h3>$68
</div>

<!-- getVerbEntryPoint ---------------------------------------------------- -->

<div class=opcode>
<h2>getVerbEntryPoint
<h3>$0B
</div>

<!-- ifClassOfIs ---------------------------------------------------------- -->

<div class=opcode>
<h2>ifClassOfIs
<h3>$1D
</div>

<!-- increment ------------------------------------------------------------ -->

<div class=opcode>
<h2>increment
<h3>$46; no parameters, uses result
<h4>Encoding</h4>
<h5>opcode result
<h4>Operation</h4>
<p><i>result</i> := <i>result</i> + 1
<p>Reads the variable pointed to by <i>result</i>, increments it, and writes it back.
</div>

<!-- isActorInBox --------------------------------------------------------- -->

<div class=opcode>
<h2>isActorInBox
<h3>$1F
</div>

<!-- isEqual -------------------------------------------------------------- -->

<div class=opcode>
<h2>isEqual
<h3>$48
</div>

<!-- isGreater ------------------------------------------------------------ -->

<div class=opcode>
<h2>isGreater
<h3>$78
</div>

<!-- isGreaterEqual ------------------------------------------------------- -->

<div class=opcode>
<h2>isGreaterEqual
<h3>$04
</div>

<!-- isLess --------------------------------------------------------------- -->

<div class=opcode>
<h2>isLess
<h3>$44
</div>

<!-- isNotEqual ----------------------------------------------------------- -->

<div class=opcode>
<h2>isNotEqual
<h3>$08
</div>

<!-- isSoundRunning ------------------------------------------------------- -->

<div class=opcode>
<h2>isSoundRunning
<h3>$7C
</div>

<!-- jumpRelative --------------------------------------------------------- -->

<div class=opcode>
<h2>jumpRelative
<h3>$18; non-standard encoding
<h4>Encoding</h4>
<h5>opcode target[16]
<h4>Operation</h4>
<p>PC := PC + <i>target</i>

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

<!-- lessOrEqual ---------------------------------------------------------- -->

<div class=opcode>
<h2>lessOrEqual
<h3>$38
</div>

<!-- lights --------------------------------------------------------------- -->

<div class=opcode>
<h2>lights
<h3>$70
</div>

<!-- loadRoom ------------------------------------------------------------- -->

<div class=opcode>
<h2>loadRoom
<h3>$72
</div>

<!-- loadRoomWithEgo ------------------------------------------------------ -->

<div class=opcode>
<h2>loadRoomWithEgo
<h3>$24
</div>

<!-- matrixOp ------------------------------------------------------------- -->

<div class=opcode>
<h2>matrixOp
<h3>$30
</div>

<!-- move ----------------------------------------------------------------- -->

<div class=opcode>
<h2>move
<h3>$1A
</div>

<!-- multiply ------------------------------------------------------------- -->

<div class=opcode>
<h2>multiply
<h3>$1B
</div>

<!-- notEqualZero --------------------------------------------------------- -->

<div class=opcode>
<h2>notEqualZero
<h3>$A8
</div>

<!-- or ------------------------------------------------------------------- -->

<div class=opcode>
<h2>or
<h3>$57; one parameter, uses result
<h4>Encoding</h4>
<h5>opcode result value[p16]
<h4>Operation</h4>
<p class=operation><i>result</i> := <i>result</i> and <i>value</i>
<p>
The variable pointed to by <I>result</I> is read, logically ORed with
<I>value</I>, and the result written back.
</div>

<!-- overRide ------------------------------------------------------------- -->

<div class=opcode>
<h2>overRide
<h3>$58
</div>

<!-- panCameraTo ---------------------------------------------------------- -->

<div class=opcode>
<h2>panCameraTo
<h3>$12
</div>

<!-- pickupObject --------------------------------------------------------- -->

<div class=opcode>
<h2>pickupObject
<h3>$25
</div>

<!-- print ---------------------------------------------------------------- -->

<div class=opcode>
<h2>print
<h3>$14
</div>

<!-- printEgo ------------------------------------------------------------- -->

<div class=opcode>
<h2>printEgo
<h3>$D8
</div>

<!-- pseudoRoom ----------------------------------------------------------- -->

<div class=opcode>
<h2>pseudoRoom
<h3>$CC
</div>

<!-- putActor ------------------------------------------------------------- -->

<div class=opcode>
<h2>putActor
<h3>$01
</div>

<!-- putActorAtObject ----------------------------------------------------- -->

<div class=opcode>
<h2>putActorAtObject
<h3>$0E
</div>

<!-- putActorInRoom ------------------------------------------------------- -->

<div class=opcode>
<h2>putActorInRoom
<h3>$2D
</div>

<!-- quitPauseRestart ----------------------------------------------------- -->

<div class=opcode>
<h2>quitPauseRestart
<h3>$98
</div>

<!-- resourceRoutines ----------------------------------------------------- -->

<div class=opcode>
<h2>resourceRoutines
<h3>$0C
</div>

<!-- roomOp --------------------------------------------------------------- -->

<div class=opcode>
<h2>roomOp
<h3>$33
</div>

<!-- saveRestoreVerbs ----------------------------------------------------- -->

<div class=opcode>
<h2>saveRestoreVerbs
<h3>$AB
</div>

<!-- setCameraAt ---------------------------------------------------------- -->

<div class=opcode>
<h2>setCameraAt
<h3>$32
</div>

<!-- setObjectName -------------------------------------------------------- -->

<div class=opcode>
<h2>setObjectName
<h3>$54
</div>

<!-- setOwnerOf ----------------------------------------------------------- -->

<div class=opcode>
<h2>setOwnerOf
<h3>$29
</div>

<!-- setState ------------------------------------------------------------- -->

<div class=opcode>
<h2>setState
<h3>$07
</div>

<!-- setVarRange ---------------------------------------------------------- -->

<div class=opcode>
<h2>setVarRange
<h3>$26
</div>

<!-- soundKludge ---------------------------------------------------------- -->

<div class=opcode>
<h2>soundKludge
<h3>$4C
</div>

<!-- startMusic ----------------------------------------------------------- -->

<div class=opcode>
<h2>startMusic
<h3>$02
</div>

<!-- startObject ---------------------------------------------------------- -->

<div class=opcode>
<h2>startObject
<h3>$37
</div>

<!-- startScript ---------------------------------------------------------- -->

<div class=opcode>
<h2>startScript
<h3>$0A; one parameter plus varargs, extra encoding in opcode
<h4>Encoding</h4>
<h5>opcode script[p8] args[v16]...
<h4>Operation</h4>
<p>Spawns a new thread running the code in script <i>script</i>. The new script has its local variables initialised to the list <i>args</i>. Uninitialised variables have undefined values.

<p>The opcode carries extra information:

<p><table class=bitfield>
<tr><th>7</th>
	<th>6</th>
		<th>5</th>
			<th>4</th>
				<th></th>
					<th>0</th></tr>
<tr><td><i>P1</i></td>
	<td><i>Q</i></td>
		<td><i>F</i></td>
			<td colspan=3>$0A</td></tr>
</table>

<p>If the <i>Q</i> bit is set, the new thread is marked as <i>quick</i>. If the
<i>F</i> bit is set, the thread is marked as <i>unfreezable</i>. The <i>P1</i>
bit is the parameter bit for <i>script</i>, as usual.
</div>

<!-- startSound ----------------------------------------------------------- -->

<div class=opcode>
<h2>startSound
<h3>$1C
</div>

<!-- stopMusic ------------------------------------------------------------ -->

<div class=opcode>
<h2>stopMusic
<h3>$20
</div>

<!-- stopObjectCode ------------------------------------------------------- -->

<div class=opcode>
<h2>stopObjectCode
<h3>$00
</div>

<!-- stopObjectScript ----------------------------------------------------- -->

<div class=opcode>
<h2>stopObjectScript
<h3>$6E
</div>

<!-- stopScript ----------------------------------------------------------- -->

<div class=opcode>
<h2>stopScript
<h3>$62
</div>

<!-- stopSound ------------------------------------------------------------ -->

<div class=opcode>
<h2>stopSound
<h3>$3C
</div>

<!-- subtract ------------------------------------------------------------- -->

<div class=opcode>
<h2>subtract
<h3>$3A
</div>

<!-- verbOp --------------------------------------------------------------- -->

<div class=opcode>
<h2>animateActor
<h3>$11
</div>

<!-- wait ----------------------------------------------------------------- -->

<div class=opcode>
<h2>wait
<h3>$AE
</div>

<!-- walkActorTo ---------------------------------------------------------- -->

<div class=opcode>
<h2>walkActorTo
<h3>$1E
</div>

<!-- walkActorToActor ----------------------------------------------------- -->

<div class=opcode>
<h2>walkActorToActor
<h3>$0D
</div>

<!-- walkActorToObject ---------------------------------------------------- -->

<div class=opcode>
<h2>walkActorToObject
<h3>$36
</div>
<HR><P STYLE="font-size: smaller; text-align: center">
All material © 2000-2002 David Given, unless where stated otherwise.
</P>

<?
echo html_round_frame_end(" ");

// end of html
echo html_p();
sidebar_end();
html_footer();
?>


--- NEW FILE: scrp-v6.php ---
<?

$file_root = "../..";
// load libs
require($file_root."/include/"."incl.php");
require($file_root."/docs/specs/"."sidebar_specs.php");

// start of html
html_header("SCUMM Reference Guide :: V6 opcode list");
sidebar_specs_start();

//display welcome table
echo html_round_frame_start("V6 opcode list","98%","",20);
?>
  
        <p>
          <big><b>V6 opcode list</b></big><br>
          <? echo html_line(); ?>
        </p>  
[...1849 lines suppressed...]
<BR>

<H4> Operation</H4>If  <I>value</I>  = 0, set  <I>bool</I>  to 1, otherwise set it to
0<BR>
<BR>
Tests the value on the stack to see if it compares to zero.
</div>
<HR><P STYLE="font-size: smaller; text-align: center">
All material © 2000-2002 David Given, unless where stated otherwise.
</P>

<?
echo html_round_frame_end(" ");

// end of html
echo html_p();
sidebar_end();
html_footer();
?>


--- NEW FILE: scrp.php ---
<?

$file_root = "../..";
// load libs
require($file_root."/include/"."incl.php");
require($file_root."/docs/specs/"."sidebar_specs.php");

// start of html
html_header("SCUMM Reference Guide :: SCRP Scripts");
sidebar_specs_start();

//display welcome table
echo html_round_frame_start("SCRP: Scripts","98%","",20);
?>

        <p>
          <big><b>SCRP: Scripts</b></big><br>
          <? echo html_line(); ?>
        </p>

<H2>Introduction</H2>

<p>Insert here

<h2>The SCUMM virtual machine</h2>

<p>The SCUMM virtual machine was given a complete rewrite between version 5 and
version 6. Both virtual machines are simple byte-code machines with built-in
cooperative threading; up to 25 threads can be run simultaneously.  Each thread
gets 16 words of local storage. Up to 8192 words and 32768 bits of global
storage are also available. (The word and bit storage areas occupy seperate
address spaces.)

<p>The V5 machine has hard-coded limits on 800 word variables and 2048 bit
variables. All operations are done to and from a variable (global or local).
The V6 machine can stores the number of variables in the <tt>MAXS</tt> resource
in the index and uses a 100-word global stack for performing operations.

<p>Additional storage is supplied in Array resources. V5 requires arrays to be
declared in the data file; V6 can define new ones on the fly, which means they
can be used as a dynamic heap.

<H2>Pointers</H2>

<p>Both V5 and V6 use a common system of encoding the address of something in
memory. These are referred to as pointers. These come in several forms,
depending on what is being pointed at.

<h4>Word variables</h4>

<p><table class=bitfield>
<tr><th>15</th>
	<th></th>
		<th>13</th>
			<th>12</th>
				<th></th>
					<th>0</th></tr>
<tr><td colspan=3>0</td>
			<td colspan=3><i>address</i></td></tr>
</table>

<h4>Indirected word variables (V5 only)</h4>

<p><table class=bitfield>
<tr><th>15</th>
	<th>14</th>
		<th>13</th>
			<th>12</th>
				<th></th>
					<th>0</th></tr>
<tr><td colspan=3>1</td> 
			<td colspan=3><i>address</i></td></tr>
<tr><td colspan=2>0</td>
		<td><i>I</i></td>
			<td colspan=3><i>offset</i></td></tr>
</table>

<p>If the <i>I</i> bit is not set, the word address
<I>address</I>+<I>offset</I> is used. If it is set, the word address
<I>address</I>+[<I>offset</I>] is used instead.

<p>[Where does the offset word go? It's unclear.]

<h4>Bit variables</h4>

<p><table class=bitfield>
<tr><th>15</th> 	<th>14</th> 	<th></th>	<th>0</th>
<tr><td>1</td>		<td colspan=3><i>address</i></td></tr>
</table>

<h4>Local variables</h4>

<p><table class=bitfield>
<tr><th>15</th>
	<th></th>
		<th>13</th>
			<th>12</th>
				<th></th>
					<th>4</th>
						<th>3</th>
							<th></th>
								<th>0</th></tr>
<tr><td colspan=3>2</td>
			<td colspan=3>0</td>
						<td colspan=3><i>var no</i></td></tr>
</table>

<H2>Threads</H2>

<p>Both engines have automatic cooperative threading. Instructions will be
executed out of a single script until it suspends for some reason; the flow of
execution will then move on to the next script. Each script has the opportunity
to run once per frame, with some exceptions.

<p>In V6, because the stack is shared among all threads, it is the script's
responsibility to ensure that the stack is empty when executing an instruction
that could cause the thread to be descheduled. Leaving items on the stack is
highly dangerous! If state needs to be saved from one frame to the next, it
should be stored in local variables.

<p>Threads may be in one of the following states:

<p><table class=list>
<tr><th>State</th> <th>Meaning</th></tr>

<tr><td>RUNNING</td>
<td align=left>
the thread is currently executing
</td></tr>

<tr><td>PENDED</td>
<td align=left>
the thread was executing, but has spawned another thread.  When the child
thread is descheduled, the pended thread will start executing again
</td></tr>

<tr><td>DELAYED</td>
<td align=left>
the thread is not executing, and is waiting for a timer to expire
</td></tr>

<tr><td>FROZEN</td>
<td align=left>
the thread is suspended and will not execute until it has been thawed again
</td></tr>

</table>

<p>A thread may spawn another thread at any point. When this happens, the
parent thread moves into the PENDED state and stops executing.  The child
thread starts executing immediately. When the child thread is descheduled, the
parent moves back into the RUNNING state and continues on immediately after the
instruction that created the thread. PENDING threads may be nested up to 15
times.

<p>To summarise:

<p>A thread will run once every frame, unless it is delayed or frozen.

<p>Any code may start a new thread at any point. (Sometimes this is done
automatically.) The new thread will immediately run until it is descheduled, at
which point execution continues in the parent thread.

<p>Any non-PENDED thread may be frozen at any point. That thread will not be
run again until it is unfrozen. Attempts to freeze a PENDED thread will be
ignored. It is possible to mark a thread as unfreezable when it is created;
however, even unfreezable threads can be frozen with the appropriate code (see
the <tt>freezeScripts</tt> and <tt>freezeUnfreeze</tt> opcodes).

<h2>Version 5 instruction encoding</h2>

<p>Unfortunately, there is no set V5 instruction encoding. In the general form,
instructions take a fixed number of parameters and return an optional value.
The format is:

<p><I>opcode</I> [<I>result</I>] [<I>parameter1</I>] [<I>parameter2</I>]... 

<p>The result is a word pointer as usual. The parameters are word LE
or byte values depending on the opcode. The meaning of the parameters
is encoded in the top bits of the opcode. For example, the <tt>add</tt>
instruction takes one parameter, and so the opcode looks like this:

<p><table class=bitfield>
<tr><th>7</th>		<th>6</th>	<th></th>	<th>0</th></tr>
<tr><td><i>p1</i></td>	<td colspan=3>$5A</td></tr>
</table>

<p>If the <I>p1</I> bit is set, then the parameter is evaluated as a pointer
and dereferenced. Otherwise it is treated as a constant.  If multiple
parameters are present, the bits work down from the MSB to the LSB.

<p>However, many instructions are exceptions to this rule. For example,
instructions such as <tt>actorSet</tt> that take an auxiliary opcode will put
it somewhere in the instruction stream; <tt>actorSet</tt> puts it after the
first parameter, and then the other parameters vary according to the particular
operation. <tt>jumpRelative</tt> puts the jump target immediately after the
opcode encoded as a constant.  Some opcodes (such as <tt>drawBox</tt>) take too
many parameters and have a supplementary opcode byte to contain the extra
parameter bits.  You have been warned.

<H2>Version 6 instruction encoding</H2>

<p>After V5, the byte-code engine was rewritten completely. The new engine is
far more orthogonal and considerably easier to understand.

<p>Most instructions use the stack for all input and output, so the opcodes in
this case are single bytes with no parameters. Some instructions do take
parameters, but these are always of fixed size and type and so no parameter
type bits are needed.

<p>As a result of this more efficient encoding, the V6 engine actually has more
instructions than the V5 one, despite using fewer entries in the opcode map.

<H2>Arrays</H2>

<p>Both V5 and V6 allow Array resources to be used as a dynamic heap.  V5
allows up to 32 one-dimensional arrays, also referred to as Strings; V6 allows
an arbitrary number (the maximum is defined in the MAXS chunk) of
two-dimensional arrays. V5 arrays can only store bytes, while V6 ones can store
bytes or words.

<p>Before an Array can be used, it must be defined. V5 does this with
<tt>arrayOps/5</tt>, passing in the Array resource number (1..32) and the size.
The specified Array is initialised to zero. V6 does it with the <tt>dim</tt>,
<tt>dim2</tt> or <tt>arrayOps/208</tt> opcodes, depending on the type of array
and how it is to be initialised.
<HR><P STYLE="font-size: smaller; text-align: center">
All material © 2000-2002 David Given, unless where stated otherwise.
</P>

<?
echo html_round_frame_end(" ");

// end of html
echo html_p();
sidebar_end();
html_footer();
?>


--- NEW FILE: sidebar_specs.php ---
<?

/*
 * SideBar lib for ScummVM
 * by Jeremy Newman <jnewman at dracowulf.com>
 *
 */
  
function sidebar_specs_start ()
{
  
    global $file_root;

?>

<table width="100%" border=0 cellpadding=0 cellspacing=0>
<tr>
<td align=center valign=top width="120">

<?

	$g = new htmlmenu("Contents");
	$g->add("Introduction", $file_root."/docs/specs/"."introduction.php");
	$g->add("CHAR", $file_root."/docs/specs/"."char.php");
	$g->add("AARY", $file_root."/docs/specs/"."aary.php");
	$g->add("SCRP", $file_root."/docs/specs/"."scrp.php");
	$g->add("V5 opcode list", $file_root."/docs/specs/"."scrp-v5.php");
	$g->add("V6 opcode list", $file_root."/docs/specs/"."scrp-v6.php");
	$g->add("Glossary", $file_root."/docs/specs/"."glossary.php");
	$g->add("SLOB files", $file_root."/docs/specs/"."slob.php");

	$g->done();


	$g = new htmlmenu("Main Menu");

	$g->add("Home", $file_root);
	$g->add("FAQ", $file_root."/faq.php");
	$g->add("ScreenShots", $file_root."/screenshots.php");
	$g->add("Compatibility", $file_root."/compatibility.php");
        $g->add("Documentation", $file_root."/documentation.php");
	$g->add("Downloads", $file_root."/downloads.php");

	$g->done();


	$g = new htmlmenu("SourceForge Menu");

	$g->add("Project Home", "http://sourceforge.net/projects/scummvm/");
	$g->add("Forums", "http://sourceforge.net/forum/?group_id=37116");
	$g->add("Bug Tracking", "http://sourceforge.net/tracker/?group_id=37116&atid=418820");
	$g->add("Daily Snapshots", "http://scummvm.sourceforge.net/daily/");
	$g->add("CVS Tree", "http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/scummvm/scummvm/");

	$g->done();      

	$g = new htmlmenu("Misc. Menu");

	$g->add("Links", $file_root."/links.php");
	$g->add("Contact", $file_root."/contact.php");

	$g->done("",'<img src="'.$file_root.'/images/hangmonk.gif" border=0 alt="monkey">');
 
?>
	<p> </p>
	
	<form action="https://www.paypal.com/cgi-bin/webscr" method="post">
	<input type="hidden" name="cmd" value="_xclick">
	<input type="hidden" name="business" value="paypal at enderboi.com">
	<input type="hidden" name="item_name" value="ScummVM donation">
	<input type="image" src="<?=$file_root?>/images/ppdonate.gif" name="submit" alt="Donate to ScummVM with PayPal!">
	</form>	
	
	<p align="center">
	  <a href="http://sourceforge.net"><img src="http://sourceforge.net/sflogo.php?group_id=37116"
	  width="88" height="31" border="0" alt="SourceForge"></a>
	</p>

</td>
<td width="100%" valign="top">

<?
}

?>

--- NEW FILE: slob.php ---
<?

$file_root = "../..";
// load libs
require($file_root."/include/"."incl.php");
require($file_root."/docs/specs/"."sidebar_specs.php");

// start of html
html_header("SCUMM Reference Guide :: SLOB files");
sidebar_specs_start();

//display welcome table 
echo html_round_frame_start("SLOB files","98%","",20);
?>

        <p>
          <big><b>SLOB files</b></big><br>
          <? echo html_line(); ?>
        </p>


<H2>Introduction</H2>

<p>SLOB files are used by Skim to store intermediate data while working on
SCUMM files. Each file can contain one or more SCUMM resources, plus metadata
used to describe the resources to the linker and to tell the linker which other
resources the SLOB file refers to.

<p>SLOB files have the following format:

<p><pre class=box>
<u>Size</u>    <u>Type</u>             <u>Description</u>
8       chunk tag        Slob chunk tag
        chunk            SVer chunk
        chunk            Data chunk
        chunks...        fixup chunks
</pre>

<p>SVer:

<p><pre class=box>
<u>Size</u>    <u>Type</u>             <u>Description</u>
8       chunk tag        Sver chunk tag
1       byte             SCUMM major version
1       byte             SCUMM minor version
1       byte             Skim major version
1       byte             Skim minor version
</pre>

<p>Data:

<p><pre class=box>
<u>Size</u>    <u>Type</u>             <u>Description</u>
8       chunk tag        Data chunk tag
        chunk            any SCUMM chunk
</pre>

<H2>Fixup chunks</H2>

<p>There are two kind of fixup chunks. <tt>OInd</tt> is used to inform
the linker that the SLOB file contains an exported resource; <tt>OFix</tt>
is used to inform the linker that the SLOB file is referring to another
resource, and which the linker needs to insert references to when
the SLOB file is linked.

<p>The linker refers to named resources by name and class. The name can
be any short string, although the Skim compiler will have trouble
if the name is not a valid C identifier. When the files are linked,
the linker will choose a resource number and patch all the resources
that referenced that particular named resource to use it. It is also
possible to patch in an offset to a resource relative to another resource.
Each resource class has its own namespace, so <TT>char largetext</TT>
and <TT>scrp largetext</TT> will not conflict.

<p>This mechanism is also used to manage word and bit variables for use in
scripts.

<h2><tt>OInd</tt> --- named resource declaration</h2>

<p><pre class=box>
<u>Size</u>    <u>Type</u>             <u>Description</u>
8       chunk tag        OInd chunk tag
2       word LE          desired resource number
        bytes...         zero-terminated path
1       byte             resource class
        bytes...         zero-terminated resource name
</pre>

<p>This chunk notifies Skim that the given resource is a named resource.  The
path given is relative to the <tt>Data</tt> chunk (so a path of <tt>/</tt> ---
which is invalid --- refers to the <tt>Data</tt> chunk itself).

<p>The resource type is a standard SCUMM resource class, or an extension
(of which more later). The resource number should be -1 if the linker
is to choose a resource number when the final link is done, or else
the number can be explicitly specified. Attempting to link two SLOB
files that contain the same resource name with conflicting explicit
object numbers will cause an error.

<p>A negative object number indicates that you don't care about the actual
number. The linker is free to use any number to represent these, provided
they're consistent, and to renumber them as required when linking
together two different SLOB files.

<p>The object name is a string containing the name of the object, which
is used to distinguish dynamically numbered objects.

<p>This is also used to keep track of other entities by use of special
object types.

<p><table class=list align=center>
<tr><th>Value</th>		<th>Meaning</th></tr>
<tr><td>128</td>		<td>Word variable</th></tr>
<tr><td>129</td>                <td>Bit variable</th></tr>
</table>

<p>When these are used, the resource path is ignored.

<H2><tt>OFix</tt> --- named resource fixup</h2>

<p><pre class=box>
<u>Size</u>    <u>Type</u>             <u>Description</u>
8       chunk tag        OInd chunk tag
4       quad LE          offset into destination resource
1       byte             action
1       byte             fixup type
        bytes...         zero-terminated path of destination resource
1       byte             byte C
        bytes...         zero-terminated string S1
        bytes...         zero-terminated string S2
</pre>

<p>The actual action taken is as follows:

<p><table class=list align=center>
<tr><th>Value</th>	<th>Meaning</th></tr>

<tr><td>0</td>
<td class=l>
Do nothing.
</td></tr>

<tr><td>1</td>
<td class=l>
Write the resource number of the named resource specified by the resource class
C and name S1 into the destination resource, in the format specified by the
fixup byte. S2 is ignored.
</td></tr>

<tr><td>2</td>
<td class=l>
Write the offset of the resource specified by the path S1, relative to the path
S2, into the destination resource, in the format specified by the fixup byte.
If the offset is too large to fit in the specified fixup then the linker will
halt with an error. C is ignored. Note that both S1 and S2 are specified
relative to the SLOB's <tt>Data</tt> chunk; it is legal for S2 to be outside
S1.
</td></tr>

</table>

<p>When <tt>action</tt> is 2, the fixup byte is interpreted as follows:

<p><table class=list align=center>
<tr><th>Value</th>		<th>Meaning</th></tr>
<tr><td>0</td>			<td>Do nothing.</td></tr>
<tr><td>1</td>			<td>Write a byte.</td></tr>
<tr><td>2</td>			<td>Write a word LE.</td></tr>
<tr><td>3</td>			<td>Write a word BE.</td></tr>
<tr><td>4</td>			<td>Write a quad LE.</td></tr>
<tr><td>5</td>			<td>Write a quad BE.</td></tr>
</table>

<HR><P STYLE="font-size: smaller; text-align: center">
All material © 2000-2002 David Given, unless where stated otherwise.
</P>

<?
echo html_round_frame_end(" ");

// end of html
echo html_p();
sidebar_end();
html_footer();
?>






More information about the Scummvm-git-logs mailing list