[next] [tail] [up]

### 8.1 Introduction

#### Requirements

The unit Graph exports functions and procedures for graphical output. It requires at least a VGA-compatible Card or a VGA-Card with software-driver (min. 512Kb video memory).

#### A word about mode selection

The graph unit was implemented for compatibility with the old Turbo Pascal graph unit. For this reason, the mode constants as they were defined in the Turbo Pascal graph unit are retained.

However, since

1. Video cards have evolved very much
2. Free Pascal runs on multiple platforms

it was decided to implement new mode and graphic driver constants, which are more independent of the specific platform the program runs on.

In this section we give a short explanation of the new mode system. the following drivers were defined:

     D1bit = 11;
     D2bit = 12;
     D4bit = 13;
     D6bit = 14;  { 64 colors Half-brite mode - Amiga }
     D8bit = 15;
     D12bit = 16; { 4096 color modes HAM mode - Amiga }
     D15bit = 17;
     D16bit = 18;
     D24bit = 19; { not yet supported }
     D32bit = 20; { not yet supported }
     D64bit = 21; { not yet supported }

     lowNewDriver = 11;
     highNewDriver = 21;

Each of these drivers specifies a desired color-depth.

The following modes have been defined:

     detectMode = 30000;
     m320x200 = 30001;
     m320x256 = 30002; { amiga resolution (PAL) }
     m320x400 = 30003; { amiga/atari resolution }
     m512x384 = 30004; { mac resolution }
     m640x200 = 30005; { vga resolution }
     m640x256 = 30006; { amiga resolution (PAL) }
     m640x350 = 30007; { vga resolution }
     m640x400 = 30008;
     m640x480 = 30009;
     m800x600 = 30010;
     m832x624 = 30011; { mac resolution }
     m1024x768 = 30012;
     m1280x1024 = 30013;
     m1600x1200 = 30014;
     m2048x1536 = 30015;

     lowNewMode = 30001;
     highNewMode = 30015;

These modes start at 30000 because Borland specified that the mode number should be ascending with increasing X resolution, and the new constants shouldn’t interfere with the old ones.

The above constants can be used to set a certain color depth and resultion, as demonstrated in the following example:

Listing: graphex/inigraph1.pp

Program inigraph1;
{ Program to demonstrate static graphics mode selection }
uses graph;
const
TheLine = 'We are now in 640 x 480 x 256 colors!'+
' (press <Return> to continue)';
var
gd, gm, lo, hi, error,tw,th: integer;
found: boolean;
begin
{ We want an 8 bit mode }
gd := D8bit;
gm := m640x480;
initgraph(gd,gm,'');
{ Make sure you always check graphresult! }
error := graphResult;
if (error <> grOk) Then
begin
writeln('640x480x256 is not supported!');
halt(1)
end;
{ We are now in 640x480x256 }
setColor(cyan);
rectangle(0,0,getmaxx,getmaxy);
{ Write a nice message in the center of the screen }
setTextStyle(defaultFont,horizDir,1);
tw:=TextWidth(TheLine);
th:=TextHeight(TheLine);
outTextXY((getMaxX - TW) div 2,
(getMaxY - TH) div 2,TheLine);
{ Wait for return }
readln;
{ Back to text mode }
closegraph;
end.

If other modes than the ones above are supported by the graphics card, you will not be able to select them with this mechanism.

For this reason, there is also a ’dynamic’ mode number, which is assigned at run-time. This number increases with increasing X resolution. It can be queried with the getmoderange call. This call will return the range of modes which are valid for a certain graphics driver. The numbers are guaranteed to be consecutive, and can be used to search for a certain resolution, as in the following example:

Listing: graphex/inigraph2.pp

Program inigraph2;
{ Program to demonstrate dynamic graphics mode selection }
uses graph;
const
TheLine = 'We are now in 640 x 480 x 256 colors!'+
' (press <Return> to continue)';
var
th,tw,gd, gm, lo, hi, error: integer;
found: boolean;
begin
{ We want an 8 bit mode }
gd := D8bit;
{ Get all available resolutions for this bitdepth }
getmoderange(gd,lo,hi);
{ If the highest available mode number is -1,
no resolutions are supported for this bitdepth }
if hi = -1 then
begin
writeln('no 8 bit modes supported!');
halt
end;
found := false;
{ Search all resolutions for 640x480 }
for gm := lo to hi do
begin
initgraph(gd,gm,'');
{ Make sure you always check graphresult! }
error := graphResult;
if (error = grOk) and
(getmaxx = 639) and (getmaxy = 479) then
begin
found := true;
break;
end;
end;
if not found then
begin
writeln('640x480x256 is not supported!');
halt(1)
end;
{ We are now in 640x480x256 }
setColor(cyan);
rectangle(0,0,getmaxx,getmaxy);
{ Write a nice message in the center of the screen }
setTextStyle(defaultFont,horizDir,1);
TW:=TextWidth(TheLine);
TH:=TextHeight(TheLine);
outTextXY((getMaxX - TW) div 2,
(getMaxY - TH) div 2,TheLine);
{ Wait for return }
readln;
{ Back to text mode }
closegraph;
end.

Thus, the getmoderange function can be used to detect all available modes and drivers, as in the following example:

Listing: graphex/modrange.pp

Program GetModeRange_Example;
{ This program demonstrates how to find all available graph modes }
uses graph;
const
{ Currently, only 4, 8, 15 and 16 bit modes are supported
but this may change in the future }
gdnames: array[D4bit..D16bit] of string[6] =
('4 bit','6 bit','8 bit','12 bit','15 bit','16 bit');
var
t: text;
line : string;
gd, c, low, high, res: integer;
begin
assign(t,'modes.txt');
rewrite(t);
close(t);
for gd := D4bit to D16bit do
begin
{ Get the available mode numbers for this driver }
getModeRange(gd,low,high);
append(t);
write(t,gdnames[gd]);
Writeln(t,': low modenr = ',low,', high modenr = ',high);
close(t);
{ If high is -1,
no resolutions are supported for this bitdepth }
if high = -1 then
begin
append(t);
writeln(t,' No modes supported!');
writeln(t);
close(t);
end
else
{ Enter all supported resolutions for this bitdepth
and write their characteristics to the file }
for c := low to high do
begin
append(t);
writeln(t,' testing mode nr ',c);
close(t);
initgraph(gd,c,'');
res := graphresult;
append(t);
{ An error occurred when entering the mode? }
if res <> grok then
writeln(t,grapherrormsg(res))
else
begin
write(t,'maxx: ',getmaxx,', maxy: ',getmaxy);
Writeln(t,', maxcolor: ',getmaxcolor);
closegraph;
end;
writeln(t);
close(t);
end;
append(t);
writeln(t);
close(t);
end;
Writeln('All supported modes are listed in modes.txt files');
end.

[next] [front] [up]