Arena HackingEdit
BSAEdit
Arena has only one BSA file, "GLOBAL.BSA", which is simply many smaller files packed together. The format is close to Daggerfall's BSA format.
BSA File Format | |
---|---|
uint16 | Number of files |
blob[] | File contents |
index[] | File indices |
The beginning of the file index section can be found at filesize-18*number_of_files
, entries have the following format:
index | |
---|---|
char[12] | 8.3 Filename |
uint16 | unused, always 0 |
uint16 | File size |
uint16 | unused, always 0 |
From there the contents of a file can be found by successively adding file sizes of previous entries (and observing the initial offset of 2).
IMG, COLEdit
The IMG format for images and COL format for color palettes match that of Daggerfall (IMG and COL), with a few differences:
Some images have no header, in that case the image is uncompressed, but width and height have to be known. All images are in 8-bit indexed color format.
IMG header | |
---|---|
uint16 | X-Offset |
uint16 | Y-Offset |
uint16 | image width |
uint16 | image height |
uint16 | flags |
uint16 | Pixel data length (equals width x height for uncompressed images) |
Following the initial header is the pixel data, after that the optional palette.
Palettes are 256 entries of 3 bytes in order r, g, b, with values 0=black to 63=full color. They are either contained in the image file, or found in one of several COL files.
LZSS compressionEdit
Let outp be the position in the stream of decompressed data written, starting at 0. Compressed data is a sequence of units until the pixel data length is reached:
The first byte encodes the meaning of the next few bytes, from low to high bit:
- 1: next byte is a literal, to be copied as is
- 0: next two bytes encode length and position of already decoded data to copy:
- 12 bit location (8 low bits found in first byte, 4 high bits found in the high bits of second byte)
- 4 bit length (4 low bits in second byte)
- len bytes starting at pos should be copied to the output:
- len = length+3
- pos = outp&~0xfff | (location+18)&0xfff; if (pos>=outp) pos-=4096
- Note that pos+len may span beyond the currently decompressed data, that way run length compression is part of the algorithm
- len bytes starting at pos should be copied to the output: