The ALD File Format

ALD is an archive format used starting with System 3.5. It is still used in System 4 but its use has declined in favor of the compressed AFA format.

It’s basically an update to the DAT format used prior to System 3.5, with wider indices allowing for more data to be archived.

struct ald_file {
    LE24 ptr_table[?];  // the pointer table
    // ptr_table[0] is the index of the link table
    // ptr_table[1] is the index of the first sector after the link table
    LE24 link_table[?]; // the link table
    BYTE data[?];       // the archived data
};

The structure above describes the general format of an ALD file. Like DAT files, ALD files are indexed in 256 byte sectors, and contain pointer and link tables.

Each item of data in the archive is assigned a unique ID which the scenario uses to refer to the data. This ID serves as an index into the link table, which is an array of 3 byte entries in the following format:

struct data_link {
    BYTE file_nr; // the file containing the data (1~)
    LE16 ptr_nr;  // index into the pointer table (1~)
}

file_nr indicates which file the data is stored in. ALD archives may be split across multiple files, with the last character before the file extension determining the file numbering. E.g. fooA.ALD would be file number 1, fooB.ALD file number 2, etc.

ptr_nr is an index into the pointer table of the file indicated by file_nr. The pointer table is an array of 3 byte sector indices into the file.

Note that both file_nr and ptr_nr are indexed beginning from 1, not 0.

The algorithm for obtaining an item of data from an ALD archive is as follows.

struct ald_file files[NR_FILES];

struct data_header *ald_get_data(struct ald_file *ald, int uid)
{
    // index into link table of first file using UID
    struct data_link *link = &files[0].link_table[uid];
    // index into pointer table of nth file
    LE16 ptr = files[link.file_nr-1].ptr_table[link.ptr_nr-1];
    // the data is stored at the sector indicated by 'ptr'
    return ((BYTE*)files[link.file_nr-1])[ptr * 256];
}

Each item of data stored in an ALD file has a header:

struct data_header {
    LE32 ptr;     // (relative) pointer to actual data
    LE32 size;    // size of the data
    LE32 time_l;  // lower half of timestamp
    LE32 time_h;  // higher half of timestamp
    char name[?]; // filename (at least 16 bytes)
}

ptr is a relative pointer to the data. It should be added to the address of the header itself in order to obtain an absolute pointer to the data.

size is the size of the data in bytes.

time_l and time_h are the lower and higher halves of a Windows FILETIME timestamp.

name is a null terminated string giving the original file name of the data. This member must be at least 16 bytes long, because the header must be at least 32 bytes.

The data itself can be anything, but System39.exe uses the file name to determine what kind of data is contained in ALD files:

File Name Data Type
fooDA.ALD Generic data
fooGA.ALD CG data
fooMA.ALD MIDI data
fooRA.ALD Cursor shapes & animations
fooSA.ALD Scenario data
fooWA.ALD Audio data

Finally, in the last sector of the file there is a 3 byte number which apparently corresponds to the version of ALD file. Known values are 0x014C4E and 0x012020. 0x012020 is the older version, but unfortunately I have no idea what the difference is between the two.