« Fichiers MAP » : différence entre les versions
m (FunJp a déplacé la page Fichiers MAP (géographie des mondes virtuels) vers Fichiers MAP) |
Aucun résumé des modifications |
||
| (5 versions intermédiaires par le même utilisateur non affichées) | |||
| Ligne 20 : | Ligne 20 : | ||
Ces identifiants peuvent varier: | Ces identifiants peuvent varier: | ||
* 0x0000 à 0x0fff (0 à 4095 décimal) pour les versions de T4C jusqu'à la version 1.50 | * 0x0000 à 0x0fff (0 à 4095 décimal) pour les versions de T4C jusqu'à la version 1.50 | ||
* 0x0000 à 0x1fff (0 à 8191 décimal) pour les versions de T4C à partir de la version 1.60 | * 0x0000 à 0x1fff (0 à 8191 décimal) pour les versions de T4C à partir de la version 1.60 jusqu'à la 1.68 par Abomination. | ||
* 0x0000 à 0x4000 (0 à 16383 décimal) pour les versions de T4C à partir de la version 1.66NMS. | * 0x0000 à 0x4000 (0 à 16383 décimal) pour les versions de T4C à partir de la version 1.66NMS ainsi que les version 1.7x (fichier map1 et map2 seulement). | ||
* 0x0000 à 0x8000 (0 à 32768 décimal) pour fichiers mapa, mapl, mapm, mapx des version de T4C à partir de la version 1.70 | |||
La compression de chacun de ces blocs est assurée par une version simplifiée de [http://fr.wikipedia.org/wiki/Run-length_encoding l'algorithme RLE]. | La compression de chacun de ces blocs est assurée par une version simplifiée de [http://fr.wikipedia.org/wiki/Run-length_encoding l'algorithme RLE]. | ||
| Ligne 83 : | Ligne 84 : | ||
=== Algorithme pseudo-RLE utilisé par Vircom === | === Algorithme pseudo-RLE utilisé par Vircom === | ||
* Pour les fichiers .map jusqu'à la version 1.50, la valeur rle_value au-dessus de laquelle l'ID de la dalle sera interprétée comme un début de séquence compressée en RLE est 0x1000. | * Pour les fichiers .map jusqu'à la version 1.50, la valeur rle_value au-dessus de laquelle l'ID de la dalle sera interprétée comme un début de séquence compressée en RLE est 0x1000. | ||
* Pour les fichiers .map à partir de la version 1.60, la valeur rle_value au-dessus de laquelle l'ID de la dalle sera interprétée comme un début de séquence compressée en RLE est 0x2000. | * Pour les fichiers .map à partir de la version 1.60 jusqu'à la version 1.68, la valeur rle_value au-dessus de laquelle l'ID de la dalle sera interprétée comme un début de séquence compressée en RLE est 0x2000. | ||
* Pour les fichiers .map à partir de la version 1.66NMS, la valeur rle_value au-dessus de laquelle l'ID de la dalle sera interprétée comme un début de séquence compressée en RLE est 0x4000. | * Pour les fichiers .map à partir de la version 1.70 ainsi que la version 1.66NMS , la valeur rle_value au-dessus de laquelle l'ID de la dalle sera interprétée comme un début de séquence compressée en RLE est 0x4000. | ||
* Pour les fichiers .mapa, .mapl, .mapm et .mapx à partir de la version 1.70, la valeur rle_value au-dessus de laquelle l'ID de la dalle sera interprétée comme un début de séquence compressée en RLE est 0x8000. | |||
L'ID de départ des dalles commence, semble-t-il, à 0x354 (852 décimal). Cette valeur sera donc ajoutée à toutes les ID décompressées. | L'ID de départ des dalles commence, semble-t-il, à 0x354 (852 décimal). Cette valeur sera donc ajoutée à toutes les ID décompressées. | ||
| Ligne 145 : | Ligne 147 : | ||
Note : Un utilisateur intelligent pourrait recompresser les map efficacement en prenant avantage de la table d'offset, en effet rien n'interdit d'utiliser le même offset pour plusieurs block, ce qui selon la map peut être très rentable. | Note : Un utilisateur intelligent pourrait recompresser les map efficacement en prenant avantage de la table d'offset, en effet rien n'interdit d'utiliser le même offset pour plusieurs block, ce qui selon la map peut être très rentable. | ||
== Format d'un fichier Map 1.7 == | |||
Dans la version 1.7 du client, les maps clients ont changé radicalement. Maintenant, une seule carte de 3072x3072 cases est maintenant séparé en 6 fichiers distincts. | |||
Ce nouveau format multi-fichiers laisse penser à une séparation d'une même carte en plusieurs couches (layer). | |||
Si l'on regarde la carte "v2_worldmap", on retrouve les fichiers suivant : | |||
* v2_worldmap.map1 | |||
* v2_worldmap.map2 | |||
* v2_worldmap.mapa | |||
* v2_worldmap.mapl | |||
* v2_worldmap.mapm | |||
* v2_worldmap.mapx | |||
Les fichiers map1 et map2 semblent être la carte du monde séparés en 2 couches distinctes : sols et décors respectivement | |||
Les fichiers mapa, mapl, mapm ainsi que mapx utilisent une nouvelle constante RLE (0x8000). Ils pourrait être les nouvelle version des cartes gérant la musique par zone (ville, forêt, caverne, ...), la météo ? | |||
=== Fichier map1 === | |||
Ce fichier se décrypte de la même manière que les fichiers ".map" traditionnels. Ils utilisent le même algorithme pseudo-RLE avec la constante utilisé par NMS 1.66 | |||
Il semble la couche des sols. Les IDs de sprites ne collant pas a ceux utilisés précédemment, il est toute fois possible de distingué des formes de terrains connus. | |||
[[Fichier:Fichier map1.png|alt=Aperçu d'un fichier de type "map1"|néant|vignette|Aperçu d'un fichier de type "map1"]] | |||
==== Format ==== | |||
Le format canonique d'un fichier .map1 :<pre>[ 4 octets ][ 4 octets ][...][ 4 octets ][ N octets ][ N octets ][...][ N octets ] | |||
[Adr bloc 1][Adr bloc 2][...][Adr bloc 576][Données Bloc 1][Données Bloc 2][...][Données Bloc 576]</pre> | |||
=== Fichier map2 === | |||
Ce fichier se décrypte de la même manière que les fichiers ".map" traditionnels. Ils utilisent le même algorithme pseudo-RLE avec la constante utilisé par NMS 1.66 | |||
Il semble contenir la couche des décors. Cette fois, plusieurs sprites correspondent à ceux utilise dans les version précédente. Il s'agit ici de la même zone que dans l'image ci-haut | |||
[[Fichier:Fichier map2.png|alt=Aperçu d'un fichier de type "map2"|néant|vignette|Aperçu d'un fichier de type "map2"]] | |||
==== Format ==== | |||
Le format canonique d'un fichier .map2 :<pre>[ 4 octets ][ 4 octets ][...][ 4 octets ][ N octets ][ N octets ][...][ N octets ] | |||
[Adr bloc 1][Adr bloc 2][...][Adr bloc 576][Données Bloc 1][Données Bloc 2][...][Données Bloc 576]</pre> | |||
=== Fichier mapa === | |||
L'entête de ce fichier respecte toujours le même format : des adresses sur 4 octets suivies de données. Cependant, le contenu de cette couche n'est pas encore connu. | |||
Ils utilisent le même algorithme pseudo-RLE avec la nouvelle constante RLE introduite sur la version 1.70 : 0x8000 | |||
serait-ce mapA pour map-alpha afin de gérer la transparance/fondu des nouveaux sprites ? | |||
=== Fichier mapl === | |||
L'entête de ce fichier respecte toujours le même format : des adresses sur 4 octets suivies de données. Cependant, le contenu de cette couche n'est pas encore connu. | |||
Ils utilisent le même algorithme pseudo-RLE avec la nouvelle constante RLE introduite sur la version 1.70 : 0x8000 | |||
=== Fichier mapm === | |||
L'entête de ce fichier respecte toujours le même format : des adresses sur 4 octets suivies de données. Cependant, le contenu de cette couche n'est pas encore connu. | |||
Ils utilisent le même algorithme pseudo-RLE avec la nouvelle constante RLE introduite sur la version 1.70 : 0x8000 | |||
serait-ce mapM pour map-music ? | |||
=== Fichier mapx === | |||
L'entête de ce fichier respecte toujours le même format : des adresses sur 4 octets suivies de données. Cependant, le contenu de cette couche n'est pas encore connu. | |||
Ils utilisent le même algorithme pseudo-RLE avec la nouvelle constante RLE introduite sur la version 1.70 : 0x8000 | |||
--Jolinar 9 mai 2017 à 15:26 | |||
--Sorkvild 31 mars 2008 à 07:04 (MSD) (remerciements à Mestoph et à Calduirn pour l'algorithme) | --Sorkvild 31 mars 2008 à 07:04 (MSD) (remerciements à Mestoph et à Calduirn pour l'algorithme) | ||
Dernière version du 12 mai 2017 à 19:28
Généralités
Les fichiers .map contiennent la description des mondes virtuels sur lesquels vous jouez. Ces mondes sont des grilles de 3072x3072 cases, pavées avec des dalles de motifs différents (eau, sable, terre, herbe, rocher, graviers, pavage etc.), et décorés ci et là avec des sprites (éléments décoratifs qui s'affichent sur plus d'une case, tels que arbres, murs, rochers, montagnes, barrières etc.)
Ces mondes sont au nombre de cinq (à l'heure actuelle) :
- Le fichier worldmap.map décrit le monde principal : les trois îles d'Althéa, plus quelques îles supplémentaires et certains intérieurs de bâtiments. Les collisions relatives à ce monde sont représentées dans les fichiers WDA par la carte de collisions nommée "Realms of Oblivion".
- Le fichier dungeonmap.map décrit l'intérieur des donjons, tours, cryptes et bâtiments en dur, ainsi que l'île de Makrsh P'Tangh. Les collisions relatives à ce monde sont représentées dans les fichiers WDA par la carte de collisions nommée "Dungeons".
- Le fichier cavernmap.map décrit l'intérieur des grottes et des cavernes, ainsi que le Royaume de l'Oracle. Les collisions relatives à ce monde sont représentées dans les fichiers WDA par la carte de collisions nommée "Caverns".
- Le fichier underworld.map décrit dans sa partie supérieure six îles non utilisées dans le jeu d'origine, placées là à l'intention des techniciens des serveurs T4C qui désirent créer de toutes pièces des îles supplémentaires pour leurs joueurs, ainsi que dans sa partie inférieure, des grottes, des cavernes et des intérieurs de donjon pour accompagner celles-ci. Les collisions relatives à ce monde sont représentées dans les fichiers WDA par la carte de collisions nommée "Addon World".
- Le fichier leoworld.map, apparu avec la version 1.50, décrit encore d'autres zones non utilisées dans le jeu d'origine, placées là à l'intention des techniciens des serveurs T4C qui désirent créer de toutes pièces des îles supplémentaires pour leurs joueurs. Les collisions relatives à ce monde sont représentées dans les fichiers WDA par la carte de collisions nommée "LeoWorld".
A noter qu'à partir de la version 1.60 de T4C, le nom de ces fichiers a été préfixé par v2_ et leur format interne diffère très légèrement (changement d'une constante).
Format d'un fichier .map
Un fichier .map représente une grille de 3072x3072 positions. Cette grille est subdivisée en 24x24 blocs de 128x128 positions dans le fichier. Chacun de ces blocs est collé à la suite de l'autre, de gauche à droite et de haut en bas, mais les adresses de départ de chacun de ces blocs sont données en début de fichier, séquentiellement, sur quatre octets.
L'index de la première position du premier bloc correspond à la position 0,0 en jeu.
L'identifiant du dallage ou du sprite relatif à chacune de ces positions est décrit sur deux octets.
Ces identifiants peuvent varier:
- 0x0000 à 0x0fff (0 à 4095 décimal) pour les versions de T4C jusqu'à la version 1.50
- 0x0000 à 0x1fff (0 à 8191 décimal) pour les versions de T4C à partir de la version 1.60 jusqu'à la 1.68 par Abomination.
- 0x0000 à 0x4000 (0 à 16383 décimal) pour les versions de T4C à partir de la version 1.66NMS ainsi que les version 1.7x (fichier map1 et map2 seulement).
- 0x0000 à 0x8000 (0 à 32768 décimal) pour fichiers mapa, mapl, mapm, mapx des version de T4C à partir de la version 1.70
La compression de chacun de ces blocs est assurée par une version simplifiée de l'algorithme RLE.
Format canonique d'un fichier .map :
[ 4 octets ][ 4 octets ][...][ 4 octets ][ N octets ][ N octets ][...][ N octets ] [Adr bloc 1][Adr bloc 2][...][Adr bloc 576][Données Bloc 1][Données Bloc 2][...][Données Bloc 576]
Algorithme de lecture des blocs
La principale difficulté d'une fonction de lecture des blocs compressés réside dans la manière de calculer la position d'une ligne de données de 128 dalles dans le buffer de l'image décompressée. Ce calcul est le suivant :
adresse = (N° bloc ''modulo'' nb blocs en largeur) * largeur bloc * taille d'un élément
+ ((N° bloc / nb blocs en hauteur) * hauteur map * taille d'un élément * hauteur bloc)
+ N° ligne * hauteur map * taille d'un élément
Soit :
adresse = (N° du bloc % 24) * 128 * 2 // X de départ du bloc à partir de la gauche de l'image
+ ((N° du bloc / 24) * 3072 * 2 * 128) // Y de départ du bloc à partir du haut de l'image
+ N° de la ligne * 3072 * 2; // Y de départ de la ligne à partir du haut du bloc
On écrira donc la fonction comme suit :
void Map_Load (unsigned char *raw_data, unsigned char *image_data, unsigned short rle_value)
{
// this function deflates a raw map file data from raw_data into image_data, using the RLE
// trigger value specified in rle_value
int block_number;
int offset;
int line_number;
int pixel_address;
unsigned char *tmp_unpack; // mallocated
// allocate space for an unpacked block of data (128x128 array, 2 bytes per slot)
tmp_unpack = (unsigned char *) malloc (128 * 128 * sizeof (short));
// for each block...
for (block_number = 0; block_number < 24 * 24; block_number++)
{
// read the block start address from the beginning of the map file
offset = *(unsigned int *) &raw_data[block_number * 4];
// uncompress this block using Vircom's pseudo-RLE algorithm
RLE_UncompressBlock (&raw_data[offset], (unsigned short *) tmp_unpack, rle_value);
// for each line in this block...
for (line_number = 0; line_number < 128; line_number++)
{
// compute line's first final pixel location in the full image array
pixel_address = (block_number % 24) * 128 * 2
+ ((block_number / 24) * 3072 * 2 * 128)
+ line_number * 3072 * 2;
// and copy the line data at this location
memcpy ((char *) &image_data[pixel_address], (char *) &tmp_unpack[line_number * 128 * 2], 128 * 2);
}
}
// map is read, decompressed and now accessible in pt_image array
free (tmp_unpack); // we no longer need the tmp_unpack memory space, so release it
return; // finished
}
Algorithme pseudo-RLE utilisé par Vircom
- Pour les fichiers .map jusqu'à la version 1.50, la valeur rle_value au-dessus de laquelle l'ID de la dalle sera interprétée comme un début de séquence compressée en RLE est 0x1000.
- Pour les fichiers .map à partir de la version 1.60 jusqu'à la version 1.68, la valeur rle_value au-dessus de laquelle l'ID de la dalle sera interprétée comme un début de séquence compressée en RLE est 0x2000.
- Pour les fichiers .map à partir de la version 1.70 ainsi que la version 1.66NMS , la valeur rle_value au-dessus de laquelle l'ID de la dalle sera interprétée comme un début de séquence compressée en RLE est 0x4000.
- Pour les fichiers .mapa, .mapl, .mapm et .mapx à partir de la version 1.70, la valeur rle_value au-dessus de laquelle l'ID de la dalle sera interprétée comme un début de séquence compressée en RLE est 0x8000.
L'ID de départ des dalles commence, semble-t-il, à 0x354 (852 décimal). Cette valeur sera donc ajoutée à toutes les ID décompressées.
Format canonique d'un bloc compressé en RLE avec l'algorithme Vircom
Voici un exemple de séquence compressée :
[2 octets][2 octets][2 octets][2 octets][2 octets][2 octets][2 octets][2 octets] [ 0x0001 ][ 0x1009 ][ 0x0002 ][ 0x0003 ][ 0x0001 ][ 0x1004 ][ 0x0003 ][ 0x0005 ]
Ce bloc se lit : 0x0001 ; 9 fois 0x0002 ; 0x0003 ; 0x0001 ; 4 fois 0x0003 ; 0x0005.
Voici donc la même séquence, décompressée :
[2 octets][2 octets][2 octets][2 octets][2 octets][2 octets][2 octets][2 octets][2 octets][2 octets][2 octets][2 octets][2 octets][2 octets][2 octets][2 octets][2 octets] [ 0x0001 ][ 0x0002 ][ 0x0002 ][ 0x0002 ][ 0x0002 ][ 0x0002 ][ 0x0002 ][ 0x0002 ][ 0x0002 ][ 0x0002 ][ 0x0003 ][ 0x0001 ][ 0x0003 ][ 0x0003 ][ 0x0003 ][ 0x0003 ][ 0x0005 ]
On remarque que les spécifications standard du format RLE, telles que la parité obligatoire des séquences répétées ou les caractères de contrôle, ne sont pas respectées. [modifier]
Implémentation
La fonction suivante en C décompresse un bloc de données de 128x128 positions compressées avec l'algorithme pseudo-RLE de Vircom.
void RLE_UncompressBlock (unsigned char *packed_data, unsigned short *unpacked_data, unsigned short rle_value)
{
// this function deflates the map data corresponding to a 128x128 pixels size block from
// packed_data into unpacked_data using the RLE trigger value specified in rle_value.
int val;
int val2;
int i;
unsigned short *start_offset;
start_offset = unpacked_data; // remember block start address
// as long as we haven't deflated 128 * 128 = 16384 positions, i.e the full block...
do
{
val = *(unsigned short *) packed_data; // get the current value we're reading (2 bytes)
packed_data += 2; // advance in packed data
// is it below the RLE trigger value ?
if (val < rle_value)
{
*unpacked_data = 0x354 + val * 4; // if so, that's uncompressed data, so just copy it
unpacked_data++; // advance two bytes in deflated data
}
else
{
// else, this is a RLE compressed sequence size. Get the repeated value (2 bytes)
val2 = *(unsigned short *) packed_data;
packed_data += 2; // advance two bytes in packed data
// for each word of repeated RLE data...
for (i = 0; i < val - rle_value; i++)
{
*unpacked_data = 0x354 + val2 * 4; // duplicate it in the deflated buffer
unpacked_data++; // and advance two bytes in deflated data
}
}
}
while (unpacked_data - start_offset < 128 * 128);
return; // finished, block is deflated
}
Note : Un utilisateur intelligent pourrait recompresser les map efficacement en prenant avantage de la table d'offset, en effet rien n'interdit d'utiliser le même offset pour plusieurs block, ce qui selon la map peut être très rentable.
Format d'un fichier Map 1.7
Dans la version 1.7 du client, les maps clients ont changé radicalement. Maintenant, une seule carte de 3072x3072 cases est maintenant séparé en 6 fichiers distincts.
Ce nouveau format multi-fichiers laisse penser à une séparation d'une même carte en plusieurs couches (layer).
Si l'on regarde la carte "v2_worldmap", on retrouve les fichiers suivant :
- v2_worldmap.map1
- v2_worldmap.map2
- v2_worldmap.mapa
- v2_worldmap.mapl
- v2_worldmap.mapm
- v2_worldmap.mapx
Les fichiers map1 et map2 semblent être la carte du monde séparés en 2 couches distinctes : sols et décors respectivement
Les fichiers mapa, mapl, mapm ainsi que mapx utilisent une nouvelle constante RLE (0x8000). Ils pourrait être les nouvelle version des cartes gérant la musique par zone (ville, forêt, caverne, ...), la météo ?
Fichier map1
Ce fichier se décrypte de la même manière que les fichiers ".map" traditionnels. Ils utilisent le même algorithme pseudo-RLE avec la constante utilisé par NMS 1.66
Il semble la couche des sols. Les IDs de sprites ne collant pas a ceux utilisés précédemment, il est toute fois possible de distingué des formes de terrains connus.
Format
Le format canonique d'un fichier .map1 :
[ 4 octets ][ 4 octets ][...][ 4 octets ][ N octets ][ N octets ][...][ N octets ] [Adr bloc 1][Adr bloc 2][...][Adr bloc 576][Données Bloc 1][Données Bloc 2][...][Données Bloc 576]
Fichier map2
Ce fichier se décrypte de la même manière que les fichiers ".map" traditionnels. Ils utilisent le même algorithme pseudo-RLE avec la constante utilisé par NMS 1.66
Il semble contenir la couche des décors. Cette fois, plusieurs sprites correspondent à ceux utilise dans les version précédente. Il s'agit ici de la même zone que dans l'image ci-haut
Format
Le format canonique d'un fichier .map2 :
[ 4 octets ][ 4 octets ][...][ 4 octets ][ N octets ][ N octets ][...][ N octets ] [Adr bloc 1][Adr bloc 2][...][Adr bloc 576][Données Bloc 1][Données Bloc 2][...][Données Bloc 576]
Fichier mapa
L'entête de ce fichier respecte toujours le même format : des adresses sur 4 octets suivies de données. Cependant, le contenu de cette couche n'est pas encore connu.
Ils utilisent le même algorithme pseudo-RLE avec la nouvelle constante RLE introduite sur la version 1.70 : 0x8000
serait-ce mapA pour map-alpha afin de gérer la transparance/fondu des nouveaux sprites ?
Fichier mapl
L'entête de ce fichier respecte toujours le même format : des adresses sur 4 octets suivies de données. Cependant, le contenu de cette couche n'est pas encore connu.
Ils utilisent le même algorithme pseudo-RLE avec la nouvelle constante RLE introduite sur la version 1.70 : 0x8000
Fichier mapm
L'entête de ce fichier respecte toujours le même format : des adresses sur 4 octets suivies de données. Cependant, le contenu de cette couche n'est pas encore connu.
Ils utilisent le même algorithme pseudo-RLE avec la nouvelle constante RLE introduite sur la version 1.70 : 0x8000
serait-ce mapM pour map-music ?
Fichier mapx
L'entête de ce fichier respecte toujours le même format : des adresses sur 4 octets suivies de données. Cependant, le contenu de cette couche n'est pas encore connu.
Ils utilisent le même algorithme pseudo-RLE avec la nouvelle constante RLE introduite sur la version 1.70 : 0x8000
--Jolinar 9 mai 2017 à 15:26
--Sorkvild 31 mars 2008 à 07:04 (MSD) (remerciements à Mestoph et à Calduirn pour l'algorithme)