|
Часть 7
6. Расширения Turbo Pascal
-----------------------------------------------------------------
Данный раздел книги не предназначен для изучения в качестве
введения в языки программирования или написания прикладных
программ.
Пользователи, которым нужна более подробная информация по
Turbo Pascal, языку машинных кодов и т.д., должны обратиться к
руководствам или многочисленным книгам по этим языкам. В данной
книге будут рассмотрены только конкретные вопросы. Конечно, при
чтении данной книги определенные знания по языкам
программирования необходимы, однако они не являются абсолютным
условием для чтения книги.
Мы представим листинги нескольких коротких программ, которые
могут быть скомпилированы и выполнены в Turbo Pascal фирмы
Borland Software.
Эти небольшие программы демонстрируют некоторые возможности
программирования для платы VGA. Особенно выделяется режим 19, так
как он позволяет использовать 256 цветов из 262144. Хотя Turbo
Pascal версий 4.0 и старше имеет множество графических команд,
доступ к режиму 19 в нем не предусмотрен.
Программирование полностью происходит на Паскале, так что
доступ к машинным командам не требуется.
Модули, служащие расширениями языка Паскаль, также написаны
на Turbo Pascal. Любые процедуры в этих модулях могут быть
настроены программистом по его требованиям. Эти подпрограммы
легко могут быть включены в другие программы, что делает
программирование для платы VGA в Паскале более простым и
одновременно более мощным.
6.1 Основы Паскаля
-----------------------------------------------------------------
Для работы с приводимыми программами требуется Turbo Pascal
версий 4.0 и старше. Для полного понимания этих программ также
требуется хорошее практическое знание языка Паскаль. Однако, даже
начинающие работать на Паскале программисты, скорее всего, смогут
понять базовую идею, лежащую в основе этих примеров.
Команды в этих программах также могут быть запрограммированы
в Turbo Pascal версии 3.0 или даже на Turbo BASIC.
Пользователи, мало заинтересованные или вообще не
интересующиеся Паскалем, могут обратиться к главам, в которых
рассматриваются законченные пакеты программ.
6.1.1 Требования для использования Паскаля
-----------------------------------------------------------------
Чтобы выполнить следующие программы и воспользоваться всеми
преимуществами доступа к 256 цветам из 262144, требуется PC с
платой VGA, правильно подключенной к аналоговому монитору.
Кроме того, важную роль играют некоторые дополнительные
процедуры на Паскале. Эти процедуры помогут вам создать свои
собственные команды. Эти команды затем легко могут быть
использованы как и любые другие команды стандартного Паскаля.
Возможность писать собственные команды и включать их в
качестве расширений стандартного языка это свойство, приближающее
Паскаль к языку программирования Forth. На языке Forth каждая
создаваемая вами программа становится новым словом команды самого
языка программирования.
То же самое справедливо для модулей Паскаля. Создавая новые
модули Паскаля, вы можете расширять язык по своему усмотрению. По
мере того, как все новые пользователи будут создавать свои модули
Паскаля, этот язык программирования будет продолжать расширяться,
отвечая изменяющимся требованиям в мире PC.
6.1.2 Создание модуля Паскаля
-----------------------------------------------------------------
Модуль Паскаля можно рассматривать как набор процедур на
языке Паскаль. Следующий фрагмент программы (не предназначенный
для того, чтобы вы его реально вводили и выполняли) может служить
в качестве общего примера использования модуля на Паскале:
Unit VGA { начало модуля }
interface { заголовок модуля }
uses dos,crt { использовать другие модули - dos и crt }
var Color : Integer; { общие переменные модуля }
{ первая строка каждой процедуры модуля }
implementation { главное тело модуля }
Procedure MODE; { текст программы в процедуре }
var Regs : Registers; { -''- }
begin { -''- }
with Regs do { -''- }
AL:=ModeHexNumber { -''- }
AH:=$00; { -''- }
end; { -''- }
Intr($10,Regs); { -''- }
end; { конец процедуры }
{...дополнительные процедуры }
end. { конец модуля }
Главное тело модуля начинается командой Паскаля
"implementation". Относительно этой команды можно дать следующие
базовые рекомендации.
В этой команде перечисляются имена процедур, перечисленные в
заголовке модуля. Однако, присвоения переменным не повторяются.
Команда оканчивается двоеточием после имени процедуры. Переменные
вводятся только в заголовке модуля и передаются конкретным
процедурам командой "interface". В этом отличие от
программирования вне данного модуля.
Это означает, что список процедур в заголовке модуля это
фактически местоположение первой строки каждой процедуры. Строка,
содержащая имя процедуры в главном теле модуля, служит только как
адрес перехода в модуле. При использовании процедуры модуля вы
всегда должны вводить первую строку процедуры в списке процедур
заголовка модуля. В противном случае логика выполнения программы
в модуле будет аналогична любым другим Паскаль-программам.
Только те переменные, что определены в круглых скоках после
каждой процедуры и названы в списке процедур, могут передаваться
в или из главного тела программы. Это мы обсудим подробнее, так
как непонимание этого вопроса легко может привести к ошибкам в
определении переменных.
Последовательность, в которой процедуры перечисляются в
заголовке, должна быть такая же, что и в команде "implementation"
в главном теле.
При работе с модулем, как и с любыми Паскаль-программами, вы
можете только такую процедуру, которая ранее была введена в
программе. Процедура может использовать другую процедуру только
если та уже выполнялась программой. В противном случае компьютер
не распознает команду, и произойдет ошибка. Особое внимание нужно
обратить на последовательность введения процедур в модуле.
Имя модуля в памяти и в тексте программы должны быть
абсолютно идентичны. В противном случае произойдет ошибка, когда
модуль будет вызван после компиляции. Это может показаться
странным, поскольку обычно в Паскале эти два имени не обязаны
совпадать. Поэтому будьте внимательны с соглашением об именах.
Руководствуйтесь следующим примером:
Если первая строка программы это: Unit Example;
Программа должна храниться как: EXAMPLE.PAS
А после компиляции вы получите: EXAMPLE.TPU
6.1.3 Изменение видео-режима: новая процедура Паскаля
-----------------------------------------------------------------
Для того, чтобы после загрузки системы и запуска программы
на Turbo Pascal изменить экранный режим, вы должны включить
средства управления графикой. Это можно сделать, включив модуль
GRAPH.TPU в вашу программу при помощи командой uses.
Если вы предпочитаете не пользоваться этим средством
(поскольку модуль GRAPH не дает доступа к режиму 19), вам
придется самостоятельно программировать регистры графической
платы.
Следовательно, логично будет создать универсальную команду,
которая даст вам доступ ко всем 17 режимам платы VGA.
Эта команда должна быть доступна в виде текста программы или
процедуры, таким образом, чтобы ее можно было настроить на
использование средств, которые появятся в будущих графических
платах.
Следующий листинг содержит Паскаль-процедуру для изменения
видео-режимов. Она использует прерывание 16 для доступа к двум
регистрам (AL,AH).
Procedure Mode(ModeHexNumber : Integer);
{ заголовок и определение переменной }
var Regs : Registers; { определение внутренних переменных процедуры }
begin { начала текста программы для процедуры }
with Regs do { подготовка регистров AL, AH к прерыванию }
AL:=ModeHexNumber { передача входной переменной видео-режима }
AH:=$00; { функция: установка видео-режима }
end; { конец цикла }
Intr($10,Regs); { вызов прерывания для шестнадцатиричного адреса $10= }
end; { = прерывание компьютера для изменения режима }
Данная процедура начинается с определения входной переменной
и подготовки регистра A. Номер желаемого видео-режима передается
в AL, младшую часть регистра A. В старшую половину регистра, АН,
передается число 0. Это число сообщает компьютеру о необходимости
при выполнении прерывания вызвать функцию для установки
видео-режима.
Вызывается прерывание, выполняющее функцию "установить
видео-режим" с номером желаемого видео-режима в качестве входного
параметра. Если аппаратная конфигурация позволяет выполнить
запрошенное изменение режима, изменение выполняется компьютером,
и результат отображается на экране.
6.1.4 Изменение видео-режимов: текст программы
-----------------------------------------------------------------
Сама по себе процедура не является программой. Показанная
выше процедура должна входить как составная часть в
Паскаль-программу. Программа выполняет запрос и позволяет
пользователю ввести номер желаемого видео-режима.
Program ChangeVideoMode; { начало и имя программы }
uses dos,crt; { использовать модули dos, crt }
var z : integer; { внутренние переменные программы }
procedure VMode(ModeHexNumber:integer)
{ начало процедуры, передача переменной }
var Regs : Registers; { из программы }
begin { в процедуру }
with Regs do begin { }
AL := Modehexnumber; { -''- }
AH := $00; { }
end; { -''- }
Intr($10,Regs); { }
end; { конец процедуры }
begin { начало главной процедуры }
clrscr; directvideo:=false; { очистить экран }
writeln('Пожалуйста введите номер видео-режима:
readln(z); { запрос и ввод }
VMode(z); { выполнение процедуры }
write('Теперь ваша система находится в режиме номер ',z);
{ текстовый вывод в новом режиме }
end. { конец программы }
6.1.5 Переключение на режим 19, шестнадцатиричный номер $13
-----------------------------------------------------------------
Насколько мощны средства работы с цветами платы VGA, можно
почувствовать только при работе в режиме MCGA 19
(шестнадцатиричный номер 13). Этот режим использует разрешение
320*200 пикселей многоцветной графической матрицы, которая была
прямым предшественником VGA. Такое относительно низкое разрешение
оставляет достаточно экранной памяти для вывода 256 цветов,
выбираемых в общей палитры из 262144 цветов.
При правильном программировании вы можете выбрать собственные
256 цветов, так что цветами стандартной палитры вы не ограничены.
Палата VGA также позволяет вам выбрать вашу палитру из общего
числа 262144 цветов в режимах работы, позволяющих иметь
одновременно лишь от 2 до 16 цветов. Вы можете воспользоваться
этим в текстовых режимах, чтобы изменить стандартные цвета,
используемые старыми графическими платами.
Следующий листинг почти идентичен программе "VMODE19" из
раздела "Примеры программ для DOS", поскольку ее скомпилированная
версия тоже может быть запущена из командной строки DOS.
Program VMode19; { строка заголовка без переменных }
var Regs: Registers; { определение внутренних переменных программы }
begin { начало главной части программы }
with Regs do begin { подготовка регистров AL,AH к вызову прерывания }
AL:=$13; AH:=$00; { ввод видео-режима 19 = шест-ричное $13 }
end; { конец цикла }
Intr($10,Regs); { вызов прерывания для шест-ричного адреса $10= }
end. { = функция для изменения видео-режима }
6.1.6 Использование команд из DOS
-----------------------------------------------------------------
Крупным преимуществом программирования на Turbo Pascal
является возможность создавать и хранить компилированные версии
ваших программ.
Компилированные программы имеют суффикс ".EXE". Это
фактически программы на машинном языке, которые могут вызываться
из командной строки DOS без запуска среды Turbo Pascal. Чтобы
воспользоваться командой, достаточно ввести ее имя без расширения
".EXE".
Примером может служить такая программа, как VMODE19,
написанная и скомпилированная с Паскаля. После компиляции
программа хранится на диске как VMODE19.EXE. Этот файл называется
исполняемой программой. Суффикс ".EXE" это сокращение от
"EXEcutable" ("исполняемая") и указывает на возможность
непосредственно запустить эту программу на исполнение.
Для запуска программы из командной строки DOS файл VMODE.EXE
нужно переписать в директорию DOS. Либо вы можете держать
дополнительные команды DOS в отдельной директории. В этом случае
маршрут доступа к этой директории должен быть задан в файле
AUNOEXEC.BAT. Для этого полное имя маршрута доступа к этой новый
директории следует указать в команде PATH файла AUTOEXEC.BAT.
Выполнив указанные шаги, вы сможете вызывать команду VMODE19
из командной строки DOS, как если бы это была стандартная команда
DOS - MODE.
6.2 Манипулирование цветами
-----------------------------------------------------------------
Сравнительно с ранними версиями, плата VGA позволяет
использовать больше цветов. Существуют различные способы
манипулирования цветами вашего текста, рамки и палитры. Всего
общая палитра VGA позволяет выбирать из 262144 цветов.
6.2.1 Цвета рамки в режиме 19
-----------------------------------------------------------------
Чтобы получить красивое цветовое решение экрана, мы должны
прежде всего создать рамку. Рамка экрана не должна мешать работе,
происходящей на экране. Цвета должны быть согласованы друг с
другом.
Следующая процедура выполняет эту задачу, адресуясь к
конкретным функциям BIOS платы VGA через прерывание 16.
Прерывание и регистры позволяют нам изменять установки платы
VGA, как это мы делали для изменения режимов. На этот раз вместо
изменения режимов мы изменим цвет рамки экрана.
Следующий листинг представляет собой Паскаль-процедуру
FRAMECOLOR:
Procedure FRAMECOLOR(ColorNumber:Integer);
{ устанавливает номер цвета рамки }
var Regs:Registers; { регистровые переменные }
begin { начало главной программы }
with Regs do begin { заполнение регистровых переменных: }
AL:=$01; { установка регистра рамки }
AH:=$10; { установка регистра палитры }
BH:=ColorNumber; { ввод цвета рамки }
end; { регистровые переменные заполнены }
Intr($10,Regs); { вызов прерывания по адресу $10 }
end; { конец процедуры }
Эта процедура также может быть встроена в программу или
модуль. Помните, что процедуры в Паскаль-программе вводятся в
заголовок программы под определениями переменных. Если процедура
помещается в модуль, он должен быть введен в заголовок программы
над определениями переменных в операторе uses. В обоих случаях
главная программа (начинающаяся командой Паскаля begin) будет
выглядеть одинаково.
Использование "самодельных" команд Паскаля ничем не
отличается от использование стандартных команд Паскаля.
После того, как процедура создана, любая программа сможет
использовать процедуру FRAMECOLOR(...), передавая ей значения от
0 до 255 (в режиме 19) для выбора в палитре цвета рамки экрана.
Диапазон вводимых значений может варьироваться в зависимости от
режима экрана и числа цветов в соответствующей палитре.
6.2.2 Цвета текста в режиме 19
-----------------------------------------------------------------
В руководстве Heimsoeth/Borland Software описаны различные
способы форматирования текстового вывода при работе с Turbo
Pascal. Существуют две команды:
TEXTCOLOR(ColorNumber);
и
TEXTBACKGROUND(ColorNumber);
Эти команды прекрасно работают при выводе текстов в
большинстве видео-режимов. К сожалению, они не годятся в режиме
19 (шестнадцатиричное 13). Но объединив эти две команды, вы можете выбрать
для текста один из 128 цветов, если цвет номер 0 будет цветом
фона.
Если вы хотите установить новый цвет фона, это можно
сделать, манипулируя цветом номер 0.
Ниже приводится процедура COLORTEXT, предназначенная для
установки цветов текста в режиме 19:
Procedure COLORTEXT(Color:Integer);
begin { установки граничных значений ввода от 0 до 127 }
if Color<0 then Color:=0;
if Color>127 then Color:=127-Color;
textbackground(Color div 16);
textcolor(Color-((Color div 16)*16));
end; { вызовы регистров двумя стандартными командами }
6.2.3 Цветовая палитра в видео-режиме 19
-----------------------------------------------------------------
Манипулирование самой палитрой несколько сложнее. По
аналогии представим, что регистры палитры находятся в большом
здании:
Существует дверь, через которую мы попадаем с улицы
(прерывание $10) в здание (регистр палитры, AH=$10). На цокольном
этаже здания (регистр цвета, AL=$10) находится 256 дверей (номера
в палитре, BX=ввод), ведущих в другие комнаты. Если дверь открыта
(вводом номера в палитре), мы обнаруживаем в комнате три лампы.
Одна из них имеет голубой плафон, одна зеленый, и одна красный
(регистры интенсивности цветовых компонент: CL, CH и DH). Каждая
лампа имеет переключатель яркости, регулирующий ее интенсивность
таким образом, чтобы освещение комнаты имело желаемую цветовую
композицию.
В вашем компьютере это соответствует установке уровней
интенсивности для голубой, зеленой и красной цветовых компонент в
регистрах CL, CH и DH значениями от 0 до 63. Значение 0 означает
вообще отсутствие данной компоненты, а 63 - высшую интенсивность
компоненты.
Поскольку мы имеет три цветовых компоненты, каждая из
которых может иметь 64 разных уровня, то всего палитра может
иметь 64*64*64=262144 цвета.
Однако, работать со всеми этими цветами одновременно
невозможно. В режиме 19 одновременно доступна палитра из 256
цветов.
Возвращаясь к нашей аналогии, для установки палитры из 256
цветов мы должны войти в каждую из 256 комнат и установить там
желаемое освещение.
Примеры цветов: Голубой + Зеленый + Красный = Цвет
63 63 63 = Белый
45 30 30 = Серо-голубой
10 20 0 = Темно-зеленый
Теперь рассмотрим процедуру PALETTE. Она служит для того,
чтобы войти в одну из комнат нашего здания и установить там три
цветовых компоненты для одного выбранного цвета палитры.
Procedure PALETTE(ColorNumber,Blue,Green,Red : byte);
var
Regs:Registers;
begin
with Regs do begin { подготовить регистры к прерыванию }
AL:=$10; { установить регистр цвета }
AH:=$10; { установить регистр палитры }
BX:=ColorNumber; { номер в палитре }
CL:=Blue; { значение интенсивности голубой компоненты }
CH:=Green; { значение интенсивности зеленой компоненты }
DH:=Red: { значение интенсивности красной компоненты }
end;
Intr($10,Regs); { вызов прерывания HEX 10 }
end;
Значение интенсивности каждой цветовой компоненты передается
в виде переменной.
Функции BIOS, предназначенные для установки палитры,
вызываются посредством ввода требуемых значений в соответствующих
регистрах, как это было показано в предыдущем примере.
Номер прерывания, выбранный номер в палитре и значения
цветовых компонент для каждого цвета вводятся вместе. После
передачи этих значений выбранный номер будет содержать
установленный вами цвет. Это может быть любой цвет из общей
палитры VGA.
6.2.4 Упрощенные манипуляции с палитрой
-----------------------------------------------------------------
Описанная выше команда "PALETTE(Номер, Голубой, Зеленый,
Красный)" позволяет пользователю за один вызов установить один
цвет из 256 цветов палитры режима VGA 19.
Если вы хотите при помощи этой команды установить всю
палитру целиком, вам придется вводить значения 256 раз, что
достаточно утомительно. Следовательно, полезно иметь команду,
которая позволила бы сразу устанавливать несколько цветов
палитры.
Процедура BLEND предназначена для создания линейной
последовательности плавного перехода из цвета в цвет внутри
выбранного диапазона номеров. Эта команда избавит вас от
установки каждого промежуточного цвета "вручную".
Оттенки промежуточных цветов в заданном диапазоне аналогичны
тому, как происходит переход при смешении двух акварельных
красок. Использование процедуры PALETTE в ней обязательно:
procedure Blend(Color1,Blue1,Green1,Red1,
Color2,Blue2,Green2,Red2);
var Number,Bl,Gr,Re: Integer;
(* цвета между двумя заданными *)
(* заполняются переходными оттенками *)
begin
Number:= Color2 - Color1;
for x :=0 to Number do begin { создание переходных оттенков }
if Number>0 then begin { Color2 должен быть больше Color1 }
Bl:= (Blue1*(Number-x) + Blue2*(x)) div Number;
Gr:= (Green1*(Number-x)+ Green2*(x))div Number;
Rd:= (Red1*(Number-x) + Red2*(x)) div Number;
end;
Palette(Color1+x,Bl,Gr,Re); { вызов этой процедуры обязателен }
end; end;
6.2.5 Просмотр палитры
-----------------------------------------------------------------
Поэкспериментировав с командами PALETTE и BLEND, вы
создадите тем самым какие-то собственные палитры. До сих пор вы
не могли визуально наблюдать сделанные вами изменения палитры.
Теперь вам понадобится выполнить просмотр палитры, чтобы
посмотреть, какие еще изменения нужно сделать.
Например, если вы хотели создать палитру естественных
цветов, вы должны были учесть, что не следует включать в нее
слишком много необычно ярких цветов. В природе большинство цветов
представляет собой тонкие комбинации аналогичных цветов или серые
тона со слабой примесью цвета. Используя такие цвета, вы не
создадите рисунков с неестественными цветами.
Насыщенные тона нужно использовать специально, если вам
нужно нарисовать яркий цветок, красный свитер, желтый автомобиль,
фиолетовый шарик и т.д. Тем самым вы выделите интересующий вас
предмет на фоне естественных, приглушенных цветов.
Хорошо иметь систематизированный метод создания реалистичных
палитр, который давал бы возможность доступа к широкому диапазону
цветов с разной степенью интенсивности.
Один из этих способов состоит в создании базовой палитры с
16 цветами спектра. Каждый из этих 16 базовых цветов может быть
разбит на 16 уровней интенсивности. Это позволяет иметь общую
палитру в 16*16=256 цветов.
При создании палитры таким способом важно иметь возможность
быстро взглянуть, что же у вас получается. Для этого существует
процедура SHOWPALETTE, которая выводит все 256 цветов текущей
палитры для обзора на экран.
Procedure SHOWPALETTE; { Текущая палитра будет }
begin { выведена на экран. }
for Y:=0 to 199 do begin { По оси X после точки 255 }
for X:=0 to 319 do begin { будут повторены цвета палитры }
PokeY := Y*20 { начиная с номера 0 }
PokeX := X; Color ;= X;
Meml[$A000+PokeY:Pokex]:=Color; { нарисовать цвета на экране }
end; end; end; { конец процедуры }
Данная процедура имеет некоторые особенности, требующие
пояснений. Во-первых, она содержит два вложенных цикла, которые
пробегают по всем 320*200 пикселям экрана в режиме 19.
Каждый цвет диапазона палитры последовательно выводится по
горизонтали, так что цвет вертикальной полосы в каждой
x-координате экрана одинаков. Y-значения должны умножаться на 20,
чтобы соответствовать требованиям команды Паскаля установки
памяти. Значения помещаются в экранную память посредством
предопределенного массива "MEML[...]".
При включении данной процедуры в программу SHOWPALETTE будет
немедленно выводить на экран все 256 цветов текущей палитры
режима 19. Правая часть экрана, с x-координатами больше 255,
будут повторять первые 64 цвета палитры. Если вы не вносили в
палитру никаких изменений, то команда SHOWPALETTE выведет
стандартную палитру VGA. При этом обратите внимание, что в данной
палитре многие номера не определены или установлены в черный
цвет.
Другая проблема состоит в том, что многие цвета
неестественно ярки. Цвета от 0 до 15 соответствуют стандартной
палитре платы EGA. Только номера от 16 до 31 содержат
естественную прогрессию серых тонов от черного к белому. В
стандартной палитре трудно найти рядом друг от друга переходные
оттенки. Например, если вам нужна прогрессия цветов от
светло-голубого к сине-черному для того, чтобы нарисовать небо,
вы должны будете создать свою собственную палитру.
При помощи команды SHOWPALETTE изучите стандартную палитру
VGA. В следующем разделе мы рассмотрим возможности создания
собственных палитр пользователя.
6.2.6 Палитры, настраиваемые пользователем
-----------------------------------------------------------------
В настоящий момент предположим, что вы изучили стандартную
палитру VGA и добавили в нее несколько собственных цветов.
Следующий шаг будет состоять в том, чтобы создать палитру,
целиком состоящую из специально выбранных цветов. Такие
настраиваемые пользователем палитры служат основой дополнительных
средств работы в видео-режиме 19 (шестнадцатиричное 13).
Как уже было сказано выше, хороший способ создания палитры
состоит в том, чтобы выбрать 16 базовых цветов и для каждого из
них еще создать 16 уровней интенсивности. Например, холодный
красный, красный, теплый красный, оранжево-красный, оранжевый,
золотисто-желтый, желтый, зелено-желтый, светло-зеленый, зеленый,
зелено-голубой, синий, голубой, сине-фиолетовый, пурпурный и
пурпурно-красный это хороший пример кольца из 16 базовых цветов.
Переходы между этими базовыми цветами выполняются путем
изменений интенсивности компонент и серых тонов, создавая
натуральную прогрессию.
Например, ярко-красный цвет с цветовыми компонентами
Голубой=0, Зеленый=0 и Красный=63 может быть трансформирован в
красноватый оттенок цвета кожи с компонентами Голубой=37,
Зеленый=42, Красный=62. Этот цвет может быть создан с 16
различными уровнями интенсивности. Повторив этот процесс с 15
другими базовыми цветами, вы получите палитру из 256 натуральных
тонов.
Процедура JANSPALETTE использует команду BLEND для каждого
из 16 базовых цветов для создания разных уровней интенсивности, в
диапазоне от светлых оттенков, через базовый цвет, и к темным
оттенкам. Для создания всех 256 цветов палитры достаточно 32
команд BLEND. Цвет номер 0 определяется отдельно.
6.2.7 Цвета палитры в текстовых режимах
-----------------------------------------------------------------
В случае платы VGA доступ к общей палитры из 262144 цветов
не ограничен режимом 19. Цвета, которые могут быть созданы
командами PALETTE и BLEND, также могут быть использованы в других
виде-режимах, хотя те позволяют одновременный вывод на экран
всего 2, 4, 8 или 16 цветов.
Таким образом, плата VGA не только совместима с прежними
режимами IBM, но и фактически расширяет их возможности, расширяя
общий выбор цветов. Без VGA вы были вынуждены работать с одним и
тем же набором цветов во всех текстовых и графических режимах.
Однако существует одно небольшое ограничение относительно
использования новых цветов VGA в старых режимах. Вы должны будете
переназначить номера цветов вашей палитры.
Например, вам может понадобиться выбрать 16 цветов между 0 и
60 вашей палитре "EGA". В этом случае номера цветов не
соответствуют их позициям в палитре. Это не позволяет работать с
командами PALETTE и BLEND.
Процедура ASSIGNCOLOR служит для того, чтобы установить
номер цвета равным его позиции в палитре. После выполнения этой
процедуры цвет 1 можно вызывать по его номеру 1 в палитре и
манипулировать с ним. Как и в случае PALETTE и FRAMECOLOR, эта
процедура также использует доступ к регистрам.
Используются регистры палитры и прерывание $10.
procedure ASSIGNCOLOR(ColorNumber, Color: integer);
(* Номера в палитре устанавливаются *)
var (* равными позиции в палитре. *)
Regs : registers; (* Это особенно полезно для новых *)
begin (* палитр в текстовых режимах. *)
with regs do begin (* Подготовка регистров к прерыванию*)
AL := $00; (* Передача номеров в порядке *)
AH := $10; (* возрастания, сколько возможно. *)
BL := ColorNumber;
BH := Color;
end;
Intr($10,regs); (* вызов прерывания шестн-ричное $10 *)
end;
Следующая программа, VTEXTCOLOR, демонстрирует работу новых
процедур BLEND, PALETTE и ASSIGNCOLOR. поскольку листинги этих
процедур уже приводились, то их текст здесь не приводится:
Program VTEXTCOLOR; { начало заголовка программы }
uses dos,crt; { вызов других модулей }
var x:integer; { определения/процедуры }
procedure AssignColor(....); { текст см. выше }
procedure Palette(.7..); { текст см. выше }
procedure Blend(..7.); { текст см. выше }
procedure Mode(....); { текст см. выше }
begin { начало главной программы }
Mode($3); { включение текстового режима 3 }
for x:=0 to 15 do AssignColor(x,x); { присвоения номеров }
Blend(0,10,35,50, 15,30,60,30); { новая палитра VGA }
for x:=0 to 15 do begin { программа в цикле выводит }
Textcolor(x); { новый цвет текстов в }
Writeln('Номер цвета = ',x); { текстовом режиме }
end; { конец цикла программы }
end. { конец демонстрации }
Эта программа покажет вам возможности VGA в текстовом режиме
3. Хотя изменения и невелики, но без VGA иметь такой набор более
мягких тонов было бы невозможно.
6.3 Графические команды Режима 19
-----------------------------------------------------------------
Для использования настроенной пользователем палитры в Turbo
Pascal нам потребуется несколько новых команд.
Следующие графические процедуры используют специальные
свойства режима 19 (шестнадцатиричное 13). По сравнению с ранее
рассмотренными процедурами следующая группа команд не может быть
эффективно использована вне режима 19 с его 256-цветной палитрой.
В других видео-режимах существуют стандартные команды
Паскаля, выполняющие примерно те же функции.
6.3.1 Чтение и вывод на экран пикселей
-----------------------------------------------------------------
Процедура PLOT принимает на входе цвет. Ее выходом является
отображение пикселя этого цвета в координатах x,y. Процедура PEEK
считывает номер цвета пикселя с координатами x,y и передает это
значение как целое число.
Procedure PLOT(x,y: Integer; Color:integer);
begin { вывод цветного пикселя в видео-режиме 19 }
if (x<320) and (x>-1) and (y<200) and (y>-1) then
mem[$A000+y*20:x]:=Color
end;
Procedure PEEK(x,y: integer;var OldColor: integer);
begin { чтение номера цвета пикселя в режиме 19 }
OldColor:=GetPixel(x1,y1);
end;
Команда Паскаля mem[] используется для прямых манипуляций с
памятью компьютера. Если раньше вы этой командой не пользовались,
прочтите следующее пояснение:
"Mem" это сокращение от слова "Memory" (память),
относящегося, естественно, к памяти вашего компьютера. Команда
"mem[..]:=значение" заставляет компьютер запомнить заданное
значение. Команда "значение:=mem[..]:" заставит компьютер извлечь
из памяти данное значение.
В первом случае "mem" используется для того, чтобы принять
значение для помещения его в память. Во втором "mem" используется
для выборки из памяти и передачи значения в переменную программы.
Аргумент в квадратных скобках представляет адрес компьютера,
с которым выполняются манипуляции. Например, если вы хотите
адресовать верхний левый угол экрана в режиме 19, то
соответствующий шестнадцатиричный адрес будет равен $A0000.
Команда выполнит чтение по адресу "mem[$A000:0]". Двоеточие,
входящее в адрес, требует дополнительного пояснения.
Оно предназначено для того, чтобы упростить сложение с
базовым адресом экранной памяти. Значение справа от двоеточия
складывается с базовым адресом. При осторожном манипулировании вы
можете складывать координаты x и y с базовым адресом экрана для
того, чтобы адресовать конкретную точку.
Вводимое справа от двоеточия x-значение будет сложено с
базовым адресом. Например, точка в верхнем правом углу будет
иметь адрес $A0000+(десятичное)319, поскольку она находится в 319
пикселях вправо от точки левого угла.
Затем Y-значение, вводимое слева от двоеточия,
непосредственно прибавляется к базовому адресу. Каждое y-значение
умножается на 320, т.к. каждая строка экрана содержит 320 точек.
Для сложения y-значений со второй шестнадцатиричной цифрой
базового адреса мы, следовательно, умножаем его а 320 и делим на
16 (вторая цифра это шестнадцатиричное число), что дает нам
корректирующий коэффициент 20.
Чтобы посмотреть, как это работает, рассмотрим следующую
процедуру:
Procedure Plot(x,y: Integer; Color:integer);
begin { вывод цветного пикселя в видео-режиме 19 }
if (x<320) and (x>-1) and (y<200) and (y>-1) then
mem[$A000+y*20:x]:=Color
end;
Осталось сказать несколько слов об ограничениях команды
PLOT. Третья строка процедуры PLOT ограничивает диапазон
координат вывода пикселя в режиме 19. Это ограничение для команды
PEEK не действует. Команду PEEK можно использовать для чтения
любых точек рисунка, даже если они не видимы в текущий момент на
экране.
6.3.2 Процедура BLOCK
-----------------------------------------------------------------
Теперь, когда мы научились пользоваться процедурами PLOT и
PEEK для манипулирования отдельными пикселями в режиме 19, можно
начинать пробовать создавать на экране рисунки.
Продолжим создание новых процедур и программ на Паскале,
основанных на использовании ранее изученных средств. Например,
процедура BLOCK служит для рисования на экране цветного
прямоугольника. Эта процедура в режиме 19 аналогична стандартной
команде паскаля BAR, которая доступна в других видео-режимах.
В противоположность команде BAR, процедура BLOCK позволяет
выбрать цвет из 256 цветов, доступных в палитре режима 19. Как и
PLOT, эта процедура основана на использовании команды Паскаля
"mem[..]".
Эта процедура проверяет введенные координаты и меняет
их местами, если координаты перепутаны. Далее находятся два
вложенных цикла, создающих координаты прямоугольника. Затем в эта
координаты пиксель за пикселем выполняется вывод с использованием
выбранного цвета VGA:
Procedure BLOCK(x1,y1,x2,y2: integer; Color:integer);
var xcmyc,Keep: integer; { рисует цветной прямоугольник }
begin { при необходимости меняет местами координаты }
if x2-1) and (yc<200) and (yc>-1) then
mem[$A000+yc*20:xc]:=Color; {рисование цветной точки }
end; { конец цикла по y }
end; { конец цикла по x }
end; { конец процедуры }
Для пояснения: цикл по x создает длину горизонтальной
строки, а цикл по y рисует эту строку нужное число раз от y1 до
y2, пока прямоугольник не будет заполнен.
6.3.3 Процедура CIRCLE
-----------------------------------------------------------------
Следующая процедура (см. на дискете) создает цветные
окружности и эллипсы в режиме 19, основываясь на ранее изученных
процедурах "Mode" (чтобы перейти в режим 19) и "Plot". Это также
означает, что процедуры должны быть связаны между собой в
программе.
Процедура CIRCLE принимает x- и y- координаты центральной
точки, значения радиусов по x и y, а также номер цвета.
Отрицательные значения радиальных значений устанавливаются
процедурой в 0. Перед началом цикла рисования значения координат
устанавливаются относительно полюсов окружности. Это означает,
что программа рисует линии от полюса окружности к ее экватору.
Программа использует счетчики для относительных координат,
двух радиальных переменных и счетчик для функции Circle.
Главный цикл программы повторяется до тех пор, пока не будет
достигнут экватор, а относительные y-координаты не станут равными
0.
Процедура работает только с положительными аргументами. Это
означает, что вычисляется только верхний правый квадрант, после
чего форма завершается посредством манипуляций с этими
относительными координатами командой PLOT.
После того, как будут нарисованы первые четыре точки в
четырех квадрантах круга, вычисляются относительные координаты
следующей точки. Вычисления основаны на значениях, генерируемых
функцией Circle. Пока этот счетчик больше или равен 0, происходит
приращение относительной x-координаты и коррекция ее счетчика.
Если счетчик Circle меньше 0, происходит уменьшение
относительного y-значения и коррекция соответствующего счетчика.
Данный сложный способ вычисления позволяет всегда получать
окружности без зазоров, так как координаты x- и y- обе
вычисляются на основе значений функции Circle.
Процедура будет работать только в программе, которая либо
вызывает модуль Turbo Pascal VGA19 (см. ниже) или содержит
процедуры PLOT и MODE. Видео-режим перед вызовом процедуры CIRCLE
должен быть переключен на режим 19 вызовом команды "MODE(19)".
Рис.3: Процедура Circle
Процедура DISK
-----------------------------------------------------------------
Создание изображения диска аналогично созданию изображения
окружности. Размещение точек в четырех квадрантах выполняется без
каких-либо сложных математических расчетов площади круга. Точки
левого и правого квадранта связываются между собой в цикле
программы.
Было бы достаточно просто рисовать горизонтальные линии
отдельной процедурой, однако это удобнее делать подпрограммой.
Выполнение ускоряется, если встроить такую подпрограмму в
процедуру, а не вызывать отдельную процедуру.
Цикл программы рисует линии от полюсов к экватору. Диск
создается на экране на базе задаваемых координат центра,
радиальных составляющих по x и по y и цвета.
Как и прочие процедуры для рисования геометрических форм,
данная процедура работает только в режиме 19. Цвет диска можно
выбрать равным одному из 256 цветов палитры режима 19, причем эту
палитру вы можете определить сами. Помните, что требуется
процедура PLOT, которая должна входить как часть полной
программы. (См. программу на дискете).
6.3.5 Рисование линий в видео-режиме 19 (процедура LINE)
-----------------------------------------------------------------
Как ни странно, процедура, предназначенная для рисования
линий, ничуть не проще процедур для рисования окружностей и
дисков. Фактически она аналогична двум последним. Это происходит
вследствие того, что создаваемые с ее помощью линии не
ограничиваются горизонтальными и вертикальными линиями и могут
проходить через все четыре квадранта экрана. Этот случай уже
рассматривался в процедуре CIRCLE.
Поскольку линии могут иметь разный наклон, мы не можем
просто выполнять положительные или отрицательные приращения по x
и по y для рисования линий. Мы опять должны использовать счетчик,
но на этот раз его значение будет зависеть от наклона линии, а не
от функции circle. Это позволит менять x- и y-координаты в
соответствии с наклоном линии.
Команда "LINE(...)" принимает две конечные точки линии и
цвет. Вычисляется разность между x- и y-координатами. После
проверки на бесконечное значение наклона в случае вертикальной
линии эти значения используются как базовые для вычисления
наклона и направления линии.
Начальная точка линии устанавливается парой координат. Эти
координаты становятся начальной точкой отсчета относительных
координат для остальной части линии. Координаты остальной части
линии вычисляются в соответствии со значениями, генерируемыми
функцией наклона (slope), до тех пор, пока не будет достигнута
конечная точка. (См. пример на дискете).
Рис.4: Демонстрация линии (LineDemonstration)
6.3.6 Создание рамок
-----------------------------------------------------------------
Хотя рамкой обычно считается незаполненный прямоугольник,
следующая процедура подходит к этому вопросу совершенно иначе.
Эта процедура для заполнения всей области экрана не использует
никаких вложенных циклов.
Для создания рамки она использует просто линии. Четыре линии
соединяются в обычных координатах угловых точек экрана. Процедура
FRAME тоже работает только в режиме 19. Цвет можно выбрать из 256
цветов палитры. Должны быть доступны процедуры LINE, PLOT и MODE.
Procedure FRAME(x1,y1,x2,y2,Color : integer);
begin
line(x1,y1,x2,y1,Color);
line(x2,y1,x2,y2,Color);
line(x2,y2,x1,y2,Color);
line(x1,y2,x1,y1,Color);
end;
Рис.5: Демонстрация рамки (FrameDemonstration)
6.4 Специализированные графические команды
-----------------------------------------------------------------
Следующие графические команды основаны на ранее
рассмотренных и являются их модификациями.
Конкретно, мы модифицируем способ, которым команды BLOCK,
LINE и DISK используют цвет для заполнения форм на экране. До сих
пор формы закрашивались одним цветом VGA.
Использование единственного цвета создает впечатление
"искусственности" создаваемой компьютером картинки. Средства
создания многоцветных изображений позволяют избавиться от этого
эффекта.
Мы создадим три новые процедуры, использующие весь диапазон
цветов, доступных в палитре VGA, для закрашивания создаваемых
форм.
Модифицированная процедура рисования линии будет называться
FEATHER, процедура рисования блока - COLUMN, а диска - BALL.
6.4.1 Предварительные требования
-----------------------------------------------------------------
Важным требованием перед началом заполнения формы многими
цветами является создание подходящей палитры. При использовании
номеров в палитре, которая не была организована соответствующим
образом, вы можете получить на экране мешанину цветов.
Полезно вспомнить содержание разделов 6.2.5 и 6.2.6
("Настройка палитры пользователем").
В следующих процедурах особенно удобно использовать палитру,
в которой имелось бы 16 базовых цветов, каждый из которых в свою
очередь имел бы 16 уровней интенсивности. Процедуры JANSPALETTE
служит для создания такого рода настраиваемой пользователем
палитры. Если вы выберете ваши цвета заполнения как диапазон
номеров в палитре, соответствующий 16 уровням интенсивности
одного из базовых цветов палитры, ваша форма будет заполнена
естественной прогрессией цветов. Тогда между цветами не будет
пробелов, и несовместимые цвета не окажутся рядом друг с другом.
Другой способ состоит в использовании команды BLEND для
переопределения выбранного диапазона номеров палитры таким
образом, чтобы между двумя заданными номерами была создана
естественная прогрессия оттенков. Этот диапазон номеров цветов в
палитре может быть затем задан в графических командах для
заполнения ими форм.
Помните, что такого рода манипуляции повлияют на
изображения, уже находящиеся к этому моменту на экране и
использующие номера цветов, которые вы переопределили.
Обычно проще, и результаты при этом более предсказуемы, если
вы создадите систематическую палитру с равномерно изменяющимися
цветами.
6.4.2 Рисование многоцветных линий процедурой FEATHER
-----------------------------------------------------------------
Процедура FEATHER (см. на дискетах) во многом похожа на
процедуру LINE. Это неудивительно, поскольку обе создают на
экране одну и ту же форму. Поэтому для полного понимания
процедуры обратитесь к описанию процедуры LINE в разделе 6.3.5.
Однако, новая процедура существенно дополнена. В ней длина
линии вычисляется по теореме Пифагора.
До сих пор мы не рассматривали длину линии, за исключением
того момента, когда определялась ее видимая часть на экране.
Теперь длина линии понадобится нам для работы с заполнением линии
цветами. Это связано с тем, что шаблон заполнения линии цветами
настраивается по длине линии, и обойти данный способ никак
нельзя.
Это позволит нам рисовать короткие и длинные линии с
одинаковым цветовым наполнением. К процедуре добавлена
дополнительная подпрограмма для вычисления длины линии.
Длина линии и число используемых для ее заполнения цветов
используются для создания цветового отношения. Цвет в каждой
точке выбирается в соответствии с цветовым отношением по мере
добавления на экран каждой точки линии. Последний цвет диапазона
будет достигнут в конечной точке линии.
Все линии, независимо от их длины, будут содержать гладкую
прогрессию всех цветов заданного цветового диапазона.
В экстремальном случае, когда вся линия состоит из одной
точки, ее цвет будет равен последнему цвету заданного диапазона.
6.4.3 Упрощенная процедура заполнения (процедура HORIZONTAL)
-----------------------------------------------------------------
Поскольку процедура FEATHER достаточно сложна, ее
многократный вызов из другой программы или процедуры будет
приводить к большому расходу машинного времени. Поэтому
желательно иметь другой способ заполнения форм, вместо
циклического повторения вызова FEATHER.
Мы будем использовать более простую и быструю версию
FEATHER, предназначенную для заполнения прямоугольников и
окружностей. Поскольку для заполнения форм нам не требуется
рисование линий во всех направлениях, достаточно процедуры,
рисующей многоцветные горизонтальные линии.
Эту работу делает процедура HORIZONTAL. (См. на дискете).
6.4.4 Многоцветные диски (процедура BALL)
-----------------------------------------------------------------
Многоцветные линии, создаваемые при помощи HORIZONTAL, можно
использовать и для заполнения других форм.
Внесем нужные изменения в процедуру DISK. Это позволит нам
рисовать окружности и эллипсы, заполненные несколькими цветами.
Эта процедура расширена и принимает параметр с вторым
номером цвета. Диск заполняется данным диапазоном цветов из
текущей палитры при помощи процедуры HORIZONTAL, описанной в
предыдущем разделе.
Ход выполнения этой процедуры аналогичен DISK. Поверхность
формы заполняется от полюсов к экватору.
Выбор цветов, доступных в заданном диапазоне вашей палитры,
существенно влияет на то, насколько "естественно" будет выглядеть
законченная форма. Если вы задали сглаженную прогрессию цветов
(или вариации интенсивности одного цвета) без внезапных резких
переходов цвета и несовместимости между цветами, заполненная
форма будет иметь трех-мерный вид и выглядеть как шар или сфероид.
Процедура BALL используется в программе Ball Demonstration.
(См. на дискете).
Рис.6: Программа BallDemonstration (Procedure BALL(...);)
6.4.5 Многоцветные блоки
-----------------------------------------------------------------
Теперь мы можем применить те же принципы к процедуре BLOCK.
Прежде чем мы сможем рисовать многоцветные блоки, в структуру
программы тоже требуется внести изменения.
Процедура COLUMN (см. на дискете) имеет один цикл вместо
двух. Второй цикл процедуры BLOCK заменяется командой HORIZONTAL.
Программа должна принимать параметры начального и конечного
цветов для последующей их передачи команде HORIZONTAL. Полученная
в результате процедура сможет заполнять область экрана между
указанными угловыми координатами многоцветными линиями.
И снова, чтобы получить эффект заполненной формы, важно
выбрать сглаженные цвета. При использовании последовательности
вариаций одного и того же базового цвета заполненная форма будет
иметь вид круглой колонны.
Рис.7: Программа ColumnDemonstration
6.5 Процедуры со смешанными цветами заполнения
-----------------------------------------------------------------
В предшествующих разделах были представлены процедуры,
работающие с цветами заполнения. Цвета заполнения выбираются из
смежных цветов палитры режима 19. Следующие разделы показывают,
как расширить эти графические процедуры при помощи других
внутренних функций для смешения цветов заполнения.
6.5.1 Процедура Horizontal со смешанными цветами заполнения
-----------------------------------------------------------------
Эффект трехмерности, который достигается за счет заполнения
форм несколькими цветами, органичен, исчезая по мере увеличения
размеров объекта.
Использование 16 уровней интенсивности одного из 16 базовых
цветов настраиваемой пользователем палитры режима 19 становится
в случае больших объектов существенно заметным, что создает
эффект "полосатости". Этот эффект можно в значительной степени
уменьшить за счет смешивания цветов заполнения.
Для этого в процедуру HORIZONTAL добавляется новый параметр
"Mix". Значение этого параметра определяет степень смешения
цветов.
Если Mix равен 0, смешение цветов не происходит. Установка
Mix равным максимальному значению приведет к полному смешению
цветов заполнения, но при этом эффект трехмерности также
теряется. Осторожное использование этого коэффициента (Mix=2)
поддержит эффект смешения без потери трехмерности изображения.
Ниже находится листинг BALLDEMONSTRATION, а листинг
процедуры MIXHORIZONTAL см. на дискете.
Program BallDemonstration;
uses crt,dos,vga19;
var xx,yy,a,b : integer; ch : char;
begin
Randomize;
Mode($13); directvideo:=false;
Janspalette;
Block(0,0,320,80,194);
FrameColor(100);
ColorText(120); gotoxy(1,1);
writeln(' Большой шар с полосатым шаблоном: ');
Ball(160,120,150,100,16*5,16*5+16);
Zerokey; ch:=readkey;
Blend(1,55,60,63,99,0,20,30);
Listpalette; gotoxy(1,1);
writeln( 'Процедура MIXBALL(...); : Полосок не видно! ');
writeln( ' с параметром MIX, с хорошим или грубым сглаживанием. ');
MixBall(160,120,150,100,1,99,2);
Zerokey; repeat
xx:=Random(320); yy:=Random(200);
z:=(random(15)+1)*16;
b:=random(10)+10; a:=b+random(5);
MixBall(xx,yy,a,b,1,99,Random(20));
until keypressed;
end.
Рис.8: Процедура MIXBALL, параметр Mix позволяет убрать
полосы на изображении.
6.5.2 Расширения процедур BALL и COLUMN
-----------------------------------------------------------------
Новая графическая процедура MIXHORIZONTAL может быть
встроена в другие процедуры. Это не требует дополнительного
программирования, поскольку сама MIXHORIZONTAL представляет собой
модификацию процедуры HORIZONTAL.
Для этого достаточно заменить имя команды HORIZONTAL на
MIXHORIZONTAL. Требуется также определить параметр Mix. Подробное
описание этих программ мы здесь повторять не станем.
Дополнительную информацию см. в разделах 6.4.3 - 6.4.5.
На ваших дискетах находятся листинги процедуры MIXBALL,
процедуры MIXCOLUMN и программы MIXDEMO.
6.5.3 Дополнительные способы работы с цветными поверхностями
(программа Quadratic)
-----------------------------------------------------------------
Мы познакомились с тем, как смешение цветов и перемещение
цветных пикселей в процедурах MIXCOLUMN и MIXBALL могут быть
использованы для сглаживания объектов и получения эффекта
трехмерности изображения. Мы также увидели, как большое значение
коэффициента смешения Mix может разрушить эффект сглаживания и
привести к тому, что изображение объекта будет грубым.
Демонстрационна программа покажет, что мы можем сделать
после заполнения поверхности объекта для уменьшения такого
эффекта "рваного" изображения. (Листинг программы см. на
дискете). В следующем примере процесс сглаживания цветов будет
рассмотрен более подробно.
Программа рисует цветную поверхность (процедура BLOCK) и
многоцветный столбец тех же размеров (процедура COLUMN). За ними
следуют еще два столбца того же размера со сглаженными цветами
(процедура MIXCOLUMN) и с грубо смешанными цветами (снова
MIXCOLUMN). И наконец, этот столбец сглаживается (процедуры
MIXCOLUMN и ANTIALIA).
6.6 Сглаживание цветов: процедура ANTIALIA
-----------------------------------------------------------------
В данном разделе мы рассмотрим графическую команду,
предназначенную для сглаживания цветов. Процесс сглаживания
цветов на английском языке называется "anti-aliasing". Отсюда
произошло имя нашей следующей процедуры: ANTALIA.
ANTALIA позволяет автоматически сглаживать цвета объекта,
что позволяет получать более изящные, мягкие и более реалистичные
изображения.
Эта процедура работает только в режиме 19, поскольку это
единственный режим, позволяющий получать подобные эффекты.
Эта процедура не столь сложна, как это может сначала
показаться. Ее основная идея состоит в том, чтобы разбить цвет на
его голубой, зеленый и красный компоненты. Затем компьютер
сравнит эти цвета с другими цветами палитры.
Анализируя данный пиксель и цвета его непосредственного
окружения, компьютер может выбрать приемлемый сглаживающий цвет.
Поскольку оптимальный цвет сглаживания обычно не входит в текущую
палитру, происходит просмотр палитры, пока в ней не будет найден
ближайший к оптимальный цвет. Этот цвет будет затем использован
для замещения цвета анализируемого пикселя.
Сглаживание цветов сильно влияет на то, как выглядит объект.
Это прекрасный способ убрать эффект "полосатости", который может
возникнуть в случае больших многоцветных объектов. При этом
интересно, что все это происходит в режиме низкого разрешения
320*200 пикселей режима 19.
Однако низкое разрешение - это та цена, которую приходится
платить за возможность работы с 256 цветами. В противном случае
потребовалось бы иметь слишком большой объем экранной памяти. Это
ограничение разрешения экрана сильно влияет на эффект
"полосатости" цветов, от которого можно избавиться благодаря
процедуре ANTALIA.
ANTALIA имеет и другие достоинства. Она убирает острые края,
которые появляются на изображении объекта, если рядом оказываются
два контрастных цвета. Одноцветным объектам можно придать
многоцветные рамки, плавно переходящие в основной цвет объекта.
Также возможны эффекты перспективы. Сглаживание областей
экрана придает перспективе более мягкий, несфокусированный вид.
Это позволяет получить "глубину" изображения.
Кроме того, проще создавать мелкие текстовые шрифты,
используя для этого сглаженные и округленные формы. Без мелких
текстовых шрифтов текстовый вывод в режиме 19 пришлось бы
выполнять при помощи стандартного текстового вывода 40 на 25
символов. Комбинация же больших неуклюжих символов с красивой
цветной графикой малопривлекательно.
Позднее мы вернемся к идее создания мелких текстовых
шрифтов. Теперь же сосредоточимся на сглаживании цветов.
Многие из вас должны знать, что большинство графических
программ уже использует сглаживание цвета. Однако сравнивать
доступность этого средства в готовом пакете и в качестве
отдельной команды в среде программмирования, такой как Turbo
Pascal, трудно по их значимости.
Готовые программные пакеты годятся для создания многих
прикладных программ. Однако данный раздел предназначен для
пользователей, желающих иметь полный контроль над экраном и
мощные средства, предлагаемые процедурой сглаживания, доступной в
качестве отдельной команды Паскаля. Мы используем эту процедуру
для построения нашей собственной библиотеки расширенных команд
Turbo Pascal.
В следующем разделе мы проработаем серию новых команд, из
которых создается процедура сглаживания ANTALIA. Каждая из
создаваемых нами в процессе создания ANTALIA процедур будет
выполнять собственную уникальную функцию. Их свойства будут
иллюстрироваться короткими графическими демонстрационными
программами.
6.6.1 Считывание палитры
-----------------------------------------------------------------
Команды, которые мы использовали для работы с палитрой VGA,
такие как "PALETTE(...)", "BLEND(...)" и "ASSIGNCOLOR(...)",
предназначены для манипулирования цветами палитры. Теперь нам
нужна команда, которая позволила бы считывать цвета из текущей
палитры.
Описанная выше команда SHOWPALETTE просто выводит на экран
текущую палитру видео-режима 19. Для некоторых внутренних
манипуляций, которые мы хотим производить с цветами, этого
недостаточно.
6.6.2 Считывание номера в палитре (процедура READPALETTE)
-----------------------------------------------------------------
Чтобы узнать, какие цвета доступны в текущей палитре в
текущий момент, мы должны иметь команду, позволяющую компьютеру
обратиться к конкретному номеру палитры и проанализировать
соответствующий ему цвет. Для этого нужен доступ к регистрам
палитры. В разделе 6.2 мы уже описали, как происходит этот
доступ.
На этот раз помимо доступа на запись нам нужен доступ на
чтение. Чтобы не вызывать прерывание дважды, мы поместим вызов
прерывания между обращениями к регистрам - после доступа на
запись и перед доступом на чтение. Это гарантирует, что ввод в
функцию будет на своем месте. Доступ на чтение выполняется
посредством вызова прерывания.
В результате выполнения функции желаемые значения цветов
кажутся доступными процедуре для чтения. (Листинг программы см.
на дискете).
6.6.3 Считывание цвета палитры непосредственно с экрана
-----------------------------------------------------------------
Теперь мы можем создать команду, которая позволит нам
выбрать и прочитать номер цвета в палитре любого пикселя экрана в
режиме 19. Для этого доступ к регистрам при помощи
READPALETTE(...) комбинируется с прямым доступом к экранной
памяти при помощи стандартной команды Паскаля mem[...].
На входе этой процедуре потребуются координаты
анализируемого пикселя. Запрос цвета палитры для пикселя на
экране выполняется, как это выше было описано для команды PEEK.
Полученный номер цвета далее анализируется при помощи
READPALETTE, и выделяются его красная, зеленая и голубая
компоненты. Эти три значения цвета затем передаются в процедуру в
качестве результата.
procedure PeekPalette (var x,y,Blue,Green,Red : Integer);
var (* считывание отдельных цветовых компонент *)
Color: Integer; (* выбранного пикселя на экране *)
begin (* соответствует Peek(...);ReadPalette(...);*)
Blue:=0; Green:=0; Red:=0; (* инициализация значений компонент *)
if (x<320) and (x>=0) and (y<200) and (y>=0) then begin
(* определение границ экрана *)
Color:=Mem[$A000+y*20:x]; (* соответствует Peek(x,y,Color); *)
ReadPalette(Color,Blue,Green,Red); (* из модуля VGA19 *)
(* расщепление цвета на 3 компоненты *)
end;
end;
Хотя эта процедура и кажется простой, при рекурсивном вызове
становится видным дрожание блока. Проблема связана с вызовом
прерывания из команды READPALETTE.
Данный вызов прерывания требует дополнительного
процессорного времени. Повторяющиеся вызовы могут привести к
ненужным паузам в выполнении программы. Кроме того, каждое
прерывание разрывает связь между процессором и экраном.
Множественные их повторения могут повлиять на изображение на
дисплее.
При обработке большой части экрана эти эффекты становятся
заметными, что снижает качество картинки на экране. Поэтому
мы должны использовать альтернативную процедуру, которая
устраняет необходимость в повторных вызовах прерывания.
В этих целях мы переносим вызов прерывания в точку
программы, где вызов будет происходить не слишком часто. Для
этого вся текущая палитра VGA должна быть считана в таблицу
переменных памяти. При этом нужно следовать правилам Паскаля для
работы с индексированными переменными.
Дополнительную информацию о создании альтернативы процедуре
PEEKPALETTE см. в следующем разделе.
6.6.4. Создание переменных списков для цветов палитры
-----------------------------------------------------------------
В данном разделе описано, как поместить значения текущей
палитры VGA в переменные списки. Тем самым мы сможем избежать
вызова прерывания при считывании каждого нового цвета палитры.
Таблица индексированных переменных будет состоять из трех
цветовых компонент: голубой, зеленой и красной для каждого из 256
номеров цвета:
var BL,GR,RE : Array [0...255] of Integer;
Переменный индекс будет являться номером палитры от 0 до
255. BL[номер_цвета] - это голубая компонента цвета,
GR[номер_цвета] - это зеленая компонента, а RE[номер_цвета] -
красная.
Например, цветовые компоненты цвета номер 97 текущей палитры
будут храниться в таблице в BL[97], GR[97] и RE[97].
Значения для списка считываются из платы VGA командой
"READPALETTE(номер_цвета)" и передаются в индексированные
переменные.
Важно помнить, что список палитры должен обновляться всякий
раз при внесении изменения в палитру. В противном случае этот
список будет содержать устаревшие данные. Фактически это
требование представляет собой единственный недостаток
использования списка палитры.
Однако, при этом данный способ имеет два явных преимущества.
Индексированные переменные списка палитры позволяет быстро
выполнять доступ к компонентам любого цвета палитры, причем
избегая прерываний.
Процедура READPALETTE(...)" является в приводимой ниже
программе, используемой для создания или обновления списка
палитры, обязательной. Показанный выше список индексированных
переменных должен уже существовать. Это определение должно
происходить вне процедуры, чтобы получаемый в результате список
палитры был доступен другим процедурам.
Следующий листинг приведен только для примера и не
предназначен для компиляции и получения из него реальной
программы.
Program MAKELIST; { Создает список цветов текущей палитры }
uses crt,dos,vga19;
var Bl,Gr,Re : Array [0...255] of Integer;
{ Индексированные переменные - эта таблица }
{ нужна для LISTPALETTE ! }
procedure ListPalette;{ Создание для палитры таблицы со }
begin { значениями голубой, зеленой }
for x:=0 to 255 do { и красной компонент для цвета x }
ReadPalette(x,Bl[x],Gr[x],Re[x]);
end;
begin { главная часть - конечно, она может быть значительно }
ListPalette; { больше по числу команд, например Mode(19) }
end.
6.6.5 Считывание цветовых компонент (процедура PEEKLIST)
-----------------------------------------------------------------
Теперь ваши программы смогут считывать цветовые компоненты,
запрашивая список палитры. При этом изображение на экране не
будет нарушаться из-за выполняемых вызовов прерываний.
Фактическая палитра и соответствующий список палитры из
индексированных переменных BL[..], GR[..] и RE[..], должны
создаваться в начале программы.
Помните, что список палитры всегда должен обновляться
командой LISTPALETTE после любых изменений, внесенных в палитру,
например, командами PALETTE или BLEND.
Другая подлежащая решению проблема состоит в том, как
использовать наш новый список палитры для получения цветовых
компонент заданной точки экрана. Для этого нужно объединить
процедуру PEEK c запросом текущего списка палитры. Эта процедура
очень похожа на PEEKPALETTE. (Листинг программы см. на дискете).
6.6.6 Поиск аналогий (процедура SIMILAR)
-----------------------------------------------------------------
Теперь мы должны научить компьютер искать и распознавать
аналогии между цветами. Эта процедура берет любой из 262144
возможных цветов VGA и сравнивает его с 256 цветами текущей
палитры. Кроме того, процедура выводит номер и палитре наиболее
близко к заданному найденного цвета.
Существующий список палитры является внешним по отношению к
этой процедуре, и данное требование является абсолютным. Список
палитры перед использованием должен быть обновлен при помощи
LISTPALETTE. (Листинг программы см. на дискете).
var Bl,Gr,Re:Array [0...255] of Integer; { список палитры }
{ Эта таблица перед использованием должна быть заполнена }
{ при помощи команды ListPalette }
Список палитры (таблица) также должен быть введен в строке
определения переменных, так чтобы он мог быть заполнен значениями
из текущей палитры. Необходимые процедуры и переменные должны
быть включены в программу до того, как компьютер сможет
фактически работать с ними в следующих процедурах.
Ранее представленные процедуры, используемые для рисования
линий и окружностей, различны. Процедура SIMILAR не работает с
входными параметрами или математической функцией. Главный цикл
процедуры выполняется без заданных параметров до тех пор, пока
не будет выполнено некоторое условие.
Этот цикл расширяет диапазон поиска для значений каждой
цветовой компоненты до тех пор, пока не будет найден цвет, все
цветовые компоненты которого окажутся в пределах этого диапазона.
Размер поискового диапазона зависит от того, сколько раз
будет выполнен цикл. Это число также определяет степень того,
насколько найденный цвет соответствует заданному. Если это число
сохранено и передано, то процедура REFERENCECOLOR может
использовать его в качестве параметра "RTG", или "рейтинга"
качества найденного соответствия.
Для этой процедуры обязательным требованием является
создание списка палитры. (Листинг программы см. на дискете).
Например, если компьютер нашел в палитре цвет, очень близкий к
искомому, рейтинг (Rtg) соответствия будет равен 1, или "очень
хорошо". Если текущая палитра не содержит похожего цвета, цикл
будет повторен до тех пор, пока значение RTG не достигнет
максимума, равного 6. Параметр рейтинга RTG может быть
использован в других программах для принятия решения о том, стоит
ли использовать цвет, найденный при поиске. Демонстрационной
программе требуется модуль VGA19.
6.6.7 Сглаживание в блоках (процедура ANTALIA)
-----------------------------------------------------------------
Процедура ANTALIA работает с прямоугольным блоком. Она
содержит процедуру BLOCK в качестве подпрограммы. Различие
состоит в том, что блок не заполняется одним цветом. Цвета,
используемые для закрашивания блока, сглаживаются.
Во время работы этой процедуры команда LISTPALETTE
используется для заполнения списка палитры значениями цветовых
компонент цветов текущей палитры VGA. Процедура PEEKLIST также
является необходимой. Она служит для считывания цвета каждой
точки в определенном блоке.
Другая подфункция анализирует точки, окружающие каждый
отдельный пиксель, обрабатываемый процедурой. Более конкретно,
существует четыре точки непосредственно справа, слева, вверху и
внизу от обрабатываемого пикселя. Три цветовых компонента этих
точек складываются и делятся на четыре, что дает средний цвет
точек в окрестностях данного пикселя.
Этот средний цвет создается из средних значений голубой,
зеленой и красной компонент окружающих точек. В большинстве
случаев такой цвет в палитре отсутствует. Следовательно, мы
должны найти в текущей палитре наилучшее приближение к этому
идеальному цвету, чтобы выполнить функцию сглаживания. Эта часть
программы выполняется процедурой REFERENCECOLOR. Качество
соответствия между идеальным цветом сглаживания и ближайшим
цветом в палитре вычисляется посредством параметра "Рейтинг".
Ближайший цвет в палитре будет использован только в том случае,
если рейтинг меньше или равен 2. ((Листинг программы см. на
дискете).
6.7 Последовательное сглаживание по пикселям
-----------------------------------------------------------------
Мы также можем разработать процедуры аналогичные ANTALIA,
для сглаживания не прямоугольных областей. Одна из них будет
служить для сглаживания конкретных пикселей. Эту процедуру можно
затем использовать для построения новых процедур сглаживания
различных форм.
Подобно тому, как процедура BLOCK являлась частью ANTALIA,
подпрограмма рисования точки на экране будет являться важной
частью следующей процедуры SMOOTH.
Процедура ANTALIA использовала для вычисления оптимального
цвета сглаживания только четыре окружающие точки. В противном
случае мог бы получиться слишком сильный эффект "перехлеста",
который свел бы на нет фактическое сглаживание.
При последовательном сглаживании по пикселям при вычислении
цвета сглаживания рассматриваются четыре окружающие точки, плюс
сама текущая точка.
Хорошая идея состоит в том, чтобы создать саму процедуру
SMOOTH, а затем встроить ее в другие, использующие ее процедуры.
Это позволит избежать повторения кода программы в других
процедурах, делая текст программы более понятным и легким для
восприятия.
После листинга SMOOTH следует использующая ее процедура
SMOOTHCIRCLE. Эта программа требует модуль VGA19, содержание
которого приводится в конце главы.
Рис.9 Демонстрация последовательного сглаживания по пикселям
6.8 Модификации существующей палитры
-----------------------------------------------------------------
Для получения некоторых эффектов вам может понадобиться
внести изменения в большое число цветов существующей палитры. Для
этого лучше иметь возможность изменять группы цветов, а может
быть, и всю палитру целиком, а не изменять каждый цвет в
отдельности.
Один из способов модификации состоит в управлении яркостью,
как на телевизоре. Все цвета палитры (заданного диапазона) при
этом увеличивают или уменьшают яркость на заданную величину.
Следующие две процедуры представляют различные способы
увеличения или уменьшения яркости палитры за счет манипулирования
голубой, зеленой и красной компонентами каждого цвета.
6.8.1 Абсолютное регулирование яркости цветов палитры
-----------------------------------------------------------------
Следующая процедура, DIM, позволяет регулировать яркость
цветов палитры, прибавляя заданное значение к красной, зеленой и
голубой компонентам выбранных номеров палитры. Положительное
значение увеличивает яркость, а отрицательное уменьшает.
Эта процедура также использует список цветов палитры,
хранимый в виде таблицы индексированных переменных. Изменения
конкретных компонент сначала выполняется в списке палитры путем
прибавления в соответствующие элементы заданного значения.
После того, как значения в списке палитры правильно
откорректированы, они передаются в плату VGA. Содержимое каждой
из индексированных переменных BL[..], GR[..] и RE[..] передаются
посредством команды PALETTE(...).
Поскольку эта команда предназначена для работы как с
отдельными номерами палитры, так и с диапазоном номеров,
выполнение главного цикла зависит от первого и последнего номеров
изменяемых цветов палитры. Другие циклы, передающие новые
значения цвета из списка палитры плате VGA, всегда пробегают от 0
до 255. Таким образом, после выполнения DIM палитра и список
будут всегда совпадать.
Следующий листинг зависит от модуля VGA19, который должен
быть прикомпонован командой uses к любой использующей его
Паскаль-программе.
6.8.2 Относительное регулирование яркости цветов палитры
-----------------------------------------------------------------
Процедура, которую мы только что рассматривали для
регулирования цветов палитры, имеет недостаток, состоящий в
"смывании" цветов в случае, если сделаны сильные изменения. Этот
эффект аналогичен "передержке" или "недодержке" пленки в
фотоаппарате при съемке.
Это происходит следующим образом: При попытке добавить
абсолютный коэффициент яркости к и без того яркому цвету голубая,
зеленая и красная компоненты этого цвета могут достигнуть
максимального значения, равного 63. Результатом является белый
цвет.
То же самое справедливо и для темных тонов. Чем больше
цветовых компонент достигает значения 0, тем больше областей
экрана выглядят черными. Если этот эффект распространится на
несколько цветов палитры, то тонкие цветовые различия некоторых
областей экрана могут быть потеряны.
Следующая процедура, DIMPERCENT, предлагает другой способ
регулирования яркости цветов экрана. Она изменяет яркость на
заданный процент. Это позволяет выполнять относительное
регулирование всех изменяемых цветов между их текущими значениями
яркости и максимальными/минимальными.
Тем самым яркие и темные тона не будут изменяться так же
сильно, как и средние тона, что позволяет сохранить тонкие
цветовые оттенки. Как и в предыдущей процедуре, положительные
значения коэффициента яркости ведут к увеличению, а отрицательные
- к уменьшению яркости изображения.
6.8.3 Преобразование цветов палитры в чисто серые тона
-----------------------------------------------------------------
Во всех предыдущих процедурах мы хорошо использовали
свойства многоцветности платы VGA. Иногда вам может понадобиться
работать только со значениями яркости цветов палитры. Для этого
цвета палитры преобразуются в серые тона.
Программа NEWPALETTE служит для этой цели, используя вызов
прерывания для доступа к специальным функциям VGA преобразования
цветов в шкалу серых тонов. Для этого голубая, зеленая и красная
компоненты каждого цвета взвешиваются отдельно, поскольку каждая
из них по-разному влияет на общую яркость цвета.
Серая шкала для каждого цвета выбирается вычислением общего
коэффициента яркости цвета. Прогрессия от белого к черному
полностью "бесцветна", так как каждая из голубой, зеленой и
красной компонент устанавливается для получения серого тона в
одно и то же значение.
Практическое применение этой программы состоит в том, чтобы
предварительно просматривать графические изображением перед
печатью их на черно-белом принтере.
См. на дискете листинг программы NEWPALETTE. Между прочим,
это одна из немногих программ данной главы, не требующая модуля
VGA19. Ее можно скомпилировать и выполнить просто в Turbo Pascal
(4.0 и т.д.).
6.9 Завершенный модуль Паскаля
-----------------------------------------------------------------
Чтобы не набирать тексты процедур всякий аз при их
использовании в программе, создайте модуль Паскаля с этими
процедурами, как было сказано в начале данной главы.
Получившийся модуль будет служить расширением языка Паскаль.
Он может быть использован в любой программе на Паскале, подобно
любому из стандартных модулей, таких как GRAPH.TPU, для чего
достаточно задать его имя в команде uses.
Помимо рассмотренных процедур, для создания завершенного
модуля нам понадобится добавить требуемые переменные, в том числе
список палитры, состоящий из индексированных переменных. Тогда
повторять определения этих переменных в каждой новой программе не
придется.
Следующая строка в любой новой программе будет вызывать
модуль VGA19.TPU:
Uses crt, dos, VGA19;
Эта строка должна находиться в верхней позиции
Паскаль-программы, перед определением переменных. Тогда вы
сможете использовать в вашей программе новые команды: MODE,
FRAMECOLOR, COLORTEXT, PALETTE, BLEND, JANSPALETTE, SHOWPALETTE,
PLOT, PEEK, BLOCK, ASSIGNCOLOR, CIRCLE, DISK, LINE, FEATHER,
BALL, COLUMN, FRAME, READPALETTE, LISTPALETTE, PEEKPALETTE,
SMOOTH, REFERENCECOLOR, PEEKLIST, ANTALIA, ATALAYA, SMOOTHCIRCLE,
DIM и DIMPERCENT.
В модуле также будут находиться и другие процедуры, ZEROKEY,
MINITEXTXY, MINIPRINT и GLASSPRINT, которые не являются
специальными графическими командами.
6.9.1 Добавление в модуль процедуры ZEROKEY
-----------------------------------------------------------------
Процедура ZEROKEY не является графической командой VGA. Эта
команда просто поможет вам в некоторых случаях сэкономить усилия.
Многие программы в некоторой точке останавливают выполнение,
и прежде, чем продолжить работу, ждут от пользователя нажатие
любой клавиши. Например, если клавиша была по ошибке нажата при
раскрашивании экрана, то это нажатие попадет в буфер клавиатуры. В
точке, где желательна остановка, в этом случае пауза не
произойдет. Это особенно неприятно во время скролинга текста на
дисплее, так как в этом случае нужный экран может "проскочить",
прежде чем вы успеете его прочесть.
Процедура ZEROREQ решает эту проблему, просто очищая буфер
клавиатуры перед тем, как программа должна сделать паузу. В
Паскаль-программах вы сможете использовать процедуры ZEROKEY и
WAIT в графических режимах. В соответствующих командах предыдущих
версий это невозможно.
Следующая процедура, P() представляет собой пример
переименования стандартной процедуры. Мы переименуем стандартную
команду Паскаля Writeln(). Новая процедура сохранит все
функциональные свойства оригинала. Если вы хотите, то можете
таким образом переименовать любые другие команды Паскаля,
например, чтобы сделать их название короче.
Procedure P(str : string);
begin Writeln(str);
end;
Процедура WAIT(...) использует новую команду ZEROKEY. Она
очищает при помощи ZEROKEY буфер клавиатуры, а затем заставляет
компьютер ожидать следующее нажатие клавиши. Это дает эффект, как
если бы постраничный скролинг текста был встроен в вашу
программу.
procedure Wait; { Очищает буфер клавиатуры и }
begin { ожидает ввод нового нажатия клавиши }
ZeroKey; { Эта процедура обязательна }
repeat
until keypressed;
end;
В наш Паскаль-модуль также включены три дополнительные
процедуры для печати мини-текста. Процедура MINIPRINT(VGA),
MINITEXT(VGA) и GLASPRINT(VGA). Эти программы аналогичны
программам, предназначенным для работы в видео-режиме 13
(шестнадцатиричное 0D). в них сделаны соответствующие изменения,
позволяющие использование мини-текста в режиме 19. Подробности
см. в главе 5.
6.10 Прямой запуск программ из DOS
-----------------------------------------------------------------
Скомпилированный модуль Turbo Pascal с суффиксом .TPU не
может быть выполнен вне Паскаля. Однако, вы можете скомпилировать
программы таким образом, чтобы их можно было непосредственно
запустить из командной строки DOS, независимо от Паскаля.
Скомпилированная и сохраненная таким образом программа имеет
расширение .EXE, что означает "исполняемый файл".
В Паскале, независимо от длины программы, вы можете
создавать эффективные команды, которые можно выполнить прямо из
командной строки DOS. Команды, созданные и используемые таким
образом, становятся практически расширениями стандартного набора
программ DOS.
Это означает, что процедуры, рассмотренные в этой главе,
можно использовать и в качестве команд DOS. В следующем разделе
приводится несколько примеров того, что вы можете теперь и что
вам было недоступно в старой команде DOS MODE. Набор команд -
расширений DOS, включенный в данную книгу, содержит эти программы
в виде команд CGAPALETTE, EGAPALETTE и VGAPALETTE.
6.10.1 Пример новой команды DOS (программа EGAPALETT)
-----------------------------------------------------------------
После компиляции следующая программа станет не только новой
демонстрацией текстового режима, но и может использоваться в
качестве новой команды DOS. Исполняемый файл должен находиться на
маршруте, доступном DOS, и в любой момент может быть запущен из
командной строки.
Следующий листинг - это листинг одной из программ,
поставляемых с данной книгой, и для него не требуются никакие
другие программы или модули из нашего комплекта программного
обеспечения.
program EGAPALET;
uses crt,dos; { Использует только стандартные модули }
type
VGARegPack = record AL,AH : Integer;
end;
var
ColorNumber,Blue,Green,Red : Byte;
x,y,Modd : integer;
procedure MODE(Input: Integer);
var
VGARegs : Registers;
begin
with VGARegs do begin { подготовка регистров к прерыванию }
AL := Input; { ввод переменной для видео-режима }
AH := $00; { функция: установка видео-режима }
end;
Intr($10,VGARegs); { вызов прерывания $10 }
end;
procedure FrameColor(ColorNumber:Byte);
var
Regs : Registers;
begin
with Regs do begin { подготовка регистров к прерыванию }
AL := $01; { установка регистра рамки }
AH := $10;
BH := ColorNumber; { Цвет рамки }
end;
Intr($10,Regs); { вызов прерывания $10 }
end;
procedure AssignColor(ColorNumber,Color : byte);
var
Regs : Registers;
begin
with Regs do begin { подготовка регистров к прерыванию }
AL := $00;
AH := $10;
BL := ColorNumber;
BH := Color;
end;
Intr($10,Regs); { вызов прерывания $10 }
end;
procedure Palette(ColorNumber,Blue,Green,Red : byte);
var
Regs : Registers;
begin
with Regs do begin { подготовка регистров к прерыванию }
AL := $10; { установить регистр цвета }
AH := $10; { установить регистр палитры }
BX :=ColorNumber; { первый устанавливаемый регистр цвета }
CL := Blue; { значение голубого }
CH := Green; { значение зеленого }
DH := Red; { значение красного }
end;
Intr($10,Regs); { вызов прерывания $10 }
end;
procedure Blend(ColrNr1,Blue1,Green1,Red1,
ColrNr2,Blue2,Green2,Red2: Byte);
var Nr,Bl,Gr,Rd: byte;
begin
Nr:= ColrNr2 - ColrNr1;
for x :=0 to Nr do begin
Bl:= (Blue1*(nr-x) + Blue2*(x)) div nr;
Gr:= (Green1*(nr-x)+ Green2*(x))div nr;
Rd:= (Red1*(nr-x) + Red2*(x)) div nr;
Palette(ColrNr1+x,Bl,Gr,Rd);
end;
end;
begin { начало главной программы }
Mode($11); { режим 17 сбрасывает все регистры }
Mode($3); { -> третья строка главной программы }
directvideo:=false; { настройка палитры }
palette(0,8,6,2) ; { черный }
palette(1,33,17,15) ; { голубой }
palette(2,27,35,20) ; { зеленый }
palette(3,25,25,15) ; { синий }
palette(4,17,19,33) ; { красный }
palette(5,24,20,30) ; { фуксин }
palette(6,12,17,27) ; { коричневый }
palette(7,31,33,35) ; { светло-серый }
palette(8,22,19,17) ; { темно-серый }
palette(9,50,35,29) ; { светло-голубой }
palette(10,50,45,20); { светлый синий }
palette(11,26,50,34); { светло-зеленый }
palette(12,25,47,60); { светло-красный }
palette(13,47,55,62); { светлый фуксин }
palette(14,33,56,60); { желтый }
palette(15,57,53,53); { белый }
palette(16,7,4,12); { фон: цвет красного вина }
for x:= 0 to 15 do AssignColor(x,x);
textbackground(1);
textcolor( 0);writeln(' черный ');
textbackground(0);
textcolor( 1);writeln(' голубой ');
textcolor( 2);writeln(' зеленый ');
textcolor( 3);writeln(' синий ');
textcolor( 4);writeln(' красный ');
textcolor( 5);writeln(' фуксин ');
textcolor( 6);writeln(' коричневый ');
textcolor( 7);writeln(' светло-серый ');
textcolor( 8);writeln(' темно-серый ');
textcolor( 9);writeln(' светло-голубой ');
textcolor(10);writeln(' светлый синий ');
textcolor(11);writeln(' светло-зеленый ');
textcolor(12);writeln(' светло-красный ');
textcolor(13);writeln(' светлый фуксин ');
textcolor(14);writeln(' желтый ');
textcolor(15);writeln(' белый ');
FrameColor(16);
end.
Несколько модифицировав эту программу, мы можем создать
процедуру CGAPALET. Для этого достаточно заменить третью строку
главной программы на Mode(1). В другой модификации мы можем
получить программу VGAPALET. Здесь третья строка главной
программы примет вид Modd:=-1;textmode(Modd);. Это даст нам
доступ к 50-строчному текстовому режиму VGA. После компиляции
программа VGAPALET.EXE будет работать в этом режиме.
Разумеется, все требования к аппаратному обеспечению
остаются в силе. Без платы VGA и совместимого аналогового
монитора с кабелем программа не пойдет. Возможности расширения
DOS такими способами практически не ограничены. Дополнительную
информацию о создании ваших собственных команд-расширений DOS см.
в Главе 4.
6.11 Дополнительные примеры программ
-----------------------------------------------------------------
В данном разделе рассматриваются некоторые идеи на примере
программ на Turbo Pascal, которые не были включены в модуль
VGA19. Описываемые графические эффекты лучше работают, будучи
реализованными в виде отдельных программ, поскольку разбить их на
самодостаточные графические команды было бы затруднительно.
Программы для расширения и перемещения части экрана можно
затем переработать в отдельные графические команды. Программа
AURORA.PAS, изображающая восход солнца, дала идею создания игры.
На базе этой идеи и была разработана игра TERRAX.PAS,
представленная в Главе 10.
6.11.1 Расширение части экрана (Zoom - "Наезд")
-----------------------------------------------------------------
Данная программа берет среднюю часть экрана и расширяет ее
таким образом, чтобы она занимала весь экран. Это выполняется при
помощи специальной процедуры, построенной на базе ранее
определенных процедур PEEK и PLOT.
Экран удваивается по размеру в направлении от краев к
середине. Цвета четвертой части поверхности считываются командой
PEEK. Затем весь экран перерисовывается при помощи четырех команд
PLOT на каждую команду PEEK. Эта процедура фактического удаления
пикселей не выполняет, поскольку происходит перерисовка всего
экрана.
При модификации данной процедуры без выполнения указанных
правил следует быть осторожным, когда дело касается пикселей,
которые не должны быть заменены. Они либо должны быть удалены,
либо, что гораздо лучше, преобразованы в что-либо другое, что
будет соответствовать картинке.
Фактически удаление точки не имеет большого значения при
работе с палитрой VGA. Удаление пикселя обычно означает замену
его цветом номер 0. На стандартной палитре это обычно черный
цвет. Однако в качестве цвета номер 0 может быть задан любой цвет
VGA. Лучше думать об "удалении" пикселя как о способе сглаживании
его относительно окружающего участка.
Ниже приводится процедура DOUBLE. Вам будут
продемонстрированы две версии этой программы.
program ZOOM; { копирует и увеличивает часть экрана }
uses
crt,dos,vga19;
var
xx,yy,zz,aa,bb : Integer;
procedure DOUBLE; { подпрограмма }
var x,y,xz,yz,Color : integer;
begin
for x:=79 to 159 do begin
for y:=49 to 99 do begin
Peek (x,y,Color);
xz:=x-159;xz:=xz*2+158;
yz:=y-99 ;yz:=yz*2+98;
Plot (xz,yz,Color); Plot(xz+1,yz,Color);
Plot(xz,yz+1,Color);Plot(xz+1,yz+1,Color);
Peek (319-x,y,Color);
xz:=319-x-159;xz:=xz*2+158;
yz:=y-99 ;yz:=yz*2+98;
Plot (xz,yz,Color); Plot(xz+1,yz,Color);
Plot(xz,yz+1,Color);Plot(xz+1,yz+1,Color);
Peek (x,199-y,Color);
xz:=x-159;xz:=xz*2+158;
yz:=199-y-99 ;yz:=yz*2+98;
Plot (xz,yz,Color); Plot(xz+1,yz,Color);
Plot(xz,yz+1,Color);Plot(xz+1,yz+1,Color);
Peek (319-x,199-y,Color);
xz:=319-x-159;xz:=xz*2+158;
yz:=199-y-99 ;yz:=yz*2+98;
Plot (xz,yz,Color); Plot(xz+1,yz,Color);
Plot(xz,yz+1,Color);Plot(xz+1,yz+1,Color);
end;end; { конец подпрограммы }
end;
begin { главная программа }
directvideo:=false;
Mode($13);
randomize;
Janspalette;
Palette(0,14,30,35);Listpalette;
for xx:=0 to 25 do begin
zz:=random(30)+160-random(30);yy:=random(40)+80;
aa:=random(17);bb:=random(aa)+1;
Disk(zz,yy,aa,bb,random(255));
SmoothCircle(zz,yy,aa,bb);
end;
Double; Double; Double;
end.
Следующая программа, BIGGER, представляет собой другой способ
реализации наезда на часть экрана. На этот раз используется
метод "растеризации".
Мы не будем создавать четыре пикселя для каждого пикселя
исходного изображения. Здесь картинка увеличивается посредством
помещения вокруг каждого исходного пикселя четырех черных
пикселей (фактически это пиксели с цветом 0 из текущей палитры).
Program BIGGER;
Uses crt,dos,vga19;
Var ch : char;
Procedure Starpalette; { 256 цветов звезды }
begin Palette(0,9,3,3);
Blend(1,6,1,12, 15,10,13,27); { красные карлики }
Blend(15,10,13,27,30,10,21,33); { оранжевые звезды }
Blend(30,10,21,33,40,18,32,36); { желтые звезды }
Blend(40,18,32,36,50,22,40,36); { желто-белые звезды }
Blend(50,22,40,36,180,58,45,43); { зеленые планеты }
Blend(180,58,45,43,255,63,45,63); { голубые планеты }
DimPercent(0,255,10);
end;
procedure DoubleDouble; { увеличивает центр экрана }
var x,y,xz,yz,Color : integer; { в режиме 19 }
begin
for x:=79 to 159 do begin { границы центра x/y }
for y:=49 to 99 do begin
Peek (x,y,Color); { верхний левый квадрант }
xz:=x-159;xz:=xz*2+158; { увеличить x }
yz:=y-99 ;yz:=yz*2+98; { увеличить y }
Plot (xz,yz,Color); { нарисовать/очистить точки }
Plot(xz+1,yz,0);Plot(xz,yz+1,0);Plot(xz+1,yz+1,0);
Peek (319-x,y,Color); { верхний правый квадрант }
xz:=319-x-159;xz:=xz*2+158; { увеличить x }
yz:=y-99 ;yz:=yz*2+98; { увеличить y }
Plot (xz,yz,Color); { нарисовать/очистить точки }
Plot(xz+1,yz,0);Plot(xz,yz+1,0);Plot(xz+1,yz+1,0);
Peek (x,199-y,Color); { нижний левый квадрант }
xz:=x-159;xz:=xz*2+158; { увеличить x }
yz:=199-y-99 ;yz:=yz*2+98; { увеличить y }
Plot (xz,yz,Color); { нарисовать/очистить точки }
Plot(xz+1,yz,0);Plot(xz,yz+1,0);Plot(xz+1,yz+1,0);
Peek (319-x,199-y,Color); { нижний правый квадрант }
xz:=319-x-159;xz:=xz*2+158; { увеличить x }
yz:=199-y-99 ;yz:=yz*2+98; { увеличить y }
Plot (xz,yz,Color); { нарисовать/очистить точки }
Plot(xz+1,yz,0);Plot(xz,yz+1,0);Plot(xz+1,yz+1,0);
end;
end;
end;
begin { начало главной программы }
Mode($13);Starpalette;
palette(127,63,45,63); directvideo:=false;
repeat gotoxy(1,11);
ColorText(127);write( 'Удвоение экрана' );
DoubleDouble;
{ средняя часть экрана увеличивается, моделируя полет }
gotoxy(1,12);ColorText( 8);write( 'Do ' );
ColorText(11);write('вы');ColorText(14);write( ' зна');
ColorText(16);write('ете ');ColorText(18);write( 'ск' );
ColorText(20);write('ол');ColorText(22);write( 'ьк' );
ColorText(24);write('о' );ColorText(26);write( ' з' );
ColorText(28);write('ве' );ColorText(30);write( 'зд' );
ColorText(32);write(' н' );ColorText(34);write( 'а' );
ColorText(36);write(' не');ColorText(38);write( ' бе' );
ColorText(48);write('?' );
for Z:=0 to 3000 do begin
X:=random(320);Y:=random(200);
Color:=random(random(random(250)))+1;
Plot(X,Y,Color);{ Рисуем звезду }
if keypressed then z:=3000;
end;
until keypressed;
end.
6.11.2 Уменьшение части экрана ("Отъезд")
-----------------------------------------------------------------
Следующая программа демонстрирует, как можно уменьшить часть
экрана. В данном случае уменьшенная часть экрана состоит из
четырех точек исходного экрана.
Добавление цветов из четырех исходных точек и расположение
совместимого с ними усредненного цвета выполняется процедурой
REFERENCECOLOR из модуля Pascal VGA19. Подробное ее описание см.
в Разделе 6.6.6.
Поскольку программа усредняет цвет четырех пикселей,
объединяя их в один усредненный, часть картинки в уменьшенном
варианте будет утеряна. Если реализовать эту программу методом
удаления пикселей, а не их усреднения, то потери будут еще
значительнее.
program REDUCE;
uses crt,dos,vga19; { заголовок программы, подключение модулей }
var
ch:char;
procedure Half; { начало подпрограммы }
var x,y,xz,yz,Bl1,Gr1,Re1,Bl2,Gr2,Re2,Bl3,Gr3,Re3,Bl4,Gr4,Re4,
Rp,Blue,Green,Red,Color : integer;
begin { начало главного тела подпрограммы }
for y:=50 to 99 do begin
for x:=80 to 159 do begin
xz:=x-159;xz:=xz*2+158;
yz:=y-99 ;yz:=yz*2+98;
peeklist(xz,yz ,Bl1,Gr1,Re1);
peeklist(xz+1,yz ,Bl2,Gr2,Re2);
peeklist(xz,yz+1 ,Bl3,Gr3,Re3);
peeklist(xz+1,yz+1,Bl4,Gr4,Re4);
Blue:=(Bl1+Bl2+Bl3+Bl4)div 4;
Green:=(Gr1+Gr2+Gr3+Gr4)div 4;
Red:=(Re1+Re2+Re3+Re4)div 4;
ReferenceColor(Rp,Color,Blue,Green,Red);
plot (x,y,Color);
xz:=319-x-159;xz:=xz*2+158;
yz:=y-99 ;yz:=yz*2+98;
peeklist(xz,yz ,Bl1,Gr1,Re1);
peeklist(xz+1,yz ,Bl2,Gr2,Re2);
peeklist(xz,yz+1 ,Bl3,Gr3,Re3);
peeklist(xz+1,yz+1,Bl4,Gr4,Re4);
Blue:=(Bl1+Bl2+Bl3+Bl4)div 4;
Green:=(Gr1+Gr2+Gr3+Gr4)div 4;
Red:=(Re1+Re2+Re3+Re4)div 4;
ReferenceColor(Rp,Color,Blue,Green,Red);
plot (319-x,y,Color);
xz:=x-159;xz:=xz*2+158;
yz:=199-y-99 ;yz:=yz*2+98;
peeklist(xz,yz ,Bl1,Gr1,Re1);
peeklist(xz+1,yz ,Bl2,Gr2,Re2);
peeklist(xz,yz+1 ,Bl3,Gr3,Re3);
peeklist(xz+1,yz+1,Bl4,Gr4,Re4);
Blue:=(Bl1+Bl2+Bl3+Bl4)div 4;
Green:=(Gr1+Gr2+Gr3+Gr4)div 4;
Red:=(Re1+Re2+Re3+Re4)div 4;
ReferenceColor(Rp,Color,Blue,Green,Red);
plot (x,199-y,Color);
xz:=319-x-159;xz:=xz*2+158;
yz:=199-y-99 ;yz:=yz*2+98;
peeklist(xz,yz ,Bl1,Gr1,Re1);
peeklist(xz+1,yz ,Bl2,Gr2,Re2);
peeklist(xz,yz+1 ,Bl3,Gr3,Re3);
peeklist(xz+1,yz+1,Bl4,Gr4,Re4);
Blue:=(Bl1+Bl2+Bl3+Bl4)div 4;
Green:=(Gr1+Gr2+Gr3+Gr4)div 4;
Red:=(Re1+Re2+Re3+Re4)div 4;
ReferenceColor(Rp,Color,Blue,Green,Red);
plot (319-x,199-y,Color);
end;
end;
end; { конец процедуры }
begin { главная программа }
directvideo:=false;
Mode($13);
Randomize;
Janspalette;
Listpalette;
for x:=0 to 100 do begin
disk(random(320),random(200),random(50),random(40),Random(255));
end;
ColorText(96);
writeln('A B C D E F G H I J K L M N O P Q R S T ');
writeln(' U V W X Y Z 1 2 3 4 5 6 7 8 9 0 ');
writeln('a b c d e f g h i j k l m n o p q r s t ');
writeln(' u v w x y z !.;,:-? +( % ) * " $ ');
writeln(' ');
Half;
Zerokey;ch:=readkey;
end.
6.11.3 Перемещение изображения
-----------------------------------------------------------------
Следующая программа, ROLLDEMO, перемещает экран по
горизонтали. Для этого каждый вертикальный столбец пикселей
временно сохраняется в памяти, а затем перерисовывается в новой
позиции экрана. Вызов этой подпрограммы 320 раз приводит к полному
смещению картинки через экран.
Эта процедура работает относительно медленно, и поэтому не
дает эффекта гладкого скролинга экрана.
program ROLLDEMO; { смещение содержимого экрана }
uses crt,vga19;
var x,y,z : integer;
Procedure ScrollLeft;
var Degrees,x,y : integer;
Save: array[0..199] of integer;
begin
for x:=0 to 319 do begin
for y:=0 to 199 do begin
Peek(x,y,Save[y]);
end;
for y:=0 to 199 do begin
if x<>319 then Peek(x+1,y,Degrees) else Peek(0,y,Degrees);
Plot(x+319,y,Save[y]);
Plot(x,y,Degrees);
end;
end;
end;
begin
randomize;
directvideo:=false; Mode($13);
Janspalette; ColorText(100);
ShowPalette; Listpalette;
Disk(100,100,50,30,200);
repeat
ScrollLeft;
until keypressed;
end.
6.11.4 Восход солнца, программа Aurora
-----------------------------------------------------------------
Данная программа создает вариации картинки при помощи
генератора случайных чисел компьютера. Базовая картинка
изображает восход солнца над морем. Генератор случайных чисел
используется для создания изображения облаков в небе. Для этой
программы нужен модуль VGA19.TPU/VGA19.PAS, в котором находятся
необходимые графические процедуры.
Первая часть программы выводит некоторый вводный текст,
после чего начинается выполнение главного цикла программы. В этом
цикле значения ширины изображения солнца, цвета неба, воды и
облаков меняются генератором случайных чисел.
После установки позиции линии горизонта (также определяется
генератором) на экран накладываются цвета неба. Затем на экран
помещается солнце. И наконец, добавляются облака. Генератор также
определяет эффект тени от облаков. Это влияет на затемнение части
изображения под облаками.
Цвета облаков можно было бы сглаживать, что улучшили бы их
изображение, однако эта подпрограмма намеренно не была включена в
программу, чтобы картинка рисовалась быстрее. Соответствующие
коды можно добавить в программу позже.
Этот процесс завершает создание верхней части изображения.
Затем на рисунок добавляется море. Вода рисуется аналогично небу.
Более светлым цветом она изображается ближе к солнцу, что дает
эффект солнечных бликов на воде. И в конце следующая текстовая
процедура рисует на экране произвольным образом генерируемое имя
планеты.
Главный цикл программы перед созданием нового рисунка ждет
нажатия клавиши на клавиатуре. Конец программы - по нажатию
клавиши .
program aurora;
uses crt,vga19;
var x,y,z,n,zx,zy,sx,sy,Nm : integer;
c,Bu : char;
SkyColor,CloudColor, WaterColor,
SunColor,SunSize, Horizontal,
IslandColor,BreakerColor,VegetationColor : Integer;
Name : string;
Procedure ScrollLeft;
var
Degrees,x,y : integer;
SaveIt: array[0..199] of integer;
begin
for x:=0 to 319 do begin
for y:=0 to 199 do begin
peek(x,y,SaveIt[y]);
end;
for y:=0 to 199 do begin
if x<>319 then peek(x+1,y,Degrees) else peek(0,y,Degrees);
plot(x,y,Degrees);
plot(x-1,y,SaveIt[y]);
end;
end;
end;
begin
Randomize;
directvideo := false;
VMode($13);
Janspalette;
Palette(0,13,15,10);
gotoxy(1,1);TextColor(6);write(' Ян Рюггеберг, Бремен, Германия ');
gotoxy(1,3);TextColor(5);write(' Abacus 5370 52nd SE, GR MI 49512 ');
gotoxy(1,5);TextColor(4);write(' Эта программа написана на Turbo Pascal');
gotoxy(1,7);TextColor(3);write(' и использует модуль VGA19 (Рюггеберг).);
gotoxy(1,9);TextColor(2);write(' Палитра использует тона цвета кожи и ');
gotoxy(1,11);TextColor(1);write(' другие цвета. ');
gotoxy(1,15);TextColor(115);write(' При нажатии клавиши AURORA создает ');
gotoxy(1,17);TextColor(117);write(' рисунок пейзажа планеты. ');
gotoxy(1,19);TextColor(119);write(' Нажатие Esc завершает программу. ');
c:=readkey;
Border(0);
repeat
SunSize:=16*(random(random(16))+1);Horizontal:=100+Random(60)-Random(20);
SkyColor:=12*SunSize+2;
WaterColor:=SkyColor+6;SunColor:=SunSize+Random(Random(4));
CloudColor :=SkyColor-16;
SunSize:=SunSize div 4 +Random(4);
for y:=0 to Horizontal-2 do begin
for x:=0 to 319 do begin
plot(x,y,-random(y div 10)*16+SkyColor);
plot(x,Horizontal-Random(Random(Random(Horizontal))),-random(y div 10)*16+SkyColor);
end;
end;
sx:=Random(300)+5; sy:=Random(Horizontal-10)+5;
if SunColor=0 then SunColor:=1;
disk (sx,sy,SunSize+2,SunSize,SunColor);
circle(sx,sy,SunSize+2,SunSize,SunColor+1);
for y:=0 to SunSize do begin
zx:=Random(319+1); zy:=Random(Horizontal);
for x:= 0 to 500 do begin
plot(zx+Random(Random(Horizontal))-Random(Random(Horizontal)),zy+Random(2)-Random(6),CloudColor-random(2));
plot(zx+Random(Random(Horizontal))-Random(Random(Horizontal)),zy+Random(6)-Random(2),CloudColor+2-random(2));
end;
end;
for x:=0 to 319 do begin
plot(x,Horizontal-1,SkyColor+1);
plot(x,Horizontal,SkyColor+4);
plot(x,Horizontal+1,WaterColor);
end;
for y:=199 downto Horizontal do begin
for x:=0 to 319 do begin
plot(x,Horizontal+199-y,random((199-y)div 14)+WaterColor);
plot(x,Random(Horizontal)+Horizontal+2,Random(2)+WaterColor);
plot(sx+Random(random(random(y)))-Random(random(random(y))),Horizontal+199-y,WaterColor-random(5)-34);
end;
end;
Gotoxy(1,24);TextColor(121);write('Sunrise on the planet ');
Nm:=random(5)+1;Name:='';
for n:=0 to NM do begin
Bu:=chr(random(26)+65);
if Bu='C' then Bu:='E';if Bu='J' then Bu:='I';
if Bu='Q' then Bu:='A';if Bu='V' then Bu:='U';
if Bu='X' then Bu:='O';if Bu='Y' then Bu:='E';
Name:=Bu+Name;
end;
write(Name);
for x:=1 to 1 do ScrollLeft;
c:=readkey;
until c=chr(27);
end.
6.12 Несколько заключительных слов по поводу
расширений Turbo Pascal
-----------------------------------------------------------------
Некоторые из представленных в данной главе программ
показывают, каким образом можно программировать для видео-режима
19 платы VGA и для MCGA, не обращаясь для этого к языку машинных
команд процессора.
Языки Turbo Pascal и Turbo BASIC дают множество возможностей
для создания ясных и понятных программ, позволяющих использовать
преимущества графики VGA.
Для этого мы использовали команды, манипулирующие
регистрами, вызовами прерываний и прямым доступом к экранной
памяти. Благодаря этому языки программирования, не имеющие прямых
средств программирования графики в видео-режиме 19, получают эту
возможность.
Использование Turbo Pascal дает преимущество с точки зрения
скорости выполнения программ. Программы на Turbo Pascal по
скорости практически неотличимы от написанных на машинных кодах.
Текст программ, или исходный код на Turbo Pascal, гораздо
короче и легче для восприятия по сравнению с программами на языке
ассемблера или машинных кодов.
Программы на Turbo BASIC могут быть даже короче, чем
программы на Turbo Pascal. Однако ценой этого является
существенно более медленное выполнение, что может повлиять на
качество графических эффектов.
Это главный недостаток Бейсика, из-за которого многие
программисты обращаются к более сложным языкам, таким как Паскаль
или Си.
6.13 Список новых процедур на Паскале
-----------------------------------------------------------------
Процедуры из Главы 6:
procedure Mode(ModeHexNumber:integer);
procedure Mode19;
procedure FrameColor(ColorNumber:integer);
procedure ColorText(Color:integer);
procedure Palette(ColorNumber,Blue,Green,Red:integer);
procedure Blend(ColorNumber1,Blue1,Green1,Red1,
ColorNumber2,Blue2,Green2,Red2:integer);
procedure ShowPalette;
procedure JansPalette;
procedure AssignColor(ColorNumber,Color:integer);
procedure Plot(x1,y1:integer;Color:integer);
procedure Peek(x1,y1:integer;var OldColor:integer);
procedure Block(x1,y1,x2,y2:integer;Color:integer);
procedure Circle(xm,ym,a,b:LongInt;Color:integer);
procedure Disk(xm,ym,a,b:LongInt;Color:integer);
procedure Line(x1,y1,x2,y2:integer;Color:integer);
procedure Frame(x1,y1,x2,y2:integer;Color:integer);
procedure Feather(x1,y1,x2,y2:integer;
Color1,Color2:integer);
procedure Horizontal(x1,x2,y:integer;
Color1,Color2:integer);
procedure Ball(xm,ym,a,b:LongInt;
Color1,Color2:integer);
procedure Column(x1,y1,x2,y2:integer;
Color1,Color2:integer);
procedure MixHorizontal(x1,x2,y:integer;
Color1,Color2,Mix:integer);
procedure MixBall(xm,ym,a,b:LongInt;
Color1,Color2,Mix:integer);
procedure MixColumn(x1,y1,x2,y2:integer;
Color1,Color2,Mix:integer);
procedure ReadPalette(ColorNumber:integer;
var Blue,Green,Red:integer);
procedure PeekPalette(var x,y,
Blue,Green,Red:integer);
procedure ListPalette;
procedure PeekList(x,y:integer;
var Blue,Green,Red:integer);
procedure Similar(var Number,
Blue,Green,Red:integer);
procedure ReferenceColor(var Rtg,Number,
Blue,Green,Red:integer);
procedure Antalia(x1,y1,x2,y2:integer);
procedure Smooth(x,y:integer);
procedure SmoothCircle(xm,ym,a,b:LongInt);
procedure Dim(Number1,Number2,Add:integer);
procedure GrayScale(ColorNumber,Count:Byte);
procedure ZeroKey;
procedure Character(cc:string);
procedure HandWriting(cc:string);
procedure MiniTextXY(x,y:integer);
procedure MiniPrint(As:string);
procedure GlasPrint(As:string);
procedure HandWritingPrint(As:string);
Процедуры из примеров программ в Главах 6 - 10:
procedure Double;
procedure DoubleDouble;
procedure Half;
procedure RollLeft;
procedure SunPalette;
procedure ShowSystem(NewName:Boolean);
procedure ShowSun;
procedure ShowDevelopment;
procedure SolarSystem;
procedure ProgramDescription;
procedure SunRise(Select:Boolean);
|
|