Portal:InItalian/Formati dei file di Blood Omen

Questa pagina è dedicata alle specifiche per i formati dei file usati in Blood Omen. Include il lavoro di esplorazione fatto dalla community da quando Blood Omen è uscito.

La maggior parte dei formati semplici (come la struttura del file BIG, le specifiche del TIM) sono stati resi esplorabili anni fa, ma altri (il formato della mappa, gli sprite) soltanto di recente, durante lo sviluppo di Blood Pill.

File BIG
Questo è un file generale che contiene tutte le risorse di gioco. La sua struttura è molto semplice:

uint32 - numero di entries Array delle entries: uint32 - Nome hash del file uint32 - Dimensione del file uint32 - Offset del file Array dei dati della entry: bytes - Contenuti del file

Immagine TIM
Immagini per PlayStation. Usate per contenere gli elementi grafici e i componenti della mappa. Le specifiche dei TIM sono ben conosciute, quindi non verranno elencate qui. Riferimenti per decodificare e codificare sono disponibili nel codice sorgente di Blood Pill.

Consigli:
 * Alcune entries del pill.big possono contenere più file TIM fusi insieme.
 * Alcuni file TIM di Blood Omen possono terminare con dei null.

VAG
I file "Very-Audio-Good" per PlayStation (variazione ADPCM di 4-bit) usati nella versione PlayStation di Blood Omen e dal preview di gioco. Non sono usati nella versione PC. Riferimenti per decodificare e codificare sono disponibili nel codice sorgente di Blood Pill.

Consigli:
 * Molti file VAG sono senza header (il loro header è confuso, non c'è neppure il fourCC "VAGb", dunque possono essere individuati solo con un'analisi sintattica).
 * Normalmente andrebbero eseguiti a 11025hz, ma alcuni (le musiche e alcuni effetti sonori) a 22050hz.

IMA ADPCM grezzi
Dei file senza header che contengono flussi grezzi IMA ADPCM che servono a sostituire i file VAG nella versione PC. Usano esattamente gli stessi nomi dei file VAG per la PlayStation.

File audio WAV
Blood Omen per PC ha alcuni effetti sonori in formato WAV (La PlayStation li ha in VAG). Questo formato è largamente conosciuto e non c'è bisogno di spiegarlo.

STR della PSX
Usato nella versione PlayStation di Blood Omen. L'STR è un flusso video MJPEG con l'audio aggiunto come interleave. Si può usare il tool jPsxDec per estrarre e decodificare questo formato dall'immagine del cd per PlayStation del gioco.

Video JAM
JAM è un formato di compressione video scadente sviluppato da Semilogic Entertainment e usato nella versione PC di Blood Omen. Il formato usa una tavolozza in comune con più frame e un tipo di compressione dinamica. La specifica e la decodifica dei JAM sono state scoperte nel 2011 da MisterGrim. Il JAM può solo contenere video, l'audio era contenuto in un file VAG separato (che era, in effetti, un IMA ADPCM grezzo).

I video JAM hanno molte più alterazioni dei STR, e la traccia audio è in mono (gli STR hanno una stereo).

Il codice per decomprimere i JAM è disponibile nel codice sorgente di Blood Pill.

Gli sprite
Gli sprite sono immagini di personaggi o altre cose animate. Ci sono tre estensioni e altrettanti nomi dei file: SHA, SDR, SHD. Tuttavia quando Blood Pill è stato sviluppato non erano noti i veri nomi dei file, quindi questa specifica viene definita "Tipi di sprite" e copre la decompressione di tutti gli sprite, inclusi quelli non utilizzati.

Sprite di tipo 1 - Carte degli oggetti
Ha sempre 1 frame e nessuna compressione.

uint32 - sempre 0x01 0x00 0x00 0x00 uint32 - dimensione del file 768 bytes - dati della mappa dei colori a 24 bit (256 colori) int16 - posizione su x int16 - posizione su y byte - larghezza byte - altezza byte - x byte - y larghezza*altezza bytes - contenuto dell'immagine (gli indici nella mappa dei colori)

Sprite di tipo 2 - Insieme di immagini
Sprite a più frame con tavolozza dedicata ad ogni frame. Usato per le raccolte di immagini dell'interfaccia (come le immagini degli incantesimi e degli oggetti).

