home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 7 Games / 07-Games.zip / CHECKOS2.ZIP / CKRDRAW.C < prev    next >
C/C++ Source or Header  |  1989-10-01  |  23KB  |  703 lines

  1. /*--------------------------------------------------------------------
  2.    CKRDRAW.C source code file for Ckd drawing functions, version 0.10
  3.              (c) 1990, Charles Petzold
  4.   --------------------------------------------------------------------*/
  5.  
  6. #define INCL_WIN
  7. #define INCL_GPI
  8. #include <os2.h>
  9. #include <stdlib.h>
  10. #include "checkers.h"
  11. #include "ckrdraw.h"
  12.  
  13.      /*----------------------------------------
  14.         Defines for board and piece dimensions
  15.        ----------------------------------------*/
  16.  
  17. #define BRD_HORZFRONT        500
  18. #define BRD_HORZBACK         350
  19. #define BRD_VERT             300
  20. #define BRD_EDGE              75
  21. #define BRD_HORZMARGIN       250
  22. #define BRD_FRONTMARGIN      250
  23. #define BRD_BACKMARGIN       250
  24. #define PIECE_XAXIS          (BRD_HORZBACK - 50)
  25. #define PIECE_YAXIS          (BRD_VERT - 50)
  26. #define PIECE_HEIGHT          50
  27.  
  28.      /*-------------------------------------
  29.         Global variables external to module
  30.        -------------------------------------*/
  31.  
  32. extern HAB hab ;
  33.  
  34.      /*-------------------------------------
  35.         Global variables internal to module
  36.        -------------------------------------*/
  37.  
  38.                // Background, board, and piece colors
  39.  
  40. static LONG clrBackground  = CLR_CYAN ;
  41. static LONG clrBlackSquare = CLR_DARKGREEN ;
  42. static LONG clrWhiteSquare = CLR_PALEGRAY ;
  43. static LONG clrBlackPiece  = CLR_RED ;
  44. static LONG clrWhitePiece  = CLR_WHITE ;
  45.  
  46.                // Text strings for saving colors to OS2.INI
  47.  
  48. static CHAR szApplication []    = "Checkers" ;
  49. static CHAR szClrBackground []  = "Background Color" ;
  50. static CHAR szClrBlackSquare [] = "Black Square Color" ;
  51. static CHAR szClrWhiteSquare [] = "White Square Color" ;
  52. static CHAR szClrBlackPiece []  = "Black Piece Color" ;
  53. static CHAR szClrWhitePiece []  = "White Piece Color" ;
  54.  
  55.                // Original viewport for adjusting board to window size
  56.  
  57. static RECTL rclOrigViewport ;
  58.  
  59.                // Bitmaps for drawing pieces
  60.  
  61. static HDC     hdcMemory ;
  62. static HPS     hpsMemory ;
  63. static HBITMAP ahbmPiece[2][2], ahbmMask[2] ;
  64. static SIZEL   sizlPiece[2] ;
  65.  
  66.      /*-------------------------------------------------------------
  67.         CkdQueryBoardDimensions: Obtains size of board with margins
  68.        -------------------------------------------------------------*/
  69.  
  70. static VOID CkdQueryBoardDimensions (SIZEL *psizlPage)
  71.      {
  72.      psizlPage->cx = 8 * BRD_HORZFRONT + 2 * BRD_HORZMARGIN ;
  73.      psizlPage->cy = 8 * BRD_VERT + BRD_FRONTMARGIN + BRD_BACKMARGIN ;
  74.      }
  75.  
  76.      /*-----------------------------------------------------------
  77.         CkdQuerySquareOrigin: Obtains lower left corner of square
  78.        -----------------------------------------------------------*/
  79.  
  80. static VOID CkdQuerySquareOrigin (SHORT x, SHORT y, POINTL *pptl)
  81.      {
  82.      pptl->x = BRD_HORZMARGIN + y * (BRD_HORZFRONT - BRD_HORZBACK) / 2 +
  83.                     x * (y * BRD_HORZBACK + (8 - y) * BRD_HORZFRONT) / 8 ;
  84.  
  85.      pptl->y = BRD_FRONTMARGIN + y * BRD_VERT ;
  86.      }
  87.  
  88.      /*-----------------------------------------------------
  89.         CkdQuerySquareCoords: Obtains coordinates of square
  90.        -----------------------------------------------------*/
  91.  
  92. static VOID CkdQuerySquareCoords (SHORT x, SHORT y, POINTL aptl[])
  93.      {
  94.      CkdQuerySquareOrigin (x,     y,     aptl + 0) ;
  95.      CkdQuerySquareOrigin (x + 1, y,     aptl + 1) ;
  96.      CkdQuerySquareOrigin (x + 1, y + 1, aptl + 2) ;
  97.      CkdQuerySquareOrigin (x,     y + 1, aptl + 3) ;
  98.      }
  99.  
  100.      /*-----------------------------------------------
  101.         CkdDrawBoardSquare: Draws one square of board
  102.        -----------------------------------------------*/
  103.  
  104. static LONG CkdDrawBoardSquare (HPS hps, SHORT x, SHORT y)
  105.      {
  106.      AREABUNDLE abnd ;
  107.      LINEBUNDLE lbnd ;
  108.      LONG       lReturn ;
  109.      POINTL     aptl[4] ;
  110.  
  111.      GpiSavePS (hps) ;
  112.  
  113.      lbnd.lColor = CLR_BLACK ;
  114.      GpiSetAttrs (hps, PRIM_LINE, LBB_COLOR, 0L, &lbnd) ;
  115.  
  116.      abnd.lColor = (x + y) & 1 ? clrWhiteSquare : clrBlackSquare ;
  117.      GpiSetAttrs (hps, PRIM_AREA, LBB_COLOR, 0L, &abnd) ;
  118.  
  119.      GpiBeginArea (hps, BA_ALTERNATE | BA_BOUNDARY) ;
  120.  
  121.      CkdQuerySquareCoords (x, y, aptl) ;
  122.      GpiMove (hps, aptl + 3) ;
  123.      GpiPolyLine (hps, 4L, aptl) ;
  124.      lReturn = GpiEndArea (hps) ;
  125.  
  126.      GpiRestorePS (hps, -1L) ;
  127.  
  128.      return lReturn ;
  129.      }
  130.  
  131.      /*----------------------------------------------------
  132.         CkdDrawAllBoardSquares: Draws all squares of board
  133.        ----------------------------------------------------*/
  134.  
  135. static LONG CkdDrawAllBoardSquares (HPS hps)
  136.      {
  137.      SHORT x, y ;
  138.  
  139.      for (y = 0 ; y < 8 ; y++)
  140.           for (x = 0 ; x < 8 ; x++)
  141.                if (CkdDrawBoardSquare (hps, x, y) == GPI_HITS)
  142.                     return MAKELONG (x, y) ;
  143.  
  144.      return MAKELONG (-1, -1) ;
  145.      }
  146.  
  147.      /*----------------------------------------------------
  148.         CkdRenderPiece: Draws piece on bitmap in memory PS
  149.        ----------------------------------------------------*/
  150.  
  151. static VOID CkdRenderPiece (HPS hpsMemory, LONG lColorBack, LONG lColor,
  152.                             LONG lColorLine, SHORT sKing)
  153.      {
  154.      ARCPARAMS  arcp ;
  155.      AREABUNDLE abnd ;
  156.      LINEBUNDLE lbnd ;
  157.      POINTL     ptl, aptlArc[2] ;
  158.      SHORT      s ;
  159.  
  160.      GpiSavePS (hpsMemory) ;
  161.  
  162.                // Draw background of bitmap
  163.  
  164.      GpiSetColor (hpsMemory, lColorBack) ;
  165.  
  166.      ptl.x = 0 ;
  167.      ptl.y = 0 ;
  168.      GpiMove (hpsMemory, &ptl) ;
  169.  
  170.      ptl.x = PIECE_XAXIS ;
  171.      ptl.y = PIECE_YAXIS + (sKing + 1) * PIECE_HEIGHT ;
  172.      GpiBox (hpsMemory, DRO_FILL, &ptl, 0L, 0L) ;
  173.  
  174.                // Set colors for areas and outlines
  175.  
  176.      abnd.lColor = lColor ;
  177.      GpiSetAttrs (hpsMemory, PRIM_AREA, ABB_COLOR, 0L, &abnd) ;
  178.  
  179.      lbnd.lColor = lColorLine ;
  180.      GpiSetAttrs (hpsMemory, PRIM_LINE, LBB_COLOR, 0L, &lbnd) ;
  181.  
  182.                // Set arc parameters
  183.  
  184.      arcp.lP = PIECE_XAXIS / 2 ;
  185.      arcp.lQ = PIECE_YAXIS / 2 ;
  186.      arcp.lR = 0 ;
  187.      arcp.lS = 0 ;
  188.      GpiSetArcParams (hpsMemory, &arcp) ;
  189.  
  190.                // draw the piece
  191.  
  192.      for (s = 0 ; s <= sKing ; s++)
  193.           {
  194.           GpiBeginArea (hpsMemory, BA_ALTERNATE | BA_BOUNDARY) ;
  195.  
  196.           ptl.x = 0 ;
  197.           ptl.y = PIECE_YAXIS / 2 + (s + 1) * PIECE_HEIGHT ;
  198.           GpiMove (hpsMemory, &ptl) ;
  199.  
  200.           ptl.y -= PIECE_HEIGHT ;
  201.           GpiLine (hpsMemory, &ptl) ;
  202.  
  203.           aptlArc[0].x = PIECE_XAXIS / 2 ;
  204.           aptlArc[0].y = s * PIECE_HEIGHT ;
  205.           aptlArc[1].x = PIECE_XAXIS ;
  206.           aptlArc[1].y = PIECE_YAXIS / 2 + s * PIECE_HEIGHT ;
  207.  
  208.           GpiPointArc (hpsMemory, aptlArc) ;
  209.  
  210.           ptl.x = PIECE_XAXIS ;
  211.           ptl.y = PIECE_YAXIS / 2 + (s + 1) * PIECE_HEIGHT ;
  212.           GpiLine (hpsMemory, &ptl) ;
  213.  
  214.           GpiEndArea (hpsMemory) ;
  215.           }
  216.  
  217.      ptl.x = PIECE_XAXIS / 2 ;
  218.      ptl.y = PIECE_YAXIS / 2 + (sKing ? 2 : 1) * PIECE_HEIGHT ;
  219.  
  220.      GpiMove (hpsMemory, &ptl) ;
  221.      GpiFullArc (hpsMemory, DRO_OUTLINEFILL, MAKEFIXED (1,0)) ;
  222.  
  223.      GpiRestorePS (hpsMemory, -1L) ;
  224.      }
  225.  
  226.      /*------------------------------------------------------
  227.         CkdQuerySquareCenter: Obtains center of board square
  228.        ------------------------------------------------------*/
  229.  
  230. static VOID CkdQuerySquareCenter (SHORT x, SHORT y, POINTL *pptlCenter)
  231.      {
  232.      POINTL aptl[4] ;
  233.  
  234.      CkdQuerySquareCoords (x, y, aptl) ;
  235.  
  236.      pptlCenter->x = (aptl[0].x + aptl[1].x + aptl[2].x + aptl[3].x) / 4 ;
  237.      pptlCenter->y = (aptl[1].y + aptl[2].y) / 2 ;
  238.      }
  239.  
  240.      /*---------------------------------------------------------------------
  241.         CkdPieceOriginFromCenter: Converts center of square to piece origin
  242.        ---------------------------------------------------------------------*/
  243.  
  244. static VOID CkdPieceOriginFromCenter (POINTL *pptl)
  245.      {
  246.      pptl->x -= PIECE_XAXIS / 2 ;
  247.      pptl->y -= PIECE_YAXIS / 2 ;
  248.      }
  249.  
  250.      /*----------------------------------------------------------------
  251.         CkdQuerySquarePieceOrigin: Obtains origin of piece on a square
  252.        ----------------------------------------------------------------*/
  253.  
  254. static VOID CkdQuerySquarePieceOrigin (SHORT x, SHORT y, POINTL *pptlOrigin)
  255.      {
  256.      CkdQuerySquareCenter (x, y, pptlOrigin) ;
  257.      CkdPieceOriginFromCenter (pptlOrigin) ;
  258.      }
  259.  
  260.      /*-----------------------------------------------------------------------
  261.         CkdConvertCoordsToIndex: Obtains index (0-31) from square coordinates
  262.        -----------------------------------------------------------------------*/
  263.  
  264. static SHORT CkdConvertCoordsToIndex (SHORT x, SHORT y, SHORT sBottom)
  265.      {
  266.      if (x < 0 || x > 7 || y < 0 || y > 7)
  267.           return -1 ;
  268.  
  269.      if ((x - (y & 1)) & 1)
  270.           return -1 ;
  271.  
  272.      if (sBottom == WHITE)
  273.           {
  274.           x = 7 - x ;
  275.           y = 7 - y ;
  276.           }
  277.  
  278.      return 3 ^ (4 * y + (x - (y & 1)) / 2) ;
  279.      }
  280.  
  281.      /*-------------------------------------------------------------
  282.         CkdShowPiece: Draws a piece on the screen at specific point
  283.        -------------------------------------------------------------*/
  284.  
  285. static VOID CkdShowPiece (HPS hps, POINTL *pptlOrg, SHORT sColor, SHORT sKing)
  286.      {
  287.      POINTL aptl[3] ;
  288.  
  289.                // Write out mask with bitwise AND
  290.  
  291.      aptl[0]   = *pptlOrg ;
  292.      aptl[1].x = pptlOrg->x + sizlPiece[sKing].cx ;
  293.      aptl[1].y = pptlOrg->y + sizlPiece[sKing].cy ;
  294.      aptl[2].x = 0 ;
  295.      aptl[2].y = 0 ;
  296.  
  297.      GpiSetBitmap (hpsMemory, ahbmMask[sKing]) ;
  298.      GpiBitBlt    (hps, hpsMemory, 3L, aptl, ROP_SRCAND, BBO_IGNORE) ;
  299.  
  300.                // Write out piece with bitwise OR
  301.  
  302.      aptl[0]   = *pptlOrg ;
  303.      aptl[1].x = pptlOrg->x + sizlPiece[sKing].cx ;
  304.      aptl[1].y = pptlOrg->y + sizlPiece[sKing].cy ;
  305.      aptl[2].x = 0 ;
  306.      aptl[2].y = 0 ;
  307.  
  308.      GpiSetBitmap (hpsMemory, ahbmPiece[sColor][sKing]) ;
  309.      GpiBitBlt    (hps, hpsMemory, 3L, aptl, ROP_SRCPAINT, BBO_IGNORE) ;
  310.  
  311.      GpiSetBitmap (hpsMemory, NULL) ;
  312.      }
  313.  
  314.      /*---------------------------------------------------------------------
  315.         CkdDrawOnePiece: Draws a piece on the board at specific coordinates
  316.        ---------------------------------------------------------------------*/
  317.  
  318. static VOID CkdDrawOnePiece (HPS hps, SHORT x, SHORT y,
  319.                              BOARD *pbrd, SHORT sBottom)
  320.      {
  321.      POINTL ptlOrigin ;
  322.      SHORT  i, sKing ;
  323.  
  324.      i = CkdConvertCoordsToIndex (x, y, sBottom) ;
  325.  
  326.      if (i == -1)
  327.           return ;
  328.  
  329.      CkdQuerySquarePieceOrigin (x, y, &ptlOrigin) ;
  330.      GpiConvert (hps, CVTC_PAGE, CVTC_DEVICE, 1L, &ptlOrigin) ;
  331.  
  332.      sKing = pbrd->ulKing & 1L << i ? 1 : 0 ;
  333.  
  334.      if (pbrd->ulBlack & 1L << i)
  335.           CkdShowPiece (hps, &ptlOrigin, BLACK, sKing) ;
  336.  
  337.      if (pbrd->ulWhite & 1L << i)
  338.           CkdShowPiece (hps, &ptlOrigin, WHITE, sKing) ;
  339.      }
  340.  
  341.      /*----------------------------------------------------
  342.         ColorDlgProc: Dialog procedure for changing colors
  343.        ----------------------------------------------------*/
  344.  
  345. MRESULT EXPENTRY ColorDlgProc (HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
  346.      {
  347.      static LONG  *pclr ;
  348.      static SHORT sColor ;
  349.      CHAR         *pchHeading ;
  350.  
  351.      switch (msg)
  352.           {
  353.           case WM_INITDLG:
  354.                switch (* (PSHORT) PVOIDFROMMP (mp2))
  355.                     {
  356.                     case IDM_COLOR_BACKGROUND:
  357.                          pchHeading = "Window Background Color" ;
  358.                          pclr = &clrBackground ;
  359.                          break ;
  360.  
  361.                     case IDM_COLOR_BLACK_SQUARE:
  362.                          pchHeading = "Black Square Color" ;
  363.                          pclr = &clrBlackSquare ;
  364.                          break ;
  365.  
  366.                     case IDM_COLOR_WHITE_SQUARE:
  367.                          pchHeading = "White Square Color" ;
  368.                          pclr = &clrWhiteSquare ;
  369.                          break ;
  370.  
  371.                     case IDM_COLOR_BLACK_PIECE:
  372.                          pchHeading = "Black Piece Color" ;
  373.                          pclr = &clrBlackPiece ;
  374.                          break ;
  375.  
  376.                     case IDM_COLOR_WHITE_PIECE:
  377.                          pchHeading = "White Piece Color" ;
  378.                          pclr = &clrWhitePiece ;
  379.                          break ;
  380.                     }
  381.                WinSetDlgItemText (hwnd, IDD_HEADING, pchHeading) ;
  382.  
  383.                sColor = (SHORT) *pclr ;
  384.  
  385.                WinSendDlgItemMsg (hwnd, IDD_COLOR + sColor, BM_SETCHECK,
  386.                                   MPFROM2SHORT (TRUE, 0), NULL) ;
  387.  
  388.                WinSetFocus (HWND_DESKTOP,
  389.                             WinWindowFromID (hwnd, IDD_COLOR + sColor)) ;
  390.                return 1 ;
  391.  
  392.           case WM_CONTROL:
  393.                WinSendDlgItemMsg (hwnd, IDD_COLOR + sColor, BM_SETCHECK,
  394.                                   MPFROM2SHORT (FALSE, 0), NULL) ;
  395.  
  396.                sColor = SHORT1FROMMP (mp1) - IDD_COLOR ;
  397.  
  398.                WinSendDlgItemMsg (hwnd, IDD_COLOR + sColor, BM_SETCHECK,
  399.                                   MPFROM2SHORT (TRUE, 0), NULL) ;
  400.                return 0 ;
  401.  
  402.           case WM_COMMAND:
  403.                switch (COMMANDMSG(&msg)->cmd)
  404.                     {
  405.                     case DID_OK:
  406.                          *pclr = (LONG) sColor ;
  407.                          WinDismissDlg (hwnd, TRUE) ;
  408.                          return 0 ;
  409.  
  410.                     case DID_CANCEL:
  411.                          WinDismissDlg (hwnd, FALSE) ;
  412.                          return 0 ;
  413.                     }
  414.                break ;
  415.           }
  416.      return WinDefDlgProc (hwnd, msg, mp1, mp2) ;
  417.      }
  418.  
  419.      /*-------------------------------------------------
  420.         CkdCreatePS: Create PS for checker board window
  421.        -------------------------------------------------*/
  422.  
  423. HPS CkdCreatePS (HWND hwnd)
  424.      {
  425.      HDC    hdc ;
  426.      HPS    hps ;
  427.      SIZEL  sizlPage ;
  428.      USHORT sDataSize ;
  429.  
  430.      CkdQueryBoardDimensions (&sizlPage) ;
  431.  
  432.      hdc = WinOpenWindowDC (hwnd) ;
  433.      hps = GpiCreatePS (hab, hdc, &sizlPage,
  434.                         PU_ARBITRARY | GPIF_DEFAULT |
  435.                         GPIT_MICRO   | GPIA_ASSOC) ;
  436.  
  437.      GpiQueryPageViewport (hps, &rclOrigViewport) ;
  438.  
  439.                // Get colors from OS2.INI
  440.  
  441.      sDataSize = sizeof (LONG) ;
  442.      WinQueryProfileData (hab, szApplication, szClrBackground,
  443.                           &clrBackground, &sDataSize) ;
  444.  
  445.      sDataSize = sizeof (LONG) ;
  446.      WinQueryProfileData (hab, szApplication, szClrBlackSquare,
  447.                           &clrBlackSquare, &sDataSize) ;
  448.  
  449.      sDataSize = sizeof (LONG) ;
  450.      WinQueryProfileData (hab, szApplication, szClrWhiteSquare,
  451.                           &clrWhiteSquare, &sDataSize) ;
  452.  
  453.      sDataSize = sizeof (LONG) ;
  454.      WinQueryProfileData (hab, szApplication, szClrBlackPiece,
  455.                           &clrBlackPiece, &sDataSize) ;
  456.  
  457.      sDataSize = sizeof (LONG) ;
  458.      WinQueryProfileData (hab, szApplication, szClrWhitePiece,
  459.                           &clrWhitePiece, &sDataSize) ;
  460.      return hps ;
  461.      }
  462.  
  463.      /*-------------------------------------------------------
  464.         CkdResizePS: Change page viewport for new window size
  465.        -------------------------------------------------------*/
  466.  
  467. VOID CkdResizePS (HPS hps, HWND hwnd)
  468.      {
  469.      LONG  lScale ;
  470.      RECTL rclWindow, rclViewport ;
  471.  
  472.      WinQueryWindowRect (hwnd, &rclWindow) ;
  473.  
  474.                // Calculate scaling factor
  475.  
  476.      lScale = min (65536L * rclWindow.xRight / rclOrigViewport.xRight,
  477.                    65536L * rclWindow.yTop   / rclOrigViewport.yTop) ;
  478.  
  479.                // Adjust page viewport of memory PS
  480.  
  481.      rclViewport.xLeft   = 0 ;
  482.      rclViewport.yBottom = 0 ;
  483.      rclViewport.xRight  = lScale * rclOrigViewport.xRight / 65536L ;
  484.      rclViewport.yTop    = lScale * rclOrigViewport.yTop   / 65536L ;
  485.  
  486.      rclViewport.xLeft   = (rclWindow.xRight - rclViewport.xRight) / 2 ;
  487.      rclViewport.yBottom = (rclWindow.yTop   - rclViewport.yTop)   / 2 ;
  488.      rclViewport.xRight += rclViewport.xLeft ;
  489.      rclViewport.yTop   += rclViewport.yBottom ;
  490.  
  491.      GpiSetPageViewport (hps, &rclViewport) ;
  492.      }
  493.  
  494.      /*---------------------------------------------------
  495.         CkdDestroyPS: Destroy PS for checker board window
  496.        ---------------------------------------------------*/
  497.  
  498. BOOL CkdDestroyPS (HPS hps)
  499.      {
  500.                // Save colors in OS2.INI
  501.  
  502.      WinWriteProfileData (hab, szApplication, szClrBackground,
  503.                           &clrBackground, sizeof (LONG)) ;
  504.  
  505.      WinWriteProfileData (hab, szApplication, szClrBlackSquare,
  506.                           &clrBlackSquare, sizeof (LONG)) ;
  507.  
  508.      WinWriteProfileData (hab, szApplication, szClrWhiteSquare,
  509.                           &clrWhiteSquare, sizeof (LONG)) ;
  510.  
  511.      WinWriteProfileData (hab, szApplication, szClrBlackPiece,
  512.                           &clrBlackPiece, sizeof (LONG)) ;
  513.  
  514.      WinWriteProfileData (hab, szApplication, szClrWhitePiece,
  515.                           &clrWhitePiece, sizeof (LONG)) ;
  516.  
  517.      return GpiDestroyPS (hps) ;
  518.      }
  519.  
  520.      /*-----------------------------------------------------------
  521.         CkdSetStandardColors: Sets colors to tournament standards
  522.        -----------------------------------------------------------*/
  523.  
  524. VOID CkdSetStandardColors (VOID)
  525.      {
  526.      clrBackground  = CLR_CYAN ;
  527.      clrBlackSquare = CLR_DARKGREEN ;
  528.      clrWhiteSquare = CLR_PALEGRAY ;
  529.      clrBlackPiece  = CLR_RED ;
  530.      clrWhitePiece  = CLR_WHITE ;
  531.      }
  532.  
  533.      /*------------------------------------------------------------
  534.         CkdCreatePieces: Creates bitmaps to use for drawing pieces
  535.        ------------------------------------------------------------*/
  536.  
  537. VOID CkdCreatePieces (HPS hps)
  538.      {
  539.      BITMAPINFOHEADER bmp ;
  540.      LONG             alBitmapFormat[2] ;
  541.      RECTL            rclViewport ;
  542.      SHORT            sColor, sKing ;
  543.      SIZEL            sizlPage ;
  544.  
  545.                // Create memory DC's and PS's
  546.  
  547.      CkdQueryBoardDimensions (&sizlPage) ;
  548.  
  549.      hdcMemory = DevOpenDC (hab, OD_MEMORY, "*", 0L, NULL, NULL) ;
  550.      hpsMemory = GpiCreatePS (hab, hdcMemory, &sizlPage,
  551.                               PU_ARBITRARY | GPIF_DEFAULT |
  552.                               GPIT_MICRO   | GPIA_ASSOC) ;
  553.  
  554.                // Set page viewport for hpsMemory
  555.  
  556.      GpiQueryPageViewport (hps, &rclViewport) ;
  557.  
  558.      rclViewport.xRight -= rclViewport.xLeft ;
  559.      rclViewport.yTop   -= rclViewport.yBottom ;
  560.      rclViewport.xLeft   = 0 ;
  561.      rclViewport.yBottom = 0 ;
  562.  
  563.      GpiSetPageViewport (hpsMemory, &rclViewport) ;
  564.  
  565.                // Get bitmap format of video display
  566.  
  567.      GpiQueryDeviceBitmapFormats (hps, 2L, alBitmapFormat) ;
  568.  
  569.                // Loop through possible color and size combinations
  570.  
  571.      for (sKing = 0 ; sKing < 2 ; sKing++)
  572.           {
  573.                     // Determine pixel dimensions of bitmaps
  574.  
  575.           sizlPiece[sKing].cx = PIECE_XAXIS ;
  576.           sizlPiece[sKing].cy = PIECE_YAXIS + (sKing + 1) * PIECE_HEIGHT ;
  577.  
  578.           GpiConvert (hpsMemory, CVTC_PAGE, CVTC_DEVICE, 1L,
  579.                       (PPOINTL) &sizlPiece[sKing]) ;
  580.  
  581.           sizlPiece[sKing].cx ++ ;
  582.           sizlPiece[sKing].cy ++ ;
  583.  
  584.                     // Set up BITMAPINFOHEADER structure
  585.  
  586.           bmp.cbFix     = sizeof bmp ;
  587.           bmp.cx        = (SHORT) sizlPiece[sKing].cx ;
  588.           bmp.cy        = (SHORT) sizlPiece[sKing].cy ;
  589.           bmp.cPlanes   = (SHORT) alBitmapFormat[0] ;
  590.           bmp.cBitCount = (SHORT) alBitmapFormat[1] ;
  591.  
  592.                     // Create ahbmPiece bitmaps
  593.  
  594.           for (sColor = BLACK ; sColor <= WHITE ; sColor++)
  595.                {
  596.                ahbmPiece[sColor][sKing] =
  597.                          GpiCreateBitmap (hps, &bmp, 0L, 0L, NULL) ;
  598.  
  599.                GpiSetBitmap (hpsMemory, ahbmPiece[sColor][sKing]) ;
  600.                CkdRenderPiece (hpsMemory, CLR_FALSE,
  601.                                sColor ? clrWhitePiece : clrBlackPiece,
  602.                                CLR_BLACK, sKing) ;
  603.                }
  604.  
  605.                     // Create ahbmMask bitmaps
  606.  
  607.           ahbmMask[sKing] = GpiCreateBitmap (hps, &bmp, 0L, 0L, NULL) ;
  608.           GpiSetBitmap (hpsMemory, ahbmMask[sKing]) ;
  609.           CkdRenderPiece (hpsMemory, CLR_TRUE, CLR_FALSE, CLR_FALSE, sKing) ;
  610.           }
  611.  
  612.      GpiSetBitmap (hpsMemory, NULL) ;
  613.      }
  614.  
  615.      /*---------------------------------------------------
  616.         CkdDestroyPieces: Destroy bitmaps used for pieces
  617.        ---------------------------------------------------*/
  618.  
  619. VOID CkdDestroyPieces (VOID)
  620.      {
  621.      SHORT sColor, sKing ;
  622.  
  623.      for (sKing = 0 ; sKing < 2 ; sKing++)
  624.           {
  625.           for (sColor = BLACK ; sColor <= WHITE ; sColor++)
  626.                if (ahbmPiece[sColor][sKing] != NULL)
  627.                     GpiDeleteBitmap (ahbmPiece[sColor][sKing]) ;
  628.  
  629.           if (ahbmMask[sKing] != NULL)
  630.                GpiDeleteBitmap (ahbmMask[sKing]) ;
  631.           }
  632.  
  633.      GpiDestroyPS (hpsMemory) ;
  634.      DevCloseDC (hdcMemory) ;
  635.      }
  636.  
  637.      /*--------------------------------------------------------------------
  638.         CkdDrawWindowBackground: Fills entire window with background color
  639.        --------------------------------------------------------------------*/
  640.  
  641. VOID CkdDrawWindowBackground (HPS hps, HWND hwnd)
  642.      {
  643.      RECTL rcl ;
  644.  
  645.      WinQueryWindowRect (hwnd, &rcl) ;
  646.      WinFillRect (hps, &rcl, clrBackground) ;
  647.      }
  648.  
  649.      /*-----------------------------------------------------------
  650.         CkdDrawWholeBoard: Draws the board squares and front edge
  651.        -----------------------------------------------------------*/
  652.  
  653. VOID CkdDrawWholeBoard (HPS hps)
  654.      {
  655.      AREABUNDLE abnd ;
  656.      LINEBUNDLE lbnd ;
  657.      SHORT      x ;
  658.      POINTL     aptl[4] ;
  659.  
  660.      CkdDrawAllBoardSquares (hps) ;
  661.  
  662.      GpiSavePS (hps) ;
  663.  
  664.      lbnd.lColor = CLR_BLACK ;
  665.      GpiSetAttrs (hps, PRIM_LINE, LBB_COLOR, 0L, &lbnd) ;
  666.  
  667.      for (x = 0 ; x < 8 ; x++)
  668.           {
  669.           CkdQuerySquareCoords (x, 0, aptl) ;
  670.  
  671.           aptl[2].x = aptl[1].x ;
  672.           aptl[2].y = aptl[1].y - BRD_EDGE ;
  673.  
  674.           aptl[3].x = aptl[0].x ;
  675.           aptl[3].y = aptl[0].y - BRD_EDGE ;
  676.  
  677.           abnd.lColor = x & 1 ? clrWhiteSquare : clrBlackSquare ;
  678.           GpiSetAttrs (hps, PRIM_AREA, LBB_COLOR, 0L, &abnd) ;
  679.  
  680.           GpiBeginArea (hps, BA_ALTERNATE | BA_BOUNDARY) ;
  681.  
  682.           GpiMove (hps, aptl + 3) ;
  683.           GpiPolyLine (hps, 4L, aptl) ;
  684.  
  685.           GpiEndArea (hps) ;
  686.           }
  687.  
  688.      GpiRestorePS (hps, -1L) ;
  689.      }
  690.  
  691.      /*-----------------------------------------------------
  692.         CkdDrawAllPieces: Draws all the pieces on the board
  693.        -----------------------------------------------------*/
  694.  
  695. VOID CkdDrawAllPieces (HPS hps, BOARD *pbrd, SHORT sBottom)
  696.      {
  697.      SHORT x, y ;
  698.  
  699.      for (y = 0 ; y < 8 ; y++)
  700.           for (x = 0 ; x < 8 ; x++)
  701.                CkdDrawOnePiece (hps, x, y, pbrd, sBottom) ;
  702.      }
  703.