Fix multi-leg promotions
[xboard.git] / winboard / woptions.c
index 4d071ce..34e3800 100644 (file)
@@ -1,7 +1,8 @@
 /*\r
  * woptions.c -- Options dialog box routines for WinBoard\r
  *\r
- * Copyright 2000, 2009, 2010 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
@@ -135,6 +136,28 @@ VOID SetLoadOptionEnables(HWND hDlg);
 VOID SetSaveOptionEnables(HWND hDlg);\r
 VOID SetTimeControlEnables(HWND hDlg);\r
 \r
+char *\r
+InterpretFileName(char *buf, char *homeDir)\r
+{ // [HGM] file name relative to homeDir. (Taken out of SafeOptionsDialog, because it is generally useful)\r
+  char *result = NULL;\r
+  if ((isalpha(buf[0]) && buf[1] == ':') ||\r
+    (buf[0] == '\\' && buf[1] == '\\')) {\r
+    return strdup(buf);\r
+  } else {\r
+    char buf2[MSG_SIZ], buf3[MSG_SIZ];\r
+    char *dummy;\r
+    GetCurrentDirectory(MSG_SIZ, buf3);\r
+    SetCurrentDirectory(homeDir);\r
+    if (GetFullPathName(buf, MSG_SIZ, buf2, &dummy)) {\r
+      result = strdup(buf2);\r
+    } else {\r
+      result = strdup(buf);\r
+    }\r
+    SetCurrentDirectory(buf3);\r
+  }\r
+  return result;\r
+}\r
+\r
 /*---------------------------------------------------------------------------*\\r
  *\r
  * General Options Dialog functions\r
@@ -187,6 +210,12 @@ GeneralOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
     CHECK_BOX(OPT_ExtraInfoInMoveHistory, appData.showEvalInMoveHistory);\r
     CHECK_BOX(OPT_HighlightMoveArrow, appData.highlightMoveWithArrow);\r
     CHECK_BOX(OPT_AutoLogo, appData.autoLogo); // [HGM] logo\r
+    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
@@ -235,6 +264,12 @@ GeneralOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
       appData.testLegality         = IS_CHECKED(OPT_TestLegality);\r
       appData.highlightMoveWithArrow=IS_CHECKED(OPT_HighlightMoveArrow);\r
       appData.autoLogo             =IS_CHECKED(OPT_AutoLogo); // [HGM] logo\r
+      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
@@ -406,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
@@ -492,7 +527,7 @@ BoardOptionsWhichRadio(HWND hDlg)
 LRESULT CALLBACK\r
 BoardOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
 {\r
-  static Boolean  mono, white, flip;\r
+  static Boolean  mono, white, flip, fonts, bitmaps, grid;\r
   static BoardSize size;\r
   static COLORREF lsc, dsc, wpc, bpc, hsc, phc;\r
   static HBITMAP pieces[3];\r
@@ -569,20 +604,32 @@ BoardOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
     if (appData.upsideDown)\r
       CheckDlgButton(hDlg, OPT_UpsideDown, TRUE);\r
 \r
+    if (appData.useBitmaps)\r
+      CheckDlgButton(hDlg, OPT_Bitmaps, TRUE);\r
+\r
+    if (appData.useFont)\r
+      CheckDlgButton(hDlg, OPT_PieceFont, TRUE);\r
+\r
+    if (appData.overrideLineGap >= 0)\r
+      CheckDlgButton(hDlg, OPT_Grid, TRUE);\r
+\r
     pieces[0] = DoLoadBitmap(hInst, "n", SAMPLE_SQ_SIZE, "s");\r
     pieces[1] = DoLoadBitmap(hInst, "n", SAMPLE_SQ_SIZE, "w");\r
     pieces[2] = DoLoadBitmap(hInst, "n", SAMPLE_SQ_SIZE, "o");\r
 \r
     lsc = lightSquareColor;\r
     dsc = darkSquareColor;\r
-    wpc = whitePieceColor;\r
-    bpc = blackPieceColor;\r
+    fonts = appData.useFont;\r
+    wpc = fonts ? appData.fontBackColorWhite : whitePieceColor;\r
+    bpc = fonts ? appData.fontForeColorBlack : blackPieceColor;\r
     hsc = highlightSquareColor;\r
     phc = premoveHighlightColor;\r
     mono = appData.monoMode;\r
     white= appData.allWhite;\r
     flip = appData.upsideDown;\r
     size = boardSize;\r
+    bitmaps = appData.useBitmaps;\r
+    grid = appData.overrideLineGap >= 0;\r
 \r
     SetBoardOptionEnables(hDlg);\r
     return TRUE;\r
@@ -620,25 +667,38 @@ BoardOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
        ChangeBoardSize(size);\r
       }\r
 \r
+      if (bitmaps && !appData.useBitmaps) InitTextures();\r
+\r
       if ((mono != appData.monoMode) ||\r
          (lsc  != lightSquareColor) ||\r
          (dsc  != darkSquareColor) ||\r
-         (wpc  != whitePieceColor) ||\r
-         (bpc  != blackPieceColor) ||\r
+         (wpc  != fonts ? appData.fontBackColorWhite : whitePieceColor) ||\r
+         (bpc  != fonts ? appData.fontForeColorBlack : blackPieceColor) ||\r
          (hsc  != highlightSquareColor) ||\r
           (flip != appData.upsideDown) ||\r
           (white != appData.allWhite) ||\r
+          (fonts != appData.useFont) ||\r
+          (bitmaps != appData.useBitmaps) ||\r
+          (grid != appData.overrideLineGap >= 0) ||\r
          (phc  != premoveHighlightColor)) {\r
 \r
          lightSquareColor = lsc;\r
          darkSquareColor = dsc;\r
-         whitePieceColor = wpc;\r
-         blackPieceColor = bpc;\r
+         if(fonts) {\r
+           appData.fontBackColorWhite = wpc;\r
+           appData.fontForeColorBlack = bpc;\r
+         } else {\r
+           whitePieceColor = wpc;\r
+           blackPieceColor = bpc;\r
+         }\r
          highlightSquareColor = hsc;\r
          premoveHighlightColor = phc;\r
          appData.monoMode = mono;\r
           appData.allWhite = white;\r
           appData.upsideDown = flip;\r
+          appData.useFont = fonts;\r
+          appData.useBitmaps = bitmaps;\r
+          if(grid != appData.overrideLineGap >= 0) appData.overrideLineGap = grid - 1;\r
 \r
          InitDrawingColors();\r
          InitDrawingSizes(boardSize, 0);\r
@@ -646,6 +706,7 @@ BoardOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
       }\r
       DeleteObject(pieces[0]);\r
       DeleteObject(pieces[1]);\r
+\r
       DeleteObject(pieces[2]);\r
       return TRUE;\r
 \r
@@ -731,12 +792,22 @@ BoardOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
 \r
     case OPT_AllWhite:\r
       white = !white;\r
-      SetBoardOptionEnables(hDlg);\r
       break;\r
 \r
     case OPT_UpsideDown:\r
       flip = !flip;\r
-      SetBoardOptionEnables(hDlg);\r
+      break;\r
+\r
+    case OPT_Bitmaps:\r
+      bitmaps = !bitmaps;\r
+      break;\r
+\r
+    case OPT_PieceFont:\r
+      fonts = !fonts;\r
+      break;\r
+\r
+    case OPT_Grid:\r
+      grid = !grid;\r
       break;\r
     }\r
     break;\r
@@ -754,39 +825,94 @@ BoardOptionsPopup(HWND hwnd)
   FreeProcInstance(lpProc);\r
 }\r
 \r
+int radioButton[] = {\r
+    OPT_VariantNormal,\r
+    -1, // Loadable\r
+    OPT_VariantWildcastle,\r
+    OPT_VariantNocastle,\r
+    OPT_VariantFRC,\r
+    OPT_VariantBughouse,\r
+    OPT_VariantCrazyhouse,\r
+    OPT_VariantLosers,\r
+    OPT_VariantSuicide,\r
+    OPT_VariantGiveaway,\r
+    OPT_VariantTwoKings,\r
+    -1, //Kriegspiel\r
+    OPT_VariantAtomic,\r
+    OPT_Variant3Check,\r
+    OPT_VariantShatranj,\r
+    -1,\r
+    -1,\r
+    -1,\r
+    -1,\r
+    -1,\r
+    -1,\r
+    -1,\r
+    -1,\r
+    OPT_VariantShogi,\r
+    -1, // Chu\r
+    OPT_VariantCourier,\r
+    OPT_VariantGothic,\r
+    OPT_VariantCapablanca,\r
+    OPT_VariantKnightmate,\r
+    OPT_VariantFairy,        \r
+    OPT_VariantCylinder,\r
+    OPT_VariantFalcon,\r
+    OPT_VariantCRC,\r
+    OPT_VariantBerolina,\r
+    OPT_VariantJanus,\r
+    OPT_VariantSuper,\r
+    OPT_VariantGreat,\r
+    -1, // Twilight,\r
+    OPT_VariantMakruk,\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
 VariantClass\r
 VariantWhichRadio(HWND hDlg)\r
 {\r
-  return (IsDlgButtonChecked(hDlg, OPT_VariantFairy) ? VariantFairy :\r
-         (IsDlgButtonChecked(hDlg, OPT_VariantGothic) ? VariantGothic :\r
-         (IsDlgButtonChecked(hDlg, OPT_VariantCrazyhouse) ? VariantCrazyhouse :\r
-         (IsDlgButtonChecked(hDlg, OPT_VariantBughouse) ? VariantBughouse :\r
-         (IsDlgButtonChecked(hDlg, OPT_VariantCourier) ? VariantCourier :\r
-         (IsDlgButtonChecked(hDlg, OPT_VariantShatranj) ? VariantShatranj :\r
-         (IsDlgButtonChecked(hDlg, OPT_VariantShogi) ? VariantShogi :\r
-         (IsDlgButtonChecked(hDlg, OPT_VariantXiangqi) ? VariantXiangqi :\r
-         (IsDlgButtonChecked(hDlg, OPT_VariantCapablanca) ? VariantCapablanca :\r
-         (IsDlgButtonChecked(hDlg, OPT_VariantTwoKings) ? VariantTwoKings :\r
-         (IsDlgButtonChecked(hDlg, OPT_VariantKnightmate) ? VariantKnightmate :\r
-         (IsDlgButtonChecked(hDlg, OPT_VariantLosers) ? VariantLosers :\r
-         (IsDlgButtonChecked(hDlg, OPT_VariantSuicide) ? VariantSuicide :\r
-         (IsDlgButtonChecked(hDlg, OPT_VariantAtomic) ? VariantAtomic :\r
-         (IsDlgButtonChecked(hDlg, OPT_VariantShatranj) ? VariantShatranj :\r
-         (IsDlgButtonChecked(hDlg, OPT_VariantFRC) ? VariantFischeRandom :\r
-         (IsDlgButtonChecked(hDlg, OPT_VariantCylinder) ? VariantCylinder :\r
-         (IsDlgButtonChecked(hDlg, OPT_VariantFalcon) ? VariantFalcon :\r
-         (IsDlgButtonChecked(hDlg, OPT_VariantCRC) ? VariantCapaRandom :\r
-         (IsDlgButtonChecked(hDlg, OPT_VariantSuper) ? VariantSuper :\r
-         (IsDlgButtonChecked(hDlg, OPT_VariantBerolina) ? VariantBerolina :\r
-         (IsDlgButtonChecked(hDlg, OPT_VariantJanus) ? VariantJanus :\r
-         (IsDlgButtonChecked(hDlg, OPT_VariantWildcastle) ? VariantWildCastle :\r
-         (IsDlgButtonChecked(hDlg, OPT_VariantNocastle) ? VariantNoCastle :\r
-         (IsDlgButtonChecked(hDlg, OPT_Variant3Check) ? Variant3Check :\r
-         (IsDlgButtonChecked(hDlg, OPT_VariantGreat) ? VariantGreat :\r
-         (IsDlgButtonChecked(hDlg, OPT_VariantGiveaway) ? VariantGiveaway :\r
-         (IsDlgButtonChecked(hDlg, OPT_VariantTwilight) ? VariantTwilight :\r
-         (IsDlgButtonChecked(hDlg, OPT_VariantMakruk) ? VariantMakruk :\r
-          VariantNormal )))))))))))))))))))))))))))));\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
+       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
 LRESULT CALLBACK\r
@@ -800,97 +926,9 @@ NewVariantDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
     /* Center the dialog over the application window */\r
     CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));\r
     Translate(hDlg, DLG_NewVariant);\r
