monobogdan

monobogdan

Топовый автор
На Пикабу
Дата рождения: 25 сентября 2001
5002m Nux76 user5001670
user5001670 и еще 53 донатера
поставил 14 плюсов и 1 минус
отредактировал 2 поста
проголосовал за 2 редактирования
в топе авторов на 619 месте

Собираем на будущие ништяки

Именно Вы, читатели, помогаете с подготовкой новых статей - все деньги отправляются на покупку девайсов для будущих статей и оборудования! Спасибо всем, кто помогает - и морально, и материально!

800 1 200
из 2 000 собрано осталось собрать
Награды:
За участие в Авторской неделеболее 1000 подписчиков Высокий разум
46К рейтинг 1925 подписчиков 0 подписок 216 постов 166 в горячем
TECHNO BROTHER

Друзья! Может кто-то продаёт HPC по адекватной цене для будущего контента?

Друзья! Может кто-то продаёт HPC по адекватной цене для будущего контента? Опрос, Покупка, Гаджеты, Компьютер, Windows, Windows Mobile, Розыск, Поиск, Девайс, Помощь, Длиннопост

О КПК на MIPS-чипсетах из конца 90х я вам уже рассказывал, о программировании под КПК середины нулевых с GPU - тоже, самое время рассмотреть такой крутой класс устройств, как HPC. Однако на юлито они сейчас стоят конских денег: может кто-то продаёт за адекватную цену любой HPC тех лет на мобильной винде (не путайте с органайзером, органайзеры на Windows CE не работают)? Подойдет и HP Jornada, и Compaq, и Ericsson. Можно монохромный, но очень желательно цветной. Можно и нерабочие/полурабочие под ремонт, только не с выпотрошенными ROM/RAM (актуально для Compaq, где ОС и ОЗУ в слотах).

Друзья! Может кто-то продаёт HPC по адекватной цене для будущего контента? Опрос, Покупка, Гаджеты, Компьютер, Windows, Windows Mobile, Розыск, Поиск, Девайс, Помощь, Длиннопост
Друзья! Может кто-то продаёт HPC по адекватной цене для будущего контента? Опрос, Покупка, Гаджеты, Компьютер, Windows, Windows Mobile, Розыск, Поиск, Девайс, Помощь, Длиннопост
Видели такие хоть раз?)
Всего голосов:
Показать полностью 3 1

Друзья! В моей семье ремонтом и моддингом занимаюсь не только я :)

Но и моя мать. Правда она ремонтирует не смартфоны и девайсы, а реставрирует кукол и моделирует различные аксессуары с последующей печатью на 3D-принтере и ручным оформлением моделей (в основном, обшивкой). Поддержите её первый пост, помогите вывести пост начинающего контентмейкера в горячее, если не трудно :) Спасибо!

Винтажная кукла из мусорного ведра получает вторую жизнь. Часть-1

Встретился с читателем в Ейске. Поболтали душевно, еще и подгончик подарил! Спасибо :)

Встретился с читателем в Ейске. Поболтали душевно, еще и подгончик подарил! Спасибо :)
TECHNO BROTHER

Друзья, разыскиваются китайские смартфоны-подделки в любом состоянии для будущих статей!

Друзья, разыскиваются китайские смартфоны-подделки в любом состоянии для будущих статей! Опрос, Поиск, Розыск, Гаджеты, Блог, Телефон, Смартфон, Девайс, Донат, Android, Покупка, Длиннопост

И снова ежемесячный пост! Как многие пикабушники уже вероятно знают, я пишу статьи и теперь ещё и снимаю видео об оживлении, моддинге и программировании под различные старые девайсы! Но некоторые девайсы, как, например, дешевые китайские подделки порой найти проблематично: большинство оказалось на свалке, а на онлайн-барахолках их не найти из-за запрета на контрафакт. Для будущего материала, я ищу китайские подделки из начала 2010х: в основном китайские копеечные игровые консоли, Android-реплики айфонов, айпадов, макбуков, Samsung Galaxy, Nokia Lumia/HTC/Sony Xperia и другие подделки на популярные бренды. Можно невключайки/нерабочие/зависающие, почти любое состояние - все постараюсь оживить и поднять. Что с ними происходит потом? Смотрите сами: Альтернативное Apple'водство: Как и зачем я променял оригинальный айфон на китайский нерабочий 14 Pro Max, На помойку? Никак нет! Пишем нативные приложения для китайских кнопочников, Сам себе Linux-смартфон: Выкидываем Android из старого Fly и пилим свою оболочку, Сам себе экосистема, портируем свежий Android на NoName-смартфон, на грани отвала eMMC: переносим Android на MicroSD, накатываем чистый Android на китайский iPhone 5s, бомж-гейминг за копейки с отвальной консолью. Так что не сомневайтесь, девайсы попадают в хорошие руки :) Все стараюсь поднять, оживить и написать про них материал! Есть что-то подобное? Пишите в комменты или в тг @monobogdan. Спасибо!

Друзья, разыскиваются китайские смартфоны-подделки в любом состоянии для будущих статей! Опрос, Поиск, Розыск, Гаджеты, Блог, Телефон, Смартфон, Девайс, Донат, Android, Покупка, Длиннопост
Друзья, разыскиваются китайские смартфоны-подделки в любом состоянии для будущих статей! Опрос, Поиск, Розыск, Гаджеты, Блог, Телефон, Смартфон, Девайс, Донат, Android, Покупка, Длиннопост
Друзья, разыскиваются китайские смартфоны-подделки в любом состоянии для будущих статей! Опрос, Поиск, Розыск, Гаджеты, Блог, Телефон, Смартфон, Девайс, Донат, Android, Покупка, Длиннопост
"Где-ж ты был пару дней назад"
Всего голосов:
Показать полностью 3 1
TECHNO BROTHER

Купил себе девкит

Похвастаюсь перед читателями на Пикабу: недавно купил себе девкит (отладочная плата, плата для разработки) Snapdragon 410 от Veriscite. На подобных девкитах, разработчики смартфонов и планшетов разрабатывают и отлаживают софт, пилят драйвера и разрабатывают аппаратную часть будущего устройства! Найти бы еще девкит на что-то 2009-2010 года, омап какой нить или типа того...

Купил себе девкит Опрос, Покупка, Хвастовство, Радость, Своими руками, Программирование, Гаджеты, Snapdragon, Qualcomm, Моддинг, Длиннопост
Купил себе девкит Опрос, Покупка, Хвастовство, Радость, Своими руками, Программирование, Гаджеты, Snapdragon, Qualcomm, Моддинг, Длиннопост

А также из интереса взял себе девборду на S3C6410. Они на юлито совсем недорого сейчас стоят, а в комплекте (если не утерян) есть диски с BSP, документацией, Platform Builder и т.п. Интересно будет поколупать!

Купил себе девкит Опрос, Покупка, Хвастовство, Радость, Своими руками, Программирование, Гаджеты, Snapdragon, Qualcomm, Моддинг, Длиннопост
Круто?
Всего голосов:
Показать полностью 3 1
TECHNO BROTHER

Самый первый Android-смартфон в мире: каким был HTC Dream? Пишем приложения для Android 1.0 в 2024

Самый первый Android-смартфон в мире: каким был HTC Dream? Пишем приложения для Android 1.0 в 2024 Опрос, Покупка, Android, Смартфон, Гаджеты, Китай, Htc, Разработка, Программирование, Java, Ретроспектива, Диковинки, Ништяки, Моддинг, Видео, Без звука, Длиннопост

Друзья! А знаете ли вы, какой Android-смартфон был первым в мире и как он выглядел? А я теперь не просто знаю, но и могу физически пощупать настоящую легенду своих лет — HTC Dream, также известный как T-Mobile G1. Однако G1 был мне интересен не только как коллекционный девайс для гика, но и потенциально-диковинное устройство для разработки приложений: ведь в современном мире принято повышать минимальную версию Android для работы тех или иных программ, а я свои буду… понижать, чтобы они смогли заработать даже на самой первой версии Android! В сегодняшней статье мы с вами: посмотрим на Dream и постараемся понять, почему HTC выбрала именно Android, неудачно перепакуем аккумулятор, бэкпортируем мои клиенты ВК, YouTube и Telegram и посмотрим, правда ли старичок «бесполезен», как говорят в ретро-обзорах или что-то ещё да может! Интересно? Тогда добро пожаловать под кат!

❯ Введение


Как я уже говорил в вводной части статьи, HTC Dream стал первым массовым Android-смартфоном в мире. Конечно, до этого момента в Google были гораздо более ранние прототипы, которые использовались при разработке устройства и что интересно — они тоже были разработаны HTC. Однако тот прототип был совершенно не похож даже на G1: это был QWERTY-моноблок с дисплеем 320x240, где всё управление происходило кнопками, а в качестве основы устройства скорее всего был выбран HTC Cavalier:

