Dark Seed platform comparison

Dark Seed was a point-and-click adventure game from 1992. It 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. The Amiga floppy disk version served as the basis for the Amiga CD32 version. The DOS floppy disk version served as the basis for the DOS CD-ROM version.

I haven't been able to examine the version released in Japan for Windows 3.1 to compare it with the DOS CD-ROM version.

DOS floppy DOS CD Amiga Macintosh Saturn PlayStation
Frame/border *FRAME.PIC *FRAME.PIC B1/B2/B3 Fram
Room picture ROOM*.PIC ROOM*.PIC R*A Room .PIC .PIC
Non-room picture *.PIC *.PIC N*A PicL, PicD
Music .SBR, .SIT .MID MX* Midi, Inst .TON, .SEQ .VAB, .SEQ
Sound effects .DIG .SFX SD* snd .PCM
Speech .VOC .VOC VC* , *.efx snd .PCM .PCM
Room moveability mask .ROM .ROM R*M
Fonts N03A, I* BFnt .FON .FON
Pointer images DS CURS DS.MP? DS.MP?
Inventory images I*
Room connections .ROM .ROM Rmdt .RMD .RMD
Object locations .ROM .ROM Rmdt .RMD .RMD
Sprite stencil/mask S*, R*S
Per-room sprites ROOM*.NSP ROOM*.NSP R*B, R*C, R*E, R*F Sprt .SPR .SPR
Sprite images .NSP .NSP N*B, N*C, W*, F* Sprt .SPR .SPR
Sprite positions and animation DS Objt
Frame-based animation .IMG, .ANM .IMG, .ANM M*A, M*B Movi .MOV .MOV
Palettes .PAL .PAL DS pltt
Messages TOSTEXT.BIN TOSTEXT.BIN DS STR# .STR .STR
Strings TOS.EXE TOS.EXE DS STR# .STR .STR
Credits START.EXE START.EXE DS STR# .STR .STR

DOS

Dark Seed for DOS seems to be based on a game engine (or entire game?) called "TOS", presumably the work of programmer Lennard Feddersen. From the manual:

The programming aspects required two programmers, Lennard Feddersen, who had been developing an engine for this type of game since September, 1990, and John Krause who constructed the promotional disk and the nightmare and title sequences.

There are several remnants of TOS in the Dark Seed for DOS files: the main game executable is called TOS.EXE and most of the strings in the game appear in TOSTEXT.BIN. A dragon-based logo for TOS as well as some icons for an editing tool are in the file TOSICONS.SPR which the Dark Seed game does not use at play-time (and were not included in all versions). Depending on version, there are also support files TOSFONT.OBT, TOSFONT.NSP, TOSICONS.SPR, TOSSTD.PAL.

The two programmers seem to have worked on two separate executables, with the "nightmare and title sequences" handled in START.EXE and the actual gameplay handled in TOS.EXE. The batch script START.BAT ties the two together so that when one exits the other begins.

Pictures

Dark Seed for DOS uses a somewhat unusual VGA graphics mode: 640x350 with 16 colors. The manual explains how this was negotiated with artist H R Giger:

Giger agreed to lend his artwork, provided Cyberdreams uses only high-resolution graphics mode, in order to avoid the "square and jagged" look of low resolution.

The two programs by (START.EXE and TOS.EXE) by the two separate programmers (Krause and Feddersen, respectively) each use their own image formats. START.EXE uses files called ".IMG" while TOS.EXE uses ".PIC" instead.

Still images

The picture files (".PIC") are compressed with a nybble-based run-length encoding scheme. Consider the file as a stream of 4-bit values, with each byte in the file representing two distinct 4-bit values: first the low-order nybble (x & 0xf), then the high-order nybble (x >> 4). This stream of values can then be interpreted as a sequence of "runs", either:

  • nybble representing the length of a solid run, followed by a single value to be repeated for that length, or
  • nybble representing the length of a literal run, followed by that many literal nybbles

