Этот сайт — моя персональная записная книжка. Интересна мне, по большей части, история, своя жизнь и немного программирование.

Избранное

Ненормальное программирование

Введение

Недавно разговорился с одним приятелем, тема разговора как-то мало-помалу сместилась в программирование. Оказалось, он давно читает мой блог и удивляется почему я, по его словам, «в последнее время увлёкся совершенно непрактичным программированием».

Я его удивил, рассказав, что тема «непрактичного» или, как я его ещё называю, «ненормального программирования» привлекает меня давно, по меньшей мере с конца 90-х годов. Я таким образом отдыхаю, выражаю свои эмоции по поводу вещей, которые меня чем-то зацепили или пытаюсь обратить внимание читателей на малооценённые концепции.

Более нормальным программированием я тоже занимаюсь, но чаще всего это работа или какая-то рутинная необходимость. В этом посте я хочу рассказать о нескольких моих проектах, которые, как я думаю, попадают под определение ненормального программирования. Проектах, которые создавались без цели как-то их напрямую использовать, так сказать, по зову души.

«Junix» (1999—2003)

Это самый старый из сохранившихся подобных проектов. И, наверное, самый монументальный. Дело было в конце 90-х, тогда ДжаваСкрипт мало кто воспринимал всерьёз. В основном его использовали для какого-нибудь простенького интерактива или, максимум, относительно несложных игр, типа «Тетриса».

Мне же было очевидно, что ДжаваСкрипт уже можно использовать для большего. Я так был уверен в своей идее, что был готов продемонстрировать её всему миру. Проект занял несколько лет — в начальной фазе я занимался им каждый вечер на протяжении нескольких месяцев, а потом изредка реализовывал какие-то идеи. Наверное это очень долго, но с документацией тогда было негусто, кроме того в каких-то вещах я был первопроходцем.

Так у меня получилось что-то вроде эмулятора командной строки «Линукса». Это был первый такой проект в мире и о нём написали все топовые интернетные издания того времени. Я реализовал интерпретатор, похожий на tcsh, несколько утилит и аналог терминала с доступом к файловой системе.

«JS-FTPd» (2001)

В то время, когда я делал этот проект, ДжаваСкрипт ещё не был монополистом в мире браузерных языков. Существовало несколько альтернативных технологий, так, например, в браузерах была технология «апплетов», позволявших писать небольшие встраиваемые в браузер приложения на языке Джава.

В то же время в браузере «Нетскейп» была нестандартная технология «LiveConnect», которая позволяла вызывать Джаву из ДжаваСкрипта, а так же запрашивать из браузера различные разрешения, например, на сетевое взаимодействие. Впервые я познакомился с этой технологией, когда писал «Junix», там я через неё работал с диском компьютера, а в этом проекте мне захотелось изучить работу с сокетами.

Используя «LiveConnect» я написал FTP-сервер — на ДжаваСкрипте, вызывая Джаву там, где ДжаваСкрипт что-то не умел. Заодно детально разобрался как устроен протокол FTP, что потом часто пригождалось.

«Крестики-нолики» на HTML и CSS (2011)

Тема игр для компьютера без программирования меня давно интересовала.Я написал их несколько. В основном, с использованием HTML и CSS. Ни тот ни другой языками программирования не считаются, тем не менее, развились настолько, что на них можно писать очень сложные интерактивные вещи.

«Крестики-нолики» один из таких проектов, где я экспериментировал с тем, что можно сделать, не прибегая к более традиционным методам создания игр в браузере.

«Арканоид» на bash (2011)

В рамках этой игры я хотел испытать две концепции.

Во-первых, мне хотелось создать в командной строке игру в реальном времени. Почему-то тогда никто не додумался до того как можно опрашивать клавиатуру, не останавливая при этом шелловский скрипт. Потом этот приём широко распространится, но в то время, насколько я могу судить, я придумал его первым.

Во-вторых, я задумал сделать игру со звуком. Для этого у меня использовался встроенный в «МакОС» синтез голоса через команду say. Манипулируя скоростью и подбирая разные смешные голоса, мне удалось сделать несколько уместных, как мне кажется, звуковых эффектов.

«Шахматы» на языке утилиты sed (2013)

Когда я решил написать шахматы на sed, знакомые, с которыми я поделился своей идеей, подумали, что я сошёл с ума. Ну а как иначе? sed — в их глазах не язык программирования, а текстовый редактор, который умеет менять «кота» на «собаку» в конфигах.

Но мне хотелось доказать, что даже в таком примитиве можно выжать больше, чем кажется. В итоге я провёл две недели в диалоге с регулярными выражениями: заставлял их считать, сравнивать числа в придуманном мной формате 111::11 (так в нём записывается число 302) и имитировать логику шахматного ИИ. Каждый день я порывался бросить: когда код превращался в лабиринт из меток и переходов, а функция вычитания занимала 59 строк, но упрямство перевешивало.

Как я уже сказал, большая часть логики сделана на регулярных выражениях, поверх которых я написал мета-язык, на котором уже и писал шахматы, благо в sed есть способ переиспользования кода. Было очень тяжело, но мне так нравилась идея, что я справился. Это был настолько сложный проект, что его выпуск породил волну публикаций по всему интернету. Информационный гул заметили даже «Гугле» и пригласили на собеседование, но я отказался.

