Я уже не первый год занимаюсь моддингом легендарной Half-Life 1, и как-то совершенно спонтанно мне пришла в голову мысль, дескать, как было бы прикольно иметь возможность компилировать карты на какой-нибудь платформе, отличной от привычных всем x86 и amd64. Затем я вспомнил, что у меня дома есть ТВ-приставка на базе Android, которую в теории можно было бы приспособить для этих дел. Если возможность есть, значит обязательно нужно провести такой эксперимент!
Что имеем
В наличии у меня была бюджетная ТВ-приставка GoldMaster I-905, совершенно ничем не примечательная. Имеет 16 гигабайт встроенной памяти, 2 гигабайта оперативной памяти. Базируется на процессоре Allwinner H313. Из интерфейсов: имеет два USB 2.0 порта, композитный видеовыход, HDMI порт. Доступ в сеть может быть обеспечен как через Wi-Fi, так и через Ethernet-порт (я использовал проводное подключение).
Также, нам нужны исходники компиляторов карт. За почти 30 лет существования игры, их вариаций появилось не так уж мало: оригинальные компиляторы от Valve, ZHLT, VHLT, P2ST, и т.д. Я же буду использовать компиляторы карт из моего проекта PrimeXT: они самые актуальные на данный момент, их будет проще всего собрать и запустить под какой-либо экзотической платформой, в отличии от всех остальных вариаций. Сама игра, а также все сопутствующие утилиты, включая компиляторы карт, написаны на C/C++. В PrimeXT используется система сборки CMake.
Подготовка
После недолгого поиска информации, я выяснил, что для сборки C++ проектов прямиком на Android мне потребуется Termux. Его нужно скачать с репозитория F-Droid, поскольку версия, опубликованная на Google Play, объявлена устаревшей и больше не поддерживается.
После установки Termux, на всякий случай обновим установленные пакеты:
pkg upgrade
Теперь установим пакеты, которые непосредственно понадобятся нам.
pkg install cmake git openssh pkg-config ninja
Для более удобной работы, я решил запустить на приставке SSH-сервер и подключиться к нему с моего компьютера. Для этого я использовал связку софта KiTTY + WinSCP. Разумеется, вместо этого можно использовать любой другой софт. А можно и обойтись вообще без SSH-сервера - просто вбивать все нужные команды в Termux ручками на устройстве. WinSCP я буду использовать для удобной работы с файлами на удалённом устройстве.
Теперь нужно запустить SSH-сервер: процедура весьма тривиальная.
Сначала, нам необходимо выставить пароль для подключения к серверу, а затем запустить соответствующую службу.
passwd
sshd
После чего, можно пробовать подключиться с компьютера к серверу. Обратите внимание, что в Termux для SSH-сервера используется порт 8022, а не привычный 22. Имя пользователя можно вписать любое, а ввести пароль нужно указанный ранее. При удачном подключении отобразится шелл.
Сборка компиляторов
После завершения всех подготовительных процедур, можно перейти непосредственно к сборке: первым делом нужно склонировать исходники в домашнюю директорию.
cd ~
git clone --recursive https://github.com/SNMetamorph/PrimeXT.git
cd PrimeXT
Далее нужно проинициализировать vcpkg. Возможно, что появится уведомление о каких-либо недостающих пакетах в системе - их нужно будет поставить вручную.
export VCPKG_FORCE_SYSTEM_BINARIES=1
external/vcpkg/bootstrap-vcpkg.sh
Затем, нужно создать и подготовить директорию, в которой будет происходить сборка.
cmake -E make_directory ./build
cd build
Теперь настал черёд сгенерировать кэш CMake и запустить сборку. Поскольку меня интересуют только компиляторы карт, я сделал пресет для CMake под названием "utils-termux-debug", в котором отключена сборка игровых библиотек, лаунчера и остальных утилит. Также, чтобы компиляция проекта прошла быстрее, я выставлю сборку в 4 потока.
cmake .. --preset utils-termux-debug
cmake --build . --parallel 4
После выполнения двух описанных выше команд, запустится процесс сборки.
Если сборка пройдёт успешно, это будет выглядеть так. В случае если возникнут какие-то ошибки, то лучше перезапустить сборку в одном потоке, так будет проще выяснить, в каком конкретно месте возникла ошибка компиляции. К слову, на этой приставке сборка в 4 потока заняла около четырёх минут, с учётом того что на фоне был запущен IPTV-плеер.
Компиляция карты
Для заключительного этапа нужно подготовить рабочую директорию, в которой будут находиться WAD-файлы с текстурами, .rad файл и исходник карты. В моем случае эта директория будет иметь название gameres.
mkdir ~/gameres
cd ~/gameres
Затем, внутри этой директории нужно создать файл gameinfo.txt со следующим содержанием:
basedir ""
gamedir "gameres"
Важный момент: в этом файле, значение параметра gamedir должно совпадать с названием рабочей директории. Далее, нужно положить используемые WAD-файлы в рабочую директорию, создать внутри неё поддиректорию с названием maps, и положить в поддиректорию .rad файл и исходник карты в виде .map файла. Все нужные файлы которые использовал я, доступны по этой ссылке.
Теперь можно попробовать скомпилировать карту, и остаётся лишь ждать.
cd ~/PrimeXT/build/Release/primext/devkit
./pxcsg ~/gameres/maps/crossfire_double1_v2.map
./pxbsp ~/gameres/maps/crossfire_double1_v2.bsp
./pxvis ~/gameres/maps/crossfire_double1_v2.bsp
./pxrad ~/gameres/maps/crossfire_double1_v2.bsp
Процесс компиляции карты состоит из четырёх этапов. При завершении каждого этапа, будет отображено затраченное на него время. В случае, если во время компиляции карты возникнут какие-то проблемы, то можно поглядеть файл с логами в поддиректории maps. Также, можно добавить компиляторам параметр запуска -dev 5, чтобы отображение процесса было более подробным.
Проверка результатов
После того как карта удачно скомпилировалась на ТВ-приставке, я решил пересобрать эту же карту на своем компьютере и после этого сравнить две этих карты. В идеале, никаких видимых различий быть не должно. Тестировать всё это дело я буду в моде PrimeXT, который в свою очередь базируется на движке Xash3D FWGS.
В движке есть команда mapstats, которая позволяет отобразить различную внутреннюю информацию о карте. Для нашей ситуации, это прямо то что нужно.
Статистика карты, скомпилированной на ТВ-приставке
Object names Objects/Maxobjs Memory / Maxmem Fullness
------------ --------------- --------------- --------
entities [variable] 64780/1048576 ( 6.2%)
planes 2179/65536 43580/1310720 ( 3.3%)
textures [variable] 4976/33554432 ( 0.0%)
vertexes 11219/65535 134628/786420 (17.1%)
visibility [variable] 199238/16777216 ( 1.2%)
nodes 5031/32767 120744/786408 (15.4%)
texinfo 1383/65535 55320/2621400 ( 2.1%)
faces 8467/65535 169340/1310700 (12.9%)
lightmaps [variable] 1745778/33554432 ( 5.2%)
clipnodes 12686/32767 101488/262136 (38.7%)
leafs 3260/32767 91280/917476 ( 9.9%)
markfaces 11552/65535 23104/131070 (17.6%)
edges 20150/1048576 80600/4194304 ( 1.9%)
surfedges 40037/2097152 160148/8388608 ( 1.9%)
models 142/1024 9088/65536 (13.9%)
deluxmaps [variable] 1745778/33554432 ( 5.2%)
=== Total BSP file data space used: 4.53 Mb ===
World size ( 5120 5824 3920 ) units
Supports transparency world water: No
Lighting: colored
World total leafs: 2318
original name: maps/crossfire_double1_v2_arm.bsp
internal name: desert
map compiler: PrimeXT Tools v.0.90 (Dec 15 2022 / 1397a04 / armv7l / android)
map editor: J.A.C.K. 1.1.2800 (vpHalfLife)
Статистика карты, скомпилированной на компьютере
Object names Objects/Maxobjs Memory / Maxmem Fullness
------------ --------------- --------------- --------
entities [variable] 64777/1048576 ( 6.2%)
planes 2179/65536 43580/1310720 ( 3.3%)
textures [variable] 4976/33554432 ( 0.0%)
vertexes 11210/65535 134520/786420 (17.1%)
visibility [variable] 198643/16777216 ( 1.2%)
nodes 5031/32767 120744/786408 (15.4%)
texinfo 1383/65535 55320/2621400 ( 2.1%)
faces 8465/65535 169300/1310700 (12.9%)
lightmaps [variable] 1744599/33554432 ( 5.2%)
clipnodes 12747/32767 101976/262136 (38.9%)
leafs 3258/32767 91224/917476 ( 9.9%)
markfaces 11512/65535 23024/131070 (17.6%)
edges 20138/1048576 80552/4194304 ( 1.9%)
surfedges 40013/2097152 160052/8388608 ( 1.9%)
models 142/1024 9088/65536 (13.9%)
deluxmaps [variable] 1744599/33554432 ( 5.2%)
=== Total BSP file data space used: 4.53 Mb ===
World size ( 5120 5824 3920 ) units
Supports transparency world water: No
Lighting: colored
World total leafs: 2316
original name: maps/crossfire_double1_v2.bsp
internal name: desert
map compiler: PrimeXT Tools v.0.90 (Dec 16 2022 / 1397a04 / amd64 / win32)
map editor: J.A.C.K. 1.1.2800 (vpHalfLife)
Как можно заметить, минимальные различия всё-таки имеются. Сложно сказать, в чём конкретно причина этих различий, но скорее всего они совсем некритичны. Далее, имеет смысл сравнить, есть ли какие-либо визуальные различия на самой карте.
Скриншоты карты, скомпилированной на компьютере
Скриншоты карты, скомпилированной на ТВ-приставке
Лично я вообще никаких визуальных различий в освещении либо геометрии не заметил, что конечно хорошо. Эксперимент можно считать удачным.
Итог
Описанными выше процедурами вполне можно компилировать карты для Half-Life 1 на практически любых устройствах, которые базируются на ОС Android или Linux. Разве что, на слишком больших и детализированных картах у устройства может не хватить оперативной памяти для компиляции. Может ли всё это быть кому-то полезно? Вполне. Например, в случае если по какой-то причине не хочется нагружать основной ПК, либо же кроме смартфона нет вообще никаких устройств, а карту скомпилировать как-то надо.