Literal runs of length n + 1 are represented with the value n. So a value of 7 means the next 8 nybbles are literals (the longest literal run that this scheme can represent).

Solid runs of length n are represented with the sign-extended value -n + 1 (or, equivalently, 17 - n). So the value 8 (-7) means the next nybble is repeated 9 times, while the value 15 (-1) means that the next nybble is repeated twice.

IMG files

John Krause's START.EXE uses IMG files which are in a format similar to PIC but quite distinct from it. The compression is byte-based rather than nybble-based, and they have some header information at the start.

The file begins with a a two-byte header: uint16le size of the decompressed buffer. After decompressing, the decomprssed data begins with a five-byte header: height (in rows, uint16), bytes per row (uint16), and mode (int8).

Animations

This section is a stub.

START.EXE uses image (IMG) and animation (ANM) files, while TOS.EXE uses picture (PIC) and (NSP).

PREFS Description Resource names
E Ship leaves? left
H Third nightmare nm3
Y Born born
C Valves valves.anm
D Doll/embryo bdoll, embryo
G Doll/book bdoll, book
B Mirror/Dark Mike dmik
Z End
I Intro

Sprites

This section is a stub.

NSP files (aNimated SPrite?)

Palettes

The palettes are stored in files with the extension ".PAL". The format is straightforward and maps very closely to VGA hardware. There are two sizes: most are 16-color palettes (stored as 48 bytes), and also a few 256-color palettes (stored as 768 bytes) but these seem to be unused in the game.

Each of the sixteen entries is three bytes: one byte for red, one byte for green, one byte for blue. The maximum value is 63. Thus pure white is represented as (63, 63, 63), pure black as (0, 0, 0).

Each room has its own palette file but many of them are complete duplicates.

Sound and music

Later (CD-ROM) versions of Dark Seed for DOS used standard MIDI files for music and Creative Labs "Voice" files for sound effects and speech. The speech files have the usual ".VOC" file extension and the sound effects use the alternative ".SFX" name.

Earlier (floppy) versions of Dark Seed for DOS provided music and sound in other formats to work with various hardware at the time. The three options are the basic PC speaker, AdLib, and Sound Blaster.

Music

This section is not fully researched.

Musical sequences are in SBR files and the instrument definitions are in a matching SIT file. There are also some PCS files, too, but they are loaded even when using SoundBlaster or AdLib sound, suggesting they are not just for the simple "PC speaker".

There are some DIG files to match many of the music pieces. Presumably these are "digital sound" definitions of some sort.

In PC Speaker mode, the PCS and DIG files are loaded together.

  • TOS1.NAM contains musical instrument names

SBR musical sequences

This section is not fully researched.

SBR files are laid out in tracks. The first byte is something that applies to the whole track, perhaps instrument number. Then follows a series of six-byte tuples. The musical note is the sixth byte, and the track ends when that byte is zero.

Thus a sequence of mostly-ascending bytes like the following:

01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 00 13 14 15 16 17 18 00

can be interpreted like the following four notes across two tracks:

channel? volume? ?? duration? percussion? voice? pitch?
01 02 03 04 05 06 07
(01) 08 09 0a 0b 0c 0d
(01) 0e 0f 10 11 12 00 (end)
13 14 15 16 17 18 00 (end)

Pitch seems to be MIDI-style, with middle C note at decimal 60 and 61 a semitone above that. A pitch of zero ends the track (the first two values are also treated as zeroes for this case). A rest seems to be indicated with a pitch of 02.

The second column is almost always zero, but sometimes there are some non-zero values at the start (like 02) or at the end (like 05). A 02 at the start is sometimes followed by 08 or 09, but usually 00 or 02. No values are higher than 09.

The third column appears to be duration/delay. Presumably there is a tempo somewhere or all the files use the same interpretation of delay.

The fourth column is also usually zero, and never more than 09, but it has wider variety of values and patterns. A few tracks have 01 at somewhat regular intervals, sometimes even a series of 010101... Perhaps it is a percussion line?

