diff --git a/README.md b/README.md index 6f589c7..44811a7 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,3 @@ -#NX Specification [PKG4] +#4th NX Format Specification [PKG5] -This repository hosts the NX (PKG4) specification, which is currently under development. \ No newline at end of file +This repository hosts the 4th NX Format (PKG5) specification, which is currently under development. \ No newline at end of file diff --git a/index.html b/index.html index ddd36ae..0478f55 100644 --- a/index.html +++ b/index.html @@ -1,17 +1,21 @@ -NX (PKG4) Format Specification +NX (PKG5) Format Specification -

3rd NX File Format [PKG4.1]

+

4th NX File Format [PKG5]

The NX file format was designed with speediness and ease of reading in mind, to speed up loading times for anything that uses a node-tree-based data file format.

-

In the NX file format, the following should be followed:

- +

In the NX file format, the following must be followed:

These are the reference implementations of the NX format:

- @@ -68,43 +77,41 @@

Recommended File Format

Node dataNode[]Node data, including all children. String offset tableUInt64[]String offset table. Contiguous block. String dataString[]String data. -Bitmap offset tableUInt64[]Bitmap offset table. Contiguous block. -BitmapsBitmap[]Bitmap data. -Audio offset tableUInt64[]Audio offset table. Contiguous block. -Audio dataAudio[]Audio data. +Byte Array offset tableUInt64[]Byte array offset table. Contiguous block. +Byte ArraysByte Array[]Byte array data. -

Header (52 bytes)

+

Header (40+ bytes)

- + - + - - - - + + +
NameTypeDescription
MagicUInt8[4]"PKG4" = {0x50, 0x4B, 0x47, 0x34}
MagicUInt8[4]"PKG5" = {0x50, 0x4B, 0x47, 0x35}
Node countUInt32Total number of nodes in the file. Cannot be zero.
Node block offsetNode*Offset to the start of the node block, which should be the base node: the parent of all other nodes in the file. This must be a multiple of 4.
Node block offsetNode*Offset to the start of the node block, which must be the base node: the parent of all other nodes in the file. This must be a multiple of 4.
String countUInt32Total number of String entries in the file. Cannot be zero.
String offset table offsetOffsetTable*Offset to the string offset table in the file, with the number of entries equal to the String count. This must be a multiple of 8.
Bitmap countUInt32Total number of Bitmap entries in the file. Zero indicates no bitmap data.
Bitmap offset table offsetOffsetTable*Offset to the bitmap offset table in the file, with the number of entries equal to Bitmap count. This must be a multiple of 8. Ignored if Bitmap count is 0.
Audio countUInt32Total number of Audio entries in the file. Zero indicates no audio data.
Audio offset table offsetOffsetTable*Offset to the audio offset table in the file, with the number of entries equal to Audio count. This must be a multiple of 8. Ignored if Audio count is 0.
Byte Array countUInt32Total number of Byte Array entries in the file.
Byte Array offset table offsetOffsetTable*Offset to the byte array offset table, with the number of entries equal to the Byte Array count. This must be a multiple of 8.
MetadataUInt8[]This field is ignored by parsers and can be used to store application-specific metadata. Note that this field can be of any length, by virtue of NX being offset-based.

Node (20 bytes)

-

Each Node is assigned a zero-based 32-bit unsigned ID in the order they appear in the node block; that is, the first Node (the base node) has ID 0, the second node has ID 1, and so on. This ID is used to point to child nodes of Nodes.
-
-All Nodes should be in one contiguous block, which should be of size 20 * Number of nodes. Nodes must be aligned to an 8-byte boundary.
-
-Children Nodes of each parent Node must be consecutive in one contiguous block, and the ID of the first child in the block is specified in the First Child ID field of the parent Node. Children Nodes of each parent Node must be sorted in ascending order according to the UTF-8 value of the node name of each child. Children Nodes of any given parent Node must have unique node names.
-
-The base node should have an ID of 0, and preferably have type 0 (None).

