FANDOM


This document is a work in progress! TODO:

  • Rename Section 1 and Section 2 based on block content purpose

Level FormatEdit

The overall level format for Driver 2 is identical to the first Driver for PSX. PSX levels consists of four different sections of data. These sections are described by the Section Definitions block, which must be the first data in the file. Blocks are simply containers for data that consist of a block identifier followed by a block size, which is then followed by that amount of data. The format of the data depends on the block identifier. The four sections are as follows:

  • Section 1 Blocks - This section consists of the Section 1 Container block, which is a container for a list of blocks.
  • Compressed Textures - This section consists of a series of compressed textures.
  • Section 2 Blocks - This section consists of the Section 2 Container block, which is a container for a list of blocks.
  • Sector Data - This section stores data such as textures, models, and world information for various sectors of the world. In order to read this section, you must use information from the Sector Info block.
Block Format
Offset Type Size Name Description
0x0000 uint32 4 blockType Identifier specifying the format/purpose of data.
0x0004 uint32 4 blockSize Size in bytes of block data.
0x0008 N/A blockSize data Data for this block.
Level Format
Offset Type Size Name Description
0x0000 Block 2048 sectionDefinitions Must be of the Section Definitions block type.
0x0800 Block Varies section1Container Must be of the Section 1 container block type.
Varies CompressedTexture[] Varies compressedTextureData Compressed Textures. To read these, you must have information from the Texture Info block.
Varies Block Varies section2Container Must be of the Section 2 container block type.
Varies N/A Varies sectorData Data for sectors. To read this you must have information from the Sector Info block.


Block SpecificationsEdit

The following is a list of block identifiers and their corresponding format. Note that the vast majority of these identifiers are not used.

THIS SECTION IS A WIPEdit

Block Identifier

Corresponding Block Format

Original name

1 (0x01) Models LUMP_MODELS
2 (0x02) World info LUMP_MAP
5 (0x05)

Texture Names

LUMP_TEXTURENAMES
7 (0x07) Road map (unused) LUMP_ROADMAP
8 (0x08) Roads (unused) LUMP_ROADS
9 (0x09) Junctions (unused) LUMP_JUNCTIONS
10 (0x0a) Road surfaces (unused) LUMP_ROADSURF
12 (0x0c)

Model Names

LUMP_MODELNAMES
16 (0x10) Road bounds (unused) LUMP_ROADBOUNDS
17 (0x11) Junction bounds (unused) LUMP_JUNCBOUNDS
20 (0x14) LUMP_SUBDIVISION
21 (0x15) Low detail table for models LUMP_LOWDETAILTABLE
22 (0x16) Motion Capture LUMP_MOTIONCAPTURE
24 (0x18) Overlay Map LUMP_OVERLAYMAP
25 (0x19)

Car Palettes

LUMP_PALLET
26 (0x1a)

Sector Info

LUMP_SPOOLINFO
28 (0x1c)

Car Models

LUMP_CAR_MODELS
33 (0x21) LUMP_CHAIR
34 (0x22)

Texture Info

LUMP_TEXTUREINFO
35 (0x23) Section 1 Container
36 (0x24) Section 2 Container
37 (0x25) Section Definitions
40 (0x28) Straights of Driver 2 LUMP_STRAIGHTS2
41 (0x29) Curves of Driver 2 LUMP_CURVES2
42 (0x2a) Junctions of Driver 2 LUMP_JUNCTIONS2
43 (0x2b) Unknown lump
255 (0xff)


Section DefinitionsEdit

Block Identifier: 37 (0x25)

This block provides information on what offset and what size the four sections of the file are. Because of this, it must be found at the beginning of the level. The block simply consists of an offset and size for each section, followed by padding. The padding must align the block to a 2048 byte boundary, with the block identifier and size included. The padding is usually filled with 'DES!', but does not have to be. Offsets are realative to the start of the level file.

Section Definitions Format

Offset

Type

Size

Name

Description

0x0000

uint32

4

section1Offset

Offset to section 1 block list.
0x0004 uint32 4 section1Size Size of section 1 block list.
0x0008 uint32 4 compressedTexturesOffset Offset to compressed texture data.
0x000C uint32 4 compressedTexturesSize Size of compressed texture data.
0x0010 uint32 4 section2Offset Offset to section 2 block list.
0x0014 uint32 4 section2Size Size of section 2 block list.
0x0018 uint32 4 sectorDataOffset Offset to sector data.
0x001C uint32 4 sectorDataSize Size of sector data.
0x0020 N/A 2008 padding Padding to 2048 byte align this block (including block type and size).

Section 1 ContainerEdit

Block Identifier: 35 (0x23)

