polserver/docs/archive/file_formats.html
Gabriele Tozzi 0d2237bbbf More on line endings normalization
Blame myself :P
2016-02-12 11:39:51 +01:00

1711 lines
No EOL
53 KiB
HTML
Raw Permalink Blame History

<html><head><title>File Formats for Ultima Online</title>
<link href="file_formats_files/format.html" rel="stylesheet" type="text/css">
<meta name="DESCRIPTION" content="Alazane's Corner: File Formats for Ultima Online."></head>
<body bgcolor="#f2f0ee" link="#67594e" vlink="#8e7b6a" background="file_formats_files/Background.jpg" class="bodytext">
<a href="http://gonzo.kiev.ua/formats/contact.html"><img align="right" border="0" alt="Contacting Alazane" src="file_formats_files/email.gif"></a><br>
<center>
<p><img src="file_formats_files/title_fformat.gif"></p>
<p><img alt="Break" src="file_formats_files/break.gif"></p>
<p>If you have any information that you feel should be added to this
document, please <a href="http://gonzo.kiev.ua/formats/contact.html">contact</a> me or one of the
fine people below.</p>
<p><img alt="Break" src="file_formats_files/break.gif"></p>
<h2>Credits</h2>
<p>
<em><strong>ANIM.MUL</strong></em>, <em><strong>ANIM.IDX</strong></em>,
<em><strong>ART.MUL</strong></em>, <em><strong>ARTIDX.MUL</strong></em>,
<em><strong>PALETTE.MUL</strong></em>, <em><strong>TEXMAPS.MUL</strong></em>,
<em><strong>TEXIDX.MUL</strong></em>, <em><strong>TILEDATA.MUL</strong></em>,
<em><strong>GUMPIDX.MUL</strong></em>, <em><strong>GUMPART.MUL</strong></em>,
<em><strong>HUES.MUL</strong></em> and
<em><strong>FAQ</strong></em>
coalation by Alazane</p>
<p>
<em><strong>MAP0</strong></em>, <em><strong>RADARCOL</strong></em>,
<em><strong>STAIDX0</strong></em>, <em><strong>STATICS0</strong></em> and
<em><strong>FAQ</strong></em>
touch-up by Tim Walters</p>
<p>
<em><strong>SKILLS.IDX</strong></em>, <em><strong>SKILLS.MUL</strong></em>
by Sir Valgriz</p>
<p>
<em><strong>SOUNDIDX</strong></em>, <em><strong>SOUND</strong></em>
by Steve Dang</p>
<p>
<em><strong>VERDATA</strong></em>
by Cironian</p>
</center>
<!-- CONTENTS -->
<h3><a name="Contents">Contents</a></h3>
<div class="bodytext4">
<a href="#1.0">1.0 Miscellaneous Information</a><br>
<div class="bodytext5">
<a href="#1.1">1.1 Types</a><br>
<a href="#1.2">1.2 Colors</a><br>
</div>
<a href="#2.0">2.0 MUL files</a><br>
<a href="#3.0">3.0 Definitions</a><br>
<div class="bodytext5">
<a href="#3.1">3.1 ANIM.IDX</a><br>
<a href="#3.2">3.2 ANIM.MUL</a><br>
<a href="#3.3">3.3 ARTIDX.MUL</a><br>
<a href="#3.4">3.4 ART.MUL</a><br>
<a href="#3.5">3.5 GUMPART.MUL</a><br>
<a href="#3.6">3.6 GUMPIDX.MUL</a><br>
<a href="#3.7">3.7 HUES.MUL</a><br>
<a href="#3.8">3.8 MAP0.MUL</a><br>
<a href="#3.9">3.9 MULTI.IDX</a><br>
<a href="#3.10">3.10 MULTI.MUL</a><br>
<a href="#3.11">3.11 PALETTE.MUL</a><br>
<a href="#3.12">3.12 RADARCOL.MUL</a><br>
<a href="#3.13">3.13 SKILLS.IDX</a><br>
<a href="#3.14">3.14 SKILLS.MUL</a><br>
<a href="#3.15">3.15 SOUND.MUL</a><br>
<a href="#3.16">3.16 SOUNDIDX.MUL</a><br>
<a href="#3.17">3.17 STAIDX0.MUL</a><br>
<a href="#3.18">3.18 STATICS0.MUL</a><br>
<a href="#3.19">3.19 TILEDATA.MUL</a><br>
<a href="#3.20">3.20 TEXIDX.MUL</a><br>
<a href="#3.21">3.21 TEXMAPS.MUL</a><br>
<a href="#3.22">3.22 VERDATA.MUL</a><br>
<a href="#3.23">3.23 DIF files</a><br>
</div>
</div>
<br>
<!-- Miscellaneous Information -->
<h3><a name="1.0">1.0 Miscellaneous Information</a></h3>
<h4><a name="1.1">1.1 Types</a></h4>
<table border="0" width="100%" class="bodytext4">
<tbody><tr>
<td>CHAR</td>
<td>8 bit</td>
<td>unsigned character (ex. 'A', 'a', etc.)</td>
</tr>
<tr>
<td>BYTE</td>
<td>8 bit</td>
<td>signed value (-128..127)</td>
</tr>
<tr>
<td>UBYTE</td>
<td>8 bit</td>
<td>unsigned value (0..255)</td>
</tr>
<tr>
<td>WORD</td>
<td>16 bit</td>
<td>signed value (-32768..32767)</td>
</tr>
<tr>
<td>UWORD</td>
<td>16 bit</td>
<td>unsigned value (0..65535)</td>
</tr>
<tr>
<td>DWORD</td>
<td>32 bit</td>
<td>signed value
(-2147483648..2147483647)</td>
</tr>
</tbody></table>
<!-- Colors -->
<h4><a name="1.2">1.2 Colors</a></h4>
<p class="bodytext4">Ultima is completely 16 bit based--meaning
that each pixel is UWORD value that can be broken down as
follows:</p>
<table border="1" class="bodytext4">
<tbody><tr>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td><EFBFBD></td>
<td><EFBFBD></td>
<td><EFBFBD></td>
<td><EFBFBD></td>
<td><EFBFBD></td>
<td><EFBFBD></td>
<td><EFBFBD></td>
<td><EFBFBD></td>
<td><EFBFBD></td>
<td><EFBFBD></td>
</tr>
<tr>
<td>5</td>
<td>4</td>
<td>3</td>
<td>2</td>
<td>1</td>
<td>0</td>
<td>9</td>
<td>8</td>
<td>7</td>
<td>6</td>
<td>5</td>
<td>4</td>
<td>3</td>
<td>2</td>
<td>1</td>
<td>0</td>
</tr>
<tr>
<td>U</td>
<td bgcolor="#ff0000"><font color="White">R</font></td>
<td bgcolor="#ff0000"><font color="White">R</font></td>
<td bgcolor="#ff0000"><font color="White">R</font></td>
<td bgcolor="#ff0000"><font color="White">R</font></td>
<td bgcolor="#ff0000"><font color="White">R</font></td>
<td bgcolor="#008000"><font color="White">G</font></td>
<td bgcolor="#008000"><font color="White">G</font></td>
<td bgcolor="#008000"><font color="White">G</font></td>
<td bgcolor="#008000"><font color="White">G</font></td>
<td bgcolor="#008000"><font color="White">G</font></td>
<td bgcolor="#0000ff"><font color="White">B</font></td>
<td bgcolor="#0000ff"><font color="White">B</font></td>
<td bgcolor="#0000ff"><font color="White">B</font></td>
<td bgcolor="#0000ff"><font color="White">B</font></td>
<td bgcolor="#0000ff"><font color="White">B</font></td>
</tr>
</tbody></table>
<p class="bodytext4">Where U=Unused, R=Red, G=Green and B=Blue</p>
<p class="bodytext4">So, to convert to 32 bit:</p>
<p class="bodytext4">
Color32 = ( (((Color16 &gt;&gt; 10) &amp; 0x1F) * 0xFF / 0x1F) |<br>
((((Color16 &gt;&gt; 5) &amp; 0x1F) * 0xFF / 0x1F) &lt;&lt; 8) |<br>
((( Color16 &amp; 0x1F) * 0xFF / 0x1F) &lt;&lt; 16));</p>
<!-- MUL Files -->
<h3><a name="2.0">2.0 MUL Files</a></h3>
<table border="0" class="bodytext4">
<tbody><tr>
<td width="79">ANIM</td>
<td width="389">Animations such as monsters, people, and armor.</td>
</tr>
<tr>
<td width="79">ANIMDATA</td>
</tr>
<tr>
<td width="79">ANIMINFO</td>
</tr>
<tr>
<td width="79">ART</td>
<td width="389">Artwork such as ground, objects, etc.</td>
</tr>
<tr>
<td width="79">ARTIDX</td>
<td width="389">Index to ART</td>
</tr>
<tr>
<td width="79">CHARDATA</td>
</tr>
<tr>
<td width="79">FONTS</td>
<td width="389">Fixed size bitmaps style fonts.</td>
</tr>
<tr>
<td width="79">GUMPART</td>
<td width="389">Gumps. Stationary controller bitmaps such as windows, buttons, paperdoll pieces, etc.</td>
</tr>
<tr>
<td width="79">GUMPIDX</td>
<td width="389">Index to GUMPART</td>
</tr>
<tr>
<td width="79">HUES</td>
</tr>
<tr>
<td width="79">LIGHT</td>
</tr>
<tr>
<td width="79">LIGHTIDX</td>
</tr>
<tr>
<td width="79">MAP0</td>
<td width="389">Terrain data</td>
</tr>
<tr>
<td width="79">MULTI</td>
<td width="389">Groups of art (houses, castles, etc)</td>
</tr>
<tr>
<td width="79">PALETTE</td>
<td width="389">Contains an 8 bit palette (use unknown)</td>
</tr>
<tr>
<td width="79">RADARCOL</td>
<td width="389">Colors for converting the terrain data to radar view</td>
</tr>
<tr>
<td width="79">REGIONS</td>
</tr>
<tr>
<td width="79">SKILLGRP</td>
</tr>
<tr>
<td width="79">SKILLS</td>
</tr>
<tr>
<td width="79">SOUND</td>
<td width="389">Sampled sounds </td>
</tr>
<tr>
<td width="79">SOUNDIDX</td>
<td width="389">Index into SOUND</td>
</tr>
<tr>
<td width="79">STAIDX0</td>
<td width="389">Index into STATICS0</td>
</tr>
<tr>
<td width="79">STATICS0</td>
<td width="389">Static objects on the map</td>
</tr>
<tr>
<td width="79">TEXIDX</td>
<td width="389">Index into TEXMAPS</td>
</tr>
<tr>
<td width="79">TEXMAPS</td>
<td width="389">Texture map data (the ground).</td>
</tr>
<tr>
<td width="79">TILEDATA</td>
<td width="389">Data about tiles in ART </td>
</tr>
<tr>
<td width="79">VERDATA</td>
<td width="389">Patched overrides of data in any of the above files.</td>
</tr>
</tbody></table>
<!------------------------------------------------------------------------>
<h3><a name="3.0">3.0 Definitions</a></h3>
<!-- ANIM.IDX -->
<h4><a name="3.1">3.1 ANIM.IDX</a></h4>
<p class="bodytext4">This file contains an index into ANIM.MUL.
To load a specific group of frames from ANIM.MUL, simply seek
BNum * 12, read in the index record and use Lookup to find the
group within ANIM.MUL.</p>
<h5>ANIM.IDX</h5>
<h6>Index Record (12 bytes)</h6>
<table border="1" class="bodytext5">
<tbody><tr>
<td width="20" bgcolor="#ffffff">0</td>
<td width="20" bgcolor="#ffffff">1</td>
<td width="20" bgcolor="#ffffff">2</td>
<td width="20" bgcolor="#ffffff">3</td>
<td width="20" bgcolor="#ffffff">4</td>
<td width="20" bgcolor="#ffffff">5</td>
<td width="20" bgcolor="#ffffff">6</td>
<td width="20" bgcolor="#ffffff">7</td>
<td width="20" bgcolor="#ffffff">8</td>
<td width="20" bgcolor="#ffffff">9</td>
<td width="20" bgcolor="#ffffff">A</td>
<td width="20" bgcolor="#ffffff">B</td>
</tr>
<tr>
<td colspan="4">Lookup</td>
<td colspan="4">Size</td>
<td colspan="4">Unknown</td>
</tr>
</tbody></table>
<p class="bodytext5">
DWORD Lookup - Is either undefined ($FFFFFFFF -1) or the file offset in ANIM.MUL<br>
DWORD Size - Size of the art tile<br>
DWORD Unknown - Unknown
</p>
<!-- ANIM.MUL -->
<h4><a name="3.2">3.2 ANIM.MUL</a></h4>
<p class="bodytext4">This file contains the raw animation data.
It can be accessed using ANIM.IDX.</p>
<h5>ANIM.IDX</h5>
<p class="bodytext5">
<b>AnimationGroup</b><br>
WORD[256] Palette<br>
DWORD FrameCount<br>
DWORD[FrameCount] FrameOffset
</p>
<h5>Frame</h5>
<p class="bodytext5">
Seek from the end of Palette plus FrameOffset[FrameNum] bytes to find the
start of Frame<br>
WORD ImageCenterX<br>
WORD ImageCenterY<br>
WORD Width<br>
WORD Height<br>
...Data Stream..<br>
</p>
<h5>Data Stream</h5>
<pre>// Note: Set CenterY and CenterY to the vertical and horizontal position in
// the bitmap at which you want the anim to be drawn.
PrevLineNum = $FF
Y = CenterY - ImageCenterY - Height
while not EOF
{
Read UWORD RowHeader
Read UWORD RowOfs
if (RowHeader = 0x7FFF) or (RowOfs = 0x7FFF) then Exit
RunLength = RowHeader and $FFF
LineNum = RowHeader shr 12
Unknown = RowOfs and $3F
RowOfs = RowOfs sar 6
X = CenterX + RowOfs
if (PrevLineNum &lt;&gt; $FF) and (LineNum &lt;&gt; PrevLineNum) then Y++
PrevLineNum = LineNum
if Y &gt;= 0 then
{
if Y &gt;= MaxHeight then Exit;
For I := 0 to RunLength-1 do
{
Read(B, 1)
Row[X+I,Y] = Palette[B]
}
}
Seek(RunLength, FromCurrent)
}
</pre>
<!-- ARTIDX.MUL -->
<h4><a name="3.2">3.2 ARTIDX.MUL</a></h4>
<p class="bodytext4">This file contains an index into ART.MUL.
To load a specific tile number in ART.MUL, simply seek BNum * 12,
read in the index tile data and use Lookup to find the tile
within ART.MUL.</p>
<h5>ARTIDX.MUL</h5>
<h6>Index Record (12 bytes)</h6>
<table border="1" class="bodytext5">
<tbody><tr>
<td width="20" bgcolor="#ffffff">0</td>
<td width="20" bgcolor="#ffffff">1</td>
<td width="20" bgcolor="#ffffff">2</td>
<td width="20" bgcolor="#ffffff">3</td>
<td width="20" bgcolor="#ffffff">4</td>
<td width="20" bgcolor="#ffffff">5</td>
<td width="20" bgcolor="#ffffff">6</td>
<td width="20" bgcolor="#ffffff">7</td>
<td width="20" bgcolor="#ffffff">8</td>
<td width="20" bgcolor="#ffffff">9</td>
<td width="20" bgcolor="#ffffff">A</td>
<td width="20" bgcolor="#ffffff">B</td>
</tr>
<tr>
<td colspan="4">Lookup</td>
<td colspan="4">Size</td>
<td colspan="4">Unknown</td>
</tr>
</tbody></table>
<p class="bodytext5">
DWORD Lookup - Is either undefined ($FFFFFFFF -1) or the file offset in ART.MUL<br>
DWORD Size - Size of the art tile<br>
DWORD Unknown - Unknown
</p>
<!-- ART.MUL -->
<h4><a name="3.4">3.4 ART.MUL</a></h4>
<p class="bodytext4">This file has no header and contains tiles
that can only be read via ARTIDX.MUL. There are two types of
tiles, which I will call Raw and Run tiles.</p>
<h5>ART.MUL</h5>
<p class="bodytext5">
DWORD Flag<br>
..DATA..<br>
<br>
if (Flag &gt; $FFFF or Flag == 0)<br>
... tile is Raw ...<br>
else<br>
... tile is Run ...<br>
end if
</p>
<h5>Raw Tile <img src="file_formats_files/MMTexMaps.gif"></h5>
<p class="bodytext5">Raw tiles are always 44x44 pixels
square. However, the data stored for a tile resembles a
square block, rotated 45 degrees.<2E> Therefore, the
tile is loaded from the tip, down to the widest portion,
then down to the bottom tip as opposed to a straight
matrix.</p>
<p class="bodytext5">WORD Pixels, in the series:<br>
2, 4, 6, 8, 10 ... 40, 42, 44, 44, 42, 40 ... 10, 8, 6,
4, 2 (See 1.2 Colors for pixel info)</p>
<p class="bodytext5">The resulting top 9 lines look
like this:</p>
<table border="0" cellspacing="1" class="bodytext5">
<tbody><tr>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
</tr>
<tr>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
</tr>
<tr>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
</tr>
<tr>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
</tr>
<tr>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
</tr>
<tr>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
</tr>
<tr>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
</tr>
<tr>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
</tr>
<tr>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#ffffff"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
<td width="10" bgcolor="#808080"><EFBFBD></td>
</tr>
</tbody></table>
<h5>Run Tile <img src="file_formats_files/Book_of_Truth.gif"></h5>
<p class="bodytext5">
UWORD Width<br>
UWORD Height
</p>
<pre>Read : UWORD Width
if (Width = 0 || Width &gt;= 1024) return
Read : UWORD Height
if (Height = 0 || Height &gt;= 1024) return
Read : LStart = A table of Height number of UWORD values
DStart = Stream position
X = 0;
Y = 0;
Seek : DStart + LStart[Y] * 2
while (Y &lt; Height)
{
<EFBFBD> Read : UWORD XOffs
<EFBFBD> Read : UWORD Run
<EFBFBD> if (XOffs + Run &gt;= 2048)
<EFBFBD><EFBFBD><EFBFBD> return
<EFBFBD> else if (XOffs + Run &lt;&gt; 0)
<EFBFBD> {
<EFBFBD><EFBFBD><EFBFBD> X += XOffs;
<EFBFBD><EFBFBD><EFBFBD> Load Run number of pixels at X (See 1.2 Colors for pixel info)
<EFBFBD><EFBFBD><EFBFBD> X += Run;
<EFBFBD> }
<EFBFBD> else
<EFBFBD> {
<EFBFBD><EFBFBD><EFBFBD> X = 0;
<EFBFBD><EFBFBD><EFBFBD> Y++;
<EFBFBD><EFBFBD><EFBFBD> Seek : DStart + LStart[Y] * 2
<EFBFBD> }
}</pre>
<!-- GUMPART -->
<h4><a name="3.5">3.5 GUMPART.MUL</a></h4>
<h5>Loading a Gump</h5>
<p class="bodytext5">Gumps are stored in runs of pixels (badly inefficient, but is better than no compression).
An array of pairs of Value &amp; Word are loaded for a particular row (shown below) and these can then be easily
shoved into a bitmap. For example, if the final bitmap was going to display one black pixel, then three white
pixels, the stream would contain 0000 0001 FFFF 0003. It is imperative that GUMPIDX.MUL be loaded since it
contains Width, Height and Size which are needed to decode the Gump.
</p>
<pre>DataStart := CurrentPosition
DWORD RowLookup[GumpIdx.Height]
for Y = 0 to GumpIdx.Height-1
{
<EFBFBD><EFBFBD>cf Y &lt; Height-1 then
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>RunBlockCount := RowLookup[Y+1]-RowLookup[Y]
<EFBFBD><EFBFBD>else
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>RunBlockCount := GumpIdx.Size div 4 - RowLookup[Y];
<EFBFBD>
<EFBFBD><EFBFBD>Seek : DataStart + RowLookup[Y] * 4
<EFBFBD><EFBFBD>(WORD Value, WORD Run)[RunBlockCount]
}</pre>
<!-- GUMPIDX -->
<h4><a name="3.6">3.6 GUMPIDX</a></h4>
<p class="bodytext4">This file contains an index into GUMPART.MUL.</p>
<h5>GUMPIDX.MUL</h5>
<h6>Index Record (12 bytes)</h6>
<table border="1" class="bodytext5">
<tbody><tr>
<td width="20" bgcolor="#ffffff">0</td>
<td width="20" bgcolor="#ffffff">1</td>
<td width="20" bgcolor="#ffffff">2</td>
<td width="20" bgcolor="#ffffff">3</td>
<td width="20" bgcolor="#ffffff">4</td>
<td width="20" bgcolor="#ffffff">5</td>
<td width="20" bgcolor="#ffffff">6</td>
<td width="20" bgcolor="#ffffff">7</td>
<td width="20" bgcolor="#ffffff">8</td>
<td width="20" bgcolor="#ffffff">9</td>
<td width="20" bgcolor="#ffffff">A</td>
<td width="20" bgcolor="#ffffff">B</td>
</tr>
<tr>
<td colspan="4">Lookup</td>
<td colspan="4">Size</td>
<td colspan="2">Height</td>
<td colspan="2">Width</td>
</tr>
</tbody></table>
<p class="bodytext5">
DWORD Lookup - Is either undefined ($FFFFFFFF -1) or the file offset in GUMPART.MUL<br>
DWORD Size - Size of the block<br>
UWORD Height - Height (in pixels) of the block<br>
UWORD Width - Width (in pixels) of the block
</p>
<!-- HUES -->
<h4><a name="3.7">3.7 HUES.MUL</a></h4>
<p class="bodytext4">Just read in HueGroups until you hit the end of the file. Note that
large chunks of this file consist of garbage--OSI admits to this (something about a bug in their old code).
</p>
<p class="bodytext4">If you want to look at the hues, check out <a href="http://alazane.surf-va.com/uohueeditor.html">this</a>.</p>
<p class="bodytext4">Hues are applied to an image in one of two ways. Either all gray pixels are mapped to the specified color
range (resulting in a part of an image changed to that color) or all pixels are first mapped to grayscale and
then the specified color range is mapped over the entire image.</p><p>
</p><h5>HueEntry</h5>
<p class="bodytext5">
WORD ColorTable[32];<br>
WORD TableStart;<br>
WORD TableEnd;<br>
CHAR Name[20];
</p>
<h5>HueGroup</h5>
<p class="bodytext5">
DWORD Header;<br>
HueEntry Entries[8];
</p>
<!-- MAP0 -->
<h4><a name="3.8">3.8 MAP0.MUL</a></h4>
<p class="bodytext4">This file holds all the base-level terrain,
and doesn't look too pretty without the static data.</p>
<p class="bodytext4">The map is stored as a 768x512 matrix of
blocks. A block is basically a 8x8 matrix of cells. Each
individual cell contains data about the tile for that cell, and
the cell's altitude.<2E> Therefore, the entire map is 6144x4096
individual cells in size.</p>
<p class="bodytext4">Blocks are loaded top-to-bottom then
left-to-right. Cells are loaded from blocks left-to-right then
top-to-bottom.</p>
<p class="bodytext4">The formula used to locate an individual
CELL in the file is a little complex, since you have to work out
what block it is in...</p>
<p class="bodytext4">If you refer to the map in blocks, then
there's 512 blocks down, by 768 blocks across.</p>
<p class="bodytext4">
XBlock = Int(XPos/8)<br>
YBlock = Int(YPos/8)<br>
Block Number = (XBlock * 512) + YBlock
</p>
<h5>MAP0 (37,748,736 bytes)</h5>
<p class="bodytext5">
393,216 [Block]s sequentially, Block = 196 bytes<br>
DWORD header, unknown content<br>
64 Cells<br>
</p>
<h5>Cell (3 bytes)</h5>
<table border="1" class="bodytext5">
<tbody><tr>
<td width="20" bgcolor="#ffffff">0</td>
<td width="20" bgcolor="#ffffff">1</td>
<td width="20" bgcolor="#ffffff">2</td>
</tr>
<tr>
<td colspan="2">Color</td>
<td>Alt</td>
</tr>
</tbody></table>
<p class="bodytext5">
UWORD cell graphic (which can be looked up in RADARCOL).<br>
BYTE Altitude (-128..127 units above/below sea level).</p>
<!-- MULTI.IDX -->
<h4><a name="3.9">3.9 MULTI.IDX</a></h4>
<p class="bodytext4">This file contains an index into MULTI.MUL</p>
<h5>MULTI.IDX</h5>
<h6>Index Record (12 bytes)</h6>
<table border="1" class="bodytext5">
<tbody><tr>
<td width="20" bgcolor="#ffffff">0</td>
<td width="20" bgcolor="#ffffff">1</td>
<td width="20" bgcolor="#ffffff">2</td>
<td width="20" bgcolor="#ffffff">3</td>
<td width="20" bgcolor="#ffffff">4</td>
<td width="20" bgcolor="#ffffff">5</td>
<td width="20" bgcolor="#ffffff">6</td>
<td width="20" bgcolor="#ffffff">7</td>
<td width="20" bgcolor="#ffffff">8</td>
<td width="20" bgcolor="#ffffff">9</td>
<td width="20" bgcolor="#ffffff">A</td>
<td width="20" bgcolor="#ffffff">B</td>
</tr>
<tr>
<td colspan="4">Start</td>
<td colspan="4">Length</td>
<td colspan="4">Unknown</td>
</tr>
</tbody></table>
<p class="bodytext5">
DWORD Lookup - Is either undefined ($FFFFFFFF -1) or the file offset in MULTI.MUL<br>
DWORD Size - Size of the multi block<br>
DWORD Unknown - Unknown
</p>
<!-- MULTI.MUL -->
<h4><a name="3.10">3.10 MULTI.MUL</a></h4>
<h5>MULTI.MUL</h5>
<p class="bodytext5">
The Size should be loaded from MULTI.IDX and as many Multi Blocks should be
read as fit into this size.
</p>
<h5>Multi Block (12 bytes)</h5>
<p class="bodytext5">
WORD BlockNum<br>
WORD X<br>
WORD Y<br>
WORD Alt<br>
UDWORD Flags
</p>
<p class="bodytext5">
Once 16384+BlockNum has been looked up in ART, the block can be drawn using
the following positioning:<br>
<br>
DrawX = LeftMostX + (MultiBlock.X - MultiBlock.Y) * 22 - (Block.Width shr 1)<br>
DrawY = TopMostY + (MultiBlock.X + MultiBlock.Y) * 22 - Block.Height - MultiBlock.Alt * 4
</p>
<!-- PALETTE -->
<h4><a name="3.11">3.11 PALETTE.MUL</a></h4>
<p class="bodytext4">Contains an 8 bit palette. Use Unknown.</p>
<h5>PALETTE.MUL (768 bytes)</h5>
<p class="bodytext5">
256 [Palette Entries]<br>
</p><h5>Palette Entries (3 bytes)</h5>
<table border="1" class="bodytext5">
<tbody><tr>
<td width="20" bgcolor="#ffffff">0</td>
<td width="20" bgcolor="#ffffff">1</td>
<td width="20" bgcolor="#ffffff">2</td>
</tr>
<tr>
<td>R</td>
<td>G</td>
<td>B</td>
</tr>
</tbody></table>
<p class="bodytext5">
UBYTE Red<br>
UBYTE Green<br>
UBYTE Blue
</p>
<!-- RADARCOL.MUL -->
<h4><a name="3.12">3.12 RADARCOL.MUL</a></h4>
<p class="bodytext4">Use to lookup colors for tile numbers from
MAP0 and STAIDX0/STATICS0.</p>
<h5>RADARCOL.MUL (131,072 bytes)</h5>
<p class="bodytext5">65536 sequential UWORD color values (see 1.2 Colors for color info)</p>
<!-- SKILLS.IDX -->
<h4><a name="3.13">3.13 SKILLS.IDX</a></h4>
<p class="bodytext4">Contains index entries into the SKILLS.MUL file.</p>
<h5>SKILLS.IDX</h5>
<table border="1" class="bodytext5">
<tbody><tr>
<td width="20" bgcolor="#ffffff">0</td>
<td width="20" bgcolor="#ffffff">1</td>
<td width="20" bgcolor="#ffffff">2</td>
<td width="20" bgcolor="#ffffff">3</td>
<td width="20" bgcolor="#ffffff">4</td>
<td width="20" bgcolor="#ffffff">5</td>
<td width="20" bgcolor="#ffffff">6</td>
<td width="20" bgcolor="#ffffff">7</td>
<td width="20" bgcolor="#ffffff">8</td>
<td width="20" bgcolor="#ffffff">9</td>
<td width="20" bgcolor="#ffffff">A</td>
<td width="20" bgcolor="#ffffff">B</td>
<td width="20" bgcolor="#ffffff">C</td>
<td width="20" bgcolor="#ffffff">D</td>
<td width="20" bgcolor="#ffffff">E</td>
<td width="20" bgcolor="#ffffff">F</td>
</tr>
<tr>
<td width="20" bgcolor="#ffffff">00</td>
<td colspan="4">Start</td>
<td colspan="4">Length</td>
<td colspan="4">Unknown</td>
</tr>
</tbody></table>
<p class="bodytext5">
DWORD is the Start position for this sound<br>
DWORD is the Length of the entire associated data segment<br>
DWORD Unknown<br>
</p>
<!-- SKILLS.MUL -->
<h4><a name="3.14">3.14 SKILLS.MUL</a></h4>
<p class="bodytext4">Contains skill names.</p>
<p class="bodytext5">
BYTE is 1 if there is a button next to the name, 0 if there is not<br>
CHAR Name[] is the name of the skill
</p>
<!-- SOUND.MUL -->
<h4><a name="3.15">3.15 SOUND.MUL</a></h4>
<p class="bodytext4">Contains sampled sounds from the game. All
sounds are 16 bit mono sampled at 22050khz.</p>
<h5>SOUND.MUL</h5>
<table border="1" class="bodytext5">
<tbody><tr>
<td><EFBFBD></td>
<td width="20" bgcolor="#ffffff"> 0</td>
<td width="20" bgcolor="#ffffff"> 1</td>
<td width="20" bgcolor="#ffffff"> 2</td>
<td width="20" bgcolor="#ffffff"> 3</td>
<td width="20" bgcolor="#ffffff"> 4</td>
<td width="20" bgcolor="#ffffff"> 5</td>
<td width="20" bgcolor="#ffffff"> 6</td>
<td width="20" bgcolor="#ffffff"> 7</td>
<td width="20" bgcolor="#ffffff"> 8</td>
<td width="20" bgcolor="#ffffff"> 9</td>
<td width="20" bgcolor="#ffffff"> A</td>
<td width="20" bgcolor="#ffffff"> B</td>
<td width="20" bgcolor="#ffffff"> C</td>
<td width="20" bgcolor="#ffffff"> D</td>
<td width="20" bgcolor="#ffffff"> E</td>
<td width="20" bgcolor="#ffffff"> F</td>
</tr>
<tr>
<td width="20" bgcolor="#ffffff"> 00</td>
<td colspan="16">Original filename</td>
</tr>
<tr>
<td width="20" bgcolor="#ffffff"> 10</td>
<td colspan="4">Unknown</td>
<td colspan="4">Unknown</td>
<td colspan="4">Unknown</td>
<td colspan="4">Unknown</td>
</tr>
<tr>
<td width="20" bgcolor="#ffffff"> 20</td>
<td colspan="16">Data...</td>
</tr>
</tbody></table>
<p class="bodytext5">
CHAR[16] Original filename<br>
DWORD Unknown<br>
DWORD Unknown<br>
DWORD Unknown<br>
DWORD Unknown<br>
DATA
</p>
<!-- SOUNDIDX.MUL -->
<h4><a name="3.16">3.16 SOUNDIDX.MUL</a></h4>
<p class="bodytext4">Contains index entries into the SOUND.MUL file.</p>
<h5>SOUNDIDX.MUL</h5>
<table border="1" class="bodytext5">
<tbody><tr>
<td width="20" bgcolor="#ffffff">0</td>
<td width="20" bgcolor="#ffffff">1</td>
<td width="20" bgcolor="#ffffff">2</td>
<td width="20" bgcolor="#ffffff">3</td>
<td width="20" bgcolor="#ffffff">4</td>
<td width="20" bgcolor="#ffffff">5</td>
<td width="20" bgcolor="#ffffff">6</td>
<td width="20" bgcolor="#ffffff">7</td>
<td width="20" bgcolor="#ffffff">8</td>
<td width="20" bgcolor="#ffffff">9</td>
<td width="20" bgcolor="#ffffff">A</td>
<td width="20" bgcolor="#ffffff">B</td>
<td width="20" bgcolor="#ffffff">C</td>
<td width="20" bgcolor="#ffffff">D</td>
<td width="20" bgcolor="#ffffff">E</td>
<td width="20" bgcolor="#ffffff">F</td>
</tr>
<tr>
<td width="20" bgcolor="#ffffff">00</td>
<td colspan="4">Start</td>
<td colspan="4">Length</td>
<td colspan="2">Index</td>
<td colspan="2">Reserved</td>
</tr>
</tbody></table>
<p class="bodytext5">
DWORD is the Start position for this sound<br>
DWORD is the Length of the entire associated data segment<br>
UWORD index<br>
UWORD reserved
</p>
<!-- STAIDX0.MUL -->
<h4><a name="3.17">3.17 STAIDX0.MUL</a></h4>
<p class="bodytext4">Contains index to entries into the
STATICS0.MUL file. Special thanks to Mental4 from
ultima.scorched.com for the hint to cracking this one The 12 byte
blocks in this file match up one to one with the blocks in the
map file, hence the file size of 768 * 512 * 12 = 4,718,592
bytes.<2E> Pretty simple, easiest to read this at the same time
as MAP0.MUL, if there's static objects, read them per block,
doing height comparisons to see which ones to draw for radar type
view.</p>
<h5>STAIDX0.MUL (4,718,592 bytes)</h5>
<p class="bodytext5">
393,216 [Index Block]s sequentially<br>
</p><h6>Index Record (12 bytes)</h6>
<table border="1" class="bodytext5">
<tbody><tr>
<td width="20" bgcolor="#ffffff">0</td>
<td width="20" bgcolor="#ffffff">1</td>
<td width="20" bgcolor="#ffffff">2</td>
<td width="20" bgcolor="#ffffff">3</td>
<td width="20" bgcolor="#ffffff">4</td>
<td width="20" bgcolor="#ffffff">5</td>
<td width="20" bgcolor="#ffffff">6</td>
<td width="20" bgcolor="#ffffff">7</td>
<td width="20" bgcolor="#ffffff">8</td>
<td width="20" bgcolor="#ffffff">9</td>
<td width="20" bgcolor="#ffffff">A</td>
<td width="20" bgcolor="#ffffff">B</td>
</tr>
<tr>
<td colspan="4">Start</td>
<td colspan="4">Length</td>
<td colspan="4">Unknown</td>
</tr>
</tbody></table>
<p class="bodytext5">
DWORD is the Start position (0xFFFFFFFF if no static objects exist for this block)<br>
DWORD is the Length of the data segment<br>
DWORD is of unknown use
</p>
<!-- STATICS0.MUL -->
<h4><a name="3.18">3.18 STATICS0.MUL</a></h4>
<p class="bodytext4">Notes: This is where all the fun stuff is,
as a side-note, I tried playing with NO static objects for the
purpose of item-recovery (stuff lost behind walls), the Britain
area is duplicated server-side (could explain the extra lag
there), same with Moonglow area, places like Buccaneer's Den,
Trinsic and other towns worked fine... no walls, no bridges, no
shallow water (note, server still stops you from walking through
walls, even if you can't see them).</p>
<h5>STATICS0.MUL</h5>
<p class="bodytext5">Static Data (7 bytes)</p>
<table border="1" class="bodytext5">
<tbody><tr>
<td width="20" bgcolor="#ffffff">0</td>
<td width="20" bgcolor="#ffffff">1</td>
<td width="20" bgcolor="#ffffff">2</td>
<td width="20" bgcolor="#ffffff">3</td>
<td width="20" bgcolor="#ffffff">4</td>
<td width="20" bgcolor="#ffffff">5</td>
<td width="20" bgcolor="#ffffff">6</td>
</tr>
<tr>
<td colspan="2">Color</td>
<td>X</td>
<td>Y</td>
<td>Alt</td>
<td colspan="2">Unknown</td>
</tr>
</tbody></table>
<p class="bodytext5">
UWORD for the Color/Object ID (add 16384 to offset it for RADARCOL.MUL)<br>
UBYTE X Offset in block (0..7)<br>
UBYTE Y Offset in block (0..7)<br>
BYTE Altitude (-128..127 units above/below sea level, like MAP0)<br>
UWORD Unknown
</p>
<!-- TILEDATA.MUL -->
<h4><a name="3.19">3.19 TILEDATA.MUL</a></h4>
<p class="bodytext4">Contains data about tiles in ART.MUL.</p>
<h5>TILEDATA.MUL</h5>
<p class="bodytext5">
512 Blocks of [Land Tile Groups]<br>
X Blocks of [Static Tile Groups]
</p>
<h5>Land Tile Groups (836 bytes)</h5>
<p class="bodytext5">
DWORD Unknown<br>
32 Blocks of [Land Tile Data]
</p>
<h5>Land Tile Data (26 bytes)</h5>
<table border="1" class="bodytext5">
<tbody><tr>
<td width="20" bgcolor="#ffffff">0</td>
<td width="20" bgcolor="#ffffff">1</td>
<td width="20" bgcolor="#ffffff">2</td>
<td width="20" bgcolor="#ffffff">3</td>
<td width="20" bgcolor="#ffffff">4</td>
<td width="20" bgcolor="#ffffff">5</td>
<td width="20" bgcolor="#ffffff">6</td>
<td width="20" bgcolor="#ffffff">7</td>
<td width="20" bgcolor="#ffffff">8</td>
<td width="20" bgcolor="#ffffff">9</td>
<td width="20" bgcolor="#ffffff">A</td>
<td width="20" bgcolor="#ffffff">B</td>
<td width="20" bgcolor="#ffffff">C</td>
<td width="20" bgcolor="#ffffff">D</td>
<td width="20" bgcolor="#ffffff">E</td>
<td width="20" bgcolor="#ffffff">F</td>
</tr>
<tr>
<td width="20" bgcolor="#ffffff">00</td>
<td colspan="4">Flags</td>
<td colspan="2">Texture ID</td>
<td colspan="10">Tile Name...</td>
</tr>
<tr>
<td width="20" bgcolor="#ffffff">10</td>
<td colspan="10">...</td>
</tr>
</tbody></table>
<p class="bodytext5">DWORD Flags (see below)<br>
UWORD Texture ID (If 0, the land tile has not texture)<br>
CHAR[20] Tile Name
</p>
<h5>Static Tile Groups (1188 bytes)</h5>
<p class="bodytext5">DWORD Unknown<br>
32 Blocks of [Static Tile Data]</p>
<h5>Static Tile Data (37 bytes)</h5>
<table border="1" class="bodytext5">
<tbody><tr>
<td width="20" bgcolor="#ffffff">0</td>
<td width="20" bgcolor="#ffffff">1</td>
<td width="20" bgcolor="#ffffff">2</td>
<td width="20" bgcolor="#ffffff">3</td>
<td width="20" bgcolor="#ffffff">4</td>
<td width="20" bgcolor="#ffffff">5</td>
<td width="20" bgcolor="#ffffff">6</td>
<td width="20" bgcolor="#ffffff">7</td>
<td width="20" bgcolor="#ffffff">8</td>
<td width="20" bgcolor="#ffffff">9</td>
<td width="20" bgcolor="#ffffff">A</td>
<td width="20" bgcolor="#ffffff">B</td>
<td width="20" bgcolor="#ffffff">C</td>
<td width="20" bgcolor="#ffffff">D</td>
<td width="20" bgcolor="#ffffff">E</td>
<td width="20" bgcolor="#ffffff">F</td>
</tr>
<tr>
<td width="20" bgcolor="#ffffff">00</td>
<td colspan="4">Flags</td>
<td>Weight</td>
<td>Quality</td>
<td colspan="3">Unknown</td>
<td>Quantity</td>
<td colspan="2">Anim ID</td>
<td>Unknown1</td>
<td>Hue</td>
<td colspan="2">Unknown2</td>
</tr>
<tr>
<td width="20" bgcolor="#ffffff">10</td>
<td>Height</td>
<td colspan="15">Tile Name...</td>
</tr>
<tr>
<td width="20" bgcolor="#ffffff">20</td>
<td colspan="5">...</td>
</tr>
</tbody></table>
<p class="bodytext5">
DWORD Flags (see below)<br>
BYTE Weight (weight of the item, 255 means not movable)<br>
BYTE Quality (If Wearable, this is a Layer. If Light Source, this is Light ID)<br>
UWORD Unknown<br>
BYTE Unknown1<br>
BYTE Quantity (if Weapon, this is Weapon Class. If Armor, Armor Class)<br>
UWORD Anim ID (The Body ID the animatation. Add 50,000 and 60,000
respectivefully to get the two gump indicies assocaited with this tile)<br>
BYTE Unknown2<br>
BYTE Hue (perhaps colored light?)<br>
UWORD Unknown3<br>
BYTE Height (If Conatainer, this is how much the container can hold)<br>
CHAR[20] Tile Name<br>
</p>
<h5>Flags</h5>
<p class="bodytext5">
0x00000001 Background<br>
0x00000002 Weapon<br>
0x00000004 Transparent<br>
0x00000008 Translucent<br>
0x00000010 Wall<br>
0x00000020 Damaging<br>
0x00000040 Impassable<br>
0x00000080 Wet<br>
0x00000100 Unknown<br>
0x00000200 Surface<br>
0x00000400 Bridge<br>
0x00000800 Generic/Stackable<br>
0x00001000 Window<br>
0x00002000 No Shoot<br>0x00004000 Prefix A<br>
0x00008000 Prefix An<br>
0x00010000 Internal (things like hair, beards, etc)<br>
0x00020000 Foliage<br>
0x00040000 Partial Hue<br>
0x00080000 Unknown 1<br>
0x00100000 Map<br>
0x00200000 Container<br>
0x00400000 Wearable<br>
0x00800000 LightSource<br>
0x01000000 Animated<br>
0x02000000 No Diagonal<br>
0x04000000 Unknown 2<br>
0x08000000 Armor<br>
0x10000000 Roof<br>
0x20000000 Door<br>
0x40000000 StairBack<br>
0x80000000 StairRight<br>
</p>
<!-- TEXIDX.MUL -->
<h4><a name="3.20">3.20 TEXIDX.MUL</a></h4>
<h5>TEXIDX.MUL</h5>
<h6>Index Record (12 bytes)</h6>
<table border="1" class="bodytext5">
<tbody><tr>
<td width="20" bgcolor="#ffffff">0</td>
<td width="20" bgcolor="#ffffff">1</td>
<td width="20" bgcolor="#ffffff">2</td>
<td width="20" bgcolor="#ffffff">3</td>
<td width="20" bgcolor="#ffffff">4</td>
<td width="20" bgcolor="#ffffff">5</td>
<td width="20" bgcolor="#ffffff">6</td>
<td width="20" bgcolor="#ffffff">7</td>
<td width="20" bgcolor="#ffffff">8</td>
<td width="20" bgcolor="#ffffff">9</td>
<td width="20" bgcolor="#ffffff">A</td>
<td width="20" bgcolor="#ffffff">B</td>
</tr>
<tr>
<td colspan="4">Start</td>
<td colspan="4">Length</td>
<td colspan="4">Unknown</td>
</tr>
</tbody></table>
<p class="bodytext5">
DWORD is the Start position<br>
DWORD is the Length of the data segment<br>
DWORD is of unknown use
</p>
<!-- TEXMAPS.MUL -->
<h4><a name="3.21">3.21 TEXMAPS.MUL</a></h4>
<p class="bodytext4">The texture maps in general were about an afternoon
hack. Since the index is the same as all the other indices and the data
is quite straightforward, it was almost an afterthought to include it.</p>
<h5>TEXMAPS.MUL</h5>
<p class="bodytext5">
Raw 16-bit data, sized as follows:<br>
If Length = 0x2000 then data = 64*64<br>
If Length = 0x8000 then data = 128*128
</p>
<!-- VERDATA.MUL -->
<h4><a name="3.22">3.22 VERDATA.MUL</a></h4>
<p class="bodytext4">VERDATA.MUL contains patch entries that override
already existing entries in the above data files. The use of VERDATA.MUL
was a recent addition to InsideUO, thanks almost completely to Cironian for
dropping the format for it on me out of the blue.</p>
<h5>VERDATA.MUL</h5>
<p class="bodytext5">First DWORD: Number of entries in index</p>
<p class="bodytext5"><b>Index entry:</b><br>
DWORD: File ID (see index below)<br>
DWORD: Block (Item number, Gump number or whatever; like in the file)<br>
DWORD: Position (Where to find this block in verdata.mul)<br>
DWORD: Size (Size in Byte)<br>
DWORD: Various (depends on the file format)
</p>
<p class="bodytext5"><b>File IDs:</b> (* means used in current verdata)<br>
00 - map0.mul<br>
01 - staidx0.mul<br>
02 - statics0.mul<br>
03 - artidx.mul<br>
04 - art.mul*<br>
05 - anim.idx<br>
06 - anim.mul<br>
07 - soundidx.mul<br>
08 - sound.mul<br>
09 - texidx.mul<br>
0A - texmaps.mul<br>
0B - gumpidx.mul<br>
0C - gumpart.mul* - Various is WORD Height + WORD Width<br>
0D - multi.idx<br>
0E - multi.mul*<br>
0F - skills.idx<br>
10 - skills.mul<br>
1E - tiledata.mul*<br>
1F - animdata.mul*
</p>
<p class="bodytext5">
The block of data that is located and read in from VERDATA.MUL is of exactly the same
format as the data in the source file.
</p>
<h4><a name="3.23">3.23 DIFF files</a></h4>
<p class="bodytext4">Stadifl#.mul,Stadifi#.mul,Stadif#.mul,Mapdifl#.mul, and
Mapdif#.mul contains patch entries that override already existing entries in
the above data files. The use of diff files is activiated by a packet sent to
the client from the server. The 3D client, starting with LBR , no longer uses
Verdata.mul. It is uknown how other data patches are done. .</p>
<h5>Stadifl#.mul, Mapdifl#.mul
</h5>
<p class="bodytext5">Until end of file, DWORDs:Block Number</p>
<h5>Stadifi#.mul</h5>
<p class="bodytext5">The format of this file maps exactly to the format of
StaIDX#.mul. Each entry corresponds to the blockid in the Stadifl#.mul. The
offset and length of the entires are the offset into Stadif#.mul
</p>
<h5>Mapdif#.mul</h5>
<p class="bodytext5">The format of this file maps exactly to Map#.mul. Each entry
corresponds to the block id in Mapdifl#.mul.</p>
<h5>Stadifi#.mul</h5>
<p class="bodytext5">The format of this file maps exactly to Statics#.mul. This
file is indexed by Stadifi#.mul</p>
<center><p><img alt="Break" src="file_formats_files/break.gif"></p>
<p>Last reviewed by <a href="http://gonzo.kiev.ua/formats/contact.html">Alazane</a> 03/23/2002</p>
</center>
</body></html>