Если вы несколько неудовлетворены видеорежимом 13h и хотите чего-то большего, но не уверены, что сможете обеспечить совместимость программ со всеми существующими видеоадаптерами, а также опасаетесь, что переход к высокому разрешению значительно замедлит скорость вывода на экран, то, возможно, вам подойдет способ программирования видеоадаптера в режиме 640x400x256 цветов, предложенный в работе 11|. Или даже в режиме 800x600x256, описанный в статье [2].
Перед тем как сделать свой выбор, давайте вспомним, с каким разрешением приходилось работать видеоадаптерам IBM-совместимых компьютеров, и попытаемся понять связь между разрешением экрана по вертикали и разрешением по горизонтали. Для этого рассмотрим величину, называемую aspect ratio, представляющую собой отношение размера точки растра по горизонтали к ее размеру по вертикали.
Для различных видеорежимов это отношение может изменяться в довольно широких пределах (см. таблицу).
При анализе таблицы следует учитывать два обстоятельства: во-первых, особенностью человеческого восприятия является более высокая требовательность к разрешению по горизонтали, чем по вертикали, и, во-вторых, для некоторых приложений значительно более удобным или просто необходимым является равенство разрешения по вертикали и по горизонтали, причем особенно там. где требуется возможно более точное соответствие изображения на экране твердой копии, или тогда, когда необходимо вращать изображение в плоскости экрана, например, в инженерной графике, в издательском деле и для летных имитаторов.
На ранних этапах развития ПК. когда оптимизировалось использование каждого килобайта видеопамяти (как с точки зрения стоимости видеоадаптера, гак и с точки зрения скорости перерисовки изображения), рассматриваемое соотношение было меньше единицы, а иногда даже меньше 1/2. Ранее я уже высказывал предположение, «гго оптимальным является соотношение, величина которого равна золотому сечению (примерно 0.62), что близко нестандартному режиму 720×350. Однако глубокое перепрограммирование видеоадаптера не входит в наши задачи, так «получше остановиться на режиме 640×400.
Все современные режимы высокого разрешения имеют aspect ratio, равное 1, что связано главным образом с особенностями Windows, а именно с отсутствием возможности переопределять вилсорежим, подбирая оптимальный для каждого приложения. При этом оптимальность приносится в жертву универсальности, да и сама задача подбора в значительной степени утратила актуальность из-за стремительного роста мощности П К. Однако, несмотря на господство Windows практически во всех областях применения персональных компьютеров, разработчики игр по-прежнему отдают предпочтение DOS, дающей возможноть управлять всеми ресурсами компьютера, в том числе и выбором разрешения экрана.
Игры в зеркале видеорежимов
Игры с точки зрения необходимого экранного разрешения можно разделить на четыре группы.
Игры на неподвижном фоне. При оптимальном программировании вполне достижимо разрешение 800×600.
Игры на подвижном фоне. Это большая часть стратегических и аркадных итр с видом со стороны. Разрешение — от 640×400 (для аркадных допустимо и ниже) до 800×600.
Игры со значительной долей анимации (или только анимация). Проблем с выводом на экран нет, могут возникнуть проблемы с местом, отводимым для хранения изображений. скоростями считывания данных с диска и декомпрессии изображения. Рекомендуемое разрешение — нс выше 640×480.
Игры с видом от первого лица. Фон должен просчитываться по законам перспективы, и поэтому заранее подготовленные картинки неприменимы. Большая часть времени тратится на вычисление изображения, а нс на вывод его на экран. В настоящее время такие игры по сложности можно разделить натри подгруппы:
простейшие, когда все действие происходит на одном уровне, все стены, полы и потолки пересекаются под прямыми углами, все остальные объекты представлены растровыми масштабируемыми картинками. Первая игра подобного рола — Wolfensten3D — работала даже на процессоре 286. Оптимальное разрешение — 640×400 (компьютер как минимум 486 DX2-66 VESA/PC1):
средней сложности, когда пол и потолок всегда горизонтальны, но могут располагаться на различных уров
нях. стены всегда вертикальны, но могут пересекаться под произвольным углом, а все остальные объекты представлены растровыми масштабируемыми изображениями. Первая игра такой сложности – Doom. Рекомендуемое разрешение — до 360×240;
высшей сложности, когда все объекты состоят из полигонов, а фон — из плоскостей, пересекающихся под произвольными углами. Первой такой игрой, вероятно, можно назвать Descent, а может быть и более ранние летные имитаторы. Поскольку при малом числе полигонов из-за высокого разрешения подчеркиваются угловатость и схематичность моделей, а большое порождает слишком высокие требования к аппаратуре, рекомендуется разрешение 320×200. но даже при этом необходим процессор Pentium.
Для летных имитаторов и других игр, в которых угол крена может отличаться от нуля, вероятно, лучше выбрать разрешение 320×240.
Что лучше?
Итак, каков же итог’? Давайте примем, что мы будем рассматривать лишь режимы с 256 цветами. Все рассматриваемые режимы с разрешением 320×200.320×240, 320×400, 360×480. 640×400, 640×480 и 800×600 можно запрограммировать, используя технику’, описанную в работах [1—3].
Режим 320×240. получивший имя собственное ModeX, широко используется в играх и легко получается из хорошо известного 320×200. Он может быть реализован на любом VGA-адаптере, т. с. относится не к SVGA, а к нестандартным VGA-режимам, следовательно, его рассмотрение выходит за рамки настоящей статьи, поэтому мы его непосредственно касаться нс будем, но практически все рекомендации, изложенные ниже, применимы и к нему.
Режимы 320×400 и 360×480 могут вызвать, скорее всего, лишь академический интерес, хотя, если как следует задуматься, то можно, наверное, подобрать такие приложения, для которых эти режимы окажутся оптимальными. Разрешение 640×400, на мой взгляд, является наиболее перспективным и обладает следующими преимуществами по сравнению с 640x480x256:
— требуется меньше видеопамяти (256 Кбайт, а не 512 Кбайт);
— осуществляется на 20% меньше вычислений при практически том же качестве (из-за неоптимальной величины aspect ratio при разрешении 640×480 улучшение незаметно);
— отсутствует необходимость в отслеживании межсегментного перехода при 16-разрядном коде, что еще более повышает производительность;
— можно не использовать видеосегмент B000h, что снижает требования к условиям успешной работы программы [2];
— позволяет организовал, две страницы видеопамяти (при использовании видеосегмента B000h), а не одну, как при разрешении 640×480;
— обеспечивает частоту регенерации экрана не ниже 70 Гц, тогда как при 640×480 частота может составить только 60 Гц.
Несколько советов
Режим 800×600 может оказаться полезен для стратегических игр на большой карте, а также для игр типа Strip Poke:). Практически все сказанное ниже относится и к нему.
Сначала приведу несколько советов, полезных для любого из видеорежимов, в которых вы программируете. Не обессудьте, если некоторые из них покажутся вам тривиальными.
В вашей графической библиотеке нс должно быть ни процедуры типа PutPixel, ни аналогичной по назначению. И хотя это во много раз быстрее, чем при использовании BIOS, для игр и анимации это недопустимо медленно. Игровая программа должна обращаться к процедурам работы с полигонами, растровыми изображениями и другими достаточно крупными объектами.
Для того чтобы передвинуть какой-либо объект относительно фона, как правило, сначала восстанавливают фон под объектом, стирая объект, а затем рисуют его в новом месте. Эту процедуру следует проводить не на видимом экране, а на теневом или виртуальном либо в буфере, куда помешают сохраненный фрагмент фона. Виртуальный экран — это та область оперативной памяти, в которой вы формируете изображение, чтобы затем одной быстрой операцией пересылки перенести его на реальный экран (видимый или теневой).
Теневой экран (теневая страница) — часть видеопамяти. Если позволяет объем видеопамяти, то можно организовать несколько страниц, на каждой из которых можно поместить изображение, однако в любой момент времени видимой является только одна, а все остальные — теневые. Любую из таких страниц можно сделать видимой.
Если вы создали теневые страницы, то используйте их только для записи, гак как скорость чтения из видеопамяти обычно более чем на порядок ниже скорости чтения из оперативной памяти. При подготовке изображения на экране обычно сначала рисуют фон, а затем поверх него все объекты, переходя от дальних к ближним. Таким образом. некоторые точки прорисовываются по два раза и более. Если коэффициент перекрытия превышает 1,5—2, то предпочтение следует отдать виртуальному экрану, гак как скорость записи в видеопамять, как правило, меньше
скорости записи в обычную память более чем в 2 раза. Следовательно, работа с теневыми экранами не исключает организации виртуальных.
В общем случае работа с теневыми экранами происходит медленнее, чем с виртуальными, так как пересылка данных из виртуального экрана на видимый осуществляется быстрее, чем переключение страниц, и требует более аккуратного программирования, зато при отсутствии ошибок (они могут проявляться далеко не на всех видеоадаптерах, что усложняет отладку) гарантирует отсутствие каких-либо помех.
Вы ведь хотите, чтобы программа работала на любом компьютере, а если это невозможно, то ей следует вместо таинственных оптических эффектов выдавать вразумительные сообщения, чередующиеся с извинениями и обещаниями исправить все в следующей версии. Для этого желательно предусмотреть специальную программу настройки, которая тестирует оборудование один раз при установке программы, а не при каждом запуске, и создает специальный файл конфигурации, в котором отражает обнаруженные ею особенности. Что должна делать основная программа при отсутствии файла конфигурации — запускать программу настройки автоматически или выдавать на экран просьбу сделать это вручную — дело ваше. В файл конфигурации целесообразно вписать номер нужного видеорежима, так как при отсутствии поддержки VESA может понадобиться довольно длительное тестирование аппаратуры 11 ].
Если вы используете несколько страниц, то следует проверить, как реагирует видеоадаптер на их переключение. Некоторые делают это сразу, а другие ждут импульса обратного хода луча верти кал ьной развертки. Если вы не произведете этой проверки, то программа может начать готовить следующий кадр изображения не на той странице, на которой вам бы хотелось, и часть экрана будет испорчена. Программа конфигурации должна также проверить, допускает ли тестируемая видеоплата работу с 32-разрядными словами. Если работа невозможна, то пользователь может увидеть картинку через густую решетку из черных вертикальных полос. Вряд ли ему это понравится. Обнаруженную особенность следует занести в файл конфигурации, и в зависимост от результата тестирования основная программа должна осуществлять пересылки на экран либо двойными, либо одинарными словами.
Видимо, вам придется работать с виртуальными экранами. Даже если вы используете несколько страниц, то на виртуальном экране можно хранить фон. Виртуальный экран целесообразно организовать в виде четырех сегментов, соответствующих цветовым плоскостям видеоадаптера.
Фрагмент библиотеки для работы с экранами приведен в листинге.
Отображение из виртуального экрана в видеопамять лучше производить последовательно, сегмент за сегментом, операторами пересылки строки (процедура ToVgaScreen). Может быть организовано несколько виртуальных экранов, один из которых является активным. Перед работой процедура проверяет, имеется ли активный экран, а затем пересылает в видеопамять поочередно все сегменты виртуального экрана. Дескрипторы сегментов хранятся в массиве Screens, куда заносятся при отведении памяти для виртуального экрана. Для общности в тексте программы предполагается, что ассемблер «не знает» 32-разрядных команд, а если это не так, то комбинацию db $66 movsw можно заменить на movsd. Естественно, библиотека должна содержать и 16-разрядный вариант этой под-программы для видеоадаптеров, не поддерживающих возможность передачи данных двойными словами.
Крупные и неподвижные прямоугольные объекты целесообразно выводить на экран тем же методом, каким происходит пересылка данных между экранами. Для этого изображения должны быть заранее (лучше на стадии написания программы) разбиты на четыре облает, каждая из которых соответствует своей плоскост видеопамяти. Мелкие и перемещающиеся изображения, а также изображения со сложной границей (спрайты) лучше выводить по столбцам (процедура PtBI). и, кроме того, они должны таким же образом размещаться и в памяти. Приведенная процедура слу-жит для отображения прямоугольных изображений, изображения сложной формы выводятся сходным образом.
в листинге приведена только одна процедура работы с реальным экраном. В общем-то все построения целесообразно выполнять на виртуальном экране, а на реальный сбрасывать уже готовое изображение. Однако может оказаться полезной и процедура, сбрасывающая на реальный экран лишь фрагмент виртуального экрана, тогда, когда есть уверенность, что остальная часть изображения осталась неизменной.
Процедуры рисования точки и заливки экрана одним цветом помешены в листинг в демонстрационных целях. В реальной работе они вам вряд ли понадобятся. Следует обратить внимание лишь на то, что при заливке за одно обращение к видеопамяти закрашиваются четыре точки.