+\r
     /* Initialize the dialog items */\r
-    switch (gameInfo.variant) {\r
-    case VariantNormal:\r
-      CheckDlgButton(hDlg, OPT_VariantNormal, TRUE);\r
-      break;\r
-    case VariantCrazyhouse:\r
-      CheckDlgButton(hDlg, OPT_VariantCrazyhouse, TRUE);\r
-      break;\r
-    case VariantBughouse:\r
-      CheckDlgButton(hDlg, OPT_VariantBughouse, TRUE);\r
-      break;\r
-    case VariantShogi:\r
-      CheckDlgButton(hDlg, OPT_VariantShogi, TRUE);\r
-      break;\r
-    case VariantXiangqi:\r
-      CheckDlgButton(hDlg, OPT_VariantXiangqi, TRUE);\r
-      break;\r
-    case VariantCapablanca:\r
-      CheckDlgButton(hDlg, OPT_VariantCapablanca, TRUE);\r
-      break;\r
-    case VariantGothic:\r
-      CheckDlgButton(hDlg, OPT_VariantGothic, TRUE);\r
-      break;\r
-    case VariantCourier:\r
-      CheckDlgButton(hDlg, OPT_VariantCourier, TRUE);\r
-      break;\r
-    case VariantKnightmate:\r
-      CheckDlgButton(hDlg, OPT_VariantKnightmate, TRUE);\r
-      break;\r
-    case VariantTwoKings:\r
-      CheckDlgButton(hDlg, OPT_VariantTwoKings, TRUE);\r
-      break;\r
-    case VariantFairy:\r
-      CheckDlgButton(hDlg, OPT_VariantFairy, TRUE);\r
-      break;\r
-    case VariantAtomic:\r
-      CheckDlgButton(hDlg, OPT_VariantAtomic, TRUE);\r
-      break;\r
-    case VariantSuicide:\r
-      CheckDlgButton(hDlg, OPT_VariantSuicide, TRUE);\r
-      break;\r
-    case VariantLosers:\r
-      CheckDlgButton(hDlg, OPT_VariantLosers, TRUE);\r
-      break;\r
-    case VariantShatranj:\r
-      CheckDlgButton(hDlg, OPT_VariantShatranj, TRUE);\r
-      break;\r
-    case VariantFischeRandom:\r
-      CheckDlgButton(hDlg, OPT_VariantFRC, TRUE);\r
-      break;\r
-    case VariantCapaRandom:\r
-      CheckDlgButton(hDlg, OPT_VariantCRC, TRUE);\r
-      break;\r
-    case VariantFalcon:\r
-      CheckDlgButton(hDlg, OPT_VariantFalcon, TRUE);\r
-      break;\r
-    case VariantCylinder:\r
-      CheckDlgButton(hDlg, OPT_VariantCylinder, TRUE);\r
-      break;\r
-    case Variant3Check:\r
-      CheckDlgButton(hDlg, OPT_Variant3Check, TRUE);\r
-      break;\r
-    case VariantSuper:\r
-      CheckDlgButton(hDlg, OPT_VariantSuper, TRUE);\r
-      break;\r
-    case VariantBerolina:\r
-      CheckDlgButton(hDlg, OPT_VariantBerolina, TRUE);\r
-      break;\r
-    case VariantJanus:\r
-      CheckDlgButton(hDlg, OPT_VariantJanus, TRUE);\r
-      break;\r
-    case VariantWildCastle:\r
-      CheckDlgButton(hDlg, OPT_VariantWildcastle, TRUE);\r
-      break;\r
-    case VariantNoCastle:\r
-      CheckDlgButton(hDlg, OPT_VariantNocastle, TRUE);\r
-      break;\r
-    case VariantGreat:\r
-      CheckDlgButton(hDlg, OPT_VariantGreat, TRUE);\r
-      break;\r
-    case VariantGiveaway:\r
-      CheckDlgButton(hDlg, OPT_VariantGiveaway, TRUE);\r
-      break;\r
-    case VariantTwilight:\r
-      CheckDlgButton(hDlg, OPT_VariantTwilight, TRUE);\r
-      break;\r
-    case VariantMakruk:\r
-      CheckDlgButton(hDlg, OPT_VariantMakruk, TRUE);\r
-      break;\r
-    default: ;\r
-    }\r
+    VariantShowRadio(hDlg);\r
 \r
     SetDlgItemInt( hDlg, IDC_Files, -1, TRUE );\r
     SendDlgItemMessage( hDlg, IDC_Files, EM_SETSEL, 0, -1 );\r