+

Each Node is assigned a zero-based 32-bit unsigned ID in the order they appear in the node block; that is, the first Node (the base node) has ID 0, the second node has ID 1, and so on. This ID is used to point to child nodes of Nodes.

+ +

All Nodes must be in one contiguous block, which must be of size 20 * Number of nodes. Nodes must be aligned to a 4-byte boundary.

+ +

Children Nodes of each parent Node must be consecutive in one contiguous block, and the ID of the first child in the block is specified in the First Child ID field of the parent Node. Children Nodes of each parent Node must be sorted in ascending order according to the UTF-8 value of the node name of each child. Children Nodes of any given parent Node must have unique node names.

+ +

The base node has an ID of 0, and should preferably be of type 0 (None).

+ - - + @@ -112,13 +119,12 @@

Node (20 bytes)

- - - +
NameTypeDescription
Node nameUInt32String ID representing the name of this node
First Child IDUInt32Node ID of first child. Present but ignored if child count is zero (0).
Children countUInt16Zero means there are no children.
TypeUInt160 = No data
1 = Int64
2 = Double
3 = String (UInt32 ID)
4 = Vector
5 = Bitmap (UInt32 ID, UInt16 Width, UInt16 Height)
6 = Audio (UInt32 ID, UInt32 Length)
DataVariesThis field is always 8 bytes. +
TypeUInt160 = None
1 = Int64
2 = Double
3 = String (UInt32 ID)
4 = Vector
5 = Byte Array (UInt32 ID)

Parsers must ignore types they do not recognise.
DataVariesThis field is always 8 bytes.
TypeDescription
0NoneThis field is ignored.
2Double64-bit IEEE double-precision floating point.
3String32-bit unsigned string ID.
4VectorTwo 32-bit signed integers (Int32), for X and Y respectively.
5Bitmap32-bit unsigned bitmap ID, followed by 16-bit unsigned width and height in that order. Ignored if Bitmap count in Header is 0.
6Audio32-bit unsigned audio ID, followed by 32-bit unsigned data length. Ignored if Audio count in Header is 0.
5Byte array32-bit unsigned byte array ID. Ignored if Byte Array count in Header is 0.
-

String (2-65537 bytes)

+

String (2–65537 bytes)

Each String is assigned a zero-based unsigned 32-bit ID. Offsets to Strings are located in the String offset table. Strings do not need to be in a contiguous block, though this is recommended. Strings must be aligned to a 2-byte boundary.

+ @@ -126,44 +132,90 @@

String (2-65537 bytes)

NameTypeDescription
String dataUInt8[]String data, encoded in UTF-8. This byte array is Length bytes long.
-

Bitmap (4-4294967299 bytes)

-

Each Bitmap is assigned a zero-based unsigned 32-bit ID. Offsets to Bitmaps are located in the bitmap offset table. Bitmaps do not need to be in a contiguous block, though this is recommended.

+

Byte Array (34+ bytes)

+

Each Byte Array is assigned a zero-based unsigned 32-bit ID. Offsets to Byte Arrays are located in the byte array offset table. Byte arrays do not need to be in a contiguous block, though this is recommended. Byte Arrays must be aligned to an 8-byte boundary.

+ - - + + + + +
NameTypeDescription
LengthUInt32Length, in bytes, of the image data. Uncompressed length is Width * Height * 4. Width and Height are specified in the Node's Data field after the bitmap ID.
Bitmap dataUInt8[]Bitmap data, stored in BGRA8888 format, that is, 1 byte each for the blue, green, red and alpha components, in that order. This data is compressed with LZ4. This byte array is Length bytes long.
LengthUInt64Length, in bytes, of the Data field.
Decoded lengthUInt64Length, in bytes, of the byte array once decoded.
EncodingUInt16Encoding.
0 = None
1 = LZ4
2 = LZ4 Frame
3 = Deflate
MetadataUInt8[16]This field is ignored by parsers and can be used to store application-specific metadata.
DataUInt8[]Data, encoded using the method specified in Encoding. This byte array is Length bytes long.
-

