home *** CD-ROM | disk | FTP | other *** search
/ The Best of Select: Games 3 / cd.iso / os2 / pmgnuchs / pmchess.c < prev    next >
Text File  |  1994-04-20  |  34KB  |  1,135 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 4.0 (PmChess)
  6. *
  7. *  Version:    1994-4-17
  8. *
  9. *   Module:    Main Module (PmChess.c)
  10. *
  11. *   Porter:    Gnu Chess 3.0 ported to Windows 3.0 by Darly Baker
  12. *
  13. *   Porter:    Gnu Chess 3.0 Ported to OS/2 1.2+ by Kent Cedola
  14. *
  15. *   Porter:    Gnu Chess 4.0 Ported to OS/2 2.1+ by Yibing Fan
  16. *
  17. *   System:    OS/2 2.11 using emx0.8h
  18. *
  19. *  Remarks:    Started with bug fixes on Kent's code of PMChess, I then
  20. *              start to port gnu chess 4.0. The chess engine now is in three
  21. *              seprated threads(the same engine start in 3 different occasions).
  22. *              The main trouble is communication between threads. Some data need
  23. *              to be passed on fly. In this version, the best line and current
  24. *              move in status dialog does not show correctly.
  25. *
  26. *  Fuction defined in this module:
  27. *       int main(short argc, char **argv)
  28. *       void  FAR   WndCreate(HWND hWnd);
  29. *       void  FAR   WndPaint(HWND hWnd);
  30. *       void  FAR   WndButton(HWND hWnd, ULONG msg, MPARAM mp1);
  31. *       void  FAR   WndDestroy(void);
  32. *       FNWP ChessProc;
  33. *       FNWP AboutProc;
  34. *       MRESULT EXPENTRY NotAvailableDlg( HWND hWnd, ULONG msg, MPARAM mp1,MPARAM mp2);
  35. *
  36. *  License:
  37. *
  38. *    CHESS is distributed in the hope that it will be useful, but WITHOUT ANY
  39. *    WARRANTY.  No author or distributor accepts responsibility to anyone for
  40. *    the consequences of using it or for whether it serves any particular
  41. *    purpose or works at all, unless he says so in writing.  Refer to the
  42. *    CHESS General Public License for full details.
  43. *
  44. *    Everyone is granted permission to copy, modify and redistribute CHESS,
  45. *    but only under the conditions described in the CHESS General Public
  46. *    License.  A copy of this license is supposed to have been given to you
  47. *    along with CHESS so you can know your rights and responsibilities.  It
  48. *    should be in a file named COPYING.  Among other things, the copyright
  49. *    notice and this notice must be preserved on all copies.
  50. ****************************************************************************/
  51.  
  52. #define INCL_DOS
  53. #define INCL_GPI
  54. #define INCL_WIN
  55. #include <os2.h>
  56. #include <string.h>
  57. #include <stdlib.h>
  58. #include <stdio.h>
  59. #include <math.h>
  60. #include <time.h>
  61. #include "PmChess.h"
  62. #include "GnuChess.h"
  63. #include "Defs.h"
  64. #include "Resource.h"
  65.  
  66. // Thread Variables
  67. TID tidcalc1, tidcalc2, tidcalc3, tiddsp;
  68. HEV hev1, hev2, hev3;
  69. ULONG ulPostCt1, ulPostCt2, ulPostCt3;
  70.  
  71. /*
  72. *  Define global variables.
  73. */
  74.   HAB  hab;                             /* Primary thread anchor block.*/
  75.   HMQ  hmq;                             /* Message queue handle.*/
  76.   HWND hwndFrame;                       /* Frame window handle.*/
  77.   HWND hwndClient;                      /* Client window handle.*/
  78.   HPS  hpsClient;
  79.   HWND hwndMenu;                        /* Menu window handle.*/
  80.  
  81.   SHORT cyClient;                       /* Height of client area.*/
  82.   SHORT cyClientIni;                    /* Height of initial client area.*/
  83.   CHAR szAppName[] = "PmChess";         /* Application name.*/
  84.   SHORT boarddraw[64];                  /* Display copies of the board */
  85.   SHORT colordraw[64];                  /* Needed because while computer is calculating*/
  86.                              /* moves it updates board and color thus you can*/
  87.                              /* not repaint the screen accuratly */
  88.  
  89.   ULONG clrBackGround;       /* color index for various colors */
  90.   ULONG clrBlackSquare;
  91.   ULONG clrWhiteSquare;
  92.   ULONG clrBlackPiece;
  93.   ULONG clrWhitePiece;
  94.   ULONG clrText, next = 1;
  95.   SHORT xchar, ychar;
  96.   SHORT coords = 1, rehash;
  97.   float ScaleFactor = 1.0;     /* initial scaling factor */
  98.   SHORT clrcase;                /* color case parameter */
  99.   extern HWND hComputerMove;    /* def in create.c */
  100.   short Best;
  101.   USHORT *Bstline;
  102.   CHAR Bch; 
  103.   CHAR szFullPath[80] = "";
  104.  extern unsigned int TTadd;
  105.  extern unsigned int ttbllimit;
  106.  
  107. /*  Define local variables.*/
  108.  
  109.    BOOL FirstSq   = -1;           /* Flag is a square is selected*/
  110.    INT GotFirst   = FALSE;
  111.    INT UseBook    = TRUE;         /* use opening book as default */
  112.    INT EditActive = FALSE;        /* Edit mode? */
  113.    INT User_Move  = TRUE;         /* User or computer's turn */
  114.    CHAR szClass[] = "PmChess";    /* Class name of main window procedure.*/
  115.    CHAR *CP[CPSIZE];              /* Class name of main window procedure.*/
  116.    char *ColorStr[2];
  117.    HPS  hpsPieces;                /* Memory PS of all chess pieces.*/
  118.    HPS   hps;
  119.  
  120. /*
  121. *  Define prototypes of local routines.
  122. */
  123.   void  FAR   WndCreate(HWND hWnd);
  124.   void  FAR   WndPaint(HWND hWnd);
  125.   void  FAR   WndButton(HWND hWnd, ULONG msg, MPARAM mp1);
  126.   VOID _System calc1(ULONG);
  127.   VOID _System calc2(ULONG);
  128.   VOID _System calc3(ULONG);
  129.   VOID _System trddsp(ULONG);
  130.   void  FAR   WndDestroy(void);
  131.   BOOL GetFileName(HWND hWnd);
  132.   FNWP ChessProc;
  133.   FNWP AboutProc;
  134. MRESULT EXPENTRY NotAvailableDlg( HWND hWnd, ULONG msg, MPARAM mp1,MPARAM mp2);
  135. extern MRESULT EXPENTRY ColorProc( HWND hWnd, ULONG msg, MPARAM mp1,MPARAM mp2);
  136. extern int ColorDialog(HWND hWnd, ULONG Param );
  137. extern void UpdateChilds (void); /*these extern's can be moved to defs.h */
  138. /***************************************************************************
  139. *
  140. *  Routine: main(In, In)
  141. *
  142. *  Remarks: This routine is then entry-point called by the OS/2 executive.
  143. *
  144. *  Returns: None.
  145. \****************************************************************************/
  146. int main(short argc, char **argv)
  147.   {
  148.   QMSG   qmsg;
  149.   ULONG  ctlData;
  150.   POINTL ptl;
  151.  
  152. #ifdef ttblsz
  153.   ttblsize = ttblsz;
  154.   rehash = -1;
  155. #endif /* ttblsz */
  156.  
  157.   /*  Allocate an anchor block and message queue to use PM services. */
  158.   hab = WinInitialize(0);
  159.   hmq = WinCreateMsgQueue(hab, 0);
  160.  
  161.   /*  Register the main window procedure. */
  162.   WinRegisterClass(hab, szClass, ChessProc, CS_SIZEREDRAW, 0);
  163.  
  164.   /*  Compute the idea client height. */
  165.   QueryBoardSize(&ptl);
  166.   cyClient = (SHORT)(ptl.y + WinQuerySysValue(HWND_DESKTOP, SV_CYSIZEBORDER)
  167.              * 2L+ WinQuerySysValue(HWND_DESKTOP, SV_CYMENU)+
  168.              WinQuerySysValue(HWND_DESKTOP, SV_CYTITLEBAR) +
  169.              (LONG)ychar * 2L);
  170.   cyClientIni = cyClient;
  171.  
  172.   /*
  173.   *  Define the control fields for creating a standard frame window.
  174.   */
  175.   ctlData = FCF_TITLEBAR | FCF_MINMAX | FCF_SIZEBORDER | FCF_SYSMENU |
  176.             FCF_MENU | FCF_TASKLIST | FCF_SHELLPOSITION |
  177.             FCF_ICON | FCF_ACCELTABLE;
  178.  
  179.   /*
  180.   *  Create our main frame window that makes us who we are.
  181.   */
  182.   hwndFrame = WinCreateStdWindow(HWND_DESKTOP, WS_VISIBLE, &ctlData,
  183.                                  szClass, NULL, WS_VISIBLE, 0, IDR_PMCHESS,
  184.                                  &hwndClient);
  185.  
  186.   /*
  187.   *  Retrieve the menu handle to speed up future processing.
  188.   */
  189.   hwndMenu = WinWindowFromID(hwndFrame, FID_MENU);
  190.  
  191.   /*
  192.   *  Size the frame window to our standard size.
  193.   */
  194.   WinSetWindowPos(hwndFrame, 0, 32, 32,
  195.                   (SHORT)(ptl.x+WinQuerySysValue(HWND_DESKTOP, SV_CXSIZEBORDER)*2L+0L),
  196.                   (SHORT)(ptl.y+WinQuerySysValue(HWND_DESKTOP, SV_CYSIZEBORDER)*2+
  197.                   WinQuerySysValue(HWND_DESKTOP, SV_CYMENU)+
  198.                   WinQuerySysValue(HWND_DESKTOP, SV_CYTITLEBAR) + (LONG)ychar * 2L),
  199.                   SWP_MOVE | SWP_SIZE);
  200.  
  201. /********** Initialize Help menu **********/
  202.    InitHelp();
  203.  
  204.   /*************************************************************************
  205.   *  Initialize the GNU Chess Logic...
  206.   \*************************************************************************/
  207.   init_main(hwndFrame);
  208.   player = opponent;
  209.   ShowSidetoMove();
  210.  
  211.   Bstline = (USHORT *) malloc (MAXDEPTH * sizeof(USHORT));
  212.  
  213.   /*************************************************************************
  214.   *  The heart of an event driven system, the message dispatch loop.
  215.   **************************************************************************/
  216.   while (WinGetMsg(hab, &qmsg, 0, 0, 0)){
  217. //    DosEnterCritSec();
  218.     WinDispatchMsg(hab, &qmsg);
  219. //    DosExitCritSec();
  220.     }
  221.  
  222. /********************* destroy the help instance ********/
  223.    DestroyHelpInstance();
  224.  
  225.   /**************************************************************************
  226.   *  Release the anchor block and message queue as we are terminating.
  227.   ***************************************************************************/
  228.   WinDestroyWindow(hwndFrame);
  229.   WinDestroyMsgQueue(hmq);
  230.   WinTerminate(hab);
  231.   return 0;
  232.   }
  233.  
  234.  
  235. /***************************************************************************
  236. *
  237. *  WndProc: ChessProc(In, In, In, In)
  238. *
  239. *  Remarks: This routine is then entry-point called by the OS/2 executive.
  240. *
  241. *  Returns: Depends on message processed.
  242. */
  243. MRESULT EXPENTRY ChessProc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  244.   { /******** beginning of ChessProc's *********/
  245.   HWND hwndOldMenu;
  246.   CHAR szBuf[64];
  247.  
  248.   switch (msg) 
  249.     {
  250.     case WM_CREATE:
  251.       WndCreate(hWnd);
  252.  
  253.     /************************************/   
  254.     /*It's bit awkward need three       */   
  255.     /*threads to do about the same thing*/   
  256.     /************************************/                                                                   
  257.         DosCreateEventSem(NULL, &hev1, 0,0);                    
  258.         tidcalc1 = _beginthread(calc1, NULL, 8192, NULL);
  259.         DosCreateEventSem(NULL, &hev2, 0,0);
  260.         tidcalc2 = _beginthread(calc2, NULL, 8192, NULL);
  261.         DosCreateEventSem(NULL, &hev3, 0,0);
  262.         tidcalc3 = _beginthread(calc3, NULL, 8192, NULL);
  263.     /*****************************************************************************/
  264.     /* This thread act as timer to signal the main process to update information */
  265.     /*****************************************************************************/
  266.         tiddsp = _beginthread(trddsp, NULL, 4096, NULL);
  267.       return (0);
  268.  
  269.  /*   case WM_DESTROY:
  270.       WndDestroy();
  271.       break;
  272. */
  273.     case WM_PAINT:
  274.       WndPaint(hWnd);
  275.       break;
  276.  
  277.     case WM_ERASEBACKGROUND:
  278.       WinFillRect(HWNDFROMMP(mp1), PVOIDFROMMP(mp2), clrBackGround);
  279.       break;
  280.  
  281.     case WM_SIZE:
  282.       cyClient = SHORT2FROMMP(mp2);
  283.      if (cyClient != 0)
  284.         { ScaleFactor = (float)cyClient / cyClientIni;}  
  285.     return (0);
  286.  
  287.     case WM_BUTTON1DOWN:
  288.       WndButton(hWnd, msg, mp1);
  289.       break;
  290.  
  291.     case WM_INITMENU:
  292.       if ( User_Move ) {            /*Abort thinklook ahead*/
  293.        /*  flag.timeout = true;  */
  294.        /*  flag.bothsides = false; */
  295.          }
  296.  
  297.       if (!EditActive)
  298.       Init_Menus(hWnd, mp1, mp2);
  299.       break;
  300.  
  301.     case WM_COMMAND:
  302.       switch (COMMANDMSG(&msg)->cmd /*SHORT1FROMMP(mp1)*/)
  303.         {
  304.         case IDM_FILE_NEW:
  305. //          if(!flag.bothsides)
  306. //           {
  307.              if (flag.easy && (player == opponent))
  308.              {
  309.                 NewGame(hWnd);
  310.                 if (UseBook) {
  311.                 Book = BOOKFAIL;
  312.                 } else {
  313.                 Book = 0;
  314.                 } /* endif */
  315.                 UpdateDisplay (hWnd, 0, 0, 1, 0);
  316.                 WinPostMsg(hWnd, UM_USER_MOVE, NULL, NULL);
  317.              } else {
  318.                flag.easy = true;
  319.                flag.timeout = true;
  320.                 DosSleep(1500);
  321.                WinPostMsg ( hWnd, UM_NEW_GAME, NULL, NULL);
  322.                    }
  323. /*           } else {
  324.               flag.bothsides = false;
  325.               flag.easy = true;
  326.               flag.timeout = true;
  327.                 DosSleep(1500);
  328.               flag.timeout = true;
  329.                 DosSleep(1500);
  330.               WinPostMsg ( hWnd, UM_NEW_GAME, NULL, NULL);
  331.            }
  332. */
  333.           break;
  334.  
  335.         case IDM_FILE_OPEN:
  336.            if(GetFileName (hWnd))
  337.            GetGame (hWnd, szFullPath);
  338.           break;
  339.  
  340.         case IDM_FILE_SAVE:
  341.            if(GetFileName (hWnd))
  342.            SaveGame (hWnd, szFullPath);
  343.           break;
  344.  
  345.         case IDM_FILE_SAVEAS:
  346.                 WinDlgBox( HWND_DESKTOP, hWnd,(PFNWP)NotAvailableDlg,
  347.                                 (HMODULE)0, IDD_NOTAVAIL, NULL);
  348.           break;
  349.  
  350.         case IDM_FILE_LIST:
  351.            ListGame ();
  352.           break;
  353.  
  354.         case IDM_FILE_EXIT:
  355.           WinPostMsg(hWnd,WM_QUIT,NULL,NULL);
  356.           return(MRESULT)TRUE;
  357.  
  358.         case IDM_EDIT_BOARD:
  359.           EditActive = TRUE;
  360.           hwndOldMenu = WinWindowFromID(hwndFrame, FID_MENU);
  361.           WinLoadMenu(hwndFrame, 0, IDR_EDIT);
  362.           WinSendMsg(hwndFrame, WM_UPDATEFRAME, NULL, NULL);
  363.           WinDestroyWindow(hwndOldMenu);
  364.           break;
  365.  
  366.         case IDM_EDIT_DONE:
  367.           EditActive = FALSE;
  368.           hwndOldMenu = WinWindowFromID(hwndFrame, FID_MENU);
  369.           WinLoadMenu(hwndFrame, 0, IDR_PMCHESS);
  370.           WinSendMsg(hwndFrame, WM_UPDATEFRAME, NULL, NULL);
  371.           WinDestroyWindow(hwndOldMenu);
  372.  
  373.           GameCnt = 0;
  374.           Game50 = 1;
  375.           ZeroRPT ();
  376.           Sdepth = 0;
  377.           InitializeStats();
  378.           WinPostMsg(hWnd, UM_USER_MOVE, NULL, NULL);
  379.           break;
  380.  
  381.         case IDM_EDIT_GAME:
  382.           /* ReviewDialog(hWnd); */
  383.           break;
  384.  
  385.         case IDM_EDIT_UNDO:
  386.           if (GameCnt > 0)
  387.             Undo(hWnd);
  388.           break;
  389.  
  390.         case IDM_EDIT_REMOVE:
  391.           if (GameCnt > 0){
  392.             Undo(hWnd);
  393.             Undo(hWnd);}
  394.           break;
  395.  
  396.         case IDM_EDIT_MOVE:
  397.           flag.timeout = true;
  398.           break;
  399.  
  400.         case IDM_EDIT_STOP:
  401.           flag.easy = true;
  402.           flag.timeout = true;
  403.           flag.bothsides =false;
  404.           break;
  405.  
  406.         case IDM_EDIT_FORCE:  /* no computer */
  407.           flag.force = !flag.force;
  408.           ShowPlayers();
  409.           WinPostMsg(hWnd, UM_USER_MOVE, NULL, NULL);
  410.           break;
  411.  
  412.         case IDM_OPTIONS_TONE:
  413.           flag.beep = !flag.beep;
  414.           break;
  415.  
  416.         case IDM_OPTIONS_COOR:
  417.           coords = !coords;
  418.           UpdateDisplay(hWnd, 0, 0, 1, 0);
  419.           break;
  420.  
  421.         case IDM_OPTIONS_STATS:
  422.           if (flag.post)
  423.             {
  424.             WinSendMsg(hStats, WM_SYSCOMMAND, MPFROMSHORT(SC_CLOSE), NULL);
  425.             flag.post = false;
  426.             }
  427.           else
  428.             {
  429.             StatDialog(hWnd);
  430.             flag.post = TRUE;
  431.             }
  432.           break;
  433.  
  434.         case IDM_OPTIONS_SPEED:
  435.           TestDialog(hWnd);
  436.           break;
  437.  
  438.         case IDM_OPTIONS_HASH:
  439.           flag.hash = !flag.hash;
  440.           break;
  441.  
  442.         case IDM_OPTIONS_BOTH:
  443.           flag.bothsides = !flag.bothsides;
  444.            if(flag.bothsides) flag.easy = true; 
  445.           Sdepth = 0;
  446.           ShowPlayers();
  447.           WinPostMsg(hWnd, UM_USER_MOVE, NULL, NULL);
  448.           break;
  449.  
  450.         case IDM_OPTIONS_BOOK:
  451.           UseBook = !UseBook;
  452.           if (UseBook) {
  453.           Book = BOOKFAIL;
  454.           } else {
  455.           Book = 0;
  456.           } /* endif */
  457.           break;
  458.  
  459.         case IDM_OPTIONS_AWINDOW:
  460.           WinLoadString(hab, 0, IDS_SETAWIN, sizeof(szBuf), szBuf);
  461.           BAwindow = DoGetNumberDlg(hWnd, szBuf, BAwindow);
  462.           break;
  463.  
  464.         case IDM_OPTIONS_BWINDOW:
  465.           WinLoadString(hab, 0, IDS_SETBWIN, sizeof(szBuf), szBuf);
  466.           BBwindow = DoGetNumberDlg(hWnd, szBuf, BBwindow);
  467.           break;
  468.  
  469.         case IDM_OPTIONS_CONTEMP:
  470.           WinLoadString(hab, 0, IDS_SETCONTEMPT, sizeof(szBuf), szBuf);
  471.           contempt = DoGetNumberDlg(hWnd, szBuf, contempt);
  472.           break;
  473.  
  474.         case IDM_SKILL_TIME:
  475.           if (TimeControlDialog(hWnd))
  476.             {
  477.             TCflag = (TCmoves > 1);
  478.  
  479.             SetTimeControl();
  480.             }
  481.           break;
  482.  
  483.         case IDM_SKILL_RANDOM:
  484.           if (dither == 0)
  485.             dither = 6;
  486.           else
  487.             dither = 0;
  488.           break;
  489.  
  490.         case IDM_SKILL_EASY:
  491.           flag.easy = flag.easy^1;
  492.           break;
  493.  
  494.  
  495.         case IDM_SKILL_DEPTH:
  496.           WinLoadString(hab, 0, IDS_MAXSEARCH, sizeof(szBuf), szBuf);
  497.           MaxSearchDepth = DoGetNumberDlg(hWnd, szBuf, MaxSearchDepth);
  498.           break;
  499.  
  500.         case IDM_SIDE_REVERSE:
  501.         flag.reverse = !flag.reverse;
  502.           UpdateDisplay(hWnd, 0, 0, 1, 0);
  503.           break;
  504.  
  505.         case IDM_SIDE_SWITCH:
  506.           computer = otherside[computer];
  507.           opponent = otherside[opponent];
  508.           flag.force = false;
  509.           Sdepth = 0;
  510.           ShowPlayers();
  511.           WinPostMsg(hWnd, UM_COMPUTER_MOVE, NULL, NULL);
  512.           break;
  513.  
  514.         case IDM_SIDE_BLACK:
  515.           computer = black;
  516.           opponent = white;
  517.           flag.force = false;
  518.           Sdepth = 0;
  519.           ShowPlayers();
  520.           WinPostMsg(hWnd, UM_COMPUTER_MOVE, NULL, NULL);
  521.           break;
  522.  
  523.         case IDM_SIDE_WHITE:
  524.           computer = white;
  525.           opponent = black;
  526.           flag.force = false;
  527.           Sdepth = 0;
  528.           ShowPlayers();
  529.           WinPostMsg(hWnd, UM_COMPUTER_MOVE, NULL, NULL);
  530.           break;
  531.  
  532.         case IDM_SIDE_REFRESH:
  533.                 WinInvalidateRect(hWnd, NULL, TRUE);
  534.           break;
  535.  
  536.        case IDM_COLORS_BACKGROUND:
  537.                 clrcase = IDM_COLORS_BACKGROUND;
  538.                 ColorDialog( hWnd, 0L);
  539.                 WinInvalidateRect(hWnd, NULL, TRUE);
  540.           break;
  541.  
  542.         case IDM_COLORS_BSQUARES:
  543.                 clrcase = IDM_COLORS_BSQUARES;
  544.                 ColorDialog( hWnd, 0L);
  545.                 WinInvalidateRect(hWnd, NULL, TRUE);
  546.           break;
  547.           
  548.         case IDM_COLORS_WSQUARES:
  549.                 clrcase = IDM_COLORS_WSQUARES;
  550.                 ColorDialog( hWnd, 0L);
  551.                 WinInvalidateRect(hWnd, NULL, TRUE);
  552.           break;
  553.         case IDM_COLORS_BPIECES:
  554.                 clrcase = IDM_COLORS_BPIECES;
  555.                 ColorDialog( hWnd, 0L);
  556.                 WinInvalidateRect(hWnd, NULL, TRUE);
  557.           break;
  558.         case IDM_COLORS_WPIECES:
  559.                 clrcase = IDM_COLORS_WPIECES;
  560.                 ColorDialog( hWnd, 0L);
  561.                 WinInvalidateRect(hWnd, NULL, TRUE);
  562.           break;
  563.         case IDM_COLORS_TEXT:
  564.                 clrcase = IDM_COLORS_TEXT;
  565.                 ColorDialog( hWnd, 0L);
  566.                 WinInvalidateRect(hWnd, NULL, TRUE);
  567.           break;
  568.  
  569.         case IDM_COLORS_DEFAULT:
  570.           SetStandardColors ();
  571.           WinInvalidateRect(hWnd, NULL, TRUE);
  572.           break;
  573.  
  574.         case IDM_HINT:
  575.           GiveHint(hWnd);
  576.           break;
  577.  
  578.    case IDM_HELP_INDEX:
  579.       HelpIndex();
  580.       break;
  581.  
  582.    case IDM_HELP_EXT:
  583.       HelpGeneral();
  584.       break;
  585.  
  586.    case IDM_HELP_DISPLAY:
  587.       HelpUsingHelp();
  588.       break;
  589.  
  590.    case IDM_HELP_KEYS:
  591.       HelpKeys();
  592.       break;
  593.  
  594.         case IDM_HELP_ABOUT:
  595.           WinDlgBox(HWND_DESKTOP, hWnd, AboutProc, 0, IDD_ABOUT, NULL);
  596.           break;
  597.         } /****************** end of switch  for cmd (SHORT1FROMMP(mp1))   *********/
  598.       return (0);
  599.  
  600.     case UM_EDITBOARD:
  601.       {
  602.       INT Square, First;
  603.  
  604.       if ( flag.reverse ) 
  605.         {
  606.         First = 63 - ((SHORT1FROMMP(mp1) >> 8) & 0xff);
  607.         Square  = 63 - (SHORT1FROMMP(mp1) & 0xff);
  608.         }
  609.         else 
  610.         {
  611.         First = (SHORT1FROMMP(mp1) >>8) & 0xff;
  612.         Square  = SHORT1FROMMP(mp1) & 0xff;
  613.         }
  614.          
  615.       board[Square] = board[First];
  616.       color[Square] = color[First];
  617.  
  618.       board[First] = no_piece;
  619.       color[First] = neutral;
  620.  
  621.       UpdateDisplay(hWnd, First, Square, false, false);
  622.       }
  623.       break;
  624.  
  625.     case UM_USER_MOVE:       
  626.       {char tmp[20];
  627.         sprintf ( tmp, CP[84] /*"My move is %s"*/ ,(char *) mvstr[0]);
  628.         WinSetWindowText ( hComputerMove, tmp);
  629.          if ( flag.bothsides && !flag.mate ) 
  630.          {
  631.           ShowPlayers();
  632.             ShowSidetoMove ();
  633.             DosPostEventSem (hev2);       /* start to calculate in autoplay mode */
  634.          } 
  635.             else if (!flag.mate) 
  636.          {
  637.             User_Move = TRUE;
  638.             ft = 0;
  639.             player = opponent;
  640.             ShowSidetoMove ();
  641. /* if transposition table is filling start it over */
  642.   if(TTadd > ttbllimit)ZeroTTable();
  643.           /* Set up to allow computer to think while user takes move */
  644.           /* if we have a move for our opponent, and we are thinking on his time, and not in force mode */
  645.             if ( hint>0 && !flag.easy && Book == 0)
  646.   /* if the hint is a promotion don't do anything, we don't know what to promote to. */
  647.     if ((board[hint >> 8] != pawn) || ((row (hint & 0x3f) != 0) && (row (hint & 0x3f) != 7)))
  648.                 {  DosPostEventSem (hev3); }         /* if deep thinking is on start engine */
  649.              }
  650.          }
  651.       break;
  652.  
  653.     case UM_USER_ENTERED_MOVE:
  654.       {
  655.          INT temp; USHORT mv; INT Square,First; CHAR str[10];
  656.          INT algbr_flag;
  657.          User_Move = FALSE;
  658.          player = opponent;
  659.  
  660.          /* Fix coord's if user "reversed" board */
  661.          if ( flag.reverse ) {
  662.             First = 63 - ((SHORT1FROMMP(mp1) >>8) & 0xff);
  663.             Square  = 63 - (SHORT1FROMMP(mp1) & 0xff);
  664.          } else {
  665.             First = (SHORT1FROMMP(mp1) >>8) & 0xff;
  666.             Square  = SHORT1FROMMP(mp1) & 0xff;
  667.          }
  668.  
  669.          /* Logic to allow selection for pawn promotion */
  670.          if ( (board[First] == pawn) &&( (Square <8) || (Square>55)) ) {
  671.             algbr_flag = promote + PromoteDialog (hWnd);
  672.          } else algbr_flag = 0;
  673.          algbr ( First, Square, algbr_flag);
  674.  
  675.          strcpy ( str, mvstr[0] );
  676.          
  677.          temp = VerifyMove ( hWnd, str, 0, &mv);
  678.          if ( temp && (mv != hint)) {
  679.             Sdepth = 0;
  680.             ft = 0;
  681.             ElapsedTime (1);
  682.             WinPostMsg( hWnd, UM_COMPUTER_MOVE, NULL, NULL);
  683.          } else if ( temp == TRUE) {
  684.             ElapsedTime (1);
  685. //            flag.musttimeout = true;
  686.             WinPostMsg ( hWnd, UM_COMPUTER_MOVE, NULL, NULL);
  687.          } else WinPostMsg ( hWnd, UM_USER_MOVE, NULL, NULL);
  688.       }
  689.       break;
  690.  
  691.     case UM_COMPUTER_MOVE:
  692.             player = computer;
  693.             ShowSidetoMove ();
  694. //            ElapsedTime (1);
  695.            if (flag.force) {
  696.                computer = opponent;
  697.                opponent = computer ^ 1;
  698.                WinPostMsg( hWnd, UM_USER_MOVE, NULL, NULL);
  699.                  }
  700.        else DosPostEventSem (hev1);   /* start thinking */
  701.        return(MRESULT) TRUE;
  702. //   break;
  703.  
  704.     case UM_NEW_GAME:
  705.              flag.bothsides = false;
  706.              flag.easy = false;
  707.              NewGame(hWnd);
  708.              if (UseBook) {
  709.              Book = BOOKFAIL;
  710.              } else {
  711.              Book = 0;
  712.              } /* endif */
  713.              UpdateDisplay (hWnd, 0, 0, 1, 0);
  714.              WinPostMsg(hWnd, UM_USER_MOVE, NULL, NULL);
  715.       break;
  716.  
  717.     case UM_UPDATE_MSG:
  718.         UpdateClocks ();
  719.         ShowResults (Best, Bstline, Bch);                      
  720. //         if (hStats && (player == computer)) {               /* cause lots of trouble */
  721. //             ShowCurrentMove (pntext, node->f, node->t);     /* disabled              */
  722. //         }
  723.       break;
  724.     } /* end of switch (msg) **********/
  725.  
  726.   return (WinDefWindowProc(hWnd, msg, mp1, mp2));
  727.   }  /******************* end of ChessProc ****************/
  728.  
  729.  
  730. /****************************************************************************
  731. *
  732. *  Routine: WndCreate(In):Static
  733. *
  734. *  Remarks: This routine processed the WM_CREATE message from the main
  735. *           client window.
  736. *
  737. *  Returns: None.
  738. \*****************************************/
  739. void FAR WndCreate(HWND hWnd)
  740.   {
  741.   FONTMETRICS fm;
  742.   hpsClient = WinGetPS(hWnd);
  743.  
  744.   /*
  745.   *  Load all the chess piece's bitmaps into a master memory ps for later.
  746.   */
  747.   hpsPieces = LoadChessPieces(hab);
  748.  
  749.   /*
  750.   *  Load the diamensions of the default system font.
  751.   */
  752.   GpiQueryFontMetrics(hpsClient, sizeof(fm), &fm);
  753.   xchar = (SHORT)fm.lEmInc;
  754.   ychar = (SHORT)fm.lMaxBaselineExt+(SHORT)fm.lExternalLeading;
  755.  
  756.   Create_Children(hWnd, xchar, ychar);
  757.  
  758.   GetStartupColors(szAppName);
  759.   /* 
  760.   *  Save the current color settings for the next time.
  761.   */
  762.   SaveColors(szAppName);
  763.  
  764.   WinReleasePS(hpsClient);
  765.   }
  766.  
  767.  
  768. /****************************************************************************
  769. *
  770. *  Routine: WndDestroy():Static
  771. *
  772. *  Remarks: This routine processed the WM_DESTROY message from the main
  773. *           client window.
  774. *
  775. *  Returns: None.
  776. */
  777. // void WndDestroy()
  778. //  {
  779. //  /*
  780. //  *  Save the current color settings for the next time.
  781. //  */
  782. //  SaveColors(szAppName);
  783.  
  784. //  WinReleasePS(hpsClient);
  785. //  }
  786.  
  787.  
  788. /****************************************************************************
  789. *
  790. *  Routine: WndPaint(In):Static
  791. *
  792. *  Remarks: This routine processed the WM_PAINT message from the main client
  793. *           client window.
  794. *
  795. *  Returns: None.
  796. */
  797.  void WndPaint(HWND hWnd)
  798.   {
  799.   RECTL rcl;
  800.  
  801.  
  802.   /*
  803.   *  Remember to properly repaint hi-lighted square.
  804.   */
  805.   if (FirstSq != -1)
  806.     {
  807.     POINTL ptl;
  808.     RECTL  rcl;
  809.  
  810.     QuerySqOrigin(FirstSq % 8, FirstSq / 8, &ptl);
  811.     rcl.xLeft   = ptl.x;
  812.     rcl.xRight  = ptl.x + 48;
  813.     rcl.yTop    = ptl.y;
  814.     rcl.yBottom = ptl.y - 48;
  815.     WinInvalidateRect(hWnd, &rcl, FALSE);
  816.     }
  817.  
  818.   /*
  819.   *  Retrieve the presentation space for drawing.
  820.   */
  821.   hps = WinBeginPaint(hWnd, 0, &rcl);
  822.  
  823.   /*
  824.   *  Clear the background.
  825.   */
  826.   WinFillRect(hps, &rcl, clrBackGround); 
  827.  
  828.   /*
  829.   *  Draw the chess board.
  830.   */
  831.   Draw_Board(hps, flag.reverse, clrBlackSquare, clrWhiteSquare);
  832.  
  833.   /*
  834.   *  Draw the coordinates if that option has been selected by the user.
  835.   */
  836.     DrawCoords(hps, flag.reverse, clrBackGround, clrText, coords);
  837.  
  838.   /*
  839.   *  Draw in the pieces.
  840.   */
  841.   DrawAllPieces(hps, hpsPieces, flag.reverse, boarddraw, colordraw,
  842.                 clrBlackPiece, clrWhitePiece);
  843.  
  844.   /*
  845.   *  All done with painting the client area.
  846.   */
  847.   WinEndPaint(hps);
  848.  
  849.   /*
  850.   *  If we have a selected square then hi-lighted it.
  851.   */
  852.   if (FirstSq != -1)
  853.     HiliteSquare(hWnd, FirstSq);
  854.   }
  855.  
  856.  
  857. /****************************************************************************
  858. *
  859. *  Routine: WndButton(In):Static
  860. *
  861. *  Remarks: This routine processed the various mouse button message from the
  862. *           main client window.
  863. *
  864. *  Returns: None.
  865. */
  866.  void WndButton(HWND hWnd, ULONG msg, MPARAM mp1)
  867.   {
  868.   POINTL ptl;
  869.   SHORT  Hit;
  870.   SHORT  x, y;
  871.  
  872.       hpsClient = WinGetPS(hWnd);
  873.  
  874.   switch (msg)
  875.     {
  876.     case WM_BUTTON1DOWN:
  877.       /*  If computer is thinking on human's time stop it at the first
  878.           button click.  add test to ensure that "human" can't interupt
  879.           the computer from thinking through its turn. */
  880.       if(!flag.bothsides)
  881.       {
  882.       if (User_Move)
  883.         {
  884.         flag.timeout   = true;
  885.         flag.bothsides = false;
  886.         }
  887.  
  888.       /* Don't continue unless reason to */
  889.       if (!(EditActive || User_Move))
  890.          break;
  891.  
  892.       ptl.x = SHORT1FROMMP(mp1);
  893.       ptl.y = SHORT2FROMMP(mp1);
  894.  
  895.       CkdQueryHitCoords(hpsClient, &ptl, &x, &y);
  896.  
  897.       if (x != -1 && y != -1)
  898.         Hit = y * 8 + x;
  899.       else
  900.         Hit = -1;
  901.  
  902.  
  903.          if ( Hit == -1 ){
  904.             if ( FirstSq != -1) {
  905.                UnHiliteSquare ( hWnd, FirstSq);
  906.                GotFirst = FALSE;
  907.                FirstSq = -1;
  908.             }
  909.             break;
  910.          }
  911.  
  912.          if ( GotFirst ) {
  913.             UnHiliteSquare( hWnd, FirstSq);
  914.             GotFirst = FALSE;
  915.  
  916.             if ( EditActive == TRUE) {
  917.                WinPostMsg(hWnd, UM_EDITBOARD, MPFROMSHORT((FirstSq<<8)|Hit), NULL);
  918.             } else if (User_Move == TRUE) {
  919.                WinPostMsg(hWnd, UM_USER_ENTERED_MOVE, MPFROMSHORT((FirstSq<<8)|Hit), NULL);
  920.             }
  921.             FirstSq = -1;
  922.          } else {
  923.             GotFirst = TRUE;
  924.             FirstSq = Hit;
  925.             HiliteSquare ( hWnd, Hit);
  926.          }
  927.       break;
  928.       }
  929.     }
  930.       WinReleasePS(hpsClient);
  931.   }
  932.  
  933. /*********************************************************************
  934.  *  Name : NotAvailableDlg
  935.  *
  936.  *  Description : Processes all messages sent to the NotAvailable
  937.  *                Information dialog box.
  938.  *
  939.  *  Concepts : Called for each message sent to the Product
  940.  *             Information dialog box.  The Product
  941.  *             Information box only has a button control so
  942.  *             this routine only processes WM_COMMAND
  943.  *             messages.  Any WM_COMMAND posted must have come
  944.  *             from the Ok button so we dismiss the dialog
  945.  *             upon receiving it.
  946.  *
  947.  *  API's : WinDismissDlg
  948.  *          WinDefDlgProc
  949.  *
  950.  * Parameters   : hwnd - Window handle to which message is addressed
  951.  *                msg - Message type
  952.  *                mp1 - First message parameter
  953.  *                mp2 - Second message parameter
  954.  *
  955.  *  Returns : Dependent upon message sent
  956.  *
  957.  ****************************************************************/
  958. MRESULT EXPENTRY NotAvailableDlg( HWND hWnd, ULONG msg, MPARAM mp1,
  959.                                   MPARAM mp2)
  960. {
  961.    switch(msg)
  962.    {
  963.       case WM_COMMAND:
  964.          /*
  965.           * No matter what the command, close the dialog
  966.           */
  967.          WinDismissDlg(hWnd, TRUE);
  968.          break;
  969.  
  970.       default:
  971.          return(WinDefDlgProc(hWnd, msg, mp1, mp2));
  972.          break;
  973.    }
  974.    return (MRESULT)0;
  975. }
  976. /********************** End of NotAvailable dialog procedure ****************/
  977.  
  978.  
  979.  
  980. MRESULT EXPENTRY AboutProc(HWND hDlg, ULONG msg, MPARAM mp1, MPARAM mp2)
  981.   {
  982.   switch (msg)
  983.     {
  984.     case WM_COMMAND:
  985.       switch (SHORT1FROMMP(mp1))
  986.         {
  987.         case IDC_OK:
  988.           WinDismissDlg(hDlg, TRUE);
  989.           break;
  990.         }
  991.       return (0);
  992.     }
  993.  
  994.   return (WinDefDlgProc(hDlg, msg, mp1, mp2));
  995.   }
  996.  
  997. /**************************************************************************
  998.  *
  999.  *  Name       : GetFileName()
  1000.  *
  1001.  *  Description: gets the name of the save file
  1002.  *
  1003.  *  Concepts:    called when the user needs to supply a name for
  1004.  *               the file to be saved
  1005.  *
  1006.  *                calls the standard file open dialog to get the
  1007.  *               file name.
  1008.  *
  1009.  *  API's      : WinLoadString
  1010.  *               WinFileDlg
  1011.  *
  1012.  *  Parameters : [none]
  1013.  *
  1014.  *  Return     :  TRUE if successful in getting a file name
  1015.  *                FALSE if not successful in getting a file name
  1016.  *
  1017.  *************************************************************************/
  1018. BOOL GetFileName(HWND hWnd)
  1019. {
  1020.    FILEDLG fdg;
  1021.    CHAR szTitle[80], szButton[80];
  1022.  
  1023.    fdg.cbSize = sizeof(FILEDLG);
  1024.  
  1025.    if(!WinLoadString(hab, 0, IDS_SAVE, 80, szTitle))
  1026.    {
  1027.        SMessageBox(hWnd, IDMSG_CANNOTLOADSTRING, IDS_CHESS);
  1028.        return FALSE;
  1029.    }
  1030.  
  1031.    if(!WinLoadString(hab, 0, IDS_SAVE, 80, szButton))
  1032.    {
  1033.        SMessageBox(hWnd, IDMSG_CANNOTLOADSTRING, IDS_CHESS);
  1034.        return FALSE;
  1035.    }
  1036.  
  1037.    fdg.pszTitle = szTitle;
  1038.    fdg.pszOKButton = szButton;
  1039.  
  1040.    fdg.ulUser = 0L;
  1041.    fdg.fl = FDS_HELPBUTTON | FDS_CENTER | FDS_SAVEAS_DIALOG;
  1042.    fdg.pfnDlgProc = (PFNWP)NULL;  /* (PFNWP)TemplateSaveFilterProc;*/
  1043.    fdg.lReturn = 0L;
  1044.    fdg.lSRC = 0L;
  1045.    fdg.hMod = (HMODULE)NULL;
  1046.    fdg.usDlgId = IDD_FILESAVE;
  1047.    fdg.x = 0;
  1048.    fdg.y = 0;
  1049.    fdg.pszIType = (PSZ)NULL;
  1050.    fdg.papszITypeList = (PAPSZ)NULL;
  1051.    fdg.pszIDrive = (PSZ)NULL;
  1052.    fdg.papszIDriveList = (PAPSZ)NULL;
  1053.    fdg.sEAType = (SHORT)0;
  1054.    fdg.papszFQFilename = (PAPSZ)NULL;
  1055.    fdg.ulFQFCount = 0L;
  1056.  
  1057.    strcpy(fdg.szFullFile, szFullPath);
  1058.  
  1059.    /* get the file */
  1060.    if(!WinFileDlg(HWND_DESKTOP, hWnd, &fdg))
  1061.        return FALSE;
  1062.  
  1063.    if(fdg.lReturn != IDC_OK)
  1064.        return FALSE;
  1065.  
  1066.    /* copy file name and path returned into buffers */
  1067.    strcpy(szFullPath, fdg.szFullFile);
  1068.  
  1069.    return TRUE;
  1070. }   /* End of GetFileName   */
  1071.  
  1072. /*======================================== calc thread ===========*/
  1073. VOID calc1 (ULONG dummy)
  1074.    {
  1075.      HAB habt; 
  1076.         habt= WinInitialize(0);
  1077.      for(;;){
  1078.         DosWaitEventSem(hev1, SEM_INDEFINITE_WAIT);
  1079.             if ( !(flag.quit || flag.mate || flag.force) ) {
  1080.             SelectMove ( computer, 1);
  1081.             if ( flag.beep ) WinAlarm(HWND_DESKTOP, WA_NOTE);
  1082.             }
  1083.             WinPostMsg( hwndClient, UM_USER_MOVE, NULL, NULL);
  1084.         DosResetEventSem(hev1, &ulPostCt1);
  1085.        }
  1086.      }
  1087.  
  1088. VOID calc2 (ULONG dummy)
  1089.    {
  1090.      HAB habt;
  1091.         habt= WinInitialize(0);
  1092.      for(;;){
  1093.         DosWaitEventSem(hev2, SEM_INDEFINITE_WAIT);
  1094.             if ( !(flag.quit || flag.mate || flag.force) ) {
  1095.             SelectMove ( opponent, 1);
  1096.             if ( flag.beep ) WinAlarm(HWND_DESKTOP, WA_NOTE);
  1097.             }
  1098.             WinPostMsg( hwndClient, UM_COMPUTER_MOVE, NULL, NULL);
  1099.         DosResetEventSem(hev2, &ulPostCt2);
  1100.        }
  1101.      }
  1102.  
  1103. VOID calc3 (ULONG dummy)
  1104.    {
  1105.      HAB habt;
  1106.      INT tmp; USHORT mv; CHAR s[10]; 
  1107.  
  1108.         habt= WinInitialize(0);
  1109.      for(;;){
  1110.         DosWaitEventSem(hev3, SEM_INDEFINITE_WAIT);
  1111.                time0 = time ( NULL);
  1112.                algbr ( hint>>8, hint&0x3f, false);
  1113.                strcpy (s, mvstr[0]);
  1114.                tmp = epsquare;
  1115.                if ( VerifyMove (hwndClient, s,1, &mv) )
  1116.                         {
  1117.                 Sdepth = 0;/*419 added */
  1118.                   SelectMove ( computer, 2);
  1119.                   VerifyMove ( hwndClient, s, 2, &mv);
  1120.                   if ( Sdepth>0 ) Sdepth --;
  1121.                         }
  1122.                ft = (time (NULL) - time0) ; /* *100?; since gnuchess4.0 time unit in 100th second */
  1123.                epsquare = tmp;
  1124.         DosResetEventSem(hev3, &ulPostCt3);
  1125.        }
  1126.      }
  1127.  
  1128. VOID trddsp (ULONG dummy)
  1129.    {
  1130.      for(;;){
  1131.       DosSleep(1000);           /* every 1 sec to update clocks */
  1132.           WinPostMsg( hwndClient, UM_UPDATE_MSG, NULL, NULL);
  1133.        }
  1134.      }
  1135.