home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Professional / OS2PRO194.ISO / os2 / wps / games / gnuchess / sources / pmchess.c < prev    next >
C/C++ Source or Header  |  1990-12-01  |  22KB  |  789 lines

  1. //
  2. //  Copyright (C) 1986, 1987, 1988, 1989, 1990 Free Software Foundation, Inc.
  3. //  Copyright (c) 1988, 1989, 1990  John Stanback
  4. //
  5. //  Project:    OS/2 PM Port of GNU CHESS 3.1 (PmChess)
  6. //
  7. //  Version:    1990-11-17
  8. //
  9. //   Module:    Main Module (PmChess.c)
  10. //
  11. //   Porter:    Ported to Windows 3.0 by Darly Baker
  12. //
  13. //   Porter:    Ported to OS/2 1.2+ by Kent Cedola
  14. //
  15. //   System:    OS2 1.2 using Microsoft C 6.0
  16. //
  17. //  Remarks:    For the most part the port to OS/2 PM was a hard port with
  18. //              very little cleaning up of the old code.  Sections with the
  19. //              double slash '//' is my doing.
  20. //
  21. //  License:
  22. //
  23. //    CHESS is distributed in the hope that it will be useful, but WITHOUT ANY
  24. //    WARRANTY.  No author or distributor accepts responsibility to anyone for
  25. //    the consequences of using it or for whether it serves any particular
  26. //    purpose or works at all, unless he says so in writing.  Refer to the
  27. //    CHESS General Public License for full details.
  28. //
  29. //    Everyone is granted permission to copy, modify and redistribute CHESS,
  30. //    but only under the conditions described in the CHESS General Public
  31. //    License.  A copy of this license is supposed to have been given to you
  32. //    along with CHESS so you can know your rights and responsibilities.  It
  33. //    should be in a file named COPYING.  Among other things, the copyright
  34. //    notice and this notice must be preserved on all copies.
  35. //
  36.  
  37. #define INCL_DOS
  38. #define INCL_GPI
  39. #define INCL_WIN
  40. #include <os2.h>
  41. #include <string.h>
  42. #include <time.h>
  43. #include "PmChess.h"
  44. #include "GnuChess.h"
  45. #include "Defs.h"
  46. #include "Resource.h"
  47.  
  48.  
  49. //
  50. //  Define global variables.
  51. //
  52.   HAB  hab;                             // Primary thread anchor block.
  53.   HMQ  hmq;                             // Message queue handle.
  54.  
  55.   HWND hwndFrame;                       // Frame window handle.
  56.   HWND hwndClient;                      // Client window handle.
  57.   HPS  hpsClient;
  58.   HWND hwndMenu;                        // Menu window handle.
  59.  
  60.   short cyClient;                       // Height of client area.
  61.  
  62.   char szAppName[] = "PmChess";         // Application name.
  63.  
  64.   short boarddraw[64];       /* Display copies of the board */
  65.   short colordraw[64];       /* Needed because while computer is calculating*/
  66.                              /* moves it updates board and color thus you can*/
  67.                              /* not repaint the screen accuratly */
  68.  
  69.   ULONG clrBackGround;       /* color index for various colors */
  70.   ULONG clrBlackSquare;
  71.   ULONG clrWhiteSquare;
  72.   ULONG clrBlackPiece;
  73.   ULONG clrWhitePiece;
  74.   ULONG clrText;
  75.  
  76.   short xchar, ychar;
  77.   short coords = 1;
  78.  
  79. //
  80. //  Define local variables.
  81. //
  82.   static BOOL FirstSq   = -1;           // Flag is a square is selected
  83.   static int GotFirst   = FALSE;
  84.   static int EditActive = FALSE;        /* Edit mode? */
  85.   static int User_Move  = TRUE;         /* User or computer's turn */
  86.   static char szClass[] = "PmChess";    // Class name of main window procedure.
  87.   static HPS  hpsPieces;                // Memory PS of all chess pieces.
  88.  
  89.  
  90. //
  91. //  Define prototypes of local routines.
  92. //
  93. void    cdecl    main(short argc, char **argv);
  94. MRESULT EXPENTRY ChessProc(HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2);
  95. static  void     WndCreate(HWND hWnd);
  96. static  void     WndPaint(HWND hWnd);
  97. static  void     WndButton(HWND hWnd, USHORT msg, MPARAM mp1);
  98. static  void     WndDestroy(void);
  99. MRESULT EXPENTRY AboutProc(HWND hDlg, USHORT msg, MPARAM mp1, MPARAM mp2);
  100.  
  101.  
  102. //***************************************************************************
  103. //
  104. //  Routine: main(In, In)
  105. //
  106. //  Remarks: This routine is then entry-point called by the OS/2 executive.
  107. //
  108. //  Returns: None.
  109. //
  110. void cdecl main(short argc, char **argv)
  111.   {
  112.   QMSG   qmsg;
  113.   ULONG  ctlData;
  114.   POINTL ptl;
  115.  
  116.  
  117.   //
  118.   //  Allocate an anchor block and message queue to use PM services.
  119.   //
  120.   hab = WinInitialize(0);
  121.   hmq = WinCreateMsgQueue(hab, 0);
  122.  
  123.   //
  124.   //  Register the main window procedure.
  125.   //
  126.   if (!WinRegisterClass(NULL, szClass, ChessProc, CS_SIZEREDRAW, 0))
  127.     {
  128.     //
  129.     //  This should never happen...
  130.     //
  131.     WinMessageBox(HWND_DESKTOP, NULL, "Register Class Failure", szAppName, 0,
  132.                   MB_OK);
  133.     goto Error;
  134.     }
  135.  
  136.   //
  137.   //  Compute the idea client height.
  138.   //
  139.   QueryBoardSize(&ptl);
  140.   cyClient = (SHORT)(ptl.y + WinQuerySysValue(HWND_DESKTOP, SV_CYSIZEBORDER)
  141.              * 2L+ WinQuerySysValue(HWND_DESKTOP, SV_CYMENU)+
  142.              WinQuerySysValue(HWND_DESKTOP, SV_CYTITLEBAR) +
  143.              (LONG)ychar * 2L);
  144.  
  145.   //
  146.   //  Define the control fields for creating a standard frame window.
  147.   //
  148.   ctlData = FCF_TITLEBAR | FCF_MINMAX | FCF_SIZEBORDER | FCF_SYSMENU |
  149.             FCF_MENU | FCF_TASKLIST | FCF_SHELLPOSITION | FCF_ICON |
  150.             FCF_PALETTE_NORMAL;
  151.  
  152.   //
  153.   //  Create our main frame window that makes us who we are.
  154.   //
  155.   hwndFrame = WinCreateStdWindow(HWND_DESKTOP, WS_VISIBLE, &ctlData,
  156.                                  szClass, NULL, WS_VISIBLE, 0, IDR_PMCHESS,
  157.                                  &hwndClient);
  158.  
  159.   //
  160.   //  Make sure the frame window creation was successful.
  161.   //
  162.   if (hwndFrame == NULL)
  163.     {
  164.     //
  165.     //  This should almost never happen...
  166.     //
  167.     WinMessageBox(HWND_DESKTOP, NULL, "Window Create Failure", szAppName, 0,
  168.                   MB_OK);
  169.     goto Error;
  170.     }
  171.  
  172.   //
  173.   //  Retrieve the menu handle to speed up future processing.
  174.   //
  175.   hwndMenu = WinWindowFromID(hwndFrame, FID_MENU);
  176.  
  177.   //
  178.   //  Size the frame window to our standard size.
  179.   //
  180.   QueryBoardSize(&ptl);
  181.   WinSetWindowPos(hwndFrame, NULL, 32, 32,
  182.                   (SHORT)(ptl.x+WinQuerySysValue(HWND_DESKTOP, SV_CXSIZEBORDER)*2L+50L),
  183.                   (SHORT)(ptl.y+WinQuerySysValue(HWND_DESKTOP, SV_CYSIZEBORDER)*2+
  184.                   WinQuerySysValue(HWND_DESKTOP, SV_CYMENU)+
  185.                   WinQuerySysValue(HWND_DESKTOP, SV_CYTITLEBAR) + (LONG)ychar * 2L),
  186.                   SWP_MOVE | SWP_SIZE);
  187.  
  188.   //
  189.   //  Initialize the GNU Chess Logic...
  190.   //
  191.   init_main(hwndFrame);
  192.   player = opponent;
  193.   ShowSidetoMove();
  194.  
  195.   //
  196.   //  The heart of an event driven system, the message dispatch loop.
  197.   //
  198.   while (WinGetMsg(hab, &qmsg, NULL, 0, 0))
  199.     WinDispatchMsg(hab, &qmsg);
  200.  
  201.   //
  202.   //  Release the anchor block and message queue as we are terminating.
  203.   //
  204. Error:
  205.   WinDestroyMsgQueue(hmq);
  206.   WinTerminate(hab);
  207.  
  208.   DosExit(EXIT_PROCESS, 0);
  209.   }
  210.  
  211.  
  212. //***************************************************************************
  213. //
  214. //  WndProc: ChessProc(In, In, In, In)
  215. //
  216. //  Remarks: This routine is then entry-point called by the OS/2 executive.
  217. //
  218. //  Returns: Depends on message processed.
  219. //
  220. MRESULT EXPENTRY ChessProc(HWND hWnd, USHORT msg, MPARAM mp1, MPARAM mp2)
  221.   {
  222.   HWND hwndOldMenu;
  223.   CHAR szBuf[64];
  224.  
  225.  
  226.   switch (msg)
  227.     {
  228.     case WM_CREATE:
  229.       WndCreate(hWnd);
  230.       return (0);
  231.  
  232.     case WM_DESTROY:
  233.       WndDestroy();
  234.       break;
  235.  
  236.     case WM_PAINT:
  237.       WndPaint(hWnd);
  238.       break;
  239.  
  240.     case WM_ERASEBACKGROUND:
  241.       WinFillRect(PVOIDFROMMP(mp1), PVOIDFROMMP(mp2), clrBackGround);
  242.       break;
  243.  
  244.     case WM_SIZE:
  245.       cyClient = SHORT2FROMMP(mp2);
  246.       break;
  247.  
  248.     case WM_BUTTON1DOWN:
  249.       WndButton(hWnd, msg, mp1);
  250.       break;
  251.  
  252.     case WM_INITMENU:
  253.       if ( User_Move ) {            /*Abort thinklook ahead*/
  254.          flag.timeout = true;
  255.          flag.bothsides = false;
  256.          }
  257.  
  258.       if (!EditActive)
  259.         Init_Menus(hWnd, mp1, mp2);
  260.       break;
  261.  
  262.     case WM_COMMAND:
  263.       switch (SHORT1FROMMP(mp1))
  264.         {
  265.         case IDM_FILE_NEW:
  266.           NewGame(hWnd);
  267.           GetOpenings(hWnd);
  268.           break;
  269.  
  270.         case IDM_FILE_OPEN:
  271.           break;
  272.  
  273.         case IDM_FILE_SAVE:
  274.           break;
  275.  
  276.         case IDM_FILE_SAVEAS:
  277.           break;
  278.  
  279.         case IDM_FILE_LIST:
  280.           break;
  281.  
  282.         case IDM_FILE_EXIT:
  283.           WinDestroyWindow(hWnd);
  284.           break;
  285.  
  286.         case IDM_EDIT_BOARD:
  287.           EditActive = TRUE;
  288.           hwndOldMenu = WinWindowFromID(hwndFrame, FID_MENU);
  289.           WinLoadMenu(hwndFrame, 0, IDR_EDIT);
  290.           WinSendMsg(hwndFrame, WM_UPDATEFRAME, NULL, NULL);
  291.           WinDestroyWindow(hwndOldMenu);
  292.           break;
  293.  
  294.         case IDM_EDIT_DONE:
  295.           EditActive = FALSE;
  296.           hwndOldMenu = WinWindowFromID(hwndFrame, FID_MENU);
  297.           WinLoadMenu(hwndFrame, 0, IDR_PMCHESS);
  298.           WinSendMsg(hwndFrame, WM_UPDATEFRAME, NULL, NULL);
  299.           WinDestroyWindow(hwndOldMenu);
  300.  
  301.           GameCnt = 0;
  302.           Game50 = 1;
  303.           ZeroRPT ();
  304.           Sdepth = 0;
  305.           InitializeStats();
  306.           WinPostMsg(hWnd, UM_USER_MOVE, NULL, NULL);
  307.           break;
  308.  
  309.         case IDM_EDIT_GAME:
  310.           //ReviewDialog(hWnd);
  311.           break;
  312.  
  313.         case IDM_EDIT_UNDO:
  314.           if (GameCnt > 0)
  315.             Undo(hWnd);
  316.           break;
  317.  
  318.         case IDM_EDIT_REMOVE:
  319.           if (GameCnt > 1)
  320.             {
  321.             Undo(hWnd);
  322.             Undo(hWnd);
  323.             }
  324.           break;
  325.  
  326.         case IDM_EDIT_FORCE:
  327.           computer = opponent;
  328.           opponent = otherside[computer];
  329.           ShowPlayers();
  330.           WinPostMsg(hWnd, UM_COMPUTER_MOVE, NULL, NULL);
  331.           break;
  332.  
  333.         case IDM_OPTIONS_TONE:
  334.           flag.beep = !flag.beep;
  335.           break;
  336.  
  337.         case IDM_OPTIONS_COOR:
  338.           coords = !coords;
  339.           UpdateDisplay(hWnd, 0, 0, 1, 0);
  340.           break;
  341.  
  342.         case IDM_OPTIONS_STATS:
  343.           if (flag.post)
  344.             {
  345.             WinSendMsg(hStats, WM_SYSCOMMAND, MPFROMSHORT(SC_CLOSE), NULL);
  346.             flag.post = false;
  347.             }
  348.           else
  349.             {
  350.             StatDialog(hWnd);
  351.             flag.post = TRUE;
  352.             }
  353.           break;
  354.  
  355.         case IDM_OPTIONS_SPEED:
  356.           TestDialog(hWnd);
  357.           break;
  358.  
  359.         case IDM_OPTIONS_HASH:
  360.           flag.hash = !flag.hash;
  361.           break;
  362.  
  363.         case IDM_OPTIONS_BOTH:
  364.           flag.bothsides = !flag.bothsides;
  365.           flag.easy = true;
  366.           Sdepth = 0;
  367.           WinPostMsg(hWnd, UM_USER_MOVE, NULL, NULL);
  368.           break;
  369.  
  370.         case IDM_OPTIONS_BOOK:
  371.           Book = NULL;
  372.           break;
  373.  
  374.         case IDM_OPTIONS_AWINDOW:
  375.           WinLoadString(hab, 0, IDS_SETAWIN, sizeof(szBuf), szBuf);
  376.           Awindow = DoGetNumberDlg(hWnd, szBuf, Awindow);
  377.           break;
  378.  
  379.         case IDM_OPTIONS_BWINDOW:
  380.           WinLoadString(hab, 0, IDS_SETBWIN, sizeof(szBuf), szBuf);
  381.           Bwindow = DoGetNumberDlg(hWnd, szBuf, Bwindow);
  382.           break;
  383.  
  384.         case IDM_OPTIONS_CONTEMP:
  385.           WinLoadString(hab, 0, IDS_SETCONTEMPT, sizeof(szBuf), szBuf);
  386.           contempt = DoGetNumberDlg(hWnd, szBuf, contempt);
  387.           break;
  388.  
  389.         case IDM_SKILL_TIME:
  390.           if (TimeControlDialog(hWnd))
  391.             {
  392.             TCflag = (TCmoves > 1);
  393.  
  394.             SetTimeControl();
  395.             }
  396.           break;
  397.  
  398.         case IDM_SKILL_RANDOM:
  399.           if (dither == 0)
  400.             dither = 6;
  401.           else
  402.             dither = 0;
  403.           break;
  404.  
  405.         case IDM_SKILL_EASY:
  406.           flag.easy = !flag.easy;
  407.           break;
  408.  
  409.         case IDM_SKILL_DEPTH:
  410.           WinLoadString(hab, 0, IDS_MAXSEARCH, sizeof(szBuf), szBuf);
  411.           MaxSearchDepth = DoGetNumberDlg(hWnd, szBuf, MaxSearchDepth);
  412.           break;
  413.  
  414.         case IDM_SIDE_REVERSE:
  415.           flag.reverse = !flag.reverse;
  416.           ShowPlayers();
  417.           UpdateDisplay(hWnd, 0, 0, 1, 0);
  418.           break;
  419.  
  420.         case IDM_SIDE_SWITCH:
  421.           computer = otherside[computer];
  422.           opponent = otherside[opponent];
  423.           flag.force = false;
  424.           Sdepth = 0;
  425.           ShowPlayers();
  426.           WinPostMsg(hWnd, UM_COMPUTER_MOVE, NULL, NULL);
  427.           break;
  428.  
  429.         case IDM_SIDE_BLACK:
  430.           computer = black;
  431.           opponent = white;
  432.           flag.force = false;
  433.           Sdepth = 0;
  434.           ShowPlayers();
  435.           WinPostMsg(hWnd, UM_COMPUTER_MOVE, NULL, NULL);
  436.           break;
  437.  
  438.         case IDM_SIDE_WHITE:
  439.           computer = white;
  440.           opponent = black;
  441.           flag.force = false;
  442.           Sdepth = 0;
  443.           ShowPlayers();
  444.           WinPostMsg(hWnd, UM_COMPUTER_MOVE, NULL, NULL);
  445.           break;
  446.  
  447.         case IDM_COLORS_BACKGROUND:
  448.         case IDM_COLORS_BSQUARES:
  449.         case IDM_COLORS_WSQUARES:
  450.         case IDM_COLORS_BPIECES:
  451.         case IDM_COLORS_WPIECES:
  452.         case IDM_COLORS_TEXT:
  453.           if (ColorDialog(hWnd, (LONG)(SHORT1FROMMP(mp1))))
  454.             WinInvalidateRect(hWnd, NULL, TRUE);
  455.           break;
  456.  
  457.         case IDM_COLORS_DEFAULT:
  458.           SetStandardColors ();
  459.           WinInvalidateRect(hWnd, NULL, TRUE);
  460.           break;
  461.  
  462.         case IDM_HINT:
  463.           GiveHint(hWnd);
  464.           break;
  465.  
  466.         case IDM_HELP_ABOUT:
  467.           WinDlgBox(HWND_DESKTOP, hWnd, AboutProc, 0, IDD_ABOUT, NULL);
  468.           break;
  469.         }
  470.       return (0);
  471.  
  472.     case UM_EDITBOARD:
  473.       {
  474.       int Square, First;
  475.  
  476.       if ( flag.reverse ) {
  477.         First = 63 - ((SHORT1FROMMP(mp1) >> 8) & 0xff);
  478.         Square  = 63 - (SHORT1FROMMP(mp1) & 0xff);
  479.       } else {
  480.         First = (SHORT1FROMMP(mp1) >>8) & 0xff;
  481.         Square  = SHORT1FROMMP(mp1) & 0xff;
  482.       }
  483.          
  484.       board[Square] = board[First];
  485.       color[Square] = color[First];
  486.  
  487.       board[First] = no_piece;
  488.       color[First] = neutral;
  489.  
  490.       UpdateDisplay(hWnd, First, Square, false, false);
  491.       }
  492.       break;
  493.  
  494.     case UM_USER_MOVE:
  495.          if ( flag.bothsides && !flag.mate ) {
  496.             SelectMove ( hWnd, opponent, 1);
  497.             if ( flag.beep ) WinAlarm(HWND_DESKTOP, WA_NOTE);
  498.             WinPostMsg( hWnd, UM_COMPUTER_MOVE, NULL, NULL);
  499.          } else if (!flag.mate) {
  500.             User_Move = TRUE;
  501.  
  502.             ft = 0;
  503.             player = opponent;
  504.             ShowSidetoMove ();
  505.          {
  506.             /* Set up to allow computer to think while user takes move*/
  507.             int tmp; unsigned short mv; char s[10];
  508.             if ( hint>0 && !flag.easy && Book == NULL) {
  509.                time0 = time ( NULL);
  510.                algbr ( hint>>8, hint&0xff, false);
  511.                strcpy ( s, mvstr[0]);
  512.                tmp = epsquare;
  513.                if ( VerifyMove (hWnd, s,1, &mv) ) {
  514.                   SelectMove ( hWnd, computer, 2);
  515.                   VerifyMove ( hWnd, mvstr[0], 2, &mv);
  516.                   if ( Sdepth>0 ) Sdepth --;
  517.                }
  518.                ft = time (NULL) - time0;
  519.                epsquare = tmp;
  520.             }
  521.             }
  522.          }
  523.       break;
  524.  
  525.     case UM_USER_ENTERED_MOVE:
  526.       {
  527.          int temp; unsigned short mv; int Square,First; char str[10];
  528.          int algbr_flag;
  529.          User_Move = FALSE;
  530.          player = opponent;
  531.  
  532.          /* Fix coord's if user "reversed" board */
  533.          if ( flag.reverse ) {
  534.             First = 63 - ((SHORT1FROMMP(mp1) >>8) & 0xff);
  535.             Square  = 63 - (SHORT1FROMMP(mp1) & 0xff);
  536.          } else {
  537.             First = (SHORT1FROMMP(mp1) >>8) & 0xff;
  538.             Square  = SHORT1FROMMP(mp1) & 0xff;
  539.          }
  540.  
  541.          /* Logic to allow selection for pawn promotion */
  542.          if ( (board[First] == pawn) &&( (Square <8) || (Square>55)) ) {
  543.             algbr_flag = promote + PromoteDialog (hWnd);
  544.          } else algbr_flag = 0;
  545.          algbr ( First, Square, algbr_flag);
  546.  
  547.          strcpy ( str, mvstr[0] );
  548.          
  549.          temp = VerifyMove ( hWnd, str, 0, &mv);
  550.          if ( temp && (mv != hint)) {
  551.             Sdepth = 0;
  552.             ft = 0;
  553.             ElapsedTime (1);
  554.             WinPostMsg( hWnd, UM_COMPUTER_MOVE, NULL, NULL);
  555.          } else if ( temp == TRUE) {
  556.             ElapsedTime (1);
  557.             WinPostMsg ( hWnd, UM_COMPUTER_MOVE, NULL, NULL);
  558.          } else WinPostMsg ( hWnd, UM_USER_MOVE, NULL, NULL);
  559.       }
  560.       break;
  561.  
  562.     case UM_COMPUTER_MOVE:
  563.          if ( !(flag.quit || flag.mate || flag.force) ) {
  564.             SelectMove ( hWnd, computer, 1);
  565.             if ( flag.beep ) WinAlarm(HWND_DESKTOP, WA_NOTE);
  566.          }
  567.          WinPostMsg( hWnd, UM_USER_MOVE, NULL, NULL);
  568.       break;
  569.     }
  570.  
  571.   return (WinDefWindowProc(hWnd, msg, mp1, mp2));
  572.   }
  573.  
  574.  
  575. //***************************************************************************
  576. //
  577. //  Routine: WndCreate(In):Static
  578. //
  579. //  Remarks: This routine processed the WM_CREATE message from the main
  580. //           client window.
  581. //
  582. //  Returns: None.
  583. //
  584. static void WndCreate(HWND hWnd)
  585.   {
  586.   FONTMETRICS fm;
  587.  
  588.  
  589.   hpsClient = WinGetPS(hWnd);
  590.  
  591.   //
  592.   //  Load all the chess piece's bitmaps into a master memory ps for later.
  593.   //
  594.   hpsPieces = LoadChessPieces(hab);
  595.  
  596.   //
  597.   //  Load the diamensions of the default system font.
  598.   //
  599.   GpiQueryFontMetrics(hpsClient, sizeof(fm), &fm);
  600.   xchar = (SHORT)fm.lEmInc;
  601.   ychar = (SHORT)fm.lMaxBaselineExt+(SHORT)fm.lExternalLeading;
  602.  
  603.   Create_Children(hWnd, xchar, ychar);
  604.  
  605.   GetStartupColors(szAppName);
  606.   }
  607.  
  608.  
  609. //***************************************************************************
  610. //
  611. //  Routine: WndDestroy():Static
  612. //
  613. //  Remarks: This routine processed the WM_DESTROY message from the main
  614. //           client window.
  615. //
  616. //  Returns: None.
  617. //
  618. static void WndDestroy()
  619.   {
  620.   //
  621.   //  Save the current color settings for the next time.
  622.   //
  623.   SaveColors(szAppName);
  624.  
  625.   WinReleasePS(hpsClient);
  626.   }
  627.  
  628.  
  629. //***************************************************************************
  630. //
  631. //  Routine: WndPaint(In):Static
  632. //
  633. //  Remarks: This routine processed the WM_PAINT message from the main client
  634. //           client window.
  635. //
  636. //  Returns: None.
  637. //
  638. static void WndPaint(HWND hWnd)
  639.   {
  640.   HPS   hps;
  641.   RECTL rcl;
  642.  
  643.  
  644.   //
  645.   //  Remember to properly repaint hi-lighted square.
  646.   //
  647.   if (FirstSq != -1)
  648.     {
  649.     POINTL ptl;
  650.     RECTL  rcl;
  651.  
  652.     QuerySqOrigin(FirstSq % 8, FirstSq / 8, &ptl);
  653.     rcl.xLeft   = ptl.x;
  654.     rcl.xRight  = ptl.x + 48;
  655.     rcl.yTop    = ptl.y;
  656.     rcl.yBottom = ptl.y - 48;
  657.     WinInvalidateRect(hWnd, &rcl, FALSE);
  658.     }
  659.  
  660.   //
  661.   //  Retrieve the presentation space for drawing.
  662.   //
  663.   hps = WinBeginPaint(hWnd, NULL, &rcl);
  664.  
  665.   //
  666.   //  Clear the background.
  667.   //
  668.   WinFillRect(hps, &rcl, clrBackGround);
  669.  
  670.   //
  671.   //  Draw the chess board.
  672.   //
  673.   Draw_Board(hps, flag.reverse, clrBlackSquare, clrWhiteSquare);
  674.  
  675.   //
  676.   //  Draw the coordinates if that option has been selected by the user.
  677.   //
  678.   if (coords)
  679.     DrawCoords(hps, flag.reverse, clrBackGround, clrText);
  680.  
  681.   //
  682.   //  Draw in the pieces.
  683.   //
  684.   DrawAllPieces(hps, hpsPieces, flag.reverse, boarddraw, colordraw,
  685.                 clrBlackPiece, clrWhitePiece);
  686.  
  687.   //
  688.   //  All done with painting the client area.
  689.   //
  690.   WinEndPaint(hps);
  691.  
  692.   //
  693.   //  If we have a selected square then hi-lighted it.
  694.   //
  695.   if (FirstSq != -1)
  696.     HiliteSquare(hWnd, FirstSq);
  697.   }
  698.  
  699.  
  700. //***************************************************************************
  701. //
  702. //  Routine: WndButton(In):Static
  703. //
  704. //  Remarks: This routine processed the various mouse button message from the
  705. //           main client window.
  706. //
  707. //  Returns: None.
  708. //
  709. static void WndButton(HWND hWnd, USHORT msg, MPARAM mp1)
  710.   {
  711.   POINTL ptl;
  712.   short  Hit;
  713.   short  x, y;
  714.  
  715.  
  716.   switch (msg)
  717.     {
  718.     case WM_BUTTON1DOWN:
  719.       /*  If computer is thinking on human's time stop it at the first
  720.           button click.  add test to ensure that "human" can't interupt
  721.           the computer from thinking through its turn. */
  722.       if (User_Move)
  723.         {
  724.         flag.timeout   = true;
  725.         flag.bothsides = false;
  726.         }
  727.  
  728.       /* Don't continue unless reason to */
  729.       if (!(EditActive || User_Move))
  730.          break;
  731.  
  732.       ptl.x = SHORT1FROMMP(mp1);
  733.       ptl.y = SHORT2FROMMP(mp1);
  734.  
  735.       CkdQueryHitCoords(hpsClient, &ptl, &x, &y);
  736.  
  737.       if (x != -1 && y != -1)
  738.         Hit = y * 8 + x;
  739.       else
  740.         Hit = -1;
  741.  
  742.  
  743.          if ( Hit == -1 ){
  744.             if ( FirstSq != -1) {
  745.                UnHiliteSquare ( hWnd, FirstSq);
  746.                GotFirst = FALSE;
  747.                FirstSq = -1;
  748.             }
  749.             break;
  750.          }
  751.  
  752.          if ( GotFirst ) {
  753.             UnHiliteSquare( hWnd, FirstSq);
  754.             GotFirst = FALSE;
  755.  
  756.             if ( EditActive == TRUE) {
  757.                WinPostMsg(hWnd, UM_EDITBOARD, MPFROMSHORT((FirstSq<<8)|Hit), NULL);
  758.             } else if (User_Move == TRUE) {
  759.                WinPostMsg(hWnd, UM_USER_ENTERED_MOVE, MPFROMSHORT((FirstSq<<8)|Hit), NULL);
  760.             }
  761.             FirstSq = -1;
  762.          } else {
  763.             GotFirst = TRUE;
  764.             FirstSq = Hit;
  765.             HiliteSquare ( hWnd, Hit);
  766.          }
  767.       break;
  768.     }
  769.   }
  770.  
  771.  
  772.  
  773. MRESULT EXPENTRY AboutProc(HWND hDlg, USHORT msg, MPARAM mp1, MPARAM mp2)
  774.   {
  775.   switch (msg)
  776.     {
  777.     case WM_COMMAND:
  778.       switch (SHORT1FROMMP(mp1))
  779.         {
  780.         case IDC_OK:
  781.           WinDismissDlg(hDlg, TRUE);
  782.           break;
  783.         }
  784.       return (0);
  785.     }
  786.  
  787.   return (WinDefDlgProc(hDlg, msg, mp1, mp2));
  788.   }
  789.