Самый первый Android-смартфон в мире: каким был HTC Dream? Пишем приложения для Android 1.0 в 2024 Опрос, Покупка, Android, Смартфон, Гаджеты, Китай, Htc, Разработка, Программирование, Java, Ретроспектива, Диковинки, Ништяки, Моддинг, Видео, Без звука, Длиннопост


И вот, 22 октября 2008 года в свет выходит HTC Dream у американского оператора T-Mobile, который гики сразу смели с виртуальных и физических магазинных полок. Стоит ли говорить о том, что смартфон имел огромный спрос не только на локальном рынке в США, но и за рубежом? Серым импортом даже в СНГ ввозилось довольно немало HTC Dream: правда сейчас их живых осталось не так уж и много :( Кстати, забавно но факт: первые серийные G1 не имели такой открытости и возможности модификации системы, которой гордятся владельцы Android-смартфонов в спорах с владельцами iPhone: даже adb был доступен только на специальной версии G1 — Android Dev Phone 1!

Но почему HTC выбрала именно Android? Чтобы ответить на этот вопрос, нужно вернуться в 2008 год, когда на рынке главенствовала Nokia со своим свежим флагманом 5800 XpressMusic. В те годы, выбор операционных систем для смартфонов был крайне невелик: по сути, производителям были доступны только две системы.

  • Первой была Windows Mobile, которая была хороша во всем: у неё была неплохая архитектура под капотом, настоящая многозадачность и работала она сносно даже на очень слабом железе. Но поскольку это Microsoft, куда же без косяков: система была нестабильной и могла повиснуть в самый неудачный момент (думаю, многие читатели помнят такие сокращения как ХР и ББ), её интерфейс не был анимированным (и не «модным») от слова совсем, а сама система была адаптирована лишь под стилус. Но тем не менее, мобильная винда продержалась на рынке смартфонов до 2010 года, как раз к моменту выхода Windows Phone 7… но это уже совсем другая история.

Самый первый Android-смартфон в мире: каким был HTC Dream? Пишем приложения для Android 1.0 в 2024 Опрос, Покупка, Android, Смартфон, Гаджеты, Китай, Htc, Разработка, Программирование, Java, Ретроспектива, Диковинки, Ништяки, Моддинг, Видео, Без звука, Длиннопост
  • Второй системой была, конечно же, Symbian, которая на первый взгляд была хорошей: довольно удобный и привычный для многих интерфейс, очень хорошая оптимизация для слабых устройств и большая база самых разных приложений. Но её недостатки были гораздо более серьёзные, чем у мобильной винды: система лицензировалась не абы кому, а только участникам Symbian Foundation и её архитектура под капотом была просто отвратительной. Если кто-то из вас когда-то занимался разработкой нативных приложений под Symbian — вы наверняка вспомните эту боль.

Самый первый Android-смартфон в мире: каким был HTC Dream? Пишем приложения для Android 1.0 в 2024 Опрос, Покупка, Android, Смартфон, Гаджеты, Китай, Htc, Разработка, Программирование, Java, Ретроспектива, Диковинки, Ништяки, Моддинг, Видео, Без звука, Длиннопост

И вот, в 2008 году на сцену выходит новичок на мобильном рынке — поисковой гигант Google со своей мобильной операционной системой Android, которая предлагала обширный функционал, нормальную среду для разработчиков и полноценный магазин приложений и делала это всё почти бесплатно: исходный код системы был опубликован под свободной лицензией и любой производитель мог использовать Android на своём устройстве полностью бесплатно, доплачивая лишь за необходимость установки Google-сервисов.

Самый первый Android-смартфон в мире: каким был HTC Dream? Пишем приложения для Android 1.0 в 2024 Опрос, Покупка, Android, Смартфон, Гаджеты, Китай, Htc, Разработка, Программирование, Java, Ретроспектива, Диковинки, Ништяки, Моддинг, Видео, Без звука, Длиннопост

Учитывая, что внутренние прототипы Google разрабатывала тоже HTC, немудрено почему именно Тайваньская компания выпустила первый Android-смартфон в мире. Увидев успех HTC Dream, крупные гиганты также потянулись на рынок Android-смартфонов: Samsung представила I7500 Galaxy, давший старт одноименной линейке, Motorola представила CLIQ, а затем и легендарный Milestone, а LG — весьма интересную модель под названием GW620. Уже в 2009 году, HTC представила Magic, который Google раздавала на конференции Google I/O в Сан-Франциско всем участникам конференции и один из таких тоже оказался в моей коллекции!

Самый первый Android-смартфон в мире: каким был HTC Dream? Пишем приложения для Android 1.0 в 2024 Опрос, Покупка, Android, Смартфон, Гаджеты, Китай, Htc, Разработка, Программирование, Java, Ретроспектива, Диковинки, Ништяки, Моддинг, Видео, Без звука, Длиннопост

Свой HTC Dream я получил совсем недавно из Китая. Я давно хотел обзавестись «дримкой» и недавно мне написал читатель Роман, предложив помощь в поиске интересующих меня девайсов на китайских аналогах авито. При этом Роман брал на себя все заморочки с организацией доставки из Китая в Москву, а из Москвы уже в мой город — Ейск, за что ему огромное спасибо. HTC Dream обошёлся мне в 2.200 рублей, а Moto Milestone — около 500 и оба устройства полностью рабочие!

Но перед тем как мы сможем перейти к фактическому обзору, нашу дримку нужно обслужить: у неё вспух аккумулятор, который уже никуда не годится, поэтому остаётся лишь его перепаковать. Перепаковка аккумулятора — это процесс замены литиевой банки на другую с сохранением оригинального контроллера и при возможности корпуса АКБ. И в моём случае произошёл определенный фейл…

❯ Перепаковываем аккумулятор


Сначала аккумулятор необходимо разобрать. Для многих этот процесс может показаться опасным, но я уверяю авс — если не тыкать в аккумулятор отвертками и не замыкать ничего в цепи BMS-контроллера и самого аккумулятора, всё будет нормально. В моём случае, разбирается он просто — отклеиваем бумажки, формирующие корпус и аккуратно вытаскиваем банку с контроллером из пластиковой основы.

Самый первый Android-смартфон в мире: каким был HTC Dream? Пишем приложения для Android 1.0 в 2024 Опрос, Покупка, Android, Смартфон, Гаджеты, Китай, Htc, Разработка, Программирование, Java, Ретроспектива, Диковинки, Ништяки, Моддинг, Видео, Без звука, Длиннопост

Затем выпаиваем плату защиты, известную также как BMS (Battery Management System) и идём искать подходящую банку. Можно установить как Б/У с другого телефона, так и новую, подходящую по размерам. Новой банки таких габаритов у меня не было, поэтому я решил воткнуть туда от АКБ для телефона LG.

Самый первый Android-смартфон в мире: каким был HTC Dream? Пишем приложения для Android 1.0 в 2024 Опрос, Покупка, Android, Смартфон, Гаджеты, Китай, Htc, Разработка, Программирование, Java, Ретроспектива, Диковинки, Ништяки, Моддинг, Видео, Без звука, Длиннопост

Но произошёл определенный нюанс: параллельно со статьей я готовил и видео, подробно снимая весь процесс перепаковки. В момент пайки отвлекся на видоискатель, перевернул бмску ввеврх-ногами и… переполюсовал аккум до входа в BMS. Результат: со смартфоном всё хорошо (на входе VBat в телефонах всегда стоит защита от переполюсовки и КЗ. Кроме того, КП способен выдержать до ~5.5В на VBat, но не более), а в контроллере BMS-дырка :(

Сначала я думал вырезать эту часть статьи, но потом решил, что авторы — тоже люди и у них тоже бывают определенные фейлы :) Но гештальт не закрыт и я обязательно выпущу ещё более подробный гайд о перепаковке аккумуляторов. В дримку можно установить BL-4C от Нокии, однако заряжаться он будет только до загрузки ядра, поэтому зарядки у нас по факту пока что нет. Ну ничего, думаю ещё найдется аккумулятор!

Самый первый Android-смартфон в мире: каким был HTC Dream? Пишем приложения для Android 1.0 в 2024 Опрос, Покупка, Android, Смартфон, Гаджеты, Китай, Htc, Разработка, Программирование, Java, Ретроспектива, Диковинки, Ништяки, Моддинг, Видео, Без звука, Длиннопост

❯ Бэкпортируем приложения


Друзья! После статей и видео о разработке самопальных приложений, мне часто пишут в личку с вопросами можно ли портировать приложения современных сервисов на смартфоны прошлых лет. И здесь ответ неутешителен: нет, без исходного кода, в том числе и нативных зависимостей ничего портировтаь так просто не выйдет. Мои приложения изначально писались так, чтобы не зависеть вообще ни от чего кроме голого API Android (ни AppCompat, ни каких либо иных зависимостей) и при этом по возможности не используются даже фичи Android из 2.x. Именно поэтому мне свои приложения портировать гораздо проще.

Современная студия уже не умеет собирать приложения для 2.1 и ниже: примерно в 2.2 немного поменялся бинарный формат XML, из-за чего десериализатор в более старых версиях Android валится с ошибкой. Однако приложения, собранные в Android Studio образца 2017 прекрасно работают и на Motorola Milestone!

Самый первый Android-смартфон в мире: каким был HTC Dream? Пишем приложения для Android 1.0 в 2024 Опрос, Покупка, Android, Смартфон, Гаджеты, Китай, Htc, Разработка, Программирование, Java, Ретроспектива, Диковинки, Ништяки, Моддинг, Видео, Без звука, Длиннопост

Поэтому всё, что нам остаётся — это лишь импортировать код приложений в более старую студию (в моём случае 2.3.2), поставить minSDK на 1 (Android 1.0) и собрать приложение… А ведь даже отладчик работает! Конечно есть определенные нюансы: например, в Android 1.0 нет атрибута onClick, дабы быстро повесить обработчик кнопки в Design-time и другие мелкие «приколы» той версии Android.

Самый первый Android-смартфон в мире: каким был HTC Dream? Пишем приложения для Android 1.0 в 2024 Опрос, Покупка, Android, Смартфон, Гаджеты, Китай, Htc, Разработка, Программирование, Java, Ретроспектива, Диковинки, Ништяки, Моддинг, Видео, Без звука, Длиннопост

Приложения бэкпортированы, а значит можно попробовать, каков же экспиренс от использования первого Android-смартфона в 2024 году!

Самый первый Android-смартфон в мире: каким был HTC Dream? Пишем приложения для Android 1.0 в 2024 Опрос, Покупка, Android, Смартфон, Гаджеты, Китай, Htc, Разработка, Программирование, Java, Ретроспектива, Диковинки, Ништяки, Моддинг, Видео, Без звука, Длиннопост

❯ Обзор


Конструктивно смартфон очень интересный. Несмотря на то, что корпус отюндь не выполнен из премиальных материалов, смартфон лежит в руке классно, но самое приятное ощущение — это открыть клавиатуру путём сдвига QWERTY-слайдера…

Самый первый Android-смартфон в мире: каким был HTC Dream? Пишем приложения для Android 1.0 в 2024 Опрос, Покупка, Android, Смартфон, Гаджеты, Китай, Htc, Разработка, Программирование, Java, Ретроспектива, Диковинки, Ништяки, Моддинг, Видео, Без звука, Длиннопост
Самый первый Android-смартфон в мире: каким был HTC Dream? Пишем приложения для Android 1.0 в 2024 Опрос, Покупка, Android, Смартфон, Гаджеты, Китай, Htc, Разработка, Программирование, Java, Ретроспектива, Диковинки, Ништяки, Моддинг, Видео, Без звука, Длиннопост

Механизм работает идеально даже спустя 16 лет после выхода устройства! Нижняя панель кнопок отличается наличием трекболла: специального колёсика, выполняющего роль DPad'а (стрелок). Трекболл долгое время был фишкой HTC, да и в целом действительно довольно удобным решением в определенных ситуациях, учитывая что первые ёмкостные тачскрины не были надёжными от слова совсем.

Самый первый Android-смартфон в мире: каким был HTC Dream? Пишем приложения для Android 1.0 в 2024 Опрос, Покупка, Android, Смартфон, Гаджеты, Китай, Htc, Разработка, Программирование, Java, Ретроспектива, Диковинки, Ништяки, Моддинг, Видео, Без звука, Длиннопост

Изначально производительность смартфона меня не устроила и я решил скинуть его до заводских настроек. Но я не учёл один факт: в то время, Google почему-то пыталась косить под Apple и позволяла активировать смартфон только при наличии активного тарифного плана с пакетом интернета и симкой T-Mobile! Поэтому пришлось быстренько откатываться до прошивки RC29 (Android 1.0) и обходить активацию с помощью adb. Инженеры HTC оставили рутовую (!) консоль, которая работает из всей системы, когда мы просто пишем что-то на аппаратной клавиатуре! Попробуйте написать Enter -> reboot -> Enter на своей дримке!

Самый первый Android-смартфон в мире: каким был HTC Dream? Пишем приложения для Android 1.0 в 2024 Опрос, Покупка, Android, Смартфон, Гаджеты, Китай, Htc, Разработка, Программирование, Java, Ретроспектива, Диковинки, Ништяки, Моддинг, Видео, Без звука, Длиннопост

После включения, нас сразу встречает оригинальный гугловский лаунчер, который может быть знаком читателям, которые пользовались первыми Android-смартфонами. Менюшка здесь открывается путём свайпа нижней шторки вверх… но поскольку в те годы, всё 2D в Android рисовалось софтварно, то плавность была далека от айфона. Но всё равно вполне шустренько.

Самый первый Android-смартфон в мире: каким был HTC Dream? Пишем приложения для Android 1.0 в 2024 Опрос, Покупка, Android, Смартфон, Гаджеты, Китай, Htc, Разработка, Программирование, Java, Ретроспектива, Диковинки, Ништяки, Моддинг, Видео, Без звука, Длиннопост

Среди стандартных приложений был почти весь джентльменский набор: и полноценный браузер, и почтовый клиент, и удобный плеер. А недостающие приложения типа клиента твиттера или аськи допиливали сторонние разработчики, так что спустя годик-два после выхода, «дримкой» всё ещё вполне можно было пользоваться.

Самый первый Android-смартфон в мире: каким был HTC Dream? Пишем приложения для Android 1.0 в 2024 Опрос, Покупка, Android, Смартфон, Гаджеты, Китай, Htc, Разработка, Программирование, Java, Ретроспектива, Диковинки, Ништяки, Моддинг, Видео, Без звука, Длиннопост

Начинаем с браузера. В качестве браузерного движка, Google решили выбрать в своё время WebKit, который исопльзовался в дроиде вплоть до 5.0, когда WebView и его фактическую реализацию разделили, попутно заменив WebKit на Chromium. Сейчас эта версия, увы, уже почти ничего не может: ни Хабр почитать, ни Пикабу… конечно сторонние клиенты могли бы решить эту проблему, но оба сайта не хотят предоставлять никакого публичного апи…
Браузер до 2.1 даже верхней шторки не имел и переходить по URL приходилось нажимая кнопку контекстного меню и только затем Go:

Самый первый Android-смартфон в мире: каким был HTC Dream? Пишем приложения для Android 1.0 в 2024 Опрос, Покупка, Android, Смартфон, Гаджеты, Китай, Htc, Разработка, Программирование, Java, Ретроспектива, Диковинки, Ништяки, Моддинг, Видео, Без звука, Длиннопост

До сих пор на устройстве работает мой любимый клиент почты — тот, который встроенный. Если ставить галки «SSL If Required», что позволяет игнорировать ошибки SSL, то он работает замечательно. Клавиатура у Dream замечательно подходит для переписок — отдельный ряд с цифрами и общее расположение кнопок этому очень и очень способствуют!

Самый первый Android-смартфон в мире: каким был HTC Dream? Пишем приложения для Android 1.0 в 2024 Опрос, Покупка, Android, Смартфон, Гаджеты, Китай, Htc, Разработка, Программирование, Java, Ретроспектива, Диковинки, Ништяки, Моддинг, Видео, Без звука, Длиннопост

Работают даже карты, позволяя сделать из смартфона с GPS в эдакий навигатор без навигации. Но карты работают очень шустро, даже поиск есть, а если вдруг Google Maps со временем отвалится, то я и вьювер OSM запилю :)

