Я все таки запилил первый видос, экранизацию одной из прошлых своих статей
Да, где-то запорол звук и видеоряд, но я старался! Пожалуйста, зацените ;)
Жизнь после отвала eMMC. Часть 2: даём новую жизнь устройствам с полностью мёртвой памятью. Загружаем Android с MicroSD
Отвал флэш-памяти типа eMMC - весьма частая болячка смартфонов и планшетов, которая массово преследует современные девайсы на протяжении вот уже более 10 лет. Симптомы проблемы знакомы многим читателям: смартфон виснет на заставке, системные приложения регулярно вылетают, или настройки системы внезапно перестают сохраняться. Сам процесс замены флэш-памяти требует навыков перекатки и пайки BGA-чипов, оборудования (трафареты для реболла, программатор с колодками, опционально подогрев) и понимания того, как работает загрузчик той или иной аппаратной платформы, поэтому в СЦ за эту процедуру могут взять достаточно большую сумму. На некоторых девайсах менять память уже совсем невыгодно, особенно когда другой такой-же аппарат стоит полторы тысячи рублей на барахолке, но воспоминания о любимом девайсе порой гораздо дороже, чем сумма за ремонт смартфона. Год назад я уже писал материал о загрузке Android с MicroSD при условии того, что eMMC ещё подает хоть какие-то признаки жизни, а сегодня я вам расскажу о способе загрузить систему с флэшки уже после того, как чип флэш-памяти отказал и ушёл в read-only. Сегодня мы с вами: узнаем о том, какие типы флэш-памяти существуют и причины их отказа, разметим MicroSD-флэшку и запишем на неё образ системы, пропатчим пути монтирования в boot.img, а также узнаем, как теперь запускать наш смартфон и посмотрим, сможет ли он работать достаточно шустро с MicroSD флэшки! Интересно узнать, как вернуть жизнь таким легендам, как Google Nexus? Тогда добро пожаловать под кат!
❯ Почему отказывает флэш-память?
Как я уже говорил в вводном абзаце, проблема внезапно отваливающейся флэш-памяти существует вот уже более 10 лет. Ещё с выходом iPhone 3Gs/4, мастера познакомились с такой болячкой, как внезапное падение устройства в режим DFU и отказ прошиваться через iTunes. Ближе к выходу Galaxy S III, HTC Desire и Wildfire, LG Nexus возникла потребность в программаторах, поскольку чипы eMMC в этих смартфонах очень часто помирали «сами по себе» из-за косяков производителя флэш-памяти. Более опытная часть моих пользователей может вспомнить такие проблемы, как отказ входа в HSPL (загрузчик HTC), бесконечная загрузка с отказом прошиваться в режиме Odin на самсунгах, падение смартфонов на базе чипсетов Qualcomm в режим 9008 (QHSUSB_BULK), а также внезапное прекращение работоспособности девайса даже при наличии адекватного потребления и реакции на кнопку включения.
В относительно современных смартфонах используется два типа чипов флэш-памяти с разными протоколами: NAND и eMMC (в современных чаще используется UFS — наследник eMMC с дифференциальным протоколом, вместо MMC). Устройства конца 2000х годов чаще использовали флэш-память типа NAND с Legacy-протоколом, который требовал ручного управления SPARE-страницами и расчета кода коррекции ошибок (ECC), чем занималось отдельное периферийное ядро в процессоре, называемое NAND-контроллером. Момент, когда нужно «приговорить» флэш-память и перевести её в режим read-only решал не сам контроллер, а драйвер NAND в прошивке устройства — и обычно он был весьма лоялен даже к «сыпящейся» памяти. Кроме того, NAND-контроллер позволял практически напрямую взаимодействовать с чипом флэш-памяти, благодаря чему в загрузчиках типа U-boot есть команда для очистки таблицы Bad-блоков и низкоуровневого форматирования флэш-памяти, дабы в дальнейшем контроллер попробовал пересчитать бэды и, потенциально, вернул некоторое число блоков обратно в строй. Такой тип «флэшек» помирал значительно реже, в основном из-за того, что софт (на моём опыте) практически никогда не уводил флэшку в read-only, «добивая» её до последнего. Из минусов такого подхода — если флэш помирала совсем, то данные из нее можно было достать только с помощью программатора, да и то не факт.
В моей довольно большой коллекции нет ни одного смартфона с Legacy NAND, где флэш бы действительно «приехала», хотя на форумах мастеров иногда встречаются старые сообщения о замене флэши на телефонах Nokia.
Второй тип памяти появился примерно в начале 2010х годов и имя ему — eMMC. Фактически, eMMC — это адаптация интерфейса MMC для использования в виде обычных чипов памяти, а не карточек, совместимая с спецификацией ~SDHC. Если выпаять чип с телефона и припаять сигнальные линии к обычному SD-кардридеру на ПК — он будет работать и определяться как полноценный диск! Таким образом, на некоторых смартфонах можно заменить eMMC на MicroSD напрямую припаяв флэшку на место чипа к соответствующим сигнальным линиям. Однако работать такое будет только если у вашего смартфона «бутербродная» компоновка, где ОЗУ припаяна поверх процессора (MTK и Spreadtrum в пролете). В eMMC используется память типа NAND, которой управляет не чипсет, а встроенный в сам чип памяти контроллер, работающий с протоколом MMC и имеющий собственную прошивку и карту бэд-блоков. Такая флэш-память может самостоятельно уходить в режим read-only когда это посчитает нужным контроллер, зачастую не давая смартфону загрузится, но при этом потенциально сохраняет данные пользователя и позволяет их прочитать дома (сделав дамп памяти устройства и смонтировав раздел userdata в Linux). Однако всё равно иногда данные теряются безвозвратно. Нюанс в том, что состояние eMMC определяет сам контроллер в чипе — поэтому «оживить» его дома и вывести из read-only невозможно. Однако я слышал, что на некоторых «бракованных» чипах памяти (в основном Samsung 2012-2013 годов), которые ушли в read-only слишком рано, можно подпаяться к тест-поинтам программатором и прошить чуть более свежую прошивку с другой ревизии этого же чипа памяти. Флэшка, бывало, оживала.
В некоторых случаях, eMMC были бракованными с завода и помирали сами по себе (!) через короткое время (около года) после покупки устройства. Я знаю как минимум два примера массового брака флэш-памяти: смартфоны HTC 2011-2012 годов, которые время от времени страдали от валящихся чипов Hynix (это касается не всех устройств, многие дожили), хотя я лично видел не так много HTC'шек с дохлой памятью, так что здесь читатели-сервисники с опытом работы в те годы могут только подтвердить или опровергнуть мои слова. А вот подтвержденный пример — смартфоны и планшеты Samsung 2012-2014 годов. Galaxy S3 с артефактами на дисплее при включении, S4 Mini в 9008 или повисшие на заставке, S4 с теми же симптомами, S4 Zoom, которые практически все померли «сами по себе» после обновления до 4.4 KitKat, N8000… Добавьте к этому слабые NC-пятаки, которые срывает при попытке снять чип феном, близко расположенный «бутербродный» процессор, который легко «убить», если орудовать феном, компаунд… и по итогу многие мастера просто спиливали чип дремелем. А что ещё делать!?
По итогу, нам остаётся искать софтварные способы загрузить систему с внешней MicroSD флэшки. И я нашел два таких способа! Первый — предварительно подготовить образ boot.img и прошить его в смартфон вместо recovery, дабы если память ушла в read-only, мы могли просто «дуалбутнутся» во второй образ с пропатченными точками монтирования системных разделов на MicroSD. А о втором, к сожалению, знают лишь единицы, хотя это просто замечательный способ, который позволяет загрузить систему уже «пост-фактум» после ухода флэшки в read-only и требует некоторых манипуляций с fastboot! Давайте же рассмотрим его подробнее.
Нашим подопытным будет рабочий смартфон Alcatel OT-5020D 2013 года выпуска, который пока не подает признаков помирающей eMMC: к сожалению, смартфонов с полудохлой памятью и разлоченным бутом у меня не оказалось, дохлые флэшки я иногда меняю и сам :) Но тем не менее, грузиться мы в любом случае будем с флэшки и вы сможете повторить все шаги в статье, дабы загрузить систему с MicroSD самому!
❯ Подготавливаем систему
Друзья! Для следующих действий, вам понадобится разблокированный загрузчик или устройство, на котором с завода загрузчик не заблокирован. Главный критерий — наличие режима fastboot.
Какие устройства не подойдут: многие смартфоны на базе чипов Spreadtrum, а также часть смартфонов Samsung на Exynos. Ни те, ни другие частенько не имеют режима fastboot от слова совсем. У Samsung есть режим загрузки с MicroSD (т. н. T-Flash Mode), но ядро он не грузит.
Какие устройства подойдут, но требуется подготовка: все смартфоны от Sony (исключение — Xperia Tipo, забагованный fastboot), Google Nexus (некоторые модели страдали из-за отвалов флэши), современные китайские новодельные noname-смартфоны (с вот таким патчем), Xiaomi, Meizu. Чипсеты: MediaTek 67xx/Qualcomm Snapdragon, возможно Kirin. Таким устройствам требуется предварительная разблокировка загрузчика.
Какие устройства подойдут даже при условии уже мертвой флэш-памяти: большинство девайсов на базе чипсетов MediaTek прошлого десятилетия, особенно бюджетных: MT6572, MT6582, MT6592, MT6580, MT6570, MT6575, MT83xx, некоторые Spreadtrum. Это касается Fly, Explay, ZTE и многих других ультрабюджетных смартфонов тех лет. Загрузчик там разблокирован с завода, никакого секьюрбута и верификации загружаемых образов нет. Но не везде можно загрузится в fastboot напрямую (попробуйте громкость вверх и громкость вниз при включении — если сразу грузится в рекавери, то нужно до отказа eMMC включить ADB, если показывает менюшку fastboot, recovery, normal boot — значит все ок).
Не подойдут: MT6573, MT6571 — там U-Boot (но его тоже можно попробовать заставить грузиться с SD).
Список устройств для потенциальной возможности загрузки с SD весьма большой! Как понять, что eMMC «всё»?
Смартфон не реагирует на зарядку и кнопку включения при заряженной АКБ: это не 100% показатель, но если поднимаются питальники с КП и потребление от кнопки есть ~0.1-0.3А — значит процессор вероятно пытается стартовать. Но не откуда. В таком случае, девайс поднять не получится — доступа к fastboot нет, флэшка полностью посыпалась. Исключение — некоторые Qualcomm'ы при наличии прожженного фьюза с завода, разрешающего загрузку с MicroSD могут стартовать ядро, но всё зависит от конфигурации aboot.
Смартфон загружается и сразу вылетают приложения, настройки не сохраняются: явный показатель того, что флэша ушла в read-only потенциально не повредив данные. Если смартфон грузится в fastboot — его ещё можно оживить, но не факт что получится вытащить данные (из-за шифрования). Если после сброса до заводских настроек эффект остается тот-же — eMMC приехала 100%.
Смартфон висит на заставке, сброс и прошивка не помогает: тоже явная причина: eMMC в read-only. В таком случае, не рекомендуется еще раз шить смартфон в надежде что все заработает, есть шанс что флэша посыпеться окончательно и вы потеряете доступ к fastboot.
Весьма всё просто, согласитесь? Как я уже сказал выше, на некоторых устройствах нужно сначала разблокировать загрузчик. Кое-где это, вероятно, получится сделать и при том что флэша ушла в read-only. Например, на устройствах Sony можно без проблем зайти в fastboot и разлочить устройство с помощью кода, полученного на сайте Sony (используйте VPN, если вы в РФ):
Как зайти в fastboot — вам придётся погуглить для конкретно своего устройства. Не нашли? Поищите как это делается на других смартфонах, которые работают на том же чипсете. Почти всегда можно зайти, если у вас включена отладка по USB с помощью команды:
adb reboot bootloader
Краткая справка: на устройствах Sony, в Fastboot можно зайти подключив устройство к ПК с зажатой громкостью вниз, на MTK громкость вверх или вниз, на HTC в HSPL, на Nexus'ах в фирменном загрузчике сразу режим Fastboot, на устройствах Tegra — включение с зажатой громкостью вверх, на смартфонах с чипсетом Intel есть fastboot, насколько помню зайти в него можно с помощью громкости вниз.
Команда для разблокировки загрузчика почти везде одна:
fastboot oem unlock
Вас могут запросить код разлочки или просто предупредить о последствиях такого действия. Как узнать, что бут разлочен?
fastboot getvar all
secure, locking и т. п. — отвечают за статус разлочки. Но даже если таких переменных нет, это не всегда значит, что загрузчик заблокирован. Возможно он разблокирован с завода :)
Теперь нам нужен образ раздела boot — boot.img. Его можно найти в файлах родной прошивки устройства, или, иногда, в zip-файлах кастомов. boot.img содержит в себе ядро Linux и небольшой раздел с файловой системой initrd (рамдиск), которая загружается в оперативную память и содержит в себе программы init, adbd, recovery, а также скрипты инициализации, которые управляют загрузкой Android и процессом зарядки (показывают анимацию, когда вы подключаете устройство выключенным к ЗУ. Да, в таком случае Linux тоже грузится!).
Если у вас есть доступ к fastboot, то попробуйте запустить его с помощью команды:
fastboot boot boot.img
Работать она будет не везде, на MTK её поддержка отключена в загрузчиках некоторых устройств. Если вы увидели на экране устройства USB Transferring — половину дела сделана! Если устройство показало лого и анимацию загрузки или ушло в ребут — потенциально, вы сможете загрузить Android с MicroSD. Если ошибка secure-boot — нужно сначала разблокировать загрузчик. Если unknown command — команда не поддерживается :(
Теперь у нас есть возможность загрузить ядро и пропатчить скрипты конфигурации, дабы изменить точки монтирования раздела /system/, /data/ и /cache/ на MicroSD-флэшку, вместо встроенной памяти.
❯ Записываем систему на MicroSD
Обратите внимание: Android очень интенсивно использует ресурс флэшки и постоянно перезаписывает сектора памяти, поэтому не поскупитесь купить нормальную MicroSD флэшку от, например, Transcend, Kingston или Samsung. Дешевые MicroSD флэшки очень-очень быстро (вероятно, за пару дней — это не шутка) выйдут из строя и придется делать всё заново!
Сначала, нам придется разбить флэшку на три раздела: /system/, /cache/, и /data/. Раздел system будет первым, cache — вторым, data — третьим. При этом раздел /sdcard/ не нужен — он автоматически маппится в /data/media/ на современных версиях Android. Сделать это можно как с ПК с помощью MicroSD-адаптера и fdisk/diskpart/gparted, так и с самого смартфона с помощью того же fdisk в busybox. Я решил это сделать с помощью другого вспомогательного смартфона с TWRP, где изначально был root-доступ через adb! Размеры выбирайте следующие: для системного диска чуть больше или по размерам с system.img (раздел read-only и не «растет» со временем), cache — 100-200Мб, userdata — всё оставшееся место на флэшке.
Разметили MicroSD? Теперь нам нужно записать на неё образ системы. Тут три пути: если у вас есть Linux-машина, то можете подмонтировать образ system.img из оригинальной прошивки и скопировать все файлы с сохранением прав, закинуть system.img в внутреннюю память другого смартфона с root-доступом и проделать все тоже самое, либо записать с помощью dd образ system.img напрямую в нужный нам раздел флэш-памяти. Я выбрал третий способ:
dd if=/sdcard/system.img of=/dev/mmcblk1p1
Разделы cache и userdata можно просто форматировать в ext4:
mke2fs -t ext4 /dev/mmcblk1p2
mke2fs -t ext4 /dev/mmcblk1p3
Готово! Необходимые для базовой работы разделы перенесены на MicroSD. Теперь, когда, у нас есть образ системы, нам нужно распаковать родной boot.img устройства и поменять точки монтирования. Я использую кухню MTKImgTools. Идём в Boot -> Unpack -> boot.img. В Unpack/boot/ появятся файлы нашего раздела boot:
Открываем файл init.rc (в случае MediaTek). Ищем строки с монтированием разделов вида emmc@system, emmc@cache, emmc@userdata и меняем их на /dev/block/mmcblk1p1, /dev/block/mmcblk1p2 и /dev/mmcblk1p3. На некоторых чипсетах, править нужно сразу fstab, или init.<чипсет>.rc:
Готово! Собираем образ обратно с помощью Boot -> Pack -> boot.img и получаем образ, который нам и надо будет загрузить с помощью fastboot. Копируем boot.img в папку с adb и пробуем загрузить систему. Это будет основная команда для старта загрузки смартфона в будущем:
fastboot boot boot.img
Увидели бутанимацию? Значит система пошла загружаться, нужно лишь подождать первой загрузки 5-10 минут! Система висит на лого или уходит в ребут? Значит, возможно, вы неверно прописали точки монтирования, записали образ system или форматировали раздел userdata. Если система 4.4 и ниже, то можно изменить default.prop, заменив ro.secure на 0 и debuggable на 1. Если вы на Android 5+ — то заменить adbd (не требующий ключи авторизации) в /system/bin на вариант из TWRP и посмотреть logcat и dmesg. Монтируется ли /system/? Загружается ли app_process? На каком этапе стопорится? Всё это пригодится при дальнейшей отладке!
Например, такая ошибка при запуске adb shell означает то, что раздел /system/ не монтирован.
Ну а на моем девайсе система уже загрузилась и работает. Но насколько шустро? В комментариях читатели часто говорили, что из-за скорости MicroSD система будет не юзабельной. Насколько это правда? Давайте посмотрим!
Вывод mount:
Как мы и видим, /system/, /data/ и /cache/ на MicroSD. custpack и mobile_info, а также nvram трогать не нужно — если в родной флэше они не повреждены, то у девайса без проблем будет работать и сеть, и Wi-Fi.
❯ Можно ли пользоваться?
Наш девайс работает на базе Android 4.2 — казалось бы, совсем старенький дроид, но тем не менее ещё кое-что, да может. Alcatel OT — это бюджетный девайс из 2013 года, но работает он, на удивление, весьма шустро и приятно!
Начинаем с самых необходимых приложений — звонилка, контакты и галерея. Все эти приложения стартуют практически моментально, лишь иногда с небольшими лагами. Однако если поставить в браузере что-то скачиваться на фоне — конечно-же, система начнет лагать.
Как насчет браузера? Ставить последний хром, поддерживающий 4.2 смысла нет — уже и он открывает далеко не все сайты. Но те сайты, что пока ещё открывает стандартный браузер почитать ещё можно: например, opennet. На смартфонах с более свежим Android, браузер будет работать относительно адекватно. Зато с соц. сетями проблем особых нет. Telegram, конечно, может конкретно подвесить смартфон в процессе подгрузки картинок с каналов, но потом все будет нормально. Решение одно: отключить автоматическое кэширование картинок и видео!
С записью видео ситуация сложная. Даже в профессиональных камерах для 1080p рекомендуются карточки не ниже 10-класса (10Мб/с) и UHS-класса для 2+K видео. На нексусе, это скорее всего превратит девайс в лагодром даже при записе 720p видео: система в фоне так или иначе регулярно читает и записывает данные и рано или поздно мы упираемся в дисковой кэш.
Об играх с динамическим стримингом ресурсов можно забыть, если флэшка достаточно медленная — будут лаги.
А в динамике это всё выглядит так:
Достаточно шустро, для смартфона 2013 года за 4 тыщи рублей?
❯ Заключение
Сегодня мы с вами узнали, каким же образом можно перенести систему на MicroSD! Да, сработает далеко не на всех девайсах, однако сам способ может помочь поднять сотни устройств обратно в строй и сделать их полезными! Это всяко лучше, чем распаивать потенциально рабочие девайсы на «доноров» или, тем-более, отправлять их на мусорку или в чермет. С современными версиями Android ситуация сложнее: и не только из-за большего числа необходимых для загрузки разделов, но и из-за возросших требований к скорости флэш-памяти (упомянутые выше UFS работают на скорости ~500Мб/с), а также, внезапно, стремительно исчезающего слота для MicroSD :(
Надеюсь, материал вам был полезен! Сегодняшняя статья подготавливалась специально в «классическом», более коротком стиле с максимумом конкретики. Если вам больше нравится такой формат, нежели подробный на 15-20+ минут на чтения — напишите в комментариях!
Кстати, если у кого-то из читателей есть ненужные устройства (в том числе с косяками) или дешевые китайские подделки на айфоны/айпады/макбуки и другие брендовые девайсы будучи нерабочими, тормозящими, или окирпиченными и вам не хотелось бы выкидывать их на свалку, а наоборот, отдать их в хорошие руки и увидеть про них статью — пишите мне в Telegram или в комментах! Готов в том числе и купить их. Особенно ищу донора дисплея на китайскую реплику iPhone 11 Pro Max: мой ударник, контроллер дисплея калится и изображения нет :(
А ещё у меня есть Telegram-канал, куда я публикую различные заметки по ремонту, программированию и моддингу девайсов, свои мысли и вовремя публикую ссылки на новый материал!
Статья подготовлена при поддержке TimeWeb.Cloud. Подписывайтесь на меня и @Timeweb.Cloud, чтобы не пропускать новые статьи каждую неделю!
Если вы профи в своем деле — покажите!
Такую задачу поставил Little.Bit пикабушникам. И на его призыв откликнулись PILOTMISHA, MorGott и Lei Radna. Поэтому теперь вы знаете, как сделать игру, скрафтить косплей, написать историю и посадить самолет. А если еще не знаете, то смотрите и учитесь.
Первый легендарный мобильный GPU: каким был PowerVR MBX Lite? Пишем игру-демку про «жигули» с нуля, ч.1
Пожалуй, многие из вас помнят, какими были мобильные игры до и после выхода первого iPhone. В начале 2000-х годов, ещё до появления яблочного смартфона, игры для телефонов в основном были весьма интересными, но тем не менее, достаточно простенькими с точки зрения графики и реализации в целом. После запуска AppStore в 2008 году, на iPhone начали выходить самые разные красочные, невиданные раннее по уровню детализации и проработке 2D и 3D игры. Но появление таких игр — отнюдь не заслуга Apple, а относительной малоизвестной компании PowerVR (подразделение Imagination Tech), которая смогла разработать на базе видеочипа Dreamcast и внедрить один из первых действительно массовых мобильных 3D-ускорителей, имя которому — PowerVR MBX! Сейчас мы с вами привыкли, что почти любой дешевый смартфон может отрисовывать графику уровня PS3 в 1080p, а то и выше, но когда-то даже уровень PS2 был роскошью… Сегодня мы с вами: узнаем предысторию появления аппаратно-ускоренной 3D-графики на телефонах, рассмотрим такую фирменную фишку PowerVR, как тайловый рендеринг, а в практической части статьи нам поможет легендарный КПК Dell Axim X51v с MBX на борту, под который мы напишем 3D-игру «про жигули» с нуля! Интересно? Тогда добро пожаловать под кат!
❯ Мобильная 3D-графика. Начало
Пожалуй, 3D-графика на мобильных устройствах начала развиваться ещё с самого начала 2000-х годов. К тому моменту, как мобильные телефоны научились запускать сторонние Java-приложения, практически сразу же появился прибыльный рынок мобильных игр. Ещё до появления поддержки jar-приложений, люди ставили рекорды в «Змейке» на телефонах Nokia, таскали ящики в «Строителе» на Siemens и играли в другие предустановленные игры на девайсах других брендов, поэтому было очевидно, что игры на мобильных телефонах рано или поздно смогут занять немалую часть сегмента портативных игровых устройств.
Именно появление J2ME дало тот самый толчок для развития мобильного гейминга. Производители телефонов активно развивали и дорабатывали мобильную платформу, добавляя в неё различные API-расширения — например, активацию приложений через СМС и доступ в WAP-интернет. Сама платформа J2ME была достаточно простой для изучения и имела низкий порог вхождения не только для людей, имевших какой-то опыт программирования, но даже для совсем новичков, которые никогда не писали код и тем более игр! Благодаря этому, появились сотни игр, многие из которых до сих пор помнят и любят: это и легендарный «мячик» Bounce, и «зайчик с морковками» Bobby Carrot, и весьма крутой Gish, а также множество различных платформеров по известным фильмам и «большим» играм!
В 2003 году появился Nokia N-Gage — первый массовый телефон, ориентированный именно на мобильный гейминг, который поддерживал не только Java-игры, но и собственные Symbian-игры с достаточно крутой 3D-графикой! Примерно в том же 2003 году, для платформы Java вышло сразу два API-расширения, которые добавляли поддержку симпатичной 3D-графики даже в самые простенькие и бюджетные телефоны: Mobile 3D Graphics (M3G, была почти везде) и Mascot Capsule (эта платформа была только на Sony Ericsson и Motorola). Именно благодаря этим API, мы с вами увидели такие легендарные игры, как V-Rally, Galaxy on Fire, Deep3D и многие другие! Но тем не менее, эти API были относительно медленными из-за программной растеризации на процессоре без отдельного 3D-ускорителя и весьма ограниченными в функционале. Ближайший пример по функционалу — уровень софтрендера первой кваки на первом Pentium! Кстати, про 3D на мобильных телефонах я писал отдельную статью, там в практической части мы пишем 3D-бродилку для Sony Ericsson!
Но помимо кнопочных телефонов, существовал сегмент High-end мультимедийных устройств, которые предоставляли гораздо больший функционал и производительность за немалые деньги. И речь, конечно же, о КПК! Девайсы, работавшие на базе шустрых процессоров Intel PXA и Samsung S3C с Windows Mobile на борту были заметно более перспективными для игр… но как-то не задалось из-за отсутствия нормальных каналов для распространения. Но тем не менее, Intel (иронично, но один из самых больших производителей ARM-чипсетов для КПК в те годы), которая уже занималась развитием десктопной графики GMA и PowerVR активно работали в этой сфере и результатом стало появление видеоускорителя 2700G, который представлял из себя не только 3D GPU PowerVR MBX Lite, но и аппаратный декодер видео, позволявший смотреть видео в высоком качестве! MBX Lite позволял запустить даже Quake 3 в 640x480 (!), пусть и в 10-15 FPS… Ещё за 5 лет до этого, далеко не все десктопные видеокарты могли выдать больше 30 FPS в 800x600!
Конечно в 2004 году уже вышел PSP, выставивший новую планку уровня 3D-графики для портативного гейминга, однако для смартфонов и КПК, уровень графики, разрешение и производительность 3D-игр на MBX Lite был просто немыслимым! Одним из самых легендарных и популярных устройств с 2700G, которое вы можете приобрести достаточно дешево и сейчас, был КПК Dell Axim X51v, флагманская модель с VGA-дисплеем тех лет. Но нельзя сказать, что только PowerVR работала в этом направлении. Параллельно NVidia выпустили GoForce, крайне редко попадающийся в «полноценном» виде (NVidia предлагала дешевле лицензировать только видео-декодер с отключением 3D-части, как это было в Toshiba Portege G900) и ATI Imageon, который чаще всего можно встретить в виде Adreno на ранних Android-чипсетах Qualcomm (Adreno — анаграмма Radeon :)).
Тем не менее, решение PowerVR было действительно массовым: компания не предлагала отдельный чип (что обычно было дороже), как конкуренты, а лицензировала другим компаниям уже готовые IP-ядра, которые производители чипов могли синтезировать и использовать в своих собственных чипсетах, или, сопроцессорах, как в случае с 2700G. Благодаря этому, MBX появился в чипсете TI OMAP 2430, использовавшийся в легендарных Nokia N93i и Nokia N95, Samsung INNOV8, Asus Lamborghini, Nokia E90 и некоторых других. Кроме того, PowerVR MBX использовался в процессоре Samsung S5L8900, судя по всему, разработанный для iPhone 2G и 3G! Благодаря этому, его можно считать одним из первых массовых 3D GPU в телефонах!
Одна из игр для iPhone 2G и N95 — Assasins Creed
И Asphalt 5!
Весьма симпатично, согласитесь?
❯ Под капотом
Но MBX, конечно же, не появился «из ниоткуда» и был основан на более ранних разработках компании Imagination Tech, а именно GPU из полноценной домашней консоли SEGA Dreamcast — PowerVR CLX2, который в свою очередь был основан на ранних десктопных GPU PowerVR из середины-конца 90-х годов. Основная фишка PowerVR была в использовании так называемой техники отложного тайлового рендеринга (TBDR), которая, в отличии от классической растеризации и сортировки с помощью Z-буфера (или ручной сортировки треугольников) всех примитивов «в лоб» (методика, используемая в PSP, PS2 и большинстве видеокарт 2000-х годов), сначала ждёт от программы списка всех рисуемых треугольников в кадре, разбивает весь экран на тайлы (небольшие прямоугольные области), которые содержат в себе информацию о пересекающихся треугольниках, а затем процессом, несколько схожим с рейтрейсингом, определяет, какой из пикселей треугольника ближе всего находится к камере наблюдателя. Таким образом, мы избавляемся от необходимости сортировки геометрии с помощью Z-буфера (который сам по себе занимает достаточно много, по меркам тех лет, памяти и страдает от проблем точности и Z-fighting'а), а также такой метод позволяет реализовать более дешевый альфа-блендинг без ручной сортировки полупрозрачных примитивов и имеет ещё одну приятную фишку — «бесплатный» Occlusion Query, который можно использовать для реализации продвинутых техник отсечения невидимой глазу геометрии.
Производительность PowerVR MBX была весьма достойной для своих лет: при частоте работы в 200МГц, видеочип обеспечивал филлрейт в 100Мп, обрабатывал до 1млн треугольников в секунду. Нативным графическим API MBX был OpenGL ES 1.1 — специальная урезанная версия OpenGL для встраиваемых устройств, из которой выбросили все ненужное и которая заточена не только под floating-point, но и под fixed-point арифметику. В остальном, особо никаких отличий для программиста по сравнению с обычными GPU не было, можно было без проблем портировать уже существующие приложения для десктопого OpenGL для мобильные девайсы, чем и пользовались энтузиасты при портировании Quake 3 на Nokia E90, КПК и другие девайсы. Также, PowerVR MBX поддерживал D3DM — графический API Windows Mobile, о котором мы поговорим позднее.
Однако PowerVR MBX был GPU с фиксированным конвейером (FFP), а не программируемым, как принято в современных 3D-ускорителях. Что-же такое программируемый и фиксированный конвейер? Давайте разберемся:
Фиксированный конвейер: для того, чтобы задать визуальную составляющую рисуемой геометрии, программист оперирует набором заранее определенных при проектировании видеочипа параметров, которые позволяют управлять внешним видом растеризуемых примитивов. Например, для реализации света, программист задает параметры каждого из 8 источников света влияющих на рисуемый объект. Если программисту необходимо наложить несколько текстур за один проход (например, для реализации плавных переходов текстур на ландшафте или нанесения карты отражений на модель), он оперировал комбайнерами, которые позволяли задавать для каждого сэмплера параметры наложения. Такой подход использовался на десктопных GPU эпохи до GeForce 3 (т. е. примерно до 2000 года), до PS3 на Sony PlayStation (Xbox сразу вышел с GeForce 3) и до PSP включительно на портативках. Очевидно, что такой подход сильно ограничивает программиста в том, как будет выглядеть его игра на той или иной видеокарте.
Программируемый конвейер: в программируемом подходе, для управления визуальной составляющей программист пишет небольшие программы для видеокарты, называемые шейдерами. Всего есть два базовых (в современных GPU их больше) этапа программируемого конвейера: первый из них — вершинный шейдер, отвечающий за трансформацию геометрии (перевод из мировой системы координат в экранную) и, например, анимацию. Трансформированные вершины отправляются в следующий этап конвейера — растеризацию, где выполняется уже пиксельный шейдер, который определяет цвет пикселя (или более корректно — фрагмента в терминологии 3D графики) — т.е например, окрас объекта в определенной цвет, текстуру (или несколько текстур), рассчитывает попиксельное освещение, накладывает тени и т. д. Кроме того, такой подход позволяет реализовать сложные техники типа Ambient Occlusion, SSR, а также пост-эффекты (например блюр/блум, правда эти два можно «сэмулировать» и на FFP при определенной сноровке).
К 2007 году, Khronos выпустили спецификацию второй версии OpenGL ES, которая добавляла в мобильные устройства поддержку программируемого конвейера и шейдеров. Таким образом, мобильные GPU всё ближе приближались к уровню консолей и могли выдавать вполне годную графику, близкую к консолям. Даже была когда-то такая консоль, как Zeebo, которая работала на базе смартфонного чипсета Qualcomm с графикой ATI Imageon (!). PowerVR уже в 2009 выпустила серию SGX, которая также использовалась в iPhone, iPad, многих Android-смартфонах и планшетах, а также PS Vita!
Modern Combat 3 на iPad
Но статья с пересказом фишек PowerVR MBX была бы не особо интересной без практической части с написанием 3D-игры под этот GPU с нуля! Поэтому предлагаю посмотреть на нашего сегодняшнего гостя, легендарный флагманский КПК Dell Axim X51v из далекого 2005 года! Для тех лет, это настоящий «жир»:
Его мне подарил мой читатель Сергей с Хабра, за что ему огромное спасибо! Девайс был в полной комплектации, даже с флэшкой и усиленной АКБ, которая до сих пор неплохо держит заряд, однако у него не работал тачскрин. Если вам интересен только процесс программирования игры, а не аппаратного ремонта, то листайте ниже сразу до следующего абзаца :)
❯ Практическая часть: ремонтируем КПК
По факту, девайс полностью работал, однако в некоторые моменты времени не откликался на кнопки и тачскрин, и по всем симптомам это напоминало дребезг кнопок. При этом тачскрин сам по себе реагировал нормально во всех местах, что, фактически, исключало вероятность его поломки (хотя резистивные тач-панели сами по себе не особо надежные, в отличии от емкостных тачскринов). Дело было вот в чём: во многих КПК тех лет был отдельный аппаратный переключатель блокировки клавиатуры и тачскрина, который можно было использовать при просмотре фильмов. Однако на моем девайсе он был слишком разболтанным…
Разбирается КПК несложно: выкручиваем 4 винта и снимаем переднюю часть корпуса. На всякий случай я прочистил грязь между тачем и верхней частью корпуса — она тоже бывает влияет на ложные нажатия и чувствительность тачскрина:
А вот и виновник наших проблем: рычажок переключателя был отломан, но все еще находится в положении «разблокирован». Даже если в выжать в упор — он все равно не работал. Ну что ж, фен в руки, сдуваем переключатель и ставим вот такую перемычку (на фото флюс ещё не отмыт):
Включаем девайс и смотрим — теперь всё работает! Вот такой простой и быстрый ремонт Axim'а. КПК мне сразу очень понравился, я и ранее знал о его легендарности, но теперь узнал и о том, что он очень круто спроектирован и собран! Кстати, есть смысл сразу сдуть концевой выключатель, который прижимает задняя крышка и заменить на перемычку.
GPU не очень хорошо работает на кастомных прошивок, на которую прошиты многие Axim X51v. Поэтому есть смысл прошить сток: качаем прошивку (Файл отката), закидываем на SD-карту и ребутим девайс нажатием клавиш Wi-Fi + включение + Reset. После этого, девайс пойдет прошиваться.
Теперь девайс чистый, как с завода! Можно приступить к написанию небольшой демки-игрушки, которая сможет продемонстрировать нам перспективы нашего КПК в 3D!
❯ Практическая часть: подготовка
Изначально, в практической части статьи должна была участвовать не менее легендарная Nokia N95. Однако вот незадача: несмотря на то, что под Symbian сохранился SDK (который работает нормально только под Windows XP), на устройствах с системой старше 9.x необходимо взламывать installserver, дабы иметь возможность ставить хоумбрю программы (к которым относится и наша игра) и отладчик TRK.
И хотя свой девайс я пропатчил, дебаггер нормально поднять мне так и не удалось. Я смог проинициализировать контекст GLES, запилить примитивный рендерер с загрузкой ассетов из памяти устройства но потом решил перевести проект на WinMobile… Проблем с разработкой под Symbian много: если приложение крашится — то оно просто закрывается, без сообщений и логов. Добавьте к этому то, что в Symbian вообще нет исключений и не всегда можно записать ошибки в лог и отладка превращается в ужас. Ситуацию исправляет Qt, который работает на N95, но в котором нет поддержки GLES (по крайней мере, в виде обычного QOpenGL, хотя возможность юзать API системы из Qt есть и дебаггер там работает нормально, так что не всё потеряно). Если вы когда-то что-то пилили под Symbian, особенно в Carbide — пишите свой опыт в комментариях, интересно почитать :)
WinMobile не менее интересен тем, что в нём поддерживается сразу два графических API: классический OpenGLES в профиле Common Lite (только fixed-point арифметика) и мобильная версия Direct3D — D3DM.dll, которая предоставляет API очень похожее на DX9, но без поддержки шейдеров. Что не менее приятно — есть официальные биндинги от Microsoft к D3DM в .NET Compact Framework, что позволяет легко писать 3D-игры под WM на C#/VB.NET.
Поскольку WinMobile — достаточно открытая для пользователя система, хватит лишь накатить VS2005/2008 на машину с WinXP/WinVista/Win7/Win8 и сразу начать разрабатывать под неё приложения, никаких проблем с отладкой и запуском приложений тут нет. На Win10/Win11 совместимость с WM5 поломали :(
Создаём приложение для смарт-устройств, выбираем в качестве целевой платформы WM5-устройство (эмулятор будет слишком медленным для наших целей, он даже для 2D-игр не подойдет) и, наконец-то, приступаем к написанию игры!
Что же за игра у нас будет? Я решил сделать эдакое 3D-переосмысление популярного в прошлом бесконечного раннера из «тетриса», где мы едем на машинке F1 и обгоняем другие машины, стараясь в них не врезаться. Основной целью является набрать как можно больше очков. Подобные игры достаточно популярны на мобильных девайсах и сейчас: вспомнить хотя-бы Highway Traffic, однако мой вариант будет весьма колоритным: ведь в моей демке мы будем кататься на ТАЗе 21099 и уворачиваться от гнилых «вторых гольфов». Ну а почему бы и нет, я просто очень люблю старые гнилые жигули и это не первый мой проект про машины этого производителя :)
❯ Практическая часть: «движок»
Как и у настоящей машины, у каждой игры должен быть собственный движок! Однако в случае конкретно нашей игры, это скорее небольшой фреймворк, который предоставляет ровно тот функционал, который нужен игре без каких либо излишеств. Необходимо изначально распланировать требования для будущего фреймворка, дабы написание игры не скатилось в процесс, известный в узких кругах как «движкописание» :)
Рендерер: с графической точки зрения, фреймворк должен реализовывать весьма небольшой функционал. Загружать геометрию и текстуры из файлов в специально-подготовленном формате, реализовывать концепцию камеры, отрисовывать статическую геометрию, а также спрайты и текст, реализовывать примитивную систему материалов, которая позволяет наносить на геометрию текстуры, красить их в определенный цвет и управлять повершинным освещением, а также наносить на геометрию отражения с помощью специально подготовленных enviornment-текстур. Кроме того, рендерер должен уметь рисовать симпатичное анимированное небо в виде полусферы.
Звук: воспроизведение wav-звуков и музыки из файлов. Да и всё пожалуй — что ещё нужно от звуковой подсистемы? :) Стерео ведь нет, поэтому и 3D-звук не нужен.
Ввод: обработка нажатий на тачскрин и аппаратные кнопки устройства, маппинг кейкодов в виртуальный «геймпад». GUI-подсистему тоже частично можно отнести именно сюда!
Физика: AABB и Sphere vs Sphere столкновения. Никакого полноценного солвера тут и не нужно :)
Начинаем, пожалуй, с реализации рендерера. Сначала нам необходимо создать окно и контекст D3DM. Процесс практически идентичен D3D8 и D3D9: передаём информацию о нужном адаптере (видеочипе) и заполняем структуру PresentationParameters, однако есть важные нюансы: аппаратный FSAA лучше всего отключить (MultisampleQuality), а также передавайте точный размер окна, в которое собираетесь рендерить изображение, иначе система начнёт софтварно (!) скейлить рендертаргет до размера окна каждый кадр, что, как сами понимаете, крайне медленно.
Из форматов Depth-Stencil форматов поддерживается D16, D24S8 и D32. Желательно использовать D16 (несмотря на тайловую архитектуру, насколько мне известно, в MBX все равно есть fallback до классического рендеринга при некоторых условиях). Практически на всех КПК и коммуникаторах использовался 16-битный цвет, т.е RGB565, но можно указать Unknown — тогда GAPI подцепит тот формат пикселя, что используется в остальной системе.
PresentParameters pp = new PresentParameters();
pp.AutoDepthStencilFormat = DepthFormat.D16;
pp.BackBufferCount = 1;
pp.BackBufferFormat = Format.Unknown;
pp.BackBufferWidth = parentForm.ClientSize.Width;
pp.BackBufferHeight = parentForm.ClientSize.Height;
pp.EnableAutoDepthStencil = true;
pp.FullScreenPresentationInterval = PresentInterval.One;
pp.MultiSample = MultiSampleType.None;
pp.PresentFlag = PresentFlag.None;
pp.SwapEffect = SwapEffect.CopyVSync;
pp.Windowed = true;
device = new Device(0, DeviceType.Default, parentForm.Handle, CreateFlags.None, pp);
device.RenderState.Lighting = false;
aspectRatio = (float)parentForm.ClientSize.Width / (float)parentForm.ClientSize.Height;
Переходим сразу же к рисованию геометрии! Для начала рендеринга, нам необходимо подготовить состояние контекста: посчитать и установить матрицы вида (т. е. камеры) и проекции для трансформации геометрии, задать рендерстейты (список состояний, например нужно ли рисовать модельку с освещением, или нет), очистить экран и Z-буфер и установить параметры фильтрации текстур. Перспективная коррекция текстур — достаточно тяжелая операция и использовать её стоит лишь при необходимости:
public void BeginScene()
{
device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, System.Drawing.Color.SkyBlue, 1.0f, 0);
device.BeginScene();
device.TextureState[0].MinFilter = TextureFilter.Point;
device.TextureState[0].MagFilter = TextureFilter.Point;
device.RenderState.TexturePerspective = true;
// Prepare projection
Matrix matrix = Matrix.PerspectiveFovLH(60.0f * MathUtils.DegToRad, aspectRatio, 0.1f, 350.0f);
device.SetTransform(TransformType.Projection, matrix);
}
public void EndScene()
{
device.EndScene();
device.Present();
System.Threading.Thread.Sleep(16);
}
Чтобы какую-то модельку нарисовать, нам нужно сначала её загрузить! Для возможности напрямую прочитать треугольники из файла и сразу записать их в вершинный буфер, я написал небольшой конвертер из формата SMD (GoldSrc) в собственный, очень простой и легковесный формат, который состоит из позиции вершины и её текстурных координат:
public struct BoundingBox
{
public float MinX, MinY, MinZ;
public float MaxX, MaxY, MaxZ;
}
public sealed class ModelConverter
{
public const int Header = 0x1234;
static BoundingBox CalculateBBox(SmdMesh mesh)
{
BoundingBox ret = new BoundingBox();
ret.MinX = float.PositiveInfinity;
ret.MinY = float.PositiveInfinity;
ret.MinZ = float.PositiveInfinity;
ret.MaxX = float.NegativeInfinity;
ret.MaxY = float.NegativeInfinity;
ret.MaxZ = float.NegativeInfinity;
foreach (SmdTriangle triangle in mesh.Triangles)
{
for (int i = 0; i < 3; i++)
{
ret.MinX = Math.Min(ret.MinX, triangle.Verts[i].Position.X);
ret.MinY = Math.Min(ret.MinY, triangle.Verts[i].Position.Y);
ret.MinZ = Math.Min(ret.MinZ, triangle.Verts[i].Position.Z);
ret.MaxX = Math.Max(ret.MaxX, triangle.Verts[i].Position.X);
ret.MaxY = Math.Max(ret.MaxY, triangle.Verts[i].Position.Y);
ret.MaxZ = Math.Max(ret.MaxZ, triangle.Verts[i].Position.Z);
}
}
return ret;
}
private static int FloatToFixedPoint(float x)
{
return ((int)((x) * 65536.0f));
}
public static void Convert(string fileName, Stream stream)
{
Console.WriteLine("Converting mesh " + fileName);
Smd2Bmd.SmdMesh mesh = new Smd2Bmd.SmdMesh(stream);
BoundingBox bb = CalculateBBox(mesh);
using(Stream outStrm = File.Create(Path.GetFileNameWithoutExtension(fileName) + ".mdl"))
{
BinaryWriter writer = new BinaryWriter(outStrm);
writer.Write(Header);
writer.Write(mesh.Triangles.Count * 3); // Verts count
// BBox
writer.Write(bb.MinX);
writer.Write(bb.MinY);
writer.Write(bb.MinZ);
writer.Write(bb.MaxX);
writer.Write(bb.MaxY);
writer.Write(bb.MaxZ);
foreach (SmdTriangle triangle in mesh.Triangles)
{
for (int i = 0; i < 3; i++)
{
writer.Write(FloatToFixedPoint(triangle.Verts[i].Position.X));
writer.Write(FloatToFixedPoint(triangle.Verts[i].Position.Y));
writer.Write(FloatToFixedPoint(triangle.Verts[i].Position.Z));
writer.Write(triangle.Verts[i].UV.X);
writer.Write(triangle.Verts[i].UV.Y);
}
}
}
}
}
Обратите внимание, PowerVR MBX оперирует fixed-point арифметикой! D3DM, конечно, может автоматически преобразовывать float-координаты вершин в числа с фиксированной точкой, вот только реализовано это криво и косо: драйвер будет конвертировать все вершины в fixed-point каждый вызов отрисовки, вместо того, чтобы один раз преобразовать их после Unlock'а вершинного буфера. Теперь представьте, насколько это тормозно для хоть сколь-либо комплексной модели :)
При этом загрузчик модели при таком подходе будет очень простым и будет работать шустро даже на таком слабеньком железе:
public Model(string debugName, Stream strm)
{
BinaryReader reader = new BinaryReader(strm);
int hdr = reader.ReadInt32();
int numVerts = reader.ReadInt32();
int vertSize = 20;
Bounds = new BoundingBox(reader.ReadSingle() * 2, reader.ReadSingle() * 2, reader.ReadSingle() * 2,
reader.ReadSingle() * 2, reader.ReadSingle() * 2, reader.ReadSingle() * 2);
PrimitiveCount = numVerts / 3;
byte[] data = new byte[numVerts * vertSize];
strm.Read(data, 0, (int)(strm.Length - strm.Position));
Buffer = new VertexBuffer(Engine.Current.Graphics.device, vertSize * numVerts, Usage.None, VertexFormats.PositionFixed | VertexFormats.Texture1, Pool.SystemMemory);
GraphicsStream gs = Buffer.Lock(0, Buffer.SizeInBytes, LockFlags.None);
gs.Write(data, 0, data.Length);
Buffer.Unlock();
DebugName = debugName;
}
Переходим к текстурам. Грузить напрямую png/jpg на КПК слишком долго, поэтому их я тоже перегоняю в собственный примитивный формат, который состоит из описания ширины/высоты, а также формата текстуры и собственно, самих пикселей. На данный момент поддерживаются только RGB565 текстуры — с ними MBX работает лучше всего:
public sealed class TextureConverter
{
public const int Header = 0x1234;
public static unsafe void Convert(string fileName, Stream stream)
{
Console.WriteLine("Converting texture " + fileName);
Bitmap bitmap = (Bitmap)Image.FromStream(stream);
byte[] pixels = new byte[bitmap.Width * bitmap.Height * 2];
System.Drawing.Imaging.BitmapData data = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height),
System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format16bppRgb565);
Marshal.Copy(data.Scan0, pixels, 0, pixels.Length);
bitmap.UnlockBits(data);
using (Stream outStrm = File.Create(Path.GetFileNameWithoutExtension(fileName) + ".tex"))
{
BinaryWriter writer = new BinaryWriter(outStrm);
writer.Write(Header);
writer.Write(0); // 0 - 565, 1 - RGBA
writer.Write(bitmap.Width);
writer.Write(bitmap.Height);
writer.Write(pixels);
}
}
}
Загрузчик тоже получился примитивным и шустрым донельзя, пусть и без какой либо компрессии. PowerVR MBX поддерживает собственный формат компрессии — PVRTC:
BinaryReader reader = new BinaryReader(strm);
int hdr = reader.ReadInt32();
int fmt = reader.ReadInt32();
Width = reader.ReadInt32();
Height = reader.ReadInt32();
byte[] data = new byte[Width * Height * 2];
strm.Read(data, 0, data.Length);
Handle = new Texture(Engine.Current.Graphics.device, Width, Height, 1, Usage.Lockable, Format.R5G6B5, Pool.VideoMemory);
int pitch;
GraphicsStream gs = Handle.LockRectangle(0, LockFlags.None, out pitch);
gs.Write(data, 0, data.Length);
Handle.UnlockRectangle(0);
strm.Close();
Переходим, наконец, к фактическому рисованию модели! Для этого мы строим мировую матрицу для трансформации нашей модели, а также задаем вершинный буфер для, собственно, вершинного конвейера и посылаем видеочипу команду отрисовки. ZBufferWriteEnable нужен для отрисовки геометрии без записи в Z-буфер, что можно использовать, например, для реализации скайбоксов:
public void DrawModel(Model model, Transform transform, Material material)
{
Matrix matrix = Matrix.RotationY(transform.Rotation.Y * MathUtils.DegToRad)
* Matrix.Translation(transform.Position);
device.SetTransform(TransformType.World, matrix);
// Setup renderstate
device.RenderState.ZBufferWriteEnable = !material.DepthWrite;
device.SetTexture(0, material.Diffuse.Handle);
device.SetStreamSource(0, model.Buffer, 0);
device.DrawPrimitives(PrimitiveType.TriangleList, 0, model.PrimitiveCount);
}
И рисуем модельку:
Model model;
Material mat;
Transform t;
void Start()
{
model = Model.FromFile("model.mdl");
mat = new Material();
mat.Diffuse = Texture2D.FromFile("test.tex");
}
void Update()
{
t = new Transform();
t.Position.Z = 150;
t.Rotation.Y += 0.1f;
graphics.DrawModel(model, t, mat);
}
Результат: у нас есть крутящийся кубик или любая другая произвольная 3D-модель!
Переходим к обработке ввода. Тут ничего сложного нет, ловим события KeyUp/KeyDown формы и назначаем виртуальным кнопкам их состояние.
public Input(Form parentForm)
{
keyState = new bool[(int)GamepadKey.Count];
parentForm.KeyPreview = true;
parentForm.KeyDown += new KeyEventHandler(OnKeyDown);
parentForm.KeyUp += new KeyEventHandler(OnKeyUp);
}
private GamepadKey ResolveKeyCode(Keys key)
{
GamepadKey k = GamepadKey.Count;
switch (key)
{
case Keys.Left:
k = GamepadKey.Left;
break;
case Keys.Right:
k = GamepadKey.Right;
break;
case Keys.Up:
k = GamepadKey.Up;
break;
case Keys.Down:
k = GamepadKey.Down;
break;
case Keys.Return:
k = GamepadKey.OK;
break;
}
return k;
}
void OnKeyUp(object sender, KeyEventArgs e)
{
GamepadKey key = ResolveKeyCode(e.KeyCode);
if (key != GamepadKey.Count)
SetKeyState(key, false);
}
void OnKeyDown(object sender, KeyEventArgs e)
{
GamepadKey key = ResolveKeyCode(e.KeyCode);
if (key != GamepadKey.Count)
SetKeyState(key, true);
}
public bool GetKeyState(GamepadKey key)
{
return keyState[(int)key];
}
private void SetKeyState(GamepadKey key, bool state)
{
keyState[(int)key] = state;
}
Теперь мы сможем управлять нашей машинкой в игре (которой пока ещё нет). Самая-самая основа для реализации игры подобного плана у нас есть, пора переходить к геймплею!
Пикабушники! А вы знаете, что это за телефон? :)
Этого красавца подарил мне читатель с Пикабу, за что ему большое спасибо! Девайс сдали в утиль, после неудачной попытки ремонта в СЦ в середине нулевых. Последний раз телефон использовался до поломки, ещё в 2006 году - 18 лет назад!
Считайте, что это своеобразный анонс подробного длиннопоста об аппаратном оживлении этого красавца, на манер статьи о N-Gage! Помимо ремонта, мы посмотрим на этот девайс подробнее, посчитаем ключи загрузчика, накатим патчи и эльфлоадер - эдакий ретро-моддинг из нулевых! И это будет не единственная статья про Siemens...
Большая дыра в безопасности Android: Почему смартфоны с зеленым роботом подвержены кражам?
Многим пользователям смартфонов знакомо такие понятия как «привязка к аккаунту». У различных вендоров смартфонах есть свои механизмы защиты смартфонов от кражи: у Apple — FMI, у Xiaomi — Mi Cloud, а у Google — FRP. Однако у Android есть давняя уязвимость, которая позволяет обходить практически любые смартфоны на «чистой» системе, даже с привязкой к Google-аккаунту. Недавно мне написал известный YouTube-блогер MaddyMurk и предложил задарить смартфон-броневичок AGM H3 на гугл-аккаунте, который он не смог сбросить. Я решил подготовить подробный материал о дырах в защите Android и на практике обойти FRP на смартфоне, который «повис» на активации. Сегодня мы с вами узнаем: почему смартфоны на Android так легко обходить, какие существуют методики и почему подобная практика невозможна на устройствах Apple. Интересно? Жду вас под катом!
❯ Какие бывают «привязки»?
Ещё в нулевых, никакой привязки к аккаунтам у телефонов не существовало. Девайсы крали направо и налево: не уверен насчёт других стран, но в СНГ, к сожалению, эта практика была развита очень хорошо. Девайсы защищались максимум пин-кодом, который телефон мог запросить при смене SIM-карты, но даже его можно было обойти с помощью т.н «мастер-кодов», которые рассчитывались на специальных сайтах в различных СЦ. На некоторых телефонах помогала обычная перепрошивка — и вот, девайс снова отправлялся на БУ рынок для продажи своему новому владельцу, абсолютно чистенький и вероятно, пересобранный в новый китайский корпус. И пофиг, что IMEI-устройства уже давно числится как краденый!
Иногда, своеобразную защиту обеспечивала редкость аппаратной платформы телефона. Например, французские Sagem, которые были довольно популярны в РФ в середине нулевых, практически никто не обслуживал, несмотря на наличие программаторов на рынке. Смена IMEI же зачастую была невозможна — на телефонах Nokia, например, в внутренней памяти хранятся т.н сертификаты для активации радиомодуля и загрузки телефона. Если в процессе кривой прошивки они были повреждены или кто-то пытался их подделать, то телефон больше не включался без генерации нового сертификата за деньги на специальном сайте. Совсем.
Единственное известное мне исключение — китайские телефоны на платформе MediaTek (кнопочники Fly, Explay и.т.п) — там IMEI вполне можно поменять на какой-нибудь левый. Хоть из семерок себе сделать :)
Одну из первых и эталонных реализаций привязки смартфона к аккаунту представила Apple с выходом iPhone 4. Помимо входа в обычный аккаунт iCloud, пользователь мог включить функцию Find My iPhone, которая позволяла найти смартфон в случае кражи. Помимо поиска утерянного девайса, включенный FMI запрашивает логин и пароль пользователя при сбросе смартфона до заводских настроек (или перепрошивке). И вот здесь кроется главная фишка реализации «яблочников»: все устройства Apple, вышедшие с конвейера и прошедшие контроль качества, заносятся в некую базу данных, где хранится связка из нескольких аппаратных идентификаторов: уникальный ID процессора, который «прожигается» на заводе и остаётся
неизменяемым навсегда, уникальный ID модема (вот здесь я точно не скажу, что является идентификатором — скорее всего IMEI) и вероятно что-то ещё. Если идентификатор хотя-бы одного модуля не соответствует тому, что хранится в базе данных Apple — устройство повиснет на ошибке активации!
С этим даже связана одна занимательная история: iPhone 4/4s страдали отвалами модема, от чего в мастерских приловчились менять их с донорских аппаратов, при этом не перекатывая всю сборку вместе с процессором и памятью. С прилётом какого-то апдейта iOS, Apple ужесточили правила активации и многие полностью исправные айфоны повисли на ошибке активации.
Несмотря на эталонную реализацию, FMI обойти можно, если для устройства есть джейлбрейк, который можно сделать до доступа на главный экран (например checkra1n). Однако мобильная сеть и звонки работать не будут — для активации модема нужен уникальный токен, который генерирует сервер активации Apple Albert. Однако, кто-то всё-де смог отреверсить механизм работы сервера активации и завести модем на «байпаснутых» устройствах…
На Android-устройствах ситуация совсем иная: здесь долгое время балом правила открытость смартфонов, которая позволяла модифицировать устройства как угодно — портировать свежие версии Android, делать кастомные прошивки с различными плюшечками и оптимизациями. Долгое время люди знать не знали, что такое секьюрбут (заблокированный загрузчик) и с чем его едят…
По причинам тотальной открытости Android-смартфонов, никто особо не замарачивался с серьёзной привязкой к облачным сервисам: устройства с пин-кодом или графическим ключом без проблем обходились сбросом до заводских настроек через рекавери… до выхода Android Lolipop!
В «пятерке», Google предприняли попытку защитить устройства от сброса через рекавери с помощью механизма FRP — Factory Reset Protection, который запрашивает Google-аккаунт, если устройство не было сброшено с помощьюсоответствующего пункта в настройках. Реализована функция была крайне просто, без каких-либо аппаратных привязок: на устройствах MediaTek и Spreadtrum достаточно было забить нулями определенный раздел памяти фирменным прошивальщиком, а иногда вход в аккаунт можно было обойти различными багами операционной системы. На более старых версиях Android, можно было с помощью adb или терминала просто установить свойство, которое отвечает за показ окна активации:
content insert --uri content://settings/secure --bind name:s:user_setup_complete --bind value:s:1
Суть была в том, что Android на этапе активации просто делает шторку неактивной и прячет виртуальные кнопки домой/меню. По факту, приложения могут отсылать любые Intent («действия» в терминологии Android) системе и открывать любые приложения поверх окна активации, без каких либо ограничений. Если перезапустить приложение активации, то появлялась и полноценная кнопка «домой» и «многозадачность». Таким образом, нехитрыми манипуляциями, на смартфонах Samsung (вся A и J серия, до 2017 года) можно было зайти в браузер и затем в настройки с помощью голосового помощника, на смартфонах Asus с помощью умной клавиатуры TouchPal можно было открыть настройки и сбросить устройство до заводских в пару кликов, а в смартфонах Xiaomi была возможность написать в каком-нибудь текстовом поле youtube.com, зажать на нем палец и открыть соответствующее приложение, откуда можно снова попасть в настройки… Вариантов действительно много!
Недавно мне написал известный блогер с YouTube — MaddyMurk и рассказал занимательную историю: он нашёл «броневичок» AGM H3, который валялся в снегу и грязи несколько месяцев, абсолютно никому не нужный. Несмотря на тяжёлые условия, девайс полностью оправдал свой статус бронированного и остался полностью живым и целым! Однако, аппарат висел на графическом ключе и Миша по старой памяти решил скинуть его до заводских настроек, в надежде что владелец не входил в Google-аккаунт. После сброса, девайс повиснул на активации и Миша спросил у меня, что с ним можно сделать. По итогу, он предложил заслать девайс мне: «авось ты сможешь его оживить». Помимо AGM, Михаил прислал мне ещё кучу ништяков: несколько «сименсов» и «сонериков», кучу запчастей на iPhone 4-5, камеру и свою фирменную кассету с музыкой — за что ему спасибо :))
Однако материал был бы неполным, если бы я не показал на практике, как можно обойти абсолютно неизвестный девайс, для которого нет гайдов по обходу активации — и тем самым не показал бы вам, насколько «дырявая» защита от кражи у Android с Google-сервисами… Переходим к практике!
❯ Обходим активацию багами
После включения, система встречает нас с предложением пройти первичную настройку. После подключения к Wi-Fi, нас встречает окно с предложением войти в аккаунт или ввести графических ключ прошлого владельца.
Наша задача: выйти из экрана авторизации в какое-нибудь приложение, откуда можно открыть встроенный в систему браузер. Вариантов масса: на некоторых устройствах, как уже было сказано, можно открывать ссылки, просто выделив их (таким образом, нужно открывать youtube или иной сайт с ассоциированным приложением в системе). Из тех, что я подметил: приложение «Google Фото» и YouTube подходят лучше всего. У моего смартфона нашлась аппаратная кнопка камеры слева, которая сразу же открывала соответствующее приложение. Хоба: фотографируем что-нибудь, нажимаем на превьюшку фотографии и попадаем в Google Фото!
Аппарат активно эксплуатировали до меня и хорошо затерли защитное стекло для камер — поэтому фото такое мутное.
Теперь нам нужно нажать «поделится объектом» и нажать «искать фотографию в Google». Лучше фотографировать что-то конкретное: например, другой смартфон или телевизор. Я снимал коробку от видеокарты и с помощью объектива нашёл обзор на неё на YouTube. Само собой, Google Поиск предложил мне открыть приложение YouTube для его просмотра!
После этого, нам нужно открыть боковое меню, тапнуть на «Настройки» и попытаться открыть какую-нибудь ссылку: например, лицензия на открытый софт. Делать это нужно быстро — иначе YouTube начнёт жаловаться на то, что версия устарела и смартфон придётся обходить по новой! После этого, смартфон предлагает нам открыть полноценный браузер.
Уже бежите качать какой-нибудь лаунчер и открывать настройки? Не тут то было — Google предусмотрели этот нюанс. Вы не сможете ничего установить из скачанного — менеджер пакетов без активации не работает. Совсем. Поэтому, мы заходим в настройки Chrome -> Уведомления и тапаем по значку логотипа приложения. Мы уже в настройках!
Сейчас сбрасывать устройство смысла нет: смартфон снова повиснет на активации (сброс сработает на устройствах с Android до 7 включительно). Однако есть забавный нюанс: если вовремя отключить Google-сервисы, то приложение активации просто начнёт считать, что мы активируем НОВОЕ устройство без СИМ-карты и предложит… пропустить шаг! Как забавно :)
Находим приложения с названиями а-ля «настройка системы» (кроме самого приложения Настройки) и всех их отключаем и снова включаем: у нас появятся все три кнопки навигации снизу и будет доступен диспетчер задач для более удобного процесса активации. Если у вашего устройства есть некое подобие Assistive Touch — оно тоже подойдет.
Теперь отключаем Google-сервисы и переключаемся на настройку системы. Жмём «Далее» и ждём пару секунд, но не дожидаемся ошибки Google-сервисов. Сразу же идём в настройки и включаем гуглосервисы обратно: по итогу, в один момент сервисы будут считать, что мы «оффлайн» и появится заветная кнопка «пропустить вход». Может получится не с первого раза. После этого, аппарат полностью «забудет» данные прошлого владельца и мы сможем без проблем войти в свой аккаунт :)
Если после этого у вас не устанавливаются приложения из обычных APK-пакетов, то тут два варианта решений: еще раз сбросить аппарат до заводских, либо устанавливать приложения с помощью adb — такой вариант тоже вполне работает:
Можно спокойно войти в свой гуглоакк.
Теперь аппарат полностью рабочий! Ретроспективу о нём не сделаешь: девайс относительно свеженький, работает на актуальной версии Android и имеет под капотом весьма неплохое железо:
Чипсет: Helio P22 с GPU PowerVR GE8320, с 8-ядрами Cortex-A53, 4 из которых работают на частоте до 2ГГц, а остальные 4 до 1.5ГГц.
ОЗУ: 4Гб
Память: 64Гб
Дисплей: 5.7 IPS-матрица. Не самая шустрая, конечно, но вполне ничего.
Аккумулятор: 5400мАч. Весьма бодро.
ОС: Android 11
В целом, весьма неплохие характеристики для современного бюджетника с приятным бонусом в виде бронированности. Уж что-что, а «бронежилет» аппарата выдержал явно многое :)
Авось кто-то из моих читателей когда-то его потерял?
❯ Заключение
Сегодня мы с вами рассмотрели некоторые базовые принципы защиты различных смартфонов от кражи и угона, а также на практике обошли плохонькую «гуглозащиту». Однако это отнюдь не призыв к действию: обходите таким образом только свои собственные смартфоны, аккаунты от которых вы когда-либо потеряли :)
Это не универсальный гайд и конкретный порядок действий может отличаться от версии Android и даже от версий оболочки. Но я рассказал, почему багами ОС можно обойти активацию и в общих принципах расписал то, почему гугловская защита такая плохая. А вы что думаете на этот счёт?
Материал подготовлен при поддержке TimeWeb Cloud. Подписывайтесь на меня и @Timeweb.Cloud, чтобы не пропускать новые статьи каждую неделю!
А ещё я завёл собственный Tg-канал, куда публикую различный бэкстейдж статей, анонсы новых материалов, опросы и ссылки на статьи в минуту выхода.
Микросмартфон за 100 рублей: Покупаем смартфон 11-летней давности и… пишем под него приложения
Размер экрана — краеугольный камень мира современных смартфонов. Кто-то считает, что дисплеи должны становиться только больше, а рамки — меньше, кто-то любит «средние» дисплеи диагональю в 5+", ну а кто-то остаётся ярым поклонником и приверженцем компактных смартфонов с крошечными дисплейчиками. В наше время, купить новый смартфон с относительно небольшим дисплеем за приемлемые деньги почти нереально — самые бюджетные модели будут слишком тормозными для современного пользователя. Некоторое время назад, я купил себе бюджетный крошечный смартфон 2012 года выпуска — Samsung Galaxy Pocket, причём всего за 100 рублей. Конечно же мне захотелось довести его до ума — а доводить пришлось руками и навыками прожженного программера! Какой смартфон можно получить за 100 рублей? Читаем в статье!
Минутка предыстории
С самого появления смартфонов на рынке, весь мир шагал к тотальному увеличению дисплеев и уменьшению рамок. В какой-то момент, большие смартфоны даже получили отдельное название — падфоны или смартпэды. Такой ход событий было не трудно предугадать: ведь производители дисплейных матриц осваивали всё более и более высокие разрешения и предлагали больше вариантов производителям смартфонов.
Однако несмотря на всеобщее засилие больших «лопат», в мире всё ещё оставались поклонники маленьких и компактных телефонов, которыми очень удобно пользоваться одной рукой. Сейчас подобные устройства представляют только небольшие бренды, известные достаточно в узких кругах — в основном, их можно купить на маркетплейсах, в обычных салонах связи их не найти. Мне известно о нескольких подобных устройствах, которые сейчас присутствуют на рынке. Первый из них «закос» под iPhone — Soyes XS11:
Но тут уж, если честно, хочется назвать такой смартфон не просто компактным, а совсем малюсеньким. На нём вполне удобно выполнять задачи звонилки, но совсем неудобно набирать текст — поэтому под наши задачи, он не особо подходит. Кроме того, эти девайсы работают на базе бюджетного смартфонного железа 6-7 летней давности, поэтому их производительность будет достаточно невысокой по меркам современного пользователя. Конечно же есть и более серьёзные варианты — например, компания Unihertz (да, тот самый продолжатель идей BlackBerry) делает смартфоны Jelly 2: дисплей с диагональю 3", Helio P61 под капотом и Android 11 на борту. Вот только цена, мягко говоря, кусачая — 18 тысяч рублей на момент написания статьи. Это слишком дорого!
Но если душа прямо таки лежит к компактным смартфонам, почему бы не обратиться к рынку Б/У устройств и не присмотреть что-то из… прошлого десятилетия? А вариантов ведь реально много — тут и LG Optimus L3 (3.2"), и Samsung Galaxy Pocket Neo (2.8"), Samsung Galaxy Star (3"), Samsung Galaxy Fame (3.5"), Samsung Galaxy Young. Все перечисленные девайсы стоят реально копейки — можно купить живой вариант до 400-500 рублей!
Я решил взять себе целых два смартфона: Samsung Galaxy Mini и Samsung Galaxy Pocket первого поколения. Оба достались мне в одном лоте за 2.000 рублей (с 20 телефонами) и обошлись мне по сто рублей, причём оба смартфона были рабочими! Чуть позже я докупил отдельно Galaxy Star (250 рублей), Galaxy Fame (250 рублей) и Galaxy Pocket Neo (~400 рублей) для полноты коллекции — вышло совсем недорого. Итак, что за характеристики мы получаем в смартфоне за 100 рублей:
Android: 2.3 Gingerbread.
Чипсет: Broadcom BCM21553 с одним ядром Cortex-A5 на частоте 832мгц. Видеочип: VideoCore IV, он же использовался в Raspberry Pi.
ОЗУ: 256 мегабайт (предположительно — DDR1).
Встроенная память: 3 гигабайта + слот для SD.
Дисплей: 2.8", 240x320, емкостной тачскрин.
Сеть: Поддержка 2G/3G. Об LTE и речи не идёт.
Выглядит не особо густо, да? И разрешение весьма низкое — большинство софта не запустится, а о клиентах современных сервисов и мечтать не приходится… или приходится?
Конечно же шаловливым ручкам захотелось вернуть жизнь этому миниатюрному красавцу и я решил использовать его как второй смартфон — при этом с клиентом ВК и музыкой, которые я запилил сам.
Разработка под старые версии Android
На самом деле, разработка под старые версии Android не особо отличается от современных версий системы. Кое-где приходится костылить, велосипедить и юзать AppCompat для реализации современных фишек на старых версий системы, но, будем честным, подобного и в последних версиях Android достаточно.
Даже сейчас нет никакой проблемы скачать последнюю версию Android Studio, подключить смартфон с включенной отладкой и отлаживать приложение прямо на девайсе — logcat тоже есть. Единственный нюанс — поиск драйверов и ручное закрытие приложений в таскменеджере, если вы деплоите под Android 2.x (Android Studio не умеет сам закрывать приложение, чтобы переустановить пакет).
В целом, за всё время разработки под старые устройства, я пришёл к следующим выводам:
Поскольку большинство устройств имеет одно ядро, для плавности интерфейса нужно минимизировать любую работу в фоне.
Взаимодействие с современными веб-сервисами может быть осложнено из-за отсутствия поддержки TLS1.2 и устаревших сертификатов (проверка сертификатов легко обходится специальным костылем, а вот TLS — нет).
У Android до 3.0 вся отрисовка интерфейса программная и она опять же, будет сказываться на скорости работы фоновых служб. Чем менее интерфейс комплексный, тем лучше.
Пушей нет — да, вообще. Однако это ничуть не помешает нам сделать уведомления практически в реальном времени с помощью… очередного костыля!
Допиливаем ВК
Я уже писал клиент ВК в рамках одной из прошлых статей. Теперь нам нужно довести его до ума — подогнать под разрешение экрана и переработать интерфейс для большей удобности, а также добавить недостающие разделы — я тот ещё любитель полистать мемчики, сидя в автобусе.
Честно сказать, вся концепция интерфейса требовала полной переработки — боковое меню банально очень неудобно использовать на подобных устройствах из-за малых размеров каждой строчки. Поэтому я решил не изобретать велосипед, а обратился к дизайнерам Apple и первоисточнику: официальному клиенту ВК для iOS 6, родом из 2012 года!
Приложение для Android выглядело +- также в те годы. Видите вкладки с разделами снизу? Они то нам и нужны — это самый удобный способ навигации на таких смартфонах! Накидав макет в layout'е, я приступил к реализации:
Изначально мне хотелось, чтобы всё приложение было плавным и анимированным: для этого я обратился к фреймворку анимаций Android. Суть очень простая — это обычный интерполятор значений от a до b за определенный промежуток времени. При этом мы не можем анимировать произвольное свойство — только те, который уже реализованы в системе (переход, поворот, масштабирование, альфа-канал). Более наглядно это можно представить вот так:
Да, это всё анимация :) Получаем примерно такой результат:
Обратите внимание, что запуск большого количества анимаций будет вызывать перерисовку даже в том случае, если элемент не видно на экране — от чего у нас будут дикие тормоза! Осторожнее с этим.
После этого, я решил доработать раздел с музыкой: я все еще пользуюсь грязными хаками для получения доступа к API музыки, поскольку «левым» клиентам такой возможности не дают. Публично его расписывать не буду, поскольку это скорее всего нелегально, да и сами ребята из ВК об этом знают (но не думаю, что будут применять какие-то санкции по отношению к «маленьким» разработчикам) — но если нужно, пишите в личку, расскажу всю концепцию.
Во первых, мне хотелось добавить возможность скачивать треки на внутреннюю память/флэшку. А во вторых, мне хотелось добавить фоновое воспроизведение — до этого возможность свернуть приложение и послушать музыку уже была, однако Android мог в любой момент прибить окно с музыкой и оставить нас с носом, остаётся только реализация в виде foreground-сервиса:
В Android есть два типа служб: background (фоновые) и foreground (видимые пользователю). Первый тип служб система может прибить когда угодно — например мало памяти или экономия заряда АКБ. А вот второй тип служб система не прибивает практически никогда, поскольку они обозначают выполнение важной операции в фоне — например скачивание файла или обновление системы. Однако у них есть одно ограничение — они должны быть привязаны к собственному уведомлению, которое нельзя закрыть. В процессе реализации возникло еще пару проблем — Wakelock'и (механизм, предотвращающий уход девайса в «сон») и WiFiLock'и (тоже самое, но для WiFi).
Точно таким же способом я реализовал механизм уведомлений — как я уже говорил раньше, пушей на старых смартфонах нет вообще ни в каком виде, поэтому пришлось реализовывать свой механизм «обновления»: каждые 3-5 секунд запрашиваем список последних 5 диалогов с сервера и сравниваем с предыдущим результатом, если есть новые сообщения — создаём нотификацию (листинг слишком длинный - пришлось перезалить на pastebin):
После этого, я начал рутинную работу по реализации интерфейса для данных с сервера — паблики, друзья, профили, лента и.т.п. В некотором смысле, реализация лента весьма занимательна: вообще, для очень больших списков существуют т.н виртуализация ListView — это когда ListView отображает только видимый пользователю кусок датасета (набора данных — например, список записей на стене) и на старых версиях Android она доступна. Однако мне было интересно реализовать вариант, который потреблял бы минимальное количество ОЗУ и где я точно знал бы, когда пользователь видит тот или иной фрагмент приложения. Поэтому я реализовал… пагинацию свайпами! Вот так привет из нулевых!
Для этого я использовал GestureDetector — встроенный в систему класс для обнаружения простых жестов — свайпов и.т.п. ВК при запросе ленты отдаёт специальную метку для получения следующей страницы новостей (поскольку она может динамически меняться и нужно хранить её стейт), мы эти метки просто сохраняем и переключаемся по странницам новостей с помощью обычных свайпов вправо-влево:
Выглядит весьма забавно.
Юзабельно ли всё это на деле?
Давайте смотреть, может ли юзать такой смартфон в наши дни. Берём наш девайс в руки, логинимся и оцениваем его производительность «вхолостую».
Работает весьма шустренько, учитывая что это бюджетник 2012 года. Как насчет нашего самопального клиента ВК? Смотрим:
Работает весьма бодро. Не сказать что также плавно, как последний айфон, но и совсем плохим результат явно не назвать!
Смартфонный функционал у девайса тоже вполне ничего: 1-2 SIM (в зависимости от версии), нормальная синхронизация контактов с ПК (однако Kies вроде-бы не работает на Windows 10, но есть vcf):
Встроенный почтовый клиент продолжает работать без каких либо проблем. Однако настраивать некоторые почтовые сервисы нужно вручную и с помощью «паролей приложений» — напрямую залогинится возможности нет. В случае «покета», придется поставить стоковый клиент из Android 2.3 вручную.
Мультимедийные возможности тоже радуют: встроенный плеер тачвиза мне всегда очень нравился. Есть и настройки эквалайзера.
Единственное, что откровенно подводит — браузер. Последним вариантом осталась Opera Mini 7 — она позволяет смотреть сайты, но не поддерживает динамический контент, только статику. Ну, зайти на википедию или почитать статью на Хабре хватит. Родной браузер уже не в состоянии что либо загрузить :(
Ну а в общем, производителньость смартфона весьма радует, согласитесь? Нельзя сказать, что он уж слишком тормозной — по крайней мере, современные ультрабюджетные смартфоны (до 4-5 тысяч рублей) зачастую показывают себя гораздо хуже чем и флагманы прошлых лет, и даже бюджетники!
Заключение
И всё таки, я считаю что мне удалось в каком-то смысле вдохнуть новую жизнь в старенький девайс. Если использовать подобный девайс как второй — на случай, если сел основной смартфон, то такой миниатюрный красаввчик может неождианно выручить даже в довольно сложной ситуации. Кроме того, эти смартфоны всеядны к аккумуляторам — достаточно подпаять + и — и они будут работать хоть от BL-4C.
Главная ценность Galaxy Pocket — в его компактных размерах. А поскольку по настоящему дешевых, маленьких и шустрых смартфонов становится всё меньше и меньше, то нам остаётся лишь продлять жизнь моделям прошлых лет! Есть ли в этом смысл и получил ли смартфон новую жизнь? Пишите в комментариях!
Клиент ВК можно сказать на 4pda. Там лежит самая последняя версия (для скачивания нужна регистрация на форуме). Если по каким-то причинам не хотите регистрироваться на форуме — я выложил актуальную версию в комментариях.
Эта статья поддерживается командой ITGLOBAL.COM
Мы — первый облачный провайдер в России, а также интегратор, поставщик ИТ-услуг, продуктов, сервисов и разработчик собственного ПО.
• Наш сайт
• Наш блог про виртуализацию и Enterprise IT
• Истории успеха наших клиентов
Меряем мир в сосисках!
Пройдя этот тест, вы узнаете, сколько нужно сосисок, чтобы спуститься по ним на дно Марианской впадины. А еще сколько их можно съесть, пока длится самый долгий в мире поцелуй. Не пропустите!
Ответ на пост «Не дадим Windows Phone умереть! Как я написал свои клиенты VK, YouTube для Nokia Lumia? Сам себе экосистема ч.2»
Это все конечно здорово, энтузиазм дело хорошее.
Может с точки зрения разработчика эта система супер-пупер крутая.
Но с точки зрения пользователя - это редкостное говнище. Хуже только, наверное, виста на пк (в целом под нее и подгонялось).
Судя по интерфейсу и дизайну - система делалась как раз для разработчиков, мол как у нас классно, можно вот это написать, это запрограммировать, это сделать». Но для обычных пользователей это все нахер не надо. Человек хочет достать телефон из кармана, позвонить, отправить пару сообщений, посмотреть видосики и всё. И он хочет, что бы его глазам это было приятно. Виндафон этого не давал даже на 1%. В нем было хреново абсолютно всё от интерфейса до реализации структуры.
Это раз.
Второе:
А вы посмотрите на свой Android-смартфон сейчас. Сколько в нём ОЗУ? 4гб? 8гб? 12гб? Смущает ли вас то, что Android умудряется неприятно подтормаживать даже с такими ресурсами? А теперь вспомните Lumia 520: Snapdragon 200, 512 мегабайт оперативной памяти. Вот так она работает из коробки.
С точки зрения разработчика это полнейшая чушь и ложь. И либо ты не понимаешь как работают системы, либо пытаешься обмануть нас. С каждым годом приложения становятся сложнее и им требуется больше ресурсов. Да может где то это не оптимально. Да, может что то можно было бы лучше. Но общая тенденция это увеличение ресурсопотребления приложений из-за улучшения графики, увеличения вычислительных процессов, усложнения логики приложений.
И это все равно что сравнивать первую денди и PS5. На ПСке сколько оперативки? 32? 64? 128? И все равно некоторые игры тормозят. А вот на денди Марио не тормозил! Ну это же полнейшая чушь.
Это же фактический обман.
Плюс сама по себе система wp это максимально сырое тесто. Хочешь хорошо - бери напильник.
А людям надо что бы ты достал из коробки и сразу стало хорошо.
Вот простое объяснение того, что это система говно и к нее нет и никогда не было будущего.
Друг, это мертвая система которая никогда не будет воскрешена. Она убогая и неприятная (имхо).
И яблоки снискали такую популярность всего лишь по одной причине - они дали людям то, что им нужно - красоту и простоту. К счастью они нашли ровно тот ключик который был нужен.
А все вот эти архаизмы типа wp давно уже умерли и никогда не воскреснут.
А ты сейчас занимаешься некрофилией. Без обид, но по фактам.