home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 21 / CD_ASCQ_21_040595.iso / dos / prg / pas / tvgr70 / vesademo.pas < prev   
Pascal/Delphi Source File  |  1994-09-23  |  14KB  |  461 lines

  1. {***************************************}
  2. {                                       }
  3. {   TVGraphic Library VESADEMO.PAS      }
  4. {        RICHARD P. ANDRESEN            }
  5. {                                       }
  6. {***************************************}
  7.  
  8. {This demo program illustrates the use of
  9.  
  10.  Borland's VESA video driver (VESA16.BGI)
  11.  
  12.  with the TVGraphic library.
  13.  
  14.  It is part of the documentation of TVGraphic.
  15.  
  16.  (******************************************)
  17.  NOTE - source code versions of TVGraphic may be
  18.     modified to use third party graphic libraries
  19.     for direct support (non-VESA) of super VGA cards.
  20.                   Inquire.
  21.  (******************************************)
  22.  
  23.  Run the Borland supplied program VESATEST.EXE to
  24.  determine if your video card supports VESA.
  25.  If VESATEST cannot locate a VESA Bios, note that
  26.  many video cards require you to run their utility
  27.  program to enable or load the VESA Bios on the card.
  28.  
  29.  According to one supplier of graphic libraries,
  30.  the VESA utility/TSR programs shipped with a number
  31.  of video cards were buggy. You may need to obtain
  32.  the latest version software from the card manufacturer.
  33.  
  34.  !! The VESA16.BGI driver must be in the directory !!
  35.       named in DriverDirectory.
  36.  
  37.     DriverDirectory = '\bp\bgi\';
  38.     Change DriverDirectory to match your computer.
  39.  
  40.  
  41. NOTE: When using the VESA16 driver within the IDE, breakpoints
  42.       after InitGraph will scramble the graphic screen.
  43.  
  44. See TVGDemo1 for a full featured demo program.
  45.  
  46. Note: You should replace the default DOS critical error handling
  47. routine (which always returns "Abort") for any program you will use
  48. alot or distribute.  See TVGDemo1.
  49.  
  50. }
  51.  
  52. program VESADEMO;
  53.  
  54. {$F+,X+,V-}    {+X - use Extended syntax so can call a function as if
  55.                   it were a procedure.}
  56.  
  57. uses DOS, Memory, MyGraph, GObjects, GDrivers,
  58.      MCursor, GMenus,
  59.      GViews,  GDialogs, GMsgBox, GStdDlg,
  60.      GApp, GWindow, GHistLst,
  61.      BMPdrvr;
  62.  
  63. const
  64.   ProgName = 'VESAdemo';
  65.   Ver      = '2.00';
  66.  
  67.   DriverDirectory = '\bp\bgi\'; {directory containing VESA16.BGI}
  68.       {change to match your computer.}
  69.  
  70. const
  71.   WinNum : integer = 0;
  72.   cmCircleWindow     = 1102;
  73.   cmVersion          = 1116;
  74.  
  75. var
  76.   OldExitProc : Pointer;  { Saves exit procedure address }
  77.   Graphic  : boolean;     { true if screen is in graphic mode }
  78.  
  79.  
  80. procedure GExitProc; far;     {must be Far}
  81.   {Exit procedure - restore screen to text mode if program halts}
  82. begin
  83.   ExitProc := OldExitProc; { Restore exit procedure address }
  84.   CloseGraph;              { Shut down the graphics system }
  85. end;
  86.  
  87.  
  88. {-------------------------------}
  89. type
  90.  
  91.   {demonstrates very simple Draw method and using TimerTick events}
  92.  
  93.   PCircles = ^TCircles;
  94.   TCircles = object(TWinBackground)
  95.     Count : integer;
  96.     Speed : integer;
  97.     constructor Init(var Bounds: TRect);
  98.     procedure Draw; virtual;
  99.     procedure DrawCircle;
  100.     procedure HandleEvent(var Event : TEvent); virtual;
  101.   end;
  102.  
  103.   constructor TCircles.Init(var Bounds: TRect);
  104.   begin
  105.     TWinBackground.Init(Bounds);
  106.     EventMask := evTimerTick;
  107.     VColor := black;               {store drawing color}
  108.   end;
  109.  
  110.   procedure TCircles.Draw;
  111.   var   Glob : TRect;
  112.   begin
  113.     MCur.Hide;              {hide cursor}
  114.     GetVPRelCoords(Glob);   {get view's outline in viewport relative coords}
  115.  
  116.     SetFillStyle(solidfill,VColor);            {set background color}
  117.     Bar(Glob.A.x,Glob.A.y,Glob.B.x,Glob.B.y);  {draw background}
  118.  
  119.     DrawCircle;
  120.  
  121.     MCur.Show;
  122.   end;
  123.  
  124.   procedure TCircles.DrawCircle;
  125.   var
  126.     Radius : word;
  127.     Glob : TRect;
  128.     Color : integer;
  129.   begin
  130.     MCur.Hide;              {hide cursor}
  131.     GetVPRelCoords(Glob);   {get view's outline in viewport relative coords}
  132.  
  133.     if (Count = 0) or (Count =8) then Color := 14
  134.       else Color := Count;
  135.     SetColor(Color);               {set circle Color based on Count}
  136.  
  137.                                    {compute radius based on view's size}
  138.     if Size.x < Size.y then Radius := Size.x
  139.     else Radius := Size.y;
  140.     Radius := Radius div 3;
  141.                                    {draw circle}
  142.     Circle(Glob.A.x+Size.x div 2, Glob.A.y+Size.y div 2, Radius);
  143.     MCur.Show;               {show the mouse cursor}
  144.   end;
  145.  
  146.   procedure TCircles.HandleEvent(var Event : TEvent);
  147.   begin
  148.     if Event.What = evTimerTick then begin
  149.          { if you want to avoid overwriting menus and modal dialog boxes,
  150.            must exit if the Application (Desktop's Owner) is not the
  151.            modal view.}
  152.       if TopView <> PView(DeskTop^.Owner) then Exit;
  153.  
  154.       Inc(Speed);
  155.       if Speed > 1023 then Speed := 0;
  156.       if (Speed mod 8 = 0) then begin
  157.         Inc(Count);
  158.         if Count > 15 then Count := 0;   {limit to highest color}
  159.         if GetState(sfActive) then DrawCircle;
  160.       end;
  161.     end;
  162.   end;
  163.  
  164. {--------------------------------}
  165. type
  166.   TDemoApp = object(TProgram)
  167.     constructor Init;
  168.     destructor Done; virtual;
  169.     procedure HandleEvent(var Event: TEvent); virtual;
  170.     procedure InsertCircleWin;
  171.     procedure InitMenuBar; virtual;
  172.     procedure InitStatusLine; virtual;
  173.     procedure IntroScreen;
  174.     procedure LoadBMP;
  175.     procedure NewWindow;
  176.   end;
  177.  
  178.  
  179. constructor TDemoApp.Init;
  180. var
  181.   GraphDriver,GraphMode,ErrorCode : integer;
  182. begin
  183.   Graphic := false;    {do first}
  184.  
  185.   InitMemory;
  186.   InitVideo;
  187.   InitEvents;
  188.   InitSysError;
  189.   InitHistory;
  190.  
  191.      {register screen driver}
  192.   RegisterBGIdriver(@EGAVGADriverProc);
  193.  
  194.   {NOTE: DetectGraph cannot find user drivers such as VESA16.BGI !!
  195.          Use function DetectVESA16 to see if card is VESA compatible.}
  196.  
  197.   if DetectVESA16 >= 0 then begin  {VESA video BIOS detected}
  198.      {note that your video card may require you to run the manufacturer's
  199.       VMODE or VESA utility program to enable the VESA BIOS on the card.
  200.       If not enabled, card will not be detected as VESA compatible.}
  201.          {register Borland VESA driver}
  202.     GraphDriver := InstallUserDriver('VESA16', @DetectVESA16);
  203.     GraphMode := 0;  {TVGraphic only supports mode 0 = 800x600}
  204.   end
  205.   else begin
  206.     GraphDriver := Detect;                { use autodetection }
  207.      {verify graphics mode - DetectGraph cannot find User drivers}
  208.     DetectGraph(GraphDriver, GraphMode);
  209.     if not ((GraphDriver = VGA) or (GraphDriver = EGA)) then begin
  210.       Done;
  211.       Writeln('Error - system does not support EGA or VGA graphics.');
  212.       Halt(1);
  213.     end;
  214.   end;
  215.  
  216.     {enter graphics mode}
  217.   if GraphDriver = VGA then GraphMode := VGAHi
  218.     else if GraphDriver = EGA then GraphMode := EGAHi;
  219.  
  220.   InitGraph(GraphDriver,GraphMode, DriverDirectory);
  221.      {DriverDirectory is needed only for VESA16 driver.
  222.       It must point to the directory on your computer
  223.       containing VESA16.BGI}
  224.  
  225.    {NOTE: When using the VESA driver within the IDE, breakpoints
  226.           after InitGraph will scramble the graphic screen.}
  227.  
  228.  
  229. (* {Note that the following autodetection code works but doesn't allow
  230.   checking of the graphic mode prior to entering graphics with InitGraph.
  231.   You would have a problem if the user tried to run on a card that
  232.   didn't support EGA or VGA. The user would get a "driver not found"
  233.   error unless the driver happened to be present - then user would
  234.   get garbage.}
  235.  
  236.   GraphDriver := InstallUserDriver('VESA16', @DetectVESA16);
  237.   GraphDriver := Detect;                { use autodetection }
  238.   {    DetectGraph will not find user installed drivers.
  239.        DetectGraph(GraphDriver, GraphMode);}
  240.   InitGraph(GraphDriver,GraphMode, DriverDirectory);
  241. *)
  242.  
  243.   ErrorCode := GraphResult;
  244.   if ErrorCode <> grOK then begin
  245.     Done;
  246.     Writeln('Graphics Error: ',GraphErrorMsg(ErrorCode));
  247.     Halt(1);
  248.   end
  249.   else begin
  250.           {install exit proc to Close graphics}
  251.     OldExitProc := ExitProc;                { save previous exit proc }
  252.     ExitProc := @GExitProc;                { insert our exit proc in chain }
  253.     Graphic := true;
  254.           {install graphic mode DOS critical error handler}
  255. (*    SysErrorFunc := GSystemError; *)
  256.           {improves look of dark gray and brown on VGA monitors,
  257.            no effect in EGA}
  258.     ImprovePaletteColors;
  259.   end;
  260.  
  261.  
  262.   TProgram.Init;     {MCur mouse initialized in TProgram.Init}
  263.  
  264.   IntroScreen;
  265. end;
  266.  
  267. destructor TDemoApp.Done;
  268. begin
  269.   if Graphic then begin
  270.     TProgram.Done;       {calls MCur.Done}
  271.     CloseGraph;
  272.     Graphic := false;
  273.   end;
  274.  
  275.   DoneHistory;
  276.   DoneSysError;
  277.   DoneEvents;
  278.   DoneVideo;
  279.   DoneMemory;
  280. end;
  281.  
  282. procedure TDemoApp.HandleEvent(var Event: TEvent);
  283.   procedure ShowVersion;
  284.   var Cmd : integer;
  285.   begin
  286.     Cmd := MessageBox(^C'TVGraphic '+ProgName+' ver '+Ver,
  287.       nil, mfInformation+mfOKButton);
  288.   end;
  289.  
  290. var
  291.   PDir,FInputBox : PView;
  292.   Cmd : integer;
  293. begin
  294.   TProgram.HandleEvent(Event);    {usual call to ancestor method}
  295.  
  296.   if Event.What = evCommand then
  297.   begin
  298.     case Event.Command of
  299.       cmNew: NewWindow;
  300.       cmOpen : LoadBMP;
  301.       cmChangeDir:
  302.         begin
  303.           PDir := New(PChDirDialog, Init(cdNormal {+ cdHelpButton},0));
  304.           Cmd := DeskTop^.ExecView(PDir);
  305.           Dispose(PDir, Done);
  306.         end;
  307.       cmCircleWindow : InsertCircleWin;
  308.       cmVersion      : ShowVersion;
  309.     end;
  310.   end;
  311. end;
  312.  
  313. procedure TDemoApp.InsertCircleWin;
  314. var
  315.   P : PView;
  316.   W : PWindow;
  317.   R : TRect;
  318. begin
  319.   R.Assign((WinNum+20)*Grid, (WinNum+20)*Grid,
  320.            (WinNum+40)*Grid, (WinNum+40)*Grid);
  321.   Inc(WinNum);  {so next window will be shoved over}
  322.  
  323.   W := New(PWindow, Init(R,'CIRCLES',wnNoNumber));
  324.  
  325.   W^.GetMaxSubViewSize(R, false);
  326.   P := New(PCircles, Init(R));
  327.   W^.Insert(P);
  328.   DeskTop^.Insert(W);
  329. end;
  330.  
  331. procedure TDemoApp.InitMenuBar;
  332. var
  333.   R: TRect;
  334. begin
  335.   GetExtent(R);
  336.   MenuBar := New(PMenuBar, Init(R, NewMenu(
  337.     NewSubMenu('~F~ile', hcNoContext, NewMenu(
  338.       NewItem('~N~ew', '', kbNoKey, cmNew, hcNew,
  339.       NewItem('~O~pen...', 'F3', kbF3, cmOpen, hcOpen,
  340.       NewLine(
  341.       NewItem('~C~hange dir...', '', kbNoKey, cmChangeDir, hcChangeDir,
  342.       NewItem('E~x~it', 'Alt+X', kbAltX, cmQuit, hcExit,
  343.       nil)))))),
  344.     NewSubMenu('~W~indows', hcNoContext, NewMenu(
  345.       NewItem('Circle~W~indow', '', kbNoKey, cmCircleWindow , hcNoContext,
  346.       NewLine(
  347.       NewItem('~S~ize/Move','Ctrl+F5', kbCtrlF5, cmResize, hcResize,
  348.       NewItem('~Z~oom', 'F5', kbF5, cmZoom, hcZoom,
  349.       NewItem('~N~ext', 'F6', kbF6, cmNext, hcNext,
  350.       NewItem('~P~revious', 'Shift+F6', kbShiftF6, cmPrev, hcPrev,
  351.       NewItem('~C~lose', 'Alt+F3', kbAltF3, cmClose, hcClose,
  352.       nil)))))))),
  353.     NewSubMenu('~I~nfo', hcNoContext, NewMenu(
  354.       NewItem('~V~ersion #', '', kbNoKey, cmVersion, hcNoContext,
  355.       nil)),
  356.     nil)))
  357.   )));
  358. end;
  359.  
  360. procedure TDemoApp.InitStatusLine;
  361. var
  362.   R: TRect;
  363. begin
  364.   GetExtent(R);
  365.   R.A.Y := R.B.Y - Boxheight+2;
  366.   StatusLine :=   New(PStatusLine, Init(R,
  367.     NewStatusDef(0, $FFFF,
  368.       NewStatusKey('~F6~ Next', kbF6, cmNext,
  369.       NewStatusKey('~Shift+F6~ Prev', kbShiftF6, cmPrev,
  370.       NewStatusKey('~Alt-X~ Exit', kbAltX, cmQuit,
  371.       (nil)))),
  372.        nil)));
  373.   StatusLine^.VFont := font8x8;  {select smaller font}
  374. end;
  375.  
  376. procedure TDemoApp.IntroScreen;
  377. begin
  378.   MessageBox(^C'If your VESA video card is not in 800x600 display, you may'+
  379.      ' need to run the card''s utility program.', nil, mfInformation + mfOKButton);
  380. end;
  381.  
  382. procedure TDemoApp.LoadBMP;
  383. var
  384.   R : TRect;
  385.   BitPtr : PBitMap;
  386.   Cmd : integer;
  387.   FInputBox : PFileDialog;
  388.   FName : PathStr;
  389.   InFile : file;
  390.   Result : word;
  391.   Buf : array[0..Sizeof(TBitMapInfoHeader)-1] of byte;
  392.   TotalBytes : LONGint; {!!!}
  393.   ErrStr : string;
  394. begin
  395.   BitPtr := nil;
  396.   Inc(WinNum);
  397.   R.A.x := 100; R.A.y := 100;
  398.   FInputBox := New(PFileDialog, Init('*.BMP', 'LOAD AND DRAW A BITMAP', '~N~ame', fdOpenButton,0));
  399.   Cmd := DeskTop^.ExecView(FInputBox);
  400.  
  401.   if (Cmd = cmFileOpen) or (Cmd = cmOK) then FInputBox^.GetFileName(FName)
  402.       else FName := '';
  403.   Dispose(FInputBox, Done);
  404.   if FName <> '' then begin
  405.     {$I-}
  406.     Assign(InFile, FName);
  407.     Reset(InFile,1);   {reads 1 byte blocks}
  408.     if IOResult <> 0 then begin
  409.       Close(InFile);
  410.       MessageBox('Can''t find file '+ FName, nil, mfError+mfOKButton);
  411.       Exit;
  412.     end;
  413.     {$I+}
  414.  
  415.       {read just the InfoHeader}
  416.     BlockRead(InFile, Buf, Sizeof(TBitMapInfoHeader), Result);
  417.  
  418.         {remember - the Infoheader is in Buf, not yet in BitPtr^.}
  419.     ErrStr := BMPFormatOKStr(PBitMap(@Buf), FName);
  420.     If ErrStr = '' then begin
  421.       BitPtr := AllocateBMPmem(PBitMap(@Buf)); {allocate mem,use special call}
  422.       if BitPtr <> nil then begin
  423.         TotalBytes := GetBitImageSize(PBitMap(@Buf));
  424.  
  425.         Reset(InFile,1);   {start again at beginning of file, read all}
  426.         BlockRead(InFile, BitPtr^, TotalBytes, Result);
  427.  
  428.         WinToTVColor(BitPtr);
  429.         MCur.Hide;
  430.         PutBitMap(100,100, BitPtr, 0, NormalPut);
  431.         MCur.Show;
  432.       end;
  433.     end
  434.     else
  435.       Cmd := MessageBox(ErrStr, nil, mfError+mfOKButton);
  436.  
  437.     Close(InFile);
  438.  
  439.   {! WARNING ! - following line disposes of memory used by this bitmap -
  440.     fine here since just want to draw bitmap once on screen but disaster
  441.     if you assign BitPtr to a View or Button in your own code!}
  442.  
  443.     if BitPtr <> nil then FreeMem(BitPtr, TotalBytes); {do here for demo}
  444.   end;
  445. end;
  446.  
  447. procedure TDemoApp.NewWindow;
  448. begin
  449.   MessageBox(^C'Use the Windows Menu to open Windows',nil,
  450.                        mfInformation+mfOKButton);
  451. end;
  452.  
  453.  
  454. var
  455.   DemoApp: TDemoApp;
  456. begin
  457.   DemoApp.Init;
  458.   DemoApp.Run;
  459.   DemoApp.Done;
  460. end.
  461.