[Из песочницы] Как создавался кроссплатформенный Half-Life или «Хедкрабы внутри ваших часов»
Парочку месяцев назад на Гиктаймсе проскакивала новость о запущенной Half-Life на Android Wear. В статье ни слова не сказано было о разработчиках и тогда один из хабровчан спросил в комментариях, почему никто из них не напишет здесь?
И вот уже годовщина с того момента, как я начал порт свободного движка Xash3D на Linux, а также, поскольку несколько моих знакомых всё же интересовались подробностями, я решил написать этот пост. Кому интересна история проекта, обходы разных проблем и мои личные советы, прошу под кат.
Начну с истории проекта. Следил за движком я ещё с 2012 года, но лишь осенью 2014 с небольшим опытом программирования на С++ я скачал исходный код движка. Загоревшись мыслью о том, что свободный игровой движок и кроссплатформенность — понятия ещё с кармаковских времён тесно связанные, я начал портировать его на Linux.
Поначалу порт планировался с использованием winelib, но со временем, вникнув в архитектуру движка, я остановился на SDL2, как самой вездесущей мультимедийной библиотеке. Да и Valve для своих портов использовали его.
И вот сразу мой первый совет тем, кто хочет переносить любое неизвестное ему приложение на любую ОС:
1) Создавайте проектные файлы сразу и, не делая ни единого изменения в проекте, компилируйте его.
Да, от моего совета ваша IDE может даже подвиснуть, так как компилятор выдаст не одну тысячу ошибок и предупреждений. У меня компилятор выдавал около 4000 ошибок.
Переходя от одной ошибки к другой, я постепенно избавлялся от них. Не оставалось и виндового кода, -Wl,--no-undefined очень сильно спасает при портировании.
И вот свершилось — загрузился движок. Показывает собственную консоль, а за окном, тем временем, уже было примерно начало декабря прошлого года. Должен подчеркнуть, что до меня попытки предпринимались и примерно на консоли и заканчивались, если не раньше. Весь декабрь ушёл на загрузку библиотек в рантайме, SDL ввод, звук — и вот я выкладываю на Linux.org.ru скриншот работы.
То, что я скидывал когда-то EXL.
Несколько человек заинтересовываются проделанной работой. Я же оглядываюсь на исходники и понимаю, что с этим уже работать нельзя: во многих местах код из-за макросов становится нечитабелен, появляются странные баги, сборка за пределами моего локалхоста очень сложна. Да и версия движка сильно старая. В комментариях к треду указывают, что новые версии распространяются на каком-то другом форуме. В итоге я начинаю всё с нуля, а мой знакомый помогает приводить всё в серьёзный вид — переводит сборку на CMake, гонит на меня плохо пахнущими тряпками за слишком большие коммиты и говнокод. Также на GitHub создаётся организация SDLash3D, названная в честь старого порта. На момент написания статьи в ней аж пять человек, но активны только двое.
Внезапносовет номер 2, который я для себя уяснил в этом время:
2) Сделайте заголовочный файл, содержащий одни макросы, которые будут вставлять нужный для целевой платформы код.
Также тут совет для тех, кто, читая эту статью, пишет код в своей студии.
3) На счёт всякого подозрительного и странного кода обращайтесь к Google. Он вам расскажет, что ваш код компилируется только под Visual Studio, у которого много нестандартных расширений. И поменьше завязывайтесь на WinAPI.
Тем временем, nicknekit/Unc0nnected молча начинает портировать старый порт на Android.
С февраля мы с Никитой начинаем работать вместе над портом. Он занимается старым портом, а я допиливаю новый и переношу в него функционал, связанный с Android.
В этот момент устанавливается базовая схема работы порта на Android. Сейчас оно выглядит так:
В марте мы создаём тред на 4PDA, о котором сообщаем об успехах переноса, новые видео и скрины. Первого же апреля выходит версия 0.1, но первое апреля не может быть без шутки, поэтому в движке сделано специально условие, при котором он закрывается, если не найден pakandroid.pak, в котором был «зашит» очень весёлый и достаточно качественный мод G-Man Invasion.
С тех пор, среди значимых событий для порта оказались:
- Поддержка сенсорного управления, сделанная совместно с Beloko Games;
- Релиз версии 0.14, который действительно принёс успех. Около 20 тыс. посетителей за два дня, судя по статистике на GitHub;
- Интерфейс Android-версии для модификаций, сделанный нашим mittorn. Мододелы могут самостоятельно выпустить свою игру ещё и на Android.
На этом можно и закончить, ниже бонус в виде отдельных коммитов и ссылки на нас на GitHub и ModDB.
Бонус №1. Несколько коммитов, связанных с разным пониманием кода в Visual Studio и GCC. После исправления их всех я точно уверен, что поддержка Си в студии — это худшее, что случалось в сфере программирования:
Бонус №2. Также некоторые коммиты, связанные с ARM, Android и OpenGL ES:
- Баг, со странным умножением и делением на 1.0 на ARM;
- Ещё проблемы с float. Вызывало рандомные краши с SIGBUS;
- А здесь ссылки нет. Просто внезапно для себя открыл, что все char на ARM — беззнаковые. Оттого навигация NPC сходила с ума, а в движке не работали спрайты. Можно или ключ -fsigned-char вставить, или явно указывать, что char должен быть знаковым для этой переменной;
- Баг рендера. Не совсем проблемы ARM, зато проблема OpenGL ES. До сих пор не пофикшена полностью;
- Своя собственная реализация dlsym() на Android, а всё потому что в Android до Lollipop просуществовал баг, с которым не резолвились некоторые символы из библиотек;
Ссылки:
Организация на GitHub.
Страница на ModDB.
Спасибо за внимание, ваш a1batross.