Навигация
Главная
Поиск
Форум
FAQ's
Ссылки
Карта сайта
Чат программистов

Статьи
-Delphi
-C/C++
-Turbo Pascal
-Assembler
-Java/JS
-PHP
-Perl
-DHTML
-Prolog
-GPSS
-Сайтостроительство
-CMS: PHP Fusion
-Инвестирование

Файлы
-Для программистов
-Компонеты для Delphi
-Исходники на Delphi
-Исходники на C/C++
-Книги по Delphi
-Книги по С/С++
-Книги по JAVA/JS
-Книги по Basic/VB/.NET
-Книги по PHP/MySQL
-Книги по Assembler
-PHP Fusion MOD'ы
-by Kest
Professional Download System
Реклама
Услуги

Автоматическое добавление статей на сайты на Wordpress, Joomla, DLE
Заказать продвижение сайта
Программа для рисования блок-схем
Инженерный калькулятор онлайн
Таблица сложения онлайн
Популярные статьи
OpenGL и Delphi... 65535
Форум на вашем ... 65535
21 ошибка прогр... 65535
HACK F.A.Q 65535
Бип из системно... 65535
Гостевая книга ... 65535
Invision Power ... 65535
Пример работы с... 65535
Содержание сайт... 65535
ТЕХНОЛОГИИ ДОСТ... 65535
Организация зап... 65535
Вызов хранимых ... 65535
Создание отчето... 65535
Имитационное мо... 65535
Программируемая... 65535
Эмулятор микроп... 65535
Подключение Mic... 65535
Создание потоко... 65535
Приложение «Про... 65535
Оператор выбора... 65535
Реклама
Часовая мастерская в барнауле ремонт и реставрация часов часовые мастерские.
Сейчас на сайте
Гостей: 5
На сайте нет зарегистрированных пользователей

Пользователей: 13,372
новичок: vausoz
Новости
Реклама
Выполняем курсовые и лабораторные по разным языкам программирования
Подробнее - курсовые и лабораторные на заказ
Delphi, Turbo Pascal, Assembler, C, C++, C#, Visual Basic, Java, GPSS, Prolog, 3D MAX, Компас 3D
Заказать программу для Windows Mobile, Symbian

Диплом - база данных поставщиков на Delphi (MS Sql Server)+ Пояснительна...
Принадлежит ли точка пересечению двух окружностей на Turbo Pascal + Отче...
Моделирование работы аэропорта на GPSS + Пояснительная записка

Вывод текста в режиме 256 цветов
Сергей Андрианов
17.12.2001


В статье «Палитра VGA: управление цветом» было рассказано о том, как правильно вывести спрайт на экран. Теперь настала очередь разобраться с текстом. Нетрудно догадаться, что единственный способ его вывода на экран — прорисовка каждой буквы по точкам, т. е. здесь применяется та же самая технология, которая уже была рассмотрена на примере отображения спрайтов. Самый универсальный вариант — выводить каждую букву как спрайт, тем более что при этом можно применить красивые многоцветные буквы различного размера. Однако, во-первых, на экране с разрешением 320x200 точек не очень-то развернешься с крупными шрифтами, а при использовании мелких трудно получить что-нибудь более удачное, чем стандартный шрифт. Во-вторых, даже при размере символа 8x8 точек для хранения одного шрифта придется отвести 16 Кбайт оперативной памяти. И в-третьих, такие шрифты нужно самостоятельно рисовать, что при 256 символах нелегкий труд, да и довольно бессмысленный для небольшой игрушки. Поэтому в качестве альтернативы пойдем по самому простому и наименее ресурсоемкому пути и выберем стандартный шрифт, который ничто не мешает сочетать со спрайтовыми.

В VideoBIOS компьютера помещена таблица со шрифтами разных размеров: 8x8, 8x14 и 8x16 точек. В России они, как правило, хранятся в теле резидентной программы, проводящей русификацию. Будем работать с самым «экономичным» из них — 8x8 точек, но для этого нужно знать адрес той ячейки памяти, с которой начинается его размещение. Этот адрес можно получить с помощью функции VideoBIOS (см. листинг 1). Для его хранения предусмотрена переменная FontTable. Ее значение ставится в блоке инициализации модуля, и тогда не требуется вызывать никаких дополнительных процедур, а шрифты станут доступны, начиная с первой строки основной программы. Надо сказать, что память при этом не расходуется (не считая 4 байт на указатель), поскольку используются шрифты, загруженные в ОЗУ.

Итак, приступим к выбору цветов для символов и фона. Вопрос не такой уж простой, каким кажется на первый взгляд. Дело в том, что после установки палитры в первых 16 регистрах уже не будет тех цветов, к которым все привыкли: 0 — черный, 1 — синий, 2 — зеленый и т. д. Конечно, можно смириться с этим и просмотреть большую простыню1 с описанием всех 256 цветов, чтобы отобрать самый подходящий. Правда, для работы все равно придется ограничиться таблицей с номерами все тех же хорошо знакомых 16 цветов, а раз так, не проще ли поручить компьютеру конвертировать привычные для нас номера в номера рабочей палитры. Однако тогда мы уже не сможем применять для отображения текста остальные 240 цветов, но так ли уж велика эта потеря? Мне, например, более симпатичен именно такой вариант.

