Чтение онлайн

на главную - закладки

Жанры

Графика для Windows средствами DirectDraw

Трухильо Стэн

Шрифт:

На этапах 3, 4 и 5 программа обращается к ресурсам, используемым потоком ввода, поэтому необходимо воспользоваться критической секцией. Объект класса CCriticalSection (critsection), объявленный в классе CursorWin (см. листинг 7.1), блокируется функцией Lock. Эта функция пытается получить доступ к критической секции. Если попытка оказывается удачной, функция захватывает критическую секцию и завершается. После этого можно смело работать с совместными ресурсами — поток заведомо обладает монопольным правом доступа к ним. Если функции Lock будет отказано в доступе (из-за того что критическая секция

в данный момент захвачена потоком ввода), функция Lock блокирует основной поток до освобождения критической секции.

На этапе 3 мы сохраняем содержимое области вторичного буфера, занятой курсором, а затем рисуем курсор в буфере. Обе операции выполняются функцией BltFast интерфейса DirectDrawSurface.

На этапе 4 выполняется переключение страниц, однако оно происходит сложнее, чем обычно. Это связано с тем, что функция Flip интерфейса DirectDrawSurface на самом деле не выполняет переключения. Она лишь приказывает видеокарте переключить страницы и после этого завершается. Фактическое переключение страниц происходит после того, как будут закончены все ранее начатые операции блиттинга во вторичный буфер. Для наших целей этого недостаточно. Нам нужно, чтобы переключение страниц было закончено до кода критической секции, потому что в противном случае поток ввода сможет обновить первичную поверхность во время переключения страниц. С помощью цикла while и функции GetFlipStatus интерфейса DirectDrawSurface мы опрашиваем DirectDraw до тех пор, пока переключение страниц не закончится (в DirectDraw не предусмотрена блокировка по этой операции, но даже если бы она и была, переключение страниц происходит слишком быстро и не оправдывает блокировки потока).

На этапе 5 мы проверяем очередь событий мыши. Элементы извлекаются из очереди, пока она не опустеет. Координаты левой (нулевой) кнопки мыши сохраняются для дальнейшего использования.

На этапе 6 в программе происходит необязательная задержка, выполняемая функцией Sleep (функция Sleep блокирует вызвавший поток на заданное количество миллисекунд). Задержка определяется текущей выделенной строкой меню задержек, она имитирует сильную загрузку процессора основным потоком. Например, при воспроизведении сложной трехмерной сцены частота вывода кадров падает. Задержка показывает, что скорость реакции нашего курсора не зависит от частоты генерации кадров.

Этап 6 не требует синхронизации, поэтому мы вызываем функцию CCriticalSection::Unlock. Если к этому моменту поток ввода был заблокирован и ожидал доступа к своей критической секции, вызов Unlock позволит ему войти в нее.

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

Теперь мы знаем, как происходит обновление экрана в основном потоке. Давайте посмотрим, как работает поток ввода.

Поток ввода 

Если не считать двух вспомогательных функций, весь поток ввода реализован в виде одной функции. Функция MouseThread приведена в листинге 7.5.

Листинг 7.5. Функция MouseThread

DWORD CursorWin::MouseThread(LPVOID p) {

 TRACE("starting mouse thread\n");

 CursorWin* win=(CursorWin*)p;

 while(TRUE) {

CMultiLock mlock((CSyncObject**)mouse_event, 2);

DWORD event=mlock.Lock(INFINITE, FALSE);

if (event-WAIT_OBJECT_0==quit_event_index) {

TRACE("got quit message: quitting mouse thread\n");

return 0;

}

critsection.Lock;

oldcurx=curx;

oldcury=cury;

BOOL buffer_empty=FALSE;

while (!buffer_empty) {

DIDEVICEOBJECTDATA data;

DWORD elements=1;

if (mouse==0) {

TRACE("invalid pointer: quitting mouse thread\n");

return 0;

}

HRESULT r=mouse->GetDeviceData(sizeof(data), &data, &elements, 0);

if (r==DI_OK && elements==1) {

static MouseClickData mc;

switch data.dwOfs) {

case DIMOFS_X:

curx+=data.dwData;

break;

case DIMOFS_Y:

cury+=data.dwData;

break;

case DIMOFS_BUTTON0:

if (data.dwData & 0x80) {

mc.x=curx;

mc.y=cury;

mc.button=0;

mouseclickqueue.AddHead(mc);

}

break;

case DIMOFS_BUTTON1:

if (data.dwData & 0x80) {

mc.x=curx;

mc.y=cury;

mc.button=1;

mouseclickqueue.AddHead(mc);

}

break;

}

} else buffer_empty=TRUE;

}

if (curx<0) curx=0;

if (cury<0) cury=0;

if (curx>=screen_width-cursor_width) curx=screen_width-cursor_width-1;

if (cury>=screen_height-cursor_height) cury=screen_height-cursor_height-1;

if (curx==oldcurx && cury==oldcury) {

//-----
обновление курсора не требуется ------

goto nevermind;

} else if (abs(curx-oldcurx) >= cursor_width || abs(cury-oldcury) >= cursor_height) {

Поделиться:
Популярные книги

Инвестиго, из медика в маги 2

Рэд Илья
2. Инвестиго
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Инвестиго, из медика в маги 2

Конструктор

Семин Никита
1. Переломный век
Фантастика:
попаданцы
альтернативная история
4.50
рейтинг книги
Конструктор

Блуждающие огни 4

Панченко Андрей Алексеевич
4. Блуждающие огни
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Блуждающие огни 4

Ох уж этот Мин Джин Хо 1

Кронос Александр
1. Мин Джин Хо
Фантастика:
попаданцы
5.00
рейтинг книги
Ох уж этот Мин Джин Хо 1

Черный Маг Императора 11

Герда Александр
11. Черный маг императора
Фантастика:
юмористическое фэнтези
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Черный Маг Императора 11

Кодекс Крови. Книга ХIV

Борзых М.
14. РОС: Кодекс Крови
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Кодекс Крови. Книга ХIV

Девочка для Генерала. Книга первая

Кистяева Марина
1. Любовь сильных мира сего
Любовные романы:
остросюжетные любовные романы
эро литература
4.67
рейтинг книги
Девочка для Генерала. Книга первая

Ты не мой Boy 2

Рам Янка
6. Самбисты
Любовные романы:
современные любовные романы
короткие любовные романы
5.00
рейтинг книги
Ты не мой Boy 2

Брачный сезон. Сирота

Свободина Виктория
Любовные романы:
любовно-фантастические романы
7.89
рейтинг книги
Брачный сезон. Сирота

Вор (Журналист-2)

Константинов Андрей Дмитриевич
4. Бандитский Петербург
Детективы:
боевики
8.06
рейтинг книги
Вор (Журналист-2)

Наследник павшего дома. Том IV

Вайс Александр
4. Расколотый мир
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Наследник павшего дома. Том IV

Адвокат Империи 2

Карелин Сергей Витальевич
2. Адвокат империи
Фантастика:
городское фэнтези
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Адвокат Империи 2

Законы Рода. Том 6

Flow Ascold
6. Граф Берестьев
Фантастика:
юмористическое фэнтези
аниме
5.00
рейтинг книги
Законы Рода. Том 6

Барон Дубов 4

Карелин Сергей Витальевич
4. Его Дубейшество
Фантастика:
юмористическое фэнтези
аниме
сказочная фантастика
фэнтези
5.00
рейтинг книги
Барон Дубов 4