Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Основи програмування Паскаль.docx
Скачиваний:
51
Добавлен:
12.05.2015
Размер:
511.7 Кб
Скачать

25. Модуль Graph і створення графіки на Паскалі

Для роботи із графікою із програми на Паскалі в папці, звідки вона запускається, повинен бути присутнім файл EGAVGA.BGI. Він представляє із себе графічний драйвер, призначений для керування відеопам'яттю в режимах підтримки моніторів типів EGA і VGA. Зрозуміло, сучасні монітори давно "переросли" ці два історично розповсюджені класи дисплеїв. Однак, на будь-якому сучасному комп'ютері підтримка відеорежимів EGA і VGA як і раніше можлива якщо не прямо, те через спеціальну програму-емулятор (див. кінець глави).

У поставку Паскаля можуть входити й інші файли з розширенням *.BGI, відповідальні за роботу з моніторами різних типів.

Крім того, при компіляції програми, що має графічний вивід, повинен бути доступний модуль GRAPH.TPU, що містить підпрограми отрисовки графічних об'єктів.

Бібліотека GRAPH.TPU підключається стандартним способом за допомогою USES у розділі описів програм:

USES Graph;

У графічному режимі, який у сучасних операційних системах типу Windows є основним, екран являє собою матрицю крапок (пикселов), причому є можливість висвітити будь-який пиксел будь-яким кольором. Координати кожного пиксела визначаються парою цілих чисел:

координата X- номер пиксела в рядку. Нумерація ліворуч праворуч, починаючи з 0;

координата Y - номер рядка пикселов. Нумерація рядків зверху вниз, починаючи з 0.

Таким чином, координати лівого верхнього кута екрана рівні (0,0). Будь-який об'єкт, высвечиваемый на екрані, являє собою сукупність окремих пикселов. При переході в графічний режим екран очищається. Кількість відтворених пикселов по горизонталі й вертикалі залежить від типу монітора й установленого графічного режиму(кожний монітор може використовувати кілька режимів, що відрізняються кількістю підтримуваних квітів і дозволом графічного екрана в пикселах):

монітор CGA - максимум 320*200 пикселов, монітор EGA – 640*350, монітор VGA – 640*480; Роботу з більш сучасними й потужними графічними режимами, що ставляться до класу Supervga, Паскаль безпосередньо не підтримує, хоча існують створені незалежними розроблювачами графічні драйвери цих режимів.

Режим функціонування екрана, крім кількості пикселов, характеризується певною палітрою- набором видимих квітів. Кожна палітра складається із чотирьох квітів для CGA або 16 квітів для EGA і VGA.

Установка графічного режиму здійснюється шляхом звертання до процедури Initgraph:

Initgraph(gd,gm,pt);

Цілочисельні змінні gdіgmзадають тип графічного дисплея й режим роботи графічного адаптера, строкова зміннаpt- шлях до файлу графічного адаптера (*.BGI). Приклад:

uses Graph;

var gd,gm,error: integer;

begin

gd:=VGA; {вибір адаптера VGA}

gm:=Vgahi; {режим 640 x 480 крапок x 16 кольорів}

Initgraph(gd,gm,'');

error:=Graphresult;

If error <> grok Then Begin

Write ('Помилка графіки: ', Grapherrormsg(error));

readln;

halt;

End;

Line (0,0,getmaxx,getmaxy); Readln; Closegraph;

end.

Тут установлюється графічний режим VGA 640*480 крапок з 16 квітами, тому що шлях до файлу EGAVGA.BGI зазначений порожнім, передбачається, що він перебуває в поточній папці, після переходу в графічний режим процедурою Lineрисується лінія з лівого верхнього в правий нижній кут екрана, потім, після натискання Enter, графічний режим закривається й відбувається вихід із програми.

Для автоматичного вибору максимально можливого режиму змінної gdнеобхідно привласнити значенняdetect, при цьому змінніgmіptне визначаються, якщо в поточному каталозі, у якім перебуває система Турбо Паскаль, є файли *.BGI. Приклад:

USES Graph;

VAR gd,gm: integer;

BEGIN

gd:=Detect;

Initgraph(gd,gm,'');

. . .

Розглянемо основні процедури й функції модуля Graph.

Closegraph;- завершує роботу в графічному режимі. Необхідно виконувати цю процедуру перед завершенням будь-якої графічної програми на Паскалі.

Cleardevice;очищає графічний екран. Обидві ці процедури не мають параметрів.

function Getmaxx:integer;- одержує максимальну координату по осі X

function Getmaxy:integer;- одержати максимальну координату по осі Y

Setcolor(Color);- установлює колір малювання ліній, крапок і тексту (аналог "пера" у програмах для малювання). Кольори кодуються так само, як у текстовому режимі. Для повноти картини перелічимо їх усе:

0 - чорний (BLACK) 8 - темно-сірий (DARKGRAY)

1 - синій (BLUE) 9 - блакитний (LIGHTBLUE)

2 - зелений (GREEN) 10 - ясно-зелений (LIGHTGREEN)

3 - ціановий (CYAN) 11 - ціановий^-ціановий-світло-ціановий (LIGHTCYAN)

4 - червоний (RED) 12 - ясно-червоний (LIGHTRED)

5 - фіолетовий (MAGENTA) 13 - фіолетовий^-фіолетовий-світло-фіолетовий (LIGHTMAGENTA)

6 - коричневий (BROWN) 14 - жовтий (YELLOW)

7 - ясно-сірий (LIGHTGRAY) 15 - білий (WHITE)

Setfillstyle (Style, Color);- установлює колір заповнення областей екрана (Color) і спосіб накладення кольору (Style). Є аналогом "кисті" у програмах для малювання ПараметрColorмає значення, зазначені вище, параметрStyle- від 1 до 11. ПриStyle=1– відбувається звичайне суцільне заповнення кольором, інші стилі дозволяють створити різні штрихування.Тут і далі замість цифр можна використовувати імена стилів, для стислості ми не будемо приводити їх усе.

Пр.Setfillstyle (Linefill,GREEN); {заповнення зеленими лініями}

Setfillstyle (Solidfill,RED); {суцільне заливання червоним}

Setlinestyle (Linestyle,Pattern,Thickness:integer);- визначає стиль малювання ліній. ТутLinestyleухвалює значення від 0 до 4,Patternпри використанні готових стилів завжди рівний 0, товщина лінії вказується тільки значенням 1 або 3 (у пикселах).

Пр.Setlinestyle (0,0,1); {Суцільна тонка лінія}

Setlinestyle (1,0,3); {Толста пунктирна}

Putpixel(X,Y,Color);- высвечивает на екрані пиксел з координатами X,Y і кольоромColor.

function Getpixel (X,Y:integer):integer;- поверне код кольору пиксела з координатами (X,Y)}

Line(X1,Y1,X2,Y2);- малює поточним кольором лінію з координатами початку (X1,Y1), і кінця (X2,Y2).

Moveto(X,Y); - установлює поточну позицію малювання в (X,Y)

Lineto(X,Y);- проводить пряму з поточної позиції в крапку з координатами (X,Y) поточним кольором.

Linerel(Dx,Dy);- проводить пряму з поточної позиції в крапку зі збільшенням координат від поточних на Dx і Dy, збільшення можуть бути й негативними.

Rectangle(X1,Y1,X2,Y2);- малює прямокутник з координатами лівого верхнього кута (X1,Y1) і правого нижнього кута (X2,Y2).

Bar(X1,Y1,X2,Y2);- малює зафарбований прямокутник з координатами діагоналі (X1,Y1) і (X2,Y2) кольором, установленим процедурою Setfillstyle.

Bar3d (X1,Y1,X2,Y2,Depth:integer; Top:boolean);- малює тривимірний паралелепіпед; параметрDepthвизначає глибину по осі X,Topуказує, чи малювати верхню грань

Пр.Bar3D (50,50,100,100,20,TRUE);

Drawpoly (Numpoint:integer; var Polypoints);- процедура малює багатокутник або ламану лінію. Аналогічна процедураFillpolyстворює зафарбований кольором заливання багатокутник. Вивчимо роботу процедури на прикладі:

Пр.

var Poly: array [1..10] of integer;

Poly[1]:=20; Poly[2]:=20; Poly[3]:=60; Poly[4]:=30;

{непарні номери – коорд. X}

Poly[5]:=60; Poly[6]:=60; Poly[7]:=40; Poly[8]:=80;

{парні – коорд. Y}

Poly[9]:=20; Poly[10]:=20; Drawpoly (5,Poly);

Floodfill (X,Y,Bordercolor:integer);- потужна процедура, що дозволяє зафарбувати будь-яку замкнену область, якої належить крапка (x,y) і яка обмежена по краях кольоромBordercolor.