uint32 - numero di frame uint32 - dimensione del file 768 bytes - dati della mappa dei colori a 24 bit (inutilizzato) Array degli header del frame: 768 bytes - dati della mappa dei colri a 24 bit uint32 - offset dei dati dell'immagine dalla fine degli header ubyte - larghezza ubyte - altezza byte - x  byte - y Array dei dati dell'immagine del frame: larghezza*altezza bytes - contenuto dell'immagine (gli indici nella mappa dei colori)

Sprite di tipo 3 - Sprite degli oggetti
Sprite a più frame con tavolozza condivisa.

uint32 - numero di frame uint32 - dimensione del file 768 bytes - dati della mappa dei colori a 24 bit int16 - offset in x per tutti i frame int16 - offset in y per tutti i frame Array degli header del frame: uint32 - offset dei dati dell'immagine dalla fine degli header ubyte - larghezza ubyte - altezza byte - x  byte - y Array dei dati dell'immagine del frame: bytes - contenuti dell'immagine compressa (gli indici nella mappa dei colori) usando un run-length encoding; alcuni file usando colori a 4 bit (vedi )

Consigli:
 * Non si sa come scoprire quale compressione del file sia usata (RLE a 0x00, o 0xFF o entrambe), sembra che l'engine dia questa informazione quando il file viene caricato
 * Alcuni file usano colori a 4 bit invece che RLE

Sprite di tipo 4 - Sprite dei personaggi
Sprite a più frame con tavolozza condivisa, con header dei frame aggiuntivi. Usato dai personaggi. Molto simile al tipo 3.

uint32 - numero di frame uint32 - dimensione del file Array degli header aggiuntivi del frame (arrotondati per eccesso al multiplo di 4 più vicino): byte - informazioni ignote 768 bytes - dati della mappa dei colori a 24 bit int16 - offset in x per tutti i frame int16 - offset in y per tutti i frame Array dehli header del frame: uint32 - offset dei dati dell'immagine dalla fine degli header ubyte - larghezza ubyte - altezza byte - x  byte - y Array dei dati dell'immagine del frame: bytes - contenuti dell'immagine compressa (gli indici nella mappa dei colori) usando un run-length encoding; alcuni file usando colori a 4 bit (vedi )

Consigli:
 * Non si sa come scoprire quale compressione del file sia usata (RLE a 0x00, o 0xFF o entrambe), sembra che l'engine dia questa informazione quando il file viene caricato
 * Alcuni file usano colori a 4 bit invece che RLE

Sprite di tipo 5
Un'altra variante del tipo 3 senza informazioni sull'offset e (a volte) con larghezza e altezza non valide, da mettere a posto con un particolare trucco.

uint32 - numero di frame uint32 - dimensione del file 768 bytes - dati della mappa dei colori a 24 bit Array degli header del frame: uint32 - offset dei dati dell'immagine dalla fine degli header ubyte - larghezza ubyte - altezza byte - x  byte - y Array dei dati dell'immagine del frame: bytes - contenuti dell'immagine compressa (gli indici nella mappa dei colori) che usano RLE (vedi )

Consigli:
 * Alcuni frame hanno larghezza e altezza non valide perché la loro larghezza è maggiore di 255 e il formato usa 1 bit per codificarle. Per correggere il problema va usato 255 + [larghezza]
 * Non si sa come scoprire quale compressione del file sia usata (RLE a 0x00, o 0xFF o entrambe), sembra che l'engine dia questa informazione quando il file viene caricato

Mappe
Le mappe sono un elemento centrale che mette insieme tutte le risorse (immagini, suoni, mattonelle, sprite). Circa l'80% della struttura della mappa è stata scoperta e questo permette di estrarre una serie di cose, incluse: le texture usate, l'immagine della mappa, posizione di mostri/effetti/oggetti, attivatori, informazioni scritte, porte e bottoni...

Ogni mappa ha un mapnum (numero della mappa) e una sezione inclusa nel nome del file. Quell'informazione viene usata per piazzare la mappa nella mappa globale di un'avventura (vedi TheLost Worlds - May survey per le informazioni complete sui nomi dei livelli).

Mattonelle
Le mattonelle sono immagini TIM a 256 colori compresse con LZ77 (vedi ).

La texture di ogni mattonella ha 8x8=64 mattonelle. L'engine renderizza ogni mattonella separatmaente, spostando la texture della mattonella del momento come necessario.

uint32 - dimensione dei dati compressi bytes - dati compressi

Consigli:
 * Dato che tutte le mattonelle sono dei TIM a 8 bit 256x256, la dimensione dei dati decompressi è sempre la stessa

File della mappa
Il file della mappa è una struttura di lunghezza fissa che contiene la posizione delle mattonelle (80x80), i nemici, le luci, i botoni e altri oggetti che compongono il livellod i Blood Omen. Per via della sua natura statica ha molti limiti, e ogni mappa ha esattamente la stessa dimensione (quindi basta copiarla in memoria).

// map trigger typedef struct {      unsigned short parm1;    // primo parm, se non definito lo script è 0xFFFF, 0xFFFE è il valore null // - numero di mappa di destinazione/origine (TRIGGER_EXIT, TRIGGER_ENTRANCE, TRIGGER_TELEPORT) // - numero del discorso (TRIGGER_INFOMARK, TRIGGER_IMAGEMARK) unsigned short parm2;   // secondo parm: // - numero del pulsante (TRIGGER_BUTTON) // - numero dell'immagine (TRIGGER_IMAGEMARK) byte          parm3;    // sezione della mappa di destinazione/origine (TRIGGER_EXIT, TRIGGER_ENTRANCE, TRIGGER_TELEPORT) byte          srcx;     // posizione byte          srcy;     // posizione byte          type;     // tipo di script, uno dei TRIGGER_ byte          u2 [ 3 ] ;    // ? byte          x;        // posizione byte          y;        // posizione byte          u3 [ 3 ] ;    // ? } bo_trigger_t; // oggetto della mappa typedef struct {      unsigned short savenum;  // id unico di salvataggio byte          itemcode; // uno dei codici MAPITEM_ byte          x;        // posizione byte          y;        // posizione byte          hidden;   // vale 1 se l'oggetto viene spawnato da un attivatore (come la distruzione di un barile) unsigned short target;  // gruppo di attivatori bersaglio byte          u [ 4 ] ;     // ? } bo_item_t; // mattonella animata typedef struct {      unsigned short targetnum; // un gruppo di attivatori byte x;                 // posizione byte u1;                // ? byte y;                 // posizione byte u2;                // ? unsigned short tile1;   // numero della mattonella unsigned short tile2;   // numero della mattonella allo stato alternativo byte contents1;         // contenuti, vedi le definizioni di CONTENTS_ per i possibili valori dei contenuti byte contents2;         // contenuti allo stato alternativo byte u3 [ 12 ] ;            // ? } bo_atile_t; // controller del pulsante typedef struct {      unsigned short target;   // un gruppo di attivatori da chiamare unsigned short tile1;   // numero della mattonella unsigned short tile2;   // numero della mattonella allo stato alternativo byte flags;             // vedi le definizioni dei BUTTONFLAG_* byte u1;                // ? unsigned short savenum; // id unico di salvataggio byte u2;                // ? byte u3;                // ? } bo_button_t; // effetto typedef struct {      byte x;                  // posizione byte y;                 // posizione byte lightposx;         // posizione della fonte di luce byte lightposy;         // posizione della fonte di luce byte sprite;            // indice dello sprite dall'array degli sprite byte lightsizex;        // dimensione dei poligoni di luce byte lightsizey;        // dimensione dei poligoni di luce byte u1;                // ? byte lightform;         // flag della forma della luce byte r;                 // quantità di rosso byte g;                 // quantità di verde byte b;                 // quantità di blu unsigned short targetnum; // gruppo di attivatori byte start_on;          // 1 se l'effetto parte attivo, 0 se parte disattivo byte u3 [ 5 ] ;             // ? } bo_effect_t; typedef struct {      byte data [ 164 ] ; } bo_object_t; // definizione dell'oggetto sulla mattonella (barili, forzieri) typedef struct {      byte x;                  // posizione iniziale byte y;                 // posizione finale byte w;                 // larghezza byte h;                 // altezza byte ofsx;              // moltiplica per 16 per il vero offset byte ofsy;              // moltiplica per 16 per il vero offset byte u1; byte u2; } bo_grpobject_t; // entità dello scenario typedef struct {      byte u1;                 // ? byte u2;                // ? byte u3;                // ? byte u4;                // ? unsigned short tile1;   // mattonella base (in realtà l'oggetto gruppo, non la mattonella 32x32 standard       unsigned short tile2;    // mattonella alternativa (oggetto gruppo)       unsigned short tile3;    // mattonella distrutta (oggetto gruppo)       byte u5;                 // ?       byte u6;                 // ?       byte pushable;           // una forza necessaria per spingere       byte toggled;            // l'attivatore che cambia lo stato (significa che c'è la mattonella 2)       byte u7;                 // ?       byte spawnitems [ 3 ] ;      // codici dell'oggetto da spawnare quando attivato/distrutto       byte u8;                 // ?       byte destructible;       // i flag distruggibili       unsigned short savenum;  // id unico di salvataggio       byte u10;                // ? byte x;                 // posizione byte y;                 // posizione byte u11;               // ? byte active;            // 1 è pieno, altrimenti 0 byte u13;               // ? } bo_scenery_t; // tracciati dei nemici typedef struct {      byte x;                  // posizione byte y;                 // posizione byte u1;                // ? byte u2;                // ? } bo_path_t; // entità nemica typedef struct {      bo_path_t paths [ 4 ] ;      // tracciati di pattugliamento byte u1 [ 12 ] ;            // ? unsigned short savenum; // id unico di salvataggio byte u2 [ 52 ] ;            // ? byte charnum;           // classe del mostro (come per lo sprite del personaggio) byte u3 [ 10 ] ;            // ? unsigned short target;  // gruppo di attivatori da chiamare quando viene ucciso byte u4 [ 20 ] ;            // ? byte lastpath;          // ? byte u6 [ 18 ] ;            // ? byte u7 [ 15 ] ;            // ? byte x;                 // posizione byte y;                 // posizione byte u8 [ 4 ] ;             // ? unsigned short speechnum; // un numero di parlato per i discorsi del travestimento byte u9 [ 6 ] ;             // ? } bo_monster_t; // struttura generale del file della mappa typedef struct {      // una catena di numeri della mappa delle mattonelle usati (per creare i nomi dei file) // ogni mappa delle mattonelle contiene 64 mattonelle, i cui numeri sono lineari // per esempio, una mattonella #131 è la mattonella #3 dalla mappa delle mattonelle #2 // con flag da 2-byte (abbreviazione senza firma) contenuti nel numero della mattonella (i flag cominciano dal byte 10) // vedi le definizioni dei TILEFLAG_ per i possibili flag delle mattonelle unsigned short tilemaps [ 40 ] ; // informazione ancora ignota byte           u1 [ 12 ] ; bo_object_t    objects [ 10 ] ; bo_monster_t   monsters [ 32 ] ; bo_grpobject_t grpobjects [ 8 ] [ 32 ] ; // mattonelle animate - una mattonella che può essere in 2 stati e che ha contenuti diversi ad ogni stato // usato per le porte, le punte che escono dal terreno ecc. // le mattonelle animate hanno un gruppo di attivatori da eseguire con degli script bo_atile_t     atiles [ 100 ] ; // l'array di un pulsante speciale controlla tutti i pulsanti usati nel livello // molto simile alle mattonelle animate // i pulsanti hanno gruppi di attivatori da eseguire con degli script bo_button_t    buttons [ 20 ] ; // informazione #2 ancora ignota byte           u2 [ 8 ] ; // oggetti spingibili nella scena - tavoli, sedie, pietre ecc. bo_scenery_t   scenery [ 256 ] ; // prima mappa delle mattonelle unsigned short backtiles [ 80 ] [ 80 ] ; // seconda mappa delle mattonelle unsigned short foretiles [ 80 ] [ 80 ] ; // mappa dei contenuti - un valore di contenuto per ogni mattonella statica (in gioco vengono sostituite dalle mattonelle modificabili, se presenti) // vedi le definizioni dei CONTENTS_ per i possibili valori dei contenuti byte           contents [ 80 ] [ 80 ] ; // linear triggers array - all triggers used on map bo_trigger_t   triggers [ 255 ] ; // triggers are non-solid interaction points, activated when player stands in them // this array golds pointers to triggers byte           triggertiles [ 80 ] [ 80 ] ; // oggetti piazzati nel livello // i codici degli oggetti 0-9 sono potenziamenti, i codici 10, 11, 12, 13 sono riservati per i codici di oggetti unici // quindi non possono esserci più di 4 tipi di oggetti unici in ogni livello //sono oggetti unici: incantesimi, armi, forme, artefatti, oggetti delle missioni byte           uniqueitems [ 4 ] ; bo_item_t      items [ 50 ] ; // dati ancora sconosciuti byte           u4 [ 8 ] ; byte           u5 [ 8 ] [ 40 ] ; byte           u6 [ 24 ] ; // effetti unsigned short sprites [ 8 ] ; bo_effect_t    effects [ 64 ] ; // dati ancora sconosciuti byte  u7 [ 936 ] ; } bo_map_t; // cose ancora non capite: // - come funziona l'illuminazione (luci di vario tipo, luce di notte e giorno, luce ambientale) // - gli interruttori dei tracciati dei mostri (alcuni tracciati sono incasinati) // - counter e attivatori dei puzzle? // flag delle mattonelle // contenuti // attivatori // flag dei pulsanti // codici degli oggetti // codici degli oggetti unici
 * 1) define TILEFLAG_UNKNOWN1      1024
 * 2) define TILEFLAG_NODRAW        2048
 * 3) define TILEFLAG_UNKNOWN3      4096
 * 4) define TILEFLAG_UNKNOWN4      8192
 * 5) define TILEFLAG_ALWAYSONTOP   16384
 * 6) define TILEFLAG_UNKNOWN6      32768
 * 1) define CONTENTS_SOLID         1
 * 2) define CONTENTS_WATER         2
 * 3) define CONTENTS_LAVA          3
 * 4) define CONTENTS_FIRE          4
 * 5) define CONTENTS_SPIKES        5
 * 6) define CONTENTS_TRAPTELEPORT  6
 * 7) define CONTENTS_JUMPWALL      8
 * 8) define CONTENTS_SWAMP         11
 * 9) define CONTENTS_JUMPFENCE     10
 * 10) define CONTENTS_MISTWALK      12
 * 11) define CONTENTS_SACRIFICE     13
 * 12) define CONTENTS_ICE           19
 * 13) define CONTENTS_SAVEGAM       44
 * 14) define CONTENTS_BATMARK       45
 * 1) define TRIGGER_EXIT           1
 * 2) define TRIGGER_ENTRANCE       2
 * 3) define TRIGGER_SPEECHMARK     3
 * 4) define TRIGGER_TOUCH          4
 * 5) define TRIGGER_TELEPORT       6
 * 6) define TRIGGER_IMAGEMARK      7
 * 1) define BUTTONFLAG_TOGGLE      1
 * 2) define BUTTONFLAG_SECRET      2
 * 1) define MAPITEM_SMALLBLOODFLASK 1
 * 2) define MAPITEM_BLOODFLASK     2
 * 3) define MAPITEM_RUNEPYRAMID    3
 * 4) define MAPITEM_PURPLESPHERE   4
 * 5) define MAPITEM_BLUESPHERE     5
 * 6) define MAPITEM_GREENSPHERE    6
 * 7) define MAPITEM_GOLDSPHERE     7
 * 8) define MAPITEM_REDSPHERE      8
 * 9) define MAPITEM_ANCIENTVIAL    9
 * 10) define MAPITEM_UNIQUE1        10 // codici di oggetti unici
 * 11) define MAPITEM_UNIQUE2        11 // codici di oggetti unici
 * 12) define MAPITEM_UNIQUE3        12 // codici di oggetti unici
 * 13) define MAPITEM_UNIQUE4        13 // codici di oggetti unici
 * 1) define ITEM_SPELL_INSPIREHATE 10
 * 2) define ITEM_SPELL_STUN        11
 * 3) define ITEM_SPELL_SPIRITWRACK 12
 * 4) define ITEM_SPELL_BLOODGOUT   13
 * 5) define ITEM_SPELL_BLOODSHOWER 14
 * 6) define ITEM_SPELL_SPIRITDEATH 15
 * 7) define ITEM_SPELL_LIGHT       16
 * 8) define ITEM_SPELL_LIGHTNING   17
 * 9) define ITEM_SPELL_REPEL       18
 * 10) define ITEM_SPELL_ENERGYBOLT  19
 * 11) define ITEM_SPELL_INCAPACITATE 20
 * 12) define ITEM_SPELL_CONTROLMIND 21
 * 13) define ITEM_SPELL_SANCTUARY   22
 * 14) define ITEM_ARTIFACT_FLAY     23
 * 15) define ITEM_ARTIFACT_PENTALICH 24
 * 16) define ITEM_ARTIFACT_IMPLODE  25
 * 17) define ITEM_ARTIFACT_FONT     26
 * 18) define ITEM_ARTIFACT_BANK     27
 * 19) define ITEM_ARTIFACT_HEART    28
 * 20) define ITEM_ARTIFACT_ANTITOXIN 29
 * 21) define ITEM_ARTIFACT_SLOWTIME 30
 * 22) define ITEM_TOKEN_MOEBIUS     31
 * 23) define ITEM_TOKEN_DEJOULE     32
 * 24) define ITEM_TOKEN_DOLL        33
 * 25) define ITEM_TOKEN_MALEK       34
 * 26) define ITEM_TOKEN_AZIMUTH     35
 * 27) define ITEM_TOKEN_MORTANIUS   36
 * 28) define ITEM_TOKEN_NUPRAPTOR   37
 * 29) define ITEM_TOKEN_BANE        38
 * 30) define ITEM_TOKEN_SIGNETRING  39
 * 31) define ITEM_TOKEN_TIMEDEVICE  40
 * 32) define ITEM_TOKEN_ANACROTHE   41
 * 33) define ITEM_WEAPON_MACE       43
 * 34) define ITEM_WEAPON_AXES       44
 * 35) define ITEM_WEAPON_FLAMESWORD 45
 * 36) define ITEM_WEAPON_SOULREAVER 46
 * 37) define ITEM_ARMOR_BONE        48
 * 38) define ITEM_ARMOR_CHAOS       49
 * 39) define ITEM_ARMOR_FLESH       50
 * 40) define ITEM_ARMOR_WRAITH      51
 * 41) define ITEM_FORM_BAT          53
 * 42) define ITEM_FORM_WOLF         54
 * 43) define ITEM_FORM_DISGUISE     55
 * 44) define ITEM_FORM_MIST         56
 * 45) define ITEM_ENDING_1          69
 * 46) define ITEM_ENDING_2          70