У редактора Paint, с помощью которого рисовались спрайты для нашей программы, есть своя любимая палитра. Если создавать картинку с нуля или преобразовать полноцветное (24-разрядное с 16 млн. цветов) изображение в палитровое (8-разрядное 256-цветное), то этот редактор будет работать с одной и той же палитрой. Хотя ее цвета могут оказаться не самыми оптимальными для решения нашей задачи, есть уверенность, что все выполненные изображения будут воспроизводиться на экране в правильных цветах. Номера цветов палитры Paint, наиболее близкие к стандартным 16, хранятся в массиве Colors нашей программы. Если 16 цветов все-таки будет не хватать, длину этого массива можно увеличить. На нулевом месте записан номер черного цвета, на первом — синего и т. д. Если вы выберете какую-либо другую палитру, то цифры придется подкорректировать. Можно, конечно, подбор цветов поручить и компьютеру, но тогда такую процедуру придется вызывать только после установки палитры. Впрочем, этот блок позволяется разместить и в модуле программы, устанавливающем палитру, однако мне хотелось сделать так, чтобы все модули были независимы друг от друга.

Модуль вывода изображения на экран в режиме 256 цветов содержит следующее:
процедуру задания параметров вывода текста SetTextParm, с помощью которой можно установить цвет символов, цвет фона под символами (если он будет отображаться), а также способ вывода текста (с прозрачным или с непрозрачным фоном);
дополнительную процедуру запроса текущих параметров текста GetTextParm. В обеих приведенных выше процедурах используются номера цветов, соответствующие стандартной палитре;
процедуру вывода текстовой строки в определенное место экрана PutText. Даются координаты верхнего левого угла прямоугольника, в котором будет выведена первая буква, т. е. так же, как и для спрайтов. Процедура не проверяет вероятность выхода за пределы экрана и не производит перенос на следующую строку, — забота об этом лежит на программисте;
процедуру вывода отдельного символа PutChar, которая используется процедурой PutText, но имеет и отдельный вход в интерфейсной части модуля;
процедуру вывода точки на экран PutPixel и функцию GetPixel, возвращающую цвет запрошенной точки. Первая используется, в свою очередь, процедурой PutChar, а вторая введена лишь для большей полноты картины. Если эти процедуры необходимы, то следует скопировать их заголовки в интерфейсную часть модуля (изначально они отсутствуют). Но вряд ли это целесообразно, поскольку поточечный вывод изображения происходит очень медленно, а в модуле вывода текста используется лишь потому, что сам текст занимает обычно лишь очень небольшую долю экрана и, кроме того, не перерисовывается на каждом кадре.

Как уже было сказано, буквы выводятся по одной точке, каждой из которых на экране отводится 1 байт, а вот в шрифтах они лежат гораздо компактнее: на одну точку приходится один бит. Весь горизонтальный ряд точек помещается в одном байте, а вся буква — в восьми. При отрисовке буквы перед записью байта в видеопамять проверяется, что находится в нужном бите таблицы шрифтов: 0 или 1. В нашем примере будем выводить надписи в каждом кадре, что более наглядно.

Чтобы посмотреть, как работает описанный модуль, следует включить его имя в директиву uses, описать дополнительную типизированную константу TextColor : byte = 0 и вставить фрагмент, приведенный в листинге 2, между вызовами процедуры отрисовки спрайта PutSprite и процедуры ожидания луча обратного хода WaitVerticalRetrace. На экране должна появиться переливающаяся разными цветами надпись, одна половина которой отображается на непрозрачном фоне, а другая — на прозрачном.

Однако за простоту и нетребовательность к ресурсам приходится платить: предлагаемый способ вывода текста не обладает свойствами спрайта и портит под ним фон. Так что если текст требуется часто перерисовывать, то следует либо самому заботиться о сохранении фона, либо задать его непрозрачным.
листинг 1
interface

{ установка параметров вывода текста }
procedure SetTextParm(color,bkcolor,typetext:byte);
{ color - цвет текста }
{ bkcolor - цвет фона }
{ typetext = 0 - прозрачный фон }
{ typetext = 1 - непрозрачный фон }

{ запрос текущих параметров }
procedure GetTextParm(var color,bkcolor,typetext:byte);

{вывод текста по координатам x,y (верхний левый угол)}
procedure PutText(x,y:word;text:string);

{вывод символа по координатам x,y (верхний левый угол)}
procedure PutChar(x,y:word;chr:char);

implementation
uses dos;
type
FTType = array[0..255,0..7]of byte; {для шрифта}
const
Colors : array[0..15]of byte =
( 0, 2, 20, 22,160,162,172,182,
109,111,125,127,237,239,253,255);
{цвета, соответствующие номерам 0-15}
var
FontTable : ^FTType; {таблица шрифта}
Color1,bkColor1 : byte;
{номера <стандартных> цветов текста и фона}
Color2,bkColor2 : byte;
{номера цветов текста и фона в выбранной палитре}
TextType : byte; {способ вывода (прозрачно или нет)}