Circle(X,Y,R);- малює окружність із центром у крапці з координатами (X,Y) і радіусомR.

Arc(X,Y,SA,EA,R); - малює дугу окружності із центром у крапці з координатами (X,Y), радіусомR, початковим кутомSAі кінцевим кутомEA. КутиSAіEAвиміряються в градусах і відлічуються проти годинникової стрілки від осі абсцис.

Існують також процедури для малювання еліпсів і секторів.

Outtextxy(X,Y,Text);- виводить текст на екран, починаючи із крапки з координатами X,Y. ТутText- константа або змінна строкового типу.

Outtext(Text);- виводить текст на екран, починаючи з поточної позиції.Text- константа

або змінна типу string.

Для стислості ми не розглядаємо методи прив'язки тексту до позицій на екрані. У бібліотеці Graph немає процедур для виведення чисельних даних. Для цього необхідно спочатку перетворити число в рядок за допомогою процедури Str, а потім за допомогою '+' підключити її до виведеною процедуроюOuttextxyрядку. Наприклад:

Max:=34.56; {Число}

Str(Max:6:2,Smax); {Перетворення числа Max у рядок Smax}

Outtextxy(400,40,'Максимум=' + Smax);

{Вивід рядка Smax з коментарем}

function Textheight (Textstr: string):integer;- поверне висоту рядка в пикселах

function Textwidth (Textstr: string):integer;- поверне ширину рядка в пикселах

Існують також процедури для керування зовнішніми графічними шрифтами, що зберігаються у файлах *.chr.

Приведемо приклади графічних програм.

Пр. Процедура, що виводить рядок тексту в центр прямокутника на екрані

procedure Centerstring (X1,Y1,X2,Y2,Color :integer; Str: string);

var cx,cy:integer;

begin

Setcolor (Color); {Установлюємо колір}

Rectangle (x1,y1,x2,y2); {Малюємо}

Rectangle (x1+2,y1+2,x2-2,y2-2); { рамку}

cx:=(x1+ x2) div 2; {Координати}

cy:=(y1+ y2) div 2; { центру прямокутника}

Settextjustify (Centertext,Centertext);{Вирівнювання тексту по центру}

Outtextxy (cx,cy,Str); {Вивід рядка}

end;

{ Звертання до даної процедури: }

... Centerstring (100,100,200,200,YELLOW,'Hello!');

Пр.Малюємо на екрані лінійний об'єкт (будиночок зі змінним числом вікон і поверхів) і "радіальний" об'єкт, для якого потрібний перерахування з декартовых координат у полярні (сонце із променями). Схема, що пояснює принцип перекладу з декартовых координат у полярні, наведена нижче.

program Domik;

uses Graph,Crt;

var Driver, Mode: Integer;

i,j,u,N,K,x2,y2:integer;

rad:real; sunx,suny:integer;

begin { Для простоти не перевіряємо правильність уведення}

Writeln ('Скільки поверхів?'); Read (N);

Writeln ('Скільки вікон на поверх?'); Read (K);

Driver := VGA; Mode:=Vgahi; Initgraph(Driver, Mode,'');

{Будиночок}

Setcolor (15);

Rectangle (20,getmaxy-20-70*n,20+k*50+(k+1)*20,getmaxy-20);

{Дах}

Moveto (20,getmaxy-20-70*n);

Lineto(10,getmaxy-20-70*n);

Lineto (20,getmaxy-40-70*n);

Lineto (20+k*50+(k+1)*20,getmaxy-40-70*n);

Lineto (30+k*50+(k+1)*20,getmaxy-20-70*n);

Lineto (20+k*50+(k+1)*20,getmaxy-20-70*n);

{Лінії між поверхами}

For i:=1 To N Do

Line (20,getmaxy-20-70*i,20+k*50+(k+1)*20,getmaxy-20-70*i);

Setfillstyle (Solidfill, Yellow);

{Вікна на кожному поверсі}

For i:=1 To N Do {Цикл по поверхах}

For j:=1 To K Do Begin {Цикл по вікнах}

Bar (20+(j-1)*70+20,getmaxy-20-(i-1)*70-60,

20+(j-1)*70+70,getmaxy-20-(i-1)*70-10);

End;

sunx:=getmaxx-50; {Центр сонця - координати на екрані}

suny:=50;

Fillellipse (sunx, suny, 30, 30); {Малюємо контур сонця}

Setcolor (Yellow);

{Малюємо промені}

u:=0;

While u<=360 Do Begin {кут u міняємо від 0 до 360 градусів}

