Dark Seed platform comparison
Dark Seed was originally made for DOS but was ported to several different platforms over the following years.
Platform | Release year |
---|---|
DOS (floppy) | 1992 |
Amiga (floppy) | 1992 |
Macintosh (floppy) | 1993 |
Amiga CD32 | 1994 |
Macintosh (CD-ROM) | 1994 |
DOS (CD-ROM) | 1994 |
Windows 3.x | 1995 |
Sega Saturn | 1995 |
PlayStation | 1995 |
It seems that the Macintosh port was influential, and served as the basis for the Saturn and PlayStation.
Amiga
The Amiga (floppy disk) and the Amiga CD32 versions are technologically similar to each other, but quite different to the other platform ports.
The game uses a graphical resolution of 320x400 (interlaced) for both editions. It had fewer (wider) horizontal pixels than the DOS game and also a coarser palette (4 bits per color channel compared to the 6 bits that DOS VGA provided).
The CD32 version has many of the same files as the Amiga floppy disk version, although with many more voice samples.
Many of the files are compressed. The "MCP" header magic number is an indicator of compression, as is "MDCS".
Pictures
Files with that begin with the header magic number "MCP" (M's Compressed Picture, perhaps?) are, once decompressed, in a suitable format for blitting to the Amiga graphics hardware.
offset | value | used for |
---|---|---|
0-2 | 'M' 'C' 'P' | file type identification |
3 | 0x11, 0x14 | number of bitplanes (1 or 4) |
4-5 | 0x0100 | width |
6-7 | 0x00e5, 0x0074 | height |
The header is eight bytes. The low-order nybble of the fourth byte is either 1 or 4, and shows the count of bitplanes. A single bitplane file can be decompressed as a single stream.
The following two 16-bit values represent width and height respectively. The width is rounded up to the next multiple of 16 then divided by 8 and stored as a count of bytes per line. The height is multiplied by half of the width and the result is stored as the number of 16-bit words per bitplane. In the case of a single bitplane, that number (height times width-rounded-up divided by 16) is the number of words in the whole decompressed file.
In the case of multiple bitplanes, the decompression result is allocated first to the first (lowest-order) bitplane until it fills up (at a 16-bit word boundary). The next bytes to be decompressed fill up the second bitplane, until it fills up, and so on until all four are filled. These filled bitplanes are all the same size, and can be converted to so-called "chunky" format of one-byte-per-pixel palette indexes using an established "planar to chunky" conversion algorithm.
Here are the header bytes of some example files and their expected decompressed size:
approximate decompressed size | sizing bytes (hex) | |
---|---|---|
r00s | 7786 | M C P 11 . 01 10 . 00 e5 |
r00m | 7328 | M C P 11 . 01 00 . 00 e5 |
r00a | 29312 | M C P 14 . 01 00 . 00 e5 |
The compressed body (LZSS)
After the eight-byte MCP file header, the actual compressed bytes follow, starting with a byte of eight "control flags".
The compression is a kind of LZSS (Lempel-Ziv Storer-Szymanski) with some idiosyncracies. Some particular parameters:
- Control flags are stored in 8-bit sequences
- The most significant bit in the control flag byte controls the first item after the control byte
- The window is 4096 bytes, initially seeded with some particular
content:
- eight bytes of zeroes at offset 0
- 256 bytes of zeroes at offset 0x3e8 to 0x5e7 (1000 to 1255 decimal)
- 256 bytes of ascending values (0, 1, 2, ..., 255) starting at offset 1256
- A control flag set (1) means copy a single literal byte into the window
- The first byte written to the output buffer is written to the start of the window
- A control flag clear (0) means that the next two bytes are a reference
- References are two bytes arranged as a 12-bit offset, and a 4 bit length
- Reference lengths are 2-17 (low-order nybble of the second reference byte, plus one)
- Reference offsets are byte indexes into the 4096-byte window
- The reference bits are interpreted such that the two-byte reference 0xAB 0xCD is offset 0xCAD of length 0xB+1
Palettes
The Amiga floppy disk and Amiga CD32 version of Dark Seed both use 16-color (4-bit) palettes. Each of the 16 entries is a 16-bit number: 0xfff is bright white, 0x000 is pure black. The palettes are stored as data in the game executable rather than in a separate file.
There is a default palette and a table of 8 alternate palettes. The table of alternate palettes is 256 bytes: 8 palettes of 16 entries. There is a different table of data elsewhere in the executable which you can use to calculate which palette to load for each resource.
ID | Disk | Palette |
---|---|---|
"B1" | 1 | 0x00 |
"M00A" | 0 | 0xcb |
"N10L" | 3 | 0x12 |
"R10A" | 2 | 0x04 |
Resource IDs are 32-bit numbers that can also be treated as ASCII filenames.
Resources with a zero palette byte: No modification.
Resources with a "positive" palette byte (0x01-0x7e): Standard with modification. The second-highest palette entry is replaced with a value from a 63-entry lookup table.
Resources with a "negative"/high palette byte (0x80-0xff): A
specific alternate palette. The number of the alternate palette can
be calculated using (x + 5) % 8
where x
is the byte in the lookup table and %
is the remainder
after division.
Sprites
Object data
The Amiga game executable contains some of the same animation information that is called "Objt" in the Macintosh port.
- Byte: sprite number
- Byte: x
- Byte: y
- Byte: count1
- Byte: count2
Then a series of:
- byte: xdelta
- byte: ydelta
Sound and music
Sound effects
Short "sound" resources (a clock ticking, glass breaking, etc) are stored without compression in files called SD01, SD02, etc. These sounds are identical on the Amiga floppy disk and CD32 version, but the CD32 has one additional sound file (SD17).
These short files are "encoded" as PCM data using the "signed 8-bit" number format, plus a small 4-byte header at the start. The header bytes are simply:
offset | meaning |
---|---|
0-1 | magic number identfier ("SD") |
2-3 | uint16 (big-endian) size of the buffer to allocate |
4 | raw int8 PCM samples |
Voice/speech messages
Longer "voice" data is stored with the same compression
algorithm as the picture resources (LZSS) in files called
VC01
(for the Amiga floppy disk version) or
001.efx
(for Amiga CD32). The CD edition contains
hundreds of these voice files, replacing or supplementing almost
every message string in the game. The floppy disk edition has
merely 24 voice files for the player character interacting with
other humans (etc).
These long "voice" files are laid out in the following shape:
offset | meaning |
---|---|
0-3 | magic number identfier ("MDCS") |
4-7 | uint32 (big-endian) size of the buffer to allocate |
8 | LZSS compressed data |
Music
Music is stored in files matching the pattern MX00
,
and begin with the magic header "MXTX". This the same header as
MaxTrax module format, and in fact these files can probably be
played with a MaxTrax module player.
The mapping of which music plays in which room is stored in the game executable as a linear table of bytes.
Rooms
The "R01A" file holds the static picture for room 1 in the same format as the other game graphics.
Room data
Object data
String lists
The Amiga editions do not store string lists in separate files, but rather as data in the game executable file.
There are two string lists:
- a big one with response messages (?-997), matching the efx speech
- a small one with item names and credits (0-301)
Both the string lists are in the same "hunk" of the executable, the final hunk.
A string list is stored as a big block of strings are provided concatenated together without any dividing marker. After the strings have finished, there is a separate numerical list of each string's starting position within that concatenated block.
NothingBoxHandQuestionCtrlcrowbarjournalscotch
^ ^ ^ ^ ^ ^ ^ ^
0 7 10 14 22 26 33 40
string number | offset | string |
---|---|---|
0 | 0 | "Nothing" |
1 | 7 | "Box" |
2 | 10 | "Hand" |
3 | 14 | "Question" |
4 | 22 | "Ctrl" |
5 | 26 | "crowbar" |
6 | 33 | "journal" |
7 | 40 | "scotch" |
Movies
MDA (M00B)
The four resources called M00B, M01B, M02B, M03B each have the signature MDA and seem to represent full-screen animations.
These files have a header structure not unlike MCP.
The low-order nybble of the fourth byte (offset 3) is used for
the number of bitplanes. (All four files have the value 4 here, for
4 bitplanes). The higher-order nybble (always 1 in these files) is
used to calculate bytes ber bitplane with the following algorithm:
(x + 1) * 2
The next four bytes are interpreted as 16-bit integers (big-endian) are width and height. Always 320 width and 400 width.
The rest of the file is structured as follows:
- MSB word, COUNT, count of the upcoming chunk of data bytes
- one byte indicating which bitplanes to update
- another byte (padding, seemingly ignored)
- COUNT bytes of image data in "chunky" pixel format (one byte per pixel), horizontal line by line
Files
filename | magic | count on floppy/CD | purpose | format |
---|---|---|---|---|
B0 | "MCP" | 3 | border picture around room picture? | |
F0 | "MCP" | 2 | endgame failure pictures? | |
I0 | "MCP" | 2 | ||
R00A | "MCP" | 65 | room pictures | custom LZSS-style compress |
R00B | "MCP" | 48 | room sprites? | ? |
R00C | "MCP" | 10 | ? | ? |
R00D | "MCP" | 5 | ? | ? |
R00E | "MCP" | 1 | ? | ? |
R00F | "MCP" | 1 | ? | ? |
R00M | "MCP" | 60 | room data | ? |
R00S | "MCP" | 19 | ? | ? |
N00A | "MCP" | 5 | ||
N00B | "MCP" | 11 | ? | ? |
N00C | "MCP" | 1 | ? | ? |
N00D | "MCP" | 14 | dark | ? |
N00L | "MCP" | 16 | light | ? |
S0 | "MCP" | 2 | ||
W0 | "MCP" | 2 | ||
M00A | "MCP" | 3 | ||
M00B | "MDA" | 4 | full-screen animations? | |
MX00 | "MXTX" | 19 | Music | MaxTrax music modules like the Legend of Kyrandia |
SD00 | "MS" | 35/36 | sounds | 8-bit signed PCM at a fixed sample rate (around 8000) |
VC00 | "MDCS" | 24/0 | voice/speech | |
000.efx | "MDCS" | 0/670 | voice/speech | Same LZSS compression as MCP but with simpler, byte-size header |
Many of the files are exactly the same between the Amiga floppy disk version and the CD32 version. There may be some language-specific changes in pictures.
- All of the "mx" (music?) files match
- Most of the r files match but a limited set differ
- r10b (largely the same but some changes about 20% through that ripple through the compression)
- r11a
- r11b
- r15a
- r24a
- r64a
- Many of the single letter files match (b3, f1, f2, s1, s2, w1, w2)
- Many of the single-letter files differ (b1, b2, i1, i2)
- Most of the N files differ but a limited set match
- n01a
- n01b
- n03c
- n06l
- n15d
- n18a
- n18b
- n19a
- n19b
- n21d
- n22b
- n23b
- n23d
- n24b
- n24d
- n25b
- n25d
- n26b
- n30b
- Most SD (sound) files match but sd17 is only present on CD32
- Only the Amiga floppy version has VC files ("voice"?), only CD32 has ".efx" files
Macintosh
The Macintosh version seems to be adapted from the DOS version but significantly reworked for the platform.
It uses the Macintosh "resource" system for pretty much everything.
Resources in Dark Seed
ResType | # | names | purpose | format |
---|---|---|---|---|
"PicL" | 23 | "Library Card Light", "Save Screen Light" | Light pictures | |
"PicD" | 13 | "Library Card Dark", "Save Screen Dark" | Dark pictures | |
"Fram" | 6 | "LightFrame", "Nightmare 1 Frame" | Graphical frames surrounding other images | |
"pltt" | 95 | "ROOM08.PAL", "BNOC.PAL", "StdDarkPal" | palettes | |
"snd " | 97+ | "Boy, that's smooth", "short english horn" | Sound data | AIFF-style, encoded as PCM-u8 or MACE3 |
"Sprt" | 102 | "ASPIRIN.NSP", "ROOM08.NSP" | Sprite animations | |
"Rmdt" | 66 | "rmMasterBedroom", "rmFrontOfHouse" | Room data | Custom format described by a TMPL resource |
"Objt" | 106 | "ASPIRIN.OBT", "ROOM08.OBT" | Room object data | Custom format described by a TMPL resource |
"TMPL" | 2 | "Objt", "Rmdt" | Resource templates | Standard Macintosh template resource format with Resorcerer extensions |
"STR#" | 9 | "Credits", "English Item Strings" | Strings | Standard Macintosh string resource format (Pascal-count) |
"Movi" | 26 | "Nightmare 1c", "SpaceLetters c" | Animations | |
"Inst" | 40 | "Song 1 Instruments" | Instrument definitions for music | |
"Midi" | 20 | "Baby Doll Morph" | Music sequences | Standard MIDI file |
A credit image says "Darkseed Macintosh developed and programmed by Brian Fitzgerald", and that name appears in other credits.
It seems to have been built with "THINK C" and AppMaker, and some debugging/development information seems to have been left behind. (A happy accident for digital preservationists.) An icon says "THIS SPACE FOR RENT", presumably as a joke.
Templates
Macintosh resource management tools like ResEdit and the third-party Resorcerer use template resources (with the ResType "TMPL") to provide a convenient user interface for resource data.
The format of TMPL resources is documented in the official Macintosh ResEdit Reference from Apple, and the Resorcerer Template Information has information on some extended structures that Resorcerer provides.
Pictures
Dark Seed uses at least four different resource types for graphic data ("PicL", "PicD", "Fram", "Room"), but they all seem to be encoded in the same way.
It presumably uses compression, perhaps similar to the compression used in Dark Seed for DOS (nybble-based run-length encoding) or Dark Seed for Amiga (LZSS).
Palettes
Many resources with ResType "pltt" have names closely tied to the DOS version of Dark Seed ("ROOM04.PAL", "LIB-BABE.PAL"). The format seems to be a 16-bit big endian count of entries, then 16 bytes for each entry. An entry is mostly zeroes. Three of the bytes are not zero, and I presume then to be a byte each for red, green and blue.
Most of the palettes seem quite similar to each other, or even exactly the same.
Sprites
The resources with ResType "Sprt" are sprite animations.
They have names quite closely tied to the DOS version of Dark Seed ("ASPIRIN.NSP", "RM10STAIRS.NSP", "ROOM04.NSP") and are often similar in size to the DOS editions too. They presumably represent much the same data as the DOS ".NSP" files but have such different byte values that the data must be structured differently.
Rooms
The "Room" resources appear to hold the per-room static picture in the same format as the other game graphics.
Room data
The resource templates tell us the structure to interpret "Rmdt" room data:
one-based count for list of links, where each item has:
- destination (UBYT, unsigned decimal byte) - presumably room number
- direction (UBYT, with four cases: enum up=0, right=1, down=2, left=3)
- x and y (each a DWRD, decimal word)
- width and height (each a UBYT)
one-based count for list of objects, where each item has:
- type (UBYT, unsigned decimal byte)
- object (UBYT)
- object x, y, width, height (each a DWRD, decimal word)
- depth (UBYT)
- sprite (UBYT)
one-based count for list of polygon points, where each item has:
- point ("PNT ", 4-byte QuickDraw point)
Object data
The resource templates tell us the structure to interpret "Objt" object data:
- one-based count for list of objects, where
each item has:
- one-based count for list of frames, where each
item has:
- x vector and y vector (each a DWRD, decimal word)
- sprite (DBYT, decimal byte)
- ticks (DBYT)
- one-based count for list of frames, where each
item has:
String lists
The game contains string lists as standard Macintosh "STR#" resources.
One list (resource ID 301, named "English item strings") contains the names of game objects in what seems to be the same order as code (crowbar=5, journal=6, scotch=7).
The credits mention separate teams for "IBM" and Macintosh. The game strings include some leftover DOS-specific values like mentioning "Soundblaster".
Movies
The resources with the ResType "Movi" are presumably the bigger animations.
They have somewhat descriptive names ("Nightmare 1a", "SpaceLetters d"), with only a few kinds of name:
- Nightmare
- SpaceLaunch
- SpaceLetters
- SpaceLand
In addition, one of the "Movi" resources (ID 131) seems to have been blanked out. It is named "-- Nightmare 2 --" and has a single byte (0xDD) as its entire content.
Sound and music
Speech and sound effects are stored as AIFF "snd " resources, as are the instrument samples that are arranged into music. Two codecs are used: raw unsigned 8-bit PCM (codec identifier "raw ", with the space) and the less-common Macintosh Audio Compression/Expansion 3:1 (codec identifier "MAC3").
The sequence and timing of notes to play is stored as standard MIDI data in "Midi" resources. The selection of instruments are stored in "Inst" resources.
The resource templates tell us the structure to interpret "Inst" instrument data:
- one-based count for list of instrument
definitions, where each item has:
- 'snd ' resource (DWRD, decimal word) - presumably resource ID
- Fixed pitch (0=none) (DWRD)
- Loop enable (BOOL, boolean byte)
- Voice enable (BOOL)
SEGA Saturn
Dark Seed was released in Japan for the SEGA Saturn around the same time as Dark Seed for PlayStation.
It seems to be based on the Macintosh version and uses some of the same file formats.
Same or similar to the Macintosh formats:
Pattern | Purpose | Format |
---|---|---|
MV000.MOV | Movies? | Similar/same format as Macintosh "Movi" movies |
OB000.OBJ | Objects? | Same format as Macintosh "Objt" objects |
SP000.SPR | Sprites? | Same format as Macintosh "Sprt" sprites |
ST000.STR | Strings, not PlayStation CD-stored media | Same format as Macintosh "STR#" string lists |
RM000.PIC | Room pictures | Same format as Macintosh "Room" graphics |
RD000.RMD | Room data | Exactly the format of Macintosh "Rmdt" |
Exactly the same data bytes as the PlayStation:
Pattern | Purpose | Format |
---|---|---|
MV000.MOV | movie? | |
KANJI.FON | font (kanji) | |
KANA.FON | font (kana) | |
DS.MP | ? |
Saturn-specific formats:
Pattern | Purpose | Format |
---|---|---|
SQ000.SEQ | music sequence | Saturn SEQ format |
TN???.TON | music instrumentation | Saturn TON format |
0000.PCM | sound | raw signed 8-bit PCM at a fixed sample rate (11025 Hz?) |
The TON data is also on the PlayStation release but may be unused - the PlayStation-standard format sound banks (VAB) are present in the PlayStation release.
Comparison count:
Saturn | pattern | PSX | pattern | similarity |
---|---|---|---|---|
1 | ds.mp | 1 | ds.mp | byte-identical |
1 | kana.fon | 1 | kana.fon | byte-identical |
1 | kanji.fon | 1 | kanji.fon | byte-identical |
4 | fr???.pic | 4 | fr???.pic | byte-identical |
9 | st???.str | 9 | st???.str | byte-identical |
13 | pd???.pic | 13 | pd???.pic | byte-identical |
17 | tn???.ton | 17 | tn???.ton | byte-identical |
17 | .seq | 19 | .seq | totally different |
19 | .vab | |||
22 | mv???.mov | 22 | mv???.mov | byte-identical |
24 | pl???.pic | 24 | pl???.pic | byte-identical |
42 | se??.pcm | |||
48 | sp????.spr | 48 | sp????.spr | byte-identical |
49 | ob????.obj | 49 | ob????.obj | |
52 | ob???.obj | 52 | ob???.obj | |
54 | sp???.spr | 54 | sp???.spr | byte-identical |
66 | rd????.rmd | 66 | rd????.rmd | byte-identical |
66 | rm????.pic | 66 | rm????.pic | byte-identical |
68 | ???.pcm | |||
616 | ????.pcm | 672 | ???.pcm | totally different |
SONY PlayStation
Dark Seed was released in Japan for the original PlayStation.
It seems to be based on the Saturn version and even includes some instrumentation sounds in Saturn-format TON files as well as the PlayStation-format VAB files that it actually uses.
The data is stored as records in an "AFS" archive volume (.VOL) with an index (.IDX) of offsets and lengths.
Some files are the same or similar to the Macintosh formats:
Pattern | Purpose | Format |
---|---|---|
MV000.MOV | Movies? | Similar/same format as Macintosh "Movi" movies |
OB000.OBJ | Objects? | Same format as Macintosh "Objt" objects |
SP000.SPR | Sprites? | Same format as Macintosh "Sprt" sprites |
ST000.STR | Strings | Same format as Macintosh "STR#" string lists |
RM000.PIC | Room pictures | Same format as Macintosh "Room" graphics |
RD000.RMD | Room data | Exactly the format of Macintosh "Rmdt" |
(Note that STR files here are strings, not the PlayStation "stored media" format.)
These files are specific to the PlayStation:
Pattern | Purpose | Format |
---|---|---|
.SEQ | Music sequence | PlayStation standard SEQ |
.VAB | Music instrumentation (sound banks) | PlayStation standard VAB |
.PCM | Sound/speech | PlayStation standard VAB (despite name) |
Strings
The strings are in the same format as Macintosh "STR#" resources: a 16-bit count for the number of strings, followed by a length byte for the first string, followed by the first string's characters, then the length byte for the second string, then the second string's characters, and so on. The text is encoded with Shift-JIS, a widely-used standard for Japanese text at the time. The Japanese PlayStation resource ST301.STR corresponds with "STR#" resource number 301 (named "English Item Strings" in the English Macintosh release):
Mac "STR#" 301 | ST301.STR |
---|---|
"nothing" | "無" ('nothing') |
"Box" | "箱" ('box') |
... | ... |
"newspaper" | "新聞" ('newspaper') |
"table" | "テーブル" ('table') |
"bottom of bed" | "ベッドの下" ('bottom of bed') |