«Тетрис» на языке AppleScript (2017)

Встроенный в «МакОс» язык автоматизации «ЭплСкрипт», кажется, никто никогда для написания игр использовать и не пытался. По крайней мере, я таких попыток не обнаружил. И немудрено — сходу неясно чем бы он мог таким оперировать, чтобы взаимодействовать с пользователем.

Я написал «Тетрис» на нём, когда понял, что графику можно выводить, манипулируя свёрнутыми в точку окнами приложений и опрашивая клавиши регулирования громкости.

«Морской бой» на клавише «Капслок» (2020)

Игру «Морской бой» я написал по двум причинам. Во-первых, у меня была идея написать какую-нибудь игру, для которой нужно было использовать только одну клавишу. Во-вторых, мне хотелось посмотреть в действии язык «Луа».

Идея с клавишей пришла в голову, когда я в очередной раз размышлял о бессмысленной для меня клавише «Капслок» — я её совершенно не использую и всегда отключаю на уровне операционной системы. Из-за этого на ней пропадает без дела маленький симпатичный светодиод.

В итоге я написал игру, где всё взаимодействие с компьютером делается через азбуку Морзе — пользуясь одной клавишей, как ключом, мы вводим координаты для игры в «Морской бой», а ответы компьютера считываем через мигание светодиода на «Капслоке». Картинка ниже — это отладочный режим, его можно включить, но по-умолчанию на экран ничего не выводится.

«Вампус» для наручных часов в корпусе «Касио» (2024)

Я вообще очень люблю различные ретро-устройства, а так же всё, что их напоминает — постоянно читаю о ретро-консолях, подписан на каналы, где обозревают интересные устройства прошлого, и когда узнал про «The Sensor Watch», небольшую плату, превращающую классические «Касио» в программируемое устройство, влюбился в эту концепцию и добыл себе всё необходимое.

До сих пор ношу эти часы почти каждый день, они у меня сейчас самые любимые.

Но если уж я добыл себе эти часы, было бы логично что-то под них запрограммировать. Вся сложность была в том, что экран устройства остался от обычных часов «Касио», надо было хорошенько постараться, чтобы что-то на нём вывести. Я какое-то время ломал голову, а потом запрограммировал классическую игру 1972 года «Охота на Вампуса». В её поздний клон я когда-то играл в детстве.

«Вампус» на командах командной строки (2024)

Была у меня ещё одна идея — сделать что-то такое, что превратило бы в игру саму оболочку командной строки (шелл). Тогда полем для игры была бы файловая система, а её командами были бы команды шелла. Для реализации выбрал тот же «Вампус», старые текстовые игрушки как нельзя лучше подходят для таких целей.

Путём разных манипуляций я ввёл целый набор всяких ограничений, чтобы шелл напоминал игру, а не просто командную строку, но если знать как всё устроено, это всё, конечно, можно обойти. Тем не менее, мне кажется, что с целью я справился.

«PowerShoot» игра, управляемая подключением зарядки (2024)

Игра, написанная под влиянием болезни. Я довольно тяжело болел и хотелось развлечь себя какой-нибудь прикольной идеей.

На искомую идею меня натолкнул звук, который раздаётся, когда «Макбук» подключается к зарядке. Я задумался, что можно же программно узнать — заряжается ноутбук или нет, а потом уже, от скуки, развил эту мысль до небольшой игрушки. В ней игрок выпускает в сторону врагов бомбу, когда ноутбук подключается к зарядке.

«Дум» на языке калькулятора bc (2025)

Концепция вывода графики в текстовую консоль существует давно — в различных терминалах было последовательно придумано несколько способов как это сделать, что меня весь интриговало. Хотя и понятно, что терминалы нынче никакие не текстовые, всё равно графика там поначалу как-то изумляет.

Во мне идея сделать что-то графическое в терминале зрела много лет и, когда я стал изучать язык утилиты bc, мне пришла в голову идея суточного хакатона — сделать на этом совершенно непригодном для написания игр языке, первую игру, да не простую, а трёхмерную, с выводом графики в консоль.

Хотя первые несколько часов хакатона я был в отчаянии от своей идеи и мне казалось, что я либо ничего не сделаю, либо не уложусь в срок, у меня всё получилось — за сутки я сделал порт игры «Wolf5k» на bc и придумал как на этом языке генерировать графику. А заодно доказал, что кодить сутки с раннего утра и до трёх ночи можно и в 47 лет.

«Throttling» игра, использующая для отображения мониторинг загрузки процессора (2025)

Как я недавно рассказывал, эта игра основывается на моей старой идее — выводить пульсацию проигрываемой мелодии через «Мониторинг ресурсов» процессора. В старых «Макбуках» каждому ядру соответствовал свой столбик и я даже написал код, но из-за инерции мониторинга красиво не вышло.

Недавно я этот код случайно нашёл и придумал небольшую игрушку. Её несложный сюжет, остающийся за рамками игрового процесса, таков: вы оператор блока реактора на АЭС, у вас отключается автоматика и вам нужно вручную удерживать температуру внутри блока, которая отображается как загрузка процессора.

Заключение