The fifth column is sometimes all zeroes but is usually a single value repeated for the entire length. The value is never more than 0x6e (110). It sometimes ends with 05 and sometimes starts with 05 and perhaps another different byte after that. Perhaps it is instrument/voice number?

Speech

The recorded voice sounds provided in Creative Labs' "Voice" (.VOC) format (unsigned 8-bit PCM at 8000 Hz).

These are played properly in SoundBlaster mode, less well with AdLib, and presumably not at all with the PC speaker.

Sound effects

The earlier versions of Dark Seed for DOS distributed on floppy disk play sound effects as if they were short musical pieces, combined in the files called TOS1.nnn.

The instructions for playing the sound effects is in the same format as music and instruments. Sound effects for the PC speaker are presumably in TOS1.PCS.

  • TOS1.PCS
  • TOS1.SBR
  • TOS1.DIG

The file TOS1.NTE contains a list of 120 sound effect names as null-terminated strings. Some are blank or the string "FREE", and the first dozen or so are repeated later around position 90.

The later CD-ROM version of Dark Seed for DOS plays recorded sound files called .SFX but their contents are in the standard Creative Voice (.VOC) format. All the sounds are 8-bit unsigned PCM data. Most (45) of these SFX are at 22727 Hz, while a few (PULSAR, KNOCK, POP, and POPII) are at 11235 Hz. The sounds do not all perfectly correspond, either: for example, there is no footstep sound effect in the CD-ROM version

String lists

The credits text is embedded as data in START.EXE, and the names of objects are embedded as data in TOS.EXE. Most of the in-game messages are read from an TOSTEXT.BIN.

The format of TOSTEXT.BIN begins with an ordered series of little-endian uint16 offset values. Each one of these offset values point to the start of a text string later in the file. The offset value is an absolute position within the file.

The series of bytes at the start of the file:

a6 07 d4 07 f6 07 ...

Can be read as a series of little-endian integers:

  • 0x07a6
  • 0x07d4
  • 0x07f6

Which in turn can be used as file offsets to find a line of text:

0x07a6: "You have dared touch an Ancient! You die!\r\n"
0x07d4: "Fido takes a chunk of your head\r\n"
0x07f6: "The fleshy stalk"...

Trace

AdLib opens the following files:

  93091353: FILES:file open command 0 file art\house.pal
  93091404: FILES:file open command 0 file art\letters.anm
 116353477: FILES:file open command 0 file art\ship.pal
 116353531: FILES:file open command 0 file art\left00.img
 116633112: FILES:file open command 0 file art\left01.img
 116906072: FILES:file open command 0 file art\i001.img
 117059306: FILES:file open command 0 file art\shipin.anm
 117064602: FILES:file open command 0 file credits.sbr
 117481719: FILES:file open command 0 file credits.pcs
 117529891: FILES:file open command 0 file credits.sit
 141428741: FILES:file open command 0 file art\t2.anm
 157367052: FILES:file open command 0 file art\tm.img
 157368774: FILES:file open command 0 file art\version.img
 157385720: FILES:file open command 0 file art\letters.anm
 157385949: FILES:file open command 0 file art\bdoll0.img
 157385991: FILES:file open command 0 file art\bdoll1.img
 157386037: FILES:file open command 0 file art\house.img
 158404462: FILES:file open command 0 file art\title.img
 158610266: FILES:file open command 0 file art\version.img
 158627215: FILES:file open command 0 file art\house.pal
 222938144: FILES:file open command 0 file art\nm1.anm
 222938393: FILES:file open command 0 file art\ship.pal
 222982876: FILES:file open command 0 file art\nmf0.img
 223289229: FILES:file open command 0 file art\nmf1.img
 223585787: FILES:file open command 0 file art\nm101.img
 223993317: FILES:file open command 0 file implant.sbr
 224304486: FILES:file open command 0 file implant.pcs
 224397303: FILES:file open command 0 file implant.sit

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:
    • 256 bytes of descending values (255, 254, ..., 1, 0) starting at offset 0x3e8 (1000 decimal)
    • 256 bytes of ascending values (0, 1, 2, ..., 255) starting at offset 1256
    • everything else zero bytes (but probably not much of it referenced)
  • 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 0xABC of length 0xD+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