Audio (0-4294967295 bytes)

-

Each Audio is assigned a zero-based unsigned 32-bit ID. Offsets to Audios are located in the audio offset table. Audios do not need to be a contiguous block, though this is recommended.

+Note that the LZ4 algorithm can only compress up to 2,147,483,647 bytes. For larger sizes, LZ4 Frame should be used. + +

Offset Table

+

Offset tables are used to refer to Strings and byte arrays. String offsets must be a multiple of 2. Byte Array offsets must be a multiple of 8.

+ - +
NameTypeDescription
Audio dataUInt8[]Audio data, including the 82-byte WZ header. This byte array is Length bytes long. Length is specified in the NX node's data field after the audio ID.
Offset ArrayUInt64[]Sequential offset array; the first offset has ID 0, the second has ID 1, and so on.
-

Offset Table

-

Offset tables are used to refer to Strings, Bitmaps and Audios. String offsets must be a multiple of 2. Bitmap and audio offsets must be a multiple of 8.

+

WZ-specific Data Types

+

This section recommends how Bitmaps and Audio files from WZs should be stored. This is also how the reference converter, WZ2NX, will store Bitmaps and MP3s.

+ +

In a NX file containing Bitmaps and Audio files from WZs that follows this recommendation, the first 2 bytes of the Metadata field of the Header must have bits 15, 10, 6 and 0 set to 1, that is, ORed with 0b1000010001000001 = {0x84, 0x41}.

+ +

Bitmap

+

The 16-byte Metadata field of the byte array containing a WZ bitmap must have the following format.

+ - + + + +
NameTypeDescription
Offset ArrayUInt64[]Sequential offset array; the first offset has ID 0, the second has ID 1, and so on.
MagicUInt8[4]"WZBM" = {0x57, 0x5A, 0x42, 0x4D}
FormatUInt32Format of the image.
0 = 32 bpp ARGB
WidthUInt32Width of the image.
HeightUInt32Height of the image.
-

Acknowledgements:

+

Note that since NX is a little-endian format, e.g. ARGB is actually stored as BGRA — it is treated as a 32-bit field, and not four octets.

+ +

If bitmap data is omitted in an NX file, the Nodes containing a bitmap must point to an empty byte array. Otherwise, the structure of the data within the byte array is as follows.

+ + + + + +
NameTypeDescription
DataUInt8[]Bitmap data. This byte array is Length bytes long. Length is specified in the Byte Array structure.
+ +

Audio

+

The 16-byte Metadata field of the byte array containing audio must have the following format.

+ + + + + + + +
NameTypeDescription
MagicUInt8[4]"WZAU" = {0x57, 0x5A, 0x41, 0x55}
DurationUInt32Audio duration, in milliseconds.
NullUInt8[8]{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
+ +

If audio data is omitted in an NX file, the Nodes containing audio must point to an empty byte array. Otherwise, the structure of the data within the byte array is as follows.

+ + + + + + + +
NameTypeDescription
Header lengthUInt16Length of the header.
HeaderWAVEFORMATEXFormat header. This structure is Header length bytes long.
Audio dataUInt8[]Audio data. This byte array is Length − Header length − 2 bytes long. Length is specified in the Byte Array structure.
+ +

Acknowledgements

-

Contributions to this specification are welcome. Please fork and then send a pull request to this repository.
-
-Creative Commons License
This specification is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License. +

Contributions to this specification are welcome. Please fork and then send a pull request to this repository.

+ +

Creative Commons License This specification is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.

\ No newline at end of file diff --git a/nxl.svg b/nxl.svg new file mode 100644 index 0000000..427de6a --- /dev/null +++ b/nxl.svg @@ -0,0 +1,299 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + +