Toutes les informations que vous trouverez sur cette page
sont le fruit d'une recherche personnelle menée avec l'aide de
Calduirn.
Si vous trouvez des incohérences ou si vous avez des précisions à apporter
n'hésitez pas à me contacter.
Quoi qu'il en soit, je rappele que toutes ces données sont la propriété
de Vircom, veillez donc à ne pas entrer dans l'illégalité en utilisant
abusivement ces informations.
Les fichiers .VSF sont les librairies graphique du jeu,
elles contiennent l'ensemble des sprites et images utilisés dans
le jeu.
Ces fichiers sont encryptés à l'aide d'une clef de 8192 octets.
A l'interieur, les éléments sont organisés à l'aide d'un système de
noms de fichiers et répertoires.
On notera aussi qu'il existe deux grands groupes: les palettes et les
données graphiques.
Les fichiers .VSB sont encodés avec la même clef et mais sont architecturés
sur un principe plus simple et contiennent l'ensemble des sons et musiques du jeu.
Decodage
La clef de décodage est générée dans
le client en utilisant une fonction random.
La routine de décryptage peut se présenter ainsi: for (i=0; i<taille; i++)
vsf_datas[i] ^= vsfkey[(i/4096)&0xfff];
Chaque octet de la clef decode un bloc de 4096 octets du fichier à
l'aide d'un OU exclusif (XOR).
Format et structures
Une fois décodé le fichier VSF est organisé en chuncks.
Le premier étant le header:
Le header
+00 : Un long (???)
+04 : Nb de chuncks
+08 : Offset du chunck 1 par rapport au debut du fichier
+12 : Offset du chunck 2 par rapport au debut du fichier
...
Dans le cas d'un VSF normal, le premier chunck correspond à la zone
des "dossiers" et le deuxieme à la zone des "fichiers".
Le chunck "Dossiers"
Ces dossiers sont virtuels et ne servent qu'à l'organisation des
données pour l'affichage dans l'éditeur.
+00 : Nombre de structures "Folder" dans ce chunck.
+04 : Premiere structure.
+xx : Deuxieme structure.
...
+00 : [byte] Type de données 1=Graphique / 2=Palette
+01 : [long] Numéro d'identifiant du dossier
+05 : [long] Numéro d'itentifiant du dossier parent
+09 : [short] Nombre de caracteres du nom du dossier
+11 : [byte] Nom du dossier
Remarque: Il existe 2 dossiers "maître" qui ont pour id parent
0, il s'agit des dossiers "Sprites" et "Palettes"
qui contiennent l'ensemble des sous dossiers.
Le chunck "Fichiers"
+00 : Nombre de structures "File" dans ce chunck.
+04 : Premiere structure.
+xx : Deuxieme structure.
...
+00 : [byte] Type de données 1=Graphique / 2=Palette
+01 : [long] Offset de la structure
"Object" par rapport au debut du fichier.
+05 : [short] Nombre de caracteres du nom de l'objet
+07 : [byte] Nom de l'objet
Ces structures files pointent sur les données (Objects) elle-même.
Les structures "Object":
Il existe 2 types d'objets: les palettes et les sprites.
Ces 2 types utilisent la même entête de structure.
Les palettes:
+00 : Numéro d'identifiant du dossier parent
+04 : Données de la palette: 256 x RGB (1 octet par composante)
Les sprites:
+00 : Numéro d'identifiant du dossier parent
+04 : Type de sprite: 1=unpack/2=pack/3=empty
+05 : 1 octet padding
+06 : Largeur du sprite en pixel
+08 : Hauteur du sprite en pixel
+10 : Offset d'affichage X
+12 : Offset d'affichage Y
+14 : 2eme offset d'affichage X
+16 : 2eme offset d'affichage Y
+18 : 2 octets padding
+20 : 4 octets non définis (a "1" si il s'agit d'une tile "sol")
+24 : Numéro de la couleur transparente du sprite
+25 : 3 octets padding
+28 : Taille des données du sprite
+32 : Données graphique du sprite
Le 2eme offset d'affichage sert à l'affichage mirroir du sprite.
Les sprites non compactés sont des images indéxée, c'est à dire que
chaque octet correspond à une entrée dans la palette.
Les sprites compactés utilisent une compression run byte length décrite
dans le paragraphe suivant.
Les sprites "empty" quand à eux sont des sprites vide qui ne sont
là que pour reserver l'entrée.
Decompression
La compression est faite ligne par ligne.
Elle est organisée de la façon suivante:
+00 : Offset X du premier pixel à decompresser
+02 : Nombre de pixel à decompresser (octet 1*4+octet 2)
+04 : Marqueur de decompression (1=N pixels transparents/#1=copier
les N pixels suivants)
+xx : Marqueur de decompression (0=fin de sprite/2=fin de ligne)
Voici un exemple de code C de decompactage:
pt_pack=data;
x=y=0;
while(1)
{
// Index du premier pixel à decompresser
x=*(short *)pt_pack;
pt_pack+=2;
// Nombre de pixels à decompresser
nb_pix=pt_pack[0]*4+pt_pack[1];
pt_pack+=2;
pt_dpack=&tmp_sprite[x+(y*lg)];
if (*pt_pack++ != 1)
{
for (i=0; i<nb_pix; i++)
pt_dpack[i]=*pt_pack++;
}
else
x+=nb_pix;
if (*pt_pack == 0) // Fin de sprite
break;
if (*pt_pack++ == 2) // Fin de ligne
y++;