This block type makes up one of the four sections of the file. It is simply a container for a list of block structures. The section data that this block resides in must be padded to a 2048 byte boundary, but the actual size of this block does not have to be. Unlike the original Driver's level format, this container does not have a block count. Instead, block are read sequentially until a block type with identifier 255 (0xff) and size 0 is encountered, which signals the end of the block list. The blocks are dword padded (i.e. to nearest 4-byte boundary), and the padding is not accounted for in the contained block sizes.

TODO: Insert what blocks are found in this container.

Section 1 Container Format

Offset

Type

Size

Name

Description

0x0000

Block[]

Varies

blocks

List of blocks containing data for level. Blocks are read until a block with 0xff as identifier is encountered.

Section 2 ContainerEdit

Block Identifier: 36 (0x24)

This block type is exactly the same as the Section 1 Container, except for the identifier and the types of blocks that are typically contained.

TODO: Insert what blocks are found in this container.

Section 2 Container Format

Offset

Type

Size

Name

Description

0x0000

Block[]

Varies

blocks

List of blocks containing data for level. Blocks are read until a block with 0xff as identifier is encountered.

World Info Edit

Block Identifier: 2 (0x02)

Original name: LUMP_MAP

This block type describes world dimensions, and contains bridged model defs.

World info header

Offset

Type

Size

Name

Description

0x0000 uint32 4 width Map width
0x0004 int32 4 height Map height
0x0008 int32 4 tileSize Leftover from Driver 1
0x000C int32 4 numSectors Sector count
0x0010 int32 4 visTableWidth Cell table width
0x0014 int32 4 numAllPackedModelDefs Number of all packed cells in level including bridged cells
0x0018 int32 4 ambientColor Leftover from Driver 1
0x001C int32[] 4*3 sunAngleXYZ Leftover from Driver 1. Sun angle?
0x0028 int32 4 numBridgedObjects Bridged model defs count
0x002C PackedModelDef numBridgedObjects packedModelDefs Packed Model defs that placed between sectors (Look at Sector Info)

Texture NamesEdit

Block Identifier: 5 (0x05)

Original name: LUMP_TEXTURENAMES

This block contains a list of texture names for the level. These texture names are referenced by the Texture Info block.

The actual data for this block consists of an array of characters the length of the block size. Names are stored as null-terminated strings one after another. There should generally not be any empty strings, but this is not guarenteed. There may be additional null characters at the end of the array to dword align the block.

Texture Names Block
Offset Type Size Description
0x0000 char[] blockSize

Series of null terminated strings for texture names.


Model NamesEdit

Block Identifier: 12 (0x0c)

Original name: LUMP_MODELNAMES

This block contains a list of model names for the level. The game uses some model names to find models such as cones, barrels, etc. Not all models are named, and not all named models are searched for in the game.

The actual data for this block consists of an array of characters the length of the block size. Names are stored as null-terminated strings one after another. Empty strings (i.e. just the null character) are allowed and must be accounted for when traversing the array. There may be additional null characters at the end of the array to dword align the block, so the number of models should be gained from the model block and not counting how many nulls occur in the Model Names block. There is guarenteed to be at least as many null-terminated strings as models in the level.

Model Names Block
Offset Type Size Description
0x0000 char[] blockSize

Series of null terminated strings for model names.

Car Models Edit

Block Identifier: 28 (0x1c)

Original name: LUMP_CAR_MODELS

The car models block contains the models for the cars in the level. It has identical format to the regular models block, except in that it adds an offset table to the models. Each offset entry contains an optional offset to the clean, damaged, and low detail models for that car. There is always 13 entries, so there is a maximum of 13 cars per level. All offsets are relative to the position immediately following the list of offset entries.

Car Model Offsets

Offset

Type

Size

Name

Description

0x0000

uint32

4 cleanOffset Offset to the clean model data for this car, or 0xffffffff if no model.
0x0004 uint32 4 damagedOffset Offset to the damaged model data for this car, or 0xffffffff if no model.
0x0008 uint32 4 lowOffset Offset to the low detail model data for this car, or 0xffffffff if no model.
Model Size Pair

Offset

Type

Size

Name

Description

0x0000

uint32

4 size Size of the following model data.
0x0004 Model size model Model data.
Car Models Format

Offset

Type

Size

Name

Description

0x0000

int32

4 numModels Total number of models found in this block.
0x0004 CarModelOffsets[] 13* offsets Offsets to the models in the block.
0x00a0 int32 4 unk Always -1?
0x00a4 ModelSizePair numModels* models Models for the level. Not sure if dword aligned or not.

Car Palettes Edit

Block Identifier: 25 (0x19)

Original name: LUMP_PALLET

This block holds palettes for the various colors of vehicles. The block consists of a total unique palette count followed by a list of car palette entry structures. 