Самый первый Android-смартфон в мире: каким был HTC Dream? Пишем приложения для Android 1.0 в 2024 Опрос, Покупка, Android, Смартфон, Гаджеты, Китай, Htc, Разработка, Программирование, Java, Ретроспектива, Диковинки, Ништяки, Моддинг, Видео, Без звука, Длиннопост

Давайте же перейдем нашим приложениям! Начинаем с моего клиента YouTube, который здесь работает, но из-за значительно более «белой» светлой темы в 1.x, надписи не видно от слова совсем.

Самый первый Android-смартфон в мире: каким был HTC Dream? Пишем приложения для Android 1.0 в 2024 Опрос, Покупка, Android, Смартфон, Гаджеты, Китай, Htc, Разработка, Программирование, Java, Ретроспектива, Диковинки, Ништяки, Моддинг, Видео, Без звука, Длиннопост

Клиент ВК здесь работает без каких либо проблем, но на «не свежей» системе заметно подлагивает. В целом, производительность всё равно далека даже от iPhone 3G в те же годы:

Самый первый Android-смартфон в мире: каким был HTC Dream? Пишем приложения для Android 1.0 в 2024 Опрос, Покупка, Android, Смартфон, Гаджеты, Китай, Htc, Разработка, Программирование, Java, Ретроспектива, Диковинки, Ништяки, Моддинг, Видео, Без звука, Длиннопост

А как насчёт Telegram? Смогу ли я написать пост в свой Telegram-канал с него, учитывая такую крутую и классную QWERTY-клавиатуру?

Самый первый Android-смартфон в мире: каким был HTC Dream? Пишем приложения для Android 1.0 в 2024 Опрос, Покупка, Android, Смартфон, Гаджеты, Китай, Htc, Разработка, Программирование, Java, Ретроспектива, Диковинки, Ништяки, Моддинг, Видео, Без звука, Длиннопост

❯ Заключение


Вот такой материал про первый Android-смартфон в мире у нас получился. Как видим, не совсем уж он и бесполезен и при определенном желании всё ещё может послужить хорошую службу своему хозяину. Берегите свои дримки :)

Также у меня естьTelegram-канал, куда я выкладываю мысли касательно ремонта и программирования под гаджеты прошлых лет.
А когда у вас появился первый Android-смартфон? Пишите в комментариях!

На какой версии системы был ваш первый Android-смартфон?
Всего голосов:


Кстати, если у кого-то из читателей есть ненужные устройства (в том числе с косяками) или дешевые китайские подделки на айфоны/айпады/макбуки и другие брендовые девайсы будучи нерабочими, тормозящими, или окирпиченными и вам не хотелось бы выкидывать их на свалку, а наоборот, отдать их в хорошие руки и увидеть про них статью — пишите мне в Telegram или в комментах! Готов в том числе и купить их. Особенно ищу донора дисплея на китайскую реплику iPhone 11: мой ударник, контроллер дисплея калится и изображения нет :(

Статья подготовлена при поддержке TimeWeb Cloud. Подписывайтесь на меня и @Timeweb.Cloud, чтобы не пропускать новые статьи каждую неделю!

Показать полностью 24 1 1
TECHNO BROTHER

Выпустил экранизацию статьи о том, как я написал тридэ игру для компьютерлв 90х с нуля

TECHNO BROTHER

Сам написал, сам полетал: как и зачем я разработал 3D-игру с нуля под компьютеры из 90-х в 2024 году?1

Сам написал, сам полетал: как и зачем я разработал 3D-игру с нуля под компьютеры из 90-х в 2024 году? Опрос, Горячее, Ништяки, Программирование, Net, 3D графика, Игры, Леталки, Пилот, Самолет, Fw-190, Directx, Gamedev, Видео, Без звука, Длиннопост

Осторожно: Несмотря на кажущуюся сложность статьи о разработке целой 3D-игры с нуля, я постарался систематизировать и упростить материал так, чтобы понятно было любому заинтересованному читателю, даже если вы далеки от программирования в целом!

Статьи о разработке инди-игр — это всегда интересно. Но разработка чего-то абсолютно с нуля, без каких-либо движков или фреймворков — ещё интереснее! Почти всю свою жизнь, буквально с 13-14 лет меня тянет пилить какие-нибудь прикольные 3D-демки и игрушки. Ещё на первом курсе ПТУ я написал небольшую демку с 3D-вертолетиками по сети и идея запилить какие-нибудь прикольные леталки не покидала меня по сей день! Спустя 6 лет, в 22 года я собрался с силами и решил написать небольшую аркадную демку про баталии на самолетиках, да так, чтобы работало аж на видеокартах из 90-х — NVidia Riva 128 и 3DFX Voodoo 3! Интересно, как происходит процесс разработки игры с нуля — от первого «тридэ» треугольника, до работающей на реальном железе демки? Тогда добро пожаловать под кат!

❯ Мотивация


Друзья! Вижу, что вам очень заходит моя постоянная рубрика о том, как работали графические ускорители из 90-х «под капотом», где мы не только разбираем их архитектуру, но и пишем демки на их собственных графических API. Мы уже успели с вами рассмотреть 3Dfx Voodoo, S3 ViRGE и мобильный PowerVR MBX и, думаю, теперь пришло время рассмотреть инструменты для разработчиков игр под Windows из 90-х. Про «старый» OpenGL рассказывать смысла не вижу — до сих пор многие новички учатся по материалам с glBegin/glEnd и FFP (Fixed Function Pipeline), а спецификацию с описанием первой версии API можно найти прямо на сайте Khronos. Зато про «старый» DirectX информации в сети очень мало и большинство документации уже потёрли даже из MSDN, хотя в нём было много чего интересного!

Сам написал, сам полетал: как и зачем я разработал 3D-игру с нуля под компьютеры из 90-х в 2024 году? Опрос, Горячее, Ништяки, Программирование, Net, 3D графика, Игры, Леталки, Пилот, Самолет, Fw-190, Directx, Gamedev, Видео, Без звука, Длиннопост

Вероятно читатель спросит — зачем пилить что-то для компьютеров 90-х годов, если большинство таких машин (к сожалению) отправились на цветмет и «никто в своем уме» не будет ими пользоваться? Ну, ретро-компьютинг и программирование демок — это, во-первых, всегда интересно. Среди моих подписчиков довольно много ребят, которые ещё учатся в школе, а уже натаскали с барахолок Pentium III или Pentium IV и GeForce 4 MX440 и сидят, балдеют и играют в замечательные игрушки из нулевых на таких машинах с по настоящему трушным опытом, да и я сам таким был и остаюсь по сей день. Вон, мне даже dlinyj скидывал свои девайсы в личку, а я сидел и слюни пускал. Так что факт остаётся фактом — ретро-компьютинг становится всё более и более популярен — что не может не радовать!

Сам написал, сам полетал: как и зачем я разработал 3D-игру с нуля под компьютеры из 90-х в 2024 году? Опрос, Горячее, Ништяки, Программирование, Net, 3D графика, Игры, Леталки, Пилот, Самолет, Fw-190, Directx, Gamedev, Видео, Без звука, Длиннопост

А во-вторых — это челлендж для самого себя! Посмотреть на то, как делали игры «деды» и попытаться запилить что-то самому, не забыв об этом написать статью и снять интересное видео в попытке донести это как можно большему числу читателей и зрителей! Конечно сам DirectX6 в целом значительно проще DX12, но некоторые техники весьма заковыристые и для достижения оптимальной производительности приходится пользоваться хаками. Ну а почему именно леталки? Потому что, наверное, хотел бы когда-нибудь полетать :)

Сам написал, сам полетал: как и зачем я разработал 3D-игру с нуля под компьютеры из 90-х в 2024 году? Опрос, Горячее, Ништяки, Программирование, Net, 3D графика, Игры, Леталки, Пилот, Самолет, Fw-190, Directx, Gamedev, Видео, Без звука, Длиннопост

Игру я решил писать на C#. Кому-то решение может показаться странным, но я уже не раз говорил, что это мой любимый язык, а при определенной сноровке — программы на нем работают даже под Windows 98. В качестве основного API для игры я выбрал DirectX 6, который вышел 7 августа 1998 года — за 3 года до моего рождения :)

Перед тем как что-то начинать делать, нужно определиться с тем, что нам нужно для нашей 3D-игры:

  • Графический движок или рендерер, работающий на базе Direct3D. В его задачи входит отрисовка геометрии, работа с освещением и материалами, отсечение моделей, находящихся вне поле зрения глаз, генерация ландшафтов из карт высот и т. п. Собственно, в нашем конкретном случае это графическим движком назвать сложно — никакого полноценного графа (иерархической структуры, как в Unity) сцены нет, толковой анимации тоже, зато есть довольно продвинутая система материалов :)

  • Звуковой движок на базе DirectSound. Здесь всё по классике: программный 3D-звук с эффектами типа «виу» и «вжух» с загрузкой звуковых дорожек из wav-файлов. Никакого стриминга звука с кольцевыми буферами и ogg/mp3 здесь не нужно!

  • Подсистема ввода, которая представляет из себя «получить состояние кнопки на клавиатуре» и «получить позицию курсора» :)

  • Остальные модули — сюда входят алгоритмы расчёта коллизий, математическая библиотека для работы с векторами и матрицами, система игровых объектов и загрузчики ресурсов. Это весьма небольшие и легкие в реализации подсистемы, но писать про каждый отдельный пункт смысла не очень много, поскольку они так или иначе часть других систем.




Как известно, в самолёте всё зависит от винта! Ну, или в нашем случае, от 3D-движка — поэтому предлагаю рассмотреть архитектуру нашего рендерера и заложить первые кирпичики в нашу 3D-игру!

❯ Графический движок


