File formats
This page gives a description of the file formats that LSD: Dream Emulator uses. Common PSX formats like TIM, TMD, and TOD are not described as they are already well known.
LBD
LBD files in LSD: Dream Emulator are used to store chunks of levels.
Sometimes if a level has a large number of LBD files, they will be split into a number of subdirectories called 'N1', 'N2', and so on. I think this is something to do with efficient sector layout on the physical game disc.
Level chunks in LSD are tile-based, and each LBD contains data for a 20x20 tile chunk of the level. Each LBD file has its own tileset, in the form of a TMD file (3D model) with objects for each tile in the chunk's tileset. Notably, different LBD files within the same level do not share a tileset - the tileset is embedded separately into each file. This leads to a lot of repeats and isn't very storage-efficient, but was probably a lot more optimized for disc reads.
Tiles in the chunk are arranged in a regular grid, and each tile can have an 'extra tile' which is simply added in the same position as itself. Note that even extra tiles can have other extra tiles, so you could have long chains of different tiles all in the same place.
Chunks in a level are arranged in a more complicated fashion than tiles in a chunk. There are two ways level chunks can be arranged: vertically, and horizontally. The horizontal arrangement is used in most levels, with the vertical arrangement being used in only two: Bright Moon Cottage, and Moonlight Tower.
Horizontally arranged levels are tiled in a 'brick wall' pattern, like so:
Where '0' is M000.LBD, '1' is M001.LBD, and so on. The dimension of the levels varies, the diagram above is the arrangement for a level with a dimension of 3. The dimension of each level is listed below:
Level | Name | Dimension |
STG00 | Bright Moon Cottage | Vertical |
STG01 | Pit & Temple | 3 |
STG02 | Kyoto | 6 |
STG03 | The Natural World | 16 |
STG04 | Happytown | 6 |
STG05 | Violence District | 5 |
STG06 | Moonlight Tower | Vertical |
STG07 | Temple Dojo | 5 |
STG08 | Flesh Tunnels | 1 |
STG09 | Clockwork Machines | 1 |
STG10 | Long Hallway | 3 |
STG11 | Sun Faces Heave | 4 |
STG12 | Black Space | 4 |
STG13 | Monument Park | 2 |
Vertically tiled levels technically apply no tiling at all—LBD chunks are all placed in the same location. The vertical nature of these levels is actually applied in the tile data, with increasing TileHeight
values causing the LBD files to span multiple storeys.
There is nothing in the LBD file to distinguish between vertical and horizontal levels, and also nothing in the file that describes the dimension of the level. There's no data in any other game files that could represent this information, therefore this data must be baked into the game executable somewhere.
LBD files also can contain a number of entities. These entities are the 'interactive objects' of LSD. Entities are stored in an MML file, which is a container for multiple MOM files. A MOM file is an entity.
Entities are just a TMD 3D object file with a collection of TOD animation files.
If an LBD file does not contain any entities this will be stated in the header, and the data will simply not be in the file.
Format
LBDFile
LBDFile
Type | Name | Description |
| Header | The header of the file. |
| TileLayout | Length is equal to This is the grid of tiles in this chunk, starting at the bottom left and continuing rightwards along X. |
| ExtraTiles | Length is equal to This is the array of extra tile data that tiles index into when they have extra tiles. |
| Tiles | TMD file containing an object for each tile in this chunk's tileset. |
| MML | MML file containing the entities in this level. |
LBDHeader
LBDHeader
Type | Name | Description |
| Version | This is always |
| HasMML |
|
| AddressOffset | Always |
| TilesTMDOffset | The offset in bytes to the TMD file containing the tiles. This needs to be added to |
| TilesTMDLength | The length of the TMD file containing the tiles in bytes. |
| MMLOffset | The offset in bytes to the MML file containing the entities. This does not need to be added to |
| MMLLength | The length of the MML file in bytes. |
| UnknownValue | This is |
| NumberOfExtraTiles | The length of the array of extra tile data in the LBD file. |
| TileWidth | The width of the LBD file in tiles. It's |
| TileHeight | The height of the LBD file in tiles. It's |
LBDTile
LBDTile
Type | Name | Description |
| DrawTile |
|
| UnknownFlag |
|
| TileType | Essentially the tile ID. It's an index into the objects array of the Tiles TMD. That object will be the tile drawn at this tile's position. |
| FootstepSoundAndCollision | Somehow encodes the footstep sound and collision of this tile. The encoding is currently unknown. |
| TileDirection | Encodes tile rotation in 90 degree increments. |
| TileHeight | The height offset in units to apply to this tile. |
| ExtraTileOffset | The offset in the file to the extra tile to draw on this tile. This needs to be added to |
| AlwaysZero | This is |
MML
An MML file is used to store a collection of MOM files. MOM files are the entities and interactive objects that appear in the game. MML files are only found within LBD files, there are none loose in the game files.
Format
MMLFile
MMLFile
Type | Name | Description |
| ID | Magic number and namesake. Always |
| NumberOfMOMs | The number of MOMs in this MML file. |
| MOMOffsets | Length is equal to |
| MOMs | Length is equal to |
MOM
A MOM file stores a single entity/interactive object that can appear in the game. For instance, the grey man and unused dog entity are both MOM files. Most of the MOM files in the game are stored in MML files in the LBD files—the two exceptions being listed above.
In practical terms, a MOM file contains a TMD file with a number of objects, and an MOS file—a container for TOD animation files. TOD animations store a number of frames, each containing transformations to apply to objects in a TMD file. Hence, when combined in a MOM file they can represent a 3D object with a number of different animations.
Format
MOMFile
MOMFile
Type | Name | Description |
| ID | Magic number and namesake. Always |
| MOMLength | The length of this MOM file in bytes. |
| TMDOffset | The offset in bytes to this MOM's TMD file, from the top of this MOM file. |
| MOS | Container for TOD animation data. |
| TMD | 3D model object data. |
MOS
A MOS file is a container for multiple TOD animation files. MOS files are only found in MOM files, there are none loose in the game files.
Format
MOSFile
MOSFile
Type | Name | Description |
| ID | Magic number and namesake. Always |
| NumberOfTODs | The number of TOD animation files in this MOS. |
| TODOffsets | Length is equal to |
| TODs | Length is equal to |
TIX
A TIX file stores texture atlases for each texture set of each level. These texture atlases are stored as a collection of TIM files that get loaded directly into VRAM when a level loads.
You'll see them in level directories (STG00–13) as TEXA.TIX
through TEXD.TIX
.
Format
TIXFile
TIXFile
Type | Name | Description |
| Header | The file header. |
| Chunks | Length is equal to |
TIXHeader
TIXHeader
The TIX header is 2048 bytes long. Remaining space after the fields listed here is empty (zero).
Type | Name | Description |
| NumberOfChunks | The number of chunks in this TIX file. |
| ChunkOffsets | Length is equal to |
| ChunkLengths | Length is equal to |
TIXChunk
TIXChunk
A TIXChunk
stores multiple TIM files to be loaded into VRAM.
Due to the length of the TIXHeader
, the first chunk is always at offset 0x800. Chunks are aligned on some form of boundary. There is seemingly no pattern for the length of a TIXChunk
, and chunks that do not fill their allocated space leave the rest empty. For these reasons, when reading the file it would probably be best to seek to the TIM offset, read the TIM, then seek directly to the next offset and continue in this fashion until the given number of TIMs is reached—finally seeking directly to the next chunk without dealing with any empty data on the end.
Type | Name | Description |
| NumberOfTIMs | The number of TIMs in this chunk. |
| TIMOffsets | Length is equal to |
| TIMs | Length is equal to |
Last updated