@@ -931,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
@@ -944,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
@@ -1188,6 +1229,7 @@ IcsOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
     CHECK_BOX(OPT_AutoKibitz, appData.autoKibitz);\r
     CHECK_BOX(OPT_AutoComment, appData.autoComment);\r
     CHECK_BOX(OPT_AutoObserve, appData.autoObserve);\r
+    CHECK_BOX(OPT_AutoCreate, appData.autoCreateLogon);\r
     CHECK_BOX(OPT_GetMoveList, appData.getMoveList);\r
     CHECK_BOX(OPT_LocalLineEditing, appData.localLineEditing);\r
     CHECK_BOX(OPT_QuietPlay, appData.quietPlay);\r
@@ -1273,6 +1315,7 @@ IcsOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
       appData.autoKibitz       = IS_CHECKED(OPT_AutoKibitz);\r
       appData.autoComment      = IS_CHECKED(OPT_AutoComment);\r
       appData.autoObserve      = IS_CHECKED(OPT_AutoObserve);\r
+      appData.autoCreateLogon  = IS_CHECKED(OPT_AutoCreate);\r
       appData.getMoveList      = IS_CHECKED(OPT_GetMoveList);\r
       appData.localLineEditing = IS_CHECKED(OPT_LocalLineEditing);\r
       appData.quietPlay        = IS_CHECKED(OPT_QuietPlay);\r
