<?xml version="1.0"?>
<?xml-stylesheet type="text/css" href="http://insidethelink.ortiche.net/wiki/skins/common/feed.css?303"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>http://insidethelink.ortiche.net/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Tahg</id>
		<title>A look inside The Link @ wiki - User contributions [en]</title>
		<link rel="self" type="application/atom+xml" href="http://insidethelink.ortiche.net/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Tahg"/>
		<link rel="alternate" type="text/html" href="http://insidethelink.ortiche.net/wiki/index.php/Special:Contributions/Tahg"/>
		<updated>2026-05-04T10:13:20Z</updated>
		<subtitle>User contributions</subtitle>
		<generator>MediaWiki 1.23.15</generator>

	<entry>
		<id>http://insidethelink.ortiche.net/wiki/index.php/Mohawk_Bitmaps</id>
		<title>Mohawk Bitmaps</title>
		<link rel="alternate" type="text/html" href="http://insidethelink.ortiche.net/wiki/index.php/Mohawk_Bitmaps"/>
				<updated>2009-11-28T10:27:21Z</updated>
		
		<summary type="html">&lt;p&gt;Tahg: /* RLE8 Compression */ edited for clarity&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Myst}}&lt;br /&gt;
{{Riven}}&lt;br /&gt;
All observed Mohawk games use a common bitmap format, besides Myst (which uses [[WDIB]] and [[Myst PICT resources|PICT]] images). Mohawk bitmaps are always stored with a tBMP tag. All values are in big endian order. tBMP resources are divided into three chunks: the header, the palette, and the image. Note that the palette is not always present (such as non-Riven 8bpp images and Riven 24bpp images).&lt;br /&gt;
&lt;br /&gt;
== Bitmap Header ==&lt;br /&gt;
{| class=&amp;quot;structure&amp;quot;&lt;br /&gt;
|unsigned short||bitmap width&lt;br /&gt;
|-&lt;br /&gt;
|unsigned short||bitmap height&lt;br /&gt;
|-&lt;br /&gt;
|unsigned short||bytes per row&lt;br /&gt;
|-&lt;br /&gt;
|unsigned short||compression details&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* ''bitmap width'' is the width of the bitmap in pixels.&lt;br /&gt;
* ''bitmap height'' is the height of the bitmap in pixels.&lt;br /&gt;
* ''bytes per row'' is the pitch of the image (bytes in a scan line).&lt;br /&gt;
* For ''compression details'', see the next section.&lt;br /&gt;
&lt;br /&gt;
'''Note''': Both ''bitmap width'' and ''bitmap height'' are only valid for the bottom 10 bits (val &amp;amp; 0x3ff, in C). ''bytes per row'' is also the same, but has to remain even (val &amp;amp; 0x3fe, in C).&lt;br /&gt;
&lt;br /&gt;
=== Compression Details ===&lt;br /&gt;
''compression details'' is split up into different sections, depending on their purpose.&lt;br /&gt;
&lt;br /&gt;
==== Bits 0-2 (Bits Per Pixel) ====&lt;br /&gt;
The lower three bits represent the images' bit depth. It is chosen from this table.&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background:silver&amp;quot;&lt;br /&gt;
|Value||Bits Per Pixel&lt;br /&gt;
|-&lt;br /&gt;
|0||1&lt;br /&gt;
|-&lt;br /&gt;
|1||4&lt;br /&gt;
|-&lt;br /&gt;
|2||8&lt;br /&gt;
|-&lt;br /&gt;
|3||16&lt;br /&gt;
|-&lt;br /&gt;
|4||24&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Other values are undefined.&lt;br /&gt;
&lt;br /&gt;
==== Bit 3 (Palette) ====&lt;br /&gt;
Bit 3 represents whether or not a palette will occur. However, this is very unreliable, as Riven never has this bit set. If the game is Riven, and the bit depth is 8, you should assume there is a palette.&lt;br /&gt;
&lt;br /&gt;
==== Bits 4-7 (Secondary Compression) ====&lt;br /&gt;
Bits 4-7 represent the secondary compression on the image. &lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background:silver&amp;quot;&lt;br /&gt;
|Value||Secondary Compression&lt;br /&gt;
|-&lt;br /&gt;
|0||None&lt;br /&gt;
|-&lt;br /&gt;
|1||RLE8&lt;br /&gt;
|-&lt;br /&gt;
|3||Another (still unknown) RLE variant&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For none, the image is raw pixels. However, there are ''bytes per row'' bytes per row, so you have to skip remaining bytes at the end of the row. In Riven, there is always no secondary compression. On the contrary, in almost all other games' images, the compression is RLE8.&lt;br /&gt;
&lt;br /&gt;
==== Bits 8-11 (Primary Compression) ====&lt;br /&gt;
Bits 8-11 represent the primary compression on the image.&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background:silver&amp;quot;&lt;br /&gt;
|Value||Secondary Compression&lt;br /&gt;
|-&lt;br /&gt;
|0||None&lt;br /&gt;
|-&lt;br /&gt;
|1||LZ&lt;br /&gt;
|-&lt;br /&gt;
|2||Another (still unknown) LZ variant&lt;br /&gt;
|-&lt;br /&gt;
|4||Riven&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For none, there is nothing to do at this stage. See details later for the LZ and Riven compression schemes.&lt;br /&gt;
&lt;br /&gt;
== Palette ==&lt;br /&gt;
While bit 3 should represent whether a palette exists or not, all 8bpp Riven images have a palette regardless. The palette starts with a short header:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;structure&amp;quot;&lt;br /&gt;
|unsigned short||table_size&lt;br /&gt;
|-&lt;br /&gt;
|byte||bits_per_color&lt;br /&gt;
|-&lt;br /&gt;
|byte||color_count&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* ''table_size'' is the size of the table, including the four byte header.&lt;br /&gt;
* ''bits_per_color'' is the bits that each color is (seems to be always 24)&lt;br /&gt;
* ''color_count'' is the amount of colors that the table contains (seems to be always 0xff)&lt;br /&gt;
&lt;br /&gt;
Following the header is ''color_count'' blocks:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;structure&amp;quot;&lt;br /&gt;
|byte||blue_component&lt;br /&gt;
|-&lt;br /&gt;
|byte||green_component&lt;br /&gt;
|-&lt;br /&gt;
|byte||red_component&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Image ==&lt;br /&gt;
&lt;br /&gt;
The rest of the tBMP resource is made up of the image. To decode the image, you must first use the primary decompression and then the secondary decompression to have the correct output image.&lt;br /&gt;
&lt;br /&gt;
=== Primary Decompression ===&lt;br /&gt;
&lt;br /&gt;
If the image has no primary decompression you can skip this step.&lt;br /&gt;
&lt;br /&gt;
==== LZ Decompression ====&lt;br /&gt;
&lt;br /&gt;
The stream consists of two parts, the header and the compressed data.&lt;br /&gt;
&lt;br /&gt;
===== LZ Header =====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;structure&amp;quot;&lt;br /&gt;
|unsigned long||uncompressed_size&lt;br /&gt;
|-&lt;br /&gt;
|unsigned long||compressed_size&lt;br /&gt;
|-&lt;br /&gt;
|unsigned short||dictionary_size&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* ''uncompressed_size'' is the size of the data after decompressing.&lt;br /&gt;
* ''compressed_size'' is the size of the data before decompressing.&lt;br /&gt;
* ''dictionary_size'' is the size of the ring buffer to use in the decompressor. However, it is '''''always''''' 0x400, and if it's not 0x400, it should be thrown out.&lt;br /&gt;
&lt;br /&gt;
===== LZ Compression =====&lt;br /&gt;
Thanks to Petroff Heroj and Ron Hayter for working out this compression.&lt;br /&gt;
&lt;br /&gt;
Until the end of the resource, each run begins with a byte. Each bit of this byte defines what to do next, starting from the least significant one.&lt;br /&gt;
* A 1 means an absolute byte follows. Read a byte from the compressed data and store it directly into the uncompressed buffer.&lt;br /&gt;
* A 0 means a length/offset pair follows. Read two bytes ''b1'' and ''b2'' from the compressed data. The most significant 6 bits of ''b1'' represent the length of the run minus 3. The 2 least significant bits of ''b1'' and the whole ''b2'' form together a 10-bit offset into the ring buffer, minus 0x42. At this point copy ''length'' bytes from the ring buffer, starting at ''offset'', to the uncompressed buffer. If ''offset'' is over 0x400 make sure to subtract 0x400 after adding the 0x42, i.e. loop around to the beginning of the ring buffer.&lt;br /&gt;
The ring-buffer should be initialized to all zeroes. Remember to store the uncompressed bytes in the ring buffer as well, looping to the beginning after 0x400 bytes.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xf7                     // decoder byte (11110111b)&lt;br /&gt;
0x87                     // absolute byte&lt;br /&gt;
0x73                     // absolute byte&lt;br /&gt;
0x27                     // absolute byte&lt;br /&gt;
0x0b                     // byte 1 of the run data: length = 2 + 3 = 5 (first 6 bits + 3)&lt;br /&gt;
0xa9                     // byte 2 of the run data: offset = 0x3a9 + 0x42 = 0x3eb&lt;br /&gt;
0x27                     // absolute byte&lt;br /&gt;
0x32                     // absolute byte&lt;br /&gt;
0x00                     // absolute byte&lt;br /&gt;
0x4e                     // absolute byte&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Riven Decompression ====&lt;br /&gt;
In compressed tBMP bitmaps, pixels are encoded as a data stream made of variable length commands. Pixels are always decoded in duplets: each command generates at least 2 pixels. The encoding is heavily based on what comes before each command, so even a little decoding bug can cripple the whole image. The commands can appear in any order inside the data stream. The first 4 bytes of the data stream are unknown and can be ignored. Many thanks to Arthur Muller for his precious help in decoding this format.&lt;br /&gt;
&lt;br /&gt;
Like the uncompressed format, sometimes duplets are generated beyond the edge of the image. Use the ''bytes per row'' value to see how many duplets are in each row.&lt;br /&gt;
&lt;br /&gt;
===== Main Commands =====&lt;br /&gt;
&lt;br /&gt;
They are all 1-byte commands, followed by a variable number of arguments.&lt;br /&gt;
&lt;br /&gt;
{| border=1 cellpadding=4 cellspacing=0 style=&amp;quot;border:1px #000 solid;border-collapse:collapse;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background:#CCC&amp;quot;&lt;br /&gt;
! Command !! Action&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;font-family:monospace&amp;quot;|0x00||End of stream: when reaching it, the decoding is complete. No additional bytes follow. I think some bitmaps don't have this, so just stop when you have decoded enough pixels to fill the image.&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;font-family:monospace&amp;quot;|0x01&amp;amp;nbsp;-0x3f||Output ''n'' pixel duplets, where ''n'' is the command value itself. Pixel data comes immediately after the command as 2*''n'' bytes representing direct indices in the 8-bit color table.&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;font-family:monospace&amp;quot;|0x40-0x7f||Repeat last 2 pixels ''n'' times, where ''n'' = ''command_value'' &amp;amp; 0x3F. No additional bytes follow.&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;font-family:monospace&amp;quot;|0x80-0xbf||Repeat last 4 pixels ''n'' times, where ''n'' = ''command_value'' &amp;amp; 0x3F. No additional bytes follow.&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;font-family:monospace&amp;quot;|0xc0-0xff||Begin of a subcommand stream. This is like the main command stream, but contains another set of commands which are somewhat more specific and a bit more complex. This command says that ''command_value'' &amp;amp; 0x3F subcommands will follow. It doesn't generate pixels itself.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== Subcommands, part 1: arithmetic operations =====&lt;br /&gt;
Subcommands are not simply 1-byte values, but are somewhat mixed with their arguments, so the full byte pattern is reported.&lt;br /&gt;
{| border=1 cellpadding=4 cellspacing=0 style=&amp;quot;border:1px #000 solid;border-collapse:collapse;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background:#CCC&amp;quot;&lt;br /&gt;
! Command !! Byte pattern !! Action&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;font-family:monospace&amp;quot;|0x01-0x0f&lt;br /&gt;
|style=&amp;quot;font-family:monospace&amp;quot;|0000mmmm&lt;br /&gt;
|Repeat duplet at relative position -''m'', where ''m'' is given in duplets. So if ''m''=1, repeat the last duplet.&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;font-family:monospace&amp;quot;|0x10&lt;br /&gt;
|style=&amp;quot;font-family:monospace&amp;quot;|0x10 p&lt;br /&gt;
|Repeat last duplet, but change second pixel to ''p''.&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;font-family:monospace&amp;quot;|0x11-0x1f&lt;br /&gt;
|style=&amp;quot;font-family:monospace&amp;quot;|0001mmmm&lt;br /&gt;
|Output the first pixel of last duplet, then pixel at relative position -''m''. ''m'' is given in pixels.&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;font-family:monospace&amp;quot;|0x20-0x2f&lt;br /&gt;
|style=&amp;quot;font-family:monospace&amp;quot;|0010xxxx&lt;br /&gt;
|Repeat last duplet, but add ''x'' to second pixel.&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;font-family:monospace&amp;quot;|0x30-0x3f&lt;br /&gt;
|style=&amp;quot;font-family:monospace&amp;quot;|0011xxxx&lt;br /&gt;
|Repeat last duplet, but subtract ''x'' to second pixel.&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;font-family:monospace&amp;quot;|0x40&lt;br /&gt;
|style=&amp;quot;font-family:monospace&amp;quot;|0x40 p&lt;br /&gt;
|Repeat last duplet, but change first pixel to ''p''.&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;font-family:monospace&amp;quot;|0x41-0x4f&lt;br /&gt;
|style=&amp;quot;font-family:monospace&amp;quot;|0100mmmm&lt;br /&gt;
|Output pixel at relative position -''m'', then second pixel of last duplet.&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;font-family:monospace&amp;quot;|0x50&lt;br /&gt;
|style=&amp;quot;font-family:monospace&amp;quot;|0x50 p1 p2&lt;br /&gt;
|Output two absolute pixel values, ''p1'' and ''p2''.&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;font-family:monospace&amp;quot;|0x51-0x57&lt;br /&gt;
|style=&amp;quot;font-family:monospace&amp;quot;|01010mmm p&lt;br /&gt;
|Output pixel at relative position -''m'', then absolute pixel value ''p''.&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;font-family:monospace&amp;quot;|0x59-0x5f&lt;br /&gt;
|style=&amp;quot;font-family:monospace&amp;quot;|01011mmm p&lt;br /&gt;
|Output absolute pixel value ''p'', then pixel at relative position -''m''.&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;font-family:monospace&amp;quot;|0x60-0x6f&lt;br /&gt;
|style=&amp;quot;font-family:monospace&amp;quot;|0110xxxx p&lt;br /&gt;
|Output absolute pixel value ''p'', then (second pixel of last duplet) + ''x''.&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;font-family:monospace&amp;quot;|0x70-0x7f&lt;br /&gt;
|style=&amp;quot;font-family:monospace&amp;quot;|0111xxxx p&lt;br /&gt;
|Output absolute pixel value ''p'', then (second pixel of last duplet) - ''x''.&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;font-family:monospace&amp;quot;|0x80-0x8f&lt;br /&gt;
|style=&amp;quot;font-family:monospace&amp;quot;|1000xxxx&lt;br /&gt;
|Repeat last duplet adding ''x'' to the first pixel.&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;font-family:monospace&amp;quot;|0x90-0x9f&lt;br /&gt;
|style=&amp;quot;font-family:monospace&amp;quot;|1001xxxx p&lt;br /&gt;
|Output (first pixel of last duplet) + ''x'', then absolute pixel value ''p''.&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;font-family:monospace&amp;quot;|0xa0&lt;br /&gt;
|style=&amp;quot;font-family:monospace&amp;quot;|0xa0 xxxxyyyy&lt;br /&gt;
|Repeat last duplet, adding ''x'' to the first pixel and ''y'' to the second.&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;font-family:monospace&amp;quot;|0xb0&lt;br /&gt;
|style=&amp;quot;font-family:monospace&amp;quot;|0xb0 xxxxyyyy&lt;br /&gt;
|Repeat last duplet, adding ''x'' to the first pixel and subtracting ''y'' from the second.&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;font-family:monospace&amp;quot;|0xc0-0xcf&lt;br /&gt;
|style=&amp;quot;font-family:monospace&amp;quot;|1100xxxx&lt;br /&gt;
|Repeat last duplet subtracting ''x'' from first pixel.&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;font-family:monospace&amp;quot;|0xd0-0xdf&lt;br /&gt;
|style=&amp;quot;font-family:monospace&amp;quot;|1101xxxx p&lt;br /&gt;
|Output (first pixel of last duplet) - ''x'', then absolute pixel value ''p''.&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;font-family:monospace&amp;quot;|0xe0&lt;br /&gt;
|style=&amp;quot;font-family:monospace&amp;quot;|0xe0 xxxxyyyy&lt;br /&gt;
|Repeat last duplet, subtracting ''x'' from first pixel and adding ''y'' to second.&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;font-family:monospace&amp;quot;|0xf0 and 0xff&lt;br /&gt;
|style=&amp;quot;font-family:monospace&amp;quot;|0xfx xxxxyyyy&lt;br /&gt;
|Repeat last duplet, subtracting ''x'' from first pixel and ''y'' from second.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== Subcommands, part 2: repeat operations =====&lt;br /&gt;
&lt;br /&gt;
Sometimes these repeat commands will try to copy more than what is available when the command is read. In those cases, the command repeats the available segment of data until the number of duplets needed is copied. Or, equivalently, the command starts copying data that it wrote earlier.&lt;br /&gt;
&lt;br /&gt;
{| border=1 cellpadding=4 cellspacing=0 style=&amp;quot;border:1px #000 solid;border-collapse:collapse;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background:#CCC&amp;quot;&lt;br /&gt;
! Command !! Byte pattern !! Action&lt;br /&gt;
|-&lt;br /&gt;
|various&lt;br /&gt;
|style=&amp;quot;font-family:monospace&amp;quot;|1x1xxxmm mmmmmmmm&lt;br /&gt;
|&lt;br /&gt;
{| border=1 cellspacing=0 style=&amp;quot;float:right;border:none;border-collapse:collapse;padding:0px 3px;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background:#CCC&amp;quot;&lt;br /&gt;
! Command !! n !! r&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;font-family:monospace&amp;quot;|0xa4&amp;amp;nbsp;-&amp;amp;nbsp;0xa7||2||0&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;font-family:monospace&amp;quot;|0xa8 - 0xab||2||1&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;font-family:monospace&amp;quot;|0xac - 0xaf||3||0&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;font-family:monospace&amp;quot;|0xb4 - 0xb7||3||1&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;font-family:monospace&amp;quot;|0xb8 - 0xbb||4||0&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;font-family:monospace&amp;quot;|0xbc - 0xbf||4||1&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;font-family:monospace&amp;quot;|0xe4 - 0xe7||5||0&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;font-family:monospace&amp;quot;|0xe8 - 0xeb||5||1&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;font-family:monospace&amp;quot;|0xec - 0xef||6||0&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;font-family:monospace&amp;quot;|0xf4 - 0xf7||6||1&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;font-family:monospace&amp;quot;|0xf8 - 0xfb||7||0&lt;br /&gt;
|}&lt;br /&gt;
Repeat n duplets from relative position -''m'' (given in pixels, not duplets). If ''r'' is 0, another byte follows and the last pixel is set to that value. ''n'' and ''r'' come from the table on the right.&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;font-family:monospace&amp;quot;|0xfc&lt;br /&gt;
|style=&amp;quot;font-family:monospace&amp;quot;|0xfc nnnnnrmm mmmmmmmm (p)&lt;br /&gt;
|Repeat n+2 duplets from relative position -''m'' (given in pixels, not duplets). If ''r'' is 0, another byte ''p'' follows and the last pixel is set to absolute value ''p''.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Secondary Decompression ===&lt;br /&gt;
In all Riven images, and some other images, there is no secondary decompression. Instead, the remaining data is just the pixels. For 24bpp images, the pixels are in BGR order. For 8bpp images, there are ''bytes per row'' pixels, so you will have to cut off the remaining bytes at the end of the data (''bytes per row'' - ''bitmap width'').&lt;br /&gt;
&lt;br /&gt;
However, many non-Riven images use the RLE8 compression.&lt;br /&gt;
&lt;br /&gt;
==== RLE8 Compression ====&lt;br /&gt;
The RLE8 compression is a rather simple form of RLE. The decoder works by decoding one row at a time, so there will be ''bitmap height'' chunks of data. Each chunk '''''always''''' decodes one row of data. &lt;br /&gt;
&lt;br /&gt;
Per Row:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;structure&amp;quot;&lt;br /&gt;
|unsigned short||byte_count&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* ''byte_count'' is the amount of bytes that will be used to decode the current row.&lt;br /&gt;
&lt;br /&gt;
The ''byte_count'' should be ignored until later. Until you have completed a row's length of pixels, you must continue decompressing the RLE data.&lt;br /&gt;
&lt;br /&gt;
Each RLE command starts with a byte. The high bit of the data represents whether or not to repeat a pixel or output direct pixels. The bottom 7 bits are the ''run_length'' minus one.&lt;br /&gt;
&lt;br /&gt;
If the high bit is set, read in another byte which represents the pixel to repeat and then output the pixel ''run_length'' times. If the high bit is not set, output ''run_length'' absolute pixels from the input stream.&lt;br /&gt;
&lt;br /&gt;
Once you have outputted the correct amount of pixels, you should move ''byte_count'' bytes from the start of the row in the compressed stream.&lt;/div&gt;</summary>
		<author><name>Tahg</name></author>	</entry>

	<entry>
		<id>http://insidethelink.ortiche.net/wiki/index.php/Riven_debug_shell</id>
		<title>Riven debug shell</title>
		<link rel="alternate" type="text/html" href="http://insidethelink.ortiche.net/wiki/index.php/Riven_debug_shell"/>
				<updated>2009-06-08T00:08:23Z</updated>
		
		<summary type="html">&lt;p&gt;Tahg: fixed help command&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The original Riven engine features a built-in debug shell with useful capabilities.&lt;br /&gt;
&lt;br /&gt;
It can be activated by typing the string b3hn in the game and then pressing ctrl+tab. A green prompt should appear in the bottom left corner of the game window. This prompt accepts several commands, listed below. After each command the prompt disappears, but it comes out again by just pressing ctrl+tab.&lt;br /&gt;
&lt;br /&gt;
* g &amp;lt;id&amp;gt;: go to card &amp;lt;id&amp;gt;&lt;br /&gt;
* gc &amp;lt;id&amp;gt;: go to card, using its RMAP identifier&lt;br /&gt;
* gs &amp;lt;stack&amp;gt; [&amp;lt;id&amp;gt;]: go to stack &amp;lt;stack&amp;gt; (e.g. tspit) and to card &amp;lt;id&amp;gt;, if specified&lt;br /&gt;
* get &amp;lt;variable&amp;gt;: get the value of a variable&lt;br /&gt;
* set &amp;lt;variable&amp;gt; &amp;lt;value&amp;gt;: set the value of a variable&lt;br /&gt;
* undo: undoes actions on cur card (autosave must be enabled)&lt;br /&gt;
* enable &amp;lt;id&amp;gt;: enable an hotspot&lt;br /&gt;
* disable &amp;lt;id&amp;gt;: disable an hotspot&lt;br /&gt;
* p: purges all purgeable blocks&lt;br /&gt;
* c: compacts entire heap&lt;br /&gt;
* pc: purges, then compacts&lt;br /&gt;
* mem: returns total free memory&lt;br /&gt;
* free: returns physical free memory (excludes virtual)&lt;br /&gt;
* debug: toggles a line with useful debug info&lt;br /&gt;
* hs: toggle hotspot display&lt;br /&gt;
* autosave: toggles autosave-every-card feature&lt;br /&gt;
* dump: saves the current card picture to a bmp file&lt;br /&gt;
* ipmm: toggles impatient PM mode&lt;br /&gt;
* slideshow: show the images from b2_data.mhk with captions&lt;br /&gt;
* pleh: shows the list of commands available (They don't make this easy do they)&lt;br /&gt;
&lt;br /&gt;
See also the [http://www.mystcommunity.com/board/lofiversion/index.php/t19142.html original source].&lt;/div&gt;</summary>
		<author><name>Tahg</name></author>	</entry>

	<entry>
		<id>http://insidethelink.ortiche.net/wiki/index.php/Riven_VARS_resources</id>
		<title>Riven VARS resources</title>
		<link rel="alternate" type="text/html" href="http://insidethelink.ortiche.net/wiki/index.php/Riven_VARS_resources"/>
				<updated>2009-06-05T13:37:18Z</updated>
		
		<summary type="html">&lt;p&gt;Tahg: updated type field&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt;{{Riven}}&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
The VARS resource is found in Riven saved game files (there is just one). It stores the state of every game variable. The data is just an array of 12-byte records, each representing a variable, with this structure:&lt;br /&gt;
{| class=&amp;quot;structure&amp;quot;&lt;br /&gt;
|unsigned long||u0||&lt;br /&gt;
|-&lt;br /&gt;
|unsigned long||type||class=&amp;quot;comment&amp;quot;|0 = unknown, 1 = integer&lt;br /&gt;
|-&lt;br /&gt;
|unsigned long||value||class=&amp;quot;comment&amp;quot;|Saved variable value&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
''u0'' starts from 2, and seems to grow when going on with the game.&lt;br /&gt;
&lt;br /&gt;
Fortunately, saved games contain a [[Riven NAME resources|NAME]] resource that labels most variables in the VARS resource. The VARS record index simply matches the NAME one.&lt;br /&gt;
&lt;br /&gt;
The number of records is not constant. If you save different games in different places then new records will appear, usually with ''u1'' = 0 and strange values. However, &amp;quot;known&amp;quot; variables (dome combination, telescope levers state etc) are always at the same record.&lt;/div&gt;</summary>
		<author><name>Tahg</name></author>	</entry>

	<entry>
		<id>http://insidethelink.ortiche.net/wiki/index.php/Riven_scripts</id>
		<title>Riven scripts</title>
		<link rel="alternate" type="text/html" href="http://insidethelink.ortiche.net/wiki/index.php/Riven_scripts"/>
				<updated>2009-05-23T17:19:00Z</updated>
		
		<summary type="html">&lt;p&gt;Tahg: /* Command 18: transition */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Riven}}&lt;br /&gt;
This document talks about the Riven scripting protocol.&lt;br /&gt;
&lt;br /&gt;
==Overview and main data structures==&lt;br /&gt;
The Riven engine is programmed using ''scripts'' attached to objects. The architecture resembles the HyperCard philosophy. A script is subdivided in ''handlers''; each handler is associated to an event which may happen to the script's object and it contains the actions to be executed when that event happens. The actions are described by a list of ''commands''. Cards and hotspots are the only entities with attached scripts.&lt;br /&gt;
&lt;br /&gt;
A script is represented by this data block:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;structure&amp;quot;&lt;br /&gt;
|unsigned short||handler_count&lt;br /&gt;
|-&lt;br /&gt;
|variable size||handler list&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Each handler is made of this block:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;structure&amp;quot;&lt;br /&gt;
|unsigned short||event_type&lt;br /&gt;
|-&lt;br /&gt;
|unsigned short||cmd_count&lt;br /&gt;
|-&lt;br /&gt;
|variable size||command list&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The following table gives event types identified until now. Types 0 ... 5 are reserved to hotspots, 6 ... 10 are reserved to cards.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;Handlers&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
{| border=1 cellpadding=4 cellspacing=0 style=&amp;quot;border:1px #000 solid;border-collapse:collapse;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background:#CCC&amp;quot;&lt;br /&gt;
! event_type !! Event name !! What happened&lt;br /&gt;
|-&lt;br /&gt;
|0||Mouse down||Mouse button pressed inside the hotspot rect&lt;br /&gt;
|-&lt;br /&gt;
|1||Mouse still down||Mouse button down, sent to last pressed hotspot (never seen in the game)&lt;br /&gt;
|-&lt;br /&gt;
|2||Mouse up||Mouse button released inside the hotspot rect&lt;br /&gt;
|-&lt;br /&gt;
|3||Mouse enter||Mouse entered the hotspot rect (never seen in the game)&lt;br /&gt;
|-&lt;br /&gt;
|4||Mouse within||Mouse held inside the hotspot rect (the event is sent repeatedly)&lt;br /&gt;
|-&lt;br /&gt;
|5||Mouse leave||Mouse left the hotspot rect&lt;br /&gt;
|-&lt;br /&gt;
|6||Load card||Card &amp;quot;loaded&amp;quot;. This is the first event sent to a card. Usually cards enable things here. Screen updates are disabled during the execution of this handler, and the display is updated at the end.&lt;br /&gt;
|-&lt;br /&gt;
|7||Close card||Leaving card.&lt;br /&gt;
|-&lt;br /&gt;
|9||Open card||Card opened. This is sent at the end, when the card has been loaded and the display has been updated. Usually cards start movies and ambient sounds here.&lt;br /&gt;
|-&lt;br /&gt;
|10||Display update||Display being updated; for example this event is triggered when the handler for event 6 completes, or by [[#Command 21: enable screen update|command 21]]. The handler is executed before actually updating the display.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In general, each command is an opcode followed by a number of arguments. The same command can be passed a variable number of arguments, though only a few commands actually behave like that. The general structure is:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;structure&amp;quot;&lt;br /&gt;
|unsigned short||cmd&lt;br /&gt;
|-&lt;br /&gt;
|unsigned short||arg_count&lt;br /&gt;
|-&lt;br /&gt;
|unsigned short||args[arg_count]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The following subsections explain what has been discovered about each command. Unlisted opcodes have never been observed in Riven.&lt;br /&gt;
&lt;br /&gt;
==Command 1: draw tBMP resource==&lt;br /&gt;
*'''Argument count:''' 9&lt;br /&gt;
*'''Arguments:''' ''tbmp_id left top right bottom u0 u1 u2 u3''&lt;br /&gt;
&lt;br /&gt;
Draw bitmap from tBMP resource ''tbmp_id'' inside the rectangle described by ''left'', ''top'', ''right'', ''bottom''. If the rectangle dimensions do not match the bitmap size, the bitmap will be attached to the top-left corner and clipped to the rectangle. Other arguments are always zero and seem ignored by the engine.&lt;br /&gt;
&lt;br /&gt;
The command will automatically update the display unless [[#Command 20: disable screen update|command 20]] was used before.&lt;br /&gt;
&lt;br /&gt;
Despite its power, command 1 is used on a few scripts only.&lt;br /&gt;
&lt;br /&gt;
==Command 2: go to card==&lt;br /&gt;
*'''Argument count:''' 1&lt;br /&gt;
*'''Arguments:''' ''id''&lt;br /&gt;
&lt;br /&gt;
Go to card ''id''. In most cases this command is used in very short hotspot scripts containing just a transition command followed by the &amp;quot;go to card&amp;quot; one. In these cases, the following event chain takes place:&lt;br /&gt;
*the old card receives [[#Handlers|event 7]];&lt;br /&gt;
*the new card receives event 6;&lt;br /&gt;
*the new card receives event 10 (because the display is begin updated);&lt;br /&gt;
*the transition effect is played and the new card image is displayed;&lt;br /&gt;
*the new card receives event 9.&lt;br /&gt;
&lt;br /&gt;
However, it is also used in card event handlers, like 9 or 10. Sometimes it appears multiple times in the same script. The event sequence for these complicated cases is not yet fully understood.&lt;br /&gt;
&lt;br /&gt;
==Command 3: activate inline SLST record==&lt;br /&gt;
*'''Argument count:''' variable&lt;br /&gt;
*'''Arguments:''' ''N ids[N] fade_flags loop volume u0 u1 volumes[N] balances[N] u2[N]''&lt;br /&gt;
&lt;br /&gt;
This command is basically an inline [[Riven SLST resources|SLST]] resource record. All referenced sound resources should be looked-up in the current stack's sound archives. The resulting sound group is made current, as if [[#Command 40: activate SLST record |command 40]] had been used.&lt;br /&gt;
&lt;br /&gt;
==Command 4: play local tWAV resource==&lt;br /&gt;
*'''Argument count:''' 3&lt;br /&gt;
*'''Arguments:''' ''id volume u1''&lt;br /&gt;
&lt;br /&gt;
Play tWAV resource ''id'' from the Mohawk archive containing the script. ''volume'' seems always 256, ''u1'' always 0. This command has no effect on the active ambient sound group; the sound is mixed with the ambient sounds.&lt;br /&gt;
&lt;br /&gt;
==Command 7: set variable value==&lt;br /&gt;
*'''Argument count:''' 2&lt;br /&gt;
*'''Arguments:''' ''var value''&lt;br /&gt;
&lt;br /&gt;
Set variable ''var'' to value ''value''.&lt;br /&gt;
&lt;br /&gt;
==Command 8: conditional branch==&lt;br /&gt;
This doesn't follow the ''command arg_count'' args scheme. It's similar to a C &amp;quot;switch&amp;quot; statement: given a variable, there is a list of possible variable values and a corresponding command list to be executed. The structure of command 8 is:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;structure&amp;quot;&lt;br /&gt;
|unsigned short||8&lt;br /&gt;
|-&lt;br /&gt;
|unsigned short||2&lt;br /&gt;
|-&lt;br /&gt;
|unsigned short||var&lt;br /&gt;
|-&lt;br /&gt;
|unsigned short||value_count&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Then ''value_count'' blocks follow, each with this structure:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;structure&amp;quot;&lt;br /&gt;
|unsigned short||value&lt;br /&gt;
|-&lt;br /&gt;
|unsigned short||command_count&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot; style=&amp;quot;color:#000&amp;quot;|commands to execute if var contains value&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
If ''value'' is 0xffff, the block is the &amp;quot;default&amp;quot; block exactly like in the C statement. As an example, let's compare the script syntax with a C-like switch statement:&lt;br /&gt;
{| align=&amp;quot;center&amp;quot; valign=&amp;quot;center&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
 0008 0002 beef 3&lt;br /&gt;
   0001 0001&lt;br /&gt;
     a&lt;br /&gt;
   0002 0001&lt;br /&gt;
     b&lt;br /&gt;
   ffff 0002&lt;br /&gt;
     c&lt;br /&gt;
     d&lt;br /&gt;
|&lt;br /&gt;
 switch (variable 0xbeef) {&lt;br /&gt;
   case 1:&lt;br /&gt;
     a;&lt;br /&gt;
     break;&lt;br /&gt;
   case 2:&lt;br /&gt;
     b;&lt;br /&gt;
     break;&lt;br /&gt;
   default:&lt;br /&gt;
     c;&lt;br /&gt;
     d;&lt;br /&gt;
     break;&lt;br /&gt;
 }&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The conditional branch command is used on levers, switches and every place where a variable value makes the difference. It's often used as a simple if-then-else mechanism.&lt;br /&gt;
&lt;br /&gt;
==Command 9: enable hotspot==&lt;br /&gt;
*'''Argument count:''' 1&lt;br /&gt;
*'''Arguments:''' ''hotspot_id''&lt;br /&gt;
&lt;br /&gt;
Enable card hotspot with the specified ''hotspot_id''.&lt;br /&gt;
&lt;br /&gt;
==Command 10: disable hotspot==&lt;br /&gt;
*'''Argument count:''' 1&lt;br /&gt;
*'''Arguments:''' ''hotspot_id''&lt;br /&gt;
&lt;br /&gt;
Disable card hotspot with the specified ''hotspot_id''. A disabled hotspot will not respond to events.&lt;br /&gt;
&lt;br /&gt;
==Command 12==&lt;br /&gt;
*'''Argument count:''' 1&lt;br /&gt;
*'''Arguments:''' ''u0''&lt;br /&gt;
&lt;br /&gt;
Unknown. ''u0'' is 0, 1 or 2. This command is used only a few times, for example near &amp;quot;go to stack&amp;quot; commands like in the &amp;quot;play riven&amp;quot; button. It doesn't seem related to anything special (e.g. movies or sounds). Setting ''u0'' to some other value or replacing the command with others doesn't produce readily observable effects. I suspect it has something to do with variables, but I have yet to realize how to check this.&lt;br /&gt;
==Command 13: set mouse cursor==&lt;br /&gt;
[[Image:Cursors.png|right|frame|Riven cursor icons and their IDs]]&lt;br /&gt;
*'''Argument count:''' 1&lt;br /&gt;
*'''Arguments:''' ''cursor''&lt;br /&gt;
&lt;br /&gt;
Set mouse cursor icon to ''cursor'', whose meaning is given on the right.&lt;br /&gt;
&lt;br /&gt;
==Command 14: pause script execution==&lt;br /&gt;
*'''Argument count:''' 2&lt;br /&gt;
*'''Arguments:''' ms ''u0''&lt;br /&gt;
&lt;br /&gt;
Pause script execution for ''ms'' milliseconds. ''ms'' is signed and the pause is effective only if ''ms'' &amp;gt; 0. ''u0'' is always 0 and its value seems ignored by the engine.&lt;br /&gt;
&lt;br /&gt;
==Command 17: call external command==&lt;br /&gt;
*'''Argument count:''' variable, at least 2&lt;br /&gt;
*'''Arguments:''' ''cmd count arg1 arg2 ...''&lt;br /&gt;
&lt;br /&gt;
Call an external piece of custom code (&amp;quot;external command&amp;quot;), which is probably hardcoded inside the Riven executable. ''cmd'' tells which external command to call, and ''count'' tells how many arguments to pass to it. Then ''count'' arguments follow. [[Riven NAME resources|NAME]] resource 3 contains the name of each external command: ''cmd'' is the corresponding NAME record index. See the [[Riven external commands|external command list]] for more info on external commands.&lt;br /&gt;
&lt;br /&gt;
==Command 18: transition==&lt;br /&gt;
*'''Argument count:''' 1 or 5&lt;br /&gt;
*'''Arguments:''' ''code [left top right bottom]''&lt;br /&gt;
&lt;br /&gt;
Schedule a transition effect described by ''code'' (see below for what code means). The transition will actually play when a display update occurs, for example with [[#Command 21: enable screen update|command 21]], [[#Command 39: activate PLST record|39]] or after going to another card (it doesn't seem to work for [[#Command 1: draw tBMP resource|command 1]], however). The optional 4 args ''left'', ''top'', ''right'', and ''bottom'' specify a clip rectangle in pixels, but are never really used in the game.&lt;br /&gt;
&lt;br /&gt;
{| border=1 cellpadding=4 cellspacing=0 style=&amp;quot;border:1px #000 solid;border-collapse:collapse;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background:#CCC&amp;quot;&lt;br /&gt;
! !!width=&amp;quot;19%&amp;quot;|Left!!width=&amp;quot;19%&amp;quot;|Right!!width=&amp;quot;19%&amp;quot;|Up!!width=&amp;quot;19%&amp;quot;|Down&lt;br /&gt;
|-&lt;br /&gt;
!style=&amp;quot;background:#CCC&amp;quot;|Wipe||0||1||2||3&lt;br /&gt;
|-&lt;br /&gt;
!style=&amp;quot;background:#CCC&amp;quot;|Scroll||4||5||6||7&lt;br /&gt;
|-&lt;br /&gt;
!style=&amp;quot;background:#CCC&amp;quot;|Scroll Away||8||9||10||11&lt;br /&gt;
|-&lt;br /&gt;
!style=&amp;quot;background:#CCC&amp;quot;|Pan||12||13||14||15&lt;br /&gt;
|-&lt;br /&gt;
!style=&amp;quot;background:#CCC&amp;quot;|Blend||colspan=&amp;quot;4&amp;quot;|16, 17(only seen on t_data, CARD 155)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
Types 0 - 15 are various types of scrolling. Bits 0 and 1 control the direction (0=left, 1=right, 2=top, 3=bottom); bit 2 tells if the new image should move (1) or stay fixed (0); bit 3 tells if the old image should move or stay fixed.&lt;br /&gt;
Riven uses effects 0 to 3 internally for turning pages. It uses effects 12 to 16 in scripts.  Effect 17 is the same case as effect 16.&lt;br /&gt;
&lt;br /&gt;
==Command 19: reload card==&lt;br /&gt;
*'''Argument count:''' 0&lt;br /&gt;
&lt;br /&gt;
Refreshes the card, behaving like a &amp;quot;go to &amp;lt;current card&amp;gt;&amp;quot; command. The full handler sequence is executed (see command 2). Often used to update the card display after an hotspot script has altered a variable.&lt;br /&gt;
&lt;br /&gt;
==Command 20: disable screen update==&lt;br /&gt;
*'''Argument count:''' 0&lt;br /&gt;
&lt;br /&gt;
This seems to disable the automatic display update for commands [[#Command 1: draw tBMP resource|1]] and [[#Command 39: activate PLST record|39]]. It doesn't work like a &amp;quot;toggle&amp;quot; command: using it multiple times won't re-enable the automatic update (it is re-enabled by command 21 instead). Its effect persists even after the script ends (extending to any successive script, e.g. hotspot ones) but is reset on card switches. Command 20 often precedes [[#Command 18: transition|command 18]].&lt;br /&gt;
&lt;br /&gt;
==Command 21: enable screen update==&lt;br /&gt;
*'''Argument count:''' 0&lt;br /&gt;
&lt;br /&gt;
This seems the opposite of [[#Command 20: disable screen update|command 20]]: it re-enables the automatic display update for commands [[#Command 1: draw tBMP resource|1]] and [[#Command 39: activate PLST record|39]], triggers [[#Handlers|event 10]], updates the display and plays the transition effect if one was scheduled before.&lt;br /&gt;
&lt;br /&gt;
Command 21 shows inconsistent behavior if used alone (sometimes it updates the display, sometimes it doesn't, sometimes it skips the transition, etc.); the correct way of using commands 20 and 21 seems to be the following construct, which is also what is usually found in scripts:&lt;br /&gt;
#disable screen update&lt;br /&gt;
#schedule transition&lt;br /&gt;
#activate [[PLST]] records / draw [[tBMP]] resources&lt;br /&gt;
#enable screen update&lt;br /&gt;
&lt;br /&gt;
This construct will compose a final picture (by overlaying the specified PLST records and tBMP bitmaps, in the same order as they appear in the script) and then play the specified transition effect from the previously displayed picture to the new one. Note that such a complex effect wouldn't be possible without commands 20/21.&lt;br /&gt;
&lt;br /&gt;
==Command 24: increment variable==&lt;br /&gt;
*'''Argument count:''' 2&lt;br /&gt;
*'''Arguments:''' ''var value''&lt;br /&gt;
&lt;br /&gt;
Add ''value'' to variable ''var''.&lt;br /&gt;
&lt;br /&gt;
==Command 27: go to stack==&lt;br /&gt;
*'''Argument count:''' 3&lt;br /&gt;
*'''Arguments:''' ''stack_name code_hi code_lo''&lt;br /&gt;
&lt;br /&gt;
Go to another stack. The destination stack is specified by ''stack_name''; you get the actual stack name string by looking up record ''stack_name'' in [[Riven NAME resources|NAME]] resource 5. The destination card is specified through ''code_hi'' (higher 16 bytes) and ''code_lo'' (lower 16 bytes) which together form an unsigned long [[Riven RMAP resources|RMAP]] card code.&lt;br /&gt;
&lt;br /&gt;
==Command 28==&lt;br /&gt;
*'''Argument count:''' 1&lt;br /&gt;
*'''Arguments:''' ''code''&lt;br /&gt;
&lt;br /&gt;
Unknown. It should have something to do with movies: it comes almost always after [[#Command 32: play foreground movie|command 32]] with the same argument. However, changing code or even removing the command itself seem to have no effect neither on the movie nor on anything else. Maybe it purges the memory used by the movie or something like that.&lt;br /&gt;
&lt;br /&gt;
==Command 29==&lt;br /&gt;
*'''Argument count:''' 0&lt;br /&gt;
&lt;br /&gt;
Unknown. Seems related to movies since in most cases it comes after [[#Command 32: play foreground movie|command 32]]. Used quite rarely.&lt;br /&gt;
==Command 31==&lt;br /&gt;
*'''Argument count:''' 1&lt;br /&gt;
*'''Arguments:''' ''code''&lt;br /&gt;
&lt;br /&gt;
Unknown. Should have something to do with movies, it comes often before [[#Command 33: play background movie|command 33]] with the same argument. Changing code seems to have no effect.&lt;br /&gt;
&lt;br /&gt;
==Command 32: play foreground movie==&lt;br /&gt;
*'''Argument count:''' 1&lt;br /&gt;
*'''Arguments:''' ''code''&lt;br /&gt;
&lt;br /&gt;
Play a movie listed in the [[Riven MLST resources|MLST]] resource, blocking the script execution until movie ends. code matches the code field of the MLST record that should be played. The MLST record must be first enabled with [[#Command 46: activate MLST record|command 46]], otherwise some other random movie will play instead (or nothing will happen at all). If multiple records have that code value, one will be chosen randomly, I guess. Sometimes this command follows [[#Command 33: play background movie|command 33]] with the same parameter: probably it just means &amp;quot;wait until the movie ends&amp;quot; in that case.&lt;br /&gt;
&lt;br /&gt;
==Command 33: play background movie==&lt;br /&gt;
*'''Argument count:''' 1&lt;br /&gt;
*'''Arguments:''' ''code''&lt;br /&gt;
&lt;br /&gt;
Start a &amp;quot;background&amp;quot; movie from [[Riven MLST resources|MLST]] record with specified code. Script execution will go on (and eventually terminate) while the movie is playing. Often this command follows [[#Command 31|command 31]]. The MLST record must be first enabled with [[#Command 46: activate MLST record|command 46]], otherwise some other random movie will play instead.&lt;br /&gt;
&lt;br /&gt;
==Command 34==&lt;br /&gt;
*'''Argument count:''' 1&lt;br /&gt;
*'''Arguments:''' ''u0''&lt;br /&gt;
&lt;br /&gt;
Unknown. ''u0'' is always 1.&lt;br /&gt;
&lt;br /&gt;
==Command 36==&lt;br /&gt;
*'''Argument count:''' 0&lt;br /&gt;
&lt;br /&gt;
Unknown.&lt;br /&gt;
&lt;br /&gt;
==Command 37==&lt;br /&gt;
*'''Argument count:''' 0&lt;br /&gt;
&lt;br /&gt;
Unknown.&lt;br /&gt;
&lt;br /&gt;
==Command 38==&lt;br /&gt;
*'''Argument count:''' 5&lt;br /&gt;
*'''Arguments:''' ''u1 u2 u3 u4 u5''&lt;br /&gt;
&lt;br /&gt;
Unknown, but should have something to do with movies. ''u1'' seems to refer to a [[Riven MLST resources|MLST]] record code, ''u5'' seems to be a [[Riven SLST resources|SLST]] record index and ''u4'' seems always 40. ''u2'' and ''u3'' seem to form a 32-bit value set to large numbers (4000, 9000...), which I suspect are milliseconds.&lt;br /&gt;
&lt;br /&gt;
This command seems to perform complex actions: if ''u4'' is changed to 0, ''u5'' is interpreted instead as a [[Riven tBMP resources|tBMP]] resource ID and that bitmap is drawn right after the movie.&lt;br /&gt;
&lt;br /&gt;
==Command 39: activate PLST record==&lt;br /&gt;
*'''Argument count:''' 1&lt;br /&gt;
*'''Arguments:''' ''record''&lt;br /&gt;
&lt;br /&gt;
Activate the specified record in the [[Riven PLST resources|PLST]] resource, making one of the card bitmaps visible. The actual screen update takes place immediately (with a transition effect, if one was scheduled before) unless [[#Command 20: disable screen update|command 20]] was used before or the command is called from [[#Handlers|handlers 6 or 10]].&lt;br /&gt;
&lt;br /&gt;
==Command 40: activate SLST record==&lt;br /&gt;
*'''Argument count:''' 1&lt;br /&gt;
*'''Arguments:''' ''record''&lt;br /&gt;
&lt;br /&gt;
Activate the specified [[Riven SLST resources|SLST]] record. A SLST record describes an ambient sound group. The Riven engine can only have one active sound group at any given time (henceforth the &amp;quot;active ambient sound group&amp;quot;). This command sets the active ambient sound group to the specified SLST record. Appropriate fading in and fading out actions are taken based on the SLST record's fade flags. Activating the active ambient sound group has no effect.&lt;br /&gt;
&lt;br /&gt;
==Command 41==&lt;br /&gt;
*'''Argument count:''' 1&lt;br /&gt;
*'''Arguments:''' ''u0''&lt;br /&gt;
&lt;br /&gt;
Unknown. Should have something to do with movies because it comes often before [[#Command 32: play foreground movie|command 32]] with the same argument. A hypothesis is that it activates a [[Riven MLST resources|MLST]] record like [[#Command 46: activate MLST record|46]], but using its code field rather than the MLST record index.&lt;br /&gt;
==Command 43: activate BLST record==&lt;br /&gt;
*'''Argument count:''' 1&lt;br /&gt;
*'''Arguments:''' ''record''&lt;br /&gt;
&lt;br /&gt;
Activate the specified record in the [[Riven BLST resources|BLST]] resource, so enable or disable one of the card hotspots (depending on the record info).&lt;br /&gt;
&lt;br /&gt;
==Command 44: activate FLST record==&lt;br /&gt;
*'''Argument count:''' 1&lt;br /&gt;
*'''Arguments:''' ''record''&lt;br /&gt;
&lt;br /&gt;
Activate the specified record in the [[Riven FLST resources|FLST]] resource, so enable a realtime [[Riven SFXE resources|SFXE]] effect.&lt;br /&gt;
&lt;br /&gt;
==Command 45: do zip mode==&lt;br /&gt;
*'''Argument count:''' 0&lt;br /&gt;
&lt;br /&gt;
Find the correct [[Riven ZIPS resources|ZIPS]] record using the hotspot name, get the destination card from the found record and go to that card. Though likely, this behavior has not been confirmed yet.&lt;br /&gt;
&lt;br /&gt;
==Command 46: activate MLST record==&lt;br /&gt;
*'''Argument count:''' 2&lt;br /&gt;
*'''Arguments:''' ''record u0''&lt;br /&gt;
&lt;br /&gt;
Activate the specified record in the [[Riven MLST resources|MLST]] resource. This command won't actually start the movie; it will only &amp;quot;enable&amp;quot; it for later playing. ''u0'' seems 0 or 1 if the movie is to be played once or looped forever, respectively. This is redundant, since the same info can be found in the MLST record; moreover, ''u0'' seems to be ignored by the engine.&lt;/div&gt;</summary>
		<author><name>Tahg</name></author>	</entry>

	<entry>
		<id>http://insidethelink.ortiche.net/wiki/index.php/Riven_engine_overview</id>
		<title>Riven engine overview</title>
		<link rel="alternate" type="text/html" href="http://insidethelink.ortiche.net/wiki/index.php/Riven_engine_overview"/>
				<updated>2009-05-23T00:19:46Z</updated>
		
		<summary type="html">&lt;p&gt;Tahg: added trap book card switch&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Riven}}&lt;br /&gt;
&lt;br /&gt;
A Riven scenario is made of virtual objects called ''stacks'' and each stack is a list of virtual objects called ''cards''. This may remember HyperCard: it's the same approach. Each card has an associated ''script'', a sequence of commands to be executed in response of events happening to the card (for example, card creation). The player interacts with the game by means of invisible buttons, placed within cards and called ''hotspots''. Hotspots have associated scripts too, responding to events different than cards (for example, mouse clicks). Within cards can also be placed bitmaps and movies. Finally, sounds can be played.&lt;br /&gt;
&lt;br /&gt;
Riven stacks are named&lt;br /&gt;
*aspit (main menu, books, setup screens)&lt;br /&gt;
**a_Data.mhk&lt;br /&gt;
**a_Sounds.mhk&lt;br /&gt;
*ospit (Gehn's office)&lt;br /&gt;
**o_Data.mhk&lt;br /&gt;
**o_Sounds.mhk&lt;br /&gt;
*pspit (prison island)&lt;br /&gt;
**p_Data.mhk&lt;br /&gt;
**p_Sounds.mhk&lt;br /&gt;
*gspit (garden island)&lt;br /&gt;
**g_Data.mhk&lt;br /&gt;
**g_Sounds.mhk&lt;br /&gt;
*rspit (rebel age)&lt;br /&gt;
**r_Data.mhk&lt;br /&gt;
**r_Sounds.mhk&lt;br /&gt;
*tspit (temple island).&lt;br /&gt;
**t_Data.mhk (Riven 5CD/Demo)&lt;br /&gt;
**t_Data1.mhk, t_Data2.mhk (Riven DVD)&lt;br /&gt;
**t_Sounds.mhk&lt;br /&gt;
*jspit (jungle island)&lt;br /&gt;
**j_Data.mhk (Riven Demo)&lt;br /&gt;
**j_Data1.mhk, j_Data2.mhk (Riven 5CD/DVD)&lt;br /&gt;
**j_Sounds.mhk&lt;br /&gt;
*bspit (boiler island)&lt;br /&gt;
**b_Data.mhk&lt;br /&gt;
**b_Sounds.mhk&lt;br /&gt;
&lt;br /&gt;
Physically, a stack is described by a set of data blocks called ''resources''. Resources are identified by a 4-char ''type'' and an integer ''ID''. Optionally they can also have a name, but it seems completely ignored by the engine. The resource type tells what kind of data is stored in the resource; see the [[Riven_resources|resource type list]] for types used in Riven.&lt;br /&gt;
&lt;br /&gt;
Resources belonging to a certain stack are archived inside an arbitrary number of [[Mohawk_archive_format|Mohawk files]] (listed above under their respective stacks). The file &amp;quot;riven.cfg&amp;quot; tells which files compose each stack by associating stack and file names.&lt;br /&gt;
&lt;br /&gt;
Saved games are Mohawk archives too, and they contain additional resource types as described in the [[Riven_resources|resource type list]].&lt;br /&gt;
&lt;br /&gt;
The Riven engine has a secret, interesting [[Riven_debug_shell|debug shell]].&lt;br /&gt;
&lt;br /&gt;
==Notes on stack switching==&lt;br /&gt;
The current stack can be changed from scripts using [[Riven scripts#Command 27: go to stack|script command 27]]. For example, when the player activates a MagLev, first the car movie is played, and then command 27 is called to change the current stack to the new island. This command is also used in the &amp;quot;Play Riven&amp;quot; button. However, most linking books actually change stack simply by moving to another card which has no buttons and no scripts. Apparently, there is some hardcoded mechanism inside the engine which triggers the stack change when one of these &amp;quot;special&amp;quot; cards is entered. These cards are listed here.&lt;br /&gt;
&lt;br /&gt;
=== CD Version ===&lt;br /&gt;
{| border=1 cellpadding=4 cellspacing=0 style=&amp;quot;border:1px #000 solid;border-collapse:collapse;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background:#CCC&amp;quot;&lt;br /&gt;
! Stack !! Card ID !! Target stack !! Target card&lt;br /&gt;
|-&lt;br /&gt;
|bspit||447||ospit||1&lt;br /&gt;
|-&lt;br /&gt;
|gspit||178||ospit||1&lt;br /&gt;
|-&lt;br /&gt;
|jspit||228||rspit||3&lt;br /&gt;
|-&lt;br /&gt;
|jspit||344||ospit||1&lt;br /&gt;
|-&lt;br /&gt;
|ospit||58||pspit||43&lt;br /&gt;
|-&lt;br /&gt;
|ospit||62||jspit||341&lt;br /&gt;
|-&lt;br /&gt;
|ospit||67||gspit||175&lt;br /&gt;
|-&lt;br /&gt;
|ospit||72||bspit||444&lt;br /&gt;
|-&lt;br /&gt;
|ospit||76||tspit||387&lt;br /&gt;
|-&lt;br /&gt;
|pspit||46||ospit||1&lt;br /&gt;
|-&lt;br /&gt;
|rspit||13||jspit||215&lt;br /&gt;
|-&lt;br /&gt;
|tspit||392||ospit||1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== DVD Version ===&lt;br /&gt;
{| border=1 cellpadding=4 cellspacing=0 style=&amp;quot;border:1px #000 solid;border-collapse:collapse;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background:#CCC&amp;quot;&lt;br /&gt;
! Stack !! Card ID !! Target stack !! Target card&lt;br /&gt;
|-&lt;br /&gt;
|aspit||8||ospit||9&lt;br /&gt;
|-&lt;br /&gt;
|bspit||447||ospit||1&lt;br /&gt;
|-&lt;br /&gt;
|gspit||178||ospit||1&lt;br /&gt;
|-&lt;br /&gt;
|jspit||228||rspit||3&lt;br /&gt;
|-&lt;br /&gt;
|jspit||343||ospit||1&lt;br /&gt;
|-&lt;br /&gt;
|ospit||58||pspit||43&lt;br /&gt;
|-&lt;br /&gt;
|ospit||62||jspit||340&lt;br /&gt;
|-&lt;br /&gt;
|ospit||67||gspit||175&lt;br /&gt;
|-&lt;br /&gt;
|ospit||72||bspit||444&lt;br /&gt;
|-&lt;br /&gt;
|ospit||76||tspit||393&lt;br /&gt;
|-&lt;br /&gt;
|pspit||46||ospit||1&lt;br /&gt;
|-&lt;br /&gt;
|rspit||13||jspit||215&lt;br /&gt;
|-&lt;br /&gt;
|tspit||398||ospit||1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Stack ID's in Saved Games ==&lt;br /&gt;
In saved games, the &amp;quot;[[Riven variables#currentstackid|currentstackid]]&amp;quot; variable holds what the current stack is by a number. This table shows what stack each number represents:&lt;br /&gt;
&lt;br /&gt;
{| border=1 cellpadding=4 cellspacing=0 style=&amp;quot;border:1px #000 solid;border-collapse:collapse;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background:#CCC&amp;quot;&lt;br /&gt;
! ID !! Stack&lt;br /&gt;
|-&lt;br /&gt;
|1||ospit&lt;br /&gt;
|-&lt;br /&gt;
|2||pspit&lt;br /&gt;
|-&lt;br /&gt;
|3||rspit&lt;br /&gt;
|-&lt;br /&gt;
|4||tspit&lt;br /&gt;
|-&lt;br /&gt;
|5||bspit&lt;br /&gt;
|-&lt;br /&gt;
|6||gspit&lt;br /&gt;
|-&lt;br /&gt;
|7||jspit&lt;br /&gt;
|-&lt;br /&gt;
|8||aspit&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Such association seems to be defined in the Riven.ini file, in particular from its &amp;quot;StackNumber&amp;quot; section.&lt;/div&gt;</summary>
		<author><name>Tahg</name></author>	</entry>

	<entry>
		<id>http://insidethelink.ortiche.net/wiki/index.php/Riven_scripts</id>
		<title>Riven scripts</title>
		<link rel="alternate" type="text/html" href="http://insidethelink.ortiche.net/wiki/index.php/Riven_scripts"/>
				<updated>2009-05-18T14:55:09Z</updated>
		
		<summary type="html">&lt;p&gt;Tahg: updated mouse events&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Riven}}&lt;br /&gt;
This document talks about the Riven scripting protocol.&lt;br /&gt;
&lt;br /&gt;
==Overview and main data structures==&lt;br /&gt;
The Riven engine is programmed using ''scripts'' attached to objects. The architecture resembles the HyperCard philosophy. A script is subdivided in ''handlers''; each handler is associated to an event which may happen to the script's object and it contains the actions to be executed when that event happens. The actions are described by a list of ''commands''. Cards and hotspots are the only entities with attached scripts.&lt;br /&gt;
&lt;br /&gt;
A script is represented by this data block:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;structure&amp;quot;&lt;br /&gt;
|unsigned short||handler_count&lt;br /&gt;
|-&lt;br /&gt;
|variable size||handler list&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Each handler is made of this block:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;structure&amp;quot;&lt;br /&gt;
|unsigned short||event_type&lt;br /&gt;
|-&lt;br /&gt;
|unsigned short||cmd_count&lt;br /&gt;
|-&lt;br /&gt;
|variable size||command list&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The following table gives event types identified until now. Types 0 ... 5 are reserved to hotspots, 6 ... 10 are reserved to cards.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;Handlers&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
{| border=1 cellpadding=4 cellspacing=0 style=&amp;quot;border:1px #000 solid;border-collapse:collapse;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background:#CCC&amp;quot;&lt;br /&gt;
! event_type !! Event name !! What happened&lt;br /&gt;
|-&lt;br /&gt;
|0||Mouse down||Mouse button pressed inside the hotspot rect&lt;br /&gt;
|-&lt;br /&gt;
|1||Mouse still down||Mouse button down, sent to last pressed hotspot (never seen in the game)&lt;br /&gt;
|-&lt;br /&gt;
|2||Mouse up||Mouse button released inside the hotspot rect&lt;br /&gt;
|-&lt;br /&gt;
|3||Mose enter||Mouse entered the hotspot rect (never seen in the game)&lt;br /&gt;
|-&lt;br /&gt;
|4||Mouse within||Mouse held inside the hotspot rect (the event is sent repeatedly)&lt;br /&gt;
|-&lt;br /&gt;
|5||Mouse leave||Mouse left the hotspot rect&lt;br /&gt;
|-&lt;br /&gt;
|6||Load card||Card &amp;quot;loaded&amp;quot;. This is the first event sent to a card. Usually cards enable things here. Screen updates are disabled during the execution of this handler, and the display is updated at the end.&lt;br /&gt;
|-&lt;br /&gt;
|7||Close card||Leaving card.&lt;br /&gt;
|-&lt;br /&gt;
|9||Open card||Card opened. This is sent at the end, when the card has been loaded and the display has been updated. Usually cards start movies and ambient sounds here.&lt;br /&gt;
|-&lt;br /&gt;
|10||Display update||Display being updated; for example this event is triggered when the handler for event 6 completes, or by [[#Command 21: enable screen update|command 21]]. The handler is executed before actually updating the display.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In general, each command is an opcode followed by a number of arguments. The same command can be passed a variable number of arguments, though only a few commands actually behave like that. The general structure is:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;structure&amp;quot;&lt;br /&gt;
|unsigned short||cmd&lt;br /&gt;
|-&lt;br /&gt;
|unsigned short||arg_count&lt;br /&gt;
|-&lt;br /&gt;
|unsigned short||args[arg_count]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The following subsections explain what has been discovered about each command. Unlisted opcodes have never been observed in Riven.&lt;br /&gt;
&lt;br /&gt;
==Command 1: draw tBMP resource==&lt;br /&gt;
*'''Argument count:''' 9&lt;br /&gt;
*'''Arguments:''' ''tbmp_id left top right bottom u0 u1 u2 u3''&lt;br /&gt;
&lt;br /&gt;
Draw bitmap from tBMP resource ''tbmp_id'' inside the rectangle described by ''left'', ''top'', ''right'', ''bottom''. If the rectangle dimensions do not match the bitmap size, the bitmap will be attached to the top-left corner and clipped to the rectangle. Other arguments are always zero and seem ignored by the engine.&lt;br /&gt;
&lt;br /&gt;
The command will automatically update the display unless [[#Command 20: disable screen update|command 20]] was used before.&lt;br /&gt;
&lt;br /&gt;
Despite its power, command 1 is used on a few scripts only.&lt;br /&gt;
&lt;br /&gt;
==Command 2: go to card==&lt;br /&gt;
*'''Argument count:''' 1&lt;br /&gt;
*'''Arguments:''' ''id''&lt;br /&gt;
&lt;br /&gt;
Go to card ''id''. In most cases this command is used in very short hotspot scripts containing just a transition command followed by the &amp;quot;go to card&amp;quot; one. In these cases, the following event chain takes place:&lt;br /&gt;
*the old card receives [[#Handlers|event 7]];&lt;br /&gt;
*the new card receives event 6;&lt;br /&gt;
*the new card receives event 10 (because the display is begin updated);&lt;br /&gt;
*the transition effect is played and the new card image is displayed;&lt;br /&gt;
*the new card receives event 9.&lt;br /&gt;
&lt;br /&gt;
However, it is also used in card event handlers, like 9 or 10. Sometimes it appears multiple times in the same script. The event sequence for these complicated cases is not yet fully understood.&lt;br /&gt;
&lt;br /&gt;
==Command 3: activate inline SLST record==&lt;br /&gt;
*'''Argument count:''' variable&lt;br /&gt;
*'''Arguments:''' ''N ids[N] fade_flags loop volume u0 u1 volumes[N] balances[N] u2[N]''&lt;br /&gt;
&lt;br /&gt;
This command is basically an inline [[Riven SLST resources|SLST]] resource record. All referenced sound resources should be looked-up in the current stack's sound archives. The resulting sound group is made current, as if [[#Command 40: activate SLST record |command 40]] had been used.&lt;br /&gt;
&lt;br /&gt;
==Command 4: play local tWAV resource==&lt;br /&gt;
*'''Argument count:''' 3&lt;br /&gt;
*'''Arguments:''' ''id volume u1''&lt;br /&gt;
&lt;br /&gt;
Play tWAV resource ''id'' from the Mohawk archive containing the script. ''volume'' seems always 256, ''u1'' always 0. This command has no effect on the active ambient sound group; the sound is mixed with the ambient sounds.&lt;br /&gt;
&lt;br /&gt;
==Command 7: set variable value==&lt;br /&gt;
*'''Argument count:''' 2&lt;br /&gt;
*'''Arguments:''' ''var value''&lt;br /&gt;
&lt;br /&gt;
Set variable ''var'' to value ''value''.&lt;br /&gt;
&lt;br /&gt;
==Command 8: conditional branch==&lt;br /&gt;
This doesn't follow the ''command arg_count'' args scheme. It's similar to a C &amp;quot;switch&amp;quot; statement: given a variable, there is a list of possible variable values and a corresponding command list to be executed. The structure of command 8 is:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;structure&amp;quot;&lt;br /&gt;
|unsigned short||8&lt;br /&gt;
|-&lt;br /&gt;
|unsigned short||2&lt;br /&gt;
|-&lt;br /&gt;
|unsigned short||var&lt;br /&gt;
|-&lt;br /&gt;
|unsigned short||value_count&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Then ''value_count'' blocks follow, each with this structure:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;structure&amp;quot;&lt;br /&gt;
|unsigned short||value&lt;br /&gt;
|-&lt;br /&gt;
|unsigned short||command_count&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot; style=&amp;quot;color:#000&amp;quot;|commands to execute if var contains value&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
If ''value'' is 0xffff, the block is the &amp;quot;default&amp;quot; block exactly like in the C statement. As an example, let's compare the script syntax with a C-like switch statement:&lt;br /&gt;
{| align=&amp;quot;center&amp;quot; valign=&amp;quot;center&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
 0008 0002 beef 3&lt;br /&gt;
   0001 0001&lt;br /&gt;
     a&lt;br /&gt;
   0002 0001&lt;br /&gt;
     b&lt;br /&gt;
   ffff 0002&lt;br /&gt;
     c&lt;br /&gt;
     d&lt;br /&gt;
|&lt;br /&gt;
 switch (variable 0xbeef) {&lt;br /&gt;
   case 1:&lt;br /&gt;
     a;&lt;br /&gt;
     break;&lt;br /&gt;
   case 2:&lt;br /&gt;
     b;&lt;br /&gt;
     break;&lt;br /&gt;
   default:&lt;br /&gt;
     c;&lt;br /&gt;
     d;&lt;br /&gt;
     break;&lt;br /&gt;
 }&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The conditional branch command is used on levers, switches and every place where a variable value makes the difference. It's often used as a simple if-then-else mechanism.&lt;br /&gt;
&lt;br /&gt;
==Command 9: enable hotspot==&lt;br /&gt;
*'''Argument count:''' 1&lt;br /&gt;
*'''Arguments:''' ''hotspot_id''&lt;br /&gt;
&lt;br /&gt;
Enable card hotspot with the specified ''hotspot_id''.&lt;br /&gt;
&lt;br /&gt;
==Command 10: disable hotspot==&lt;br /&gt;
*'''Argument count:''' 1&lt;br /&gt;
*'''Arguments:''' ''hotspot_id''&lt;br /&gt;
&lt;br /&gt;
Disable card hotspot with the specified ''hotspot_id''. A disabled hotspot will not respond to events.&lt;br /&gt;
&lt;br /&gt;
==Command 12==&lt;br /&gt;
*'''Argument count:''' 1&lt;br /&gt;
*'''Arguments:''' ''u0''&lt;br /&gt;
&lt;br /&gt;
Unknown. ''u0'' is 0, 1 or 2. This command is used only a few times, for example near &amp;quot;go to stack&amp;quot; commands like in the &amp;quot;play riven&amp;quot; button. It doesn't seem related to anything special (e.g. movies or sounds). Setting ''u0'' to some other value or replacing the command with others doesn't produce readily observable effects. I suspect it has something to do with variables, but I have yet to realize how to check this.&lt;br /&gt;
==Command 13: set mouse cursor==&lt;br /&gt;
[[Image:Cursors.png|right|frame|Riven cursor icons and their IDs]]&lt;br /&gt;
*'''Argument count:''' 1&lt;br /&gt;
*'''Arguments:''' ''cursor''&lt;br /&gt;
&lt;br /&gt;
Set mouse cursor icon to ''cursor'', whose meaning is given on the right.&lt;br /&gt;
&lt;br /&gt;
==Command 14: pause script execution==&lt;br /&gt;
*'''Argument count:''' 2&lt;br /&gt;
*'''Arguments:''' ms ''u0''&lt;br /&gt;
&lt;br /&gt;
Pause script execution for ''ms'' milliseconds. ''ms'' is signed and the pause is effective only if ''ms'' &amp;gt; 0. ''u0'' is always 0 and its value seems ignored by the engine.&lt;br /&gt;
&lt;br /&gt;
==Command 17: call external command==&lt;br /&gt;
*'''Argument count:''' variable, at least 2&lt;br /&gt;
*'''Arguments:''' ''cmd count arg1 arg2 ...''&lt;br /&gt;
&lt;br /&gt;
Call an external piece of custom code (&amp;quot;external command&amp;quot;), which is probably hardcoded inside the Riven executable. ''cmd'' tells which external command to call, and ''count'' tells how many arguments to pass to it. Then ''count'' arguments follow. [[Riven NAME resources|NAME]] resource 3 contains the name of each external command: ''cmd'' is the corresponding NAME record index. See the [[Riven external commands|external command list]] for more info on external commands.&lt;br /&gt;
&lt;br /&gt;
==Command 18: transition==&lt;br /&gt;
*'''Argument count:''' 1 or 5&lt;br /&gt;
*'''Arguments:''' ''code [left top right bottom]''&lt;br /&gt;
&lt;br /&gt;
Schedule a transition effect described by ''code'' (see below for what code means). The transition will actually play when a display update occurs, for example with [[#Command 21: enable screen update|command 21]], [[#Command 39: activate PLST record|39]] or after going to another card (it doesn't seem to work for [[#Command 1: draw tBMP resource|command 1]], however). The optional 4 args ''left'', ''top'', ''right'', and ''bottom'' specify a clip rectangle in pixels, but are never really used in the game.&lt;br /&gt;
&lt;br /&gt;
{| border=1 cellpadding=4 cellspacing=0 style=&amp;quot;border:1px #000 solid;border-collapse:collapse;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background:#CCC&amp;quot;&lt;br /&gt;
! code !! Effect&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;font-family:monospace&amp;quot;|0...15&lt;br /&gt;
|Scroll. Bits 0 and 1 control the direction (0=left, 1=right, 2=top, 3=bottom); bit 2 tells if the new image should move (1) or stay fixed (0); bit 3 tells if the old image should move or stay fixed.&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;font-family:monospace&amp;quot;|16||Dissolve.&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;font-family:monospace&amp;quot;|17||Seems to behave like 16, rare (t_Data, CARD 155).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note that Riven uses only transitions from 12 to 17; other effects were discovered by hacking scripts. Maybe there are more.&lt;br /&gt;
&lt;br /&gt;
==Command 19: reload card==&lt;br /&gt;
*'''Argument count:''' 0&lt;br /&gt;
&lt;br /&gt;
Refreshes the card, behaving like a &amp;quot;go to &amp;lt;current card&amp;gt;&amp;quot; command. The full handler sequence is executed (see command 2). Often used to update the card display after an hotspot script has altered a variable.&lt;br /&gt;
&lt;br /&gt;
==Command 20: disable screen update==&lt;br /&gt;
*'''Argument count:''' 0&lt;br /&gt;
&lt;br /&gt;
This seems to disable the automatic display update for commands [[#Command 1: draw tBMP resource|1]] and [[#Command 39: activate PLST record|39]]. It doesn't work like a &amp;quot;toggle&amp;quot; command: using it multiple times won't re-enable the automatic update (it is re-enabled by command 21 instead). Its effect persists even after the script ends (extending to any successive script, e.g. hotspot ones) but is reset on card switches. Command 20 often precedes [[#Command 18: transition|command 18]].&lt;br /&gt;
&lt;br /&gt;
==Command 21: enable screen update==&lt;br /&gt;
*'''Argument count:''' 0&lt;br /&gt;
&lt;br /&gt;
This seems the opposite of [[#Command 20: disable screen update|command 20]]: it re-enables the automatic display update for commands [[#Command 1: draw tBMP resource|1]] and [[#Command 39: activate PLST record|39]], triggers [[#Handlers|event 10]], updates the display and plays the transition effect if one was scheduled before.&lt;br /&gt;
&lt;br /&gt;
Command 21 shows inconsistent behavior if used alone (sometimes it updates the display, sometimes it doesn't, sometimes it skips the transition, etc.); the correct way of using commands 20 and 21 seems to be the following construct, which is also what is usually found in scripts:&lt;br /&gt;
#disable screen update&lt;br /&gt;
#schedule transition&lt;br /&gt;
#activate [[PLST]] records / draw [[tBMP]] resources&lt;br /&gt;
#enable screen update&lt;br /&gt;
&lt;br /&gt;
This construct will compose a final picture (by overlaying the specified PLST records and tBMP bitmaps, in the same order as they appear in the script) and then play the specified transition effect from the previously displayed picture to the new one. Note that such a complex effect wouldn't be possible without commands 20/21.&lt;br /&gt;
&lt;br /&gt;
==Command 24: increment variable==&lt;br /&gt;
*'''Argument count:''' 2&lt;br /&gt;
*'''Arguments:''' ''var value''&lt;br /&gt;
&lt;br /&gt;
Add ''value'' to variable ''var''.&lt;br /&gt;
&lt;br /&gt;
==Command 27: go to stack==&lt;br /&gt;
*'''Argument count:''' 3&lt;br /&gt;
*'''Arguments:''' ''stack_name code_hi code_lo''&lt;br /&gt;
&lt;br /&gt;
Go to another stack. The destination stack is specified by ''stack_name''; you get the actual stack name string by looking up record ''stack_name'' in [[Riven NAME resources|NAME]] resource 5. The destination card is specified through ''code_hi'' (higher 16 bytes) and ''code_lo'' (lower 16 bytes) which together form an unsigned long [[Riven RMAP resources|RMAP]] card code.&lt;br /&gt;
&lt;br /&gt;
==Command 28==&lt;br /&gt;
*'''Argument count:''' 1&lt;br /&gt;
*'''Arguments:''' ''code''&lt;br /&gt;
&lt;br /&gt;
Unknown. It should have something to do with movies: it comes almost always after [[#Command 32: play foreground movie|command 32]] with the same argument. However, changing code or even removing the command itself seem to have no effect neither on the movie nor on anything else. Maybe it purges the memory used by the movie or something like that.&lt;br /&gt;
&lt;br /&gt;
==Command 29==&lt;br /&gt;
*'''Argument count:''' 0&lt;br /&gt;
&lt;br /&gt;
Unknown. Seems related to movies since in most cases it comes after [[#Command 32: play foreground movie|command 32]]. Used quite rarely.&lt;br /&gt;
==Command 31==&lt;br /&gt;
*'''Argument count:''' 1&lt;br /&gt;
*'''Arguments:''' ''code''&lt;br /&gt;
&lt;br /&gt;
Unknown. Should have something to do with movies, it comes often before [[#Command 33: play background movie|command 33]] with the same argument. Changing code seems to have no effect.&lt;br /&gt;
&lt;br /&gt;
==Command 32: play foreground movie==&lt;br /&gt;
*'''Argument count:''' 1&lt;br /&gt;
*'''Arguments:''' ''code''&lt;br /&gt;
&lt;br /&gt;
Play a movie listed in the [[Riven MLST resources|MLST]] resource, blocking the script execution until movie ends. code matches the code field of the MLST record that should be played. The MLST record must be first enabled with [[#Command 46: activate MLST record|command 46]], otherwise some other random movie will play instead (or nothing will happen at all). If multiple records have that code value, one will be chosen randomly, I guess. Sometimes this command follows [[#Command 33: play background movie|command 33]] with the same parameter: probably it just means &amp;quot;wait until the movie ends&amp;quot; in that case.&lt;br /&gt;
&lt;br /&gt;
==Command 33: play background movie==&lt;br /&gt;
*'''Argument count:''' 1&lt;br /&gt;
*'''Arguments:''' ''code''&lt;br /&gt;
&lt;br /&gt;
Start a &amp;quot;background&amp;quot; movie from [[Riven MLST resources|MLST]] record with specified code. Script execution will go on (and eventually terminate) while the movie is playing. Often this command follows [[#Command 31|command 31]]. The MLST record must be first enabled with [[#Command 46: activate MLST record|command 46]], otherwise some other random movie will play instead.&lt;br /&gt;
&lt;br /&gt;
==Command 34==&lt;br /&gt;
*'''Argument count:''' 1&lt;br /&gt;
*'''Arguments:''' ''u0''&lt;br /&gt;
&lt;br /&gt;
Unknown. ''u0'' is always 1.&lt;br /&gt;
&lt;br /&gt;
==Command 36==&lt;br /&gt;
*'''Argument count:''' 0&lt;br /&gt;
&lt;br /&gt;
Unknown.&lt;br /&gt;
&lt;br /&gt;
==Command 37==&lt;br /&gt;
*'''Argument count:''' 0&lt;br /&gt;
&lt;br /&gt;
Unknown.&lt;br /&gt;
&lt;br /&gt;
==Command 38==&lt;br /&gt;
*'''Argument count:''' 5&lt;br /&gt;
*'''Arguments:''' ''u1 u2 u3 u4 u5''&lt;br /&gt;
&lt;br /&gt;
Unknown, but should have something to do with movies. ''u1'' seems to refer to a [[Riven MLST resources|MLST]] record code, ''u5'' seems to be a [[Riven SLST resources|SLST]] record index and ''u4'' seems always 40. ''u2'' and ''u3'' seem to form a 32-bit value set to large numbers (4000, 9000...), which I suspect are milliseconds.&lt;br /&gt;
&lt;br /&gt;
This command seems to perform complex actions: if ''u4'' is changed to 0, ''u5'' is interpreted instead as a [[Riven tBMP resources|tBMP]] resource ID and that bitmap is drawn right after the movie.&lt;br /&gt;
&lt;br /&gt;
==Command 39: activate PLST record==&lt;br /&gt;
*'''Argument count:''' 1&lt;br /&gt;
*'''Arguments:''' ''record''&lt;br /&gt;
&lt;br /&gt;
Activate the specified record in the [[Riven PLST resources|PLST]] resource, making one of the card bitmaps visible. The actual screen update takes place immediately (with a transition effect, if one was scheduled before) unless [[#Command 20: disable screen update|command 20]] was used before or the command is called from [[#Handlers|handlers 6 or 10]].&lt;br /&gt;
&lt;br /&gt;
==Command 40: activate SLST record==&lt;br /&gt;
*'''Argument count:''' 1&lt;br /&gt;
*'''Arguments:''' ''record''&lt;br /&gt;
&lt;br /&gt;
Activate the specified [[Riven SLST resources|SLST]] record. A SLST record describes an ambient sound group. The Riven engine can only have one active sound group at any given time (henceforth the &amp;quot;active ambient sound group&amp;quot;). This command sets the active ambient sound group to the specified SLST record. Appropriate fading in and fading out actions are taken based on the SLST record's fade flags. Activating the active ambient sound group has no effect.&lt;br /&gt;
&lt;br /&gt;
==Command 41==&lt;br /&gt;
*'''Argument count:''' 1&lt;br /&gt;
*'''Arguments:''' ''u0''&lt;br /&gt;
&lt;br /&gt;
Unknown. Should have something to do with movies because it comes often before [[#Command 32: play foreground movie|command 32]] with the same argument. A hypothesis is that it activates a [[Riven MLST resources|MLST]] record like [[#Command 46: activate MLST record|46]], but using its code field rather than the MLST record index.&lt;br /&gt;
==Command 43: activate BLST record==&lt;br /&gt;
*'''Argument count:''' 1&lt;br /&gt;
*'''Arguments:''' ''record''&lt;br /&gt;
&lt;br /&gt;
Activate the specified record in the [[Riven BLST resources|BLST]] resource, so enable or disable one of the card hotspots (depending on the record info).&lt;br /&gt;
&lt;br /&gt;
==Command 44: activate FLST record==&lt;br /&gt;
*'''Argument count:''' 1&lt;br /&gt;
*'''Arguments:''' ''record''&lt;br /&gt;
&lt;br /&gt;
Activate the specified record in the [[Riven FLST resources|FLST]] resource, so enable a realtime [[Riven SFXE resources|SFXE]] effect.&lt;br /&gt;
&lt;br /&gt;
==Command 45: do zip mode==&lt;br /&gt;
*'''Argument count:''' 0&lt;br /&gt;
&lt;br /&gt;
Find the correct [[Riven ZIPS resources|ZIPS]] record using the hotspot name, get the destination card from the found record and go to that card. Though likely, this behavior has not been confirmed yet.&lt;br /&gt;
&lt;br /&gt;
==Command 46: activate MLST record==&lt;br /&gt;
*'''Argument count:''' 2&lt;br /&gt;
*'''Arguments:''' ''record u0''&lt;br /&gt;
&lt;br /&gt;
Activate the specified record in the [[Riven MLST resources|MLST]] resource. This command won't actually start the movie; it will only &amp;quot;enable&amp;quot; it for later playing. ''u0'' seems 0 or 1 if the movie is to be played once or looped forever, respectively. This is redundant, since the same info can be found in the MLST record; moreover, ''u0'' seems to be ignored by the engine.&lt;/div&gt;</summary>
		<author><name>Tahg</name></author>	</entry>

	</feed>