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

Video cards have evolved very much 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 resolution, as demonstrated in the below example.

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 second example below.

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

Example

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.

Example

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
      CloseGraph();
    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.

Example

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');
procedure WriteRes(const depth : integer);
var
  tw, th : integer;
  v, text : String;
begin
  text := 'Current resolution is '; str(getmaxx+1, v);
  text := text + v + 'x'; str(getmaxy+1, v);
  text := text + v + 'x' + gdnames[depth];
  setTextStyle(defaultFont,horizDir,1);
  TW:=TextWidth(text);
  TH:=TextHeight(text);
  outTextXY((getMaxX - TW) div 2,
            (getMaxY - TH) div 2,text);
end;
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);
          WriteRes(gd);
        close(t);
        end;
    append(t);
    writeln(t);
    close(t);
    end;
  Writeln('All supported modes are listed in modes.txt files');
end.