<?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=Aaron</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=Aaron"/>
		<link rel="alternate" type="text/html" href="http://insidethelink.ortiche.net/wiki/index.php/Special:Contributions/Aaron"/>
		<updated>2026-05-01T15:19:55Z</updated>
		<subtitle>User contributions</subtitle>
		<generator>MediaWiki 1.23.15</generator>

	<entry>
		<id>http://insidethelink.ortiche.net/wiki/index.php/Riven_tMOV_resources</id>
		<title>Riven tMOV resources</title>
		<link rel="alternate" type="text/html" href="http://insidethelink.ortiche.net/wiki/index.php/Riven_tMOV_resources"/>
				<updated>2010-03-10T21:06:48Z</updated>
		
		<summary type="html">&lt;p&gt;Aaron: update the quicktime reference link (the old one was broken)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt;{{Riven}}&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
tMOV resources are QuickTime movies. For a complete reference of the format, please see [http://developer.apple.com/mac/library/documentation/QuickTime/QTFF/QTFFPreface/qtffPreface.html here].&lt;br /&gt;
&lt;br /&gt;
== Codecs ==&lt;br /&gt;
&lt;br /&gt;
All Riven movies use the Cinepak video codec and the Apple IMA 4:1 audio codec.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
Note that all offsets in the stco chunk are absolute offsets in the Mohawk archive, not offsets within the video as the format specifies.&lt;/div&gt;</summary>
		<author><name>Aaron</name></author>	</entry>

	<entry>
		<id>http://insidethelink.ortiche.net/wiki/index.php/Mohawk_Sounds</id>
		<title>Mohawk Sounds</title>
		<link rel="alternate" type="text/html" href="http://insidethelink.ortiche.net/wiki/index.php/Mohawk_Sounds"/>
				<updated>2010-03-10T21:04:58Z</updated>
		
		<summary type="html">&lt;p&gt;Aaron: I added a link to more information on ADPCM encoding&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Myst}}&lt;br /&gt;
{{Riven}}&lt;br /&gt;
It happens that Myst, Riven and other products share a somewhat common format for storing audio data (sounds and music): we called it the ''Mohawk sounds'' format. Though this page is complete enough to correctly decode sounds (at least &amp;quot;by ear&amp;quot;), the format has a number of obscure details and unknown fields, especially those connected to data sizes. Thanks to Ron Hayter for providing details on the DVD version of Riven's tWAV resources.&lt;br /&gt;
&lt;br /&gt;
The format is structured in chunks, much like the common WAV audio format. The audio data can be compressed in three ways:&lt;br /&gt;
* Raw unsigned PCM data, used in older games.&lt;br /&gt;
* Intel DVI ADPCM format, a lossy differential encoding which stores the difference between consecutive samples as 4-bit delta samples, yielding a compression factor of 4:1.&lt;br /&gt;
* MPEG-2 Layer II encoding - Used in the DVD version of Riven.&lt;br /&gt;
&lt;br /&gt;
It's important to note that the compressed data block contains more data than necessary (in Riven): the additional data is just garbage at the end of the block, and is skipped by the Riven decoder when the sound is played. Unfortunately, the headers seem to ignore this excess data: this makes reverse-engineering of these fields very difficult, since every relation with the full resource size is lost. It's necessary to introduce an &amp;quot;effective resource size&amp;quot; excluding the excess data.&lt;br /&gt;
&lt;br /&gt;
==The header==&lt;br /&gt;
The data block begins with the following header:&lt;br /&gt;
{| class=&amp;quot;structure&amp;quot;&lt;br /&gt;
|4 bytes||mhwk_magic&lt;br /&gt;
|-&lt;br /&gt;
|unsigned long||size&lt;br /&gt;
|-&lt;br /&gt;
|4 bytes||wave_magic&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
*''mhwk_magic'' is the string 'MHWK'. It's equal to the [[Mohawk archive format#IFF header|Mohawk format signature]]!&lt;br /&gt;
*''size'' is the effective resource size, minus the ADPC chunk size, minus 2.&lt;br /&gt;
*''wave_magic'' is the string 'WAVE'.&lt;br /&gt;
&lt;br /&gt;
After this header come the chunks. Until now, 3 chunk types have been identified: '[[#The ADPC chunk|ADPC]]', '[[#The Cue.23 chunk|Cue#]]' and '[[#The Data chunk|Data]]'.&lt;br /&gt;
&lt;br /&gt;
==The ADPC chunk==&lt;br /&gt;
This chunk holds some information about the audio sample format. Its size is not constant.&lt;br /&gt;
{| class=&amp;quot;structure&amp;quot;&lt;br /&gt;
|4 bytes||chunk_type&lt;br /&gt;
|-&lt;br /&gt;
|unsigned long||chunk_size&lt;br /&gt;
|-&lt;br /&gt;
|unsigned short||u0&lt;br /&gt;
|-&lt;br /&gt;
|unsigned short||channels&lt;br /&gt;
|-&lt;br /&gt;
|unsigned long||u1&lt;br /&gt;
|-&lt;br /&gt;
|unsigned long||u2[channels]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
*''chunk_type'' is the string 'ADPC'.&lt;br /&gt;
*''chunk_size'' is the chunk size minus 8.&lt;br /&gt;
*''channels'' is the number of audio channels.&lt;br /&gt;
*''u0'' is 2 when there is the Cue# chunk, and 1 when there isn't.&lt;br /&gt;
*''u1'' is always 0.&lt;br /&gt;
*''u2'' is always 0x00400000 for both channels.&lt;br /&gt;
&lt;br /&gt;
If there is the Cue# chunk, then there is additional data in the ADPC chunk:&lt;br /&gt;
{| class=&amp;quot;structure&amp;quot;&lt;br /&gt;
|unsigned long||u3&lt;br /&gt;
|-&lt;br /&gt;
|unsigned long||u4[channels]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
*''u3'' seems to be in units of samples (maybe it's a position within the audio stream).&lt;br /&gt;
*''u4'' looks more like a record than a single unsigned long value, but values are obscure and I have no idea about its meaning.&lt;br /&gt;
&lt;br /&gt;
Finally, the ADPC chunk is only present when there is ADPCM sound.&lt;br /&gt;
&lt;br /&gt;
==The Cue# chunk==&lt;br /&gt;
This chunk is rare in Riven, only a few tWAV resources have it and just one resource has an interesting one (that's tWAV 3 from p_Sounds.mhk). This chunk seems to contain &amp;quot;cue points&amp;quot;, in a way similar to the corresponding chunk of the WAVE format. This is much more common in other games, especially Myst.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;structure&amp;quot;&lt;br /&gt;
|4 bytes||chunk_type&lt;br /&gt;
|-&lt;br /&gt;
|unsigned long||chunk_size&lt;br /&gt;
|-&lt;br /&gt;
|unsigned short||point_count&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
*''chunk_type'' is the string 'Cue#'.&lt;br /&gt;
*''chunk_size'' is the chunk size minus 8.&lt;br /&gt;
*''point_count'' is the number of cue points.&lt;br /&gt;
&lt;br /&gt;
Following this fixed structure there are ''point_count'' records; each record describes a cue point with a position inside the audio stream and an associated ASCII text string:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;structure&amp;quot;&lt;br /&gt;
|unsigned long||position&lt;br /&gt;
|-&lt;br /&gt;
|unsigned char||name_len&lt;br /&gt;
|-&lt;br /&gt;
|unsigned char||name[name_len+1]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
*''position'' is the cue point position within the audio stream, in units of samples.&lt;br /&gt;
*''name_len'' is the length of the associated string.&lt;br /&gt;
*''name'' is the associated string (zero-terminated).&lt;br /&gt;
&lt;br /&gt;
Most Cue# chunks have ''point_count'' set to 0, so they contain nothing. Riven tWAV 3 from p_Sounds.mhk has two cue points, named &amp;lt;code&amp;gt;Beg Loop&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;End Loop&amp;lt;/code&amp;gt;. Please note that the chunk structure has been guessed from this single case, so the statistics is very poor :-\&lt;br /&gt;
&lt;br /&gt;
I don't know if the engine uses this chunk at all.&lt;br /&gt;
&lt;br /&gt;
==The Data chunk==&lt;br /&gt;
This chunk is always present since it contains the actual audio samples.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;structure&amp;quot;&lt;br /&gt;
|4 bytes||chunk_type&lt;br /&gt;
|-&lt;br /&gt;
|unsigned long||chunk_size&lt;br /&gt;
|-&lt;br /&gt;
|unsigned short||sample_rate&lt;br /&gt;
|-&lt;br /&gt;
|unsigned long||sample_count&lt;br /&gt;
|-&lt;br /&gt;
|unsigned char||bits_per_sample&lt;br /&gt;
|-&lt;br /&gt;
|unsigned char||channels&lt;br /&gt;
|-&lt;br /&gt;
|unsigned short||encoding&lt;br /&gt;
|-&lt;br /&gt;
|unsigned short||loop&lt;br /&gt;
|-&lt;br /&gt;
|unsigned long||loop_start&lt;br /&gt;
|-&lt;br /&gt;
|unsigned long||loop_end&lt;br /&gt;
|-&lt;br /&gt;
|variable||audio_data&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
*''chunk_type'' is the string 'Data'.&lt;br /&gt;
*''chunk_size'' is the full chunk size, including ''chunk_type'' and ''chunk_size'' itself.&lt;br /&gt;
*''sample_rate'' is the audio sampling rate (always 22050).&lt;br /&gt;
*''sample_count'' is the number of audio samples.&lt;br /&gt;
*''bits_per_sample'' is the number of bits per sample per channel.&lt;br /&gt;
*''channels'' is the number of audio channels.&lt;br /&gt;
*''encoding'' tells how the audio data is stored. It's 0 for raw unsigned PCM, 1 for ADPCM, 2 for MPEG-2 Audio Layer II.&lt;br /&gt;
*''loop'' means loop if the value is 0xFFFF (not used in Riven).&lt;br /&gt;
*''loop_start'' is the starting point of the loop (not used in Riven).&lt;br /&gt;
*''loop_end'' is the ending point of the loop (not used in Riven).&lt;br /&gt;
*''audio_data'' is the audio data stream, encoded according to encoding. In case of 1-channel ADPC audio, each byte holds 2 compressed samples (higher and lower 4 bits of the byte); in case of stereo ADPC sounds, each byte stores one compressed sample for each channel (higher and lower 4 bits of the byte).&lt;br /&gt;
&lt;br /&gt;
A good reference for ADPCM decoding (which sounds right to me) can be found [http://wiki.multimedia.cx/index.php?title=IMA_ADPCM here]. Use the decoding method involving the if statements and bit-shifts, which sounds the best. It can be found near the bottom of the page.&lt;/div&gt;</summary>
		<author><name>Aaron</name></author>	</entry>

	<entry>
		<id>http://insidethelink.ortiche.net/wiki/index.php/Talk:Riven_tBMP_resources</id>
		<title>Talk:Riven tBMP resources</title>
		<link rel="alternate" type="text/html" href="http://insidethelink.ortiche.net/wiki/index.php/Talk:Riven_tBMP_resources"/>
				<updated>2009-02-24T03:21:44Z</updated>
		
		<summary type="html">&lt;p&gt;Aaron: citations and clarifying authorship&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Aaron, I'm not entirely clear on your recent additions to the tBMP decode algorithms. Are you aware of specific images that exhibit the behaviors you describe to use a test cases, or a decoder implementation which respects those details?&lt;br /&gt;
&lt;br /&gt;
[Tito] I think I've seen Aaron's effects in some compressed tBMPs. In particular, I recall being surprised by observing duplets repeating themselves, though I don't remember which tBMPs I was inspecting at the time.&lt;br /&gt;
&lt;br /&gt;
[ [[User:Aaron|Aaron]] 06:55, 23 February 2009 (CET) ] I mean to go back and check specifically for this, but I'm almost completely certain that this is true. Initially, in my algorithm, I used an unsigned integer to represent the number of pixels to look back from where I started, and decremented it each time I copied a pixel. This crippled all my images, and caused weird segfaults when it rolled over after 0. This was fixed when I used a signed integer type (ie let the command copy into newly-written pixels). This is basically an implementation detail, most people would do it a different way where this doesn't matter, or use a signed integer to begin with. [also, I think that pixel-based lookbacks ignore the extra space off the edge, while duplet-based ones do not, but I'm not certain on that. I'll verify that too, but it's too late now.] I didn't realize this was new information, I just thought it was left out.&lt;br /&gt;
&lt;br /&gt;
[ [[User:Aaron|Aaron]] 04:21, 24 February 2009 (CET) ] OK, I found specific examples. First of all, pixel lookbacks either never happen close enough to new rows to look back into the last row, or they take into account the extra info not in the final image (the bytes per row thing I mentioned in the article), so I'm glad I tried to confirm it before adding it. As for the others, all of these examples are from my original 5-cd riven set, and they're all from b_Data.MHK. tBMPs 99, 101, and 106 (and others) have a higher bytes per row than image width, and only appear correctly when rendered as if they were (bytes per row) wide, then cropped. tBMP 0 (and almost every other compressed image) has many repeat subcommands that ask for more data than there is available at the time. Specifically, byte 165 of the command stream of tBMP 0 is 0xEC followed by 0x08, meaning n = 6 and m = 8, so it needs 12 pixels copied from 8 pixels ago. These images only render correctly when they are allowed to read into themselves. This also happens with repeat command 0xFC. I hope this clarifies things.&lt;/div&gt;</summary>
		<author><name>Aaron</name></author>	</entry>

	<entry>
		<id>http://insidethelink.ortiche.net/wiki/index.php/Talk:Riven_tBMP_resources</id>
		<title>Talk:Riven tBMP resources</title>
		<link rel="alternate" type="text/html" href="http://insidethelink.ortiche.net/wiki/index.php/Talk:Riven_tBMP_resources"/>
				<updated>2009-02-23T05:55:15Z</updated>
		
		<summary type="html">&lt;p&gt;Aaron: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Aaron, I'm not entirely clear on your recent additions to the tBMP decode algorithms. Are you aware of specific images that exhibit the behaviors you describe to use a test cases, or a decoder implementation which respects those details?&lt;br /&gt;
&lt;br /&gt;
[Tito] I think I've seen Aaron's effects in some compressed tBMPs. In particular, I recall being surprised by observing duplets repeating themselves, though I don't remember which tBMPs I was inspecting at the time.&lt;br /&gt;
&lt;br /&gt;
[ [[User:Aaron|agrif]] 06:55, 23 February 2009 (CET) ] I mean to go back and check specifically for this, but I'm almost completely certain that this is true. Initially, in my algorithm, I used an unsigned integer to represent the number of pixels to look back from where I started, and decremented it each time I copied a pixel. This crippled all my images, and caused weird segfaults when it rolled over after 0. This was fixed when I used a signed integer type (ie let the command copy into newly-written pixels). This is basically an implementation detail, most people would do it a different way where this doesn't matter, or use a signed integer to begin with. [also, I think that pixel-based lookbacks ignore the extra space off the edge, while duplet-based ones do not, but I'm not certain on that. I'll verify that too, but it's too late now.] I didn't realize this was new information, I just thought it was left out.&lt;/div&gt;</summary>
		<author><name>Aaron</name></author>	</entry>

	<entry>
		<id>http://insidethelink.ortiche.net/wiki/index.php/Riven_tBMP_resources</id>
		<title>Riven tBMP resources</title>
		<link rel="alternate" type="text/html" href="http://insidethelink.ortiche.net/wiki/index.php/Riven_tBMP_resources"/>
				<updated>2009-02-19T19:22:49Z</updated>
		
		<summary type="html">&lt;p&gt;Aaron: /* Subcommands, part 2: repeat operations */ Clarifying repeat commands where it copies more pixels than available at the time&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Riven}}&lt;br /&gt;
This page shows the structure of Riven tBMP resources, which store game bitmaps.&lt;br /&gt;
&lt;br /&gt;
==General tBMP structure==&lt;br /&gt;
tBMP resources store 8-bit and 24-bit bitmaps, which can be plain or compressed. Everything is in big-endian order. Each resource begins with this structure:&lt;br /&gt;
{| class=&amp;quot;structure&amp;quot;&lt;br /&gt;
|unsigned short||bitmap width (pixels)&lt;br /&gt;
|-&lt;br /&gt;
|unsigned short||bitmap height (pixels)&lt;br /&gt;
|-&lt;br /&gt;
|unsigned short||bytes per row&lt;br /&gt;
|-&lt;br /&gt;
|unsigned char||compression flag&lt;br /&gt;
|-&lt;br /&gt;
|unsigned char||truecolor flag&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
If the truecolor flag is 4 then the bitmap is a 24-bit image, and the structure goes on with height rows, each row following this structure:&lt;br /&gt;
{| class=&amp;quot;structure&amp;quot;&lt;br /&gt;
|''width''*3 unsigned chars||pixel values (BGR, BGR, BGR...)&lt;br /&gt;
|-&lt;br /&gt;
|''width'' unsigned chars||unknown (zero)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note that there is only one 24-bit bitmap in the whole game! It's tBMP 24 in b2_data.mhk, and it's a secret image.&lt;br /&gt;
&lt;br /&gt;
If the truecolor flag is not 4 the tBMP is a normal 8-bit bitmap and after the initial fields we find:&lt;br /&gt;
{| class=&amp;quot;structure&amp;quot;&lt;br /&gt;
|unsigned long||unknown (seems always 0x030418ff)&lt;br /&gt;
|-&lt;br /&gt;
|256*3 unsigned chars||color table (BGR, BGR, BGR...)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
If the compression flag is 0, the bitmap is uncompressed: pixel data follows immediately as a simple block of pixels. Each pixel is a byte representing an index in the color table. Rows may be padded with filling bytes to reach the specified number of bytes per row; just discard those extra bytes. Otherwise, if the compression flag is 4 then the bitmap is compressed with a proprietary format (explained below); the compressed data block follows immediately.&lt;br /&gt;
&lt;br /&gt;
==Compression details==&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;/div&gt;</summary>
		<author><name>Aaron</name></author>	</entry>

	<entry>
		<id>http://insidethelink.ortiche.net/wiki/index.php/Riven_tBMP_resources</id>
		<title>Riven tBMP resources</title>
		<link rel="alternate" type="text/html" href="http://insidethelink.ortiche.net/wiki/index.php/Riven_tBMP_resources"/>
				<updated>2009-02-19T19:10:28Z</updated>
		
		<summary type="html">&lt;p&gt;Aaron: /* Compression details */ &amp;quot;bytes per row&amp;quot; in compressed tBMP clarification, minor formatting correction&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Riven}}&lt;br /&gt;
This page shows the structure of Riven tBMP resources, which store game bitmaps.&lt;br /&gt;
&lt;br /&gt;
==General tBMP structure==&lt;br /&gt;
tBMP resources store 8-bit and 24-bit bitmaps, which can be plain or compressed. Everything is in big-endian order. Each resource begins with this structure:&lt;br /&gt;
{| class=&amp;quot;structure&amp;quot;&lt;br /&gt;
|unsigned short||bitmap width (pixels)&lt;br /&gt;
|-&lt;br /&gt;
|unsigned short||bitmap height (pixels)&lt;br /&gt;
|-&lt;br /&gt;
|unsigned short||bytes per row&lt;br /&gt;
|-&lt;br /&gt;
|unsigned char||compression flag&lt;br /&gt;
|-&lt;br /&gt;
|unsigned char||truecolor flag&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
If the truecolor flag is 4 then the bitmap is a 24-bit image, and the structure goes on with height rows, each row following this structure:&lt;br /&gt;
{| class=&amp;quot;structure&amp;quot;&lt;br /&gt;
|''width''*3 unsigned chars||pixel values (BGR, BGR, BGR...)&lt;br /&gt;
|-&lt;br /&gt;
|''width'' unsigned chars||unknown (zero)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note that there is only one 24-bit bitmap in the whole game! It's tBMP 24 in b2_data.mhk, and it's a secret image.&lt;br /&gt;
&lt;br /&gt;
If the truecolor flag is not 4 the tBMP is a normal 8-bit bitmap and after the initial fields we find:&lt;br /&gt;
{| class=&amp;quot;structure&amp;quot;&lt;br /&gt;
|unsigned long||unknown (seems always 0x030418ff)&lt;br /&gt;
|-&lt;br /&gt;
|256*3 unsigned chars||color table (BGR, BGR, BGR...)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
If the compression flag is 0, the bitmap is uncompressed: pixel data follows immediately as a simple block of pixels. Each pixel is a byte representing an index in the color table. Rows may be padded with filling bytes to reach the specified number of bytes per row; just discard those extra bytes. Otherwise, if the compression flag is 4 then the bitmap is compressed with a proprietary format (explained below); the compressed data block follows immediately.&lt;br /&gt;
&lt;br /&gt;
==Compression details==&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;
{| 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;/div&gt;</summary>
		<author><name>Aaron</name></author>	</entry>

	</feed>