
{DEMO - demo program for BGI256 driver }
{as of 21 May 1995}
{Usage:  "DEMO256 [ModeNumber] [Driver]" } {vga="1 3"} {vga256="0 5"}

{$M 30000,0,500000}
PROGRAM DEMO256;
USES crt,dos,GRAPH,AniSub,WrMode,VesaChk,LpUnit;

{- $DEFINE INTERNAL}  {make this definition valid to load driver into code}

CONST drv : INTEGER = DETECT;
      mode : INTEGER = 0;
      result : INTEGER = 0;
      ERROR : INTEGER = 0;

VAR   Temp,I,X,Y,Xi,Yi,H,L:INTEGER;
      xtemp,ytemp:integer;
      wl,XL,YL,TL,SL,VL,T : longint;
      f:text;
      ts,s:string;
      P : pointer;
      SPix,SPiy:word;
      Size,C,K,J : word;
      LineStyle : word;
      ch :char;
      Pal:PaletteType;
      Max  : integer;
      x1,y1,x2,y2 : word;
      SelectMode : integer;
      WhichDriver : integer;
      Poly : array[0..10] of pointtype;
      RGBpal : RGBpaletteType;

function fstr(I:integer):string;
var s:string;
begin
  str(i,s);
  fstr := s;
end;


{$F+}
function AutoDet:integer;
begin
  AutoDet := SelectMode;  {Autodetect the mode}
end;
{$F-}

{$IFDEF INTERNAL}
  procedure Bgi256Proc; external;
  {$L BGI256.OBJ}
{$ENDIF}


BEGIN
  P := nil;
  StartMouse;      {code to hide mouse cursor if needed}

{--------------------------------------------------}
{misc commands that initialize the graphics system }

  SelectMode := 0;
  S := 'x';
  if paramcount > 0 then
  begin
    s := ParamStr(1);
    case s[1] of
      '0': SelectMode := 0;
      '1': SelectMode := 1;
      '2': SelectMode := 2;
      '3': SelectMode := 3;
      '4': SelectMode := 4;
      '5': SelectMode := 5;
     else
       SelectMode := 127;
    end; {case}
  end;
  WhichDriver := 0;
  if paramcount > 1 then
  begin
    s := Paramstr(2);
    case s[1] of
      '0': WhichDriver := 0;
      '1': WhichDriver := 1;
      '2': WhichDriver := 2;
      '3': WhichDriver := 3;
      '4': WhichDriver := 4;
      '5': WhichDriver := 5;
      else val(s,WhichDriver,Error);
    end; {case}
  end;
  temp := Paramcount;
  if (WhichDriver < 6) then
    DRV := 0
  else
    DRV := WhichDriver-5;
  Result := 0;


  WRITELN('BGI Driver Demo V3.05  Copyright (c) 1992,1995 Knight Software');

  if (WhichDriver <= 5) then
  begin
    case WhichDriver of
      0: result := installuserdriver('BGI256',  @AutoDet);
      1: result := installuserdriver('V7BGI256',@AutoDet);
      2: result := installuserdriver('TRI256',  @AutoDet);
      3: result := installuserdriver('egavga',  @AutoDet);
      4: result := installuserdriver('VESA16',  @AutoDet);
      5: result := installuserdriver('VGA256',  @AutoDet);
    end; {case}
  end;
  ERROR := graphresult;
  WRITELN('INSTALLresult = ', result,' ',drv,'  ',mode);

{$IFDEF INTERNAL}
  Temp := RegisterBGIdriver(@Bgi256Proc);
{$ENDIF}

{  detectgraph(drv,mode);
  if drv > 0 then
    drv := result
  else
    drv := 0; }

  mode := 0;
  initgraph( drv, mode, '' );
  Result := GraphResult;
  if (Result <> 0) or (drv < 0) then
  begin
    closegraph;
    writeln('Graph Driver:',drv,' Graph Mode:',mode,' not supported');
    halt(1);
  end;

{--------------------------------------------------}
{misc commands that identify the graphics system }

  Mode := GetGraphMode;
  Max := GetMaxMode;
  if SelectMode = 127 then SelectMode := 0;

(*
  SetWriteMode(2);
  SetWriteMode($E0+25);
  Result := GetMaxMode;
*)

  GetRGBblock(0,256,RGBpal);