rad:=u*pi/180; { переклад із градусів у радіани для функцій sin,cos }

{ rad радіан = u градусів }

{ pi радіан = 180 градусів }

x2:=Round(sunx+50*cos(rad)); { x=r*cos(fi),y=r*sin(fi) - формули для }

y2:=Round(suny+50*sin(rad)); { перекладу з полярних координат у декартовы }

Line (sunx,suny,x2,y2);

u:=u+12; {крок по куту=12 градусів}

End;

repeat until keypressed;

Closegraph;

end.

Пр.Програма побудови графіка функції f(x) у заданих границях [a,b] зміни аргументу x. Схема перерахування наведена нижче.

program Graphoffun;

uses graph,crt; { Використовуємо графічний і екранний модулі Паскаля }

function f(x:real):real; { Функція, графік якої будуємо }

begin

f:=sin(x)+cos(x);

end;

function getreal(s:string):real;

var f:real; {Уведення із клавіатури речовинного числа з контролем помилок}

begin

repeat

write (s);

{$I-}readln(f);{$I+}

if Ioresult=0 then break

else writeln ('Помилка! Уведене не число');

until false;

getreal:=f;

end;

procedure Init; { Процедура ініціалізації графічного режиму }

{ VGA 640*480 пикселов, 16 квітів }

var driver,mode,error:integer;

begin

driver:=VGA;

mode:=Vgahi;

Initgraph(driver,mode,'');

error:=Graphresult;{ Перевіряємо результат останньої операції із графікою }

if error<>0 then begin { Не нуль означає помилку! }

Writeln;

Write ('Не можу инициализировать графіку! Помилка ',Grapherrormsg(error));

Halt (1); { Повідомлення про помилку й достроковий вихід із програми }

end;

end;

var a,b: real; { Границі зміни x }

xmax,ymax: integer; { Розміри графічного екрана по довжині й висоті }

xstep:real; { Крок по X, що залежить від дозволу монітора }

x,fx:real; { Поточні значення аргументу й функції }

fmax,fmin:real; { Максимальне й мінімальне значення f(x) }

cx,cy:integer; { Екранні координати крапки (x,f(x)) }

