-
Notifications
You must be signed in to change notification settings - Fork 15
/
file formats.txt
374 lines (269 loc) · 12 KB
/
file formats.txt
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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
The structure of Carmageddon 2 game files
-----------------------------------------
by Dan L'Ecuyer
This document covers the following file types used in C2:
ACT - actor file
DAT - model file
MAT - material file
PIX - image file
TWT - library file
With the exception of TWT, the file structures are all based on a common
record layout. A record is composed of a 4-byte type word and a 4-byte length
word followed by any amount of data. For example, here is the first record
for each type of file:
ACT - 00.00.00.12 00.00.00.08 00.00.00.01 00.00.00.02
DAT - 00.00.00.12 00.00.00.08 00.00.FA.CE 00.00.00.02
MAT - 00.00.00.12 00.00.00.08 00.00.00.05 00.00.00.02
PIX - 00.00.00.12 00.00.00.08 00.00.00.02 00.00.00.02
The important thing to note about these structures is that they use a
big-endian byte order. An Intel-based PC uses a little-endian byte order.
That is, the CPU memory is organized as lowest byte first. A big-endian
processor such as the 68000 series formerly used on the Apple Mac organizes
memory as lowest byte last (this is big-endian order). My guess is that the
file structures used in C2 do not originate on the PC. Perhaps the original
development environment used to create Carmageddon (starting from version 1)
was a more advanced machine with a big-endian processor.
In the above structures, I used a combination of network address syntax
and hexadecimal number representation. Each 4-byte number is separated into
four bytes using a decimal point. Each single-byte value is expressed as
hexadecimal. In decimal, the above would look like:
ACT - 0.0.0.18 0.0.0.8 0.0.0.1 0.0.0.2
DAT - 0.0.0.18 0.0.0.8 0.0.250.206 0.0.0.2
MAT - 0.0.0.18 0.0.0.8 0.0.0.5 0.0.0.2
PIX - 0.0.0.18 0.0.0.8 0.0.0.2 0.0.0.2
In any case, the initial record is similar for each file type. The type
word is always the value 12h or 18d. The length word is 8 (since 8 bytes of
data follow). The third word indicates the file type. The last value is
always 2 for both C1 and C2.
I have been able to identify the following record types used in the
various files (shown in the usual order of occurrence):
ACT - 23h, 35d = actor name and attributes
ACT - 2Bh, 43d = transformation matrix
ACT - 25h, 37d = unknown (contains no data)
ACT - 32h, 50d = bounding box
ACT - 29h, 41d = start of hierarchy level
ACT - 26h, 38d = material names
ACT - 24h, 36d = model name
ACT - 2Ah, 42d = end of hierarchy level
DAT - 36h, 54d = model name and attributes
DAT - 17h, 23d = vertices
DAT - 18h, 24d = texture coordinates
DAT - 35h, 53d = faces
DAT - 16h, 22d = material names
DAT - 1Ah, 26d = face materials
MAT - 3Ch, 60d = material name and attributes
MAT - 1Ch, 28d = image name
PIX - 3Dh, 61d = image name and attributes
PIX - 21h, 33d = pixel data
With only a few small differences, the above applies to the C1 file
formats as well. Note that the P08 and P16 files are simply PIX files
which contain more than one pix.
Warning: Plaything does not always write the records with the correct
length attribute. The game and Plaything both ignore the lengths when loading
the data files. That's fine for the game but it doesn't help if you want to
write a file scanning utility.
Floating point representation
=============================
Many values in the game files are floating point rather than integer.
Expressed in hexadecimal, a floating point number makes no sense. For
example, the number 1.0 is 3F.80.00.00 in hexadecimal. The floating point
bits break down like this:
bit 31 = sign bit (1 is negative, 0 is positive)
bits 30 to 23 = exponent (-127 to +127)
bits 22 to 0 = mantissa
In big-endian format, the sign bit is the highest bit in the first byte
while the exponent is in the lower 7 bits of the first byte and the highest
bit of the second byte.
ACT file construction
=====================
Beginning of the file:
00.00.00.12 00.00.00.08 00.00.00.01 00.00.00.02
ACT - 23h, 35d = actor name and attributes
2 bytes = attributes (meaning unknown)
X bytes = actor name
1 byte = null
ACT - 2Bh, 43d = transformation matrix
Always 48 bytes in an array of 12 floating point values.
Default values are indicated in brackets.
Xx (1) Yx (0) Zx (0)
Xy (0) Yy (1) Zy (0)
Xz (0) Yz (0) Zz (1)
Px (0) Py (0) Pz (0)
Px, Py and Pz are absolute coordinates for the position of the actor in
3D space. It is beyond the scope of this document to explain the function
of the transformation matrix.
ACT - 25h, 37d = unknown (contains no data)
This is always present in ACT files generated by Plaything. I have not
experimented to see what effect this has on the game engine if this record
is omitted. I just assume that it is needed.
ACT - 32h, 50d = bounding box
Always 24 bytes in an array of 6 floating point values.
Xmin Ymin Zmin Xmax Ymax Zmax
ACT - 29h, 41d = start of hierarchy level
Empty record indicating the start of a new sublevel in the hierarchy.
ACT - 26h, 38d = material names
This is not normally used. Models typically contain their own list of
materials. However, it can be sometimes advantageous to list the materials
in the actor file instead of the model file. I have not experimented with
this.
ACT - 24h, 36d = model name
X bytes = model name
1 byte = null
ACT - 2Ah, 42d = end of hierarchy level
Empty record indicating the end of a sublevel in the hierarchy. The number
of end markers must match the number of start markers. Also, each actor
must have its own end marker.
Note:
There MUST be a null marker (8 null bytes) at the end of an ACT file else
the game will crash.
The ACT file for a track has a special actor name at the beginning. The
format of the name is (with a single space character between each part):
PP01 X Z B N
X = number of track models in the X direction
Z = number of track models in the Z direction
B = extra buffer space (for what?)
N = number of noncars (can be zero)
DAT file construction
=====================
Beginning of the file:
00.00.00.12 00.00.00.08 00.00.FA.CE 00.00.00.02
DAT - 36h, 54d = model name and attributes
2 bytes = attributes (meaning unknown)
X bytes = model name
1 byte = null
DAT - 17h, 23d = vertices
4 bytes = number of vertices
X bytes = 3 floating point values for each vertex
DAT - 18h, 24d = texture coordinates
4 bytes = number of coordinates
X bytes = 2 floating point values for each coordinate
DAT - 35h, 53d = faces
4 bytes = number of faces
X bytes = 9 bytes for each face
Each face:
2 bytes = 1st vertex
2 bytes = 2nd vertex
2 bytes = 3rd vertex
3 bytes = unknown (Plaything uses 0.1.0)
The vertices are numbered from 0 on upward. Due to the fact that a 16-bit
value is used to identify each vertex, it is impossible to have more than
65,536 vertices in a single model. If the index is considered to be a
signed number (I don't know if the game does that), then the maximum
number of vertices is 32,768.
DAT - 16h, 22d = material names
4 bytes = number of material names
X bytes = name plus null byte for each material
DAT - 1Ah, 26d = face materials
4 bytes = number of faces
4 bytes = unknown (00.00.00.02)
X bytes = 2-byte index for each face
The index is 1-based and refers to the preceding list of materials.
Note:
Each model in a DAT file MUST end with a null marker (8 null bytes). There
does not appear to be any support for smoothing groups within the data
structure. It is possible that the unknown 3 bytes for each face may have
something to do with smoothing groups. Experimentation has shown that it is
possible to funk up collision detection by playing with these bytes. That
probably means that they do not have anything to do with smoothing. I still
need to determine whether they have some effect on lighting.
MAT file construction
=====================
Beginning of the file:
00.00.00.12 00.00.00.08 00.00.00.05 00.00.00.02
MAT - 3Ch, 60d = material name and attributes
4 bytes = colour RGBf (FF.FF.FF.FF)
4 bytes = *ambient lighting (3D.CC.CC.CD)
4 bytes = *directional lighting (3F.33.33.33)
4 bytes = *specular lighting (00.00.00.00)
4 bytes = *specular power (41.A0.00.00)
4 bytes = flags (00.00.00.21)
24 bytes = transformation matrix
4 bytes = *unknown (0A.1F.00.00)
13 bytes = *null
X bytes = material name
1 byte = null
Default values (generated by Plaything) are shown in brackets. Attributes
prefixed with an asterisk do not have any visible effect in the game. The
flag byte in the colour attribute may be either FFh or not FFh. If not FFh
then faces using that material disappear from the game (any possible use?).
The transformation matrix is 2D and follows the same format as the 3D
matrix but with one less dimension. It does work. I currently only use it
to flip the axes on a material but you can do fancier things than that. The
flag bits are as follows:
00.00.00.01 - lit
00.00.00.02 - pre-lit
00.00.00.04 - smooth
00.00.00.18 - env mapped
00.00.00.20 - *correct perspective
00.00.00.40 - decal
00.00.07.80 - i/u/v
00.00.08.00 - always visible
00.00.10.00 - *two-sided
00.00.20.00 - force front
00.00.40.00 - dither
00.00.80.00 - nil
00.07.00.00 - map/mip
00.08.00.00 - fog local
00.10.00.00 - subdivide
00.20.00.00 - Z transparency
00.40.00.00 - nil
00.80.00.00 - nil
The names are taken from the Plaything descriptions for these flags. Some
of them don't do anything and some do weird stuff. Only two flags, which I
have indicated with an asterisk, seem useful. The "correct perspective"
flag does nothing in-game but it works in Plaything. The "two-sided" flag
is, of course, pretty useful since it makes materials like fences and
windows visible from both sides.
MAT - 1Ch, 28d = image name
X bytes = image name
1 byte = null
Note:
Each material in a MAT file must end with a null marker.
PIX file construction
=====================
Beginning of the file:
00.00.00.12 00.00.00.08 00.00.00.02 00.00.00.02
PIX - 3Dh, 61d = image name and attributes
1 byte = image type
2 bytes = unknown (equals image width)
2 bytes = image width
2 bytes = image height
6 bytes = unknown (null)
X bytes = image name
1 byte = null
The image type may be 03 for an 8-bit image, 05 for a 16-bit normal image
or 12h (18d) for a 16-bit translucent image. An 8-bit image can only
support transparency.
PIX - 21h, 33d = pixel data
4 bytes = number of pixels
4 bytes = bytes per pixel (1 for 8-bit, 2 for 16-bit)
X bytes = pixel data
Note:
Each image in a PIX file must end with a null marker.
For 8-bit images, the pixel data is one byte per pixel. This byte indexes
the colour palette (null represents transparency). For 16-bit images, the
pixel data is two bytes per pixel. There are two colour formats. This is
the normal format:
bits 15 to 11 = red (5 bits)
bits 10 to 5 = green (6 bits)
bits 4 to 0 = blue (5 bits)
This is the translucent format (four bits per channel):
bits 15 to 12 = translucency (0 = transparent, 15 = opaque)
bits 11 to 8 = red
bits 7 to 4 = green
bits 3 to 0 = blue
TWT file construction
=====================
4 bytes = size of TWT file
4 bytes = number of files
X bytes = 56-byte header for each file
The header is:
4 bytes = file size
X bytes = file name
1 byte = null
Y bytes = padding to make 56 bytes
Each file follows in the same order as the headers. Important note: the
files MUST be padded to a multiple of 4 bytes. For example, a 16-byte file
does not need padding. A 15-byte file needs one byte of padding (at the end
of the file). Failure to pad the files with the correct number of bytes
will crash the game.