RETRO MOBILE
3 поста
3 поста
Недавно мне написал Дмитрий - читатель с Хабра, который живёт в Беларуси. Дмитрий довольно давно читает мой блог, ему нравятся мои статьи и он захотел подогнать мне ретро-железо для будущих статей - и здесь есть много всего интересного!
В первой коробочке лежали материнские платы. И не абы какие, а очень крутые и интересные. Например материнка на SiS 530 интересна тем, что у этого чипсета не было AGP, а роль видеоускорителя выполнял немного допиленный SiS 6326. Материнка на пга370 интересна тем же - только там в качестве видеочипа используется i815-производный гп. А ещё тут есть слотовая материнка с процессором... В слоте.
Во второй коробочке лежал крутой подгон - белорусские шоколадки. В целом я гораздо больше люблю именно сладости из Беларуси, они сильно качественнее чем те, что можно найти в пятерочке/магните в РФ. Помимо шоколадок, меня ждали легендарные телефоны - Samsung X100, Huawei U8110, ZenFone 2 на x86 процессоре Intel, а также Nokia и...
...GBA SP с картриджем для оригинального Gameboy. GBA SP осталась от прошлых жильцов в уставшем, но предположительно рабочем состоянии. Девайсы эти неубиваемые, если шлейф в норме и КП не сдох - ещё мои внуки будут пользоваться. Картридж я опознал как Super Battletank: War in the Gulf 1994 года выпуска
Но самый крутой подгон - это ноутбук Toshiba Satellite 100CS 1996 года выпуска (поздравьте молодого, ему в этом году исполнилось 30 лет!) с 75МГц Intel Pentium (без MMX), 8МБ EDO RAM, 500МБ HDD и 10.4" пассивной цветной матрицей, способной выдавать до 256 цветов :)
Ноут включается, проходит POST, но не показывает ничего на экране. Скорее всего связано с шлейфом, у них они отходят от времени. Самой крутой фишкой некоторых японских ноутов тех лет я считаю то, что у них блок питания встроен в устройство и для использования достаточно иметь с собой кабель в розетку.
Большое спасибо Дмитрию за такой крутой подгон :) Тошибой займусь когда приеду домой, а на этой неделе вас ждёт статья о ремонте ноутбука ещё старше - на 486'ом процессоре от Cyrix и монохромной матрицей, родом из 1994 года. Когда то он трудился на кафедре университета, в нем упала в КЗ главная цепь питания, но теперь, спустя 20-25 лет после списания, он попал в гиковские руки :)
Летом ВК подключил партнёрскую программу с Озоном и предложил "авторам" (в основном нейрослоп постов бестолковых) монетизацию за счёт рекламы всяких товаров. И ладно бы эти товары были норм..
Но предлагают откровенный развод на бабки. Один из самых частых товаров, который стабильно попадается раз в 20 постов в ленте - реклама смартфона Pagraer i17 Pro Max под видом "недорогой" вариации на iPhone с топовым железом.