oldx,oldy:integer; { У ці змінні будемо запам'ятовувати координати

останньої крапки, щоб з'єднати її з поточної }

xcoef,ycoef:real; { Коефіцієнти перерахування до екранних координат }

ss:string; { Рядок для виведення тексту на екран }

begin { Початок головної програми }

clrscr;

repeat { Цикл уведення границь a,b з перевіркою }

{ правильності введення }

a:=getreal ('Ліва границя по X=');

b:=getreal ('Права границя по X=');

if a>b then write ('Помилка! Ліва границя повинна бути менше правої');

until a<b;

Init; { Инициализировать графіку }

xmax:=getmaxx; ymax:=getmaxy; { Довідатися розміри графічного екрана }

xstep:=(b-a)/(xmax-19); { Довідатися крок по X, що відповідає одному }

{ пикселу. Перші й останні 10 пикселов не використовуємо, тому залишається

xmax-19 пикселов для малювання графіка.

Щоб масштабувати дані по осі Y, потрібно спочатку довідатися максимальне

і мінімальне значення f(x), тому потрібен цикл: }

x:=a; { Починаємо з лівої границі }

fmax:=f(a); fmin:=fmax;

while x<=b do begin { Цикл обчислення чергового значення f(x) }

fx:=f(x); { Обчислили f(x) за допомогою підпрограми }

if fx>fmax then fmax:=fx { Шукаємо максимум і }

else if fx<fmin then fmin:=fx; { мінімум f(x) }

x:=x+xstep; { Робимо крок по X }

end; { Кінець першого циклу }

{ Тепер значення f(x) обмежені інтервалом [fmin,fmax],

значення x обмежені межами [a,b] і можна будь-яку крапку з

координатами (x,f(x)) перевести в крапку на екрані монітора.

Взагалі, X, що належить інтервалу [A,B], можна лінійно перетворити

в Y, що належить інтервалу [C,D] по формулі

D - C

Y = C + (X - A) ---------

B - A

Використовуємо цю формулу для розрахунків коефіцієнтів перетворення величин

x, f(x) до екранних координат cx,cy }

xcoef:=(xmax-19)/(b-a);

ycoef:=(ymax-19)/(fmax-fmin);

{ Намалюємо на екрані обрамлення графіка й граничні значення по осях X,Y: }

setfillstyle (Solidfill,Cyan);

bar (10,10,xmax-10,ymax-10);

setcolor (Yellow);

rectangle (9,9,xmax-9,ymax-9);

{ Для горизонтального тексту крапкою прив'язки буде лівий верхній кут

прямокутника з текстом, а розмір символу за замовчуванням рівний 8*8 крапок.

З обліком цього вважаємо координати для функції Outtextxy }

str (a:8:3,ss); outtextxy (2,ymax-8, ss); { Ліва границя по X }

str (b:8:3,ss); outtextxy (xmax-66,ymax-8, ss); { Права границя по X }

settextstyle (Defaultfont,Vertdir,1); { Границі по Y виводимо вертикально }

{ Для поверненого на 90 градусів тексту крапкою прив'язки буде

правий верхній кут прямокутника з текстом. }

str (fmax:8:3,ss); outtextxy (9,2, ss); { Максимум f(x) }

str (fmin:8:3,ss); outtextxy (9,ymax-66, ss); { Мінімум f(x) }

setcolor (White); { Установлюємо колір для малювання графіка }

{ Тепер можна в циклі отрисовать значення f(x): }

x:=a;

while x<=b do begin

fx:=f(x);

cx:=10+Round((x-a)*xcoef); { Екранна координата X }

cy:=ymax-10-round((fx-fmin)*ycoef); { Екранна координата Y - урахували, }

{ що вона вважається зверху вниз! }

putpixel (cx,cy,Lightred); { Нарешті, ставимо крапку на екрані }

if x>a then line (oldx,oldy,cx,cy); { З'єднуємо дві останні крапки - }

{ це поліпшує графік у випадку різкої зміни f(x) }

oldx:=cx; oldy:=cy; { Запам'ятовуємо поточну крапку }

x:=x+xstep; { Переходимо до наступної крапки на екрані }

end; { Кінець циклу отрисовки }

repeat until Keypressed; { Чекаємо натискання будь-якої клавіші }

Closegraph; { Повернутися в текстовий режим }

end. { Кінець програми }

Недолік цієї програми – відсутність пропорційного масштабування по осях x і y. Подумайте, як її можна поліпшити. Лістинг 12 з Додатка 4 представляє більш об'ємну графічну програму, що реалізує нескладну комп'ютерну гру. Функція Drawцього лістингу може також бути прикладом обробки 16-кольорового зображення у форматі BMP із програми на Паскалі.

Розв'язок завдань, пов'язаних з виводом графіки на екран, часто вимагає збереження ділянки екранного зображення в оперативній пам'яті з наступним відновленням колишньої картинки. Для розв'язку цієї проблеми в бібліотеці Graphпередбачений набір відповідних функцій.

У першу чергу потрібно оцінити обсяг пам'яті, необхідний для збереження ділянки екрана. Стандартна функція бібліотеки Graph, що має видImagesize (x1,y1,x2,y2:integer):Word, деx1,y1– екранні координати верхнього лівого, аx2,y2– правого нижнього кута, повертає число байт пам'яті, необхідних для збереження заданої прямокутної області. Ця функція може визначити обсяг пам'яті до 64 Кб включно, тому що тип значення, що вертається, – беззнаковецілеWord (див. розділ 2.2). Якщо кількість необхідної пам'яті більше або рівно 64 Кб, вертається значення помилки-11(grerror). Зрозуміло, виклик функції припускає, що монітор перебуває в графічному режимі.

Після того, як необхідна кількість байт визначене, програма повинна подбати про виділення ділянки оперативної пам'яті, призначеного для збереження зображення. Це легко зробити, використовуючи системну процедуру Getmem (var p:Pointer; size:Word), де обсяг пам'ятіsizeраніше визначений функцієюImagesize, а зміннаpявляє собоюпокажчик. Раніше незнайомий нам тип даних "покажчик" служить для непрямого виклику одних змінних через інші. Фактично, змінна-покажчик зберігає адреса інший типізованої змінної й може звернутися до неї, використовуючи синтаксисp, деp– ім'я покажчика. Застосування покажчиків дозволяє створювати динамічні змінні, здатні в різні моменти часу адресувати різні ділянки оперативної пам'яті, у яких зберігаються дані. Найбільший блок пам'яті, який може виділитиGetmem, також рівний 64 Кб. Звільнити раніше зайняту пам'ять можна процедуроюFreemem (var p:Pointer; size:word).

Нарешті, третій крок – зберегти ділянку екрана, використовуючи тільки що сформований в оперативній пам'яті буфер. Для цієї мети досить використовувати процедуру Getimage (x1,y1,x2,y2:Integer; var p). Тут параметриx1,y1,x2,y2мають той же зміст, що для функціїImagesize, а нетипізований параметр-покажчикpотриманий процедуроюGetmem.

Тепер необхідний ділянка екрана збережена в пам'яті й може бути зайнятий новим зображенням. Після того, як зображення виконало свої функції й потрібно відновити колишній фрагмент екрана, досить викликати процедуру Putimage (x,y:integer; var p; mode:word), деx,y– екранні координати лівого верхнього кута відновлюваної області,p– покажчик на збережену пам'ять, а зміннаmodeвизначає, яка двійкова операція буде використана при виведення зображення на екран. Для незміненого відновлення зображення слід передавати в якостіmodeзначенняNormalput, інші можливі значення параметра –Copyput,Xorput,Orput,AndputіNotput. Усі описані функції використані в лістингу, наведеному нижче. Його вивчення допоможе Вам у написанні аналогічних програм, що підтримують рух по екрану графічних об'єктів.

Uses Graph,Crt;

Var Gd, Gm : Integer;

P : Pointer;

Size : Word;

x,y,width,height: integer;

ch:char;

changed:boolean;

Begin

{Ініціалізація графіки}

Gd:=VGA; Gm:=Vgahi;

Initgraph(Gd, Gm, '');

If Graphresult <> grok Then Halt(1);

{Отрисовка тла}

Setfillstyle(Xhatchfill, Cyan);

Bar(0, 0, Getmaxx, Getmaxy);

{Параметри активного вікна}

x:=getmaxx div 2;

y:=getmaxy div 2;

width:=40;

height:=30;

{Виділення пам'яті для збереження тла під вікном}

Size := Imagesize(x,y,x+width-1,y+height-1);

Getmem(P, Size);

Getimage(x, y, x+width-1, y+height-1, P);

{Перша отрисовка активного вікна}

Setfillstyle(Solidfill, Red);

bar (x,y,x+width-1,y+height-1);

{Ознака зміни положення вікна}

changed:=false;

repeat {Цикл руху об'єкта}

ch:= readkey; {Читаємо код клавіші}

if ch=#0 then begin {Якщо це розширений код...}

ch:= readkey; {...те читаємо другий байт}

case ch of {Реагуємо тільки на 4 клавіші:}

#72: if y>0 then changed:=true; {стрілка нагору}

#80: if y+height<getmaxy then changed:=true; {стрілка вниз}

#75: if x>0 then changed:=true; {стрілка вліво}

#77: if y+width<getmaxx then changed:=true; {стрілка вправо}

end;

if changed=true then begin {якщо прапор реакції виставлений}

Putimage(x, y, P, Normalput);

{відновлюємо екран під вікном}

case ch of {і міняємо потрібну координату вікна}

#72: dec(y);

#80: inc(y);

#75: dec(x);

#77: inc(x);

end;

Getimage(x, y, x+width-1, y+height-1, P);

{зберігаємо екран під новим положенням вікна}

bar (x,y,x+width-1,y+height-1); {і перемальовуємо вікно}

changed:=false; {не забуваємо скинути прапор зміни}

end;

end;

until ch=#27; {...поки не натиснута Esc}

Freemem (p,size); {звільняємо раніше виділену пам'ять}

Closegraph; {і закриваємо графіку}

End.

Говорячи про написання графічних програм стосовно до Паскалю, не можна обійти стороною питання про підтримку Dos-Графіки сучасними комп'ютерами. На жаль, багато сучасних платформ не підтримують графічні відеорежими DOS. Допомогти може емулятор Dos-Машини, такий як вільно розповсюджувана програма Dosbox. Скачавши Dosbox за адресою http://dosbox.sourceforge.netі встановивши її, ми можемо запускати додатка DOS у будь-якому відеорежимі з підтримкою (емуляцією) численних застарілих програмних і апаратних розв'язків.

Бажане також установити оболонку емулятора, що дозволяє створювати для Dos-Додатків ярлики, що настроюються. Оболонка Dosshell доступна за адресою http://www.loonies.narod.ru/dosshell.htm, а довідатися про емулятори DOS більше Ви можете по адресахhttp://ru.wikipedia.org/wiki/DOSBox,http://gh.gameslife.ru/text/dosbox.htm.