home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgLangD.iso / C++-7 / DISK4 / SAMPLES / GRAPHICS / GRDEMO.C$ / GRDEMO
Encoding:
Text File  |  1992-02-27  |  20.2 KB  |  719 lines

  1. /* GRDEMO.C - Demonstrates capabilities of the Microsoft graphics library.
  2.  * Uses MENU module to display menus. Uses TURTLE module for Turtle
  3.  * graphics.
  4.  */
  5.  
  6. #include <graph.h>
  7. #include <math.h>
  8. #include <malloc.h>
  9. #include <stdlib.h>
  10. #include <stdio.h>
  11. #include <conio.h>
  12. #include <time.h>
  13. #include "turtle.h"
  14. #include "menu.h"
  15.  
  16. /* Function prototypes */
  17. int  main( void );
  18. void Circles( void );
  19. void Sphere( void );
  20. int  Polygons( void );
  21. int  Spiral( int angle, double inc );
  22. int  InSpiral( double side, int angle, int inc );
  23. void Bug( void );
  24. void Adjust( void );
  25. void Diamond( double xy );
  26.  
  27. /* Returns a random number between min and max, which must be in
  28.  * integer range.
  29.  */
  30. #define getrandom( min, max ) ((rand() % (int)(((max) + 1) - (min))) + (min))
  31.  
  32. /* Constants */
  33. #define PI      3.141593
  34. #define LASTATR 15
  35. #define NLASTATR 14
  36.  
  37. /* Array and enum for main menu */
  38. ITEM mnuMain[] =
  39. {                    /* Highlight Char  Pos */
  40.     { 0, "Quit"            },   /* Q     0  */
  41.     { 0, "Circles"         },   /* C     0  */
  42.     { 0, "Rotating Sphere" },   /* R     0  */
  43.     { 0, "Tunnel"          },   /* T     0  */
  44.     { 0, "Spiral"          },   /* S     0  */
  45.     { 0, "Inverted Spiral" },   /* I     0  */
  46.     { 0, "Bug"             },   /* B     0  */
  47.     { 0, "Adjust Window"   },   /* A     0  */
  48.     { 0, "Mode Change"     },   /* M     0  */
  49.     { 0, ""                }
  50. };
  51.  
  52. /* Define constants (0, 1, 2,...) for menu choices */
  53. enum CHOICES
  54. {
  55.     QUIT, CIRCLES, SPHERE, TUNNEL, SPIRAL, INSPIRAL, BUG, ADJUST, CHANGE
  56. };
  57.  
  58. /* Arrays of video mode menu items and of corresponding mode numbers.
  59.  * Each has a temporary array containing all items, and a pointer version
  60.  * including all except Olivetti.
  61.  */
  62. ITEM mnuModesT[] =
  63. {                    /* Highlight Char  Pos */
  64.     { 0, "ORESCOLOR "   },      /* O     0  */
  65.     { 4, "MRES4COLOR "  },      /* 4     4  */
  66.     { 4, "MRESNOCOLOR"  },      /* N     4  */
  67.     { 4, "HRESBW"       },      /* B     4  */
  68.     { 0, "MRES16COLOR"  },      /* M     0  */
  69.     { 0, "HRES16COLOR"  },      /* H     0  */
  70.     { 0, "ERESCOLOR"    },      /* E     0  */
  71.     { 4, "VRES2COLOR"   },      /* 2     4  */
  72.     { 0, "VRES16COLOR"  },      /* V     0  */
  73.     { 1, "MRES256COLOR" },      /* R     1  */
  74.     { 6, "ORES256COLOR" },      /* 6     6  */
  75.     { 7, "VRES256COLOR" },      /* C     7  */
  76.  
  77.     /* Warning: The following values are commented out because using
  78.      * them with some monitors may damage the monitor. Make sure you
  79.      * have adequate hardware before experimenting with them.
  80.      */
  81.  
  82.     /* Uncomment if you have a NEC MultiSync 3D monitor or equivalent. */
  83. //  { 0, "SRES16COLOR"  },  /* S     0  */
  84. //  { 1, "SRES256COLOR" },  /* R     1  */
  85.  
  86.     /* Uncomment if you have a NEC MultiSync 4D monitor or equivalent. */
  87. //  { 0, "XRES16COLOR"  },  /* X     0  */
  88. //  { 5, "XRES256COLOR" },  /* 5     5  */
  89.  
  90.     /* Uncomment if you have a NEC MultiSync 5D monitor or equivalent. */
  91. //  { 0, "ZRES16COLOR"  },      /* Z     0  */
  92. //  { 9, "ZRES256COLOR" },      /* L     9  */
  93.     { 0, ""             }
  94. };
  95. ITEM *mnuModes = &mnuModesT[1];  /* Default is no Olivetti mode */
  96.  
  97. int aModesT[] =
  98. {
  99.     _ORESCOLOR,
  100.     _MRES4COLOR,
  101.     _MRESNOCOLOR,
  102.     _HRESBW,
  103.     _MRES16COLOR,
  104.     _HRES16COLOR,
  105.     _ERESCOLOR,
  106.     _VRES2COLOR,
  107.     _VRES16COLOR,
  108.     _MRES256COLOR,
  109.     _ORES256COLOR,
  110.     _VRES256COLOR,
  111.  
  112.     /* Uncomment if you have a NEC MultiSync 3D monitor or equivalent. */
  113. //  _SRES16COLOR,
  114. //  _SRES256COLOR,
  115.  
  116.     /* Uncomment if you have a NEC MultiSync 4D monitor or equivalent. */
  117. //  _XRES16COLOR,
  118. //  _XRES256COLOR,
  119.  
  120.     /* Uncomment if you have a NEC MultiSync 5D monitor or equivalent. */
  121. //  _ZRES16COLOR,
  122. //  _ZRES256COLOR,
  123.  
  124.     _TEXTMONO,
  125.     _ERESNOCOLOR,
  126.     _HERCMONO
  127. };
  128. int *aModes = &aModesT[1];              /* Default is no Olivetti mode */
  129.  
  130. /* Global video configuration */
  131. struct videoconfig vc;
  132.  
  133. int main()
  134. {
  135.     short rowMid, colMid;
  136.     short fColor, fFirstTime = TRUE;
  137.     short iMode, iLastMode, iMainCur = 0, iModesCur = 0;
  138.  
  139.     _displaycursor( _GCURSOROFF );
  140.     _getvideoconfig( &vc );
  141.     rowMid = vc.numtextrows / 2;
  142.     colMid = vc.numtextcols / 2;
  143.  
  144.     /* Select best graphics mode, adjust menus, set color flag. Note
  145.      * that this requires checking both the adapter and the mode.
  146.      */
  147.     switch( vc.adapter )
  148.     {
  149.         case _OCGA:
  150.             mnuModes = &mnuModesT[0];           /* Turn on Olivetti mode */
  151.             aModes = &aModesT[0];
  152.         case _CGA:
  153.             mnuModesT[4].achItem[0] = '\0';     /* Turn off EGA modes    */
  154.             iMode = _MRES4COLOR;
  155.             break;
  156.         case _HGC:
  157.             mnuModesT[7].achItem[0] = '\0';
  158.             iMode = _HERCMONO;
  159.             break;
  160.         case _OEGA:
  161.             mnuModes = &mnuModesT[0];           /* Turn on Olivetti mode */
  162.             aModes = &aModesT[0];
  163.         case _EGA:
  164.             mnuModesT[7].achItem[0] = '\0';     /* Turn off VGA modes    */
  165.             if( vc.memory > 64 )
  166.                 iMode = _ERESCOLOR;
  167.             else
  168.                 iMode = _HRES16COLOR;
  169.             break;
  170.         case _OVGA:
  171.             mnuModes = &mnuModesT[0];           /* Turn on Olivetti mode */
  172.             aModes = &aModesT[0];
  173.         case _VGA:
  174.             mnuModesT[10].achItem[0] = '\0';    /* Turn off SVGA modes   */
  175.             iMode = _VRES16COLOR;
  176.             break;
  177.         case _SVGA:
  178.             iMode = _VRES16COLOR;
  179.             break;
  180.         case _MCGA:
  181.             iMode = _MRES256COLOR;
  182.             break;
  183.         case _MDPA:
  184.         default:
  185.             puts( "No graphics mode available.\n" );
  186.             return TRUE;
  187.     }
  188.     switch( vc.mode )
  189.     {
  190.         case _TEXTBW80:
  191.         case _TEXTBW40:
  192.             fColor = FALSE;
  193.             break;
  194.         case _TEXTMONO:
  195.         case _ERESNOCOLOR:
  196.         case _HERCMONO:
  197.             fColor = FALSE;
  198.             if( iMode != _HERCMONO )
  199.                 iMode = _ERESNOCOLOR;
  200.             mnuMain[8].achItem[0] = '\0';       /* Turn off mode change */
  201.             break;
  202.         default:
  203.             fColor = TRUE;
  204.             break;
  205.     }
  206.  
  207.     /* Find current mode in mode array. */
  208.     for( iModesCur = 0; aModes[iModesCur] != iMode; iModesCur++ )
  209.         ;
  210.     iLastMode = iMode;
  211.  
  212.     /* Seed randomizer with time. */
  213.     srand( (unsigned)time( NULL ) );
  214.  
  215.     while( TRUE )
  216.     {
  217.         /* Set text mode and optionally clear the screen to blue. */
  218.         if( iMainCur != CHANGE )
  219.             _setvideomode(_DEFAULTMODE );
  220.         if( fColor )
  221.             _setbkcolor( (long)_TBLUE );
  222.         _clearscreen( _GCLEARSCREEN );
  223.  
  224.         /* Select from menu. */
  225.         iMainCur = Menu( rowMid, colMid, mnuMain, iMainCur );
  226.  
  227.         /* Set graphics mode and initialize turtle graphics. Put border
  228.          * on window.
  229.          */
  230.         if( iMainCur != CHANGE )
  231.         {
  232.             if( !_setvideomode( iMode ) )
  233.             {
  234.                 _settextposition( 1, 22 );
  235.                 _outtext( "Mode not recognized" );
  236.                 iMode = iLastMode;
  237.                 continue;
  238.             }
  239.             iLastMode = iMode;
  240.  
  241.             _displaycursor( _GCURSOROFF );
  242.             _getvideoconfig( &vc );
  243.             InitTurtle( &vc );
  244.             Rectangle( 2 * tc.xMax, 2 * tc.yMax );
  245.  
  246.             /* After drawing border, reset drawing area inside border. */
  247.             tc.xsLeft++; tc.xsRight--; tc.ysTop++; tc.ysBot--;
  248.             Home();
  249.         }
  250.  
  251.         /* Branch to menu choice. */
  252.         switch( iMainCur )
  253.         {
  254.             case QUIT:
  255.                 _setvideomode( _DEFAULTMODE );
  256.                 return FALSE;
  257.             case CIRCLES:
  258.                 Circles();
  259.                 break;
  260.             case SPHERE:
  261.                 Sphere();
  262.                 break;
  263.             case TUNNEL:
  264.                 PenDown( FALSE );
  265.                 MoveTo( -tc.xMax * .2, tc.yMax * .15 );
  266.                 PenDown( TRUE );
  267.                 Polygons();
  268.                 while( !ClickOrPress() )
  269.                     NextColorValue( DEFAULT );   /* Rotate palette */
  270.                 break;
  271.             case SPIRAL:
  272.                 if( Spiral( getrandom( 30, 80 ), (double)getrandom( 1, 5 ) ) )
  273.                     break;
  274.                 while( !ClickOrPress() )
  275.                     NextColorValue( DEFAULT );
  276.                 break;
  277.             case INSPIRAL:
  278.                 NextColorIndex( 0 );
  279.                 if( InSpiral( (double)getrandom( 8, 20 ),
  280.                               getrandom( 4, 22 ),
  281.                               getrandom( 3, 31 ) ) )
  282.                     break;
  283.                 while( !ClickOrPress() )
  284.                     NextColorValue( DEFAULT );
  285.                 break;
  286.             case BUG:
  287.                 Bug();
  288.                 break;
  289.             case ADJUST:
  290.                 Adjust();
  291.                 continue;
  292.             case CHANGE:
  293.                 _clearscreen( _GCLEARSCREEN );
  294.  
  295.                 iModesCur = Menu( rowMid, colMid, mnuModes, iModesCur );
  296.                 iMode = aModes[iModesCur];
  297.                 break;
  298.         }
  299.     }
  300. }
  301.  
  302. /* Circles - Draw circles of varying sizes and colors on screen in a
  303.  * round pattern.
  304.  *
  305.  * Params: None
  306.  *
  307.  * Return: None
  308.  *
  309.  * Uses:   tc
  310.  */
  311. void Circles()
  312. {
  313.     double x, y, xyRadius;
  314.     int fFill, fPenDown;
  315.  
  316.     /* Initialize and save pen and fill flags. */
  317.     if( tc.cci <= 4 )
  318.         fFill = SetFill( FALSE );
  319.     else
  320.         fFill = SetFill( TRUE );
  321.     fPenDown = PenDown( FALSE );
  322.  
  323.     while( TRUE )
  324.     {
  325.         /* Draw circles. */
  326.         for( xyRadius = 10.0; xyRadius <= 130.0; xyRadius++ )
  327.         {
  328.             x = (tc.xMax - 30) * atan( sin( xyRadius / PI ) );
  329.             y = (tc.yMax - 30) * atan( cos( xyRadius / PI ) );
  330.             MoveTo( x, y );
  331.             PenColor( NextColorIndex( DEFAULT ) );
  332.             Circle( xyRadius );
  333.             if( ClickOrPress() )
  334.             {
  335.                 PenDown( fPenDown );
  336.                 SetFill( fFill );
  337.                 return;
  338.             }
  339.         }
  340.  
  341.         /* For palette modes (except 256 color), start over. */
  342.         if( tc.ccv == 64 || tc.ccv == 16 )
  343.         {
  344.             _clearscreen( _GCLEARSCREEN );
  345.             SetFill( FALSE );
  346.             MoveTo( 0.0, 0.0 );
  347.             PenColor( WHITE );
  348.             Rectangle( 2 * tc.xMax, 2 * tc.yMax );
  349.             SetFill( fFill );
  350.             NextColorValue( DEFAULT );
  351.         }
  352.     }
  353. }
  354.  
  355. /* Sphere - Draw and fill slices of a sphere. Rotate colors in EGA+ modes
  356.  * with more than 4 color indexes.
  357.  *
  358.  * Params: None
  359.  *
  360.  * Return: None
  361.  *
  362.  * Uses:   tc
  363.  */
  364. void Sphere()
  365. {
  366.     double xCur, xSize, ySize, xInc;
  367.     short ciBorder, fFill;
  368.  
  369.     ySize = xSize = tc.yMax * 0.9 * 2;
  370.     fFill = SetFill( FALSE );
  371.     NextColorIndex( 0 );
  372.     xInc = xSize / 14;
  373.     ciBorder = PenColor( DEFAULT );
  374.     BorderColor( ciBorder );
  375.  
  376.     /* Draw slices. */
  377.     for( xCur = xInc; xCur <= xSize; xCur += xInc * 2 )
  378.         Ellipse( xCur, ySize );
  379.     SetFill( TRUE );
  380.     PenDown( FALSE );
  381.     Turn( 90 );
  382.     xSize /= 2;
  383.     MoveTo( xSize - xInc, 0.0 );
  384.  
  385.     NextColorValue( LIMITED );
  386.  
  387.     /* Fill slices. */
  388.     while( tc.xCur >= (-xSize + xInc))
  389.     {
  390.         PenColor( NextColorIndex( DEFAULT ) );
  391.         FillIn();
  392.         Move( -xInc );
  393.     }
  394.  
  395.     while( !ClickOrPress() )
  396.         NextColorValue( LIMITED );
  397.  
  398.     PenDown( TRUE );
  399.     SetFill( fFill );
  400. }
  401.  
  402. /* Polygons - Draws polygons (starting with triangle) of increasing
  403.  * size by incrementing the number of sides without changing the
  404.  * length of sides. Make sure pen is down.
  405.  *
  406.  * Params: None
  407.  *
  408.  * Return: 1 for user interrupt, 0 for edge of screen encountered
  409.  *
  410.  * Uses:   tc
  411.  */
  412. int Polygons()
  413. {
  414.     int cSides = 3, atrib = 1;
  415.     double dxy = tc.yUnit;
  416.  
  417.     while( TRUE )
  418.     {
  419.         PenColor( NextColorIndex( DEFAULT ) );
  420.         if( !Poly( cSides++, dxy += 1.5 ) )
  421.             return FALSE;
  422.         if( ClickOrPress() )
  423.             return TRUE;
  424.     }
  425. }
  426.  
  427. /* Spiral - Draw a spiral by incrementing the length of each side
  428.  * of a rotating figure.
  429.  *
  430.  * Params: ang - determines tightness
  431.  *         xyInc - determines size of sides
  432.  *
  433.  * Return: 1 for user interrupt, 0 for edge of screen encountered
  434.  *
  435.  * Uses:   tc
  436.  */
  437. int Spiral( int ang, double xyInc )
  438. {
  439.     double xy = tc.yUnit;
  440.  
  441.     while( TRUE )
  442.     {
  443.         PenColor( NextColorIndex( DEFAULT ) );
  444.         if( !Move( xy += xyInc ) )
  445.             return FALSE;
  446.         Turn( ang );
  447.         if( ClickOrPress() )
  448.             return TRUE;
  449.     }
  450. }
  451.  
  452. /* InSpiral - Draw an inverted spiral by increasing each angle
  453.  * of a rotating figure while keeping the length of sides constant.
  454.  *
  455.  * Params: xy - determines size
  456.  *         ang - initial angle determines shape
  457.  *         angInc - determines tightness and shape
  458.  *
  459.  * Return: 1 for user interrupt, 0 for edge of screen encountered
  460.  */
  461. int InSpiral( double xy, int ang, int angInc )
  462. {
  463.     while( TRUE )
  464.     {
  465.         PenColor( NextColorIndex( DEFAULT ) );
  466.         if( !Move( xy ) )
  467.             return FALSE;
  468.         Turn( ang += angInc );
  469.         if( ClickOrPress())
  470.             return TRUE;
  471.     }
  472. }
  473.  
  474. /* Bug - Draws a winged bug on the screen. Then moves it randomly
  475.  * around the screen.
  476.  *
  477.  * Params: None
  478.  *
  479.  * Return: None
  480.  *
  481.  * Uses:   tc
  482.  */
  483. void Bug()
  484. {
  485.  
  486.     static unsigned char uTopWing[] = { 0x81, 0x3c, 0xc3, 0x66,
  487.                                         0x66, 0x0f, 0xf0, 0x18 };
  488.     static unsigned char uBotWing[] = { 0x66, 0x0f, 0xf0, 0x18,
  489.                                         0x81, 0x3c, 0xc3, 0x66 };
  490.     char *buffer;               /* Buffer for image */
  491.  
  492.     /* Draw bug. */
  493.     PenDown( FALSE );
  494.     SetFill( TRUE );
  495.     Move( 40.0 );               /* Draw and fill front wings */
  496.     Turn( 90 );
  497.     Move( 80.0 );
  498.     PenColor( 1 );
  499.     _setfillmask( uTopWing );
  500.     Ellipse( 172.0, 70.0 );
  501.     Turn( 180 );
  502.     Move( 160.0 );
  503.     Ellipse( 172.0, 70.0 );
  504.     Turn(-90 );
  505.     MoveTo( 0.0, 0.0 );
  506.     Move( 25.0 );               /* Draw and fill back wings */
  507.     Turn( 90 );
  508.     Move( 70.0 );
  509.     PenColor( 2 );
  510.     _setfillmask( uBotWing );
  511.     Ellipse( 150.0, 70.0 );
  512.     Turn( 180 );
  513.     Move( 140.0 );
  514.     Ellipse( 150.0, 70.0 );
  515.     Turn(-90 );
  516.     MoveTo( 0.0, 0.0 );
  517.     _setfillmask( NULL );       /* Draw body */
  518.     PenColor( 3 );
  519.     BorderColor( 3 );
  520.     Ellipse( 52.0, 220.0 );
  521.     PenColor( 1 );              /* Drill eyes */
  522.     BorderColor( 1 );
  523.     SetFill( FALSE );
  524.     Move( 90.0 );
  525.     Turn( 90 );
  526.     Move( 22.0 );
  527.     Circle( 20.0 );
  528.     PenColor( 0 );
  529.     FillIn();
  530.     PenColor( 1 );
  531.     Turn( 180 );
  532.     Move( 44.0 );
  533.     Circle( 20.0 );
  534.     PenColor( 0 );
  535.     FillIn();
  536.  
  537.     /* Move into position - top-right of image. */
  538.     MoveTo( 0.0, 0.0 );
  539.     TurnTo( 0 );
  540.     Move( 120.0 );
  541.     Turn( -90 );
  542.     Move( 175.0 );
  543.     Turn( 90 );
  544.  
  545.     /* Size image and allocate memory for it. */
  546.     buffer = (char *)malloc( (size_t)ImageSize( 350.0, 240.0 ) );
  547.     GetImage( 350.0, 240.0, buffer );
  548.  
  549.     /* Move randomly, adjusting at edges. */
  550.     while( !ClickOrPress() )
  551.     {
  552.         if( tc.xCur <= (-tc.xMax + 15.0) )
  553.             TurnTo( 90 );
  554.         else if( tc.yCur <= (-tc.yMax + 15.0) )
  555.             TurnTo( 180 );
  556.         else if( tc.xCur >= (tc.xMax - 365.0) )
  557.             TurnTo( 270 );
  558.         else if( tc.yCur >= (tc.yMax - 255.0) )
  559.             TurnTo( 0 );
  560.         else
  561.             Turn( getrandom( -20, 20 ) );
  562.         Move( 3.0 );
  563.         PutImage( buffer, _GPSET );
  564.     }
  565.     free( (char *)buffer );
  566. }
  567.  
  568. /* Adjust - Allow the user to interactively adjust the display window.
  569.  * Unshifted direction keys adjust the window size. Shifted direction
  570.  * keys move the window. The numeric keypad plus and minus keys adjust
  571.  * aspect without changing the window. A window frame and a diamond give
  572.  * visual feedback on adjustments.
  573.  *
  574.  * Params: None
  575.  *
  576.  * Return: None
  577.  *
  578.  * Uses:   tc and vc
  579.  */
  580. #define WININC 4
  581. void Adjust()
  582. {
  583.     short iWriteMode;
  584.     double xyRadius = 400.0, xEdge, yEdge;
  585.     char achT[80];
  586.  
  587.     /* Display instructions. */
  588.     _clearscreen( _GCLEARSCREEN );
  589.     _settextposition( 2, 2 );
  590.     _outtext(" Grey PLUS and MINUS Adjust aspect" );
  591.     _settextposition( 3, 2 );
  592.     _outtext(" Cursor keys         Size window" );
  593.     _settextposition( 4, 2 );
  594.     _outtext(" SHIFT cursor keys   Move window" );
  595.     _settextposition( 5, 2 );
  596.     _outtext(" ENTER               Finished" );
  597.  
  598.     /* Save old write mode and set XOR so you can erase figures by
  599.      * redrawing. This allows lines to overwrite text without erasing.
  600.      */
  601.     iWriteMode = _getwritemode();
  602.     _setwritemode( _GXOR );
  603.  
  604.     while( TRUE )
  605.     {
  606.         /* Display data. */
  607.         _settextposition( 6, 2 );
  608.         sprintf( achT,
  609.                  " Ratio=%1.2f  Left=%.3i  Top=%.3i  Right=%.3i  Bottom=%.3i",
  610.                  tc.yxRatio, tc.xsLeft, tc.ysTop,  tc.xsRight,  tc.ysBot );
  611.         _outtext( achT );
  612.  
  613.         /* Calculate current box edges. */
  614.         xEdge = 2 * tc.xMax;
  615.         yEdge = 2 * tc.yMax;
  616.  
  617.         /* Draw border rectangle and diamond that illustrates ratio. */
  618.         Rectangle( xEdge, yEdge );
  619.         Diamond( xyRadius );
  620.  
  621.         switch( GetKey( CLEAR_WAIT ) )
  622.         {
  623.             /* Adjust aspect. */
  624.             case N_MINUS:
  625.                 if( tc.yxRatio > 0.4 )
  626.                     tc.yxRatio = (tc.xMax - (WININC * tc.yUnit)) / tc.yMax;
  627.                 break;
  628.             case N_PLUS:
  629.                 if( tc.yxRatio < 8.0 )
  630.                     tc.yxRatio = (tc.xMax + (WININC * tc.yUnit)) / tc.yMax;
  631.                 break;
  632.  
  633.             /* Adjust window size. */
  634.             case U_RT:
  635.                 if( tc.xsLeft < (vc.numxpixels / 3) )
  636.                     tc.xsLeft += WININC;
  637.                 if( tc.xsRight > (vc.numxpixels - (vc.numxpixels / 3)) )
  638.                     tc.xsRight -= WININC;
  639.                 break;
  640.             case U_LT:
  641.                 if( tc.xsLeft > WININC )
  642.                     tc.xsLeft -= WININC;
  643.                 if( tc.xsRight < vc.numxpixels )
  644.                     tc.xsRight += WININC;
  645.                 break;
  646.             case U_DN:
  647.                 if( tc.ysTop < (vc.numypixels / 3) )
  648.                     tc.ysTop += WININC;
  649.                 if( tc.ysBot > (vc.numypixels - (vc.numypixels / 3)) )
  650.                     tc.ysBot -= WININC;
  651.                 break;
  652.             case U_UP:
  653.                 if( tc.ysTop > WININC )
  654.                     tc.ysTop -= WININC;
  655.                 if( tc.ysBot < vc.numypixels )
  656.                     tc.ysBot += WININC;
  657.                 break;
  658.  
  659.             /* Adjust window position. */
  660.             case S_LT:
  661.                 if( tc.xsLeft > WININC )
  662.                 {
  663.                     tc.xsLeft -= WININC;
  664.                     tc.xsRight -= WININC;
  665.                 }
  666.                 break;
  667.             case S_RT:
  668.                 if( tc.xsRight < vc.numxpixels )
  669.                 {
  670.                     tc.xsLeft += WININC;
  671.                     tc.xsRight += WININC;
  672.                 }
  673.                 break;
  674.             case S_UP:
  675.                 if( tc.ysTop > WININC )
  676.                 {
  677.                     tc.ysTop -= WININC;
  678.                     tc.ysBot -= WININC;
  679.                 }
  680.                 break;
  681.             case S_DN:
  682.                 if( tc.ysBot < vc.numypixels )
  683.                 {
  684.                     tc.ysTop += WININC;
  685.                     tc.ysBot += WININC;
  686.                 }
  687.                 break;
  688.  
  689.             /* Finished. */
  690.             case ENTER:
  691.                 _setwritemode( iWriteMode );
  692.                 return;
  693.  
  694.             /* Ignore unknown key. */
  695.             default:
  696.                 break;
  697.         }
  698.         /* Redraw figures to erase them. Reset defaults. */
  699.         Rectangle( xEdge, yEdge );
  700.         Diamond( xyRadius );
  701.         Home();
  702.     }
  703. }
  704.  
  705. /* Routine used by Adjust to draw its diamond. */
  706. void Diamond( double xy )
  707. {
  708.         PenDown( FALSE );
  709.         MoveTo( 0.0, xy );
  710.         PenDown( TRUE );
  711.         MoveTo( xy, 0.0 );
  712.         MoveTo( 0.0, -xy );
  713.         MoveTo( -xy, 0.0 );
  714.         MoveTo( 0.0, xy );
  715.         PenDown( FALSE );
  716.         MoveTo( 0.0, 0.0 );
  717.         PenDown( TRUE );
  718. }
  719.