Metodi di compressione
 Run Length Encoding (RLE) basato sull'indice

Usato sui dati degli sprite per comprimere le zone nere che normalmente sono trasparenti. Questa tecnica altera il processo di lettura dei byte 0x0 e 0xFF. Se durante la lettura dei dati dell'immagine si ottiene questo byte, si dovrà leggere un byte in più che conterrà il numero di volte che quel byte va ripetuto. Blood Omen RLE è usato solo per valori di 0x00 o 0xFF. Esempio:

// output di 32 byte col valore 0xFF 0xFF 0x20

Immagini a 4 bit

Codifica 2 pixel per ogni byte con una tavolozza da 256 colori ma con solo 16 colori usati (gli altri pixel sono neri).

Per ogni byte produce 2 byte, in ordine: Esempio:
 * byte 1: - (int)( /16)*16; // mod 16
 * byte 2: (int)( /16) // div 16

231 manderà in output 2 pixel coi valori: byte 1: 7 byte 2: 14

Variazione del LZ77

Una variazione degli algoritmi di compressione dei dati del LZ77 (LZ1).

Un decodificatore campione è disponibile a The Lost Worlds e nel codice sorgente di Blood Pill.

Ringraziamenti

 * Andrey [Rackot] Grachev - specifiche del file BIG
 * Pavel [VorteX] Timofeyev - file della mappa, sprite
 * Ben Lincoln - decompressore LZ77
 * Specifiche di decodifica JAM di MisterGrim
 * Balder e Zench dai forum di XentaX (www.xentax.com) - IMA ADPCM

Vedere anche

 * Blood Pill
 * jPsxDec homepage
 * TIM specifications at QHimmWiki
 * Blood Omen Decompressor homepage
 * Blood Omen Map Survey (TheLostWorlds)