Я отобрал всего несколько проектов из того «ненормального», что я делал. Надеюсь, вполне очевидно, что «ненормальное» программирование я ценю и люблю очень давно. Для меня это не просто странное баловство, а способ изучить какие-то привлекательные идеи и выразить свои чувства по отношению к ним.

Программирование, как например, и рисование, может быть процессом получения как можно более точной копией задачи, просто в другой форме, как, например, в реализме. В целом, нужный и почитаемый навык, но оно может быть и очень абстрактным, отражающим иную реальность, такой, какой она видится внутри, как идея.

Мучительная потребность поделиться своими внутренними идеями, думаю, знакома любому художнику. Я делаю свои странные программы по той же причине — потому что не могу, да и не хочу держать эти идеи только внутри себя.

Батарейки CR2032

Я, как и многие, наверное, подозревал, что с плоскими батарейками что-то крепко не так. Купишь что-нибудь с родной батарейкой, оно работает год, потом поменяешь, садится через месяц. Особенно заметно на примере брелка от автомобиля. Причём с пальчиковыми батарейками такого разительного различия не наблюдаются, там тоже есть колебания, конечно, но не настолько обидные.

А тут недавно в одном из каналов попалась ссылка на тестрирование батарей CR2032. У меня на картинке лишь вершина айсберга, загляните сами — разница между лидером и аутсайдером в 11 раз! Что, кстати, неплохо укладывается в мои ощущения в год и месяц работы.

Что расстраивает, батарейки известных брендов, согласно этому сравнению, работают средне. Надеюсь дело в том, что их не стесняются подделывать.

Из хорошего. Приятно удивили батарейки «Фотон» — они на втором месте, что тоже логично — подделывать местный бренд опаснее. Буду теперь, пожалуй, покупать именно их.

7000 и кафе

Формально эта заметка — семитысячная на этом сайте. Формально, потому что некоторые посты я пишу задним числом, копируя их из «Дневников жизни», которые я вёл с 1989 года по 2000-й. Там работа даже не близка к завершению, так что, очевидно, в будущем нумерация поменяется.

Тем не менее, это знаковое число и я, по подсказке одного из читателей, планировал написать её о чём-нибудь значительном. Мне нравилась идея собрать сюда какое-то количество интересных ссылок, какой-то выжимки из того, что я написал за эти годы.

К сожалению, я заболел и с задачей не справился — список пока находится в зачаточном состоянии. Был выбор — не писать какое-то время или продолжить писать дальше, пропустив семитысячную заметку.

Честно говоря, я планировал выбрать первый вариант, но вчера случилось событие о котором невозможно молчать, — мы с ещё двумя друзьями подписали договор, условия которого обсуждали почти месяц. В скором времени мы будем открывать кафе, даже два — одну точку в виде киоска недалеко от одной из центральных улиц Казани и ещё одну на фудкорте строящегося торгового центра.

По мере успеха предприятия, буду сюда об этом писать, пока же вперёд забегать не буду — помимо подписи на трёх экземплярах договора мной пока ничего не сделано.

Прошлое: Дни Интернета в Казани

Вчера встретил в кафе нашего офисного центра своего друга А. Х., который общался о чём-то за столиком с тремя молоденькими девушками. Он махнул мне рукой, я подошёл поздороваться и оказалось, что эти трое — журналистки, собирающие воспоминания о том как развивалась отрасль айти в девяностых и двухтысячных.

А. Х. попросил меня помочь, но сначала мне пришлось отказаться — меня ждали на встрече. Позже выяснилось, что встречу передвинули и у меня есть минут 15—20, чтобы спринтом пробежаться по памяти и чем-нибудь поделиться.

События очень давние, поэтому вспомнить удалось не так много как хотелось бы, но зато в памяти всплыл один забавный случай, про который я нигде не писал. Журналисткам он не подошёл по тематике, поделюсь здесь.

В конце девяностых—начале двухтысячных в Казани проводились Дни Интернета. Событие, насколько я помню, должно было стать ежегодным, но не стало. Его провели не менее двух раз и в какой-то момент оно благополучно загнулось.

В интернете об этом упоминаний не сохранилось, но кое-что можно наковырять в веб-архиве, в частности на сайте передачи «Система 104».

Я был на двух «Днях». Один из них проводил на свои деньги известный тогда в казанском интернете деятель Daddy Hab, а второй, если мне не изменяет память, провайдер «Сантел-интернет», ныне несуществующий. Но может и не он.

Кажется оба раза это было в зале НКЦ «Казань», но что там конкретно было, я уже и не помню. Вероятно, просто тусовка с алкоголем. Но что я помню хорошо, что перед одним из этих событий в качестве приглашённого гостя был анонсирован Артемий Лебедев, в те годы — абсолютная суперзвезда в интернете.

На беду организаторов я тогда с ним активно переписывался, поэтому не постеснялся узнать правда ли его пригласили. Он сказал, что в первый раз об этом слышит и я, для смеха, выслал ему фотографию флайера с его именем. К сожалению, электронная почта того времени работала иногда из рук вон плохо и файл с картинкой никак до него не доходил. На третьей попытке я его сконвертировал, для надёжности, в несколько форматов и выложил на свой сайт ссылками, которые и отослал ему в письме.

Как пошутил А. Х., я делился файлами через облако до того как это стало модным.

