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
LBDHeader
Header
The header of the file.
LBDTile
array
TileLayout
Length is equal to Header.TileWidth * Header.TileHeight
.
This is the grid of tiles in this chunk, starting at the bottom left and continuing rightwards along X.
LBDTile
array
ExtraTiles
Length is equal to Header.NumberOfExtraTiles
.
This is the array of extra tile data that tiles index into when they have extra tiles.
TMDFile
Tiles
TMD file containing an object for each tile in this chunk's tileset.
MMLFile
MML
MML file containing the entities in this level.
LBDHeader
LBDHeader
Type
Name
Description
uint16_t
Version
This is always 0x1
.
uint16_t
HasMML
0x1
if this LBD has an MML file, 0x0
otherwise.
uint32_t
AddressOffset
Always 0x18
, this gets added to some other memory offsets.
uint32_t
TilesTMDOffset
The offset in bytes to the TMD file containing the tiles. This needs to be added to AddressOffset
.
uint32_t
TilesTMDLength
The length of the TMD file containing the tiles in bytes.
uint32_t
MMLOffset
The offset in bytes to the MML file containing the entities. This does not need to be added to AddressOffset
. If this LBD does not contain an MML then this will point out of bounds.
uint32_t
MMLLength
The length of the MML file in bytes.
uint16_t
UnknownValue
This is 0x4C
in every LBD file. Its purpose is currently unknown.
uint16_t
NumberOfExtraTiles
The length of the array of extra tile data in the LBD file.
uint16_t
TileWidth
The width of the LBD file in tiles. It's 0x14
(20) for every LBD.
uint16_t
TileHeight
The height of the LBD file in tiles. It's 0x14
for every LBD.
LBDTile
LBDTile
Type
Name
Description
uint8_t
DrawTile
0x1
if tile is visible, 0x0
otherwise.
uint8_t
UnknownFlag
0x0
or 0x1
, but usage is unknown.
uint16_t
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.
uint8_t
FootstepSoundAndCollision
Somehow encodes the footstep sound and collision of this tile. The encoding is currently unknown.
uint8_t
TileDirection
Encodes tile rotation in 90 degree increments. 0x0
is no rotation, 0x1
is 90 degrees, 0x2
is 180 degrees, and 0x3
is 270 degrees.
int16_t
TileHeight
The height offset in units to apply to this tile.
uint16_t
ExtraTileOffset
The offset in the file to the extra tile to draw on this tile. This needs to be added to AddressOffset
from the LBDHeader
.
uint16_t
AlwaysZero
This is 0x0
in every LBD file. Its use is currently unknown.
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
uint32_t
ID
Magic number and namesake. Always 0x4D4D4C20
, or "MML "
.
uint32_t
NumberOfMOMs
The number of MOMs in this MML file.
uint32_t
array
MOMOffsets
Length is equal to NumberOfMOMs
. This is an array of byte offsets to each MOM file from the top of the MML file.
MOMFile
MOMs
Length is equal to NumberOfMOMs
. This is an array of the MOM files in the file.
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
uint32_t
ID
Magic number and namesake. Always 0x4D4F4D20
, or "MOM "
.
uint32_t
MOMLength
The length of this MOM file in bytes.
uint32_t
TMDOffset
The offset in bytes to this MOM's TMD file, from the top of this MOM file.
MOSFile
MOS
Container for TOD animation data.
TMDFile
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
uint32_t
ID
Magic number and namesake. Always 0x4D4F5320
, or "MOS "
.
uint32_t
NumberOfTODs
The number of TOD animation files in this MOS.
uint32_t
array
TODOffsets
Length is equal to NumberOfTODs
. Contains byte offsets to each TOD file from the top of this MOS file.
TODFile
array
TODs
Length is equal to NumberOfTODs
. This is the animation data.
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
TIXHeader
Header
The file header.
TIXChunk
array
Chunks
Length is equal to TIXHeader.NumberOfChunks
. Each chunk can store multiple TIM files.
TIXHeader
TIXHeader
The TIX header is 2048 bytes long. Remaining space after the fields listed here is empty (zero).
Type
Name
Description
uint32_t
NumberOfChunks
The number of chunks in this TIX file.
uint32_t
array
ChunkOffsets
Length is equal to NumberOfChunks
. Each element in this array is an offset in bytes to a TIXChunk
from the start of the TIX file.
uint32_t
array
ChunkLengths
Length is equal to NumberOfChunks
. Each element in this array is the length of the TIXChunk
at the corresponding index into ChunkOffsets
.
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
uint32_t
NumberOfTIMs
The number of TIMs in this chunk.
uint32_t
array
TIMOffsets
Length is equal to NumberOfTIMs
. Each element is an offset in bytes from the top of this TIXChunk
to a TIM file.
TIMFile
TIMs
Length is equal to NumberOfTIMs
. Each element is a TIM file.
Last updated