214
правокИзменения
AHI
,metadesc
AHI {{lang-en|ATI Handheld Interface}} — драйвер для чипов ATI. Присутствует в каждой прошивке для телефонов, где есть чип ATI, а это - все телефоны на базе [[LTE]] и [[LTE2]].
<metadesc>AHI - драйвер для чипов ATI. Присутствует в каждой прошивке для телефонов, где есть чип ATI, а это - все телефоны на базе LTE и LTE2.</metadesc>
== Чипы ATI ==
Два основных чипа, используемых в телефонах [[Motorola]]:
*[[ATI W2250]] - преимущественно в LTE
API драйвера для различных чипов одинаков, однако внутреннее устройство значительно различается (''По словам владельцев. Лично мне неизвестно, насколько. A51'')
== Применение ==
Вывод графики через драйвер, в обход стандартных средств прошивки (см. [[Canvas]]), предоставляет больше возможностей по сравнению с последними, и, при правильном применении, работает значительно быстрее.
С учётом сказанного, для наиболее эффективного использования средств, предоставляемых драйвером, их следует использовать в приложении, основанном на [[Task|таске]].
== Основные понятия и начало работы ==
API драйвера напоминает интерфейсом обычные графические библиотеки, как например GDI. Рассмотрим основные понятия и приёмы работы с AHI в применении к эльфописанию.
Для обеспечения такой возможности используется специальный объект, с которым разработчику [[ELF|эльфа]] под драйвер придётся сталкиваться постоянно - это ''контекст устройства''.
=== Контекст устройства ===
'''Контекст устройства''' ({{lang-en|Device Context}}) — структура данных, обеспечивающая эксклюзивный доступ к устройству вывода для приложения, использующего эту структуру и предотвращающая влияние других приложений на процесс работы с устройством. В ней хранятся все данные о текущем состоянии устройства, устанавливаемом приложением - владельцем контекста.
</li>
</ol>
=== Поверхности ===
Прежде чем переходить к рассмотрению непосредственно программирования под AHI, необходимо ознакомиться с ещё одним важнейшим понятием - "поверхностями".
*:Устанавливается функцией [[AhiDrawSurfSrcSet]]
*'''Поверхность кисти ("Brush Surface")
*:С этой поверхностью приложения никогда не работают напрямую, но о её существовании лучше нужно знать, чтобы проще было понимать принцип работы некоторых функций рисования - она является важным вспомогательным инструментом. Всегда монохромная (однобитная), и используется как параметр PATTERN в [[ROP|растровых операциях]].
*:Устанавливается самим драйвером, а настраивается с помощью функции [[AhiDrawBrushSet]].
Иногда требуется создать собственную поверхность в видеопамяти, например, чтобы закешировать спрайт (вывод графики из внутренней памяти намного быстрее, чем из системной). Для этого можно использовать функции [[AhiSurfAlloc]], [[AhiSurfFree]], [[AhiSurfReuse]].
=== Координаты ===
Ещё одна вещь, с которой придётся постоянно иметь дело - это точки и области экрана и их координаты.
*Ось Y направлена вниз
Два основных объекта для описания координатных положений - это <tt>AHIPOINT_T</tt/> и <tt>AHIRECT_T</tt>:
<pre>
typedef struct
*<tt>AHIRECT_T</tt> указывает область на целевой поверхности, куда попадёт картинка из поверхности-источника, и именно он задаёт размер картинки.
*<tt>AHIPOINT_T</tt> указывает координаты левого верхнего угла на поверхности-источнике, откуда будет скопирована область, размерами равная размерам прямоугольника <tt>AHIRECT_T</tt>.
=== Цвет ===
Как многие знают, во многих телефонах используются дисплеи с глубиной цвета 16 бит (Покомпонентно: 5 бит на красный, 6 бит на зелёный и 5 - на синий, "RGB565"), а в настольных компьютерах - с глубиной цвета в 24 бита (по 8 бит на каждую компоненту цвета, "RGB888"). Многие привыкли к заданию цвета в 24-битном формате на настольных компьютерах, да и это намного легче, стоит только рассмотреть пример: 0xFACE8D - в 24bpp сразу видно, какая интенсивность цвета на каждой компоненте, а на 16bpp это будет 0xFE71, и ничего не понятно... Вебдизайнеры поймут.
Так вот по крайней мере [[W2250]] не имеет поддержки 18-битных поверхностей, чтобы обеспечить использование возможностей такого дисплея, так что это был не более чем маркетинговый ход. Впрочем, это же судя по всему касается и [[LTE2]] телефонов, так как для графики там опять же используются 16-битные поверхности.
Во многих графических адаптерах прошлого (хотя, и по сей день нередко используется, например, в консолях) основным режимом был 8-битный цвет с палитрой. К моему великому сожалению, портативные чипы ATI не имеют аппаратной поддержки 8-битных палитр (8-битный цвет - возможно, только в формате RGB322, но не проверено), но есть особенность, которую можно назвать однобитной палитрой.
Однобитные поверхности занимают особое место среди прочих. А именно, при выводе однобитной картинки, мы можем задавать 16-битный цвет, который будет представлять "1", "цвет переднего плана", и цвет, представляющий "0", "цвет фона", либо сделать один из них прозрачным. Фактически, получаем палитру для однобитного изображения.
Эти два цвета также задаются отдельно для кисти (а она, как мы узнали из предыдущих разделов, тоже однобитная поверхность!) - с помощью функций [[AhiDrawBrushFgColorSet]] и [[AhiDrawBrushBgColorSet]], и для остальных однобитных изображений - функциями [[AhiDrawFgColorSet]] и [[AhiDrawBgColorSet]].
=== Инициализация ===
Итак, у нас теперь есть контекст, полученный одним из двух способов, указанных выше. Что дальше?
Чтобы не углубляться в рамках этой статьи в растровые операции, ограничимся пока что простым правилом:
Для вывода растровых изображений устанавливаем <tt>AHIROP_SRCCOPY</tt>, а для рисования цветом - <tt>AHIROP_PATTERNAHIROP_PATCOPY</tt>.
Отсановимся на последнем, так как пригодится в последующем примере.
<pre>
// Устанавливаем растровую операцию на применение кисти
AhiDrawRopSet( dCtx, AHIROP3(AHIROP_PATTERNAHIROP_PATCOPY) );
</pre>
</li>
Конечно, некоторые из этих операций понадобится повторить перед вызовом определённых функций, с другими установками, но надеюсь это уже не составит для Вас проблем.
=== Проба пера =Примеры == Наконец, всё готово для того, чтобы уже можно что-нибудь уже да и нарисовать. !Не будем здесь заострять внимание на таких тривиальных вещах, как размещение последующих примеров в коде и инициализация приложения. Пускай, например, это будет вызов рисовать мы будем в таймеревызове по таймеру. === Первый пример ===
Для первого раза нарисуем цветной графический примитив.
AhiDrawSpans( dCtx, &rect, 1, 0);
</pre>
References: [[AhiDrawSpans]], [[AhiDrawBrushFgColorSet]] После этого мы получим на экране синий квадрат в левом верхнем углу. Не больно-то и сложно, не так ли? === Второй пример === Теперь мы попытаемся решить задачу чуть посложнее, а именно - выведем какую-нибдь картинку. Код для загрузки картинок можно взять из библиотеки AHG, написанной '''tim apple''', а саму картинку нужно будет [[Подготовка графики для ATI|подготовить особым образом]]. <pre>/* Проведём инициализацию при загрузке эльфа: */ // Сюда будет загружена наша картинка. Не забудьте освободить память bitmap.image по завершению!AHIBITMAP_T bitmap; // Загружаем картинку!BMP_LoadFromFile(L"file://b/image.bmp", &bitmap); /* Теперь нарисуем картинку на экране средствами ATI */ AHIPOINT_T point;AHIRECT_T rect; // Пусть мы хотим вывести картинку в левом верхнем углу, задаём область как в предыдущем примереrect.x1 = 0;rect.y1 = 0;rect.x2 = bitmap.width;rect.y2 = bitmap.height; // И ещё - точку на исходной картинке. Мы выводим целиком, так что нули.point.x = 0;point.y = 0; // Не забываем, что в прошлый раз мы установили операцию PATCOPY, но она не подходит для вывода растра!AhiDrawRopSet( dCtx, AHIROP3(AHIROP_SRCCOPY) ); // Осталось собственно вывести картинку!AhiDrawBitmapBlt( dCtx, &rect, &point, &bitmap, NULL, 0 );</pre>References: [[AhiDrawBitmapBlt]], [[AhiDrawRopSet]] === Третий пример === В третьем, заключительном примере мы создадим собственную поверхность, перенесём её в видеопамять и будем работать уже из неё.Пример во многом повторяет предыдущий, но смотрите внимательнее - есть значительные отличия! <pre>/* Проведём инициализацию при загрузке эльфа: */ // Сюда будет загружена наша картинка. Не забудьте освободить память bitmap.image по завершению!AHIBITMAP_T bitmap;// Это - размер новой поверхностиAHIPOINT_T size;// Сюда мы сохраним указатель на новую поверхностьAHISURFACE_T surface; // Загружаем картинку!BMP_LoadFromFile(L"file://b/image.bmp", &bitmap); /* Создадим новую поверхность - surface, по размеру картинки*/size.x = bitmap.width;size.y = bitmap.height; AhiSurfAlloc( dCtx, &surface, &size, AHIFMT_16BPP_565, 0 ); /* Перенесём картинку на нашу новую поверхность, просто нарисовав её из системной памяти */ AHIPOINT_T point;AHIRECT_T rect; // Задаём область выводаrect.x1 = 0;rect.y1 = 0;rect.x2 = bitmap.width;rect.y2 = bitmap.height; // И точку на исходной картинкеpoint.x = 0;point.y = 0; // Не забываем, что в прошлый раз мы установили операцию PATCOPY, но она не подходит для вывода растра!AhiDrawRopSet( dCtx, AHIROP3(AHIROP_SRCCOPY) ); // Сейчас мы хотим вывести картинку на новую поверхность.AhiDrawSurfDstSet( dCtx, surface, 0 );// Так как выводить будем из системной памяти, поверхность-источник нам не важна. // Выводим картинкуAhiDrawBitmapBlt( dCtx, &rect, &point, &bitmap, NULL, 0 ); /* Теперь мы можем работать с этой картинкой в видеопамяти */AHIPOINT_T point;AHIRECT_T rect; // Сейчас мы хотим вывести картинку из новой поверхности на экран.AhiDrawSurfSrcSet( dCtx, surface, 0 );AhiDrawSurfDstSet( dCtx, sDisp, 0 ); point.x = 0;point.y = 0; rect.x1 = 0;rect.y1 = 0;rect.x2 = bitmap.width;rect.y2 = bitmap.height; // Для вывода из видеопамяти используется эта функцияAhiDrawBitBlt( dCtx, &rect, &point );</pre>References: [[AhiDrawBitBlt]], [[AhiDrawSpansAhiSurfAlloc]], [[AhiDrawSurfSrcSet]], [[AhiDrawSurfDstSet]], [[AhiDrawBitmapBlt]], [[AhiDrawRopSet]] == Заключение == Итак, рассмотрев основные моменты работы с драйвером ATI и даже несколько конкретных примеров, у вас не должно возникнуть больших проблем с разработкой эльфов с его использованием.Тем более, что уже существует несколько подобных эльфов, с исходным кодом которых можно ознакомиться.
[[Категория:Эльфостроение]]