@@ -1390,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
@@ -1464,6 +1510,8 @@ IcsOptionsPopup(HWND hwnd)
  *\r
 \*---------------------------------------------------------------------------*/\r
 \r
+char *string; // sorry\r
+\r
 VOID\r
 SetSampleFontText(HWND hwnd, int id, const MyFont *mf)\r
 {\r
@@ -1481,7 +1529,9 @@ SetSampleFontText(HWND hwnd, int id, const MyFont *mf)
                 mf->mfp.pointSize, mf->mfp.faceName,\r
                 mf->mfp.bold ? " bold" : "",\r
                 mf->mfp.italic ? " italic" : "");\r
+ if(id != OPT_SamplePieceFont)\r
   SetDlgItemText(hwnd, id, buf);\r
+ else SetDlgItemText(hwnd, id, string);\r
 \r
   hControl = GetDlgItem(hwnd, id);\r
   hdc = GetDC(hControl);\r
@@ -1518,6 +1568,7 @@ SetSampleFontText(HWND hwnd, int id, const MyFont *mf)
 \r
   /* format the text in the rich edit control */\r
   SendMessage(hControl, EM_SETCHARFORMAT, SCF_ALL, (LPARAM) &cf);\r
+ if(id != OPT_SamplePieceFont)\r
   SendMessage(hControl, EM_SETRECT, (WPARAM)0, (LPARAM) &rectFormat);\r
 \r
   /* clean up */\r
