Бессонный хакатон
Думаю для кого-то это будет неожиданностью, но я ни разу в жизни не участвовал в хакатонах. Меня приглашали посудить парочку, но я сейчас про участие в качестве программиста. Странно, но несмотря на недавнюю бешеную популярность хакатонов, как-то не довелось.
А тут дочка после ветрянки подхватила какое-то ОРЗ с высокой температурой и у меня выдались две бессонные ночи — жена на конференции, мы с дочкой вдвоём. Из-за температуры она плохо спала, а я просыпался, потому что она меня часто будила.
В итоге, было проще не спать, чем спать вот так урывками, но просто так без сна листать ленты социальных сетей скучно, и я надумал устроить себе хакатон.
Условия — до рассвета решить какую-нибудь сложную задачу и чем бесполезнее, тем лучше. Я очень люблю бесполезные задачи на досуге, — полезных мне на работе хватает.
В момент этого решения я как раз долистал в какой-то из лент до ностальгических воспоминаний о «Спектруме» и вспомнил как набрёл когда-то на архив журналов «ZX-Ревю» и «ZX-Форум». Когда-то в детстве, когда у меня у самого был «Спектрум», я их выписывал.
Некоторые из них я тогда не смог посмотреть, так как они были в виде программ для «Спектрума» — издательство пыталось перейти на более прогрессивный формат электронного журнала.
Так я и определился с целью: выковырять содержимое этих журналов наружу, чтобы их можно было смотреть на моём ноутбуке не только в эмуляторе.
Для начала я поискал чем можно расковырять формат, в котором распространяется журнал. Утилита нашлась быстро и я даже поправил в ней небольшой баг — она не собиралась под «МакОС».
Изучение расковырянного содержимого принесло одно расстройство — внутри оказалось бинарное представление программы на Бейсике и несколько файлов неизвестного формата. Судя по тому как отображается журнал в эмуляторе, формат не текстовый. Вряд ли я бы справился с его обратным инжинирингом за ночь.
Поэтому я решил попробовать другую идею — сделать автоматическую скриншотилку, которая сдирала бы содержимое экрана эмулятора и собирала бы из него длинный графический файл. Так как у журнала двухуровневое меню, файлов должно образоваться несколько, а всю интерактивщину я решить сделать в обычном HTML и CSS.
В итоге получился набор инструментов из двух файлов на смеси bash и PHP.
Первый, make_screenshots скриншотит эмулятор, вырезает оттуда экран «Спектрума», жмёт на кнопку «вниз», заботится о том, чтобы экраны не дублировались и понимает когда больше не удаётся пролистнуть. Многие вещи там захардкожены — например, задержки, положение экрана эмулятора и кнопки на виртуальной клавиатуре.
Второй, convert_to_jpegs превращает полученный набор скриншотов в файлы JPEG. Во множественном числе, потому что оказалось, что максимальная высота файла JPEG — 65535 пикселей. В такую высоту у меня всё не влезало, поэтому пришлось разбивать получающуюся простыню два файла. Вообще, можно было бы использовать PNG, там такого ограничения нет, но он в таком размере очень сильно нагружает браузер.
Потом я эти скриншоты уже руками обверстал в HTML и планирую результат тоже положить на «Гитхаб», как только у меня закончится процесс оптимизации JPEG. Он очень долгий, но овчинка выделки стоит — около 20—25% экономии, а файлы там большие — по несколько мегабайт.
Как будет готово, напишу про это отдельный небольшой пост.
Круто, но потом же функционировать днём надо, а после бессонной ночи это очень проблематично и даже опасно для окружающих..
Здоровья дочке!
Увы, это моя не первая бессонная ночь и не последняя, я думаю, справлюсь )
Немного удивляет использование jpeg для количества цветов у Спектрума.
У меня используется JPEG с качеством 29, с ним он оставляет далеко позади формат PNG8 и тем более GIF.
А выгрузку статей в текстовом формате использовать не получилось? В разделе «Описание оболочки» говорится о такой возможности для распечатки или использовании листинга программ.
Там надо примерно так же, насколько я понял, — листать и выгружать. Это как-то совсем неудобно. Потом из эмулятора эти тексты надо каким-то образом получить (каким?). Мне кажется скриншоты проще, да и сохраняется вообще всё, включая цвет.