Smaller image overlays and updates are stored as flat images in the additional materials files. They are pictures in the same MCP (compressed picture) format as the room pictures.

The coordinates and parameters for which parts of the image data are used, as well as animation timing, live in the executable file (see Object data).

R00B stores the sprite image data for room 0, but not all rooms have such image data. Room 1 has none at all, while room 31 has several separate images for different sprites: R31B (stick), R31C (Delbert throwing), R31D (dog), R31E (Delbert walking and drinking), and R31F (Delbert standing).

The image data for player walking sprites is stored in the resource file W1 (light world) and W2 (dark world). Likewise, the image data for the player falling is stored in resources F1 (light world) and F2 (dark world).

The styled font used for the opening credit sequence is a sprite too, stored in N03A. The main font for message text in the game is stored in the same file as the inventory pictures: I1 (light world) and I2 (dark world).

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

The "R01M" file holds the movement mask for Mike, the player character, in room 1. It is a single-bitplane image the same size as the room picture, and distinguishes between the places Mike can move to (bit set) and cannot move to (bit clear). All (or at least most) rooms have a movement mask.

The "R01S" file doesn't exist because room 1 doesn't have a room-specific sprite stencil. It uses the general light-world sprite stencil S1. Room 5, the upstairs hall, does have a room-specific sprite stencil. It is a single-bitplane image the same size as the room picture. Only the pixel locations with bits set in the stencil will draw through. This allows a sense of layered depth, letting the sprites appear to go "behind" parts of the picture.

Object data

This section is a stub.

The locations of in-game clickable objects seem to be stored somewhere in the game executable, but I don't yet know the location or format.

Likewise, room connections are still unknown to me.

In both cases, I have a hunch that the data is in the same "hunk" of the executable as most of the game variables, but I haven't confirmed anything yet.

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

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 difference data for the frame in the format described below

Each frame is structured as follows:

  • changes for bitplane 0
    • five bytes (40 bits)
    • a series of byte-column row changes
  • changes for bitplane 1
    • five bytes (40 bits)
    • a series of byte-column row changes
  • changes for bitplane 2
    • five bytes (40 bits)
    • a series of byte-column row changes
  • changes for bitplane 3
    • five bytes (40 bits)
    • a series of byte-column row changes

Each bit in the five-byte stretch at the start of each bitplane represents a "byte column" (8 pixels) in the picture. If there are no changes to this bitplane in this frame, these bits will all be clear. If the first (highest-order) bit is set, the leftmost "byte column" has changes in this frame -- that is, some of the left-most 8 pixels have changed value.

For each column bit set, there will be a set of row updates. These follow in order directly after the byte column change summary.

  • count of upcoming row updates, each of which has:
    • byte (uint8) for row count which is is split:
      • high bit clear means changes are included
      • high bit set means no changes to row count rows
      • remaining bits are the actual row count (RC)
    • Series (length RC) of bytes of of data to be XORed

Files

