Главная > Творчество > The Matrix has you…

The Matrix has you…

В далеком уже 1999 году свет увидел шедевр австралийской кинематографической индустрии — The Matrix. Своей идеей и исполнением он потряс воображение многих, не обойдя стороной и меня. Киберпанковский сюжет начинается с того, что некий хакер узнает, что реальность, в которой он живет, является виртуальной средой нейроинтерактивного симулятора, а его тело на самом деле находится в капсуле, подключенной к сети. В кино я всегда обращаю внимание на мониторы компьютеров, пытаясь узнать пользовательский интерфейс, изображенный на нем. За все время мне наверное всего пару раз удалось встретить что-то знакомое. Один из них в фильме Правдивая ложь (True Lies) там был Windows 3.1 на арабском языке), второй — как раз в Матрице герой фильма использовал сетевой сканер nmap:

В остальных же такие разношерстные и смешные GUI, что просто диву даешься, кто это все придумывает. Выглядит ну не правдоподобно. А в Матрице с этим делом все весьма не плохо обстояло, графические интерфейсы смотряться стильно, без излишнего лоска и в то же время весьма юзабельно. Помню, тогда мне очень понравилась идея отображения на дисплее нераскодированного сигнала матрицы. Суть в том, что вычислительной мощности компьютеров движения сопротивления не хватало чтобы раскодировать сигнал, поэтому его отображали на экране как есть — в виде символов. Операторы же настолько долго работали с этой кодировкой, что уже вместо символов видели объекты ими описываемые. Мне очень захотелось воспроизвести это на своем мониторе. Забегая вперед, покажу, как это все выглядит сейчас:

Скачать скринсейвер Матрица в моем исполнении можно здесь.

Многие товарищи склонны делать сложные заставки, с 3d-графикой и крутыми спецэффектами. Мне всегда казался сомнительным данный подход, ибо при этом расходуется значительная часть ресурсов системы, таких как процессорное время и память. В моем понимании, скринсейвер должен быть легким. Именно такой я и постарался сделать свою матрицу.
В отличие от бинарных часов я не стал откладывать дело в многолетний ящик и сразу взялся за программирование. Забавная история случилась в самом начале. Дело в том, что я не знал, где взять шрифт матрицы (там оригинальный набор иероглифов). Видео-захватывающая аппаратура в то время была дорогостоящей и не очень распространенной, а перерисовывать с экрана, запаузив видеомагнитофон (да-да, это было еще на VHS)… Сначала я просто взял инструкцию к какой-то технике на китайском языке, отсканировал и сделал шрифт с китайскими и корейскими иероглифами. Позже, волею судеб оказался я в одном продуктовом магазине, где мне выдали полиэтиленовый пакет со скриншотом сигнала матрицы. Такие совпадения я склонен относить к знакам судьбы. Быстренько это дело сосканировал и перегнал в шрифт. Первая версия скринсейвера была написана под DOS для текстового режима (80×25 16 цветов). Символы задавал знакогенератором (через прерывание INT10h), в общем то самая сложная часть была в алгоритме генерации самого сигнала. Алгоритм основан на random’e, но, чтоб в целом все гармонично смотрелось я заложил в него фишку — в один момент времени на экране присутствует определенное количество символов. И скринсейвер этот я встроил в замечательный файловый менеджер тех времен — Dos Navigator
Не прошло и года как для меня настала эпоха Windows-программирования, и я окончательно ушел от DOS-разработки. Дошли руки и до модернизации скринсейвера. Первая обновленная версия застала еще Windows 95. Я узнал, как создаются экранные заставки Windows именно под эту платформу, что Windows screensaver — это обыкновенный исполняемый EXE-файл, с расширением SCR, а также поддерживающий определенную логику запуска, а именно:
Windows screensaver может быть запущен в 4 состояниях — зависит от того, с каким ключом переданным через коммандную строку запускается приложение. Это могут быть ключи:
-s — скринсейвер запускается в режиме просмтора
-с — скринсейвер запускается в режиме настройки (пользователь нажал кнопку Настройки в Свойствах экрана)
-p — скринсейвер запускается в режиме предпросмотра, это когда пользователь зашел в Свойства экрана и ему показывают превью.
-a — скринсейвер запускается в режиме разблокирования системы — когда пользователь отошел от компа, в это время запустился скринсейвер, и чтоб у кого-то другого при выключении его не было возможности работать под чужим аккаунтом.
Ну пожалуй самое интересное — это работа с режимом превью. И интересность вся заключается в том, что вторым параметром коммандной строки передается хэндл Windows-окона (HWND), в котором и показывается превью. То есть, все нужно для показа превью, это захватить графический контекст и собственно рисовать на нем, ну и неплохо бы смасштабировать изображение. Все это делается нативным WinAPI примерно так:

procedure DrawBitmap(dc: HDC; hBitmap: HBITMAP; xStart, yStart: integer); stdcall;
var
 bm: BITMAP;
 hdcMem: HDC;
 ptSize, ptOrg: TPoint;
begin
 if dc  0 then
   begin
     hdcMem := CreateCompatibleDC(dc);
     if (hdcMem  0) then
       begin
         SelectObject(dc, hFont);
         SetBkMode(dc, TRANSPARENT);
         SetTextColor(dc, $C0);
         TextOut(dc, 42, 150, 'Hello World', 19);
         DeleteDC(hdcMem);
       end;
   end;
   UpdateWindow(hMyWnd);
end;

Это delphi-код, так как проект написан на этой платформе.
И что следует заметить. Прошло одиннадцать лет как я решил собрать и выложить на суд общественности продукт своего раннего творчества. За это время сменилось несколько поколений Windows, а схема с экранными заставками осталась почти без изменений. За исключением того, что механизм разблокирования (ввод пароля) упразднился еще в Windows 2000 (он стал стандартным, не требующим от программера дополнительных движений), ничего кардинально то и не поменялось. Чтобы сменить текущему пользователю экранную заставку, нужно поменять значение ключа реестра HKEY_CURRENT_USER\Control Panel\Desktop\SCRSAVE.EXE, хотя более надежный и правильный способ — воспользоваться утилитой rundll32.exe. Необходимо запустить ее с параметрами коммандой строки desk.cpl,InstallScreenSaver path_to_scr_file. Вообще, до настояшего момента скринсейвер распространялся среди моих знакомых стихийным образом — на флешках или по емэйлу, и вот я созрел до того, чтобы собрать это дело в виде законченного продукта, то есть причесать код, сделать инсталлятор и красивое лицо. Инстяллатор решил использовать Inno Setup. Долго искал какой-нибудь стандартный скрипт именно для создания инсталлятора скринсейвера (тратить время на написание было жалко). Наконец нашел. В конце статьи выложу для скачивания, может кому пригодится.
Забавно же однако смотреть на свой код годы спустя. В данном случае интересно, что алогритм, реализующий сигнал матрицы, содержится в модуле matrix_bp.pas. Это объясняется тем, что текстовый скринсейвер был выполнен в виде программы Borland Pascal, которая содержалась в единственном файле — matrix.pas. Поскольку структура Delphi-проекта несколько сложнее, а писать заново алгоритм генерации сигнала казалось нецелесообразным, выход напрашивался сам. Таким образом программа matrix.pas стала модулем matrix_bp.pas, где постфикс bp — дань памяти великому Borland Pascal’ю, ставшему третьим языком программирования, с которым мне довелось работь (после бейсика и ассемблера).
Итересно также использование технологии нитей (Threads) — сейчас это кажется абсолютно необоснованным, так как все можно было решить одной главной нитью и примитивным Windows-таймером, поскольку отрисовка на окне дозволяется только в главной нити процесса. Все дополнительные нити встраивают свой код отрисовки в очередь главной нити.
Ну и все-равно я считаю, что для тогдашнего моего уровня развития получилось весьма недурно. По крайней мере так говорят пользователи. Хотя они могут и лукавить)))…

  1. Пока что нет комментариев.
Подписаться на комментарии по RSS