2017-02-04 5 views
1

J'ai un fichier qui définit un ensemble de tuiles (utilisé dans un jeu en ligne). Le format de chaque tuile est la suivante:Les bits intstruct 32 bits ne semblent pas correspondre (nodejs)

x: 12 bits 
    y: 12 bits 
tile: 8 bits 

32 bits au total, de sorte que chaque tuile peut être exprimé comme un nombre entier de 32 bits.

Plus d'informations sur le format de fichier se trouve ici:

http://wiki.minegoboom.com/index.php/LVL_Format

http://www.rarefied.org/subspace/lvlformat.html

Les 4 structures d'octets ne sont pas brisées le long des limites d'octet. Comme vous pouvez voir x: et y: sont tous les deux définis comme 12 bits. c'est à dire. x est stocké dans 1,5 octets, y est stocké dans 1,5 octets et tile est stocké dans 1 octet.

Même si x et y utilisent 12 bits, leur valeur maximale est 1023, de sorte qu'ils peuvent être exprimés en 10 bits. C'était au créateur du format. Je suppose qu'ils remplissaient simplement les choses afin qu'ils puissent utiliser un entier de 32 bits pour chaque tuile? De toute façon, pour x et y nous pouvons ignorer les 2 derniers bits.

J'utilise un buffer nodejs pour lire le fichier et j'utilise le code suivant pour lire les valeurs. Ce code fonctionne bien mais quand je lis les bits eux-mêmes, dans une tentative pour mieux comprendre le binaire, je vois quelque chose qui me rend confus.

Prenez, par exemple un int qui exprime les éléments suivants:

x: 1023 
    y: 1023 
tile: 1 

Création des tuiles dans un éditeur de carte et la lecture du fichier résultant en un retour tampon <Buffer ff f3 3f 01>

Lorsque je convertir chaque octet en chaîne de bits je reçois les éléments suivants:

ff = 11111111 
f3 = 11110011 
3f = 00111111 
01 = 00000001 

11111111 11110011 00111111 00000001 

Je suppose que je devrais prendre les premiers 12 bits comme x mais côtelette de f les 2 derniers bits. Utilisez les 12 bits suivants comme y, en coupant à nouveau 2 bits, et les 8 bits restants seront les tile.

x: 1111111111 
    y: 0011001111 
tile: 00000001 

Le x est correct (1111111111 = 1023), le y est faux (0011001111 = 207, et non 1023), et la tuile est correcte (00000001 = 1)

Je suis confus et manifestement manquant quelque chose.

Répondre

1

Il est plus logique de regarder dans cet ordre: (ce serait la représentation binaire de n)

00000001 00111111 11110011 11111111 

Sur cet ordre, vous pouvez facilement faire le masquage et le déplacement visuellement.

Le problème avec ce que vous avez fait est que par exemple dans 11111111 11110011, les bits du deuxième octet qui appartiennent au premier champ sont au droit (la partie inférieure de cet octet), qui, dans cet ordre est discontinu .

En outre, le masquage avec 0x03FF fait que les deux premiers champs ont 10 bits, avec deux bits qui disparaissent. Vous pouvez les faire 12 bits en masquant avec 0x0FFF. Comme c'est le cas maintenant, vous avez effectivement deux bits de remplissage.

+0

Je ne comprends pas pourquoi ces bits seraient sur le * droit *. Que voulez-vous dire par la partie la plus basse? – samstr

+0

@samstr parce que c'est ainsi que nous écrivons habituellement les nombres, avec le chiffre le plus bas sur la droite et le chiffre le plus significatif sur la gauche. Si vous imprimez les bits dans un octet dans l'autre sens, alors dans votre ordre des octets a de nouveau un sens. Mais la combinaison de différents ordres (bit le plus bas à droite, mais octet le plus bas à gauche) le rend vraiment gênant. – harold

+0

merci! quand vous m'avez montré l'ordre '00000001 00111111 11110011 11111111' (représentation binaire de' n') quelque chose a cliqué. 'console.log (tileBuffer.readUInt32LE (0) .toString (2)); // 1001111111111001111111111' Il faut un peu de rembourrage mais je peux travailler avec ça. Merci encore! – samstr