Do you have a website?
Want to Monetize it with Ads?Test Google's Free Ad Server now!
Google.com/DoubleClick

There are no available options for this view.

Parent Directory Parent Directory | Revision Log Revision Log

Revision 1.37 - (show annotations) (download)
Wed Feb 6 21:09:54 2008 UTC (3 years, 2 months ago) by firefreak
Branch: MAIN
CVS Tags: HEAD
Changes since 1.36: +89 -0 lines
File MIME type: text/plain
Added first info on Mac resource file format
1
2 ==========================================
3 THE UNOFFICIAL SYSTEM SHOCK SPECIFICATIONS
4 ==========================================
5
6 0.1 Table of contents (INCOMPLETE)
7
8 0 DOCUMENT META-DATA
9
10 0.1 Table of contents
11
12 1 GENERAL FILE INFORMATION
13
14 1.1 Resource file format
15 1.1.1 Resource file header
16 1.1.2 Chunk directory
17
18 1.2 Resource file compression algorithm
19 1.2.1 Decoder approach
20 1.2.2 Encoder behaviour
21
22 1.3 Summary of data files
23
24 1.4 Mac resource files
25
26 2 GENERIC CHUNK TYPES
27
28 2.1 Textures and sprites
29 2.1.1 Bitmap header
30 2.1.2 Bitmap compression
31 2.1.3 Pixel 'Animation'
32 2.1.4 private palettes
33
34 2.2 Sounds
35
36 3 THE MAP ARCHIVE
37 3.0.1 Level chunk list
38
39 3.1 Level map
40 3.1.1 Chunk xx02
41 3.1.2 Chunk xx03
42 3.1.3 The level information chunk
43 3.1.4 The tile map
44 3.1.6 The texture list
45
46 3.2 Objects
47 3.2.1 The master object table
48 3.2.2 The object cross-reference table
49 3.2.3 The weapons table, class 0
50 3.2.4 The ammo table, class 1
51 3.2.5 The projectile table, class 2
52 3.2.6 The grenades / explosives table, class 3
53 3.2.7 The patches table, class 4
54 3.2.8 The hardware table, class 5
55 3.2.9 The software / logs table, class 6
56 3.2.10 The scenery / decorations table, class 7
57 3.2.11 The items table, class 8
58 3.2.12 The switches / panels table, class 9
59 3.2.13 The doors / gratings table, class 10
60 3.2.14 The animations table, class 11
61 3.2.15 The traps and triggers table, class 12
62 3.2.16 The containers table, class 13
63 3.2.17 The critters table, class 14
64
65 4 OBJECT PROPERTIES
66
67 4.0 WEAPONS TABLE, class 0
68 4.0.0 SEMI-AUTO WEAPON TABLE, class 0/0
69 4.0.1 AUTOMATIC WEAPON TABLE, class 0/1
70 4.0.2 PROJECTILE WEAPON TABLE, class 0/2
71 4.0.3 MELEE WEAPON TABLE, class 0/3
72 4.0.4 ENERGY BEAM WEAPON TABLE, class 0/4
73 4.0.5 ENERGY PROJECTILE WEAPON TABLE, class 0/5
74
75 4.1 AMMO CLIP TABLE, class 1
76
77 4.2 PROJECTILE TABLE, class 2
78 4.2.0 TRACER TABLE, class 2/0
79 4.2.1 PROJECTILE TABLE, class 2/1
80 4.2.2 class 2/2
81
82 4.3 GRENADES / EXPLOSIVES TABLE, class 3
83 4.3.0 GRENADES TABLE, class 3/0
84 4.3.1 EXPLOSIVES TABLE, class 3/1
85
86 4.4 PATCHES TABLE, class 4
87
88 4.5 HARDWARE TABLE, class 5
89
90 4.6 SOFTS TABLE, class 6
91
92 4.7 FIXTURES TABLE, class 7
93
94 4.8 ITEMS TABLE, class 8
95 4.8.0 Junk
96 4.8.1 Debris
97 4.8.2 Corpses
98 4.8.3 Items
99 4.8.4 Access cards
100 4.8.5 Cyber items
101 4.8.6 Stains
102 4.8.7 Quest items
103
104 4.9 SWITCHES TABLE, class 9
105 4.9.0 Switches
106 4.9.1 Receptacles
107 4.9.2 Terminals
108 4.9.3 Panels
109 4.9.4 Vending
110 4.9.5 Cybertoggles
111
112 4.10 PORTALS (DOORS, GRATINGS) TABLE, class 10
113
114 4.11 ANIMATED TABLE, class 11
115
116 4.12 MARKER TABLE, class 12
117
118 4.13 CONTAINER TABLE, class 13
119
120 4.14 CRITTER TABLE, class 14
121
122 4.15 COMMON OBJECT PROPERTIES
123
124 5 MUSIC
125
126
127 1.1 THE LG RESOURCE FILE FORMAT
128 -------------------------------
129
130 Most of the resource files used by System Shock share the same basic format.
131 These usually have the file extension `.res'.
132
133 Looking Glass resource files are chunkfiles as is common in games: each file
134 is made up of sub-files or chunks (my name for them) which may in turn contain
135 sub-chunks (my really bad name for them). System Shock has several resource
136 files each containing a set of related chunks. Game maps, graphics, text and
137 sounds all reside in resource files. Follows the basic format of a resfile.
138
139
140 1.1.1 Resource file header
141
142 The resource file header consists of the first 128 bytes of the file.
143
144 0000 string "LG Res File v2\r\n\x1A"
145 0011 blank not used
146 007C int32 file offset to chunk directory
147
148 Although the byte 0x1A is found in all res files immediately after the magic
149 string, it is not part of the string. It serves as a terminator for an
150 optional comment that may follow the string header.
151 For a true res file implementation this should be respected - but for
152 SystemShock only, treating the 0x1A byte as fixed is ok.
153
154 1.1.2 Chunk directory
155
156 The chunk directory is a 6 byte header followed directly by directory entries:
157
158 0000 int16 no. chunks in file
159 0002 int32 file offset to beginning of first chunk
160
161 Chunk directory entry : 10 bytes
162
163 0000 int16 chunk ID (globally unique modulo language versions)
164 0002 int24 chunk length (unpacked)
165 0005 int8 chunk type : 00 flat uncompressed
166 01 flat compressed
167 02 subdir uncompressed
168 03 subdir compressed
169 0006 int24 chunk length (packed in file)
170 0009 int8 content type: 00 palette (?data)
171 01 text
172 02 bitmap
173 03 font
174 04 video clip
175 07 sound effect (Glen Sawyer)
176 0F 3D model
177 11 audio log / cutscene (Glen Sawyer)
178 30 map
179
180 Note: all chunks begin on a 4-byte boundary, so does the chunk directory.
181
182
183 ==============================
184
185 Chunk subdir header : 2 bytes + 4 bytes per subblock + 4 bytes
186
187 0000 int16 no. subblocks
188 0002 int32 chunk offset to first subblock
189 ...
190 nnnn int32 chunk offset to last subblock
191 nnnn+4 int32 total length of chunk
192
193 Note: for type 3 (subdir, compressed) chunks the subdir is not compressed;
194 offsets are offsets in the unpacked data
195
196 Some subdirs have their data immediately after the directory, others have
197 two bytes space between them.
198
199
200
201 1.2 RESOURCE FILE COMPRESSION ALGORITHM
202 ---------------------------------------
203
204 The compression algorithm used for resfiles is a simple dictionary-based
205 coding scheme. The data stored in the compressed chunk consists of a
206 continuous stream of 14-bit words stored big-endian i.e. if the first 7
207 bytes in the chunk are
208
209 aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg
210
211 the corresponding words are
212
213 aaaaaaaabbbbbb bbccccccccdddd ddddeeeeeeeeff ffffffgggggggg
214
215 with the high bit to the left in each case.
216
217 To unpack a word from the compressed data stream, say it has value x.
218 If x == 0x3fff (16383) it is the end-of-stream marker. Stop.
219 If x == 0x3ffe (16382) reinitialise the dictionary. Forget all stored
220 positions and lengths of compressed words and start as if from scratch.
221 If x is less than 256, write the literal byte x to the uncompressed data.
222 Otherwise take n = x - 256; re-unpack the n'th word from the compressed data
223 followed by the next _uncompressed_ byte; if this would take us beyond the
224 end of the so-far uncompressed data, write a literal zero byte instead.
225
226
227 1.2.1 Decoder approach
228
229 I handle decompression by keeping a dictionary of all 16127 (16384-256-1)
230 possible reference words (as opposed to literal bytes or the end-of-stream
231 marker) consisting of position in the uncompressed stream, unpacked length
232 and original reference from the compressed data. Initialise all the lengths to
233 1. Each time we take a word from the compressed stream, make a note of its
234 position, and if it is a reference word (255 < x < 16383) its value. For a
235 literal byte we then just write the byte to the output stream. Otherwise look
236 up the reference in the dictionary; if its length is 1 we have not encountered
237 it before, set the length to 1 + (length of original reference). Then unpack
238 it by repeating (length) bytes from (position).
239
240 (I'm not 100% sure about this but it gets all the lengths right and comes up
241 with reasonable looking unpacked data)
242
243 As promised, here is a sample unpacking routine in C.
244
245 ---
246
247 void unpack_data (unsigned char *pack, unsigned char *unpack,
248 unsigned long packsize, unsigned long unpacksize)
249 {
250
251 unsigned char *byteptr;
252 unsigned char *exptr;
253 unsigned long word;
254 int nbits;
255 int val;
256
257 int ntokens = 0;
258 static int offs_token [16384];
259 static int len_token [16384];
260 static int org_token [16384];
261
262 int i;
263
264 for (i = 0; i < 16384; ++i)
265 {
266 len_token [i] = 1;
267 org_token [i] = -1;
268 }
269 memset (unpack, 0, unpacksize);
270
271 byteptr = pack;
272 exptr = unpack;
273 nbits = 0;
274
275 while (exptr - unpack < unpacksize)
276 {
277
278 while (nbits < 14)
279 {
280 word = (word << 8) + *byteptr++;
281 nbits += 8;
282 }
283
284 nbits -= 14;
285 val = (word >> nbits) & 0x3FFF;
286 if (val == 0x3FFF)
287 {
288 break;
289 }
290
291 if (val == 0x3FFE)
292 {
293 for (i = 0; i < 16384; ++i)
294 {
295 len_token [i] = 1;
296 org_token [i] = -1;
297 }
298 ntokens = 0;
299 continue;
300 }
301
302 if (ntokens < 16384)
303 {
304 offs_token [ntokens] = exptr - unpack;
305 if (val >= 0x100)
306 {
307 org_token [ntokens] = val - 0x100;
308 }
309 ++ntokens;
310 }
311
312 if (val < 0x100)
313 {
314 *exptr++ = val;
315 }
316 else
317 {
318 val -= 0x100;
319
320 if (len_token [val] == 1)
321 {
322 if (org_token [val] != -1)
323 {
324 len_token [val] += len_token [org_token [val]];
325 }
326 else
327 {
328 len_token [val] += 1;
329 }
330 }
331 for (i = 0; i < len_token [val]; ++i)
332 {
333 *exptr++ = unpack [i + offs_token [val]];
334 }
335
336 }
337
338 }
339
340 }
341
342 ---
343
344 1.2.2 Encoder behaviour
345
346 The encoder follows the standard LZW algorithm.
347
348 Futhermore, it has the following features:
349 - The End-Of-Stream marker is always written at the end, even if the decoder
350 would know to stop because of reaching the end of the decompressed size.
351 - Regardless of at which bit-position the encoder stopped, always one extra
352 0x00 byte is added to the compressed byte stream.
353 - When the encoder has its dictionary exhausted it continues to work with it
354 until it tried to create a new key for the 1000th time. Then, a dictionary
355 reset is performed (and marked in the stream).
356 Note that the decoder has to follow accordingly (Hint: it will anyway - even
357 IF the decoder would create extra keys, it never would read their values
358 from the stream since that is impossible)
359
360
361 1.3 SUMMARY OF DATA FILES
362 -------------------------
363
364 System Shock data files fall into two categories: cached and rarely-accessed
365 files which are left on the CD, and frequently-accessed files which are stored
366 on the hard disc.
367
368
369 1.3.1 CD files
370
371 These are always found in directory cdrom/data on the CD.
372
373 archive.dat Level map archive
374 bwtabl.dat
375 citalog.res Audio logs (English)
376 citbark.res Audio trap messages (English)
377 cutspal.res Palettes for cutscenes
378 death.res
379 frnalog.res Audio logs (French)
380 frnbark.res Audio trap messages (French)
381 gamepal.res In-game palette data
382 geralog.res Audio logs (German)
383 gerbark.res Audio trap messages (German)
384 gryntabl.dat
385 intro.res MainMenu screens
386 ipal.dat Colour cube
387 lofrintr.res
388 logeintr.res
389 lowdeth.res
390 lowend.res
391 lowintr.res
392 mongtabl.dat
393 objart.res Sprites for objects
394 objprop.dat Object properties (generic and class-specific)
395 shadtabl.dat
396 splash.res Splash screens
397 splshpal.res Palette for splash screen (Origin)
398 start1.res
399 svfrintr.res
400 svgadeth.res
401 svgaend.res
402 svgaintr.res
403 svgeintr.res
404 textprop.dat Texture properties
405 vidmail.res Video mail
406 whyttabl.dat
407 win1.res
408
409
410 1.3.2 Hard-disc files
411
412 These start off in directory hd/data of the CDROM, and are copied to the data
413 subdirectory of your System Shock install on the hard disc
414
415 citmat.res Textures for 3D object models
416 cybstrng.res Game strings (English)
417 digifx.res
418 digiparm.bin
419 frnstrng.res Game strings (French)
420 gamescr.res HUD borders, fonts, buttons
421 gerstrng.res Game strings (German)
422 handart.res Graphics for wielded weapons
423 intro.res MainMenu screens
424 mfdart.res MFD icons (target/email/item display) (English)
425 mfdfrn.res MFD icons (target/email/item display) (French)
426 mfdger.res MFD icons (target/email/item display) (German)
427 obj3d.res 3D object models
428 objart2.res Graphics for critters
429 objart3.res Graphics for critters, decals and doors
430 objprop.dat Object properties
431 sideart.res Sidebar icons
432 texture.res Map textures
433
434
435
436 1.4 Mac resource files
437
438 The Mac (PPC) version of System Shock 1 has its resources stored in a different
439 file format.
440 Note: Unless otherwise stated, within this document everything refers to
441 the Intel version -- Mac resource files have been deciphered for not a so
442 long time.
443 Also: All integer fields in the PPC files are stored in big endian.
444
445 Videos and audios are stored in dedicated files, videos have a readable
446 file name and audios a number (probably the chunk id).
447 Audio files are raw PCM (8bit, 22kHz) files and have an 8 byte header:
448 0000 uint32 Null
449 0004 uint32 ASCII 'mdat'
450
451 Resources are stored in files with the extension .rsrc (With the exception of
452 Archive.data) and differ to the intel variant by:
453 - They have not the LG resource file format, but similar
454 - Chunks are not classified (type) on chunk level nor seem they to be
455 compressed at all
456
457
458 Resource file header:
459
460 Not much has been deciphered as of yet (also contains some strings)
461
462 0000 uint32 Unknown (typically 0x00000100)
463 0004 uint32 file offset to chunk directory
464 0008 uint32 Previous value minus 0x00000100 ??
465 ...
466 007A uint32 total file length
467 ...
468
469 Since the first three uint32 fields are similar (identical?) to the first
470 of the chunk directory header, I believe that this is some sort of master-
471 container file format with its entries linked like a double linked list;
472 But since yet only files with two entries have been discovered, a sequence
473 can not be seen...
474 -- ff1
475
476
477 Chunk directory header: (38 bytes)
478
479 0000 uint32 File offset to start of chunks? (typically 0x00000100)
480 0004 uint32 File offset to chunk directory (pointing to itself?)
481 0008 uint32 Previous value minus 0x00000100 ??
482 000C uint32 Length of Chunk Directory - up to file end *)
483 0010 6xb Unknown
484 0016 uint32 Unknown (typically 0x0000001C)
485 001A uint32 Unknown
486 001E uint32 Type? Resolves to ASCII:
487 'sIMG' objart
488 'sA01' archive
489 's???' gamepal
490 0022 uint16 Number of Chunk Directory Entries minus One
491 0024 uint16 Unknown (typically 0x000A)
492
493 *) Note that there are dummy bytes at the end (filler values) if the chunk
494 entries don't fill up the directory size.
495
496
497 Chunk Directory Entry: (12 bytes)
498
499 0000 uint16 ChunkId
500 0002 uint16 Starting with 0x0000, a counter with +2 increment?
501 0004 uint32 Start Offset of Chunk, relative to base chunk start
502 0008 uint32 Unknown -- always 0x00000000 ?
503
504 Chunk Entry:
505 0000 uint32 Data Length
506 0004 Nxb Data
507
508
509
510 objart.rsrc: This file has only one chunk that contains its own header.
511
512 Header:
513 0000 uint16 Amount of entries minus One (= 0x06AA)
514 0002 n*4b Offset of image start from chunk start
515
516 A referenced entry then has a standard bitmap header, although the
517 type field seems only to be a byte (the second), with the first
518 being unknown. No RLE compressed bitmaps currently found.
519
520
521
522
523 2 GENERIC CHUNK TYPES
524 =====================
525
526
527 2.1 TEXTURES AND SPRITES
528 ------------------------
529
530 Textures and sprites have content type 2 (bitmap) and use the following general
531 format:
532
533
534 2.1.1 Bitmap header
535
536 The bitmap header is 28 bytes long, as follows.
537
538 0000 int32 ??? always 0
539 0004 int16 type (0x00: uncompressed, 0x02: appears like 0x00, 0x04: compressed)
540 0006 int16 ???
541 0008 int16 width
542 000A int16 height
543 000C int16 width in bytes
544 000E int8 ??? log2 width
545 000F int8 ??? log2 height
546 0010 int16 \
547 0012 int16 \ These seem to be used for animation frames to keep the
548 0014 int16 / sprite centred.
549 0016 int16 /
550 0018 int32 ??? (not) always 0
551
552 The hotspot rect (0x0010-0x0017) is interesting. It bounds a single pixel at
553 the centre bottom of the sprite (it's only valid for sprites, I think).
554
555 Note on the int32 field at 0x0018:
556 At chunks with more than one bitmap in it (nsubchunks > 1) this value
557 was set as: bitmapN.value + (size of subchunkN) == bitmapN+1.value .
558 I can't read anything out of this system - but perhaps I don't see the
559 wood from the trees...
560
561 2.1.2 Bitmap compression
562
563 A compressed (type 4) bitmap can be unpacked as follows:
564 00 nn xx write nn bytes of colour xx
565 nn .. .. 0<nn<0x80 copy nn bytes direct
566 80 00 00 skip rest of file (end of compressed data)
567 80 mm nn 0<nn<0x80 skip (nn*256+mm) bytes (write transparencies)
568 80 nn 80 .. .. copy nn bytes direct
569 80 mm nn 0x80<nn<0xC0 copy ((nn&0x3f)*256+mm) bytes
570 80 mm nn xx 0xC0<nn write ((nn&0x3f)*256+mm) bytes of colour xx
571 nn 0x80<nn skip (nn&0x7f) bytes
572
573 Thanks to Joerg Fischer (jofis@cs.uni-sb.de) for kindly sending me the source
574 code to his texture extractor (you can get it from the hackers' page at TTLG)
575 which cleared up some questions I had about the bitmap format. Vasily Volkov
576 (no known e-presence) also had a hand in the decompression. Joerg has asked
577 that I not distribute the sources myself; email him direct if you want them.
578
579 Note that _all_ bitmaps are subchunks, even when there is only one bitmap
580 stored in a chunk. This is presumably to simplify the loading logic.
581
582 Textures are uncompressed square bitmaps stored at 4 resolutions each: 16x16,
583 32x32, 64x64 and 128x128. There are 273 textures stored, but some (a few) do
584 not contain useful graphics. Chunks containing textures are:
585
586 76 16x16 textures (sub-chunks 0-272)
587 77 32x32 textures (sub-chunks 0-272)
588 707-979 64x64 textures (one chunk each)
589 1000-1272 128x128 textures (one chunk each)
590
591 Note on the 80 command: the following two bytes appear to be an uint16 value,
592 encoded in LittleEndian. It could be that they are swapped in the MAC edition.
593
594 Furthermore, the 80 mm C0 case is not described above, but this one has not
595 been found in the resource files (yet).
596
597
598 Notes on the encoder:
599 If large areas are to be compressed, the lengths are first expressed with
600 the 80 commands until the length can be encoded with one of the smaller codes.
601
602 But it appears that the original coder had a maximum length limit of 0x7FFF
603 since there are rare occasions of large empty areas at the end encoded with
604 80 FF 7F 80 00 00 -- we would get the same result without the first 3 bytes.
605
606 It has also been found that the original encoder had some quirks, resulting
607 in a little less optimal compression; For example, the sequence
608 44 02 00 1E had been found where 45 01 1E would have been technically
609 'more' correct and with better compression.
610 It could be that these are the results of extra edits...
611
612
613 2.1.3 Pixel 'Animation'
614
615 The 'animations' that appear with some textures (SHODAN's mail
616 images, hardware buttons, ...) are done by palette looping.
617 It seems that there are generally four steps.
618 Those I have yet found out:
619
620 ?? 0x04 to 0x07
621 ?? 0x08 to 0x0B
622 Sensaround: 0x0C to 0x0F
623 Motion Booster: 0x10 to 0x13
624 SHODAN: seems to use 0x14 to 0x17
625 Jump Boots: 0x18 to 0x1B
626 ?? 0x1C to 0x1F
627
628 ff1: Perhaps energy weapons are done the same way...
629 12052002, ff1: must be; furthermore the ones marked with ??
630 also ought to be animated (guessed).
631 0x00 to 0x03 I hardly think is one loop as it
632 includes 'special' index 0x00
633
634
635 2.1.4 private palettes
636
637 Some bitmaps (yet only found at uncompressed ones) have their own special
638 palette stored past the bitmap bits + 4 bytes. ie:
639
640 HEADER (size 0x001C)
641 BITMAP BITS (size width * height)
642 unknown (size 0x0004, int32 - found to be 1, could be flag for pal)
643 PRIV PALETTE (size 0x0300)
644
645 When in search for some example bitmaps with private palettes, look for
646 the chunk 0x073A (System Shock), which contains 3 images - the three
647 intro screens.
648
649
650 2.2 SOUNDS
651 ----------
652
653 All sounds are stored in 8bit, mono, linear signed format, either at 11 or
654 22kHz.
655
656 Digitised sound effects reside in the file digifx.res and have chunk type 07.
657 These are simply Creative Labs .voc files embedded in the resfile, one chunk
658 each. Check Wotsit (www.wotsit.org) for the format.
659
660 Audio logs reside in the files citalog.res (English), geralog.res (German) and
661 frnalog.res (French) and have chunk type 0x11 (17). Chunk IDs are shared
662 between the languages (i.e. the same log will have the same ID in each
663 language file). If the text of a log has chunk ID n, the audio sample will
664 have chunk ID 300+n.
665
666 Audio logs seem to be embedded movie files of some description but I don't
667 know which format they are in yet.
668
669 MOVI Format:
670
671 MOVI Chunks are itself chunk directories. Length and type are implicitly
672 taken from the index table from the first MOVI (master) chunk.
673
674 Master chunk 'MOVI'
675 HEADER size 256 bytes (including 'MOVI')
676 0000 4xint8 'MOVI'
677 0004 int32 no. directory entries
678 0008 int32 size of index table
679 000C int32 size of the contents (excluding HEADER, PAL, INDEX)
680 0010 int32 length of movie (in 1/65536 seconds)
681 0014 int32 No idea
682 0018 int16 width of video
683 001A int16 height of video
684
685 0026 int16 sample rate of audio (?)
686
687
688 PALETTE size 3*256 bytes
689 the initial palette to be used for video.
690
691
692 INDEX TABLE list of Index Entries, each of the form:
693 0000 3xint8 Timestamp. This is an 8.16 fixed point number
694 of seconds.
695 0003 int8 type of entry:
696 b0-2 Chunk type
697 b3-6 Additional info.
698 Chunk types are:
699 0 End of movie
700 1 Video frame
701 2 Audio (PCM, 8bit, 1Channel)
702 3 Subtitle or control (text)
703 4 Palette
704 5 Dictionary (used in hi-res codec)
705 0004 int32 offset of the subchunk (starting from beginning)
706
707 0 End of movie
708 This marks the end of the chunk directory. It only really exists so that the
709 length of the last chunk may be calculated (there is no "length" field, so
710 length is taken to be [offset next chunk] - [offset this chunk] ).
711
712 1 Video subchunk
713 The 4 bits "additional info" in the type field gives the compression format.
714 2 are used: low-resolution cutscenes are format 4 (type=0x21) and use the
715 "type 4" bitmap format described in section 2.1.2. Such a frame is preceded
716 by an 8-byte bounding box definition (System Shock ignores this; it is always
717 set to the entire frame size).
718 0000 int16 start_x
719 0002 int16 start_y
720 0004 int16 width
721 0006 int16 height
722 0008 compressed bitmap data
723
724 High-resolution cutscenes use format 0xf (type=0x79). This compression format
725 is rather more sophisticated and a lot more complicated. It uses two
726 auxiliary chunks, which are defined at the start of each scene (alongside the
727 palette) and which remain constant throughout the scene. These are the auxpal
728 and dictionary chunks of type 5, described below.
729 The video chunks themselves are divided into 2 sections. The basic format of
730 a video frame is
731 0000 int16 Offset (in bytes from start of frame) to section 2 (xxxx)
732 0002 ... Section 1: main packed data stream
733 xxxx ... Section 2: pixel data
734
735 A high-resolution video frame is divided into 4x4 pixel tiles (so a 600x300
736 frame is 150x75 tiles in size). Each tile is unpacked independently of all
737 the others.
738 The real key to the frame is (unsurprisingly) the frame chunk section 1. This
739 is interpreted as a (big-endian) bitstream with variable word length. To
740 unpack a frame given its packed chunk and the (previously read) dictionary
741 and auxpal chunks, we proceed as follows:
742 0. Read 12 bits from the packed stream. This forms an offset d (0-0xfff)
743 into the dictionary chunk. (Not all 12 bits necessarily belong
744 exclusively to this word, see below).
745 1. Take the d'th (counting from 0) 24-bit word from the dictionary chunk.
746 This is the control word c. A control word is made up as follows:
747 bits 0-16 (0x01ffff) Parameter field
748 bits 17-19 (0x0e0000) Type field
749 bits 20-23 (0xf00000) Count field
750 2. A count field of zero is a long offset. The base offset consists of the
751 type and parameter field taken together (i.e. is a 20-bit offset
752 0-0xfffff). The next 4 bits from the packed data stream (after the
753 offset d) are added to this, and the result forms a new offset into
754 dictionary chunk. We then return to step 1 to collect a new control
755 word. This enables much larger dictionary chunks, however the later
756 parts of the chunk can only be reached at the cost of reduced
757 compression.
758 3. The (nonzero) count field of the current control word is the number of
759 bits by which to advance the pointer into the pack stream. If this is
760 less than 12, the low bits of the current offset will of course form
761 the high bits of the next. Since the dictionary chunk is run-length
762 encoded (see below), a word may be repeated without taking up more
763 space on disc, allowing the low bits of the offset to vary in order to
764 accommodate the next. This is a cunning way of squeezing some bits (on
765 average) out of the packed tile.
766 4. The action that is now taken depends on the type field. Different types
767 may require parameters to be taken from the frame chunk section 2 and/
768 or the auxpal chunk:
769 Type 0: The parameter field is interpreted as 2 literal pixel values
770 (8-bit palette indices). These are duplicated twice
771 horizontally (low high low high, from L-R) and 4x vertically
772 to make a 4x4 tile. Note that a zero index here is NOT
773 counted as transparent.
774 Type 1: The parameter field is interpreted as 2 palette indices
775 (zero is transparent): the high byte corresponds to a 1 bit
776 in the pixmap and the low to a 0. The next 16 bits from
777 frame section 2 are treated as 16 1-bit pixels: bit 0 (0,0),
778 bit 1 (1,0), bit 4 (0,1) and so on to make a 4x4 tile.
779 Type 2: The parameter field is interpreted as an offset into the
780 auxpal chunk giving 4 palette indices. The next 32 bits from
781 section 2 are treated are 16 2-bit pixels.
782 Type 3: As type 2, but with 8 palette indices and a 48-bit word of
783 3-bit pixels from section 2.
784 Type 4: As type 3, but 4 bits per pixel, 16 indices, 64 bits.
785 Type 5: Skip. The parameter field is ignored[1]. The next 5 bits
786 from the packed stream (section 1) gives the number of tiles
787 to skip: a value of 0x1f here means skip the rest of the
788 row.
789 Type 6: Repeat previous control word[2].
790 Type 7: As type 6 (this value is not used).
791 5. If the frame has not yet been fully unpacked, return to step 0.
792
793 Notes on the high-resolution frame format:
794 [1] The real decompression algorithm proceeds row-by-row, making an
795 intermediate list of all the control words for that row in a row buffer.
796 The parameter field of a type 5 control word is replaced by the parameter
797 from the packed stream at this stage, and forms the offset when the row
798 buffer is unpacked into the image.
799 [2] This can improve compression ratios if two consecutive tiles or skips can
800 be represented by the same control word (this doesn't necessarily mean
801 that tiles are identical, since they may take bitmap or offset data from
802 the frame). A copy word may well take fewer bits to reach than the
803 previous full word.
804
805 2 Audio subchunk
806 This is just raw 8-bit audio data.
807
808 3 Subtitle subchunks
809 0000 4xint8 subtitle control
810 0004 uint16 sizeof of header (?)
811 0004 8xint8 unknown
812 0010 null terminated string
813
814
815 Subtitle control 'AREA'
816 Presumably it defines the area for the subtitles, it appears only
817 once in the movie (preceeding all subtitles).
818 example: "10 165 310 195 CLR"
819
820 Subtitle controls 'STD ', 'FRN ', 'GER '
821 which language the subtitle (textpart) is in (given that the game was
822 written by Americans, std = english, of course).
823 The null terminated string is the text to display
824
825
826 4 Palette subchunks
827 Both types 0x04 and 0x4C always come up in pairs and point to the same
828 offset. (Could be because older and newer type version of the file format).
829 As the sizes of those subchunks always is 0x0300 bytes I assume they
830 contain palette information - which is confirmed.
831
832 5 Dictionary
833 There are 2 different types of chunk here, which always appear in pairs at
834 the start of a scene. The auxpal chunk (type=0x05) is very simple: it
835 consists of an (unpacked) list of palette indices making up the auxpals for
836 the image tiles (see above).
837 The dictionary chunk (type=0x0d) contains all the control words for the video
838 codec. It uses a simple run-length coding scheme: the top 8 bits of each 32-
839 bit word in the packed chunk gives the number of occurrences, the low 24 bits
840 are the control word. The basic format of the dictionary chunk is:
841 0000 uint32 Size of unpacked chunk (in bytes, 3 to a word)
842 0004 ... Packed dictionary chunk.
843
844
845 3 THE MAP ARCHIVE
846 =================
847
848 The game maps are stored in the file archive.dat which contains 834 chunks
849 starting at ID 4000. The sharp-eyed amongst us will note that
850 834 == 52 * 16 + 2. I would have thought 64 * 13 would be more logical as
851 there are 10 levels (1-9 + R) and 3 groves, but the chunk sizes clearly
852 repeat in blocks of 52. I haven't yet examined the maps thoroughly enough to
853 figure out the extra 3: perhaps they are to do with cyberspace?
854
855 3.0.1 Level list
856
857 Reactor Map 0 (chunk 40xx)
858 Levels 1-9 Map L (chunk 4Lxx)
859 SHODAN c/space Map 10 (chunk 50xx)
860 Delta grove Map 11 (chunk 51xx)
861 Alpha grove Map 12 (chunk 52xx)
862 Beta grove Map 13 (chunk 53xx)
863 C/space L1-2 Map 14 (chunk 54xx)
864 C/space other Map 15 (chunk 55xx)
865
866 (Thanks to Glen Sawyer <glen_s@enol.com> for compiling the list)
867
868 Each map uses 52 blocks but has IDs allocated for 100. Chunks 4000 and 4001 are
869 not specific to any individual map, so level R uses chunks 4002-4053, level
870 1 4102-4153 and so on.
871
872
873 3.0.2 Archive name
874
875 This resides in chunk 4000 and consists of a C-style string containing the
876 archive name. In the original archive.dat this is "Start game" with a great
877 deal of trailing garbage to a length of 128 bytes. When the map is first
878 archived to change levels this becomes "Starting Game" and keeps the trailing
879 junk. In a save game proper (savgamXX.dat) the save game name makes up the
880 whole chunk.
881
882
883 3.0.3 Player information
884
885 This resides in chunk 4001.
886
887
888 3.1 LEVEL MAP
889 -------------
890
891 The first 6 chunks (xx02-xx07) in each map (seem to) contain information about
892 the level geometry.
893
894
895 3.1.1 Chunk xx02
896 3.1.2 Chunk xx03
897
898 These chunks are only 4 bytes long, containing a single 32-bit word. I don't
899 know what they mean yet tho.
900
901
902 3.1.3 The level information chunk
903
904 This resides in blocks 4004, 4104 etc. and contains miscellaneous information
905 about the level.
906
907 0000 int32 \ Map size in tiles
908 0004 int32 /
909 0008 int32 ?? always 6 could be log2 map size
910 000C int32 ?? always 6
911 0010 int32 log2 (no. height units per tile width). If this value is x,
912 a (non-sloping) tile with height 2**x will be a perfect cube.
913 0014 int32 This is a placeholder for the tile map pointer when the chunk
914 is loaded into memory. It is meaningless on disc
915 0018 int32 Cyberspace flag. 1 if level is c/space, 0 otherwise
916
917
918 3.1.4 The tile map
919
920 This resides in blocks 4005, 4105 etc. and is always compressed. The unpacked
921 chunk has size 0x10000 (aha! 16*64*64, you say). This is a 64x64 grid of
922 tiles, starting at the bottom left corner of the level, where each tile does
923 indeed (thanks Jim!) have format
924
925 0000 int8 Type. I have so far identified
926 00 solid
927 01 open
928 02 diagonal open s/e
929 03 diagonal open s/w
930 04 diagonal open n/w
931 05 diagonal open n/e
932 06 slope s->n (all slopes expressed as low->high)
933 07 slope w->e
934 08 slope n->s
935 09 slope e->w
936 though there are certainly more types defined. Perhaps there
937 are diagonal slopes as well.
938 10-Jun-2000 Glen has now identified the diagonals:
939 0A slope se->nw valley
940 0B slope sw->ne valley
941 0C slope nw->se valley
942 0D slope ne->sw valley
943 0E slope nw->se ridge
944 0F slope ne->sw ridge
945 10 slope se->nw ridge
946 11 slope sw->ne ridge
947 A "valley" tile has 3 vertices level and one lower: the floor
948 is split into 2 triangular sloping sections along the diagonal
949 from the lower to the opposite vertex. A "ridge" tile has 3
950 vertices level and one higher, and is likewise split along the
951 diagonal. (This means that ridged tiles are no longer
952 completely convex and need careful handling in 3D). If that
953 makes sense I'll be impressed 8-)
954 0001 int8 Floor
955 0002 int8 Ceiling. These are
956 bit 0-4 height (ceiling is in units DOWN from top)
957 bit 5-6 orientation
958 bit 7 hazard flag (floor contains biohazard, ceiling
959 radiation hazard flag)
960 0003 int8 Steepness of slope
961 0004 int16 Index into object xref table of first object in tile
962 0006 int16 Texture info
963 0008 int32 Flags
964 000C 4xint8 State (?) These always seem to contain FF 00 00 00 in the
965 archive.dat file; presumably they contain game flags when
966 levels are archived in saved games.
967
968 It appears that slopes can refer to floor, ceiling or both, presumably
969 controlled by bits in the flag word but I haven't identified which ones.
970 30-May-2000 It looks as if slope is controlled by bits 12-13 in the flag word
971 as follows:
972 xxxxx0xx Floor & ceiling, same direction
973 xxxxx4xx Floor & ceiling, ceiling opposite dir to tile type
974 xxxxx8xx Floor only
975 xxxxxCxx Ceiling only
976 Only 30 flag bits still to go 8-)
977
978 Some further info about valleys, ridges and inverted ceilings:
979 An uninverted ceiling of a valley floor looks like a ridge (and vice versa),
980 so that in each case the ceiling and the floor could fit into the other.
981 At an inverted ceiling, the 'mirrored' type of the other group is used;
982 As an example: The inverted ceiling of a SE->NW valley takes the ceiling
983 info of a NW->SE ridge tile.
984 To verify these cases look into levels 7 and 9:
985 7 (antenna rooms): Here valley (floor) tiles have inverted ceilings, also valleys
986 9 (CPU room): Here valley (floor) tiles have non-inverted ceilings, thus ridges
987
988
989 Texture info: It appears that each level may use a maximum of 64 textures out
990 of the 273 available. This strongly suggests that 6 bits are used per
991 texture. My current best guess at bits in the texture info word is:
992 0-5 Wall texture (index into texture list)
993 6-10 Ceiling texture
994 11-15 Floor texture
995 It appears that there are only 32 floor/ceiling textures available. The height
996 bytes don't supply the missing bit; heights are definitely signed.
997 13-Jun-2000 That last bit was a lie. Only the bottom 5 bits of the height
998 bytes are used for tile heights. The others seem to be environmental flags.
999 Each tile may only store ONE wall texture (unless there are others stored
1000 elsewhere that I haven't yet found out about). They may clearly pick and
1001 choose between their own and adjacent textures; current best guess is that
1002 this is controlled by bit 8 of the flags word.
1003
1004 Flags:
1005 80000000 tile visited (automapper)
1006 0F0F0000 shade control
1007 0000F000 music nibble
1008 00000C00 slope control
1009 00000200 Spooky music flag? This appears to be set for areas which
1010 have been largely remodelled by SHODAN's forces.
1011 00000100 use adjacent rather than local textures for walls
1012 0000001F vertical texture offset adjust
1013
1014
1015 3.1.6 The texture list
1016
1017 This resides in blocks 4007, 4107 etc. and contains a 16-bit word for each
1018 texture used by the level, up to a maximum of 64. A texture ID as stored in
1019 the tile map is an index into this list.
1020
1021
1022
1023 3.2 OBJECTS
1024 -----------
1025
1026 An "object" in System Shock can be anything that isn't part of the basic level
1027 geometry itself i.e. not a wall or floor texture. This includes all items,
1028 sprites, 3D models, decals, doors and gratings, and invisible stuff such as
1029 traps and triggers.
1030
1031 An object is generally identified by class, subclass and type. This forms a
1032 hierarchy of object classification from coarsest (class) to finest (type).
1033 This is denoted in this document and elsewhere as class/subclass/type, e.g.
1034 the Cyberjack is object 12/0/4 .
1035
1036 Object classes are
1037 0 Weapons
1038 1 Ammo
1039 2 Projectiles
1040 3 Grenades and explosives
1041 4 Patches
1042 5 Hardware
1043 6 Software & logs
1044 7 Scenery and fixtures
1045 8 Gettable and other objects
1046 9 Switches and panels
1047 10 Doors and gratings
1048 11 Animated objects (?)
1049 12 Traps and markers
1050 13 Containers (includes corpses)
1051 14 Critters
1052
1053 The object information is stored from chunk xx08 to xx24 inclusive. The first
1054 two tables give general information about the objects and their positioning in
1055 the level map. The remaining 15 are each specific to a given object class, and
1056 contain extra information about the objects in that class.
1057
1058
1059 3.2.1 The master object table
1060
1061 This resides in chunks 4008, 4108 etc. and contains an entry for everything in
1062 the level that is not part of a tile (i.e. a wall, floor or ceiling).
1063 Each entry is 27 bytes long as follows:
1064
1065 0000 int8 in-use flag. 0 slot is free, 1 in use.
1066 0001 int8 object class
1067 0002 int8 object subclass
1068 0003 int16 class index. This is an index into the class specific table in
1069 one of the following chunks.
1070 0005 int16 index into object cross-reference table (next chunk)
1071 0007 int16 prev link
1072 0009 int16 next link
1073 000B int16 x coord (high byte is tile x)
1074 000D int16 y coord (high byte is tile y)
1075 000F int8 z coord (?)
1076 0010 int8 \
1077 0011 int8 } These seem to be the 3 angles for 3d positioning
1078 0012 int8 /
1079 0013 int8 ?? AI index - is 0xFF for all but damageable things (critters
1080 and crates)
1081 0014 int8 object type
1082 0015 int16 Hitpoints? Initial values tend to be round decimal numbers
1083 0017 int8 State (sprite frame)
1084
1085
1086 3.2.2 The object cross-reference table
1087
1088 This resides in chunks 4009, 4109 etc. and is used to link map tiles with the
1089 objects that they contain. The "index" field in the tile map is an index
1090 into this table. Entries themselves contain an index field which is used to
1091 chain objects together when there is more than one object in a map tile.
1092
1093 Objects which extend over more than one tile get an entry in this table for
1094 each tile which partially contains them. Entries for a single object and
1095 multiple tiles are linked by the 5th field (0008) while entries for a single
1096 tile and multiple objects are linked by the 4th (0006).
1097
1098 An object cross-ref entry consists of 10 bytes as follows:
1099
1100 0000 int16 Tile x position
1101 0002 int16 Tile y position
1102 0004 int16 Index into master object table
1103 0006 int16 Cross-ref index for next object in tile
1104 0008 int16 Cross-ref index for next tile object extends into
1105
1106
1107 3.2.3 The weapons table, class 0
1108
1109 This resides in chunks 4010, 4110 etc. and contains special info on weapons.
1110 Each entry consists of 8 bytes as follows:
1111
1112 0000 int16 Weapon index in master object table
1113 0002 int16 "Prev" link for slot list
1114 0004 int16 "Next" link for slot list
1115 0006 int8 Ammo type (projectile) or charge (energy)
1116 0007 int8 Ammo count (projectile) or ?temperature (energy)
1117
1118
1119 3.2.4 The ammo table, class 1
1120
1121 This resides in chunks 4011, 4111 etc. and contains special info on ammo clips.
1122 An ammo clip is an ammo clip is an ammo clip, really, so this chunk isn't
1123 very interesting; it has 6 bytes in it:
1124
1125 0000 int16 Ammo clip index in master object table
1126 0002 int16 "Prev" link for slot list
1127 0004 int16 "Next" link for slot list
1128
1129
1130 3.2.5 The projectile table, class 2
1131
1132 This resides in chunks 4012, 4112 etc. and is not used in the map archive for
1133 obvious reasons. It might be used in saved games.
1134
1135
1136 3.2.6 The grenades / explosives table, class 3
1137
1138
1139 3.2.7 The patches table, class 4
1140
1141 This resides in chunk 4014, 4114 etc. and contains information about the
1142 dermal patches. There is no special information on these, so this table just
1143 contains the master object cross-ref and the links for the slot list.
1144
1145
1146 3.2.8 The hardware table, class 5
1147
1148 This resides in chunks 4015, 4115 etc. and contains information on hardware.
1149 Each entry is 7 bytes long:
1150
1151 0000 int16 Hardware index in master object table
1152 0002 int16 "Prev" link for slot list
1153 0004 int16 "Next" link for slot list
1154 0006 int8 Version
1155
1156
1157 3.2.9 The software / logs table, class 6
1158
1159 This resides in chunks 4016, 4116 etc. and contains information on software
1160 and logs. Each entry is 9 bytes long:
1161
1162 0000 int16 Software index in master object table
1163 0002 int16 "Prev" link for slot list
1164 0004 int16 "Next" link for slot list
1165 0006 int8 (Softs) Version no. of software
1166 0007 int8 (Log) Log chunk number (offset from 0x09B8 2488)
1167 0008 int8 (Log) Level no. log refers to
1168
1169
1170 3.2.10 The scenery / decorations table, class 7
1171
1172 This resides in chunks 4017, 4117 etc. and contains information on permanent
1173 fixtures of the station which aren't parts of walls. Each entry is 16 bytes
1174 long; the first 6 bytes are the index and slot-list links as follows, and
1175 the rest depend on the object type.
1176
1177 For WORDS 07:02:03
1178 0006 int16 text (subchunk to chunk 0868 (2152))
1179 0008 int16 font and size
1180 000A int16 colour (0 seems to default to red)
1181
1182 For animated screens (Glen figured this one out):
1183 0006 int16 Number of frames
1184 0008 int16 Loop repeats backwards flag
1185 000C int16 Start frame (offset from chunk 321)
1186
1187 Some values of "start frame" are special:
1188 246 Static fading into SHODAN's face
1189 247
1190 248-255 Surveillance ID, see "surveillance control chunk" below
1191
1192 For values of "start frame" greater than 255 the low 7 bits give a text message
1193 (subchunk of text chunk 0877 2167) to be rendered onto the screen. Here 127
1194 0x7F is the special value; it is used for the random numbers in the CPU rooms
1195 on levels 1-6 before the nodes have been destroyed.
1196 If bit 7 is set for a text message the text scrolls vertically. Each frame
1197 consists of several strings, starting at (start frame & 0x7f) + (current
1198 frame). The number of strings per frame is simply the number that will fit on
1199 the screen; partial lines are not drawn.
1200
1201
1202 For bridges subchunk 7 (Glen again):
1203 0008 int8 bits 0-3 X size (4 is tile width)
1204 bits 4-7 Y size (4 is tile width) - 0 is bridge's normal size
1205 in its 3D model
1206 0009 int8 bridge height (0 is default) 32 units per texture height
1207 000A int8 bits 0-6 top/bottom texture
1208 bit 7 set if texture comes from the main textures referred
1209 to in chunk xx07, otherwise it is taken from the 3D model
1210 texture maps in citmat.res .
1211 000B int8 side textures (similarly)
1212
1213
1214 Note that in CYBERSPACE levels (10, 14, 15) fixtures are not used as such, but
1215 are co-opted as extra softs/logs in case that table becomes full, and act as
1216 objects of class 6. From a cursory investigation the fixture data in this
1217 case seems to be:
1218 0006 int16 version no. (softs)
1219 0008 int16 softs/logs subclass
1220 000C int16 softs/logs type
1221
1222
1223 3.2.11 The items table, class 8
1224
1225
1226
1227 3.2.12 The switches / panels table, class 9
1228
1229 This resides in chunks 4019, 4119 etc. and contains information on switches and
1230 panels. Each entry is 30 bytes long, having the first 12 Bytes in common;
1231 the second half is specific to switch type.
1232 As it seems, the State of the switch (mostly Puzzles) isn't stored within
1233 this table.
1234
1235 0000 int16 Panel index in master object table
1236 0002 int16 "Prev" link for slot list
1237 0004 int16 "Next" link for slot list
1238 0006 int16 unknown??
1239 0008 int16 Condition: Variable Index
1240 0010 int16 Condition: Message on fail
1241
1242 Number Pads (9 3 7):
1243 000C int16 Combination in BCD
1244 000E int16 Map Object to trigger
1245 0018 int16 Map Object to Extra Trigger (?)
1246
1247
1248 Puzzles (9/3/0 to 9/3/3)
1249
1250 These are either wire or block (power) puzzles. The dword at offset 0x10 seems
1251 to be the determining factor: if bit 28 is set (0x10000000) it is a block
1252 puzzle, else it is a wire puzzle.
1253
1254 For both types the word at offset 0x0C is a reference to a map object to frob
1255 when the puzzle is completed.
1256
1257 For a wire puzzle:
1258 0010 int8 Size (nibble0: Wires (default: 4 if 0),
1259 nibble1: Connectors per side (default: 6 if 0))
1260 0011 int8 Power level to be reached (out of 0xFF)
1261 0012 int16 unknown
1262 0014 int32 Target State of Wires
1263 0018 int32 Current State of Wires
1264 The States are stored in 3bit pairs from right to left
1265 (first pair: first wire, second pair second, ...)
1266 the first triple states the left connector,
1267 the second the right one.
1268 (so a maximum of 8 connectors is possible and
1269 maximum of 5 Wires (32 / 6 = 5)
1270
1271 For a block puzzle:
1272 0010 int32 "Helper" trigger object for state (is an Action 0x00 Trigger)
1273 Bit 28 of this field is set to indicate that it is a block puzzle.
1274 0016 int32 Puzzle information:
1275 b4-6 Y coord of power source connector
1276 b7-8 Source direction (10=left)
1277 b12-14 Y coord of power destination connector
1278 b15-16 Destination direction (11=right, 00=up)
1279 b20-23 Width
1280 b24-27 Height
1281 b28-31 Side effect type
1282
1283 The actual state of the puzzle is stored in the "helper" object's trigger info,
1284 from offset 0x10 on. Each block has 3 bits describing what is in it. Blocks
1285 are stored from top left to bottom right in the usual order, but the way in
1286 which they are encoded is slightly complicated.
1287 Puzzle state is read in 32-bit words starting at the LAST dword in the trigger
1288 info, and the block descriptors are rotated out at the bottom. When the word
1289 has been fully examined, any bits left over are kept and combined with enough
1290 bits from the bottom of the previous word to make up a 3-bit block descriptor.
1291 Thus the top left block is described by the bottom 3 bits of the last trigger
1292 word (the bottom 3 bits of the byte at offset 0x1C), the next block to the
1293 right by bits 3-5 of the same word, and so on until the 11th block, if the
1294 puzzle is that large. This is made up of the top 2 bits of the last word (bits
1295 6-7 of byte 0x1F) as its low 2 bits and the bottom bit of the penultimate word
1296 (bit 0 of byte 0x18) as the high bit. The 12th block is taken from bits 1-3 of
1297 the penultimate word, and so on.
1298 It might be simpler just to look at Trig_get_block_puzzle() in src/trigger.c
1299 for clarification of the above.
1300
1301 Block types are:
1302 00 Empty
1303 01 Inactive connector (x)
1304 02 Active connector (+)
1305 04 Solid block
1306 06 Switching node (hollow square)
1307
1308
1309 Panels:
1310 yet unknown
1311
1312 Buttons (9 0 2):
1313 yet unknown
1314
1315 Cyberjacks:
1316 000C int16 X of target Cyberspace
1317 0010 int16 Y of target Cyberspace
1318 0014 int16 Z of target Cyberspace
1319 0018 int16 Level (Cyberspace)
1320
1321 Elevators (9 3 5):
1322 000C int16 Map index of Panel of target Level1
1323 000E int16 Map index of Panel of target Level2
1324 0012 int16 Map index of Panel of target Level3
1325 0018 int16 Bitfield of accessible Levels (Actual)
1326 001A int16 Bitfield of accessible Levels (Shaft)
1327 Levels with a 1 in the "shaft" field but not in the "Actual" field
1328 give a "Shaft damage: Unable to go there" message.
1329
1330
1331
1332 3.2.13 The doors / gratings table, class 10
1333
1334 This resides in chunks 4020, 4120 etc. and contains information on doors and
1335 gratings. Each entry is 14 bytes long:
1336
1337 0000 int16 Door index in master object table
1338 0002 int16 "Prev" link for slot list
1339 0004 int16 "Next" link for slot list
1340 0006 int16 ?? trigger cross-ref
1341 0008 int16 Message
1342 000A int8 Access required 0-31
1343
1344
1345 3.2.14 The animations table, class 11
1346
1347
1348 3.2.15 The traps and triggers table, class 12
1349
1350 This resides in chunks 4022, 4122 etc. and contains information on traps and
1351 triggers.
1352
1353 A trigger has a type and an action. The type is stored with the generic object
1354 definition in the master object table and determines how the trigger is set
1355 off. The action is stored with the trigger definition in this table and
1356 determines what happens. Types of trigger are
1357
1358 Entry 0C 00 00 Player enters trigger's tile
1359 Null 0C 00 01 Not set off automatically, must be
1360 explicitly activated by a switch or
1361 another trigger
1362 Floor 0C 00 02
1363 Player death 0C 00 03 Player dies. These are used to
1364 resurrect the player if the
1365 resurrection machine has been reset
1366 Deathwatch 0C 00 04 Object is destroyed / dies
1367 AOE entry 0C 00 05
1368 AOE continuous 0C 00 06
1369 AI hint 0C 00 07
1370 Level 0C 00 08 Player enters level
1371 Continuous 0C 00 09
1372 Repulsor 0C 00 0A Repulsor lift floor
1373 Ecology 0C 00 0B
1374 SHODAN 0C 00 0C
1375 Tripbeam 0C 01 00
1376 Biohazard 0C 02 00
1377 Rad hazard 0C 02 01
1378 Chem hazard 0C 02 02
1379 Map note 0C 02 03 Map note placed by player (presumably)
1380 Music mark 0C 02 04
1381
1382 Trigger data is 28 bytes long. The first 12 bytes have the same format for all
1383 triggers; the remaining 16 depend for their interpretation on the action.
1384
1385 0000 int16 Trigger index in master object list
1386 0002 int16 "Prev" link for slot list
1387 0004 int16 "Next" link for slot list
1388 0006 int8 Action
1389 0007 int8 Once-only flag? 0 or 1
1390 0008 4xint8 Condition
1391
1392 The condition is usually a game variable and value, but depends on the trigger
1393 type; for deathwatch triggers it is the class and type of the object(s) being
1394 watched.
1395
1396 Trigger actions are
1397
1398 00 Do nothing / default action (switch)
1399
1400 01 Transport (elevator panel / cyber term)
1401
1402 02 Resurrection?
1403
1404 03 Clone object
1405 000C int16 Object to transport.
1406 000E int16 Delete flag?
1407 0010 int16 Tile destination X
1408 0014 int16 Tile destination Y
1409 0018 int16 Destination height?
1410
1411 04 Set variable
1412 000C int16 variable to set
1413 0010 int16 value
1414 0012 int16 ?? action 00 set 01 add
1415 0014 int16 Optional message to receive
1416
1417 06 Activate / Open. Set off triggers, open doors.
1418 000C int16 1st object to activate.
1419 000E int16 Delay before activating object 1.
1420 0010 ... Up to 4 objects and delays stored here.
1421
1422 07 Change lighting
1423 000C int16 Control point 1
1424 000E int16 Control point 2
1425 ... ?
1426
1427 08 View "Static" effect
1428
1429 09 Moving platform
1430 000C int16 Tile x coord of platform
1431 0010 int16 Tile y coord of platform
1432 0014 int16 Target floor height
1433 0016 int16 Target ceiling height
1434 0018 int16 Speed
1435
1436 0C Choice. Set off trigger depending on [what?]
1437 000C int16 Trigger 1
1438 0010 int16 Trigger 2
1439
1440 0F Player receives email
1441 000C int16 Chunk no. of email (offset from 2441 0x0989)
1442
1443 10 This is used in the radiation treatment area on level R.
1444
1445 13 Change object state.
1446
1447 16 Trap message
1448 000C int16 "Success" message
1449 0010 int16 "Fail" message
1450
1451 17 Spawn
1452 000C int32 Class/subclass/type of object to spawn
1453 0010 int16 Control point 1 (object)
1454 0012 int16 Control point 2 (object)
1455 0014 ??
1456 0018 ??
1457
1458 18 Change type. This is used for force bridges / doors
1459 000C int16 Object ID to change.
1460 0010 int8 New type.
1461 0012 ??
1462
1463 3.2.16 The containers table, class 13
1464
1465 This resides in chunks 4023, 4123 etc. and contains information on containers.
1466 As the name suggests, a container is an object that may contain other objects;
1467 this includes corpses and dead monsters as well as crates etc. Each entry is
1468 21 bytes long:
1469
1470 0000 int16 Container index in master object table
1471 0002 int16 "Prev" link for slot list
1472 0004 int16 "Next" link for slot list
1473 0006 4xint16 Up to 4 objects contained
1474 000E int8 Width (for crates) 0 means use default
1475 000F int8 Height (for crates) 0 means use default
1476 0010 int8 Depth (for crates) 0 means use default
1477 0011 int8 Top texture (for crates) 0 means use default
1478 0012 int8 Side texture (for crates) 0 means use default
1479 0013 int16 ??
1480
1481 Crates, like bridges, may specify their dimensions and texture mapping
1482 information independently of the actual 3D model they are associated with
1483 (which is just a placeholder and is ignored). Default dimensions are 80x80x80
1484 for a "small crate" (13/0/0), 160x160x160 for a "large crate" (13/0/1) and
1485 240x240x240 for a "secure crate" (13/0/2). Textures are taken from the
1486 special model texture block from chunk 2180.
1487
1488
1489
1490 3.2.17 The critters table, class 14
1491
1492
1493 ==============================
1494
1495 The surveillance control chunk
1496
1497 This resides in chunks 4043, 4143 etc. and controls surveillance screens i.e.
1498 those displaying live scenes from within the 3D world.
1499
1500 It contains a maximum of 8 16-bit words giving the object IDs of up to 8 "null"
1501 trigger objects; these are dummy objects which exist only to provide a
1502 position and orientation for the camera transform associated with that screen.
1503
1504 Objects referred to in this chunk are linked by special values in the "start
1505 frame" field of their respective screens. Special start frames 248-255 refer
1506 to words 0-7 in this chunk. Thus if a screen has start frame 248, the first
1507 word in the surveillance control chunk is used as an object ID to look up an
1508 object whose position and orientation are then used to render a scene into a
1509 bitmap, which in turn is projected onto the screen.
1510
1511
1512 ===============================
1513 Logs, eMails, vMails, Data Fragments (From Rebecca)
1514
1515 Those texts are stored in blocks of Strings (String arrays). Information about
1516 them is also stored in this block:
1517 Line Content
1518 0 Info
1519 1 'Title' (that appears in lists)
1520 2 Sender
1521 3 Subject
1522 4 to n-1 Verbose Text
1523 n Empty Line ("")
1524 n+1 to m-1 Terse Text
1525 m Empty Line ("")
1526
1527 Info Line: has the following format:
1528 [event ][colour ]LeftId[,[ ]RightId]
1529 event: 'iEE' or 't'
1530 EE = Hex Number of Log/eMail to follow immediately
1531 't' is set for Texts following a 'iEE' Text
1532 colour: 'cCC'
1533 CC = Hex Number of Colour Index in Palette;
1534 only Sender and Subject are drawn in this colour
1535 LeftId, RightId:
1536 decimal subchunk number of left (and right) bitmaps to show;
1537 (based from main chunk ID 0x28)
1538 Note that the blank between ',' and RightId is omitted sometimes...
1539
1540 vMails only have a number between 256 and 261 in this line - but don't
1541 match any bitmaps -- orig SS even skips Sender and Subject Lines (since
1542 there is no bitmap where they could be shown)
1543
1544 Title, Sender, Subject: always one line
1545
1546 Verbose and Terse Text:
1547 although the texts are torn apart, those breaks do not mark Newlines.
1548 Instead, character 0x0A does this. Character 0x02 marks possible
1549 soft hyphens (but as it turned out, not all texts are formatted this way).
1550 The string '$N' is a placeholder for the hackers name.
1551
1552 ===============================
1553 Notes (Sheets lying on the ground on Citadel)
1554
1555 Same as above, those Texts are stored in string arrays. They don't have
1556 any special formatting or different versions, just one block of Text form
1557 the first line on and end with one empty line.
1558
1559
1560 The object properties list, objprop.dat
1561 ---------------------------------------
1562
1563 This file is not a resource file, it is a flat file containing tables of
1564 miscellaneous object information. For each object class, there is a general
1565 table, followed by a table for each subclass. Each object (with very few
1566 exceptions) therefore has 2 table entries. If there is nothing of interest to
1567 be defined, the entry may be a single zero byte.
1568
1569 The object properties file has a "header" consisting of a single 4-byte
1570 integer, 0x0000002d, purpose unknown to date.
1571
1572
1573 4.0 WEAPONS TABLE, class 0
1574 --------------------------
1575
1576 The generic weapon info begins at file offset 0x0004, and has 2 bytes per
1577 weapon to a total of 32:
1578
1579 0000 int8 If I were to hazard a guess, I might surmise that this was
1580 involved with firing rate
1581 0001 int8 This controls what types of clip the weapon takes.
1582 b0-3 clip types. There is a bit for each of a possible
1583 4 types within the subclass, if set the weapon
1584 accepts that clip (0-3)
1585 b4-7 clip subclass
1586 This byte is zero for energy weapons, of course.
1587
1588 In the following, a "common weapon information" structure refers to an 8-byte
1589 table as follows
1590
1591 0000 int16 Damage
1592 0002 int8 "Offence" value
1593 0003 int8 Damage type. This seems to be organised as a bitfield:
1594 01 impact
1595 02 energy
1596 04 EMP
1597 08 ion (the ion rifle has this bit set)
1598 10 gas
1599 20 tranq
1600 40 needle (SV needle darts and full-auto rounds)
1601 0004 int8 Seems to have to do with special effects. EMP weapons have 0x33
1602 here
1603 0005 int16 Not used in the main weapons table. Seems to be used for
1604 critter attack descriptions
1605 0007 int8 Armour penetration
1606
1607
1608 4.0.0 SEMI-AUTO WEAPON TABLE, class 0/0
1609
1610 There is no extra information on these, and the table consists of 5 zero bytes.
1611
1612
1613 4.0.1 SEMI-AUTO WEAPON TABLE, class 0/1
1614
1615 There is no extra information on these, and the table consists of 2 zero bytes.
1616
1617
1618 4.0.2 PROJECTILE WEAPON TABLE, class 0/2
1619
1620 This table contains 16 bytes per weapon in this subclass, 32 in total:
1621
1622 0000 8byte common weapon info
1623 0008 int8
1624 0009 int32 Projectile class/subclass/type
1625
1626
1627 4.0.3 MELEE WEAPON TABLE, class 0/3
1628
1629 This table contains 13 bytes per melee weapon, 26 in total:
1630
1631 0000 8byte common weapon info
1632 0008 int8 Energy usage
1633 0009 int8 ?? kickback ??
1634 000a int8 ?? Range ??
1635
1636
1637 4.0.4 ENERGY BEAM WEAPON TABLE, class 0/4
1638
1639 This table seems to have the same values as the melee weapons table above.
1640
1641
1642 4.0.5 ENERGY PROJECTILE WEAPON TABLE, class 0/5
1643
1644 This table contains 18 bytes per projectile weapon, 36 in total:
1645
1646 0000 8byte common weapon info
1647 0008 int8 Energy usage
1648 000d int32 Projectile class/subclass/type
1649
1650
1651 4.1 AMMO CLIP TABLE, class 1
1652 ----------------------------
1653
1654 The generic ammo clip info begins at file offset 0x00B0, and has 14 bytes per
1655 ammo clip to a total of 210:
1656
1657 0000 8byte common weapon info
1658 0008 int8 No. rounds per clip
1659 0009 int8 ?? kickback ??
1660 000a int16
1661 000c int8 ?? Range ??
1662 000d int8
1663
1664 The "specific" info for ammo clips just consists of a single zero byte each.
1665
1666
1667 4.2 PROJECTILE TABLE, class 2
1668 -----------------------------
1669
1670 The generic projectile info begins at file offset 0x0191, and has 1 byte per
1671 projectile.
1672
1673
1674 4.2.0 TRACER TABLE, class 2/0
1675
1676 This table has 20 bytes reserved for each projectile in this class, to a total
1677 of 120. In the file objprop.dat they are all zero.
1678
1679
1680 4.2.1 PROJECTILE TABLE, class 2/1
1681
1682 This table contains 6 bytes per projectile in this class, to a total of 96.
1683 These control the cyberspace model colour scheme. Naturally they are only used
1684 for the c/space projectiles.
1685
1686
1687 4.2.2 class 2/2
1688
1689 This table has a single zero byte for each object in this class, 2 in all.
1690
1691
1692 4.3 GRENADES / EXPLOSIVES TABLE, class 3
1693 ----------------------------------------
1694
1695 The generic explosives info begins at file offset 0x0283, and has 15 bytes per
1696 explosives type, to a total of 120.
1697
1698 0000 8byte common weapon info
1699 ...
1700
1701
1702 4.3.0 GRENADES TABLE, class 3/0
1703
1704 This table has a single zero byte for each object in this class, 5 in all.
1705
1706
1707 4.3.1 EXPLOSIVES TABLE, class 3/1
1708
1709 This table has 3 bytes for each object in this class, to a total of 9.
1710
1711
1712 4.4 PATCHES TABLE, class 4
1713 --------------------------
1714
1715 The patch info begins at file offset 0x0309.
1716 Generic: 22 bytes, all zeros.
1717 Specific: 1 byte, all zeros.
1718
1719
1720 4.5 HARDWARE TABLE, class 5
1721 ---------------------------
1722
1723 Beginning at file offset 0x03AA.
1724 Generic: 9 bytes, all zeros.
1725 Specific: 1 byte, all zeros.
1726
1727
1728 4.6 SOFTS TABLE, class 6
1729 ------------------------
1730
1731 Beginning at file offset 0x0440.
1732 Generic: 5 bytes, all zeros.
1733 Specific: 1 byte, all zeros.
1734
1735
1736 4.7 FIXTURES TABLE, class 7
1737 ---------------------------
1738
1739 Beginning at file offset 0x04C4.
1740 Generic: 2 bytes, all zeros.
1741 Specific: 1 byte, all zeros.
1742
1743
1744 4.8 ITEMS TABLE, class 8
1745 ------------------------
1746
1747 The common items info begins at file offset 0x05ab and has 2 bytes per item in
1748 class 8, to a total of 160 - all zeros.
1749
1750 4.8.0 JUNK class 8/0 0x064b 8x1 bytes - zero
1751 4.8.1 DEBRIS class 8/1 0x0653 10x1 bytes - zero
1752 4.8.2 CORPSES class 8/2 0x065d 15x1 bytes - zero
1753 4.8.3 ITEMS class 8/3 0x066c 6x1 bytes - zero
1754 4.8.4 ACCESS CARDS class 8/4 0x0672 12x1 bytes - zero
1755
1756 4.8.5 CYBER ITEMS TABLE, class 8/5
1757
1758 This table begins at objprop.dat offset 0x067e and contains 6 bytes per cyber
1759 item, 72 in all, containing the colour scheme for each.
1760
1761 4.8.6 STAINS class 8/6 0x06c6 9x1 bytes - zero
1762 4.8.7 QUEST ITEMS class 8/7 0x06cf 8x2 bytes - zero
1763
1764
1765 4.9 SWITCHES TABLE, class 9
1766 ---------------------------
1767
1768 The common switch table begins at objprop.dat offset 0x06df and has but a
1769 single zero byte per switch object, to a total of 35.
1770
1771 There is NO table for vending machines class 9/4, and no space allotted in
1772 objprop.dat . These don't appear in the game and were obviously an intended
1773 element that didn't make it.
1774
1775 4.9.0 SWITCHES class 9/0 0x0702 9x1 bytes - zero
1776 4.9.1 RECEPTACLES class 9/1 0x070b 7x1 bytes - zero
1777 4.9.2 TERMINALS class 9/2 0x0712 3x1 bytes - zero
1778 4.9.3 PANELS class 9/3 0x0715 11x1 bytes - zero
1779 4.9.4 VENDING class 9/4 ------ ---
1780 4.9.5 CYBERTOGGLES class 9/5 0x0720 3x1 bytes - zero
1781
1782
1783 4.10 PORTALS (DOORS, GRATINGS) TABLE, class 10
1784 ----------------------------------------------
1785
1786 Beginning at file offset 0x0723.
1787 Generic: 1 byte, all zeros.
1788 Specific: 1 byte, all zeros.
1789
1790
1791 4.11 ANIMATED TABLE, class 11
1792 -----------------------------
1793
1794 Beginning at file offset 0x0775.
1795 Generic: 2 bytes
1796
1797 0000 uint16 unknown
1798
1799
1800 4.11.0 ???? class 11/0 9x1 bytes - zero
1801 4.11.1 ???? class 11/1 11x1 bytes - zero
1802
1803 4.11.2 ????, class 11/2
1804
1805 This table contains 1 byte per animated in this subclass:
1806
1807 0000 byte unknown
1808
1809
1810
1811 4.12 MARKER TABLE, class 12
1812 ---------------------------
1813
1814 Beginning at file offset 0x07DB.
1815 Generic: 1 byte, all zeros.
1816 Specific: 1 byte, all zeros.
1817
1818
1819 4.13 CONTAINER TABLE, class 13
1820 ------------------------------
1821
1822 Beginning at file offset 0x0801.
1823 Generic: 3 byte, all zeros.
1824 Specific: 1 byte, all zeros.
1825
1826
1827 4.14 CRITTER TABLE, class 14
1828 ----------------------------
1829
1830 Beginning at file offset 0x08B9.
1831 Generic: 75 bytes per critter (!):
1832
1833 0000 75byte unknown
1834
1835
1836 4.14.0 ???? class 14/0 9x1 bytes - zero
1837 4.14.1 ???? class 14/1 12x2 bytes - zero
1838
1839 4.14.2 ????, class 14/2
1840
1841 0000 uint16 unknown
1842
1843 4.14.3 CYBER, class 14/3
1844
1845 0000 6byte colour scheme
1846
1847 4.14.4 ???? class 14/4 2x1 bytes - zero
1848
1849
1850 4.15 COMMON OBJECT PROPERTIES
1851 -----------------------------
1852
1853 The very last table in the file is the common object properties; every object
1854 in the game has an entry here, 27 bytes per object (476 in total):
1855
1856 0000 int32 ??? mass (in units of 100g)
1857 0004 int16 hitpoints
1858 0006 int8 armour
1859 0007 int8 render type
1860 01 3D object
1861 02 sprite
1862 03 screen
1863 04 critter
1864 06 fragments (e.g. the Cyberdog)
1865 07 not drawn
1866 08 oriented surface (door, wall decoration)
1867 0B special case handling required
1868 0C force door
1869 000e int8 vulnerabilities. This has the same bit values as the weapon
1870 "type" field
1871 000f int8 Special vulnerabilities. This relates to the "special effects"
1872 field of the weapon descriptions. Some objects are
1873 particularly vulnerable to certain types of weapon, e.g.
1874 magpulse+robots.
1875 0012 int8 "defence" value
1876 0014 int16 flags
1877 0001 inventory object (main or access card)
1878 0002 touchable (something interesting happens when touched;
1879 projectile / pushable / melee
1880 0010 consumable; inv. item is consumed when used
1881 0020 blocks 3d (door) when shut i.e. is opaque, don't bother
1882 drawing behind it
1883 0100 solid but openable i.e door
1884 0200 solid, can't be walked or fallen through
1885 0400 ?? set for some explosions
1886 0800 explodes on hit; missile or live grenade
1887 0016 int16 3D model: index, in obj3d.res
1888 0019 int8 b4-7 no. extra frames
1889
1890 Some notes on render type: 3D objects use the model information from chunk
1891 (2300 + "3D model" field). Critters are drawn as sprites, but with the
1892 appropriate frame based on orientation and state. "Fragments" objects have 2
1893 bitmaps. The first contains the colour information for the fragments. The
1894 second gives the z position of each fragment: it is a grey-scale bitmap with
1895 the shade of grey (offset from colour 0xd0) giving the z value.
1896
1897
1898 5 MUSIC
1899 -------
1900
1901 The in-game music in System Shock is context specific, which means the music
1902 adapts to where you are and what you do (or happens to you).
1903 To achieve this, the music is split up into sequences that can be joined
1904 dynamically. System Shock not only does this, but also dynamically lays
1905 several sequences (of different types) over each other, adding variety.
1906
1907 5.0 Music files
1908 ---------------
1909
1910 The music files (.xmi) are XMIDI files for the Miles sound system - pretty
1911 much common in games of the 90s.
1912 Some files contain only one sequence - these are for movies and main menu.
1913 The in-game files are named "thm??.xmi" - The ?? do not match
1914 to the corresponding level number, but, as the name suggests, are theme indices
1915 (See Tile info above).
1916
1917
1918 5.0.1 Theme listing
1919 -------------------
1920
1921 0: Only technical chirps; flight deck hangars come to mind
1922 1: Medical level
1923 2: Level 6
1924 3: Level 2
1925 4: Level 5 & 7
1926 5: Nature (Groves)
1927 6: Bridge?
1928 7: Elevator. Without doubt.
1929 10: Cyberspace
1930
1931
1932 5.1 Music descriptor files
1933 --------------------------
1934
1935 For each of the theme files, corresponding .dat and .bin files exist,
1936 describing the sequences.
1937
1938 ff1: I don't exactly know why there are two descriptor files (with different
1939 endings) - my best guess is that one is read by the Miles sound engine, and
1940 the other by the game.
1941
1942
1943 5.1.1 Theme descriptor file .dat
1944 --------------------------------
1945
1946 A flat binary file, with sequence specific descriptors:
1947
1948 0000 int8 Amount of sequences
1949 0001 int8 Unknown -- always 0x01
1950 0002 n*16*byte Sequence descriptor. Note: Not all files contain the proper
1951 number of descriptors. Best guess is that the missing are not used.
1952
1953 Sequence descriptor:
1954 0000 int8 ???? often equal to byte at offset 0001
1955 0001 int8 ???? often equal to byte at offset 0000
1956 0002 byte always 0x00
1957 0003 int16 ????
1958 0005 int8 always 0x0A -- could be length identifier of following array
1959 Note: thm10.dat, last one has 0x00
1960 0006 10*int8 ???? contents in the range of [0x00..0x04]
1961
1962
1963 5.1.2 Theme descriptor file .bin
1964 --------------------------------
1965
1966 Also a flat binary file, always a size of 405 bytes, that groups the sequences
1967 to theme groups.
1968 In-game there is one 'main' music track and a number of background voices.
1969
1970 The main track has three groups:
1971 - Idle, quiet sequences; Played when strolling around empty areas
1972 - Tension sequences; Played with enemies nearby
1973 - Action sequences; During fights
1974
1975 The number and identity of background voices has not been fixed as of yet,
1976 but the following factors may be of relevance and need to be determined:
1977 - Remodelled areas (tiles) -- see remodelled flag at Tile structure
1978 - Machinery/Electrics nearby
1979
1980 The file seems to be split into three parts:
1981 - Main track infos
1982 - background voices
1983 - unknown data?
1984
1985 At least the bytes of the first two parts specify the indices of a music
1986 sequence. If set to 0xFF the slot is not used.
1987
1988 File data, first part:
1989 0000 - 000F up to 16 entries for quiet sequences
1990 0010 - 0017 up to 8 entries for tension
1991 0018 - 001F up to 8 entries for action
1992 0020 - 0020 one (optional) entry for startup sequence (new game, load game)
1993 0021 - 0022 unused, always 0xFF
1994 0023 - 0023 Death sequence
1995 0024 - 0024 Revival sequence (?) - not always set (makes sense)
1996 0025 - 0028 unused, always 0xFF
1997
1998 File data, second part; 32 entries of 10 bytes length:
1999 0029 - 0032 background voice; basic theme; note that some have the health alarm there?
2000 0033 - 003C mainly one-note piano beats; space? some with alarm?
2001 003D - 0046 sounds a bit eery; another background voice?
2002 0047 - 0050 one-note piano beats -- slightly different than the other group
2003 0051 - 0096 7x10 unused (0xFF)
2004 0097 - 00A0 always 5 entries, always the same: the health alarm
2005 00A1 - 00AA faster health alarm
2006 00AB - 00BE 2x10 unused (0xFF)
2007 00BF - 00C8 mechanical beats (some with alarms?)
2008 00C9 - 00D2 unused (0xFF)
2009 00D3 - 00DC always 5 entries, background for tension change (raising tension?)
2010 00DD - 00E6 always 5 entries, background for tension change (falling tension?)
2011 00E7 - 0122 6x10 unused (0xFF)
2012 0123 - 012C only set for thm0 -- one entry with mechanical beat
2013 012D - 0136 thm0
2014 0137 - 0140 thm0
2015 0141 - 014A thm0
2016 014B - 0154 thm0
2017 0155 - 0168 2x10 unused (0xFF)
2018
2019 File data, third part; Unknown:
2020 0169 - 0194 ???? -- bytes are set [0x01..0x05 or ..0x07], 0x00 only at the end
2021
2022
2023 5.2 Trivia
2024 ----------
2025
2026 Common sequences (health alarm, death, ...) are often around the same index,
2027 so they are easy to spot in the .bin files.
2028
2029 It is interesting that not all sequences (with meaningful data) are used
2030 according to .bin files.
2031
2032 The elevator theme has only the idle group set; No tension, fight or background
2033 voices set (only exception is the death sequence of course). So, regardless
2034 what happens to you in the elevator, you get that soothing melody ;)
2035
2036
2037 5.x Work in Progress
2038 --------------------
2039
2040 Background voices often come in groups of 5 or 7 sequences, yet sometimes
2041 there doesn't appear to be meaningful data in them (some contain the health
2042 alarm -- why?)
2043
2044 Are sequences played in the same order they are specified in their group or
2045 does something affect the order?
2046
2047 The contents of the 10 bytes in the .dat files seem a bit gaussian distributed;
2048 Also, their sum is close to the first two bytes of the sequence descriptor...
2049
2050
2051
2052 --------------------------------------------------------------------------
2053
2054
2055 The texture properties file, textprop.dat
2056 -----------------------------------------
2057
2058 This is not a resource file, but a flat file containing an 11-byte record for
2059 each texture in the game, structured as follows:
2060
2061 0001 int8 Starfield control (for station windows)
2062 0002 int8 Animation group
2063 0003 int8 Animation index (within group)
2064 0004 int8 \ These are usually the same as the low byte of the texture no.
2065 0005 int8 /
2066 0006 int32 Always 10
2067 000A int8 Climbable flag (1 for e.g. ladders and vines)
2068
2069
2070 The 3D model file, obj3d.res
2071 ----------------------------
2072
2073 This file contains the model definitions for all 3D objects (not sprites).
2074 Each model lives in its own chunk, of type 0x0F, of which it is subchunk 0.
2075
2076 Coordinates are (apparently) stored as 24.8 fixed-point numbers.
2077
2078 The model header consists of 8 bytes, followed by the instructions on how to
2079 draw the object:
2080
2081 0006 int16 no. faces
2082
2083 Models appear to be based around drawing commands:
2084
2085 0000 end of sub-hull
2086 0000 int16 command = 0x0000
2087
2088 0001 define face:
2089 0000 int16 command = 0x0001
2090 0002 int16 face length
2091 0004 3*fix normal vector
2092 0010 3*fix point on face
2093 001C ... face drawing commands
2094
2095 0003 define multiple vertices
2096 0000 int16 command = 0x0003
2097 0002 int16 no. vertices
2098 0006 3*fix first vertex
2099 0012 ... more vertices
2100
2101 0004 draw flat-shaded polygon:
2102 0000 int16 command = 0x0004
2103 0002 int16 no. vertices
2104 0004 n*int16 vertices (defined previously in file)
2105
2106 0005 set colour for flat shading
2107 0000 int16 command = 0x0005
2108 0002 int16 colour
2109
2110 0006 split plane??? this defines a plane and references 2 faces, but I don't know what
2111 it's actually for
2112 0000 int16 command = 0x0006
2113 0002 3*fix normal vector
2114 000E 3*fix point on face
2115 001A int16 left child offset (from start of this command)
2116 001C int16 right child offset (from start of this command)
2117
2118 000A define vertex:
2119 0000 int16 command = 0x000A
2120 0002 int16 vertex no. to define
2121 0004 int16 reference vertex
2122 0006 fix offset from reference in X direction
2123
2124 000B define vertex: as 0x000A except offset is in Y direction
2125 000C define vertex: as 0x000A except offset is in Z direction
2126
2127 000D define vertex: as 0x000A except 2 offsets X, Y
2128 000E X, Z
2129 000F Y, Z
2130
2131 0015 ??? define initial vertex
2132 0000 int16 command = 0x0015
2133 0004 3*fix vertex coords
2134
2135 001C define colour and shade
2136 0000 int16 command = 0x001C
2137 0002 int16 colour
2138 0004 int16 shade
2139
2140 0025 define texture mapping:
2141 0000 int16 command = 0x0025
2142 0002 int16 no. vertices
2143 0004 int16 vertex no. of first vertex
2144 fix texture u coord (fix16.16)
2145 fix texture v coord (fix16.16)
2146 000E int16 vertex no. of second vertex
2147 ...
2148
2149 0026 plot texture-mapped face:
2150 0000 int16 command = 0x0026
2151 0002 int16 texture no. (stored in citmat.res 475-525)
2152 0004 int16 no. vertices
2153 0006 n*int16 vertex numbers
2154
2155
2156
2157 vidmail.res
2158 -----------
2159
2160 Video mails. This file has 24 chunks:
2161 - the first 12 (id 0A40 to 0A4B)
2162 contain the frames in subchunks
2163 - the second 12 (id 0A4C to 0A57)
2164 are video information chunks (type 04) stored in
2165 one subchunk each
2166
2167 This I have yet found out about the videos:
2168 - a framerate of about 10 per second
2169 - some videos are split up into several parts (chunks)
2170 - the TriOp init jingle is id 0A4A (the first part
2171 always played)
2172 - the frames (bitmaps) contain huge areas of
2173 value 00 which means the previous pixel at
2174 this position has to be preserved.
2175 (ff1: But this is not always true as I found out...)
2176 - the video info structure should store the information
2177 about keyframes (if there are such)
2178
2179
2180 The video information structure (type 04)
2181 I yet don't know what everything means;
2182 it's of variable size since it contains a sub-table:
2183
2184 0000 int16 width of video (always 00C8)
2185 0002 int16 height of video (always 0064)
2186 0004 int16 corresponding chunk id of frames
2187 0006 6xint8 ?? always 00
2188 000C int16 ?? (TriOp jingle: 0001
2189 all other: 0000)
2190 000E nx5xint8 sub-table of n entries
2191 mmmm int16 'end tag' always 010C
2192
2193 The video info sub-table
2194 This table seems to determine how frames should be rendered.
2195 The from_ and to_ fields are inclusive;
2196 the first entry has from_frame = 0 and
2197 the last has to_frame = last frame
2198
2199 0000 int8 'video command' (my name for it, always 04)
2200 0001 int8 from_frame
2201 0002 int8 to_frame
2202 0003 int8 ?? render operation? (*)
2203 0004 int8 ?? flags? (contains 0x00 to 0x04) (*)
2204
2205 *) those last two bytes could be the frame time as Jim
2206 suggested - but if that is true, where is the information
2207 how frames are drawn?