2. Скопируйте CPP-, H- и RC-файлы из каталога с компилируемой программой в каталог с новой, пустой рабочей областью.
3. Включите файлы в пустой проект (командой Project|Add to project|Files).
Заодно можно настроить прекомпилированные заголовки (см. выше). Проект готов к компиляции.
Хотя пользователи Visual C++ 4.x смогут пользоваться программами из этой книги, DirectDraw AppWizard работать не будет. Если читатели проявят достаточный интерес, я могу создать соответствующую версию и поместить ее на Web-узел.
Варианты Visual C++
И последнее замечание о Visual C++. Поскольку этот продукт выпускается в трех вариантах (Learning, Professional и Enterprise), иногда читателям не удается скомпилировать проект. Для написания и тестирования программ этой книги я пользовался вариантом Professional, так что при работе с другими вариантами могут возникнуть проблемы. Впрочем, в основном это проблемы мелкие и легко излечимые. Если у вас возникнут трудности и вы решите обратиться ко мне, пожалуйста, укажите версию и вариант Visual C++.
В этом разделе рассматривается несколько не связанных друг с другом, но полезных тем. Сначала мы поговорим об одной ошибке DirectDraw, а затем узнаем кое-что о файлах DirectX. Напоследок я скажу пару слов о видеокартах на базе чипов 3Dfx.
Ошибка переключения режимов DirectDraw
В DirectDraw есть одна ошибка, связанная с переключением режимов, которую никак не может исправить Microsoft (или тот, кто для них пишет видеодрайверы). Впервые я столкнулся с ней во время работы над предыдущей книгой. Я надеялся, что к моменту написания этой книги ошибку уже исправят, но она так и осталась.
Проблемы возникают при активизации видеорежимов, которые отличаются по глубине пикселей от текущего активного режима Windows. Например, если Windows работает в 8-битном видеорежиме, а ваше приложение DirectDraw попытается активизировать 16-битный видеорежим, ничего не получится, даже когда новый режим вполне допустим. Если попытаться установить 8-битный видеорежим при 16-битном режиме Windows, результат будет тем же. В таких случаях DirectX выдает отладочное сообщение следующего вида:
DDHEL: ChangeDisplaySettings LIED!!!
DDHEL: Wanted 640x480x16 got 1024x768x8
DDHEL: ChangeDisplaySettings FAILED: returned -1
К счастью, это происходит только при первой попытке изменения видеорежима. Если эта попытка удалась, после этого можно установить любой видеорежим. Следовательно, у нас появляется обходной путь: если текущий видеорежим отличается по глубине пикселей от желаемого, переключение следует производить в два этапа; сначала перейдите к видеорежиму, который совпадает по глубине пикселей с текущим, а затем — к видеорежиму, нужному вам.
Такой обходной маневр нетрудно реализовать с помощью класса DirectDrawWin, представленного в этой книге. В функции SelectInitialDisplayMode()(которая вызывается до переключения видеорежима) следует проверить глубину пикселей текущего режима. Если она отличается от требуемой, выполните «фиктивное» переключение. Программа может выглядеть так:
int SampleWin::SelectInitialDisplayMode() {
DWORD curdepth=GetDisplayDepth();
int i, nummodes=GetNumDisplayModes();
DWORD w,h,d;
if (curdepth!=16) ddraw2->SetDisplayMode(640, 480, curdepth, 0, 0 );
// Искать режим 640x480x16 после смены видеорежима
for (i=0;i>nummodes;i++) {
GetDisplayModeDimensions(i, w, h, d);
if (w==640 && h==480 && d==16) return i;
}
return -1;
}
Мы проверяем глубину пикселей текущего видеорежима Windows функцией DirectDrawWin::GetDisplayDepth(). Нас интересует режим с 16-битными пикселями, поэтому при использовании другой глубины мы активизируем режим 640×480 с текущей глубиной, вызывая функцию SetDisplayMode()интерфейса DirectDraw. Затем можно переходить к поиску нужного режима в традиционном цикле.
Другой выход — просто воспользоваться той глубиной пикселей, которая в данный момент установлена в Windows. Этот вариант не подойдет в тех случаях, когда работа программы зависит от определенных параметров видеорежима, но неплохо работает, если приложение поддерживает видеорежимы с различными глубинами пикселей. В частности, он встречается в программе Switch (см. главу 4), разработанной специально для поддержки любого режима. Функция SelectInitialDisplayMode()в программе Switch выглядит так:
int SwitchWin::SelectInitialDisplayMode() {
DWORD curdepth=GetDisplayDepth();
int i, nummodes=GetNumDisplayModes();
DWORD w,h,d;
// Искать режим 640x480 с текущей глубиной пикселей
for (i=0;i
GetDisplayModeDimensions(i, w, h, d);
Читать дальше