Под капотом обещают топовый Snapdragon... 450B (средний процессор из 2017 года с 8-ю A53'ими ядрами на 1.8ГГц, вчистую проигрывает даже смартфонам на юнисоке т310 за 5к. Свежие версии пабг он уже точно не потянет), 12ГБ ОЗУ (из которых только 4ГБ настоящие, а остальные 8ГБ - свап на флэшке), HD+ 90Гц IPS-экран (это ок, стандарт для бюджеток) и 5.3Ач АКБ (стандарт для бюджеток, но на практике может быть заметно меньше). Android тоже обещают свежий, на практике максимум 10-11 5 летней давности.
И Вишенка на торте - 512ГБ встройки, из которых реальных ну максимум 64-128. У этого же бренда есть смартфоны за 6-8к на Helio P60 - годный проц, но из 2018 - и вендоры чаще всего ставят ту версию Android, которую даёт MediaTek с PDK (а это максимум 10-11, GSI образы свежее почему то никто не накатывает)



A18 Pro превращается в P60, если пролистать до описания
Забавно что ни MediaTek, ни Qualcomm эти процы уже много лет не поддерживает и не производит, так что собирают смартфоны из остатков на складах, а среди сотен накрученных отзывов попадаются гневные, где вскрываются реальные ТТХ.
И по своей натуре это норм смартфоны за 5-6к, B-бренды типа Blackview тоже выпускают подобные, но по нормальной цене, с свежей версией ведра и чуть более свежими процами типа T310'ого. Собсна ВК и Озон, почему вы поощряете развод, а если смартфон покупает человек в теме и видит расхождение с ТТХ, просто предлагаете ему возврат средств?
Осторожно: Эта статья — не просто очередная ретроспектива с воспоминаниями, а конкретный разбор сетевой архитектуры и хаков, благодаря которым стал возможен мультиплеер в GTA аж на 1.000 человек одновременно. Если вам интересен геймдев и то, как работают игры под капотом — статья обязательна к прочтению!
GTA: San Andreas запомнилась нам как легендарная игра с немыслимым, по меркам 2004 года, масштабом. В ней был и огромный бесшовный мир, состоящий из трех городов, и массивный автопарк аж из 213 транспортных средств, и длинная интересная история с кучей сайд‑активностей, прохождение которых занимает как минимум несколько дней, и даже элементы RPG с базовой прокачкой персонажа.
И вот всё в ней было идеально, кроме одного — мультиплеера. Rockstar не успела доделать полноценный режим сетевой игры, оставив лишь подачку в виде локального кооперативного режима на PS2, в котором даже миссии проходить было нельзя. Однако группа моддеров под руководством Kalcor смогла воплотить то, что не удалось сделать Rockstar — реализовать мультиплеер в GTA SA аж на 1.000 человек одновременно. И о том, как им удалось это сделать, я расскажу в рамках сегодняшней статьи!
❯ Предыстория
Серия GTA получила статус культовой задолго до выхода San Andreas. Ещё в 2001 году, на PS2 вышла GTA III, повествовавшая нам об истории немого гангстера по имени Клод, который волею судьбы был вынужден сражаться за свое выживание на улицах грязного и холодного Либерти‑Сити. В отличии от прошлых игр серии, GTA 3 перенесла геймплей в полноценное 3D, умудрившись реализовать на скромном железе PlayStation 2 огромный и (почти) бесшовный город, состоящий из трех островов.
После прохождения одиночной компании, многим игрокам хотелось большего: причем речь шла не о DLC с новыми миссиями, а о полноценном мультиплеере, где можно было бы устраивать анархию с другими игроками. И что интересно — мультиплеер изначально планировался Rockstar, но по каким‑то причинам был вырезан из игры (скорее всего нехватка времени), о чём говорят оставленные строки с упоминанием сетевой игры.
[FEM_MP] MULTIPLAYER
[FEF_LAN] LAN
[FEF_INT] INTERNET
[FEN_CON] Connection
[FEN_GAM] Find game
[FEN_TY] Game type
[FEN_GNA] Game name:
[FEN_NAM] Name:
[FEN_NCI] NOT CONNECTED TO THE INTERNET
[FEN_NET] Network
[FEN_PLA] Number of players:
[FEN_PLC] Player color
[FEN_PLS] Player settings
[FEN_UKH] Unknown host
[FEN_UKM] Map not found
[FEN_UKT] Game type not found
[FET_MAP] SELECT MAP
Через год, в 2002 году, игра вышла на ПК и моментально привлекла внимание моддеров. Точную хронологию событий восстановить сложно, но скорее всего моддеры сначала написали софт для распаковки/запаковки текстур в форматах txd, затем импортеры и экспортеры 3D‑моделей в формате dff для 3 ds Max/Milkshape 3D, и параллельно с этим ковыряли скриптовый движок игры под названием SCM. SCM представлял из себя специализированную виртуальную машину, которая загружала огромную многопоточную программу под названием main.scm, которая в свою очередь контролировала чуть ли не половину геймплея игры: зоны банд, места спавна машин, пикапы оружия и здоровья, а также содержала логику миссий вместе с побочными заданиями.
Схожая система использовалась и в GTA2, причём DMA Design (бывшее название Rockstar North) в 1999 году опубликовала официальный компилятор вместе с документацией и примерами скриптов — что и послужило отправной точкой для реверса SCM (под «капотом» обе работали похожим образом, но у GTA2 номера опкодов другие):
Откуда там потоки?
Конечно многопоточность в SCM была условной, потоки в скриптах не могли выполняться параллельно на разных ядрах процессора и не контроллировались планировщиком задач в ОС. Вместо этого, у движка игры был собственный планировщик, который каждый кадр брал по одной инструкции каждого потока и выполнял только её. Такой подход позволяет не превращать игровой цикл в мешанину из коллбэков, корутин и await'ов и сохранить синхронность и последовательноть скриптовой части игры.
Фича настолько удобная, что Oracle реализовала эту концепцию за счет виртуальных потоков в Java 21:)
Первой попыткой реализовать мультиплеер в GTA 3 стал GTA3: AM aka MTA 0.1, выпущенный через год после релиза игры на ПК — 9 февраля 2003 года. Первая версия мода была написана на VB6 (да, да, звучит дико) немецким подростком и являлась результатом реверс‑инжиниринга кода игры, в котором на тот момент разобрали только структуру класса автомобиля и игрока. Из‑за этого синхронизировалось только две машины, а для того чтобы увидеть второго игрока, нужно было сначала сесть в машину в которой будет ехать второй игрок, затем выйти из нее и сесть в «свою» — и только после этого игроки смогут увидеть друг друга, причем вторая машина будет без водителя.
В MTA 0.2 добавили чат и пофиксили краши, а в MTA 0.3 реализовали полноценную синхронизацию других игроков вместе с первыми игровым режимами — Deathmatch и Stunt. Именно в 0.3 впервые использовалась своя собственная реализация main.scm — mta.scm, за счет которой, скорее всего, и реализовали синхронизацию игроков: скриптовый движок позволяет создавать пешеходов и машины, а также управлять их позицией, поворотом, ускорением и даже может заставить их стрелять в определенном направлении — и этого было достаточно для базовой синхронизации игроков. Весной 2003 года вышла GTA: Vice City на ПК, которая использовала всё тот же движок, и за короткое время разработчики перенесли наработки в новую игру, а к команде присоединился австралиец Kalcor, который позже станет известен как разработчик SAMP:
Однако разработчики отнюдь не работали «вслепую». Как рассказывал Kalcor, примерно в 2004 году, у команды MTA появились связи с программистами из Rockstar, которые неофициально делились заголовочными файлами с описанием структур и функций игры. Выяснилось что контекст скриптового движка можно легко «угнать», если подсунуть ему свою структуру CRunningScript с указателем на произвольный буфер с опкодами, и заставить игру делать всё что пожелаешь. Именно эта находка позже легла в основу CLEO (ближе к версии 3.0), который позволил подключать к игре кастомные скриптовые моды и даже расширять её функционал за счет добавления новых опкодов.
Изначально сервер в MTA занимался лишь пересылкой состояния игроков, в то время как игровые режимы реализовывались на клиентской стороне. Kalcor'а это не устраивало, но команда стояла на своём — так что в 2005 году он покинул проект, чтобы начать свой — VCMP с RakNet в качестве сетевого транспорта и скриптингом на стороне сервера. В качестве скриптового движка он выбрал AMX — маленький, но очень шустрый C‑подобный язык, пригодный для написания небольших игровых режимов (и совершенно непригодный для написания всяких RP — страшно представить, что творится в коде условного Radmir/Arizona RP), который до этого использовался для написания серверных модов в CS 1.6 (помните AMX Mod X?:)) и хорошо зарекомендовал себя.
Команда VCMP чуть позже выбросила AMX и перешла на Squirrel — куда более пригодный язык для написания больших режимов, в то время как SAMP так и остался на AMX. Скорее всего Kalcor просто устал в 2010-х поддерживать свой мод и у него не было времени или желания добавлять что‑то ещё.
В том же 2005 году, GTA: San Andreas наконец‑то вышла на ПК и Kalcor принялся портировать наработки VCMP для неё, благо движок оставался всё тем же. Самая первая версия SAMP поддерживала только гонки по чекпоинтам, но в мае 2006 года вышла полноценная публичная бета, заработал сайт sa‑mp.com и с этого всё началось...
Насчет движка
Несмотря на это, игра всё равно очень сильно изменилась "под капотом" - добавили возможность выполнения внешних скриптов из script.img, сделали основу для DLC (потом её использовали в моде DYOM), сильно расширили лимиты scm и очень сильно доработали механизм стриминга. Именно благодаря доработке больше не было экранов "Greetings fromVice CitySan Andreas" :)
Оригинальная версия могла обрабатывать до 100 игроков на одном сервере (что уже немало), но Kalcor продолжал дорабатывать мультиплеер, и в версии 0.2 лимиты подняли до 200, в 0.3 — до 500, а в 0.3 c — аж до 1000 игроков одновременно! Это уже вполне уровень MMO. Kalcor достиг этого за счет динамического стриминга объектов на сервере: если игрок или автомобиль находится вне зоны стриминга (которая определялась сферой радиусом в 150 м вокруг игрока), то сервер банально переставал слать информацию об обновлениях объекта и клиент его удалял — но если 1000 игроков собирались в одном месте... FPS на большинстве компьютеров тех лет падал в однозначные значения.
В последующие годы SAMP активно развивался — добавляли новые функции, объекты и скины, пока в 2015 не вышел последний крупный апдейт — 0.3.7, который добавлял статических NPC. После этого, активная поддержка модификации закончилась... а вот серверов — нет. С 2010 по ~2020 год, SAMP проживал свои лучшие дни: серверы уже не ограничивались простыми DM/Stunt/Cops And Robbers режимами на пару сотен человек, администраторы серверов активно вкладывались в RP и RPG режимы, которые превращали GTA в симулятор реальной жизни с отыгрышем ролей, работами со своим начальством из реальных игроков, собственной сложной экономикой и имуществом, которое стоило реальные деньги (условные бизнесы на Radmir могут продавать за 10–15 тысяч реальных рублей). Доход этих проектов исчисляется миллионами рублей, а их авторы смогли себе позволить практически полный порт GTA SA на Unity под мобильные устройства...
❯ Изучаем архитектуру
Но в чем секрет SAMP и как он работает под капотом? В студенческие годы я и сам писал свой мультиплеер для Vice City, который работал как External‑чит, написанный на C# (звучит дико, но оно работало на базовом уровне), изучая исходный код SAMP 0.2. И в нём есть много фишек, о которых будет интересно узнать как молодым инди‑разработчикам, так и реверс‑инженерам и простым игрокам.
Детали реализации моего мультиплеера
Моя реализация мультиплеера работала за счет перезаписи процесса игры функциями ReadProcessMemory и WriteProcessMemory, а также инъекций шеллкода. Вместе с клиентом шел ассемблер FASM, который на лету компилировал мелкие функции по типу «угнать скриптовый контекст, выполнить n опкодов и вернуть результат», выделял в памяти игры небольшой пул для данных с помощью системного аллокатора VirtualAlloc, и затем выполнял код с помощью функции WinAPI CreateRemoteThread.
За счет этой же концепции работают инжекторы dll‑библиотек, которыми пользуются всяческие кряки для софта, моды и читы для онлайн‑игр. В целом, никто не мешает инжектнуть и Managed библиотеку в нативную игру при условии использования.NET Framework: тогда библиотеку можно загрузить через COM по CLSID с помощью шеллкода, либо внедрить рантайм.NET в игру с помощью ICLRHostControl, либо инжектнуть обычную C++/CLR библиотеку в качестве нативной DLL, которая создаст контекст.NET. Для обычных.NET без Framework остаются способы с инжектом hostfxr и через COM.
Кроме того, маршаллер в.NET позволяет без проблем вызывать нативные функции через GetDelegateForFunctionPointer, в том числе и виртуальные, если первым аргументом идёт указатель на экземпляр. Так что возможности хукинга в.NET очень обширные:)
Начнем с вами с клиентской части, которая инжектится в игру как обычная dll‑библиотека в качестве asi‑плагина. После загрузки, ОС вызывает функцию DllMain, в которой создается поток, ожидающий полноценного запуска игры:
После того как игра инициализировалась до этапа показа стартовых роликов, клиент хукает состояние меню так, чтобы игра сразу перешла к загрузке мира, а также «угоняет» главный цикл игры и контекст D3D9 для отрисовки оверлея с чатом и HUD'а над головами других игроков. Угон происходит за счет патчинга функции Render2DStuff, в начало которой записывается инструкция jmp с указателем на функцию, которая будет вызываться перед выполнением оригинального кода.
Насчет патчей
Помните патчи для телефонов Siemens, которые позволяли загружать Elf'ы и воспроизводить MP3? Они работали по точно такому же принципу, только там jmp сразу же записывался в код прошивки, а функция выносилась куда-нибудь в "свободное место".
Хук главного цикла происходит аккурат в тот момент, когда игра закончила отрисовку всех объектов на экране и перешла к отрисовке интерфейса. Именно в этот момент клиент выполняет синхронизацию игроков, спавнит объекты и занимается прочими полезными делами, при этом каждая серверная сущность (игрок, автомобиль, объект, пикап и меню) имеет свой отдельный фиксированный пул.
В каждом пуле есть несколько сотен слотов для сущностей, причем память для них выделена заранее. При получении сообщения от сервера вида WorldPlayerAdd/WorldVehicleAdd, клиент вызывает функции игры и физически создает объект в мире игры, а сами пакеты присылаются сервером в момент входа в зону стриминга:
Создание и манипуляция объектами происходит за счет угона контекста скриптового движка SCM, о котором мы говорили ранее. Клиент заставляет игру создать еще одного игрока/машину/пикап (эта же функция используется для кооператива на PS2) и перехватывает над ним управление. Тут есть интересный момент — по умолчанию в GTA нет нормальной системы динамической подгрузки ресурсов «по необходимости», все модели и анимации скрипты подгружают вручную с помощью опкодов 0×247 и 0×4ED, а если этого не сделать — то игра крашнется.
В свою очередь, контекст SCM угоняется путем создания экземпляра объекта CRunningScript с заполнением указателя на текущую инструкцию (dwIP) и стека (если это нужно). После того как скриптовый движок обработал команду, хук достает результат выполнения (например ID созданной машины или персонажа) из стека и сохраняет его как хэндл для манипуляции объектом в будущем:
int __declspec(naked) ExecuteScriptBuf()
{
__asm
{
mov bScmLocalDebug, 1;
mov eax, OFFSET ScriptBuf
mov ecx, gst // В ecx сохраняется указатель на объект CRunningScript
mov [ecx+0x14], eax // В eax указатель на IP (буфер с опкодами)
call ProcessOneCommand // После чего вызывается функция ProcessOneCommand
// которая выполняет ровно один опкод в буфере
// (эта же функция используеся игрой для реализации многопоточности)
mov ecx, gst
mov eax, [ecx+0xC5] // Далее указатлеь на флаг, означающий вернул ли опкод значение запимыватся в eax
mov bScmLocalDebug, 0;
ret // return.
}
}
Интереснее всего выполнена синхронизация управления персонажами. Помните я говорил о том, что в PS2-версии GTA SA был локальный кооператив на двух игроков? Так вот: у каждого объекта игрока есть своя структура с описанием того, какие кнопки управления сейчас зажаты. Поэтому ходьба, стрельба и прицеливание реализованы как раз за счет прямой синхронизации нажатых кнопок: ваш клиент помимо координат и ускорения отсылает ещё и состояние кнопок, в то время как другие игроки у вас «честно» бегают на клиенте, но при сильном рассинхроне позиции их откидывает на ту позицию, которую прислал сервер помимо нажатых кнопок. Из‑за этого бег в SAMP'е был таким «рваным»:
А почему нельзя синхронизировать стейт отдельно?
Резонный вопрос: зачем симулировать кнопки, если можно вручную задавать текущую анимацию игрока и честно синхронизировать позицию и ускорение с поправкой на компенсацию лагов?
Тут проблема в том, что во первых такая анимация бега будет рассинхронизирована с движением персонажа (GTA активно использует Root motion) без информации о текущем проигрываемом кадре, а во вторых на эту систему подвязан механизм регистрации стрельбы — о котором я сейчас расскажу.
Не менее интересно сделана и регистрация попаданий. Те читатели, которые застали ранние версии SAMP, могли вспомнить такое явление, как «стрельба по пингу»: если ты просто стреляешь по модельке бегущего персонажа — ты гарантированно не попадаешь из‑за лага на сервере. Но если стрелять с небольшим упреждением (~20-30 пикселей от персонажа в сторону вектора его движения), то попадание засчитывалось. Происходило это как раз вследствие механизма синхронизации кнопок, который я описал в прошлом абзаце: клиент синхронизировал не сам факт попадания на нашем клиенте (нужную функцию игры для хукинга на тот момент просто не нашли), а лишь наш угол прицеливания и зажатую кнопку стрельбы. Таким образом, обработка попаданий ложилась полностью на того игрока, в которого мы стреляем — если мы попали в него на его клиенте, у него отнималось здоровье, которое отсылалось на сервер и засчитывалось как попадание. Но поскольку все пакеты доходят с заметной задержкой, за условные 120 мс уже пройдет 7.5 кадров игры и игрок «у себя» давно убежит за пределы экрана, а мы у него будем стрелять «в молоко»:)
В 2014 году Kalcor всё таки нашёл нужную функцию для определения попадания на клиенте (предположительно хукнув условный CPed::InflictDamage) и смог реализовать нормальную обработку, добавив коллбэк OnPlayerTakeDamage и назвав её компенсацией лагов. С этого момента стрельба перестала быть ватной.
Как должно быть правильно?
В SAMP используется полуавторитарная модель мультиплеера: сервер отвечает за основные правила игры и игровой режим, но полностью доверяет игрокам в вопросах текущей позиции, ускорения и здоровья (и именно поэтому в SAMP'е так легко летать над картой, использовать спидхаки и прочие приколы).
В такой модели самым правильным решением является обработка попадания на клиенте того игрока, который стреляет и последующая отсылка пакета InflictDamage на сервер, что в свою очередь убирает все минусы «ватной» стрельбы, но порождает возможность реализации деструктивных читов по типу «зафлудить сервер пакетом InflictDamage и застрелить всех с другого конца карты» (что тоже можно без проблем детектить).
В авторитарных моделях (Quake, Half‑Life, CS2, CoD и других играх) такие приколы вообще невозможны, поскольку клиент отсылает только кнопки и угол прицеливания (и ничего более, даже позицию не отсылает), в то время как весь геймплей обрабатывает сервер и отсылает на клиент лишь обновленное состояние мира, которое сглаживается с помощью компенсации лагов. С этим решением нет возможности читерить деструктивно (то есть спавнить объекты, телепортировать игроков в клетки и прочие прелести P2P и полуавторитарных моделей), но игра сильно зависит от тикрейта на сервере и пинга, играть нормально в CS с пингом 100+ невозможно, в отличии от игр с полуавторитарной моделью.
На сервере тоже есть на что посмотреть. В своей основе, сервер является ретранслятором сообщений от игроков: он принимает пакеты синхронизации, обновляет состояние игроков на серверной части и рассылает их другим игрокам. Тут всё по классике:
Однако для управления поведением сервера предусмотрены режимы, написанные на скриптовом языке Pawno (тот самый AMX). На каждое событие сервер вызывает коллбэк, скрипт в свою очередь выбирает как на него реагировать: если персонаж сел в машину, в которую ему садится нельзя (допустим это ТС фракции, к которой он не принадлежит), то скрипт может его оттуда принудительно выкинуть.
Помимо игровых режимов, сервер также запускал так называемые фильтр‑скрипты, которые получали всё те же коллбэки, но использовались как своеобразная система плагинов. На фильтрскриптах реализовывали античиты, логирование, а также маппинг карты: интереснее всего то, что кастомные объекты на карте создавались прямо из скриптов (вместо отдельного файла с описанием сцены), что в некоторых игровых режимах раздувало код до десятков тысяч строк в одном файле:)
У сервера были серьезные проблемы с оптимизацией. Например каждый вызов коллбэка, сервер искал функцию с её именем, что в свою очередь требовало итерацию по таблице символов вместе с strcmp. Именно поэтому сколь либо крупные паблики требовали серьезных серверных мощностей, несмотря на простоту серверной модели. А ещё, как и у любого уважающего себя сервера, у него был RCON — специальная консоль, с помощью которой сервером можно было управлять удаленно.
В целом, сервер был простым и шустрым в свой основе, но застой с AMX несколько тормозил прогресс игровых режимов, а из‑за отсутствия клиентских модификаций все серверы выглядели «одинаковыми» (хотя тут ещё влияет преемственность RP‑проектов, многие из которых берут корни от SAMP RP, и других режимов типа DM‑Stunt).
❯ Заключение
Вот так работал легендарный мод для GTA «под капотом». И хотя его сетевая модель выглядит достаточно простой, тысячи человеко‑часов, потраченные Kalcor'ом на реверс‑инжиниринг и отладку кода вызывают неподдельный гиковсий респект! Но история мультиплеера в GTA на этом не закончилась, и для GTA V вышло как минимум 3 мультиплеера — alt:V, RageMP и FiveM. И что самое интересное — Rockstar Games купила команду FiveM в 2023 году, дабы превратить сторонний мод в полуофициальный мультиплеер, закрыв альтернативные проекты:(
А вы играли когда‑нибудь в SAMP? Понравилась ли вам статья? В ближайшее время я хочу сделать полный разбор архитектуры GTA III/VC/SA со всеми интересными фишками и оптимизациями «под капотом», если вам интересен такой формат — дайте знать, обязательно сделаю:)
В качестве тестовых машин, мне было бы интересно пощупать что‑то ещё из семейства Nvidia ION/Radeon Xpress Graphics/VIA Chrome9 HC/Trident Blade. Если у кого‑то есть всякие интересные тонкие клиенты или ноутбуки на прикольном железе, или что‑то AMD'шное времен 939/462 — пишите в ЛС, обязательно сделаю контент!
Олды блога могут вспомнить мою демку про самолетики. Возможно скоро будет статья про куда более крутую игру для ретро компьютеров и возможно даже PSP и PS2!
Ну а я надеюсь, что вам было интересно. Подписывайтесь на блог, чтобы не пропускать новые статьи каждую неделю! А если вам интересна тематика ремонта, моддинга и программирования для гаджетов прошлых лет — подписывайтесь на мой Telegram‑канал «Клуб фанатов балдежа„, куда я выкладываю бэкстейджи статей, ссылки на новые статьи и видео, а также иногда выкладываю полезные посты. А ролики (не всегда дублирующие статьи) можно найти на моём YouTube канале.“»
А если вы хотите что‑нибудь подарить из железа и увидеть о нём статью — пишите мне в Telegram. Меня очень интересуют самые разные гаджеты: начиная от игровых консолей и любых связанных с геймингом устройств, телефонов, смартфонов, КПК, заканчивая ретро‑компьютерами и ноутбуками. Кто знает, может героем следующей подобной статьи окажется ноутбук из 90-х?:‑)
После обзоров устройства не продаются, а остаются в моей коллекции. Когда‑нибудь я хочу сделать музей, где к каждому устройству можно будет приложить QR и почитать мою статью. Кто знает, вдруг на следующей неделе я также подробно расскажу про девайс из вашей юности?:)
Фото Nokia 9300 с сайта mobile‑review.com
Кстати, у меня есть GameBoy Advance SP, под который я очень хочу написать игру. Однако мой экземпляр был залит водой и кофе. Может у кого‑то есть донор с дохлой платой, откуда я смог бы взять контроллер питания? У меня AGS-101.
Недавно мне написал читатель Илья с Хабра и предложил подогнать ноутбук Mitac SLT486DLB родом из начала-середины 90-х годов, который долгое время работал на кафедре некоего университета на дальнем востоке. Илья сам пытался его запустить от ЛБП, однако ноутбук совсем не подавал признаков жизни и он решил подарить его мне.
После разборки, я обнаружил следы прошлого ремонта - кто-то перепаивал диод Шоттки на входе, немного поплавив пластик рядом.
Чуть левее меня ждал сгоревший предохранитель на входе питания и КЗ по +17V. Подключив ЛБП на 1В/1А, я обнаружил калящийся танталовый конденсатор на модуле DC-DC преобразователя главной шины питания. Снял модуль - КЗ ушло, заменил на электролит - плата подала признаки жизни.
5В - главная шина питания для ноутбуков и компьютеров тех лет. Даже многие процессоры работали от 5В :) модуль собран на ШИМ TL494, но думаю его без проблем можно поменять на XL4015E1 за 200 рублей
Рядом с преобразователем на 5В расположился DC-DC преобразователь, формирующий питание процессора. Он был в норме, на входе 5В и VIn, на выходе 3.6В (в зависимости от процессора, у меня LV).
Далее я подал питание на VIn и ноутбук включился, радостно пискнув о том, что POST пройден.
Из за отсутствия родного БП с пином Sense, ноут отказывался включаться как от VChg на разъёме питания, так и от VBat, поэтому кинул VBat в обход схемы выбора источника питания на VIn, не потеряв ни в защите от КЗ, ни от переполюсовки.
Открываем флюс, собираем, включаем и балдеем😎 с HDD DOS не загрузился, но флоппик работает, так что пойду записывать MS-DOS 6.22 с экстендером и буду запускать все крутые игры для DOS на своем Cx486 66МГц!
Спойлер: Вы тоже можете купить такой одноплатник за 800 рублей, благо на барахолках их навалом. Ну а как их починить и превратить во что-то полезное, я расскажу в рамках сегодняшней статьи!
По правде сказать, я огромный фанат купить что-то очень дешевое и нерабочее, чтобы затем найти новое применение железу со свалки. Недавно я изучал Авито и наткнулся на тонкие клиенты Dell Wyse 3040 по 800 рублей с нерабочими eMMC. Казалось бы, тонких клиентов на вторичке навалом — но у этого был 4х-ядерный процессор от Intel, неплохой GPU с поддержкой DirectX11, 2 гигабайта оперативной памяти и целых 4 слота под USB. Надо брать!
В этой статье всё как вы любите: диагностика, изучение схемотехники, перекатка и замена флэшки в BGA-корпусе, попытки впихнуть невпихуемое и очень изощренные способы загрузить Linux. Интересно? Тогда жду вас под катом!
Недавно я мониторил барахолки на предмет каких-то необычных ретро гаджетов по типу телефонов, ноутбуков и минипк. В основном они мне интересны из-за возможности погонять на них ретро-игры, запустить экзотические ОС или просто для тестирования демок своих игр, которые я пишу в рамках отдельной серии статей. Неделю назад в моих рекомендациях всплыл некий Dell Wyse 3040: тонкий клиент на 4х-ядерном Intel Atom z8350, который из коробки работает на собственной операционке ThinOS.
По сути, это обычный x86 мини-компьютер, который вместо ноутбучного Celeron/Pentium использует планшетный Intel Atom на платформе Cherry Trail: такие Atom'ы можно было найти в дешевых Wintel-планшетах типа Irbis TW85, а также ноутбуках в категории «до 15.000 рублей» в 2015-2020 годах. У большинства таких гаджетов была одна критическая болячка: в качестве накопителя они использовали чипы памяти eMMC из смартфонов, а поскольку ресурс таких флэшек значительно ниже оных в обычных SSD-накопителях, они выходили из строя всего через 2-3 года активного использования. Wyse 3040 тоже использовал eMMC в качестве SSD, из-за чего сотни, если не тысячи экземпляров дожили до наших дней рабочими лишь частично и пошли под списание. Как раз именно такой списанный экземпляр я и решил купить всего за 870 рублей.
Конечно я немного лукавлю насчет "одной единственной болячки". У тех же Irbis'ов летело всё: USB-OTG хост, контроллеры питания, тачскрины, биосы... в общем, это было то ещё удовольствие.
Когда я получил девайс, он сразу же меня впечатлил: мало того что размером с мою ладошку (как и eBox, о котором я рассказывал в рамках прошлой статьи), так ещё и с полностью пассивным охлаждением, питанием от 5В/2А и целой кучей интерфейсных разъемов. На передней панели расположилась кнопка питания, один порт USB 3.0, один USB 2.0, а также 3.5мм джек для подключения наушников.
В то время как на задней целых два DisplayPort'а, ещё два USB и Ethernet. Существовало несколько разных версий 3040'ого: в базовой из коммуникаций есть только RJ-45 и накопитель объёмом в 8ГБ, а в продвинутой добавили ещё и Wi-Fi/Bluetoth модуль и увеличили объём накопителя аж до 16ГБ. В мои руки попала как раз базовая версия.
После получения, я пришёл домой, подключил компьютер и... увидел сообщение «No bootable devices found". В UEFI-прошивке Dell'ов есть режим самодиагностики, который честно сказал, что не может ничего прочитать с eMMC — а значит она не просто ушла в режим «только для чтения», а вообще полностью посыпалась. Неужто там стоят легендарные чипы от Samsung, которые в своё время досрочно унесли с собой Galaxy S4, S4 Mini, S4 Zoom, S3, Tab 3...
О косячных флэшках Samsung я недавно писал большую статью с практическим восстановлением редчайшей консоли-смартфона на Android. Ссылка в комментариях :)
Теперь отремонтировать наш минипк можно только заменив чип памяти на новый, благо сделать это не особо сложно. Для этого сначала нужно разобрать компьютер, что называется, голыми руками — отщелкиваем нижнюю часть корпуса с клипс и разбираем "бутерброд":
После чего перед нами открывается следующая картина:
В глаза сразу бросаются два чипа оперативной памяти типа DDR3 объёмом по 512МБ каждый, LAN-трансформатор, LDO для питания LAN-контроллера и слот M2... казалось бы, можно ставить самый дешевый SATA SSD с «алика» и заканчивать статью, но у этого слота нет ни PCI-E, ни SATA линий — на него выведена шина SDIO для подключения Wi-Fi/BT модуля в старших версиях.
С фронтальной стороны платы нас встречает относительно небольшая система охлаждения, состоящая из радиатора, который отводит тепло и с процессора, и с контроллера питания, и с памяти. TDP у процессора крошечный — всего ~2Вт, поэтому активное охлаждение ему не нужно совсем (а вот его температуры под нагрузкой мы узнаем чуть позже).
Под радиатором скрывается кастомный контроллер питания Texas Instruments SND9039A2, разработанный специально для Cherry Trail. Эти КП используются во всех устройствах на этой платформе, что потенциально несколько усложняет ремонт — те же Bay Trail'ы нередко использовали куда более распространенные и задокументированные КП от AXP.
КП формирует 6 основных шин питания из шины 5V: 1.15V, 1.25V и 1.05V для питания процессора, 1.35V для питания DDR3 в режиме LV, ещё одна 1.15V для питания видеочипа и 1.8V для общения с периферией. Помимо основных шести DC-DC преобразователей, в КП также есть аж 14 LDO, которые формируют периферийные шины по типу VRTC (дежурка и часы реального времени), 3.3V и 1.2V. За основную шину питания — т.е 5V отвечает другой чип — NCP81231, так что если компьютер не включается — смотрите в первую очередь в его сторону.
В центре платы расположилось сердце устройства — тот самый процессор Atom Z8350, представленный в феврале 2016 года. Концептуально это система на кристалле — по сути весь компьютер выполнен в виде одного крошечного чипа, выполненного по техпроцессу 14нм. Внутри него скрываются:
4 ядра на архитектуре Airmont, способные работать на частоте от 1.4ГГц до 1.9ГГц в турбобусте и имеющие 2МБ общего L2-кэша. Кроме того, ядра поддерживают HyperThreading и являются прямыми наследниками ядер Silvermont, используемых в смартфонах Asus ZenFone и планшетах Asus FonePad. Так что да, чисто технически — этот процессор близкий родственник смартфонных чипов :)
GPU Intel HD Graphics 400, способный работать на частоте до 500МГц и имеющий всего 12 унифицированных шейдеров (даже в GeForce GT710 было 192 унифицированных шейдера, в i3 6100 — 24). Тем не менее, HD Graphics 400 вполне тянет игры из начала нулевых, имеет целых два DisplayPort'а и поддержку DSI-матриц планшетов, умеет декодировать 4K видео и поддерживает DirectX 11.2.
Встроенный контроллер оперативной памяти типа DDR3, плюс контроллер eMMC для накопителя. Интересно то, что SATA в нём вообще не было — что ещё раз подтверждает родство с смартфонными процессорами.
Из внешних шин есть PCI-Express 2.0 1x (да, всего одна дифпара на всю систему), UART, SPI, I2C и SDIO. За звук отвечает I2S контроллер, а за общение с параллельной периферией отдельный GPIO-контроллер.
И всё это с TDP всего в 2Вт!
Круто, да? Рядом с процессором расположились ещё два банка ОЗУ по 512МБ каждый, в сумме дающий нам 2ГБ памяти. В теории объём можно расширить и до 4ГБ, однако это потребует патч SPD-таблицы в UEFI, ведь отдельной SPD EEPROM-ки тут нет. Помимо этого, около процессора можно заметить гигабитный Ethernet-контроллер Realtek RTL8111H, подключенный через единственную дифференциальную пару PCI-Express в процессоре, и аудиоконтроллер ALC5672 от всё той же Realtek.
А ещё чуть ниже можно увидеть SPI-флэшку с прошивкой UEFI — MXIC 25U12873F, рядом с виновником торжества — eMMC-флэшкой Hynix H26M41204HPR объёмом в 8ГБ. И именно её нам сейчас предстоит заменить.
Как и во многих других устройствах, в Wyse 3040 используются флэшки в корпусе BGA153. Этот корпус пережил уже целых 3 поколения памяти: сначала в него упаковывали eNAND, затем eMMC, а сейчас во всю используют для UFS. У этого корпуса есть совместимый брат — BGA169, который отличается дополнительными пинами по бокам. Существуют два вида таких чипов:
Собственно сам чип-памяти eMMC, который состоит только из NAND-памяти.
И eMCP, который состоит из бутерброда флэш-память + оперативная память. Такой тип активно использовался в смартфонах и планшетах.
Оба этих типа частично взаимозаменяемы между собой — можно без проблем поставить eMCP в устройство с обычной eMMC на борту (просто пины оперативной памяти подключены не будут), однако обратное делать уже нельзя, иначе устройство останется без оперативной памяти. Перед заменой eMMC, старый чип необходимо выпаять, предварительно намазав под пузо флюс. Я использую AMAOE M53:
Никакого компаунда здесь нет, а плата хоть и толстая, но не особо теплоемкая — так что eMMC легко отлетает за минуту прогрева при 320 градусах на среднем потоке воздуха и без нижнего подогрева.
Плата маленькая, благодаря чему её не «ведёт» при длительном прогреве без нижнего подогрева.
Когда чип начал покачиваться от легкого прикосновения отвертки, осторожно поддеваем его специальным скальпелем и откидываем в ту сторону, где меньше всего обвязки. Но если он слишком упорно сопротивляется — лучше погреть его подольше, иначе есть шанс оторвать пятаки:
Эта гифка — лишь иллюстрация. Никогда не снимайте чип убрав фен, шанс оторвать пятаки крайне высок.
Далее зачищаем посадочную площадку оплеткой или просто паяльником, проверяем все ли пятаки на месте и отмываем площадку от флюса. На некоторых устройствах, например большинстве смартфонов от Samsung, NC-пятаки (никуда не подключенные пустышки) стабильно отлетают из-за сомнительного качества самих плат, так что если NC отлетели — ничего страшного. Должно быть вот так красиво:
Поискав в запасах чипы BGA153, я нашел два одинаковых SanDisk'а по 8ГБ, один из которых я сдул с убитой платы планшета, а также BGA169 чип от Toshiba на 32ГБ с Nokia N8. Чип от N8 я припаять нормально не смог из-за того что он слишком большой для этой площадки, а вот SanDisk'и залетели на плату на ура.
Поскольку чипы долго лежали в коробочке без вакуума, ставить их прям так рискованно — есть шанс что на шариках припоя уже образовались окислы, что может нарушить контакт в будущем. Поэтому снимаем старые шары паяльником, центрируем чип в трафарете и не перебарщивая наносим паяльную пасту, не забывая убрать излишки лопаткой. Я использую премиум пасту Mechanic XG50 и всем рекомендую :)
Далее оплавляем припой при температуре ~290-300 градусов. Если сильно переборщить — флюс испарится быстрее, чем припой начнет оплавляться и шары повылетают. Если поставить меньше — шары будут дольше оплавляться. С нагревом чипов памяти нужно быть осторожным — даже eMMC боится перегрева, не говоря уже об очень хрупких UFS, которые снимать нужно обязательно на нижнем подогреве.
Далее капаем немного флюса на посадочную площадку:
И припаиваем чип к плате. Даже если он где-то встал неровно, поверхностное натяжение поставит чип на место, а если его всё таки сдует чуть дальше, чем он должен быть — можно его осторожно поправить скальпелем.
И вот, чип наконец-то установлен! Но, как в известном анекдоте, есть нюанс...
После включения, EFI всё также жаловался на отсутствие устройств, с которых можно загрузиться. Однако селф-тест теперь сразу вылетал с ошибкой «Short eMMC read test unsuccessful», что надвинуло меня на мысль о том, что инициализации не происходит.
Я перекатал несколько разных чипов еще 5 раз и эффект изменился только с чипом от Samsung на 4ГБ. И вот тут то я понял: а что, если только UEFI не видит eMMC из-за несовместимости бутпротокола в extCSD? Ведь на схеме не просто так указаны страпы для выбора ревизии памяти. И точно — флэшка Samsung заработала тут нормально. После этого я решил загрузить Linux с USB и проверить /dev/ — и eMMC там определился за счет собственного драйвера для Cherry Trail!
Что такое ExtCSD?
Это специальный конфигурационный регистр в eMMC, который отвечает за управление размером аппаратных разделов Boot, а также протоколом загрузки.
Дело в том, что не у всех устройств первичный загрузчик может сам проинициализировать флэшку и загрузить оттуда SPL, некоторые чипы заранее настраивают протокол загрузки в этом регистре и затем побайтно считывают загрузчик с помощью специального механизма. Если ExtCSD настроен неправильно - то устройство просто окирпичится. Касается это Tegra и Atom :)
Далее я поставил обратно чип от SanDisk, загрузился в Puppy и увидел что система запустила проверку разделов с файловой системой ext, что уже очень хороший знак — флэшка успешно инициализируется и читается системой. На этом этапе чип можно пропатчить с помощью специальной утилиты, но дампа extCSD оригинальной флэшки у меня нет :(
В качестве системы, я решил выбрать Debian 12 Bookworm — она не слишком старая и не слишком тяжелая, особенно с рабочим столом Xfce. Установщик сразу увидел eMMC, которую теперь необходимо переразметить — сейчас там остатки Android от планшета, из которого этот чип выпаяли.
После установки компьютер перезагрузился... но вы же не думаете, что всё было так просто? Он снова не увидел eMMC. Дело в том, что в Wyse 3040 кривой UEFI, который не учитывает путь до загрузчика из NVRAM и грузит только стандартный BOOTX64.EFI. Я скопировал его из папки EFI/debian/ в EFI/boot/
И даже после этого UEFI его не увидел, а значит моя теория с тем, что EFI привередлив к ExtCSD флэшки — верна. Поэтому я решил сделать финт ушами и записать на маленькую USB-флэшку только ядро и initrd, перенаправив root на eMMC. Для этого монтируем флэшку и копируем initrd из под Rescue-режима Debian:
mkdir -p /emmc/
mount -o remount,rw /cdrom/
mount -t /dev/mmcblk0p2 /emmc/
cp /emmc/initrd.img /cdrom/
Патчим grub.cfg так, чтобы он указывал на initrd и ядро на флэшке:
menuentry --hotkey=g 'Boot' {
set background_color=black
linux /install.amd/vmlinuz vga=788 root=/dev/mmcblk0p2 ---
initrd /initrd.img
}
И загружаемся с флэшки. Как итог — система пошла грузиться и уже через минуту я увидел окно входа LightDM.
Теперь компьютером можно полноценно пользоваться. Debian сразу подцепил все необходимые драйвера, в том числе и для GPU — так что даже аппаратное ускорение интерфейса присутствует. Конечно 2ГБ памяти для современного ПК очень мало, но тем не менее, 4х-ядерный Atom ещё кое-что может!
Например, можно с некоторыми лагами серфить современный интернет. Я спокойно зашел на свой профиль на Хабре дабы поностальгировать со статей 2023 года. И мне это удалось сделать, даже скроллинг почти не тормозит.
Драйвера Mesa также подтянулись сами, благодаря чему работает WebGL. Помимо 3D, также есть аппаратное ускорение видео, благодаря чему из такого минипк можно сделать мультимедийный центр.
А ещё этот малыш даже игры тянет! В OpenArena мы получаем 40-60 кадров на большинстве локаций в 800x600... результат конечно не супер крутой (все таки это игра на базе движка Quake 3), но тем не менее в TuxRacer или эмуляторы ретро-консолей поиграть можно :)
При максимальной нагрузке, процессор едва греется до 55 градусов — так что температурный режим у него максимально безопасный и думаю он никогда не начнет троттлить и не выдаст низкий уровень на пин PROCHOT при своевременном обслуживании :)
Что такое PROCHOT?
Это специальный сигнал на всех процессорах Intel, который сигнализирует о перегреве самого процессора или зоны VRM.
Ради интереса, я погонял его в бенчмарке sysbench cpu, где он набрал 1476 попугаев. Это результат примерно в два раза хуже чем у Core 2 Quad Extreme Q9300 и в полтора раза хуже чем у Pentium G4400. Для планшетного процессора результат отличный, Intel N95 с гордостью перенял эстафету экономичного, но достаточно шустрого процессора :)
Учитывая неплохую производительность и минимальное энергопотребление, вас наверняка может заинтересовать перспектива использования этого минипк в качестве SBC. И он вполне для этого годится! На плате есть пятаки для отладочного порта, где выведено сразу несколько шин I2C, UART и JTAG. К I2C можно «достучаться» с помощью i2c_dev, а к UART'у через обычный ttyS.
Более того, путем небольших вмешательств в плату можно взять линии PCI-Express с сетевого контроллера для подключения внешней видеокарты или накопителя, а питание для внешних дисплеев и прочей периферии можно попробовать взять прямо из шин питания компьютера. Например 3.3v можно взять от LDO, который формирует IO-питание LAN-контроллера — у него запас аж 3А, так что хватит с головой :)
Так что лично я считаю, что Wyse 3040 — прекрасная альтернатива Raspberry Pi 2/3 и OrangePi Zero/PC, которые сейчас можно найти на авито по схожей цене, а иногда даже и выше. А вы?
Вот такой интересный компьютер я купил всего за 800 рублей. Пару часов времени, немного паяльной пасты, трафарет и фен — и вот компьютер по цене пиццы уже работает и радует меня как маленький домашний сервер с минимальным потреблением. И ведь таких экземпляров на вторичке сотни, и каждый из них можно использовать для организации медиацентра, мини-NAS, сервера или, если очень постараться, и накатить Windows, даже машинки для ретро-игр. А что думаете вы? Какие применения могут быть у такого 4х-ядерного компьютера? Пишите свое мнение в комментариях!
В качестве тестовых машин, мне было бы интересно пощупать что‑то ещё из семейства Nvidia ION/Radeon Xpress Graphics/VIA Chrome9 HC/Trident Blade. Если у кого‑то есть всякие интересные тонкие клиенты или ноутбуки на прикольном железе, или что‑то AMD'шное времен 939/462 — пишите в ЛС, обязательно сделаю контент!
Олды блога могут вспомнить мою демку про самолетики. Возможно скоро будет статья про куда более крутую игру для ретро компьютеров и возможно даже PSP и PS2!
Ну а я надеюсь, что вам было интересно. Подписывайтесь на блог, чтобы не пропускать новые статьи каждую неделю! А если вам интересна тематика ремонта, моддинга и программирования для гаджетов прошлых лет — подписывайтесь на мой Telegram‑канал «Клуб фанатов балдежа„, куда я выкладываю бэкстейджи статей, ссылки на новые статьи и видео, а также иногда выкладываю полезные посты. А ролики (не всегда дублирующие статьи) можно найти на моём YouTube канале.“»
А если вы хотите что‑нибудь подарить из железа и увидеть о нём статью — пишите мне в Telegram. Меня очень интересуют самые разные гаджеты: начиная от игровых консолей и любых связанных с геймингом устройств, телефонов, смартфонов, КПК, заканчивая ретро‑компьютерами и ноутбуками. Кто знает, может героем следующей подобной статьи окажется ноутбук из 90-х?:‑)
После обзоров устройства не продаются, а остаются в моей коллекции. Когда‑нибудь я хочу сделать музей, где к каждому устройству можно будет приложить QR и почитать мою статью. Кто знает, вдруг на следующей неделе я также подробно расскажу про девайс из вашей юности?:)
Фото Nokia 9300 с сайта mobile‑review.com
Кстати, у меня есть GameBoy Advance SP, под который я очень хочу написать игру. Однако мой экземпляр был залит водой и кофе. Может у кого‑то есть донор с дохлой платой, откуда я смог бы взять контроллер питания? У меня AGS-101.
Дело было вечером, делать было нечего. На авито увидел тонкий клиент Dell Wyse 3040 всего за 800 рублей. Машинка интересная - 4х-ядерный Atom, 2ГБ ОЗУ с потенциалом расширения до 4-х, eMMC в качестве SSD... казалось бы - шикарно
Но как и в одном бородатом анекдоте, есть нюанс. За такую цену эти минипк продают с отвальной eMMC, которая и без того здесь скромного объема - всего 8ГБ.
Комп был препарирован, eMMC успешно заменена, накатан Debian и теперь машинка выполняет роль домашнего сервера с пусть небыстрым, но все таки SSD😎
Как думаете, 800 рублей и 3 часа времени - дорого за комп с 4 ядрами, неплохим GPU Intel HD Graphics, 2ГБ DDR3 памяти и гигабитной сетью?
В этом году сегмент бюджетных смартфонов с ценой до 10.000 рублей не отличается особым разнообразием. Подавляющее большинство моделей построено на базе чипсетов от Unisoc, визуально имитируют внешний вид iPhone 17 Air и отличаются лишь экранами и конфигурацией памяти, за исключением редких "броневичков" с сменными аккумуляторами типа Cubot KingKong Dura.
Свежий Blackview Wave 10 является хорошим примером сбалансированного ультрабюджетника: за 10к мы получаем 8-ядерный Unisoc T615, 8ГБ оперативной памяти и 256ГБ постоянной, и свежую версию Android с фирменной оболочкой DokeOS. Стоит ли он своих денег? Сегодня узнаем!
Вообще, я сейчас пользуюсь сразу двумя смартфонами параллельно: Blackview Xplore 2 Projector как основной, и Cubot KingKong Dura в качестве дополнительного. Каждый из девайсов выполняет свою собственную задачу: Xplore 2 держит аккумулятор неделю, у него предфлагманское железо, и присутствует неплохой проектор - в условиях съёмной квартиры без телевизора, нам с девушкой функционал DLP-проектора пришелся очень по нраву. У KingKong Dura же есть два сменных аккумулятора, которые выручают в ситуациях когда забыл зарядить оба гаджета, плюс на нем стоит Max и прочие ВКонтакте.
Но недавно мне понадобился третий смартфон, причем на свежем, но бюджетном железе и ценой до 10к - и оным стал Blackview Wave 10. Нужен он мне был для тестирования своего хобби-проекта - 3D-игры для Android на самопальном движке с минимальным весом и числом зависимостей. Собственно пару лет назад мы такую игру уже с вами делали:
Помните как мы тестировали концепцию "Write once, run anywhere" и писали игру с единой кодовой базой для всех Java-устройств? :)
Смартфон я заказал 3 сентября, а приехал он в мой день рождения - 25 сентября.
Внутри устройства стандартная начинка по меркам бюджетника:
Процессор: восьмиядерный Unisoc T615, который состоит из 2-х ядер Cortex A75, работающих на частоте до 1.8ГГц и 6-и Cortex A55, работающих на частоте до 1.6ГГц, а за графику отвечает Mali-G57 в одноядерной конфигурации, работающий на частоте 850МГц. T615 является "средним" чипом в семействе T6xx и от T620 отличается только несколько сниженной частотой работы процессорных ядер.
Помимо основных ядер, в процессоре также располагается модем, способный работать в LTE, 3G и 2G сетях, а платформа поддерживает Wi-Fi 5, BT 5.2, GPS, Глонасс, BeiDou и Galileo. По производительности процессор находится между MediaTek Helio G81 и G99 - мастодонтов бюджетных смартфонов.
Память: eMCP-чип, состоящий из 8ГБ оперативной памяти типа LPDDR4X и 128/256ГБ постоянной UFS. Для такого ценового сегмента конфигурация отличная - ОЗУ будет хватать для полноценной многозадачности, да и постоянной памяти здесь тоже вполне хватает. Помимо прочего, Wave 10 поддерживает MicroSD карты памяти.
Дисплей: большая IPS-матрица с диагональю 6.88", разрешением 720x1640 (HD+) и частотой обновления в 120Гц. Пожалуй это самая сильная сторона устройства, хотя я скучаю по временам, когда за 10к можно было купить смартфон с OLED'ом :)
Камеры: 32МП основная и 13МП фронтальная, модели сенсоров, к сожалению, неизвестны.
Аккумулятор: 5Ач, стандартная литий-полимерная без углеродных приколов. Быструю зарядку устройство не поддерживает.
Габариты: 171.9x78x9мм при весе в 205г, кроме того, устройство соответствует стандарту IP54 и не боится ни брызг воды, ни пыли. Тут всё стандартно.
Дополнительные фичи: сканер отпечатков пальца. Поддержки NFC нет.
ОС: Android 16 с фирменной оболочкой DokeOS 5.0. По правде сказать, я больше предпочитаю AOSP, нежели перегруженные функционалом оболочки, однако в моем Xplore 2 Projector, DokeOS показала себя отлично.
Поставляется аппарат в вот такой симпатичной коробочке:
Внутри коробки всё стандартно: сам смартфон, зарядное устройство, силиконовый чехол, кабель Type-C, защитное стекло, скрепка и мануал. На дисплей смартфона сразу наклеена пленка.
Блок питания здесь совсем простой и может выдавать только 10Вт. Как я уже говорил ранее, быструю зарядку смартфон совсем не поддерживает и заряжается около 2-2.5ч.
Визуально смартфон весьма симпатичный и отлично лежит в руке. На выбор предлагается четыре веселых цвета - оранжевый (как у iPhone 17 Air), черный, зеленый и голубой. В отличии от большинства других бюджетников этого года, Wave 10 внешне напоминает не iPhone 17 Air, а Galaxy S26 :)
Несмотря на 5 глазков камер, модуль по факту здесь только один, плюс вспышка. Не знаю с чем связана мода на фейковые объективы, но справедливости ради отмечу что камера здесь действительно очень неплохая по меркам бюджетника (об этом чуть позже).
С фронтальной стороны скрывается дисплей с относительно крупными рамками - при этом матрица одна из самых сильных сторон Wave 10. Экран неплохо откалиброван, у него приличная цветопередача и производительность смартфона вполне позволяет пользоваться 120Гц режимом с комфортом.
В целом первые впечатления от смартфона положительные, но главная фишка бюджетных Blackview - в DokeOS. Давайте же включим смартфон и проверим на что он способен на практике!
Включаем
После включения, нас встречает рабочий стол DokeOS. В целом, оболочка представляет из себя небольшой набор полезного софта + некоторые твики в настройках. Среди приложений можно найти морозилку (позволяет отключать неиспользуемые приложения), трекер здоровья, погоду и системный клинер.
Также в оболочке есть оверлей для игр, который позволяет начать запись экрана, настроить частоту обновления, установить говернор с желаемым профилем производительности, и посмотреть фреймтайм игры. За последнюю фичу большой респект и лайк :)
Среди обещанных ИИ-фишек есть 4 приложения: чат (клиент к DeepSeek'у), музыка (клиент к Suno), видео и обработка фото. У всех приложений есть платные подписки, которые, однако, покупать необязательно - у каждого есть отдельный ежедневный лимит использований. Например можно отредактировать 20 фотографий в день бесплатно.
В целом, в большинстве повседневных сценариев смартфон показывает себя отлично. Приложения запускаются быстро, каких-то лагов при переключении между ними нет, серфинг в интернете, мессенджеры, видеохостинги и стриминговые сервисы работают шустро.
Тестируем
Переходим к тестированию устройства. Как мы с вами помним, в Wave 10 используется бюджетный 8-ядерный процессор Unisoc T615, состоящий из двух A75'ых и шести A55'ых ядер. Эти ядра появились ещё в 2017 году, и несмотря на возраст почти в 9 лет, они всё ещё используются в современных чипах - взять хотя-бы G99/G100/G200, где A55'ых целых 6 штук.
Например в Antutu 12 (не путать с 11), T615 смог выбить 474.314 попугая, в то время как T620, будучи разогнанным T615, выбивает уже 552.150 попугаев, а G99 целых 663.219 попугаев благодаря более современным A76'ым вместо A75'ых. Тем не менее, процессор уделывает G81 и G85, которые набирают чуть больше 300к попугаев в бенчмарке.
В GeekBench 7, T615 набирает 381 попугай в однопоточном режиме и 1496 в многопоточном. По сравнению с T620, T615 набрал на 100 очков меньше чем T620 из-за того, что клок A75'ых ядер снижен на 400МГц. В Geekbench T615 также расположился между G81, Dimensity 720 и G99, и по чистой производительности близок к Snapdragon 845 2018 года выпуска.
В PCMark Work 3.1, процессор набрал 9705 попугаев - аж на 1.000 очков больше чем T620. Но тут причины такого разброса не ясны :)
В целом как я уже и говорил, для повседневных задач смартфона хватит с головой. Но вот как насчет игр? В популярном шутере Standoff 2, T615 выдаёт стабильные 60 FPS на максимальных настройках графики в нативном разрешении. В целом оно и немудрено - в игре статический свет, в большинстве своем узкие и закрытые карты, где можно без проблем посчитать Occlusion Culling и хороший, оптимизированный рендер.
При этом несмотря на слабый процессор, Wave 10 вполне тянет и куда более тяжелый PUBG Mobile на минимальных настройках графики в 50-60 кадров. При быстрой езде иногда случаются микрофризы, однако они особо не мешают игре и поиграть на лоу-ранках можно без проблем.
Приятно порадовала COD: Mobile, которая также здесь работает отлично на низких настройках графики. Есть стабильные 60 FPS практически без микрофризов - так что даже в мейнстримные онлайн игры можно поиграть с комфортом.
Правда на совсем тяжелые тайтлы типа Genshin Impact можно не замахиваться. Кроме того, смартфон неплохо тянет эмуляторы игровых консолей вплоть до PSP включительно (кроме PS2). О ПК играх в Winlator'е можно забыть, однако даже тайтлы с PSP могут полностью закрыть потребность в сингплеерных мобильных играх.
Вот чем смартфон реально смог удивить, так это камерой. Я уже привык к тому, что в смартфонах до 20к, камера чаще всего очень посредственная и либо сильно мылит картинку, либо пытается вытянуть изображение нейронкой, что выглядит так себе, либо просто снимает на уровне Nokia 5800 несмотря на сенсор высокого разрешения. Хотя у Wave 10 тыловая камера всего на 32МП, она выдает очень приличные кадры при дневном освещении: видны как детали вблизи, так и вдали, при этом на умеренном расстоянии детали остаются четкими.
ISP у процессоров Unisoc достаточно простенький, поэтому в бюджетных смартфонах качество фотографий в основном вытягивает сам сенсор, а не драйвер камеры. В большинстве кейсов даже в авто-режиме можно получить приличное фото, а при базовой обработке (LUT, контраст) - фотографии, которые не стыдно выложить в инсту.
Однако у Unisoc'ов нет нормального денойзера, из-за чего мелкие объекты на значительном расстоянии превращаются в кашу. Лучше всего это можно увидеть на примере фото ниже:
В общем и целом - качество съёмки находится на очень приличном уровне и по сути для улучшения восприятия всех снимков при хорошем свете достаточно лишь приложение камеры с нормальным LUT'ом. Фронталка снимает неплохо, главным плюсом в ней считаю то, что смартфон не накидывает нейрохрючева для улучшения лица и таким образом не смазывает его черты.
Заключение
Вот такой интересный смартфон мне подогнали ребята из Blackview. В целом, это обычный ультрабюджетный сбалансированный смартфон: процессор хоть и не самый производительный, но его легко хватает для повседневного использования и легких игр. Памяти тоже не рекордно-много, но более чем достаточно для большинства кейсов. Камеры не супер крутые, но в обычных сценах проявляют себя как минимум неплохо. В общем, за свою цену хорошее устройство.
Плюсы:
Замечательная IPS-матрица с частотой обновления 120Гц.
Свежая версия Android, не перегруженная хламом оболочка DokeOS.
Отличная скорость работы в повседневных приложениях и легких играх.
Хорошая для своего ценового сегмента камера.
Аккумулятора хватает на полутора-двое суток умеренного использования.
Минусы:
Нет NFC. Пожалуй это самый главный минус, который нивелируется оплатой по QR лишь частично.
Нет быстрой зарядки. Тут уж кому как, я лично привык заряжать свой 20Ач Blackview Xplore 2 Projector за полтора часа :)
Слабоват процессор. Хотелось бы хотя-бы разогнанный T620, а лучше G99.
Задумывались ли вы когда-нибудь о том, как разработчики 3D-игр умудрялись выжимать красивую графику из слабого железа в 90-х годах? Вспомните NFS High Stakes, Quake 3, Unreal или Jurassic Park: Tresspaser — все они, несмотря на простоту технологий, выглядят сногсшибательно - в них были и зеркала, и отражения на металлических поверхностях, и продвинутый статический свет с рейтрейсингом, и даже четкие тени...
...но немногие знают, что на видеокартах уровня 3dfx Voodoo 2 это достигалось путём использования хитрых техник, хаков и особенностей видеокарт тех лет. В этой статьи мы с вами из первых уст рассмотрим такие техники на практике — ведь одним из моих хобби является написание 3D-демок и игр под ретро-железо.
Конечно начать рассказ стоит с железа, на котором работали 3D-игры в те годы. Среднестатистический компьютер в середине девяностых состоял из:
Процессора — Intel 386/486 на частоте 16-50МГц, и его аналогов от AMD/Cyrix в сборках попроще, а Pentium 66 и 133 можно было встретить в моделях побогаче.
Оперативной памяти — 4-8 мегабайт в бюджетных сборках и 16-32 в более богатых
Видеокарты — простой VGA-адаптер без ускорения 2D, или же 2D-ускоритель типа S3 Trio с поддержкой аппаратного блиттинга. 3D ускорять такие видеокарты не умели.
HDD — от ~100 до 500МБ на бюджетных сборках, и до ~1ГБ на некоторых дорогих.
О 3D-ускорении в домашних ПК тогда можно было только мечтать, однако многие разработчики всё равно делали полноценные, пусть и несложные по графике 3D-игры и демки — просто в них отрисовкой мира занимался процессор. Такой подход назывался Software rendering и стал возможен благодаря развитию FPU в x86-процессорах — диковинке, о которой большинству чипов на ARM/MIPS оставалось только мечтать (FPU не было даже в PlayStation 1).
У софтрендеров были как плюсы, так и минусы. Главным плюсом можно отметить то, что в отличии от ранних видеокарт, у них не было фиксированного конвейера и разработчик мог реализовать отрисовку именно так, как он хочет — иными словами, он мог встроить «шейдеры» прямо в функцию растеризации треугольника. Другим важным плюсом я считаю то, что рендер имел «бесплатный» прямой доступ к буферу кадра, что позволяло реализовывать разные пост-эффекты по типу LUT, блюра или капель дождя на стекле.
Пример реализации дождя в Дальнобойщиках. Хотя именно в Д1 могли реализовать не пост-эффектом, а полупрозрачной текстурой-маской, которая формируется процессором, или вообще через стенсильный буфер.
Но были и минусы, и самый важный — огромная нагрузка на процессор, которая росла обратно пропорционально разрешению игры. В 320x200 Pentium 66 ещё мог кое-как справиться с простой сценой без особого овердрава (как в Quake 1), но на 640x480 и 800x600 FPS падал в однозначные числа. Второй минус происходит из первого — отсутствие фильтрации и перспективной коррекции текстур во многих играх, из-за чего текстуры полов и стен под определенным углом начинают искажаться.
Что тако Overdraw?
Overdraw — процент отрисовки поверхностей, которые перекрывают уже отрисованный ранее фрагмент.
Простой пример — мы сидим в доме и смотрим в стену. Если игра нарисует сначала ландшафт за домом, затем забор, затем качели за забором, и только потом стену перед нашим носом — это уже Overdraw. Некоторые игры умудряются рисовать за кадр практически весь уровень и это сильно бьёт по филлрейту.
В Quake-подобных такого не было, поскольку там работал хитрый PVS-куллинг, который отсекал даже те стенки, которые сейчас находятся прямо за стенкой на которую мы смотрим.
Гигагерцовый Vortex86 уже не вывозил Quake 1 в 1280x1024 даже под DOS!
Первой 3D-видеокартой на ПК была STG2000 (также известная как Diamond Edge 3D), выпущенная в 1995 году на чипе NV1 — который по совместительству был первым видеочипом Nvidia. На практике, NV1 был целым мультимедийным комбайном: в одном чипе скрывался 3D-ускоритель, 2D-ускоритель, аудио и MIDI-контроллер, и даже контроллер геймпадов Sega Saturn. И всё бы хорошо, но видеочип от Nvidia оперировал не привычными треугольниками, а квадами с хитрым способом представления текстурных координат — портирование 3D-игр на «треугольных» софтрендерах было слишком сложным, требовало переделывание всей геометрии (а значит и переобучения 3D-моделеров), из-за чего большинство разработчиков решило не заморачиваться и NV1 провалился, чуть не обанкротив молодую Nvidia.
Всего через год, в 1996 году, появилась первая 3dfx Voodoo, которая перевернула мир 3D-игр на ПК с ног на голову. Это был первый полноценный 3D-ускоритель, который мог реально разгрузить процессор и рендерить игры в куда большем разрешении с приличным FPS — можно было замахнуться не только на 640x480, но и 800x600 при 16-битном цвете! Главным нюансом было то, что 3dfx Voodoo был именно ускорителем — то есть чисто технически, он умел только растеризовывать треугольники, интерполировать цвета и наносить на них текстуры, и накладывать туман: у него не было ни вершинного конвейера, ни клиппинга, ни освещения — всё это делал процессор. Но под Voodoo было легко программировать, у него был понятный API Glide, а ещё он стоил относительно приемлемых денег — что и сделало 3dfx Voodoo стандартом на рынке конца 90-х.
Однако во времена первой 3dfx Voodoo, игры были сильно ограничены в плане графики из-за конвейера. Дело в том, что Voodoo 1, как и ViRGE с ATi 3D Rage, умели наносить лишь одну текстуру за проход отрисовки — из-за чего для рендеринга уровней с освещением приходилось рисовать сцену два раза — первый проход с основной текстурой, второй с лайтмапой в режиме альфа-блендинга с смешиванием, а если были ещё и detail-текстуры — то добавлялся и третий проход! Учтите что GL/D3D были ещё глупыми, и на каждый такой проход приходилось снова и снова трансформировать и клипать геометрию что также било по процессору.
Решением стало появление текстурных комбайнеров в ~1997-1998 году, которые были прямым предком пиксельных шейдеров. В зависимости от числа текстурных юнитов, видеокарта могла смешивать сразу несколько текстур за один проход отрисовки, и делать не только умножение — но и сэмплинг по маске (полезно было для реализации ландшафтов, ранняя вариация Splatmapping'а), умножение итогового цвета в два раза (для реализации эффекта псевдоблума), DOT3-бампмаппинг, Environment mapped bump-mapping (помните демки из конца 90-х с красивой отражающейся водичкой? Вот это и есть EMBM) и ещё много разных интересных эффектов.
Помните красивую шейдерную водичку из Morrowind? Она была сделана по сэмплу из D3D8. Ничего сложного в этой водичке нет: отражение наносилось с помощью проекционной матрицы для текстурных координат, а бамп маппинг работал за счет комбайнеров.
В 1999 году появился первый GPU — GeForce 256, который имел поддержку T&L и переносил вершинный конвейер и хранение геометрии на видеокарту, а в 2001'ом — GeForce 3 с поддержкой полноценных вершинных и пиксельных шейдеров. С того момента всё и изменилось: игры стали ещё более крутыми, графонистыми, появились новые техники освещения помимо затенения по Фонгу, и так мы с вами дошли до PBR с GI в реалтайме в любом мейнстримном движке...
...но давайте же вспомним, как разработчики реализовывали свет на ограниченном железе в 90-х годах. Причём в некоторых играх освещение было достаточно сложным и реалистичным — взять как пример Quake и Half-Life, которые вероятно одними из первых адаптировали технику Radiosity-лайтмап в играх.
Radiosity — техника просчета глобального освещения с переотражениями и тенями за счет использования программного рейтрейсинга. QRAD бьёт всё сцену на так называемые патчи, считает для них влияние других патчей (в основном видимость и дистанцию) и симулирует аппроксимацию того, как свет проходил бы и отражался через них в реальном мире. То есть это именно физическая симуляция работы света, а не её красивая аппроксимация в виде шедоумап/Blinn-Phong в более современных играх с реалтайм освещением.
Главным нюансом Radiosity было то, что его невозможно было просчитывать в реальном времени до появления RTX-карт, поэтому освещение, рассчитанное этим алгоритмом, запекалось в специальные текстуры и затем наносилось на этапе рендеринга как второй слой.
Освещение в реальном времени реализовывалось схожим с современными играми способом, однако распределение света работало несколько по другому. В основе лежали всё те же алгоритмы затенения по Фонгу и ставший классикой N dot l, однако поскольку видеокарты в те годы не умели считать освещение сами и этим занимался процессор, программа (или OpenGL/D3D) рассчитывала свет для каждой вершины модели, а не пикселя, а полученный цвет от освещения записывался прямо в вершину.
В растеризации треугольников есть такое понятие, как барицентрические координаты — это интерполированные между тремя вершинами точки, которые описывают текущую «позицию» в системе координат треугольника и используются как для нанесения текстур и расчета попиксельного света, так и для интерполяции цвета. Как раз за счет интерполяции цвета между всеми тремя вершинами мы и получаем плавное освещение на каждом треугольнике, что в сумме даёт реалистичное освещение и блики, но только если у модели достаточная детализация. Такой подход называется затенением по Гуро.
Почему освещение в реальном времени использовали так мало?
Само по себе освещение в реальном времени не было прям таким уж тяжелым в те годы, но его использовали очень мало. Почему? Да потому что в графических API было строгое ограничение на число одновременных источников света для модели — всего 8 штук. Это нормально для модели персонажа, но мало для куска уровня, на который может влиять 10 источников света от фонарей/лампочек и т.д.
Решением проблемы стало появление Forward+ и Deferred-рендеринга, где свет считается в скринспейсе только для видимых пикселей. В мобильных играх повершинное освещение активно использовалось примерно до 2015 года.
Интересным способом реализовывали и фонарики, а также свет от ночных фонарей и других источников света, которые дают конусообразное освещение. Тут было две техники: либо использование честных Spotlight'ов (поддержка которых была как в D3D, так и в OpenGL), либо использование проективных текстур. Концепция проективных текстур очень простая: если умножить WorldSpace-позицию треугольника на комбинированную ViewProject-матрицу проектора (т.е позиции с которой светит фонарик), то мы получаем ClipSpace-координаты в пространстве проектора (верные и для треугольника) — и таким образом можем нанести на него текстуру так, будто на него текстуру проецирует проектор из реального мира.
Таким же способом реализовывали и так называемые проективные тени — ближайший предок шедоумап. Там суть заключалась в том, что в отдельную текстуру рендерится объект с позиции источника света, а затем на дорогу или пол проецируется текстура тени, создавая мягкие, красивые и дорогие по VRAM тени задолго до PCF-шедоумап! Такой подход использовался в Mafia 1, Half-Life 2 и Street Legal Racing: Redline.
Здесь можно увидеть четкие и относительно мягкие тени, пусть и с альясингом. Для 2003 года это отличный результат.
Ну и конечно проективные текстуры использовались для реализации простых blob-теней во многих аркадах нулевых и 2010-х годов.
Раз уж мы с вами заговорили о тенях, то нужно обязательно вспомнить о так называемых Shadow Volumes или стенсильных тенях. На рубеже 90-х и 2000-х, вопрос теней в реальном времени в играх стоял остро. Shadowmap уже, конечно, придумали, однако видеокарты всё ещё не умели сравнивать Z-координату в шедоумапах до появления специального расширения в OpenGL и D3D9. Более того, шедоумапы без фильтрации страдали от альясинга и очень сомнительного качества, пусть даже у них было полноценное самозатенение.
Пример Shadowmap из статьи на gamedev.ru. Кстати, сделаны только на FFP!
Shadow Volumes работали по другому принципу, нежели image-based техники и предлагали весьма интересный способ решения проблемы:
Сначала программа вытягивает силуэтные грани модели по направлению от источника света. Получившаяся модель называется теневым объёмом.
Затем рисуется теневой объем только с передними видимыми гранями, а в стенсил-буфер записывается значение 1.
Далее рисуется всё тот же теневой объем, но только с задними видимыми гранями, которые перезаписывают в стенсил-буфер значение 0 в местах не связанных с тенью.
После рисования всей сцены, рисуется серый полупрозрачный прямоугольник на весь экран с включенной проверкой по стенсилу. Если в стенсиле значение 0 — значит тени в этом пикселе нет, если 1 — значит есть, и таким образом мы получаем корректные, четкие и красивые тени без проблем, свойственных ShadowMap'ам.
Стенсильный буфер работает по тому же принципу, что и трафарет при рисовании на листе бумаги, только в 3D-графике. Он имеет такое же разрешение, как и сама игра, и каждый пиксель в нем является флагом «можно ли рисовать в этом месте или нет» для основного экрана (рендертаргета) игры.
Силуэт о которм мы говорили. Скриншот из статьи Семёна Козлова на gamedev.ru.
Стенсильные тени использовались во многих играх вплоть до ~2005 года. Самые известные — GTA San Andreas (там тени падали от фонарных столбов, пешеходов и машин) и F.E.A.R, однако поскольку просчет объёмов приходилось делать на процессоре для каждого источника света отдельно — техника устарела к появлению D3D10, и даже геометрические шейдеры, где их можно было считать почти бесплатно, волюмы не спасли.
Еще одна интересная техника тех лет — попытка симуляции атмосферного эффекта Godrays, или так называемые лучи Иакова: когда свет проходит сквозь узкие щели в пыльной и темной комнате, он выглядит как объемные лучи и многие разработчики делали красивый фейк этого эффекта за счет простейших вытянутых коробок с градиентной полупрозрачной текстурой. Эффектом пользуются еще с 90-х годов по сей день:
Не менее интересно были реализованы и отражения. Сейчас в сети часто можно встретить жалобы игроков на то, что в современных играх отражения слишком примитивные, особенно это касается гонок, где в зеркалах автомобиля можно увидеть только статическую Reflection prob'у, а в зеркалах зданий разве что замыленную копию мира, отрисованную в рендертаргет низкого разрешения. В пример игроки приводят игры из нулевых и даже девяностых, где отражения были честными!
В GTA в зеркало можно было стрелять из снайперки и даже самого себя пристрелить. Многие думают что за зеркалом прячется клон игрока в виде отдельного игрового объекта, однако на практике снайперка — единственное оружие в игре, где пуля реально является объектом, а не рейкастом и она просто попадала по хитбоксу игрока сразу в тот момент, как была выпущена.
Секрет таких отражений в использовании всё того же стенсил-буфера. Игра сначала рисует объект зеркала с записью маски «зеркальных» пикселей в стенсил, затем рисует мир еще раз задом-наперед относительно зеркала и с помощью стенсилбуфера обрезает все пиксели, что попадают за пределы зеркала. Да, да, эта техника буквально строится на концепции «зазеркалья» и использовалась даже в Duke Nukem 3D 1995 года!
Однако у техники есть куча минусов: например с ней зеркало может быть только прямой формы, никаких отражающихся чайников и кузовов автомобилей. Кроме того, она требует реализации адекватного отсечения по перекрытию, иначе в отражении еще раз может отрисоваться половина мира и уронить FPS (самый простой способ — поделить уровень на комнаты и рисовать только ту комнату, в которой находится игрок, в таком случае зеркала превращаются в частный случай порталов). Но многие игры использовали ее для воды до появления нормального рендера в текстуру в качестве альтернативы screenspace-отражений.
Для кузовов автомобилей и других не-плоских объектов применялась иная, довольно хитрая техника. До появления кубических карт текстур (из которых сэмплить можно в «3д» координатах, которые в свою очередь можно посчитать от угла взгляда на объект) активно применялась техника сферических карт отражений. Выглядели они как 360 фотографии:
Поскольку геометрию трансформировал процессор, на этапе перемножения вершин на MVP-матрицу он генерировал новые текстурные координаты, которые брали нормаль вершины в пространстве камеры, делили его на 2 и прибавляли 0.5, дабы перевести из View-space в Normalized-space. Получалось что координата идеально огибала сферу и делала красивые отражения. Бонусом эту же карту можно было использовать в качестве неба (которое анимировалось путем того, что сфера прсто крутилась вокруг своей оси) — и таким образом мы получали статический Reflection-probe.
На скриншоте из NFS Hot Pursuit 1 можно увидеть отражения не только на автомобилях, но и на дороге. Техника была по сути «бесплатной» на видеокартах с мультитекстурированием — как например на 3dfx Voodoo 2.
Кроме того, думаю многим читателям будет интересно узнать о том, как в те годы делали анимацию. Ни для кого не секрет, что в подавляющем большинстве современных игр для анимации используется скиннинг — то есть модель разбивается на иерархию (кости), где трансформация каждого элемента зависит от трансформации родительского элемента. Это очень удобно для гуманоидных персонажей, поскольку позволяет легко одевать персонажа в броню или положить ему в руки пушку, а также позволяет использовать одну анимацию на десятках разных персонажей.
Однако до появления скиннинга существовала еще одна очень похожая система, называемая Object Transform. Работает она по тому же принципу, но положение объектов зависит не от костей и их весов, а от позиции/поворота самих объектов. Иными словами, персонажи собирались просто из набора кусочков — руки, локти, торс, ноги, и всё анимировалось отдельно. Помните угловатых персонажей в GTA III и Quake 3? Вот это оно и есть :)
Обратите внимание на сочленения — видно что колени и бедра как бы впиваются в таз персонажа, поскольку это отдельные объекты. Модель Томми выглядит естественно благодаря использованию скиннинга. Скриншот с gtaforums.
Помимо Object Transform, в те годы также активно использовался морфинг. Это самая простая система анимации, которая «запекает» позиции вершин для каждого кадра отдельно, после чего вершины интерполируются движком для создания плавности. Несмотря на возможность реализации интересных эффектов по типу реакции на взрывы и лицевой анимации, она является самой неэффективной, поскольку занимает много памяти и не умеет ретаргетинг (применение одной анимации к нескольким моделям). Кроме того, с этой системой сложно положить пушку в руки персонажу, из-за чего во многих играх оружие было неотъемлемой частью персонажа.
В Quake можно было отключить интерполяцию и анимация монстров становилась дерганной и резкой. В современных играх этот способ тоже используется для объектов вдалеке - для экономии числа вычислений в вершинном шейдере.
Однако у этой системы есть неоспоримый плюс — нулевая нагрузка на процессор, благодаря чему ее использовали в Quake 1 и 2, и иногда используют для некоторых особых случаев в современных играх.
❯ Заключение
Вот такими техниками пользовались разработчики игр в 90-х годах. Многие из них используются и по сей день — например лайтмаппинг, шедоумапы, морфинг и PVS никуда не делись, и все эти техники за последние 20 лет сильно прокачались. А вам интересно было узнать о том, как работали графические фишки в играх прошлых лет? Стоит ли писать подобный материал для 2D-игр (там выйдет поменьше, но тоже есть о чем рассказать)? Пишите свое мнение в комментариях!
К слову можно считать эту статью предисловием к будущему материалу о разработке 3D-игры для ретро-компьютеров с нуля, без каких либо движков! В качестве тестовых машин, мне было бы интересно пощупать что‑то ещё из семейства Nvidia ION/Radeon Xpress Graphics/VIA Chrome9 HC/Trident Blade. Если у кого‑то есть всякие интересные тонкие клиенты или ноутбуки на прикольном железе, или что‑то AMD'шное времен 939/462 — пишите в ЛС, обязательно сделаю контент!
Олды блога могут вспомнить мою демку про самолетики. Возможно скоро будет статья про куда более крутую игру для ретро компьютеров и возможно даже PSP и PS2!
Ну а я надеюсь, что вам было интересно. Подписывайтесь на блог, чтобы не пропускать новые статьи каждую неделю! А если вам интересна тематика ремонта, моддинга и программирования для гаджетов прошлых лет — подписывайтесь на мой Telegram‑канал «Клуб фанатов балдежа„, куда я выкладываю бэкстейджи статей, ссылки на новые статьи и видео, а также иногда выкладываю полезные посты. А ролики (не всегда дублирующие статьи) можно найти на моём YouTube канале.“»
А если вы хотите что‑нибудь подарить из железа и увидеть о нём статью — пишите мне в Telegram, Max или ВК. Меня очень интересуют самые разные гаджеты: начиная от игровых консолей и любых связанных с геймингом устройств, телефонов, смартфонов, КПК, заканчивая ретро‑компьютерами и ноутбуками. Кто знает, может героем следующей подобной статьи окажется ноутбук из 90-х?:‑)
После обзоров устройства не продаются, а остаются в моей коллекции. Когда‑нибудь я хочу сделать музей, где к каждому устройству можно будет приложить QR и почитать мою статью. Кто знает, вдруг на следующей неделе я также подробно расскажу про девайс из вашей юности?:)
Фото Nokia 9300 с сайта mobile‑review.com
Кстати, у меня есть GameBoy Advance SP, под который я очень хочу написать игру. Однако мой экземпляр был залит водой и кофе. Может у кого‑то есть донор с дохлой платой, откуда я смог бы взять контроллер питания? У меня AGS-101.