{  FOR I := 0 TO 255 DO
  begin
    RGBpal[i].red   := i;
    RGBpal[i].green := i;
    RGBpal[i].blue  := i;
  end;
  SetRGBblock(0,256,RGBpal); }

 { InhibitBiosPaletteReload;
  InhibitGraphPaletteReload;
  RestoreCRTmode; }

  SetGraphMode(SelectMode);    {<-- set the desired mode here}
  result := graphresult;

  UpdateDisplayInfo;     {update info and identify the version of BGI256}
  cleardevice;
  GraphDefaults;


  C := GetColor;
  setcolor(white);
  SettextStyle(0,0,1);
  X := succ(GetMaxX);
  Y := succ(GetMaxY);
  outtextxy(10,GetMaxY-15,'Result:'+fstr(result)+' Drv:'+fstr(drv)+' Mode:'+fstr(mode)+' Max:'+fstr(Max)+' C:'+Fstr(C));
  outtextxy(GetMaxX-68,GetMaxY-120,'Sx:'+fstr(X));
  outtextxy(GetMaxX-68,GetMaxY-110,'Sy:'+fstr(Y));
  if VirtualBGI then
  begin
    outtextxy(GetMaxX-68,GetMaxY-100,'Vx:'+fstr(VirtualWidth));
    outtextxy(GetMaxX-68,GetMaxY-90, 'Vy:'+fstr(VirtualHeight));
    outtextxy(GetMaxX-68,GetMaxY-130,'Sb:'+fstr(ScanLength));
    Size := VideoMemorySize;
    if Size <> 0 then
      outtextxy(GetMaxX-68,GetMaxY-140,'M:'+fstr(Size)+'K');
  end;

  ts := '';
  s := GetDriverName;  {preload S with driver name if available}
  if length(S) > 0 then s := s+' ';
  if (BGIVersion > 0) then
  begin
    ts := fstr(BGIVersion mod 100);
    if Length(ts) = 1 then ts := '0'+ts;
    ts := 'V'+fstr(BGIVersion div 100)+'.'+ts;
  end;
  s := s + ts;
  if length(S) > 0 then s := s+': ';
  mode := GetGraphMode;
  ts := GetModeName(mode);
  if (length(s) > 0) and (length(ts) > 0) then s := s+' ';
  s := s+ts;
  x := (GetMaxX div 2) - (TextWidth(s) div 2);
  outtextxy(X,15,s);       {eg "320x200 VGA/MCGA"}

