Fix multi-leg promotions
[xboard.git] / winboard / woptions.c
index 8a8406a..34e3800 100644 (file)
@@ -1,7 +1,8 @@
 /*\r
  * woptions.c -- Options dialog box routines for WinBoard\r
  *\r
- * Copyright 2000, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.\r
+ * Copyright 2000, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 Free\r
+ * Software Foundation, Inc.\r
  *\r
  * Enhancements Copyright 2005 Alessandro Scotti\r
  *\r
@@ -212,6 +213,9 @@ GeneralOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
     CHECK_BOX(OPT_SmartMove, appData.oneClick); // [HGM] one-click\r
     CHECK_BOX(OPT_AutoTags, appData.autoDisplayTags); // [HGM]\r
     CHECK_BOX(OPT_AutoComment, appData.autoDisplayComment); // [HGM]\r
+    CHECK_BOX(OPT_Headers, appData.headers); // [HGM]\r
+    CHECK_BOX(OPT_Variations, appData.variations); // [HGM]\r
+    CHECK_BOX(OPT_AutoExtend, appData.autoExtend); // [HGM]\r
 \r
 #undef CHECK_BOX\r
 \r
@@ -263,6 +267,9 @@ GeneralOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
       appData.oneClick             =IS_CHECKED(OPT_SmartMove); // [HGM] one-click\r
       appData.autoDisplayTags      =IS_CHECKED(OPT_AutoTags); // [HGM]\r
       appData.autoDisplayComment   =IS_CHECKED(OPT_AutoComment); // [HGM]\r
+      appData.headers              =IS_CHECKED(OPT_Headers); // [HGM]\r
+      appData.variations           =IS_CHECKED(OPT_Variations); // [HGM]\r
+      appData.autoExtend           =IS_CHECKED(OPT_AutoExtend); // [HGM]\r
 \r
 #undef IS_CHECKED\r
 \r
@@ -434,7 +441,7 @@ PaintSampleSquare(
   /*\r
    * clean up\r
    */\r
-  SelectObject(hdcMem, oldBrushPiece);\r
+  SelectObject(hdcMem, oldBrushSquare);\r
   SelectObject(hdcMem, oldPen);\r
   DeleteObject(brushPiece);\r
   DeleteObject(brushPieceDetail);\r
@@ -843,7 +850,7 @@ int radioButton[] = {
     -1,\r
     -1,\r
     OPT_VariantShogi,\r
-    OPT_VariantXiangqi,\r
+    -1, // Chu\r
     OPT_VariantCourier,\r
     OPT_VariantGothic,\r
     OPT_VariantCapablanca,\r
@@ -858,10 +865,12 @@ int radioButton[] = {
     OPT_VariantGreat,\r
     -1, // Twilight,\r
     OPT_VariantMakruk,\r
-    OPT_VariantASEAN,\r
     OPT_VariantSChess,\r
     OPT_VariantGrand,\r
     OPT_VariantSpartan, // Spartan\r
+    OPT_VariantXiangqi,\r
+    OPT_VariantASEAN,\r
+    OPT_VariantLion,\r
     -2 // sentinel\r
 };\r
 \r
@@ -869,22 +878,40 @@ VariantClass
 VariantWhichRadio(HWND hDlg)\r
 {\r
   int i=0, j;\r
+  *engineVariant = NULLCHAR;\r
   while((j = radioButton[i++]) != -2) {\r
        if(j == -1) continue; // no menu button\r
        if(IsDlgButtonChecked(hDlg, j) &&\r
           (appData.noChessProgram || strstr(first.variants, VariantName(i-1)))) return (VariantClass) i-1;\r
   }\r
+  for(i=0; i<15; i++) { // check for engine-defined variants\r
+    if(IsDlgButtonChecked(hDlg, OPT_EngineVariant+i) ) {\r
+       GetDlgItemText(hDlg, OPT_EngineVariant+i, engineVariant, MSG_SIZ); // remember name, so we can resolve it later\r
+       return VariantUnknown;\r
+    }\r
+  }\r
   return gameInfo.variant; // If no button checked, keep old\r
 }\r
 \r
 void\r
 VariantShowRadio(HWND hDlg)\r
 {\r
+  char c = *engineVariant, *v, *p;\r
   int i=0, j;\r
   CheckDlgButton(hDlg, radioButton[gameInfo.variant], TRUE);\r
+  *engineVariant = NULLCHAR; // [HGM] kludge to prevent VariantName will always return engineVariant\r
   while((j = radioButton[i++]) != -2) {\r
        if(j == -1) continue; // no menu button\r
-       EnableWindow(GetDlgItem(hDlg, j), appData.noChessProgram || strstr(first.variants, VariantName(i-1)));\r
+       v = VariantName(i-1); p = strstr(first.variants, v);\r
+       EnableWindow(GetDlgItem(hDlg, j), appData.noChessProgram || p && (!*v || strlen(v) == strlen(p) || p[strlen(v)] == ','));\r
+  }\r
+  *engineVariant = c;\r
+  for(i=0; i<15; i++) { // initialize engine-defined variants\r
+    char *v = EngineDefinedVariant(&first, i); // get name of #i\r
+    if(v) { // there is such a variant\r
+       EnableWindow(GetDlgItem(hDlg, OPT_EngineVariant+i), TRUE);     // and enable the button\r
+       SetDlgItemText(hDlg, OPT_EngineVariant+i, v);                  // put its name on button\r
+    } else EnableWindow(GetDlgItem(hDlg, OPT_EngineVariant+i), FALSE); // no such variant; disable button\r
   }\r
 }\r
 \r
@@ -942,7 +969,7 @@ NewVariantDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
       }\r
 \r
       gameInfo.variant = v;\r
