Skip to content

Instantly share code, notes, and snippets.

@subzey subzey/ufomaker.js Secret
Created May 20, 2013

Embed
What would you like to do?
ufomaker.js
#!/usr/bin/env node
var writeStream = require('fs').createWriteStream('ufo.pcx');
function write(){
byteArray = Array.prototype.slice.call(arguments);
writeStream.write(new Buffer(byteArray));
}
// Производитель. Всегда 0x0A
write(0x0A);
// Версия
// 0 - 16 стандартных цветов EGA
// 2 - 16 произвольных цветов
// 3 - без палитры
// 5 - с расширенной палитрой
write(0x02);
// Сжатие. Одно возможное значение - 1 (RLE)
write(0x01);
// Бит на пиксель.
// 4 цвета - 2 бита
write(0x02);
// Координаты левого верхнего угла.
// Без второй пары координат уже смысла не имеет, пишем для удобства (0, 0)
write(0x00, 0x00, 0x00, 0x00);
// Координаты правого нижнего угла.
// (6, 4), 4 x Uint, little-endian
write(0x06, 0x00, 0x04, 0x00);
// Разрешение по вертикали и горизонтали.
// Имеет смысл при печати и факсимильной связи. Пишем 72 dpi, 72 dpi
write(0x48, 0x00, 0x48, 0x00);
// 16-цветовая палитра. По одному байту на R, G и B.
write(0xFF, 0xFF, 0xFF); // (0) Белый, цвет фона
write(0x66, 0x66, 0x66); // (1) Светло-серый
write(0x40, 0x40, 0x40); // (2) Темно-серый
write(0x84, 0xA7, 0xCA); // (3) Синий
// добиваем палитру пустыми значениями до длины 16
write(0x00, 0x00, 0x00); // (4)
write(0x00, 0x00, 0x00); // (5)
write(0x00, 0x00, 0x00); // (6)
write(0x00, 0x00, 0x00); // (7)
write(0x00, 0x00, 0x00); // (8)
write(0x00, 0x00, 0x00); // (9)
write(0x00, 0x00, 0x00); // (10)
write(0x00, 0x00, 0x00); // (11)
write(0x00, 0x00, 0x00); // (12)
write(0x00, 0x00, 0x00); // (13)
write(0x00, 0x00, 0x00); // (14)
write(0x00, 0x00, 0x00); // (15)
// Зарезеривировано
write(0x0);
// Количество битовых плоскостей. R, G и B определяются палитрой, так что одна.
write(0x1);
// Байтов на сканлайн.
// В случае нескольких плоскостей в сканлайне — байтов на плоскость.
// Должно быть четным.
// 7 значений по 2 бита - два байта
write(0x02, 0x00);
// Тип палитры CGA. Мы ее не используем, так что забиваем нулями.
write(0x00, 0x00);
// Разрешение экрана. Еще одна мета-информация, которую все игнорируют.
// Пусть будет, 640x480
write(0x80, 0x02, 0xe0, 0x01);
// Добиваем нулями заголовок до 128 байт
for (var i=0; i<54; i++){
write(0x00);
}
// Растр
// Первый сканлайн: 00 00 10 10 10 00 00
// Первые 8 бит: 0x0A
// Последние два бита нам неизвестны, поэтому значение второго байта от 0x80 до 0x83.
// Особой разницы нет, выбираем 0x80.
// Спецзначений нет, экранировать не нужно
write(0x0A, 0x80);
// Второй сканлайн: 00 10 01 01 01 10 00
write(0x25, 0x60);
// Третий сканлайн: 10 10 10 10 10 10 10
write(0xAA, 0xAA);
// Четвертый сканлайн: 10 11 01 11 01 11 10
write(0xB7, 0x78);
// Пятый сканлайн: 00 10 10 10 10 10 00
write(0x2A, 0xA0);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.