@@ -1542,8 +1593,9 @@ CopyFont(MyFont *dest, const MyFont *src)
 LRESULT CALLBACK\r
 FontOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
 {\r
-  static MyFont workFont[NUM_FONTS];\r
+  static MyFont workFont[NUM_FONTS+1];\r
   static BOOL firstPaint;\r
+  static char pieceText[] = "ABCDEFGHIJKLMNOPQRSTUVWXZabcdefghijklmnopqrstuvwxyz";\r
   int i;\r
   RECT rect;\r
 \r
@@ -1553,6 +1605,9 @@ FontOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
     /* copy the current font settings into a working copy */\r
     for (i=0; i < NUM_FONTS; i++)\r
       CopyFont(&workFont[i], font[boardSize][i]);\r
+    strncpy(workFont[NUM_FONTS].mfp.faceName, appData.renderPiecesWithFont, sizeof(workFont[NUM_FONTS].mfp.faceName));\r
+    workFont[NUM_FONTS].mfp.pointSize = 16.;\r
+    workFont[NUM_FONTS].mfp.charset = DEFAULT_CHARSET;\r
 \r
     Translate(hDlg, DLG_Fonts);\r
     if (!appData.icsActive)\r
@@ -1581,6 +1636,9 @@ FontOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
       SetSampleFontText(hDlg, OPT_SampleCommentsFont, &workFont[COMMENT_FONT]);\r
       SetSampleFontText(hDlg, OPT_SampleConsoleFont, &workFont[CONSOLE_FONT]);\r
       SetSampleFontText(hDlg, OPT_SampleMoveHistoryFont, &workFont[MOVEHISTORY_FONT]);\r
+      SetSampleFontText(hDlg, OPT_SampleGameListFont, &workFont[GAMELIST_FONT]);\r
+      string = appData.fontToPieceTable;\r
+      SetSampleFontText(hDlg, OPT_SamplePieceFont, &workFont[NUM_FONTS]);\r
       firstPaint = FALSE;\r
     }\r
     break;\r