Разумеется я не помнил этого в таких подробностях, но вчера написал Артемию, в надежде, что у него осталось это письмо и не обманулся — он мне его переслал, после чего эта история проступила в памяти более ясно.

Организаторы так и не признались, что не стали приглашать Лебедева и на самом событии интригу тянули до последнего. Я бродил в толпе и вносил смуту среди своих знакомых, но и у меня, думаю, теплилась надежда.

К сожалению, чуда не случилось. В итоге в какой-то момент объявили, что он не приедет — якобы очень извиняется, застрял в метро и не успел на самолёт.

cmd.sh

Я тут случайно в спор ввязался — можно ли переписать бат-файл так, чтобы он запускался и выводил примерно одинаковый результат на трёх основных операционных системах — Виндоузе, Линуксе и МакОСи.

Речь шла о вполне определённом файле, там запрограммировано небольшое меню и в зависимости от выбранного пункта запускается та или иная, одинаковая для всех ОС, последовательность команд.

Мой собеседник мне не верил, когда я утверждал, что это вполне возможно, и требовал доказательств.

Что ж. Основная моя идея была в том, чтобы заменить команды батника на вызовы баш-функций, которые я спрячу в специальных конструкциях. В Виндоузе файл обработает обычный cmd.exe, на остальных операционках — bash.

То, что мне предстояло адаптировать начиналось вполне стандартно:

@ECHO off
CHCP 1251
CLS

Что тут происходит? Выключается вывод команд на экран (при адаптации это можно игнорировать), ставится однобайтовая кодировка CP1251 (это хорошо бы учесть) и очищается экран.

Поскольку «баш» этих команд не знает, надо определить три функции, спрятав их от cmd.exe. Сделать это несложно. Команду «двоеточие» cmd.exe трактует как начало метки и на дальнейшее не реагирует, а «баш» считает её пустой командой, которую можно точкой с запятой отделить от строки, которую мы хотим спрятать:

:; @ECHO() { :;}; CLS() { clear; }; CHCP() { ENC="$1"; }

Следующее, чему надо научиться — выводить текст в указанной в батнике кодировке. Это просто:

:; ECHO.() { echo $@ | iconv -f "CP$ENC"; }

Если теперь сделать файл запускаемым и добавить впереди #!/bin/bash (и пренебречь тем, что cmd.exe успевает ругнуться на эту строку до очистки экрана), у нас получится следующий файл, работающий во всех трёх операционках (кодировка должна быть Windows-1251):

#!/bin/bash
:; @ECHO() { :;}; CLS() { clear; }; CHCP() { ENC="$1"; }
@ECHO off
CHCP 1251
CLS
:; ECHO.() { echo $@ | iconv -f "CP$ENC"; }
ECHO. Всем привет

А вот дальше сложнее. Само меню организовано в оригинале так:

SET /p opt=Введите цифру:

IF %opt%==1 GOTO dns_auto
IF %opt%==2 GOTO dnschange
IF %opt%==3 GOTO exit

В «баше» goto (переход к метке) отсутствует и это проблема. Аналогов тоже нет. Единственное, что тут можно сделать — использовать вызов функций, но синтаксис в «бате» и «баше» сильно различается.

Как быть? Во-первых, сэмулировать функцией команду SET, во-вторвых, упростить это место, чтобы меньше было писать кода на «баше»:

:; SET() { shift; ECHO. -n "${@#*=}"; read -n1 "${1%%=*}"; echo; }
:; CALL() { eval "$(sed 's/%\(.*\)%/$\1/g' <<< "$1")" 2>&-; }

SET /p opt=Введите цифру:
CALL :menu_%opt%

Первая функция парсит команду SET выводит строку после равно, ждёт ввода и записывает значение в имя переменной, указанной слева от равно.

Вторая — заменяет CALL. В ней %variable% заменяется на $variable, выполняется подстановка переменной и получившееся имя выполняется как команда или функция «баша». Конструкция 2>&- нужна, чтобы избежать вывода ошибки в ситуации, если пользователь введёт что-нибудь не то.

Теперь надо как-то научиться определять функции так, чтобы их нормально «видел» и cmd.exe, и «баш». В батнике функции — просто любое место программы, начинающееся с метки и заканчивающееся вызовом GOTO :EOF:

:function_1
ECHO это якобы функция
GOTO :EOF

В «баше» то же самое могло бы выглядеть, например, так:

function_1() {
    echo это функция
}

Как это объединить? Я придумал следующий подход:

:; GOTO() { :; };

GOTO ;#start
:function_1 (){
ECHO. это [якобы] функция
GOTO :EOF
:; }

:;#start

В первой строке определяется пустая функция для «баша», потому что эта часть синтаксиса бат-файла нам не нужна.

Ниже идёт строка GOTO ;#start. С точки зрения «баша» тут две конструкции — GOTO, которая вызывает определённую выше пустую функцию и #start — строка комментария, так как в«баше» с «решётки» начинаются комментарии.

В «батнике» же эта же строка будет означать переход к метке с именем ;#start. Этот переход нужен нам, чтобы «обогнуть» строки, которые определены ниже, иначе cmd.exe начнёт сразу их выполнять, а нам этого не нужно. Их нельзя «спрятать» ниже основной программы, так как в «баше» функции должны определены раньше их вызова.

