• Worms Zone

    Worms Zone – червячная зона

    Worms Zone – онлайн-игра с динамичной сюжетной линией и забавной графикой. Начните растить своего червя

    Read more »
  • Way of Tanks

    Way of Tanks

    Way of Tanks – это танковый ранер с бесконечным геймплеем и разнообразной трассой. Игрок свайпами

    Read more »
  • Road Fighter

    Road Fighter

    Road Fighter — видеоигра в жанре аркадных автогонок, разработанная компанией Konami и выпущенная в виде

    Read more »
  • ZX-Spectrum 48k

    Неизвестный Синклер

    Весьма занимательное чтиво об истории становления компьютера ZX-Spectrum, Клайве Синклере и компании Sinclair Research. Цветной,

    Read more »
  • King Valley

    King’s Valley на ZX-Spectrum

    Моя версия игры King’s Valley для ZX-Spectrum, которую я написал еще в школьные годы, аккурат

    Read more »
  • YouCompleteMe in action

    Рандомные тормоза Vim с плагином YouCompleteMe

    Пользуюсь для C/C++ комплитером YouCompleteMe, базирующемся на clang. Периодически YCM тормозил так сильно, что ввод

    Read more »
  • Simple Viewer GL

    Simple Viewer GL

    Небольшой вьювер изображений использующий OpenGL. Пользуюсь этим вьювером в повседневной работе для быстрого просмотра списка

    Read more »
  • Rubik's Stopwatch

    Rubik’s cube Stop-watch

    Таймер для учёта времени сборки кубика Рубика и прочих головоломок. Более подробно о возможностях таймера

    Read more »

Emscripten: can’t open file embuilder.py

Начиная с версии 1.38.1 emscripten при компиляции вашего проекта может возникнуть такая ошибка:

ERROR:root:We cannot build the native system library in “~/.emscripten_ports/binaryen/binaryen-version_48” when under the influence of emmake/emconfigure. To avoid this, create system dirs beforehand, so they are not auto-built on demand. For example, for binaryen, do “python embuilder.py build binaryen”
ERROR:root:a problem occurred when using an emscripten-ports library. try to run emcc –clear-ports and then run this command again

Решается эта проблема двумя командами:

$ emcc --clear-ports
$ python embuilder.py build binaryen

При возникновении сообщения об ошибке «can’t open file ’embuilder.py’: [Errno 2] No such file or directory», укажите полный путь к текущей версии embuilder.py. В моем случае путь получается такой:

$ python /usr/local/Cellar/emscripten/1.38.5/libexec/embuilder.py build binaryen

Nexus Player flash firmware

Попытка обновления фирмвари приставки стабильно завершалась с ошибкой:

wiping userdata...
/usr/local/bin/mke2fs failed with status 1
error: Cannot generate image for userdata

Прыжки с бубном и потопывание ногами не помогало. Но решение проблемы оказалось простым – нужно обновить mke2fs до свежей версии:

$ brew cask install android-platform-tools

Smart Tiles

Smart Tiles Smart Tiles – на квадратном поле объединяй несколько одинаковых клеток в одну с большим номиналом. Размышляй, анализируй и дойди до вершины игры – получи клетку с максимальным номиналом. Быстрая, но увлекательная логическая игра с элементами стратегии.

Написал игру за неделю с нуля. Хотел уложиться в 5 рабочих дней, но в итоге ушло 7 дней. Больше всего времени ушло на “мелочи” вроде баланса игры и небольших свисто-перделок. Фоновую музыку и аудио-эффекты взял из библиотеки Sonniss.com, которая не так давно выложила в открытый доступ 30 Гб аудио в формате WAV 44KHz.

Изначально планировал сделать игру для Facebook Messenger, а для Android и iOS игра получилась “автоматически”. Разработку вел из-под macOS для, простите за каламбур, macOS на собственном C++ движке.

Smart Tiles for iOS
Smart Tiles for Android
Smart Tiles for Facebook Messenger

Worms Zone – червячная зона

Worms Zone Worms Zone – онлайн-игра с динамичной сюжетной линией и забавной графикой. Начните растить своего червя прямо сейчас. Стремясь стать настоящей анакондой, маленький червь никогда не сидит на одном месте – он готов укусить любого. Впрочем, существует опасность стать ужином для более удачливого игрока.

Вот и выпустил вторую публичную версию игры Worms Zone для Web, iOS, tvOS, Android. В ближайшее время будет доступна версия для Facebook Instant Games. Версии для macOS, Linux и Windows публично недоступны.

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

Так же добавились новые поверапы: временный удлинитель червя; радар для отображения чужих червей на карте; x5 множитель, позволяющий быстро вырастить червя и заработать очки.

Новые пиктограммы поверапов и новый шейдер, реализующий “круговой индикатор” для отображения оставшегося времени действия поверапа. Этот шейдер я сделал на базе моего старого шейдера, доступного на Shader Toy.

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

Conan – менеджер пакетов C/C++

Conan C/C++ package manager Благодаря LORу узнал о менеджере пакетов Conan C/C++ package manager. Это консольныя, децентрализованаая и кроссплатформенная (заявлена поддержка Windows, Linux, OSX, FreeBSD, и SunOS) утилита предназначенная для упрощения жизни разработчика.
Поддеживаются различные билд-системы – Visual Studio MSBuild, CMake, Makefiles, SCons, и многие другие. Как сказано в документации, Conan’у вообще монопенисуально, какую били-систему вы используете.