{--------------------------------------------------}
{simple commands that excersize the graphics system }

  C := 7;
  C := GetMaxColor;
  GetModeRange(drv,L,H);
  Max := GetMaxMode;
  GetDefaultPalette(Pal);
  SetBkColor(0);
  C := 5;
  SETCOLOR(C);
  C := GetColor;

  MOVETO(0,0);         {test cp and putpixel}
  FOR Y := 0 TO 10 DO
    FOR X := 0 TO 10 DO
      PUTPIXEL(X,Y,3);

  SPix := 10;          {show colors available}
  SPiy := 155;
  MOVETO(SPix,SPiy);
  FOR X := 0 TO 255+1 DO
  begin
    PutPixel(SPix+X-1,pred(SPiy),15*(X and 1));
    PutPixel(SPix+X-1,succ(SPiy+10),15*(X and 1));
  end;
  FOR Y := SPiy TO SPiy+10 DO
  begin
    PutPixel(pred(SPix),Y,15*(Y and 1));
    PutPixel(255+SPix+1,Y,15*(Y and 1));
    FOR X := 0 TO 255 DO
    BEGIN
      PUTPIXEL(SPix+X,Y,X);
    END;
  end;


  SETFILLSTYLE(XHatchFill,2);       {misc bar types}
  bar( 20, 20, 35, 35 );
  SETFILLSTYLE(XHatchFill,4);
  bar( 21, 21, 36, 36 );
  SETFILLSTYLE(1,6);
  bar( 50, 50, 85, 97 );
  SETFILLSTYLE(2,2);
  BAR3D(30,60,60,95,10,true);
  setFILLSTYLE(3, 3 );
  bar( GetMaxX-40, GetMaxY-80, GetMaxX-8, GetMaxY-8 );
  SETFILLSTYLE(4,4);
  bar( 125, 129, 145, 149 );

  setcolor(15);                    {do an ellipse}
  moveto(100,350);
  fillellipse(100,300,50,50);
  SetLineStyle(3,0,3);
  setcolor( 4 );                   {now do a circle}
  circle( 112, 98, 20 );


  FOR I := 0 TO 15 DO    {show bitmapped text formats available}
  BEGIN
    SetColor(i xor $f);    {set text background color}
    SetWriteMode(TextMode+SetBackColor);
    SetColor(i);           {set text foreground color}
    SetWriteMode(TextMode+MoveWrite);
    if i <= 9 then C := i+$30 else C := i+$37;
    outtextxy(Spix+(i*8),170,char(c));
  END;
  SetWriteMode(TextMode+ForeMoveWrite);
  setwritemode(0);

  SetLineStyle(0,0,1);
  setcolor(14);          {draw diagonal lines}
  moveto(0,0);
  line( 0, 0, GetMaxX, GetMaxY);
  setcolor(14);
  SetLineStyle(3,0,3);
  line( GetMaxX, 0, 0, GetMaxY);


  SetLineStyle(3,0,3);    {draw dashed lines around border}
  setcolor(1);
  rectangle(0,0,GetMaxX,GetMaxY);
  setcolor(2);
  rectangle(4,4,GetMaxX-4,GetMaxY-4);

  SetLineStyle(3,0,3);    {draw multiple patterned lines}
  for i := 0 to 7 do
  begin
    setcolor(1+i);
    line( GetMaxX-299-(i*3), 70+(i*3), GetMaxX-299+20+(i*7), 70+(i*3) );
  end;

  SETFILLSTYLE(SolidFill,black); {clear area around first pixel}
  bar(0,0,2,2);
  setlinestyle(0,0,1);
  setcolor(12);            {one pixel length line}
  moveto(0,0);
  line( 0, 0, 0, 0 );


  SetTextStyle(0,0,1);     {show some bitmapped text}
  setcolor( 5 );
  moveto( 100, GetMaxY-80);
  outtextXY(100,GetMaxY-80,'OutText 1');
  SetTextStyle(0,0,2);     {more text, but twice as big}
  setcolor( 6 );
  outtextxy( (GetMaxX div 2)-12, GetMaxY-30, 'OutText2' );

  if GetMaxY > 400 then
    Y := 199               {do some image stuff}
  else
    Y := GetMaxY div 4;
  X := Y;
  SetWriteMode(MiscCommand+SetGetImageReadOnly);
  setwritemode(0);
  Size := ImageSize(0,0,X,Y);
  GetMem(P,Size);
  GetImage(0,0,X,Y,P^);
  Xi := succ(GetMaxX) div 2;
  Yi := succ(GetMaxY) div 2;
  PutImage(Xi,Yi,P^,NormalPut);
  freemem(P,Size);
  P := nil;
  setcolor(white);
  SetLineStyle(0,0,1);     {draw a rectangle around the moved image}
  rectangle(pred(Xi),pred(Yi),succ(Xi+X),succ(Yi+Y));
  setcolor(succ(GetMaxColor div 4));
  CIRCLE(Xi,Yi,85);        {draw a big circle around the screen center}

  C := 10;                 {exersize getpixel/putpixel by drawing}
  PutPixel(0,0,C);         {at the four corners of the screen}
  C := GetPixel(0,0);
  PutPixel(0,0,C);
  C := 12;
  PutPixel(GetMaxX,0,C);
  C := GetPixel(GetMaxX,0);
  PutPixel(GetMaxX,0,C);
  C := 11;
  PutPixel(0,GetMaxY,C);
  C := GetPixel(0,GetMaxY);
  PutPixel(0,GetMaxY,C);
  C := 15;
  PutPixel(GetMaxX,GetMaxY,C);
  C := GetPixel(GetMaxX,GetMaxY);
  PutPixel(GetMaxX,GetMaxY,C);

  setwritemode(0);
  setLineStyle(UserBitLn,$ffff,1);  {draw three patterned lines}
  setcolor(yellow);                 {on the top of the screen}
  moveto(20,9);
  lineto(GetMaxX-20,9);
  setLineStyle(UserBitLn,$5555,1);
  setcolor(yellow);
  moveto(24,11);
  lineto(GetMaxX-24,11);
  setLineStyle(UserBitLn,$1111,1);
  setcolor(yellow);
  moveto(28,13);
  lineto(GetMaxX-28,13);

  SetLineStyle(0,0,1);
  setcolor(green);
  rectangle(0,0,10,10);     {check that things line up properly}
  putpixel(0,0,magenta);
  setcolor(yellow);
  rectangle(1,1,9,9);
  SETFILLSTYLE(SolidFill,4);
  bar(2,2,8,8);
  settextstyle(0,0,1);
  setcolor(blue);
  outtextxy(2,2,'H');


  Y := 100;
  K := $1151;            {do some user defined patterned lines}
  for j := 0 to 2 do     {with special bgi256 line pattern modes}
  begin
    X := 8;
    case j of
      0: SetWriteMode(MiscCommand+SetLineStyleMode0);
      1: SetWriteMode(MiscCommand+SetLineStyleMode1);
      2: SetWriteMode(MiscCommand+SetLineStyleMode2);
    end;
    setwritemode(0);
    LineStyle := j * 4;
    for i := 0 to 2 do
    begin
      inc(x,3);
      putpixel(x,y+1,lightgray);
      putpixel(X+32+3,Y+1,lightgray);
      putpixel(x+64+1,y+1,lightgray);

      setLineStyle(UserBitLn,K,1);
      PUTPIXEL(X-1,Y,CYAN);
      MOVETO(X+0,Y);
      SETCOLOR(LIGHTRED);
      LINETO(X+32+3,Y);
      SETCOLOR(LIGHTGREEN);
      LINETO(X+64+1,Y);
      PUTPIXEL(X+64+1+1,Y,CYAN);

      Y := Y+2;
      setLineStyle(UserBitLn,K,1);
      PUTPIXEL(X-1,Y,CYAN);
      SETCOLOR(LIGHTRED);
      LINE(X+0,y,X+32+3,Y);
      SETCOLOR(LIGHTGREEN);
      LINE(X+32+3+1,Y,X+64+1,Y);
      PUTPIXEL(X+64+1+1,Y,CYAN);

      setLineStyle(UserBitLn,K,1);
      Y := Y + 3;
    end;
  end;

  setLineStyle(0,0,1);
  settextstyle(0,0,1);
  setfillstyle(Solidfill,black);   {re-initialize the screen}
  setwritemode(0);                 {after the saucer stuff}

  if (BGIversion = 302) then
    AnimateStyle := 1
  else if (BGIVersion > 0) then
    AnimateStyle := 2
  else
    AnimateStyle := 0;
  DoSaucer;              {do flying saucer stuff - see ANISUB}