Что происходит дальше? С точки зрения cmd.exe ниже расположена метка :function_1 (как показывают мои эксперименты, часть после пробела просто отбрасывается), потом тело функции, команда её завершения GOTO :EOF и метка с именем :;}.

С точки зрения «баша» там определяется функция с именем :function_1, ниже идут вызовы уже определённых мною функций ECHO. и GOTO, а ещё ниже — уже знакомая нам пустая команда : и фигурная скобка, завершающая тело функции.

Соединяем всё вместе и получается следующая программа:

#!/bin/bash
:; @ECHO() { :;}; CLS() { clear; }; CHCP() { ENC="$1"; }
@ECHO off
CHCP 1251
CLS

:; GOTO() { :; };
:; ECHO.() { echo $@ | iconv -f "CP$ENC"; }; PAUSE() { read; }; 
:; SET() { shift; ECHO. -n "${@#*=}"; read "${1%%=*}"; }
:; CALL() { eval "$(sed 's/%\(.*\)%/$\1/g' <<< "$1")" 2>&-; }

GOTO ;#start

:menu_1 (){
ECHO. Пункт первый
GOTO :EOF
:; }

:menu_2 (){
ECHO. Пункт второй
GOTO :EOF
:; }

:;#start

SET /p opt=Введите цифру:
CALL :menu_%opt%

Мой оппонент признал, что в споре я победил.

Пишем на «Флиппере Зеро» по-русски

Вкратце: в русским текстом работать можно, но сложно, код лежит на «Гитхабе».

Не мог не обратить внимание, что несмотря на приличное количество русскоязычных авторов программ для «Флиппера Зеро» и российское происхождение устройства, в софте под него нигде не обнаружилось ни одной буквы по-русски.

Flipper Zero

Стало интересно — а есть ли вообще в устройстве поддержка русского языка? Сел вечерком за исходники прошивки и оказалось, что однозначного ответа на заданный вопрос нет. Частичная поддержка есть и её можно заставить работать, но она работает как будто по недосмотру — никто её не собирался делать, так случайно вышло.

Вывод русских букв (трансляция с экрана через оболочку qFlipper)

Сейчас расскажу, что я имею ввиду и постараюсь покороче, никто сейчас не любит длинные тексты.

Внутри «Флиппера» довольно много всякого АПИ для вывода текста, от незатейливого, выводящего строку в заданные координаты, до довольно навороченного, умеющего переносить и выравнивать текст. К сожалению, с русскими буквами оно работать не умеет.

Под капотом у этого АПИ — очень известная в своей нише библиотека U∞g2, у которой по историческим, видимо, причинам есть два набора функций для работы со строками. Одни принимают только однобайтовую кодировку ASCII, другие работают в Юникоде.

АПИ «Флиппера», к сожалению, использует функции, которые с Юникодом работать не умеют. К счастью, по какой-то случайности, упомянутое АПИ содержит два вызова, которые помогают решить эту проблему, правда придётся помучаться.

Первый из них — canvas_set_custom_u8g2_font.

Чтобы что-то написать русскими буквами, нужен шрифт, который их содержит. Стандартный вывод canvas_set_font позволяет выбрать один из нескольких шрифтов, ни одни из которых кириллицу не поддерживает. Тут и приходит на помощь canvas_set_custom_u8g2_font. Он позволяет выбрать произвольный шрифт пакета U∞g2, — внутри их целая куча и некоторые в названии содержат слово «cyrillic».

Вот как я это делаю:

#include <u8g2/u8g2_fonts.c>
// …
canvas_set_custom_u8g2_font(canvas, u8g2_font_haxrcorp4089_t_cyrillic);

Файл u8g2/u8g2_fonts.c внутри себя содержит шрифты в особом формате, можно открыть его прямо в текстовом виде и посмотреть как всё устроено.

Шрифт мы выбрали, теперь надо что-нибудь вывести. Тут на помощь приходит canvas_draw_glyph. «Под капотом» у него лежит u8g2_DrawGlyph, которая понимает символы Юникода почти без танцев с бубном. Думаю, это чистое везение — наверняка эта функция появилась сильно позднее, поэтому у неё нет двух вариантов для работы с разными кодировками.

Плохая новость в том, что строки в коде мы обычно пишем в кодировке UTF-8, а canvas_draw_glyph ожидает их в UCS-2. Но есть и хорошая новость — в прошивке доступно АПИ для перекодирования, как обычно, великолепно документированное на языке Си.

Но canvas_draw_glyph, как можно понять из названия, выводит только один символ. Как же вывести строку? Достаточно просто — надо вывести её посимвольно, сдвигая координату на ширину символа. Звучит просто, но как это сделать?

Тут нас ждёт очередная засада. Дело в том, что canvas_glyph_width, которая должна бы это делать, принимает на вход только char, при том, что нижележащая u8g2_GetGlyphWidth преспокойно работает с Юникодом.

Поэтому я сделал просто — выдрал реализацию u8g2_GetGlyphWidth себе в исходники. В итоге мякотка моего решения выглядит вот так:

void unicode_draw_utf8_str(Canvas* canvas, uint8_t x, uint8_t y, char* str) {
    FuriStringUTF8State state = FuriStringUTF8StateStarting;
    FuriStringUnicodeValue value = 0;

    for(; *str; str++) {
        furi_string_utf8_decode(*str, &state, &value);
        if(state == FuriStringUTF8StateError) furi_crash(NULL);

        if(state == FuriStringUTF8StateStarting) {
            canvas_draw_glyph(canvas, x, y, value);
            x += unicode_GetGlyphWidth(&canvas->fb, value);
        }
    }
}

Тут unicode_GetGlyphWidth — скопированная реализация u8g2_GetGlyphWidth, а furi_string_utf8_decode используется для кодирования UTF-8-строки в последовательные символы UCS-2.

Надпись в «Гитхабе»

С тех пор как в первый раз увидел панель активности «Гитхаба», хочу на ней что-нибудь написать. Я даже всерьёз как-то порывался составить себе карту на год, чтобы по ней коммитить, пока не получится рисунок, но поленился. А позже сообразил, что можно сдвигать дату коммита в прошлое.

Моя панель активности за год на «Гитхабе»

И вот, годы спустя, я наконец сподобился сделать скрипт, чтобы автоматизировать процесс и написать себе там слово «ПРИВЕТ».

Скрипт переводит подготовленную картинку размером 52×7 пискелей в нужную интенсивность коммитов и распределяет их по датам. Для надписи я использовал шрифт silkscreen, русифицированный когда-то Димой Смирновым и чуть-чуть его размыл в графическом редакторе.

Если захотите себе такую же, вам понадобится так же bash, git и утилиты из набора ImageMagick. Создаёте пустой репозиторий на «Гитхабе», привязываете его к локальному, запускаете мою утилиту с картинкой и любуетесь изображением на панели активности.

GBox для Huwaei

Три года назад, пройдя от любви до ненависти к «Самсунгу» один шаг, я перешёл на «Хуавей», рискнув попытаться обойтись без гугловых сервисов. Честно сказать, продержался недолго — пришлось взламывать смартфон и почти сорокаминутным шаманством возвращаться в зону комфорта.

После этого ставить можно было что угодно, но работало не очень — уведомления не доходили, «Мир пэй» работать отказался, синтез и распознавание речи — тоже, а в смартфоне торчало какое-то увешанное иероглифами хакерское приложение.

Приложение GBox, установленное на моём телефоне; приложения не знают, что они внутри Huawei

В конце прошлого года, озаботившись выбором новой кофеварки, я потерял бдительность и вместо этого купил себе новый смартфон.

Я уже давно хотел побаловать себя апгрейдом смартфона, и консультант в магазине, почуяв мои колебания рядом со стендом «Хуавея», мастерски разбил каждый пункт моих сомнений. В том числе показал мне способ как не страдать от отсутствия сервисов «Гугла».

Оказывается существует панацея — приложение GBox. Оно ставится прямо из собственного магазина «Хуавея» и запускает внутри себя любое гугловое приложение (включая «Гугл Плей»), притворяясь для него смартфоном, свободным от санкций. В моём случае это какой-то «Сяоми», но в интернетах пишут, что модель и производитель выбираются случайным образом.

Всё гугловое запускается в некой изолированной среде, а наружу создаются ярлыки, отдельные для каждого приложения. Удивительно, но работают даже пуш-уведомления.

Мне такой способ понравился значительно больше — не засоряется система, и приложения, типа «Мир пэя», не сходят с ума от противоестественного симбиоза сервисов «Гугла» и «Хуавея».

О хранении пластинок

У нас дома есть настоящий патефон в хорошем состоянии. Эта вещь когда-то принадлежала дедушке жены и мы регулярно ею пользуемся — ставим пластинки по велению души или по просьбе друзей.

Поэтому я постепенно расширяю коллекцию — докупаю пластинки на местном блошином рынке или в интернете. Коллекция пока не велика и стоит у меня на одной из полок. Пластинки именно стоят, так правильно — на каждом конверте любой пластинки это напечатано в виде инструкции.

Отпечаток одной пластинки на другой — видно отзеркаленную надпись «RUSSIA» и след вокруг «яблока»

У меня как-то руки не доходили выяснить почему пластинки надо ставить именно вертикально, но помог случай. Несколько дней назад я заглянул в кафе к своему приятелю, а там на одной из полок углядел патефонные пластинки, валявшиеся там для антуража, — стопкой и без конверта.

Некоторые из них меня заинтересовали (там была даже парочка дореволюционных), поэтому я взял их послушать и только дома обнаружил, что за годы хранения стопкой одна из односторонних пластинок испортила дорожки на рабочей стороне другой — там отпечатался рельеф вокруг «яблока» и часть надписи «REPRODUCED IN RUSSIA».

Вывод простой: хранение стопкой портит пластинки, так как под весом стопки одна пластинка может повредить дорожки на другой.

DOOGEE S98 Pro

В счёт годовой премии решил поменять себе смартфон — вместо служившего верой и правдой почти три года «Хуавея», купил себе тоже «Хуавей», но интереснее. Но об этом как-нибудь потом.

Прежний телефон выставил на продажу на «Авито». Продавался он что-то ни шатко, ни валко — похоже в Новый год всем не до новых приобретений. В основном попадались желающие получить его с хорошей скидкой или поменяться на что-нибудь для меня бесполезное.