И все это под лицензией MIT. То, чего так давно ждут разрабочики от “нового” стандарта C++.

Emscripten initialization

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

По-умолчанию этот параметр установлен в TRUE. И сегодня я получил слайд-шоу, установив его в значение по-умолчанию.

EmscriptenWebGLContextAttributes attr;
emscripten_webgl_init_context_attributes(&attr);

attr.alpha = EM_FALSE;
attr.depth = EM_FALSE;
attr.stencil = EM_FALSE;
attr.antialias = EM_FALSE; // <-- this should be set to FALSE!
attr.preserveDrawingBuffer = EM_FALSE;
attr.preferLowPowerToHighPerformance = EM_FALSE;
attr.failIfMajorPerformanceCaveat = EM_FALSE;
attr.enableExtensionsByDefault = EM_TRUE;
attr.premultipliedAlpha = EM_TRUE;
attr.majorVersion = 1;
attr.minorVersion = 0;

EMSCRIPTEN_WEBGL_CONTEXT_HANDLE ctx = emscripten_webgl_create_context(nullptr, &attr);
emscripten_webgl_make_context_current(ctx);

Emscripten HiDPI

На HiDPI мониторах downscaled текстуры выглядят мягко говоря не очень красиво. Искал способ решить эту проблему. В итоге мои исследования привели к такому не самому легковесному решению.

  1. Получить device pixel ratio для настройки размров canvas.
  2. Получить размер canvas и разрешение css.
  3. На их основе вычислить отношение.
  4. Использовать это отношение для расчета координат мыши и тача.

После этого все будет выглядеть красиво на HiDPI мониторах. Но есть одна “особенность” – увеличенный (в зависимости от отношения размеров css и canvas) в несколько раз фреймбуфер. При отношении равном 2, получаем размер фреймбуфера в четыре раза больший, со всеми вытекающими.

Немного кода

CSS

canvas {
    width: 100vw;
    height: 100vh;
    display: block;
}

JavaScript

window.addEventListener('resize', resizeCanvas, false);

function resizeCanvas() {
    var realToCSSPixels = window.devicePixelRatio;

    var displayWidth  = Math.floor(canvas.clientWidth  * realToCSSPixels);
    var displayHeight = Math.floor(canvas.clientHeight * realToCSSPixels);

    if (canvas.width !== displayWidth || canvas.height !== displayHeight) {
        canvas.width  = displayWidth;
        canvas.height = displayHeight;
    }
}

resizeCanvas();

C++

int width, height;
emscripten_get_canvas_element_size(nullptr, &width, &height);

double cssWidth, cssHeight;
emscripten_get_element_css_size(nullptr, &cssWidth, &cssHeight);

const auto ratiox = (float)(width / cssWidth);
const auto ration = (float)(height / cssHeight);

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

Simple Viewer GL

Simple Viewer GL Некоторые пользователи моего вьювера жаловались на медленное проигрывание GIF-анимации во вьювере. И чем больше по размеру GIF-файл, тем медленнее происходит загрузка следующего фрейма. И проблема была явно не в медленном декодировании фрейма и его загрузке в GL-текстуру. Все оказалось проще. Каждый раз, когда вьювер запрашивал следующий фрейм, он заново инициализировал giflib, скармливал ему заново путь к файлу, выбирал нужный фрейм и только потом загружал его GL-текстуру.

Фикс получился прост как валенок. Хотя нет, из шерсти делать войлок я не умею, а вот исправить способ работы с GIF-анимацией удалось за пару минут. Теперь и большие анимации проигрываются без тормозов.

А еще я добавил экспериментальную поддержку JPEG 2000, основанную на библиотеке OpenJPEG. А так же написал загрузчик Apple Icon Image. Заодно сделал небольшой рефакторинг PNG, дабы унифицировать код загрузки, т.к. он используется и для загрузки PNG, и для ICO, а теперь и для ICNS.

Подробнее о Simpel Viewer GL.

История поиска одного бага

Debugging Довольно много времени потратил на поиск “плавающего” бага. За это время успел отрефакторить кучу кода, до которого руки не доходили ранее. Но баг не ловился. И в его поимке не смогли помочь ни Xcode Instruments, ни Xcode Analyzer (фронтэнд к статическому анализатору llvm).

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

Падения игры под отладчиком и backtrace давали BAD EXC, что как бы намекало на испорченную где-то ранее память. Но где именно? Статический анализатор, по идее, должен на раз находить access out of bounds. Но анализатор молчал, типа вообще все пучком.

От безысходности и обиды на самого себя, решил синхронизировать линуксовую версию с main branch, т.к. в процессе поиска бага был сделан серьезный рефакторинг кода. Ну и очевидно, что погонять движок под valgrind никогда лишним не будет.
И valgrind сразу же нашел memory corruption (тот самый “плавающий” баг, на поиски которого я убил много времени. И мелкий ничего не значащий memory leak.

Linux и valgrind рулят!

GIF из видеоролика

Простой способ создания анимированного GIF из видеоролика. Представленный способ выполняется в два этапа:
1. Делим на кадры, попутно изменяя размер изображения (в данном случае до 320 по ширине, высота меняется пропорционально).
2. Создаем GIF-анимацию из отдельных кадров.

$ ffmpeg -i input.mp4 -vf scale=320:-1:flags=lanczos,fps=10 frames_%03d.png
$ convert -loop 0 frames_*.png output.gif
1 2 3 71