procedure SetTextParm(color,bkcolor,typetext:byte);
begin
Color1 := color;
bkColor1 := bkcolor;
TextType := typetext;
Color2 := Colors[Color1];
bkColor2 := Colors[bkColor1];
end;

procedure GetTextParm(var color,bkcolor,typetext:byte);
begin
color := Color1;
bkcolor := bkColor1;
typetext := TextType;
end;

procedure PutText(x,y:word;text:string);
var
i:word;
begin
if(byte(text[0])>0)then
for i := 1 to byte(text[0]) do
putchar(x+8*(i-1),y,text[i])
end;

procedure PutPixel(x,y:word;c:byte); {вывод точки}
begin
mem[SegA000:x+y*320] := c;
end;

function getpixel(x,y:word):byte; {запрос цвета точки}
begin
getpixel := mem[SegA000:x+y*320];
end;

procedure putchar(x,y:word;chr:char);
var
i,j,k,l : word;
cc,bb : byte;
begin
l := byte(chr);
case TextType of
0: for i := 0 to 7 do { прозрачный фон }
for j := 0 to 7 do
if (FontTable^[l,i] and
(1 shl (7-j)) <> 0) then
putpixel(x+j,y+i,Color2);
1: for i := 0 to 7 do { непрозрачный фон }
for j := 0 to 7 do
if (FontTable^[l,i] and
(1 shl (7-j)) <> 0) then
putpixel(x+j,y+i,Color2)
else putpixel(x+j,y+i,bkColor2);
end;
end;

var r : registers;

begin {инициализация - получаем адрес таблицы шрифтов}
r.ax := $1130;
r.bh := 3;
intr($10,r);
FontTable := ptr(r.es,r.bp);
Color1 := 15; {заносим величины по умолчанию}
bkColor1 := 0;
TextType := 1;
Color2 := Colors[Color1];
bkColor2 := Colors[bkColor1];
end.

листинг 2
inc(TextColor);
SetTextParm(TextColor div 16, (TextColor + 48) div 16,1);
PutText(56,16,'Демонстрационная');
SetTextParm(TextColor and $F,0,0);
PutText(192,16,'программа');
Опубликовал Kest October 31 2008 20:16:37 · 0 Комментариев · 10881 Прочтений · Для печати

• Не нашли ответ на свой вопрос? Тогда задайте вопрос в комментариях или на форуме! •


Комментарии
Нет комментариев.
Добавить комментарий
Имя:



smiley smiley smiley smiley smiley smiley smiley smiley smiley
Запретить смайлики в комментариях

Введите проверочный код:* =
Рейтинги
Рейтинг доступен только для пользователей.

Пожалуйста, залогиньтесь или зарегистрируйтесь для голосования.

Нет данных для оценки.
Гость
Имя

Пароль



Вы не зарегистрированны?
Нажмите здесь для регистрации.

Забыли пароль?
Запросите новый здесь.
Поделиться ссылкой
Фолловь меня в Твиттере! • Смотрите канал о путешествияхКак приготовить мидии в тайланде?
Загрузки
Новые загрузки
iChat v.7.0 Final...
iComm v.6.1 - выв...
Visual Studio 200...
CodeGear RAD Stud...
Шаблон для новост...

Случайные загрузки
Trojan [Исходник ...
Библия хакера 2. ...
TmxOutlookBarPro
FilesInfo
Модифицированная ...
SysInfo [Исходник...
Pirc
Генетический алго...
Шейдеры в Delphi
PCX
Delphi и технолог...
TelBook
ComboBox97
Импорт новостей ...
DelphiX
Экранная лупа
Программирование ...
EditButton
SUIPack
AboutSystem

Топ загрузок
Приложение Клие... 100774
Delphi 7 Enterp... 97839
Converter AMR<-... 20268
GPSS World Stud... 17014
Borland C++Buil... 14194
Borland Delphi ... 10293
Turbo Pascal fo... 7374
Калькулятор [Ис... 5984
Visual Studio 2... 5207
Microsoft SQL S... 3661
Случайные статьи
Создание потоков. ...
Управление ресурса...
сервера и сведения...
Процедура GetTextS...
Классы ORM.
Стандарты кодирования
Профили плотности ...
Для входа в просмо...
Горилла: теннисные...
Casino Pharaon
Игровые автоматы В...
Предсказуемость во...
Разделяемая память.
Мультиплексировани...
ГЛАВА 7. ЕЩЕ НЕСК...
Итератор end
Операторы ввода-вы...
ThisForm.PageFrame1.
Фотоаппарат Canon:...
Применение беспров...
Проблемы, связанны...
Расчет токов корот...
О казино
Средства для прогр...
east.microsoft.
Статистика



Друзья сайта
Программы, игры


Полезно
В какую объединенную сеть входит классовая сеть? Суммирование маршрутов Занимают ли таблицы память маршрутизатора?