Я меняльщикам обычно даже не отвечаю — сразу закрываю диалог без лишних слов. Но сегодня в одном из предложений поменяться мелькнула какая-то незнакомая модель — DOOGEE S98 Pro и я из любопытства решил одним глазком глянуть в интернете что это такое.

Только что распакованный смартфон DOOGEE S98 Pro

Оказалось, что это смартфон в «походной» комплектации — защищённый (IP68, IP69K, MIL-STD-810G), со стеклом Corning Gorilla Glass 5, с большим аккумулятором (утверждается, что заряд будет держаться до двух с половиной недель), с камерой ночного видения и тепловизором (!).

Владелец рассказал, что промахнулся с выбором — у него далеко не походный образ жизни, а в городе этот телефон неудобен — тяжёлый, большой, да и его фишки применить просто негде.

Сделал фотографию ёлки дома — сквозь неё видно батарею, а на полу — следы от труб системы отопления

Я решил, что это судьба — давно ищу себе телефон для суровых условий, учитывая, что я время от времени люблю залезть по́ уши в какое-нибудь болото, просто чудо, что я ещё ни разу не раскокал в таком режиме какой-нибудь нежный «офисный» смартфон.

Тепловизор зимой в новой квартире оказался занятной игрушкой, тем более сейчас в Казани стоят экстремальные морозы за −30°, много нового узнаёшь о своей квартире при помощи этой штуковины.

На диване след от недавно сидящего там меня, а температура кота — около 34,8 градусов

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

Камера ночного видения — тоже интересная штука, используется инфракрасная камера с инфракрасной же подсветкой. Не знаю насколько будет полезно на природе, но по тёмной квартире походить интересно, чувствуешь себя как в каком-то боевике.

Ночной город из окна лестничного пролёта одной из многоэтажек

Вдаль камера то ли промахивается с фокусом, то ли просто «мылит» из-за недостаточного разрешения, что очень хорошо видно на снимке города, который я сделал из окна лестничного пролёта в гостях.

Надо будет попробовать поснимать днём — интересно какой будет эффект.

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

Получил нагрудный знак

Перед Новым годом Республика сделала прекрасный подарок: сегодня я из рук министра цифровизации Айрата Хайруллина получил нагрудный знак «За достижения в области информатизации и связи РТ».

Нагрудный знак «За достижения в области информатизации и связи РТ» и книжечка к нему

Предупреждая вопросы: никакого особого статуса этот нагрудный знак не даёт, просто приятное признание заслуг.

Грека и рак

В детстве меня много мучали буквой «р» — я её тогда не произносил и до сих пор этого не делаю, правда большинство этого не замечает, — со временем сам собой как-то научился её имитировать.

Походы к логопеду, в данном случае, дали мне только одно: я с пулемётной скоростью, быстрее всех, кто со мной пытался соревноваться, умею выдавать скороговорку про беспечного грека, который суёт руки в реки:

Ехал грека через реку,
Видит грека: в ре́ке рак,
Сунул грека руку в реку,
Рак за руку греку цап!

Сегодня веселил этим дочку и она, отсмеявшись, задала очень интересные вопросы: что за грека? через какую реку и куда он ехал? и зачем он засунул руку в реку?

Грека едет через реку в литературно-художественном и научно-публицистическом журнале «Красная Новь», №4, 1924 год

Судя по тому, что удалось нагуглить, ответы на эти вопросы неизвестны, однако проследив судьбу скороговорки от нашего времени до 20-х годов (в более ранних источниках грека не обнаруживается), кое-что узнать всё-таки удалось.

Первое, что меня сильно удивило, «грека», — по всей видимости, национальность, а не имя (как я думал ранее), — во всех ранних источниках это слово написано с маленькой буквы. Так что история не персонализированная и шансов когда-либо узнать, что грека забыл за рекою, исчезающе мало.

А во-вторых (и тут нас ждёт небольшое открытие), нашёлся ранний (1924 года) вариант скороговорки, в котором история несколько меняется! Он на скриншоте, в этом варианте грека «и рукою рака цап» и это совершенно другое дело.

Вообще в двадцатом веке вариантов концовки было множество: «грека за руку рак — цап!» (Георгий Никифоров, «Кимба», 1926), «рак у грека руку цап» (Бирюков, «Крылатые слова на Урале», 1960) или тот, что на скриншоте (Б. Д. Четвериков, «Атава», 1924 год).

Мне хочется верить, что самый ранний вариант, — опубликованный Борисом Дмитриевичем Четвериковым в «Красной Нови», является исходным, так как в нём больше логики. Если это так, то по меньшей мере один вопрос в истории про греку отпадает сам собой.

Интересная операция (18+)

В последнее своё посещение блошиного рынка сфотографировал в качестве курьёза одну книгу — очень уж удивило название, которое я понял так, что до революции в России пытались делать операции по смене пола.

Меня это сильно удивило — уж очень прогрессивно выглядит. Где 1914-й год и где тема гомосексуальности, а тем более — смены пола.

Операція образованія искусственаго влагалища изъ прямой кишки. С.-П., Типография В. Ѳ. Киршбаума, 1914

Уже забыл про эту историю, но на днях разбирая чем забит мой смартфон, опять наткнулся на эту фотку. Ну и стало интересно — что за врач такой жил в России, как он вообще пришёл к этой теме и какова была реакция в обществе на его изыскания?