Поскольку C# — управляемый язык и напрямую дёргать COM-интерфейсы формально не может, а готовых обёрток для DirectX 6 по понятным причинам нет, мне пришлось писать свою. Простыми словами, обёртка обеспечивает слой совместимости между нативными библиотеками, написанными на C++ и управляемым кодом, написанном на C#/VB и т.п. Благо в мире .NET есть такое замечательное, но увы, забытое расширение плюсов, как С++/CLI, которое позволяет прозрачно смешивать нативный код и «байткод» .NET, благодаря которому разработка пошла значительно быстрее.

Сам написал, сам полетал: как и зачем я разработал 3D-игру с нуля под компьютеры из 90-х в 2024 году? Опрос, Горячее, Ништяки, Программирование, Net, 3D графика, Игры, Леталки, Пилот, Самолет, Fw-190, Directx, Gamedev, Видео, Без звука, Длиннопост

Любой графический движок начинается с создания окна и инициализации контекста графического API (инициализации видеокарты, если простыми словами) для рисования в это самое окно. В случае Direct3D6 всё интереснее тем, что фактически здесь уже был свой аналог современного DXGI (DirectX Graphics Infrastructure — библиотека для управления видеокартами, мониторами в системе), который назывался DirectDraw. Изначально DDraw использовался для аппаратного ускорения графики на VGA 2D-акселеллераторах — тех самых S3 ViRGE и Oak Technology и предназначался в основном для операций блиттинга (копирования картинки в картинку), но в D3D ему выделили функции управления видеопамятью и поэтому они очень тесно связаны.

Инициализация начинается с создания так называемой первичной поверхности (которая будет отображаться на экран) и заднего буфера (в который будет рисоваться само изображение), или в терминологии современных API — Swap-chain.

DDSURFACEDESC rtDesc;
memset(&rtDesc, 0, sizeof(rtDesc));
rtDesc.dwSize = sizeof(rtDesc);
rtDesc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
rtDesc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
rtDesc.dwWidth = Width;
rtDesc.dwHeight = Height;
Guard(ddraw->CreateSurface(&rtDesc, &sSurf, 0));
Guard(sSurf->QueryInterface(IID_IDirectDrawSurface4, (LPVOID*)&sSurf4));

Теперь у нас есть окно, куда можно что-нибудь нарисовать!

Сам написал, сам полетал: как и зачем я разработал 3D-игру с нуля под компьютеры из 90-х в 2024 году? Опрос, Горячее, Ништяки, Программирование, Net, 3D графика, Игры, Леталки, Пилот, Самолет, Fw-190, Directx, Gamedev, Видео, Без звука, Длиннопост

Но 3D мы пока рисовать не можем — ведь контекста D3D у нас всё ещё нет, благо создаётся он очень просто. Единственный момент: Z-буфер нужно создать перед созданием устройства, иначе работать он не будет.

DDSURFACEDESC zbufDesc;
memset(&zbufDesc, 0, sizeof(zbufDesc));
zbufDesc.dwSize = sizeof(zbufDesc);
zbufDesc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
zbufDesc.ddsCaps.dwCaps = DDSCAPS_ZBUFFER | DDSCAPS_VIDEOMEMORY;
memcpy(&zbufDesc.ddpfPixelFormat, Window::zBufferFormat, sizeof(zbufDesc.ddpfPixelFormat));
zbufDesc.dwWidth = Width;
zbufDesc.dwHeight = Height;

IDirectDrawSurface* zTemp;
IDirectDrawSurface4* zSurface;
Guard(ddraw->CreateSurface(&zbufDesc, &zTemp, 0));
Guard(zTemp->QueryInterface(IID_IDirectDrawSurface4, (LPVOID*)&zSurface));

// Attach Z-Buffer to backbuffer
Guard(d3dSurface->AddAttachedSurface(zSurface));
Guard(d3d->CreateDevice(IID_IDirect3DHALDevice, surf, &device, 0));

Мы уже на полпути перед тем как нарисовать первый тридэ-треугольник: осталось лишь объявить структуру вершины и написать обёртки над… Begin/End! Да, в Direct3D когда-то тоже была концепция из OpenGL, а связана она с тем, что в видеокартах тех лет вершины передавались не буферами, а по одному, уже трансформированные. Подробнее об этом можно почитать в моей статье о S3 ViRGE:

public value struct Vertex
{
public:
float X, Y, Z;
float NX, NY, NZ;
D3DCOLOR Diffuse;
float U, V;
};

...

Vertex[] v = new Vertex[3];
v[0] = new Vertex()
{
X = 0,
Y = 0,
Z = 0,
U = 0,
V = 0
};
v[1] = new Vertex()
{
X = 1,
Y = 0,
Z = 0,
U = 1,
V = 0
};
v[2] = new Vertex()
{
X = 1,
Y = 1,
Z = 0,
U = 1,
V = 1
};

dev.BeginScene();
dev.Begin(PrimitiveType.TriangleList, Device.VertexFormat);
dev.Vertex(v[0]);
dev.Vertex(v[1]);
dev.Vertex(v[2]);
dev.End();
dev.EndScene();

И вот, у нас есть первый треугольник! Читатель может спросить — а где же здесь игра и причём здесь треугольники, мы же не на уроке геометрии… Дело в том, что вся 3D-графика в современных играх строится из треугольников. Любая моделька на экране — это набор из маленьких примитивов, которые в процессе рисования на экран подвергаются процессу трансформации — преобразованию из мировых координат (то есть абсолютной позиции в мире) сначала в координаты камеры (таким образом, при движении камеры, на самом деле двигаются объекты вокруг камеры), а затем и в экранные координаты, где происходит перспективное деление и каждый треугольник начинает выглядеть как трёхмерный…

Таким образом, из тысяч треугольников можно описать самые разные объекты — от трёхмерной модели моих любимых «жигулей», до персонажей.

Сам написал, сам полетал: как и зачем я разработал 3D-игру с нуля под компьютеры из 90-х в 2024 году? Опрос, Горячее, Ништяки, Программирование, Net, 3D графика, Игры, Леталки, Пилот, Самолет, Fw-190, Directx, Gamedev, Видео, Без звука, Длиннопост

Но если сейчас нарисовать самолетик, то он будет исключительно белым, без намёка на освещение или детали. А для его «раскрашивания» служат текстуры — специальные изображения, подогнанные под текстурные координаты геометрии, которые помогают дополнить образ 3D-моделей деталями: асфальт на дороге, трава на земле, дверная карты в жигулях…

Сам написал, сам полетал: как и зачем я разработал 3D-игру с нуля под компьютеры из 90-х в 2024 году? Опрос, Горячее, Ништяки, Программирование, Net, 3D графика, Игры, Леталки, Пилот, Самолет, Fw-190, Directx, Gamedev, Видео, Без звука, Длиннопост

И вот с текстурами ситуация в D3D6 не менее интересная и очень похожа на современные GAPI: нам необходимо сначала создать текстуру в системной памяти (ОЗУ) и только затем скопировать её в видеопамять. Причём форматов текстур не слишком много. Я выбрал RGB565 (16-битный), хотя есть поддержка и форматов со сжатием — тот-же S3TC.

bool hasMips = mipCount > 1; // If texture has more than 1 mipmap, then create surface as complex, if not - then as single-level.

DDSURFACEDESC2 desc;
memset(&desc, 0, sizeof(desc));
desc.dwSize = sizeof(desc);
desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_TEXTURESTAGE | DDSD_CKSRCBLT;
desc.ddsCaps.dwCaps = DDSCAPS_TEXTURE | (hasMips ? (DDSCAPS_MIPMAP | DDSCAPS_COMPLEX) : 0);
desc.ddsCaps.dwCaps2 = DDSCAPS2_TEXTUREMANAGE;
desc.ddckCKSrcBlt.dwColorSpaceHighValue = 0;
desc.ddckCKSrcBlt.dwColorSpaceLowValue = 0;
memcpy(&desc.ddpfPixelFormat, DXSharp::Helpers::Window::opaqueTextureFormat, sizeof(desc.ddpfPixelFormat));
desc.dwWidth = Width = width;
desc.dwHeight = Height = height;

IDirectDrawSurface4* surf;
IDirect3DTexture2* tex;

IDirectDraw4* dd2;
window->ddraw->QueryInterface(IID_IDirectDraw4, (LPVOID*)&dd2);

Guard(dd2->CreateSurface(&desc, &surf, 0));
Guard(surf->QueryInterface(IID_IDirect3DTexture2, (LPVOID*)&tex));

А чтобы её использовать, нужно «сказать» об этом видеокарте с помощью биндинга текстуры к текстурному юниту. Те, у кого были в свое время 3dfx Voodoo, наверняка поймут, о чём я :)

Guard(device->SetTexture(stage, tex->texture));

И вот у нас уже есть треугольник с текстурой! Осталось лишь домножить его матрицы трансформации, перспективную матрицу…