Car palette entries consist of the car number which is being described (or it might be the paint job being described?), the atlas index which the palette belongs to, and the texture index which the atlassed sub-texture comes from. It then has a palette index, which if equal to 0xffffffff, is followed by a PSX 16-color palette structure, otherwise if not equal to 0xffffffff it is equal to the index into the unique palette array and no further data occurs in the entry.

Entries are to be read in by first reading the carNum member. If it is equal to 0xffffffff, it signals the end of the list and the rest of the structure should not be read. Otherwise the atlasIndex, texIndex, and paletteIndex members can be read in, and if paletteIndex equals 0xffffffff, a palette structure is read in. This is repeated until the terminating 0xffffffff is found.

The unique palette count gives the total number of palettes that will occur in the block. As palettes are found in the palette entry structures, this is filled in. To do this one must keep track of the current index, and increment it after each new palette is found.

Car Palette Entry

Offset

Type

Size

Name

Description

0x0000

int32

4 carNum Number of the car which this corresponds to? Maybe paint job index? If equal to 0xffffffff, it signals the end of the list of entries.
0x0004 int32 4 atlasIndex Index of the atlassed sub-texture which this palette is for.
0x0008 int32 4 texIndex Index of the texture the atlassed sub-texture comes from.
0x000C int32 4 paletteIndex If equals 0xffffffff, a palette follows this member. Otherwise it is an index into the unique palette list for this block.
0x0010 Palette 32 palette Only follows paletteIndex if paletteIndex is 0xffffffff. Standard PSX 16-color palette.
Car Palettes Format

Offset

Type

Size

Name

Description

0x0000

uint32

4 numPalettes Total unique palettes in this block. This is not the same as the number of entries in the block.
0x0004 CarPaletteEntry[] Varies entries Entries for the block. See above for termination condition.


Texture InfoEdit

Block Identifier: 34 (0x22)

Original name: LUMP_TEXTUREINFO

The texture info block contains information about the textures and texture atlasing in the level.

Texture Flags Format

Offset

Type

Size

Name

Description

0x0000

uint16

2 flags Only interested in 1 and 4 for moment, which indicate compressed.
0x0002 uint16 2 carnum Might not be carnum anymore
0x0004 uint32 4 offset Holdover from old level format and is not used (I think). At least does not tell where textures are located.
Texture Atlas Info Format

Offset

Type

Size

Name

Description

0x0000

uint16

2 importIndex The index which it was imported in as in the devs program? Not needed.
0x0002 uint16 2 nameOffset Offset of string into the texture names data for this atlas.
0x0004 uint8 1 x x position.
0x0005 uint8 1 y y position.
0x0006 uint8 1 w width. 0==256?
0x0007 uint8 1 h height. 0==256?
Compressed Texture Size Format

Offset

Type

Size

Name

Description

0x0000

uint32

4 index Index of this texture.
0x0004 uint32 4 size Size of compressed texture.

Although compressed texture sizes structs have 16 nodes, only the first numTextures ones are used. Textures can then be read in sequentially.

Compressed Texture Sizes Format

Offset

Type

Size

Name

Description

0x0000

uint32

4 numTextures Number of textures in list.
0x0004 CompressedTextureSize[] 16*8 textureSizes Indicies and sizes of compressed textures.
Texture Info Format

Offset

Type

Size

Name

Description

0x0000

uint32

4 numTextures

The number of 256x256 textures in the level.

0x0004 uint32 4 numAtlasDefinitions The number of atlas definitions in this block.
0x0008 TextureFlags numTextures* textureFlags Flags for the textures.
Varies uint32 4 unk1 Possibly more flags
Varies uint32 4 unk2 Possibly offset to another texture?
Varies TextureAtlasInfo numTextures* textureAtlasInfos

Describes position and size of atlased textures.

Varies CompTexSizes Varies? flag1TexSizes Contains sizes for textures with flag 1 set.
Varies CompTexSizes Varies? flag4TexSizes Contains sizes for textures with flag 4 set.

To read in compressed textures, seek to start of compressed textures section. Read in all flag 1 textures first, then read in all flag 4 textures. Other textures can be found in section 4 (sector data) which needs Sector Info block to read. Most textures will not have any texture data associated with them, probably because they were stripped from the level due to not being used.

Sector InfoEdit

Block Identifier: 26 (0x1a)

Original name: LUMP_SPOOLINFO

The sector info block contains information needed for traversing and reading data from section four (the sector data section) of the level.

Note that all offsets and sizes are to be multiplied by 2048 to get actual offset and size. Offsets are relative to start of sector data section (section 4 of level).

