2017-02-04 28 views
1

У меня есть файл, который определяет набор фрагментов (используемых в онлайн-игре). Формат для каждой плитки выглядит следующим образом:32-битные биты int struct, похоже, не совпадают (nodejs)

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

32 бит в целом, так что каждая плитка может быть выражена в виде 32-разрядного целого числа.

Более подробную информацию о формате файла можно найти здесь:

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

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

В 4 байта структуры не сломаны по границам байтов. Как вы можете видеть x: и y: оба определены как 12 бит. то есть. x хранится в 1,5 байтах, y хранится в 1,5 байтах, а tile хранится в 1 байт.

Хотя x и y используют 12 бит, их максимальное значение равно 1023, поэтому их можно было бы выразить в 10 бит. Это было до создателя формата. Я предполагаю, что они просто дополняли вещи, чтобы они могли использовать 32-битное целое для каждой плитки? В любом случае, для x и y мы можем игнорировать последние 2 бита.

Я использую bufferjs Buffer для чтения файла, и я использую следующий код для чтения значений.

var n = tileBuffer.readUInt32LE(0); 
var x = n & 0x03FF; 
var y = (n >> 12) & 0x03FF; 
var tile = (n >> 24) & 0x00ff; 

Этот код работает отлично, но когда я прочитал сами биты, в попытке понять двоичный лучше, я вижу что-то, что меня смущает.

Возьмите, например, INT, который выражает следующее:

x: 1023 
    y: 1023 
tile: 1 

Создание плитки в редакторе карт и чтения результирующего файла в буфер возвращает <Buffer ff f3 3f 01>

Когда я конвертировать каждый байт в строка бит я получаю следующее:

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

11111111 11110011 00111111 00000001 

Я предполагаю, что я должен просто взять первые 12 бит, как x но отбивные из f последние 2 бита. Используйте следующие 12 бит как y, снова отрубив 2 бита, а остальные 8 бит будут tile.

x: 1111111111 
    y: 0011001111 
tile: 00000001 

x правильно (1111111111 = 1023), то y неправильно (0011001111 = 207, а не 1023), и плитка правильно (00000001 = 1)

Я запутался и, очевидно, не хватает что нибудь.

ответ

1

Это имеет смысл смотреть на него в таком порядке: (это будет двоичная n)

00000001 00111111 11110011 11111111 

В таком порядке, вы можете легко сделать маскировку и смещение визуально.

Проблема с тем, что вы сделали в том, что, например, в 11111111 11110011, биты второго байта, которые принадлежат к первому полю находятся в правой (самая нижняя часть этого байта), который в этом порядке является прерывистым ,

Кроме того, маскирование с помощью 0x03FF делает эти первые два поля имеющими 10 бит, причем два бита просто исчезают. Вы можете сделать их 12 бит путем маскировки с помощью 0x0FFF. Как и сейчас, вы фактически имеете два бита заполнения.

+0

Я не понимаю, почему эти биты будут на * праве *. Что вы подразумеваете под самой нижней частью? – samstr

+0

@samstr, потому что мы обычно пишем цифры, причем младшая цифра справа и самая значимая цифра слева. Если вы печатаете биты в байте, наоборот, тогда ваш порядок байтов снова имеет смысл. Но сочетание разных заказов (младший бит справа, но младший байт слева) делает его действительно неудобным. – harold

+0

спасибо! когда вы указали мне код '00000001 00111111 11110011 11111111' (двоичное представление' n'), что-то нажало. 'console.log (tileBuffer.readUInt32LE (0) .toString (2)); // 1001111111111001111111111' Для этого требуется некоторое заполнение, но я могу работать с этим. Еще раз спасибо! – samstr