Сам написал, сам полетал: как и зачем я разработал 3D-игру с нуля под компьютеры из 90-х в 2024 году? Опрос, Горячее, Ништяки, Программирование, Net, 3D графика, Игры, Леталки, Пилот, Самолет, Fw-190, Directx, Gamedev, Видео, Без звука, Длиннопост

Реализуем простенький загрузчик моделей из формата SMD (GoldSrc, Half-Life или CS1.6), который грузит статичные модельки без скиннинга, а также загрузчик текстур из bmp и вот — мы уже имеем 3D-модельку самолёта с текстурой.

for(int i = 0; i < smd.Triangles.Count; i++)
{
uint c = new Color(255, 255, 255, 255).GetRGBA();

for (int j = 0; j < 3; j++)
vert[i * 3 + j] = new Vertex()
{
X = smd.Triangles[i].Verts[j].Position.X,
Y = smd.Triangles[i].Verts[j].Position.Y,
Z = smd.Triangles[i].Verts[j].Position.Z,
U = smd.Triangles[i].Verts[j].UV.X,
V = smd.Triangles[i].Verts[j].UV.Y,
NX = smd.Triangles[i].Verts[j].Normal.X,
NY = smd.Triangles[i].Verts[j].Normal.Y,
NZ = smd.Triangles[i].Verts[j].Normal.Z,
Diffuse = c
};
}

Сам написал, сам полетал: как и зачем я разработал 3D-игру с нуля под компьютеры из 90-х в 2024 году? Опрос, Горячее, Ништяки, Программирование, Net, 3D графика, Игры, Леталки, Пилот, Самолет, Fw-190, Directx, Gamedev, Видео, Без звука, Длиннопост

Возможно в каких-то играх и не нужно небо, но в леталках — уж точно необходимо. И без учёта динамических облаков, здесь есть две популярные техники:

Возможно в каких-то играх и не нужно небо, но в леталках — уж точно необходимо. И без учёта динамических облаков, здесь есть две популярные техники:

  • Sky-sphere, которая заключается в том, что небо представляет из себя полусферу с наложенной поверх текстурой неба в специальном формате. Такую полусферу очень часто крутят вокруг своей оси по оси Y, создавая эффект плывущих облаков. И получается вполне себе симпатичное анимированное небо. Иные варианты включают в себя многослойные реализации, где крутится могут лишь облака, когда статичные элементы фона остаются на месте.

  • Skybox — здесь суть простая, вокруг камеры рисуется «коробка» с вывернутыми в обратную сторону треугольниками, на которых рисуется текстура одной из сторон панорамы с выключенной записью в Z-буфер. Получается не только симпатично, но ещё и быстрее Skysphere на слабом железе, правда скайбоксы обычно статичным. Скайбоксы можно найти почти везде: например, в Counter-Strike, Half-Life.

    На скриншоте ниже можно увидеть пример скайбокса:

Сам написал, сам полетал: как и зачем я разработал 3D-игру с нуля под компьютеры из 90-х в 2024 году? Опрос, Горячее, Ништяки, Программирование, Net, 3D графика, Игры, Леталки, Пилот, Самолет, Fw-190, Directx, Gamedev, Видео, Без звука, Длиннопост



Я выбрал скайбоксы. Реализация — проще пареной репы:

materials[0].Texture = TextureLoader.LoadFromImage(string.Format("{0}{1}_bk.bmp", Path, name));
materials[1].Texture = TextureLoader.LoadFromImage(string.Format("{0}{1}_ft.bmp", Path, name));
materials[2].Texture = TextureLoader.LoadFromImage(string.Format("{0}{1}_lf.bmp", Path, name));
materials[3].Texture = TextureLoader.LoadFromImage(string.Format("{0}{1}_rt.bmp", Path, name));
materials[4].Texture = TextureLoader.LoadFromImage(string.Format("{0}{1}_up.bmp", Path, name));
materials[5].Texture = TextureLoader.LoadFromImage(string.Format("{0}{1}_dn.bmp", Path, name));

....

Engine.Current.Graphics.DrawMesh(mesh, 0, 6, v, new Vector3(0, 0, 0), new Vector3(1, 1, 1), materials[1]); // Forward
Engine.Current.Graphics.DrawMesh(mesh, 6, 12, v, new Vector3(0, 0, 0), new Vector3(1, 1, 1), materials[3]); // Right
Engine.Current.Graphics.DrawMesh(mesh, 12, 18, v, new Vector3(0, 0, 0), new Vector3(1, 1, 1), materials[0]); // Back
Engine.Current.Graphics.DrawMesh(mesh, 18, 24, v, new Vector3(0, 0, 0), new Vector3(1, 1, 1), materials[2]); // Left
Engine.Current.Graphics.DrawMesh(mesh, 24, 30, v, new Vector3(0, 0, 0), new Vector3(1, 1, 1), materials[4]); // Left

Сам написал, сам полетал: как и зачем я разработал 3D-игру с нуля под компьютеры из 90-х в 2024 году? Опрос, Горячее, Ништяки, Программирование, Net, 3D графика, Игры, Леталки, Пилот, Самолет, Fw-190, Directx, Gamedev, Видео, Без звука, Длиннопост

Но летать в пустом мире неинтересно и для этого нам нужен хотя бы ландшафт, который называется Terrain. Концепция Terrain простая — у нас есть карта высот, каждый пиксель который описывает высоту той или иной точки.

Мы проходимся по всей картинке и строим сетку треугольников, где высота определяется именно соседними пикселями на этой самой карте высот. На практике это выглядит так:

for (int i = 1; i < bmp.Width - 1; i++)
{
for(int j = 1; j < bmp.Height - 1; j++)
{
float baseX = (float)i * XZScale;
float baseZ = (float)j * XZScale;

// Transform vertices
verts[vertOffset] = new DXSharp.D3D.Vertex()
{
X = baseX,
Y = ((float)bmp.GetPixel(i, j).R / 255.0f) * YScale,
Z = baseZ,
U = 0,
V = 1 * TextureScale,
NY = 1
};
verts[vertOffset + 2] = new DXSharp.D3D.Vertex()
{
X = baseX,
Y = ((float)bmp.GetPixel(i, j + 1).R / 255.0f) * YScale,
Z = baseZ + XZScale,
U = 0,
V = 0,
NY = 1
};
verts[vertOffset + 1] = new DXSharp.D3D.Vertex()
{
X = baseX + XZScale,
Y = ((float)bmp.GetPixel(i + 1, j + 1).R / 255.0f) * YScale,
Z = baseZ + XZScale,
U = 1 * TextureScale,
V = 0,
NY = 1
};
verts[vertOffset + 3] = new DXSharp.D3D.Vertex()
{
X = baseX,
Y = ((float)bmp.GetPixel(i, j).R / 255.0f) * YScale,
Z = baseZ,
U = 0,
V = 1 * TextureScale,
NY = 1
};
verts[vertOffset + 4] = new DXSharp.D3D.Vertex()
{
X = baseX + XZScale,
Y = ((float)bmp.GetPixel(i + 1, j).R / 255.0f) * YScale,
Z = baseZ,
U = 1 * TextureScale,
V = 1 * TextureScale,
NY = 1
};
verts[vertOffset + 5] = new DXSharp.D3D.Vertex()
{
X = baseX + XZScale,
Y = ((float)bmp.GetPixel(i + 1, j + 1).R / 255.0f) * YScale,
Z = baseZ + XZScale,
U = 1 * TextureScale,
V = 0,
NY = 1
};

vertOffset += 6;
}
}

А результат — такой! Это самый простой кейс с Terrain'ом: в реальных играх, где ландшафт достаточно большой, его обычно бьют на так называемые патчи и дальние участки ландшафта упрощают с помощью специальных алгоритмов. Таким образом построены ландшафтры, например, в TES Skyrim.

Сам написал, сам полетал: как и зачем я разработал 3D-игру с нуля под компьютеры из 90-х в 2024 году? Опрос, Горячее, Ништяки, Программирование, Net, 3D графика, Игры, Леталки, Пилот, Самолет, Fw-190, Directx, Gamedev, Видео, Без звука, Длиннопост

Но ландшафт выглядит слишком скучно — ни травы, ни деревьев, ни даже разных текстур! Одна трава — да что ж это за ландшафтр такой :) И здесь нам на помощь приходят т. н. комбайнеры — которые дают возможность наносить сразу несколько текстур за один проход отрисовки геометрии. Конкретно в данном случае я решил использовал альфа-канал в цвете вершины в качестве значения, определяющего какой текстурой красить тот или иной участок ландшафта. Визуализировать это можно так (где прозрачные участки — там должна быть вторая текстура):