Shared data groups contain information about textures and models that are loaded depending on your position in the level. These structures are indexed from the Sector Data Info struct. Note that most of these have values which are not offsets/sizes (I don't know what these ones are for yet) so only attempt to use the ones that are referenced from a Sector Data Info structure. Textures are stored in a list with the usual uncompressed format (i.e. number of palettes followed by palette data, padding, then uncompressed texture).

 Shared Data Group

Offset

Type

Size

Name

Description

0x0000

uint16

2

textureOffset Offset to textures. Textures are in uncompressed format.

0x0002

uint16

2

modelsOffset Offset to models.

0x0004

uint16

2

unk1

0x0006

uint16

2

unk2

0x0008

uint8

1

modelsSize Number of 2048 chunks of model data.
0x0009 uint8 1 unk3

0x000a

uint8

1

numTextures Number of uncompressed textures at offset.
0x000b uint8 1 unk4

0x000c

uint16

2

unk5

0x00e

uint16 2 unk6
 Data Group Textures

Offset

Type

Size

Name

Description

0x0000

uint8[] 16 textureIndices Indices of textures that are present in this group. Unused indices are filled with 0xff.

Note: There are not offsets to individual sections of data within a sectors data info. Instead you must seek using the sizes listed below. The segments appear in the following order (for known used segments): contentsTableSize, contentsNodesSize, modelDefsSize, roadTableSize.

Packed Model Def format

Offset

Type

Size

Name

Description

0x0000 uint16 2 x X offset relatively of sector
0x0002 int16 2 y_addindex packed "+1024 to model index" (1 bit) and Y offset (15 bits)
0x0004 uint16 2 z Z offset relatively of sector
0x0006 uint16 2 rotation_model packed rotation (6 bit) and model index (10 bit)

To unpack rotation:

rotation = (rotation_model & 0x3f) / 64.0f*PI_F*2.0f;

To unpack model index:

modelindex = (rotation_model >> 6) + ((object.y_addindex & 0x1) ? 1024 : 0);
 Sector Data Info

Offset

Type

Size

Name

Description

0x0000

uint16

2

sectorOffset Offset to the start of the sector data.

0x0002

uint8

1

unk0

0x0003

uint8

1

unk1

0x0004

uint8

1

visibilityOffset Always 0

0x0005

uint8

1

contentsOffset Holdover from Driver 1

0x0006

uint8

1

packedCellsOffset Cells offset relatively contentsOffset

0x0007

uint8

1

modelDefsSize Number of 2048 byte chunks of packed model def structures.

0x0008

uint8

1

dataGroupIndex Index into the array of shared data groups, or 0xff if no data group is used. 0xFF if no datagroup used
0x0009 uint8 1 unk2
0x000a uint8 1 roadTableSize Holdover from Driver 1, not sure what this is in Driver 2 yet.
0x000b uint8 1 heightmapSize Holdover from Driver 1, not sure what this is in Driver 2 yet.

To access Packed Model Defs you need to use sectorDataOffset from Section Definitions, all offsets aligned by 2048 bytes. So, for each sector packed cells are located at sectorDataOffset + 2048 * (sectorOffset + contentsOffset + packedCellsOffset). Read them sequentally until you hit DES! padding.

 Sector Info Format

Offset

Type

Size

Name

Description

0x0000

uint32

4

unk

Unknown

0x0004

uint32

4

unkSize Unknown size.

0x0008

N/A

unkSize

unkData

Always 0?

Varies?

uint32

4

numDataGroups

Number of shared data group infos.

Varies?

SharedDataGroup[]

numDataGroups*

dataGroupInfos

Information about shared data group position/size.

Varies?

DataGroupTextures[] numDataGroups* dataGroupTexs Texture indicies of textures included in the data group.

Varies?

uint32[]

4*12

unk2 Unknown data. 12 ints?
Varies uint32 4 numSectors Number of sectors in level.
Varies uint16[] numSectors* sectorDataOffsets Gives offset in sectorDataInfos if sector has data, otherwise is 0xFFFF
Varies uint32 4 dataInfoSize Size of following sector-data-info data.
Varies SectorDataInfo (dataInfoSize/12)* sectorDataInfos Info on offsets and sizes of sector data segments.

In proper way sectorDataInfos accessed by using sectorDataOffsets. To pick valid sector data offset you'll need a sectorsW and sectorsH.

To find width and height of two dimensional sector array:

sectorsW = width / visTableWidth; sectorsH = height / visTableWidth;

Traverse sectorDataOffsets as two-dimensional array:

for(y = 0; y < sectorsH; y++)
{
	for(x = 0; x < sectorsW; x++)
	{
		sectorIndex = y*sectorsW + x;
		...
	}
}

Accessing SectorDataInfo:

sectorOffset = sectorDataOffsets[sectorIndex];

if(sectorOffset == 0xFFFF)
	continue; // skip, it's empty

sectorDataInfo = sectorDataInfos[sectorOffset/12];

To find sector X and Z position, you need to multiply X or Y by 65536

Community content is available under CC-BY-SA unless otherwise noted.