LEV File Specification

Main Header

4 bytes: size of the level file header
2 bytes: (with 3 bytes of padding) that describes the version number of the header
4 bytes: Unknown/Unused
4 bytes: A 32 bit integer that refers to the position in the file where some now obsolete data is.
4 bytes: Unknown/Unused
4 bytes: A 32 bit integer that refers to the position in the file where the navigation data is.

Map Data Header

1 byte: size of the file header
4 bytes: An 8 bit integer (with 3 bytes of padding) that describes the version number of the header
8 bytes: A 64 bit integer that describes how many Unique IDs for things that have been used.
4 bytes: width (32 bit integer)
4 bytes: height (32 bit integer)
1 byte: A Boolean which is always true

Map Data

33792 bytes: A “palette” of themes that can be on the height field
4 bytes: Ambient Sound Version. 3 = Global, 0 = Use Heightmap Sound
4 bytes: The number of sound themes that are available.

33792 bytes: A “palette” of sound atmosphere themes that can be on the height field.

4 bytes: A checksum. this exists only if the map header pad byte 2 is 9

loop of number of sound themes - 1

uint string length
char[string length] string

endloop

HeightMap

Then, the real meat of the file: the heightfield data. (Width+1)*(Height+1) (read in above) cells are written out. A cell consists of the following data:

4 bytes: A 32 bit integer that’s the size of the cell being written (should always be the same for every cell).
1 bytes: An 8 bit integerthat describes the version number of the cell
4 bytes: A 32 bit floating point number that’s the height of the ground at that point divided by 2048.
1 byte: Should be 0.
3 bytes: These are actually an array of 3 single bytes. Each byte refers to a ground theme in the palette defined in the header.
2 bytes: A 2 element array that contains the strength of the ground themes in the previous array. The 2 numbers should add up to 255 (less if 3 themes are used).
1 byte: A Boolean that specifies whether the hero can walk on the ground at this point.
1 byte: A Boolean that specifies whether the camera is allowed to pass over the ground at this point.
1 byte: Sound Theme
1 byte: Should be 0.
1 byte: Boolean that specifies whether this cell is a shore point
1 byte: Unknown/Unused

Sound Map

There then follows a Width*Height amount of cells. These cells have the following format:

4 bytes: A 32 bit integer that’s the size of the cell being written.
1 byte: An 8 bit integer that describes the version number of the cell
3 bytes: A 3 element array with each byte referring to a sound atmosphere theme in the palette defined in the header.
2 bytes: A 2 element array that contains the strength of the sound atmosphere themes in the previous array. The 2 numbers should add up to 255 (less if 3 themes are used)
1 byte: A sound theme palette index.

Navigation Data

Main Header

4 bytes - Start of Navigation Data
4 bytes - Number of Navigation Sections
[Section Names]

4 bytes - String Length
[String Length] String
4 bytes - Start of Section's Navigation Data

[/Section Names]

Section Header

4 bytes - Size
4 bytes - Version
4 bytes - Level Width
4 bytes - Level Height
4 bytes - Unknown Number of levels, see navigation nodes
4 bytes - Number Interactive Nodes
[Interactive Nodes] Location of Interactive Items
4 bytes - Number of SubSets
4 bytes - Number of Level Nodes
[Level Nodes] Walkable Area layered by accuracy

Interactive Nodes

4 bytes - X coord
4 bytes - Y coord
4 bytes - SubSet

Level Nodes

A Subset has 7 Layers (0-6), each defining blocks of walkable area.
Layer 0 = 32 X 32
Layer 1 = 16 X 16
Layer 2 = 8 X 8
Layer 3 = 4 X 4
Layer 4 = 2 X 2
Layer 5 = 1 X 1
Layer 6 = 0.5 X 0.5

Standard and Root Nodes

00 00 00 00
00 01 00 00

struct NAV_STANDARD_NODE {
  BYTE unknown
  BYTE ROOT
  BYTE unknown
  BYTE END
  BYTE	Layer; //0-6
  BYTE	SubSet;
  FLOAT	X Coord;
  FLOAT	Y Coord;
  DWORD	NodeID;
  DWORD	ChildNode;  //Top Right
  DWORD	ChildNode;  //Top Left
  DWORD	ChildNode;  //Bottom Right
  DWORD	ChildNode;  //Bottom Left
};
Navigation Nodes

00 00 00 01
00 01 00 01

struct NAV_NODE {
  BYTE unknown
  BYTE ROOT
  BYTE unknown
  BYTE END
  BYTE	Layer; //0-6
  BYTE	SubSet;
  FLOAT	X Coord;
  FLOAT	Y Coord;
  DWORD	NodeID;                    
  DWORD	Level;                     //Represents some sort of z level attribute
  BYTE	Unknown;                   //So far, Subset 0 = 0 or 128, SubSet 1+ = 64
  DWORD	NumberNodes;
  DWORD	AdjacentNode[NumberNodes]; //Adjanent navigation or exit nodes
};
Exit Node

01 00 00 01
01 00 01 01

struct EXIT_NODE {
  BYTE unknown
  BYTE ROOT
  BYTE unknown
  BYTE END
  BYTE	Layer; //0-6
  BYTE	SubSet;
  FLOAT	X Coord;
  FLOAT	Y Coord;
  DWORD	NodeID;
  DWORD	Level;                     //Represents some sort of z level attribute
  BYTE	Unknown;                   //So far, Subset 0 = 0 or 128, SubSet 1+ = 64
  DWORD	NumberNodes;
  DWORD	AdjacentNode[NumberNodes]; //Adjanent navigation or exit nodes
  DWORD	NumberUIDs;
  QWORD	TNG_UID[NumberUIDs];        // Stripped UID to create the real uid add 18446741874686296064 to this value
};
Blank Node

00 01 01

struct BLANK_NODE {
  BYTE unknown;
  BYTE ROOT;
  BYTE unknown;
};
 
file_formats/lev.txt · Last modified: 2007/10/31 07:25 by keshire
 
Recent changes RSS feed Creative Commons License Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki