<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-GB">
	<id>https://moddingwiki.shikadi.net/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Fergusdog</id>
	<title>ModdingWiki - User contributions [en-gb]</title>
	<link rel="self" type="application/atom+xml" href="https://moddingwiki.shikadi.net/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Fergusdog"/>
	<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/wiki/Special:Contributions/Fergusdog"/>
	<updated>2026-05-15T09:09:41Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.39.11</generator>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_Palette_Format&amp;diff=12636</id>
		<title>Eye of the Beholder Palette Format</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_Palette_Format&amp;diff=12636"/>
		<updated>2025-10-31T04:30:16Z</updated>

		<summary type="html">&lt;p&gt;Fergusdog: /* Java code to read .PAL files (EOB I PC version) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Palette Infobox&lt;br /&gt;
 | Hardware = VGA&lt;br /&gt;
 | Depth = 18-bit&lt;br /&gt;
 | Count = 256&lt;br /&gt;
 | Games = &lt;br /&gt;
   {{Game|Eye of the Beholder}}&lt;br /&gt;
   {{Game|Eye of the Beholder II: The Legend of Darkmoon}}&lt;br /&gt;
   {{Game|Lands of Lore: The Throne of Chaos}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Eye of the Beholder&#039;&#039; uses a [[VGA_Palette#The_.22Classic.22_format|6-bit RGB 256-colour palette]].&lt;br /&gt;
&lt;br /&gt;
=== PC version of Eye of the Beholder I ===&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;.PAL&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;.COL&amp;lt;/code&amp;gt; files used in the PC version of &#039;&#039;EOB I&#039;&#039; differ slightly from the standard format in that all bytes in the files must be bit-shifted two bits to the left.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Example:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The 4th byte in the file &amp;lt;code&amp;gt;BRICK.PAL&amp;lt;/code&amp;gt;, which holds the red channel for the second colour in the palette, reads &amp;lt;code&amp;gt;EA&amp;lt;/code&amp;gt; in hexadecimal or &amp;lt;code&amp;gt;11101010&amp;lt;/code&amp;gt; in binary.&lt;br /&gt;
Bit-shifted, it becomes &amp;lt;code&amp;gt;10101000&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;A8&amp;lt;/code&amp;gt; in hex, which is the correct value.&lt;br /&gt;
&lt;br /&gt;
=== Bit-shifting vs. mathematical scaling ===&lt;br /&gt;
&lt;br /&gt;
While the above shifting gives visually acceptable results, it is not strictly mathematically correct.&lt;br /&gt;
For example, full white in 6-bit RGB (&amp;lt;code&amp;gt;00111111&amp;lt;/code&amp;gt;) becomes &amp;lt;code&amp;gt;11111100&amp;lt;/code&amp;gt; when bit-shifted, which is no longer full white in 8-bit RGB.&lt;br /&gt;
&lt;br /&gt;
For accurate colour intensities, the following formula should be used:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; 8bitRGB = (6bitRGB &amp;amp; 0x3F) * 255 / 63 &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Java code to read .PAL files (EOB I PC version) ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt; &lt;br /&gt;
import java.io.*;&lt;br /&gt;
&lt;br /&gt;
public class PAL {&lt;br /&gt;
&lt;br /&gt;
    private byte[] m_rawData;&lt;br /&gt;
    public byte[][] m_palette;&lt;br /&gt;
&lt;br /&gt;
    public PAL(String filename) throws IOException {&lt;br /&gt;
        File f = new File(filename);&lt;br /&gt;
        long fileSize = f.length();&lt;br /&gt;
        m_rawData = new byte[(int) fileSize];&lt;br /&gt;
&lt;br /&gt;
        FileInputStream fis = new FileInputStream(filename);&lt;br /&gt;
        int tr = fis.read(m_rawData);&lt;br /&gt;
        fis.close();&lt;br /&gt;
&lt;br /&gt;
        m_palette = new byte[(int) (fileSize / 3)][3];&lt;br /&gt;
        for (int i = 0; i &amp;lt; m_palette.length; i++) {&lt;br /&gt;
            m_palette[i][0] = (byte) Math.round(((m_rawData[i * 3] &amp;amp; 0x3F) * 255.0f / 63));&lt;br /&gt;
            m_palette[i][1] = (byte) Math.round(((m_rawData[1 + i * 3] &amp;amp; 0x3F) * 255.0f / 63));&lt;br /&gt;
            m_palette[i][2] = (byte) Math.round(((m_rawData[2 + i * 3] &amp;amp; 0x3F) * 255.0f / 63));&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
https://web.archive.org/web/20180516034756/http://eob.wikispaces.com/eob.pal&lt;/div&gt;</summary>
		<author><name>Fergusdog</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VCN_Format&amp;diff=12635</id>
		<title>Eye of the Beholder VCN Format</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VCN_Format&amp;diff=12635"/>
		<updated>2025-10-31T04:26:55Z</updated>

		<summary type="html">&lt;p&gt;Fergusdog: /* See Also */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Tileset Infobox&lt;br /&gt;
 | Hardware1 = VGA&lt;br /&gt;
 | MaxTiles = 65535&lt;br /&gt;
 | Palette = Internal, External&lt;br /&gt;
 | Names = N&lt;br /&gt;
 | TileMinSize = 8&amp;amp;times;8&lt;br /&gt;
 | TileMaxSize = 8&amp;amp;times;8&lt;br /&gt;
 | NumPlanes = 1&lt;br /&gt;
 | PlaneArrangement = Linear&lt;br /&gt;
 | HasTransparency = P&lt;br /&gt;
 | HasHitmap = N&lt;br /&gt;
 | Metadata = None&lt;br /&gt;
 | Subtilesets = N&lt;br /&gt;
 | Compressed = N&lt;br /&gt;
 | Hidden = N&lt;br /&gt;
 | Games = &lt;br /&gt;
   {{Game|Eye of the Beholder}}&lt;br /&gt;
   {{Game|Eye of the Beholder II: The Legend of Darkmoon}}&lt;br /&gt;
   {{Game|Lands of Lore: The Throne of Chaos}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;VCN&#039;&#039;&#039; file stores 8×8 image tiles that form the game&#039;s 3D view window, the “view cone.” These tiles are used to build the backdrop of a level (floor and ceiling), as well as the wall segments shown from different distances and angles.&lt;br /&gt;
&lt;br /&gt;
The VCN tiles are combined at runtime according to layout data in the corresponding &#039;&#039;&#039;VMP&#039;&#039;&#039; file, which defines how each wall and corridor segment is assembled from these tiles. Together, the VCN and VMP files generate the illusion of depth as the player moves through the grid-based dungeon. The VCN and VMP file are referenced in the level&#039;s &#039;&#039;&#039;INF&#039;&#039;&#039; file.&lt;br /&gt;
&lt;br /&gt;
The name &#039;&#039;&#039;VCN&#039;&#039;&#039; possibly stands for View Cone, referring to the visible area of the 3D viewport, or View Compressed Nibble, reflecting that each tile stores 4-bit (nibble) pixel data.&lt;br /&gt;
&lt;br /&gt;
== File Structure (PC version) ==&lt;br /&gt;
&lt;br /&gt;
In the PC version, VCN files are compressed, using the [[Westwood LCW]] compression (see [[Westwood CPS Format]]). In the demo, they are uncompressed. &lt;br /&gt;
&lt;br /&gt;
The uncompressed data has this structure:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset !! Size !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x00 || 2 bytes (LE) || Number of 8×8 tiles contained in the file.&lt;br /&gt;
|-&lt;br /&gt;
| 0x02 || 16 bytes || Backdrop palette – 16 color indices (0–255).&lt;br /&gt;
|-&lt;br /&gt;
| 0x12 || 16 bytes || Wall palette – 16 color indices (0–255).&lt;br /&gt;
|-&lt;br /&gt;
| 0x22 || 32 × N bytes || Pixel data for N tiles, each 8×8 pixels (4 bits per pixel, i.e. two pixels per byte).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
struct VCN {&lt;br /&gt;
    uint16_t tile_count;&lt;br /&gt;
    uint8_t  back_palette[16];&lt;br /&gt;
    uint8_t  wall_palette[16];&lt;br /&gt;
    struct Tile {&lt;br /&gt;
        uint8_t pixels[4][8]; // 8×8 pixels, 4 bytes per row&lt;br /&gt;
    } blocks[tile_count];&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;tile_count&#039;&#039;&#039; – Number of 8×8 tiles in the file.  &lt;br /&gt;
* &#039;&#039;&#039;back_palette&#039;&#039;&#039; – 16 palette indices used for backdrop tiles (floor/ceiling).  &lt;br /&gt;
* &#039;&#039;&#039;wall_palette&#039;&#039;&#039; – 16 palette indices used for wall tiles.  &lt;br /&gt;
* &#039;&#039;&#039;tiles&#039;&#039;&#039; – Array of tile data. Each byte encodes two 4-bit pixel indices.&lt;br /&gt;
&lt;br /&gt;
== Amiga Version (16-color planar) ==&lt;br /&gt;
&lt;br /&gt;
The Amiga version uses a slightly different layout and 5-bit planar graphics instead of nibble-packed pixels.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
struct VCN {&lt;br /&gt;
    uint16_t tile_count;&lt;br /&gt;
    uint16_t palette[16];&lt;br /&gt;
    struct Tile {&lt;br /&gt;
        uint8_t pixels[5][8];&lt;br /&gt;
    } tiles[tile_count];&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;tile_count&#039;&#039;&#039; – Number of tiles in the file.  &lt;br /&gt;
* &#039;&#039;&#039;palette&#039;&#039;&#039; – 16-entry palette in the same format as CPS files.  &lt;br /&gt;
:* Each entry replaces index [I]+1 in the global palette from `INVENT.CPS`.  &lt;br /&gt;
:* Colors of value `0x0000` are ignored.  &lt;br /&gt;
:* &#039;&#039;EOB2&#039;&#039; uses an external 32-color palette in $xRGB format.  &lt;br /&gt;
* &#039;&#039;&#039;tiles&#039;&#039;&#039; – Array of 8×8 planar tiles, 5 bitplanes deep.  &lt;br /&gt;
&lt;br /&gt;
Planar → chunky conversion example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
uint8_t chunky[8][8];&lt;br /&gt;
for (int y = 0; y &amp;lt; 8; y++)&lt;br /&gt;
  for (int x = 0; x &amp;lt; 8; x++) {&lt;br /&gt;
    int bit = 1 &amp;lt;&amp;lt; (7 - x);&lt;br /&gt;
    uint8_t data = 0;&lt;br /&gt;
    for (int plane = 0; plane &amp;lt; 5; plane++)&lt;br /&gt;
      if (rawPlanarData[plane][y] &amp;amp; bit) data |= (1 &amp;lt;&amp;lt; plane);&lt;br /&gt;
    chunky[y][x] = data;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Lands of Lore Version (128-color extended format) ==&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;Lands of Lore&#039;&#039; engine uses an extended variant of the VCN format supporting 128 colors and multiple palette tables.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
struct VCN {&lt;br /&gt;
    uint16_t tile_count;&lt;br /&gt;
    uint8_t  tile_palette_pos_table[tile_count];&lt;br /&gt;
    struct PosPaletteTables {&lt;br /&gt;
        uint8_t backdrop_wall_palettes[16];&lt;br /&gt;
    } pos_palette_tables[8];&lt;br /&gt;
    uint8_t palette[3*128]; // 128 colors, 24-bit&lt;br /&gt;
    struct Tile {&lt;br /&gt;
        uint8_t pixels[4][8];&lt;br /&gt;
    } tiles[tile_count];&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;tile_count&#039;&#039;&#039; – Number of 8×8 tiles.  &lt;br /&gt;
* &#039;&#039;&#039;tile_palette_pos_table&#039;&#039;&#039; – For each tile, an index (0–7) into the `pos_palette_tables`.  &lt;br /&gt;
* &#039;&#039;&#039;pos_palette_tables&#039;&#039;&#039; – 8 tables of 16 entries each, defining color positions within the 256-color master palette.  &lt;br /&gt;
* &#039;&#039;&#039;palette&#039;&#039;&#039; – Local 128-color palette (3 bytes per entry, EOB-format RGB).  &lt;br /&gt;
* &#039;&#039;&#039;tiles&#039;&#039;&#039; – Tile data (two pixels per byte).  &lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Notes&#039;&#039;&#039;&lt;br /&gt;
* PC and LoL versions use 4-bit “nibble” pixels; Amiga uses 5-bit planar data.  &lt;br /&gt;
* All versions rely on external palettes to map indices to RGB colors.  &lt;br /&gt;
* The number of blocks determines the total number of 8×8 tiles available for constructing the dungeon view.&lt;br /&gt;
&lt;br /&gt;
== Tiles ==&lt;br /&gt;
&lt;br /&gt;
The very first tile is fully transparent, 7 tilesets follow. The first are the tiles for the backdrop (ceiling/floor), then 6 different wall types (including doorways and stairs) follow.&lt;br /&gt;
&lt;br /&gt;
== Rendering ==&lt;br /&gt;
&lt;br /&gt;
Each 8×8 tile stores pixel values as &#039;&#039;&#039;palette indices&#039;&#039;&#039;, which are mapped in two steps:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;Local palette lookup&#039;&#039;&#039; – Each tile references either the &#039;&#039;&#039;backdrop palette&#039;&#039;&#039; or the &#039;&#039;&#039;wall palette&#039;&#039;&#039;. Which palette is used depends on the tile index, as specified by the VMP layout.&lt;br /&gt;
# &#039;&#039;&#039;Global palette lookup&#039;&#039;&#039; – The palette index is then used to select an actual RGB color from the &#039;&#039;&#039;level’s PAL file&#039;&#039;&#039; (e.g., BRICK.PAL), as specified in the level&#039;s INF file.&lt;br /&gt;
&lt;br /&gt;
=== Example (wall tile) ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
raw pixel byte = 0x53&lt;br /&gt;
→ high nibble = 5 → pixel 1&lt;br /&gt;
→ low nibble  = 3 → pixel 2&lt;br /&gt;
&lt;br /&gt;
Step 1: Local palette lookup&lt;br /&gt;
pixel 1: wall_palette[5] → 7&lt;br /&gt;
pixel 2: wall_palette[3] → 4&lt;br /&gt;
&lt;br /&gt;
Step 2: Global palette lookup&lt;br /&gt;
pixel 1 RGB = BRICK.PAL[7]&lt;br /&gt;
pixel 2 RGB = BRICK.PAL[4]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; A palette index of 0 is treated as &#039;&#039;transparent&#039;&#039;, and no pixel is drawn for that position in the viewport.&lt;br /&gt;
&lt;br /&gt;
== Relationship to INF, VMP, and PAL ==&lt;br /&gt;
&lt;br /&gt;
Each level in &#039;&#039;Eye of the Beholder&#039;&#039; references a set of resource files that define its appearance. The &#039;&#039;&#039;INF&#039;&#039;&#039; file serves as the level’s manifest, specifying which &#039;&#039;&#039;VNP&#039;&#039;&#039;, &#039;&#039;&#039;VCN&#039;&#039;&#039;, and &#039;&#039;&#039;PAL&#039;&#039;&#039; files to use.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;VCN&#039;&#039;&#039; – Contains the raw 8×8 tiles for walls and backdrop components.  &lt;br /&gt;
* &#039;&#039;&#039;VMP&#039;&#039;&#039; – Provides a layout map: it stores indices into the VCN file, defining which tile to place where in the view cone.  &lt;br /&gt;
* &#039;&#039;&#039;PAL&#039;&#039;&#039; – Defines the RGB colors corresponding to palette indices used in the VCN tiles.  &lt;br /&gt;
&lt;br /&gt;
Together, these files allow the engine to construct the &#039;&#039;&#039;view cone&#039;&#039;&#039; dynamically:&lt;br /&gt;
&lt;br /&gt;
# The VMP file tells the engine which 8×8 tiles from the VCN to use for each wall projection and the backdrop.  &lt;br /&gt;
# Each tile references either the backdrop or wall palette.  &lt;br /&gt;
# The palette indices are then mapped to RGB values from the level’s PAL file.  &lt;br /&gt;
# The engine combines the tiles according to the VMP layout to render the final 3D view.&lt;br /&gt;
&lt;br /&gt;
== Summary ==&lt;br /&gt;
&lt;br /&gt;
* Contains 8×8 nibble-encoded tiles.&lt;br /&gt;
* Uses two intermediate 16-color palettes (backdrop and wall) and PAL palette from level INF file.&lt;br /&gt;
* Indexed by matching VMP layout file.&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
* [[Eye of the Beholder VMP Format]] – layout map for assembling VCN tiles&lt;br /&gt;
* [[Eye of the Beholder Maze Information Format]] - level info file&lt;br /&gt;
* [[Eye of the Beholder Palette Format]] - palette format&lt;br /&gt;
* [[Westwood LCW]] – LCW compression format&lt;br /&gt;
* [[Westwood CPS Format]] – Reference for the compressed VCN format&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
https://web.archive.org/web/20180521003835/http://eob.wikispaces.com/eob.vcn&lt;/div&gt;</summary>
		<author><name>Fergusdog</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VCN_Format&amp;diff=12634</id>
		<title>Eye of the Beholder VCN Format</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VCN_Format&amp;diff=12634"/>
		<updated>2025-10-31T04:26:13Z</updated>

		<summary type="html">&lt;p&gt;Fergusdog: /* See Also */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Tileset Infobox&lt;br /&gt;
 | Hardware1 = VGA&lt;br /&gt;
 | MaxTiles = 65535&lt;br /&gt;
 | Palette = Internal, External&lt;br /&gt;
 | Names = N&lt;br /&gt;
 | TileMinSize = 8&amp;amp;times;8&lt;br /&gt;
 | TileMaxSize = 8&amp;amp;times;8&lt;br /&gt;
 | NumPlanes = 1&lt;br /&gt;
 | PlaneArrangement = Linear&lt;br /&gt;
 | HasTransparency = P&lt;br /&gt;
 | HasHitmap = N&lt;br /&gt;
 | Metadata = None&lt;br /&gt;
 | Subtilesets = N&lt;br /&gt;
 | Compressed = N&lt;br /&gt;
 | Hidden = N&lt;br /&gt;
 | Games = &lt;br /&gt;
   {{Game|Eye of the Beholder}}&lt;br /&gt;
   {{Game|Eye of the Beholder II: The Legend of Darkmoon}}&lt;br /&gt;
   {{Game|Lands of Lore: The Throne of Chaos}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;VCN&#039;&#039;&#039; file stores 8×8 image tiles that form the game&#039;s 3D view window, the “view cone.” These tiles are used to build the backdrop of a level (floor and ceiling), as well as the wall segments shown from different distances and angles.&lt;br /&gt;
&lt;br /&gt;
The VCN tiles are combined at runtime according to layout data in the corresponding &#039;&#039;&#039;VMP&#039;&#039;&#039; file, which defines how each wall and corridor segment is assembled from these tiles. Together, the VCN and VMP files generate the illusion of depth as the player moves through the grid-based dungeon. The VCN and VMP file are referenced in the level&#039;s &#039;&#039;&#039;INF&#039;&#039;&#039; file.&lt;br /&gt;
&lt;br /&gt;
The name &#039;&#039;&#039;VCN&#039;&#039;&#039; possibly stands for View Cone, referring to the visible area of the 3D viewport, or View Compressed Nibble, reflecting that each tile stores 4-bit (nibble) pixel data.&lt;br /&gt;
&lt;br /&gt;
== File Structure (PC version) ==&lt;br /&gt;
&lt;br /&gt;
In the PC version, VCN files are compressed, using the [[Westwood LCW]] compression (see [[Westwood CPS Format]]). In the demo, they are uncompressed. &lt;br /&gt;
&lt;br /&gt;
The uncompressed data has this structure:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset !! Size !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x00 || 2 bytes (LE) || Number of 8×8 tiles contained in the file.&lt;br /&gt;
|-&lt;br /&gt;
| 0x02 || 16 bytes || Backdrop palette – 16 color indices (0–255).&lt;br /&gt;
|-&lt;br /&gt;
| 0x12 || 16 bytes || Wall palette – 16 color indices (0–255).&lt;br /&gt;
|-&lt;br /&gt;
| 0x22 || 32 × N bytes || Pixel data for N tiles, each 8×8 pixels (4 bits per pixel, i.e. two pixels per byte).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
struct VCN {&lt;br /&gt;
    uint16_t tile_count;&lt;br /&gt;
    uint8_t  back_palette[16];&lt;br /&gt;
    uint8_t  wall_palette[16];&lt;br /&gt;
    struct Tile {&lt;br /&gt;
        uint8_t pixels[4][8]; // 8×8 pixels, 4 bytes per row&lt;br /&gt;
    } blocks[tile_count];&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;tile_count&#039;&#039;&#039; – Number of 8×8 tiles in the file.  &lt;br /&gt;
* &#039;&#039;&#039;back_palette&#039;&#039;&#039; – 16 palette indices used for backdrop tiles (floor/ceiling).  &lt;br /&gt;
* &#039;&#039;&#039;wall_palette&#039;&#039;&#039; – 16 palette indices used for wall tiles.  &lt;br /&gt;
* &#039;&#039;&#039;tiles&#039;&#039;&#039; – Array of tile data. Each byte encodes two 4-bit pixel indices.&lt;br /&gt;
&lt;br /&gt;
== Amiga Version (16-color planar) ==&lt;br /&gt;
&lt;br /&gt;
The Amiga version uses a slightly different layout and 5-bit planar graphics instead of nibble-packed pixels.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
struct VCN {&lt;br /&gt;
    uint16_t tile_count;&lt;br /&gt;
    uint16_t palette[16];&lt;br /&gt;
    struct Tile {&lt;br /&gt;
        uint8_t pixels[5][8];&lt;br /&gt;
    } tiles[tile_count];&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;tile_count&#039;&#039;&#039; – Number of tiles in the file.  &lt;br /&gt;
* &#039;&#039;&#039;palette&#039;&#039;&#039; – 16-entry palette in the same format as CPS files.  &lt;br /&gt;
:* Each entry replaces index [I]+1 in the global palette from `INVENT.CPS`.  &lt;br /&gt;
:* Colors of value `0x0000` are ignored.  &lt;br /&gt;
:* &#039;&#039;EOB2&#039;&#039; uses an external 32-color palette in $xRGB format.  &lt;br /&gt;
* &#039;&#039;&#039;tiles&#039;&#039;&#039; – Array of 8×8 planar tiles, 5 bitplanes deep.  &lt;br /&gt;
&lt;br /&gt;
Planar → chunky conversion example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
uint8_t chunky[8][8];&lt;br /&gt;
for (int y = 0; y &amp;lt; 8; y++)&lt;br /&gt;
  for (int x = 0; x &amp;lt; 8; x++) {&lt;br /&gt;
    int bit = 1 &amp;lt;&amp;lt; (7 - x);&lt;br /&gt;
    uint8_t data = 0;&lt;br /&gt;
    for (int plane = 0; plane &amp;lt; 5; plane++)&lt;br /&gt;
      if (rawPlanarData[plane][y] &amp;amp; bit) data |= (1 &amp;lt;&amp;lt; plane);&lt;br /&gt;
    chunky[y][x] = data;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Lands of Lore Version (128-color extended format) ==&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;Lands of Lore&#039;&#039; engine uses an extended variant of the VCN format supporting 128 colors and multiple palette tables.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
struct VCN {&lt;br /&gt;
    uint16_t tile_count;&lt;br /&gt;
    uint8_t  tile_palette_pos_table[tile_count];&lt;br /&gt;
    struct PosPaletteTables {&lt;br /&gt;
        uint8_t backdrop_wall_palettes[16];&lt;br /&gt;
    } pos_palette_tables[8];&lt;br /&gt;
    uint8_t palette[3*128]; // 128 colors, 24-bit&lt;br /&gt;
    struct Tile {&lt;br /&gt;
        uint8_t pixels[4][8];&lt;br /&gt;
    } tiles[tile_count];&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;tile_count&#039;&#039;&#039; – Number of 8×8 tiles.  &lt;br /&gt;
* &#039;&#039;&#039;tile_palette_pos_table&#039;&#039;&#039; – For each tile, an index (0–7) into the `pos_palette_tables`.  &lt;br /&gt;
* &#039;&#039;&#039;pos_palette_tables&#039;&#039;&#039; – 8 tables of 16 entries each, defining color positions within the 256-color master palette.  &lt;br /&gt;
* &#039;&#039;&#039;palette&#039;&#039;&#039; – Local 128-color palette (3 bytes per entry, EOB-format RGB).  &lt;br /&gt;
* &#039;&#039;&#039;tiles&#039;&#039;&#039; – Tile data (two pixels per byte).  &lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Notes&#039;&#039;&#039;&lt;br /&gt;
* PC and LoL versions use 4-bit “nibble” pixels; Amiga uses 5-bit planar data.  &lt;br /&gt;
* All versions rely on external palettes to map indices to RGB colors.  &lt;br /&gt;
* The number of blocks determines the total number of 8×8 tiles available for constructing the dungeon view.&lt;br /&gt;
&lt;br /&gt;
== Tiles ==&lt;br /&gt;
&lt;br /&gt;
The very first tile is fully transparent, 7 tilesets follow. The first are the tiles for the backdrop (ceiling/floor), then 6 different wall types (including doorways and stairs) follow.&lt;br /&gt;
&lt;br /&gt;
== Rendering ==&lt;br /&gt;
&lt;br /&gt;
Each 8×8 tile stores pixel values as &#039;&#039;&#039;palette indices&#039;&#039;&#039;, which are mapped in two steps:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;Local palette lookup&#039;&#039;&#039; – Each tile references either the &#039;&#039;&#039;backdrop palette&#039;&#039;&#039; or the &#039;&#039;&#039;wall palette&#039;&#039;&#039;. Which palette is used depends on the tile index, as specified by the VMP layout.&lt;br /&gt;
# &#039;&#039;&#039;Global palette lookup&#039;&#039;&#039; – The palette index is then used to select an actual RGB color from the &#039;&#039;&#039;level’s PAL file&#039;&#039;&#039; (e.g., BRICK.PAL), as specified in the level&#039;s INF file.&lt;br /&gt;
&lt;br /&gt;
=== Example (wall tile) ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
raw pixel byte = 0x53&lt;br /&gt;
→ high nibble = 5 → pixel 1&lt;br /&gt;
→ low nibble  = 3 → pixel 2&lt;br /&gt;
&lt;br /&gt;
Step 1: Local palette lookup&lt;br /&gt;
pixel 1: wall_palette[5] → 7&lt;br /&gt;
pixel 2: wall_palette[3] → 4&lt;br /&gt;
&lt;br /&gt;
Step 2: Global palette lookup&lt;br /&gt;
pixel 1 RGB = BRICK.PAL[7]&lt;br /&gt;
pixel 2 RGB = BRICK.PAL[4]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; A palette index of 0 is treated as &#039;&#039;transparent&#039;&#039;, and no pixel is drawn for that position in the viewport.&lt;br /&gt;
&lt;br /&gt;
== Relationship to INF, VMP, and PAL ==&lt;br /&gt;
&lt;br /&gt;
Each level in &#039;&#039;Eye of the Beholder&#039;&#039; references a set of resource files that define its appearance. The &#039;&#039;&#039;INF&#039;&#039;&#039; file serves as the level’s manifest, specifying which &#039;&#039;&#039;VNP&#039;&#039;&#039;, &#039;&#039;&#039;VCN&#039;&#039;&#039;, and &#039;&#039;&#039;PAL&#039;&#039;&#039; files to use.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;VCN&#039;&#039;&#039; – Contains the raw 8×8 tiles for walls and backdrop components.  &lt;br /&gt;
* &#039;&#039;&#039;VMP&#039;&#039;&#039; – Provides a layout map: it stores indices into the VCN file, defining which tile to place where in the view cone.  &lt;br /&gt;
* &#039;&#039;&#039;PAL&#039;&#039;&#039; – Defines the RGB colors corresponding to palette indices used in the VCN tiles.  &lt;br /&gt;
&lt;br /&gt;
Together, these files allow the engine to construct the &#039;&#039;&#039;view cone&#039;&#039;&#039; dynamically:&lt;br /&gt;
&lt;br /&gt;
# The VMP file tells the engine which 8×8 tiles from the VCN to use for each wall projection and the backdrop.  &lt;br /&gt;
# Each tile references either the backdrop or wall palette.  &lt;br /&gt;
# The palette indices are then mapped to RGB values from the level’s PAL file.  &lt;br /&gt;
# The engine combines the tiles according to the VMP layout to render the final 3D view.&lt;br /&gt;
&lt;br /&gt;
== Summary ==&lt;br /&gt;
&lt;br /&gt;
* Contains 8×8 nibble-encoded tiles.&lt;br /&gt;
* Uses two intermediate 16-color palettes (backdrop and wall) and PAL palette from level INF file.&lt;br /&gt;
* Indexed by matching VMP layout file.&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
* [[Eye of the Beholder VMP Format]] – layout map for assembling VCN tiles&lt;br /&gt;
* [[Eye of the Beholder Maze Information Format]] - level info file&lt;br /&gt;
* [[Eye of the Beholder PAL Format]] - palette format&lt;br /&gt;
* [[Westwood LCW]] – LCW compression format&lt;br /&gt;
* [[Westwood CPS Format]] – Reference for the compressed VCN format&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
https://web.archive.org/web/20180521003835/http://eob.wikispaces.com/eob.vcn&lt;/div&gt;</summary>
		<author><name>Fergusdog</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VCN_Format&amp;diff=12633</id>
		<title>Eye of the Beholder VCN Format</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VCN_Format&amp;diff=12633"/>
		<updated>2025-10-31T04:25:50Z</updated>

		<summary type="html">&lt;p&gt;Fergusdog: /* See Also */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Tileset Infobox&lt;br /&gt;
 | Hardware1 = VGA&lt;br /&gt;
 | MaxTiles = 65535&lt;br /&gt;
 | Palette = Internal, External&lt;br /&gt;
 | Names = N&lt;br /&gt;
 | TileMinSize = 8&amp;amp;times;8&lt;br /&gt;
 | TileMaxSize = 8&amp;amp;times;8&lt;br /&gt;
 | NumPlanes = 1&lt;br /&gt;
 | PlaneArrangement = Linear&lt;br /&gt;
 | HasTransparency = P&lt;br /&gt;
 | HasHitmap = N&lt;br /&gt;
 | Metadata = None&lt;br /&gt;
 | Subtilesets = N&lt;br /&gt;
 | Compressed = N&lt;br /&gt;
 | Hidden = N&lt;br /&gt;
 | Games = &lt;br /&gt;
   {{Game|Eye of the Beholder}}&lt;br /&gt;
   {{Game|Eye of the Beholder II: The Legend of Darkmoon}}&lt;br /&gt;
   {{Game|Lands of Lore: The Throne of Chaos}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;VCN&#039;&#039;&#039; file stores 8×8 image tiles that form the game&#039;s 3D view window, the “view cone.” These tiles are used to build the backdrop of a level (floor and ceiling), as well as the wall segments shown from different distances and angles.&lt;br /&gt;
&lt;br /&gt;
The VCN tiles are combined at runtime according to layout data in the corresponding &#039;&#039;&#039;VMP&#039;&#039;&#039; file, which defines how each wall and corridor segment is assembled from these tiles. Together, the VCN and VMP files generate the illusion of depth as the player moves through the grid-based dungeon. The VCN and VMP file are referenced in the level&#039;s &#039;&#039;&#039;INF&#039;&#039;&#039; file.&lt;br /&gt;
&lt;br /&gt;
The name &#039;&#039;&#039;VCN&#039;&#039;&#039; possibly stands for View Cone, referring to the visible area of the 3D viewport, or View Compressed Nibble, reflecting that each tile stores 4-bit (nibble) pixel data.&lt;br /&gt;
&lt;br /&gt;
== File Structure (PC version) ==&lt;br /&gt;
&lt;br /&gt;
In the PC version, VCN files are compressed, using the [[Westwood LCW]] compression (see [[Westwood CPS Format]]). In the demo, they are uncompressed. &lt;br /&gt;
&lt;br /&gt;
The uncompressed data has this structure:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset !! Size !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x00 || 2 bytes (LE) || Number of 8×8 tiles contained in the file.&lt;br /&gt;
|-&lt;br /&gt;
| 0x02 || 16 bytes || Backdrop palette – 16 color indices (0–255).&lt;br /&gt;
|-&lt;br /&gt;
| 0x12 || 16 bytes || Wall palette – 16 color indices (0–255).&lt;br /&gt;
|-&lt;br /&gt;
| 0x22 || 32 × N bytes || Pixel data for N tiles, each 8×8 pixels (4 bits per pixel, i.e. two pixels per byte).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
struct VCN {&lt;br /&gt;
    uint16_t tile_count;&lt;br /&gt;
    uint8_t  back_palette[16];&lt;br /&gt;
    uint8_t  wall_palette[16];&lt;br /&gt;
    struct Tile {&lt;br /&gt;
        uint8_t pixels[4][8]; // 8×8 pixels, 4 bytes per row&lt;br /&gt;
    } blocks[tile_count];&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;tile_count&#039;&#039;&#039; – Number of 8×8 tiles in the file.  &lt;br /&gt;
* &#039;&#039;&#039;back_palette&#039;&#039;&#039; – 16 palette indices used for backdrop tiles (floor/ceiling).  &lt;br /&gt;
* &#039;&#039;&#039;wall_palette&#039;&#039;&#039; – 16 palette indices used for wall tiles.  &lt;br /&gt;
* &#039;&#039;&#039;tiles&#039;&#039;&#039; – Array of tile data. Each byte encodes two 4-bit pixel indices.&lt;br /&gt;
&lt;br /&gt;
== Amiga Version (16-color planar) ==&lt;br /&gt;
&lt;br /&gt;
The Amiga version uses a slightly different layout and 5-bit planar graphics instead of nibble-packed pixels.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
struct VCN {&lt;br /&gt;
    uint16_t tile_count;&lt;br /&gt;
    uint16_t palette[16];&lt;br /&gt;
    struct Tile {&lt;br /&gt;
        uint8_t pixels[5][8];&lt;br /&gt;
    } tiles[tile_count];&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;tile_count&#039;&#039;&#039; – Number of tiles in the file.  &lt;br /&gt;
* &#039;&#039;&#039;palette&#039;&#039;&#039; – 16-entry palette in the same format as CPS files.  &lt;br /&gt;
:* Each entry replaces index [I]+1 in the global palette from `INVENT.CPS`.  &lt;br /&gt;
:* Colors of value `0x0000` are ignored.  &lt;br /&gt;
:* &#039;&#039;EOB2&#039;&#039; uses an external 32-color palette in $xRGB format.  &lt;br /&gt;
* &#039;&#039;&#039;tiles&#039;&#039;&#039; – Array of 8×8 planar tiles, 5 bitplanes deep.  &lt;br /&gt;
&lt;br /&gt;
Planar → chunky conversion example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
uint8_t chunky[8][8];&lt;br /&gt;
for (int y = 0; y &amp;lt; 8; y++)&lt;br /&gt;
  for (int x = 0; x &amp;lt; 8; x++) {&lt;br /&gt;
    int bit = 1 &amp;lt;&amp;lt; (7 - x);&lt;br /&gt;
    uint8_t data = 0;&lt;br /&gt;
    for (int plane = 0; plane &amp;lt; 5; plane++)&lt;br /&gt;
      if (rawPlanarData[plane][y] &amp;amp; bit) data |= (1 &amp;lt;&amp;lt; plane);&lt;br /&gt;
    chunky[y][x] = data;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Lands of Lore Version (128-color extended format) ==&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;Lands of Lore&#039;&#039; engine uses an extended variant of the VCN format supporting 128 colors and multiple palette tables.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
struct VCN {&lt;br /&gt;
    uint16_t tile_count;&lt;br /&gt;
    uint8_t  tile_palette_pos_table[tile_count];&lt;br /&gt;
    struct PosPaletteTables {&lt;br /&gt;
        uint8_t backdrop_wall_palettes[16];&lt;br /&gt;
    } pos_palette_tables[8];&lt;br /&gt;
    uint8_t palette[3*128]; // 128 colors, 24-bit&lt;br /&gt;
    struct Tile {&lt;br /&gt;
        uint8_t pixels[4][8];&lt;br /&gt;
    } tiles[tile_count];&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;tile_count&#039;&#039;&#039; – Number of 8×8 tiles.  &lt;br /&gt;
* &#039;&#039;&#039;tile_palette_pos_table&#039;&#039;&#039; – For each tile, an index (0–7) into the `pos_palette_tables`.  &lt;br /&gt;
* &#039;&#039;&#039;pos_palette_tables&#039;&#039;&#039; – 8 tables of 16 entries each, defining color positions within the 256-color master palette.  &lt;br /&gt;
* &#039;&#039;&#039;palette&#039;&#039;&#039; – Local 128-color palette (3 bytes per entry, EOB-format RGB).  &lt;br /&gt;
* &#039;&#039;&#039;tiles&#039;&#039;&#039; – Tile data (two pixels per byte).  &lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Notes&#039;&#039;&#039;&lt;br /&gt;
* PC and LoL versions use 4-bit “nibble” pixels; Amiga uses 5-bit planar data.  &lt;br /&gt;
* All versions rely on external palettes to map indices to RGB colors.  &lt;br /&gt;
* The number of blocks determines the total number of 8×8 tiles available for constructing the dungeon view.&lt;br /&gt;
&lt;br /&gt;
== Tiles ==&lt;br /&gt;
&lt;br /&gt;
The very first tile is fully transparent, 7 tilesets follow. The first are the tiles for the backdrop (ceiling/floor), then 6 different wall types (including doorways and stairs) follow.&lt;br /&gt;
&lt;br /&gt;
== Rendering ==&lt;br /&gt;
&lt;br /&gt;
Each 8×8 tile stores pixel values as &#039;&#039;&#039;palette indices&#039;&#039;&#039;, which are mapped in two steps:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;Local palette lookup&#039;&#039;&#039; – Each tile references either the &#039;&#039;&#039;backdrop palette&#039;&#039;&#039; or the &#039;&#039;&#039;wall palette&#039;&#039;&#039;. Which palette is used depends on the tile index, as specified by the VMP layout.&lt;br /&gt;
# &#039;&#039;&#039;Global palette lookup&#039;&#039;&#039; – The palette index is then used to select an actual RGB color from the &#039;&#039;&#039;level’s PAL file&#039;&#039;&#039; (e.g., BRICK.PAL), as specified in the level&#039;s INF file.&lt;br /&gt;
&lt;br /&gt;
=== Example (wall tile) ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
raw pixel byte = 0x53&lt;br /&gt;
→ high nibble = 5 → pixel 1&lt;br /&gt;
→ low nibble  = 3 → pixel 2&lt;br /&gt;
&lt;br /&gt;
Step 1: Local palette lookup&lt;br /&gt;
pixel 1: wall_palette[5] → 7&lt;br /&gt;
pixel 2: wall_palette[3] → 4&lt;br /&gt;
&lt;br /&gt;
Step 2: Global palette lookup&lt;br /&gt;
pixel 1 RGB = BRICK.PAL[7]&lt;br /&gt;
pixel 2 RGB = BRICK.PAL[4]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; A palette index of 0 is treated as &#039;&#039;transparent&#039;&#039;, and no pixel is drawn for that position in the viewport.&lt;br /&gt;
&lt;br /&gt;
== Relationship to INF, VMP, and PAL ==&lt;br /&gt;
&lt;br /&gt;
Each level in &#039;&#039;Eye of the Beholder&#039;&#039; references a set of resource files that define its appearance. The &#039;&#039;&#039;INF&#039;&#039;&#039; file serves as the level’s manifest, specifying which &#039;&#039;&#039;VNP&#039;&#039;&#039;, &#039;&#039;&#039;VCN&#039;&#039;&#039;, and &#039;&#039;&#039;PAL&#039;&#039;&#039; files to use.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;VCN&#039;&#039;&#039; – Contains the raw 8×8 tiles for walls and backdrop components.  &lt;br /&gt;
* &#039;&#039;&#039;VMP&#039;&#039;&#039; – Provides a layout map: it stores indices into the VCN file, defining which tile to place where in the view cone.  &lt;br /&gt;
* &#039;&#039;&#039;PAL&#039;&#039;&#039; – Defines the RGB colors corresponding to palette indices used in the VCN tiles.  &lt;br /&gt;
&lt;br /&gt;
Together, these files allow the engine to construct the &#039;&#039;&#039;view cone&#039;&#039;&#039; dynamically:&lt;br /&gt;
&lt;br /&gt;
# The VMP file tells the engine which 8×8 tiles from the VCN to use for each wall projection and the backdrop.  &lt;br /&gt;
# Each tile references either the backdrop or wall palette.  &lt;br /&gt;
# The palette indices are then mapped to RGB values from the level’s PAL file.  &lt;br /&gt;
# The engine combines the tiles according to the VMP layout to render the final 3D view.&lt;br /&gt;
&lt;br /&gt;
== Summary ==&lt;br /&gt;
&lt;br /&gt;
* Contains 8×8 nibble-encoded tiles.&lt;br /&gt;
* Uses two intermediate 16-color palettes (backdrop and wall) and PAL palette from level INF file.&lt;br /&gt;
* Indexed by matching VMP layout file.&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
* [[Eye of the Beholder VMP Format]] – layout map for assembling VCN tiles&lt;br /&gt;
* [[Eye of the Beholder Maze Information Format]] - level info file&lt;br /&gt;
* [[Eye of the Beholder PAL]] - palette format&lt;br /&gt;
* [[Westwood LCW]] – LCW compression format&lt;br /&gt;
* [[Westwood CPS Format]] – Reference for the compressed VCN format&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
https://web.archive.org/web/20180521003835/http://eob.wikispaces.com/eob.vcn&lt;/div&gt;</summary>
		<author><name>Fergusdog</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12632</id>
		<title>Eye of the Beholder VMP Format</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12632"/>
		<updated>2025-10-31T04:23:42Z</updated>

		<summary type="html">&lt;p&gt;Fergusdog: /* Sources */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NeedMoreInfo}}&lt;br /&gt;
{{Map Infobox&lt;br /&gt;
 | Type = 2D tile-based&lt;br /&gt;
 | Layers = 5&lt;br /&gt;
 | Tile size = 8&amp;amp;times;8&lt;br /&gt;
 | Viewport = 176&amp;amp;times;120&lt;br /&gt;
 | Games = &lt;br /&gt;
   {{Game|Eye of the Beholder}}&lt;br /&gt;
   {{Game|Eye of the Beholder II: The Legend of Darkmoon}}&lt;br /&gt;
   {{Game|Lands of Lore: The Throne of Chaos}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file assembles the tiles from the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset.&lt;br /&gt;
It functions similarly to a map file in other video games, except that in [[Eye of the Beholder]] it does not represent a top-down layout. Instead, it defines the 3D view of the dungeon, often referred to as the &#039;&#039;view cone&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
In essence, the &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file contains a collection of indices that reference tile graphics within the &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. These indices are interpreted by the game’s main executable to construct the player&#039;s first-person view of the world.&lt;br /&gt;
&lt;br /&gt;
== File Format (PC version) ==&lt;br /&gt;
&lt;br /&gt;
In [[Lands of Lore: The Throne of Chaos]], &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; files are compressed , using the [[Westwood LCW]] compression (see [[Westwood CPS Format]]).&lt;br /&gt;
The uncompressed format is defined as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short index_count; &lt;br /&gt;
    unsigned short indices[index_count]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each entry in &amp;lt;code&amp;gt;indices&amp;lt;/code&amp;gt; represents an index that references a specific block in the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. For more details on the index entries, see the [[#Tile Index|Tile Index]] section below.&lt;br /&gt;
&lt;br /&gt;
== File Format (Amiga version) ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short header; &lt;br /&gt;
    unsigned short backdrop_tiles[22][15]; &lt;br /&gt;
    unsigned short padding[101]; &lt;br /&gt;
    unsigned short wall_tiles[wall_types_count][431]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;header&amp;lt;/code&amp;gt;&lt;br /&gt;
: {{TODO|Not yet fully investigated, but most likely specifies the number of wall types defined in the file.}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;backdrop_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the static backdrop (ceiling/floor) image..&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;padding&amp;lt;/code&amp;gt;&lt;br /&gt;
: Each wall type uses 431 tile indices. To match this count for the backdrop tiles, a padding of 101 empty indices is added (&amp;lt;code&amp;gt;22 × 15 + 101 = 431&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the wall graphics for each wall type.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_types_count&amp;lt;/code&amp;gt;&lt;br /&gt;
: Probably stored in the header, but can also be calculated as: &amp;lt;code&amp;gt;(filesize - 2) / (431 * 2) - 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tile Index ==&lt;br /&gt;
&lt;br /&gt;
Each index is represented as a 16-bit value using the following bit structure (most significant bits first):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct TileIndex { &lt;br /&gt;
    bool z-mask: 1; &lt;br /&gt;
    bool mirror_x: 1; &lt;br /&gt;
    unsigned tile_index: 14; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;z-mask&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;, only draw onto the tranparent pixels of the tile(s) below. In effect, acts as a mask for z-order, so the drawn tile appears behind the tile being drawn over. {{TODO|Need to confirm, expand?}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;mirror_x&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; flip the tile horizontally.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;tile_index&amp;lt;/code&amp;gt;&lt;br /&gt;
: A 14-bit index selecting a specific tile from the corresponding &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset (see [[Eye of the Beholder VCN Format]]).&lt;br /&gt;
&lt;br /&gt;
== Rendering the View Cone ==&lt;br /&gt;
&lt;br /&gt;
The 3D view in [[Eye of the Beholder]] covers an area of &#039;&#039;&#039;22 × 15 tiles&#039;&#039;&#039; and is composed of five layers — the backdrop (ceiling and floor) and four wall layers. The backdrop is rendered first and provides the ceiling and floor as a single combined image. The wall layers are then drawn on top, alternating between front-facing and side-facing walls to construct the 3D perspective.&lt;br /&gt;
&lt;br /&gt;
The following diagram illustrates the layout of the view cone:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
Layer 5 (backdrop)  &lt;br /&gt;
                                  ─────────────────────────────────&lt;br /&gt;
Layer 4                               A | B | C | D | E | F | G &lt;br /&gt;
                                         ─── ─── ─── ─── ─── &lt;br /&gt;
Layer 3                                   H | I | J | K | L &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 2                                       M | N | O &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 1 (closest)                             P | ^ | Q  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The caret (&amp;lt;code&amp;gt;^&amp;lt;/code&amp;gt;) represents the party’s position. Vertical bars (&amp;lt;code&amp;gt;|&amp;lt;/code&amp;gt;) and overbars (&amp;lt;code&amp;gt;───&amp;lt;/code&amp;gt;) in the diagram denote walls at various distances.&lt;br /&gt;
&lt;br /&gt;
In total, there are 25 distinct wall positions within the player’s field of vision. To render all walls correctly, the engine must read 17 map cells (A–Q) from the dungeon layout.&lt;br /&gt;
&lt;br /&gt;
The first 22 x 15 = &#039;&#039;&#039;330&#039;&#039;&#039; tile indices are used for the backdrop. The background is horizontally flipped when &amp;lt;code&amp;gt;party.x &amp;amp; party.y &amp;amp; party.direction == 1&amp;lt;/code&amp;gt;. In other words, certain movements or rotations from the current position cause the background to appear mirrored.&lt;br /&gt;
&lt;br /&gt;
What follows are &#039;&#039;&#039;431&#039;&#039;&#039; tile indices per wall type. [[Eye of the Beholder]] has 6 different wall types: solid wall type 1, solid wall type 2, door frame, stairs up, stairs down and portal. The wall types are defined in the [[Eye of the Beholder Maze Format]] files. Each block in the MAZ file has wall information for all 4 walls (north, east, south, west) from which the wall type is inferred - for each wall in the level.&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;margin:auto;&amp;quot;&lt;br /&gt;
| [[File:BRICK bg.png|frame|Backdrop from BRICK.VMP]]&lt;br /&gt;
| [[File:BRICK wall 1.png|frame|Wall Type 1 from BRICK.VMP]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Render Code ==&lt;br /&gt;
&lt;br /&gt;
Pseudo code for rendering the background:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void drawBackground(bool xflip)&lt;br /&gt;
{&lt;br /&gt;
   for (int y=0; y&amp;lt;15; y++)&lt;br /&gt;
   {&lt;br /&gt;
      for (int x=0; x&amp;lt;22; x++)&lt;br /&gt;
      {&lt;br /&gt;
         int tile;&lt;br /&gt;
 &lt;br /&gt;
         if (xflip)&lt;br /&gt;
            tile=vmp.backgroundTiles[21-x][y];&lt;br /&gt;
         else&lt;br /&gt;
            tile=vmp.backgroundTiles[x][y];&lt;br /&gt;
 &lt;br /&gt;
         /* xor with xflip to make block flip and background flip cancel each other out. */&lt;br /&gt;
         int blockFlip = (tile&amp;amp;0x4000)^flipX;&lt;br /&gt;
         int blockIndex= tile&amp;amp;0x3fff;&lt;br /&gt;
 &lt;br /&gt;
         if (blockFlip)&lt;br /&gt;
            drawBlockXFlip(x*8, y*8, vcn.blocks[blockIndex]);&lt;br /&gt;
         else&lt;br /&gt;
            drawBlock(x*8, y*8, vcn.blocks[blockIndex]);&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To render the walls, we can use this structure:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
struct WallRenderData&lt;br /&gt;
{&lt;br /&gt;
   int baseOffset;&lt;br /&gt;
   int offsetInViewPort;&lt;br /&gt;
   int visibleWidthInBlocks;&lt;br /&gt;
   int visibleHeightInBlocks;&lt;br /&gt;
   int skipValue;&lt;br /&gt;
   int flipFlag;&lt;br /&gt;
} wallRenderData[25] /* 25 different wall positions */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;baseOffset&amp;lt;/code&amp;gt;&lt;br /&gt;
: Base offset into tileIndices[wallType-1]. This is an offset into the 431 index block for each wall type. So for stairs up (type 4) at position B the total offset would be 330 + (4-1) * 431 + 102 (see below).&lt;br /&gt;
; &amp;lt;code&amp;gt;offsetInViewPort&amp;lt;/code&amp;gt;&lt;br /&gt;
: Where to start rendering in the viewport:&lt;br /&gt;
: &amp;lt;code&amp;gt;xpos = offsetInViewPort % 22;&amp;lt;/code&amp;gt;&lt;br /&gt;
: &amp;lt;code&amp;gt;ypos = offsetInViewPort / 22;&amp;lt;/code&amp;gt;&lt;br /&gt;
; &amp;lt;code&amp;gt;visibleWidthInBlocks&amp;lt;/code&amp;gt;&lt;br /&gt;
: how many tiles to render in x direction.&lt;br /&gt;
; &amp;lt;code&amp;gt;visibleHeightInBlocks&amp;lt;/code&amp;gt;&lt;br /&gt;
: how many tiles to render in y direction.&lt;br /&gt;
; &amp;lt;code&amp;gt;skipValue&amp;lt;/code&amp;gt;&lt;br /&gt;
: Number of tiles to the next row in the tileIndices[wallType-1] array.&lt;br /&gt;
; &amp;lt;code&amp;gt;flipFlag&amp;lt;/code&amp;gt;&lt;br /&gt;
: &amp;lt;code&amp;gt;True&amp;lt;/code&amp;gt; if the wall is to be x-flipped in the viewport. Generally all right-walls are x-flipped.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
   /* Side-Walls left back */&lt;br /&gt;
   { 104, 66,  5,  1,  2, 0},             /* A-east */&lt;br /&gt;
   { 102, 68,  5,  3,  0, 0},             /* B-east */&lt;br /&gt;
   {  97, 74,  5,  1,  0, 0},             /* C-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side-Walls right back */&lt;br /&gt;
   {  97, 79,  5,  1,  0, 1},              /* E-west */&lt;br /&gt;
   { 102, 83,  5,  3,  0, 1},              /* F-west */&lt;br /&gt;
   { 104, 87,  5,  1,  2, 1},              /* G-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls back */&lt;br /&gt;
   { 133, 66,  5,  2,  4, 0},              /* B-south */&lt;br /&gt;
   { 129, 68,  5,  6,  0, 0},              /* C-south */&lt;br /&gt;
   { 129, 74,  5,  6,  0, 0},              /* D-south */&lt;br /&gt;
   { 129, 80,  5,  6,  0, 0},              /* E-south */&lt;br /&gt;
   { 129, 86,  5,  2,  4, 0},              /* F-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle back left */&lt;br /&gt;
   { 117, 66,  6,  2,  0, 0},              /* H-east */&lt;br /&gt;
   {  81, 50,  8,  2,  0, 0},              /* I-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle back right */&lt;br /&gt;
   {  81, 58,  8,  2,  0, 1},              /* K-west */&lt;br /&gt;
   { 117, 86,  6,  2,  0, 1},              /* L-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls middle back */&lt;br /&gt;
   { 163, 44,  8,  6,  4, 0},              /* I-south */&lt;br /&gt;
   { 159, 50,  8, 10,  0, 0},              /* J-south */&lt;br /&gt;
   { 159, 60,  8,  6,  4, 0},              /* K-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle front left */&lt;br /&gt;
   {  45, 25, 12,  3,  0, 0},              /* M-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle front right */&lt;br /&gt;
   {  45, 38, 12,  3,  0, 1},              /* O-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls middle front */&lt;br /&gt;
   { 252, 22, 12,  3, 13, 0},              /* M-south */&lt;br /&gt;
   { 239, 41, 12,  3, 13, 0},              /* O-south */&lt;br /&gt;
   { 239, 25, 12, 16,  0, 0},              /* N-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side wall front left */&lt;br /&gt;
   {  0,  0, 15,  3,  0, 0},              /* P-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side wall front right */&lt;br /&gt;
   {  0, 19, 15,  3,  0, 1},              /* Q-west */&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pseudo code for rendering a wall:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* wallType = wallType index aquired from the wallMapping[mazeByte].wallType. See the .inf file.&lt;br /&gt;
 * wallPosition = index to wall position in the viewport.&lt;br /&gt;
 */&lt;br /&gt;
void drawWall(int wallType, int wallPosition)&lt;br /&gt;
{&lt;br /&gt;
   /* 0x4000 because when x-ored with this flip flag in the tile data,&lt;br /&gt;
      the resulting flip state will be correct */&lt;br /&gt;
   int flipX=wallRenderData[wallPosition].flipFlag ? 0:0x4000;&lt;br /&gt;
   int offset=wallRenderData[wallPosition].baseOffset;&lt;br /&gt;
 &lt;br /&gt;
   for (int y=0; y&amp;lt;wallRenderData[wallPosition].visibleHeightInBlocks; y++)&lt;br /&gt;
   {&lt;br /&gt;
      for (int x=0; x&amp;lt;wallRenderData[wallPosition].visibleWidthInBlocks; x++)&lt;br /&gt;
      {&lt;br /&gt;
         int blockIndex;&lt;br /&gt;
         if (flipX==0)&lt;br /&gt;
         {&lt;br /&gt;
            blockIndex=x+y*22+wallRenderData[wallPosition].offsetInViewPort;&lt;br /&gt;
         }&lt;br /&gt;
         else&lt;br /&gt;
         {&lt;br /&gt;
            blockIndex=wallRenderData[wallPosition].offsetInViewPort+&lt;br /&gt;
                       wallRenderData[wallPosition].visibleWidthInBlocks-&lt;br /&gt;
                       1-&lt;br /&gt;
                       x+y*22;&lt;br /&gt;
         }&lt;br /&gt;
 &lt;br /&gt;
         int xpos=blockIndex%22;&lt;br /&gt;
         int ypos=blockIndex/22;&lt;br /&gt;
 &lt;br /&gt;
         int tile=vmp.wallTiles[wallType][offset];&lt;br /&gt;
 &lt;br /&gt;
         /* xor with wall flip-x to make block flip and wall flip cancel each other out. */&lt;br /&gt;
         int blockFlip = (tile&amp;amp;0x4000)^flipX;&lt;br /&gt;
         int blockIndex= tile&amp;amp;0x3fff;&lt;br /&gt;
 &lt;br /&gt;
         if (blockFlip)&lt;br /&gt;
            drawBlockXFlip(xpos*8, ypos*8, vcn.blocks[blockIndex]);&lt;br /&gt;
         else&lt;br /&gt;
            drawBlock(xpos*8, ypos*8, vcn.blocks[blockIndex]);&lt;br /&gt;
 &lt;br /&gt;
         offset++;&lt;br /&gt;
      }&lt;br /&gt;
      offset+=wallRenderData[wallPosition].skipValue;&lt;br /&gt;
   }&lt;br /&gt;
 &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Relationship to INF, VMP, and MAZ ==&lt;br /&gt;
&lt;br /&gt;
Each level in [[Eye of the Beholder]] references a set of resource files that define its appearance. The &#039;&#039;&#039;INF&#039;&#039;&#039; file serves as the level’s manifest, specifying which &#039;&#039;&#039;VNP&#039;&#039;&#039;, &#039;&#039;&#039;VCN&#039;&#039;&#039;, and &#039;&#039;&#039;MAZ&#039;&#039;&#039; files to use.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;VCN&#039;&#039;&#039; – Contains the raw 8×8 tiles for walls and backdrop components.  &lt;br /&gt;
* &#039;&#039;&#039;VMP&#039;&#039;&#039; – Provides a layout map: it stores indices into the VCN file, defining which tile to place where in the view cone.  &lt;br /&gt;
* &#039;&#039;&#039;MAZ&#039;&#039;&#039; – Defines the wall parameters for each wall in each block (north, east, south, west). From the wall parameters, the wall types are determined (type 1, type 2, doorway, stairs up, stairs down, portal).&lt;br /&gt;
&lt;br /&gt;
Together, these files allow the engine to construct the &#039;&#039;&#039;view cone&#039;&#039;&#039; dynamically:&lt;br /&gt;
&lt;br /&gt;
# The MAZ file tells the engine which wall type to use for which location. (Sidenote: this can be dynamically changed via scripts in the INF file, so the MAZ file only supplies initial values)&lt;br /&gt;
# The VMP file tells the engine which 8×8 tiles from the VCN to use for each wall projection and the backdrop.    &lt;br /&gt;
# The engine combines the tiles according to the VMP layout to render the final 3D view.&lt;br /&gt;
&lt;br /&gt;
== Summary ==&lt;br /&gt;
&lt;br /&gt;
* Defines the 3D dungeon view (“view cone”) by indexing tiles from the associated .VCN tileset.&lt;br /&gt;
* Contains 330 backdrop tile indices and 431 tile indices per wall type.&lt;br /&gt;
* Used together with VCN (tile graphics), MAZ (wall definitions), and INF (level manifest) files.&lt;br /&gt;
* Tile indices include bit flags for horizontal flip and z-mask rendering.&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
* [[Eye of the Beholder VCN Format]] – VCN tileset&lt;br /&gt;
* [[Eye of the Beholder Maze Information Format]] - level info file&lt;br /&gt;
* [[Eye of the Beholder Maze Format]] - maze file&lt;br /&gt;
* [[Westwood LCW]] – LCW compression format&lt;br /&gt;
* [[Westwood CPS Format]] – Reference for the compressed VCN format&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
&lt;br /&gt;
https://web.archive.org/web/20180521005936/http://eob.wikispaces.com/eob.vmp&lt;/div&gt;</summary>
		<author><name>Fergusdog</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12631</id>
		<title>Eye of the Beholder VMP Format</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12631"/>
		<updated>2025-10-31T04:22:50Z</updated>

		<summary type="html">&lt;p&gt;Fergusdog: /* See Also */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NeedMoreInfo}}&lt;br /&gt;
{{Map Infobox&lt;br /&gt;
 | Type = 2D tile-based&lt;br /&gt;
 | Layers = 5&lt;br /&gt;
 | Tile size = 8&amp;amp;times;8&lt;br /&gt;
 | Viewport = 176&amp;amp;times;120&lt;br /&gt;
 | Games = &lt;br /&gt;
   {{Game|Eye of the Beholder}}&lt;br /&gt;
   {{Game|Eye of the Beholder II: The Legend of Darkmoon}}&lt;br /&gt;
   {{Game|Lands of Lore: The Throne of Chaos}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file assembles the tiles from the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset.&lt;br /&gt;
It functions similarly to a map file in other video games, except that in [[Eye of the Beholder]] it does not represent a top-down layout. Instead, it defines the 3D view of the dungeon, often referred to as the &#039;&#039;view cone&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
In essence, the &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file contains a collection of indices that reference tile graphics within the &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. These indices are interpreted by the game’s main executable to construct the player&#039;s first-person view of the world.&lt;br /&gt;
&lt;br /&gt;
== File Format (PC version) ==&lt;br /&gt;
&lt;br /&gt;
In [[Lands of Lore: The Throne of Chaos]], &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; files are compressed , using the [[Westwood LCW]] compression (see [[Westwood CPS Format]]).&lt;br /&gt;
The uncompressed format is defined as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short index_count; &lt;br /&gt;
    unsigned short indices[index_count]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each entry in &amp;lt;code&amp;gt;indices&amp;lt;/code&amp;gt; represents an index that references a specific block in the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. For more details on the index entries, see the [[#Tile Index|Tile Index]] section below.&lt;br /&gt;
&lt;br /&gt;
== File Format (Amiga version) ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short header; &lt;br /&gt;
    unsigned short backdrop_tiles[22][15]; &lt;br /&gt;
    unsigned short padding[101]; &lt;br /&gt;
    unsigned short wall_tiles[wall_types_count][431]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;header&amp;lt;/code&amp;gt;&lt;br /&gt;
: {{TODO|Not yet fully investigated, but most likely specifies the number of wall types defined in the file.}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;backdrop_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the static backdrop (ceiling/floor) image..&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;padding&amp;lt;/code&amp;gt;&lt;br /&gt;
: Each wall type uses 431 tile indices. To match this count for the backdrop tiles, a padding of 101 empty indices is added (&amp;lt;code&amp;gt;22 × 15 + 101 = 431&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the wall graphics for each wall type.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_types_count&amp;lt;/code&amp;gt;&lt;br /&gt;
: Probably stored in the header, but can also be calculated as: &amp;lt;code&amp;gt;(filesize - 2) / (431 * 2) - 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tile Index ==&lt;br /&gt;
&lt;br /&gt;
Each index is represented as a 16-bit value using the following bit structure (most significant bits first):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct TileIndex { &lt;br /&gt;
    bool z-mask: 1; &lt;br /&gt;
    bool mirror_x: 1; &lt;br /&gt;
    unsigned tile_index: 14; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;z-mask&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;, only draw onto the tranparent pixels of the tile(s) below. In effect, acts as a mask for z-order, so the drawn tile appears behind the tile being drawn over. {{TODO|Need to confirm, expand?}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;mirror_x&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; flip the tile horizontally.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;tile_index&amp;lt;/code&amp;gt;&lt;br /&gt;
: A 14-bit index selecting a specific tile from the corresponding &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset (see [[Eye of the Beholder VCN Format]]).&lt;br /&gt;
&lt;br /&gt;
== Rendering the View Cone ==&lt;br /&gt;
&lt;br /&gt;
The 3D view in [[Eye of the Beholder]] covers an area of &#039;&#039;&#039;22 × 15 tiles&#039;&#039;&#039; and is composed of five layers — the backdrop (ceiling and floor) and four wall layers. The backdrop is rendered first and provides the ceiling and floor as a single combined image. The wall layers are then drawn on top, alternating between front-facing and side-facing walls to construct the 3D perspective.&lt;br /&gt;
&lt;br /&gt;
The following diagram illustrates the layout of the view cone:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
Layer 5 (backdrop)  &lt;br /&gt;
                                  ─────────────────────────────────&lt;br /&gt;
Layer 4                               A | B | C | D | E | F | G &lt;br /&gt;
                                         ─── ─── ─── ─── ─── &lt;br /&gt;
Layer 3                                   H | I | J | K | L &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 2                                       M | N | O &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 1 (closest)                             P | ^ | Q  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The caret (&amp;lt;code&amp;gt;^&amp;lt;/code&amp;gt;) represents the party’s position. Vertical bars (&amp;lt;code&amp;gt;|&amp;lt;/code&amp;gt;) and overbars (&amp;lt;code&amp;gt;───&amp;lt;/code&amp;gt;) in the diagram denote walls at various distances.&lt;br /&gt;
&lt;br /&gt;
In total, there are 25 distinct wall positions within the player’s field of vision. To render all walls correctly, the engine must read 17 map cells (A–Q) from the dungeon layout.&lt;br /&gt;
&lt;br /&gt;
The first 22 x 15 = &#039;&#039;&#039;330&#039;&#039;&#039; tile indices are used for the backdrop. The background is horizontally flipped when &amp;lt;code&amp;gt;party.x &amp;amp; party.y &amp;amp; party.direction == 1&amp;lt;/code&amp;gt;. In other words, certain movements or rotations from the current position cause the background to appear mirrored.&lt;br /&gt;
&lt;br /&gt;
What follows are &#039;&#039;&#039;431&#039;&#039;&#039; tile indices per wall type. [[Eye of the Beholder]] has 6 different wall types: solid wall type 1, solid wall type 2, door frame, stairs up, stairs down and portal. The wall types are defined in the [[Eye of the Beholder Maze Format]] files. Each block in the MAZ file has wall information for all 4 walls (north, east, south, west) from which the wall type is inferred - for each wall in the level.&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;margin:auto;&amp;quot;&lt;br /&gt;
| [[File:BRICK bg.png|frame|Backdrop from BRICK.VMP]]&lt;br /&gt;
| [[File:BRICK wall 1.png|frame|Wall Type 1 from BRICK.VMP]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Render Code ==&lt;br /&gt;
&lt;br /&gt;
Pseudo code for rendering the background:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void drawBackground(bool xflip)&lt;br /&gt;
{&lt;br /&gt;
   for (int y=0; y&amp;lt;15; y++)&lt;br /&gt;
   {&lt;br /&gt;
      for (int x=0; x&amp;lt;22; x++)&lt;br /&gt;
      {&lt;br /&gt;
         int tile;&lt;br /&gt;
 &lt;br /&gt;
         if (xflip)&lt;br /&gt;
            tile=vmp.backgroundTiles[21-x][y];&lt;br /&gt;
         else&lt;br /&gt;
            tile=vmp.backgroundTiles[x][y];&lt;br /&gt;
 &lt;br /&gt;
         /* xor with xflip to make block flip and background flip cancel each other out. */&lt;br /&gt;
         int blockFlip = (tile&amp;amp;0x4000)^flipX;&lt;br /&gt;
         int blockIndex= tile&amp;amp;0x3fff;&lt;br /&gt;
 &lt;br /&gt;
         if (blockFlip)&lt;br /&gt;
            drawBlockXFlip(x*8, y*8, vcn.blocks[blockIndex]);&lt;br /&gt;
         else&lt;br /&gt;
            drawBlock(x*8, y*8, vcn.blocks[blockIndex]);&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To render the walls, we can use this structure:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
struct WallRenderData&lt;br /&gt;
{&lt;br /&gt;
   int baseOffset;&lt;br /&gt;
   int offsetInViewPort;&lt;br /&gt;
   int visibleWidthInBlocks;&lt;br /&gt;
   int visibleHeightInBlocks;&lt;br /&gt;
   int skipValue;&lt;br /&gt;
   int flipFlag;&lt;br /&gt;
} wallRenderData[25] /* 25 different wall positions */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;baseOffset&amp;lt;/code&amp;gt;&lt;br /&gt;
: Base offset into tileIndices[wallType-1]. This is an offset into the 431 index block for each wall type. So for stairs up (type 4) at position B the total offset would be 330 + (4-1) * 431 + 102 (see below).&lt;br /&gt;
; &amp;lt;code&amp;gt;offsetInViewPort&amp;lt;/code&amp;gt;&lt;br /&gt;
: Where to start rendering in the viewport:&lt;br /&gt;
: &amp;lt;code&amp;gt;xpos = offsetInViewPort % 22;&amp;lt;/code&amp;gt;&lt;br /&gt;
: &amp;lt;code&amp;gt;ypos = offsetInViewPort / 22;&amp;lt;/code&amp;gt;&lt;br /&gt;
; &amp;lt;code&amp;gt;visibleWidthInBlocks&amp;lt;/code&amp;gt;&lt;br /&gt;
: how many tiles to render in x direction.&lt;br /&gt;
; &amp;lt;code&amp;gt;visibleHeightInBlocks&amp;lt;/code&amp;gt;&lt;br /&gt;
: how many tiles to render in y direction.&lt;br /&gt;
; &amp;lt;code&amp;gt;skipValue&amp;lt;/code&amp;gt;&lt;br /&gt;
: Number of tiles to the next row in the tileIndices[wallType-1] array.&lt;br /&gt;
; &amp;lt;code&amp;gt;flipFlag&amp;lt;/code&amp;gt;&lt;br /&gt;
: &amp;lt;code&amp;gt;True&amp;lt;/code&amp;gt; if the wall is to be x-flipped in the viewport. Generally all right-walls are x-flipped.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
   /* Side-Walls left back */&lt;br /&gt;
   { 104, 66,  5,  1,  2, 0},             /* A-east */&lt;br /&gt;
   { 102, 68,  5,  3,  0, 0},             /* B-east */&lt;br /&gt;
   {  97, 74,  5,  1,  0, 0},             /* C-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side-Walls right back */&lt;br /&gt;
   {  97, 79,  5,  1,  0, 1},              /* E-west */&lt;br /&gt;
   { 102, 83,  5,  3,  0, 1},              /* F-west */&lt;br /&gt;
   { 104, 87,  5,  1,  2, 1},              /* G-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls back */&lt;br /&gt;
   { 133, 66,  5,  2,  4, 0},              /* B-south */&lt;br /&gt;
   { 129, 68,  5,  6,  0, 0},              /* C-south */&lt;br /&gt;
   { 129, 74,  5,  6,  0, 0},              /* D-south */&lt;br /&gt;
   { 129, 80,  5,  6,  0, 0},              /* E-south */&lt;br /&gt;
   { 129, 86,  5,  2,  4, 0},              /* F-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle back left */&lt;br /&gt;
   { 117, 66,  6,  2,  0, 0},              /* H-east */&lt;br /&gt;
   {  81, 50,  8,  2,  0, 0},              /* I-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle back right */&lt;br /&gt;
   {  81, 58,  8,  2,  0, 1},              /* K-west */&lt;br /&gt;
   { 117, 86,  6,  2,  0, 1},              /* L-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls middle back */&lt;br /&gt;
   { 163, 44,  8,  6,  4, 0},              /* I-south */&lt;br /&gt;
   { 159, 50,  8, 10,  0, 0},              /* J-south */&lt;br /&gt;
   { 159, 60,  8,  6,  4, 0},              /* K-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle front left */&lt;br /&gt;
   {  45, 25, 12,  3,  0, 0},              /* M-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle front right */&lt;br /&gt;
   {  45, 38, 12,  3,  0, 1},              /* O-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls middle front */&lt;br /&gt;
   { 252, 22, 12,  3, 13, 0},              /* M-south */&lt;br /&gt;
   { 239, 41, 12,  3, 13, 0},              /* O-south */&lt;br /&gt;
   { 239, 25, 12, 16,  0, 0},              /* N-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side wall front left */&lt;br /&gt;
   {  0,  0, 15,  3,  0, 0},              /* P-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side wall front right */&lt;br /&gt;
   {  0, 19, 15,  3,  0, 1},              /* Q-west */&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pseudo code for rendering a wall:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* wallType = wallType index aquired from the wallMapping[mazeByte].wallType. See the .inf file.&lt;br /&gt;
 * wallPosition = index to wall position in the viewport.&lt;br /&gt;
 */&lt;br /&gt;
void drawWall(int wallType, int wallPosition)&lt;br /&gt;
{&lt;br /&gt;
   /* 0x4000 because when x-ored with this flip flag in the tile data,&lt;br /&gt;
      the resulting flip state will be correct */&lt;br /&gt;
   int flipX=wallRenderData[wallPosition].flipFlag ? 0:0x4000;&lt;br /&gt;
   int offset=wallRenderData[wallPosition].baseOffset;&lt;br /&gt;
 &lt;br /&gt;
   for (int y=0; y&amp;lt;wallRenderData[wallPosition].visibleHeightInBlocks; y++)&lt;br /&gt;
   {&lt;br /&gt;
      for (int x=0; x&amp;lt;wallRenderData[wallPosition].visibleWidthInBlocks; x++)&lt;br /&gt;
      {&lt;br /&gt;
         int blockIndex;&lt;br /&gt;
         if (flipX==0)&lt;br /&gt;
         {&lt;br /&gt;
            blockIndex=x+y*22+wallRenderData[wallPosition].offsetInViewPort;&lt;br /&gt;
         }&lt;br /&gt;
         else&lt;br /&gt;
         {&lt;br /&gt;
            blockIndex=wallRenderData[wallPosition].offsetInViewPort+&lt;br /&gt;
                       wallRenderData[wallPosition].visibleWidthInBlocks-&lt;br /&gt;
                       1-&lt;br /&gt;
                       x+y*22;&lt;br /&gt;
         }&lt;br /&gt;
 &lt;br /&gt;
         int xpos=blockIndex%22;&lt;br /&gt;
         int ypos=blockIndex/22;&lt;br /&gt;
 &lt;br /&gt;
         int tile=vmp.wallTiles[wallType][offset];&lt;br /&gt;
 &lt;br /&gt;
         /* xor with wall flip-x to make block flip and wall flip cancel each other out. */&lt;br /&gt;
         int blockFlip = (tile&amp;amp;0x4000)^flipX;&lt;br /&gt;
         int blockIndex= tile&amp;amp;0x3fff;&lt;br /&gt;
 &lt;br /&gt;
         if (blockFlip)&lt;br /&gt;
            drawBlockXFlip(xpos*8, ypos*8, vcn.blocks[blockIndex]);&lt;br /&gt;
         else&lt;br /&gt;
            drawBlock(xpos*8, ypos*8, vcn.blocks[blockIndex]);&lt;br /&gt;
 &lt;br /&gt;
         offset++;&lt;br /&gt;
      }&lt;br /&gt;
      offset+=wallRenderData[wallPosition].skipValue;&lt;br /&gt;
   }&lt;br /&gt;
 &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Relationship to INF, VMP, and MAZ ==&lt;br /&gt;
&lt;br /&gt;
Each level in [[Eye of the Beholder]] references a set of resource files that define its appearance. The &#039;&#039;&#039;INF&#039;&#039;&#039; file serves as the level’s manifest, specifying which &#039;&#039;&#039;VNP&#039;&#039;&#039;, &#039;&#039;&#039;VCN&#039;&#039;&#039;, and &#039;&#039;&#039;MAZ&#039;&#039;&#039; files to use.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;VCN&#039;&#039;&#039; – Contains the raw 8×8 tiles for walls and backdrop components.  &lt;br /&gt;
* &#039;&#039;&#039;VMP&#039;&#039;&#039; – Provides a layout map: it stores indices into the VCN file, defining which tile to place where in the view cone.  &lt;br /&gt;
* &#039;&#039;&#039;MAZ&#039;&#039;&#039; – Defines the wall parameters for each wall in each block (north, east, south, west). From the wall parameters, the wall types are determined (type 1, type 2, doorway, stairs up, stairs down, portal).&lt;br /&gt;
&lt;br /&gt;
Together, these files allow the engine to construct the &#039;&#039;&#039;view cone&#039;&#039;&#039; dynamically:&lt;br /&gt;
&lt;br /&gt;
# The MAZ file tells the engine which wall type to use for which location. (Sidenote: this can be dynamically changed via scripts in the INF file, so the MAZ file only supplies initial values)&lt;br /&gt;
# The VMP file tells the engine which 8×8 tiles from the VCN to use for each wall projection and the backdrop.    &lt;br /&gt;
# The engine combines the tiles according to the VMP layout to render the final 3D view.&lt;br /&gt;
&lt;br /&gt;
== Summary ==&lt;br /&gt;
&lt;br /&gt;
* Defines the 3D dungeon view (“view cone”) by indexing tiles from the associated .VCN tileset.&lt;br /&gt;
* Contains 330 backdrop tile indices and 431 tile indices per wall type.&lt;br /&gt;
* Used together with VCN (tile graphics), MAZ (wall definitions), and INF (level manifest) files.&lt;br /&gt;
* Tile indices include bit flags for horizontal flip and z-mask rendering.&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
* [[Eye of the Beholder VCN Format]] – VCN tileset&lt;br /&gt;
* [[Eye of the Beholder Maze Information Format]] - level info file&lt;br /&gt;
* [[Eye of the Beholder Maze Format]] - maze file&lt;br /&gt;
* [[Westwood LCW]] – LCW compression format&lt;br /&gt;
* [[Westwood CPS Format]] – Reference for the compressed VCN format&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
&lt;br /&gt;
[[https://web.archive.org/web/20180521005936/http://eob.wikispaces.com/eob.vmp]]&lt;/div&gt;</summary>
		<author><name>Fergusdog</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12630</id>
		<title>Eye of the Beholder VMP Format</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12630"/>
		<updated>2025-10-31T04:21:23Z</updated>

		<summary type="html">&lt;p&gt;Fergusdog: /* See Also */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NeedMoreInfo}}&lt;br /&gt;
{{Map Infobox&lt;br /&gt;
 | Type = 2D tile-based&lt;br /&gt;
 | Layers = 5&lt;br /&gt;
 | Tile size = 8&amp;amp;times;8&lt;br /&gt;
 | Viewport = 176&amp;amp;times;120&lt;br /&gt;
 | Games = &lt;br /&gt;
   {{Game|Eye of the Beholder}}&lt;br /&gt;
   {{Game|Eye of the Beholder II: The Legend of Darkmoon}}&lt;br /&gt;
   {{Game|Lands of Lore: The Throne of Chaos}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file assembles the tiles from the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset.&lt;br /&gt;
It functions similarly to a map file in other video games, except that in [[Eye of the Beholder]] it does not represent a top-down layout. Instead, it defines the 3D view of the dungeon, often referred to as the &#039;&#039;view cone&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
In essence, the &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file contains a collection of indices that reference tile graphics within the &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. These indices are interpreted by the game’s main executable to construct the player&#039;s first-person view of the world.&lt;br /&gt;
&lt;br /&gt;
== File Format (PC version) ==&lt;br /&gt;
&lt;br /&gt;
In [[Lands of Lore: The Throne of Chaos]], &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; files are compressed , using the [[Westwood LCW]] compression (see [[Westwood CPS Format]]).&lt;br /&gt;
The uncompressed format is defined as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short index_count; &lt;br /&gt;
    unsigned short indices[index_count]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each entry in &amp;lt;code&amp;gt;indices&amp;lt;/code&amp;gt; represents an index that references a specific block in the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. For more details on the index entries, see the [[#Tile Index|Tile Index]] section below.&lt;br /&gt;
&lt;br /&gt;
== File Format (Amiga version) ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short header; &lt;br /&gt;
    unsigned short backdrop_tiles[22][15]; &lt;br /&gt;
    unsigned short padding[101]; &lt;br /&gt;
    unsigned short wall_tiles[wall_types_count][431]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;header&amp;lt;/code&amp;gt;&lt;br /&gt;
: {{TODO|Not yet fully investigated, but most likely specifies the number of wall types defined in the file.}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;backdrop_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the static backdrop (ceiling/floor) image..&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;padding&amp;lt;/code&amp;gt;&lt;br /&gt;
: Each wall type uses 431 tile indices. To match this count for the backdrop tiles, a padding of 101 empty indices is added (&amp;lt;code&amp;gt;22 × 15 + 101 = 431&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the wall graphics for each wall type.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_types_count&amp;lt;/code&amp;gt;&lt;br /&gt;
: Probably stored in the header, but can also be calculated as: &amp;lt;code&amp;gt;(filesize - 2) / (431 * 2) - 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tile Index ==&lt;br /&gt;
&lt;br /&gt;
Each index is represented as a 16-bit value using the following bit structure (most significant bits first):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct TileIndex { &lt;br /&gt;
    bool z-mask: 1; &lt;br /&gt;
    bool mirror_x: 1; &lt;br /&gt;
    unsigned tile_index: 14; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;z-mask&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;, only draw onto the tranparent pixels of the tile(s) below. In effect, acts as a mask for z-order, so the drawn tile appears behind the tile being drawn over. {{TODO|Need to confirm, expand?}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;mirror_x&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; flip the tile horizontally.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;tile_index&amp;lt;/code&amp;gt;&lt;br /&gt;
: A 14-bit index selecting a specific tile from the corresponding &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset (see [[Eye of the Beholder VCN Format]]).&lt;br /&gt;
&lt;br /&gt;
== Rendering the View Cone ==&lt;br /&gt;
&lt;br /&gt;
The 3D view in [[Eye of the Beholder]] covers an area of &#039;&#039;&#039;22 × 15 tiles&#039;&#039;&#039; and is composed of five layers — the backdrop (ceiling and floor) and four wall layers. The backdrop is rendered first and provides the ceiling and floor as a single combined image. The wall layers are then drawn on top, alternating between front-facing and side-facing walls to construct the 3D perspective.&lt;br /&gt;
&lt;br /&gt;
The following diagram illustrates the layout of the view cone:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
Layer 5 (backdrop)  &lt;br /&gt;
                                  ─────────────────────────────────&lt;br /&gt;
Layer 4                               A | B | C | D | E | F | G &lt;br /&gt;
                                         ─── ─── ─── ─── ─── &lt;br /&gt;
Layer 3                                   H | I | J | K | L &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 2                                       M | N | O &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 1 (closest)                             P | ^ | Q  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The caret (&amp;lt;code&amp;gt;^&amp;lt;/code&amp;gt;) represents the party’s position. Vertical bars (&amp;lt;code&amp;gt;|&amp;lt;/code&amp;gt;) and overbars (&amp;lt;code&amp;gt;───&amp;lt;/code&amp;gt;) in the diagram denote walls at various distances.&lt;br /&gt;
&lt;br /&gt;
In total, there are 25 distinct wall positions within the player’s field of vision. To render all walls correctly, the engine must read 17 map cells (A–Q) from the dungeon layout.&lt;br /&gt;
&lt;br /&gt;
The first 22 x 15 = &#039;&#039;&#039;330&#039;&#039;&#039; tile indices are used for the backdrop. The background is horizontally flipped when &amp;lt;code&amp;gt;party.x &amp;amp; party.y &amp;amp; party.direction == 1&amp;lt;/code&amp;gt;. In other words, certain movements or rotations from the current position cause the background to appear mirrored.&lt;br /&gt;
&lt;br /&gt;
What follows are &#039;&#039;&#039;431&#039;&#039;&#039; tile indices per wall type. [[Eye of the Beholder]] has 6 different wall types: solid wall type 1, solid wall type 2, door frame, stairs up, stairs down and portal. The wall types are defined in the [[Eye of the Beholder Maze Format]] files. Each block in the MAZ file has wall information for all 4 walls (north, east, south, west) from which the wall type is inferred - for each wall in the level.&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;margin:auto;&amp;quot;&lt;br /&gt;
| [[File:BRICK bg.png|frame|Backdrop from BRICK.VMP]]&lt;br /&gt;
| [[File:BRICK wall 1.png|frame|Wall Type 1 from BRICK.VMP]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Render Code ==&lt;br /&gt;
&lt;br /&gt;
Pseudo code for rendering the background:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void drawBackground(bool xflip)&lt;br /&gt;
{&lt;br /&gt;
   for (int y=0; y&amp;lt;15; y++)&lt;br /&gt;
   {&lt;br /&gt;
      for (int x=0; x&amp;lt;22; x++)&lt;br /&gt;
      {&lt;br /&gt;
         int tile;&lt;br /&gt;
 &lt;br /&gt;
         if (xflip)&lt;br /&gt;
            tile=vmp.backgroundTiles[21-x][y];&lt;br /&gt;
         else&lt;br /&gt;
            tile=vmp.backgroundTiles[x][y];&lt;br /&gt;
 &lt;br /&gt;
         /* xor with xflip to make block flip and background flip cancel each other out. */&lt;br /&gt;
         int blockFlip = (tile&amp;amp;0x4000)^flipX;&lt;br /&gt;
         int blockIndex= tile&amp;amp;0x3fff;&lt;br /&gt;
 &lt;br /&gt;
         if (blockFlip)&lt;br /&gt;
            drawBlockXFlip(x*8, y*8, vcn.blocks[blockIndex]);&lt;br /&gt;
         else&lt;br /&gt;
            drawBlock(x*8, y*8, vcn.blocks[blockIndex]);&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To render the walls, we can use this structure:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
struct WallRenderData&lt;br /&gt;
{&lt;br /&gt;
   int baseOffset;&lt;br /&gt;
   int offsetInViewPort;&lt;br /&gt;
   int visibleWidthInBlocks;&lt;br /&gt;
   int visibleHeightInBlocks;&lt;br /&gt;
   int skipValue;&lt;br /&gt;
   int flipFlag;&lt;br /&gt;
} wallRenderData[25] /* 25 different wall positions */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;baseOffset&amp;lt;/code&amp;gt;&lt;br /&gt;
: Base offset into tileIndices[wallType-1]. This is an offset into the 431 index block for each wall type. So for stairs up (type 4) at position B the total offset would be 330 + (4-1) * 431 + 102 (see below).&lt;br /&gt;
; &amp;lt;code&amp;gt;offsetInViewPort&amp;lt;/code&amp;gt;&lt;br /&gt;
: Where to start rendering in the viewport:&lt;br /&gt;
: &amp;lt;code&amp;gt;xpos = offsetInViewPort % 22;&amp;lt;/code&amp;gt;&lt;br /&gt;
: &amp;lt;code&amp;gt;ypos = offsetInViewPort / 22;&amp;lt;/code&amp;gt;&lt;br /&gt;
; &amp;lt;code&amp;gt;visibleWidthInBlocks&amp;lt;/code&amp;gt;&lt;br /&gt;
: how many tiles to render in x direction.&lt;br /&gt;
; &amp;lt;code&amp;gt;visibleHeightInBlocks&amp;lt;/code&amp;gt;&lt;br /&gt;
: how many tiles to render in y direction.&lt;br /&gt;
; &amp;lt;code&amp;gt;skipValue&amp;lt;/code&amp;gt;&lt;br /&gt;
: Number of tiles to the next row in the tileIndices[wallType-1] array.&lt;br /&gt;
; &amp;lt;code&amp;gt;flipFlag&amp;lt;/code&amp;gt;&lt;br /&gt;
: &amp;lt;code&amp;gt;True&amp;lt;/code&amp;gt; if the wall is to be x-flipped in the viewport. Generally all right-walls are x-flipped.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
   /* Side-Walls left back */&lt;br /&gt;
   { 104, 66,  5,  1,  2, 0},             /* A-east */&lt;br /&gt;
   { 102, 68,  5,  3,  0, 0},             /* B-east */&lt;br /&gt;
   {  97, 74,  5,  1,  0, 0},             /* C-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side-Walls right back */&lt;br /&gt;
   {  97, 79,  5,  1,  0, 1},              /* E-west */&lt;br /&gt;
   { 102, 83,  5,  3,  0, 1},              /* F-west */&lt;br /&gt;
   { 104, 87,  5,  1,  2, 1},              /* G-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls back */&lt;br /&gt;
   { 133, 66,  5,  2,  4, 0},              /* B-south */&lt;br /&gt;
   { 129, 68,  5,  6,  0, 0},              /* C-south */&lt;br /&gt;
   { 129, 74,  5,  6,  0, 0},              /* D-south */&lt;br /&gt;
   { 129, 80,  5,  6,  0, 0},              /* E-south */&lt;br /&gt;
   { 129, 86,  5,  2,  4, 0},              /* F-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle back left */&lt;br /&gt;
   { 117, 66,  6,  2,  0, 0},              /* H-east */&lt;br /&gt;
   {  81, 50,  8,  2,  0, 0},              /* I-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle back right */&lt;br /&gt;
   {  81, 58,  8,  2,  0, 1},              /* K-west */&lt;br /&gt;
   { 117, 86,  6,  2,  0, 1},              /* L-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls middle back */&lt;br /&gt;
   { 163, 44,  8,  6,  4, 0},              /* I-south */&lt;br /&gt;
   { 159, 50,  8, 10,  0, 0},              /* J-south */&lt;br /&gt;
   { 159, 60,  8,  6,  4, 0},              /* K-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle front left */&lt;br /&gt;
   {  45, 25, 12,  3,  0, 0},              /* M-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle front right */&lt;br /&gt;
   {  45, 38, 12,  3,  0, 1},              /* O-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls middle front */&lt;br /&gt;
   { 252, 22, 12,  3, 13, 0},              /* M-south */&lt;br /&gt;
   { 239, 41, 12,  3, 13, 0},              /* O-south */&lt;br /&gt;
   { 239, 25, 12, 16,  0, 0},              /* N-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side wall front left */&lt;br /&gt;
   {  0,  0, 15,  3,  0, 0},              /* P-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side wall front right */&lt;br /&gt;
   {  0, 19, 15,  3,  0, 1},              /* Q-west */&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pseudo code for rendering a wall:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* wallType = wallType index aquired from the wallMapping[mazeByte].wallType. See the .inf file.&lt;br /&gt;
 * wallPosition = index to wall position in the viewport.&lt;br /&gt;
 */&lt;br /&gt;
void drawWall(int wallType, int wallPosition)&lt;br /&gt;
{&lt;br /&gt;
   /* 0x4000 because when x-ored with this flip flag in the tile data,&lt;br /&gt;
      the resulting flip state will be correct */&lt;br /&gt;
   int flipX=wallRenderData[wallPosition].flipFlag ? 0:0x4000;&lt;br /&gt;
   int offset=wallRenderData[wallPosition].baseOffset;&lt;br /&gt;
 &lt;br /&gt;
   for (int y=0; y&amp;lt;wallRenderData[wallPosition].visibleHeightInBlocks; y++)&lt;br /&gt;
   {&lt;br /&gt;
      for (int x=0; x&amp;lt;wallRenderData[wallPosition].visibleWidthInBlocks; x++)&lt;br /&gt;
      {&lt;br /&gt;
         int blockIndex;&lt;br /&gt;
         if (flipX==0)&lt;br /&gt;
         {&lt;br /&gt;
            blockIndex=x+y*22+wallRenderData[wallPosition].offsetInViewPort;&lt;br /&gt;
         }&lt;br /&gt;
         else&lt;br /&gt;
         {&lt;br /&gt;
            blockIndex=wallRenderData[wallPosition].offsetInViewPort+&lt;br /&gt;
                       wallRenderData[wallPosition].visibleWidthInBlocks-&lt;br /&gt;
                       1-&lt;br /&gt;
                       x+y*22;&lt;br /&gt;
         }&lt;br /&gt;
 &lt;br /&gt;
         int xpos=blockIndex%22;&lt;br /&gt;
         int ypos=blockIndex/22;&lt;br /&gt;
 &lt;br /&gt;
         int tile=vmp.wallTiles[wallType][offset];&lt;br /&gt;
 &lt;br /&gt;
         /* xor with wall flip-x to make block flip and wall flip cancel each other out. */&lt;br /&gt;
         int blockFlip = (tile&amp;amp;0x4000)^flipX;&lt;br /&gt;
         int blockIndex= tile&amp;amp;0x3fff;&lt;br /&gt;
 &lt;br /&gt;
         if (blockFlip)&lt;br /&gt;
            drawBlockXFlip(xpos*8, ypos*8, vcn.blocks[blockIndex]);&lt;br /&gt;
         else&lt;br /&gt;
            drawBlock(xpos*8, ypos*8, vcn.blocks[blockIndex]);&lt;br /&gt;
 &lt;br /&gt;
         offset++;&lt;br /&gt;
      }&lt;br /&gt;
      offset+=wallRenderData[wallPosition].skipValue;&lt;br /&gt;
   }&lt;br /&gt;
 &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Relationship to INF, VMP, and MAZ ==&lt;br /&gt;
&lt;br /&gt;
Each level in [[Eye of the Beholder]] references a set of resource files that define its appearance. The &#039;&#039;&#039;INF&#039;&#039;&#039; file serves as the level’s manifest, specifying which &#039;&#039;&#039;VNP&#039;&#039;&#039;, &#039;&#039;&#039;VCN&#039;&#039;&#039;, and &#039;&#039;&#039;MAZ&#039;&#039;&#039; files to use.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;VCN&#039;&#039;&#039; – Contains the raw 8×8 tiles for walls and backdrop components.  &lt;br /&gt;
* &#039;&#039;&#039;VMP&#039;&#039;&#039; – Provides a layout map: it stores indices into the VCN file, defining which tile to place where in the view cone.  &lt;br /&gt;
* &#039;&#039;&#039;MAZ&#039;&#039;&#039; – Defines the wall parameters for each wall in each block (north, east, south, west). From the wall parameters, the wall types are determined (type 1, type 2, doorway, stairs up, stairs down, portal).&lt;br /&gt;
&lt;br /&gt;
Together, these files allow the engine to construct the &#039;&#039;&#039;view cone&#039;&#039;&#039; dynamically:&lt;br /&gt;
&lt;br /&gt;
# The MAZ file tells the engine which wall type to use for which location. (Sidenote: this can be dynamically changed via scripts in the INF file, so the MAZ file only supplies initial values)&lt;br /&gt;
# The VMP file tells the engine which 8×8 tiles from the VCN to use for each wall projection and the backdrop.    &lt;br /&gt;
# The engine combines the tiles according to the VMP layout to render the final 3D view.&lt;br /&gt;
&lt;br /&gt;
== Summary ==&lt;br /&gt;
&lt;br /&gt;
* Defines the 3D dungeon view (“view cone”) by indexing tiles from the associated .VCN tileset.&lt;br /&gt;
* Contains 330 backdrop tile indices and 431 tile indices per wall type.&lt;br /&gt;
* Used together with VCN (tile graphics), MAZ (wall definitions), and INF (level manifest) files.&lt;br /&gt;
* Tile indices include bit flags for horizontal flip and z-mask rendering.&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
* [[Eye of the Beholder VCN Format]] – VCN tileset&lt;br /&gt;
* [[Eye of the Beholder Maze Information Format]] - level info file&lt;br /&gt;
* [[Eye of the Beholder Maze Format]] - maze file&lt;br /&gt;
* [[Westwood LCW]] – LCW compression format&lt;br /&gt;
* [[Westwood CPS Format]] – Reference for the compressed VCN format&lt;/div&gt;</summary>
		<author><name>Fergusdog</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12629</id>
		<title>Eye of the Beholder VMP Format</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12629"/>
		<updated>2025-10-31T04:20:54Z</updated>

		<summary type="html">&lt;p&gt;Fergusdog: /* Summary */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NeedMoreInfo}}&lt;br /&gt;
{{Map Infobox&lt;br /&gt;
 | Type = 2D tile-based&lt;br /&gt;
 | Layers = 5&lt;br /&gt;
 | Tile size = 8&amp;amp;times;8&lt;br /&gt;
 | Viewport = 176&amp;amp;times;120&lt;br /&gt;
 | Games = &lt;br /&gt;
   {{Game|Eye of the Beholder}}&lt;br /&gt;
   {{Game|Eye of the Beholder II: The Legend of Darkmoon}}&lt;br /&gt;
   {{Game|Lands of Lore: The Throne of Chaos}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file assembles the tiles from the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset.&lt;br /&gt;
It functions similarly to a map file in other video games, except that in [[Eye of the Beholder]] it does not represent a top-down layout. Instead, it defines the 3D view of the dungeon, often referred to as the &#039;&#039;view cone&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
In essence, the &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file contains a collection of indices that reference tile graphics within the &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. These indices are interpreted by the game’s main executable to construct the player&#039;s first-person view of the world.&lt;br /&gt;
&lt;br /&gt;
== File Format (PC version) ==&lt;br /&gt;
&lt;br /&gt;
In [[Lands of Lore: The Throne of Chaos]], &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; files are compressed , using the [[Westwood LCW]] compression (see [[Westwood CPS Format]]).&lt;br /&gt;
The uncompressed format is defined as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short index_count; &lt;br /&gt;
    unsigned short indices[index_count]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each entry in &amp;lt;code&amp;gt;indices&amp;lt;/code&amp;gt; represents an index that references a specific block in the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. For more details on the index entries, see the [[#Tile Index|Tile Index]] section below.&lt;br /&gt;
&lt;br /&gt;
== File Format (Amiga version) ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short header; &lt;br /&gt;
    unsigned short backdrop_tiles[22][15]; &lt;br /&gt;
    unsigned short padding[101]; &lt;br /&gt;
    unsigned short wall_tiles[wall_types_count][431]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;header&amp;lt;/code&amp;gt;&lt;br /&gt;
: {{TODO|Not yet fully investigated, but most likely specifies the number of wall types defined in the file.}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;backdrop_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the static backdrop (ceiling/floor) image..&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;padding&amp;lt;/code&amp;gt;&lt;br /&gt;
: Each wall type uses 431 tile indices. To match this count for the backdrop tiles, a padding of 101 empty indices is added (&amp;lt;code&amp;gt;22 × 15 + 101 = 431&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the wall graphics for each wall type.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_types_count&amp;lt;/code&amp;gt;&lt;br /&gt;
: Probably stored in the header, but can also be calculated as: &amp;lt;code&amp;gt;(filesize - 2) / (431 * 2) - 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tile Index ==&lt;br /&gt;
&lt;br /&gt;
Each index is represented as a 16-bit value using the following bit structure (most significant bits first):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct TileIndex { &lt;br /&gt;
    bool z-mask: 1; &lt;br /&gt;
    bool mirror_x: 1; &lt;br /&gt;
    unsigned tile_index: 14; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;z-mask&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;, only draw onto the tranparent pixels of the tile(s) below. In effect, acts as a mask for z-order, so the drawn tile appears behind the tile being drawn over. {{TODO|Need to confirm, expand?}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;mirror_x&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; flip the tile horizontally.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;tile_index&amp;lt;/code&amp;gt;&lt;br /&gt;
: A 14-bit index selecting a specific tile from the corresponding &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset (see [[Eye of the Beholder VCN Format]]).&lt;br /&gt;
&lt;br /&gt;
== Rendering the View Cone ==&lt;br /&gt;
&lt;br /&gt;
The 3D view in [[Eye of the Beholder]] covers an area of &#039;&#039;&#039;22 × 15 tiles&#039;&#039;&#039; and is composed of five layers — the backdrop (ceiling and floor) and four wall layers. The backdrop is rendered first and provides the ceiling and floor as a single combined image. The wall layers are then drawn on top, alternating between front-facing and side-facing walls to construct the 3D perspective.&lt;br /&gt;
&lt;br /&gt;
The following diagram illustrates the layout of the view cone:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
Layer 5 (backdrop)  &lt;br /&gt;
                                  ─────────────────────────────────&lt;br /&gt;
Layer 4                               A | B | C | D | E | F | G &lt;br /&gt;
                                         ─── ─── ─── ─── ─── &lt;br /&gt;
Layer 3                                   H | I | J | K | L &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 2                                       M | N | O &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 1 (closest)                             P | ^ | Q  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The caret (&amp;lt;code&amp;gt;^&amp;lt;/code&amp;gt;) represents the party’s position. Vertical bars (&amp;lt;code&amp;gt;|&amp;lt;/code&amp;gt;) and overbars (&amp;lt;code&amp;gt;───&amp;lt;/code&amp;gt;) in the diagram denote walls at various distances.&lt;br /&gt;
&lt;br /&gt;
In total, there are 25 distinct wall positions within the player’s field of vision. To render all walls correctly, the engine must read 17 map cells (A–Q) from the dungeon layout.&lt;br /&gt;
&lt;br /&gt;
The first 22 x 15 = &#039;&#039;&#039;330&#039;&#039;&#039; tile indices are used for the backdrop. The background is horizontally flipped when &amp;lt;code&amp;gt;party.x &amp;amp; party.y &amp;amp; party.direction == 1&amp;lt;/code&amp;gt;. In other words, certain movements or rotations from the current position cause the background to appear mirrored.&lt;br /&gt;
&lt;br /&gt;
What follows are &#039;&#039;&#039;431&#039;&#039;&#039; tile indices per wall type. [[Eye of the Beholder]] has 6 different wall types: solid wall type 1, solid wall type 2, door frame, stairs up, stairs down and portal. The wall types are defined in the [[Eye of the Beholder Maze Format]] files. Each block in the MAZ file has wall information for all 4 walls (north, east, south, west) from which the wall type is inferred - for each wall in the level.&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;margin:auto;&amp;quot;&lt;br /&gt;
| [[File:BRICK bg.png|frame|Backdrop from BRICK.VMP]]&lt;br /&gt;
| [[File:BRICK wall 1.png|frame|Wall Type 1 from BRICK.VMP]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Render Code ==&lt;br /&gt;
&lt;br /&gt;
Pseudo code for rendering the background:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void drawBackground(bool xflip)&lt;br /&gt;
{&lt;br /&gt;
   for (int y=0; y&amp;lt;15; y++)&lt;br /&gt;
   {&lt;br /&gt;
      for (int x=0; x&amp;lt;22; x++)&lt;br /&gt;
      {&lt;br /&gt;
         int tile;&lt;br /&gt;
 &lt;br /&gt;
         if (xflip)&lt;br /&gt;
            tile=vmp.backgroundTiles[21-x][y];&lt;br /&gt;
         else&lt;br /&gt;
            tile=vmp.backgroundTiles[x][y];&lt;br /&gt;
 &lt;br /&gt;
         /* xor with xflip to make block flip and background flip cancel each other out. */&lt;br /&gt;
         int blockFlip = (tile&amp;amp;0x4000)^flipX;&lt;br /&gt;
         int blockIndex= tile&amp;amp;0x3fff;&lt;br /&gt;
 &lt;br /&gt;
         if (blockFlip)&lt;br /&gt;
            drawBlockXFlip(x*8, y*8, vcn.blocks[blockIndex]);&lt;br /&gt;
         else&lt;br /&gt;
            drawBlock(x*8, y*8, vcn.blocks[blockIndex]);&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To render the walls, we can use this structure:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
struct WallRenderData&lt;br /&gt;
{&lt;br /&gt;
   int baseOffset;&lt;br /&gt;
   int offsetInViewPort;&lt;br /&gt;
   int visibleWidthInBlocks;&lt;br /&gt;
   int visibleHeightInBlocks;&lt;br /&gt;
   int skipValue;&lt;br /&gt;
   int flipFlag;&lt;br /&gt;
} wallRenderData[25] /* 25 different wall positions */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;baseOffset&amp;lt;/code&amp;gt;&lt;br /&gt;
: Base offset into tileIndices[wallType-1]. This is an offset into the 431 index block for each wall type. So for stairs up (type 4) at position B the total offset would be 330 + (4-1) * 431 + 102 (see below).&lt;br /&gt;
; &amp;lt;code&amp;gt;offsetInViewPort&amp;lt;/code&amp;gt;&lt;br /&gt;
: Where to start rendering in the viewport:&lt;br /&gt;
: &amp;lt;code&amp;gt;xpos = offsetInViewPort % 22;&amp;lt;/code&amp;gt;&lt;br /&gt;
: &amp;lt;code&amp;gt;ypos = offsetInViewPort / 22;&amp;lt;/code&amp;gt;&lt;br /&gt;
; &amp;lt;code&amp;gt;visibleWidthInBlocks&amp;lt;/code&amp;gt;&lt;br /&gt;
: how many tiles to render in x direction.&lt;br /&gt;
; &amp;lt;code&amp;gt;visibleHeightInBlocks&amp;lt;/code&amp;gt;&lt;br /&gt;
: how many tiles to render in y direction.&lt;br /&gt;
; &amp;lt;code&amp;gt;skipValue&amp;lt;/code&amp;gt;&lt;br /&gt;
: Number of tiles to the next row in the tileIndices[wallType-1] array.&lt;br /&gt;
; &amp;lt;code&amp;gt;flipFlag&amp;lt;/code&amp;gt;&lt;br /&gt;
: &amp;lt;code&amp;gt;True&amp;lt;/code&amp;gt; if the wall is to be x-flipped in the viewport. Generally all right-walls are x-flipped.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
   /* Side-Walls left back */&lt;br /&gt;
   { 104, 66,  5,  1,  2, 0},             /* A-east */&lt;br /&gt;
   { 102, 68,  5,  3,  0, 0},             /* B-east */&lt;br /&gt;
   {  97, 74,  5,  1,  0, 0},             /* C-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side-Walls right back */&lt;br /&gt;
   {  97, 79,  5,  1,  0, 1},              /* E-west */&lt;br /&gt;
   { 102, 83,  5,  3,  0, 1},              /* F-west */&lt;br /&gt;
   { 104, 87,  5,  1,  2, 1},              /* G-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls back */&lt;br /&gt;
   { 133, 66,  5,  2,  4, 0},              /* B-south */&lt;br /&gt;
   { 129, 68,  5,  6,  0, 0},              /* C-south */&lt;br /&gt;
   { 129, 74,  5,  6,  0, 0},              /* D-south */&lt;br /&gt;
   { 129, 80,  5,  6,  0, 0},              /* E-south */&lt;br /&gt;
   { 129, 86,  5,  2,  4, 0},              /* F-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle back left */&lt;br /&gt;
   { 117, 66,  6,  2,  0, 0},              /* H-east */&lt;br /&gt;
   {  81, 50,  8,  2,  0, 0},              /* I-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle back right */&lt;br /&gt;
   {  81, 58,  8,  2,  0, 1},              /* K-west */&lt;br /&gt;
   { 117, 86,  6,  2,  0, 1},              /* L-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls middle back */&lt;br /&gt;
   { 163, 44,  8,  6,  4, 0},              /* I-south */&lt;br /&gt;
   { 159, 50,  8, 10,  0, 0},              /* J-south */&lt;br /&gt;
   { 159, 60,  8,  6,  4, 0},              /* K-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle front left */&lt;br /&gt;
   {  45, 25, 12,  3,  0, 0},              /* M-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle front right */&lt;br /&gt;
   {  45, 38, 12,  3,  0, 1},              /* O-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls middle front */&lt;br /&gt;
   { 252, 22, 12,  3, 13, 0},              /* M-south */&lt;br /&gt;
   { 239, 41, 12,  3, 13, 0},              /* O-south */&lt;br /&gt;
   { 239, 25, 12, 16,  0, 0},              /* N-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side wall front left */&lt;br /&gt;
   {  0,  0, 15,  3,  0, 0},              /* P-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side wall front right */&lt;br /&gt;
   {  0, 19, 15,  3,  0, 1},              /* Q-west */&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pseudo code for rendering a wall:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* wallType = wallType index aquired from the wallMapping[mazeByte].wallType. See the .inf file.&lt;br /&gt;
 * wallPosition = index to wall position in the viewport.&lt;br /&gt;
 */&lt;br /&gt;
void drawWall(int wallType, int wallPosition)&lt;br /&gt;
{&lt;br /&gt;
   /* 0x4000 because when x-ored with this flip flag in the tile data,&lt;br /&gt;
      the resulting flip state will be correct */&lt;br /&gt;
   int flipX=wallRenderData[wallPosition].flipFlag ? 0:0x4000;&lt;br /&gt;
   int offset=wallRenderData[wallPosition].baseOffset;&lt;br /&gt;
 &lt;br /&gt;
   for (int y=0; y&amp;lt;wallRenderData[wallPosition].visibleHeightInBlocks; y++)&lt;br /&gt;
   {&lt;br /&gt;
      for (int x=0; x&amp;lt;wallRenderData[wallPosition].visibleWidthInBlocks; x++)&lt;br /&gt;
      {&lt;br /&gt;
         int blockIndex;&lt;br /&gt;
         if (flipX==0)&lt;br /&gt;
         {&lt;br /&gt;
            blockIndex=x+y*22+wallRenderData[wallPosition].offsetInViewPort;&lt;br /&gt;
         }&lt;br /&gt;
         else&lt;br /&gt;
         {&lt;br /&gt;
            blockIndex=wallRenderData[wallPosition].offsetInViewPort+&lt;br /&gt;
                       wallRenderData[wallPosition].visibleWidthInBlocks-&lt;br /&gt;
                       1-&lt;br /&gt;
                       x+y*22;&lt;br /&gt;
         }&lt;br /&gt;
 &lt;br /&gt;
         int xpos=blockIndex%22;&lt;br /&gt;
         int ypos=blockIndex/22;&lt;br /&gt;
 &lt;br /&gt;
         int tile=vmp.wallTiles[wallType][offset];&lt;br /&gt;
 &lt;br /&gt;
         /* xor with wall flip-x to make block flip and wall flip cancel each other out. */&lt;br /&gt;
         int blockFlip = (tile&amp;amp;0x4000)^flipX;&lt;br /&gt;
         int blockIndex= tile&amp;amp;0x3fff;&lt;br /&gt;
 &lt;br /&gt;
         if (blockFlip)&lt;br /&gt;
            drawBlockXFlip(xpos*8, ypos*8, vcn.blocks[blockIndex]);&lt;br /&gt;
         else&lt;br /&gt;
            drawBlock(xpos*8, ypos*8, vcn.blocks[blockIndex]);&lt;br /&gt;
 &lt;br /&gt;
         offset++;&lt;br /&gt;
      }&lt;br /&gt;
      offset+=wallRenderData[wallPosition].skipValue;&lt;br /&gt;
   }&lt;br /&gt;
 &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Relationship to INF, VMP, and MAZ ==&lt;br /&gt;
&lt;br /&gt;
Each level in [[Eye of the Beholder]] references a set of resource files that define its appearance. The &#039;&#039;&#039;INF&#039;&#039;&#039; file serves as the level’s manifest, specifying which &#039;&#039;&#039;VNP&#039;&#039;&#039;, &#039;&#039;&#039;VCN&#039;&#039;&#039;, and &#039;&#039;&#039;MAZ&#039;&#039;&#039; files to use.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;VCN&#039;&#039;&#039; – Contains the raw 8×8 tiles for walls and backdrop components.  &lt;br /&gt;
* &#039;&#039;&#039;VMP&#039;&#039;&#039; – Provides a layout map: it stores indices into the VCN file, defining which tile to place where in the view cone.  &lt;br /&gt;
* &#039;&#039;&#039;MAZ&#039;&#039;&#039; – Defines the wall parameters for each wall in each block (north, east, south, west). From the wall parameters, the wall types are determined (type 1, type 2, doorway, stairs up, stairs down, portal).&lt;br /&gt;
&lt;br /&gt;
Together, these files allow the engine to construct the &#039;&#039;&#039;view cone&#039;&#039;&#039; dynamically:&lt;br /&gt;
&lt;br /&gt;
# The MAZ file tells the engine which wall type to use for which location. (Sidenote: this can be dynamically changed via scripts in the INF file, so the MAZ file only supplies initial values)&lt;br /&gt;
# The VMP file tells the engine which 8×8 tiles from the VCN to use for each wall projection and the backdrop.    &lt;br /&gt;
# The engine combines the tiles according to the VMP layout to render the final 3D view.&lt;br /&gt;
&lt;br /&gt;
== Summary ==&lt;br /&gt;
&lt;br /&gt;
* Defines the 3D dungeon view (“view cone”) by indexing tiles from the associated .VCN tileset.&lt;br /&gt;
* Contains 330 backdrop tile indices and 431 tile indices per wall type.&lt;br /&gt;
* Used together with VCN (tile graphics), MAZ (wall definitions), and INF (level manifest) files.&lt;br /&gt;
* Tile indices include bit flags for horizontal flip and z-mask rendering.&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
* [[Eye of the Beholder VMP Format]] – layout map for assembling VCN tiles&lt;br /&gt;
* [[Eye of the Beholder Maze Information Format]] - level info file&lt;br /&gt;
* [[Eye of the Beholder Maze Format]] - maze file&lt;br /&gt;
* [[Westwood LCW]] – LCW compression format&lt;br /&gt;
* [[Westwood CPS Format]] – Reference for the compressed VCN format&lt;/div&gt;</summary>
		<author><name>Fergusdog</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12628</id>
		<title>Eye of the Beholder VMP Format</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12628"/>
		<updated>2025-10-31T04:16:48Z</updated>

		<summary type="html">&lt;p&gt;Fergusdog: /* Render Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NeedMoreInfo}}&lt;br /&gt;
{{Map Infobox&lt;br /&gt;
 | Type = 2D tile-based&lt;br /&gt;
 | Layers = 5&lt;br /&gt;
 | Tile size = 8&amp;amp;times;8&lt;br /&gt;
 | Viewport = 176&amp;amp;times;120&lt;br /&gt;
 | Games = &lt;br /&gt;
   {{Game|Eye of the Beholder}}&lt;br /&gt;
   {{Game|Eye of the Beholder II: The Legend of Darkmoon}}&lt;br /&gt;
   {{Game|Lands of Lore: The Throne of Chaos}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file assembles the tiles from the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset.&lt;br /&gt;
It functions similarly to a map file in other video games, except that in [[Eye of the Beholder]] it does not represent a top-down layout. Instead, it defines the 3D view of the dungeon, often referred to as the &#039;&#039;view cone&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
In essence, the &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file contains a collection of indices that reference tile graphics within the &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. These indices are interpreted by the game’s main executable to construct the player&#039;s first-person view of the world.&lt;br /&gt;
&lt;br /&gt;
== File Format (PC version) ==&lt;br /&gt;
&lt;br /&gt;
In [[Lands of Lore: The Throne of Chaos]], &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; files are compressed , using the [[Westwood LCW]] compression (see [[Westwood CPS Format]]).&lt;br /&gt;
The uncompressed format is defined as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short index_count; &lt;br /&gt;
    unsigned short indices[index_count]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each entry in &amp;lt;code&amp;gt;indices&amp;lt;/code&amp;gt; represents an index that references a specific block in the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. For more details on the index entries, see the [[#Tile Index|Tile Index]] section below.&lt;br /&gt;
&lt;br /&gt;
== File Format (Amiga version) ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short header; &lt;br /&gt;
    unsigned short backdrop_tiles[22][15]; &lt;br /&gt;
    unsigned short padding[101]; &lt;br /&gt;
    unsigned short wall_tiles[wall_types_count][431]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;header&amp;lt;/code&amp;gt;&lt;br /&gt;
: {{TODO|Not yet fully investigated, but most likely specifies the number of wall types defined in the file.}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;backdrop_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the static backdrop (ceiling/floor) image..&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;padding&amp;lt;/code&amp;gt;&lt;br /&gt;
: Each wall type uses 431 tile indices. To match this count for the backdrop tiles, a padding of 101 empty indices is added (&amp;lt;code&amp;gt;22 × 15 + 101 = 431&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the wall graphics for each wall type.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_types_count&amp;lt;/code&amp;gt;&lt;br /&gt;
: Probably stored in the header, but can also be calculated as: &amp;lt;code&amp;gt;(filesize - 2) / (431 * 2) - 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tile Index ==&lt;br /&gt;
&lt;br /&gt;
Each index is represented as a 16-bit value using the following bit structure (most significant bits first):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct TileIndex { &lt;br /&gt;
    bool z-mask: 1; &lt;br /&gt;
    bool mirror_x: 1; &lt;br /&gt;
    unsigned tile_index: 14; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;z-mask&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;, only draw onto the tranparent pixels of the tile(s) below. In effect, acts as a mask for z-order, so the drawn tile appears behind the tile being drawn over. {{TODO|Need to confirm, expand?}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;mirror_x&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; flip the tile horizontally.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;tile_index&amp;lt;/code&amp;gt;&lt;br /&gt;
: A 14-bit index selecting a specific tile from the corresponding &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset (see [[Eye of the Beholder VCN Format]]).&lt;br /&gt;
&lt;br /&gt;
== Rendering the View Cone ==&lt;br /&gt;
&lt;br /&gt;
The 3D view in [[Eye of the Beholder]] covers an area of &#039;&#039;&#039;22 × 15 tiles&#039;&#039;&#039; and is composed of five layers — the backdrop (ceiling and floor) and four wall layers. The backdrop is rendered first and provides the ceiling and floor as a single combined image. The wall layers are then drawn on top, alternating between front-facing and side-facing walls to construct the 3D perspective.&lt;br /&gt;
&lt;br /&gt;
The following diagram illustrates the layout of the view cone:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
Layer 5 (backdrop)  &lt;br /&gt;
                                  ─────────────────────────────────&lt;br /&gt;
Layer 4                               A | B | C | D | E | F | G &lt;br /&gt;
                                         ─── ─── ─── ─── ─── &lt;br /&gt;
Layer 3                                   H | I | J | K | L &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 2                                       M | N | O &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 1 (closest)                             P | ^ | Q  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The caret (&amp;lt;code&amp;gt;^&amp;lt;/code&amp;gt;) represents the party’s position. Vertical bars (&amp;lt;code&amp;gt;|&amp;lt;/code&amp;gt;) and overbars (&amp;lt;code&amp;gt;───&amp;lt;/code&amp;gt;) in the diagram denote walls at various distances.&lt;br /&gt;
&lt;br /&gt;
In total, there are 25 distinct wall positions within the player’s field of vision. To render all walls correctly, the engine must read 17 map cells (A–Q) from the dungeon layout.&lt;br /&gt;
&lt;br /&gt;
The first 22 x 15 = &#039;&#039;&#039;330&#039;&#039;&#039; tile indices are used for the backdrop. The background is horizontally flipped when &amp;lt;code&amp;gt;party.x &amp;amp; party.y &amp;amp; party.direction == 1&amp;lt;/code&amp;gt;. In other words, certain movements or rotations from the current position cause the background to appear mirrored.&lt;br /&gt;
&lt;br /&gt;
What follows are &#039;&#039;&#039;431&#039;&#039;&#039; tile indices per wall type. [[Eye of the Beholder]] has 6 different wall types: solid wall type 1, solid wall type 2, door frame, stairs up, stairs down and portal. The wall types are defined in the [[Eye of the Beholder Maze Format]] files. Each block in the MAZ file has wall information for all 4 walls (north, east, south, west) from which the wall type is inferred - for each wall in the level.&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;margin:auto;&amp;quot;&lt;br /&gt;
| [[File:BRICK bg.png|frame|Backdrop from BRICK.VMP]]&lt;br /&gt;
| [[File:BRICK wall 1.png|frame|Wall Type 1 from BRICK.VMP]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Render Code ==&lt;br /&gt;
&lt;br /&gt;
Pseudo code for rendering the background:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void drawBackground(bool xflip)&lt;br /&gt;
{&lt;br /&gt;
   for (int y=0; y&amp;lt;15; y++)&lt;br /&gt;
   {&lt;br /&gt;
      for (int x=0; x&amp;lt;22; x++)&lt;br /&gt;
      {&lt;br /&gt;
         int tile;&lt;br /&gt;
 &lt;br /&gt;
         if (xflip)&lt;br /&gt;
            tile=vmp.backgroundTiles[21-x][y];&lt;br /&gt;
         else&lt;br /&gt;
            tile=vmp.backgroundTiles[x][y];&lt;br /&gt;
 &lt;br /&gt;
         /* xor with xflip to make block flip and background flip cancel each other out. */&lt;br /&gt;
         int blockFlip = (tile&amp;amp;0x4000)^flipX;&lt;br /&gt;
         int blockIndex= tile&amp;amp;0x3fff;&lt;br /&gt;
 &lt;br /&gt;
         if (blockFlip)&lt;br /&gt;
            drawBlockXFlip(x*8, y*8, vcn.blocks[blockIndex]);&lt;br /&gt;
         else&lt;br /&gt;
            drawBlock(x*8, y*8, vcn.blocks[blockIndex]);&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To render the walls, we can use this structure:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
struct WallRenderData&lt;br /&gt;
{&lt;br /&gt;
   int baseOffset;&lt;br /&gt;
   int offsetInViewPort;&lt;br /&gt;
   int visibleWidthInBlocks;&lt;br /&gt;
   int visibleHeightInBlocks;&lt;br /&gt;
   int skipValue;&lt;br /&gt;
   int flipFlag;&lt;br /&gt;
} wallRenderData[25] /* 25 different wall positions */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;baseOffset&amp;lt;/code&amp;gt;&lt;br /&gt;
: Base offset into tileIndices[wallType-1]. This is an offset into the 431 index block for each wall type. So for stairs up (type 4) at position B the total offset would be 330 + (4-1) * 431 + 102 (see below).&lt;br /&gt;
; &amp;lt;code&amp;gt;offsetInViewPort&amp;lt;/code&amp;gt;&lt;br /&gt;
: Where to start rendering in the viewport:&lt;br /&gt;
: &amp;lt;code&amp;gt;xpos = offsetInViewPort % 22;&amp;lt;/code&amp;gt;&lt;br /&gt;
: &amp;lt;code&amp;gt;ypos = offsetInViewPort / 22;&amp;lt;/code&amp;gt;&lt;br /&gt;
; &amp;lt;code&amp;gt;visibleWidthInBlocks&amp;lt;/code&amp;gt;&lt;br /&gt;
: how many tiles to render in x direction.&lt;br /&gt;
; &amp;lt;code&amp;gt;visibleHeightInBlocks&amp;lt;/code&amp;gt;&lt;br /&gt;
: how many tiles to render in y direction.&lt;br /&gt;
; &amp;lt;code&amp;gt;skipValue&amp;lt;/code&amp;gt;&lt;br /&gt;
: Number of tiles to the next row in the tileIndices[wallType-1] array.&lt;br /&gt;
; &amp;lt;code&amp;gt;flipFlag&amp;lt;/code&amp;gt;&lt;br /&gt;
: &amp;lt;code&amp;gt;True&amp;lt;/code&amp;gt; if the wall is to be x-flipped in the viewport. Generally all right-walls are x-flipped.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
   /* Side-Walls left back */&lt;br /&gt;
   { 104, 66,  5,  1,  2, 0},             /* A-east */&lt;br /&gt;
   { 102, 68,  5,  3,  0, 0},             /* B-east */&lt;br /&gt;
   {  97, 74,  5,  1,  0, 0},             /* C-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side-Walls right back */&lt;br /&gt;
   {  97, 79,  5,  1,  0, 1},              /* E-west */&lt;br /&gt;
   { 102, 83,  5,  3,  0, 1},              /* F-west */&lt;br /&gt;
   { 104, 87,  5,  1,  2, 1},              /* G-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls back */&lt;br /&gt;
   { 133, 66,  5,  2,  4, 0},              /* B-south */&lt;br /&gt;
   { 129, 68,  5,  6,  0, 0},              /* C-south */&lt;br /&gt;
   { 129, 74,  5,  6,  0, 0},              /* D-south */&lt;br /&gt;
   { 129, 80,  5,  6,  0, 0},              /* E-south */&lt;br /&gt;
   { 129, 86,  5,  2,  4, 0},              /* F-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle back left */&lt;br /&gt;
   { 117, 66,  6,  2,  0, 0},              /* H-east */&lt;br /&gt;
   {  81, 50,  8,  2,  0, 0},              /* I-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle back right */&lt;br /&gt;
   {  81, 58,  8,  2,  0, 1},              /* K-west */&lt;br /&gt;
   { 117, 86,  6,  2,  0, 1},              /* L-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls middle back */&lt;br /&gt;
   { 163, 44,  8,  6,  4, 0},              /* I-south */&lt;br /&gt;
   { 159, 50,  8, 10,  0, 0},              /* J-south */&lt;br /&gt;
   { 159, 60,  8,  6,  4, 0},              /* K-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle front left */&lt;br /&gt;
   {  45, 25, 12,  3,  0, 0},              /* M-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle front right */&lt;br /&gt;
   {  45, 38, 12,  3,  0, 1},              /* O-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls middle front */&lt;br /&gt;
   { 252, 22, 12,  3, 13, 0},              /* M-south */&lt;br /&gt;
   { 239, 41, 12,  3, 13, 0},              /* O-south */&lt;br /&gt;
   { 239, 25, 12, 16,  0, 0},              /* N-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side wall front left */&lt;br /&gt;
   {  0,  0, 15,  3,  0, 0},              /* P-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side wall front right */&lt;br /&gt;
   {  0, 19, 15,  3,  0, 1},              /* Q-west */&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pseudo code for rendering a wall:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* wallType = wallType index aquired from the wallMapping[mazeByte].wallType. See the .inf file.&lt;br /&gt;
 * wallPosition = index to wall position in the viewport.&lt;br /&gt;
 */&lt;br /&gt;
void drawWall(int wallType, int wallPosition)&lt;br /&gt;
{&lt;br /&gt;
   /* 0x4000 because when x-ored with this flip flag in the tile data,&lt;br /&gt;
      the resulting flip state will be correct */&lt;br /&gt;
   int flipX=wallRenderData[wallPosition].flipFlag ? 0:0x4000;&lt;br /&gt;
   int offset=wallRenderData[wallPosition].baseOffset;&lt;br /&gt;
 &lt;br /&gt;
   for (int y=0; y&amp;lt;wallRenderData[wallPosition].visibleHeightInBlocks; y++)&lt;br /&gt;
   {&lt;br /&gt;
      for (int x=0; x&amp;lt;wallRenderData[wallPosition].visibleWidthInBlocks; x++)&lt;br /&gt;
      {&lt;br /&gt;
         int blockIndex;&lt;br /&gt;
         if (flipX==0)&lt;br /&gt;
         {&lt;br /&gt;
            blockIndex=x+y*22+wallRenderData[wallPosition].offsetInViewPort;&lt;br /&gt;
         }&lt;br /&gt;
         else&lt;br /&gt;
         {&lt;br /&gt;
            blockIndex=wallRenderData[wallPosition].offsetInViewPort+&lt;br /&gt;
                       wallRenderData[wallPosition].visibleWidthInBlocks-&lt;br /&gt;
                       1-&lt;br /&gt;
                       x+y*22;&lt;br /&gt;
         }&lt;br /&gt;
 &lt;br /&gt;
         int xpos=blockIndex%22;&lt;br /&gt;
         int ypos=blockIndex/22;&lt;br /&gt;
 &lt;br /&gt;
         int tile=vmp.wallTiles[wallType][offset];&lt;br /&gt;
 &lt;br /&gt;
         /* xor with wall flip-x to make block flip and wall flip cancel each other out. */&lt;br /&gt;
         int blockFlip = (tile&amp;amp;0x4000)^flipX;&lt;br /&gt;
         int blockIndex= tile&amp;amp;0x3fff;&lt;br /&gt;
 &lt;br /&gt;
         if (blockFlip)&lt;br /&gt;
            drawBlockXFlip(xpos*8, ypos*8, vcn.blocks[blockIndex]);&lt;br /&gt;
         else&lt;br /&gt;
            drawBlock(xpos*8, ypos*8, vcn.blocks[blockIndex]);&lt;br /&gt;
 &lt;br /&gt;
         offset++;&lt;br /&gt;
      }&lt;br /&gt;
      offset+=wallRenderData[wallPosition].skipValue;&lt;br /&gt;
   }&lt;br /&gt;
 &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Relationship to INF, VMP, and MAZ ==&lt;br /&gt;
&lt;br /&gt;
Each level in [[Eye of the Beholder]] references a set of resource files that define its appearance. The &#039;&#039;&#039;INF&#039;&#039;&#039; file serves as the level’s manifest, specifying which &#039;&#039;&#039;VNP&#039;&#039;&#039;, &#039;&#039;&#039;VCN&#039;&#039;&#039;, and &#039;&#039;&#039;MAZ&#039;&#039;&#039; files to use.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;VCN&#039;&#039;&#039; – Contains the raw 8×8 tiles for walls and backdrop components.  &lt;br /&gt;
* &#039;&#039;&#039;VMP&#039;&#039;&#039; – Provides a layout map: it stores indices into the VCN file, defining which tile to place where in the view cone.  &lt;br /&gt;
* &#039;&#039;&#039;MAZ&#039;&#039;&#039; – Defines the wall parameters for each wall in each block (north, east, south, west). From the wall parameters, the wall types are determined (type 1, type 2, doorway, stairs up, stairs down, portal).&lt;br /&gt;
&lt;br /&gt;
Together, these files allow the engine to construct the &#039;&#039;&#039;view cone&#039;&#039;&#039; dynamically:&lt;br /&gt;
&lt;br /&gt;
# The MAZ file tells the engine which wall type to use for which location. (Sidenote: this can be dynamically changed via scripts in the INF file, so the MAZ file only supplies initial values)&lt;br /&gt;
# The VMP file tells the engine which 8×8 tiles from the VCN to use for each wall projection and the backdrop.    &lt;br /&gt;
# The engine combines the tiles according to the VMP layout to render the final 3D view.&lt;br /&gt;
&lt;br /&gt;
== Summary ==&lt;br /&gt;
&lt;br /&gt;
* Defines the 3D dungeon view (“view cone”) by indexing tiles from the associated .VCN tileset.&lt;br /&gt;
* Contains 330 backdrop tile indices and 431 tile indices per wall type.&lt;br /&gt;
* Used together with VCN (tile graphics), MAZ (wall definitions), and INF (level manifest) files.&lt;br /&gt;
* Tile indices include bit flags for horizontal flip and z-mask rendering.&lt;/div&gt;</summary>
		<author><name>Fergusdog</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12627</id>
		<title>Eye of the Beholder VMP Format</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12627"/>
		<updated>2025-10-31T04:12:47Z</updated>

		<summary type="html">&lt;p&gt;Fergusdog: /* Relationship to INF, VMP, and MAZ */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NeedMoreInfo}}&lt;br /&gt;
{{Map Infobox&lt;br /&gt;
 | Type = 2D tile-based&lt;br /&gt;
 | Layers = 5&lt;br /&gt;
 | Tile size = 8&amp;amp;times;8&lt;br /&gt;
 | Viewport = 176&amp;amp;times;120&lt;br /&gt;
 | Games = &lt;br /&gt;
   {{Game|Eye of the Beholder}}&lt;br /&gt;
   {{Game|Eye of the Beholder II: The Legend of Darkmoon}}&lt;br /&gt;
   {{Game|Lands of Lore: The Throne of Chaos}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file assembles the tiles from the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset.&lt;br /&gt;
It functions similarly to a map file in other video games, except that in [[Eye of the Beholder]] it does not represent a top-down layout. Instead, it defines the 3D view of the dungeon, often referred to as the &#039;&#039;view cone&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
In essence, the &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file contains a collection of indices that reference tile graphics within the &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. These indices are interpreted by the game’s main executable to construct the player&#039;s first-person view of the world.&lt;br /&gt;
&lt;br /&gt;
== File Format (PC version) ==&lt;br /&gt;
&lt;br /&gt;
In [[Lands of Lore: The Throne of Chaos]], &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; files are compressed , using the [[Westwood LCW]] compression (see [[Westwood CPS Format]]).&lt;br /&gt;
The uncompressed format is defined as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short index_count; &lt;br /&gt;
    unsigned short indices[index_count]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each entry in &amp;lt;code&amp;gt;indices&amp;lt;/code&amp;gt; represents an index that references a specific block in the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. For more details on the index entries, see the [[#Tile Index|Tile Index]] section below.&lt;br /&gt;
&lt;br /&gt;
== File Format (Amiga version) ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short header; &lt;br /&gt;
    unsigned short backdrop_tiles[22][15]; &lt;br /&gt;
    unsigned short padding[101]; &lt;br /&gt;
    unsigned short wall_tiles[wall_types_count][431]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;header&amp;lt;/code&amp;gt;&lt;br /&gt;
: {{TODO|Not yet fully investigated, but most likely specifies the number of wall types defined in the file.}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;backdrop_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the static backdrop (ceiling/floor) image..&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;padding&amp;lt;/code&amp;gt;&lt;br /&gt;
: Each wall type uses 431 tile indices. To match this count for the backdrop tiles, a padding of 101 empty indices is added (&amp;lt;code&amp;gt;22 × 15 + 101 = 431&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the wall graphics for each wall type.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_types_count&amp;lt;/code&amp;gt;&lt;br /&gt;
: Probably stored in the header, but can also be calculated as: &amp;lt;code&amp;gt;(filesize - 2) / (431 * 2) - 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tile Index ==&lt;br /&gt;
&lt;br /&gt;
Each index is represented as a 16-bit value using the following bit structure (most significant bits first):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct TileIndex { &lt;br /&gt;
    bool z-mask: 1; &lt;br /&gt;
    bool mirror_x: 1; &lt;br /&gt;
    unsigned tile_index: 14; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;z-mask&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;, only draw onto the tranparent pixels of the tile(s) below. In effect, acts as a mask for z-order, so the drawn tile appears behind the tile being drawn over. {{TODO|Need to confirm, expand?}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;mirror_x&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; flip the tile horizontally.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;tile_index&amp;lt;/code&amp;gt;&lt;br /&gt;
: A 14-bit index selecting a specific tile from the corresponding &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset (see [[Eye of the Beholder VCN Format]]).&lt;br /&gt;
&lt;br /&gt;
== Rendering the View Cone ==&lt;br /&gt;
&lt;br /&gt;
The 3D view in [[Eye of the Beholder]] covers an area of &#039;&#039;&#039;22 × 15 tiles&#039;&#039;&#039; and is composed of five layers — the backdrop (ceiling and floor) and four wall layers. The backdrop is rendered first and provides the ceiling and floor as a single combined image. The wall layers are then drawn on top, alternating between front-facing and side-facing walls to construct the 3D perspective.&lt;br /&gt;
&lt;br /&gt;
The following diagram illustrates the layout of the view cone:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
Layer 5 (backdrop)  &lt;br /&gt;
                                  ─────────────────────────────────&lt;br /&gt;
Layer 4                               A | B | C | D | E | F | G &lt;br /&gt;
                                         ─── ─── ─── ─── ─── &lt;br /&gt;
Layer 3                                   H | I | J | K | L &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 2                                       M | N | O &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 1 (closest)                             P | ^ | Q  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The caret (&amp;lt;code&amp;gt;^&amp;lt;/code&amp;gt;) represents the party’s position. Vertical bars (&amp;lt;code&amp;gt;|&amp;lt;/code&amp;gt;) and overbars (&amp;lt;code&amp;gt;───&amp;lt;/code&amp;gt;) in the diagram denote walls at various distances.&lt;br /&gt;
&lt;br /&gt;
In total, there are 25 distinct wall positions within the player’s field of vision. To render all walls correctly, the engine must read 17 map cells (A–Q) from the dungeon layout.&lt;br /&gt;
&lt;br /&gt;
The first 22 x 15 = &#039;&#039;&#039;330&#039;&#039;&#039; tile indices are used for the backdrop. The background is horizontally flipped when &amp;lt;code&amp;gt;party.x &amp;amp; party.y &amp;amp; party.direction == 1&amp;lt;/code&amp;gt;. In other words, certain movements or rotations from the current position cause the background to appear mirrored.&lt;br /&gt;
&lt;br /&gt;
What follows are &#039;&#039;&#039;431&#039;&#039;&#039; tile indices per wall type. [[Eye of the Beholder]] has 6 different wall types: solid wall type 1, solid wall type 2, door frame, stairs up, stairs down and portal. The wall types are defined in the [[Eye of the Beholder Maze Format]] files. Each block in the MAZ file has wall information for all 4 walls (north, east, south, west) from which the wall type is inferred - for each wall in the level.&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;margin:auto;&amp;quot;&lt;br /&gt;
| [[File:BRICK bg.png|frame|Backdrop from BRICK.VMP]]&lt;br /&gt;
| [[File:BRICK wall 1.png|frame|Wall Type 1 from BRICK.VMP]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Render Code ==&lt;br /&gt;
&lt;br /&gt;
Pseudo code for rendering the background:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void drawBackground(bool xflip)&lt;br /&gt;
{&lt;br /&gt;
   for (int y=0; y&amp;lt;15; y++)&lt;br /&gt;
   {&lt;br /&gt;
      for (int x=0; x&amp;lt;22; x++)&lt;br /&gt;
      {&lt;br /&gt;
         int tile;&lt;br /&gt;
 &lt;br /&gt;
         if (xflip)&lt;br /&gt;
            tile=vmp.backgroundTiles[21-x][y];&lt;br /&gt;
         else&lt;br /&gt;
            tile=vmp.backgroundTiles[x][y];&lt;br /&gt;
 &lt;br /&gt;
         /* xor with xflip to make block flip and background flip cancel each other out. */&lt;br /&gt;
         int blockFlip = (tile&amp;amp;0x4000)^flipX;&lt;br /&gt;
         int blockIndex= tile&amp;amp;0x3fff;&lt;br /&gt;
 &lt;br /&gt;
         if (blockFlip)&lt;br /&gt;
            drawBlockXFlip(x*8, y*8, vcn.blocks[blockIndex]);&lt;br /&gt;
         else&lt;br /&gt;
            drawBlock(x*8, y*8, vcn.blocks[blockIndex]);&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To render the walls, we can use this structure:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
struct WallRenderData&lt;br /&gt;
{&lt;br /&gt;
   int baseOffset;&lt;br /&gt;
   int offsetInViewPort;&lt;br /&gt;
   int visibleWidthInBlocks;&lt;br /&gt;
   int visibleHeightInBlocks;&lt;br /&gt;
   int skipValue;&lt;br /&gt;
   int flipFlag;&lt;br /&gt;
} wallRenderData[25] /* 25 different wall positions */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;baseOffset&amp;lt;/code&amp;gt;&lt;br /&gt;
: Base offset into tileIndices[wallType-1]. This is an offset into the 431 index block for each wall type.&lt;br /&gt;
; &amp;lt;code&amp;gt;offsetInViewPort&amp;lt;/code&amp;gt;&lt;br /&gt;
: Where to start rendering in the viewport:&lt;br /&gt;
: &amp;lt;code&amp;gt;xpos = offsetInViewPort % 22;&amp;lt;/code&amp;gt;&lt;br /&gt;
: &amp;lt;code&amp;gt;ypos = offsetInViewPort / 22;&amp;lt;/code&amp;gt;&lt;br /&gt;
; &amp;lt;code&amp;gt;visibleWidthInBlocks&amp;lt;/code&amp;gt;&lt;br /&gt;
: how many tiles to render in x direction.&lt;br /&gt;
; &amp;lt;code&amp;gt;visibleHeightInBlocks&amp;lt;/code&amp;gt;&lt;br /&gt;
: how many tiles to render in y direction.&lt;br /&gt;
; &amp;lt;code&amp;gt;skipValue&amp;lt;/code&amp;gt;&lt;br /&gt;
: Number of tiles to the next row in the tileIndices[wallType-1] array.&lt;br /&gt;
; &amp;lt;code&amp;gt;flipFlag&amp;lt;/code&amp;gt;&lt;br /&gt;
: &amp;lt;code&amp;gt;True&amp;lt;/code&amp;gt; if the wall is to be x-flipped in the viewport. Generally all right-walls are x-flipped.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
   /* Side-Walls left back */&lt;br /&gt;
   { 104, 66,  5,  1,  2, 0},             /* A-east */&lt;br /&gt;
   { 102, 68,  5,  3,  0, 0},             /* B-east */&lt;br /&gt;
   {  97, 74,  5,  1,  0, 0},             /* C-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side-Walls right back */&lt;br /&gt;
   {  97, 79,  5,  1,  0, 1},              /* E-west */&lt;br /&gt;
   { 102, 83,  5,  3,  0, 1},              /* F-west */&lt;br /&gt;
   { 104, 87,  5,  1,  2, 1},              /* G-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls back */&lt;br /&gt;
   { 133, 66,  5,  2,  4, 0},              /* B-south */&lt;br /&gt;
   { 129, 68,  5,  6,  0, 0},              /* C-south */&lt;br /&gt;
   { 129, 74,  5,  6,  0, 0},              /* D-south */&lt;br /&gt;
   { 129, 80,  5,  6,  0, 0},              /* E-south */&lt;br /&gt;
   { 129, 86,  5,  2,  4, 0},              /* F-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle back left */&lt;br /&gt;
   { 117, 66,  6,  2,  0, 0},              /* H-east */&lt;br /&gt;
   {  81, 50,  8,  2,  0, 0},              /* I-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle back right */&lt;br /&gt;
   {  81, 58,  8,  2,  0, 1},              /* K-west */&lt;br /&gt;
   { 117, 86,  6,  2,  0, 1},              /* L-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls middle back */&lt;br /&gt;
   { 163, 44,  8,  6,  4, 0},              /* I-south */&lt;br /&gt;
   { 159, 50,  8, 10,  0, 0},              /* J-south */&lt;br /&gt;
   { 159, 60,  8,  6,  4, 0},              /* K-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle front left */&lt;br /&gt;
   {  45, 25, 12,  3,  0, 0},              /* M-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle front right */&lt;br /&gt;
   {  45, 38, 12,  3,  0, 1},              /* O-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls middle front */&lt;br /&gt;
   { 252, 22, 12,  3, 13, 0},              /* M-south */&lt;br /&gt;
   { 239, 41, 12,  3, 13, 0},              /* O-south */&lt;br /&gt;
   { 239, 25, 12, 16,  0, 0},              /* N-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side wall front left */&lt;br /&gt;
   {  0,  0, 15,  3,  0, 0},              /* P-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side wall front right */&lt;br /&gt;
   {  0, 19, 15,  3,  0, 1},              /* Q-west */&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pseudo code for rendering a wall:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* wallType = wallType index aquired from the wallMapping[mazeByte].wallType. See the .inf file.&lt;br /&gt;
 * wallPosition = index to wall position in the viewport.&lt;br /&gt;
 */&lt;br /&gt;
void drawWall(int wallType, int wallPosition)&lt;br /&gt;
{&lt;br /&gt;
   /* 0x4000 because when x-ored with this flip flag in the tile data,&lt;br /&gt;
      the resulting flip state will be correct */&lt;br /&gt;
   int flipX=wallRenderData[wallPosition].flipFlag ? 0:0x4000;&lt;br /&gt;
   int offset=wallRenderData[wallPosition].baseOffset;&lt;br /&gt;
 &lt;br /&gt;
   for (int y=0; y&amp;lt;wallRenderData[wallPosition].visibleHeightInBlocks; y++)&lt;br /&gt;
   {&lt;br /&gt;
      for (int x=0; x&amp;lt;wallRenderData[wallPosition].visibleWidthInBlocks; x++)&lt;br /&gt;
      {&lt;br /&gt;
         int blockIndex;&lt;br /&gt;
         if (flipX==0)&lt;br /&gt;
         {&lt;br /&gt;
            blockIndex=x+y*22+wallRenderData[wallPosition].offsetInViewPort;&lt;br /&gt;
         }&lt;br /&gt;
         else&lt;br /&gt;
         {&lt;br /&gt;
            blockIndex=wallRenderData[wallPosition].offsetInViewPort+&lt;br /&gt;
                       wallRenderData[wallPosition].visibleWidthInBlocks-&lt;br /&gt;
                       1-&lt;br /&gt;
                       x+y*22;&lt;br /&gt;
         }&lt;br /&gt;
 &lt;br /&gt;
         int xpos=blockIndex%22;&lt;br /&gt;
         int ypos=blockIndex/22;&lt;br /&gt;
 &lt;br /&gt;
         int tile=vmp.wallTiles[wallType][offset];&lt;br /&gt;
 &lt;br /&gt;
         /* xor with wall flip-x to make block flip and wall flip cancel each other out. */&lt;br /&gt;
         int blockFlip = (tile&amp;amp;0x4000)^flipX;&lt;br /&gt;
         int blockIndex= tile&amp;amp;0x3fff;&lt;br /&gt;
 &lt;br /&gt;
         if (blockFlip)&lt;br /&gt;
            drawBlockXFlip(xpos*8, ypos*8, vcn.blocks[blockIndex]);&lt;br /&gt;
         else&lt;br /&gt;
            drawBlock(xpos*8, ypos*8, vcn.blocks[blockIndex]);&lt;br /&gt;
 &lt;br /&gt;
         offset++;&lt;br /&gt;
      }&lt;br /&gt;
      offset+=wallRenderData[wallPosition].skipValue;&lt;br /&gt;
   }&lt;br /&gt;
 &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Relationship to INF, VMP, and MAZ ==&lt;br /&gt;
&lt;br /&gt;
Each level in [[Eye of the Beholder]] references a set of resource files that define its appearance. The &#039;&#039;&#039;INF&#039;&#039;&#039; file serves as the level’s manifest, specifying which &#039;&#039;&#039;VNP&#039;&#039;&#039;, &#039;&#039;&#039;VCN&#039;&#039;&#039;, and &#039;&#039;&#039;MAZ&#039;&#039;&#039; files to use.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;VCN&#039;&#039;&#039; – Contains the raw 8×8 tiles for walls and backdrop components.  &lt;br /&gt;
* &#039;&#039;&#039;VMP&#039;&#039;&#039; – Provides a layout map: it stores indices into the VCN file, defining which tile to place where in the view cone.  &lt;br /&gt;
* &#039;&#039;&#039;MAZ&#039;&#039;&#039; – Defines the wall parameters for each wall in each block (north, east, south, west). From the wall parameters, the wall types are determined (type 1, type 2, doorway, stairs up, stairs down, portal).&lt;br /&gt;
&lt;br /&gt;
Together, these files allow the engine to construct the &#039;&#039;&#039;view cone&#039;&#039;&#039; dynamically:&lt;br /&gt;
&lt;br /&gt;
# The MAZ file tells the engine which wall type to use for which location. (Sidenote: this can be dynamically changed via scripts in the INF file, so the MAZ file only supplies initial values)&lt;br /&gt;
# The VMP file tells the engine which 8×8 tiles from the VCN to use for each wall projection and the backdrop.    &lt;br /&gt;
# The engine combines the tiles according to the VMP layout to render the final 3D view.&lt;br /&gt;
&lt;br /&gt;
== Summary ==&lt;br /&gt;
&lt;br /&gt;
* Defines the 3D dungeon view (“view cone”) by indexing tiles from the associated .VCN tileset.&lt;br /&gt;
* Contains 330 backdrop tile indices and 431 tile indices per wall type.&lt;br /&gt;
* Used together with VCN (tile graphics), MAZ (wall definitions), and INF (level manifest) files.&lt;br /&gt;
* Tile indices include bit flags for horizontal flip and z-mask rendering.&lt;/div&gt;</summary>
		<author><name>Fergusdog</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12626</id>
		<title>Eye of the Beholder VMP Format</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12626"/>
		<updated>2025-10-31T04:09:55Z</updated>

		<summary type="html">&lt;p&gt;Fergusdog: /* Relationship to INF, VMP, and PAL */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NeedMoreInfo}}&lt;br /&gt;
{{Map Infobox&lt;br /&gt;
 | Type = 2D tile-based&lt;br /&gt;
 | Layers = 5&lt;br /&gt;
 | Tile size = 8&amp;amp;times;8&lt;br /&gt;
 | Viewport = 176&amp;amp;times;120&lt;br /&gt;
 | Games = &lt;br /&gt;
   {{Game|Eye of the Beholder}}&lt;br /&gt;
   {{Game|Eye of the Beholder II: The Legend of Darkmoon}}&lt;br /&gt;
   {{Game|Lands of Lore: The Throne of Chaos}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file assembles the tiles from the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset.&lt;br /&gt;
It functions similarly to a map file in other video games, except that in [[Eye of the Beholder]] it does not represent a top-down layout. Instead, it defines the 3D view of the dungeon, often referred to as the &#039;&#039;view cone&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
In essence, the &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file contains a collection of indices that reference tile graphics within the &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. These indices are interpreted by the game’s main executable to construct the player&#039;s first-person view of the world.&lt;br /&gt;
&lt;br /&gt;
== File Format (PC version) ==&lt;br /&gt;
&lt;br /&gt;
In [[Lands of Lore: The Throne of Chaos]], &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; files are compressed , using the [[Westwood LCW]] compression (see [[Westwood CPS Format]]).&lt;br /&gt;
The uncompressed format is defined as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short index_count; &lt;br /&gt;
    unsigned short indices[index_count]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each entry in &amp;lt;code&amp;gt;indices&amp;lt;/code&amp;gt; represents an index that references a specific block in the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. For more details on the index entries, see the [[#Tile Index|Tile Index]] section below.&lt;br /&gt;
&lt;br /&gt;
== File Format (Amiga version) ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short header; &lt;br /&gt;
    unsigned short backdrop_tiles[22][15]; &lt;br /&gt;
    unsigned short padding[101]; &lt;br /&gt;
    unsigned short wall_tiles[wall_types_count][431]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;header&amp;lt;/code&amp;gt;&lt;br /&gt;
: {{TODO|Not yet fully investigated, but most likely specifies the number of wall types defined in the file.}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;backdrop_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the static backdrop (ceiling/floor) image..&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;padding&amp;lt;/code&amp;gt;&lt;br /&gt;
: Each wall type uses 431 tile indices. To match this count for the backdrop tiles, a padding of 101 empty indices is added (&amp;lt;code&amp;gt;22 × 15 + 101 = 431&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the wall graphics for each wall type.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_types_count&amp;lt;/code&amp;gt;&lt;br /&gt;
: Probably stored in the header, but can also be calculated as: &amp;lt;code&amp;gt;(filesize - 2) / (431 * 2) - 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tile Index ==&lt;br /&gt;
&lt;br /&gt;
Each index is represented as a 16-bit value using the following bit structure (most significant bits first):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct TileIndex { &lt;br /&gt;
    bool z-mask: 1; &lt;br /&gt;
    bool mirror_x: 1; &lt;br /&gt;
    unsigned tile_index: 14; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;z-mask&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;, only draw onto the tranparent pixels of the tile(s) below. In effect, acts as a mask for z-order, so the drawn tile appears behind the tile being drawn over. {{TODO|Need to confirm, expand?}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;mirror_x&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; flip the tile horizontally.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;tile_index&amp;lt;/code&amp;gt;&lt;br /&gt;
: A 14-bit index selecting a specific tile from the corresponding &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset (see [[Eye of the Beholder VCN Format]]).&lt;br /&gt;
&lt;br /&gt;
== Rendering the View Cone ==&lt;br /&gt;
&lt;br /&gt;
The 3D view in [[Eye of the Beholder]] covers an area of &#039;&#039;&#039;22 × 15 tiles&#039;&#039;&#039; and is composed of five layers — the backdrop (ceiling and floor) and four wall layers. The backdrop is rendered first and provides the ceiling and floor as a single combined image. The wall layers are then drawn on top, alternating between front-facing and side-facing walls to construct the 3D perspective.&lt;br /&gt;
&lt;br /&gt;
The following diagram illustrates the layout of the view cone:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
Layer 5 (backdrop)  &lt;br /&gt;
                                  ─────────────────────────────────&lt;br /&gt;
Layer 4                               A | B | C | D | E | F | G &lt;br /&gt;
                                         ─── ─── ─── ─── ─── &lt;br /&gt;
Layer 3                                   H | I | J | K | L &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 2                                       M | N | O &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 1 (closest)                             P | ^ | Q  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The caret (&amp;lt;code&amp;gt;^&amp;lt;/code&amp;gt;) represents the party’s position. Vertical bars (&amp;lt;code&amp;gt;|&amp;lt;/code&amp;gt;) and overbars (&amp;lt;code&amp;gt;───&amp;lt;/code&amp;gt;) in the diagram denote walls at various distances.&lt;br /&gt;
&lt;br /&gt;
In total, there are 25 distinct wall positions within the player’s field of vision. To render all walls correctly, the engine must read 17 map cells (A–Q) from the dungeon layout.&lt;br /&gt;
&lt;br /&gt;
The first 22 x 15 = &#039;&#039;&#039;330&#039;&#039;&#039; tile indices are used for the backdrop. The background is horizontally flipped when &amp;lt;code&amp;gt;party.x &amp;amp; party.y &amp;amp; party.direction == 1&amp;lt;/code&amp;gt;. In other words, certain movements or rotations from the current position cause the background to appear mirrored.&lt;br /&gt;
&lt;br /&gt;
What follows are &#039;&#039;&#039;431&#039;&#039;&#039; tile indices per wall type. [[Eye of the Beholder]] has 6 different wall types: solid wall type 1, solid wall type 2, door frame, stairs up, stairs down and portal. The wall types are defined in the [[Eye of the Beholder Maze Format]] files. Each block in the MAZ file has wall information for all 4 walls (north, east, south, west) from which the wall type is inferred - for each wall in the level.&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;margin:auto;&amp;quot;&lt;br /&gt;
| [[File:BRICK bg.png|frame|Backdrop from BRICK.VMP]]&lt;br /&gt;
| [[File:BRICK wall 1.png|frame|Wall Type 1 from BRICK.VMP]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Render Code ==&lt;br /&gt;
&lt;br /&gt;
Pseudo code for rendering the background:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void drawBackground(bool xflip)&lt;br /&gt;
{&lt;br /&gt;
   for (int y=0; y&amp;lt;15; y++)&lt;br /&gt;
   {&lt;br /&gt;
      for (int x=0; x&amp;lt;22; x++)&lt;br /&gt;
      {&lt;br /&gt;
         int tile;&lt;br /&gt;
 &lt;br /&gt;
         if (xflip)&lt;br /&gt;
            tile=vmp.backgroundTiles[21-x][y];&lt;br /&gt;
         else&lt;br /&gt;
            tile=vmp.backgroundTiles[x][y];&lt;br /&gt;
 &lt;br /&gt;
         /* xor with xflip to make block flip and background flip cancel each other out. */&lt;br /&gt;
         int blockFlip = (tile&amp;amp;0x4000)^flipX;&lt;br /&gt;
         int blockIndex= tile&amp;amp;0x3fff;&lt;br /&gt;
 &lt;br /&gt;
         if (blockFlip)&lt;br /&gt;
            drawBlockXFlip(x*8, y*8, vcn.blocks[blockIndex]);&lt;br /&gt;
         else&lt;br /&gt;
            drawBlock(x*8, y*8, vcn.blocks[blockIndex]);&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To render the walls, we can use this structure:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
struct WallRenderData&lt;br /&gt;
{&lt;br /&gt;
   int baseOffset;&lt;br /&gt;
   int offsetInViewPort;&lt;br /&gt;
   int visibleWidthInBlocks;&lt;br /&gt;
   int visibleHeightInBlocks;&lt;br /&gt;
   int skipValue;&lt;br /&gt;
   int flipFlag;&lt;br /&gt;
} wallRenderData[25] /* 25 different wall positions */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;baseOffset&amp;lt;/code&amp;gt;&lt;br /&gt;
: Base offset into tileIndices[wallType-1]. This is an offset into the 431 index block for each wall type.&lt;br /&gt;
; &amp;lt;code&amp;gt;offsetInViewPort&amp;lt;/code&amp;gt;&lt;br /&gt;
: Where to start rendering in the viewport:&lt;br /&gt;
: &amp;lt;code&amp;gt;xpos = offsetInViewPort % 22;&amp;lt;/code&amp;gt;&lt;br /&gt;
: &amp;lt;code&amp;gt;ypos = offsetInViewPort / 22;&amp;lt;/code&amp;gt;&lt;br /&gt;
; &amp;lt;code&amp;gt;visibleWidthInBlocks&amp;lt;/code&amp;gt;&lt;br /&gt;
: how many tiles to render in x direction.&lt;br /&gt;
; &amp;lt;code&amp;gt;visibleHeightInBlocks&amp;lt;/code&amp;gt;&lt;br /&gt;
: how many tiles to render in y direction.&lt;br /&gt;
; &amp;lt;code&amp;gt;skipValue&amp;lt;/code&amp;gt;&lt;br /&gt;
: Number of tiles to the next row in the tileIndices[wallType-1] array.&lt;br /&gt;
; &amp;lt;code&amp;gt;flipFlag&amp;lt;/code&amp;gt;&lt;br /&gt;
: &amp;lt;code&amp;gt;True&amp;lt;/code&amp;gt; if the wall is to be x-flipped in the viewport. Generally all right-walls are x-flipped.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
   /* Side-Walls left back */&lt;br /&gt;
   { 104, 66,  5,  1,  2, 0},             /* A-east */&lt;br /&gt;
   { 102, 68,  5,  3,  0, 0},             /* B-east */&lt;br /&gt;
   {  97, 74,  5,  1,  0, 0},             /* C-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side-Walls right back */&lt;br /&gt;
   {  97, 79,  5,  1,  0, 1},              /* E-west */&lt;br /&gt;
   { 102, 83,  5,  3,  0, 1},              /* F-west */&lt;br /&gt;
   { 104, 87,  5,  1,  2, 1},              /* G-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls back */&lt;br /&gt;
   { 133, 66,  5,  2,  4, 0},              /* B-south */&lt;br /&gt;
   { 129, 68,  5,  6,  0, 0},              /* C-south */&lt;br /&gt;
   { 129, 74,  5,  6,  0, 0},              /* D-south */&lt;br /&gt;
   { 129, 80,  5,  6,  0, 0},              /* E-south */&lt;br /&gt;
   { 129, 86,  5,  2,  4, 0},              /* F-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle back left */&lt;br /&gt;
   { 117, 66,  6,  2,  0, 0},              /* H-east */&lt;br /&gt;
   {  81, 50,  8,  2,  0, 0},              /* I-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle back right */&lt;br /&gt;
   {  81, 58,  8,  2,  0, 1},              /* K-west */&lt;br /&gt;
   { 117, 86,  6,  2,  0, 1},              /* L-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls middle back */&lt;br /&gt;
   { 163, 44,  8,  6,  4, 0},              /* I-south */&lt;br /&gt;
   { 159, 50,  8, 10,  0, 0},              /* J-south */&lt;br /&gt;
   { 159, 60,  8,  6,  4, 0},              /* K-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle front left */&lt;br /&gt;
   {  45, 25, 12,  3,  0, 0},              /* M-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle front right */&lt;br /&gt;
   {  45, 38, 12,  3,  0, 1},              /* O-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls middle front */&lt;br /&gt;
   { 252, 22, 12,  3, 13, 0},              /* M-south */&lt;br /&gt;
   { 239, 41, 12,  3, 13, 0},              /* O-south */&lt;br /&gt;
   { 239, 25, 12, 16,  0, 0},              /* N-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side wall front left */&lt;br /&gt;
   {  0,  0, 15,  3,  0, 0},              /* P-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side wall front right */&lt;br /&gt;
   {  0, 19, 15,  3,  0, 1},              /* Q-west */&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pseudo code for rendering a wall:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* wallType = wallType index aquired from the wallMapping[mazeByte].wallType. See the .inf file.&lt;br /&gt;
 * wallPosition = index to wall position in the viewport.&lt;br /&gt;
 */&lt;br /&gt;
void drawWall(int wallType, int wallPosition)&lt;br /&gt;
{&lt;br /&gt;
   /* 0x4000 because when x-ored with this flip flag in the tile data,&lt;br /&gt;
      the resulting flip state will be correct */&lt;br /&gt;
   int flipX=wallRenderData[wallPosition].flipFlag ? 0:0x4000;&lt;br /&gt;
   int offset=wallRenderData[wallPosition].baseOffset;&lt;br /&gt;
 &lt;br /&gt;
   for (int y=0; y&amp;lt;wallRenderData[wallPosition].visibleHeightInBlocks; y++)&lt;br /&gt;
   {&lt;br /&gt;
      for (int x=0; x&amp;lt;wallRenderData[wallPosition].visibleWidthInBlocks; x++)&lt;br /&gt;
      {&lt;br /&gt;
         int blockIndex;&lt;br /&gt;
         if (flipX==0)&lt;br /&gt;
         {&lt;br /&gt;
            blockIndex=x+y*22+wallRenderData[wallPosition].offsetInViewPort;&lt;br /&gt;
         }&lt;br /&gt;
         else&lt;br /&gt;
         {&lt;br /&gt;
            blockIndex=wallRenderData[wallPosition].offsetInViewPort+&lt;br /&gt;
                       wallRenderData[wallPosition].visibleWidthInBlocks-&lt;br /&gt;
                       1-&lt;br /&gt;
                       x+y*22;&lt;br /&gt;
         }&lt;br /&gt;
 &lt;br /&gt;
         int xpos=blockIndex%22;&lt;br /&gt;
         int ypos=blockIndex/22;&lt;br /&gt;
 &lt;br /&gt;
         int tile=vmp.wallTiles[wallType][offset];&lt;br /&gt;
 &lt;br /&gt;
         /* xor with wall flip-x to make block flip and wall flip cancel each other out. */&lt;br /&gt;
         int blockFlip = (tile&amp;amp;0x4000)^flipX;&lt;br /&gt;
         int blockIndex= tile&amp;amp;0x3fff;&lt;br /&gt;
 &lt;br /&gt;
         if (blockFlip)&lt;br /&gt;
            drawBlockXFlip(xpos*8, ypos*8, vcn.blocks[blockIndex]);&lt;br /&gt;
         else&lt;br /&gt;
            drawBlock(xpos*8, ypos*8, vcn.blocks[blockIndex]);&lt;br /&gt;
 &lt;br /&gt;
         offset++;&lt;br /&gt;
      }&lt;br /&gt;
      offset+=wallRenderData[wallPosition].skipValue;&lt;br /&gt;
   }&lt;br /&gt;
 &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Relationship to INF, VMP, and MAZ ==&lt;br /&gt;
&lt;br /&gt;
Each level in [[Eye of the Beholder]] references a set of resource files that define its appearance. The &#039;&#039;&#039;INF&#039;&#039;&#039; file serves as the level’s manifest, specifying which &#039;&#039;&#039;VNP&#039;&#039;&#039;, &#039;&#039;&#039;VCN&#039;&#039;&#039;, and &#039;&#039;&#039;MAZ&#039;&#039;&#039; files to use.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;VCN&#039;&#039;&#039; – Contains the raw 8×8 tiles for walls and backdrop components.  &lt;br /&gt;
* &#039;&#039;&#039;VMP&#039;&#039;&#039; – Provides a layout map: it stores indices into the VCN file, defining which tile to place where in the view cone.  &lt;br /&gt;
* &#039;&#039;&#039;MAZ&#039;&#039;&#039; – Defines the wall parameters for each wall in each block (north, east, south, west). From the wall parameters, the wall types are determined (type 1, type 2, doorway, stairs up, stairs down, portal).&lt;br /&gt;
&lt;br /&gt;
Together, these files allow the engine to construct the &#039;&#039;&#039;view cone&#039;&#039;&#039; dynamically:&lt;br /&gt;
&lt;br /&gt;
# The MAZ file tells the engine which wall type to use for which location. (Sidenote: this can be dynamically changed via scripts in the INF file, so the MAZ file only supplies initial values)&lt;br /&gt;
# The VMP file tells the engine which 8×8 tiles from the VCN to use for each wall projection and the backdrop.    &lt;br /&gt;
# The engine combines the tiles according to the VMP layout to render the final 3D view.&lt;/div&gt;</summary>
		<author><name>Fergusdog</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12625</id>
		<title>Eye of the Beholder VMP Format</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12625"/>
		<updated>2025-10-31T04:04:57Z</updated>

		<summary type="html">&lt;p&gt;Fergusdog: /* Render Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NeedMoreInfo}}&lt;br /&gt;
{{Map Infobox&lt;br /&gt;
 | Type = 2D tile-based&lt;br /&gt;
 | Layers = 5&lt;br /&gt;
 | Tile size = 8&amp;amp;times;8&lt;br /&gt;
 | Viewport = 176&amp;amp;times;120&lt;br /&gt;
 | Games = &lt;br /&gt;
   {{Game|Eye of the Beholder}}&lt;br /&gt;
   {{Game|Eye of the Beholder II: The Legend of Darkmoon}}&lt;br /&gt;
   {{Game|Lands of Lore: The Throne of Chaos}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file assembles the tiles from the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset.&lt;br /&gt;
It functions similarly to a map file in other video games, except that in [[Eye of the Beholder]] it does not represent a top-down layout. Instead, it defines the 3D view of the dungeon, often referred to as the &#039;&#039;view cone&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
In essence, the &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file contains a collection of indices that reference tile graphics within the &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. These indices are interpreted by the game’s main executable to construct the player&#039;s first-person view of the world.&lt;br /&gt;
&lt;br /&gt;
== File Format (PC version) ==&lt;br /&gt;
&lt;br /&gt;
In [[Lands of Lore: The Throne of Chaos]], &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; files are compressed , using the [[Westwood LCW]] compression (see [[Westwood CPS Format]]).&lt;br /&gt;
The uncompressed format is defined as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short index_count; &lt;br /&gt;
    unsigned short indices[index_count]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each entry in &amp;lt;code&amp;gt;indices&amp;lt;/code&amp;gt; represents an index that references a specific block in the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. For more details on the index entries, see the [[#Tile Index|Tile Index]] section below.&lt;br /&gt;
&lt;br /&gt;
== File Format (Amiga version) ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short header; &lt;br /&gt;
    unsigned short backdrop_tiles[22][15]; &lt;br /&gt;
    unsigned short padding[101]; &lt;br /&gt;
    unsigned short wall_tiles[wall_types_count][431]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;header&amp;lt;/code&amp;gt;&lt;br /&gt;
: {{TODO|Not yet fully investigated, but most likely specifies the number of wall types defined in the file.}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;backdrop_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the static backdrop (ceiling/floor) image..&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;padding&amp;lt;/code&amp;gt;&lt;br /&gt;
: Each wall type uses 431 tile indices. To match this count for the backdrop tiles, a padding of 101 empty indices is added (&amp;lt;code&amp;gt;22 × 15 + 101 = 431&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the wall graphics for each wall type.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_types_count&amp;lt;/code&amp;gt;&lt;br /&gt;
: Probably stored in the header, but can also be calculated as: &amp;lt;code&amp;gt;(filesize - 2) / (431 * 2) - 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tile Index ==&lt;br /&gt;
&lt;br /&gt;
Each index is represented as a 16-bit value using the following bit structure (most significant bits first):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct TileIndex { &lt;br /&gt;
    bool z-mask: 1; &lt;br /&gt;
    bool mirror_x: 1; &lt;br /&gt;
    unsigned tile_index: 14; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;z-mask&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;, only draw onto the tranparent pixels of the tile(s) below. In effect, acts as a mask for z-order, so the drawn tile appears behind the tile being drawn over. {{TODO|Need to confirm, expand?}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;mirror_x&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; flip the tile horizontally.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;tile_index&amp;lt;/code&amp;gt;&lt;br /&gt;
: A 14-bit index selecting a specific tile from the corresponding &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset (see [[Eye of the Beholder VCN Format]]).&lt;br /&gt;
&lt;br /&gt;
== Rendering the View Cone ==&lt;br /&gt;
&lt;br /&gt;
The 3D view in [[Eye of the Beholder]] covers an area of &#039;&#039;&#039;22 × 15 tiles&#039;&#039;&#039; and is composed of five layers — the backdrop (ceiling and floor) and four wall layers. The backdrop is rendered first and provides the ceiling and floor as a single combined image. The wall layers are then drawn on top, alternating between front-facing and side-facing walls to construct the 3D perspective.&lt;br /&gt;
&lt;br /&gt;
The following diagram illustrates the layout of the view cone:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
Layer 5 (backdrop)  &lt;br /&gt;
                                  ─────────────────────────────────&lt;br /&gt;
Layer 4                               A | B | C | D | E | F | G &lt;br /&gt;
                                         ─── ─── ─── ─── ─── &lt;br /&gt;
Layer 3                                   H | I | J | K | L &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 2                                       M | N | O &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 1 (closest)                             P | ^ | Q  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The caret (&amp;lt;code&amp;gt;^&amp;lt;/code&amp;gt;) represents the party’s position. Vertical bars (&amp;lt;code&amp;gt;|&amp;lt;/code&amp;gt;) and overbars (&amp;lt;code&amp;gt;───&amp;lt;/code&amp;gt;) in the diagram denote walls at various distances.&lt;br /&gt;
&lt;br /&gt;
In total, there are 25 distinct wall positions within the player’s field of vision. To render all walls correctly, the engine must read 17 map cells (A–Q) from the dungeon layout.&lt;br /&gt;
&lt;br /&gt;
The first 22 x 15 = &#039;&#039;&#039;330&#039;&#039;&#039; tile indices are used for the backdrop. The background is horizontally flipped when &amp;lt;code&amp;gt;party.x &amp;amp; party.y &amp;amp; party.direction == 1&amp;lt;/code&amp;gt;. In other words, certain movements or rotations from the current position cause the background to appear mirrored.&lt;br /&gt;
&lt;br /&gt;
What follows are &#039;&#039;&#039;431&#039;&#039;&#039; tile indices per wall type. [[Eye of the Beholder]] has 6 different wall types: solid wall type 1, solid wall type 2, door frame, stairs up, stairs down and portal. The wall types are defined in the [[Eye of the Beholder Maze Format]] files. Each block in the MAZ file has wall information for all 4 walls (north, east, south, west) from which the wall type is inferred - for each wall in the level.&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;margin:auto;&amp;quot;&lt;br /&gt;
| [[File:BRICK bg.png|frame|Backdrop from BRICK.VMP]]&lt;br /&gt;
| [[File:BRICK wall 1.png|frame|Wall Type 1 from BRICK.VMP]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Render Code ==&lt;br /&gt;
&lt;br /&gt;
Pseudo code for rendering the background:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void drawBackground(bool xflip)&lt;br /&gt;
{&lt;br /&gt;
   for (int y=0; y&amp;lt;15; y++)&lt;br /&gt;
   {&lt;br /&gt;
      for (int x=0; x&amp;lt;22; x++)&lt;br /&gt;
      {&lt;br /&gt;
         int tile;&lt;br /&gt;
 &lt;br /&gt;
         if (xflip)&lt;br /&gt;
            tile=vmp.backgroundTiles[21-x][y];&lt;br /&gt;
         else&lt;br /&gt;
            tile=vmp.backgroundTiles[x][y];&lt;br /&gt;
 &lt;br /&gt;
         /* xor with xflip to make block flip and background flip cancel each other out. */&lt;br /&gt;
         int blockFlip = (tile&amp;amp;0x4000)^flipX;&lt;br /&gt;
         int blockIndex= tile&amp;amp;0x3fff;&lt;br /&gt;
 &lt;br /&gt;
         if (blockFlip)&lt;br /&gt;
            drawBlockXFlip(x*8, y*8, vcn.blocks[blockIndex]);&lt;br /&gt;
         else&lt;br /&gt;
            drawBlock(x*8, y*8, vcn.blocks[blockIndex]);&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To render the walls, we can use this structure:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
struct WallRenderData&lt;br /&gt;
{&lt;br /&gt;
   int baseOffset;&lt;br /&gt;
   int offsetInViewPort;&lt;br /&gt;
   int visibleWidthInBlocks;&lt;br /&gt;
   int visibleHeightInBlocks;&lt;br /&gt;
   int skipValue;&lt;br /&gt;
   int flipFlag;&lt;br /&gt;
} wallRenderData[25] /* 25 different wall positions */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;baseOffset&amp;lt;/code&amp;gt;&lt;br /&gt;
: Base offset into tileIndices[wallType-1]. This is an offset into the 431 index block for each wall type.&lt;br /&gt;
; &amp;lt;code&amp;gt;offsetInViewPort&amp;lt;/code&amp;gt;&lt;br /&gt;
: Where to start rendering in the viewport:&lt;br /&gt;
: &amp;lt;code&amp;gt;xpos = offsetInViewPort % 22;&amp;lt;/code&amp;gt;&lt;br /&gt;
: &amp;lt;code&amp;gt;ypos = offsetInViewPort / 22;&amp;lt;/code&amp;gt;&lt;br /&gt;
; &amp;lt;code&amp;gt;visibleWidthInBlocks&amp;lt;/code&amp;gt;&lt;br /&gt;
: how many tiles to render in x direction.&lt;br /&gt;
; &amp;lt;code&amp;gt;visibleHeightInBlocks&amp;lt;/code&amp;gt;&lt;br /&gt;
: how many tiles to render in y direction.&lt;br /&gt;
; &amp;lt;code&amp;gt;skipValue&amp;lt;/code&amp;gt;&lt;br /&gt;
: Number of tiles to the next row in the tileIndices[wallType-1] array.&lt;br /&gt;
; &amp;lt;code&amp;gt;flipFlag&amp;lt;/code&amp;gt;&lt;br /&gt;
: &amp;lt;code&amp;gt;True&amp;lt;/code&amp;gt; if the wall is to be x-flipped in the viewport. Generally all right-walls are x-flipped.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
   /* Side-Walls left back */&lt;br /&gt;
   { 104, 66,  5,  1,  2, 0},             /* A-east */&lt;br /&gt;
   { 102, 68,  5,  3,  0, 0},             /* B-east */&lt;br /&gt;
   {  97, 74,  5,  1,  0, 0},             /* C-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side-Walls right back */&lt;br /&gt;
   {  97, 79,  5,  1,  0, 1},              /* E-west */&lt;br /&gt;
   { 102, 83,  5,  3,  0, 1},              /* F-west */&lt;br /&gt;
   { 104, 87,  5,  1,  2, 1},              /* G-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls back */&lt;br /&gt;
   { 133, 66,  5,  2,  4, 0},              /* B-south */&lt;br /&gt;
   { 129, 68,  5,  6,  0, 0},              /* C-south */&lt;br /&gt;
   { 129, 74,  5,  6,  0, 0},              /* D-south */&lt;br /&gt;
   { 129, 80,  5,  6,  0, 0},              /* E-south */&lt;br /&gt;
   { 129, 86,  5,  2,  4, 0},              /* F-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle back left */&lt;br /&gt;
   { 117, 66,  6,  2,  0, 0},              /* H-east */&lt;br /&gt;
   {  81, 50,  8,  2,  0, 0},              /* I-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle back right */&lt;br /&gt;
   {  81, 58,  8,  2,  0, 1},              /* K-west */&lt;br /&gt;
   { 117, 86,  6,  2,  0, 1},              /* L-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls middle back */&lt;br /&gt;
   { 163, 44,  8,  6,  4, 0},              /* I-south */&lt;br /&gt;
   { 159, 50,  8, 10,  0, 0},              /* J-south */&lt;br /&gt;
   { 159, 60,  8,  6,  4, 0},              /* K-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle front left */&lt;br /&gt;
   {  45, 25, 12,  3,  0, 0},              /* M-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle front right */&lt;br /&gt;
   {  45, 38, 12,  3,  0, 1},              /* O-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls middle front */&lt;br /&gt;
   { 252, 22, 12,  3, 13, 0},              /* M-south */&lt;br /&gt;
   { 239, 41, 12,  3, 13, 0},              /* O-south */&lt;br /&gt;
   { 239, 25, 12, 16,  0, 0},              /* N-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side wall front left */&lt;br /&gt;
   {  0,  0, 15,  3,  0, 0},              /* P-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side wall front right */&lt;br /&gt;
   {  0, 19, 15,  3,  0, 1},              /* Q-west */&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pseudo code for rendering a wall:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* wallType = wallType index aquired from the wallMapping[mazeByte].wallType. See the .inf file.&lt;br /&gt;
 * wallPosition = index to wall position in the viewport.&lt;br /&gt;
 */&lt;br /&gt;
void drawWall(int wallType, int wallPosition)&lt;br /&gt;
{&lt;br /&gt;
   /* 0x4000 because when x-ored with this flip flag in the tile data,&lt;br /&gt;
      the resulting flip state will be correct */&lt;br /&gt;
   int flipX=wallRenderData[wallPosition].flipFlag ? 0:0x4000;&lt;br /&gt;
   int offset=wallRenderData[wallPosition].baseOffset;&lt;br /&gt;
 &lt;br /&gt;
   for (int y=0; y&amp;lt;wallRenderData[wallPosition].visibleHeightInBlocks; y++)&lt;br /&gt;
   {&lt;br /&gt;
      for (int x=0; x&amp;lt;wallRenderData[wallPosition].visibleWidthInBlocks; x++)&lt;br /&gt;
      {&lt;br /&gt;
         int blockIndex;&lt;br /&gt;
         if (flipX==0)&lt;br /&gt;
         {&lt;br /&gt;
            blockIndex=x+y*22+wallRenderData[wallPosition].offsetInViewPort;&lt;br /&gt;
         }&lt;br /&gt;
         else&lt;br /&gt;
         {&lt;br /&gt;
            blockIndex=wallRenderData[wallPosition].offsetInViewPort+&lt;br /&gt;
                       wallRenderData[wallPosition].visibleWidthInBlocks-&lt;br /&gt;
                       1-&lt;br /&gt;
                       x+y*22;&lt;br /&gt;
         }&lt;br /&gt;
 &lt;br /&gt;
         int xpos=blockIndex%22;&lt;br /&gt;
         int ypos=blockIndex/22;&lt;br /&gt;
 &lt;br /&gt;
         int tile=vmp.wallTiles[wallType][offset];&lt;br /&gt;
 &lt;br /&gt;
         /* xor with wall flip-x to make block flip and wall flip cancel each other out. */&lt;br /&gt;
         int blockFlip = (tile&amp;amp;0x4000)^flipX;&lt;br /&gt;
         int blockIndex= tile&amp;amp;0x3fff;&lt;br /&gt;
 &lt;br /&gt;
         if (blockFlip)&lt;br /&gt;
            drawBlockXFlip(xpos*8, ypos*8, vcn.blocks[blockIndex]);&lt;br /&gt;
         else&lt;br /&gt;
            drawBlock(xpos*8, ypos*8, vcn.blocks[blockIndex]);&lt;br /&gt;
 &lt;br /&gt;
         offset++;&lt;br /&gt;
      }&lt;br /&gt;
      offset+=wallRenderData[wallPosition].skipValue;&lt;br /&gt;
   }&lt;br /&gt;
 &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Relationship to INF, VMP, and PAL ==&lt;br /&gt;
&lt;br /&gt;
Each level in &#039;&#039;Eye of the Beholder&#039;&#039; references a set of resource files that define its appearance. The &#039;&#039;&#039;INF&#039;&#039;&#039; file serves as the level’s manifest, specifying which &#039;&#039;&#039;VNP&#039;&#039;&#039;, &#039;&#039;&#039;VCN&#039;&#039;&#039;, and &#039;&#039;&#039;PAL&#039;&#039;&#039; files to use.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;VCN&#039;&#039;&#039; – Contains the raw 8×8 tiles for walls and backdrop components.  &lt;br /&gt;
* &#039;&#039;&#039;VMP&#039;&#039;&#039; – Provides a layout map: it stores indices into the VCN file, defining which tile to place where in the view cone.  &lt;br /&gt;
* &#039;&#039;&#039;PAL&#039;&#039;&#039; – Defines the RGB colors corresponding to palette indices used in the VCN tiles.  &lt;br /&gt;
&lt;br /&gt;
Together, these files allow the engine to construct the &#039;&#039;&#039;view cone&#039;&#039;&#039; dynamically:&lt;br /&gt;
&lt;br /&gt;
# The VMP file tells the engine which 8×8 tiles from the VCN to use for each wall projection and the backdrop.  &lt;br /&gt;
# Each tile references either the backdrop or wall palette.  &lt;br /&gt;
# The palette indices are then mapped to RGB values from the level’s PAL file.  &lt;br /&gt;
# The engine combines the tiles according to the VMP layout to render the final 3D view.&lt;/div&gt;</summary>
		<author><name>Fergusdog</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12624</id>
		<title>Eye of the Beholder VMP Format</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12624"/>
		<updated>2025-10-31T04:03:16Z</updated>

		<summary type="html">&lt;p&gt;Fergusdog: /* Render Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NeedMoreInfo}}&lt;br /&gt;
{{Map Infobox&lt;br /&gt;
 | Type = 2D tile-based&lt;br /&gt;
 | Layers = 5&lt;br /&gt;
 | Tile size = 8&amp;amp;times;8&lt;br /&gt;
 | Viewport = 176&amp;amp;times;120&lt;br /&gt;
 | Games = &lt;br /&gt;
   {{Game|Eye of the Beholder}}&lt;br /&gt;
   {{Game|Eye of the Beholder II: The Legend of Darkmoon}}&lt;br /&gt;
   {{Game|Lands of Lore: The Throne of Chaos}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file assembles the tiles from the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset.&lt;br /&gt;
It functions similarly to a map file in other video games, except that in [[Eye of the Beholder]] it does not represent a top-down layout. Instead, it defines the 3D view of the dungeon, often referred to as the &#039;&#039;view cone&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
In essence, the &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file contains a collection of indices that reference tile graphics within the &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. These indices are interpreted by the game’s main executable to construct the player&#039;s first-person view of the world.&lt;br /&gt;
&lt;br /&gt;
== File Format (PC version) ==&lt;br /&gt;
&lt;br /&gt;
In [[Lands of Lore: The Throne of Chaos]], &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; files are compressed , using the [[Westwood LCW]] compression (see [[Westwood CPS Format]]).&lt;br /&gt;
The uncompressed format is defined as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short index_count; &lt;br /&gt;
    unsigned short indices[index_count]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each entry in &amp;lt;code&amp;gt;indices&amp;lt;/code&amp;gt; represents an index that references a specific block in the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. For more details on the index entries, see the [[#Tile Index|Tile Index]] section below.&lt;br /&gt;
&lt;br /&gt;
== File Format (Amiga version) ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short header; &lt;br /&gt;
    unsigned short backdrop_tiles[22][15]; &lt;br /&gt;
    unsigned short padding[101]; &lt;br /&gt;
    unsigned short wall_tiles[wall_types_count][431]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;header&amp;lt;/code&amp;gt;&lt;br /&gt;
: {{TODO|Not yet fully investigated, but most likely specifies the number of wall types defined in the file.}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;backdrop_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the static backdrop (ceiling/floor) image..&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;padding&amp;lt;/code&amp;gt;&lt;br /&gt;
: Each wall type uses 431 tile indices. To match this count for the backdrop tiles, a padding of 101 empty indices is added (&amp;lt;code&amp;gt;22 × 15 + 101 = 431&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the wall graphics for each wall type.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_types_count&amp;lt;/code&amp;gt;&lt;br /&gt;
: Probably stored in the header, but can also be calculated as: &amp;lt;code&amp;gt;(filesize - 2) / (431 * 2) - 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tile Index ==&lt;br /&gt;
&lt;br /&gt;
Each index is represented as a 16-bit value using the following bit structure (most significant bits first):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct TileIndex { &lt;br /&gt;
    bool z-mask: 1; &lt;br /&gt;
    bool mirror_x: 1; &lt;br /&gt;
    unsigned tile_index: 14; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;z-mask&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;, only draw onto the tranparent pixels of the tile(s) below. In effect, acts as a mask for z-order, so the drawn tile appears behind the tile being drawn over. {{TODO|Need to confirm, expand?}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;mirror_x&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; flip the tile horizontally.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;tile_index&amp;lt;/code&amp;gt;&lt;br /&gt;
: A 14-bit index selecting a specific tile from the corresponding &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset (see [[Eye of the Beholder VCN Format]]).&lt;br /&gt;
&lt;br /&gt;
== Rendering the View Cone ==&lt;br /&gt;
&lt;br /&gt;
The 3D view in [[Eye of the Beholder]] covers an area of &#039;&#039;&#039;22 × 15 tiles&#039;&#039;&#039; and is composed of five layers — the backdrop (ceiling and floor) and four wall layers. The backdrop is rendered first and provides the ceiling and floor as a single combined image. The wall layers are then drawn on top, alternating between front-facing and side-facing walls to construct the 3D perspective.&lt;br /&gt;
&lt;br /&gt;
The following diagram illustrates the layout of the view cone:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
Layer 5 (backdrop)  &lt;br /&gt;
                                  ─────────────────────────────────&lt;br /&gt;
Layer 4                               A | B | C | D | E | F | G &lt;br /&gt;
                                         ─── ─── ─── ─── ─── &lt;br /&gt;
Layer 3                                   H | I | J | K | L &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 2                                       M | N | O &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 1 (closest)                             P | ^ | Q  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The caret (&amp;lt;code&amp;gt;^&amp;lt;/code&amp;gt;) represents the party’s position. Vertical bars (&amp;lt;code&amp;gt;|&amp;lt;/code&amp;gt;) and overbars (&amp;lt;code&amp;gt;───&amp;lt;/code&amp;gt;) in the diagram denote walls at various distances.&lt;br /&gt;
&lt;br /&gt;
In total, there are 25 distinct wall positions within the player’s field of vision. To render all walls correctly, the engine must read 17 map cells (A–Q) from the dungeon layout.&lt;br /&gt;
&lt;br /&gt;
The first 22 x 15 = &#039;&#039;&#039;330&#039;&#039;&#039; tile indices are used for the backdrop. The background is horizontally flipped when &amp;lt;code&amp;gt;party.x &amp;amp; party.y &amp;amp; party.direction == 1&amp;lt;/code&amp;gt;. In other words, certain movements or rotations from the current position cause the background to appear mirrored.&lt;br /&gt;
&lt;br /&gt;
What follows are &#039;&#039;&#039;431&#039;&#039;&#039; tile indices per wall type. [[Eye of the Beholder]] has 6 different wall types: solid wall type 1, solid wall type 2, door frame, stairs up, stairs down and portal. The wall types are defined in the [[Eye of the Beholder Maze Format]] files. Each block in the MAZ file has wall information for all 4 walls (north, east, south, west) from which the wall type is inferred - for each wall in the level.&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;margin:auto;&amp;quot;&lt;br /&gt;
| [[File:BRICK bg.png|frame|Backdrop from BRICK.VMP]]&lt;br /&gt;
| [[File:BRICK wall 1.png|frame|Wall Type 1 from BRICK.VMP]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Render Code ==&lt;br /&gt;
&lt;br /&gt;
Pseudo code for rendering the background:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void drawBackground(bool xflip)&lt;br /&gt;
{&lt;br /&gt;
   for (int y=0; y&amp;lt;15; y++)&lt;br /&gt;
   {&lt;br /&gt;
      for (int x=0; x&amp;lt;22; x++)&lt;br /&gt;
      {&lt;br /&gt;
         int tile;&lt;br /&gt;
 &lt;br /&gt;
         if (xflip)&lt;br /&gt;
            tile=vmp.backgroundTiles[21-x][y];&lt;br /&gt;
         else&lt;br /&gt;
            tile=vmp.backgroundTiles[x][y];&lt;br /&gt;
 &lt;br /&gt;
         /* xor with xflip to make block flip and background flip cancel each other out. */&lt;br /&gt;
         int blockFlip = (tile&amp;amp;0x4000)^flipX;&lt;br /&gt;
         int blockIndex= tile&amp;amp;0x3fff;&lt;br /&gt;
 &lt;br /&gt;
         if (blockFlip)&lt;br /&gt;
            drawBlockXFlip(x*8, y*8, vcn.blocks[blockIndex]);&lt;br /&gt;
         else&lt;br /&gt;
            drawBlock(x*8, y*8, vcn.blocks[blockIndex]);&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To render the walls, we can use this structure:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
struct WallRenderData&lt;br /&gt;
{&lt;br /&gt;
   int baseOffset;&lt;br /&gt;
   int offsetInViewPort;&lt;br /&gt;
   int visibleWidthInBlocks;&lt;br /&gt;
   int visibleHeightInBlocks;&lt;br /&gt;
   int skipValue;&lt;br /&gt;
   int flipFlag;&lt;br /&gt;
} wallRenderData[25] /* 25 different wall positions */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;baseOffset&amp;lt;/code&amp;gt;&lt;br /&gt;
: Base offset into tileIndices[wallType-1]. This is an offset into the 431 index block for each wall type.&lt;br /&gt;
; &amp;lt;code&amp;gt;offsetInViewPort&amp;lt;/code&amp;gt;&lt;br /&gt;
: Where to start rendering in the viewport:&lt;br /&gt;
: &amp;lt;code&amp;gt;xpos = offsetInViewPort % 22;&amp;lt;/code&amp;gt;&lt;br /&gt;
: &amp;lt;code&amp;gt;ypos = offsetInViewPort / 22;&amp;lt;/code&amp;gt;&lt;br /&gt;
; &amp;lt;code&amp;gt;visibleWidthInBlocks&amp;lt;/code&amp;gt;&lt;br /&gt;
: how many tiles to render in x direction.&lt;br /&gt;
; &amp;lt;code&amp;gt;visibleHeightInBlocks&amp;lt;/code&amp;gt;&lt;br /&gt;
: how many tiles to render in y direction.&lt;br /&gt;
; &amp;lt;code&amp;gt;skipValue&amp;lt;/code&amp;gt;&lt;br /&gt;
: Number of tiles to the next row in the tileIndices[wallType-1] array.&lt;br /&gt;
; &amp;lt;code&amp;gt;flipFlag&amp;lt;/code&amp;gt;&lt;br /&gt;
: &amp;lt;code&amp;gt;True&amp;lt;/code&amp;gt; if the wall is to be x-flipped in the viewport. Generally all right-walls are x-flipped.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
   /* Side-Walls left back */&lt;br /&gt;
   { 104, 66,  5,  1,  2, 0},             /* A-east */&lt;br /&gt;
   { 102, 68,  5,  3,  0, 0},             /* B-east */&lt;br /&gt;
   {  97, 74,  5,  1,  0, 0},             /* C-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side-Walls right back */&lt;br /&gt;
   {  97, 79,  5,  1,  0, 1},              /* E-west */&lt;br /&gt;
   { 102, 83,  5,  3,  0, 1},              /* F-west */&lt;br /&gt;
   { 104, 87,  5,  1,  2, 1},              /* G-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls back */&lt;br /&gt;
   { 133, 66,  5,  2,  4, 0},              /* B-south */&lt;br /&gt;
   { 129, 68,  5,  6,  0, 0},              /* C-south */&lt;br /&gt;
   { 129, 74,  5,  6,  0, 0},              /* D-south */&lt;br /&gt;
   { 129, 80,  5,  6,  0, 0},              /* E-south */&lt;br /&gt;
   { 129, 86,  5,  2,  4, 0},              /* F-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle back left */&lt;br /&gt;
   { 117, 66,  6,  2,  0, 0},              /* H-east */&lt;br /&gt;
   {  81, 50,  8,  2,  0, 0},              /* I-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle back right */&lt;br /&gt;
   {  81, 58,  8,  2,  0, 1},              /* K-west */&lt;br /&gt;
   { 117, 86,  6,  2,  0, 1},              /* L-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls middle back */&lt;br /&gt;
   { 163, 44,  8,  6,  4, 0},              /* I-south */&lt;br /&gt;
   { 159, 50,  8, 10,  0, 0},              /* J-south */&lt;br /&gt;
   { 159, 60,  8,  6,  4, 0},              /* K-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle front left */&lt;br /&gt;
   {  45, 25, 12,  3,  0, 0},              /* M-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle front right */&lt;br /&gt;
   {  45, 38, 12,  3,  0, 1},              /* O-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls middle front */&lt;br /&gt;
   { 252, 22, 12,  3, 13, 0},              /* M-south */&lt;br /&gt;
   { 239, 41, 12,  3, 13, 0},              /* O-south */&lt;br /&gt;
   { 239, 25, 12, 16,  0, 0},              /* N-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side wall front left */&lt;br /&gt;
   {  0,  0, 15,  3,  0, 0},              /* P-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side wall front right */&lt;br /&gt;
   {  0, 19, 15,  3,  0, 1},              /* Q-west */&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pseudo code for rendering a wall:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* wallType = wallType index aquired from the wallMapping[mazeByte].wallType. See the .inf file.&lt;br /&gt;
 * wallPosition = index to wall position in the viewport.&lt;br /&gt;
 */&lt;br /&gt;
void drawWall(int wallType, int wallPosition)&lt;br /&gt;
{&lt;br /&gt;
   /* 0x4000 because when x-ored with this flip flag in the tile data,&lt;br /&gt;
      the resulting flip state will be correct */&lt;br /&gt;
   int flipX=wallRenderData[wallPosition].flipFlag ? 0:0x4000;&lt;br /&gt;
   int offset=wallRenderData[wallPosition].baseOffset;&lt;br /&gt;
 &lt;br /&gt;
   for (int y=0; y&amp;lt;wallRenderData[wallPosition].visibleHeightInBlocks; y++)&lt;br /&gt;
   {&lt;br /&gt;
      for (int x=0; x&amp;lt;wallRenderData[wallPosition].visibleWidthInBlocks; x++)&lt;br /&gt;
      {&lt;br /&gt;
         int blockIndex;&lt;br /&gt;
         if (flipX==0)&lt;br /&gt;
         {&lt;br /&gt;
            blockIndex=x+y*22+wallRenderData[wallPosition].offsetInViewPort;&lt;br /&gt;
         }&lt;br /&gt;
         else&lt;br /&gt;
         {&lt;br /&gt;
            blockIndex=wallRenderData[wallPosition].offsetInViewPort+&lt;br /&gt;
                       wallRenderData[wallPosition].visibleWidthInBlocks-&lt;br /&gt;
                       1-&lt;br /&gt;
                       x+y*22;&lt;br /&gt;
         }&lt;br /&gt;
 &lt;br /&gt;
         int xpos=blockIndex%22;&lt;br /&gt;
         int ypos=blockIndex/22;&lt;br /&gt;
 &lt;br /&gt;
         int tile=vmp.wallTiles[wallType][offset];&lt;br /&gt;
 &lt;br /&gt;
         /* xor with wall flip-x to make block flip and wall flip cancel each other out. */&lt;br /&gt;
         int blockFlip = (tile&amp;amp;0x4000)^flipX;&lt;br /&gt;
         int blockIndex= tile&amp;amp;0x3fff;&lt;br /&gt;
 &lt;br /&gt;
         if (blockFlip)&lt;br /&gt;
            drawBlockXFlip(xpos*8, ypos*8, vcn.blocks[blockIndex]);&lt;br /&gt;
         else&lt;br /&gt;
            drawBlock(xpos*8, ypos*8, vcn.blocks[blockIndex]);&lt;br /&gt;
 &lt;br /&gt;
         offset++;&lt;br /&gt;
      }&lt;br /&gt;
      offset+=wallRenderData[wallPosition].skipValue;&lt;br /&gt;
   }&lt;br /&gt;
 &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Fergusdog</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12623</id>
		<title>Eye of the Beholder VMP Format</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12623"/>
		<updated>2025-10-31T04:01:44Z</updated>

		<summary type="html">&lt;p&gt;Fergusdog: /* Render Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NeedMoreInfo}}&lt;br /&gt;
{{Map Infobox&lt;br /&gt;
 | Type = 2D tile-based&lt;br /&gt;
 | Layers = 5&lt;br /&gt;
 | Tile size = 8&amp;amp;times;8&lt;br /&gt;
 | Viewport = 176&amp;amp;times;120&lt;br /&gt;
 | Games = &lt;br /&gt;
   {{Game|Eye of the Beholder}}&lt;br /&gt;
   {{Game|Eye of the Beholder II: The Legend of Darkmoon}}&lt;br /&gt;
   {{Game|Lands of Lore: The Throne of Chaos}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file assembles the tiles from the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset.&lt;br /&gt;
It functions similarly to a map file in other video games, except that in [[Eye of the Beholder]] it does not represent a top-down layout. Instead, it defines the 3D view of the dungeon, often referred to as the &#039;&#039;view cone&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
In essence, the &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file contains a collection of indices that reference tile graphics within the &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. These indices are interpreted by the game’s main executable to construct the player&#039;s first-person view of the world.&lt;br /&gt;
&lt;br /&gt;
== File Format (PC version) ==&lt;br /&gt;
&lt;br /&gt;
In [[Lands of Lore: The Throne of Chaos]], &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; files are compressed , using the [[Westwood LCW]] compression (see [[Westwood CPS Format]]).&lt;br /&gt;
The uncompressed format is defined as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short index_count; &lt;br /&gt;
    unsigned short indices[index_count]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each entry in &amp;lt;code&amp;gt;indices&amp;lt;/code&amp;gt; represents an index that references a specific block in the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. For more details on the index entries, see the [[#Tile Index|Tile Index]] section below.&lt;br /&gt;
&lt;br /&gt;
== File Format (Amiga version) ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short header; &lt;br /&gt;
    unsigned short backdrop_tiles[22][15]; &lt;br /&gt;
    unsigned short padding[101]; &lt;br /&gt;
    unsigned short wall_tiles[wall_types_count][431]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;header&amp;lt;/code&amp;gt;&lt;br /&gt;
: {{TODO|Not yet fully investigated, but most likely specifies the number of wall types defined in the file.}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;backdrop_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the static backdrop (ceiling/floor) image..&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;padding&amp;lt;/code&amp;gt;&lt;br /&gt;
: Each wall type uses 431 tile indices. To match this count for the backdrop tiles, a padding of 101 empty indices is added (&amp;lt;code&amp;gt;22 × 15 + 101 = 431&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the wall graphics for each wall type.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_types_count&amp;lt;/code&amp;gt;&lt;br /&gt;
: Probably stored in the header, but can also be calculated as: &amp;lt;code&amp;gt;(filesize - 2) / (431 * 2) - 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tile Index ==&lt;br /&gt;
&lt;br /&gt;
Each index is represented as a 16-bit value using the following bit structure (most significant bits first):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct TileIndex { &lt;br /&gt;
    bool z-mask: 1; &lt;br /&gt;
    bool mirror_x: 1; &lt;br /&gt;
    unsigned tile_index: 14; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;z-mask&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;, only draw onto the tranparent pixels of the tile(s) below. In effect, acts as a mask for z-order, so the drawn tile appears behind the tile being drawn over. {{TODO|Need to confirm, expand?}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;mirror_x&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; flip the tile horizontally.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;tile_index&amp;lt;/code&amp;gt;&lt;br /&gt;
: A 14-bit index selecting a specific tile from the corresponding &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset (see [[Eye of the Beholder VCN Format]]).&lt;br /&gt;
&lt;br /&gt;
== Rendering the View Cone ==&lt;br /&gt;
&lt;br /&gt;
The 3D view in [[Eye of the Beholder]] covers an area of &#039;&#039;&#039;22 × 15 tiles&#039;&#039;&#039; and is composed of five layers — the backdrop (ceiling and floor) and four wall layers. The backdrop is rendered first and provides the ceiling and floor as a single combined image. The wall layers are then drawn on top, alternating between front-facing and side-facing walls to construct the 3D perspective.&lt;br /&gt;
&lt;br /&gt;
The following diagram illustrates the layout of the view cone:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
Layer 5 (backdrop)  &lt;br /&gt;
                                  ─────────────────────────────────&lt;br /&gt;
Layer 4                               A | B | C | D | E | F | G &lt;br /&gt;
                                         ─── ─── ─── ─── ─── &lt;br /&gt;
Layer 3                                   H | I | J | K | L &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 2                                       M | N | O &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 1 (closest)                             P | ^ | Q  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The caret (&amp;lt;code&amp;gt;^&amp;lt;/code&amp;gt;) represents the party’s position. Vertical bars (&amp;lt;code&amp;gt;|&amp;lt;/code&amp;gt;) and overbars (&amp;lt;code&amp;gt;───&amp;lt;/code&amp;gt;) in the diagram denote walls at various distances.&lt;br /&gt;
&lt;br /&gt;
In total, there are 25 distinct wall positions within the player’s field of vision. To render all walls correctly, the engine must read 17 map cells (A–Q) from the dungeon layout.&lt;br /&gt;
&lt;br /&gt;
The first 22 x 15 = &#039;&#039;&#039;330&#039;&#039;&#039; tile indices are used for the backdrop. The background is horizontally flipped when &amp;lt;code&amp;gt;party.x &amp;amp; party.y &amp;amp; party.direction == 1&amp;lt;/code&amp;gt;. In other words, certain movements or rotations from the current position cause the background to appear mirrored.&lt;br /&gt;
&lt;br /&gt;
What follows are &#039;&#039;&#039;431&#039;&#039;&#039; tile indices per wall type. [[Eye of the Beholder]] has 6 different wall types: solid wall type 1, solid wall type 2, door frame, stairs up, stairs down and portal. The wall types are defined in the [[Eye of the Beholder Maze Format]] files. Each block in the MAZ file has wall information for all 4 walls (north, east, south, west) from which the wall type is inferred - for each wall in the level.&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;margin:auto;&amp;quot;&lt;br /&gt;
| [[File:BRICK bg.png|frame|Backdrop from BRICK.VMP]]&lt;br /&gt;
| [[File:BRICK wall 1.png|frame|Wall Type 1 from BRICK.VMP]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Render Code ==&lt;br /&gt;
&lt;br /&gt;
Pseudo code for rendering the background:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void drawBackground(bool xflip)&lt;br /&gt;
{&lt;br /&gt;
   for (int y=0; y&amp;lt;15; y++)&lt;br /&gt;
   {&lt;br /&gt;
      for (int x=0; x&amp;lt;22; x++)&lt;br /&gt;
      {&lt;br /&gt;
         int tile;&lt;br /&gt;
 &lt;br /&gt;
         if (xflip)&lt;br /&gt;
            tile=vmp.backgroundTiles[21-x][y];&lt;br /&gt;
         else&lt;br /&gt;
            tile=vmp.backgroundTiles[x][y];&lt;br /&gt;
 &lt;br /&gt;
         /* xor with xflip to make block flip and background flip cancel each other out. */&lt;br /&gt;
         int blockFlip = (tile&amp;amp;0x4000)^flipX;&lt;br /&gt;
         int blockIndex= tile&amp;amp;0x3fff;&lt;br /&gt;
 &lt;br /&gt;
         if (blockFlip)&lt;br /&gt;
            drawBlockXFlip(x*8, y*8, vcn.blocks[blockIndex]);&lt;br /&gt;
         else&lt;br /&gt;
            drawBlock(x*8, y*8, vcn.blocks[blockIndex]);&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To render the walls, we can use this structure:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
struct WallRenderData&lt;br /&gt;
{&lt;br /&gt;
   int baseOffset;&lt;br /&gt;
   int offsetInViewPort;&lt;br /&gt;
   int visibleWidthInBlocks;&lt;br /&gt;
   int visibleHeightInBlocks;&lt;br /&gt;
   int skipValue;&lt;br /&gt;
   int flipFlag;&lt;br /&gt;
} wallRenderData[25] /* 25 different wall positions */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;baseOffset&amp;lt;/code&amp;gt;&lt;br /&gt;
: Base offset into tileIndices[wallType-1]. This is an offset into the 431 index block for each wall type.&lt;br /&gt;
; &amp;lt;code&amp;gt;offsetInViewPort&amp;lt;/code&amp;gt;&lt;br /&gt;
: Where to start rendering in the viewport:&lt;br /&gt;
: &amp;lt;code&amp;gt;xpos = offsetInViewPort % 22;&amp;lt;/code&amp;gt;&lt;br /&gt;
: &amp;lt;code&amp;gt;ypos = offsetInViewPort / 22;&amp;lt;/code&amp;gt;&lt;br /&gt;
; &amp;lt;code&amp;gt;visibleWidthInBlocks&amp;lt;/code&amp;gt;&lt;br /&gt;
: how many tiles to render in x direction.&lt;br /&gt;
; &amp;lt;code&amp;gt;visibleHeightInBlocks&amp;lt;/code&amp;gt;&lt;br /&gt;
: how many tiles to render in y direction.&lt;br /&gt;
; &amp;lt;code&amp;gt;skipValue&amp;lt;/code&amp;gt;&lt;br /&gt;
: Number of tiles to the next row in the tileIndices[wallType-1] array.&lt;br /&gt;
; &amp;lt;code&amp;gt;flipFlag&amp;lt;/code&amp;gt;&lt;br /&gt;
: &amp;lt;code&amp;gt;True&amp;lt;/code&amp;gt; if the wall is to be x-flipped in the viewport. Generally all right-walls are x-flipped.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
   /* Side-Walls left back */&lt;br /&gt;
   { 104, 66,  5,  1,  2, 0},             /* A-east */&lt;br /&gt;
   { 102, 68,  5,  3,  0, 0},             /* B-east */&lt;br /&gt;
   {  97, 74,  5,  1,  0, 0},             /* C-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side-Walls right back */&lt;br /&gt;
   {  97, 79,  5,  1,  0, 1},              /* E-west */&lt;br /&gt;
   { 102, 83,  5,  3,  0, 1},              /* F-west */&lt;br /&gt;
   { 104, 87,  5,  1,  2, 1},              /* G-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls back */&lt;br /&gt;
   { 133, 66,  5,  2,  4, 0},              /* B-south */&lt;br /&gt;
   { 129, 68,  5,  6,  0, 0},              /* C-south */&lt;br /&gt;
   { 129, 74,  5,  6,  0, 0},              /* D-south */&lt;br /&gt;
   { 129, 80,  5,  6,  0, 0},              /* E-south */&lt;br /&gt;
   { 129, 86,  5,  2,  4, 0},              /* F-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle back left */&lt;br /&gt;
   { 117, 66,  6,  2,  0, 0},              /* H-east */&lt;br /&gt;
   {  81, 50,  8,  2,  0, 0},              /* I-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle back right */&lt;br /&gt;
   {  81, 58,  8,  2,  0, 1},              /* K-west */&lt;br /&gt;
   { 117, 86,  6,  2,  0, 1},              /* L-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls middle back */&lt;br /&gt;
   { 163, 44,  8,  6,  4, 0},              /* I-south */&lt;br /&gt;
   { 159, 50,  8, 10,  0, 0},              /* J-south */&lt;br /&gt;
   { 159, 60,  8,  6,  4, 0},              /* K-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle front left */&lt;br /&gt;
   {  45, 25, 12,  3,  0, 0},              /* M-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle front right */&lt;br /&gt;
   {  45, 38, 12,  3,  0, 1},              /* O-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls middle front */&lt;br /&gt;
   { 252, 22, 12,  3, 13, 0},              /* M-south */&lt;br /&gt;
   { 239, 41, 12,  3, 13, 0},              /* O-south */&lt;br /&gt;
   { 239, 25, 12, 16,  0, 0},              /* N-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side wall front left */&lt;br /&gt;
   {  0,  0, 15,  3,  0, 0},              /* P-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side wall front right */&lt;br /&gt;
   {  0, 19, 15,  3,  0, 1},              /* Q-west */&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pseudo code for rendering a wall:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   /* wallType = wallType index aquired from the wallMapping[mazeByte].wallType. See the .inf file.&lt;br /&gt;
    * wallPosition = index to wall position in the viewport.&lt;br /&gt;
    */&lt;br /&gt;
   void drawWall(int wallType, int wallPosition)&lt;br /&gt;
   {&lt;br /&gt;
      /* 0x4000 because when x-ored with this flip flag in the tile data,&lt;br /&gt;
         the resulting flip state will be correct */&lt;br /&gt;
      int flipX=wallRenderData[wallPosition].flipFlag ? 0:0x4000;&lt;br /&gt;
      int offset=wallRenderData[wallPosition].baseOffset;&lt;br /&gt;
 &lt;br /&gt;
      for (int y=0; y&amp;lt;wallRenderData[wallPosition].visibleHeightInBlocks; y++)&lt;br /&gt;
      {&lt;br /&gt;
         for (int x=0; x&amp;lt;wallRenderData[wallPosition].visibleWidthInBlocks; x++)&lt;br /&gt;
         {&lt;br /&gt;
            int blockIndex;&lt;br /&gt;
            if (flipX==0)&lt;br /&gt;
            {&lt;br /&gt;
               blockIndex=x+y*22+wallRenderData[wallPosition].offsetInViewPort;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
               blockIndex=wallRenderData[wallPosition].offsetInViewPort+&lt;br /&gt;
                          wallRenderData[wallPosition].visibleWidthInBlocks-&lt;br /&gt;
                          1-&lt;br /&gt;
                          x+y*22;&lt;br /&gt;
            }&lt;br /&gt;
 &lt;br /&gt;
            int xpos=blockIndex%22;&lt;br /&gt;
            int ypos=blockIndex/22;&lt;br /&gt;
 &lt;br /&gt;
            int tile=vmp.wallTiles[wallType][offset];&lt;br /&gt;
 &lt;br /&gt;
            /* xor with wall flip-x to make block flip and wall flip cancel each other out. */&lt;br /&gt;
            int blockFlip = (tile&amp;amp;0x4000)^flipX;&lt;br /&gt;
            int blockIndex= tile&amp;amp;0x3fff;&lt;br /&gt;
 &lt;br /&gt;
            if (blockFlip)&lt;br /&gt;
               drawBlockXFlip(xpos*8, ypos*8, vcn.blocks[blockIndex]);&lt;br /&gt;
            else&lt;br /&gt;
               drawBlock(xpos*8, ypos*8, vcn.blocks[blockIndex]);&lt;br /&gt;
 &lt;br /&gt;
            offset++;&lt;br /&gt;
         }&lt;br /&gt;
        offset+=wallRenderData[wallPosition].skipValue;&lt;br /&gt;
      }&lt;br /&gt;
 &lt;br /&gt;
   }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Fergusdog</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12622</id>
		<title>Eye of the Beholder VMP Format</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12622"/>
		<updated>2025-10-31T03:58:42Z</updated>

		<summary type="html">&lt;p&gt;Fergusdog: /* Render Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NeedMoreInfo}}&lt;br /&gt;
{{Map Infobox&lt;br /&gt;
 | Type = 2D tile-based&lt;br /&gt;
 | Layers = 5&lt;br /&gt;
 | Tile size = 8&amp;amp;times;8&lt;br /&gt;
 | Viewport = 176&amp;amp;times;120&lt;br /&gt;
 | Games = &lt;br /&gt;
   {{Game|Eye of the Beholder}}&lt;br /&gt;
   {{Game|Eye of the Beholder II: The Legend of Darkmoon}}&lt;br /&gt;
   {{Game|Lands of Lore: The Throne of Chaos}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file assembles the tiles from the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset.&lt;br /&gt;
It functions similarly to a map file in other video games, except that in [[Eye of the Beholder]] it does not represent a top-down layout. Instead, it defines the 3D view of the dungeon, often referred to as the &#039;&#039;view cone&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
In essence, the &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file contains a collection of indices that reference tile graphics within the &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. These indices are interpreted by the game’s main executable to construct the player&#039;s first-person view of the world.&lt;br /&gt;
&lt;br /&gt;
== File Format (PC version) ==&lt;br /&gt;
&lt;br /&gt;
In [[Lands of Lore: The Throne of Chaos]], &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; files are compressed , using the [[Westwood LCW]] compression (see [[Westwood CPS Format]]).&lt;br /&gt;
The uncompressed format is defined as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short index_count; &lt;br /&gt;
    unsigned short indices[index_count]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each entry in &amp;lt;code&amp;gt;indices&amp;lt;/code&amp;gt; represents an index that references a specific block in the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. For more details on the index entries, see the [[#Tile Index|Tile Index]] section below.&lt;br /&gt;
&lt;br /&gt;
== File Format (Amiga version) ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short header; &lt;br /&gt;
    unsigned short backdrop_tiles[22][15]; &lt;br /&gt;
    unsigned short padding[101]; &lt;br /&gt;
    unsigned short wall_tiles[wall_types_count][431]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;header&amp;lt;/code&amp;gt;&lt;br /&gt;
: {{TODO|Not yet fully investigated, but most likely specifies the number of wall types defined in the file.}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;backdrop_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the static backdrop (ceiling/floor) image..&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;padding&amp;lt;/code&amp;gt;&lt;br /&gt;
: Each wall type uses 431 tile indices. To match this count for the backdrop tiles, a padding of 101 empty indices is added (&amp;lt;code&amp;gt;22 × 15 + 101 = 431&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the wall graphics for each wall type.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_types_count&amp;lt;/code&amp;gt;&lt;br /&gt;
: Probably stored in the header, but can also be calculated as: &amp;lt;code&amp;gt;(filesize - 2) / (431 * 2) - 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tile Index ==&lt;br /&gt;
&lt;br /&gt;
Each index is represented as a 16-bit value using the following bit structure (most significant bits first):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct TileIndex { &lt;br /&gt;
    bool z-mask: 1; &lt;br /&gt;
    bool mirror_x: 1; &lt;br /&gt;
    unsigned tile_index: 14; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;z-mask&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;, only draw onto the tranparent pixels of the tile(s) below. In effect, acts as a mask for z-order, so the drawn tile appears behind the tile being drawn over. {{TODO|Need to confirm, expand?}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;mirror_x&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; flip the tile horizontally.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;tile_index&amp;lt;/code&amp;gt;&lt;br /&gt;
: A 14-bit index selecting a specific tile from the corresponding &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset (see [[Eye of the Beholder VCN Format]]).&lt;br /&gt;
&lt;br /&gt;
== Rendering the View Cone ==&lt;br /&gt;
&lt;br /&gt;
The 3D view in [[Eye of the Beholder]] covers an area of &#039;&#039;&#039;22 × 15 tiles&#039;&#039;&#039; and is composed of five layers — the backdrop (ceiling and floor) and four wall layers. The backdrop is rendered first and provides the ceiling and floor as a single combined image. The wall layers are then drawn on top, alternating between front-facing and side-facing walls to construct the 3D perspective.&lt;br /&gt;
&lt;br /&gt;
The following diagram illustrates the layout of the view cone:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
Layer 5 (backdrop)  &lt;br /&gt;
                                  ─────────────────────────────────&lt;br /&gt;
Layer 4                               A | B | C | D | E | F | G &lt;br /&gt;
                                         ─── ─── ─── ─── ─── &lt;br /&gt;
Layer 3                                   H | I | J | K | L &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 2                                       M | N | O &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 1 (closest)                             P | ^ | Q  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The caret (&amp;lt;code&amp;gt;^&amp;lt;/code&amp;gt;) represents the party’s position. Vertical bars (&amp;lt;code&amp;gt;|&amp;lt;/code&amp;gt;) and overbars (&amp;lt;code&amp;gt;───&amp;lt;/code&amp;gt;) in the diagram denote walls at various distances.&lt;br /&gt;
&lt;br /&gt;
In total, there are 25 distinct wall positions within the player’s field of vision. To render all walls correctly, the engine must read 17 map cells (A–Q) from the dungeon layout.&lt;br /&gt;
&lt;br /&gt;
The first 22 x 15 = &#039;&#039;&#039;330&#039;&#039;&#039; tile indices are used for the backdrop. The background is horizontally flipped when &amp;lt;code&amp;gt;party.x &amp;amp; party.y &amp;amp; party.direction == 1&amp;lt;/code&amp;gt;. In other words, certain movements or rotations from the current position cause the background to appear mirrored.&lt;br /&gt;
&lt;br /&gt;
What follows are &#039;&#039;&#039;431&#039;&#039;&#039; tile indices per wall type. [[Eye of the Beholder]] has 6 different wall types: solid wall type 1, solid wall type 2, door frame, stairs up, stairs down and portal. The wall types are defined in the [[Eye of the Beholder Maze Format]] files. Each block in the MAZ file has wall information for all 4 walls (north, east, south, west) from which the wall type is inferred - for each wall in the level.&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;margin:auto;&amp;quot;&lt;br /&gt;
| [[File:BRICK bg.png|frame|Backdrop from BRICK.VMP]]&lt;br /&gt;
| [[File:BRICK wall 1.png|frame|Wall Type 1 from BRICK.VMP]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Render Code ==&lt;br /&gt;
&lt;br /&gt;
Pseudo code for rendering the background:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void drawBackground(bool xflip)&lt;br /&gt;
{&lt;br /&gt;
   for (int y=0; y&amp;lt;15; y++)&lt;br /&gt;
   {&lt;br /&gt;
      for (int x=0; x&amp;lt;22; x++)&lt;br /&gt;
      {&lt;br /&gt;
         int tile;&lt;br /&gt;
 &lt;br /&gt;
         if (xflip)&lt;br /&gt;
            tile=vmp.backgroundTiles[21-x][y];&lt;br /&gt;
         else&lt;br /&gt;
            tile=vmp.backgroundTiles[x][y];&lt;br /&gt;
 &lt;br /&gt;
         /* xor with xflip to make block flip and background flip cancel each other out. */&lt;br /&gt;
         int blockFlip = (tile&amp;amp;0x4000)^flipX;&lt;br /&gt;
         int blockIndex= tile&amp;amp;0x3fff;&lt;br /&gt;
 &lt;br /&gt;
         if (blockFlip)&lt;br /&gt;
            drawBlockXFlip(x*8, y*8, vcn.blocks[blockIndex]);&lt;br /&gt;
         else&lt;br /&gt;
            drawBlock(x*8, y*8, vcn.blocks[blockIndex]);&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To render the walls, we can use this structure:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
struct WallRenderData&lt;br /&gt;
{&lt;br /&gt;
   int baseOffset;&lt;br /&gt;
   int offsetInViewPort;&lt;br /&gt;
   int visibleWidthInBlocks;&lt;br /&gt;
   int visibleHeightInBlocks;&lt;br /&gt;
   int skipValue;&lt;br /&gt;
   int flipFlag;&lt;br /&gt;
} wallRenderData[25] /* 25 different wall positions */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;baseOffset&amp;lt;/code&amp;gt;&lt;br /&gt;
: Base offset into tileIndices[wallType-1]. This is an offset into the 431 index block for each wall type.&lt;br /&gt;
; &amp;lt;code&amp;gt;offsetInViewPort&amp;lt;/code&amp;gt;&lt;br /&gt;
: Where to start rendering in the viewport:&lt;br /&gt;
: &amp;lt;code&amp;gt;xpos = offsetInViewPort % 22;&amp;lt;/code&amp;gt;&lt;br /&gt;
: &amp;lt;code&amp;gt;ypos = offsetInViewPort / 22;&amp;lt;/code&amp;gt;&lt;br /&gt;
; &amp;lt;code&amp;gt;visibleWidthInBlocks&amp;lt;/code&amp;gt;&lt;br /&gt;
: how many tiles to render in x direction.&lt;br /&gt;
; &amp;lt;code&amp;gt;visibleHeightInBlocks&amp;lt;/code&amp;gt;&lt;br /&gt;
: how many tiles to render in y direction.&lt;br /&gt;
; &amp;lt;code&amp;gt;skipValue&amp;lt;/code&amp;gt;&lt;br /&gt;
: Number of tiles to the next row in the tileIndices[wallType-1] array.&lt;br /&gt;
; &amp;lt;code&amp;gt;flipFlag&amp;lt;/code&amp;gt;&lt;br /&gt;
: &amp;lt;code&amp;gt;True&amp;lt;/code&amp;gt; if the wall is to be x-flipped in the viewport. Generally all right-walls are x-flipped.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
   /* Side-Walls left back */&lt;br /&gt;
   { 104, 66,  5,  1,  2, 0},             /* A-east */&lt;br /&gt;
   { 102, 68,  5,  3,  0, 0},             /* B-east */&lt;br /&gt;
   {  97, 74,  5,  1,  0, 0},             /* C-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side-Walls right back */&lt;br /&gt;
   {  97, 79,  5,  1,  0, 1},              /* E-west */&lt;br /&gt;
   { 102, 83,  5,  3,  0, 1},              /* F-west */&lt;br /&gt;
   { 104, 87,  5,  1,  2, 1},              /* G-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls back */&lt;br /&gt;
   { 133, 66,  5,  2,  4, 0},              /* B-south */&lt;br /&gt;
   { 129, 68,  5,  6,  0, 0},              /* C-south */&lt;br /&gt;
   { 129, 74,  5,  6,  0, 0},              /* D-south */&lt;br /&gt;
   { 129, 80,  5,  6,  0, 0},              /* E-south */&lt;br /&gt;
   { 129, 86,  5,  2,  4, 0},              /* F-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle back left */&lt;br /&gt;
   { 117, 66,  6,  2,  0, 0},              /* H-east */&lt;br /&gt;
   {  81, 50,  8,  2,  0, 0},              /* I-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle back right */&lt;br /&gt;
   {  81, 58,  8,  2,  0, 1},              /* K-west */&lt;br /&gt;
   { 117, 86,  6,  2,  0, 1},              /* L-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls middle back */&lt;br /&gt;
   { 163, 44,  8,  6,  4, 0},              /* I-south */&lt;br /&gt;
   { 159, 50,  8, 10,  0, 0},              /* J-south */&lt;br /&gt;
   { 159, 60,  8,  6,  4, 0},              /* K-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle front left */&lt;br /&gt;
   {  45, 25, 12,  3,  0, 0},              /* M-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle front right */&lt;br /&gt;
   {  45, 38, 12,  3,  0, 1},              /* O-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls middle front */&lt;br /&gt;
   { 252, 22, 12,  3, 13, 0},              /* M-south */&lt;br /&gt;
   { 239, 41, 12,  3, 13, 0},              /* O-south */&lt;br /&gt;
   { 239, 25, 12, 16,  0, 0},              /* N-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side wall front left */&lt;br /&gt;
   {  0,  0, 15,  3,  0, 0},              /* P-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side wall front right */&lt;br /&gt;
   {  0, 19, 15,  3,  0, 1},              /* Q-west */&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Fergusdog</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12621</id>
		<title>Eye of the Beholder VMP Format</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12621"/>
		<updated>2025-10-31T03:57:24Z</updated>

		<summary type="html">&lt;p&gt;Fergusdog: /* Render Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NeedMoreInfo}}&lt;br /&gt;
{{Map Infobox&lt;br /&gt;
 | Type = 2D tile-based&lt;br /&gt;
 | Layers = 5&lt;br /&gt;
 | Tile size = 8&amp;amp;times;8&lt;br /&gt;
 | Viewport = 176&amp;amp;times;120&lt;br /&gt;
 | Games = &lt;br /&gt;
   {{Game|Eye of the Beholder}}&lt;br /&gt;
   {{Game|Eye of the Beholder II: The Legend of Darkmoon}}&lt;br /&gt;
   {{Game|Lands of Lore: The Throne of Chaos}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file assembles the tiles from the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset.&lt;br /&gt;
It functions similarly to a map file in other video games, except that in [[Eye of the Beholder]] it does not represent a top-down layout. Instead, it defines the 3D view of the dungeon, often referred to as the &#039;&#039;view cone&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
In essence, the &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file contains a collection of indices that reference tile graphics within the &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. These indices are interpreted by the game’s main executable to construct the player&#039;s first-person view of the world.&lt;br /&gt;
&lt;br /&gt;
== File Format (PC version) ==&lt;br /&gt;
&lt;br /&gt;
In [[Lands of Lore: The Throne of Chaos]], &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; files are compressed , using the [[Westwood LCW]] compression (see [[Westwood CPS Format]]).&lt;br /&gt;
The uncompressed format is defined as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short index_count; &lt;br /&gt;
    unsigned short indices[index_count]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each entry in &amp;lt;code&amp;gt;indices&amp;lt;/code&amp;gt; represents an index that references a specific block in the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. For more details on the index entries, see the [[#Tile Index|Tile Index]] section below.&lt;br /&gt;
&lt;br /&gt;
== File Format (Amiga version) ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short header; &lt;br /&gt;
    unsigned short backdrop_tiles[22][15]; &lt;br /&gt;
    unsigned short padding[101]; &lt;br /&gt;
    unsigned short wall_tiles[wall_types_count][431]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;header&amp;lt;/code&amp;gt;&lt;br /&gt;
: {{TODO|Not yet fully investigated, but most likely specifies the number of wall types defined in the file.}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;backdrop_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the static backdrop (ceiling/floor) image..&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;padding&amp;lt;/code&amp;gt;&lt;br /&gt;
: Each wall type uses 431 tile indices. To match this count for the backdrop tiles, a padding of 101 empty indices is added (&amp;lt;code&amp;gt;22 × 15 + 101 = 431&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the wall graphics for each wall type.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_types_count&amp;lt;/code&amp;gt;&lt;br /&gt;
: Probably stored in the header, but can also be calculated as: &amp;lt;code&amp;gt;(filesize - 2) / (431 * 2) - 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tile Index ==&lt;br /&gt;
&lt;br /&gt;
Each index is represented as a 16-bit value using the following bit structure (most significant bits first):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct TileIndex { &lt;br /&gt;
    bool z-mask: 1; &lt;br /&gt;
    bool mirror_x: 1; &lt;br /&gt;
    unsigned tile_index: 14; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;z-mask&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;, only draw onto the tranparent pixels of the tile(s) below. In effect, acts as a mask for z-order, so the drawn tile appears behind the tile being drawn over. {{TODO|Need to confirm, expand?}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;mirror_x&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; flip the tile horizontally.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;tile_index&amp;lt;/code&amp;gt;&lt;br /&gt;
: A 14-bit index selecting a specific tile from the corresponding &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset (see [[Eye of the Beholder VCN Format]]).&lt;br /&gt;
&lt;br /&gt;
== Rendering the View Cone ==&lt;br /&gt;
&lt;br /&gt;
The 3D view in [[Eye of the Beholder]] covers an area of &#039;&#039;&#039;22 × 15 tiles&#039;&#039;&#039; and is composed of five layers — the backdrop (ceiling and floor) and four wall layers. The backdrop is rendered first and provides the ceiling and floor as a single combined image. The wall layers are then drawn on top, alternating between front-facing and side-facing walls to construct the 3D perspective.&lt;br /&gt;
&lt;br /&gt;
The following diagram illustrates the layout of the view cone:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
Layer 5 (backdrop)  &lt;br /&gt;
                                  ─────────────────────────────────&lt;br /&gt;
Layer 4                               A | B | C | D | E | F | G &lt;br /&gt;
                                         ─── ─── ─── ─── ─── &lt;br /&gt;
Layer 3                                   H | I | J | K | L &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 2                                       M | N | O &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 1 (closest)                             P | ^ | Q  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The caret (&amp;lt;code&amp;gt;^&amp;lt;/code&amp;gt;) represents the party’s position. Vertical bars (&amp;lt;code&amp;gt;|&amp;lt;/code&amp;gt;) and overbars (&amp;lt;code&amp;gt;───&amp;lt;/code&amp;gt;) in the diagram denote walls at various distances.&lt;br /&gt;
&lt;br /&gt;
In total, there are 25 distinct wall positions within the player’s field of vision. To render all walls correctly, the engine must read 17 map cells (A–Q) from the dungeon layout.&lt;br /&gt;
&lt;br /&gt;
The first 22 x 15 = &#039;&#039;&#039;330&#039;&#039;&#039; tile indices are used for the backdrop. The background is horizontally flipped when &amp;lt;code&amp;gt;party.x &amp;amp; party.y &amp;amp; party.direction == 1&amp;lt;/code&amp;gt;. In other words, certain movements or rotations from the current position cause the background to appear mirrored.&lt;br /&gt;
&lt;br /&gt;
What follows are &#039;&#039;&#039;431&#039;&#039;&#039; tile indices per wall type. [[Eye of the Beholder]] has 6 different wall types: solid wall type 1, solid wall type 2, door frame, stairs up, stairs down and portal. The wall types are defined in the [[Eye of the Beholder Maze Format]] files. Each block in the MAZ file has wall information for all 4 walls (north, east, south, west) from which the wall type is inferred - for each wall in the level.&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;margin:auto;&amp;quot;&lt;br /&gt;
| [[File:BRICK bg.png|frame|Backdrop from BRICK.VMP]]&lt;br /&gt;
| [[File:BRICK wall 1.png|frame|Wall Type 1 from BRICK.VMP]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Render Code ==&lt;br /&gt;
&lt;br /&gt;
Pseudo code for rendering the background:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void drawBackground(bool xflip)&lt;br /&gt;
{&lt;br /&gt;
   for (int y=0; y&amp;lt;15; y++)&lt;br /&gt;
   {&lt;br /&gt;
      for (int x=0; x&amp;lt;22; x++)&lt;br /&gt;
      {&lt;br /&gt;
         int tile;&lt;br /&gt;
 &lt;br /&gt;
         if (xflip)&lt;br /&gt;
            tile=vmp.backgroundTiles[21-x][y];&lt;br /&gt;
         else&lt;br /&gt;
            tile=vmp.backgroundTiles[x][y];&lt;br /&gt;
 &lt;br /&gt;
         /* xor with xflip to make block flip and background flip cancel each other out. */&lt;br /&gt;
         int blockFlip = (tile&amp;amp;0x4000)^flipX;&lt;br /&gt;
         int blockIndex= tile&amp;amp;0x3fff;&lt;br /&gt;
 &lt;br /&gt;
         if (blockFlip)&lt;br /&gt;
            drawBlockXFlip(x*8, y*8, vcn.blocks[blockIndex]);&lt;br /&gt;
         else&lt;br /&gt;
            drawBlock(x*8, y*8, vcn.blocks[blockIndex]);&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To render the walls, we can use this structure:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
struct WallRenderData&lt;br /&gt;
{&lt;br /&gt;
   int baseOffset;&lt;br /&gt;
   int offsetInViewPort;&lt;br /&gt;
   int visibleWidthInBlocks;&lt;br /&gt;
   int visibleHeightInBlocks;&lt;br /&gt;
   int skipValue;&lt;br /&gt;
   int flipFlag;&lt;br /&gt;
} wallRenderData[25] /* 25 different wall positions */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;baseOffset&amp;lt;/code&amp;gt;&lt;br /&gt;
: Base offset into tileIndices[wallType-1]. This is an offset into the 431 index block for each wall type.&lt;br /&gt;
; &amp;lt;code&amp;gt;offsetInViewPort&amp;lt;/code&amp;gt;&lt;br /&gt;
: Where to start rendering in the viewport:&lt;br /&gt;
: &amp;lt;code&amp;gt;xpos = offsetInViewPort % 22;&amp;lt;/code&amp;gt;&lt;br /&gt;
: &amp;lt;code&amp;gt;ypos = offsetInViewPort / 22;&amp;lt;/code&amp;gt;&lt;br /&gt;
; &amp;lt;code&amp;gt;visibleWidthInBlocks&amp;lt;/code&amp;gt;&lt;br /&gt;
: how many tiles to render in x direction.&lt;br /&gt;
; &amp;lt;code&amp;gt;visibleHeightInBlocks&amp;lt;/code&amp;gt;&lt;br /&gt;
: how many tiles to render in y direction.&lt;br /&gt;
; &amp;lt;code&amp;gt;skipValue&amp;lt;/code&amp;gt;&lt;br /&gt;
: Number of tiles to the next row in the tileIndices[wallType-1] array.&lt;br /&gt;
; &amp;lt;code&amp;gt;flipFlag&amp;lt;/code&amp;gt;&lt;br /&gt;
: &amp;lt;code&amp;gt;True&amp;lt;/code&amp;gt; if the wall is to be x-flipped in the viewport. Generally all right-walls are x-flipped.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
   /* Side-Walls left back */&lt;br /&gt;
   { 104, 66,  5,  1,  2, 0},             /* A-east */&lt;br /&gt;
   { 102, 68,  5,  3,  0, 0},             /* B-east */&lt;br /&gt;
   {  97, 74,  5,  1,  0, 0},             /* C-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side-Walls right back */&lt;br /&gt;
   {  97, 79,  5,  1,  0, 1},              /* E-west */&lt;br /&gt;
   { 102, 83,  5,  3,  0, 1},              /* F-west */&lt;br /&gt;
   { 104, 87,  5,  1,  2, 1},              /* G-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls back */&lt;br /&gt;
   { 133, 66,  5,  2,  4, 0},              /* B-south */&lt;br /&gt;
   { 129, 68,  5,  6,  0, 0},              /* C-south */&lt;br /&gt;
   { 129, 74,  5,  6,  0, 0},              /* D-south */&lt;br /&gt;
   { 129, 80,  5,  6,  0, 0},              /* E-south */&lt;br /&gt;
   { 129, 86,  5,  2,  4, 0},              /* F-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle back left */&lt;br /&gt;
   { 117, 66,  6,  2,  0, 0},              /* H-east */&lt;br /&gt;
   {  81, 50,  8,  2,  0, 0},              /* I-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle back right */&lt;br /&gt;
   {  81, 58,  8,  2,  0, 1},              /* K-west */&lt;br /&gt;
   { 117, 86,  6,  2,  0, 1},              /* L-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls middle back */&lt;br /&gt;
   {  62, 44,  8,  6,  4, 0},              /* I-south */&lt;br /&gt;
   {  58, 50,  8, 10,  0, 0},              /* J-south */&lt;br /&gt;
   {  58, 60,  8,  6,  4, 0},              /* K-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle front left */&lt;br /&gt;
   { -56, 25, 12,  3,  0, 0},              /* M-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle front right */&lt;br /&gt;
   { -56, 38, 12,  3,  0, 1},              /* O-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls middle front */&lt;br /&gt;
   { 151, 22, 12,  3, 13, 0},              /* M-south */&lt;br /&gt;
   { 138, 41, 12,  3, 13, 0},              /* O-south */&lt;br /&gt;
   { 138, 25, 12, 16,  0, 0},              /* N-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side wall front left */&lt;br /&gt;
   {-101,  0, 15,  3,  0, 0},              /* P-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side wall front right */&lt;br /&gt;
   {-101, 19, 15,  3,  0, 1},              /* Q-west */&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Fergusdog</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12620</id>
		<title>Eye of the Beholder VMP Format</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12620"/>
		<updated>2025-10-31T03:56:03Z</updated>

		<summary type="html">&lt;p&gt;Fergusdog: /* Render Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NeedMoreInfo}}&lt;br /&gt;
{{Map Infobox&lt;br /&gt;
 | Type = 2D tile-based&lt;br /&gt;
 | Layers = 5&lt;br /&gt;
 | Tile size = 8&amp;amp;times;8&lt;br /&gt;
 | Viewport = 176&amp;amp;times;120&lt;br /&gt;
 | Games = &lt;br /&gt;
   {{Game|Eye of the Beholder}}&lt;br /&gt;
   {{Game|Eye of the Beholder II: The Legend of Darkmoon}}&lt;br /&gt;
   {{Game|Lands of Lore: The Throne of Chaos}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file assembles the tiles from the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset.&lt;br /&gt;
It functions similarly to a map file in other video games, except that in [[Eye of the Beholder]] it does not represent a top-down layout. Instead, it defines the 3D view of the dungeon, often referred to as the &#039;&#039;view cone&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
In essence, the &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file contains a collection of indices that reference tile graphics within the &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. These indices are interpreted by the game’s main executable to construct the player&#039;s first-person view of the world.&lt;br /&gt;
&lt;br /&gt;
== File Format (PC version) ==&lt;br /&gt;
&lt;br /&gt;
In [[Lands of Lore: The Throne of Chaos]], &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; files are compressed , using the [[Westwood LCW]] compression (see [[Westwood CPS Format]]).&lt;br /&gt;
The uncompressed format is defined as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short index_count; &lt;br /&gt;
    unsigned short indices[index_count]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each entry in &amp;lt;code&amp;gt;indices&amp;lt;/code&amp;gt; represents an index that references a specific block in the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. For more details on the index entries, see the [[#Tile Index|Tile Index]] section below.&lt;br /&gt;
&lt;br /&gt;
== File Format (Amiga version) ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short header; &lt;br /&gt;
    unsigned short backdrop_tiles[22][15]; &lt;br /&gt;
    unsigned short padding[101]; &lt;br /&gt;
    unsigned short wall_tiles[wall_types_count][431]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;header&amp;lt;/code&amp;gt;&lt;br /&gt;
: {{TODO|Not yet fully investigated, but most likely specifies the number of wall types defined in the file.}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;backdrop_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the static backdrop (ceiling/floor) image..&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;padding&amp;lt;/code&amp;gt;&lt;br /&gt;
: Each wall type uses 431 tile indices. To match this count for the backdrop tiles, a padding of 101 empty indices is added (&amp;lt;code&amp;gt;22 × 15 + 101 = 431&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the wall graphics for each wall type.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_types_count&amp;lt;/code&amp;gt;&lt;br /&gt;
: Probably stored in the header, but can also be calculated as: &amp;lt;code&amp;gt;(filesize - 2) / (431 * 2) - 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tile Index ==&lt;br /&gt;
&lt;br /&gt;
Each index is represented as a 16-bit value using the following bit structure (most significant bits first):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct TileIndex { &lt;br /&gt;
    bool z-mask: 1; &lt;br /&gt;
    bool mirror_x: 1; &lt;br /&gt;
    unsigned tile_index: 14; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;z-mask&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;, only draw onto the tranparent pixels of the tile(s) below. In effect, acts as a mask for z-order, so the drawn tile appears behind the tile being drawn over. {{TODO|Need to confirm, expand?}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;mirror_x&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; flip the tile horizontally.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;tile_index&amp;lt;/code&amp;gt;&lt;br /&gt;
: A 14-bit index selecting a specific tile from the corresponding &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset (see [[Eye of the Beholder VCN Format]]).&lt;br /&gt;
&lt;br /&gt;
== Rendering the View Cone ==&lt;br /&gt;
&lt;br /&gt;
The 3D view in [[Eye of the Beholder]] covers an area of &#039;&#039;&#039;22 × 15 tiles&#039;&#039;&#039; and is composed of five layers — the backdrop (ceiling and floor) and four wall layers. The backdrop is rendered first and provides the ceiling and floor as a single combined image. The wall layers are then drawn on top, alternating between front-facing and side-facing walls to construct the 3D perspective.&lt;br /&gt;
&lt;br /&gt;
The following diagram illustrates the layout of the view cone:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
Layer 5 (backdrop)  &lt;br /&gt;
                                  ─────────────────────────────────&lt;br /&gt;
Layer 4                               A | B | C | D | E | F | G &lt;br /&gt;
                                         ─── ─── ─── ─── ─── &lt;br /&gt;
Layer 3                                   H | I | J | K | L &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 2                                       M | N | O &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 1 (closest)                             P | ^ | Q  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The caret (&amp;lt;code&amp;gt;^&amp;lt;/code&amp;gt;) represents the party’s position. Vertical bars (&amp;lt;code&amp;gt;|&amp;lt;/code&amp;gt;) and overbars (&amp;lt;code&amp;gt;───&amp;lt;/code&amp;gt;) in the diagram denote walls at various distances.&lt;br /&gt;
&lt;br /&gt;
In total, there are 25 distinct wall positions within the player’s field of vision. To render all walls correctly, the engine must read 17 map cells (A–Q) from the dungeon layout.&lt;br /&gt;
&lt;br /&gt;
The first 22 x 15 = &#039;&#039;&#039;330&#039;&#039;&#039; tile indices are used for the backdrop. The background is horizontally flipped when &amp;lt;code&amp;gt;party.x &amp;amp; party.y &amp;amp; party.direction == 1&amp;lt;/code&amp;gt;. In other words, certain movements or rotations from the current position cause the background to appear mirrored.&lt;br /&gt;
&lt;br /&gt;
What follows are &#039;&#039;&#039;431&#039;&#039;&#039; tile indices per wall type. [[Eye of the Beholder]] has 6 different wall types: solid wall type 1, solid wall type 2, door frame, stairs up, stairs down and portal. The wall types are defined in the [[Eye of the Beholder Maze Format]] files. Each block in the MAZ file has wall information for all 4 walls (north, east, south, west) from which the wall type is inferred - for each wall in the level.&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;margin:auto;&amp;quot;&lt;br /&gt;
| [[File:BRICK bg.png|frame|Backdrop from BRICK.VMP]]&lt;br /&gt;
| [[File:BRICK wall 1.png|frame|Wall Type 1 from BRICK.VMP]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Render Code ==&lt;br /&gt;
&lt;br /&gt;
Pseudo code for rendering the background:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void drawBackground(bool xflip)&lt;br /&gt;
{&lt;br /&gt;
   for (int y=0; y&amp;lt;15; y++)&lt;br /&gt;
   {&lt;br /&gt;
      for (int x=0; x&amp;lt;22; x++)&lt;br /&gt;
      {&lt;br /&gt;
         int tile;&lt;br /&gt;
 &lt;br /&gt;
         if (xflip)&lt;br /&gt;
            tile=vmp.backgroundTiles[21-x][y];&lt;br /&gt;
         else&lt;br /&gt;
            tile=vmp.backgroundTiles[x][y];&lt;br /&gt;
 &lt;br /&gt;
         /* xor with xflip to make block flip and background flip cancel each other out. */&lt;br /&gt;
         int blockFlip = (tile&amp;amp;0x4000)^flipX;&lt;br /&gt;
         int blockIndex= tile&amp;amp;0x3fff;&lt;br /&gt;
 &lt;br /&gt;
         if (blockFlip)&lt;br /&gt;
            drawBlockXFlip(x*8, y*8, vcn.blocks[blockIndex]);&lt;br /&gt;
         else&lt;br /&gt;
            drawBlock(x*8, y*8, vcn.blocks[blockIndex]);&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To render the walls, we can use this structure:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
struct WallRenderData&lt;br /&gt;
{&lt;br /&gt;
   int baseOffset;&lt;br /&gt;
   int offsetInViewPort;&lt;br /&gt;
   int visibleWidthInBlocks;&lt;br /&gt;
   int visibleHeightInBlocks;&lt;br /&gt;
   int skipValue;&lt;br /&gt;
   int flipFlag;&lt;br /&gt;
} wallRenderData[25] /* 25 different wall positions */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;baseOffset&amp;lt;/code&amp;gt;&lt;br /&gt;
: Base offset into tileIndices[wallType-1]. This is an offset into the 431 index block for each wall type.&lt;br /&gt;
; &amp;lt;code&amp;gt;offsetInViewPort&amp;lt;/code&amp;gt;&lt;br /&gt;
: Where to start rendering in the viewport:&lt;br /&gt;
: &amp;lt;code&amp;gt;xpos = offsetInViewPort % 22;&amp;lt;/code&amp;gt;&lt;br /&gt;
: &amp;lt;code&amp;gt;ypos = offsetInViewPort / 22;&amp;lt;/code&amp;gt;&lt;br /&gt;
; &amp;lt;code&amp;gt;visibleWidthInBlocks&amp;lt;/code&amp;gt;&lt;br /&gt;
: how many tiles to render in x direction.&lt;br /&gt;
; &amp;lt;code&amp;gt;visibleHeightInBlocks&amp;lt;/code&amp;gt;&lt;br /&gt;
: how many tiles to render in y direction.&lt;br /&gt;
; &amp;lt;code&amp;gt;skipValue&amp;lt;/code&amp;gt;&lt;br /&gt;
: Number of tiles to the next row in the tileIndices[wallType-1] array.&lt;br /&gt;
; &amp;lt;code&amp;gt;flipFlag&amp;lt;/code&amp;gt;&lt;br /&gt;
: &amp;lt;code&amp;gt;True&amp;lt;/code&amp;gt; if the wall is to be x-flipped in the viewport. Generally all right-walls are x-flipped.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
   /* Side-Walls left back */&lt;br /&gt;
   { 104, 66,  5,  1,  2, 0},             /* A-east */&lt;br /&gt;
   { 102, 68,  5,  3,  0, 0},             /* B-east */&lt;br /&gt;
   {  97, 74,  5,  1,  0, 0},             /* C-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side-Walls right back */&lt;br /&gt;
   {  97, 79,  5,  1,  0, 1},              /* E-west */&lt;br /&gt;
   { 102, 83,  5,  3,  0, 1},              /* F-west */&lt;br /&gt;
   { 104, 87,  5,  1,  2, 1},              /* G-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls back */&lt;br /&gt;
   {  32, 66,  5,  2,  4, 0},              /* B-south */&lt;br /&gt;
   {  28, 68,  5,  6,  0, 0},              /* C-south */&lt;br /&gt;
   {  28, 74,  5,  6,  0, 0},              /* D-south */&lt;br /&gt;
   {  28, 80,  5,  6,  0, 0},              /* E-south */&lt;br /&gt;
   {  28, 86,  5,  2,  4, 0},              /* F-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle back left */&lt;br /&gt;
   {  16, 66,  6,  2,  0, 0},              /* H-east */&lt;br /&gt;
   { -20, 50,  8,  2,  0, 0},              /* I-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle back right */&lt;br /&gt;
   { -20, 58,  8,  2,  0, 1},              /* K-west */&lt;br /&gt;
   {  16, 86,  6,  2,  0, 1},              /* L-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls middle back */&lt;br /&gt;
   {  62, 44,  8,  6,  4, 0},              /* I-south */&lt;br /&gt;
   {  58, 50,  8, 10,  0, 0},              /* J-south */&lt;br /&gt;
   {  58, 60,  8,  6,  4, 0},              /* K-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle front left */&lt;br /&gt;
   { -56, 25, 12,  3,  0, 0},              /* M-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle front right */&lt;br /&gt;
   { -56, 38, 12,  3,  0, 1},              /* O-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls middle front */&lt;br /&gt;
   { 151, 22, 12,  3, 13, 0},              /* M-south */&lt;br /&gt;
   { 138, 41, 12,  3, 13, 0},              /* O-south */&lt;br /&gt;
   { 138, 25, 12, 16,  0, 0},              /* N-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side wall front left */&lt;br /&gt;
   {-101,  0, 15,  3,  0, 0},              /* P-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side wall front right */&lt;br /&gt;
   {-101, 19, 15,  3,  0, 1},              /* Q-west */&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Fergusdog</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12619</id>
		<title>Eye of the Beholder VMP Format</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12619"/>
		<updated>2025-10-31T03:54:56Z</updated>

		<summary type="html">&lt;p&gt;Fergusdog: /* Render Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NeedMoreInfo}}&lt;br /&gt;
{{Map Infobox&lt;br /&gt;
 | Type = 2D tile-based&lt;br /&gt;
 | Layers = 5&lt;br /&gt;
 | Tile size = 8&amp;amp;times;8&lt;br /&gt;
 | Viewport = 176&amp;amp;times;120&lt;br /&gt;
 | Games = &lt;br /&gt;
   {{Game|Eye of the Beholder}}&lt;br /&gt;
   {{Game|Eye of the Beholder II: The Legend of Darkmoon}}&lt;br /&gt;
   {{Game|Lands of Lore: The Throne of Chaos}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file assembles the tiles from the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset.&lt;br /&gt;
It functions similarly to a map file in other video games, except that in [[Eye of the Beholder]] it does not represent a top-down layout. Instead, it defines the 3D view of the dungeon, often referred to as the &#039;&#039;view cone&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
In essence, the &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file contains a collection of indices that reference tile graphics within the &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. These indices are interpreted by the game’s main executable to construct the player&#039;s first-person view of the world.&lt;br /&gt;
&lt;br /&gt;
== File Format (PC version) ==&lt;br /&gt;
&lt;br /&gt;
In [[Lands of Lore: The Throne of Chaos]], &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; files are compressed , using the [[Westwood LCW]] compression (see [[Westwood CPS Format]]).&lt;br /&gt;
The uncompressed format is defined as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short index_count; &lt;br /&gt;
    unsigned short indices[index_count]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each entry in &amp;lt;code&amp;gt;indices&amp;lt;/code&amp;gt; represents an index that references a specific block in the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. For more details on the index entries, see the [[#Tile Index|Tile Index]] section below.&lt;br /&gt;
&lt;br /&gt;
== File Format (Amiga version) ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short header; &lt;br /&gt;
    unsigned short backdrop_tiles[22][15]; &lt;br /&gt;
    unsigned short padding[101]; &lt;br /&gt;
    unsigned short wall_tiles[wall_types_count][431]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;header&amp;lt;/code&amp;gt;&lt;br /&gt;
: {{TODO|Not yet fully investigated, but most likely specifies the number of wall types defined in the file.}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;backdrop_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the static backdrop (ceiling/floor) image..&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;padding&amp;lt;/code&amp;gt;&lt;br /&gt;
: Each wall type uses 431 tile indices. To match this count for the backdrop tiles, a padding of 101 empty indices is added (&amp;lt;code&amp;gt;22 × 15 + 101 = 431&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the wall graphics for each wall type.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_types_count&amp;lt;/code&amp;gt;&lt;br /&gt;
: Probably stored in the header, but can also be calculated as: &amp;lt;code&amp;gt;(filesize - 2) / (431 * 2) - 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tile Index ==&lt;br /&gt;
&lt;br /&gt;
Each index is represented as a 16-bit value using the following bit structure (most significant bits first):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct TileIndex { &lt;br /&gt;
    bool z-mask: 1; &lt;br /&gt;
    bool mirror_x: 1; &lt;br /&gt;
    unsigned tile_index: 14; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;z-mask&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;, only draw onto the tranparent pixels of the tile(s) below. In effect, acts as a mask for z-order, so the drawn tile appears behind the tile being drawn over. {{TODO|Need to confirm, expand?}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;mirror_x&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; flip the tile horizontally.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;tile_index&amp;lt;/code&amp;gt;&lt;br /&gt;
: A 14-bit index selecting a specific tile from the corresponding &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset (see [[Eye of the Beholder VCN Format]]).&lt;br /&gt;
&lt;br /&gt;
== Rendering the View Cone ==&lt;br /&gt;
&lt;br /&gt;
The 3D view in [[Eye of the Beholder]] covers an area of &#039;&#039;&#039;22 × 15 tiles&#039;&#039;&#039; and is composed of five layers — the backdrop (ceiling and floor) and four wall layers. The backdrop is rendered first and provides the ceiling and floor as a single combined image. The wall layers are then drawn on top, alternating between front-facing and side-facing walls to construct the 3D perspective.&lt;br /&gt;
&lt;br /&gt;
The following diagram illustrates the layout of the view cone:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
Layer 5 (backdrop)  &lt;br /&gt;
                                  ─────────────────────────────────&lt;br /&gt;
Layer 4                               A | B | C | D | E | F | G &lt;br /&gt;
                                         ─── ─── ─── ─── ─── &lt;br /&gt;
Layer 3                                   H | I | J | K | L &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 2                                       M | N | O &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 1 (closest)                             P | ^ | Q  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The caret (&amp;lt;code&amp;gt;^&amp;lt;/code&amp;gt;) represents the party’s position. Vertical bars (&amp;lt;code&amp;gt;|&amp;lt;/code&amp;gt;) and overbars (&amp;lt;code&amp;gt;───&amp;lt;/code&amp;gt;) in the diagram denote walls at various distances.&lt;br /&gt;
&lt;br /&gt;
In total, there are 25 distinct wall positions within the player’s field of vision. To render all walls correctly, the engine must read 17 map cells (A–Q) from the dungeon layout.&lt;br /&gt;
&lt;br /&gt;
The first 22 x 15 = &#039;&#039;&#039;330&#039;&#039;&#039; tile indices are used for the backdrop. The background is horizontally flipped when &amp;lt;code&amp;gt;party.x &amp;amp; party.y &amp;amp; party.direction == 1&amp;lt;/code&amp;gt;. In other words, certain movements or rotations from the current position cause the background to appear mirrored.&lt;br /&gt;
&lt;br /&gt;
What follows are &#039;&#039;&#039;431&#039;&#039;&#039; tile indices per wall type. [[Eye of the Beholder]] has 6 different wall types: solid wall type 1, solid wall type 2, door frame, stairs up, stairs down and portal. The wall types are defined in the [[Eye of the Beholder Maze Format]] files. Each block in the MAZ file has wall information for all 4 walls (north, east, south, west) from which the wall type is inferred - for each wall in the level.&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;margin:auto;&amp;quot;&lt;br /&gt;
| [[File:BRICK bg.png|frame|Backdrop from BRICK.VMP]]&lt;br /&gt;
| [[File:BRICK wall 1.png|frame|Wall Type 1 from BRICK.VMP]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Render Code ==&lt;br /&gt;
&lt;br /&gt;
Pseudo code for rendering the background:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void drawBackground(bool xflip)&lt;br /&gt;
{&lt;br /&gt;
   for (int y=0; y&amp;lt;15; y++)&lt;br /&gt;
   {&lt;br /&gt;
      for (int x=0; x&amp;lt;22; x++)&lt;br /&gt;
      {&lt;br /&gt;
         int tile;&lt;br /&gt;
 &lt;br /&gt;
         if (xflip)&lt;br /&gt;
            tile=vmp.backgroundTiles[21-x][y];&lt;br /&gt;
         else&lt;br /&gt;
            tile=vmp.backgroundTiles[x][y];&lt;br /&gt;
 &lt;br /&gt;
         /* xor with xflip to make block flip and background flip cancel each other out. */&lt;br /&gt;
         int blockFlip = (tile&amp;amp;0x4000)^flipX;&lt;br /&gt;
         int blockIndex= tile&amp;amp;0x3fff;&lt;br /&gt;
 &lt;br /&gt;
         if (blockFlip)&lt;br /&gt;
            drawBlockXFlip(x*8, y*8, vcn.blocks[blockIndex]);&lt;br /&gt;
         else&lt;br /&gt;
            drawBlock(x*8, y*8, vcn.blocks[blockIndex]);&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To render the walls, we can use this structure:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
struct WallRenderData&lt;br /&gt;
{&lt;br /&gt;
   int baseOffset;&lt;br /&gt;
   int offsetInViewPort;&lt;br /&gt;
   int visibleWidthInBlocks;&lt;br /&gt;
   int visibleHeightInBlocks;&lt;br /&gt;
   int skipValue;&lt;br /&gt;
   int flipFlag;&lt;br /&gt;
} wallRenderData[25] /* 25 different wall positions */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;baseOffset&amp;lt;/code&amp;gt;&lt;br /&gt;
: Base offset into tileIndices[wallType-1]. This is an offset into the 431 index block for each wall type.&lt;br /&gt;
; &amp;lt;code&amp;gt;offsetInViewPort&amp;lt;/code&amp;gt;&lt;br /&gt;
: Where to start rendering in the viewport:&lt;br /&gt;
: &amp;lt;code&amp;gt;xpos = offsetInViewPort % 22;&amp;lt;/code&amp;gt;&lt;br /&gt;
: &amp;lt;code&amp;gt;ypos = offsetInViewPort / 22;&amp;lt;/code&amp;gt;&lt;br /&gt;
; &amp;lt;code&amp;gt;visibleWidthInBlocks&amp;lt;/code&amp;gt;&lt;br /&gt;
: how many tiles to render in x direction.&lt;br /&gt;
; &amp;lt;code&amp;gt;visibleHeightInBlocks&amp;lt;/code&amp;gt;&lt;br /&gt;
: how many tiles to render in y direction.&lt;br /&gt;
; &amp;lt;code&amp;gt;skipValue&amp;lt;/code&amp;gt;&lt;br /&gt;
: Number of tiles to the next row in the tileIndices[wallType-1] array.&lt;br /&gt;
; &amp;lt;code&amp;gt;flipFlag&amp;lt;/code&amp;gt;&lt;br /&gt;
: &amp;lt;code&amp;gt;True&amp;lt;/code&amp;gt; if the wall is to be x-flipped in the viewport. Generally all right-walls are x-flipped.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
   /* Side-Walls left back */&lt;br /&gt;
   {   3, 66,  5,  1,  2, 0},             /* A-east */&lt;br /&gt;
   {   1, 68,  5,  3,  0, 0},             /* B-east */&lt;br /&gt;
   {  -4, 74,  5,  1,  0, 0},             /* C-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side-Walls right back */&lt;br /&gt;
   {  -4, 79,  5,  1,  0, 1},              /* E-west */&lt;br /&gt;
   {   1, 83,  5,  3,  0, 1},              /* F-west */&lt;br /&gt;
   {   3, 87,  5,  1,  2, 1},              /* G-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls back */&lt;br /&gt;
   {  32, 66,  5,  2,  4, 0},              /* B-south */&lt;br /&gt;
   {  28, 68,  5,  6,  0, 0},              /* C-south */&lt;br /&gt;
   {  28, 74,  5,  6,  0, 0},              /* D-south */&lt;br /&gt;
   {  28, 80,  5,  6,  0, 0},              /* E-south */&lt;br /&gt;
   {  28, 86,  5,  2,  4, 0},              /* F-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle back left */&lt;br /&gt;
   {  16, 66,  6,  2,  0, 0},              /* H-east */&lt;br /&gt;
   { -20, 50,  8,  2,  0, 0},              /* I-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle back right */&lt;br /&gt;
   { -20, 58,  8,  2,  0, 1},              /* K-west */&lt;br /&gt;
   {  16, 86,  6,  2,  0, 1},              /* L-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls middle back */&lt;br /&gt;
   {  62, 44,  8,  6,  4, 0},              /* I-south */&lt;br /&gt;
   {  58, 50,  8, 10,  0, 0},              /* J-south */&lt;br /&gt;
   {  58, 60,  8,  6,  4, 0},              /* K-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle front left */&lt;br /&gt;
   { -56, 25, 12,  3,  0, 0},              /* M-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle front right */&lt;br /&gt;
   { -56, 38, 12,  3,  0, 1},              /* O-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls middle front */&lt;br /&gt;
   { 151, 22, 12,  3, 13, 0},              /* M-south */&lt;br /&gt;
   { 138, 41, 12,  3, 13, 0},              /* O-south */&lt;br /&gt;
   { 138, 25, 12, 16,  0, 0},              /* N-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side wall front left */&lt;br /&gt;
   {-101,  0, 15,  3,  0, 0},              /* P-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side wall front right */&lt;br /&gt;
   {-101, 19, 15,  3,  0, 1},              /* Q-west */&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Fergusdog</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12618</id>
		<title>Eye of the Beholder VMP Format</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12618"/>
		<updated>2025-10-31T03:52:19Z</updated>

		<summary type="html">&lt;p&gt;Fergusdog: /* Tile Index */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NeedMoreInfo}}&lt;br /&gt;
{{Map Infobox&lt;br /&gt;
 | Type = 2D tile-based&lt;br /&gt;
 | Layers = 5&lt;br /&gt;
 | Tile size = 8&amp;amp;times;8&lt;br /&gt;
 | Viewport = 176&amp;amp;times;120&lt;br /&gt;
 | Games = &lt;br /&gt;
   {{Game|Eye of the Beholder}}&lt;br /&gt;
   {{Game|Eye of the Beholder II: The Legend of Darkmoon}}&lt;br /&gt;
   {{Game|Lands of Lore: The Throne of Chaos}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file assembles the tiles from the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset.&lt;br /&gt;
It functions similarly to a map file in other video games, except that in [[Eye of the Beholder]] it does not represent a top-down layout. Instead, it defines the 3D view of the dungeon, often referred to as the &#039;&#039;view cone&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
In essence, the &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file contains a collection of indices that reference tile graphics within the &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. These indices are interpreted by the game’s main executable to construct the player&#039;s first-person view of the world.&lt;br /&gt;
&lt;br /&gt;
== File Format (PC version) ==&lt;br /&gt;
&lt;br /&gt;
In [[Lands of Lore: The Throne of Chaos]], &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; files are compressed , using the [[Westwood LCW]] compression (see [[Westwood CPS Format]]).&lt;br /&gt;
The uncompressed format is defined as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short index_count; &lt;br /&gt;
    unsigned short indices[index_count]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each entry in &amp;lt;code&amp;gt;indices&amp;lt;/code&amp;gt; represents an index that references a specific block in the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. For more details on the index entries, see the [[#Tile Index|Tile Index]] section below.&lt;br /&gt;
&lt;br /&gt;
== File Format (Amiga version) ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short header; &lt;br /&gt;
    unsigned short backdrop_tiles[22][15]; &lt;br /&gt;
    unsigned short padding[101]; &lt;br /&gt;
    unsigned short wall_tiles[wall_types_count][431]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;header&amp;lt;/code&amp;gt;&lt;br /&gt;
: {{TODO|Not yet fully investigated, but most likely specifies the number of wall types defined in the file.}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;backdrop_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the static backdrop (ceiling/floor) image..&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;padding&amp;lt;/code&amp;gt;&lt;br /&gt;
: Each wall type uses 431 tile indices. To match this count for the backdrop tiles, a padding of 101 empty indices is added (&amp;lt;code&amp;gt;22 × 15 + 101 = 431&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the wall graphics for each wall type.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_types_count&amp;lt;/code&amp;gt;&lt;br /&gt;
: Probably stored in the header, but can also be calculated as: &amp;lt;code&amp;gt;(filesize - 2) / (431 * 2) - 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tile Index ==&lt;br /&gt;
&lt;br /&gt;
Each index is represented as a 16-bit value using the following bit structure (most significant bits first):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct TileIndex { &lt;br /&gt;
    bool z-mask: 1; &lt;br /&gt;
    bool mirror_x: 1; &lt;br /&gt;
    unsigned tile_index: 14; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;z-mask&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;, only draw onto the tranparent pixels of the tile(s) below. In effect, acts as a mask for z-order, so the drawn tile appears behind the tile being drawn over. {{TODO|Need to confirm, expand?}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;mirror_x&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; flip the tile horizontally.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;tile_index&amp;lt;/code&amp;gt;&lt;br /&gt;
: A 14-bit index selecting a specific tile from the corresponding &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset (see [[Eye of the Beholder VCN Format]]).&lt;br /&gt;
&lt;br /&gt;
== Rendering the View Cone ==&lt;br /&gt;
&lt;br /&gt;
The 3D view in [[Eye of the Beholder]] covers an area of &#039;&#039;&#039;22 × 15 tiles&#039;&#039;&#039; and is composed of five layers — the backdrop (ceiling and floor) and four wall layers. The backdrop is rendered first and provides the ceiling and floor as a single combined image. The wall layers are then drawn on top, alternating between front-facing and side-facing walls to construct the 3D perspective.&lt;br /&gt;
&lt;br /&gt;
The following diagram illustrates the layout of the view cone:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
Layer 5 (backdrop)  &lt;br /&gt;
                                  ─────────────────────────────────&lt;br /&gt;
Layer 4                               A | B | C | D | E | F | G &lt;br /&gt;
                                         ─── ─── ─── ─── ─── &lt;br /&gt;
Layer 3                                   H | I | J | K | L &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 2                                       M | N | O &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 1 (closest)                             P | ^ | Q  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The caret (&amp;lt;code&amp;gt;^&amp;lt;/code&amp;gt;) represents the party’s position. Vertical bars (&amp;lt;code&amp;gt;|&amp;lt;/code&amp;gt;) and overbars (&amp;lt;code&amp;gt;───&amp;lt;/code&amp;gt;) in the diagram denote walls at various distances.&lt;br /&gt;
&lt;br /&gt;
In total, there are 25 distinct wall positions within the player’s field of vision. To render all walls correctly, the engine must read 17 map cells (A–Q) from the dungeon layout.&lt;br /&gt;
&lt;br /&gt;
The first 22 x 15 = &#039;&#039;&#039;330&#039;&#039;&#039; tile indices are used for the backdrop. The background is horizontally flipped when &amp;lt;code&amp;gt;party.x &amp;amp; party.y &amp;amp; party.direction == 1&amp;lt;/code&amp;gt;. In other words, certain movements or rotations from the current position cause the background to appear mirrored.&lt;br /&gt;
&lt;br /&gt;
What follows are &#039;&#039;&#039;431&#039;&#039;&#039; tile indices per wall type. [[Eye of the Beholder]] has 6 different wall types: solid wall type 1, solid wall type 2, door frame, stairs up, stairs down and portal. The wall types are defined in the [[Eye of the Beholder Maze Format]] files. Each block in the MAZ file has wall information for all 4 walls (north, east, south, west) from which the wall type is inferred - for each wall in the level.&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;margin:auto;&amp;quot;&lt;br /&gt;
| [[File:BRICK bg.png|frame|Backdrop from BRICK.VMP]]&lt;br /&gt;
| [[File:BRICK wall 1.png|frame|Wall Type 1 from BRICK.VMP]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Render Code ==&lt;br /&gt;
&lt;br /&gt;
Pseudo code for rendering the background:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void drawBackground(bool xflip)&lt;br /&gt;
{&lt;br /&gt;
   for (int y=0; y&amp;lt;15; y++)&lt;br /&gt;
   {&lt;br /&gt;
      for (int x=0; x&amp;lt;22; x++)&lt;br /&gt;
      {&lt;br /&gt;
         int tile;&lt;br /&gt;
 &lt;br /&gt;
         if (xflip)&lt;br /&gt;
            tile=vmp.backgroundTiles[21-x][y];&lt;br /&gt;
         else&lt;br /&gt;
            tile=vmp.backgroundTiles[x][y];&lt;br /&gt;
 &lt;br /&gt;
         /* xor with xflip to make block flip and background flip cancel each other out. */&lt;br /&gt;
         int blockFlip = (tile&amp;amp;0x4000)^flipX;&lt;br /&gt;
         int blockIndex= tile&amp;amp;0x3fff;&lt;br /&gt;
 &lt;br /&gt;
         if (blockFlip)&lt;br /&gt;
            drawBlockXFlip(x*8, y*8, vcn.blocks[blockIndex]);&lt;br /&gt;
         else&lt;br /&gt;
            drawBlock(x*8, y*8, vcn.blocks[blockIndex]);&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To render the walls, we can use this structure:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
struct WallRenderData&lt;br /&gt;
{&lt;br /&gt;
   int baseOffset;&lt;br /&gt;
   int offsetInViewPort;&lt;br /&gt;
   int visibleWidthInBlocks;&lt;br /&gt;
   int visibleHeightInBlocks;&lt;br /&gt;
   int skipValue;&lt;br /&gt;
   int flipFlag;&lt;br /&gt;
} wallRenderData[25] /* 25 different wall positions */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;baseOffset&amp;lt;/code&amp;gt;&lt;br /&gt;
: Base offset into tileIndices[wallType-1]. This is an offset into the 431 index block for each wall type.&lt;br /&gt;
; &amp;lt;code&amp;gt;offsetInViewPort&amp;lt;/code&amp;gt;&lt;br /&gt;
: Where to start rendering in the viewport:&lt;br /&gt;
: &amp;lt;code&amp;gt;xpos = offsetInViewPort % 22;&amp;lt;/code&amp;gt;&lt;br /&gt;
: &amp;lt;code&amp;gt;ypos = offsetInViewPort / 22;&amp;lt;/code&amp;gt;&lt;br /&gt;
; &amp;lt;code&amp;gt;visibleWidthInBlocks&amp;lt;/code&amp;gt;&lt;br /&gt;
: how many tiles to render in x direction.&lt;br /&gt;
; &amp;lt;code&amp;gt;visibleHeightInBlocks&amp;lt;/code&amp;gt;&lt;br /&gt;
: how many tiles to render in y direction.&lt;br /&gt;
; &amp;lt;code&amp;gt;skipValue&amp;lt;/code&amp;gt;&lt;br /&gt;
: Number of tiles to the next row in the tileIndices[wallType-1] array.&lt;br /&gt;
; &amp;lt;code&amp;gt;flipFlag&amp;lt;/code&amp;gt;&lt;br /&gt;
: &amp;lt;code&amp;gt;True&amp;lt;/code&amp;gt; if the wall is to be x-flipped in the viewport. Generally all right-walls are x-flipped.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
   /* Side-Walls left back */&lt;br /&gt;
   {   3, 66, 5, 1, 2, 0},             /* A-east */&lt;br /&gt;
   {   1, 68, 5, 3, 0, 0},             /* B-east */&lt;br /&gt;
   {  -4, 74, 5, 1, 0, 0},             /* C-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side-Walls right back */&lt;br /&gt;
   {  -4, 79, 5, 1, 0, 1},              /* E-west */&lt;br /&gt;
   {   1, 83, 5, 3, 0, 1},              /* F-west */&lt;br /&gt;
   {   3, 87, 5, 1, 2, 1},              /* G-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls back */&lt;br /&gt;
   {  32, 66, 5, 2, 4, 0},              /* B-south */&lt;br /&gt;
   {  28, 68, 5, 6, 0, 0},              /* C-south */&lt;br /&gt;
   {  28, 74, 5, 6, 0, 0},              /* D-south */&lt;br /&gt;
   {  28, 80, 5, 6, 0, 0},              /* E-south */&lt;br /&gt;
   {  28, 86, 5, 2, 4, 0},              /* F-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle back left */&lt;br /&gt;
   {  16, 66, 6, 2, 0, 0},              /* H-east */&lt;br /&gt;
   { -20, 50, 8, 2, 0, 0},              /* I-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle back right */&lt;br /&gt;
   { -20, 58, 8, 2, 0, 1},              /* K-west */&lt;br /&gt;
   {  16, 86, 6, 2, 0, 1},              /* L-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls middle back */&lt;br /&gt;
   {  62, 44, 8, 6, 4, 0},              /* I-south */&lt;br /&gt;
   {  58, 50, 8,10, 0, 0},              /* J-south */&lt;br /&gt;
   {  58, 60, 8, 6, 4, 0},              /* K-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle front left */&lt;br /&gt;
   { -56, 25,12, 3, 0, 0},              /* M-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle front right */&lt;br /&gt;
   { -56, 38,12, 3, 0, 1},              /* O-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls middle front */&lt;br /&gt;
   { 151, 22,12, 3,13, 0},              /* M-south */&lt;br /&gt;
   { 138, 41,12, 3,13, 0},              /* O-south */&lt;br /&gt;
   { 138, 25,12,16, 0, 0},              /* N-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side wall front left */&lt;br /&gt;
   {-101,  0,15, 3, 0, 0},              /* P-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side wall front right */&lt;br /&gt;
   {-101, 19,15, 3, 0, 1},              /* Q-west */&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Fergusdog</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12617</id>
		<title>Eye of the Beholder VMP Format</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12617"/>
		<updated>2025-10-31T03:51:45Z</updated>

		<summary type="html">&lt;p&gt;Fergusdog: /* Render Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NeedMoreInfo}}&lt;br /&gt;
{{Map Infobox&lt;br /&gt;
 | Type = 2D tile-based&lt;br /&gt;
 | Layers = 5&lt;br /&gt;
 | Tile size = 8&amp;amp;times;8&lt;br /&gt;
 | Viewport = 176&amp;amp;times;120&lt;br /&gt;
 | Games = &lt;br /&gt;
   {{Game|Eye of the Beholder}}&lt;br /&gt;
   {{Game|Eye of the Beholder II: The Legend of Darkmoon}}&lt;br /&gt;
   {{Game|Lands of Lore: The Throne of Chaos}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file assembles the tiles from the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset.&lt;br /&gt;
It functions similarly to a map file in other video games, except that in [[Eye of the Beholder]] it does not represent a top-down layout. Instead, it defines the 3D view of the dungeon, often referred to as the &#039;&#039;view cone&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
In essence, the &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file contains a collection of indices that reference tile graphics within the &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. These indices are interpreted by the game’s main executable to construct the player&#039;s first-person view of the world.&lt;br /&gt;
&lt;br /&gt;
== File Format (PC version) ==&lt;br /&gt;
&lt;br /&gt;
In [[Lands of Lore: The Throne of Chaos]], &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; files are compressed , using the [[Westwood LCW]] compression (see [[Westwood CPS Format]]).&lt;br /&gt;
The uncompressed format is defined as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short index_count; &lt;br /&gt;
    unsigned short indices[index_count]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each entry in &amp;lt;code&amp;gt;indices&amp;lt;/code&amp;gt; represents an index that references a specific block in the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. For more details on the index entries, see the [[#Tile Index|Tile Index]] section below.&lt;br /&gt;
&lt;br /&gt;
== File Format (Amiga version) ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short header; &lt;br /&gt;
    unsigned short backdrop_tiles[22][15]; &lt;br /&gt;
    unsigned short padding[101]; &lt;br /&gt;
    unsigned short wall_tiles[wall_types_count][431]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;header&amp;lt;/code&amp;gt;&lt;br /&gt;
: {{TODO|Not yet fully investigated, but most likely specifies the number of wall types defined in the file.}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;backdrop_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the static backdrop (ceiling/floor) image..&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;padding&amp;lt;/code&amp;gt;&lt;br /&gt;
: Each wall type uses 431 tile indices. To match this count for the backdrop tiles, a padding of 101 empty indices is added (&amp;lt;code&amp;gt;22 × 15 + 101 = 431&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the wall graphics for each wall type.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_types_count&amp;lt;/code&amp;gt;&lt;br /&gt;
: Probably stored in the header, but can also be calculated as: &amp;lt;code&amp;gt;(filesize - 2) / (431 * 2) - 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tile Index ==&lt;br /&gt;
&lt;br /&gt;
Each index is represented as a 16-bit value using the following bit structure (most significant bits first):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct TileIndex { &lt;br /&gt;
    bool z-mask: 1; &lt;br /&gt;
    bool mirror_x: 1; &lt;br /&gt;
    unsigned tile_index: 14; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;z-mask&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;, only draw onto the tranparent pixels of the tile(s) below. In effect, acts as a mask for z-order, so the drawn tile appears behind the tile being drawn over. {{TODO|Need to confirm, expand?}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;mirror_x&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; flip the tile horizontally. Used to draw the right walls, for example.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;tile_index&amp;lt;/code&amp;gt;&lt;br /&gt;
: A 14-bit index selecting a specific tile from the corresponding &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset (see [[Eye of the Beholder VCN Format]]).&lt;br /&gt;
&lt;br /&gt;
== Rendering the View Cone ==&lt;br /&gt;
&lt;br /&gt;
The 3D view in [[Eye of the Beholder]] covers an area of &#039;&#039;&#039;22 × 15 tiles&#039;&#039;&#039; and is composed of five layers — the backdrop (ceiling and floor) and four wall layers. The backdrop is rendered first and provides the ceiling and floor as a single combined image. The wall layers are then drawn on top, alternating between front-facing and side-facing walls to construct the 3D perspective.&lt;br /&gt;
&lt;br /&gt;
The following diagram illustrates the layout of the view cone:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
Layer 5 (backdrop)  &lt;br /&gt;
                                  ─────────────────────────────────&lt;br /&gt;
Layer 4                               A | B | C | D | E | F | G &lt;br /&gt;
                                         ─── ─── ─── ─── ─── &lt;br /&gt;
Layer 3                                   H | I | J | K | L &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 2                                       M | N | O &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 1 (closest)                             P | ^ | Q  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The caret (&amp;lt;code&amp;gt;^&amp;lt;/code&amp;gt;) represents the party’s position. Vertical bars (&amp;lt;code&amp;gt;|&amp;lt;/code&amp;gt;) and overbars (&amp;lt;code&amp;gt;───&amp;lt;/code&amp;gt;) in the diagram denote walls at various distances.&lt;br /&gt;
&lt;br /&gt;
In total, there are 25 distinct wall positions within the player’s field of vision. To render all walls correctly, the engine must read 17 map cells (A–Q) from the dungeon layout.&lt;br /&gt;
&lt;br /&gt;
The first 22 x 15 = &#039;&#039;&#039;330&#039;&#039;&#039; tile indices are used for the backdrop. The background is horizontally flipped when &amp;lt;code&amp;gt;party.x &amp;amp; party.y &amp;amp; party.direction == 1&amp;lt;/code&amp;gt;. In other words, certain movements or rotations from the current position cause the background to appear mirrored.&lt;br /&gt;
&lt;br /&gt;
What follows are &#039;&#039;&#039;431&#039;&#039;&#039; tile indices per wall type. [[Eye of the Beholder]] has 6 different wall types: solid wall type 1, solid wall type 2, door frame, stairs up, stairs down and portal. The wall types are defined in the [[Eye of the Beholder Maze Format]] files. Each block in the MAZ file has wall information for all 4 walls (north, east, south, west) from which the wall type is inferred - for each wall in the level.&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;margin:auto;&amp;quot;&lt;br /&gt;
| [[File:BRICK bg.png|frame|Backdrop from BRICK.VMP]]&lt;br /&gt;
| [[File:BRICK wall 1.png|frame|Wall Type 1 from BRICK.VMP]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Render Code ==&lt;br /&gt;
&lt;br /&gt;
Pseudo code for rendering the background:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void drawBackground(bool xflip)&lt;br /&gt;
{&lt;br /&gt;
   for (int y=0; y&amp;lt;15; y++)&lt;br /&gt;
   {&lt;br /&gt;
      for (int x=0; x&amp;lt;22; x++)&lt;br /&gt;
      {&lt;br /&gt;
         int tile;&lt;br /&gt;
 &lt;br /&gt;
         if (xflip)&lt;br /&gt;
            tile=vmp.backgroundTiles[21-x][y];&lt;br /&gt;
         else&lt;br /&gt;
            tile=vmp.backgroundTiles[x][y];&lt;br /&gt;
 &lt;br /&gt;
         /* xor with xflip to make block flip and background flip cancel each other out. */&lt;br /&gt;
         int blockFlip = (tile&amp;amp;0x4000)^flipX;&lt;br /&gt;
         int blockIndex= tile&amp;amp;0x3fff;&lt;br /&gt;
 &lt;br /&gt;
         if (blockFlip)&lt;br /&gt;
            drawBlockXFlip(x*8, y*8, vcn.blocks[blockIndex]);&lt;br /&gt;
         else&lt;br /&gt;
            drawBlock(x*8, y*8, vcn.blocks[blockIndex]);&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To render the walls, we can use this structure:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
struct WallRenderData&lt;br /&gt;
{&lt;br /&gt;
   int baseOffset;&lt;br /&gt;
   int offsetInViewPort;&lt;br /&gt;
   int visibleWidthInBlocks;&lt;br /&gt;
   int visibleHeightInBlocks;&lt;br /&gt;
   int skipValue;&lt;br /&gt;
   int flipFlag;&lt;br /&gt;
} wallRenderData[25] /* 25 different wall positions */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;baseOffset&amp;lt;/code&amp;gt;&lt;br /&gt;
: Base offset into tileIndices[wallType-1]. This is an offset into the 431 index block for each wall type.&lt;br /&gt;
; &amp;lt;code&amp;gt;offsetInViewPort&amp;lt;/code&amp;gt;&lt;br /&gt;
: Where to start rendering in the viewport:&lt;br /&gt;
: &amp;lt;code&amp;gt;xpos = offsetInViewPort % 22;&amp;lt;/code&amp;gt;&lt;br /&gt;
: &amp;lt;code&amp;gt;ypos = offsetInViewPort / 22;&amp;lt;/code&amp;gt;&lt;br /&gt;
; &amp;lt;code&amp;gt;visibleWidthInBlocks&amp;lt;/code&amp;gt;&lt;br /&gt;
: how many tiles to render in x direction.&lt;br /&gt;
; &amp;lt;code&amp;gt;visibleHeightInBlocks&amp;lt;/code&amp;gt;&lt;br /&gt;
: how many tiles to render in y direction.&lt;br /&gt;
; &amp;lt;code&amp;gt;skipValue&amp;lt;/code&amp;gt;&lt;br /&gt;
: Number of tiles to the next row in the tileIndices[wallType-1] array.&lt;br /&gt;
; &amp;lt;code&amp;gt;flipFlag&amp;lt;/code&amp;gt;&lt;br /&gt;
: &amp;lt;code&amp;gt;True&amp;lt;/code&amp;gt; if the wall is to be x-flipped in the viewport. Generally all right-walls are x-flipped.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
   /* Side-Walls left back */&lt;br /&gt;
   {   3, 66, 5, 1, 2, 0},             /* A-east */&lt;br /&gt;
   {   1, 68, 5, 3, 0, 0},             /* B-east */&lt;br /&gt;
   {  -4, 74, 5, 1, 0, 0},             /* C-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side-Walls right back */&lt;br /&gt;
   {  -4, 79, 5, 1, 0, 1},              /* E-west */&lt;br /&gt;
   {   1, 83, 5, 3, 0, 1},              /* F-west */&lt;br /&gt;
   {   3, 87, 5, 1, 2, 1},              /* G-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls back */&lt;br /&gt;
   {  32, 66, 5, 2, 4, 0},              /* B-south */&lt;br /&gt;
   {  28, 68, 5, 6, 0, 0},              /* C-south */&lt;br /&gt;
   {  28, 74, 5, 6, 0, 0},              /* D-south */&lt;br /&gt;
   {  28, 80, 5, 6, 0, 0},              /* E-south */&lt;br /&gt;
   {  28, 86, 5, 2, 4, 0},              /* F-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle back left */&lt;br /&gt;
   {  16, 66, 6, 2, 0, 0},              /* H-east */&lt;br /&gt;
   { -20, 50, 8, 2, 0, 0},              /* I-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle back right */&lt;br /&gt;
   { -20, 58, 8, 2, 0, 1},              /* K-west */&lt;br /&gt;
   {  16, 86, 6, 2, 0, 1},              /* L-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls middle back */&lt;br /&gt;
   {  62, 44, 8, 6, 4, 0},              /* I-south */&lt;br /&gt;
   {  58, 50, 8,10, 0, 0},              /* J-south */&lt;br /&gt;
   {  58, 60, 8, 6, 4, 0},              /* K-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle front left */&lt;br /&gt;
   { -56, 25,12, 3, 0, 0},              /* M-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle front right */&lt;br /&gt;
   { -56, 38,12, 3, 0, 1},              /* O-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls middle front */&lt;br /&gt;
   { 151, 22,12, 3,13, 0},              /* M-south */&lt;br /&gt;
   { 138, 41,12, 3,13, 0},              /* O-south */&lt;br /&gt;
   { 138, 25,12,16, 0, 0},              /* N-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side wall front left */&lt;br /&gt;
   {-101,  0,15, 3, 0, 0},              /* P-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side wall front right */&lt;br /&gt;
   {-101, 19,15, 3, 0, 1},              /* Q-west */&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Fergusdog</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12616</id>
		<title>Eye of the Beholder VMP Format</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12616"/>
		<updated>2025-10-31T03:48:51Z</updated>

		<summary type="html">&lt;p&gt;Fergusdog: /* Render Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NeedMoreInfo}}&lt;br /&gt;
{{Map Infobox&lt;br /&gt;
 | Type = 2D tile-based&lt;br /&gt;
 | Layers = 5&lt;br /&gt;
 | Tile size = 8&amp;amp;times;8&lt;br /&gt;
 | Viewport = 176&amp;amp;times;120&lt;br /&gt;
 | Games = &lt;br /&gt;
   {{Game|Eye of the Beholder}}&lt;br /&gt;
   {{Game|Eye of the Beholder II: The Legend of Darkmoon}}&lt;br /&gt;
   {{Game|Lands of Lore: The Throne of Chaos}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file assembles the tiles from the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset.&lt;br /&gt;
It functions similarly to a map file in other video games, except that in [[Eye of the Beholder]] it does not represent a top-down layout. Instead, it defines the 3D view of the dungeon, often referred to as the &#039;&#039;view cone&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
In essence, the &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file contains a collection of indices that reference tile graphics within the &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. These indices are interpreted by the game’s main executable to construct the player&#039;s first-person view of the world.&lt;br /&gt;
&lt;br /&gt;
== File Format (PC version) ==&lt;br /&gt;
&lt;br /&gt;
In [[Lands of Lore: The Throne of Chaos]], &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; files are compressed , using the [[Westwood LCW]] compression (see [[Westwood CPS Format]]).&lt;br /&gt;
The uncompressed format is defined as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short index_count; &lt;br /&gt;
    unsigned short indices[index_count]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each entry in &amp;lt;code&amp;gt;indices&amp;lt;/code&amp;gt; represents an index that references a specific block in the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. For more details on the index entries, see the [[#Tile Index|Tile Index]] section below.&lt;br /&gt;
&lt;br /&gt;
== File Format (Amiga version) ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short header; &lt;br /&gt;
    unsigned short backdrop_tiles[22][15]; &lt;br /&gt;
    unsigned short padding[101]; &lt;br /&gt;
    unsigned short wall_tiles[wall_types_count][431]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;header&amp;lt;/code&amp;gt;&lt;br /&gt;
: {{TODO|Not yet fully investigated, but most likely specifies the number of wall types defined in the file.}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;backdrop_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the static backdrop (ceiling/floor) image..&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;padding&amp;lt;/code&amp;gt;&lt;br /&gt;
: Each wall type uses 431 tile indices. To match this count for the backdrop tiles, a padding of 101 empty indices is added (&amp;lt;code&amp;gt;22 × 15 + 101 = 431&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the wall graphics for each wall type.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_types_count&amp;lt;/code&amp;gt;&lt;br /&gt;
: Probably stored in the header, but can also be calculated as: &amp;lt;code&amp;gt;(filesize - 2) / (431 * 2) - 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tile Index ==&lt;br /&gt;
&lt;br /&gt;
Each index is represented as a 16-bit value using the following bit structure (most significant bits first):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct TileIndex { &lt;br /&gt;
    bool z-mask: 1; &lt;br /&gt;
    bool mirror_x: 1; &lt;br /&gt;
    unsigned tile_index: 14; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;z-mask&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;, only draw onto the tranparent pixels of the tile(s) below. In effect, acts as a mask for z-order, so the drawn tile appears behind the tile being drawn over. {{TODO|Need to confirm, expand?}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;mirror_x&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; flip the tile horizontally. Used to draw the right walls, for example.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;tile_index&amp;lt;/code&amp;gt;&lt;br /&gt;
: A 14-bit index selecting a specific tile from the corresponding &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset (see [[Eye of the Beholder VCN Format]]).&lt;br /&gt;
&lt;br /&gt;
== Rendering the View Cone ==&lt;br /&gt;
&lt;br /&gt;
The 3D view in [[Eye of the Beholder]] covers an area of &#039;&#039;&#039;22 × 15 tiles&#039;&#039;&#039; and is composed of five layers — the backdrop (ceiling and floor) and four wall layers. The backdrop is rendered first and provides the ceiling and floor as a single combined image. The wall layers are then drawn on top, alternating between front-facing and side-facing walls to construct the 3D perspective.&lt;br /&gt;
&lt;br /&gt;
The following diagram illustrates the layout of the view cone:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
Layer 5 (backdrop)  &lt;br /&gt;
                                  ─────────────────────────────────&lt;br /&gt;
Layer 4                               A | B | C | D | E | F | G &lt;br /&gt;
                                         ─── ─── ─── ─── ─── &lt;br /&gt;
Layer 3                                   H | I | J | K | L &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 2                                       M | N | O &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 1 (closest)                             P | ^ | Q  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The caret (&amp;lt;code&amp;gt;^&amp;lt;/code&amp;gt;) represents the party’s position. Vertical bars (&amp;lt;code&amp;gt;|&amp;lt;/code&amp;gt;) and overbars (&amp;lt;code&amp;gt;───&amp;lt;/code&amp;gt;) in the diagram denote walls at various distances.&lt;br /&gt;
&lt;br /&gt;
In total, there are 25 distinct wall positions within the player’s field of vision. To render all walls correctly, the engine must read 17 map cells (A–Q) from the dungeon layout.&lt;br /&gt;
&lt;br /&gt;
The first 22 x 15 = &#039;&#039;&#039;330&#039;&#039;&#039; tile indices are used for the backdrop. The background is horizontally flipped when &amp;lt;code&amp;gt;party.x &amp;amp; party.y &amp;amp; party.direction == 1&amp;lt;/code&amp;gt;. In other words, certain movements or rotations from the current position cause the background to appear mirrored.&lt;br /&gt;
&lt;br /&gt;
What follows are &#039;&#039;&#039;431&#039;&#039;&#039; tile indices per wall type. [[Eye of the Beholder]] has 6 different wall types: solid wall type 1, solid wall type 2, door frame, stairs up, stairs down and portal. The wall types are defined in the [[Eye of the Beholder Maze Format]] files. Each block in the MAZ file has wall information for all 4 walls (north, east, south, west) from which the wall type is inferred - for each wall in the level.&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;margin:auto;&amp;quot;&lt;br /&gt;
| [[File:BRICK bg.png|frame|Backdrop from BRICK.VMP]]&lt;br /&gt;
| [[File:BRICK wall 1.png|frame|Wall Type 1 from BRICK.VMP]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Render Code ==&lt;br /&gt;
&lt;br /&gt;
Pseudo code for rendering the background:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void drawBackground(bool xflip)&lt;br /&gt;
{&lt;br /&gt;
   for (int y=0; y&amp;lt;15; y++)&lt;br /&gt;
   {&lt;br /&gt;
      for (int x=0; x&amp;lt;22; x++)&lt;br /&gt;
      {&lt;br /&gt;
         int tile;&lt;br /&gt;
 &lt;br /&gt;
         if (xflip)&lt;br /&gt;
            tile=vmp.backgroundTiles[21-x][y];&lt;br /&gt;
         else&lt;br /&gt;
            tile=vmp.backgroundTiles[x][y];&lt;br /&gt;
 &lt;br /&gt;
         /* xor with xflip to make block flip and background flip cancel each other out. */&lt;br /&gt;
         int blockFlip = (tile&amp;amp;0x4000)^flipX;&lt;br /&gt;
         int blockIndex= tile&amp;amp;0x3fff;&lt;br /&gt;
 &lt;br /&gt;
         if (blockFlip)&lt;br /&gt;
            drawBlockXFlip(x*8, y*8, vcn.blocks[blockIndex]);&lt;br /&gt;
         else&lt;br /&gt;
            drawBlock(x*8, y*8, vcn.blocks[blockIndex]);&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To render the walls, we can use this structure:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
struct WallRenderData&lt;br /&gt;
{&lt;br /&gt;
   int baseOffset;&lt;br /&gt;
   int offsetInViewPort;&lt;br /&gt;
   int visibleWidthInBlocks;&lt;br /&gt;
   int visibleHeightInBlocks;&lt;br /&gt;
   int skipValue;&lt;br /&gt;
   int flipFlag;&lt;br /&gt;
} wallRenderData[25]= /* 25 different wall positions */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;baseOffset&amp;lt;/code&amp;gt;&lt;br /&gt;
: Base offset into tileIndices[wallType-1]. This is an offset into the 431 index block for each wall type.&lt;br /&gt;
; &amp;lt;code&amp;gt;offsetInViewPort&amp;lt;/code&amp;gt;&lt;br /&gt;
: Where to start rendering in the viewport:&lt;br /&gt;
: &amp;lt;code&amp;gt;xpos = offsetInViewPort%22;&amp;lt;/code&amp;gt;&lt;br /&gt;
: &amp;lt;code&amp;gt;ypos = offsetInViewPort/22;&amp;lt;/code&amp;gt;&lt;br /&gt;
; &amp;lt;code&amp;gt;visibleWidthInBlocks&amp;lt;/code&amp;gt;&lt;br /&gt;
: how many tiles to render in x direction.&lt;br /&gt;
visibleHeightInBlocks&lt;br /&gt;
How many visible blocks hight the wall is in the viewport.&lt;br /&gt;
skipValue&lt;br /&gt;
Number of tiles to the next row in the wallTiles[wallType-1] array.&lt;br /&gt;
flipFlag&lt;br /&gt;
1 if the wall is to be x-flipped in the viewport. Generally all right-walls are x-flipped.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
   /* Side-Walls left back */&lt;br /&gt;
   {   3, 66, 5, 1, 2, 0},             /* A-east */&lt;br /&gt;
   {   1, 68, 5, 3, 0, 0},             /* B-east */&lt;br /&gt;
   {  -4, 74, 5, 1, 0, 0},             /* C-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side-Walls right back */&lt;br /&gt;
   {  -4, 79, 5, 1, 0, 1},              /* E-west */&lt;br /&gt;
   {   1, 83, 5, 3, 0, 1},              /* F-west */&lt;br /&gt;
   {   3, 87, 5, 1, 2, 1},              /* G-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls back */&lt;br /&gt;
   {  32, 66, 5, 2, 4, 0},              /* B-south */&lt;br /&gt;
   {  28, 68, 5, 6, 0, 0},              /* C-south */&lt;br /&gt;
   {  28, 74, 5, 6, 0, 0},              /* D-south */&lt;br /&gt;
   {  28, 80, 5, 6, 0, 0},              /* E-south */&lt;br /&gt;
   {  28, 86, 5, 2, 4, 0},              /* F-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle back left */&lt;br /&gt;
   {  16, 66, 6, 2, 0, 0},              /* H-east */&lt;br /&gt;
   { -20, 50, 8, 2, 0, 0},              /* I-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle back right */&lt;br /&gt;
   { -20, 58, 8, 2, 0, 1},              /* K-west */&lt;br /&gt;
   {  16, 86, 6, 2, 0, 1},              /* L-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls middle back */&lt;br /&gt;
   {  62, 44, 8, 6, 4, 0},              /* I-south */&lt;br /&gt;
   {  58, 50, 8,10, 0, 0},              /* J-south */&lt;br /&gt;
   {  58, 60, 8, 6, 4, 0},              /* K-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle front left */&lt;br /&gt;
   { -56, 25,12, 3, 0, 0},              /* M-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle front right */&lt;br /&gt;
   { -56, 38,12, 3, 0, 1},              /* O-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls middle front */&lt;br /&gt;
   { 151, 22,12, 3,13, 0},              /* M-south */&lt;br /&gt;
   { 138, 41,12, 3,13, 0},              /* O-south */&lt;br /&gt;
   { 138, 25,12,16, 0, 0},              /* N-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side wall front left */&lt;br /&gt;
   {-101,  0,15, 3, 0, 0},              /* P-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side wall front right */&lt;br /&gt;
   {-101, 19,15, 3, 0, 1},              /* Q-west */&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Fergusdog</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12615</id>
		<title>Eye of the Beholder VMP Format</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12615"/>
		<updated>2025-10-31T03:45:20Z</updated>

		<summary type="html">&lt;p&gt;Fergusdog: /* Render Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NeedMoreInfo}}&lt;br /&gt;
{{Map Infobox&lt;br /&gt;
 | Type = 2D tile-based&lt;br /&gt;
 | Layers = 5&lt;br /&gt;
 | Tile size = 8&amp;amp;times;8&lt;br /&gt;
 | Viewport = 176&amp;amp;times;120&lt;br /&gt;
 | Games = &lt;br /&gt;
   {{Game|Eye of the Beholder}}&lt;br /&gt;
   {{Game|Eye of the Beholder II: The Legend of Darkmoon}}&lt;br /&gt;
   {{Game|Lands of Lore: The Throne of Chaos}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file assembles the tiles from the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset.&lt;br /&gt;
It functions similarly to a map file in other video games, except that in [[Eye of the Beholder]] it does not represent a top-down layout. Instead, it defines the 3D view of the dungeon, often referred to as the &#039;&#039;view cone&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
In essence, the &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file contains a collection of indices that reference tile graphics within the &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. These indices are interpreted by the game’s main executable to construct the player&#039;s first-person view of the world.&lt;br /&gt;
&lt;br /&gt;
== File Format (PC version) ==&lt;br /&gt;
&lt;br /&gt;
In [[Lands of Lore: The Throne of Chaos]], &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; files are compressed , using the [[Westwood LCW]] compression (see [[Westwood CPS Format]]).&lt;br /&gt;
The uncompressed format is defined as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short index_count; &lt;br /&gt;
    unsigned short indices[index_count]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each entry in &amp;lt;code&amp;gt;indices&amp;lt;/code&amp;gt; represents an index that references a specific block in the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. For more details on the index entries, see the [[#Tile Index|Tile Index]] section below.&lt;br /&gt;
&lt;br /&gt;
== File Format (Amiga version) ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short header; &lt;br /&gt;
    unsigned short backdrop_tiles[22][15]; &lt;br /&gt;
    unsigned short padding[101]; &lt;br /&gt;
    unsigned short wall_tiles[wall_types_count][431]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;header&amp;lt;/code&amp;gt;&lt;br /&gt;
: {{TODO|Not yet fully investigated, but most likely specifies the number of wall types defined in the file.}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;backdrop_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the static backdrop (ceiling/floor) image..&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;padding&amp;lt;/code&amp;gt;&lt;br /&gt;
: Each wall type uses 431 tile indices. To match this count for the backdrop tiles, a padding of 101 empty indices is added (&amp;lt;code&amp;gt;22 × 15 + 101 = 431&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the wall graphics for each wall type.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_types_count&amp;lt;/code&amp;gt;&lt;br /&gt;
: Probably stored in the header, but can also be calculated as: &amp;lt;code&amp;gt;(filesize - 2) / (431 * 2) - 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tile Index ==&lt;br /&gt;
&lt;br /&gt;
Each index is represented as a 16-bit value using the following bit structure (most significant bits first):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct TileIndex { &lt;br /&gt;
    bool z-mask: 1; &lt;br /&gt;
    bool mirror_x: 1; &lt;br /&gt;
    unsigned tile_index: 14; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;z-mask&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;, only draw onto the tranparent pixels of the tile(s) below. In effect, acts as a mask for z-order, so the drawn tile appears behind the tile being drawn over. {{TODO|Need to confirm, expand?}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;mirror_x&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; flip the tile horizontally. Used to draw the right walls, for example.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;tile_index&amp;lt;/code&amp;gt;&lt;br /&gt;
: A 14-bit index selecting a specific tile from the corresponding &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset (see [[Eye of the Beholder VCN Format]]).&lt;br /&gt;
&lt;br /&gt;
== Rendering the View Cone ==&lt;br /&gt;
&lt;br /&gt;
The 3D view in [[Eye of the Beholder]] covers an area of &#039;&#039;&#039;22 × 15 tiles&#039;&#039;&#039; and is composed of five layers — the backdrop (ceiling and floor) and four wall layers. The backdrop is rendered first and provides the ceiling and floor as a single combined image. The wall layers are then drawn on top, alternating between front-facing and side-facing walls to construct the 3D perspective.&lt;br /&gt;
&lt;br /&gt;
The following diagram illustrates the layout of the view cone:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
Layer 5 (backdrop)  &lt;br /&gt;
                                  ─────────────────────────────────&lt;br /&gt;
Layer 4                               A | B | C | D | E | F | G &lt;br /&gt;
                                         ─── ─── ─── ─── ─── &lt;br /&gt;
Layer 3                                   H | I | J | K | L &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 2                                       M | N | O &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 1 (closest)                             P | ^ | Q  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The caret (&amp;lt;code&amp;gt;^&amp;lt;/code&amp;gt;) represents the party’s position. Vertical bars (&amp;lt;code&amp;gt;|&amp;lt;/code&amp;gt;) and overbars (&amp;lt;code&amp;gt;───&amp;lt;/code&amp;gt;) in the diagram denote walls at various distances.&lt;br /&gt;
&lt;br /&gt;
In total, there are 25 distinct wall positions within the player’s field of vision. To render all walls correctly, the engine must read 17 map cells (A–Q) from the dungeon layout.&lt;br /&gt;
&lt;br /&gt;
The first 22 x 15 = &#039;&#039;&#039;330&#039;&#039;&#039; tile indices are used for the backdrop. The background is horizontally flipped when &amp;lt;code&amp;gt;party.x &amp;amp; party.y &amp;amp; party.direction == 1&amp;lt;/code&amp;gt;. In other words, certain movements or rotations from the current position cause the background to appear mirrored.&lt;br /&gt;
&lt;br /&gt;
What follows are &#039;&#039;&#039;431&#039;&#039;&#039; tile indices per wall type. [[Eye of the Beholder]] has 6 different wall types: solid wall type 1, solid wall type 2, door frame, stairs up, stairs down and portal. The wall types are defined in the [[Eye of the Beholder Maze Format]] files. Each block in the MAZ file has wall information for all 4 walls (north, east, south, west) from which the wall type is inferred - for each wall in the level.&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;margin:auto;&amp;quot;&lt;br /&gt;
| [[File:BRICK bg.png|frame|Backdrop from BRICK.VMP]]&lt;br /&gt;
| [[File:BRICK wall 1.png|frame|Wall Type 1 from BRICK.VMP]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Render Code ==&lt;br /&gt;
&lt;br /&gt;
Pseudo code for rendering the background:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void drawBackground(bool xflip)&lt;br /&gt;
{&lt;br /&gt;
   for (int y=0; y&amp;lt;15; y++)&lt;br /&gt;
   {&lt;br /&gt;
      for (int x=0; x&amp;lt;22; x++)&lt;br /&gt;
      {&lt;br /&gt;
         int tile;&lt;br /&gt;
 &lt;br /&gt;
         if (xflip)&lt;br /&gt;
            tile=vmp.backgroundTiles[21-x][y];&lt;br /&gt;
         else&lt;br /&gt;
            tile=vmp.backgroundTiles[x][y];&lt;br /&gt;
 &lt;br /&gt;
         /* xor with xflip to make block flip and background flip cancel each other out. */&lt;br /&gt;
         int blockFlip = (tile&amp;amp;0x4000)^flipX;&lt;br /&gt;
         int blockIndex= tile&amp;amp;0x3fff;&lt;br /&gt;
 &lt;br /&gt;
         if (blockFlip)&lt;br /&gt;
            drawBlockXFlip(x*8, y*8, vcn.blocks[blockIndex]);&lt;br /&gt;
         else&lt;br /&gt;
            drawBlock(x*8, y*8, vcn.blocks[blockIndex]);&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To render the walls, we can use this structure:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
struct WallRenderData&lt;br /&gt;
{&lt;br /&gt;
   int baseOffset;&lt;br /&gt;
   int offsetInViewPort;&lt;br /&gt;
   int visibleWidthInBlocks;&lt;br /&gt;
   int visibleHeightInBlocks;&lt;br /&gt;
   int skipValue;&lt;br /&gt;
   int flipFlag;&lt;br /&gt;
} wallRenderData[25]= /* 25 different wall positions */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;baseOffset&amp;lt;/code&amp;gt;&lt;br /&gt;
: Base offset into tileIndices[wallType-1]. This is an offset into the 431 index block for each wall type.&lt;br /&gt;
; &amp;lt;code&amp;gt;offsetInViewPort&amp;lt;/code&amp;gt;&lt;br /&gt;
: Block index in the viewport where to start render. {{TODO|Needs explanation}}&lt;br /&gt;
xpos = offsetInViewPort%22;&lt;br /&gt;
ypos = offsetInViewPort/22;&lt;br /&gt;
visibleWidthInBlocks&lt;br /&gt;
How many visible blocks wide the wall is in the viewport.&lt;br /&gt;
visibleHeightInBlocks&lt;br /&gt;
How many visible blocks hight the wall is in the viewport.&lt;br /&gt;
skipValue&lt;br /&gt;
Number of tiles to the next row in the wallTiles[wallType-1] array.&lt;br /&gt;
flipFlag&lt;br /&gt;
1 if the wall is to be x-flipped in the viewport. Generally all right-walls are x-flipped.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
   /* Side-Walls left back */&lt;br /&gt;
   {   3, 66, 5, 1, 2, 0},             /* A-east */&lt;br /&gt;
   {   1, 68, 5, 3, 0, 0},             /* B-east */&lt;br /&gt;
   {  -4, 74, 5, 1, 0, 0},             /* C-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side-Walls right back */&lt;br /&gt;
   {  -4, 79, 5, 1, 0, 1},              /* E-west */&lt;br /&gt;
   {   1, 83, 5, 3, 0, 1},              /* F-west */&lt;br /&gt;
   {   3, 87, 5, 1, 2, 1},              /* G-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls back */&lt;br /&gt;
   {  32, 66, 5, 2, 4, 0},              /* B-south */&lt;br /&gt;
   {  28, 68, 5, 6, 0, 0},              /* C-south */&lt;br /&gt;
   {  28, 74, 5, 6, 0, 0},              /* D-south */&lt;br /&gt;
   {  28, 80, 5, 6, 0, 0},              /* E-south */&lt;br /&gt;
   {  28, 86, 5, 2, 4, 0},              /* F-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle back left */&lt;br /&gt;
   {  16, 66, 6, 2, 0, 0},              /* H-east */&lt;br /&gt;
   { -20, 50, 8, 2, 0, 0},              /* I-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle back right */&lt;br /&gt;
   { -20, 58, 8, 2, 0, 1},              /* K-west */&lt;br /&gt;
   {  16, 86, 6, 2, 0, 1},              /* L-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls middle back */&lt;br /&gt;
   {  62, 44, 8, 6, 4, 0},              /* I-south */&lt;br /&gt;
   {  58, 50, 8,10, 0, 0},              /* J-south */&lt;br /&gt;
   {  58, 60, 8, 6, 4, 0},              /* K-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle front left */&lt;br /&gt;
   { -56, 25,12, 3, 0, 0},              /* M-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle front right */&lt;br /&gt;
   { -56, 38,12, 3, 0, 1},              /* O-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls middle front */&lt;br /&gt;
   { 151, 22,12, 3,13, 0},              /* M-south */&lt;br /&gt;
   { 138, 41,12, 3,13, 0},              /* O-south */&lt;br /&gt;
   { 138, 25,12,16, 0, 0},              /* N-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side wall front left */&lt;br /&gt;
   {-101,  0,15, 3, 0, 0},              /* P-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side wall front right */&lt;br /&gt;
   {-101, 19,15, 3, 0, 1},              /* Q-west */&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Fergusdog</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12614</id>
		<title>Eye of the Beholder VMP Format</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12614"/>
		<updated>2025-10-31T03:43:12Z</updated>

		<summary type="html">&lt;p&gt;Fergusdog: /* Render Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NeedMoreInfo}}&lt;br /&gt;
{{Map Infobox&lt;br /&gt;
 | Type = 2D tile-based&lt;br /&gt;
 | Layers = 5&lt;br /&gt;
 | Tile size = 8&amp;amp;times;8&lt;br /&gt;
 | Viewport = 176&amp;amp;times;120&lt;br /&gt;
 | Games = &lt;br /&gt;
   {{Game|Eye of the Beholder}}&lt;br /&gt;
   {{Game|Eye of the Beholder II: The Legend of Darkmoon}}&lt;br /&gt;
   {{Game|Lands of Lore: The Throne of Chaos}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file assembles the tiles from the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset.&lt;br /&gt;
It functions similarly to a map file in other video games, except that in [[Eye of the Beholder]] it does not represent a top-down layout. Instead, it defines the 3D view of the dungeon, often referred to as the &#039;&#039;view cone&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
In essence, the &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file contains a collection of indices that reference tile graphics within the &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. These indices are interpreted by the game’s main executable to construct the player&#039;s first-person view of the world.&lt;br /&gt;
&lt;br /&gt;
== File Format (PC version) ==&lt;br /&gt;
&lt;br /&gt;
In [[Lands of Lore: The Throne of Chaos]], &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; files are compressed , using the [[Westwood LCW]] compression (see [[Westwood CPS Format]]).&lt;br /&gt;
The uncompressed format is defined as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short index_count; &lt;br /&gt;
    unsigned short indices[index_count]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each entry in &amp;lt;code&amp;gt;indices&amp;lt;/code&amp;gt; represents an index that references a specific block in the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. For more details on the index entries, see the [[#Tile Index|Tile Index]] section below.&lt;br /&gt;
&lt;br /&gt;
== File Format (Amiga version) ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short header; &lt;br /&gt;
    unsigned short backdrop_tiles[22][15]; &lt;br /&gt;
    unsigned short padding[101]; &lt;br /&gt;
    unsigned short wall_tiles[wall_types_count][431]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;header&amp;lt;/code&amp;gt;&lt;br /&gt;
: {{TODO|Not yet fully investigated, but most likely specifies the number of wall types defined in the file.}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;backdrop_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the static backdrop (ceiling/floor) image..&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;padding&amp;lt;/code&amp;gt;&lt;br /&gt;
: Each wall type uses 431 tile indices. To match this count for the backdrop tiles, a padding of 101 empty indices is added (&amp;lt;code&amp;gt;22 × 15 + 101 = 431&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the wall graphics for each wall type.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_types_count&amp;lt;/code&amp;gt;&lt;br /&gt;
: Probably stored in the header, but can also be calculated as: &amp;lt;code&amp;gt;(filesize - 2) / (431 * 2) - 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tile Index ==&lt;br /&gt;
&lt;br /&gt;
Each index is represented as a 16-bit value using the following bit structure (most significant bits first):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct TileIndex { &lt;br /&gt;
    bool z-mask: 1; &lt;br /&gt;
    bool mirror_x: 1; &lt;br /&gt;
    unsigned tile_index: 14; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;z-mask&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;, only draw onto the tranparent pixels of the tile(s) below. In effect, acts as a mask for z-order, so the drawn tile appears behind the tile being drawn over. {{TODO|Need to confirm, expand?}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;mirror_x&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; flip the tile horizontally. Used to draw the right walls, for example.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;tile_index&amp;lt;/code&amp;gt;&lt;br /&gt;
: A 14-bit index selecting a specific tile from the corresponding &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset (see [[Eye of the Beholder VCN Format]]).&lt;br /&gt;
&lt;br /&gt;
== Rendering the View Cone ==&lt;br /&gt;
&lt;br /&gt;
The 3D view in [[Eye of the Beholder]] covers an area of &#039;&#039;&#039;22 × 15 tiles&#039;&#039;&#039; and is composed of five layers — the backdrop (ceiling and floor) and four wall layers. The backdrop is rendered first and provides the ceiling and floor as a single combined image. The wall layers are then drawn on top, alternating between front-facing and side-facing walls to construct the 3D perspective.&lt;br /&gt;
&lt;br /&gt;
The following diagram illustrates the layout of the view cone:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
Layer 5 (backdrop)  &lt;br /&gt;
                                  ─────────────────────────────────&lt;br /&gt;
Layer 4                               A | B | C | D | E | F | G &lt;br /&gt;
                                         ─── ─── ─── ─── ─── &lt;br /&gt;
Layer 3                                   H | I | J | K | L &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 2                                       M | N | O &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 1 (closest)                             P | ^ | Q  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The caret (&amp;lt;code&amp;gt;^&amp;lt;/code&amp;gt;) represents the party’s position. Vertical bars (&amp;lt;code&amp;gt;|&amp;lt;/code&amp;gt;) and overbars (&amp;lt;code&amp;gt;───&amp;lt;/code&amp;gt;) in the diagram denote walls at various distances.&lt;br /&gt;
&lt;br /&gt;
In total, there are 25 distinct wall positions within the player’s field of vision. To render all walls correctly, the engine must read 17 map cells (A–Q) from the dungeon layout.&lt;br /&gt;
&lt;br /&gt;
The first 22 x 15 = &#039;&#039;&#039;330&#039;&#039;&#039; tile indices are used for the backdrop. The background is horizontally flipped when &amp;lt;code&amp;gt;party.x &amp;amp; party.y &amp;amp; party.direction == 1&amp;lt;/code&amp;gt;. In other words, certain movements or rotations from the current position cause the background to appear mirrored.&lt;br /&gt;
&lt;br /&gt;
What follows are &#039;&#039;&#039;431&#039;&#039;&#039; tile indices per wall type. [[Eye of the Beholder]] has 6 different wall types: solid wall type 1, solid wall type 2, door frame, stairs up, stairs down and portal. The wall types are defined in the [[Eye of the Beholder Maze Format]] files. Each block in the MAZ file has wall information for all 4 walls (north, east, south, west) from which the wall type is inferred - for each wall in the level.&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;margin:auto;&amp;quot;&lt;br /&gt;
| [[File:BRICK bg.png|frame|Backdrop from BRICK.VMP]]&lt;br /&gt;
| [[File:BRICK wall 1.png|frame|Wall Type 1 from BRICK.VMP]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Render Code ==&lt;br /&gt;
&lt;br /&gt;
Pseudo code for rendering the background:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void drawBackground(bool xflip)&lt;br /&gt;
{&lt;br /&gt;
   for (int y=0; y&amp;lt;15; y++)&lt;br /&gt;
   {&lt;br /&gt;
      for (int x=0; x&amp;lt;22; x++)&lt;br /&gt;
      {&lt;br /&gt;
         int tile;&lt;br /&gt;
 &lt;br /&gt;
         if (xflip)&lt;br /&gt;
            tile=vmp.backgroundTiles[21-x][y];&lt;br /&gt;
         else&lt;br /&gt;
            tile=vmp.backgroundTiles[x][y];&lt;br /&gt;
 &lt;br /&gt;
         /* xor with xflip to make block flip and background flip cancel each other out. */&lt;br /&gt;
         int blockFlip = (tile&amp;amp;0x4000)^flipX;&lt;br /&gt;
         int blockIndex= tile&amp;amp;0x3fff;&lt;br /&gt;
 &lt;br /&gt;
         if (blockFlip)&lt;br /&gt;
            drawBlockXFlip(x*8, y*8, vcn.blocks[blockIndex]);&lt;br /&gt;
         else&lt;br /&gt;
            drawBlock(x*8, y*8, vcn.blocks[blockIndex]);&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To render the walls, we can use this structure:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
struct WallRenderData&lt;br /&gt;
{&lt;br /&gt;
   int baseOffset;&lt;br /&gt;
   int offsetInViewPort;&lt;br /&gt;
   int visibleWidthInBlocks;&lt;br /&gt;
   int visibleHeightInBlocks;&lt;br /&gt;
   int skipValue;&lt;br /&gt;
   int flipFlag;&lt;br /&gt;
} wallRenderData[25]= /* 25 different wall positions */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;baseOffset&amp;lt;/code&amp;gt;&lt;br /&gt;
: Base offset into tileIndices[wallType-1].&lt;br /&gt;
; &amp;lt;code&amp;gt;offsetInViewPort&amp;lt;/code&amp;gt;&lt;br /&gt;
: Block index in the viewport where to start render.&lt;br /&gt;
xpos = offsetInViewPort%22;&lt;br /&gt;
ypos = offsetInViewPort/22;&lt;br /&gt;
visibleWidthInBlocks&lt;br /&gt;
How many visible blocks wide the wall is in the viewport.&lt;br /&gt;
visibleHeightInBlocks&lt;br /&gt;
How many visible blocks hight the wall is in the viewport.&lt;br /&gt;
skipValue&lt;br /&gt;
Number of tiles to the next row in the wallTiles[wallType-1] array.&lt;br /&gt;
flipFlag&lt;br /&gt;
1 if the wall is to be x-flipped in the viewport. Generally all right-walls are x-flipped.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
   /* Side-Walls left back */&lt;br /&gt;
   {   3, 66, 5, 1, 2, 0},             /* A-east */&lt;br /&gt;
   {   1, 68, 5, 3, 0, 0},             /* B-east */&lt;br /&gt;
   {  -4, 74, 5, 1, 0, 0},             /* C-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side-Walls right back */&lt;br /&gt;
   {  -4, 79, 5, 1, 0, 1},              /* E-west */&lt;br /&gt;
   {   1, 83, 5, 3, 0, 1},              /* F-west */&lt;br /&gt;
   {   3, 87, 5, 1, 2, 1},              /* G-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls back */&lt;br /&gt;
   {  32, 66, 5, 2, 4, 0},              /* B-south */&lt;br /&gt;
   {  28, 68, 5, 6, 0, 0},              /* C-south */&lt;br /&gt;
   {  28, 74, 5, 6, 0, 0},              /* D-south */&lt;br /&gt;
   {  28, 80, 5, 6, 0, 0},              /* E-south */&lt;br /&gt;
   {  28, 86, 5, 2, 4, 0},              /* F-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle back left */&lt;br /&gt;
   {  16, 66, 6, 2, 0, 0},              /* H-east */&lt;br /&gt;
   { -20, 50, 8, 2, 0, 0},              /* I-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle back right */&lt;br /&gt;
   { -20, 58, 8, 2, 0, 1},              /* K-west */&lt;br /&gt;
   {  16, 86, 6, 2, 0, 1},              /* L-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls middle back */&lt;br /&gt;
   {  62, 44, 8, 6, 4, 0},              /* I-south */&lt;br /&gt;
   {  58, 50, 8,10, 0, 0},              /* J-south */&lt;br /&gt;
   {  58, 60, 8, 6, 4, 0},              /* K-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle front left */&lt;br /&gt;
   { -56, 25,12, 3, 0, 0},              /* M-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle front right */&lt;br /&gt;
   { -56, 38,12, 3, 0, 1},              /* O-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls middle front */&lt;br /&gt;
   { 151, 22,12, 3,13, 0},              /* M-south */&lt;br /&gt;
   { 138, 41,12, 3,13, 0},              /* O-south */&lt;br /&gt;
   { 138, 25,12,16, 0, 0},              /* N-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side wall front left */&lt;br /&gt;
   {-101,  0,15, 3, 0, 0},              /* P-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side wall front right */&lt;br /&gt;
   {-101, 19,15, 3, 0, 1},              /* Q-west */&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Fergusdog</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12613</id>
		<title>Eye of the Beholder VMP Format</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12613"/>
		<updated>2025-10-31T03:41:26Z</updated>

		<summary type="html">&lt;p&gt;Fergusdog: /* Render Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NeedMoreInfo}}&lt;br /&gt;
{{Map Infobox&lt;br /&gt;
 | Type = 2D tile-based&lt;br /&gt;
 | Layers = 5&lt;br /&gt;
 | Tile size = 8&amp;amp;times;8&lt;br /&gt;
 | Viewport = 176&amp;amp;times;120&lt;br /&gt;
 | Games = &lt;br /&gt;
   {{Game|Eye of the Beholder}}&lt;br /&gt;
   {{Game|Eye of the Beholder II: The Legend of Darkmoon}}&lt;br /&gt;
   {{Game|Lands of Lore: The Throne of Chaos}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file assembles the tiles from the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset.&lt;br /&gt;
It functions similarly to a map file in other video games, except that in [[Eye of the Beholder]] it does not represent a top-down layout. Instead, it defines the 3D view of the dungeon, often referred to as the &#039;&#039;view cone&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
In essence, the &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file contains a collection of indices that reference tile graphics within the &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. These indices are interpreted by the game’s main executable to construct the player&#039;s first-person view of the world.&lt;br /&gt;
&lt;br /&gt;
== File Format (PC version) ==&lt;br /&gt;
&lt;br /&gt;
In [[Lands of Lore: The Throne of Chaos]], &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; files are compressed , using the [[Westwood LCW]] compression (see [[Westwood CPS Format]]).&lt;br /&gt;
The uncompressed format is defined as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short index_count; &lt;br /&gt;
    unsigned short indices[index_count]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each entry in &amp;lt;code&amp;gt;indices&amp;lt;/code&amp;gt; represents an index that references a specific block in the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. For more details on the index entries, see the [[#Tile Index|Tile Index]] section below.&lt;br /&gt;
&lt;br /&gt;
== File Format (Amiga version) ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short header; &lt;br /&gt;
    unsigned short backdrop_tiles[22][15]; &lt;br /&gt;
    unsigned short padding[101]; &lt;br /&gt;
    unsigned short wall_tiles[wall_types_count][431]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;header&amp;lt;/code&amp;gt;&lt;br /&gt;
: {{TODO|Not yet fully investigated, but most likely specifies the number of wall types defined in the file.}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;backdrop_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the static backdrop (ceiling/floor) image..&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;padding&amp;lt;/code&amp;gt;&lt;br /&gt;
: Each wall type uses 431 tile indices. To match this count for the backdrop tiles, a padding of 101 empty indices is added (&amp;lt;code&amp;gt;22 × 15 + 101 = 431&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the wall graphics for each wall type.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_types_count&amp;lt;/code&amp;gt;&lt;br /&gt;
: Probably stored in the header, but can also be calculated as: &amp;lt;code&amp;gt;(filesize - 2) / (431 * 2) - 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tile Index ==&lt;br /&gt;
&lt;br /&gt;
Each index is represented as a 16-bit value using the following bit structure (most significant bits first):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct TileIndex { &lt;br /&gt;
    bool z-mask: 1; &lt;br /&gt;
    bool mirror_x: 1; &lt;br /&gt;
    unsigned tile_index: 14; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;z-mask&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;, only draw onto the tranparent pixels of the tile(s) below. In effect, acts as a mask for z-order, so the drawn tile appears behind the tile being drawn over. {{TODO|Need to confirm, expand?}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;mirror_x&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; flip the tile horizontally. Used to draw the right walls, for example.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;tile_index&amp;lt;/code&amp;gt;&lt;br /&gt;
: A 14-bit index selecting a specific tile from the corresponding &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset (see [[Eye of the Beholder VCN Format]]).&lt;br /&gt;
&lt;br /&gt;
== Rendering the View Cone ==&lt;br /&gt;
&lt;br /&gt;
The 3D view in [[Eye of the Beholder]] covers an area of &#039;&#039;&#039;22 × 15 tiles&#039;&#039;&#039; and is composed of five layers — the backdrop (ceiling and floor) and four wall layers. The backdrop is rendered first and provides the ceiling and floor as a single combined image. The wall layers are then drawn on top, alternating between front-facing and side-facing walls to construct the 3D perspective.&lt;br /&gt;
&lt;br /&gt;
The following diagram illustrates the layout of the view cone:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
Layer 5 (backdrop)  &lt;br /&gt;
                                  ─────────────────────────────────&lt;br /&gt;
Layer 4                               A | B | C | D | E | F | G &lt;br /&gt;
                                         ─── ─── ─── ─── ─── &lt;br /&gt;
Layer 3                                   H | I | J | K | L &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 2                                       M | N | O &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 1 (closest)                             P | ^ | Q  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The caret (&amp;lt;code&amp;gt;^&amp;lt;/code&amp;gt;) represents the party’s position. Vertical bars (&amp;lt;code&amp;gt;|&amp;lt;/code&amp;gt;) and overbars (&amp;lt;code&amp;gt;───&amp;lt;/code&amp;gt;) in the diagram denote walls at various distances.&lt;br /&gt;
&lt;br /&gt;
In total, there are 25 distinct wall positions within the player’s field of vision. To render all walls correctly, the engine must read 17 map cells (A–Q) from the dungeon layout.&lt;br /&gt;
&lt;br /&gt;
The first 22 x 15 = &#039;&#039;&#039;330&#039;&#039;&#039; tile indices are used for the backdrop. The background is horizontally flipped when &amp;lt;code&amp;gt;party.x &amp;amp; party.y &amp;amp; party.direction == 1&amp;lt;/code&amp;gt;. In other words, certain movements or rotations from the current position cause the background to appear mirrored.&lt;br /&gt;
&lt;br /&gt;
What follows are &#039;&#039;&#039;431&#039;&#039;&#039; tile indices per wall type. [[Eye of the Beholder]] has 6 different wall types: solid wall type 1, solid wall type 2, door frame, stairs up, stairs down and portal. The wall types are defined in the [[Eye of the Beholder Maze Format]] files. Each block in the MAZ file has wall information for all 4 walls (north, east, south, west) from which the wall type is inferred - for each wall in the level.&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;margin:auto;&amp;quot;&lt;br /&gt;
| [[File:BRICK bg.png|frame|Backdrop from BRICK.VMP]]&lt;br /&gt;
| [[File:BRICK wall 1.png|frame|Wall Type 1 from BRICK.VMP]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Render Code ==&lt;br /&gt;
&lt;br /&gt;
Pseudo code for rendering the background:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void drawBackground(bool xflip)&lt;br /&gt;
{&lt;br /&gt;
   for (int y=0; y&amp;lt;15; y++)&lt;br /&gt;
   {&lt;br /&gt;
      for (int x=0; x&amp;lt;22; x++)&lt;br /&gt;
      {&lt;br /&gt;
         int tile;&lt;br /&gt;
 &lt;br /&gt;
         if (xflip)&lt;br /&gt;
            tile=vmp.backgroundTiles[21-x][y];&lt;br /&gt;
         else&lt;br /&gt;
            tile=vmp.backgroundTiles[x][y];&lt;br /&gt;
 &lt;br /&gt;
         /* xor with xflip to make block flip and background flip cancel each other out. */&lt;br /&gt;
         int blockFlip = (tile&amp;amp;0x4000)^flipX;&lt;br /&gt;
         int blockIndex= tile&amp;amp;0x3fff;&lt;br /&gt;
 &lt;br /&gt;
         if (blockFlip)&lt;br /&gt;
            drawBlockXFlip(x*8, y*8, vcn.blocks[blockIndex]);&lt;br /&gt;
         else&lt;br /&gt;
            drawBlock(x*8, y*8, vcn.blocks[blockIndex]);&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To render the walls, we can use this structure:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
struct WallRenderData&lt;br /&gt;
{&lt;br /&gt;
   int baseOffset;&lt;br /&gt;
   int offsetInViewPort;&lt;br /&gt;
   int visibleWidthInBlocks;&lt;br /&gt;
   int visibleHeightInBlocks;&lt;br /&gt;
   int skipValue;&lt;br /&gt;
   int flipFlag;&lt;br /&gt;
} wallRenderData[25]= /* 25 different wall positions */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;baseOffset&amp;lt;/code&amp;gt;&lt;br /&gt;
Base offset into wallTiles[wallType-1]. This can be negative, but don&#039;t be deceived, this is just a base. The other values will add to this base making sure the wallTiles[wallType-1] array is accessed within bounds.&lt;br /&gt;
; &amp;lt;code&amp;gt;offsetInViewPort&amp;lt;/code&amp;gt;&lt;br /&gt;
Block index in the viewport where to start render.&lt;br /&gt;
xpos = offsetInViewPort%22;&lt;br /&gt;
ypos = offsetInViewPort/22;&lt;br /&gt;
visibleWidthInBlocks&lt;br /&gt;
How many visible blocks wide the wall is in the viewport.&lt;br /&gt;
visibleHeightInBlocks&lt;br /&gt;
How many visible blocks hight the wall is in the viewport.&lt;br /&gt;
skipValue&lt;br /&gt;
Number of tiles to the next row in the wallTiles[wallType-1] array.&lt;br /&gt;
flipFlag&lt;br /&gt;
1 if the wall is to be x-flipped in the viewport. Generally all right-walls are x-flipped.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
   /* Side-Walls left back */&lt;br /&gt;
   {   3, 66, 5, 1, 2, 0},             /* A-east */&lt;br /&gt;
   {   1, 68, 5, 3, 0, 0},             /* B-east */&lt;br /&gt;
   {  -4, 74, 5, 1, 0, 0},             /* C-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side-Walls right back */&lt;br /&gt;
   {  -4, 79, 5, 1, 0, 1},              /* E-west */&lt;br /&gt;
   {   1, 83, 5, 3, 0, 1},              /* F-west */&lt;br /&gt;
   {   3, 87, 5, 1, 2, 1},              /* G-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls back */&lt;br /&gt;
   {  32, 66, 5, 2, 4, 0},              /* B-south */&lt;br /&gt;
   {  28, 68, 5, 6, 0, 0},              /* C-south */&lt;br /&gt;
   {  28, 74, 5, 6, 0, 0},              /* D-south */&lt;br /&gt;
   {  28, 80, 5, 6, 0, 0},              /* E-south */&lt;br /&gt;
   {  28, 86, 5, 2, 4, 0},              /* F-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle back left */&lt;br /&gt;
   {  16, 66, 6, 2, 0, 0},              /* H-east */&lt;br /&gt;
   { -20, 50, 8, 2, 0, 0},              /* I-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle back right */&lt;br /&gt;
   { -20, 58, 8, 2, 0, 1},              /* K-west */&lt;br /&gt;
   {  16, 86, 6, 2, 0, 1},              /* L-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls middle back */&lt;br /&gt;
   {  62, 44, 8, 6, 4, 0},              /* I-south */&lt;br /&gt;
   {  58, 50, 8,10, 0, 0},              /* J-south */&lt;br /&gt;
   {  58, 60, 8, 6, 4, 0},              /* K-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle front left */&lt;br /&gt;
   { -56, 25,12, 3, 0, 0},              /* M-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle front right */&lt;br /&gt;
   { -56, 38,12, 3, 0, 1},              /* O-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls middle front */&lt;br /&gt;
   { 151, 22,12, 3,13, 0},              /* M-south */&lt;br /&gt;
   { 138, 41,12, 3,13, 0},              /* O-south */&lt;br /&gt;
   { 138, 25,12,16, 0, 0},              /* N-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side wall front left */&lt;br /&gt;
   {-101,  0,15, 3, 0, 0},              /* P-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side wall front right */&lt;br /&gt;
   {-101, 19,15, 3, 0, 1},              /* Q-west */&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Fergusdog</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12612</id>
		<title>Eye of the Beholder VMP Format</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12612"/>
		<updated>2025-10-31T03:40:37Z</updated>

		<summary type="html">&lt;p&gt;Fergusdog: /* Render the View Cone */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NeedMoreInfo}}&lt;br /&gt;
{{Map Infobox&lt;br /&gt;
 | Type = 2D tile-based&lt;br /&gt;
 | Layers = 5&lt;br /&gt;
 | Tile size = 8&amp;amp;times;8&lt;br /&gt;
 | Viewport = 176&amp;amp;times;120&lt;br /&gt;
 | Games = &lt;br /&gt;
   {{Game|Eye of the Beholder}}&lt;br /&gt;
   {{Game|Eye of the Beholder II: The Legend of Darkmoon}}&lt;br /&gt;
   {{Game|Lands of Lore: The Throne of Chaos}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file assembles the tiles from the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset.&lt;br /&gt;
It functions similarly to a map file in other video games, except that in [[Eye of the Beholder]] it does not represent a top-down layout. Instead, it defines the 3D view of the dungeon, often referred to as the &#039;&#039;view cone&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
In essence, the &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file contains a collection of indices that reference tile graphics within the &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. These indices are interpreted by the game’s main executable to construct the player&#039;s first-person view of the world.&lt;br /&gt;
&lt;br /&gt;
== File Format (PC version) ==&lt;br /&gt;
&lt;br /&gt;
In [[Lands of Lore: The Throne of Chaos]], &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; files are compressed , using the [[Westwood LCW]] compression (see [[Westwood CPS Format]]).&lt;br /&gt;
The uncompressed format is defined as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short index_count; &lt;br /&gt;
    unsigned short indices[index_count]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each entry in &amp;lt;code&amp;gt;indices&amp;lt;/code&amp;gt; represents an index that references a specific block in the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. For more details on the index entries, see the [[#Tile Index|Tile Index]] section below.&lt;br /&gt;
&lt;br /&gt;
== File Format (Amiga version) ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short header; &lt;br /&gt;
    unsigned short backdrop_tiles[22][15]; &lt;br /&gt;
    unsigned short padding[101]; &lt;br /&gt;
    unsigned short wall_tiles[wall_types_count][431]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;header&amp;lt;/code&amp;gt;&lt;br /&gt;
: {{TODO|Not yet fully investigated, but most likely specifies the number of wall types defined in the file.}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;backdrop_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the static backdrop (ceiling/floor) image..&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;padding&amp;lt;/code&amp;gt;&lt;br /&gt;
: Each wall type uses 431 tile indices. To match this count for the backdrop tiles, a padding of 101 empty indices is added (&amp;lt;code&amp;gt;22 × 15 + 101 = 431&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the wall graphics for each wall type.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_types_count&amp;lt;/code&amp;gt;&lt;br /&gt;
: Probably stored in the header, but can also be calculated as: &amp;lt;code&amp;gt;(filesize - 2) / (431 * 2) - 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tile Index ==&lt;br /&gt;
&lt;br /&gt;
Each index is represented as a 16-bit value using the following bit structure (most significant bits first):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct TileIndex { &lt;br /&gt;
    bool z-mask: 1; &lt;br /&gt;
    bool mirror_x: 1; &lt;br /&gt;
    unsigned tile_index: 14; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;z-mask&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;, only draw onto the tranparent pixels of the tile(s) below. In effect, acts as a mask for z-order, so the drawn tile appears behind the tile being drawn over. {{TODO|Need to confirm, expand?}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;mirror_x&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; flip the tile horizontally. Used to draw the right walls, for example.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;tile_index&amp;lt;/code&amp;gt;&lt;br /&gt;
: A 14-bit index selecting a specific tile from the corresponding &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset (see [[Eye of the Beholder VCN Format]]).&lt;br /&gt;
&lt;br /&gt;
== Rendering the View Cone ==&lt;br /&gt;
&lt;br /&gt;
The 3D view in [[Eye of the Beholder]] covers an area of &#039;&#039;&#039;22 × 15 tiles&#039;&#039;&#039; and is composed of five layers — the backdrop (ceiling and floor) and four wall layers. The backdrop is rendered first and provides the ceiling and floor as a single combined image. The wall layers are then drawn on top, alternating between front-facing and side-facing walls to construct the 3D perspective.&lt;br /&gt;
&lt;br /&gt;
The following diagram illustrates the layout of the view cone:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
Layer 5 (backdrop)  &lt;br /&gt;
                                  ─────────────────────────────────&lt;br /&gt;
Layer 4                               A | B | C | D | E | F | G &lt;br /&gt;
                                         ─── ─── ─── ─── ─── &lt;br /&gt;
Layer 3                                   H | I | J | K | L &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 2                                       M | N | O &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 1 (closest)                             P | ^ | Q  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The caret (&amp;lt;code&amp;gt;^&amp;lt;/code&amp;gt;) represents the party’s position. Vertical bars (&amp;lt;code&amp;gt;|&amp;lt;/code&amp;gt;) and overbars (&amp;lt;code&amp;gt;───&amp;lt;/code&amp;gt;) in the diagram denote walls at various distances.&lt;br /&gt;
&lt;br /&gt;
In total, there are 25 distinct wall positions within the player’s field of vision. To render all walls correctly, the engine must read 17 map cells (A–Q) from the dungeon layout.&lt;br /&gt;
&lt;br /&gt;
The first 22 x 15 = &#039;&#039;&#039;330&#039;&#039;&#039; tile indices are used for the backdrop. The background is horizontally flipped when &amp;lt;code&amp;gt;party.x &amp;amp; party.y &amp;amp; party.direction == 1&amp;lt;/code&amp;gt;. In other words, certain movements or rotations from the current position cause the background to appear mirrored.&lt;br /&gt;
&lt;br /&gt;
What follows are &#039;&#039;&#039;431&#039;&#039;&#039; tile indices per wall type. [[Eye of the Beholder]] has 6 different wall types: solid wall type 1, solid wall type 2, door frame, stairs up, stairs down and portal. The wall types are defined in the [[Eye of the Beholder Maze Format]] files. Each block in the MAZ file has wall information for all 4 walls (north, east, south, west) from which the wall type is inferred - for each wall in the level.&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;margin:auto;&amp;quot;&lt;br /&gt;
| [[File:BRICK bg.png|frame|Backdrop from BRICK.VMP]]&lt;br /&gt;
| [[File:BRICK wall 1.png|frame|Wall Type 1 from BRICK.VMP]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Render Code ==&lt;br /&gt;
&lt;br /&gt;
Pseudo code for rendering the background:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void drawBackground(bool xflip)&lt;br /&gt;
{&lt;br /&gt;
   for (int y=0; y&amp;lt;15; y++)&lt;br /&gt;
   {&lt;br /&gt;
      for (int x=0; x&amp;lt;22; x++)&lt;br /&gt;
      {&lt;br /&gt;
         int tile;&lt;br /&gt;
 &lt;br /&gt;
         if (xflip)&lt;br /&gt;
            tile=vmp.backgroundTiles[21-x][y];&lt;br /&gt;
         else&lt;br /&gt;
            tile=vmp.backgroundTiles[x][y];&lt;br /&gt;
 &lt;br /&gt;
         /* xor with xflip to make block flip and background flip cancel each other out. */&lt;br /&gt;
         int blockFlip = (tile&amp;amp;0x4000)^flipX;&lt;br /&gt;
         int blockIndex= tile&amp;amp;0x3fff;&lt;br /&gt;
 &lt;br /&gt;
         if (blockFlip)&lt;br /&gt;
            drawBlockXFlip(x*8, y*8, vcn.blocks[blockIndex]);&lt;br /&gt;
         else&lt;br /&gt;
            drawBlock(x*8, y*8, vcn.blocks[blockIndex]);&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To render the walls, we can use this structure:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
struct WallRenderData&lt;br /&gt;
{&lt;br /&gt;
   int baseOffset;&lt;br /&gt;
   int offsetInViewPort;&lt;br /&gt;
   int visibleWidthInBlocks;&lt;br /&gt;
   int visibleHeightInBlocks;&lt;br /&gt;
   int skipValue;&lt;br /&gt;
   int flipFlag;&lt;br /&gt;
} wallRenderData[25]= /* 25 different wall positions */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
baseOffset&lt;br /&gt;
Base offset into wallTiles[wallType-1]. This can be negative, but don&#039;t be deceived, this is just a base. The other values will add to this base making sure the wallTiles[wallType-1] array is accessed within bounds.&lt;br /&gt;
offsetInViewPort&lt;br /&gt;
Block index in the viewport where to start render.&lt;br /&gt;
xpos = offsetInViewPort%22;&lt;br /&gt;
ypos = offsetInViewPort/22;&lt;br /&gt;
visibleWidthInBlocks&lt;br /&gt;
How many visible blocks wide the wall is in the viewport.&lt;br /&gt;
visibleHeightInBlocks&lt;br /&gt;
How many visible blocks hight the wall is in the viewport.&lt;br /&gt;
skipValue&lt;br /&gt;
Number of tiles to the next row in the wallTiles[wallType-1] array.&lt;br /&gt;
flipFlag&lt;br /&gt;
1 if the wall is to be x-flipped in the viewport. Generally all right-walls are x-flipped.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
   /* Side-Walls left back */&lt;br /&gt;
   {   3, 66, 5, 1, 2, 0},             /* A-east */&lt;br /&gt;
   {   1, 68, 5, 3, 0, 0},             /* B-east */&lt;br /&gt;
   {  -4, 74, 5, 1, 0, 0},             /* C-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side-Walls right back */&lt;br /&gt;
   {  -4, 79, 5, 1, 0, 1},              /* E-west */&lt;br /&gt;
   {   1, 83, 5, 3, 0, 1},              /* F-west */&lt;br /&gt;
   {   3, 87, 5, 1, 2, 1},              /* G-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls back */&lt;br /&gt;
   {  32, 66, 5, 2, 4, 0},              /* B-south */&lt;br /&gt;
   {  28, 68, 5, 6, 0, 0},              /* C-south */&lt;br /&gt;
   {  28, 74, 5, 6, 0, 0},              /* D-south */&lt;br /&gt;
   {  28, 80, 5, 6, 0, 0},              /* E-south */&lt;br /&gt;
   {  28, 86, 5, 2, 4, 0},              /* F-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle back left */&lt;br /&gt;
   {  16, 66, 6, 2, 0, 0},              /* H-east */&lt;br /&gt;
   { -20, 50, 8, 2, 0, 0},              /* I-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle back right */&lt;br /&gt;
   { -20, 58, 8, 2, 0, 1},              /* K-west */&lt;br /&gt;
   {  16, 86, 6, 2, 0, 1},              /* L-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls middle back */&lt;br /&gt;
   {  62, 44, 8, 6, 4, 0},              /* I-south */&lt;br /&gt;
   {  58, 50, 8,10, 0, 0},              /* J-south */&lt;br /&gt;
   {  58, 60, 8, 6, 4, 0},              /* K-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle front left */&lt;br /&gt;
   { -56, 25,12, 3, 0, 0},              /* M-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle front right */&lt;br /&gt;
   { -56, 38,12, 3, 0, 1},              /* O-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls middle front */&lt;br /&gt;
   { 151, 22,12, 3,13, 0},              /* M-south */&lt;br /&gt;
   { 138, 41,12, 3,13, 0},              /* O-south */&lt;br /&gt;
   { 138, 25,12,16, 0, 0},              /* N-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side wall front left */&lt;br /&gt;
   {-101,  0,15, 3, 0, 0},              /* P-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side wall front right */&lt;br /&gt;
   {-101, 19,15, 3, 0, 1},              /* Q-west */&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Fergusdog</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12611</id>
		<title>Eye of the Beholder VMP Format</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12611"/>
		<updated>2025-10-31T03:39:31Z</updated>

		<summary type="html">&lt;p&gt;Fergusdog: /* Render the View Cone */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NeedMoreInfo}}&lt;br /&gt;
{{Map Infobox&lt;br /&gt;
 | Type = 2D tile-based&lt;br /&gt;
 | Layers = 5&lt;br /&gt;
 | Tile size = 8&amp;amp;times;8&lt;br /&gt;
 | Viewport = 176&amp;amp;times;120&lt;br /&gt;
 | Games = &lt;br /&gt;
   {{Game|Eye of the Beholder}}&lt;br /&gt;
   {{Game|Eye of the Beholder II: The Legend of Darkmoon}}&lt;br /&gt;
   {{Game|Lands of Lore: The Throne of Chaos}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file assembles the tiles from the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset.&lt;br /&gt;
It functions similarly to a map file in other video games, except that in [[Eye of the Beholder]] it does not represent a top-down layout. Instead, it defines the 3D view of the dungeon, often referred to as the &#039;&#039;view cone&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
In essence, the &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file contains a collection of indices that reference tile graphics within the &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. These indices are interpreted by the game’s main executable to construct the player&#039;s first-person view of the world.&lt;br /&gt;
&lt;br /&gt;
== File Format (PC version) ==&lt;br /&gt;
&lt;br /&gt;
In [[Lands of Lore: The Throne of Chaos]], &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; files are compressed , using the [[Westwood LCW]] compression (see [[Westwood CPS Format]]).&lt;br /&gt;
The uncompressed format is defined as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short index_count; &lt;br /&gt;
    unsigned short indices[index_count]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each entry in &amp;lt;code&amp;gt;indices&amp;lt;/code&amp;gt; represents an index that references a specific block in the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. For more details on the index entries, see the [[#Tile Index|Tile Index]] section below.&lt;br /&gt;
&lt;br /&gt;
== File Format (Amiga version) ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short header; &lt;br /&gt;
    unsigned short backdrop_tiles[22][15]; &lt;br /&gt;
    unsigned short padding[101]; &lt;br /&gt;
    unsigned short wall_tiles[wall_types_count][431]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;header&amp;lt;/code&amp;gt;&lt;br /&gt;
: {{TODO|Not yet fully investigated, but most likely specifies the number of wall types defined in the file.}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;backdrop_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the static backdrop (ceiling/floor) image..&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;padding&amp;lt;/code&amp;gt;&lt;br /&gt;
: Each wall type uses 431 tile indices. To match this count for the backdrop tiles, a padding of 101 empty indices is added (&amp;lt;code&amp;gt;22 × 15 + 101 = 431&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the wall graphics for each wall type.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_types_count&amp;lt;/code&amp;gt;&lt;br /&gt;
: Probably stored in the header, but can also be calculated as: &amp;lt;code&amp;gt;(filesize - 2) / (431 * 2) - 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tile Index ==&lt;br /&gt;
&lt;br /&gt;
Each index is represented as a 16-bit value using the following bit structure (most significant bits first):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct TileIndex { &lt;br /&gt;
    bool z-mask: 1; &lt;br /&gt;
    bool mirror_x: 1; &lt;br /&gt;
    unsigned tile_index: 14; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;z-mask&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;, only draw onto the tranparent pixels of the tile(s) below. In effect, acts as a mask for z-order, so the drawn tile appears behind the tile being drawn over. {{TODO|Need to confirm, expand?}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;mirror_x&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; flip the tile horizontally. Used to draw the right walls, for example.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;tile_index&amp;lt;/code&amp;gt;&lt;br /&gt;
: A 14-bit index selecting a specific tile from the corresponding &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset (see [[Eye of the Beholder VCN Format]]).&lt;br /&gt;
&lt;br /&gt;
== Render the View Cone ==&lt;br /&gt;
&lt;br /&gt;
The 3D view in [[Eye of the Beholder]] covers an area of &#039;&#039;&#039;22 × 15 tiles&#039;&#039;&#039; and is composed of five layers — the backdrop (ceiling and floor) and four wall layers. The backdrop is rendered first and provides the ceiling and floor as a single combined image. The wall layers are then drawn on top, alternating between front-facing and side-facing walls to construct the 3D perspective.&lt;br /&gt;
&lt;br /&gt;
The following diagram illustrates the layout of the view cone:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
Layer 5 (backdrop)  &lt;br /&gt;
                                  ─────────────────────────────────&lt;br /&gt;
Layer 4                               A | B | C | D | E | F | G &lt;br /&gt;
                                         ─── ─── ─── ─── ─── &lt;br /&gt;
Layer 3                                   H | I | J | K | L &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 2                                       M | N | O &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 1 (closest)                             P | ^ | Q  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The caret (&amp;lt;code&amp;gt;^&amp;lt;/code&amp;gt;) represents the party’s position. Vertical bars (&amp;lt;code&amp;gt;|&amp;lt;/code&amp;gt;) and overbars (&amp;lt;code&amp;gt;───&amp;lt;/code&amp;gt;) in the diagram denote walls at various distances.&lt;br /&gt;
&lt;br /&gt;
In total, there are 25 distinct wall positions within the player’s field of vision. To render all walls correctly, the engine must read 17 map cells (A–Q) from the dungeon layout.&lt;br /&gt;
&lt;br /&gt;
The first 22 x 15 = &#039;&#039;&#039;330&#039;&#039;&#039; tile indices are used for the backdrop. The background is horizontally flipped when &amp;lt;code&amp;gt;party.x &amp;amp; party.y &amp;amp; party.direction == 1&amp;lt;/code&amp;gt;. In other words, certain movements or rotations from the current position cause the background to appear mirrored.&lt;br /&gt;
&lt;br /&gt;
What follows are &#039;&#039;&#039;431&#039;&#039;&#039; tile indices per wall type. [[Eye of the Beholder]] has 6 different wall types: solid wall type 1, solid wall type 2, door frame, stairs up, stairs down and portal. The wall types are defined in the [[Eye of the Beholder Maze Format]] files. Each block in the MAZ file has wall information for all 4 walls (north, east, south, west) from which the wall type is inferred - for each wall in the level.&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;margin:auto;&amp;quot;&lt;br /&gt;
| [[File:BRICK bg.png|frame|Backdrop from BRICK.VMP]]&lt;br /&gt;
| [[File:BRICK wall 1.png|frame|Wall Type 1 from BRICK.VMP]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Render Code ==&lt;br /&gt;
&lt;br /&gt;
Pseudo code for rendering the background:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void drawBackground(bool xflip)&lt;br /&gt;
{&lt;br /&gt;
   for (int y=0; y&amp;lt;15; y++)&lt;br /&gt;
   {&lt;br /&gt;
      for (int x=0; x&amp;lt;22; x++)&lt;br /&gt;
      {&lt;br /&gt;
         int tile;&lt;br /&gt;
 &lt;br /&gt;
         if (xflip)&lt;br /&gt;
            tile=vmp.backgroundTiles[21-x][y];&lt;br /&gt;
         else&lt;br /&gt;
            tile=vmp.backgroundTiles[x][y];&lt;br /&gt;
 &lt;br /&gt;
         /* xor with xflip to make block flip and background flip cancel each other out. */&lt;br /&gt;
         int blockFlip = (tile&amp;amp;0x4000)^flipX;&lt;br /&gt;
         int blockIndex= tile&amp;amp;0x3fff;&lt;br /&gt;
 &lt;br /&gt;
         if (blockFlip)&lt;br /&gt;
            drawBlockXFlip(x*8, y*8, vcn.blocks[blockIndex]);&lt;br /&gt;
         else&lt;br /&gt;
            drawBlock(x*8, y*8, vcn.blocks[blockIndex]);&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To render the walls, we can use this structure:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
struct WallRenderData&lt;br /&gt;
{&lt;br /&gt;
   int baseOffset;&lt;br /&gt;
   int offsetInViewPort;&lt;br /&gt;
   int visibleWidthInBlocks;&lt;br /&gt;
   int visibleHeightInBlocks;&lt;br /&gt;
   int skipValue;&lt;br /&gt;
   int flipFlag;&lt;br /&gt;
} wallRenderData[25]= /* 25 different wall positions */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
baseOffset&lt;br /&gt;
Base offset into wallTiles[wallType-1]. This can be negative, but don&#039;t be deceived, this is just a base. The other values will add to this base making sure the wallTiles[wallType-1] array is accessed within bounds.&lt;br /&gt;
offsetInViewPort&lt;br /&gt;
Block index in the viewport where to start render.&lt;br /&gt;
xpos = offsetInViewPort%22;&lt;br /&gt;
ypos = offsetInViewPort/22;&lt;br /&gt;
visibleWidthInBlocks&lt;br /&gt;
How many visible blocks wide the wall is in the viewport.&lt;br /&gt;
visibleHeightInBlocks&lt;br /&gt;
How many visible blocks hight the wall is in the viewport.&lt;br /&gt;
skipValue&lt;br /&gt;
Number of tiles to the next row in the wallTiles[wallType-1] array.&lt;br /&gt;
flipFlag&lt;br /&gt;
1 if the wall is to be x-flipped in the viewport. Generally all right-walls are x-flipped.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
   /* Side-Walls left back */&lt;br /&gt;
   {   3, 66, 5, 1, 2, 0},             /* A-east */&lt;br /&gt;
   {   1, 68, 5, 3, 0, 0},             /* B-east */&lt;br /&gt;
   {  -4, 74, 5, 1, 0, 0},             /* C-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side-Walls right back */&lt;br /&gt;
   {  -4, 79, 5, 1, 0, 1},              /* E-west */&lt;br /&gt;
   {   1, 83, 5, 3, 0, 1},              /* F-west */&lt;br /&gt;
   {   3, 87, 5, 1, 2, 1},              /* G-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls back */&lt;br /&gt;
   {  32, 66, 5, 2, 4, 0},              /* B-south */&lt;br /&gt;
   {  28, 68, 5, 6, 0, 0},              /* C-south */&lt;br /&gt;
   {  28, 74, 5, 6, 0, 0},              /* D-south */&lt;br /&gt;
   {  28, 80, 5, 6, 0, 0},              /* E-south */&lt;br /&gt;
   {  28, 86, 5, 2, 4, 0},              /* F-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle back left */&lt;br /&gt;
   {  16, 66, 6, 2, 0, 0},              /* H-east */&lt;br /&gt;
   { -20, 50, 8, 2, 0, 0},              /* I-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle back right */&lt;br /&gt;
   { -20, 58, 8, 2, 0, 1},              /* K-west */&lt;br /&gt;
   {  16, 86, 6, 2, 0, 1},              /* L-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls middle back */&lt;br /&gt;
   {  62, 44, 8, 6, 4, 0},              /* I-south */&lt;br /&gt;
   {  58, 50, 8,10, 0, 0},              /* J-south */&lt;br /&gt;
   {  58, 60, 8, 6, 4, 0},              /* K-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle front left */&lt;br /&gt;
   { -56, 25,12, 3, 0, 0},              /* M-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle front right */&lt;br /&gt;
   { -56, 38,12, 3, 0, 1},              /* O-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls middle front */&lt;br /&gt;
   { 151, 22,12, 3,13, 0},              /* M-south */&lt;br /&gt;
   { 138, 41,12, 3,13, 0},              /* O-south */&lt;br /&gt;
   { 138, 25,12,16, 0, 0},              /* N-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side wall front left */&lt;br /&gt;
   {-101,  0,15, 3, 0, 0},              /* P-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side wall front right */&lt;br /&gt;
   {-101, 19,15, 3, 0, 1},              /* Q-west */&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Fergusdog</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12610</id>
		<title>Eye of the Beholder VMP Format</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12610"/>
		<updated>2025-10-31T03:38:18Z</updated>

		<summary type="html">&lt;p&gt;Fergusdog: /* Render the View Cone */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NeedMoreInfo}}&lt;br /&gt;
{{Map Infobox&lt;br /&gt;
 | Type = 2D tile-based&lt;br /&gt;
 | Layers = 5&lt;br /&gt;
 | Tile size = 8&amp;amp;times;8&lt;br /&gt;
 | Viewport = 176&amp;amp;times;120&lt;br /&gt;
 | Games = &lt;br /&gt;
   {{Game|Eye of the Beholder}}&lt;br /&gt;
   {{Game|Eye of the Beholder II: The Legend of Darkmoon}}&lt;br /&gt;
   {{Game|Lands of Lore: The Throne of Chaos}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file assembles the tiles from the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset.&lt;br /&gt;
It functions similarly to a map file in other video games, except that in [[Eye of the Beholder]] it does not represent a top-down layout. Instead, it defines the 3D view of the dungeon, often referred to as the &#039;&#039;view cone&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
In essence, the &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file contains a collection of indices that reference tile graphics within the &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. These indices are interpreted by the game’s main executable to construct the player&#039;s first-person view of the world.&lt;br /&gt;
&lt;br /&gt;
== File Format (PC version) ==&lt;br /&gt;
&lt;br /&gt;
In [[Lands of Lore: The Throne of Chaos]], &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; files are compressed , using the [[Westwood LCW]] compression (see [[Westwood CPS Format]]).&lt;br /&gt;
The uncompressed format is defined as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short index_count; &lt;br /&gt;
    unsigned short indices[index_count]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each entry in &amp;lt;code&amp;gt;indices&amp;lt;/code&amp;gt; represents an index that references a specific block in the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. For more details on the index entries, see the [[#Tile Index|Tile Index]] section below.&lt;br /&gt;
&lt;br /&gt;
== File Format (Amiga version) ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short header; &lt;br /&gt;
    unsigned short backdrop_tiles[22][15]; &lt;br /&gt;
    unsigned short padding[101]; &lt;br /&gt;
    unsigned short wall_tiles[wall_types_count][431]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;header&amp;lt;/code&amp;gt;&lt;br /&gt;
: {{TODO|Not yet fully investigated, but most likely specifies the number of wall types defined in the file.}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;backdrop_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the static backdrop (ceiling/floor) image..&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;padding&amp;lt;/code&amp;gt;&lt;br /&gt;
: Each wall type uses 431 tile indices. To match this count for the backdrop tiles, a padding of 101 empty indices is added (&amp;lt;code&amp;gt;22 × 15 + 101 = 431&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the wall graphics for each wall type.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_types_count&amp;lt;/code&amp;gt;&lt;br /&gt;
: Probably stored in the header, but can also be calculated as: &amp;lt;code&amp;gt;(filesize - 2) / (431 * 2) - 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tile Index ==&lt;br /&gt;
&lt;br /&gt;
Each index is represented as a 16-bit value using the following bit structure (most significant bits first):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct TileIndex { &lt;br /&gt;
    bool z-mask: 1; &lt;br /&gt;
    bool mirror_x: 1; &lt;br /&gt;
    unsigned tile_index: 14; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;z-mask&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;, only draw onto the tranparent pixels of the tile(s) below. In effect, acts as a mask for z-order, so the drawn tile appears behind the tile being drawn over. {{TODO|Need to confirm, expand?}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;mirror_x&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; flip the tile horizontally. Used to draw the right walls, for example.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;tile_index&amp;lt;/code&amp;gt;&lt;br /&gt;
: A 14-bit index selecting a specific tile from the corresponding &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset (see [[Eye of the Beholder VCN Format]]).&lt;br /&gt;
&lt;br /&gt;
== Render the View Cone ==&lt;br /&gt;
&lt;br /&gt;
The 3D view in [[Eye of the Beholder]] covers an area of &#039;&#039;&#039;22 × 15 tiles&#039;&#039;&#039; and is composed of five layers — the backdrop (ceiling and floor) and four wall layers. The backdrop is rendered first and provides the ceiling and floor as a single combined image. The wall layers are then drawn on top, alternating between front-facing and side-facing walls to construct the 3D perspective.&lt;br /&gt;
&lt;br /&gt;
The following diagram illustrates the layout of the view cone:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
Layer 5 (backdrop)  &lt;br /&gt;
                                  ─────────────────────────────────&lt;br /&gt;
Layer 4                               A | B | C | D | E | F | G &lt;br /&gt;
                                         ─── ─── ─── ─── ─── &lt;br /&gt;
Layer 3                                   H | I | J | K | L &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 2                                       M | N | O &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 1 (closest)                             P | ^ | Q  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The caret (&amp;lt;code&amp;gt;^&amp;lt;/code&amp;gt;) represents the party’s position. Vertical bars (&amp;lt;code&amp;gt;|&amp;lt;/code&amp;gt;) and overbars (&amp;lt;code&amp;gt;───&amp;lt;/code&amp;gt;) in the diagram denote walls at various distances.&lt;br /&gt;
&lt;br /&gt;
In total, there are 25 distinct wall positions within the player’s field of vision. To render all walls correctly, the engine must read 17 map cells (A–Q) from the dungeon layout.&lt;br /&gt;
&lt;br /&gt;
The first 22 x 15 = &#039;&#039;&#039;330&#039;&#039;&#039; tile indices are used for the backdrop. The background is horizontally flipped when &amp;lt;code&amp;gt;party.x &amp;amp; party.y &amp;amp; party.direction == 1&amp;lt;/code&amp;gt;. In other words, certain movements or rotations from the current position cause the background to appear mirrored.&lt;br /&gt;
&lt;br /&gt;
What follows are &#039;&#039;&#039;431&#039;&#039;&#039; tile indices per wall type. [[Eye of the Beholder]] has 6 different wall types: solid wall type 1, solid wall type 2, door frame, stairs up, stairs down and portal. The wall types are defined in the [[Eye of the Beholder Maze Format]] files. Each block in the MAZ file has wall information for all 4 walls (north, east, south, west) from which the wall type is inferred - for each wall in the level.&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;margin:auto;&amp;quot;&lt;br /&gt;
| [[File:BRICK bg.png|frame|Backdrop from BRICK.VMP]]&lt;br /&gt;
| [[File:BRICK wall 1.png|frame|Wall Type 1 from BRICK.VMP]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Pseudo code for rendering the background:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void drawBackground(bool xflip)&lt;br /&gt;
{&lt;br /&gt;
   for (int y=0; y&amp;lt;15; y++)&lt;br /&gt;
   {&lt;br /&gt;
      for (int x=0; x&amp;lt;22; x++)&lt;br /&gt;
      {&lt;br /&gt;
         int tile;&lt;br /&gt;
 &lt;br /&gt;
         if (xflip)&lt;br /&gt;
            tile=vmp.backgroundTiles[21-x][y];&lt;br /&gt;
         else&lt;br /&gt;
            tile=vmp.backgroundTiles[x][y];&lt;br /&gt;
 &lt;br /&gt;
         /* xor with xflip to make block flip and background flip cancel each other out. */&lt;br /&gt;
         int blockFlip = (tile&amp;amp;0x4000)^flipX;&lt;br /&gt;
         int blockIndex= tile&amp;amp;0x3fff;&lt;br /&gt;
 &lt;br /&gt;
         if (blockFlip)&lt;br /&gt;
            drawBlockXFlip(x*8, y*8, vcn.blocks[blockIndex]);&lt;br /&gt;
         else&lt;br /&gt;
            drawBlock(x*8, y*8, vcn.blocks[blockIndex]);&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To render the walls, we can use this structure:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
struct WallRenderData&lt;br /&gt;
{&lt;br /&gt;
   int baseOffset;&lt;br /&gt;
   int offsetInViewPort;&lt;br /&gt;
   int visibleWidthInBlocks;&lt;br /&gt;
   int visibleHeightInBlocks;&lt;br /&gt;
   int skipValue;&lt;br /&gt;
   int flipFlag;&lt;br /&gt;
} wallRenderData[25]= /* 25 different wall positions */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
baseOffset&lt;br /&gt;
Base offset into wallTiles[wallType-1]. This can be negative, but don&#039;t be deceived, this is just a base. The other values will add to this base making sure the wallTiles[wallType-1] array is accessed within bounds.&lt;br /&gt;
offsetInViewPort&lt;br /&gt;
Block index in the viewport where to start render.&lt;br /&gt;
xpos = offsetInViewPort%22;&lt;br /&gt;
ypos = offsetInViewPort/22;&lt;br /&gt;
visibleWidthInBlocks&lt;br /&gt;
How many visible blocks wide the wall is in the viewport.&lt;br /&gt;
visibleHeightInBlocks&lt;br /&gt;
How many visible blocks hight the wall is in the viewport.&lt;br /&gt;
skipValue&lt;br /&gt;
Number of tiles to the next row in the wallTiles[wallType-1] array.&lt;br /&gt;
flipFlag&lt;br /&gt;
1 if the wall is to be x-flipped in the viewport. Generally all right-walls are x-flipped.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
   /* Side-Walls left back */&lt;br /&gt;
   {   3, 66, 5, 1, 2, 0},             /* A-east */&lt;br /&gt;
   {   1, 68, 5, 3, 0, 0},             /* B-east */&lt;br /&gt;
   {  -4, 74, 5, 1, 0, 0},             /* C-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side-Walls right back */&lt;br /&gt;
   {  -4, 79, 5, 1, 0, 1},              /* E-west */&lt;br /&gt;
   {   1, 83, 5, 3, 0, 1},              /* F-west */&lt;br /&gt;
   {   3, 87, 5, 1, 2, 1},              /* G-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls back */&lt;br /&gt;
   {  32, 66, 5, 2, 4, 0},              /* B-south */&lt;br /&gt;
   {  28, 68, 5, 6, 0, 0},              /* C-south */&lt;br /&gt;
   {  28, 74, 5, 6, 0, 0},              /* D-south */&lt;br /&gt;
   {  28, 80, 5, 6, 0, 0},              /* E-south */&lt;br /&gt;
   {  28, 86, 5, 2, 4, 0},              /* F-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle back left */&lt;br /&gt;
   {  16, 66, 6, 2, 0, 0},              /* H-east */&lt;br /&gt;
   { -20, 50, 8, 2, 0, 0},              /* I-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle back right */&lt;br /&gt;
   { -20, 58, 8, 2, 0, 1},              /* K-west */&lt;br /&gt;
   {  16, 86, 6, 2, 0, 1},              /* L-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls middle back */&lt;br /&gt;
   {  62, 44, 8, 6, 4, 0},              /* I-south */&lt;br /&gt;
   {  58, 50, 8,10, 0, 0},              /* J-south */&lt;br /&gt;
   {  58, 60, 8, 6, 4, 0},              /* K-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle front left */&lt;br /&gt;
   { -56, 25,12, 3, 0, 0},              /* M-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle front right */&lt;br /&gt;
   { -56, 38,12, 3, 0, 1},              /* O-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls middle front */&lt;br /&gt;
   { 151, 22,12, 3,13, 0},              /* M-south */&lt;br /&gt;
   { 138, 41,12, 3,13, 0},              /* O-south */&lt;br /&gt;
   { 138, 25,12,16, 0, 0},              /* N-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side wall front left */&lt;br /&gt;
   {-101,  0,15, 3, 0, 0},              /* P-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side wall front right */&lt;br /&gt;
   {-101, 19,15, 3, 0, 1},              /* Q-west */&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Fergusdog</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12609</id>
		<title>Eye of the Beholder VMP Format</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12609"/>
		<updated>2025-10-31T03:35:13Z</updated>

		<summary type="html">&lt;p&gt;Fergusdog: /* Render the View Cone */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NeedMoreInfo}}&lt;br /&gt;
{{Map Infobox&lt;br /&gt;
 | Type = 2D tile-based&lt;br /&gt;
 | Layers = 5&lt;br /&gt;
 | Tile size = 8&amp;amp;times;8&lt;br /&gt;
 | Viewport = 176&amp;amp;times;120&lt;br /&gt;
 | Games = &lt;br /&gt;
   {{Game|Eye of the Beholder}}&lt;br /&gt;
   {{Game|Eye of the Beholder II: The Legend of Darkmoon}}&lt;br /&gt;
   {{Game|Lands of Lore: The Throne of Chaos}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file assembles the tiles from the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset.&lt;br /&gt;
It functions similarly to a map file in other video games, except that in [[Eye of the Beholder]] it does not represent a top-down layout. Instead, it defines the 3D view of the dungeon, often referred to as the &#039;&#039;view cone&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
In essence, the &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file contains a collection of indices that reference tile graphics within the &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. These indices are interpreted by the game’s main executable to construct the player&#039;s first-person view of the world.&lt;br /&gt;
&lt;br /&gt;
== File Format (PC version) ==&lt;br /&gt;
&lt;br /&gt;
In [[Lands of Lore: The Throne of Chaos]], &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; files are compressed , using the [[Westwood LCW]] compression (see [[Westwood CPS Format]]).&lt;br /&gt;
The uncompressed format is defined as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short index_count; &lt;br /&gt;
    unsigned short indices[index_count]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each entry in &amp;lt;code&amp;gt;indices&amp;lt;/code&amp;gt; represents an index that references a specific block in the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. For more details on the index entries, see the [[#Tile Index|Tile Index]] section below.&lt;br /&gt;
&lt;br /&gt;
== File Format (Amiga version) ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short header; &lt;br /&gt;
    unsigned short backdrop_tiles[22][15]; &lt;br /&gt;
    unsigned short padding[101]; &lt;br /&gt;
    unsigned short wall_tiles[wall_types_count][431]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;header&amp;lt;/code&amp;gt;&lt;br /&gt;
: {{TODO|Not yet fully investigated, but most likely specifies the number of wall types defined in the file.}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;backdrop_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the static backdrop (ceiling/floor) image..&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;padding&amp;lt;/code&amp;gt;&lt;br /&gt;
: Each wall type uses 431 tile indices. To match this count for the backdrop tiles, a padding of 101 empty indices is added (&amp;lt;code&amp;gt;22 × 15 + 101 = 431&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the wall graphics for each wall type.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_types_count&amp;lt;/code&amp;gt;&lt;br /&gt;
: Probably stored in the header, but can also be calculated as: &amp;lt;code&amp;gt;(filesize - 2) / (431 * 2) - 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tile Index ==&lt;br /&gt;
&lt;br /&gt;
Each index is represented as a 16-bit value using the following bit structure (most significant bits first):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct TileIndex { &lt;br /&gt;
    bool z-mask: 1; &lt;br /&gt;
    bool mirror_x: 1; &lt;br /&gt;
    unsigned tile_index: 14; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;z-mask&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;, only draw onto the tranparent pixels of the tile(s) below. In effect, acts as a mask for z-order, so the drawn tile appears behind the tile being drawn over. {{TODO|Need to confirm, expand?}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;mirror_x&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; flip the tile horizontally. Used to draw the right walls, for example.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;tile_index&amp;lt;/code&amp;gt;&lt;br /&gt;
: A 14-bit index selecting a specific tile from the corresponding &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset (see [[Eye of the Beholder VCN Format]]).&lt;br /&gt;
&lt;br /&gt;
== Render the View Cone ==&lt;br /&gt;
&lt;br /&gt;
The 3D view in [[Eye of the Beholder]] covers an area of &#039;&#039;&#039;22 × 15 tiles&#039;&#039;&#039; and is composed of five layers — the backdrop (ceiling and floor) and four wall layers. The backdrop is rendered first and provides the ceiling and floor as a single combined image. The wall layers are then drawn on top, alternating between front-facing and side-facing walls to construct the 3D perspective.&lt;br /&gt;
&lt;br /&gt;
The following diagram illustrates the layout of the view cone:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
Layer 5 (backdrop)  &lt;br /&gt;
                                  ─────────────────────────────────&lt;br /&gt;
Layer 4                               A | B | C | D | E | F | G &lt;br /&gt;
                                         ─── ─── ─── ─── ─── &lt;br /&gt;
Layer 3                                   H | I | J | K | L &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 2                                       M | N | O &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 1 (closest)                             P | ^ | Q  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The caret (&amp;lt;code&amp;gt;^&amp;lt;/code&amp;gt;) represents the party’s position. Vertical bars (&amp;lt;code&amp;gt;|&amp;lt;/code&amp;gt;) and overbars (&amp;lt;code&amp;gt;───&amp;lt;/code&amp;gt;) in the diagram denote walls at various distances.&lt;br /&gt;
&lt;br /&gt;
In total, there are 25 distinct wall positions within the player’s field of vision. To render all walls correctly, the engine must read 17 map cells (A–Q) from the dungeon layout.&lt;br /&gt;
&lt;br /&gt;
The first 22 x 15 = &#039;&#039;&#039;330&#039;&#039;&#039; tile indices are used for the backdrop. The background is horizontally flipped when &amp;lt;code&amp;gt;party.x &amp;amp; party.y &amp;amp; party.direction == 1&amp;lt;/code&amp;gt;. In other words, certain movements or rotations from the current position cause the background to appear mirrored.&lt;br /&gt;
&lt;br /&gt;
What follows are &#039;&#039;&#039;431&#039;&#039;&#039; tile indices per wall type. [[Eye of the Beholder]] has 6 different wall types: solid wall type 1, solid wall type 2, door frame, stairs up, stairs down and portal. The wall types are defined in the [[Eye of the Beholder Maze Format]] files. Each block in the MAZ file has wall information for all 4 walls (north, east, south, west) from which the wall type is inferred - for each wall in the level.&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;margin:auto;&amp;quot;&lt;br /&gt;
| [[File:BRICK bg.png|frame|Backdrop from BRICK.VMP]]&lt;br /&gt;
| [[File:BRICK wall 1.png|frame|Wall Type 1 from BRICK.VMP]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Pseudo code for rendering the background:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void drawBackground(bool xflip)&lt;br /&gt;
{&lt;br /&gt;
   for (int y=0; y&amp;lt;15; y++)&lt;br /&gt;
   {&lt;br /&gt;
      for (int x=0; x&amp;lt;22; x++)&lt;br /&gt;
      {&lt;br /&gt;
         int tile;&lt;br /&gt;
 &lt;br /&gt;
         if (xflip)&lt;br /&gt;
            tile=vmp.backgroundTiles[21-x][y];&lt;br /&gt;
         else&lt;br /&gt;
            tile=vmp.backgroundTiles[x][y];&lt;br /&gt;
 &lt;br /&gt;
         /* xor with xflip to make block flip and background flip cancel each other out. */&lt;br /&gt;
         int blockFlip = (tile&amp;amp;0x4000)^flipX;&lt;br /&gt;
         int blockIndex= tile&amp;amp;0x3fff;&lt;br /&gt;
 &lt;br /&gt;
         if (blockFlip)&lt;br /&gt;
            drawBlockXFlip(x*8, y*8, vcn.blocks[blockIndex]);&lt;br /&gt;
         else&lt;br /&gt;
            drawBlock(x*8, y*8, vcn.blocks[blockIndex]);&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To render the walls, we can use this structure:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
struct WallRenderData&lt;br /&gt;
{&lt;br /&gt;
   int baseOffset;&lt;br /&gt;
   int offsetInViewPort;&lt;br /&gt;
   int visibleWidthInBlocks;&lt;br /&gt;
   int visibleHeightInBlocks;&lt;br /&gt;
   int skipValue;&lt;br /&gt;
   int flipFlag;&lt;br /&gt;
} wallRenderData[25]= /* 25 different wall positions */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
   /* Side-Walls left back */&lt;br /&gt;
   {   3, 66, 5, 1, 2, 0},             /* A-east */&lt;br /&gt;
   {   1, 68, 5, 3, 0, 0},             /* B-east */&lt;br /&gt;
   {  -4, 74, 5, 1, 0, 0},             /* C-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side-Walls right back */&lt;br /&gt;
   {  -4, 79, 5, 1, 0, 1},              /* E-west */&lt;br /&gt;
   {   1, 83, 5, 3, 0, 1},              /* F-west */&lt;br /&gt;
   {   3, 87, 5, 1, 2, 1},              /* G-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls back */&lt;br /&gt;
   {  32, 66, 5, 2, 4, 0},              /* B-south */&lt;br /&gt;
   {  28, 68, 5, 6, 0, 0},              /* C-south */&lt;br /&gt;
   {  28, 74, 5, 6, 0, 0},              /* D-south */&lt;br /&gt;
   {  28, 80, 5, 6, 0, 0},              /* E-south */&lt;br /&gt;
   {  28, 86, 5, 2, 4, 0},              /* F-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle back left */&lt;br /&gt;
   {  16, 66, 6, 2, 0, 0},              /* H-east */&lt;br /&gt;
   { -20, 50, 8, 2, 0, 0},              /* I-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle back right */&lt;br /&gt;
   { -20, 58, 8, 2, 0, 1},              /* K-west */&lt;br /&gt;
   {  16, 86, 6, 2, 0, 1},              /* L-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls middle back */&lt;br /&gt;
   {  62, 44, 8, 6, 4, 0},              /* I-south */&lt;br /&gt;
   {  58, 50, 8,10, 0, 0},              /* J-south */&lt;br /&gt;
   {  58, 60, 8, 6, 4, 0},              /* K-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle front left */&lt;br /&gt;
   { -56, 25,12, 3, 0, 0},              /* M-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle front right */&lt;br /&gt;
   { -56, 38,12, 3, 0, 1},              /* O-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls middle front */&lt;br /&gt;
   { 151, 22,12, 3,13, 0},              /* M-south */&lt;br /&gt;
   { 138, 41,12, 3,13, 0},              /* O-south */&lt;br /&gt;
   { 138, 25,12,16, 0, 0},              /* N-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side wall front left */&lt;br /&gt;
   {-101,  0,15, 3, 0, 0},              /* P-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side wall front right */&lt;br /&gt;
   {-101, 19,15, 3, 0, 1},              /* Q-west */&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
baseOffset&lt;br /&gt;
Base offset into wallTiles[wallType-1]. This can be negative, but don&#039;t be deceived, this is just a base. The other values will add to this base making sure the wallTiles[wallType-1] array is accessed within bounds.&lt;br /&gt;
offsetInViewPort&lt;br /&gt;
Block index in the viewport where to start render.&lt;br /&gt;
xpos = offsetInViewPort%22;&lt;br /&gt;
ypos = offsetInViewPort/22;&lt;br /&gt;
visibleWidthInBlocks&lt;br /&gt;
How many visible blocks wide the wall is in the viewport.&lt;br /&gt;
visibleHeightInBlocks&lt;br /&gt;
How many visible blocks hight the wall is in the viewport.&lt;br /&gt;
skipValue&lt;br /&gt;
Number of tiles to the next row in the wallTiles[wallType-1] array.&lt;br /&gt;
flipFlag&lt;br /&gt;
1 if the wall is to be x-flipped in the viewport. Generally all right-walls are x-flipped.&lt;/div&gt;</summary>
		<author><name>Fergusdog</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12608</id>
		<title>Eye of the Beholder VMP Format</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12608"/>
		<updated>2025-10-31T03:33:37Z</updated>

		<summary type="html">&lt;p&gt;Fergusdog: /* Render the View Cone */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NeedMoreInfo}}&lt;br /&gt;
{{Map Infobox&lt;br /&gt;
 | Type = 2D tile-based&lt;br /&gt;
 | Layers = 5&lt;br /&gt;
 | Tile size = 8&amp;amp;times;8&lt;br /&gt;
 | Viewport = 176&amp;amp;times;120&lt;br /&gt;
 | Games = &lt;br /&gt;
   {{Game|Eye of the Beholder}}&lt;br /&gt;
   {{Game|Eye of the Beholder II: The Legend of Darkmoon}}&lt;br /&gt;
   {{Game|Lands of Lore: The Throne of Chaos}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file assembles the tiles from the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset.&lt;br /&gt;
It functions similarly to a map file in other video games, except that in [[Eye of the Beholder]] it does not represent a top-down layout. Instead, it defines the 3D view of the dungeon, often referred to as the &#039;&#039;view cone&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
In essence, the &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file contains a collection of indices that reference tile graphics within the &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. These indices are interpreted by the game’s main executable to construct the player&#039;s first-person view of the world.&lt;br /&gt;
&lt;br /&gt;
== File Format (PC version) ==&lt;br /&gt;
&lt;br /&gt;
In [[Lands of Lore: The Throne of Chaos]], &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; files are compressed , using the [[Westwood LCW]] compression (see [[Westwood CPS Format]]).&lt;br /&gt;
The uncompressed format is defined as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short index_count; &lt;br /&gt;
    unsigned short indices[index_count]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each entry in &amp;lt;code&amp;gt;indices&amp;lt;/code&amp;gt; represents an index that references a specific block in the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. For more details on the index entries, see the [[#Tile Index|Tile Index]] section below.&lt;br /&gt;
&lt;br /&gt;
== File Format (Amiga version) ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short header; &lt;br /&gt;
    unsigned short backdrop_tiles[22][15]; &lt;br /&gt;
    unsigned short padding[101]; &lt;br /&gt;
    unsigned short wall_tiles[wall_types_count][431]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;header&amp;lt;/code&amp;gt;&lt;br /&gt;
: {{TODO|Not yet fully investigated, but most likely specifies the number of wall types defined in the file.}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;backdrop_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the static backdrop (ceiling/floor) image..&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;padding&amp;lt;/code&amp;gt;&lt;br /&gt;
: Each wall type uses 431 tile indices. To match this count for the backdrop tiles, a padding of 101 empty indices is added (&amp;lt;code&amp;gt;22 × 15 + 101 = 431&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the wall graphics for each wall type.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_types_count&amp;lt;/code&amp;gt;&lt;br /&gt;
: Probably stored in the header, but can also be calculated as: &amp;lt;code&amp;gt;(filesize - 2) / (431 * 2) - 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tile Index ==&lt;br /&gt;
&lt;br /&gt;
Each index is represented as a 16-bit value using the following bit structure (most significant bits first):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct TileIndex { &lt;br /&gt;
    bool z-mask: 1; &lt;br /&gt;
    bool mirror_x: 1; &lt;br /&gt;
    unsigned tile_index: 14; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;z-mask&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;, only draw onto the tranparent pixels of the tile(s) below. In effect, acts as a mask for z-order, so the drawn tile appears behind the tile being drawn over. {{TODO|Need to confirm, expand?}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;mirror_x&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; flip the tile horizontally. Used to draw the right walls, for example.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;tile_index&amp;lt;/code&amp;gt;&lt;br /&gt;
: A 14-bit index selecting a specific tile from the corresponding &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset (see [[Eye of the Beholder VCN Format]]).&lt;br /&gt;
&lt;br /&gt;
== Render the View Cone ==&lt;br /&gt;
&lt;br /&gt;
The 3D view in [[Eye of the Beholder]] covers an area of &#039;&#039;&#039;22 × 15 tiles&#039;&#039;&#039; and is composed of five layers — the backdrop (ceiling and floor) and four wall layers. The backdrop is rendered first and provides the ceiling and floor as a single combined image. The wall layers are then drawn on top, alternating between front-facing and side-facing walls to construct the 3D perspective.&lt;br /&gt;
&lt;br /&gt;
The following diagram illustrates the layout of the view cone:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
Layer 5 (backdrop)  &lt;br /&gt;
                                  ─────────────────────────────────&lt;br /&gt;
Layer 4                               A | B | C | D | E | F | G &lt;br /&gt;
                                         ─── ─── ─── ─── ─── &lt;br /&gt;
Layer 3                                   H | I | J | K | L &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 2                                       M | N | O &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 1 (closest)                             P | ^ | Q  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The caret (&amp;lt;code&amp;gt;^&amp;lt;/code&amp;gt;) represents the party’s position. Vertical bars (&amp;lt;code&amp;gt;|&amp;lt;/code&amp;gt;) and overbars (&amp;lt;code&amp;gt;───&amp;lt;/code&amp;gt;) in the diagram denote walls at various distances.&lt;br /&gt;
&lt;br /&gt;
In total, there are 25 distinct wall positions within the player’s field of vision. To render all walls correctly, the engine must read 17 map cells (A–Q) from the dungeon layout.&lt;br /&gt;
&lt;br /&gt;
The first 22 x 15 = &#039;&#039;&#039;330&#039;&#039;&#039; tile indices are used for the backdrop. The background is horizontally flipped when &amp;lt;code&amp;gt;party.x &amp;amp; party.y &amp;amp; party.direction == 1&amp;lt;/code&amp;gt;. In other words, certain movements or rotations from the current position cause the background to appear mirrored.&lt;br /&gt;
&lt;br /&gt;
What follows are &#039;&#039;&#039;431&#039;&#039;&#039; tile indices per wall type. [[Eye of the Beholder]] has 6 different wall types: solid wall type 1, solid wall type 2, door frame, stairs up, stairs down and portal. The wall types are defined in the [[Eye of the Beholder Maze Format]] files. Each block in the MAZ file has wall information for all 4 walls (north, east, south, west) from which the wall type is inferred - for each wall in the level.&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;margin:auto;&amp;quot;&lt;br /&gt;
| [[File:BRICK bg.png|frame|Backdrop from BRICK.VMP]]&lt;br /&gt;
| [[File:BRICK wall 1.png|frame|Wall Type 1 from BRICK.VMP]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Pseudo code for rendering the background:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   void drawBackground(bool xflip)&lt;br /&gt;
   {&lt;br /&gt;
      for (int y=0; y&amp;lt;15; y++)&lt;br /&gt;
      {&lt;br /&gt;
         for (int x=0; x&amp;lt;22; x++)&lt;br /&gt;
         {&lt;br /&gt;
            int tile;&lt;br /&gt;
 &lt;br /&gt;
            if (xflip)&lt;br /&gt;
               tile=vmp.backgroundTiles[21-x][y];&lt;br /&gt;
            else&lt;br /&gt;
               tile=vmp.backgroundTiles[x][y];&lt;br /&gt;
 &lt;br /&gt;
            /* xor with xflip to make block flip and background flip cancel each other out. */&lt;br /&gt;
            int blockFlip = (tile&amp;amp;0x4000)^flipX;&lt;br /&gt;
            int blockIndex= tile&amp;amp;0x3fff;&lt;br /&gt;
 &lt;br /&gt;
            if (blockFlip)&lt;br /&gt;
               drawBlockXFlip(x*8, y*8, vcn.blocks[blockIndex]);&lt;br /&gt;
            else&lt;br /&gt;
               drawBlock(x*8, y*8, vcn.blocks[blockIndex]);&lt;br /&gt;
         }&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To render the walls, we can use this structure:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
struct WallRenderData&lt;br /&gt;
{&lt;br /&gt;
   int baseOffset;&lt;br /&gt;
   int offsetInViewPort;&lt;br /&gt;
   int visibleWidthInBlocks;&lt;br /&gt;
   int visibleHeightInBlocks;&lt;br /&gt;
   int skipValue;&lt;br /&gt;
   int flipFlag;&lt;br /&gt;
} wallRenderData[25]= /* 25 different wall positions */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
   /* Side-Walls left back */&lt;br /&gt;
   {   3, 66, 5, 1, 2, 0},             /* A-east */&lt;br /&gt;
   {   1, 68, 5, 3, 0, 0},             /* B-east */&lt;br /&gt;
   {  -4, 74, 5, 1, 0, 0},             /* C-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side-Walls right back */&lt;br /&gt;
   {  -4, 79, 5, 1, 0, 1},              /* E-west */&lt;br /&gt;
   {   1, 83, 5, 3, 0, 1},              /* F-west */&lt;br /&gt;
   {   3, 87, 5, 1, 2, 1},              /* G-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls back */&lt;br /&gt;
   {  32, 66, 5, 2, 4, 0},              /* B-south */&lt;br /&gt;
   {  28, 68, 5, 6, 0, 0},              /* C-south */&lt;br /&gt;
   {  28, 74, 5, 6, 0, 0},              /* D-south */&lt;br /&gt;
   {  28, 80, 5, 6, 0, 0},              /* E-south */&lt;br /&gt;
   {  28, 86, 5, 2, 4, 0},              /* F-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle back left */&lt;br /&gt;
   {  16, 66, 6, 2, 0, 0},              /* H-east */&lt;br /&gt;
   { -20, 50, 8, 2, 0, 0},              /* I-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle back right */&lt;br /&gt;
   { -20, 58, 8, 2, 0, 1},              /* K-west */&lt;br /&gt;
   {  16, 86, 6, 2, 0, 1},              /* L-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls middle back */&lt;br /&gt;
   {  62, 44, 8, 6, 4, 0},              /* I-south */&lt;br /&gt;
   {  58, 50, 8,10, 0, 0},              /* J-south */&lt;br /&gt;
   {  58, 60, 8, 6, 4, 0},              /* K-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle front left */&lt;br /&gt;
   { -56, 25,12, 3, 0, 0},              /* M-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle front right */&lt;br /&gt;
   { -56, 38,12, 3, 0, 1},              /* O-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls middle front */&lt;br /&gt;
   { 151, 22,12, 3,13, 0},              /* M-south */&lt;br /&gt;
   { 138, 41,12, 3,13, 0},              /* O-south */&lt;br /&gt;
   { 138, 25,12,16, 0, 0},              /* N-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side wall front left */&lt;br /&gt;
   {-101,  0,15, 3, 0, 0},              /* P-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side wall front right */&lt;br /&gt;
   {-101, 19,15, 3, 0, 1},              /* Q-west */&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
baseOffset&lt;br /&gt;
Base offset into wallTiles[wallType-1]. This can be negative, but don&#039;t be deceived, this is just a base. The other values will add to this base making sure the wallTiles[wallType-1] array is accessed within bounds.&lt;br /&gt;
offsetInViewPort&lt;br /&gt;
Block index in the viewport where to start render.&lt;br /&gt;
xpos = offsetInViewPort%22;&lt;br /&gt;
ypos = offsetInViewPort/22;&lt;br /&gt;
visibleWidthInBlocks&lt;br /&gt;
How many visible blocks wide the wall is in the viewport.&lt;br /&gt;
visibleHeightInBlocks&lt;br /&gt;
How many visible blocks hight the wall is in the viewport.&lt;br /&gt;
skipValue&lt;br /&gt;
Number of tiles to the next row in the wallTiles[wallType-1] array.&lt;br /&gt;
flipFlag&lt;br /&gt;
1 if the wall is to be x-flipped in the viewport. Generally all right-walls are x-flipped.&lt;/div&gt;</summary>
		<author><name>Fergusdog</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12607</id>
		<title>Eye of the Beholder VMP Format</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12607"/>
		<updated>2025-10-31T03:31:46Z</updated>

		<summary type="html">&lt;p&gt;Fergusdog: /* Render the View Cone */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NeedMoreInfo}}&lt;br /&gt;
{{Map Infobox&lt;br /&gt;
 | Type = 2D tile-based&lt;br /&gt;
 | Layers = 5&lt;br /&gt;
 | Tile size = 8&amp;amp;times;8&lt;br /&gt;
 | Viewport = 176&amp;amp;times;120&lt;br /&gt;
 | Games = &lt;br /&gt;
   {{Game|Eye of the Beholder}}&lt;br /&gt;
   {{Game|Eye of the Beholder II: The Legend of Darkmoon}}&lt;br /&gt;
   {{Game|Lands of Lore: The Throne of Chaos}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file assembles the tiles from the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset.&lt;br /&gt;
It functions similarly to a map file in other video games, except that in [[Eye of the Beholder]] it does not represent a top-down layout. Instead, it defines the 3D view of the dungeon, often referred to as the &#039;&#039;view cone&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
In essence, the &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file contains a collection of indices that reference tile graphics within the &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. These indices are interpreted by the game’s main executable to construct the player&#039;s first-person view of the world.&lt;br /&gt;
&lt;br /&gt;
== File Format (PC version) ==&lt;br /&gt;
&lt;br /&gt;
In [[Lands of Lore: The Throne of Chaos]], &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; files are compressed , using the [[Westwood LCW]] compression (see [[Westwood CPS Format]]).&lt;br /&gt;
The uncompressed format is defined as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short index_count; &lt;br /&gt;
    unsigned short indices[index_count]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each entry in &amp;lt;code&amp;gt;indices&amp;lt;/code&amp;gt; represents an index that references a specific block in the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. For more details on the index entries, see the [[#Tile Index|Tile Index]] section below.&lt;br /&gt;
&lt;br /&gt;
== File Format (Amiga version) ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short header; &lt;br /&gt;
    unsigned short backdrop_tiles[22][15]; &lt;br /&gt;
    unsigned short padding[101]; &lt;br /&gt;
    unsigned short wall_tiles[wall_types_count][431]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;header&amp;lt;/code&amp;gt;&lt;br /&gt;
: {{TODO|Not yet fully investigated, but most likely specifies the number of wall types defined in the file.}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;backdrop_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the static backdrop (ceiling/floor) image..&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;padding&amp;lt;/code&amp;gt;&lt;br /&gt;
: Each wall type uses 431 tile indices. To match this count for the backdrop tiles, a padding of 101 empty indices is added (&amp;lt;code&amp;gt;22 × 15 + 101 = 431&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the wall graphics for each wall type.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_types_count&amp;lt;/code&amp;gt;&lt;br /&gt;
: Probably stored in the header, but can also be calculated as: &amp;lt;code&amp;gt;(filesize - 2) / (431 * 2) - 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tile Index ==&lt;br /&gt;
&lt;br /&gt;
Each index is represented as a 16-bit value using the following bit structure (most significant bits first):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct TileIndex { &lt;br /&gt;
    bool z-mask: 1; &lt;br /&gt;
    bool mirror_x: 1; &lt;br /&gt;
    unsigned tile_index: 14; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;z-mask&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;, only draw onto the tranparent pixels of the tile(s) below. In effect, acts as a mask for z-order, so the drawn tile appears behind the tile being drawn over. {{TODO|Need to confirm, expand?}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;mirror_x&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; flip the tile horizontally. Used to draw the right walls, for example.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;tile_index&amp;lt;/code&amp;gt;&lt;br /&gt;
: A 14-bit index selecting a specific tile from the corresponding &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset (see [[Eye of the Beholder VCN Format]]).&lt;br /&gt;
&lt;br /&gt;
== Render the View Cone ==&lt;br /&gt;
&lt;br /&gt;
The 3D view in [[Eye of the Beholder]] covers an area of &#039;&#039;&#039;22 × 15 tiles&#039;&#039;&#039; and is composed of five layers — the backdrop (ceiling and floor) and four wall layers. The backdrop is rendered first and provides the ceiling and floor as a single combined image. The wall layers are then drawn on top, alternating between front-facing and side-facing walls to construct the 3D perspective.&lt;br /&gt;
&lt;br /&gt;
The following diagram illustrates the layout of the view cone:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
Layer 5 (backdrop)  &lt;br /&gt;
                                  ─────────────────────────────────&lt;br /&gt;
Layer 4                               A | B | C | D | E | F | G &lt;br /&gt;
                                         ─── ─── ─── ─── ─── &lt;br /&gt;
Layer 3                                   H | I | J | K | L &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 2                                       M | N | O &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 1 (closest)                             P | ^ | Q  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The caret (&amp;lt;code&amp;gt;^&amp;lt;/code&amp;gt;) represents the party’s position. Vertical bars (&amp;lt;code&amp;gt;|&amp;lt;/code&amp;gt;) and overbars (&amp;lt;code&amp;gt;───&amp;lt;/code&amp;gt;) in the diagram denote walls at various distances.&lt;br /&gt;
&lt;br /&gt;
In total, there are 25 distinct wall positions within the player’s field of vision. To render all walls correctly, the engine must read 17 map cells (A–Q) from the dungeon layout.&lt;br /&gt;
&lt;br /&gt;
The first 22 x 15 = &#039;&#039;&#039;330&#039;&#039;&#039; tile indices are used for the backdrop. The background is horizontally flipped when &amp;lt;code&amp;gt;party.x &amp;amp; party.y &amp;amp; party.direction == 1&amp;lt;/code&amp;gt;. In other words, certain movements or rotations from the current position cause the background to appear mirrored.&lt;br /&gt;
&lt;br /&gt;
What follows are &#039;&#039;&#039;431&#039;&#039;&#039; tile indices per wall type. [[Eye of the Beholder]] has 6 different wall types: solid wall type 1, solid wall type 2, door frame, stairs up, stairs down and portal. The wall types are defined in the [[Eye of the Beholder Maze Format]] files. Each block in the MAZ file has wall information for all 4 walls (north, east, south, west) from which the wall type is inferred - for each wall in the level.&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;margin:auto;&amp;quot;&lt;br /&gt;
| [[File:BRICK bg.png|frame|Backdrop from BRICK.VMP]]&lt;br /&gt;
| [[File:BRICK wall 1.png|frame|Wall Type 1 from BRICK.VMP]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
To render the walls, we can use this structure:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
struct WallRenderData&lt;br /&gt;
{&lt;br /&gt;
   int baseOffset;&lt;br /&gt;
   int offsetInViewPort;&lt;br /&gt;
   int visibleWidthInBlocks;&lt;br /&gt;
   int visibleHeightInBlocks;&lt;br /&gt;
   int skipValue;&lt;br /&gt;
   int flipFlag;&lt;br /&gt;
} wallRenderData[25]= /* 25 different wall positions */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
   /* Side-Walls left back */&lt;br /&gt;
   {   3, 66, 5, 1, 2, 0},             /* A-east */&lt;br /&gt;
   {   1, 68, 5, 3, 0, 0},             /* B-east */&lt;br /&gt;
   {  -4, 74, 5, 1, 0, 0},             /* C-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side-Walls right back */&lt;br /&gt;
   {  -4, 79, 5, 1, 0, 1},              /* E-west */&lt;br /&gt;
   {   1, 83, 5, 3, 0, 1},              /* F-west */&lt;br /&gt;
   {   3, 87, 5, 1, 2, 1},              /* G-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls back */&lt;br /&gt;
   {  32, 66, 5, 2, 4, 0},              /* B-south */&lt;br /&gt;
   {  28, 68, 5, 6, 0, 0},              /* C-south */&lt;br /&gt;
   {  28, 74, 5, 6, 0, 0},              /* D-south */&lt;br /&gt;
   {  28, 80, 5, 6, 0, 0},              /* E-south */&lt;br /&gt;
   {  28, 86, 5, 2, 4, 0},              /* F-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle back left */&lt;br /&gt;
   {  16, 66, 6, 2, 0, 0},              /* H-east */&lt;br /&gt;
   { -20, 50, 8, 2, 0, 0},              /* I-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle back right */&lt;br /&gt;
   { -20, 58, 8, 2, 0, 1},              /* K-west */&lt;br /&gt;
   {  16, 86, 6, 2, 0, 1},              /* L-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls middle back */&lt;br /&gt;
   {  62, 44, 8, 6, 4, 0},              /* I-south */&lt;br /&gt;
   {  58, 50, 8,10, 0, 0},              /* J-south */&lt;br /&gt;
   {  58, 60, 8, 6, 4, 0},              /* K-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle front left */&lt;br /&gt;
   { -56, 25,12, 3, 0, 0},              /* M-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle front right */&lt;br /&gt;
   { -56, 38,12, 3, 0, 1},              /* O-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls middle front */&lt;br /&gt;
   { 151, 22,12, 3,13, 0},              /* M-south */&lt;br /&gt;
   { 138, 41,12, 3,13, 0},              /* O-south */&lt;br /&gt;
   { 138, 25,12,16, 0, 0},              /* N-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side wall front left */&lt;br /&gt;
   {-101,  0,15, 3, 0, 0},              /* P-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side wall front right */&lt;br /&gt;
   {-101, 19,15, 3, 0, 1},              /* Q-west */&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
baseOffset&lt;br /&gt;
Base offset into wallTiles[wallType-1]. This can be negative, but don&#039;t be deceived, this is just a base. The other values will add to this base making sure the wallTiles[wallType-1] array is accessed within bounds.&lt;br /&gt;
offsetInViewPort&lt;br /&gt;
Block index in the viewport where to start render.&lt;br /&gt;
xpos = offsetInViewPort%22;&lt;br /&gt;
ypos = offsetInViewPort/22;&lt;br /&gt;
visibleWidthInBlocks&lt;br /&gt;
How many visible blocks wide the wall is in the viewport.&lt;br /&gt;
visibleHeightInBlocks&lt;br /&gt;
How many visible blocks hight the wall is in the viewport.&lt;br /&gt;
skipValue&lt;br /&gt;
Number of tiles to the next row in the wallTiles[wallType-1] array.&lt;br /&gt;
flipFlag&lt;br /&gt;
1 if the wall is to be x-flipped in the viewport. Generally all right-walls are x-flipped.&lt;/div&gt;</summary>
		<author><name>Fergusdog</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12606</id>
		<title>Eye of the Beholder VMP Format</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12606"/>
		<updated>2025-10-31T03:30:16Z</updated>

		<summary type="html">&lt;p&gt;Fergusdog: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NeedMoreInfo}}&lt;br /&gt;
{{Map Infobox&lt;br /&gt;
 | Type = 2D tile-based&lt;br /&gt;
 | Layers = 5&lt;br /&gt;
 | Tile size = 8&amp;amp;times;8&lt;br /&gt;
 | Viewport = 176&amp;amp;times;120&lt;br /&gt;
 | Games = &lt;br /&gt;
   {{Game|Eye of the Beholder}}&lt;br /&gt;
   {{Game|Eye of the Beholder II: The Legend of Darkmoon}}&lt;br /&gt;
   {{Game|Lands of Lore: The Throne of Chaos}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file assembles the tiles from the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset.&lt;br /&gt;
It functions similarly to a map file in other video games, except that in [[Eye of the Beholder]] it does not represent a top-down layout. Instead, it defines the 3D view of the dungeon, often referred to as the &#039;&#039;view cone&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
In essence, the &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file contains a collection of indices that reference tile graphics within the &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. These indices are interpreted by the game’s main executable to construct the player&#039;s first-person view of the world.&lt;br /&gt;
&lt;br /&gt;
== File Format (PC version) ==&lt;br /&gt;
&lt;br /&gt;
In [[Lands of Lore: The Throne of Chaos]], &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; files are compressed , using the [[Westwood LCW]] compression (see [[Westwood CPS Format]]).&lt;br /&gt;
The uncompressed format is defined as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short index_count; &lt;br /&gt;
    unsigned short indices[index_count]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each entry in &amp;lt;code&amp;gt;indices&amp;lt;/code&amp;gt; represents an index that references a specific block in the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. For more details on the index entries, see the [[#Tile Index|Tile Index]] section below.&lt;br /&gt;
&lt;br /&gt;
== File Format (Amiga version) ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short header; &lt;br /&gt;
    unsigned short backdrop_tiles[22][15]; &lt;br /&gt;
    unsigned short padding[101]; &lt;br /&gt;
    unsigned short wall_tiles[wall_types_count][431]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;header&amp;lt;/code&amp;gt;&lt;br /&gt;
: {{TODO|Not yet fully investigated, but most likely specifies the number of wall types defined in the file.}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;backdrop_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the static backdrop (ceiling/floor) image..&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;padding&amp;lt;/code&amp;gt;&lt;br /&gt;
: Each wall type uses 431 tile indices. To match this count for the backdrop tiles, a padding of 101 empty indices is added (&amp;lt;code&amp;gt;22 × 15 + 101 = 431&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the wall graphics for each wall type.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_types_count&amp;lt;/code&amp;gt;&lt;br /&gt;
: Probably stored in the header, but can also be calculated as: &amp;lt;code&amp;gt;(filesize - 2) / (431 * 2) - 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tile Index ==&lt;br /&gt;
&lt;br /&gt;
Each index is represented as a 16-bit value using the following bit structure (most significant bits first):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct TileIndex { &lt;br /&gt;
    bool z-mask: 1; &lt;br /&gt;
    bool mirror_x: 1; &lt;br /&gt;
    unsigned tile_index: 14; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;z-mask&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;, only draw onto the tranparent pixels of the tile(s) below. In effect, acts as a mask for z-order, so the drawn tile appears behind the tile being drawn over. {{TODO|Need to confirm, expand?}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;mirror_x&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; flip the tile horizontally. Used to draw the right walls, for example.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;tile_index&amp;lt;/code&amp;gt;&lt;br /&gt;
: A 14-bit index selecting a specific tile from the corresponding &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset (see [[Eye of the Beholder VCN Format]]).&lt;br /&gt;
&lt;br /&gt;
== Render the View Cone ==&lt;br /&gt;
&lt;br /&gt;
The 3D view in [[Eye of the Beholder]] covers an area of &#039;&#039;&#039;22 × 15 tiles&#039;&#039;&#039; and is composed of five layers — the backdrop (ceiling and floor) and four wall layers. The backdrop is rendered first and provides the ceiling and floor as a single combined image. The wall layers are then drawn on top, alternating between front-facing and side-facing walls to construct the 3D perspective.&lt;br /&gt;
&lt;br /&gt;
The following diagram illustrates the layout of the view cone:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
Layer 5 (backdrop)  &lt;br /&gt;
                                  ─────────────────────────────────&lt;br /&gt;
Layer 4                               A | B | C | D | E | F | G &lt;br /&gt;
                                         ─── ─── ─── ─── ─── &lt;br /&gt;
Layer 3                                   H | I | J | K | L &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 2                                       M | N | O &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 1 (closest)                             P | ^ | Q  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The caret (&amp;lt;code&amp;gt;^&amp;lt;/code&amp;gt;) represents the party’s position. Vertical bars (&amp;lt;code&amp;gt;|&amp;lt;/code&amp;gt;) and overbars (&amp;lt;code&amp;gt;───&amp;lt;/code&amp;gt;) in the diagram denote walls at various distances.&lt;br /&gt;
&lt;br /&gt;
In total, there are 25 distinct wall positions within the player’s field of vision. To render all walls correctly, the engine must read 17 map cells (A–Q) from the dungeon layout.&lt;br /&gt;
&lt;br /&gt;
The first 22 x 15 = &#039;&#039;&#039;330&#039;&#039;&#039; tile indices are used for the backdrop. The background is horizontally flipped when &amp;lt;code&amp;gt;party.x &amp;amp; party.y &amp;amp; party.direction == 1&amp;lt;/code&amp;gt;. In other words, certain movements or rotations from the current position cause the background to appear mirrored.&lt;br /&gt;
&lt;br /&gt;
What follows are &#039;&#039;&#039;431&#039;&#039;&#039; tile indices per wall type. [[Eye of the Beholder]] has 6 different wall types: solid wall type 1, solid wall type 2, door frame, stairs up, stairs down and portal. The wall types are defined in the [[Eye of the Beholder Maze Format]] files. Each block in the MAZ file has wall information for all 4 walls (north, east, south, west) from which the wall type is inferred - for each wall in the level.&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;margin:auto;&amp;quot;&lt;br /&gt;
| [[File:BRICK bg.png|frame|Backdrop from BRICK.VMP]]&lt;br /&gt;
| [[File:BRICK wall 1.png|frame|Wall Type 1 from BRICK.VMP]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
To simplify rendering, the following structure can be used:&lt;br /&gt;
struct WallRenderData&lt;br /&gt;
{&lt;br /&gt;
   int baseOffset;&lt;br /&gt;
   int offsetInViewPort;&lt;br /&gt;
   int visibleWidthInBlocks;&lt;br /&gt;
   int visibleHeightInBlocks;&lt;br /&gt;
   int skipValue;&lt;br /&gt;
   int flipFlag;&lt;br /&gt;
} wallRenderData[25]= /* 25 different wall positions exists */&lt;br /&gt;
{&lt;br /&gt;
   /* Side-Walls left back */&lt;br /&gt;
   {   3, 66, 5, 1, 2, 0},             /* A-east */&lt;br /&gt;
   {   1, 68, 5, 3, 0, 0},             /* B-east */&lt;br /&gt;
   {  -4, 74, 5, 1, 0, 0},             /* C-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side-Walls right back */&lt;br /&gt;
   {  -4, 79, 5, 1, 0, 1},              /* E-west */&lt;br /&gt;
   {   1, 83, 5, 3, 0, 1},              /* F-west */&lt;br /&gt;
   {   3, 87, 5, 1, 2, 1},              /* G-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls back */&lt;br /&gt;
   {  32, 66, 5, 2, 4, 0},              /* B-south */&lt;br /&gt;
   {  28, 68, 5, 6, 0, 0},              /* C-south */&lt;br /&gt;
   {  28, 74, 5, 6, 0, 0},              /* D-south */&lt;br /&gt;
   {  28, 80, 5, 6, 0, 0},              /* E-south */&lt;br /&gt;
   {  28, 86, 5, 2, 4, 0},              /* F-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle back left */&lt;br /&gt;
   {  16, 66, 6, 2, 0, 0},              /* H-east */&lt;br /&gt;
   { -20, 50, 8, 2, 0, 0},              /* I-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle back right */&lt;br /&gt;
   { -20, 58, 8, 2, 0, 1},              /* K-west */&lt;br /&gt;
   {  16, 86, 6, 2, 0, 1},              /* L-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls middle back */&lt;br /&gt;
   {  62, 44, 8, 6, 4, 0},              /* I-south */&lt;br /&gt;
   {  58, 50, 8,10, 0, 0},              /* J-south */&lt;br /&gt;
   {  58, 60, 8, 6, 4, 0},              /* K-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle front left */&lt;br /&gt;
   { -56, 25,12, 3, 0, 0},              /* M-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side walls middle front right */&lt;br /&gt;
   { -56, 38,12, 3, 0, 1},              /* O-west */&lt;br /&gt;
 &lt;br /&gt;
   /* Frontwalls middle front */&lt;br /&gt;
   { 151, 22,12, 3,13, 0},              /* M-south */&lt;br /&gt;
   { 138, 41,12, 3,13, 0},              /* O-south */&lt;br /&gt;
   { 138, 25,12,16, 0, 0},              /* N-south */&lt;br /&gt;
 &lt;br /&gt;
   /* Side wall front left */&lt;br /&gt;
   {-101,  0,15, 3, 0, 0},              /* P-east */&lt;br /&gt;
 &lt;br /&gt;
   /* Side wall front right */&lt;br /&gt;
   {-101, 19,15, 3, 0, 1},              /* Q-west */&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
baseOffset&lt;br /&gt;
Base offset into wallTiles[wallType-1]. This can be negative, but don&#039;t be deceived, this is just a base. The other values will add to this base making sure the wallTiles[wallType-1] array is accessed within bounds.&lt;br /&gt;
offsetInViewPort&lt;br /&gt;
Block index in the viewport where to start render.&lt;br /&gt;
xpos = offsetInViewPort%22;&lt;br /&gt;
ypos = offsetInViewPort/22;&lt;br /&gt;
visibleWidthInBlocks&lt;br /&gt;
How many visible blocks wide the wall is in the viewport.&lt;br /&gt;
visibleHeightInBlocks&lt;br /&gt;
How many visible blocks hight the wall is in the viewport.&lt;br /&gt;
skipValue&lt;br /&gt;
Number of tiles to the next row in the wallTiles[wallType-1] array.&lt;br /&gt;
flipFlag&lt;br /&gt;
1 if the wall is to be x-flipped in the viewport. Generally all right-walls are x-flipped.&lt;/div&gt;</summary>
		<author><name>Fergusdog</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12605</id>
		<title>Eye of the Beholder VMP Format</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12605"/>
		<updated>2025-10-31T03:22:08Z</updated>

		<summary type="html">&lt;p&gt;Fergusdog: /* Render the View Cone */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NeedMoreInfo}}&lt;br /&gt;
{{Map Infobox&lt;br /&gt;
 | Type = 2D tile-based&lt;br /&gt;
 | Layers = 5&lt;br /&gt;
 | Tile size = 8&amp;amp;times;8&lt;br /&gt;
 | Viewport = 176&amp;amp;times;120&lt;br /&gt;
 | Games = &lt;br /&gt;
   {{Game|Eye of the Beholder}}&lt;br /&gt;
   {{Game|Eye of the Beholder II: The Legend of Darkmoon}}&lt;br /&gt;
   {{Game|Lands of Lore: The Throne of Chaos}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file assembles the tiles from the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset.&lt;br /&gt;
It functions similarly to a map file in other video games, except that in [[Eye of the Beholder]] it does not represent a top-down layout. Instead, it defines the 3D view of the dungeon, often referred to as the &#039;&#039;view cone&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
In essence, the &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file contains a collection of indices that reference tile graphics within the &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. These indices are interpreted by the game’s main executable to construct the player&#039;s first-person view of the world.&lt;br /&gt;
&lt;br /&gt;
== File Format (PC version) ==&lt;br /&gt;
&lt;br /&gt;
In [[Lands of Lore: The Throne of Chaos]], &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; files are compressed , using the [[Westwood LCW]] compression (see [[Westwood CPS Format]]).&lt;br /&gt;
The uncompressed format is defined as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short index_count; &lt;br /&gt;
    unsigned short indices[index_count]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each entry in &amp;lt;code&amp;gt;indices&amp;lt;/code&amp;gt; represents an index that references a specific block in the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. For more details on the index entries, see the [[#Tile Index|Tile Index]] section below.&lt;br /&gt;
&lt;br /&gt;
== File Format (Amiga version) ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short header; &lt;br /&gt;
    unsigned short backdrop_tiles[22][15]; &lt;br /&gt;
    unsigned short padding[101]; &lt;br /&gt;
    unsigned short wall_tiles[wall_types_count][431]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;header&amp;lt;/code&amp;gt;&lt;br /&gt;
: {{TODO|Not yet fully investigated, but most likely specifies the number of wall types defined in the file.}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;backdrop_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the static backdrop (ceiling/floor) image..&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;padding&amp;lt;/code&amp;gt;&lt;br /&gt;
: Each wall type uses 431 tile indices. To match this count for the backdrop tiles, a padding of 101 empty indices is added (&amp;lt;code&amp;gt;22 × 15 + 101 = 431&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the wall graphics for each wall type.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_types_count&amp;lt;/code&amp;gt;&lt;br /&gt;
: Probably stored in the header, but can also be calculated as: &amp;lt;code&amp;gt;(filesize - 2) / (431 * 2) - 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tile Index ==&lt;br /&gt;
&lt;br /&gt;
Each index is represented as a 16-bit value using the following bit structure (most significant bits first):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct TileIndex { &lt;br /&gt;
    bool z-mask: 1; &lt;br /&gt;
    bool mirror_x: 1; &lt;br /&gt;
    unsigned tile_index: 14; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;z-mask&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;, only draw onto the tranparent pixels of the tile(s) below. In effect, acts as a mask for z-order, so the drawn tile appears behind the tile being drawn over. {{TODO|Need to confirm, expand?}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;mirror_x&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; flip the tile horizontally. Used to draw the right walls, for example.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;tile_index&amp;lt;/code&amp;gt;&lt;br /&gt;
: A 14-bit index selecting a specific tile from the corresponding &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset (see [[Eye of the Beholder VCN Format]]).&lt;br /&gt;
&lt;br /&gt;
== Render the View Cone ==&lt;br /&gt;
&lt;br /&gt;
The 3D view in [[Eye of the Beholder]] covers an area of &#039;&#039;&#039;22 × 15 tiles&#039;&#039;&#039; and is composed of five layers — the backdrop (ceiling and floor) and four wall layers. The backdrop is rendered first and provides the ceiling and floor as a single combined image. The wall layers are then drawn on top, alternating between front-facing and side-facing walls to construct the 3D perspective.&lt;br /&gt;
&lt;br /&gt;
The following diagram illustrates the layout of the view cone:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
Layer 5 (backdrop)  &lt;br /&gt;
                                  ─────────────────────────────────&lt;br /&gt;
Layer 4                               A | B | C | D | E | F | G &lt;br /&gt;
                                         ─── ─── ─── ─── ─── &lt;br /&gt;
Layer 3                                   H | I | J | K | L &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 2                                       M | N | O &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 1 (closest)                             P | ^ | Q  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The caret (&amp;lt;code&amp;gt;^&amp;lt;/code&amp;gt;) represents the party’s position. Vertical bars (&amp;lt;code&amp;gt;|&amp;lt;/code&amp;gt;) and overbars (&amp;lt;code&amp;gt;───&amp;lt;/code&amp;gt;) in the diagram denote walls at various distances.&lt;br /&gt;
&lt;br /&gt;
In total, there are 25 distinct wall positions within the player’s field of vision. To render all walls correctly, the engine must read 17 map cells (A–Q) from the dungeon layout.&lt;br /&gt;
&lt;br /&gt;
The first 22 x 15 = &#039;&#039;&#039;330&#039;&#039;&#039; tile indices are used for the backdrop. The background is horizontally flipped when &amp;lt;code&amp;gt;party.x &amp;amp; party.y &amp;amp; party.direction == 1&amp;lt;/code&amp;gt;. In other words, certain movements or rotations from the current position cause the background to appear mirrored.&lt;br /&gt;
&lt;br /&gt;
What follows are &#039;&#039;&#039;431&#039;&#039;&#039; tile indices per wall type. [[Eye of the Beholder]] has 6 different wall types: solid wall type 1, solid wall type 2, door frame, stairs up, stairs down and portal. The wall types are defined in the [[Eye of the Beholder Maze Format]] files. Each block in the MAZ file has wall information for all 4 walls (north, east, south, west) from which the wall type is inferred - for each wall in the level.&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;margin:auto;&amp;quot;&lt;br /&gt;
| [[File:BRICK bg.png|frame|Backdrop from BRICK.VMP]]&lt;br /&gt;
| [[File:BRICK wall 1.png|frame|Wall Type 1 from BRICK.VMP]]&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Fergusdog</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12604</id>
		<title>Eye of the Beholder VMP Format</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12604"/>
		<updated>2025-10-31T03:19:17Z</updated>

		<summary type="html">&lt;p&gt;Fergusdog: /* Render the View Cone */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NeedMoreInfo}}&lt;br /&gt;
{{Map Infobox&lt;br /&gt;
 | Type = 2D tile-based&lt;br /&gt;
 | Layers = 5&lt;br /&gt;
 | Tile size = 8&amp;amp;times;8&lt;br /&gt;
 | Viewport = 176&amp;amp;times;120&lt;br /&gt;
 | Games = &lt;br /&gt;
   {{Game|Eye of the Beholder}}&lt;br /&gt;
   {{Game|Eye of the Beholder II: The Legend of Darkmoon}}&lt;br /&gt;
   {{Game|Lands of Lore: The Throne of Chaos}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file assembles the tiles from the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset.&lt;br /&gt;
It functions similarly to a map file in other video games, except that in [[Eye of the Beholder]] it does not represent a top-down layout. Instead, it defines the 3D view of the dungeon, often referred to as the &#039;&#039;view cone&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
In essence, the &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file contains a collection of indices that reference tile graphics within the &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. These indices are interpreted by the game’s main executable to construct the player&#039;s first-person view of the world.&lt;br /&gt;
&lt;br /&gt;
== File Format (PC version) ==&lt;br /&gt;
&lt;br /&gt;
In [[Lands of Lore: The Throne of Chaos]], &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; files are compressed , using the [[Westwood LCW]] compression (see [[Westwood CPS Format]]).&lt;br /&gt;
The uncompressed format is defined as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short index_count; &lt;br /&gt;
    unsigned short indices[index_count]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each entry in &amp;lt;code&amp;gt;indices&amp;lt;/code&amp;gt; represents an index that references a specific block in the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. For more details on the index entries, see the [[#Tile Index|Tile Index]] section below.&lt;br /&gt;
&lt;br /&gt;
== File Format (Amiga version) ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short header; &lt;br /&gt;
    unsigned short backdrop_tiles[22][15]; &lt;br /&gt;
    unsigned short padding[101]; &lt;br /&gt;
    unsigned short wall_tiles[wall_types_count][431]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;header&amp;lt;/code&amp;gt;&lt;br /&gt;
: {{TODO|Not yet fully investigated, but most likely specifies the number of wall types defined in the file.}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;backdrop_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the static backdrop (ceiling/floor) image..&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;padding&amp;lt;/code&amp;gt;&lt;br /&gt;
: Each wall type uses 431 tile indices. To match this count for the backdrop tiles, a padding of 101 empty indices is added (&amp;lt;code&amp;gt;22 × 15 + 101 = 431&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the wall graphics for each wall type.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_types_count&amp;lt;/code&amp;gt;&lt;br /&gt;
: Probably stored in the header, but can also be calculated as: &amp;lt;code&amp;gt;(filesize - 2) / (431 * 2) - 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tile Index ==&lt;br /&gt;
&lt;br /&gt;
Each index is represented as a 16-bit value using the following bit structure (most significant bits first):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct TileIndex { &lt;br /&gt;
    bool z-mask: 1; &lt;br /&gt;
    bool mirror_x: 1; &lt;br /&gt;
    unsigned tile_index: 14; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;z-mask&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;, only draw onto the tranparent pixels of the tile(s) below. In effect, acts as a mask for z-order, so the drawn tile appears behind the tile being drawn over. {{TODO|Need to confirm, expand?}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;mirror_x&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; flip the tile horizontally. Used to draw the right walls, for example.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;tile_index&amp;lt;/code&amp;gt;&lt;br /&gt;
: A 14-bit index selecting a specific tile from the corresponding &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset (see [[Eye of the Beholder VCN Format]]).&lt;br /&gt;
&lt;br /&gt;
== Render the View Cone ==&lt;br /&gt;
&lt;br /&gt;
The 3D view in [[Eye of the Beholder]] covers an area of &#039;&#039;&#039;22 × 15 tiles&#039;&#039;&#039; and is composed of five layers — the backdrop (ceiling and floor) and four wall layers. The backdrop is rendered first and provides the ceiling and floor as a single combined image. The wall layers are then drawn on top, alternating between front-facing and side-facing walls to construct the 3D perspective.&lt;br /&gt;
&lt;br /&gt;
The following diagram illustrates the layout of the view cone:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
Layer 5 (backdrop)  &lt;br /&gt;
                                  ─────────────────────────────────&lt;br /&gt;
Layer 4                               A | B | C | D | E | F | G &lt;br /&gt;
                                         ─── ─── ─── ─── ─── &lt;br /&gt;
Layer 3                                   H | I | J | K | L &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 2                                       M | N | O &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 1 (closest)                             P | ^ | Q  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The caret (&amp;lt;code&amp;gt;^&amp;lt;/code&amp;gt;) represents the party’s position. Vertical bars (&amp;lt;code&amp;gt;|&amp;lt;/code&amp;gt;) and overbars (&amp;lt;code&amp;gt;───&amp;lt;/code&amp;gt;) in the diagram denote walls at various distances.&lt;br /&gt;
&lt;br /&gt;
In total, there are 25 distinct wall positions within the player’s field of vision. To render all walls correctly, the engine must read 17 map cells (A–Q) from the dungeon layout.&lt;br /&gt;
&lt;br /&gt;
The first 22 x 15 = &#039;&#039;&#039;330&#039;&#039;&#039; tile indices are used for the backdrop. The background is horizontally flipped when &amp;lt;code&amp;gt;party.x &amp;amp; party.y &amp;amp; party.direction == 1&amp;lt;/code&amp;gt;. In other words, certain movements or rotations from the current position cause the background to appear mirrored.&lt;br /&gt;
&lt;br /&gt;
What follows are &#039;&#039;&#039;431&#039;&#039;&#039; tile indices per wall type. [[Eye of the Beholder]] has 6 different wall types: solid wall type 1, solid wall type 2, door frame, stairs up, stairs down, portal.&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;margin:auto;&amp;quot;&lt;br /&gt;
| [[File:BRICK bg.png|frame|Backdrop from BRICK.VMP]]&lt;br /&gt;
| [[File:BRICK wall 1.png|frame|Wall Type 1 from BRICK.VMP]]&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Fergusdog</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12603</id>
		<title>Eye of the Beholder VMP Format</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12603"/>
		<updated>2025-10-31T02:58:10Z</updated>

		<summary type="html">&lt;p&gt;Fergusdog: /* Render the View Cone */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NeedMoreInfo}}&lt;br /&gt;
{{Map Infobox&lt;br /&gt;
 | Type = 2D tile-based&lt;br /&gt;
 | Layers = 5&lt;br /&gt;
 | Tile size = 8&amp;amp;times;8&lt;br /&gt;
 | Viewport = 176&amp;amp;times;120&lt;br /&gt;
 | Games = &lt;br /&gt;
   {{Game|Eye of the Beholder}}&lt;br /&gt;
   {{Game|Eye of the Beholder II: The Legend of Darkmoon}}&lt;br /&gt;
   {{Game|Lands of Lore: The Throne of Chaos}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file assembles the tiles from the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset.&lt;br /&gt;
It functions similarly to a map file in other video games, except that in [[Eye of the Beholder]] it does not represent a top-down layout. Instead, it defines the 3D view of the dungeon, often referred to as the &#039;&#039;view cone&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
In essence, the &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file contains a collection of indices that reference tile graphics within the &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. These indices are interpreted by the game’s main executable to construct the player&#039;s first-person view of the world.&lt;br /&gt;
&lt;br /&gt;
== File Format (PC version) ==&lt;br /&gt;
&lt;br /&gt;
In [[Lands of Lore: The Throne of Chaos]], &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; files are compressed , using the [[Westwood LCW]] compression (see [[Westwood CPS Format]]).&lt;br /&gt;
The uncompressed format is defined as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short index_count; &lt;br /&gt;
    unsigned short indices[index_count]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each entry in &amp;lt;code&amp;gt;indices&amp;lt;/code&amp;gt; represents an index that references a specific block in the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. For more details on the index entries, see the [[#Tile Index|Tile Index]] section below.&lt;br /&gt;
&lt;br /&gt;
== File Format (Amiga version) ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short header; &lt;br /&gt;
    unsigned short backdrop_tiles[22][15]; &lt;br /&gt;
    unsigned short padding[101]; &lt;br /&gt;
    unsigned short wall_tiles[wall_types_count][431]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;header&amp;lt;/code&amp;gt;&lt;br /&gt;
: {{TODO|Not yet fully investigated, but most likely specifies the number of wall types defined in the file.}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;backdrop_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the static backdrop (ceiling/floor) image..&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;padding&amp;lt;/code&amp;gt;&lt;br /&gt;
: Each wall type uses 431 tile indices. To match this count for the backdrop tiles, a padding of 101 empty indices is added (&amp;lt;code&amp;gt;22 × 15 + 101 = 431&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the wall graphics for each wall type.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_types_count&amp;lt;/code&amp;gt;&lt;br /&gt;
: Probably stored in the header, but can also be calculated as: &amp;lt;code&amp;gt;(filesize - 2) / (431 * 2) - 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tile Index ==&lt;br /&gt;
&lt;br /&gt;
Each index is represented as a 16-bit value using the following bit structure (most significant bits first):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct TileIndex { &lt;br /&gt;
    bool z-mask: 1; &lt;br /&gt;
    bool mirror_x: 1; &lt;br /&gt;
    unsigned tile_index: 14; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;z-mask&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;, only draw onto the tranparent pixels of the tile(s) below. In effect, acts as a mask for z-order, so the drawn tile appears behind the tile being drawn over. {{TODO|Need to confirm, expand?}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;mirror_x&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; flip the tile horizontally. Used to draw the right walls, for example.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;tile_index&amp;lt;/code&amp;gt;&lt;br /&gt;
: A 14-bit index selecting a specific tile from the corresponding &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset (see [[Eye of the Beholder VCN Format]]).&lt;br /&gt;
&lt;br /&gt;
== Render the View Cone ==&lt;br /&gt;
&lt;br /&gt;
The 3D view in [[Eye of the Beholder]] covers an area of &#039;&#039;&#039;22 × 15 tiles&#039;&#039;&#039; and is composed of five layers — the backdrop (ceiling and floor) and four wall layers. The backdrop is rendered first and provides the ceiling and floor as a single combined image. The wall layers are then drawn on top, alternating between front-facing and side-facing walls to construct the 3D perspective.&lt;br /&gt;
&lt;br /&gt;
The following diagram illustrates the layout of the view cone:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
Layer 5 (backdrop)  &lt;br /&gt;
                                  ─────────────────────────────────&lt;br /&gt;
Layer 4                               A | B | C | D | E | F | G &lt;br /&gt;
                                         ─── ─── ─── ─── ─── &lt;br /&gt;
Layer 3                                   H | I | J | K | L &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 2                                       M | N | O &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 1 (closest)                             P | ^ | Q  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The caret (&amp;lt;code&amp;gt;^&amp;lt;/code&amp;gt;) represents the party’s position. Vertical bars (&amp;lt;code&amp;gt;|&amp;lt;/code&amp;gt;) and overbars (&amp;lt;code&amp;gt;───&amp;lt;/code&amp;gt;) in the diagram denote walls at various distances.&lt;br /&gt;
&lt;br /&gt;
In total, there are 25 distinct wall positions within the player’s field of vision. To render all walls correctly, the engine must read 17 map cells (A–Q) from the dungeon layout.&lt;br /&gt;
&lt;br /&gt;
The first 22 x 15 = &#039;&#039;&#039;330&#039;&#039;&#039; tile indices are used for the backdrop. The background is horizontally flipped when &amp;lt;code&amp;gt;party.x &amp;amp; party.y &amp;amp; party.direction == 1&amp;lt;/code&amp;gt;. In other words, certain movements or rotations from the current position cause the background to appear mirrored.&lt;br /&gt;
&lt;br /&gt;
What follows are &#039;&#039;&#039;431&#039;&#039;&#039; tile indices per wall type. [[Eye of the Beholder]] has 6 different wall types: solid wall type 1, solid wall type 2, door frame, stairs up, stairs down, teleporter wall.&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;margin:auto;&amp;quot;&lt;br /&gt;
| [[File:BRICK bg.png|frame|Backdrop from BRICK.VMP]]&lt;br /&gt;
| [[File:BRICK wall 1.png|frame|Wall Type 1 from BRICK.VMP]]&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Fergusdog</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12602</id>
		<title>Eye of the Beholder VMP Format</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12602"/>
		<updated>2025-10-31T02:57:34Z</updated>

		<summary type="html">&lt;p&gt;Fergusdog: /* Render the View Cone */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NeedMoreInfo}}&lt;br /&gt;
{{Map Infobox&lt;br /&gt;
 | Type = 2D tile-based&lt;br /&gt;
 | Layers = 5&lt;br /&gt;
 | Tile size = 8&amp;amp;times;8&lt;br /&gt;
 | Viewport = 176&amp;amp;times;120&lt;br /&gt;
 | Games = &lt;br /&gt;
   {{Game|Eye of the Beholder}}&lt;br /&gt;
   {{Game|Eye of the Beholder II: The Legend of Darkmoon}}&lt;br /&gt;
   {{Game|Lands of Lore: The Throne of Chaos}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file assembles the tiles from the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset.&lt;br /&gt;
It functions similarly to a map file in other video games, except that in [[Eye of the Beholder]] it does not represent a top-down layout. Instead, it defines the 3D view of the dungeon, often referred to as the &#039;&#039;view cone&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
In essence, the &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file contains a collection of indices that reference tile graphics within the &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. These indices are interpreted by the game’s main executable to construct the player&#039;s first-person view of the world.&lt;br /&gt;
&lt;br /&gt;
== File Format (PC version) ==&lt;br /&gt;
&lt;br /&gt;
In [[Lands of Lore: The Throne of Chaos]], &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; files are compressed , using the [[Westwood LCW]] compression (see [[Westwood CPS Format]]).&lt;br /&gt;
The uncompressed format is defined as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short index_count; &lt;br /&gt;
    unsigned short indices[index_count]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each entry in &amp;lt;code&amp;gt;indices&amp;lt;/code&amp;gt; represents an index that references a specific block in the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. For more details on the index entries, see the [[#Tile Index|Tile Index]] section below.&lt;br /&gt;
&lt;br /&gt;
== File Format (Amiga version) ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short header; &lt;br /&gt;
    unsigned short backdrop_tiles[22][15]; &lt;br /&gt;
    unsigned short padding[101]; &lt;br /&gt;
    unsigned short wall_tiles[wall_types_count][431]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;header&amp;lt;/code&amp;gt;&lt;br /&gt;
: {{TODO|Not yet fully investigated, but most likely specifies the number of wall types defined in the file.}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;backdrop_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the static backdrop (ceiling/floor) image..&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;padding&amp;lt;/code&amp;gt;&lt;br /&gt;
: Each wall type uses 431 tile indices. To match this count for the backdrop tiles, a padding of 101 empty indices is added (&amp;lt;code&amp;gt;22 × 15 + 101 = 431&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the wall graphics for each wall type.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_types_count&amp;lt;/code&amp;gt;&lt;br /&gt;
: Probably stored in the header, but can also be calculated as: &amp;lt;code&amp;gt;(filesize - 2) / (431 * 2) - 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tile Index ==&lt;br /&gt;
&lt;br /&gt;
Each index is represented as a 16-bit value using the following bit structure (most significant bits first):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct TileIndex { &lt;br /&gt;
    bool z-mask: 1; &lt;br /&gt;
    bool mirror_x: 1; &lt;br /&gt;
    unsigned tile_index: 14; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;z-mask&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;, only draw onto the tranparent pixels of the tile(s) below. In effect, acts as a mask for z-order, so the drawn tile appears behind the tile being drawn over. {{TODO|Need to confirm, expand?}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;mirror_x&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; flip the tile horizontally. Used to draw the right walls, for example.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;tile_index&amp;lt;/code&amp;gt;&lt;br /&gt;
: A 14-bit index selecting a specific tile from the corresponding &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset (see [[Eye of the Beholder VCN Format]]).&lt;br /&gt;
&lt;br /&gt;
== Render the View Cone ==&lt;br /&gt;
&lt;br /&gt;
The 3D view in [[Eye of the Beholder]] covers an area of &#039;&#039;&#039;22 × 15 tiles&#039;&#039;&#039; and is composed of five layers — the backdrop (ceiling and floor) and four wall layers. The backdrop is rendered first and provides the ceiling and floor as a single combined image. The wall layers are then drawn on top, alternating between front-facing and side-facing walls to construct the 3D perspective.&lt;br /&gt;
&lt;br /&gt;
The following diagram illustrates the layout of the view cone:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
Layer 5 (backdrop)  &lt;br /&gt;
                                  ─────────────────────────────────&lt;br /&gt;
Layer 4                               A | B | C | D | E | F | G &lt;br /&gt;
                                         ─── ─── ─── ─── ─── &lt;br /&gt;
Layer 3                                   H | I | J | K | L &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 2                                       M | N | O &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 1 (closest)                             P | ^ | Q  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The caret (&amp;lt;code&amp;gt;^&amp;lt;/code&amp;gt;) represents the party’s position. Vertical bars (&amp;lt;code&amp;gt;|&amp;lt;/code&amp;gt;) and overbars (&amp;lt;code&amp;gt;───&amp;lt;/code&amp;gt;) in the diagram denote walls at various distances.&lt;br /&gt;
&lt;br /&gt;
In total, there are 25 distinct wall positions within the player’s field of vision. To render all walls correctly, the engine must read 17 map cells (A–Q) from the dungeon layout.&lt;br /&gt;
&lt;br /&gt;
The first 22 x 15 = &#039;&#039;&#039;330&#039;&#039;&#039; tile indices are used for the backdrop. The background is horizontally flipped when &amp;lt;code&amp;gt;party.x &amp;amp; party.y &amp;amp; party.direction == 1&amp;lt;/code&amp;gt;. In other words, certain movements or rotations from the current position cause the background to appear mirrored.&lt;br /&gt;
&lt;br /&gt;
What follows are 431 tile indices per wall type. [[Eye of the Beholder]] has 6 different wall types: solid wall type 1, solid wall type 2, door frame, stairs up, stairs down, teleporter wall.&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;margin:auto;&amp;quot;&lt;br /&gt;
| [[File:BRICK bg.png|frame|Backdrop from BRICK.VMP]]&lt;br /&gt;
| [[File:BRICK wall 1.png|frame|Wall Type 1 from BRICK.VMP]]&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Fergusdog</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12601</id>
		<title>Eye of the Beholder VMP Format</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12601"/>
		<updated>2025-10-31T02:56:10Z</updated>

		<summary type="html">&lt;p&gt;Fergusdog: /* Render the View Cone */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NeedMoreInfo}}&lt;br /&gt;
{{Map Infobox&lt;br /&gt;
 | Type = 2D tile-based&lt;br /&gt;
 | Layers = 5&lt;br /&gt;
 | Tile size = 8&amp;amp;times;8&lt;br /&gt;
 | Viewport = 176&amp;amp;times;120&lt;br /&gt;
 | Games = &lt;br /&gt;
   {{Game|Eye of the Beholder}}&lt;br /&gt;
   {{Game|Eye of the Beholder II: The Legend of Darkmoon}}&lt;br /&gt;
   {{Game|Lands of Lore: The Throne of Chaos}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file assembles the tiles from the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset.&lt;br /&gt;
It functions similarly to a map file in other video games, except that in [[Eye of the Beholder]] it does not represent a top-down layout. Instead, it defines the 3D view of the dungeon, often referred to as the &#039;&#039;view cone&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
In essence, the &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file contains a collection of indices that reference tile graphics within the &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. These indices are interpreted by the game’s main executable to construct the player&#039;s first-person view of the world.&lt;br /&gt;
&lt;br /&gt;
== File Format (PC version) ==&lt;br /&gt;
&lt;br /&gt;
In [[Lands of Lore: The Throne of Chaos]], &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; files are compressed , using the [[Westwood LCW]] compression (see [[Westwood CPS Format]]).&lt;br /&gt;
The uncompressed format is defined as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short index_count; &lt;br /&gt;
    unsigned short indices[index_count]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each entry in &amp;lt;code&amp;gt;indices&amp;lt;/code&amp;gt; represents an index that references a specific block in the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. For more details on the index entries, see the [[#Tile Index|Tile Index]] section below.&lt;br /&gt;
&lt;br /&gt;
== File Format (Amiga version) ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short header; &lt;br /&gt;
    unsigned short backdrop_tiles[22][15]; &lt;br /&gt;
    unsigned short padding[101]; &lt;br /&gt;
    unsigned short wall_tiles[wall_types_count][431]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;header&amp;lt;/code&amp;gt;&lt;br /&gt;
: {{TODO|Not yet fully investigated, but most likely specifies the number of wall types defined in the file.}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;backdrop_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the static backdrop (ceiling/floor) image..&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;padding&amp;lt;/code&amp;gt;&lt;br /&gt;
: Each wall type uses 431 tile indices. To match this count for the backdrop tiles, a padding of 101 empty indices is added (&amp;lt;code&amp;gt;22 × 15 + 101 = 431&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the wall graphics for each wall type.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_types_count&amp;lt;/code&amp;gt;&lt;br /&gt;
: Probably stored in the header, but can also be calculated as: &amp;lt;code&amp;gt;(filesize - 2) / (431 * 2) - 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tile Index ==&lt;br /&gt;
&lt;br /&gt;
Each index is represented as a 16-bit value using the following bit structure (most significant bits first):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct TileIndex { &lt;br /&gt;
    bool z-mask: 1; &lt;br /&gt;
    bool mirror_x: 1; &lt;br /&gt;
    unsigned tile_index: 14; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;z-mask&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;, only draw onto the tranparent pixels of the tile(s) below. In effect, acts as a mask for z-order, so the drawn tile appears behind the tile being drawn over. {{TODO|Need to confirm, expand?}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;mirror_x&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; flip the tile horizontally. Used to draw the right walls, for example.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;tile_index&amp;lt;/code&amp;gt;&lt;br /&gt;
: A 14-bit index selecting a specific tile from the corresponding &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset (see [[Eye of the Beholder VCN Format]]).&lt;br /&gt;
&lt;br /&gt;
== Render the View Cone ==&lt;br /&gt;
&lt;br /&gt;
The 3D view in [[Eye of the Beholder]] covers an area of &#039;&#039;&#039;22 × 15 tiles&#039;&#039;&#039; and is composed of five layers — the backdrop (ceiling and floor) and four wall layers. The backdrop is rendered first and provides the ceiling and floor as a single combined image. The wall layers are then drawn on top, alternating between front-facing and side-facing walls to construct the 3D perspective.&lt;br /&gt;
&lt;br /&gt;
The following diagram illustrates the layout of the view cone:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
Layer 5 (backdrop)  &lt;br /&gt;
                                  ─────────────────────────────────&lt;br /&gt;
Layer 4                               A | B | C | D | E | F | G &lt;br /&gt;
                                         ─── ─── ─── ─── ─── &lt;br /&gt;
Layer 3                                   H | I | J | K | L &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 2                                       M | N | O &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 1 (closest)                             P | ^ | Q  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The caret (&amp;lt;code&amp;gt;^&amp;lt;/code&amp;gt;) represents the party’s position. Vertical bars (&amp;lt;code&amp;gt;|&amp;lt;/code&amp;gt;) and overbars (&amp;lt;code&amp;gt;───&amp;lt;/code&amp;gt;) in the diagram denote walls at various distances.&lt;br /&gt;
&lt;br /&gt;
In total, there are 25 distinct wall positions within the player’s field of vision. To render all walls correctly, the engine must read 17 map cells (A–Q) from the dungeon layout.&lt;br /&gt;
&lt;br /&gt;
The first 22 x 15 = &#039;&#039;&#039;330&#039;&#039;&#039; tile indices are used for the backdrop. The background is horizontally flipped when &amp;lt;code&amp;gt;party.x &amp;amp; party.y &amp;amp; party.direction == 1&amp;lt;/code&amp;gt;. In other words, certain movements or rotations from the current position cause the background to appear mirrored.&lt;br /&gt;
&lt;br /&gt;
What follows are 431 tile indices per wall type. [[Eye of the Beholder]] has 6 different wall types.&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;margin:auto;&amp;quot;&lt;br /&gt;
| [[File:BRICK bg.png|frame|Backdrop from BRICK.VMP]]&lt;br /&gt;
| [[File:BRICK wall 1.png|frame|Wall Type 1 from BRICK.VMP]]&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Fergusdog</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12600</id>
		<title>Eye of the Beholder VMP Format</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12600"/>
		<updated>2025-10-31T02:53:23Z</updated>

		<summary type="html">&lt;p&gt;Fergusdog: /* Render the View Cone */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NeedMoreInfo}}&lt;br /&gt;
{{Map Infobox&lt;br /&gt;
 | Type = 2D tile-based&lt;br /&gt;
 | Layers = 5&lt;br /&gt;
 | Tile size = 8&amp;amp;times;8&lt;br /&gt;
 | Viewport = 176&amp;amp;times;120&lt;br /&gt;
 | Games = &lt;br /&gt;
   {{Game|Eye of the Beholder}}&lt;br /&gt;
   {{Game|Eye of the Beholder II: The Legend of Darkmoon}}&lt;br /&gt;
   {{Game|Lands of Lore: The Throne of Chaos}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file assembles the tiles from the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset.&lt;br /&gt;
It functions similarly to a map file in other video games, except that in [[Eye of the Beholder]] it does not represent a top-down layout. Instead, it defines the 3D view of the dungeon, often referred to as the &#039;&#039;view cone&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
In essence, the &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file contains a collection of indices that reference tile graphics within the &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. These indices are interpreted by the game’s main executable to construct the player&#039;s first-person view of the world.&lt;br /&gt;
&lt;br /&gt;
== File Format (PC version) ==&lt;br /&gt;
&lt;br /&gt;
In [[Lands of Lore: The Throne of Chaos]], &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; files are compressed , using the [[Westwood LCW]] compression (see [[Westwood CPS Format]]).&lt;br /&gt;
The uncompressed format is defined as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short index_count; &lt;br /&gt;
    unsigned short indices[index_count]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each entry in &amp;lt;code&amp;gt;indices&amp;lt;/code&amp;gt; represents an index that references a specific block in the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. For more details on the index entries, see the [[#Tile Index|Tile Index]] section below.&lt;br /&gt;
&lt;br /&gt;
== File Format (Amiga version) ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short header; &lt;br /&gt;
    unsigned short backdrop_tiles[22][15]; &lt;br /&gt;
    unsigned short padding[101]; &lt;br /&gt;
    unsigned short wall_tiles[wall_types_count][431]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;header&amp;lt;/code&amp;gt;&lt;br /&gt;
: {{TODO|Not yet fully investigated, but most likely specifies the number of wall types defined in the file.}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;backdrop_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the static backdrop (ceiling/floor) image..&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;padding&amp;lt;/code&amp;gt;&lt;br /&gt;
: Each wall type uses 431 tile indices. To match this count for the backdrop tiles, a padding of 101 empty indices is added (&amp;lt;code&amp;gt;22 × 15 + 101 = 431&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the wall graphics for each wall type.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_types_count&amp;lt;/code&amp;gt;&lt;br /&gt;
: Probably stored in the header, but can also be calculated as: &amp;lt;code&amp;gt;(filesize - 2) / (431 * 2) - 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tile Index ==&lt;br /&gt;
&lt;br /&gt;
Each index is represented as a 16-bit value using the following bit structure (most significant bits first):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct TileIndex { &lt;br /&gt;
    bool z-mask: 1; &lt;br /&gt;
    bool mirror_x: 1; &lt;br /&gt;
    unsigned tile_index: 14; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;z-mask&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;, only draw onto the tranparent pixels of the tile(s) below. In effect, acts as a mask for z-order, so the drawn tile appears behind the tile being drawn over. {{TODO|Need to confirm, expand?}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;mirror_x&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; flip the tile horizontally. Used to draw the right walls, for example.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;tile_index&amp;lt;/code&amp;gt;&lt;br /&gt;
: A 14-bit index selecting a specific tile from the corresponding &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset (see [[Eye of the Beholder VCN Format]]).&lt;br /&gt;
&lt;br /&gt;
== Render the View Cone ==&lt;br /&gt;
&lt;br /&gt;
The 3D view in [[Eye of the Beholder]] covers an area of &#039;&#039;&#039;22 × 15 tiles&#039;&#039;&#039; and is composed of five layers — the backdrop (ceiling and floor) and four wall layers. The backdrop is rendered first and provides the ceiling and floor as a single combined image. The wall layers are then drawn on top, alternating between front-facing and side-facing walls to construct the 3D perspective.&lt;br /&gt;
&lt;br /&gt;
The following diagram illustrates the layout of the view cone:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
Layer 5 (backdrop)  &lt;br /&gt;
                                  ─────────────────────────────────&lt;br /&gt;
Layer 4                               A | B | C | D | E | F | G &lt;br /&gt;
                                         ─── ─── ─── ─── ─── &lt;br /&gt;
Layer 3                                   H | I | J | K | L &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 2                                       M | N | O &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 1 (closest)                             P | ^ | Q  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The caret (&amp;lt;code&amp;gt;^&amp;lt;/code&amp;gt;) represents the party’s position. Vertical bars (&amp;lt;code&amp;gt;|&amp;lt;/code&amp;gt;) and overbars (&amp;lt;code&amp;gt;───&amp;lt;/code&amp;gt;) in the diagram denote walls at various distances.&lt;br /&gt;
&lt;br /&gt;
In total, there are 25 distinct wall positions within the player’s field of vision. To render all walls correctly, the engine must read 17 map cells (A–Q) from the dungeon layout.&lt;br /&gt;
&lt;br /&gt;
The very first tile in the &#039;&#039;&#039;VCN&#039;&#039;&#039; tileset is a fully transparent tile. The following 22 x 15 = &#039;&#039;&#039;330&#039;&#039;&#039; tiles are used for the backdrop. The background is horizontally flipped when &amp;lt;code&amp;gt;party.x &amp;amp; party.y &amp;amp; party.direction == 1&amp;lt;/code&amp;gt;. In other words, certain movements or rotations from the current position cause the background to appear mirrored.&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;margin:auto;&amp;quot;&lt;br /&gt;
| [[File:BRICK bg.png|frame|Backdrop from BRICK.VMP]]&lt;br /&gt;
| [[File:BRICK wall 1.png|frame|Wall Type 1 from BRICK.VMP]]&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Fergusdog</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12599</id>
		<title>Eye of the Beholder VMP Format</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12599"/>
		<updated>2025-10-31T02:52:45Z</updated>

		<summary type="html">&lt;p&gt;Fergusdog: /* Render the View Cone */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NeedMoreInfo}}&lt;br /&gt;
{{Map Infobox&lt;br /&gt;
 | Type = 2D tile-based&lt;br /&gt;
 | Layers = 5&lt;br /&gt;
 | Tile size = 8&amp;amp;times;8&lt;br /&gt;
 | Viewport = 176&amp;amp;times;120&lt;br /&gt;
 | Games = &lt;br /&gt;
   {{Game|Eye of the Beholder}}&lt;br /&gt;
   {{Game|Eye of the Beholder II: The Legend of Darkmoon}}&lt;br /&gt;
   {{Game|Lands of Lore: The Throne of Chaos}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file assembles the tiles from the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset.&lt;br /&gt;
It functions similarly to a map file in other video games, except that in [[Eye of the Beholder]] it does not represent a top-down layout. Instead, it defines the 3D view of the dungeon, often referred to as the &#039;&#039;view cone&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
In essence, the &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file contains a collection of indices that reference tile graphics within the &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. These indices are interpreted by the game’s main executable to construct the player&#039;s first-person view of the world.&lt;br /&gt;
&lt;br /&gt;
== File Format (PC version) ==&lt;br /&gt;
&lt;br /&gt;
In [[Lands of Lore: The Throne of Chaos]], &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; files are compressed , using the [[Westwood LCW]] compression (see [[Westwood CPS Format]]).&lt;br /&gt;
The uncompressed format is defined as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short index_count; &lt;br /&gt;
    unsigned short indices[index_count]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each entry in &amp;lt;code&amp;gt;indices&amp;lt;/code&amp;gt; represents an index that references a specific block in the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. For more details on the index entries, see the [[#Tile Index|Tile Index]] section below.&lt;br /&gt;
&lt;br /&gt;
== File Format (Amiga version) ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short header; &lt;br /&gt;
    unsigned short backdrop_tiles[22][15]; &lt;br /&gt;
    unsigned short padding[101]; &lt;br /&gt;
    unsigned short wall_tiles[wall_types_count][431]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;header&amp;lt;/code&amp;gt;&lt;br /&gt;
: {{TODO|Not yet fully investigated, but most likely specifies the number of wall types defined in the file.}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;backdrop_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the static backdrop (ceiling/floor) image..&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;padding&amp;lt;/code&amp;gt;&lt;br /&gt;
: Each wall type uses 431 tile indices. To match this count for the backdrop tiles, a padding of 101 empty indices is added (&amp;lt;code&amp;gt;22 × 15 + 101 = 431&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the wall graphics for each wall type.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_types_count&amp;lt;/code&amp;gt;&lt;br /&gt;
: Probably stored in the header, but can also be calculated as: &amp;lt;code&amp;gt;(filesize - 2) / (431 * 2) - 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tile Index ==&lt;br /&gt;
&lt;br /&gt;
Each index is represented as a 16-bit value using the following bit structure (most significant bits first):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct TileIndex { &lt;br /&gt;
    bool z-mask: 1; &lt;br /&gt;
    bool mirror_x: 1; &lt;br /&gt;
    unsigned tile_index: 14; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;z-mask&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;, only draw onto the tranparent pixels of the tile(s) below. In effect, acts as a mask for z-order, so the drawn tile appears behind the tile being drawn over. {{TODO|Need to confirm, expand?}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;mirror_x&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; flip the tile horizontally. Used to draw the right walls, for example.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;tile_index&amp;lt;/code&amp;gt;&lt;br /&gt;
: A 14-bit index selecting a specific tile from the corresponding &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset (see [[Eye of the Beholder VCN Format]]).&lt;br /&gt;
&lt;br /&gt;
== Render the View Cone ==&lt;br /&gt;
&lt;br /&gt;
The 3D view in [[Eye of the Beholder]] covers an area of &#039;&#039;&#039;22 × 15 tiles&#039;&#039;&#039; and is composed of five layers — the backdrop (ceiling and floor) and four wall layers. The backdrop is rendered first and provides the ceiling and floor as a single combined image. The wall layers are then drawn on top, alternating between front-facing and side-facing walls to construct the 3D perspective.&lt;br /&gt;
&lt;br /&gt;
The following diagram illustrates the layout of the view cone:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
Layer 5 (backdrop)  &lt;br /&gt;
                                  ─────────────────────────────────&lt;br /&gt;
Layer 4                               A | B | C | D | E | F | G &lt;br /&gt;
                                         ─── ─── ─── ─── ─── &lt;br /&gt;
Layer 3                                   H | I | J | K | L &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 2                                       M | N | O &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 1 (closest)                             P | ^ | Q  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The caret (&amp;lt;code&amp;gt;^&amp;lt;/code&amp;gt;) represents the party’s position. Vertical bars (&amp;lt;code&amp;gt;|&amp;lt;/code&amp;gt;) and overbars (&amp;lt;code&amp;gt;───&amp;lt;/code&amp;gt;) in the diagram denote walls at various distances.&lt;br /&gt;
&lt;br /&gt;
In total, there are 25 distinct wall positions within the player’s field of vision. To render all walls correctly, the engine must read 17 map cells (A–Q) from the dungeon layout.&lt;br /&gt;
&lt;br /&gt;
The very first tile in the &#039;&#039;&#039;VCN&#039;&#039;&#039; tileset is a fully transparent tile. The following 22 x 15 = &#039;&#039;&#039;330&#039;&#039;&#039; tiles are used for the backdrop. The background is horizontally flipped when &amp;lt;code&amp;gt;party.x &amp;amp; party.y &amp;amp; party.direction == 1&amp;lt;/code&amp;gt;. In other words, certain movements or rotations from the current position cause the background to appear mirrored.&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;margin:auto;&amp;quot;&lt;br /&gt;
| [[File:BRICK bg.png|frame|Backdrop from BRICK.PAL]]&lt;br /&gt;
| [[File:BRICK wall 1.png|frame|Wall Type 1 from BRICK.PAL]]&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Fergusdog</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12598</id>
		<title>Eye of the Beholder VMP Format</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12598"/>
		<updated>2025-10-31T02:50:16Z</updated>

		<summary type="html">&lt;p&gt;Fergusdog: /* Render the View Cone */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NeedMoreInfo}}&lt;br /&gt;
{{Map Infobox&lt;br /&gt;
 | Type = 2D tile-based&lt;br /&gt;
 | Layers = 5&lt;br /&gt;
 | Tile size = 8&amp;amp;times;8&lt;br /&gt;
 | Viewport = 176&amp;amp;times;120&lt;br /&gt;
 | Games = &lt;br /&gt;
   {{Game|Eye of the Beholder}}&lt;br /&gt;
   {{Game|Eye of the Beholder II: The Legend of Darkmoon}}&lt;br /&gt;
   {{Game|Lands of Lore: The Throne of Chaos}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file assembles the tiles from the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset.&lt;br /&gt;
It functions similarly to a map file in other video games, except that in [[Eye of the Beholder]] it does not represent a top-down layout. Instead, it defines the 3D view of the dungeon, often referred to as the &#039;&#039;view cone&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
In essence, the &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file contains a collection of indices that reference tile graphics within the &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. These indices are interpreted by the game’s main executable to construct the player&#039;s first-person view of the world.&lt;br /&gt;
&lt;br /&gt;
== File Format (PC version) ==&lt;br /&gt;
&lt;br /&gt;
In [[Lands of Lore: The Throne of Chaos]], &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; files are compressed , using the [[Westwood LCW]] compression (see [[Westwood CPS Format]]).&lt;br /&gt;
The uncompressed format is defined as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short index_count; &lt;br /&gt;
    unsigned short indices[index_count]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each entry in &amp;lt;code&amp;gt;indices&amp;lt;/code&amp;gt; represents an index that references a specific block in the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. For more details on the index entries, see the [[#Tile Index|Tile Index]] section below.&lt;br /&gt;
&lt;br /&gt;
== File Format (Amiga version) ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short header; &lt;br /&gt;
    unsigned short backdrop_tiles[22][15]; &lt;br /&gt;
    unsigned short padding[101]; &lt;br /&gt;
    unsigned short wall_tiles[wall_types_count][431]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;header&amp;lt;/code&amp;gt;&lt;br /&gt;
: {{TODO|Not yet fully investigated, but most likely specifies the number of wall types defined in the file.}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;backdrop_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the static backdrop (ceiling/floor) image..&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;padding&amp;lt;/code&amp;gt;&lt;br /&gt;
: Each wall type uses 431 tile indices. To match this count for the backdrop tiles, a padding of 101 empty indices is added (&amp;lt;code&amp;gt;22 × 15 + 101 = 431&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the wall graphics for each wall type.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_types_count&amp;lt;/code&amp;gt;&lt;br /&gt;
: Probably stored in the header, but can also be calculated as: &amp;lt;code&amp;gt;(filesize - 2) / (431 * 2) - 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tile Index ==&lt;br /&gt;
&lt;br /&gt;
Each index is represented as a 16-bit value using the following bit structure (most significant bits first):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct TileIndex { &lt;br /&gt;
    bool z-mask: 1; &lt;br /&gt;
    bool mirror_x: 1; &lt;br /&gt;
    unsigned tile_index: 14; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;z-mask&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;, only draw onto the tranparent pixels of the tile(s) below. In effect, acts as a mask for z-order, so the drawn tile appears behind the tile being drawn over. {{TODO|Need to confirm, expand?}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;mirror_x&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; flip the tile horizontally. Used to draw the right walls, for example.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;tile_index&amp;lt;/code&amp;gt;&lt;br /&gt;
: A 14-bit index selecting a specific tile from the corresponding &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset (see [[Eye of the Beholder VCN Format]]).&lt;br /&gt;
&lt;br /&gt;
== Render the View Cone ==&lt;br /&gt;
&lt;br /&gt;
The 3D view in [[Eye of the Beholder]] covers an area of &#039;&#039;&#039;22 × 15 tiles&#039;&#039;&#039; and is composed of five layers — the backdrop (ceiling and floor) and four wall layers. The backdrop is rendered first and provides the ceiling and floor as a single combined image. The wall layers are then drawn on top, alternating between front-facing and side-facing walls to construct the 3D perspective.&lt;br /&gt;
&lt;br /&gt;
The following diagram illustrates the layout of the view cone:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
Layer 5 (backdrop)  &lt;br /&gt;
                                  ─────────────────────────────────&lt;br /&gt;
Layer 4                               A | B | C | D | E | F | G &lt;br /&gt;
                                         ─── ─── ─── ─── ─── &lt;br /&gt;
Layer 3                                   H | I | J | K | L &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 2                                       M | N | O &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 1 (closest)                             P | ^ | Q  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The caret (&amp;lt;code&amp;gt;^&amp;lt;/code&amp;gt;) represents the party’s position. Vertical bars (&amp;lt;code&amp;gt;|&amp;lt;/code&amp;gt;) and overbars (&amp;lt;code&amp;gt;───&amp;lt;/code&amp;gt;) in the diagram denote walls at various distances.&lt;br /&gt;
&lt;br /&gt;
In total, there are 25 distinct wall positions within the player’s field of vision. To render all walls correctly, the engine must read 17 map cells (A–Q) from the dungeon layout.&lt;br /&gt;
&lt;br /&gt;
The very first tile in the &#039;&#039;&#039;VCN&#039;&#039;&#039; tileset is a fully transparent tile. The following 22 x 15 = &#039;&#039;&#039;330&#039;&#039;&#039; tiles are used for the backdrop. The background is horizontally flipped when &amp;lt;code&amp;gt;party.x &amp;amp; party.y &amp;amp; party.direction == 1&amp;lt;/code&amp;gt;. In other words, certain movements or rotations from the current position cause the background to appear mirrored.&lt;br /&gt;
&lt;br /&gt;
[[File:BRICK bg.png|frame|center|Backdrop from BRICK.PAL]] [[File:BRICK wall 1.png|frame|center|Wall Type 1 from BRICK.PAL]]&lt;/div&gt;</summary>
		<author><name>Fergusdog</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12597</id>
		<title>Eye of the Beholder VMP Format</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12597"/>
		<updated>2025-10-31T02:47:04Z</updated>

		<summary type="html">&lt;p&gt;Fergusdog: /* Render the View Cone */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NeedMoreInfo}}&lt;br /&gt;
{{Map Infobox&lt;br /&gt;
 | Type = 2D tile-based&lt;br /&gt;
 | Layers = 5&lt;br /&gt;
 | Tile size = 8&amp;amp;times;8&lt;br /&gt;
 | Viewport = 176&amp;amp;times;120&lt;br /&gt;
 | Games = &lt;br /&gt;
   {{Game|Eye of the Beholder}}&lt;br /&gt;
   {{Game|Eye of the Beholder II: The Legend of Darkmoon}}&lt;br /&gt;
   {{Game|Lands of Lore: The Throne of Chaos}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file assembles the tiles from the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset.&lt;br /&gt;
It functions similarly to a map file in other video games, except that in [[Eye of the Beholder]] it does not represent a top-down layout. Instead, it defines the 3D view of the dungeon, often referred to as the &#039;&#039;view cone&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
In essence, the &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file contains a collection of indices that reference tile graphics within the &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. These indices are interpreted by the game’s main executable to construct the player&#039;s first-person view of the world.&lt;br /&gt;
&lt;br /&gt;
== File Format (PC version) ==&lt;br /&gt;
&lt;br /&gt;
In [[Lands of Lore: The Throne of Chaos]], &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; files are compressed , using the [[Westwood LCW]] compression (see [[Westwood CPS Format]]).&lt;br /&gt;
The uncompressed format is defined as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short index_count; &lt;br /&gt;
    unsigned short indices[index_count]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each entry in &amp;lt;code&amp;gt;indices&amp;lt;/code&amp;gt; represents an index that references a specific block in the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. For more details on the index entries, see the [[#Tile Index|Tile Index]] section below.&lt;br /&gt;
&lt;br /&gt;
== File Format (Amiga version) ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short header; &lt;br /&gt;
    unsigned short backdrop_tiles[22][15]; &lt;br /&gt;
    unsigned short padding[101]; &lt;br /&gt;
    unsigned short wall_tiles[wall_types_count][431]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;header&amp;lt;/code&amp;gt;&lt;br /&gt;
: {{TODO|Not yet fully investigated, but most likely specifies the number of wall types defined in the file.}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;backdrop_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the static backdrop (ceiling/floor) image..&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;padding&amp;lt;/code&amp;gt;&lt;br /&gt;
: Each wall type uses 431 tile indices. To match this count for the backdrop tiles, a padding of 101 empty indices is added (&amp;lt;code&amp;gt;22 × 15 + 101 = 431&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the wall graphics for each wall type.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_types_count&amp;lt;/code&amp;gt;&lt;br /&gt;
: Probably stored in the header, but can also be calculated as: &amp;lt;code&amp;gt;(filesize - 2) / (431 * 2) - 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tile Index ==&lt;br /&gt;
&lt;br /&gt;
Each index is represented as a 16-bit value using the following bit structure (most significant bits first):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct TileIndex { &lt;br /&gt;
    bool z-mask: 1; &lt;br /&gt;
    bool mirror_x: 1; &lt;br /&gt;
    unsigned tile_index: 14; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;z-mask&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;, only draw onto the tranparent pixels of the tile(s) below. In effect, acts as a mask for z-order, so the drawn tile appears behind the tile being drawn over. {{TODO|Need to confirm, expand?}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;mirror_x&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; flip the tile horizontally. Used to draw the right walls, for example.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;tile_index&amp;lt;/code&amp;gt;&lt;br /&gt;
: A 14-bit index selecting a specific tile from the corresponding &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset (see [[Eye of the Beholder VCN Format]]).&lt;br /&gt;
&lt;br /&gt;
== Render the View Cone ==&lt;br /&gt;
&lt;br /&gt;
The 3D view in [[Eye of the Beholder]] covers an area of &#039;&#039;&#039;22 × 15 tiles&#039;&#039;&#039; and is composed of five layers — the backdrop (ceiling and floor) and four wall layers. The backdrop is rendered first and provides the ceiling and floor as a single combined image. The wall layers are then drawn on top, alternating between front-facing and side-facing walls to construct the 3D perspective.&lt;br /&gt;
&lt;br /&gt;
The following diagram illustrates the layout of the view cone:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
Layer 5 (backdrop)  &lt;br /&gt;
                                  ─────────────────────────────────&lt;br /&gt;
Layer 4                               A | B | C | D | E | F | G &lt;br /&gt;
                                         ─── ─── ─── ─── ─── &lt;br /&gt;
Layer 3                                   H | I | J | K | L &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 2                                       M | N | O &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 1 (closest)                             P | ^ | Q  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The caret (&amp;lt;code&amp;gt;^&amp;lt;/code&amp;gt;) represents the party’s position. Vertical bars (&amp;lt;code&amp;gt;|&amp;lt;/code&amp;gt;) and overbars (&amp;lt;code&amp;gt;───&amp;lt;/code&amp;gt;) in the diagram denote walls at various distances.&lt;br /&gt;
&lt;br /&gt;
In total, there are 25 distinct wall positions within the player’s field of vision. To render all walls correctly, the engine must read 17 map cells (A–Q) from the dungeon layout.&lt;br /&gt;
&lt;br /&gt;
The very first tile in the &#039;&#039;&#039;VCN&#039;&#039;&#039; tileset is a fully transparent tile. The following 22 x 15 = &#039;&#039;&#039;330&#039;&#039;&#039; tiles are used for the backdrop. The background is horizontally flipped when &amp;lt;code&amp;gt;party.x &amp;amp; party.y &amp;amp; party.direction == 1&amp;lt;/code&amp;gt;. In other words, certain movements or rotations from the current position cause the background to appear mirrored.&lt;br /&gt;
&lt;br /&gt;
[[File:BRICK bg.png|frame|Backdrop from BRICK.PAL]] [[File:BRICK wall 1.png|frame|Wall Type 1 from BRICK.PAL]]&lt;/div&gt;</summary>
		<author><name>Fergusdog</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12596</id>
		<title>Eye of the Beholder VMP Format</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12596"/>
		<updated>2025-10-31T02:44:00Z</updated>

		<summary type="html">&lt;p&gt;Fergusdog: /* Render the View Cone */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NeedMoreInfo}}&lt;br /&gt;
{{Map Infobox&lt;br /&gt;
 | Type = 2D tile-based&lt;br /&gt;
 | Layers = 5&lt;br /&gt;
 | Tile size = 8&amp;amp;times;8&lt;br /&gt;
 | Viewport = 176&amp;amp;times;120&lt;br /&gt;
 | Games = &lt;br /&gt;
   {{Game|Eye of the Beholder}}&lt;br /&gt;
   {{Game|Eye of the Beholder II: The Legend of Darkmoon}}&lt;br /&gt;
   {{Game|Lands of Lore: The Throne of Chaos}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file assembles the tiles from the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset.&lt;br /&gt;
It functions similarly to a map file in other video games, except that in [[Eye of the Beholder]] it does not represent a top-down layout. Instead, it defines the 3D view of the dungeon, often referred to as the &#039;&#039;view cone&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
In essence, the &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file contains a collection of indices that reference tile graphics within the &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. These indices are interpreted by the game’s main executable to construct the player&#039;s first-person view of the world.&lt;br /&gt;
&lt;br /&gt;
== File Format (PC version) ==&lt;br /&gt;
&lt;br /&gt;
In [[Lands of Lore: The Throne of Chaos]], &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; files are compressed , using the [[Westwood LCW]] compression (see [[Westwood CPS Format]]).&lt;br /&gt;
The uncompressed format is defined as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short index_count; &lt;br /&gt;
    unsigned short indices[index_count]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each entry in &amp;lt;code&amp;gt;indices&amp;lt;/code&amp;gt; represents an index that references a specific block in the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. For more details on the index entries, see the [[#Tile Index|Tile Index]] section below.&lt;br /&gt;
&lt;br /&gt;
== File Format (Amiga version) ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short header; &lt;br /&gt;
    unsigned short backdrop_tiles[22][15]; &lt;br /&gt;
    unsigned short padding[101]; &lt;br /&gt;
    unsigned short wall_tiles[wall_types_count][431]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;header&amp;lt;/code&amp;gt;&lt;br /&gt;
: {{TODO|Not yet fully investigated, but most likely specifies the number of wall types defined in the file.}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;backdrop_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the static backdrop (ceiling/floor) image..&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;padding&amp;lt;/code&amp;gt;&lt;br /&gt;
: Each wall type uses 431 tile indices. To match this count for the backdrop tiles, a padding of 101 empty indices is added (&amp;lt;code&amp;gt;22 × 15 + 101 = 431&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the wall graphics for each wall type.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_types_count&amp;lt;/code&amp;gt;&lt;br /&gt;
: Probably stored in the header, but can also be calculated as: &amp;lt;code&amp;gt;(filesize - 2) / (431 * 2) - 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tile Index ==&lt;br /&gt;
&lt;br /&gt;
Each index is represented as a 16-bit value using the following bit structure (most significant bits first):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct TileIndex { &lt;br /&gt;
    bool z-mask: 1; &lt;br /&gt;
    bool mirror_x: 1; &lt;br /&gt;
    unsigned tile_index: 14; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;z-mask&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;, only draw onto the tranparent pixels of the tile(s) below. In effect, acts as a mask for z-order, so the drawn tile appears behind the tile being drawn over. {{TODO|Need to confirm, expand?}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;mirror_x&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; flip the tile horizontally. Used to draw the right walls, for example.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;tile_index&amp;lt;/code&amp;gt;&lt;br /&gt;
: A 14-bit index selecting a specific tile from the corresponding &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset (see [[Eye of the Beholder VCN Format]]).&lt;br /&gt;
&lt;br /&gt;
== Render the View Cone ==&lt;br /&gt;
&lt;br /&gt;
The 3D view in [[Eye of the Beholder]] covers an area of &#039;&#039;&#039;22 × 15 tiles&#039;&#039;&#039; and is composed of five layers — the backdrop (ceiling and floor) and four wall layers. The backdrop is rendered first and provides the ceiling and floor as a single combined image. The wall layers are then drawn on top, alternating between front-facing and side-facing walls to construct the 3D perspective.&lt;br /&gt;
&lt;br /&gt;
The following diagram illustrates the layout of the view cone:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
Layer 5 (backdrop)  &lt;br /&gt;
                                  ─────────────────────────────────&lt;br /&gt;
Layer 4                               A | B | C | D | E | F | G &lt;br /&gt;
                                         ─── ─── ─── ─── ─── &lt;br /&gt;
Layer 3                                   H | I | J | K | L &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 2                                       M | N | O &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 1 (closest)                             P | ^ | Q  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The caret (&amp;lt;code&amp;gt;^&amp;lt;/code&amp;gt;) represents the party’s position. Vertical bars (&amp;lt;code&amp;gt;|&amp;lt;/code&amp;gt;) and overbars (&amp;lt;code&amp;gt;───&amp;lt;/code&amp;gt;) in the diagram denote walls at various distances.&lt;br /&gt;
&lt;br /&gt;
In total, there are 25 distinct wall positions within the player’s field of vision. To render all walls correctly, the engine must read 17 map cells (A–Q) from the dungeon layout.&lt;br /&gt;
&lt;br /&gt;
The very first tile in the &#039;&#039;&#039;VCN&#039;&#039;&#039; tileset is a fully transparent tile. The following 22 x 15 = &#039;&#039;&#039;330&#039;&#039;&#039; tiles are used for the backdrop. The background is horizontally flipped when &amp;lt;code&amp;gt;party.x &amp;amp; party.y &amp;amp; party.direction == 1&amp;lt;/code&amp;gt;. In other words, certain movements or rotations from the current position cause the background to appear mirrored.&lt;br /&gt;
&lt;br /&gt;
[[File:BRICK bg.png]] [[File:BRICK wall 1.png]]&lt;/div&gt;</summary>
		<author><name>Fergusdog</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=File:BRICK_wall_1.png&amp;diff=12595</id>
		<title>File:BRICK wall 1.png</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=File:BRICK_wall_1.png&amp;diff=12595"/>
		<updated>2025-10-31T02:42:22Z</updated>

		<summary type="html">&lt;p&gt;Fergusdog: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Fergusdog</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12594</id>
		<title>Eye of the Beholder VMP Format</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12594"/>
		<updated>2025-10-31T02:42:02Z</updated>

		<summary type="html">&lt;p&gt;Fergusdog: /* Render the View Cone */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NeedMoreInfo}}&lt;br /&gt;
{{Map Infobox&lt;br /&gt;
 | Type = 2D tile-based&lt;br /&gt;
 | Layers = 5&lt;br /&gt;
 | Tile size = 8&amp;amp;times;8&lt;br /&gt;
 | Viewport = 176&amp;amp;times;120&lt;br /&gt;
 | Games = &lt;br /&gt;
   {{Game|Eye of the Beholder}}&lt;br /&gt;
   {{Game|Eye of the Beholder II: The Legend of Darkmoon}}&lt;br /&gt;
   {{Game|Lands of Lore: The Throne of Chaos}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file assembles the tiles from the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset.&lt;br /&gt;
It functions similarly to a map file in other video games, except that in [[Eye of the Beholder]] it does not represent a top-down layout. Instead, it defines the 3D view of the dungeon, often referred to as the &#039;&#039;view cone&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
In essence, the &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file contains a collection of indices that reference tile graphics within the &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. These indices are interpreted by the game’s main executable to construct the player&#039;s first-person view of the world.&lt;br /&gt;
&lt;br /&gt;
== File Format (PC version) ==&lt;br /&gt;
&lt;br /&gt;
In [[Lands of Lore: The Throne of Chaos]], &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; files are compressed , using the [[Westwood LCW]] compression (see [[Westwood CPS Format]]).&lt;br /&gt;
The uncompressed format is defined as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short index_count; &lt;br /&gt;
    unsigned short indices[index_count]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each entry in &amp;lt;code&amp;gt;indices&amp;lt;/code&amp;gt; represents an index that references a specific block in the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. For more details on the index entries, see the [[#Tile Index|Tile Index]] section below.&lt;br /&gt;
&lt;br /&gt;
== File Format (Amiga version) ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short header; &lt;br /&gt;
    unsigned short backdrop_tiles[22][15]; &lt;br /&gt;
    unsigned short padding[101]; &lt;br /&gt;
    unsigned short wall_tiles[wall_types_count][431]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;header&amp;lt;/code&amp;gt;&lt;br /&gt;
: {{TODO|Not yet fully investigated, but most likely specifies the number of wall types defined in the file.}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;backdrop_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the static backdrop (ceiling/floor) image..&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;padding&amp;lt;/code&amp;gt;&lt;br /&gt;
: Each wall type uses 431 tile indices. To match this count for the backdrop tiles, a padding of 101 empty indices is added (&amp;lt;code&amp;gt;22 × 15 + 101 = 431&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the wall graphics for each wall type.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_types_count&amp;lt;/code&amp;gt;&lt;br /&gt;
: Probably stored in the header, but can also be calculated as: &amp;lt;code&amp;gt;(filesize - 2) / (431 * 2) - 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tile Index ==&lt;br /&gt;
&lt;br /&gt;
Each index is represented as a 16-bit value using the following bit structure (most significant bits first):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct TileIndex { &lt;br /&gt;
    bool z-mask: 1; &lt;br /&gt;
    bool mirror_x: 1; &lt;br /&gt;
    unsigned tile_index: 14; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;z-mask&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;, only draw onto the tranparent pixels of the tile(s) below. In effect, acts as a mask for z-order, so the drawn tile appears behind the tile being drawn over. {{TODO|Need to confirm, expand?}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;mirror_x&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; flip the tile horizontally. Used to draw the right walls, for example.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;tile_index&amp;lt;/code&amp;gt;&lt;br /&gt;
: A 14-bit index selecting a specific tile from the corresponding &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset (see [[Eye of the Beholder VCN Format]]).&lt;br /&gt;
&lt;br /&gt;
== Render the View Cone ==&lt;br /&gt;
&lt;br /&gt;
The 3D view in [[Eye of the Beholder]] covers an area of &#039;&#039;&#039;22 × 15 tiles&#039;&#039;&#039; and is composed of five layers — the backdrop (ceiling and floor) and four wall layers. The backdrop is rendered first and provides the ceiling and floor as a single combined image. The wall layers are then drawn on top, alternating between front-facing and side-facing walls to construct the 3D perspective.&lt;br /&gt;
&lt;br /&gt;
The following diagram illustrates the layout of the view cone:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
Layer 5 (backdrop)  &lt;br /&gt;
                                  ─────────────────────────────────&lt;br /&gt;
Layer 4                               A | B | C | D | E | F | G &lt;br /&gt;
                                         ─── ─── ─── ─── ─── &lt;br /&gt;
Layer 3                                   H | I | J | K | L &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 2                                       M | N | O &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 1 (closest)                             P | ^ | Q  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The caret (&amp;lt;code&amp;gt;^&amp;lt;/code&amp;gt;) represents the party’s position. Vertical bars (&amp;lt;code&amp;gt;|&amp;lt;/code&amp;gt;) and overbars (&amp;lt;code&amp;gt;───&amp;lt;/code&amp;gt;) in the diagram denote walls at various distances.&lt;br /&gt;
&lt;br /&gt;
In total, there are 25 distinct wall positions within the player’s field of vision. To render all walls correctly, the engine must read 17 map cells (A–Q) from the dungeon layout.&lt;br /&gt;
&lt;br /&gt;
The very first tile in the &#039;&#039;&#039;VCN&#039;&#039;&#039; tileset is a fully transparent tile. The following 22 x 15 = &#039;&#039;&#039;330&#039;&#039;&#039; tiles are used for the backdrop. The background is horizontally flipped when &amp;lt;code&amp;gt;party.x &amp;amp; party.y &amp;amp; party.direction == 1&amp;lt;/code&amp;gt;. In other words, certain movements or rotations from the current position cause the background to appear mirrored.&lt;br /&gt;
&lt;br /&gt;
[[File:BRICK bg.png]]&lt;/div&gt;</summary>
		<author><name>Fergusdog</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=File:BRICK_bg.png&amp;diff=12593</id>
		<title>File:BRICK bg.png</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=File:BRICK_bg.png&amp;diff=12593"/>
		<updated>2025-10-31T02:40:36Z</updated>

		<summary type="html">&lt;p&gt;Fergusdog: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Fergusdog</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12592</id>
		<title>Eye of the Beholder VMP Format</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12592"/>
		<updated>2025-10-31T02:35:46Z</updated>

		<summary type="html">&lt;p&gt;Fergusdog: /* Render the View Cone */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NeedMoreInfo}}&lt;br /&gt;
{{Map Infobox&lt;br /&gt;
 | Type = 2D tile-based&lt;br /&gt;
 | Layers = 5&lt;br /&gt;
 | Tile size = 8&amp;amp;times;8&lt;br /&gt;
 | Viewport = 176&amp;amp;times;120&lt;br /&gt;
 | Games = &lt;br /&gt;
   {{Game|Eye of the Beholder}}&lt;br /&gt;
   {{Game|Eye of the Beholder II: The Legend of Darkmoon}}&lt;br /&gt;
   {{Game|Lands of Lore: The Throne of Chaos}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file assembles the tiles from the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset.&lt;br /&gt;
It functions similarly to a map file in other video games, except that in [[Eye of the Beholder]] it does not represent a top-down layout. Instead, it defines the 3D view of the dungeon, often referred to as the &#039;&#039;view cone&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
In essence, the &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file contains a collection of indices that reference tile graphics within the &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. These indices are interpreted by the game’s main executable to construct the player&#039;s first-person view of the world.&lt;br /&gt;
&lt;br /&gt;
== File Format (PC version) ==&lt;br /&gt;
&lt;br /&gt;
In [[Lands of Lore: The Throne of Chaos]], &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; files are compressed , using the [[Westwood LCW]] compression (see [[Westwood CPS Format]]).&lt;br /&gt;
The uncompressed format is defined as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short index_count; &lt;br /&gt;
    unsigned short indices[index_count]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each entry in &amp;lt;code&amp;gt;indices&amp;lt;/code&amp;gt; represents an index that references a specific block in the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. For more details on the index entries, see the [[#Tile Index|Tile Index]] section below.&lt;br /&gt;
&lt;br /&gt;
== File Format (Amiga version) ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short header; &lt;br /&gt;
    unsigned short backdrop_tiles[22][15]; &lt;br /&gt;
    unsigned short padding[101]; &lt;br /&gt;
    unsigned short wall_tiles[wall_types_count][431]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;header&amp;lt;/code&amp;gt;&lt;br /&gt;
: {{TODO|Not yet fully investigated, but most likely specifies the number of wall types defined in the file.}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;backdrop_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the static backdrop (ceiling/floor) image..&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;padding&amp;lt;/code&amp;gt;&lt;br /&gt;
: Each wall type uses 431 tile indices. To match this count for the backdrop tiles, a padding of 101 empty indices is added (&amp;lt;code&amp;gt;22 × 15 + 101 = 431&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the wall graphics for each wall type.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_types_count&amp;lt;/code&amp;gt;&lt;br /&gt;
: Probably stored in the header, but can also be calculated as: &amp;lt;code&amp;gt;(filesize - 2) / (431 * 2) - 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tile Index ==&lt;br /&gt;
&lt;br /&gt;
Each index is represented as a 16-bit value using the following bit structure (most significant bits first):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct TileIndex { &lt;br /&gt;
    bool z-mask: 1; &lt;br /&gt;
    bool mirror_x: 1; &lt;br /&gt;
    unsigned tile_index: 14; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;z-mask&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;, only draw onto the tranparent pixels of the tile(s) below. In effect, acts as a mask for z-order, so the drawn tile appears behind the tile being drawn over. {{TODO|Need to confirm, expand?}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;mirror_x&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; flip the tile horizontally. Used to draw the right walls, for example.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;tile_index&amp;lt;/code&amp;gt;&lt;br /&gt;
: A 14-bit index selecting a specific tile from the corresponding &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset (see [[Eye of the Beholder VCN Format]]).&lt;br /&gt;
&lt;br /&gt;
== Render the View Cone ==&lt;br /&gt;
&lt;br /&gt;
The 3D view in [[Eye of the Beholder]] covers an area of &#039;&#039;&#039;22 × 15 tiles&#039;&#039;&#039; and is composed of five layers — the backdrop (ceiling and floor) and four wall layers. The backdrop is rendered first and provides the ceiling and floor as a single combined image. The wall layers are then drawn on top, alternating between front-facing and side-facing walls to construct the 3D perspective.&lt;br /&gt;
&lt;br /&gt;
The following diagram illustrates the layout of the view cone:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
Layer 5 (backdrop)  &lt;br /&gt;
                                  ─────────────────────────────────&lt;br /&gt;
Layer 4                               A | B | C | D | E | F | G &lt;br /&gt;
                                         ─── ─── ─── ─── ─── &lt;br /&gt;
Layer 3                                   H | I | J | K | L &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 2                                       M | N | O &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 1 (closest)                             P | ^ | Q  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The caret (&amp;lt;code&amp;gt;^&amp;lt;/code&amp;gt;) represents the party’s position. Vertical bars (&amp;lt;code&amp;gt;|&amp;lt;/code&amp;gt;) and overbars (&amp;lt;code&amp;gt;───&amp;lt;/code&amp;gt;) in the diagram denote walls at various distances.&lt;br /&gt;
&lt;br /&gt;
In total, there are 25 distinct wall positions within the player’s field of vision. To render all walls correctly, the engine must read 17 map cells (A–Q) from the dungeon layout.&lt;br /&gt;
&lt;br /&gt;
The very first tile in the &#039;&#039;&#039;VCN&#039;&#039;&#039; tileset is a fully transparent tile. The following 22 x 15 = &#039;&#039;&#039;330&#039;&#039;&#039; tiles are used for the backdrop. The background is horizontally flipped when &amp;lt;code&amp;gt;party.x &amp;amp; party.y &amp;amp; party.direction == 1&amp;lt;/code&amp;gt;. In other words, certain movements or rotations from the current position cause the background to appear mirrored.&lt;/div&gt;</summary>
		<author><name>Fergusdog</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12591</id>
		<title>Eye of the Beholder VMP Format</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12591"/>
		<updated>2025-10-31T02:35:03Z</updated>

		<summary type="html">&lt;p&gt;Fergusdog: /* Render the View Cone */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NeedMoreInfo}}&lt;br /&gt;
{{Map Infobox&lt;br /&gt;
 | Type = 2D tile-based&lt;br /&gt;
 | Layers = 5&lt;br /&gt;
 | Tile size = 8&amp;amp;times;8&lt;br /&gt;
 | Viewport = 176&amp;amp;times;120&lt;br /&gt;
 | Games = &lt;br /&gt;
   {{Game|Eye of the Beholder}}&lt;br /&gt;
   {{Game|Eye of the Beholder II: The Legend of Darkmoon}}&lt;br /&gt;
   {{Game|Lands of Lore: The Throne of Chaos}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file assembles the tiles from the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset.&lt;br /&gt;
It functions similarly to a map file in other video games, except that in [[Eye of the Beholder]] it does not represent a top-down layout. Instead, it defines the 3D view of the dungeon, often referred to as the &#039;&#039;view cone&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
In essence, the &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file contains a collection of indices that reference tile graphics within the &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. These indices are interpreted by the game’s main executable to construct the player&#039;s first-person view of the world.&lt;br /&gt;
&lt;br /&gt;
== File Format (PC version) ==&lt;br /&gt;
&lt;br /&gt;
In [[Lands of Lore: The Throne of Chaos]], &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; files are compressed , using the [[Westwood LCW]] compression (see [[Westwood CPS Format]]).&lt;br /&gt;
The uncompressed format is defined as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short index_count; &lt;br /&gt;
    unsigned short indices[index_count]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each entry in &amp;lt;code&amp;gt;indices&amp;lt;/code&amp;gt; represents an index that references a specific block in the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. For more details on the index entries, see the [[#Tile Index|Tile Index]] section below.&lt;br /&gt;
&lt;br /&gt;
== File Format (Amiga version) ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short header; &lt;br /&gt;
    unsigned short backdrop_tiles[22][15]; &lt;br /&gt;
    unsigned short padding[101]; &lt;br /&gt;
    unsigned short wall_tiles[wall_types_count][431]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;header&amp;lt;/code&amp;gt;&lt;br /&gt;
: {{TODO|Not yet fully investigated, but most likely specifies the number of wall types defined in the file.}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;backdrop_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the static backdrop (ceiling/floor) image..&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;padding&amp;lt;/code&amp;gt;&lt;br /&gt;
: Each wall type uses 431 tile indices. To match this count for the backdrop tiles, a padding of 101 empty indices is added (&amp;lt;code&amp;gt;22 × 15 + 101 = 431&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the wall graphics for each wall type.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_types_count&amp;lt;/code&amp;gt;&lt;br /&gt;
: Probably stored in the header, but can also be calculated as: &amp;lt;code&amp;gt;(filesize - 2) / (431 * 2) - 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tile Index ==&lt;br /&gt;
&lt;br /&gt;
Each index is represented as a 16-bit value using the following bit structure (most significant bits first):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct TileIndex { &lt;br /&gt;
    bool z-mask: 1; &lt;br /&gt;
    bool mirror_x: 1; &lt;br /&gt;
    unsigned tile_index: 14; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;z-mask&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;, only draw onto the tranparent pixels of the tile(s) below. In effect, acts as a mask for z-order, so the drawn tile appears behind the tile being drawn over. {{TODO|Need to confirm, expand?}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;mirror_x&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; flip the tile horizontally. Used to draw the right walls, for example.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;tile_index&amp;lt;/code&amp;gt;&lt;br /&gt;
: A 14-bit index selecting a specific tile from the corresponding &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset (see [[Eye of the Beholder VCN Format]]).&lt;br /&gt;
&lt;br /&gt;
== Render the View Cone ==&lt;br /&gt;
&lt;br /&gt;
The 3D view in [[Eye of the Beholder]] covers an area of &#039;&#039;&#039;22 × 15 tiles&#039;&#039;&#039; and is composed of five layers — the backdrop (ceiling and floor) and four wall layers. The backdrop is rendered first and provides the ceiling and floor as a single combined image. The wall layers are then drawn on top, alternating between front-facing and side-facing walls to construct the 3D perspective.&lt;br /&gt;
&lt;br /&gt;
The following diagram illustrates the layout of the view cone:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
Layer 5 (backdrop)  &lt;br /&gt;
                                  ─────────────────────────────────&lt;br /&gt;
Layer 4                               A | B | C | D | E | F | G &lt;br /&gt;
                                         ─── ─── ─── ─── ─── &lt;br /&gt;
Layer 3                                   H | I | J | K | L &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 2                                       M | N | O &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 1 (closest)                             P | ^ | Q  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The caret (&amp;lt;code&amp;gt;^&amp;lt;/code&amp;gt;) represents the party’s position. Vertical bars (&amp;lt;code&amp;gt;|&amp;lt;/code&amp;gt;) and overbars (&amp;lt;code&amp;gt;───&amp;lt;/code&amp;gt;) in the diagram denote walls at various distances.&lt;br /&gt;
&lt;br /&gt;
In total, there are 25 distinct wall positions within the player’s field of vision. To render all walls correctly, the engine must read 17 map cells (A–Q) from the dungeon layout.&lt;br /&gt;
&lt;br /&gt;
The very first tile in the VCN tileset is a fully transparent tile. The following 22 x 15 = 330 tiles are for the backdrop.&lt;br /&gt;
The background is horizontally flipped when &amp;lt;code&amp;gt;party.x &amp;amp; party.y &amp;amp; party.direction == 1&amp;lt;/code&amp;gt;. In other words, certain movements or rotations from the current position cause the background to appear mirrored.&lt;/div&gt;</summary>
		<author><name>Fergusdog</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12590</id>
		<title>Eye of the Beholder VMP Format</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12590"/>
		<updated>2025-10-31T02:31:53Z</updated>

		<summary type="html">&lt;p&gt;Fergusdog: /* Render the View Cone */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NeedMoreInfo}}&lt;br /&gt;
{{Map Infobox&lt;br /&gt;
 | Type = 2D tile-based&lt;br /&gt;
 | Layers = 5&lt;br /&gt;
 | Tile size = 8&amp;amp;times;8&lt;br /&gt;
 | Viewport = 176&amp;amp;times;120&lt;br /&gt;
 | Games = &lt;br /&gt;
   {{Game|Eye of the Beholder}}&lt;br /&gt;
   {{Game|Eye of the Beholder II: The Legend of Darkmoon}}&lt;br /&gt;
   {{Game|Lands of Lore: The Throne of Chaos}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file assembles the tiles from the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset.&lt;br /&gt;
It functions similarly to a map file in other video games, except that in [[Eye of the Beholder]] it does not represent a top-down layout. Instead, it defines the 3D view of the dungeon, often referred to as the &#039;&#039;view cone&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
In essence, the &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file contains a collection of indices that reference tile graphics within the &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. These indices are interpreted by the game’s main executable to construct the player&#039;s first-person view of the world.&lt;br /&gt;
&lt;br /&gt;
== File Format (PC version) ==&lt;br /&gt;
&lt;br /&gt;
In [[Lands of Lore: The Throne of Chaos]], &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; files are compressed , using the [[Westwood LCW]] compression (see [[Westwood CPS Format]]).&lt;br /&gt;
The uncompressed format is defined as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short index_count; &lt;br /&gt;
    unsigned short indices[index_count]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each entry in &amp;lt;code&amp;gt;indices&amp;lt;/code&amp;gt; represents an index that references a specific block in the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. For more details on the index entries, see the [[#Tile Index|Tile Index]] section below.&lt;br /&gt;
&lt;br /&gt;
== File Format (Amiga version) ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short header; &lt;br /&gt;
    unsigned short backdrop_tiles[22][15]; &lt;br /&gt;
    unsigned short padding[101]; &lt;br /&gt;
    unsigned short wall_tiles[wall_types_count][431]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;header&amp;lt;/code&amp;gt;&lt;br /&gt;
: {{TODO|Not yet fully investigated, but most likely specifies the number of wall types defined in the file.}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;backdrop_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the static backdrop (ceiling/floor) image..&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;padding&amp;lt;/code&amp;gt;&lt;br /&gt;
: Each wall type uses 431 tile indices. To match this count for the backdrop tiles, a padding of 101 empty indices is added (&amp;lt;code&amp;gt;22 × 15 + 101 = 431&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the wall graphics for each wall type.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_types_count&amp;lt;/code&amp;gt;&lt;br /&gt;
: Probably stored in the header, but can also be calculated as: &amp;lt;code&amp;gt;(filesize - 2) / (431 * 2) - 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tile Index ==&lt;br /&gt;
&lt;br /&gt;
Each index is represented as a 16-bit value using the following bit structure (most significant bits first):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct TileIndex { &lt;br /&gt;
    bool z-mask: 1; &lt;br /&gt;
    bool mirror_x: 1; &lt;br /&gt;
    unsigned tile_index: 14; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;z-mask&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;, only draw onto the tranparent pixels of the tile(s) below. In effect, acts as a mask for z-order, so the drawn tile appears behind the tile being drawn over. {{TODO|Need to confirm, expand?}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;mirror_x&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; flip the tile horizontally. Used to draw the right walls, for example.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;tile_index&amp;lt;/code&amp;gt;&lt;br /&gt;
: A 14-bit index selecting a specific tile from the corresponding &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset (see [[Eye of the Beholder VCN Format]]).&lt;br /&gt;
&lt;br /&gt;
== Render the View Cone ==&lt;br /&gt;
&lt;br /&gt;
The 3D view in [[Eye of the Beholder]] covers an area of &#039;&#039;&#039;22 × 15 tiles&#039;&#039;&#039; and is composed of five layers — the backdrop (ceiling and floor) and four wall layers. The backdrop is rendered first and provides the ceiling and floor as a single combined image. The wall layers are then drawn on top, alternating between front-facing and side-facing walls to construct the 3D perspective.&lt;br /&gt;
&lt;br /&gt;
The following diagram illustrates the layout of the view cone:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
Layer 5 (backdrop)  &lt;br /&gt;
                                  ─────────────────────────────────&lt;br /&gt;
Layer 4                               A | B | C | D | E | F | G &lt;br /&gt;
                                         ─── ─── ─── ─── ─── &lt;br /&gt;
Layer 3                                   H | I | J | K | L &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 2                                       M | N | O &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 1 (closest)                             P | ^ | Q  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The caret (&amp;lt;code&amp;gt;^&amp;lt;/code&amp;gt;) represents the party’s position. Vertical bars (&amp;lt;code&amp;gt;|&amp;lt;/code&amp;gt;) and overbars (&amp;lt;code&amp;gt;───&amp;lt;/code&amp;gt;) in the diagram denote walls at various distances.&lt;br /&gt;
&lt;br /&gt;
In total, there are 25 distinct wall positions within the player’s field of vision. To render all walls correctly, the engine must read 17 map cells (A–Q) from the dungeon layout.&lt;br /&gt;
&lt;br /&gt;
The background is horizontally flipped when &amp;lt;code&amp;gt;party.x &amp;amp; party.y &amp;amp; party.direction == 1&amp;lt;/code&amp;gt;. In other words, certain movements or rotations from the current position cause the background to appear mirrored.&lt;/div&gt;</summary>
		<author><name>Fergusdog</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12589</id>
		<title>Eye of the Beholder VMP Format</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12589"/>
		<updated>2025-10-31T02:31:25Z</updated>

		<summary type="html">&lt;p&gt;Fergusdog: /* Render the View Cone */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NeedMoreInfo}}&lt;br /&gt;
{{Map Infobox&lt;br /&gt;
 | Type = 2D tile-based&lt;br /&gt;
 | Layers = 5&lt;br /&gt;
 | Tile size = 8&amp;amp;times;8&lt;br /&gt;
 | Viewport = 176&amp;amp;times;120&lt;br /&gt;
 | Games = &lt;br /&gt;
   {{Game|Eye of the Beholder}}&lt;br /&gt;
   {{Game|Eye of the Beholder II: The Legend of Darkmoon}}&lt;br /&gt;
   {{Game|Lands of Lore: The Throne of Chaos}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file assembles the tiles from the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset.&lt;br /&gt;
It functions similarly to a map file in other video games, except that in [[Eye of the Beholder]] it does not represent a top-down layout. Instead, it defines the 3D view of the dungeon, often referred to as the &#039;&#039;view cone&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
In essence, the &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file contains a collection of indices that reference tile graphics within the &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. These indices are interpreted by the game’s main executable to construct the player&#039;s first-person view of the world.&lt;br /&gt;
&lt;br /&gt;
== File Format (PC version) ==&lt;br /&gt;
&lt;br /&gt;
In [[Lands of Lore: The Throne of Chaos]], &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; files are compressed , using the [[Westwood LCW]] compression (see [[Westwood CPS Format]]).&lt;br /&gt;
The uncompressed format is defined as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short index_count; &lt;br /&gt;
    unsigned short indices[index_count]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each entry in &amp;lt;code&amp;gt;indices&amp;lt;/code&amp;gt; represents an index that references a specific block in the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. For more details on the index entries, see the [[#Tile Index|Tile Index]] section below.&lt;br /&gt;
&lt;br /&gt;
== File Format (Amiga version) ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short header; &lt;br /&gt;
    unsigned short backdrop_tiles[22][15]; &lt;br /&gt;
    unsigned short padding[101]; &lt;br /&gt;
    unsigned short wall_tiles[wall_types_count][431]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;header&amp;lt;/code&amp;gt;&lt;br /&gt;
: {{TODO|Not yet fully investigated, but most likely specifies the number of wall types defined in the file.}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;backdrop_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the static backdrop (ceiling/floor) image..&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;padding&amp;lt;/code&amp;gt;&lt;br /&gt;
: Each wall type uses 431 tile indices. To match this count for the backdrop tiles, a padding of 101 empty indices is added (&amp;lt;code&amp;gt;22 × 15 + 101 = 431&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the wall graphics for each wall type.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_types_count&amp;lt;/code&amp;gt;&lt;br /&gt;
: Probably stored in the header, but can also be calculated as: &amp;lt;code&amp;gt;(filesize - 2) / (431 * 2) - 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tile Index ==&lt;br /&gt;
&lt;br /&gt;
Each index is represented as a 16-bit value using the following bit structure (most significant bits first):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct TileIndex { &lt;br /&gt;
    bool z-mask: 1; &lt;br /&gt;
    bool mirror_x: 1; &lt;br /&gt;
    unsigned tile_index: 14; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;z-mask&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;, only draw onto the tranparent pixels of the tile(s) below. In effect, acts as a mask for z-order, so the drawn tile appears behind the tile being drawn over. {{TODO|Need to confirm, expand?}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;mirror_x&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; flip the tile horizontally. Used to draw the right walls, for example.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;tile_index&amp;lt;/code&amp;gt;&lt;br /&gt;
: A 14-bit index selecting a specific tile from the corresponding &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset (see [[Eye of the Beholder VCN Format]]).&lt;br /&gt;
&lt;br /&gt;
== Render the View Cone ==&lt;br /&gt;
&lt;br /&gt;
The 3D view in [[Eye of the Beholder]] covers an area of &#039;&#039;&#039;22 × 15 tiles&#039;&#039;&#039; and is composed of five layers — the backdrop (ceiling and floor) and four wall layers. The backdrop is rendered first and provides the ceiling and floor as a single combined image. The wall layers are then drawn on top, alternating between front-facing and side-facing walls to construct the 3D perspective.&lt;br /&gt;
&lt;br /&gt;
The following diagram illustrates the layout of the view cone:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
Layer 5 (backdrop)                ─────────────────────────────────&lt;br /&gt;
Layer 4                               A | B | C | D | E | F | G &lt;br /&gt;
                                         ─── ─── ─── ─── ─── &lt;br /&gt;
Layer 3                                   H | I | J | K | L &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 2                                       M | N | O &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 1 (closest)                             P | ^ | Q  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The caret (&amp;lt;code&amp;gt;^&amp;lt;/code&amp;gt;) represents the party’s position. Vertical bars (&amp;lt;code&amp;gt;|&amp;lt;/code&amp;gt;) and overbars (&amp;lt;code&amp;gt;───&amp;lt;/code&amp;gt;) in the diagram denote walls at various distances.&lt;br /&gt;
&lt;br /&gt;
In total, there are 25 distinct wall positions within the player’s field of vision. To render all walls correctly, the engine must read 17 map cells (A–Q) from the dungeon layout.&lt;br /&gt;
&lt;br /&gt;
The background is horizontally flipped when &amp;lt;code&amp;gt;party.x &amp;amp; party.y &amp;amp; party.direction == 1&amp;lt;/code&amp;gt;. In other words, certain movements or rotations from the current position cause the background to appear mirrored.&lt;/div&gt;</summary>
		<author><name>Fergusdog</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12588</id>
		<title>Eye of the Beholder VMP Format</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12588"/>
		<updated>2025-10-31T02:30:43Z</updated>

		<summary type="html">&lt;p&gt;Fergusdog: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NeedMoreInfo}}&lt;br /&gt;
{{Map Infobox&lt;br /&gt;
 | Type = 2D tile-based&lt;br /&gt;
 | Layers = 5&lt;br /&gt;
 | Tile size = 8&amp;amp;times;8&lt;br /&gt;
 | Viewport = 176&amp;amp;times;120&lt;br /&gt;
 | Games = &lt;br /&gt;
   {{Game|Eye of the Beholder}}&lt;br /&gt;
   {{Game|Eye of the Beholder II: The Legend of Darkmoon}}&lt;br /&gt;
   {{Game|Lands of Lore: The Throne of Chaos}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file assembles the tiles from the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset.&lt;br /&gt;
It functions similarly to a map file in other video games, except that in [[Eye of the Beholder]] it does not represent a top-down layout. Instead, it defines the 3D view of the dungeon, often referred to as the &#039;&#039;view cone&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
In essence, the &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file contains a collection of indices that reference tile graphics within the &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. These indices are interpreted by the game’s main executable to construct the player&#039;s first-person view of the world.&lt;br /&gt;
&lt;br /&gt;
== File Format (PC version) ==&lt;br /&gt;
&lt;br /&gt;
In [[Lands of Lore: The Throne of Chaos]], &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; files are compressed , using the [[Westwood LCW]] compression (see [[Westwood CPS Format]]).&lt;br /&gt;
The uncompressed format is defined as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short index_count; &lt;br /&gt;
    unsigned short indices[index_count]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each entry in &amp;lt;code&amp;gt;indices&amp;lt;/code&amp;gt; represents an index that references a specific block in the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. For more details on the index entries, see the [[#Tile Index|Tile Index]] section below.&lt;br /&gt;
&lt;br /&gt;
== File Format (Amiga version) ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short header; &lt;br /&gt;
    unsigned short backdrop_tiles[22][15]; &lt;br /&gt;
    unsigned short padding[101]; &lt;br /&gt;
    unsigned short wall_tiles[wall_types_count][431]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;header&amp;lt;/code&amp;gt;&lt;br /&gt;
: {{TODO|Not yet fully investigated, but most likely specifies the number of wall types defined in the file.}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;backdrop_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the static backdrop (ceiling/floor) image..&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;padding&amp;lt;/code&amp;gt;&lt;br /&gt;
: Each wall type uses 431 tile indices. To match this count for the backdrop tiles, a padding of 101 empty indices is added (&amp;lt;code&amp;gt;22 × 15 + 101 = 431&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the wall graphics for each wall type.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_types_count&amp;lt;/code&amp;gt;&lt;br /&gt;
: Probably stored in the header, but can also be calculated as: &amp;lt;code&amp;gt;(filesize - 2) / (431 * 2) - 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tile Index ==&lt;br /&gt;
&lt;br /&gt;
Each index is represented as a 16-bit value using the following bit structure (most significant bits first):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct TileIndex { &lt;br /&gt;
    bool z-mask: 1; &lt;br /&gt;
    bool mirror_x: 1; &lt;br /&gt;
    unsigned tile_index: 14; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;z-mask&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;, only draw onto the tranparent pixels of the tile(s) below. In effect, acts as a mask for z-order, so the drawn tile appears behind the tile being drawn over. {{TODO|Need to confirm, expand?}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;mirror_x&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; flip the tile horizontally. Used to draw the right walls, for example.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;tile_index&amp;lt;/code&amp;gt;&lt;br /&gt;
: A 14-bit index selecting a specific tile from the corresponding &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset (see [[Eye of the Beholder VCN Format]]).&lt;br /&gt;
&lt;br /&gt;
== Render the View Cone ==&lt;br /&gt;
&lt;br /&gt;
The 3D view in [[Eye of the Beholder]] covers an area of &#039;&#039;&#039;22 × 15 tiles&#039;&#039;&#039; and is composed of five layers — the backdrop (ceiling and floor) and five wall layers. The backdrop is rendered first and provides the ceiling and floor as a single combined image. The wall layers are then drawn on top, alternating between front-facing and side-facing walls to construct the 3D perspective.&lt;br /&gt;
&lt;br /&gt;
The following diagram illustrates the layout of the view cone:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
Layer 5 (backdrop)                ─────────────────────────────────&lt;br /&gt;
Layer 4                               A | B | C | D | E | F | G &lt;br /&gt;
                                         ─── ─── ─── ─── ─── &lt;br /&gt;
Layer 3                                   H | I | J | K | L &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 2                                       M | N | O &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 1 (closest)                             P | ^ | Q  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The caret (&amp;lt;code&amp;gt;^&amp;lt;/code&amp;gt;) represents the party’s position. Vertical bars (&amp;lt;code&amp;gt;|&amp;lt;/code&amp;gt;) and overbars (&amp;lt;code&amp;gt;───&amp;lt;/code&amp;gt;) in the diagram denote walls at various distances.&lt;br /&gt;
&lt;br /&gt;
In total, there are 25 distinct wall positions within the player’s field of vision. To render all walls correctly, the engine must read 17 map cells (A–Q) from the dungeon layout.&lt;br /&gt;
&lt;br /&gt;
The background is horizontally flipped when &amp;lt;code&amp;gt;party.x &amp;amp; party.y &amp;amp; party.direction == 1&amp;lt;/code&amp;gt;. In other words, certain movements or rotations from the current position cause the background to appear mirrored.&lt;/div&gt;</summary>
		<author><name>Fergusdog</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12587</id>
		<title>Eye of the Beholder VMP Format</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Eye_of_the_Beholder_VMP_Format&amp;diff=12587"/>
		<updated>2025-10-31T02:28:30Z</updated>

		<summary type="html">&lt;p&gt;Fergusdog: /* Render the View Cone */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NeedMoreInfo}}&lt;br /&gt;
{{Map Infobox&lt;br /&gt;
 | Type = 2D tile-based&lt;br /&gt;
 | Layers = 5&lt;br /&gt;
 | Tile size = 8&amp;amp;times;8&lt;br /&gt;
 | Viewport = 176&amp;amp;times;120&lt;br /&gt;
 | Games = &lt;br /&gt;
   {{Game|Eye of the Beholder}}&lt;br /&gt;
   {{Game|Eye of the Beholder II: The Legend of Darkmoon}}&lt;br /&gt;
   {{Game|Lands of Lore: The Throne of Chaos}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file assembles the tiles from the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset.&lt;br /&gt;
It functions similarly to a map file in other video games, except that in [[Eye of the Beholder]] it does not represent a top-down layout. Instead, it defines the 3D view of the dungeon, often referred to as the &#039;&#039;view cone&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
In essence, the &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; file contains a collection of indices that reference tile graphics within the &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. These indices are interpreted by the game’s main executable to construct the player&#039;s first-person view of the world.&lt;br /&gt;
&lt;br /&gt;
== File Format (PC version) ==&lt;br /&gt;
&lt;br /&gt;
In [[Lands of Lore: The Throne of Chaos]], &amp;lt;code&amp;gt;.VMP&amp;lt;/code&amp;gt; files are compressed , using the [[Westwood LCW]] compression (see [[Westwood CPS Format]]).&lt;br /&gt;
The uncompressed format is defined as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short index_count; &lt;br /&gt;
    unsigned short indices[index_count]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each entry in &amp;lt;code&amp;gt;indices&amp;lt;/code&amp;gt; represents an index that references a specific block in the associated &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; file. For more details on the index entries, see the [[#Tile Index|Tile Index]] section below.&lt;br /&gt;
&lt;br /&gt;
== File Format (Amiga version) ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct VMP { &lt;br /&gt;
    unsigned short header; &lt;br /&gt;
    unsigned short backdrop_tiles[22][15]; &lt;br /&gt;
    unsigned short padding[101]; &lt;br /&gt;
    unsigned short wall_tiles[wall_types_count][431]; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;header&amp;lt;/code&amp;gt;&lt;br /&gt;
: {{TODO|Not yet fully investigated, but most likely specifies the number of wall types defined in the file.}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;backdrop_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the static backdrop (ceiling/floor) image.&lt;br /&gt;
: The background is horizontally flipped when &amp;lt;code&amp;gt;party.x &amp;amp; party.y &amp;amp; party.direction == 1&amp;lt;/code&amp;gt;. In other words, certain movements or rotations from the current position cause the background to appear mirrored.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;padding&amp;lt;/code&amp;gt;&lt;br /&gt;
: Each wall type uses 431 tile indices. To match this count for the backdrop tiles, a padding of 101 empty indices is added (&amp;lt;code&amp;gt;22 × 15 + 101 = 431&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_tiles&amp;lt;/code&amp;gt;&lt;br /&gt;
: Tile indices defining the wall graphics for each wall type.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;wall_types_count&amp;lt;/code&amp;gt;&lt;br /&gt;
: Probably stored in the header, but can also be calculated as: &amp;lt;code&amp;gt;(filesize - 2) / (431 * 2) - 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tile Index ==&lt;br /&gt;
&lt;br /&gt;
Each index is represented as a 16-bit value using the following bit structure (most significant bits first):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; struct TileIndex { &lt;br /&gt;
    bool z-mask: 1; &lt;br /&gt;
    bool mirror_x: 1; &lt;br /&gt;
    unsigned tile_index: 14; &lt;br /&gt;
}; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;z-mask&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;, only draw onto the tranparent pixels of the tile(s) below. In effect, acts as a mask for z-order, so the drawn tile appears behind the tile being drawn over. {{TODO|Need to confirm, expand?}}&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;mirror_x&amp;lt;/code&amp;gt;&lt;br /&gt;
: When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; flip the tile horizontally. Used to draw the right walls, for example.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;tile_index&amp;lt;/code&amp;gt;&lt;br /&gt;
: A 14-bit index selecting a specific tile from the corresponding &amp;lt;code&amp;gt;.VCN&amp;lt;/code&amp;gt; tileset (see [[Eye of the Beholder VCN Format]]).&lt;br /&gt;
&lt;br /&gt;
== Render the View Cone ==&lt;br /&gt;
&lt;br /&gt;
The 3D view in [[Eye of the Beholder]] covers an area of &#039;&#039;&#039;22 × 15 tiles&#039;&#039;&#039; and is composed of five layers — the backdrop (ceiling and floor) and five wall layers. The backdrop is rendered first and provides the ceiling and floor as a single combined image. The wall layers are then drawn on top, alternating between front-facing and side-facing walls to construct the 3D perspective.&lt;br /&gt;
&lt;br /&gt;
The following diagram illustrates the layout of the view cone:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
Layer 5 (backdrop)                ─────────────────────────────────&lt;br /&gt;
Layer 4                               A | B | C | D | E | F | G &lt;br /&gt;
                                         ─── ─── ─── ─── ─── &lt;br /&gt;
Layer 3                                   H | I | J | K | L &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 2                                       M | N | O &lt;br /&gt;
                                             ─── ─── ─── &lt;br /&gt;
Layer 1 (closest)                             P | ^ | Q  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The caret (&amp;lt;code&amp;gt;^&amp;lt;/code&amp;gt;) represents the party’s position. Vertical bars (&amp;lt;code&amp;gt;|&amp;lt;/code&amp;gt;) and overbars (&amp;lt;code&amp;gt;───&amp;lt;/code&amp;gt;) in the diagram denote walls at various distances.&lt;br /&gt;
&lt;br /&gt;
In total, there are 25 distinct wall positions within the player’s field of vision. To render all walls correctly, the engine must read 17 map cells (A–Q) from the dungeon layout.&lt;/div&gt;</summary>
		<author><name>Fergusdog</name></author>
	</entry>
</feed>