{-------------------------------------------------------------}
{ Screen two - test virtual screen capabilities (if available) }

  if VirtualBGI then
  begin
    while keypressed do
      ch := readkey;
    GraphDefaults;                 {re-initialize the screen}
    setfillstyle(Solidfill,black); {after the saucer stuff}

    L := 15*8;     {text box width}
    H := 15;       {text box height}
    VL := longint(VirtualWidth)*longint(VirtualHeight);
    K := trunc(sqrt(VL));
    X := ((K div L) * L ) + 8;
    Y := VL div X;
    if X < ScreenWidth then
      X := ScreenWidth;
    if Y < ScreenHeight then
      Y := ScreenHeight;
    SetVirtualWidth(X);
    SetDrawingSize(VirtualWidth,VirtualHeight);
    SetGraphMode(GetGraphMode);
    UpdateDisplayInfo;
    cleardevice;

    SETFILLSTYLE(1,4);
    setcolor(4);
    bar(0,0,GetMaxX,GetMaxY);

    setcolor(white);
    outtextxy(1,1, 'Virtual Pixels:'+fstr(VirtualWidth));
    outtextxy(1,10,'Virtual Lines :'+fstr(VirtualHeight));
    outtextxy(1,20,'Drawing Pixels:'+fstr(DrawingWidth));
    outtextxy(1,30,'Drawing Lines :'+fstr(DrawingHeight));
    outtextxy(1,40,'Screen  Pixels:'+fstr(ScreenWidth));
    outtextxy(1,50,'Screen  Lines :'+fstr(ScreenHeight));

    K := DrawingWidth div L;
    J := DrawingHeight div H;
    for x := 0 to pred(K) do
    begin
      for y := 0 to pred(J) do
      begin
        if ((y*H) > 50) or ((x*L) > 150) then
        begin
          setcolor(lightgray);
          s := 'X:'+fstr((x*L)+2)+' Y:'+fstr((y*H)+2);
          outtextxy((x*L)+8,(y*H)+4,s);
          setcolor(darkgray);
          rectangle(x*L+1,y*H+1,(x*L)+L-2,(y*H)+H-2);
          putpixel(x*L+2,y*H+2,white);
        end;
      end;
    end;
    setcolor(yellow);
    rectangle(0,0,GetMaxX,GetMaxY);

    if ((DrawingWidth <> ScreenWidth) or
        (DrawingHeight <> ScreenHeight)) then
    begin
      setcolor(white);
      xtemp := 1;
      ytemp := 0;
      settextstyle(0,0,1);
      setfillstyle(Solidfill,black);
      x1 := 8;
      y1 := ScreenHeight-H-15;
      x2 := x1+256;
      y2 := y1+10;
      Size := ImageSize(x1,y1,x2,y2);
      GetMem(P,Size);
      GetImage(x1,y1,x2,y2,P^);
      x := 0;
      y := 0;
      while not(KeyPressed) do
      begin
        if xtemp <> 0 then    {show vertical scrolling}
        begin
          inc(x,xtemp);
          if x <= 0 then
          begin
            ytemp := -1;
            xtemp := 0;
          end;
          if x >= GetmaxX-(ScreenWidth-1) then
          begin
            ytemp := 1;
            xtemp := 0;
          end;
        end;
        if ytemp <> 0 then
        begin
          inc(y,ytemp);
          if y <= 0 then
          begin
            xtemp := 1;
            ytemp := 0;
          end;
          if y >= GetMaxY-(ScreenHeight-1) then
          begin
            xtemp := -1;
            ytemp := 0;
          end;
        end;
        if x < 0 then x := 0;
        if y < 0 then y := 0;
        VertWait(1);  {wait for vertical sync (prevents flashing)}
        SetScreenOfs(x,y);

        PutImage(X1,Y1,P^,NormalPut);
        freemem(P,Size);
        P := nil;
        x1 := ScreenOfsX+8;
        y1 := ScreenOfsY+ScreenHeight-H-15;
        x2 := x1+256;
        y2 := y1+10;
        Size := ImageSize(x1,y1,x2,y2);
        GetMem(P,Size);
        GetImage(x1,y1,x2,y2,P^);
        bar(x1+1,y1+1,x2,y2);
        outtextxy(x1+1,y1+2,' Sx:'+fstr(ScreenOfsX)+
                            ' Sy:'+fstr(ScreenOfsY)+
                            ' Mx:'+fstr(ScreenOfsX+ScreenWidth-1)+
                            ' My:'+fstr(ScreenOfsY+ScreenHeight-1) );
        if (x = 0) and (y = 0) then
          delay(2000);
      end;
      PutImage(X1,Y1,P^,NormalPut);
      freemem(P,Size);
      P := nil;
    end;
  end;
  while KeyPressed do
    ch := readkey;


