Blood Omen file formats

From Blood Wiki
Revision as of 12:34, 22 November 2012 by VorteX (Talk | contribs)

Jump to: navigation, search

This page is dedicated to file formats used to store resources fo Blood Omen. It encompasses exploring work done by the community since Blood Omen was released.

Most basic formats - such as .BIG file structure, TIM specs, were unveiled long time ago, but some ones (map format, sprites) was unveiled lately during Blood Pill utility development.

Contents

Compression methods

Index-based RLE

Used on sprite data to compress black areas which is normally transparent. This technique alters reading process of byte 0x0 and 0xFF. If got this byte when reading picture data, should read 1 byte more which will be times to repeat this byte.

Example:

// output 32 bytes with value 0xFF
0xFF 0x20

4-bit images

Encode 2 pixels per byte with 256 color palette but with only 16 colors used (other pixels are black).

For each byte it produces 2 bytes in order:

  • byte 1 : <byte> - (int)(<byte>/16)*16; // <byte> mod 16
  • byte 2 : (int)(<byte>/16) // <byte> div 16

Example:

 231 will output 2 pixels with values:
 byte 1 : 7
 byte 2 : 14

Variation of LZ77

A variation of the LZ77 (LZ1) data compression algorithms.

Example decoder can be found at The Lost Worlds and Blood Pill sourcecode.

BIG file

This is general file storing all game resources. It's structure is quite simple:

uint32 - number of entries
Array of entries:
  uint32 - Hashed name of file
  uint32 - File size
  uint32 - File offset
Array of entry data:
  bytes - File contents

Tricks:

  • There can be gaps between files

TIM image

Playstation images. Used to store graphics and tiles. TIM specs are widely known, so it will be not listed here. Reference decoder/encoder can be found at Blood Pill sourcecode.

Tricks:

  • Some pill.big entries can contain several TIM's glued together.
  • Some blood omen TIM files can contain tails with nulls.

Sounds

VAG

Playstation's Very-Audio-Good files (4-bit ADPCM variation) used in blood omen playstation version and by blood omen sneak peek preview. Unused in PC version. Reference decoder/encoder can be found in Blood Pill sourcecode.

Tricks:

  • Many VAG files are headerless (having mess in the header, even no 'VAGb' fourCC, hence could only be detected by direct parsing).
  • Normally should be played at 11025hz, but some ones (music and some sounds) at 22050hz

RAW IMA ADPCM

Headerless files containing raw IMA ADPCM stream to replaces VAG files in PC version. They are using exactly same file names as VAG files in playstation version.

Tricks:

  • Files have no header at all

Waveform Audio File

Blood Omen PC version have some sounds in .WAV format (playstation have them in .VAG). This format is widely known and does not need to be explained.

Tricks:

  • It seems game doesnt use WAV headers, some file have bogus play rate and should be tweaked manually to play with correct rate thay listened in game

Sprites

Sprites are images of characters and animated stuff. There are 3 extensions as of filenames: SHA, SDR, SHD. However, when Blood Pill was developed, there were no knowledge of real file names, so this spec will define "Sprite types" which covers unpacking of all sprites, including unused ones.

Sprite type 1

Item cards. Always have 1 frame and no compression used.

uint32 - always 0x01 0x00 0x00 0x00 
uint32 - file size
768 bytes - 24-bit colormap data (256 colors)
int16 - x position
int16 - y position
byte - width
byte - height
byte - x
byte - y
width*height bytes - picture contents (indexes into colormap)

Tricks:

  • Really, it is simplified sprite type 3

Sprite type 2

Multiframe sprite with per-frame palette. Used by interface images collections (such as spell/item pics).

uint32 - number of frames
uint32 - file size
768 bytes - 24-bit colormap data (unused)
Array of frame headers:
  768 bytes - 24-bit colormap data
  uint32 - offset to the picture data from the end of headers
  ubyte - width
  ubyte - height
  byte - x
  byte - y
Array of frame picture data:
  width*height bytes - picture contents (indexes into colormap)

Tricks:

  • In some files real width/height may be double of what written in header

Sprite type 3

Multiframe sprite with shared palette.

uint32 - number of frames
uint32 - file size
768 bytes - 24-bit colormap data
int16 - x offset for all frames
int16 - y offset for all frames
Array of frame headers:
  uint32 - offset to the picture data from the end of headers
  ubyte - width
  ubyte - height
  byte - x
  byte - y
Array of frame picture data:
  bytes - compressed picture contents (indexes into colormap) using Index-based RLE, some files using 4-bit color

Tricks:

  • It is unknown how to get what compression file do use (Index-based in 0x00, or 0xFF or both), it seems engine gives that info when file get loaded
  • Some files are using 4-bit color instead of Index-based compression

Sprite type 4

Multiframe sprite with shared palette, with additional frames headers. Used by actor sprites and effects. Pretty same as type 3.

uint32 - number of frames
uint32 - file size
Array of additional frame headers (rounded to the greatest multiplier of 4):
   byte - unknown info
768 bytes - 24-bit colormap data
int16 - x offset for all frames
int16 - y offset for all frames
Array of frame headers:
  uint32 - offset to the picture data from the end of headers
  ubyte - width
  ubyte - height
  byte - x
  byte - y
Array of frame picture data:
  bytes - compressed picture contents (indexes into colormap) using Index-based RLE, some files using 4-bit color

Tricks:

  • It is unknown how to get what compression file do use (Index-based in 0x00, or 0xFF or both), it seems engine gives that info when file get loaded
  • Some files are using 4-bit color instead of Index-based compression

Sprite type 5

Another variation of type 3 with no offset info and (sometimes) broken width/height, which should be fixed with special trick.

uint32 - number of frames
uint32 - file size
768 bytes - 24-bit colormap data
Array of frame headers:
  uint32 - offset to the picture data from the end of headers
  ubyte - width
  ubyte - height
  byte - x
  byte - y
Array of frame picture data:
  bytes - compressed picture contents (indexes into colormap) using Index-based RLE

Tricks:

  • Some frames have broken width/height because they width is above 255 and format uses 1 byte to encode it, 255 + [width] should be used to correct this
  • It is unknown how to get what compression file do use (Index-based in 0x00, or 0xFF or both), it seems engine gives that info when file get loaded

Maps

Maps are central thing which brings all resources (images, sounds, tiles, sprites) together. There is about 80% of map structure revealed, allowing to extract general amount of things from it, including: textures used, a map image, monster/effect/item placement, triggers, info marks, doors and buttons etc.

Each map has a mapnum and section that is included in filename. That info is used to place map in a global adventure map (see TheLost Worlds - May survey for complete info about level naming).

Tiles

Tiles are 256-color TIM images compressed with LZ77 (see #Compression methods)).

Each tile texture has 8x8 = 64 tiles. Engine renders all tile separately, switching current tile texture as needed.

uint32 - compressed data size
bytes - compressed data

Tricks:

  • Since all tiles are 8-bit 256x256 TIM, unpacked data size is always same

Map file

Map file is fixed-length structure which holds tiles placement (80x80), enemies, lights, buttons and other objects to form Blood Omen level. Because of it's fixed nature, there are many limits, and each map file have exactly same size (so it can just be copied into memory).

Personal tools
Namespaces

Variants
Actions
Navigation
Toolbox