@@ -1596,6 +1654,13 @@ FontOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
       for (i=0; i < NUM_FONTS; i++)\r
        CopyFont(font[boardSize][i], &workFont[i]);\r
 \r
+      { // Make new piece-to-char table\r
+       char buf[MSG_SIZ];\r
+       GetDlgItemText(hDlg, OPT_SamplePieceFont, buf, MSG_SIZ);\r
+       ASSIGN(appData.fontToPieceTable, buf);\r
+      }\r
+      ASSIGN(appData.renderPiecesWithFont, workFont[NUM_FONTS].mfp.faceName); // piece font\r
+\r
       /* a sad necessity due to the original design of having a separate\r
        * console font, tags font, and comment font for each board size.  IMHO\r
        * these fonts should not be dependent on the current board size.  I'm\r
@@ -1609,6 +1674,7 @@ FontOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
        CopyFont(font[i][CONSOLE_FONT],  &workFont[CONSOLE_FONT]);\r
        CopyFont(font[i][COMMENT_FONT],  &workFont[COMMENT_FONT]);\r
        CopyFont(font[i][MOVEHISTORY_FONT],  &workFont[MOVEHISTORY_FONT]);\r
+       CopyFont(font[i][GAMELIST_FONT],  &workFont[GAMELIST_FONT]);\r
       }\r
       /* end sad necessity */\r
 \r
@@ -1698,6 +1764,17 @@ FontOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
       SetSampleFontText(hDlg, OPT_SampleMoveHistoryFont, &workFont[MOVEHISTORY_FONT]);\r
       break;\r
 \r
+    case OPT_ChooseGameListFont:\r
+      MyCreateFont(hDlg, &workFont[GAMELIST_FONT]);\r
+      SetSampleFontText(hDlg, OPT_SampleGameListFont, &workFont[GAMELIST_FONT]);\r
+      break;\r
+\r
+    case OPT_ChoosePieceFont:\r
+      MyCreateFont(hDlg, &workFont[NUM_FONTS]);\r
+      string = pieceText;\r
+      SetSampleFontText(hDlg, OPT_SamplePieceFont, &workFont[NUM_FONTS]);\r
+      break;\r
+\r
     case OPT_DefaultFonts:\r
       for (i=0; i<NUM_FONTS; i++) {\r
        DeleteObject(&workFont[i].hf);\r
@@ -1711,6 +1788,7 @@ FontOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
       SetSampleFontText(hDlg, OPT_SampleCommentsFont, &workFont[COMMENT_FONT]);\r
       SetSampleFontText(hDlg, OPT_SampleConsoleFont, &workFont[CONSOLE_FONT]);\r
       SetSampleFontText(hDlg, OPT_SampleMoveHistoryFont, &workFont[MOVEHISTORY_FONT]);\r
+      SetSampleFontText(hDlg, OPT_SampleGameListFont, &workFont[GAMELIST_FONT]);\r
       break;\r
     }\r
   }\r
@@ -1736,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
@@ -2164,7 +2243,7 @@ ParseCommSettings(char *arg, DCB *dcb)
   if (cd->label == NULL) goto cant_parse;\r
   return;\r
 cant_parse:\r
-    ExitArgError(_("Can't parse com port settings"), arg);\r
+    ExitArgError(_("Can't parse com port settings"), arg, TRUE);\r
 }\r
 \r
 \r
@@ -2413,6 +2492,17 @@ CommPortOptionsPopup(HWND hwnd)
  *\r
 \*---------------------------------------------------------------------------*/\r
 \r