-      appData.variant = VariantName(v);\r
+      ASSIGN(appData.variant, VariantName(v));\r
 \r
       appData.NrFiles = (int) GetDlgItemInt(hDlg, IDC_Files, NULL, FALSE );\r
       appData.NrRanks = (int) GetDlgItemInt(hDlg, IDC_Ranks, NULL, FALSE );\r
@@ -955,6 +982,9 @@ NewVariantDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
       shuffleOpenings = FALSE; /* [HGM] shuffle: possible shuffle reset when we switch */\r
       startedFromPositionFile = FALSE; /* [HGM] loadPos: no longer valid in new variant */\r
       appData.pieceToCharTable = NULL;\r
+      ASSIGN(appData.pieceNickNames, "");\r
+      ASSIGN(appData.colorNickNames, "");\r
+      ASSIGN(appData.men, "");\r
       Reset(TRUE, TRUE);\r
 \r
       return TRUE;\r
@@ -1403,6 +1433,9 @@ IcsOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
       UpdateSampleText(hDlg, OPT_SampleSeek, &mca[ColorSeek]);\r
       break;\r
 \r
+\r
+\r
+\r
     case OPT_ChooseNormalColor:\r
       ColorizeTextPopup(hDlg, ColorNormal);\r
       UpdateSampleText(hDlg, OPT_SampleNormal, &mca[ColorNormal]);\r
