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