{-------------------------------------------------------------}
{ Screen three - test text capabilities}

  if VirtualBGI then
  begin
    SetVirtualWidth(ScreenWidth);
    SetDrawingSize(ScreenWidth,ScreenHeight);
    SetGraphMode(GetGraphMode);   {restore stuff after virtual}
    UpdateDisplayinfo;
    if DisplayImagePages > 1 then
    begin
      SetActivePage(1);
      SetVisualPage(1);
      setfillstyle(Solidfill,blue);
      bar(0,0,GetMaxX,GetMaxY);     {clear screen to blue background}
      SetColor(Green);
      rectangle(0,0,GetMaxX,GetMaxY);
      outtextxy(10,20,'Active Page 1');
      SetActivePage(0);
    end;
  end;

  x := GetMaxX;
  y := GetMaxY;
  setfillstyle(Solidfill,blue);
  bar(0,0,GetMaxX,GetMaxY);     {clear screen to blue background}

  x := ScreenWidth-1;
  y := ScreenHeight-1;
  setcolor(lightgray);
  rectangle(0,0,x,y);
  setcolor(red);
  rectangle(1,1,x-1,y-1);
  outtextxy(10,20,'Active Page 0');

  setcolor(cyan);
  outtextxy(2,100,'OutText 3 '+#192+#193+#194+#191+' '+fstr(GetMaxX)); {line draw chars}
  setcolor(white);
  outtextxy(2,2,'Hello');
  setcolor(green);
  settextstyle(triplexfont,0,1);
  outtextxy(2,50,'Hello');
  setcolor(yellow);
  settextstyle(triplexfont,0,7);
  outtextxy(2,125,'Hello');

  while KeyPressed do ch := readkey;
  CH := #255;
  T := 0;
  s := fstr(T);
  while ch = #255 do
  begin
    if DisplayImagePages > 1 then
    begin
      VertWait(1);  {wait for vertical sync (prevents flashing)}
      SetVisualPage((T and 1));
      SetActivePage(1);
      setfillstyle(solidfill,blue);
      bar(10,120,10+textwidth(s)+20,130);
      setcolor(t and $ff);
      settextstyle(0,0,1);
      s := fstr(T div 2);
      outtextxy(11,121,s);
      delay(500);
      inc(T);
    end;
    if Keypressed then
    begin
      CH := READKEY;
      IF CH = #0 THEN CH := char(ord(READKEY)+$80);
    end;
  end;
  if upcase(ch) = 'P' then PRINTSCREEN(0,Red,true);

  closegraph;
  WRITELN('Finished');
END.

