Editing Blood Omen file formats
Warning: You are not logged in.
Your IP address will be recorded in this page's edit history.The edit can be undone.
Please check the comparison below to verify that this is what you want to do, and then save the changes below to finish undoing the edit.
Latest revision | Your text | ||
Line 1: | Line 1: | ||
− | {{ | + | {{finished}} |
− | This page is dedicated to | + | {{grammar}} |
+ | 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 simple 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]] development. | + | Most simple 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. |
+ | |||
+ | ==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: | ||
+ | |||
+ | <span style="color:green">// output 32 bytes with value 0xFF</span> | ||
+ | 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; <span style="color:green">// <byte> mod 16</span> | ||
+ | * byte 2 : (int)(<byte>/16) <span style="color:green">// <byte> div 16</span> | ||
+ | |||
+ | 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 [http://www.thelostworlds.net/Software/Blood_Omen_Decompressor.html The Lost Worlds] and [[Blood Pill]] sourcecode. | ||
==BIG file== | ==BIG file== | ||
Line 15: | Line 45: | ||
'''bytes''' - File contents | '''bytes''' - File contents | ||
− | + | Tricks: | |
+ | * There can be gaps between files | ||
==TIM image== | ==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 [ | + | 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 pill.big entries can contain several TIM's glued together. | ||
* Some blood omen TIM files can contain tails with nulls. | * Some blood omen TIM files can contain tails with nulls. | ||
Line 27: | Line 58: | ||
===VAG=== | ===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 [ | + | 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). | * 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 | * Normally should be played at 11025hz, but some ones (music and some sounds) at 22050hz | ||
Line 36: | Line 67: | ||
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. | 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=== | ===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. | 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 | ||
==Video== | ==Video== | ||
Line 53: | Line 86: | ||
JAM videos have much more artifacts than STR, sound track is mono (STR have stereo). | JAM videos have much more artifacts than STR, sound track is mono (STR have stereo). | ||
− | JAM decompressing code can be found [ | + | JAM decompressing code can be found in [[Blood Pill]] sourcecode. |
==Sprites== | ==Sprites== | ||
Line 73: | Line 106: | ||
'''width*height bytes''' - picture contents (indexes into colormap) | '''width*height bytes''' - picture contents (indexes into colormap) | ||
− | + | Tricks: | |
+ | * Really, it is simplified sprite type 3 | ||
===Sprite type 2 - Images collection=== | ===Sprite type 2 - Images collection=== | ||
Line 91: | Line 125: | ||
'''width*height bytes''' - picture contents (indexes into colormap) | '''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 - Object sprites=== | ===Sprite type 3 - Object sprites=== | ||
Line 108: | Line 143: | ||
'''byte''' - y | '''byte''' - y | ||
<span style="color:green">Array of frame picture data:</span> | <span style="color:green">Array of frame picture data:</span> | ||
− | '''bytes''' - compressed picture contents (indexes into colormap) using | + | '''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 ( | + | * 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 | + | * Some files are using 4-bit color instead of Index-based compression |
===Sprite type 4 - character sprites=== | ===Sprite type 4 - character sprites=== | ||
Line 120: | Line 155: | ||
'''uint32''' - file size | '''uint32''' - file size | ||
<span style="color:green">Array of additional frame headers (rounded to the greatest multiplier of 4):</span> | <span style="color:green">Array of additional frame headers (rounded to the greatest multiplier of 4):</span> | ||
− | '''byte''' - | + | '''byte''' - unknown info |
'''768 bytes''' - 24-bit colormap data | '''768 bytes''' - 24-bit colormap data | ||
'''int16''' - x offset for all frames | '''int16''' - x offset for all frames | ||
Line 131: | Line 166: | ||
'''byte''' - y | '''byte''' - y | ||
<span style="color:green">Array of frame picture data:</span> | <span style="color:green">Array of frame picture data:</span> | ||
− | '''bytes''' - compressed picture contents (indexes into colormap) using | + | '''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 ( | + | * 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 | + | * Some files are using 4-bit color instead of Index-based compression |
===Sprite type 5=== | ===Sprite type 5=== | ||
Line 150: | Line 185: | ||
'''byte''' - y | '''byte''' - y | ||
<span style="color:green">Array of frame picture data:</span> | <span style="color:green">Array of frame picture data:</span> | ||
− | '''bytes''' - compressed picture contents (indexes into colormap) using RLE | + | '''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 | * 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 ( | + | * 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== | ||
Line 170: | Line 205: | ||
'''bytes''' - compressed data | '''bytes''' - compressed data | ||
− | + | Tricks: | |
* Since all tiles are 8-bit 256x256 TIM, unpacked data size is always same | * Since all tiles are 8-bit 256x256 TIM, unpacked data size is always same | ||
Line 177: | Line 212: | ||
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). | 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). | ||
− | <span style="color:green">// | + | <span style="color:green">// map trigger</span> |
− | <span style="color: | + | <span style="color:darkblue">typedef struct</span> |
− | + | <span style="color:darkblue">'''{'''</span> | |
− | + | '''unsigned short''' parm1; <span style="color:green">// first parm, if script is not defined it's 0xFFFF, 0xFFFE is null value</span> | |
− | + | <span style="color:green">// - destination/source map number (TRIGGER_EXIT, TRIGGER_ENTRANCE, TRIGGER_TELEPORT)</span> | |
− | + | <span style="color:green">// - speech num (TRIGGER_INFOMARK, TRIGGER_IMAGEMARK)</span> | |
− | + | '''unsigned short''' parm2; <span style="color:green">// second parm:</span> | |
− | + | <span style="color:green">// - button num (TRIGGER_BUTTON)</span> | |
− | + | <span style="color:green">// - pic num (TRIGGER_IMAGEMARK)</span> | |
− | + | '''byte''' parm3; <span style="color:green">// destination/source map section (TRIGGER_EXIT, TRIGGER_ENTRANCE, TRIGGER_TELEPORT)</span> | |
− | + | '''byte''' srcx; <span style="color:green">// sposition</span> | |
− | + | '''byte''' srcy; <span style="color:green">// sposition</span> | |
− | + | '''byte''' type; <span style="color:green">// script type, one of TRIGGER_</span> | |
− | + | '''byte''' u2<span style="color:darkblue">'''['''</span>3<span style="color:darkblue">''']'''</span>; <span style="color:green">// ?</span> | |
− | + | '''byte''' x; <span style="color:green">// position</span> | |
− | + | '''byte''' y; <span style="color:green">// position</span> | |
− | + | '''byte''' u3<span style="color:darkblue">'''['''</span>3<span style="color:darkblue">''']'''</span>; <span style="color:green">// ?</span> | |
− | }bo_trigger_t; | + | <span style="color:darkblue">'''}'''</span>'''bo_trigger_t'''; |
− | <span style="color: | + | <span style="color:green">// map item</span> |
− | + | <span style="color:darkblue">typedef struct</span> | |
− | + | <span style="color:darkblue">'''{'''</span> | |
− | + | '''unsigned short''' savenum; <span style="color:green">// unique savegame id</span> | |
− | + | '''byte''' itemcode; <span style="color:green">// one of MAPITEM_ code</span> | |
− | + | '''byte''' x; <span style="color:green">// position</span> | |
− | + | '''byte''' y; <span style="color:green">// position</span> | |
− | + | '''byte''' hidden; <span style="color:green">// set to 1 if item is spawned by trigger (like barrel destruction)</span> | |
− | + | '''unsigned short''' target; <span style="color:green">// targeted triggergroup</span> | |
− | }bo_item_t; | + | '''byte''' u<span style="color:darkblue">'''['''</span>4<span style="color:darkblue">''']'''</span>; <span style="color:green">// ?</span> |
+ | <span style="color:darkblue">'''}'''</span>'''bo_item_t'''; | ||
− | <span style="color: | + | <span style="color:green">// animated tile</span> |
− | + | <span style="color:darkblue">typedef struct</span> | |
− | + | <span style="color:darkblue">'''{'''</span> | |
− | + | '''unsigned short''' targetnum;<span style="color:green">// a triggergroup</span> | |
− | + | '''byte''' x; <span style="color:green">// position</span> | |
− | + | '''byte''' u1; <span style="color:green">// ?</span> | |
− | + | '''byte''' y; <span style="color:green">// position</span> | |
− | + | '''byte''' u2; <span style="color:green">// ?</span> | |
− | + | '''unsigned short''' tile1; <span style="color:green">// tilenum</span> | |
− | + | '''unsigned short''' tile2; <span style="color:green">// alternate state tilenum</span> | |
− | + | '''byte''' contents1; <span style="color:green">// contents, see CONTENTS_ defines for possible content values</span> | |
− | + | '''byte''' contents2; <span style="color:green">// alternate state contents</span> | |
− | }bo_atile_t; | + | '''byte''' u3<span style="color:darkblue">'''['''</span>12<span style="color:darkblue">''']'''</span>; <span style="color:green">// ?</span> |
+ | <span style="color:darkblue">'''}'''</span>'''bo_atile_t'''; | ||
− | <span style="color: | + | <span style="color:green">// button controller</span> |
− | + | <span style="color:darkblue">typedef struct</span> | |
− | + | <span style="color:darkblue">'''{'''</span> | |
− | + | '''unsigned short''' target; <span style="color:green">// a triggergroup to call</span> | |
− | + | '''unsigned short''' tile1; <span style="color:green">// tilenum</span> | |
− | + | '''unsigned short''' tile2; <span style="color:green">// alternate state tilenum</span> | |
− | + | '''byte''' flags; <span style="color:green">// see BUTTONFLAG_* defs</span> | |
− | + | '''byte''' u1; <span style="color:green">// ?</span> | |
− | + | '''unsigned short''' savenum; <span style="color:green">// unique savegame id</span> | |
− | + | '''byte''' u2; <span style="color:green">// ?</span> | |
− | }bo_button_t; | + | '''byte''' u3; <span style="color:green">// ?</span> |
+ | <span style="color:darkblue">'''}'''</span>'''bo_button_t'''; | ||
− | <span style="color: | + | <span style="color:green">// effect</span> |
− | { | + | <span style="color:darkblue">typedef struct</span> |
− | + | <span style="color:darkblue">'''{'''</span> | |
− | + | '''byte''' x; <span style="color:green">// position</span> | |
− | + | '''byte''' y; <span style="color:green">// position</span> | |
− | + | '''byte''' lightposx; <span style="color:green">// position of lightsource</span> | |
− | + | '''byte''' lightposy; <span style="color:green">// position of lightsource</span> | |
− | + | '''byte''' sprite; <span style="color:green">// index of sprite from sprites array</span> | |
− | + | '''byte''' lightsizex; <span style="color:green">// size of light polygons</span> | |
− | + | '''byte''' lightsizey; <span style="color:green">// size of light polygons</span> | |
− | + | '''byte''' u1; <span style="color:green">// ?</span> | |
− | + | '''byte''' lightform; <span style="color:green">// light form flags</span> | |
− | + | '''byte''' r; <span style="color:green">// red color component</span> | |
− | + | '''byte''' g; <span style="color:green">// green color component</span> | |
− | + | '''byte''' b; <span style="color:green">// darkblue color component</span> | |
− | + | '''unsigned short''' targetnum;<span style="color:green">// triggergroup</span> | |
− | + | '''byte''' start_on; <span style="color:green">// 1 if effect starts on, 0 if starts off</span> | |
− | }bo_effect_t; | + | '''byte''' u3<span style="color:darkblue">'''['''</span>5<span style="color:darkblue">''']'''</span>; <span style="color:green">// ?</span> |
+ | <span style="color:darkblue">'''}'''</span>'''bo_effect_t'''; | ||
− | <span style="color: | + | <span style="color:darkblue">typedef struct</span> |
− | + | <span style="color:darkblue">'''{'''</span> | |
− | + | '''byte''' data<span style="color:darkblue">'''['''</span>164<span style="color:darkblue">''']'''</span>; | |
− | }bo_object_t; | + | <span style="color:darkblue">'''}'''</span>'''bo_object_t'''; |
− | <span style="color: | + | <span style="color:green">// tile object definition (barrels, chests)</span> |
− | { | + | <span style="color:darkblue">typedef struct</span> |
− | + | <span style="color:darkblue">'''{'''</span> | |
− | + | '''byte''' x; <span style="color:green">// start position</span> | |
− | + | '''byte''' y; <span style="color:green">// end position</span> | |
− | + | '''byte''' w; <span style="color:green">// width</span> | |
− | + | '''byte''' h; <span style="color:green">// height</span> | |
− | + | '''byte''' ofsx; <span style="color:green">// multiply by 16 to get real offset</span> | |
− | + | '''byte''' ofsy; <span style="color:green">// multiply by 16 to get real offset</span> | |
− | + | '''byte''' u1; | |
− | }bo_grpobject_t; | + | '''byte''' u2; |
+ | <span style="color:darkblue">'''}'''</span>'''bo_grpobject_t'''; | ||
− | <span style="color: | + | <span style="color:green">// scenery entities</span> |
− | { | + | <span style="color:darkblue">typedef struct</span> |
− | + | <span style="color:darkblue">'''{'''</span> | |
− | + | '''byte''' u1; <span style="color:green">// ?</span> | |
− | + | '''byte''' u2; <span style="color:green">// ?</span> | |
− | + | '''byte''' u3; <span style="color:green">// ?</span> | |
− | + | '''byte''' u4; <span style="color:green">// ?</span> | |
− | + | '''unsigned short''' tile1; <span style="color:green">// base tile (grpobject really, not standart 32x32 tile)</span> | |
− | + | '''unsigned short''' tile2; <span style="color:green">// toggled tile (grpobject)</span> | |
− | + | '''unsigned short''' tile3; <span style="color:green">// destroyed tilee (grpobject)</span> | |
− | + | '''byte''' u5; <span style="color:green">// ?</span> | |
− | + | '''byte''' u6; <span style="color:green">// ?</span> | |
− | + | '''byte''' pushable; <span style="color:green">// a strength required to push</span> | |
− | + | '''byte''' toggled; <span style="color:green">// trigger can toggle it's state (means tile2 is there)</span> | |
− | + | '''byte''' u7; <span style="color:green">// ?</span> | |
− | + | '''byte''' spawnitems<span style="color:darkblue">'''['''</span>3<span style="color:darkblue">''']'''</span>; <span style="color:green">// item codes to spawn when toggled/destroyed</span> | |
− | + | '''byte''' u8; <span style="color:green">// ?</span> | |
− | + | '''byte''' destructible; <span style="color:green">// destructible flags</span> | |
− | + | '''unsigned short''' savenum; <span style="color:green">// unique savegame id</span> | |
− | + | '''byte''' u10; <span style="color:green">// ?</span> | |
− | + | '''byte''' x; <span style="color:green">// position</span> | |
− | + | '''byte''' y; <span style="color:green">// position</span> | |
− | + | '''byte''' u11; <span style="color:green">// ? </span> | |
− | + | '''byte''' active; <span style="color:green">// 1 is filled, otherwise 0</span> | |
− | }bo_scenery_t; | + | '''byte''' u13; <span style="color:green">// ? </span> |
+ | <span style="color:darkblue">'''}'''</span>'''bo_scenery_t'''; | ||
− | <span style="color: | + | <span style="color:green">// enemy paths</span> |
− | { | + | <span style="color:darkblue">typedef struct</span> |
− | + | <span style="color:darkblue">'''{'''</span> | |
− | + | '''byte''' x; <span style="color:green">// position</span> | |
− | + | '''byte''' y; <span style="color:green">// position</span> | |
− | + | '''byte''' u1; <span style="color:green">// ?</span> | |
− | }bo_path_t; | + | '''byte''' u2; <span style="color:green">// ?</span> |
+ | <span style="color:darkblue">'''}'''</span>'''bo_path_t'''; | ||
− | <span style="color: | + | <span style="color:green">// enemy entity</span> |
− | { | + | <span style="color:darkblue">typedef struct</span> |
− | + | <span style="color:darkblue">'''{'''</span> | |
− | + | bo_path_t paths<span style="color:darkblue">'''['''</span>4<span style="color:darkblue">''']'''</span>; <span style="color:green">// patrole paths</span> | |
− | + | '''byte''' u1<span style="color:darkblue">'''['''</span>12<span style="color:darkblue">''']'''</span>; <span style="color:green">// ?</span> | |
− | + | '''unsigned short''' savenum; <span style="color:green">// unique savegame id</span> | |
− | + | '''byte''' u2<span style="color:darkblue">'''['''</span>52<span style="color:darkblue">''']'''</span>; <span style="color:green">// ?</span> | |
− | + | '''byte''' charnum; <span style="color:green">// monster class (same as char* sprite)</span> | |
− | + | '''byte''' u3<span style="color:darkblue">'''['''</span>10<span style="color:darkblue">''']'''</span>; <span style="color:green">// ?</span> | |
− | + | '''unsigned short''' target; <span style="color:green">// triggergroup to call once killed</span> | |
− | + | '''byte''' u4<span style="color:darkblue">'''['''</span>20<span style="color:darkblue">''']'''</span>; <span style="color:green">// ?</span> | |
− | + | '''byte''' lastpath; <span style="color:green">// ?</span> | |
− | + | '''byte''' u6<span style="color:darkblue">'''['''</span>18<span style="color:darkblue">''']'''</span>; <span style="color:green">// ?</span> | |
− | + | '''byte''' u7<span style="color:darkblue">'''['''</span>15<span style="color:darkblue">''']'''</span>; <span style="color:green">// ?</span> | |
− | + | '''byte''' x; <span style="color:green">// position</span> | |
− | + | '''byte''' y; <span style="color:green">// position</span> | |
− | + | '''byte''' u8<span style="color:darkblue">'''['''</span>4<span style="color:darkblue">''']'''</span>; <span style="color:green">// ?</span> | |
− | + | '''unsigned short''' speechnum;<span style="color:green">// a speech number for disguise talk</span> | |
− | }bo_monster_t; | + | '''byte''' u9<span style="color:darkblue">'''['''</span>6<span style="color:darkblue">''']'''</span>; <span style="color:green">// ?</span> |
+ | <span style="color:darkblue">'''}'''</span>'''bo_monster_t'''; | ||
− | <span style="color: | + | <span style="color:green">// general map file structure</span> |
− | { | + | <span style="color:darkblue">typedef struct</span> |
− | + | <span style="color:darkblue">'''{'''</span> | |
− | + | <span style="color:green">// a chain of tilemap numbers used (to make a filenames)</span> | |
− | + | <span style="color:green">// each tilemap holds 64 tiles, tiles numbering is linear</span> | |
− | + | <span style="color:green">// like, a tile #131 is tile #3 from tilemap #2</span> | |
− | + | <span style="color:green">// being 2-'''byte''' ('''unsigned short''') tilenum contains some flags (flag are starting from '''byte''' 10)</span> | |
− | + | <span style="color:green">// see TILEFLAG_ defines for possible tileflags</span> | |
− | + | '''unsigned short''' tilemaps<span style="color:darkblue">'''['''</span>40<span style="color:darkblue">''']'''</span>; | |
− | + | <span style="color:green">// yet unknown info</span> | |
− | + | '''byte''' u1<span style="color:darkblue">'''['''</span>12<span style="color:darkblue">''']'''</span>; | |
− | + | '''bo_object_t''' objects<span style="color:darkblue">'''['''</span>10<span style="color:darkblue">''']'''</span>; | |
− | + | '''bo_monster_t''' monsters<span style="color:darkblue">'''['''</span>32<span style="color:darkblue">''']'''</span>; | |
− | + | '''bo_grpobject_t''' grpobjects<span style="color:darkblue">'''['''</span>8<span style="color:darkblue">''']'''</span><span style="color:darkblue">'''['''</span>32<span style="color:darkblue">''']'''</span>; | |
− | + | <span style="color:green">// animated tiles - a tiles that can be toggled between 2 states and have different contents for each state</span> | |
− | + | <span style="color:green">// used on doors, spikes that pops up on the floor etc.</span> | |
− | + | <span style="color:green">// animated tiles have triggergroup to be executed by script</span> | |
− | + | '''bo_atile_t''' atiles<span style="color:darkblue">'''['''</span>100<span style="color:darkblue">''']'''</span>; | |
− | + | <span style="color:green">// a special buttons array holds all buttons used on level</span> | |
− | + | <span style="color:green">// pretty similar to animated tiles</span> | |
− | + | <span style="color:green">// buttons have triggergroup to be executed by script</span> | |
− | + | '''bo_button_t''' buttons<span style="color:darkblue">'''['''</span>20<span style="color:darkblue">''']'''</span>; | |
− | + | <span style="color:green">// yet unknown info #2</span> | |
− | + | '''byte''' u2<span style="color:darkblue">'''['''</span>8<span style="color:darkblue">''']'''</span>; | |
− | + | <span style="color:green">// scenery pushable objects - tables, chairs, stones etc.</span> | |
− | + | '''bo_scenery_t''' scenery<span style="color:darkblue">'''['''</span>256<span style="color:darkblue">''']'''</span>; | |
− | + | <span style="color:green">// first tilemap</span> | |
− | + | '''unsigned short''' backtiles<span style="color:darkblue">'''['''</span>80<span style="color:darkblue">''']'''</span><span style="color:darkblue">'''['''</span>80<span style="color:darkblue">''']'''</span>; | |
− | + | <span style="color:green">// second tilemap</span> | |
− | + | '''unsigned short''' foretiles<span style="color:darkblue">'''['''</span>80<span style="color:darkblue">''']'''</span><span style="color:darkblue">'''['''</span>80<span style="color:darkblue">''']'''</span>; | |
− | + | <span style="color:green">// contents map - a contents value for each static tile (in game they get overriden by switchable tiles if presented)</span> | |
− | + | <span style="color:green">// see CONTENTS_ defines for possible content values</span> | |
− | + | '''byte''' contents<span style="color:darkblue">'''['''</span>80<span style="color:darkblue">''']'''</span><span style="color:darkblue">'''['''</span>80<span style="color:darkblue">''']'''</span>; | |
− | + | <span style="color:green">// linear triggers array - all triggers used on map</span> | |
− | + | '''bo_trigger_t''' triggers<span style="color:darkblue">'''['''</span>255<span style="color:darkblue">''']'''</span>; | |
− | + | <span style="color:green">// triggers are non-solid interaction points, activated when player stands in them</span> | |
− | + | <span style="color:green">// this array golds pointers to triggers</span> | |
− | + | '''byte''' triggertiles<span style="color:darkblue">'''['''</span>80<span style="color:darkblue">''']'''</span><span style="color:darkblue">'''['''</span>80<span style="color:darkblue">''']'''</span>; | |
− | + | <span style="color:green">// items placed on level</span> | |
− | + | <span style="color:green">// itemcodes 0-9 are powerups, codes 10, 11, 12, 13 reserved for unique item codes</span> | |
− | + | <span style="color:green">// so there will be not more than 4 unique item type per level</span> | |
− | + | <span style="color:green">// unique items are: spells, weapons, forms, artifacts, tokens</span> | |
− | + | '''byte''' uniqueitems<span style="color:darkblue">'''['''</span>4<span style="color:darkblue">''']'''</span>; | |
− | + | '''bo_item_t''' items<span style="color:darkblue">'''['''</span>50<span style="color:darkblue">''']'''</span>; | |
− | + | <span style="color:green">// yet unknown data</span> | |
− | + | '''byte''' u4<span style="color:darkblue">'''['''</span>8<span style="color:darkblue">''']'''</span>; | |
− | + | '''byte''' u5<span style="color:darkblue">'''['''</span>8<span style="color:darkblue">''']'''</span><span style="color:darkblue">'''['''</span>40<span style="color:darkblue">''']'''</span>; | |
− | + | '''byte''' u6<span style="color:darkblue">'''['''</span>24<span style="color:darkblue">''']'''</span>; | |
− | + | <span style="color:green">// effects</span> | |
− | + | '''unsigned short''' sprites<span style="color:darkblue">'''['''</span>8<span style="color:darkblue">''']'''</span>; | |
− | + | '''bo_effect_t''' effects<span style="color:darkblue">'''['''</span>64<span style="color:darkblue">''']'''</span>; | |
− | + | <span style="color:green">// yet unknown data</span> | |
− | + | '''byte''' u7<span style="color:darkblue">'''['''</span>936<span style="color:darkblue">''']'''</span>; | |
− | + | <span style="color:darkblue">'''}'''</span>bo_map_t; | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
<span style="color:green">// things that are not figured out yet:</span> | <span style="color:green">// things that are not figured out yet:</span> | ||
<span style="color:green">// - how lightning is done (variable form lights, day-night light, ambient light)</span> | <span style="color:green">// - how lightning is done (variable form lights, day-night light, ambient light)</span> | ||
− | <span style="color:green">// - monster | + | <span style="color:green">// - monster's paths's switch (some paths are messed up)</span> |
<span style="color:green">// - counters and puzzle triggers?</span> | <span style="color:green">// - counters and puzzle triggers?</span> | ||
− | |||
− | |||
− | |||
− | |||
<span style="color:green">// tileflags</span> | <span style="color:green">// tileflags</span> | ||
− | + | #define '''TILEFLAG_UNKNOWN1''' 1024 | |
− | + | #define '''TILEFLAG_NODRAW''' 2048 | |
− | + | #define '''TILEFLAG_UNKNOWN3''' 4096 | |
− | + | #define '''TILEFLAG_UNKNOWN4''' 8192 | |
− | + | #define '''TILEFLAG_ALWAYSONTOP''' 16384 | |
− | + | #define '''TILEFLAG_UNKNOWN6''' 32768 | |
− | + | ||
− | + | ||
<span style="color:green">// contents</span> | <span style="color:green">// contents</span> | ||
− | + | #define '''CONTENTS_SOLID''' 1 | |
− | + | #define '''CONTENTS_WATER''' 2 | |
− | + | #define '''CONTENTS_LAVA''' 3 | |
− | + | #define '''CONTENTS_FIRE''' 4 | |
− | + | #define '''CONTENTS_SPIKES''' 5 | |
− | + | #define '''CONTENTS_TRAPTELEPORT''' 6 | |
− | + | #define '''CONTENTS_JUMPWALL''' 8 | |
− | + | #define '''CONTENTS_SWAMP''' 11 | |
− | + | #define '''CONTENTS_JUMPFENCE''' 10 | |
− | + | #define '''CONTENTS_MISTWALK''' 12 | |
− | + | #define '''CONTENTS_SACRIFICE''' 13 | |
− | + | #define '''CONTENTS_ICE''' 19 | |
− | + | #define '''CONTENTS_SAVEGAM''' 44 | |
− | + | #define '''CONTENTS_BATMARK''' 45 | |
− | + | ||
<span style="color:green">// triggers</span> | <span style="color:green">// triggers</span> | ||
− | + | #define '''TRIGGER_EXIT''' 1 | |
− | + | #define '''TRIGGER_ENTRANCE''' 2 | |
− | + | #define '''TRIGGER_SPEECHMARK''' 3 | |
− | + | #define '''TRIGGER_TOUCH''' 4 | |
− | + | #define '''TRIGGER_TELEPORT''' 6 | |
− | + | #define '''TRIGGER_IMAGEMARK''' 7 | |
<span style="color:green">// button flags</span> | <span style="color:green">// button flags</span> | ||
− | + | #define '''BUTTONFLAG_TOGGLE''' 1 | |
− | + | #define '''BUTTONFLAG_SECRET''' 2 | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
<span style="color:green">// item codes</span> | <span style="color:green">// item codes</span> | ||
− | + | #define '''MAPITEM_SMALLBLOODFLASK''' 1 | |
− | + | #define '''MAPITEM_BLOODFLASK''' 2 | |
− | + | #define '''MAPITEM_RUNEPYRAMID''' 3 | |
− | + | #define '''MAPITEM_PURPLESPHERE''' 4 | |
− | + | #define '''MAPITEM_BLUESPHERE''' 5 | |
− | + | #define '''MAPITEM_GREENSPHERE''' 6 | |
− | + | #define '''MAPITEM_GOLDSPHERE''' 7 | |
− | + | #define '''MAPITEM_REDSPHERE''' 8 | |
− | + | #define '''MAPITEM_ANCIENTVIAL''' 9 | |
− | + | #define '''MAPITEM_UNIQUE1''' 10 <span style="color:green">// unique item codes</span> | |
− | + | #define '''MAPITEM_UNIQUE2''' 11 <span style="color:green">// unique item codes</span> | |
− | + | #define '''MAPITEM_UNIQUE3''' 12 <span style="color:green">// unique item codes</span> | |
− | + | #define '''MAPITEM_UNIQUE4''' 13 <span style="color:green">// unique item codes</span> | |
− | <span style="color:green">// | + | <span style="color:green">// unique item codes</span> |
− | + | #define '''ITEM_SPELL_INSPIREHATE''' 10 | |
− | + | #define '''ITEM_SPELL_STUN''' 11 | |
− | + | #define '''ITEM_SPELL_SPIRITWRACK''' 12 | |
− | + | #define '''ITEM_SPELL_BLOODGOUT''' 13 | |
− | + | #define '''ITEM_SPELL_BLOODSHOWER''' 14 | |
− | + | #define '''ITEM_SPELL_SPIRITDEATH''' 15 | |
− | + | #define '''ITEM_SPELL_LIGHT''' 16 | |
− | + | #define '''ITEM_SPELL_LIGHTNING''' 17 | |
− | + | #define '''ITEM_SPELL_REPEL''' 18 | |
− | + | #define '''ITEM_SPELL_ENERGYBOLT''' 19 | |
− | + | #define '''ITEM_SPELL_INCAPACITATE''' 20 | |
− | + | #define '''ITEM_SPELL_CONTROLMIND''' 21 | |
− | + | #define '''ITEM_SPELL_SANCTUARY''' 22 | |
− | + | #define '''ITEM_ARTIFACT_FLAY''' 23 | |
− | + | #define '''ITEM_ARTIFACT_PENTALICH''' 24 | |
− | + | #define '''ITEM_ARTIFACT_IMPLODE''' 25 | |
− | + | #define '''ITEM_ARTIFACT_FONT''' 26 | |
− | + | #define '''ITEM_ARTIFACT_BANK''' 27 | |
− | + | #define '''ITEM_ARTIFACT_HEART''' 28 | |
− | + | #define '''ITEM_ARTIFACT_ANTITOXIN''' 29 | |
− | + | #define '''ITEM_ARTIFACT_SLOWTIME''' 30 | |
− | + | #define '''ITEM_TOKEN_MOEBIUS''' 31 | |
− | + | #define '''ITEM_TOKEN_DEJOULE''' 32 | |
− | + | #define '''ITEM_TOKEN_DOLL''' 33 | |
− | + | #define '''ITEM_TOKEN_MALEK''' 34 | |
− | + | #define '''ITEM_TOKEN_AZIMUTH''' 35 | |
− | + | #define '''ITEM_TOKEN_MORTANIUS''' 36 | |
− | + | #define '''ITEM_TOKEN_NUPRAPTOR''' 37 | |
− | + | #define '''ITEM_TOKEN_BANE''' 38 | |
− | + | #define '''ITEM_TOKEN_SIGNETRING''' 39 | |
− | + | #define '''ITEM_TOKEN_TIMEDEVICE''' 40 | |
− | + | #define '''ITEM_TOKEN_ANACROTHE''' 41 | |
− | + | #define '''ITEM_WEAPON_MACE''' 43 | |
− | + | #define '''ITEM_WEAPON_AXES''' 44 | |
− | + | #define '''ITEM_WEAPON_FLAMESWORD''' 45 | |
− | + | #define '''ITEM_WEAPON_SOULREAVER''' 46 | |
− | + | #define '''ITEM_ARMOR_BONE''' 48 | |
− | + | #define '''ITEM_ARMOR_CHAOS''' 49 | |
− | + | #define '''ITEM_ARMOR_FLESH''' 50 | |
− | + | #define '''ITEM_ARMOR_WRAITH''' 51 | |
− | + | #define '''ITEM_FORM_BAT''' 53 | |
− | + | #define '''ITEM_FORM_WOLF''' 54 | |
− | + | #define '''ITEM_FORM_DISGUISE''' 55 | |
− | + | #define '''ITEM_FORM_MIST''' 56 | |
− | + | #define '''ITEM_ENDING_1''' 69 | |
− | + | #define '''ITEM_ENDING_2''' 70 | |
− | + | ||
− | + | ||
− | + | ||
− | ''' | + | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | ''' | + | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
==Credits== | ==Credits== | ||
Line 557: | Line 535: | ||
* [[Blood Pill]] | * [[Blood Pill]] | ||
* [http://kenai.com/projects/jpsxdec/pages/Home jPsxDec homepage] | * [http://kenai.com/projects/jpsxdec/pages/Home jPsxDec homepage] | ||
− | |||
* [http://www.thelostworlds.net/Software/Blood_Omen_Decompressor.html Blood Omen Decompressor homepage] | * [http://www.thelostworlds.net/Software/Blood_Omen_Decompressor.html Blood Omen Decompressor homepage] | ||
* [http://www.thelostworlds.net/BO1/Map_Survey.html Blood Omen Map Survey (TheLostWorlds)] | * [http://www.thelostworlds.net/BO1/Map_Survey.html Blood Omen Map Survey (TheLostWorlds)] | ||
− | |||
− | |||
− | |||
− |