LIB Format (Shadowcaster)

From ModdingWiki
Jump to navigation Jump to search

Overview

Shadowcaster .lib archives can be considered the "ancestor" of the Doom WAD format. They are mostly similar, realistically only differing in how you are expected to find the sub-file directory.

At the high level, .lib archives consist of a data region, the directory region, and finally the number of records stored at the very end of the file.

Data Region

The data region is simply every file's contents, concatenated end-to-end. There can possibly be "hidden" sections; one file does not necessarily need to exactly start at the end of the previous, or itself end at the start of the next.

In the case of .lib files, mostly level data and music are stored; graphics are stored in DAT files.

Directory

The directory immediately precedes the record count, and consists of a number of 21-byte entries with the following format:

uint32_t Size;
uint32_t Offset;  // from beginning of file
char RecordName[13];

Record Count

Determining how many records are stored in the directory is done by seeking to the end of the file and reading the final uint16_t found there.

Reading a lib file

Adapted from MapCaster GML:

// first, we get the number of records and construct a pointer to the start of the directory
buffer_seek(Lib, buffer_seek_start, filesize - 2);
NumRecords = buffer_read(Lib, buffer_u16);
// offset to the start of the directory:
Directory = filesize - 2 - (NumRecords * 21);

// seek to the start of the directory
buffer_seek(Lib, buffer_seek_start, Directory);

// Read all entries until the end
for(i = 0; i < NumRecords; i++) {
    Records[i] = ds_map_create();
    r = Records[i];
    r[? "Size"] = buffer_read(Lib, buffer_u32);
    r[? "Offset"] = buffer_read(Lib, buffer_u32);
    
    // read the name string
    r[? "Name"] = ReadString(13);  // directory subfile names are always exactly 13 bytes and follow 8.3 DOS filename convention, and are null-terminated

}