Начал, как полагается с «Википедии» и знатно удивился, когда узнал из неё, что первая операция по смене пола была сделана в 1931 году. Тогда что за операции делал доктор, написавший эту книгу? Может я случайно наткнулся на сенсацию?

Загадку разрешила одна из досок объявлений, где продают различное старьё. Там удалось найти несколько фотографий внутренних страниц книги, которые всё прояснили.

Оказывается операция, которая имеется в виду в книге, делалась женщинам с физическим отклонением — тем, у кого по разными причинам влагалище не развилось. Такая операция тоже, конечно, крутое достижение, но оскароносный фильм по этой истории уже не снимешь.

Голос Александра III? (вряд ли)


Александр III Александрович (1845—1894) — император Всероссийский, царь Польский и великий князь Финляндский. Отец последнего российского монарха Николая II

Оказывается в интернете есть аудиозапись, на которой, по одному из предположений, звучат голоса Александра Третьего и его супруги Марии Фёдоровны.

Запись была сделана на восковой цилиндр между между 1889 и 1893 годами в резиденции датского короля во Фреденсборге генеральным консулом Готфридом Рубеном, который в период 1889—1897 годов записывал известных певцов и актеров того времени, а также важных высокородных гостей членов монаршей семьи на недавно изобретенном фонографе.

В 2007-м году Университетская библиотека Дании начала оцифровку коллекции консула и выложила её в интернет на своём сайте, а в 2018 году датский журналист Йенс Корнелиус высказал предположение, что голоса на одной из записей могут принадлежать Александру III с супругой.

Прямых доказательств этому нет, но в пользу этой теории говорит тот факт, что замок Фреденсборг, где записывался голос, является резиденцией датских королей. И вряд ли там мог петь по-русски кто-то еще, кроме царя. Чья жена, к слову — урожденная датская принцесса Дагмара.

Из-за способа записи звук неважного качества, а часть записи вообще на датском, поэтому без расшифровки некоторые места не понять:

Женский голос:

— Я очень рада вас видеть сегодня. Потому, что хорошая погода, можно пойти гулять! (неразборчиво, на датском)

Мужской голос:

— Вы хотите я говорил что-нибудь вам. Это не всегда так легко, когда вы хотите… И еще вы прибавили, что хотите чтобы я спел что-нибудь. Ну что же, вот, как например, это…

Поёт:

Сам Бисмарк чуть от радости
Не вырвал трёх волос,
Как телеграф известие
Такое нам принес,
Что немцы храбро заняли
Пункт важный и большой
И утверждали в Африке
Права страны родной…
С тех пор в Берлине стар и млад
Одно лишь и твердят:
Nach Afrika, nach Kamerun!
Vivat, Nach Kamerun!
Nach Afrika, nach Kamerun!
Так немцы говорят!
Nach Afrika, nach Kamerun!
Vivat, Nach Kamerun!
Nach Afrika, nach Kamerun!
Так немцы говорят!

Мужской голос:

— Закончим на этом, не могу вам читать сегодня. Если б вы заранее меня предупредили, так это другое дело. Я бы взял с собой книгу или что-нибудь в этом роде, чтобы мне прочитать. А так прямо из головы, это нелегко. Вы меня застали врасплох. И конец. До свидания, господа.

Женской голос (на датском):

— Меня очень веселит слушать голос моего мужа.

1 + 1 = 1

Те, кто следит за недвижимостью, наверное знают, что она сейчас растёт в цене, как на дрожжах. Это связывают с очень низкими ипотечными ставками, которыми правительство надеялось поддержать народ в коронавирусное время.

Получилась уникальная ситуация, которой мы с женой решили воспользоваться. Появилась мысль продать две квартиры — пустующую однушку и ту квартиру, в которой сейчас живём, чтобы купить жильё побольше в районе получше. Выбрали ипотеку с государственной поддержкой 0,01/6,5% — то есть первый год одна сотая процента, потом — 6,5.

Чтобы получить такую ипотеку, пришлось собирать довольно большой первый взнос — такие условия. Своих денег не хватило, пришлось занимать. Отдали потом с продажи однушки. Кстати, пока её продавали, она дорожала два раза. В теории можно было бы подождать ещё, но нам очень хотелось поскорее отдать деньги.

И вот что из этого получилось: цену на свою будущую квартиру (она ещё строится) мы зафиксировали ещё осенью, когда её купили, тогда как однушка, которую мы продавали несколько месяцев, чтобы отдать долги, дорожала и не прекращает дорожать квартира, в которой мы живём. Так что мы ожидаем после осуществления всего плана остаться в большом плюсе.

При этом весь год мы платим ипотеку под 0,01%, которую надеемся закрыть после продажи второй квартиры, лишь немного «въехав» в 6,5% — сдача нашей новостройки только летом, а потом ещё отделку делать и покупателей искать.

Получается довольно выигрышная ситуация, при условии что застройщик достроит дом. Это единственное относительно уязвимое место во всём плане, поэтому к выбору застройщика подошли ответственно. Я пишу «относительно», так как все наши деньги лежат на так называемом «условном счету» (эскроу-счёте) и перейдут к застройщику только после того как мы примем квартиру, то есть потеря денег нам не грозит в любом случае.

Ранее Ctrl + ↓