<?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=The+Ultra-Mind</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=The+Ultra-Mind"/>
	<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/wiki/Special:Contributions/The_Ultra-Mind"/>
	<updated>2026-05-14T05:48:30Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.39.11</generator>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Talk:Ultima_II_Dungeon_Format&amp;diff=10705</id>
		<title>Talk:Ultima II Dungeon Format</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Talk:Ultima_II_Dungeon_Format&amp;diff=10705"/>
		<updated>2022-09-19T16:38:45Z</updated>

		<summary type="html">&lt;p&gt;The Ultra-Mind: Created page with &amp;quot;==What platform?== I&amp;#039;m new around here, but is it implied that this wiki only covers Microsoft platforms? This article seems to assume it&amp;#039;s understood that that this is only a...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==What platform?==&lt;br /&gt;
I&#039;m new around here, but is it implied that this wiki only covers Microsoft platforms? This article seems to assume it&#039;s understood that that this is only about MS-DOS and none of the other platforms, which may or may not (for all I know) function the same way as the MS-DOS version.[[User:The Ultra-Mind|The Ultra-Mind]] ([[User talk:The Ultra-Mind|talk]]) 16:38, 19 September 2022 (GMT)&lt;/div&gt;</summary>
		<author><name>The Ultra-Mind</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Ultima_II_Dungeon_Format&amp;diff=10704</id>
		<title>Ultima II Dungeon Format</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Ultima_II_Dungeon_Format&amp;diff=10704"/>
		<updated>2022-09-19T16:37:24Z</updated>

		<summary type="html">&lt;p&gt;The Ultra-Mind: Displaytitle, formatting, rewriting essays, including towers, adding C function&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{DISPLAYTITLE:&#039;&#039;Ultima II&#039;&#039; Dungeon Format}}&lt;br /&gt;
{{NeedMoreInfo}}&lt;br /&gt;
{{Map Infobox&lt;br /&gt;
 | Type = 2D tile-based&lt;br /&gt;
 | Layers = 1&lt;br /&gt;
 | Tile size = N/A&lt;br /&gt;
 | Viewport = N/A&lt;br /&gt;
 | Games = &lt;br /&gt;
   {{Game|Ultima II: Revenge of the Enchantress}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;[[Ultima II: Revenge of the Enchantress]]&#039;&#039;&#039;&#039;&#039; has several &#039;&#039;&#039;dungeon/tower&#039;&#039;&#039; maps. Dungeon maps are those map files whose names end in “5” while the tower maps’ end in “4”. This pattern applies to the unpatched version of the game as well as those patched by the [https://exodus.voyd.net/projects/ultima2/ &#039;&#039;Ultima&amp;amp;nbsp;2&#039;&#039; Upgrade patch]. All other maps are [[Ultima II Map Format|planets or towns]].&lt;br /&gt;
&lt;br /&gt;
== File Format ==&lt;br /&gt;
The map for each floor is a 256-byte chunk, starting from the beginning of the file for the first level (&amp;quot;level 0&amp;quot;) through to the last level. That makes the map files at least 4096 bytes, although they all are larger than that.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Level 0&amp;quot; is the closest level to the surface, meaning the bottom level for towers and top level for dungeons.&lt;br /&gt;
&lt;br /&gt;
Also note that some map files are corrupted. Look to the &#039;&#039;Ultima&amp;amp;nbsp;2&#039;&#039; Upgrade patch for fixes.&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Data type !! Name !! Description&lt;br /&gt;
|-&lt;br /&gt;
| [[UINT8]][4,096] || Tile Id || The tile id for each tile in the map.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Tile Data ==&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Tile Id !! Tile Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x00 || Floor&lt;br /&gt;
|-&lt;br /&gt;
| 0x10 || Ladder up&lt;br /&gt;
|-&lt;br /&gt;
| 0x20 || Ladder down&lt;br /&gt;
|-&lt;br /&gt;
| 0x30 || Ladder up/down&lt;br /&gt;
|-&lt;br /&gt;
| 0x40 || Chest or tri-lithium&lt;br /&gt;
|-&lt;br /&gt;
| 0x80 || Wall&lt;br /&gt;
|-&lt;br /&gt;
| 0xC0 || Door&lt;br /&gt;
|-&lt;br /&gt;
| 0xE0 || Secret door&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Source Code ==&lt;br /&gt;
===FreeBASIC===&lt;br /&gt;
==== Map Viewer ====&lt;br /&gt;
This FreeBASIC program displays all the dungeon/tower levels of the specified map.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;freebasic&amp;quot;&amp;gt;&lt;br /&gt;
&#039; Draws the maps of &#039;&#039;Ultima II&#039;&#039; dungeons/towers.&lt;br /&gt;
&lt;br /&gt;
&#039; Change the file path to the dungeon/tower you want.&lt;br /&gt;
&#039; File names ending with a “5” are dungeon maps and towers end in “4”.&lt;br /&gt;
Dim As String FilePath = &amp;quot;H:\DOS\Ultima2\mapx24&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Screen 13&lt;br /&gt;
&lt;br /&gt;
Dim As UByte Map&lt;br /&gt;
Dim As UByte X&lt;br /&gt;
Dim As UByte Y&lt;br /&gt;
Dim As UByte TileNumber&lt;br /&gt;
&lt;br /&gt;
&#039; Open the map file.&lt;br /&gt;
Open FilePath For Binary As #1&lt;br /&gt;
&lt;br /&gt;
Color 8&lt;br /&gt;
Locate 3, 23: Print Chr(177)&lt;br /&gt;
Color 6&lt;br /&gt;
Locate 7, 23: Print Chr(219)&lt;br /&gt;
Color 9&lt;br /&gt;
Locate 9, 23: Print Chr(219)&lt;br /&gt;
Color 10&lt;br /&gt;
Locate 11, 23: Print &amp;quot;$&amp;quot;&lt;br /&gt;
Color 14&lt;br /&gt;
Locate 13, 23: Print Chr(24)&lt;br /&gt;
Locate 15, 23: Print Chr(25)&lt;br /&gt;
Locate 17, 23: Print Chr(18)&lt;br /&gt;
&lt;br /&gt;
Color 15&lt;br /&gt;
Locate 3, 25: Print &amp;quot;- Wall&amp;quot;&lt;br /&gt;
Locate 5, 25: Print &amp;quot;- Floor&amp;quot;&lt;br /&gt;
Locate 7, 25: Print &amp;quot;- Door&amp;quot;&lt;br /&gt;
Locate 9, 25: Print &amp;quot;- Secret Door&amp;quot;&lt;br /&gt;
Locate 11, 25: Print &amp;quot;- Chest&amp;quot;&lt;br /&gt;
Locate 13, 25: Print &amp;quot;- Ladder Up&amp;quot;&lt;br /&gt;
Locate 15, 25: Print &amp;quot;- Ladder Down&amp;quot;&lt;br /&gt;
Locate 17, 25: Print &amp;quot;- Up/Down&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Line (15, 15)-(144, 144), 7, B&lt;br /&gt;
&lt;br /&gt;
&#039; Load the entire map, and draw the appropriate tiles.&lt;br /&gt;
For Map = 0 To 15&lt;br /&gt;
    For Y = 0 To 15&lt;br /&gt;
        For X = 0 To 15&lt;br /&gt;
            Get #1, , TileNumber&lt;br /&gt;
    &lt;br /&gt;
            Locate Y + 3, X + 3&lt;br /&gt;
            Select Case TileNumber&lt;br /&gt;
            Case &amp;amp;h00       &#039; Floor&lt;br /&gt;
                Color 0&lt;br /&gt;
                Print &amp;quot; &amp;quot;&lt;br /&gt;
            Case &amp;amp;h10       &#039; Ladder Up&lt;br /&gt;
                Color 14&lt;br /&gt;
                Print Chr(24)&lt;br /&gt;
            Case &amp;amp;h20       &#039; Ladder Down&lt;br /&gt;
                Color 14&lt;br /&gt;
                Print Chr(25)&lt;br /&gt;
            Case &amp;amp;h30       &#039; Ladder Up/Down&lt;br /&gt;
                Color 14&lt;br /&gt;
                Print Chr(18)&lt;br /&gt;
            Case &amp;amp;h40       &#039; Chest&lt;br /&gt;
                Color 10&lt;br /&gt;
                Print &amp;quot;$&amp;quot;&lt;br /&gt;
            Case &amp;amp;h80       &#039; Wall&lt;br /&gt;
                Color 8&lt;br /&gt;
                Print Chr(177)&lt;br /&gt;
            Case &amp;amp;hC0       &#039; Door&lt;br /&gt;
                Color 6&lt;br /&gt;
                Print Chr(219)&lt;br /&gt;
            Case &amp;amp;hE0       &#039; Secret Door&lt;br /&gt;
                Color 9&lt;br /&gt;
                Print Chr(219)&lt;br /&gt;
            End Select&lt;br /&gt;
        Next X&lt;br /&gt;
    Next Y&lt;br /&gt;
    &lt;br /&gt;
    Color 15&lt;br /&gt;
    Locate 23, 3: Print &amp;quot;Floor: &amp;quot; + Str(Map)&lt;br /&gt;
    &lt;br /&gt;
    Sleep&lt;br /&gt;
Next Map&lt;br /&gt;
&lt;br /&gt;
Close #1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Credits ====&lt;br /&gt;
&lt;br /&gt;
This map format was reverse engineered by [[User:TheAlmightyGuru|TheAlmightyGuru]]. If you find this information helpful in a project you&#039;re working on, please give credit where credit is due. (A link back to this wiki would be nice too!)&lt;br /&gt;
&lt;br /&gt;
===C===&lt;br /&gt;
The above FreeBASIC algorithm does not take into account the implied elements of dungeons/towers, such as the tri-lithium on the final level or half the outer walls. This C function will supply that.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#define MAP_CODE_FLOOR 0x00&lt;br /&gt;
#define MAP_CODE_UP 0x01&lt;br /&gt;
#define MAP_CODE_DOWN 0x02&lt;br /&gt;
#define MAP_CODE_UPDOWN 0x03&lt;br /&gt;
#define MAP_CODE_CHEST 0x04&lt;br /&gt;
#define MAP_CODE_WALL 0x05&lt;br /&gt;
#define MAP_CODE_DOOR 0x06&lt;br /&gt;
#define MAP_CODE_SECRET 0x07&lt;br /&gt;
#define MAP_CODE_TRILI 0x08&lt;br /&gt;
#define MAP_CODE_UNKNOWN 0x09&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
    Takes a 256-byte chunk from the map file, representing a level and returns a 17x17 map for the entire level,&lt;br /&gt;
    including parts that are not explicitly encoded (such as missing outer walls and tri-lithium).\nWhile the function&lt;br /&gt;
    does do sanity checking, it will sometimes process entire map files that are not for dungeons or towers, without&lt;br /&gt;
    returning an error.\nThe output can be rotated 90° (several times if you like).&lt;br /&gt;
    @param nRotation 0 = no rotation, 1 = 90° rotation, 2 = 180° rotation, 3 = -90° rotation.&lt;br /&gt;
    @param nMap The 0-based index for the level being mapped.&lt;br /&gt;
    @param code The level as taken raw from a map file.&lt;br /&gt;
    @param tiles The output, including all features implied by the engine (i.e. outer walls and tri-li)&lt;br /&gt;
    @return True if everything in \c code had dungeon/tower codes, false if characters not conforming to dungeon/tower&lt;br /&gt;
    codes.&lt;br /&gt;
*/&lt;br /&gt;
bool getMap(int nRotation, int nMap, unsigned char code[16][16], unsigned char tiles[17][17]) {&lt;br /&gt;
    bool bGood = true;&lt;br /&gt;
    const int inWidth = 16, inHeight = 16;&lt;br /&gt;
    const int outWidth = 17, outHeight = 17;&lt;br /&gt;
    memset(tiles, MAP_CODE_WALL, outWidth*outHeight);    //so we get the uncoded outer wall&lt;br /&gt;
&lt;br /&gt;
    for (int x = 0; x &amp;lt; inWidth &amp;amp;&amp;amp; bGood; x++) {&lt;br /&gt;
        for (int y = 0; y &amp;lt; inHeight &amp;amp;&amp;amp; bGood; y++) {&lt;br /&gt;
            unsigned char c = code[y][x];&lt;br /&gt;
            int nOutY = y, nOutX = x;&lt;br /&gt;
            for (int i = 0; i &amp;lt; nRotation; i++) {&lt;br /&gt;
                int nOriginalX = nOutX;&lt;br /&gt;
                nOutX = outHeight - 1 - nOutY;&lt;br /&gt;
                nOutY = nOriginalX;&lt;br /&gt;
            }&lt;br /&gt;
            unsigned char &amp;amp;o = tiles[nOutY][nOutX];&lt;br /&gt;
            switch (c) {&lt;br /&gt;
                case 0x00: o = MAP_CODE_FLOOR; break;&lt;br /&gt;
                case 0x10: o = MAP_CODE_UP; break;&lt;br /&gt;
                case 0x20: o = MAP_CODE_DOWN; break;&lt;br /&gt;
                case 0x30: o = MAP_CODE_UPDOWN; break;&lt;br /&gt;
                case 0x40: o = nMap &amp;lt; 15 ? MAP_CODE_CHEST : MAP_CODE_TRILI; break;&lt;br /&gt;
                case 0x80: o = MAP_CODE_WALL; break;&lt;br /&gt;
                case 0xC0: o = MAP_CODE_DOOR; break;&lt;br /&gt;
                case 0xE0: o = MAP_CODE_SECRET; break;&lt;br /&gt;
                default:&lt;br /&gt;
                    o = MAP_CODE_UNKNOWN;&lt;br /&gt;
                    bGood = false;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return bGood;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>The Ultra-Mind</name></author>
	</entry>
</feed>