+int\r
+LoadOptionsWhichRadio(HWND hDlg)\r
+{\r
+  return (IsDlgButtonChecked(hDlg, OPT_Exact) ? 1 :\r
+         (IsDlgButtonChecked(hDlg, OPT_Subset) ? 2 :\r
+         (IsDlgButtonChecked(hDlg, OPT_Struct) ? 3 :\r
+         (IsDlgButtonChecked(hDlg, OPT_Material) ? 4 :\r
+         (IsDlgButtonChecked(hDlg, OPT_Range) ? 5 :\r
+         (IsDlgButtonChecked(hDlg, OPT_Difference) ? 6 : -1))))));\r
+}\r
+\r
 VOID\r
 SetLoadOptionEnables(HWND hDlg)\r
 {\r
@@ -2428,6 +2518,7 @@ LoadOptions(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
 {\r
   char buf[MSG_SIZ];\r
   float fnumber;\r
+  int ok;\r
 \r
   switch (message) {\r
   case WM_INITDIALOG: /* message: initialize dialog box */\r
@@ -2443,6 +2534,33 @@ LoadOptions(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
       CheckDlgButton(hDlg, OPT_Autostep, FALSE);\r
     }\r
     SetLoadOptionEnables(hDlg);\r
+    SetDlgItemInt(hDlg, OPT_elo1, appData.eloThreshold1, FALSE);\r
+    SetDlgItemInt(hDlg, OPT_elo2, appData.eloThreshold2, FALSE);\r
+    SetDlgItemInt(hDlg, OPT_date, appData.dateThreshold, FALSE);\r
+    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
+      break;\r
+    case 2:\r
+      CheckDlgButton(hDlg, OPT_Subset, TRUE);\r
+      break;\r
+    case 3:\r
+      CheckDlgButton(hDlg, OPT_Struct, TRUE);\r
+      break;\r
+    case 4:\r
+      CheckDlgButton(hDlg, OPT_Material, TRUE);\r
+      break;\r
+    case 5:\r
+      CheckDlgButton(hDlg, OPT_Range, TRUE);\r
+      break;\r
+    case 6:\r
+      CheckDlgButton(hDlg, OPT_Difference, TRUE);\r
+      break;\r
+    }\r
     return TRUE;\r
 \r
   case WM_COMMAND: /* message: received a command */\r
@@ -2460,6 +2578,17 @@ LoadOptions(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
       } else {\r
        appData.timeDelay = (float) -1.0;\r
       }\r
+      appData.eloThreshold1 = GetDlgItemInt(hDlg, OPT_elo1, &ok, FALSE);\r
+      appData.eloThreshold2 = GetDlgItemInt(hDlg, OPT_elo2, &ok, FALSE);\r
+      appData.dateThreshold = GetDlgItemInt(hDlg, OPT_date, &ok, FALSE);\r
+      appData.stretch = GetDlgItemInt(hDlg, OPT_Stretch, &ok, FALSE);\r
+      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
@@ -2547,7 +2676,7 @@ SaveOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
       if (IsDlgButtonChecked(hDlg, OPT_Autosave)) {\r
        appData.autoSaveGames = TRUE;\r
        if (IsDlgButtonChecked(hDlg, OPT_AVPrompt)) {\r
-         appData.saveGameFile = "";\r
+         ASSIGN(appData.saveGameFile, ""); // [HGM] make sure value is ALWAYS in allocated memory\r
        } else /*if (IsDlgButtonChecked(hDlg, OPT_AVToFile))*/ {\r
          GetDlgItemText(hDlg, OPT_AVFilename, buf, MSG_SIZ);\r
          if (*buf == NULLCHAR) {\r
@@ -2555,25 +2684,12 @@ SaveOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
                       _("Option Error"), MB_OK|MB_ICONEXCLAMATION);\r
            return FALSE;\r
          }\r
-         if ((isalpha(buf[0]) && buf[1] == ':') ||\r
-           (buf[0] == '\\' && buf[1] == '\\')) {\r
-           appData.saveGameFile = strdup(buf);\r
-         } else {\r
-           char buf2[MSG_SIZ], buf3[MSG_SIZ];\r
-           char *dummy;\r
-           GetCurrentDirectory(MSG_SIZ, buf3);\r
-           SetCurrentDirectory(installDir);\r
-           if (GetFullPathName(buf, MSG_SIZ, buf2, &dummy)) {\r
-             appData.saveGameFile = strdup(buf2);\r
-           } else {\r
-             appData.saveGameFile = strdup(buf);\r
-           }\r
-           SetCurrentDirectory(buf3);\r
-         }\r
+         FREE(appData.saveGameFile);\r
+         appData.saveGameFile = InterpretFileName(buf, homeDir);\r
        }\r
       } else {\r
        appData.autoSaveGames = FALSE;\r
-       appData.saveGameFile = "";\r
+       ASSIGN(appData.saveGameFile, "");\r
       }\r
       appData.oldSaveStyle = IsDlgButtonChecked(hDlg, OPT_Old);\r
       appData.saveOutOfBookInfo = IsDlgButtonChecked( hDlg, OPT_OutOfBookInfo );\r
@@ -2643,7 +2759,8 @@ LRESULT CALLBACK
 TimeControl(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
 {\r
   char buf[MSG_SIZ], *tc;\r
-  int mps, increment, odds1, odds2, st;\r
+  int mps, odds1, odds2, st;\r
+  float increment;\r
   BOOL ok, ok2;\r
 \r
   switch (message) {\r
@@ -2652,7 +2769,7 @@ TimeControl(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
     CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));\r
     Translate(hDlg, DLG_TimeControl);\r
     /* Initialize the dialog items */\r
-    if (appData.clockMode && !appData.icsActive) {\r
+    if (/*appData.clockMode &&*/ !appData.icsActive) { // [HGM] even if !clockMode, we could want to set it in tournament dialog\r
       if (searchTime) {\r
        CheckRadioButton(hDlg, OPT_TCUseMoves, OPT_TCUseFixed,\r
                         OPT_TCUseFixed);\r
@@ -2667,12 +2784,15 @@ TimeControl(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
        SetDlgItemText(hDlg, OPT_TCTime2, "");\r
        SetDlgItemText(hDlg, OPT_TCInc, "");\r
       } else {\r
+       int i = appData.timeIncrement;\r
+       if(i == appData.timeIncrement) snprintf(buf, MSG_SIZ, "%d", i);\r
+       else snprintf(buf, MSG_SIZ, "%4.2f", appData.timeIncrement);\r
        CheckRadioButton(hDlg, OPT_TCUseMoves, OPT_TCUseFixed,\r
                         OPT_TCUseInc);\r
        SetDlgItemText(hDlg, OPT_TCTime, "");\r
        SetDlgItemText(hDlg, OPT_TCMoves, "");\r
        SetDlgItemText(hDlg, OPT_TCTime2, appData.timeControl);\r
-       SetDlgItemInt(hDlg, OPT_TCInc, appData.timeIncrement, FALSE);\r
+       SetDlgItemText(hDlg, OPT_TCInc, buf);\r
       }\r
       SetDlgItemInt(hDlg, OPT_TCOdds1, 1, FALSE);\r
       SetDlgItemInt(hDlg, OPT_TCOdds2, 1, FALSE);\r
@@ -2712,7 +2832,8 @@ TimeControl(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
        }\r
       tc = buf;\r
       } else {\r
-       increment = GetDlgItemInt(hDlg, OPT_TCInc, &ok, FALSE);\r
+       GetDlgItemText(hDlg, OPT_TCInc, buf, MSG_SIZ);\r
+       ok = (sscanf(buf, "%f%c", &increment, buf) == 1);\r
        if (!ok || increment < 0) {\r
          MessageBox(hDlg, _("Invalid increment"),\r
                     _("Option Error"), MB_OK|MB_ICONEXCLAMATION);\r
@@ -2882,7 +3003,21 @@ VOID EnginePlayOptionsPopup(HWND hwnd)
  * UCI Options Dialog functions\r
  *\r
 \*---------------------------------------------------------------------------*/\r
-static BOOL BrowseForFolder( const char * title, char * path )\r
+INT CALLBACK BrowseCallbackProc(HWND hwnd, \r
+                                UINT uMsg,\r
+                                LPARAM lp, \r
+                                LPARAM pData) \r
+{\r
+    switch(uMsg) \r
+    {\r
+      case BFFM_INITIALIZED: \r
+        SendMessage(hwnd, BFFM_SETSELECTION, TRUE, (LPARAM)pData);\r
+        break;\r
+    }\r
+    return 0;\r
+}\r
+\r
+BOOL BrowseForFolder( const char * title, char * path )\r
 {\r
     BOOL result = FALSE;\r
     BROWSEINFO bi;\r
@@ -2892,6 +3027,8 @@ static BOOL BrowseForFolder( const char * title, char * path )
 \r
     bi.lpszTitle = title == 0 ? _("Choose Folder") : title;\r
     bi.ulFlags = BIF_RETURNONLYFSDIRS;\r
+    bi.lpfn = BrowseCallbackProc;\r
+    bi.lParam = (LPARAM) path;\r
 \r
     pidl = SHBrowseForFolder( &bi );\r
 \r
@@ -2911,6 +3048,13 @@ static 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
@@ -2926,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
@@ -2940,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
@@ -2951,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
@@ -2993,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