filename magic count on floppy/CD purpose format
R00A "MCP" 1,4 65 room pictures custom LZSS-style compress
R00B "MCP" 1,4 48 room sprites ?
R00C "MCP" 1,4 10 ? ?
R00D "MCP" 1,4 5 alternate room sprites ?
R00E "MCP" 1,4 1 ? ?
R00F "MCP" 1,4 1 ? ?
R00M "MCP" 1,1 60 per-room movement mask (where the player can walk) compressed bitplane (1 bit per pixel)
R00S "MCP" 1,1 19 per-room stencil for sprite drawing ?
N00A "MCP" 1,4 5 misc pictures, font
N00B "MCP" 1,4 11 picture alternate sections ?
N00C "MCP" 1,4 1 ? ?
N00D "MCP" 1,4 14 pictures, dark ?
N00L "MCP" 1,4 16 pictures, light ?
B0 "MCP" 1,4 3 border picture around room picture
F0 "MCP" 1,4 2 falling sprites for player character
I0 "MCP" 1,4 2 inventory and game font
S0 "MCP" 1,1 2 per-world stencils for sprite drawing compressed bitplane (1 bit per pixel)
W0 "MCP" 1,4 2 walking sprites for player character
M00A "MCP" 1,4 3 movie start screens
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
file content
N01A nightmare picture doll head machine
N03A font for credits etc
N04A travel book (light) compression seems askew
N18A doll in box
N19A mirror reflection
M00A opening credit frame and background
M01A nightmare implant picture
M03A sideways mike mirror picture
N00D menu screen
N02D business card (dark border?)
N03D MaxTrax licensing credit
N05D Blueprints (dark border)
N09D Library card (dark border)
N12D journal scrap (dark border) "I know that I am doomed"
N15D binocular view (dark)
N16D diary ripped (dark) "After I moved into this house"
N20D journal scrap (dark) compression seems askew; "made it into a tool"
N21D evil plans
N23D ??? dark compression seems askew
N24D ??? goggle face dark
N25D ??? li face dark
N26D ??? mask face dark
R07D animation frames for breaking mirror
R16D animation frames for handing (payment?)
R30D animation frames for guard handing
???D couldn't see
R53D fido stick animation frames
N08L box with note compression seems askew
N09L library card (light)
N10L better homes and cellars interlaced
N11L mover's note interlaced
N12L journal "I know that I am doomed", compression seems askew
N13L newspaper interlaced
N14L shard with note interlaced

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 (like the newspaper, the note from the movers, etc).

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).

The window frame pictures ("Fram" resources) come in two sizes, one default and one for 12-inch displays (presumably targeting a 512x384 resolution instead of the default 640x480).

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; a pair of DWRDs?)

The shortest Rmdt resource is ID 1030, with the name "rmPrisonCell". It corresponds to ROOM30.ROM in Dark Seed for DOS.

000000020129013700BC000C000C002900BD01BE006C0038006E000000040140008200FD00AF00FD01B8014001E5

0000 one-based count of links
     (no links)

    0002 one-based count of objects

        01 object 1 type
          29 object 1 number (ITEM_TIN_CUP)
            0137 object 1 x
                00BC object 1 y
                    000C object 1 width
                        000C object 1 height
                            00 object 1 depth
                              29 object 1 sprite

                                00 object 2 type
                                  BD object 2 number (ITEM_CELL_BARS)
                                    01BE object 2 x
                                        006C object 2 y
                                            0038 object 2 width
                                                006E object 2 height
                                                    00 object 2 depth
                                                      00 object 2 sprite


                                                        0004 one-based count of polygon points

                                                            01400082 point 1 (320, 82)
                                                                    00FD00AF point 2 (253, 175)
                                                                            00FD01B8 point 3 (253, 440)
                                                                                    014001E5 point 4 (320, 485)

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 of the smaller "Objt" resources is ID 1001, named "ROOM01.OBT" and corresponding to the file ROOM01.OBT in Dark Seed for DOS. The Macintosh resource is smaller than the DOS file, but the actual values seem to be identical.

0002000200000000 41 05 0000 0000 42 05 0001 0000 0000 00 05

0002 count of objects

    0002 count of object 1's frames

        0000 x vector for object 1 frame 1
            0000 y vector
                41 sprite number
                  05 ticks

                    0000 x vector for object 1 frame 2
                        0000 y vector for object 1 frame 2
                            42 sprite number
                              05 ticks

                                0001 count of object 2's frames
                                    0000 x vector for object 2 frame 1
                                        0000 y vector for object 2 frame 1
                                            00 sprite number
                                              05 ticks

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 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')