This shows you the differences between two versions of the page.
file_formats:lev [2007/10/31 00:25] |
file_formats:lev [2007/10/31 00:25] (current) |
||
---|---|---|---|
Line 1: | Line 1: | ||
+ | =====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] \\ | ||
+ | <code> | ||
+ | 4 bytes - String Length | ||
+ | [String Length] String | ||
+ | 4 bytes - Start of Section's Navigation Data | ||
+ | </code> | ||
+ | [/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 \\ | ||
+ | [[lev#Interactive Nodes|[Interactive Nodes]]] //Location of Interactive Items//\\ | ||
+ | 4 bytes - Number of SubSets \\ | ||
+ | 4 bytes - Number of Level Nodes \\ | ||
+ | [[lev#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//** \\ | ||
+ | <code> | ||
+ | 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 | ||
+ | }; | ||
+ | </code> | ||
+ | ==Navigation Nodes== | ||
+ | **//00 00 00 01//** \\ | ||
+ | **//00 01 00 01//** \\ | ||
+ | <code> | ||
+ | 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 | ||
+ | }; | ||
+ | </code> | ||
+ | ==Exit Node== | ||
+ | **//01 00 00 01//** \\ | ||
+ | **//01 00 01 01//** \\ | ||
+ | <code> | ||
+ | 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 | ||
+ | }; | ||
+ | </code> | ||
+ | ==Blank Node== | ||
+ | **//00 01 01//** \\ | ||
+ | <code> | ||
+ | struct BLANK_NODE { | ||
+ | BYTE unknown; | ||
+ | BYTE ROOT; | ||
+ | BYTE unknown; | ||
+ | }; | ||
+ | </code> |