@@ -1781,6 +1814,7 @@ FontsOptionsPopup(HWND hwnd)
 SoundComboData soundComboData[] = {\r
   {N_("Move"), NULL},\r
   {N_("Bell"), NULL},\r
+  {N_("Roar"), NULL},\r
   {N_("ICS Alarm"), NULL},\r
   {N_("ICS Win"), NULL},\r
   {N_("ICS Loss"), NULL},\r
@@ -2506,6 +2540,7 @@ LoadOptions(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
     SetDlgItemInt(hDlg, OPT_Stretch, appData.stretch, FALSE);\r
     CheckDlgButton(hDlg, OPT_Reversed, appData.ignoreColors);\r
     CheckDlgButton(hDlg, OPT_Mirror, appData.findMirror);\r
+    SetDlgItemText(hDlg, OPT_Counts,  "");\r
     switch (appData.searchMode) {\r
     case 1:\r
       CheckDlgButton(hDlg, OPT_Exact, TRUE);\r
@@ -2550,6 +2585,10 @@ LoadOptions(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
       appData.searchMode = LoadOptionsWhichRadio(hDlg);\r
       appData.ignoreColors = IsDlgButtonChecked(hDlg, OPT_Reversed);\r
       appData.findMirror   = IsDlgButtonChecked(hDlg, OPT_Mirror);\r
+      GetDlgItemText(hDlg, OPT_Counts, buf, MSG_SIZ);\r
+      appData.minPieces = appData.maxPieces = 0;\r
+      sscanf(buf, "%d-%d", &appData.minPieces, &appData.maxPieces);\r
+      if(appData.maxPieces < appData.minPieces) appData.maxPieces = appData.minPieces;\r
       EndDialog(hDlg, TRUE);\r
       return TRUE;\r
 \r
@@ -3009,6 +3048,13 @@ BOOL BrowseForFolder( const char * title, char * path )
     return result;\r
 }\r
 \r
+int\r
+IsMultiFormat(char *s)\r
+{\r
+  char *p = strchr(s, ':');\r
+  return p && p != s+1;\r
+}\r
+\r
 LRESULT CALLBACK UciOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
 {\r
   char buf[MAX_PATH];\r
@@ -3024,7 +3070,10 @@ LRESULT CALLBACK UciOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM
     /* Initialize the dialog items */\r
     SetDlgItemText( hDlg, IDC_PolyglotDir, appData.polyglotDir );\r
     SetDlgItemInt( hDlg, IDC_HashSize, appData.defaultHashSize, TRUE );\r
+    if(appData.defaultPathEGTB[0])\r
     SetDlgItemText( hDlg, IDC_PathToEGTB, appData.defaultPathEGTB );\r
+    else\r
+    SetDlgItemText( hDlg, IDC_PathToEGTB, appData.egtFormats );\r
     SetDlgItemInt( hDlg, IDC_SizeOfEGTB, appData.defaultCacheSizeEGTB, TRUE );\r
     CheckDlgButton( hDlg, IDC_UseBook, (BOOL) appData.usePolyglotBook );\r
     SetDlgItemText( hDlg, IDC_BookFile, appData.polyglotBook );\r
@@ -3038,6 +3087,8 @@ LRESULT CALLBACK UciOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM
     SetDlgItemInt( hDlg, IDC_Games, appData.defaultMatchGames, TRUE );\r
 \r
     SendDlgItemMessage( hDlg, IDC_PolyglotDir, EM_SETSEL, 0, -1 );\r
+    // [HGM] Yet another ponder duplicate\r
+    CheckDlgButton( hDlg, OPT_PonderNextMove, (BOOL) appData.ponderNextMove );\r
 \r
     return TRUE;\r
 \r
@@ -3049,14 +3100,19 @@ LRESULT CALLBACK UciOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM
       appData.defaultHashSize = GetDlgItemInt(hDlg, IDC_HashSize, NULL, FALSE );\r
       appData.defaultCacheSizeEGTB = GetDlgItemInt(hDlg, IDC_SizeOfEGTB, NULL, FALSE );\r
       GetDlgItemText( hDlg, IDC_PathToEGTB, buf, sizeof(buf) );\r
-      appData.defaultPathEGTB = strdup(buf);\r
+      if(IsMultiFormat(buf)) {\r
+        ASSIGN(appData.egtFormats, buf);\r
+      } else {\r
+        ASSIGN(appData.defaultPathEGTB, buf);\r
+      }\r
       GetDlgItemText( hDlg, IDC_BookFile, buf, sizeof(buf) );\r
       appData.polyglotBook = strdup(buf);\r
       appData.usePolyglotBook = (Boolean) IsDlgButtonChecked( hDlg, IDC_UseBook );\r
-      // [HGM] smp: get nr of cores:\r
+      // [HGM] smp: get nr of cores and ponder:\r
       oldCores = appData.smpCores;\r
       appData.smpCores = GetDlgItemInt(hDlg, IDC_Cores, NULL, FALSE );\r
       if(appData.smpCores != oldCores) NewSettingEvent(FALSE, &(first.maxCores), "cores", appData.smpCores);\r
+      PonderNextMoveEvent((Boolean) IsDlgButtonChecked( hDlg, OPT_PonderNextMove ));\r
       // [HGM] book: read tick boxes for own book use\r
       appData.firstHasOwnBookUCI  = (Boolean) IsDlgButtonChecked( hDlg, IDC_OwnBook1 );\r
       appData.secondHasOwnBookUCI = (Boolean) IsDlgButtonChecked( hDlg, IDC_OwnBook2 );\r
@@ -3091,6 +3147,7 @@ LRESULT CALLBACK UciOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM
           ofn.hwndOwner = hDlg;\r
           ofn.hInstance = hInst;\r
           ofn.lpstrFilter = filter;\r
+\r
           ofn.lpstrFile = buf;\r
           ofn.nMaxFile = sizeof(buf);\r
           ofn.lpstrTitle = _("Choose Book");\r