BGIDEMO.C
上传用户:sunrenlu
上传日期:2022-06-13
资源大小:1419k
文件大小:39k
源码类别:

操作系统开发

开发平台:

DOS

  1. /*
  2.    GRAPHICS DEMO FOR Borland C++ 
  3.    Copyright (c) 1987,88,91 Borland International. All rights reserved.
  4.    From the command line, use:
  5. bcc bgidemo graphics.lib
  6. */
  7. #ifdef __TINY__
  8. #error BGIDEMO will not run in the tiny model.
  9. #endif
  10. #include <dos.h>
  11. #include <math.h>
  12. #include <conio.h>
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. #include <stdarg.h>
  16. #include <graphics.h>
  17. #define ESC 0x1b /* Define the escape key */
  18. #define TRUE 1 /* Define some handy constants */
  19. #define FALSE 0 /* Define some handy constants */
  20. #define PI 3.14159  /* Define a value for PI */
  21. #define ON 1 /* Define some handy constants */
  22. #define OFF 0 /* Define some handy constants */
  23. #define NFONTS 11
  24. char *Fonts[NFONTS] = {
  25.   "DefaultFont",   "TriplexFont",   "SmallFont",
  26.   "SansSerifFont", "GothicFont", "ScriptFont", "SimplexFont", "TriplexScriptFont",
  27.   "ComplexFont", "EuropeanFont", "BoldFont"
  28. };
  29. char *LineStyles[] = {
  30.   "SolidLn",  "DottedLn",  "CenterLn",  "DashedLn",  "UserBitLn"
  31. };
  32. char *FillStyles[] = {
  33.   "EmptyFill",  "SolidFill",      "LineFill",      "LtSlashFill",
  34.   "SlashFill",  "BkSlashFill",    "LtBkSlashFill", "HatchFill",
  35.   "XHatchFill", "InterleaveFill", "WideDotFill",   "CloseDotFill"
  36. };
  37. char *TextDirect[] = {
  38.   "HorizDir",  "VertDir"
  39. };
  40. char *HorizJust[] = {
  41.   "LeftText",   "CenterText",   "RightText"
  42. };
  43. char *VertJust[] = {
  44.   "BottomText",  "CenterText",  "TopText"
  45. };
  46. struct PTS {
  47.   int x, y;
  48. }; /* Structure to hold vertex points */
  49. int    GraphDriver; /* The Graphics device driver */
  50. int    GraphMode; /* The Graphics mode value */
  51. double AspectRatio; /* Aspect ratio of a pixel on the screen*/
  52. int    MaxX, MaxY; /* The maximum resolution of the screen */
  53. int    MaxColors; /* The maximum # of colors available */
  54. int    ErrorCode; /* Reports any graphics errors */
  55. struct palettetype palette; /* Used to read palette info */
  56. /* */
  57. /* Function prototypes */
  58. /* */
  59. void Initialize(void);
  60. void ReportStatus(void);
  61. void TextDump(void);
  62. void Bar3DDemo(void);
  63. void RandomBars(void);
  64. void TextDemo(void);
  65. void ColorDemo(void);
  66. void ArcDemo(void);
  67. void CircleDemo(void);
  68. void PieDemo(void);
  69. void BarDemo(void);
  70. void LineRelDemo(void);
  71. void PutPixelDemo(void);
  72. void PutImageDemo(void);
  73. void LineToDemo(void);
  74. void LineStyleDemo(void);
  75. void CRTModeDemo(void);
  76. void UserLineStyleDemo(void);
  77. void FillStyleDemo(void);
  78. void FillPatternDemo(void);
  79. void PaletteDemo(void);
  80. void PolyDemo(void);
  81. void SayGoodbye(void);
  82. void Pause(void);
  83. void MainWindow(char *header);
  84. void StatusLine(char *msg);
  85. void DrawBorder(void);
  86. void changetextstyle(int font, int direction, int charsize);
  87. int  gprintf(int *xloc, int *yloc, char *fmt, ... );
  88. /* */
  89. /* Begin main function */
  90. /* */
  91. int main()
  92. {
  93.   rt_init();
  94.   Initialize();  /* Set system into Graphics mode */
  95.   ReportStatus(); /* Report results of the initialization */
  96.   ColorDemo(); /* Begin actual demonstration */
  97.   if( GraphDriver==EGA || GraphDriver==EGALO || GraphDriver==VGA )
  98.     PaletteDemo();
  99.   PutPixelDemo();
  100.   PutImageDemo();
  101.   Bar3DDemo();
  102.   BarDemo();
  103.   RandomBars();
  104.   ArcDemo();
  105.   CircleDemo();
  106.   PieDemo();
  107.   LineRelDemo();
  108.   LineToDemo();
  109.   LineStyleDemo();
  110.   UserLineStyleDemo();
  111.   TextDump();
  112.   TextDemo();
  113.   CRTModeDemo();
  114.   FillStyleDemo();
  115.   FillPatternDemo();
  116.   PolyDemo();
  117.   SayGoodbye();  /* Give user the closing screen  */
  118.   closegraph();  /* Return the system to text mode */
  119.   return(0);
  120. }
  121. /* */
  122. /* INITIALIZE: Initializes the graphics system and reports  */
  123. /* any errors which occured. */
  124. /* */
  125. void Initialize(void)
  126. {
  127.   int xasp, yasp; /* Used to read the aspect ratio*/
  128.   GraphDriver = DETECT;  /* Request auto-detection */
  129.   initgraph( &GraphDriver, &GraphMode, "" );
  130.   ErrorCode = graphresult(); /* Read result of initialization*/
  131.   if( ErrorCode != grOk ){ /* Error occured during init */
  132.     printf(" Graphics System Error: %sn", grapherrormsg( ErrorCode ) );
  133.     exit( 1 );
  134.   }
  135.   getpalette( &palette ); /* Read the palette from board */
  136.   MaxColors = getmaxcolor() + 1; /* Read maximum number of colors*/
  137.   MaxX = getmaxx();
  138.   MaxY = getmaxy(); /* Read size of screen */
  139.   getaspectratio( &xasp, &yasp ); /* read the hardware aspect */
  140.   AspectRatio = (double)xasp / (double)yasp; /* Get correction factor */
  141. }
  142. /* */
  143. /* REPORTSTATUS: Report the current configuration of the system */
  144. /* after the auto-detect initialization. */
  145. /* */
  146. void ReportStatus(void)
  147. {
  148.   struct viewporttype   viewinfo; /* Params for inquiry procedures*/
  149.   struct linesettingstype lineinfo;
  150.   struct fillsettingstype fillinfo;
  151.   struct textsettingstype textinfo;
  152.   struct palettetype   palette;
  153.   char *driver, *mode; /* Strings for driver and mode */
  154.   int x, y;
  155.   getviewsettings( &viewinfo );
  156.   getlinesettings( &lineinfo );
  157.   getfillsettings( &fillinfo );
  158.   gettextsettings( &textinfo );
  159.   getpalette( &palette );
  160.   x = 10;
  161.   y = 4;
  162.   MainWindow( "Status report after InitGraph" );
  163.   settextjustify( LEFT_TEXT, TOP_TEXT );
  164.   driver = getdrivername();
  165.   mode = getmodename(GraphMode); /* get current setting */
  166.   gprintf( &x, &y, "Graphics device    : %-20s (%d)", driver, GraphDriver );
  167.   gprintf( &x, &y, "Graphics mode      : %-20s (%d)", mode, GraphMode );
  168.   gprintf( &x, &y, "Screen resolution  : ( 0, 0, %d, %d )", getmaxx(), getmaxy() );
  169.   gprintf( &x, &y, "Current view port  : ( %d, %d, %d, %d )",
  170.   viewinfo.left, viewinfo.top, viewinfo.right, viewinfo.bottom );
  171.   gprintf( &x, &y, "Clipping           : %s", viewinfo.clip ? "ON" : "OFF" );
  172.   gprintf( &x, &y, "Current position   : ( %d, %d )", getx(), gety() );
  173.   gprintf( &x, &y, "Colors available   : %d", MaxColors );
  174.   gprintf( &x, &y, "Current color      : %d", getcolor() );
  175.   gprintf( &x, &y, "Line style         : %s", LineStyles[ lineinfo.linestyle ] );
  176.   gprintf( &x, &y, "Line thickness     : %d", lineinfo.thickness );
  177.   gprintf( &x, &y, "Current fill style : %s", FillStyles[ fillinfo.pattern ] );
  178.   gprintf( &x, &y, "Current fill color : %d", fillinfo.color );
  179.   gprintf( &x, &y, "Current font       : %s", Fonts[ textinfo.font ] );
  180.   gprintf( &x, &y, "Text direction     : %s", TextDirect[ textinfo.direction ] );
  181.   gprintf( &x, &y, "Character size     : %d", textinfo.charsize );
  182.   gprintf( &x, &y, "Horizontal justify : %s", HorizJust[ textinfo.horiz ] );
  183.   gprintf( &x, &y, "Vertical justify   : %s", VertJust[ textinfo.vert ] );
  184.   Pause(); /* Pause for user to read screen*/
  185. }
  186. /* */
  187. /* TEXTDUMP: Display the all the characters in each of the  */
  188. /* available fonts. */
  189. /* */
  190. void TextDump()
  191. {
  192.   static int CGASizes[]  = {
  193.     1, 3, 7, 3, 3, 2, 2, 2, 2, 2, 2  };
  194.   static int NormSizes[] = {
  195.     1, 4, 7, 4, 4, 2, 2, 2, 2, 2, 2  };
  196.   char buffer[80];
  197.   int font, ch, wwidth, lwidth, size;
  198.   struct viewporttype vp;
  199.   for( font=0 ; font<NFONTS ; ++font ){ /* For each available font */
  200.     sprintf( buffer, "%s Character Set", Fonts[font] );
  201.     MainWindow( buffer ); /* Display fontname as banner */
  202.     getviewsettings( &vp ); /* read current viewport */
  203.     settextjustify( LEFT_TEXT, TOP_TEXT );
  204.     moveto( 2, 3 );
  205.     buffer[1] = '';                   /* Terminate string             */
  206.     wwidth = vp.right - vp.left; /* Determine the window width */
  207.     lwidth = textwidth( "H" );          /* Get average letter width     */
  208.     if( font == DEFAULT_FONT ){
  209.       changetextstyle( font, HORIZ_DIR, 1 );
  210.       ch = 0;
  211.       while( ch < 256 ){ /* For each possible character */
  212. buffer[0] = ch;  /* Put character into a string */
  213. outtext( buffer ); /* send string to screen */
  214. if( (getx() + lwidth) > wwidth )
  215.   moveto( 2, gety() + textheight("H") + 3 );
  216. ++ch; /* Goto the next character */
  217.       }
  218.     }
  219.     else{
  220.       size = (MaxY < 200) ? CGASizes[font] : NormSizes[font];
  221.       changetextstyle( font, HORIZ_DIR, size );
  222.       ch = '!';                         /* Begin at 1st printable       */
  223.       while( ch < 256 ){ /* For each printable character */
  224. buffer[0] = ch;  /* Put character into a string */
  225. outtext( buffer ); /* send string to screen */
  226. if( (lwidth+getx()) > wwidth ) /* Are we still in window? */
  227.   moveto( 2, gety()+textheight("H")+3 );
  228. ++ch; /* Goto the next character */
  229.       }
  230.     }
  231.     Pause(); /* Pause until user acks */
  232.   } /* End of FONT loop */
  233. }
  234. /* */
  235. /* BAR3DDEMO: Display a 3-D bar chart on the screen. */
  236. /* */
  237. void Bar3DDemo(void)
  238. {
  239.   static int barheight[] = {
  240.     1, 3, 5, 4, 3, 2, 1, 5, 4, 2, 3   };
  241.   struct viewporttype vp;
  242.   int xstep, ystep;
  243.   int i, j, h, color, bheight;
  244.   char buffer[10];
  245.   MainWindow( "Bar 3-D / Rectangle Demonstration" );
  246.   h = 3 * textheight( "H" );
  247.   getviewsettings( &vp );
  248.   settextjustify( CENTER_TEXT, TOP_TEXT );
  249.   changetextstyle( TRIPLEX_FONT, HORIZ_DIR, 4 );
  250.   outtextxy( MaxX/2, 6, "These are 3-D Bars" );
  251.   changetextstyle( DEFAULT_FONT, HORIZ_DIR, 1 );
  252.   setviewport( vp.left+50, vp.top+40, vp.right-50, vp.bottom-10, 1 );
  253.   getviewsettings( &vp );
  254.   line( h, h, h, vp.bottom-vp.top-h );
  255.   line( h, (vp.bottom-vp.top)-h, (vp.right-vp.left)-h, (vp.bottom-vp.top)-h );
  256.   xstep = ((vp.right-vp.left) - (2*h)) / 10;
  257.   ystep = ((vp.bottom-vp.top) - (2*h)) / 5;
  258.   j = (vp.bottom-vp.top) - h;
  259.   settextjustify( CENTER_TEXT, CENTER_TEXT );
  260.   for( i=0 ; i<6 ; ++i ){
  261.     line( h/2, j, h, j );
  262.     itoa( i, buffer, 10 );
  263.     outtextxy( 0, j, buffer );
  264.     j -= ystep;
  265.   }
  266.   j = h;
  267.   settextjustify( CENTER_TEXT, TOP_TEXT );
  268.   for( i=0 ; i<11 ; ++i ){
  269.     color = random( MaxColors );
  270.     setfillstyle( i+1, color );
  271.     line( j, (vp.bottom-vp.top)-h, j, (vp.bottom-vp.top-3)-(h/2) );
  272.     itoa( i, buffer, 10 );
  273.     outtextxy( j, (vp.bottom-vp.top)-(h/2), buffer );
  274.     if( i != 10 ){
  275.       bheight = (vp.bottom-vp.top) - h - 1;
  276.       bar3d( j, (vp.bottom-vp.top-h)-(barheight[i]*ystep), j+xstep, bheight, 15, 1 );
  277.     }
  278.     j += xstep;
  279.   }
  280.   Pause(); /* Pause for user's response    */
  281. }
  282. /* */
  283. /* RANDOMBARS: Display random bars  */
  284. /* */
  285. void RandomBars(void)
  286. {
  287.   int color;
  288.   MainWindow( "Random Bars" );
  289.   StatusLine( "Esc aborts or press a key..." ); /* Put msg at bottom of screen   */
  290.   while( !kbhit() ){ /* Until user enters a key... */
  291.     color = random( MaxColors-1 )+1;
  292.     setcolor( color );
  293.     setfillstyle( random(11)+1, color );
  294.     bar3d( random( getmaxx() ), random( getmaxy() ),
  295.    random( getmaxx() ), random( getmaxy() ), 0, OFF);
  296.   }
  297.   Pause(); /* Pause for user's response    */
  298. }
  299. /* */
  300. /* TEXTDEMO: Show each font in several sizes to the user. */
  301. /* */
  302. void TextDemo(void)
  303. {
  304.   int charsize[] = {
  305.     1, 3, 7, 3, 4, 2, 2, 2, 2, 2, 2   };
  306.   int font, size;
  307.   int h, x, y, i;
  308.   struct viewporttype vp;
  309.   char buffer[80];
  310.   for( font=0 ; font<NFONTS ; ++font ){ /* For each of the avail. fonts */
  311.     sprintf( buffer, "%s Demonstration", Fonts[font] );
  312.     MainWindow( buffer );
  313.     getviewsettings( &vp );
  314.     changetextstyle( font, VERT_DIR, charsize[font] );
  315.     settextjustify( CENTER_TEXT, BOTTOM_TEXT );
  316.     outtextxy( 2*textwidth("M"), vp.bottom - 2*textheight("M"), "Vertical" );
  317.     changetextstyle( font, HORIZ_DIR, charsize[font] );
  318.     settextjustify( LEFT_TEXT, TOP_TEXT );
  319.     outtextxy( 2*textwidth("M"), 2, "Horizontal" );
  320.     settextjustify( CENTER_TEXT, CENTER_TEXT );
  321.     x = (vp.right - vp.left) / 2;
  322.     y = textheight( "H" );
  323.     for( i=1 ; i<5 ; ++i ){ /* For each of the sizes */
  324.       size = (font == SMALL_FONT) ? i+3 : i;
  325.       changetextstyle( font, HORIZ_DIR, size );
  326.       h = textheight( "H" );
  327.       y += h;
  328.       sprintf( buffer, "Size %d", size );
  329.       outtextxy( x, y, buffer );
  330.     }
  331.     if( font != DEFAULT_FONT ){  /* Show user declared font size */
  332.       y += h / 2; /* Move down the screen  */
  333.       settextjustify( CENTER_TEXT, TOP_TEXT );
  334.       setusercharsize( 5, 6, 3, 2 );
  335.       changetextstyle( font, HORIZ_DIR, USER_CHAR_SIZE );
  336.       outtextxy( (vp.right-vp.left)/2, y, "User Defined Size" );
  337.     }
  338.     Pause(); /* Pause to let user look */
  339.   } /* End of FONT loop */
  340. }
  341. /* */
  342. /* COLORDEMO: Display the current color palette on the screen. */
  343. /* */
  344. void ColorDemo(void)
  345. {
  346.   struct viewporttype vp;
  347.   int color, height, width;
  348.   int x, y, i, j;
  349.   char cnum[5];
  350.   MainWindow( "Color Demonstration" );  /* Show demonstration name      */
  351.   color = 1;
  352.   getviewsettings( &vp ); /* Get the current window size */
  353.   width  = 2 * ( (vp.right+1) / 16 );    /* Get box dimensions    */
  354.   height = 2 * ( (vp.bottom-10) / 10 );
  355.   x = width / 2;
  356.   y = height / 2; /* Leave 1/2 box border  */
  357.   for( j=0 ; j<3 ; ++j ){ /* Row loop */
  358.     for( i=0 ; i<5 ; ++i ){ /* Column loop */
  359.       setfillstyle(SOLID_FILL, color); /* Set to solid fill in color */
  360.       setcolor( color ); /* Set the same border color */
  361.       bar( x, y, x+width, y+height ); /* Draw the rectangle */
  362.       rectangle( x, y, x+width, y+height );  /* outline the rectangle */
  363.       if( color == BLACK ){ /* If box was black... */
  364. setcolor( WHITE ); /* Set drawing color to white */
  365. rectangle( x, y, x+width, y+height );  /* Outline black in white*/
  366.       }
  367.       itoa( color, cnum, 10 ); /* Convert # to ASCII */
  368.       outtextxy( x+(width/2), y+height+4, cnum );  /* Show color # */
  369.       color = ++color % MaxColors; /* Advance to the next color */
  370.       x += (width / 2) * 3; /* move the column base  */
  371.     } /* End of Column loop */
  372.     y += (height / 2) * 3; /* move the row base */
  373.     x = width / 2; /* reset column base */
  374.   } /* End of Row loop */
  375.   Pause(); /* Pause for user's response    */
  376. }
  377. /* */
  378. /* ARCDEMO: Display a random pattern of arcs on the screen */
  379. /* until the user says enough. */
  380. /* */
  381. void ArcDemo(void)
  382. {
  383.   int mradius; /* Maximum radius allowed */
  384.   int eangle; /* Random end angle of Arc */
  385.   struct arccoordstype ai; /* Used to read Arc Cord info */
  386.   MainWindow( "Arc Demonstration" );
  387.   StatusLine( "ESC Aborts - Press a Key to stop" );
  388.   mradius = MaxY / 10; /* Determine the maximum radius */
  389.   while( !kbhit() ){ /* Repeat until a key is hit */
  390.     setcolor( random( MaxColors - 1 ) + 1 ); /* Randomly select a color */
  391.     eangle = random( 358 ) + 1;  /* Select an end angle */
  392.     arc( random(MaxX), random(MaxY), random(eangle), eangle, mradius );
  393.     getarccoords( &ai ); /* Read Cord data */
  394.     line( ai.x, ai.y, ai.xstart, ai.ystart ); /* line from start to center */
  395.     line( ai.x, ai.y, ai.xend,   ai.yend ); /* line from end to center   */
  396.   } /* End of WHILE not KBHIT */
  397.   Pause(); /* Wait for user's response     */
  398. }
  399. /* */
  400. /* CIRCLEDEMO: Display a random pattern of circles on the screen */
  401. /* until the user says enough. */
  402. /* */
  403. void CircleDemo(void)
  404. {
  405.   int mradius; /* Maximum radius allowed */
  406.   MainWindow( "Circle Demonstration" );
  407.   StatusLine( "ESC Aborts - Press a Key to stop" );
  408.   mradius = MaxY / 10; /* Determine the maximum radius */
  409.   while( !kbhit() ){ /* Repeat until a key is hit */
  410.     setcolor( random( MaxColors - 1 ) + 1 ); /* Randomly select a color */
  411.     circle( random(MaxX), random(MaxY), random(mradius) );
  412.   } /* End of WHILE not KBHIT */
  413.   Pause(); /* Wait for user's response     */
  414. }
  415. /* */
  416. /* PIEDEMO: Display a pie chart on the screen. */
  417. /* */
  418. #define adjasp( y ) ((int)(AspectRatio * (double)(y)))
  419. #define torad( d ) (( (double)(d) * PI ) / 180.0 )
  420. void PieDemo(void)
  421. {
  422.   struct viewporttype vp;
  423.   int xcenter, ycenter, radius, lradius;
  424.   int x, y;
  425.   double radians, piesize;
  426.   MainWindow( "Pie Chart Demonstration" );
  427.   getviewsettings( &vp ); /* Get the current viewport */
  428.   xcenter = (vp.right - vp.left) / 2; /* Center the Pie horizontally */
  429.   ycenter = (vp.bottom - vp.top) / 2+20;/* Center the Pie vertically */
  430.   radius  = (vp.bottom - vp.top) / 3; /* It will cover 2/3rds screen */
  431.   piesize = (vp.bottom - vp.top) / 4.0; /* Optimum height ratio of pie */
  432.   while( (AspectRatio*radius) < piesize ) ++radius;
  433.   lradius = radius + ( radius / 5 ); /* Labels placed 20% farther */
  434.   changetextstyle( TRIPLEX_FONT, HORIZ_DIR, 4 );
  435.   settextjustify( CENTER_TEXT, TOP_TEXT );
  436.   outtextxy( MaxX/2, 6, "This is a Pie Chart" );
  437.   changetextstyle( TRIPLEX_FONT, HORIZ_DIR, 1 );
  438.   settextjustify( CENTER_TEXT, TOP_TEXT );
  439.   setfillstyle( SOLID_FILL, RED );
  440.   pieslice( xcenter+10, ycenter-adjasp(10), 0, 90, radius );
  441.   radians = torad( 45 );
  442.   x = xcenter + (int)( cos( radians ) * (double)lradius );
  443.   y = ycenter - (int)( sin( radians ) * (double)lradius * AspectRatio );
  444.   settextjustify( LEFT_TEXT, BOTTOM_TEXT );
  445.   outtextxy( x, y, "25 %" );
  446.   setfillstyle( WIDE_DOT_FILL, GREEN );
  447.   pieslice( xcenter, ycenter, 90, 135, radius );
  448.   radians = torad( 113 );
  449.   x = xcenter + (int)( cos( radians ) * (double)lradius );
  450.   y = ycenter - (int)( sin( radians ) * (double)lradius * AspectRatio );
  451.   settextjustify( RIGHT_TEXT, BOTTOM_TEXT );
  452.   outtextxy( x, y, "12.5 %" );
  453.   setfillstyle( INTERLEAVE_FILL, YELLOW );
  454.   settextjustify( RIGHT_TEXT, CENTER_TEXT );
  455.   pieslice( xcenter-10, ycenter, 135, 225, radius );
  456.   radians = torad( 180 );
  457.   x = xcenter + (int)( cos( radians ) * (double)lradius );
  458.   y = ycenter - (int)( sin( radians ) * (double)lradius * AspectRatio );
  459.   settextjustify( RIGHT_TEXT, CENTER_TEXT );
  460.   outtextxy( x, y, "25 %" );
  461.   setfillstyle( HATCH_FILL, BLUE );
  462.   pieslice( xcenter, ycenter, 225, 360, radius );
  463.   radians = torad( 293 );
  464.   x = xcenter + (int)( cos( radians ) * (double)lradius );
  465.   y = ycenter - (int)( sin( radians ) * (double)lradius * AspectRatio );
  466.   settextjustify( LEFT_TEXT, TOP_TEXT );
  467.   outtextxy( x, y, "37.5 %" );
  468.   Pause(); /* Pause for user's response    */
  469. }
  470. /* */
  471. /* BARDEMO: Draw a 2-D bar chart using Bar and Rectangle. */
  472. /* */
  473. void BarDemo(void)
  474. {
  475.   int barheight[] = {
  476.     1, 3, 5, 2, 4   };
  477.   int styles[]   = {
  478.     1, 3, 10, 5, 9, 1 };
  479.   int xstep, ystep;
  480.   int sheight, swidth;
  481.   int i, j, h;
  482.   struct viewporttype vp;
  483.   char buffer[40];
  484.   MainWindow( "Bar / Rectangle demonstration" );
  485.   h = 3 * textheight( "H" );
  486.   getviewsettings( &vp );
  487.   settextjustify( CENTER_TEXT, TOP_TEXT );
  488.   changetextstyle( TRIPLEX_FONT, HORIZ_DIR, 4 );
  489.   outtextxy( MaxX /2, 6, "These are 2-D Bars" );
  490.   changetextstyle( DEFAULT_FONT, HORIZ_DIR, 1 );
  491.   setviewport( vp.left+50, vp.top+30, vp.right-50, vp.bottom-10, 1 );
  492.   getviewsettings( &vp );
  493.   sheight = vp.bottom - vp.top;
  494.   swidth  = vp.right  - vp.left;
  495.   line( h, h, h, sheight-h );
  496.   line( h, sheight-h, sheight-h, sheight-h );
  497.   ystep = (sheight - (2*h) ) / 5;
  498.   xstep = (swidth  - (2*h) ) / 5;
  499.   j = sheight - h;
  500.   settextjustify( CENTER_TEXT, CENTER_TEXT );
  501.   for( i=0 ; i<6 ; ++i ){
  502.     line( h/2, j, h, j );
  503.     itoa( i, buffer, 10 );
  504.     outtextxy( 0, j, buffer );
  505.     j -= ystep;
  506.   }
  507.   j = h;
  508.   settextjustify( CENTER_TEXT, TOP_TEXT );
  509.   for( i=0 ; i<6 ; ++i ){
  510.     setfillstyle( styles[i], random(MaxColors) );
  511.     line( j, sheight - h, j, sheight- 3 - (h/2) );
  512.     itoa( i, buffer, 10 );
  513.     outtextxy( j, sheight - (h/2), buffer );
  514.     if( i != 5 ){
  515.       bar( j, (sheight-h)-(barheight[i] * ystep), j+xstep, sheight-h-1 );
  516.       rectangle( j, (sheight-h)-(barheight[i] * ystep), j+xstep, sheight-h);
  517.     }
  518.     j += xstep;
  519.   }
  520.   Pause();
  521. }
  522. /* */
  523. /* LINERELDEMO: Display pattern using moverel and linerel cmds. */
  524. /* */
  525. void LineRelDemo(void)
  526. {
  527.   struct viewporttype vp;
  528.   int h, w, dx, dy, cx, cy;
  529.   struct PTS outs[7];
  530.   MainWindow( "MoveRel / LineRel Demonstration" );
  531.   StatusLine( "Press any key to continue, ESC to Abort" );
  532.   getviewsettings( &vp );
  533.   cx = (vp.right  - vp.left) / 2; /* Center of the screen coords */
  534.   cy = (vp.bottom - vp.top ) / 2;
  535.   h  = (vp.bottom - vp.top ) / 8;
  536.   w  = (vp.right  - vp.left) / 9;
  537.   dx = 2 * w;
  538.   dy = 2 * h;
  539.   setcolor( BLACK );
  540.   setfillstyle( SOLID_FILL, BLUE );
  541.   bar( 0, 0, vp.right-vp.left, vp.bottom-vp.top ); /* Draw backgnd */
  542.   outs[0].x = cx -  dx;
  543.   outs[0].y = cy -  dy;
  544.   outs[1].x = cx - (dx-w);
  545.   outs[1].y = cy - (dy+h);
  546.   outs[2].x = cx +  dx;
  547.   outs[2].y = cy - (dy+h);
  548.   outs[3].x = cx +  dx;
  549.   outs[3].y = cy +  dy;
  550.   outs[4].x = cx + (dx-w);
  551.   outs[4].y = cy + (dy+h);
  552.   outs[5].x = cx -  dx;
  553.   outs[5].y = cy + (dy+h);
  554.   outs[6].x = cx -  dx;
  555.   outs[6].y = cy -  dy;
  556.   setfillstyle( SOLID_FILL, WHITE );
  557.   fillpoly( 7, (int far *)outs );
  558.   outs[0].x = cx - (w/2);
  559.   outs[0].y = cy + h;
  560.   outs[1].x = cx + (w/2);
  561.   outs[1].y = cy + h;
  562.   outs[2].x = cx + (w/2);
  563.   outs[2].y = cy - h;
  564.   outs[3].x = cx - (w/2);
  565.   outs[3].y = cy - h;
  566.   outs[4].x = cx - (w/2);
  567.   outs[4].y = cy + h;
  568.   setfillstyle( SOLID_FILL, BLUE );
  569.   fillpoly( 5, (int far *)outs );
  570.   /* Draw a Tesseract object on the screen using the LineRel and */
  571.   /* MoveRel drawing commands. */
  572.   moveto( cx-dx, cy-dy );
  573.   linerel(  w, -h );
  574.   linerel(  3*w, 0 );
  575.   linerel(   0,  5*h );
  576.   linerel( -w, h );
  577.   linerel( -3*w, 0 );
  578.   linerel(   0, -5*h );
  579.   moverel( w, -h );
  580.   linerel(   0,  5*h );
  581.   linerel( w+(w/2), 0 );
  582.   linerel(   0, -3*h );
  583.   linerel( w/2,   -h );
  584.   linerel( 0, 5*h );
  585.   moverel(  0, -5*h );
  586.   linerel( -(w+(w/2)), 0 );
  587.   linerel( 0, 3*h );
  588.   linerel( -w/2, h );
  589.   moverel( w/2, -h );
  590.   linerel( w, 0 );
  591.   moverel( 0, -2*h );
  592.   linerel( -w, 0 );
  593.   Pause(); /* Wait for user's response     */
  594. }
  595. /* */
  596. /* PUTPIXELDEMO: Display a pattern of random dots on the screen */
  597. /* and pick them back up again. */
  598. /* */
  599. void PutPixelDemo(void)
  600. {
  601.   int seed = 1958;
  602.   int i, x, y, h, w, color;
  603.   struct viewporttype vp;
  604.   MainWindow( "PutPixel / GetPixel Demonstration" );
  605.   getviewsettings( &vp );
  606.   h = vp.bottom - vp.top;
  607.   w = vp.right - vp.left;
  608.   srand( seed ); /* Restart random # function */
  609.   for( i=0 ; i<5000 ; ++i ){ /* Put 5000 pixels on screen */
  610.     x = 1 + random( w - 1 ); /* Generate a random location */
  611.     y = 1 + random( h - 1 );
  612.     color = random( MaxColors );
  613.     putpixel( x, y, color );
  614.   }
  615.   srand( seed ); /* Restart Random # at same # */
  616.   for( i=0 ; i<5000 ; ++i ){ /* Take the 5000 pixels off */
  617.     x = 1 + random( w - 1 ); /* Generate a random location */
  618.     y = 1 + random( h - 1 );
  619.     color = getpixel( x, y ); /* Read the color pixel  */
  620.     if( color == random( MaxColors ) ) /* Used to keep RANDOM in sync */
  621.       putpixel( x, y, 0 ); /* Write pixel to BLACK  */
  622.   }
  623.   Pause(); /* Wait for user's response     */
  624. }
  625. /* */
  626. /*   PUTIMAGEDEMO */
  627. /* */
  628. void PutImageDemo(void)
  629. {
  630.   static int r     = 20;
  631.   static int StartX = 100;
  632.   static int StartY = 50;
  633.   struct viewporttype vp;
  634.   int PauseTime, x, y, ulx, uly, lrx, lry, size, i, width, height, step;
  635.   void *Saucer;
  636.   MainWindow("GetImage / PutImage Demonstration");
  637.   getviewsettings( &vp );
  638.   /* Draw Saucer */
  639.   setfillstyle( SOLID_FILL, getmaxcolor() );
  640.   fillellipse(StartX, StartY, r, (r/3)+2);
  641.   ellipse(StartX, StartY-4, 190, 357, r, r/3);
  642.   line(StartX+7, StartY-6, StartX+10, StartY-12);
  643.   circle(StartX+10, StartY-12, 2);
  644.   line(StartX-7, StartY-6, StartX-10, StartY-12);
  645.   circle(StartX-10, StartY-12, 2);
  646.   /* Read saucer image */
  647.   ulx = StartX-(r+1);
  648.   uly = StartY-14;
  649.   lrx = StartX+(r+1);
  650.   lry = StartY+(r/3)+3;
  651.   width = lrx - ulx + 1;
  652.   height = lry - uly + 1;
  653.   size = imagesize(ulx, uly, lrx, lry);
  654.   Saucer = malloc( size );
  655.   getimage(ulx, uly, lrx, lry, Saucer);
  656.   putimage(ulx, uly, Saucer, XOR_PUT);
  657. /* Plot some "stars"  */
  658.   for ( i=0 ; i<1000; ++i )
  659.     putpixel(random(MaxX), random(MaxY), random( MaxColors-1 )+1);
  660.   x = MaxX / 2;
  661.   y = MaxY / 2;
  662.   PauseTime = 70;
  663.   /* until a key is hit */
  664.   while ( !kbhit() ) {
  665.     /* Draw the Saucer */
  666.     putimage(x, y, Saucer, XOR_PUT);      /*  draw image  */
  667.     delay(PauseTime);
  668.     putimage(x, y, Saucer, XOR_PUT);      /* erase image  */
  669.     /* Move Saucer */
  670.     step = random( 2*r );
  671.     if ((step/2) % 2 != 0 )
  672.       step = -1 * step;
  673.     x = x + step;
  674.     step = random( r );
  675.     if ((step/2) % 2 != 0 )
  676.       step = -1 * step;
  677.     y = y + step;
  678.     if (vp.left + x + width - 1 > vp.right)
  679.       x = vp.right-vp.left-width + 1;
  680.     else
  681.       if (x < 0)
  682. x = 0;
  683.     if (vp.top + y + height - 1 > vp.bottom)
  684.       y = vp.bottom-vp.top-height + 1;
  685.     else
  686.       if (y < 0)
  687. y = 0;
  688.   }
  689.   free( Saucer );
  690.   Pause();
  691. }
  692. /* */
  693. /* LINETODEMO: Display a pattern using moveto and lineto commands. */
  694. /* */
  695. #define MAXPTS 15
  696. void LineToDemo(void)
  697. {
  698.   struct viewporttype vp;
  699.   struct PTS points[MAXPTS];
  700.   int i, j, h, w, xcenter, ycenter;
  701.   int radius, angle, step;
  702.   double  rads;
  703.   MainWindow( "MoveTo / LineTo Demonstration" );
  704.   getviewsettings( &vp );
  705.   h = vp.bottom - vp.top;
  706.   w = vp.right - vp.left;
  707.   xcenter = w / 2; /* Determine the center of circle */
  708.   ycenter = h / 2;
  709.   radius  = (h - 30) / (AspectRatio * 2);
  710.   step   = 360 / MAXPTS; /* Determine # of increments */
  711.   angle = 0; /* Begin at zero degrees */
  712.   for( i=0 ; i<MAXPTS ; ++i ){ /* Determine circle intercepts */
  713.     rads = (double)angle * PI / 180.0; /* Convert angle to radians */
  714.     points[i].x = xcenter + (int)( cos(rads) * radius );
  715.     points[i].y = ycenter - (int)( sin(rads) * radius * AspectRatio );
  716.     angle += step; /* Move to next increment */
  717.   }
  718.   circle( xcenter, ycenter, radius ); /* Draw bounding circle  */
  719.   for( i=0 ; i<MAXPTS ; ++i ){ /* Draw the cords to the circle */
  720.     for( j=i ; j<MAXPTS ; ++j ){ /* For each remaining intersect */
  721.       moveto(points[i].x, points[i].y); /* Move to beginning of cord */
  722.       lineto(points[j].x, points[j].y); /* Draw the cord */
  723.     }
  724.   }
  725.   Pause(); /* Wait for user's response     */
  726. }
  727. /* */
  728. /* LINESTYLEDEMO: Display a pattern using all of the standard */
  729. /* line styles that are available.  */
  730. /* */
  731. void LineStyleDemo(void)
  732. {
  733.   int style, step;
  734.   int x, y, w;
  735.   struct viewporttype vp;
  736.   char buffer[40];
  737.   MainWindow( "Pre-defined line styles" );
  738.   getviewsettings( &vp );
  739.   w = vp.right - vp.left;
  740.   x = 35;
  741.   y = 10;
  742.   step = w / 11;
  743.   settextjustify( LEFT_TEXT, TOP_TEXT );
  744.   outtextxy( x, y, "Normal Width" );
  745.   settextjustify( CENTER_TEXT, TOP_TEXT );
  746.   for( style=0 ; style<4 ; ++style ){
  747.     setlinestyle( style, 0, NORM_WIDTH );
  748.     line( x, y+20, x, vp.bottom-40 );
  749.     itoa( style, buffer, 10 );
  750.     outtextxy( x, vp.bottom-30, buffer );
  751.     x += step;
  752.   }
  753.   x += 2 * step;
  754.   settextjustify( LEFT_TEXT, TOP_TEXT );
  755.   outtextxy( x, y, "Thick Width" );
  756.   settextjustify( CENTER_TEXT, TOP_TEXT );
  757.   for( style=0 ; style<4 ; ++style ){
  758.     setlinestyle( style, 0, THICK_WIDTH );
  759.     line( x, y+20, x, vp.bottom-40 );
  760.     itoa( style, buffer, 10 );
  761.     outtextxy( x, vp.bottom-30, buffer );
  762.     x += step;
  763.   }
  764.   settextjustify( LEFT_TEXT, TOP_TEXT );
  765.   Pause(); /* Wait for user's response     */
  766. }
  767. /* */
  768. /* CRTMODEDEMO: Demonstrate the effects of the change mode  */
  769. /* commands on the current screen.  */
  770. /* */
  771. void CRTModeDemo(void)
  772. {
  773.   struct viewporttype vp;
  774.   int mode;
  775.   MainWindow( "SetGraphMode / RestoreCRTMode demo" );
  776.   getviewsettings( &vp );
  777.   mode = getgraphmode();
  778.   settextjustify( CENTER_TEXT, CENTER_TEXT );
  779.   outtextxy( (vp.right-vp.left)/2, (vp.bottom-vp.top)/2,
  780.   "Now you are in graphics mode..." );
  781.   StatusLine( "Press any key for text mode..." );
  782.   getch();
  783.   restorecrtmode();
  784.   printf( "Now you are in text mode.nn" );
  785.   printf( "Press any key to go back to graphics..." );
  786.   getch();
  787.   setgraphmode( mode );
  788.   MainWindow( "SetGraphMode / RestoreCRTMode demo" );
  789.   settextjustify( CENTER_TEXT, CENTER_TEXT );
  790.   outtextxy( (vp.right-vp.left)/2, (vp.bottom-vp.top)/2,
  791.   "Back in Graphics Mode..." );
  792.   Pause(); /* Wait for user's response     */
  793. }
  794. /* */
  795. /* USERLINESTYLEDEMO: Display line styles showing the user  */
  796. /* defined line style functions. */
  797. /* */
  798. void UserLineStyleDemo(void)
  799. {
  800.   int x, y, i, h, flag;
  801.   unsigned int style;
  802.   struct viewporttype vp;
  803.   MainWindow( "User defined line styles" );
  804.   getviewsettings( &vp );
  805.   h = vp.bottom - vp.top;
  806.   x = 4;
  807.   y = 10;
  808.   style = 0;
  809.   i = 0;
  810.   settextjustify( CENTER_TEXT, TOP_TEXT );
  811.   flag = TRUE; /* Set the bits in this pass */
  812.   while( x < vp.right-2 ){ /* Draw lines across the screen */
  813.     if( flag ) /* If flag, set bits...  */
  814.       style = style | (1 << i);  /*    Set the Ith bit in word */
  815.     else /* If no flag, clear bits */
  816.     style = style & !(0x8000 >> i); /*    Clear the Ith bit in word */
  817.     setlinestyle( USERBIT_LINE, style, NORM_WIDTH );
  818.     line( x, y, x, h-y ); /* Draw the new line pattern */
  819.     x += 5; /* Move the X location of line */
  820.     i = ++i % 16; /* Advance to next bit pattern */
  821.     if( style == 0xffff ){ /* Are all bits set? */
  822.       flag = FALSE; /*   begin removing bits */
  823.       i = 0; /* Start with whole pattern */
  824.     }
  825.     else{ /* Bits not all set... */
  826.       if( style == 0 ) /* Are all bits clear? */
  827. flag = TRUE; /*   begin setting bits  */
  828.     }
  829.   }
  830.   settextjustify( LEFT_TEXT, TOP_TEXT );
  831.   Pause(); /* Wait for user's response     */
  832. }
  833. /* */
  834. /* FILLSTYLEDEMO: Display the standard fill patterns available. */
  835. /* */
  836. void FillStyleDemo(void)
  837. {
  838.   int h, w, style;
  839.   int i, j, x, y;
  840.   struct viewporttype vp;
  841.   char buffer[40];
  842.   MainWindow( "Pre-defined Fill Styles" );
  843.   getviewsettings( &vp );
  844.   w = 2 * ((vp.right  +  1) / 13);
  845.   h = 2 * ((vp.bottom - 10) / 10);
  846.   x = w / 2;
  847.   y = h / 2; /* Leave 1/2 blk margin  */
  848.   style = 0;
  849.   for( j=0 ; j<3 ; ++j ){ /* Three rows of boxes */
  850.     for( i=0 ; i<4 ; ++i ){ /* Four column of boxes  */
  851.       setfillstyle(style, MaxColors-1); /* Set the fill style and WHITE */
  852.       bar( x, y, x+w, y+h ); /* Draw the actual box */
  853.       rectangle( x, y, x+w, y+h ); /* Outline the box */
  854.       itoa( style, buffer, 10 ); /* Convert style 3 to ASCII */
  855.       outtextxy( x+(w / 2), y+h+4, buffer );
  856.       ++style; /* Go on to next style # */
  857.       x += (w / 2) * 3;  /* Go to next column */
  858.     } /* End of coulmn loop */
  859.     x = w / 2; /* Put base back to 1st column */
  860.     y += (h / 2) * 3; /* Advance to next row */
  861.   } /* End of Row loop */
  862.   settextjustify( LEFT_TEXT, TOP_TEXT );
  863.   Pause(); /* Wait for user's response     */
  864. }
  865. /* */
  866. /* FILLPATTERNDEMO: Demonstrate how to use the user definable */
  867. /* fill patterns. */
  868. /* */
  869. void FillPatternDemo(void)
  870. {
  871.   int style;
  872.   int h, w;
  873.   int x, y, i, j;
  874.   char buffer[40];
  875.   struct viewporttype vp;
  876.   static char patterns[][8] = {
  877.     { 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55 },
  878.     { 0x33, 0x33, 0xCC, 0xCC, 0x33, 0x33, 0xCC, 0xCC },
  879.     { 0xF0, 0xF0, 0xF0, 0xF0, 0x0F, 0x0F, 0x0F, 0x0F },
  880.     { 0x00, 0x10, 0x28, 0x44, 0x28, 0x10, 0x00, 0x00 },
  881.     { 0x00, 0x70, 0x20, 0x27, 0x24, 0x24, 0x07, 0x00 },
  882.     { 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00 },
  883.     { 0x00, 0x00, 0x3C, 0x3C, 0x3C, 0x3C, 0x00, 0x00 },
  884.     { 0x00, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x00 },
  885.     { 0x00, 0x00, 0x22, 0x08, 0x00, 0x22, 0x1C, 0x00 },
  886.     { 0xFF, 0x7E, 0x3C, 0x18, 0x18, 0x3C, 0x7E, 0xFF },
  887.     { 0x00, 0x10, 0x10, 0x7C, 0x10, 0x10, 0x00, 0x00 },
  888.     { 0x00, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x00 }
  889.   };
  890.   MainWindow( "User Defined Fill Styles" );
  891.   getviewsettings( &vp );
  892.   w = 2 * ((vp.right  +  1) / 13);
  893.   h = 2 * ((vp.bottom - 10) / 10);
  894.   x = w / 2;
  895.   y = h / 2; /* Leave 1/2 blk margin  */
  896.   style = 0;
  897.   for( j=0 ; j<3 ; ++j ){ /* Three rows of boxes */
  898.     for( i=0 ; i<4 ; ++i ){ /* Four column of boxes  */
  899.       setfillpattern( &patterns[style][0], MaxColors-1 );
  900.       bar( x, y, x+w, y+h ); /* Draw the actual box */
  901.       rectangle( x, y, x+w, y+h ); /* Outline the box */
  902.       itoa( style, buffer, 10 ); /* Convert style 3 to ASCII */
  903.       outtextxy( x+(w / 2), y+h+4, buffer );
  904.       ++style; /* Go on to next style # */
  905.       x += (w / 2) * 3;  /* Go to next column */
  906.     } /* End of coulmn loop */
  907.     x = w / 2; /* Put base back to 1st column */
  908.     y += (h / 2) * 3; /* Advance to next row */
  909.   } /* End of Row loop */
  910.   settextjustify( LEFT_TEXT, TOP_TEXT );
  911.   Pause(); /* Wait for user's response     */
  912. }
  913. /* */
  914. /* POLYDEMO: Display a random pattern of polygons on the screen */
  915. /* until the user says enough. */
  916. /* */
  917. void PaletteDemo(void)
  918. {
  919.   int i, j, x, y, color;
  920.   struct viewporttype vp;
  921.   int height, width;
  922.   MainWindow( "Palette Demonstration" );
  923.   StatusLine( "Press any key to continue, ESC to Abort" );
  924.   getviewsettings( &vp );
  925.   width  = (vp.right - vp.left) / 15; /* get width of the box  */
  926.   height = (vp.bottom - vp.top) / 10; /* Get the height of the box */
  927.   x = y = 0; /* Start in upper corner */
  928.   color = 1; /* Begin at 1st color */
  929.   for( j=0 ; j<10 ; ++j ){ /* For 10 rows of boxes  */
  930.     for( i=0 ; i<15 ; ++i ){ /* For 15 columns of boxes */
  931.       setfillstyle( SOLID_FILL, color++ ); /* Set the color of box */
  932.       bar( x, y, x+width, y+height ); /* Draw the box  */
  933.       x += width + 1; /* Advance to next col */
  934.       color = 1 + (color % (MaxColors - 2)); /* Set new color */
  935.     } /* End of COLUMN loop */
  936.     x = 0; /* Goto 1st column */
  937.     y += height + 1; /* Goto next row */
  938.   } /* End of ROW loop */
  939.   while( !kbhit() ){ /* Until user enters a key... */
  940.     setpalette( 1+random(MaxColors - 2), random( 65 ) );
  941.   }
  942.   setallpalette( &palette );
  943.   Pause(); /* Wait for user's response     */
  944. }
  945. /* */
  946. /* POLYDEMO: Display a random pattern of polygons on the screen */
  947. /* until the user says enough. */
  948. /* */
  949. #define MaxPts 6 /* Maximum # of pts in polygon */
  950. void PolyDemo(void)
  951. {
  952.   struct PTS poly[ MaxPts ]; /* Space to hold datapoints */
  953.   int color; /* Current drawing color */
  954.   int i;
  955.   MainWindow( "DrawPoly / FillPoly Demonstration" );
  956.   StatusLine( "ESC Aborts - Press a Key to stop" );
  957.   while( !kbhit() ){ /* Repeat until a key is hit */
  958.     color = 1 + random( MaxColors-1 ); /* Get a random color # (no blk)*/
  959.     setfillstyle( random(10), color ); /* Set a random line style */
  960.     setcolor( color ); /* Set the desired color */
  961.     for( i=0 ; i<(MaxPts-1) ; i++ ){ /* Determine a random polygon */
  962.       poly[i].x = random( MaxX ); /* Set the x coord of point */
  963.       poly[i].y = random( MaxY ); /* Set the y coord of point */
  964.     }
  965.     poly[i].x = poly[0].x; /* last point = first point */
  966.     poly[i].y = poly[1].y;
  967.     fillpoly( MaxPts, (int far *)poly );    /* Draw the actual polygon     */
  968.   } /* End of WHILE not KBHIT */
  969.   Pause(); /* Wait for user's response     */
  970. }
  971. /* */
  972. /* SAYGOODBYE: Give a closing screen to the user before leaving. */
  973. /* */
  974. void SayGoodbye(void)
  975. {
  976.   struct viewporttype viewinfo;  /* Structure to read viewport */
  977.   int h, w;
  978.   MainWindow( "== Finale ==" );
  979.   getviewsettings( &viewinfo );  /* Read viewport settings */
  980.   changetextstyle( TRIPLEX_FONT, HORIZ_DIR, 4 );
  981.   settextjustify( CENTER_TEXT, CENTER_TEXT );
  982.   h = viewinfo.bottom - viewinfo.top;
  983.   w = viewinfo.right  - viewinfo.left;
  984.   outtextxy( w/2, h/2, "That's all, folks!" );
  985.   StatusLine( "Press any key to EXIT" );
  986.   getch();
  987.   cleardevice(); /* Clear the graphics screen */
  988. }
  989. /* */
  990. /* PAUSE: Pause until the user enters a keystroke. If the */
  991. /* key is an ESC, then exit program, else simply return. */
  992. /* */
  993. void Pause(void)
  994. {
  995.   static char msg[] = "Esc aborts or press a key...";
  996.   int c;
  997.   StatusLine( msg ); /* Put msg at bottom of screen */
  998.   c = getch(); /* Read a character from kbd */
  999.   if( ESC == c ){ /* Does user wish to leave? */
  1000.     closegraph(); /* Change to text mode */
  1001.     exit( 1 ); /* Return to OS  */
  1002.   }
  1003.   if( 0 == c ){  /* Did use hit a non-ASCII key? */
  1004.     c = getch(); /* Read scan code for keyboard */
  1005.   }
  1006.   cleardevice(); /* Clear the screen */
  1007. }
  1008. /* */
  1009. /* MAINWINDOW: Establish the main window for the demo and set */
  1010. /* a viewport for the demo code. */
  1011. /* */
  1012. void MainWindow( char *header )
  1013. {
  1014.   int height;
  1015.   cleardevice(); /* Clear graphics screen */
  1016.   setcolor( MaxColors - 1 ); /* Set current color to white */
  1017.   setviewport( 0, 0, MaxX, MaxY, 1 ); /* Open port to full screen */
  1018.   height = textheight( "H" );           /* Get basic text height        */
  1019.   changetextstyle( DEFAULT_FONT, HORIZ_DIR, 1 );
  1020.   settextjustify( CENTER_TEXT, TOP_TEXT );
  1021.   outtextxy( MaxX/2, 2, header );
  1022.   setviewport( 0, height+4, MaxX, MaxY-(height+4), 1 );
  1023.   DrawBorder();
  1024.   setviewport( 1, height+5, MaxX-1, MaxY-(height+5), 1 );
  1025. }
  1026. /* */
  1027. /* STATUSLINE: Display a status line at the bottom of the screen. */
  1028. /* */
  1029. void StatusLine( char *msg )
  1030. {
  1031.   int height;
  1032.   setviewport( 0, 0, MaxX, MaxY, 1 ); /* Open port to full screen */
  1033.   setcolor( MaxColors - 1 ); /* Set current color to white */
  1034.   changetextstyle( DEFAULT_FONT, HORIZ_DIR, 1 );
  1035.   settextjustify( CENTER_TEXT, TOP_TEXT );
  1036.   setlinestyle( SOLID_LINE, 0, NORM_WIDTH );
  1037.   setfillstyle( EMPTY_FILL, 0 );
  1038.   height = textheight( "H" );           /* Detemine current height      */
  1039.   bar( 0, MaxY-(height+4), MaxX, MaxY );
  1040.   rectangle( 0, MaxY-(height+4), MaxX, MaxY );
  1041.   outtextxy( MaxX/2, MaxY-(height+2), msg );
  1042.   setviewport( 1, height+5, MaxX-1, MaxY-(height+5), 1 );
  1043. }
  1044. /* */
  1045. /* DRAWBORDER: Draw a solid single line around the current  */
  1046. /* viewport. */
  1047. /* */
  1048. void DrawBorder(void)
  1049. {
  1050.   struct viewporttype vp;
  1051.   setcolor( MaxColors - 1 ); /* Set current color to white */
  1052.   setlinestyle( SOLID_LINE, 0, NORM_WIDTH );
  1053.   getviewsettings( &vp );
  1054.   rectangle( 0, 0, vp.right-vp.left, vp.bottom-vp.top );
  1055. }
  1056. /* */
  1057. /* CHANGETEXTSTYLE: similar to settextstyle, but checks for */
  1058. /* errors that might occur whil loading the font file. */
  1059. /* */
  1060. void changetextstyle(int font, int direction, int charsize)
  1061. {
  1062.   int ErrorCode;
  1063.   graphresult(); /* clear error code */
  1064.   settextstyle(font, direction, charsize);
  1065.   ErrorCode = graphresult(); /* check result  */
  1066.   if( ErrorCode != grOk ){ /* if error occured */
  1067.     closegraph();
  1068.     printf(" Graphics System Error: %sn", grapherrormsg( ErrorCode ) );
  1069.     exit( 1 );
  1070.   }
  1071. }
  1072. /* */
  1073. /* GPRINTF: Used like PRINTF except the output is sent to the */
  1074. /* screen in graphics mode at the specified co-ordinate. */
  1075. /* */
  1076. int gprintf( int *xloc, int *yloc, char *fmt, ... )
  1077. {
  1078.   va_list  argptr; /* Argument list pointer */
  1079.   char str[140]; /* Buffer to build sting into */
  1080.   int cnt; /* Result of SPRINTF for return */
  1081.   va_start( argptr, fmt ); /* Initialize va_ functions */
  1082.   cnt = vsprintf( str, fmt, argptr ); /* prints string to buffer */
  1083.   outtextxy( *xloc, *yloc, str ); /* Send string in graphics mode */
  1084.   *yloc += textheight( "H" ) + 2;       /* Advance to next line         */
  1085.   va_end( argptr ); /* Close va_ functions */
  1086.   return( cnt ); /* Return the conversion count */
  1087. }