Soul Blazer... I did some poking around with its map system a while back.
*rummages through disorganized notes*
The map pointers are part of the map metadata at 0x28200. The metadata is actually a small control code system that I haven't worked out completely, but the [10 01] command loads the map data. ([10 02] is probably for overlays/underlays, like the Grass Valley clouds or the animated background in Leo's Painting.)
A dump of 0x28200The map data pointed to by a [10 01] has a four-byte header: one byte for width, one for height, and two for the total number of bytes to decompress. The rest is the compressed data.
To decompress, treat the bytes as a stream of bits. There are two basic commands:
Literal
(1) <8 bits>
The next position in RAM is filled with <8 bits>.
Repeat
(0) <8 bits> <4 bits>
Copy (2 + <4 bits>) bytes from a previous address.
To get the previous address, add 0x11 to <8 bits> and modulo by 0x100.
Find the most recent address in RAM that ends with this value, and start copying from there.
C source code for decompressionSample output: Trial Room (the map from the first post)Sample output: Mountain of SoulsSample output: Magridd CastleThe current map is stored in RAM at 7E8000.
The map is divided into blocks of 256 bytes, corresponding to a 16x16 grid of 16x16-pixel map tiles.
These tiles are ordered left to right, and top to bottom.
The blocks themselves are also ordered this way.
ex. A 2x2-block map:
a..b e..f
. . . .
. . . .
c..d g..h
i..j m..n
. . . .
. . . .
k..l o..p
a = 7E8000
b = 7E800F
c = 7E80F0
d = 7E80FF
e = 7E8100
f = 7E810F
...
i = 7E8200
...
m = 7E8300
...
p = 7E83FF
I'm pretty sure the maximum size for a map is 0x1000 bytes, or 16 blocks - more than this and the game thinks the map has multiple "levels", which is how the lair-sealing resurrected areas work. The basic starting "town" map is described by the first 0x1000 bytes, and the next 0x1000 is an overlay with some houses and stuff, and so on.
Because of this, I'm not sure if "height" is the best description for the second byte of the map data header. For example, the Mountain of Souls and Magridd Castle (actually, all of the towns...) have a "height" of 0x10 (16 blocks), but the height of the map you can actually walk on is a mere four blocks.
Unrelated but interesting: Illusion of Gaia uses the same algorithm for map compression. It has different commands for
map metadata - [06] instead of [10], for example - but the actual compression is the same.
ASCII maps from Illusion of Gaia, produced with an early version of the decompressor - I think every byte in these maps was ORed by 0x20 to avoid control characters (such as newlines, tabs, and the dreaded 0x07 bell).