-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.html
169 lines (155 loc) · 12.2 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
<!DOCTYPE html>
<html>
<head>
<title>NX (PKG4) Format Specification</title>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<style type="text/css">
body {
font-family:sans-serif;
margin: 0 auto;
width: 85%;
}
table {
border-collapse: collapse;
width: 100%;
}
table, td, th {
border: 1px solid black;
}
td, th {
padding: 4px 5px;
}
th {
background-color: black;
color: white;
font-weight: bold;
}
th.name {
width:12.2%;
min-width:11em;
}
th.type {
width:8.5%;
min-width:6.7em;
}
.mono {
font-family: monospace;
}
</style>
</head>
<body>
<h1>3rd NX File Format [PKG4.1]</h1>
<p>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.</p>
<p>In the NX file format, the following should be followed:</p>
<ul>
<li>All offsets are unsigned 64-bit integers, zero-based, and are from the beginning of the file.</li>
<li>Signed integers use Two's complement.</li>
<li>All multi-byte integer and and floating point types are in little endian byte order.</li>
<li>Floating point types follow IEEE standards.</li>
<li>Any compression should be done using LZ4.</li>
<li>The file extension should be <strong>.nx</strong>.</li>
</ul>
<p>These are the reference implementations of the NX format:</p>
<ul>
<li><a href="https://github.com/NoLifeDev/NoLifeNx">NoLifeNx</a> (C++), by retep998, a library for reading NX files.</li>
<li><a href="https://github.com/NoLifeDev/NoLifeWzToNx">NoLifeWzToNx</a> (C++), by retep998, a tool to convert WZ files to NX.</li>
<li><a href="https://github.com/angelsl/ms-reNX">reNX</a> (C#), by angelsl, a library for reading and writing NX files.</li>
<li><a href="https://github.com/angelsl/ms-wz2nx">WZ2NX</a> (C#), by angelsl, a tool to convert WZ files to NX.</li>
</ul>
<h3>Recommended File Format</h3>
<table>
<tr><th class="name">Name</th><th class="type">Type</th><th class="desc">Description</th></tr>
<tr><td>Header</td><td class="mono">Header</td><td>File header</td></tr>
<tr><td>Node data</td><td class="mono">Node[]</td><td>Node data, including all children.</td></tr>
<tr><td>String offset table</td><td class="mono">UInt64[]</td><td>String offset table. Contiguous block.</td></tr>
<tr><td>String data</td><td class="mono">String[]</td><td>String data.</td></tr>
<tr><td>Bitmap offset table</td><td class="mono">UInt64[]</td><td>Bitmap offset table. Contiguous block.</td></tr>
<tr><td>Bitmaps</td><td class="mono">Bitmap[]</td><td>Bitmap data.</td></tr>
<tr><td>Audio offset table</td><td class="mono">UInt64[]</td><td>Audio offset table. Contiguous block.</td></tr>
<tr><td>Audio data</td><td class="mono">Audio[]</td><td>Audio data.</td></tr>
</table>
<h3>Header (52 bytes)</h3>
<table>
<tr><th class="name">Name</th><th class="type">Type</th><th class="desc">Description</th></tr>
<!-- <tr><td></td><td class="mono"></td><td></td></tr> -->
<tr><td>Magic</td><td class="mono">UInt8[4]</td><td class="mono">"PKG4" = {0x50, 0x4B, 0x47, 0x34}</td></tr>
<tr><td>Node count</td><td class="mono">UInt32</td><td>Total number of nodes in the file. Cannot be zero.</td></tr>
<tr><td>Node block offset</td><td class="mono">Node*</td><td>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.</td></tr>
<tr><td>String count</td><td class="mono">UInt32</td><td>Total number of <code>String</code> entries in the file. Cannot be zero.</td></tr>
<tr><td>String offset table offset</td><td class="mono">OffsetTable*</td><td>Offset to the string offset table in the file, with the number of entries equal to the <code>String</code> count. This must be a multiple of 8.</td></tr>
<tr><td>Bitmap count</td><td class="mono">UInt32</td><td>Total number of <code>Bitmap</code> entries in the file. Zero indicates no bitmap data.</td></tr>
<tr><td>Bitmap offset table offset</td><td class="mono">OffsetTable*</td><td>Offset to the bitmap offset table in the file, with the number of entries equal to <code>Bitmap count</code>. This must be a multiple of 8. Ignored if <code>Bitmap count</code> is <code>0</code>.</td></tr>
<tr><td>Audio count</td><td class="mono">UInt32</td><td>Total number of <code>Audio</code> entries in the file. Zero indicates no audio data.</td></tr>
<tr><td>Audio offset table offset</td><td class="mono">OffsetTable*</td><td>Offset to the audio offset table in the file, with the number of entries equal to <code>Audio count</code>. This must be a multiple of 8. Ignored if <code>Audio count</code> is <code>0</code>.</td></tr>
</table>
<h3>Node (20 bytes)</h3>
<p>Each <code>Node</code> is assigned a zero-based 32-bit unsigned ID in the order they appear in the node block; that is, the first <code>Node</code> (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 <code>Node</code>s.<br />
<br />
All <code>Node</code>s should be in one contiguous block, which should be of size <code>20 * Number of nodes</code>. <code>Node</code>s must be aligned to an 8-byte boundary.<br />
<br />
Children <code>Node</code>s of each parent <code>Node</code> must be consecutive in one contiguous block, and the ID of the first child in the block is specified in the <code>First Child ID</code> field of the parent <code>Node</code>. Children <code>Node</code>s of each parent <code>Node</code> must be sorted in ascending order according to the UTF-8 value of the node name of each child. Children <code>Node</code>s of any given parent <code>Node</code> must have unique node names.<br />
<br />
The base node should have an ID of 0, and <em>preferably</em> have type 0 (None).</p>
<table>
<tr><th class="name">Name</th><th class="type">Type</th><th colspan="3" class="desc">Description</th></tr>
<!-- <tr><td></td><td class="mono"></td><td></td></tr> -->
<tr><td>Node name</td><td class="mono">UInt32</td><td colspan="3"><code>String</code> ID representing the name of this node</td></tr>
<tr><td>First Child ID</td><td class="mono">UInt32</td><td colspan="3">Node ID of first child. Present but ignored if child count is zero (0).</td></tr>
<tr><td>Children count</td><td class="mono">UInt16</td><td colspan="3">Zero means there are no children.</td></tr>
<tr><td>Type</td><td class="mono">UInt16</td><td class="mono" colspan="3">0 = No data<br />1 = Int64<br />2 = Double<br />3 = String (UInt32 ID)<br />4 = Vector<br />5 = Bitmap (UInt32 ID, UInt16 Width, UInt16 Height)<br />6 = Audio (UInt32 ID, UInt32 Length)</td></tr>
<tr><td rowspan="9">Data</td><td rowspan="9">Varies</td><td colspan="3">This field is always 8 bytes.
<tr><th colspan="2">Type</th><th>Description</th></tr>
<tr><td class="mono">0</td><td class="mono">None</td><td>This field is ignored.</td></tr>
<tr><td class="mono">1</td><td class="mono">Int64</td><td>64-bit signed integer.</td></tr>
<tr><td class="mono">2</td><td class="mono">Double</td><td>64-bit IEEE double-precision floating point.</td></tr>
<tr><td class="mono">3</td><td class="mono">String</td><td>32-bit unsigned string ID.</td></tr>
<tr><td class="mono">4</td><td class="mono">Vector</td><td>Two 32-bit signed integers (<code>Int32</code>), for X and Y respectively.</td></tr>
<tr><td class="mono">5</td><td class="mono">Bitmap</td><td>32-bit unsigned bitmap ID, followed by 16-bit unsigned width and height in that order. Ignored if <code>Bitmap count</code> in <code>Header</code> is <code>0</code>.</td></tr>
<tr><td class="mono">6</td><td class="mono">Audio</td><td>32-bit unsigned audio ID, followed by 32-bit unsigned data length. Ignored if <code>Audio count</code> in <code>Header</code> is <code>0</code>.</td></tr>
</td></tr>
</table>
<h3>String (2-65537 bytes)</h3>
<p>Each <code>String</code> is assigned a zero-based unsigned 32-bit ID. Offsets to <code>String</code>s are located in the String offset table. <code>String</code>s do not need to be in a contiguous block, though this is recommended. <code>String</code>s must be aligned to a 2-byte boundary.</p>
<table>
<tr><th class="name">Name</th><th class="type">Type</th><th class="desc">Description</th></tr>
<!-- <tr><td></td><td class="mono"></td><td></td></tr> -->
<tr><td>Length</td><td class="mono">UInt16</td><td>Length, in bytes, of the following string data</td></tr>
<tr><td>String data</td><td class="mono">UInt8[]</td><td>String data, encoded in UTF-8. This byte array is <code>Length</code> bytes long.</td></tr>
</table>
<h3>Bitmap (4-4294967299 bytes)</h3>
<p>Each <code>Bitmap</code> is assigned a zero-based unsigned 32-bit ID. Offsets to <code>Bitmap</code>s are located in the bitmap offset table. <code>Bitmap</code>s do not need to be in a contiguous block, though this is recommended.</p>
<table>
<tr><th class="name">Name</th><th class="type">Type</th><th class="desc">Description</th></tr>
<!-- <tr><td></td><td class="mono"></td><td></td></tr> -->
<tr><td>Length</td><td class="mono">UInt32</td><td>Length, in bytes, of the image data. Uncompressed length is <code>Width * Height * 4</code>. <code>Width</code> and <code>Height</code> are specified in the <code>Node</code>'s <code>Data</code> field after the bitmap ID.</td></tr>
<tr><td>Bitmap data</td><td class="mono">UInt8[]</td><td>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 <code>Length</code> bytes long.</td></tr>
</table>
<h3>Audio (0-4294967295 bytes)</h3>
<p>Each <code>Audio</code> is assigned a zero-based unsigned 32-bit ID. Offsets to <code>Audio</code>s are located in the audio offset table. <code>Audio</code>s do not need to be a contiguous block, though this is recommended.</p>
<table>
<tr><th class="name">Name</th><th class="type">Type</th><th class="desc">Description</th></tr>
<!-- <tr><td></td><td class="mono"></td><td></td></tr> -->
<tr><td>Audio data</td><td class="mono">UInt8[]</td><td>Audio data, including the 82-byte WZ header. This byte array is <code>Length</code> bytes long. Length is specified in the NX node's data field after the audio ID.</td></tr>
</table>
<h3>Offset Table</h3>
<p>Offset tables are used to refer to <code>String</code>s, <code>Bitmap</code>s and <code>Audio</code>s. String offsets must be a multiple of 2. Bitmap and audio offsets must be a multiple of 8.</p>
<table>
<tr><th class="name">Name</th><th class="type">Type</th><th class="desc">Description</th></tr>
<!-- <tr><td></td><td class="mono"></td><td></td></tr> -->
<tr><td>Offset Array</td><td class="mono">UInt64[]</td><td>Sequential offset array; the first offset has ID 0, the second has ID 1, and so on.</td></tr>
</table>
<p><strong>Acknowledgements:</strong></p>
<ul>
<li><strong><a href="https://github.com/retep998">Retep998</a></strong>, one of the two co-writers of the NX format.</li>
<li><strong><a href="https://github.com/angelsl">angelsl</a></strong>, the other co-writer and the author of this Specification.</li>
<li><strong><a href="https://github.com/aaronweiss74">aaronweiss74</a></strong>, for his suggestions, help and support, and for writing <a href="https://github.com/aaronweiss74/pkgnx">pkgnx</a>.</li>
<li><strong><a href="https://github.com/Zepheus">Cedric</a></strong>, for his suggestions, help and support, and for writing <a href="https://github.com/Zepheus/javanx">javanx</a>.</li>
<li><strong><a href="https://github.com/strax">Sami</a></strong>, for his support and for writing <a href="https://github.com/strax/nx-pkg4">nx-pkg4</a>.</li>
<li><strong><a href="http://code.google.com/p/lz4/">LZ4</a></strong>, the compression algorithm used in NX.</li>
<li><strong><a href="http://github.com/">GitHub</a></strong>, for hosting this and all our projects.</li>
</ul>
<p>Contributions to this specification are welcome. Please fork and then send a pull request to <a href="https://github.com/nxformat/nxformat.github.com">this repository</a>.<br />
<br />
<a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/deed.en_US"><img alt="Creative Commons License" style="border-width:0" src="http://i.creativecommons.org/l/by-sa/3.0/80x15.png" /></a><br />This <span xmlns:dct="http://purl.org/dc/terms/" href="http://purl.org/dc/dcmitype/Text" rel="dct:type">specification</span> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/deed.en_US">Creative Commons Attribution-ShareAlike 3.0 Unported License</a>.
</body>
</html>