Сам написал, сам полетал: как и зачем я разработал 3D-игру с нуля под компьютеры из 90-х в 2024 году? Опрос, Горячее, Ништяки, Программирование, Net, 3D графика, Игры, Леталки, Пилот, Самолет, Fw-190, Directx, Gamedev, Видео, Без звука, Длиннопост

Этот способ даёт возможность использовать всего лишь две текстуры за один проход, в современных играх используется сплат-маппинг, позволяющий использовать более 4х-текстур за один проход!

Context.SetTextureStageState(1, (int)TextureStageState.AlphaOp, (int)TextureStageOp.Modulate);
Context.SetTextureStageState(1, (int)TextureStageState.AlphaArg1, (int)TextureArgument.Texture);
Context.SetTextureStageState(1, (int)TextureStageState.AlphaArg2, (int)TextureArgument.Texture);

Context.SetTextureStageState(0, (int)TextureStageState.ColorOp, (int)TextureStageOp.SelectArg1);
Context.SetTextureStageState(0, (int)TextureStageState.ColorArg1, (int)TextureArgument.Texture);
Context.SetTextureStageState(0, (int)TextureStageState.ColorArg2, (int)TextureArgument.Texture);

Context.SetTextureStageState(1, (int)TextureStageState.ColorOp, (int)TextureStageOp.BlendDiffuseAlpha);
Context.SetTextureStageState(1, (int)TextureStageState.ColorArg1, (int)TextureArgument.Texture);
Context.SetTextureStageState(1, (int)TextureStageState.ColorArg2, (int)TextureArgument.Current);

Сам написал, сам полетал: как и зачем я разработал 3D-игру с нуля под компьютеры из 90-х в 2024 году? Опрос, Горячее, Ништяки, Программирование, Net, 3D графика, Игры, Леталки, Пилот, Самолет, Fw-190, Directx, Gamedev, Видео, Без звука, Длиннопост

Но тем не менее, выглядит вполне прикольно. Однако текстуры вдали выглядят слишком грубо и отдают пикселями. Ретро-стайл скажете вы? Согласен, но фильтрация и мипмаппинг здесь необходимы! Мип-маппинг — это техника, которая делит большую текстуру на несколько небольших разного размера. Каждый размер называется mip-уровнем и в два раза меньше прошлого: таким образом, у текстуры 256x256 9 уровней: 256x256, 128x128, 64x64 и так до 1x1. Мой самопальный конвертер текстур в собственный формат заранее «запекает» все мип-уровни, дабы быстро грузить текстуры с медленных HDD, а линейная фильтрация с мипмаппингом позволяет сгладить текстуры вдали, дабы они не резали глаза:

device->SetTextureStageState(0, D3DTSS_MIPFILTER, D3DTFP_LINEAR);
device->SetTextureStageState(0, D3DTSS_MINFILTER, D3DFILTER_LINEAR);
device->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DFILTER_LINEAR);

device->SetTextureStageState(1, D3DTSS_MIPFILTER, D3DTFP_LINEAR);
device->SetTextureStageState(1, D3DTSS_MINFILTER, D3DFILTER_LINEAR);
device->SetTextureStageState(1, D3DTSS_MAGFILTER, D3DFILTER_LINEAR);

Ну и давайте же посадим немного деревьев на наш ландшафт! Для этого я добавил псевдослучайное добавление деревьев и кустов при генерации геометрии ландшафта:

if (rand.Next(0, 32) % 8 == 0)
foliageBatches.Add(new FoliagePlacement()
{
Mesh = foliage[rand.Next(0, foliage.Length)],
Position = new Vector3(baseX, ((float)bmp.GetPixel(i, j).R / 255.0f) * YScale, baseZ)
});

Сам написал, сам полетал: как и зачем я разработал 3D-игру с нуля под компьютеры из 90-х в 2024 году? Опрос, Горячее, Ништяки, Программирование, Net, 3D графика, Игры, Леталки, Пилот, Самолет, Fw-190, Directx, Gamedev, Видео, Без звука, Длиннопост

Упс, наши деревья — черные! А всё потому, что у них нет альфа-канала, благодаря которому видеокарта может отделить прозрачные пиксели текстуры от непрозрачных. Полноценный альфа-блендинг (полупрозрачность) здесь слишком дорогой, поэтому приходится использовать технику, называемую колоркеями (Color key). Техника очень схожая с Chromakey, благодаря которым вырезают фон из видео, но чуть попроще (тем, что цвет прозрачности фиксированный, без Threshold). У нас есть определенный цвет, который считается прозрачным и не используется во всей картинке. Нередко это Magenta, в моём случае — полностью чёрный:

Сам написал, сам полетал: как и зачем я разработал 3D-игру с нуля под компьютеры из 90-х в 2024 году? Опрос, Горячее, Ништяки, Программирование, Net, 3D графика, Игры, Леталки, Пилот, Самолет, Fw-190, Directx, Gamedev, Видео, Без звука, Длиннопост

Включаем колоркей и наслаждаемся прозрачными деревьями на фоне ландшафта!

Сам написал, сам полетал: как и зачем я разработал 3D-игру с нуля под компьютеры из 90-х в 2024 году? Опрос, Горячее, Ништяки, Программирование, Net, 3D графика, Игры, Леталки, Пилот, Самолет, Fw-190, Directx, Gamedev, Видео, Без звука, Длиннопост

Ой-ой, а FPS то успел просесть с 1.000 до 50 из-за большого количества DIP'ов (и не очень хорошей работе современных GPU с старыми гапи). Время оптимизаций! Пока что нам хватит обычного Frustum culling'а, также известного как «отсечение по пирамиде видимости». Суть алгоритма простая: из матрицы вида и проекции строятся 6 плоскостей, каждая из которых описывает одну из сторон системы координат: левая, правая, верхняя, нижняя, ближняя и дальняя. Таким образом, делая обычную проверку нахождения точки в World-space и одной из плоскостей, мы можем отсечь невидимую глазам геометрию и не тратить ресурсы GPU и CPU на отрисовку невидимой геометрии:

public void Calculate(Matrix viewProj)
{
float[] items = viewProj.Items;
Planes[0] = new Vector4(items[3] - items[0], items[7] - items[4], items[11] - items[8], items[15] - items[12]);
Planes[0].Normalize();
Planes[1] = new Vector4(items[3] + items[0], items[7] + items[4], items[11] + items[8], items[15] + items[12]);
Planes[1].Normalize();
Planes[2] = new Vector4(items[3] + items[1], items[7] + items[5], items[11] + items[9], items[15] + items[13]);
Planes[2].Normalize();
Planes[3] = new Vector4(items[3] - items[1], items[7] - items[5], items[11] - items[9], items[15] - items[13]);
Planes[3].Normalize();

Planes[4] = new Vector4(items[3] - items[2], items[7] - items[6], items[11] - items[10], items[15] - items[14]);
Planes[4].Normalize();
Planes[5] = new Vector4(items[3] + items[2], items[7] + items[6], items[11] + items[10], items[15] + items[14]);
Planes[5].Normalize();
}

// Allocation-less
public bool IsPointInFrustum(float x, float y, float z)
{
foreach(Vector4 v in Planes)
{
if (v.X * x + v.Y * y + v.Z * z + v.W <= 0)
return false;
}

return true;
}

public bool IsSphereInFrustum(float x, float y, float z, float radius)
{
foreach (Vector4 v in Planes)
{
if (v.X * x + v.Y * y + v.Z * z + v.W <= -radius)
return false;
}

return true;
}

Затем проверяем, находится ли сфера внутри каждой из 6 плоскостей и если нет, то не рисуем геометрию вообще:

if (mesh.Radius > 0 && !Camera.IsSphereVisible(position, mesh.Radius))
return;

С учётом всех оптимизацией, получаем 17-20 кадров на этом GPU что можно считать… весьма неплохим результатом, учитывая что всё ещё есть куда оптимизировать!

❯ Звук


Эта часть статьи будет без иллюстраций, поскольку звук нужно слушать :) Но тем не менее, детали реализации звуковой подсистемы в DirectX весьма интересны и значительно отличаются от современного подхода.


Инициализация контекста DSound начинается с создания primary-буфера, который выступает в роли микшера перед отправкой звука на аудио-карту. Создаётся он довольно легко:

BufferDescription desc = new BufferDescription();
desc.Flags = BufferFlags.PrimaryBuffer | BufferFlags.Control3D;

primaryBuffer = Context.CreateSoundBuffer(desc);

После этого, в самом простом случае (без стриминга звука) нам достаточно лишь выгрузить PCM-поток на аудио-карту и начать его играть:

public WaveBuffer(WaveFormat fmt, byte[] pcmData)
{
BufferDescription desc = new BufferDescription();
desc.BufferBytes = (uint)pcmData.Length;
desc.Flags = BufferFlags.ControlDefault |BufferFlags.Software;
desc.Format = fmt;

buffer = Engine.Current.Sound.Context.CreateSoundBuffer(desc);
IntPtr data = buffer.Lock();
Marshal.Copy(pcmData, 0, data, pcmData.Length);
buffer.Unlock();

buffer.Play();
}

И всё! Да, вот так легко. BufferFlags.Software заменяется на Hardware, если необходимо аппаратное ускорение.

❯ Ввод


Пожалуй, это самая простая часть нашей статьи :) Как я уже говорил ранее, никакого особого функционала от модуля обработки ввода не нужно, лишь получать состояние кнопок — и с этим справляется лишь один метод…

[DllImport("user32.dll")]
static extern short GetAsyncKeyState(Keys vKey);

public static bool GetKeyState(Keys key)
{
return (GetAsyncKeyState(key) & 0x8000) != 0;
}


Ну что ж, основа готова, давайте перейдем к реализации самого геймплея!

❯ Пилим геймплей


Сначала нам нужно реализовать логику полёта нашего самолётика. В целом, в нашем конкретном кейсе всё просто — для поворотов используем углы Эйлера (лень было писать класс для кватерниона), считаем Forward-вектор (вектор, указывающий на направление прямо) и просто крутим повороты по оси X и Y в нужную сторону, прибавляя к позиции самолетика Forward вектор, умноженный на скорость полёта. Правда, с таким подходом есть некоторые проблемы: выполнить петлю не получится, поскольку Forward-вектор всегда смотрит именно прямо и не учитывает обратную направленность по оси X.

Rotation.X += -v * (YawSpeed * Engine.Current.DeltaTime);
Rotation.Y += h * (YawSpeed * Engine.Current.DeltaTime);

Rotation.Z = MathUtils.Lerp(Rotation.Z, 35 * -h, 4.0f * Engine.Current.DeltaTime);

Vector3 fw = GetForward();
Position.X += fw.X * (Speed * Engine.Current.DeltaTime);
Position.Y += fw.Y * (Speed * Engine.Current.DeltaTime);
Position.Z += fw.Z * (Speed * Engine.Current.DeltaTime);

Мы с вами хотим, чтобы камера всегда следила за нашим самолётиком. Для этого нужно взять Forward-вектор объекта и умножить каждую его компоненту на дальность от источника камеры. Эдакая бомж-версия lookat, правда с кучей ограничений, как минимум с Gimbal lock (потерей одной из осей поворота), а чтобы камера казалась плавной и придавала динамичности игре — мы делаем EaseIn/EaseOut эффект путём неправильного использования формулы линейной интерполяции :)

Vector3 forward = GetForward();
// Adjust camera
Engine.Current.Graphics.Camera.Position = new Vector3(Position.X + (forward.X * -12.0f),
Position.Y + (forward.Y * -12.0f) + 4.0f, Position.Z + (forward.Z * -12.0f));
Engine.Current.Graphics.Camera.Rotation.Y = MathUtils.Lerp(Engine.Current.Graphics.Camera.Rotation.Y, Rotation.Y + (yaw * 30), 3.0f * Engine.Current.DeltaTime);
Engine.Current.Graphics.Camera.Rotation.X = MathUtils.Lerp(Engine.Current.Graphics.Camera.Rotation.X, Rotation.X + (pitch * 5), 3.0f * Engine.Current.DeltaTime);
Engine.Current.Graphics.Camera.MarkUpdated();

Сам написал, сам полетал: как и зачем я разработал 3D-игру с нуля под компьютеры из 90-х в 2024 году? Опрос, Горячее, Ништяки, Программирование, Net, 3D графика, Игры, Леталки, Пилот, Самолет, Fw-190, Directx, Gamedev, Видео, Без звука, Длиннопост

Ну, летать мы с вами уже можем… да, сильно по аркадному, но всё же :) Пришло время реализовать каких-нибудь соперников, а именно вражеские самолёты! Вообще, реализация нормального ИИ на самолетах, тем более в симуляторах — задачка очень нетривиальная, поскольку боты будут либо читерить, используя не те рычаги, что использует игрок, либо тупить и играть будет не сильно интересно. Вон, что «Варгейминг», что «Гайдзины» крутые в этом плане — я б ниасилил нормальных ботов для мультиплеерного симулятора или даже аркады :))

Вычисляем угол между позицией самолетика соперника и позицией игрока и интерполируем текущий угол по оси Y: получается вполне плавно, правда в нормальных играх ещё и компенсируют эффект «плаванья» вокруг игрока по синусоиде. Для подъёма и спуска по вертикали просто берём абсолютную величину выше/ниже:

float angle = (float)Math.Atan2(Game.Current.Player.Position.X - Position.X, Game.Current.Player.Position.Z - Position.Z);
float vert = MathUtils.Clamp(Position.Y - Game.Current.Player.Position.Y, -1, 1);
Rotation.X = MathUtils.Lerp(Rotation.X, vert * 35, 1.5f * Engine.Current.DeltaTime);

float prevY = Rotation.Y;
Rotation.Y = MathUtils.Lerp(Rotation.Y, angle * MathUtils.RadToDeg, 1.5f * Engine.Current.DeltaTime);
float diffY = Rotation.Y - prevY > 0 ? 1 : -1;
Rotation.Z = MathUtils.Lerp(Rotation.Z, 15 * -diffY, 4.0f * Engine.Current.DeltaTime);

Наши боты будут читерить, причём жёстко. Они будут иметь значительно большую маневренность, нежели игрок, но при этом их скорость будет сильно медленнее игрока, дабы можно было их обогнать и стряхнуть с хвоста.

Сам написал, сам полетал: как и зачем я разработал 3D-игру с нуля под компьютеры из 90-х в 2024 году? Опрос, Горячее, Ништяки, Программирование, Net, 3D графика, Игры, Леталки, Пилот, Самолет, Fw-190, Directx, Gamedev, Видео, Без звука, Длиннопост

Ну что ж, демка у нас есть и в этот раз я подготовился получше, чем в статье про 3dfx Voodoo: я собрал целых два тестовых стенда и попросил у подписчиков потестировать демку на своих машинах с диковинным железом из 90-х и нулевых годов. Железо у нас такое:

  • Процессор: Celeron 600MHz Coppermine

  • ОЗУ: 192Mb SDRAM 133MHz

  • GPU: Asus GeForce 4 MX420

  • ОС: WinXP SP3

Сам написал, сам полетал: как и зачем я разработал 3D-игру с нуля под компьютеры из 90-х в 2024 году? Опрос, Горячее, Ништяки, Программирование, Net, 3D графика, Игры, Леталки, Пилот, Самолет, Fw-190, Directx, Gamedev, Видео, Без звука, Длиннопост

На Win98 я так и не смог нормально накатить драйвера на MSDC (Mass Storage Device Class — «флэшки»), поэтому «считерил» и поставил WinXP. Изначально я планировал ставить Win2000 — но там .NET 2.0 работает с косяками (при том что этот же самый .NET работает на Win98!).

❯ Тесты


Давайте же посмотрим, как демка идёт на трушном железе. Для наглядности, я решил записать видео.

Переходим к интегрированной графике, а именно к EEEPC 701 4G с Intel GMA 900 на борту! Те, кто знают что такое GMA, понимают насколько эти встройки не приспособлены для игр. Несмотря на наличие поддержки вторых шейдеров, из-за отсутствия аппаратного вершинного конвейера чип ничего не тянет. Но моя игрушка — исключение и она работает на удивление очень даже неплохо! 15-20 кадров точно есть и это при том что есть куда оптимизировать!

А дальше у нас идут тесты от подписчиков в Telegram-канале, которым я скинул билд и пригласил потестить демку на ретро-железе. Первый тест от читателя на ноутбуке с Pentium III и редкой встройкой Trident CyberBlade XP показал весьма неплохой результат — 15-20 кадров:

Дальше тот же читатель, имя которое он просил не раскрывать, потестил демку на ATI Rage M6 — очень и очень бодрый GPU, который выдает стабильные 20-25-30 кадров!

❯ Заключение


Вот такая демка, мини-игрушка у меня получилось. Да, весьма примитивненько, зато прикольно, запилено за пару дней и можно полетать на виртуальных самолетиках. Также у меня есть Telegram-канал, куда я публикую различные мысли связанные с подручным ремонтом, моддингом и программированием под гаджеты прошлых лет, а также публикую туда ссылки на новые статьи и видео! Найти исходный код демки вы можете на моём Github.

Понравилась статья? Пишите своё мнение в комментариях, я старался :)

Статья подготовлена при поддержке TimeWeb.Cloud. Подписывайтесь на меня и @Timeweb.Cloud, чтобы не пропускать новые статьи каждую неделю!

Статья...
Всего голосов:
Показать полностью 20 4 1
Отличная работа, все прочитано!