changes from H.G. Muller; version 4.3.2
[xboard.git] / winboard / winboard.c
index f9c566b..d2facc2 100644 (file)
@@ -1,6 +1,6 @@
-/* \r
+/*\r
  * WinBoard.c -- Windows NT front end to XBoard\r
- * $Id: winboard.c,v 2.3 2003/11/25 05:25:20 mann Exp $
+ * $Id: winboard.c,v 2.3 2003/11/25 05:25:20 mann Exp $\r
  *\r
  * Copyright 1991 by Digital Equipment Corporation, Maynard, Massachusetts.\r
  * Enhancements Copyright 1992-2001 Free Software Foundation, Inc.\r
@@ -57,7 +57,7 @@
 \r
 #include <stdio.h>\r
 #include <stdlib.h>\r
-#include <time.h>
+#include <time.h>\r
 #include <malloc.h>\r
 #include <sys/stat.h>\r
 #include <fcntl.h>\r
 #include "wsockerr.h"\r
 #include "defaults.h"\r
 \r
-#include "wsnap.h"
-
-void InitEngineUCI( const char * iniDir, ChessProgramState * cps );
-
-int myrandom(void);
-void mysrandom(unsigned int seed);
-
+#include "wsnap.h"\r
+\r
+void InitEngineUCI( const char * iniDir, ChessProgramState * cps );\r
+\r
+  int myrandom(void);\r
+  void mysrandom(unsigned int seed);\r
+\r
+extern int whiteFlag, blackFlag;\r
+\r
 typedef struct {\r
   ChessSquare piece;  \r
   POINT pos;      /* window coordinates of current pos */\r
@@ -148,7 +150,7 @@ char *icsNames;
 char *firstChessProgramNames;\r
 char *secondChessProgramNames;\r
 \r
-#define ARG_MAX 128*1024 /* [AS] For Roger Brown's very long list! */
+#define ARG_MAX 128*1024 /* [AS] For Roger Brown's very long list! */\r
 \r
 #define PALETTESIZE 256\r
 \r
@@ -164,7 +166,7 @@ ColorClass currentColorClass;
 \r
 HWND hCommPort = NULL;    /* currently open comm port */\r
 static HWND hwndPause;    /* pause button */\r
-static HBITMAP pieceBitmap[3][(int) WhiteKing + 1];\r
+static HBITMAP pieceBitmap[3][(int) BlackPawn]; /* [HGM] nr of bitmaps referred to bP in stead of wK */\r
 static HBRUSH lightSquareBrush, darkSquareBrush,\r
   whitePieceBrush, blackPieceBrush, iconBkgndBrush, outlineBrush;\r
 static POINT gridEndpoints[(BOARD_SIZE + 1) * 4];\r
@@ -179,18 +181,18 @@ static int doingSizing = FALSE;
 static int lastSizing = 0;\r
 static int prevStderrPort;\r
 \r
-/* [AS] Support for background textures */
-#define BACK_TEXTURE_MODE_DISABLED      0
-#define BACK_TEXTURE_MODE_PLAIN         1
-#define BACK_TEXTURE_MODE_FULL_RANDOM   2
-
-static HBITMAP liteBackTexture = NULL;
-static HBITMAP darkBackTexture = NULL;
-static int liteBackTextureMode = BACK_TEXTURE_MODE_PLAIN;
-static int darkBackTextureMode = BACK_TEXTURE_MODE_PLAIN;
-static int backTextureSquareSize = 0;
-static struct { int x; int y; int mode; } backTextureSquareInfo[BOARD_SIZE][BOARD_SIZE];
-
+/* [AS] Support for background textures */\r
+#define BACK_TEXTURE_MODE_DISABLED      0\r
+#define BACK_TEXTURE_MODE_PLAIN         1\r
+#define BACK_TEXTURE_MODE_FULL_RANDOM   2\r
+\r
+static HBITMAP liteBackTexture = NULL;\r
+static HBITMAP darkBackTexture = NULL;\r
+static int liteBackTextureMode = BACK_TEXTURE_MODE_PLAIN;\r
+static int darkBackTextureMode = BACK_TEXTURE_MODE_PLAIN;\r
+static int backTextureSquareSize = 0;\r
+static struct { int x; int y; int mode; } backTextureSquareInfo[BOARD_SIZE][BOARD_SIZE];\r
+\r
 #if __GNUC__ && !defined(_winmajor)\r
 #define oldDialog 0 /* cygwin doesn't define _winmajor; mingw does */\r
 #else\r
@@ -239,24 +241,24 @@ SizeInfo sizeInfo[] =
 #define MF(x) {x, {0, }, {0, }, 0}\r
 MyFont fontRec[NUM_SIZES][NUM_FONTS] =\r
 {\r
-  { MF(CLOCK_FONT_TINY), MF(MESSAGE_FONT_TINY), MF(COORD_FONT_TINY), MF(CONSOLE_FONT_TINY), MF(COMMENT_FONT_TINY), MF(EDITTAGS_FONT_TINY), MF(MOVEHISTORY_FONT_ALL) },
-  { MF(CLOCK_FONT_TEENY), MF(MESSAGE_FONT_TEENY), MF(COORD_FONT_TEENY), MF(CONSOLE_FONT_TEENY), MF(COMMENT_FONT_TEENY), MF(EDITTAGS_FONT_TEENY), MF(MOVEHISTORY_FONT_ALL) },
-  { MF(CLOCK_FONT_DINKY), MF(MESSAGE_FONT_DINKY), MF(COORD_FONT_DINKY), MF(CONSOLE_FONT_DINKY), MF(COMMENT_FONT_DINKY), MF(EDITTAGS_FONT_DINKY), MF(MOVEHISTORY_FONT_ALL) },
-  { MF(CLOCK_FONT_PETITE), MF(MESSAGE_FONT_PETITE), MF(COORD_FONT_PETITE), MF(CONSOLE_FONT_PETITE), MF(COMMENT_FONT_PETITE), MF(EDITTAGS_FONT_PETITE), MF(MOVEHISTORY_FONT_ALL) },
-  { MF(CLOCK_FONT_SLIM), MF(MESSAGE_FONT_SLIM), MF(COORD_FONT_SLIM), MF(CONSOLE_FONT_SLIM), MF(COMMENT_FONT_SLIM), MF(EDITTAGS_FONT_SLIM), MF(MOVEHISTORY_FONT_ALL) },
-  { MF(CLOCK_FONT_SMALL), MF(MESSAGE_FONT_SMALL), MF(COORD_FONT_SMALL), MF(CONSOLE_FONT_SMALL), MF(COMMENT_FONT_SMALL), MF(EDITTAGS_FONT_SMALL), MF(MOVEHISTORY_FONT_ALL) },
-  { MF(CLOCK_FONT_MEDIOCRE), MF(MESSAGE_FONT_MEDIOCRE), MF(COORD_FONT_MEDIOCRE), MF(CONSOLE_FONT_MEDIOCRE), MF(COMMENT_FONT_MEDIOCRE), MF(EDITTAGS_FONT_MEDIOCRE), MF(MOVEHISTORY_FONT_ALL) },
-  { MF(CLOCK_FONT_MIDDLING), MF(MESSAGE_FONT_MIDDLING), MF(COORD_FONT_MIDDLING), MF(CONSOLE_FONT_MIDDLING), MF(COMMENT_FONT_MIDDLING), MF(EDITTAGS_FONT_MIDDLING), MF(MOVEHISTORY_FONT_ALL) },
-  { MF(CLOCK_FONT_AVERAGE), MF(MESSAGE_FONT_AVERAGE), MF(COORD_FONT_AVERAGE), MF(CONSOLE_FONT_AVERAGE), MF(COMMENT_FONT_AVERAGE), MF(EDITTAGS_FONT_AVERAGE), MF(MOVEHISTORY_FONT_ALL) },
-  { MF(CLOCK_FONT_MODERATE), MF(MESSAGE_FONT_MODERATE), MF(COORD_FONT_MODERATE), MF(CONSOLE_FONT_MODERATE), MF(COMMENT_FONT_MODERATE), MF(EDITTAGS_FONT_MODERATE), MF(MOVEHISTORY_FONT_ALL) },
-  { MF(CLOCK_FONT_MEDIUM), MF(MESSAGE_FONT_MEDIUM), MF(COORD_FONT_MEDIUM), MF(CONSOLE_FONT_MEDIUM), MF(COMMENT_FONT_MEDIUM), MF(EDITTAGS_FONT_MEDIUM), MF(MOVEHISTORY_FONT_ALL) },
-  { MF(CLOCK_FONT_BULKY), MF(MESSAGE_FONT_BULKY), MF(COORD_FONT_BULKY), MF(CONSOLE_FONT_BULKY), MF(COMMENT_FONT_BULKY), MF(EDITTAGS_FONT_BULKY), MF(MOVEHISTORY_FONT_ALL) },
-  { MF(CLOCK_FONT_LARGE), MF(MESSAGE_FONT_LARGE), MF(COORD_FONT_LARGE), MF(CONSOLE_FONT_LARGE), MF(COMMENT_FONT_LARGE), MF(EDITTAGS_FONT_LARGE), MF(MOVEHISTORY_FONT_ALL) },
-  { MF(CLOCK_FONT_BIG), MF(MESSAGE_FONT_BIG), MF(COORD_FONT_BIG), MF(CONSOLE_FONT_BIG), MF(COMMENT_FONT_BIG), MF(EDITTAGS_FONT_BIG), MF(MOVEHISTORY_FONT_ALL) },
-  { MF(CLOCK_FONT_HUGE), MF(MESSAGE_FONT_HUGE), MF(COORD_FONT_HUGE), MF(CONSOLE_FONT_HUGE), MF(COMMENT_FONT_HUGE), MF(EDITTAGS_FONT_HUGE), MF(MOVEHISTORY_FONT_ALL) },
-  { MF(CLOCK_FONT_GIANT), MF(MESSAGE_FONT_GIANT), MF(COORD_FONT_GIANT), MF(CONSOLE_FONT_GIANT), MF(COMMENT_FONT_GIANT), MF(EDITTAGS_FONT_GIANT), MF(MOVEHISTORY_FONT_ALL) },
-  { MF(CLOCK_FONT_COLOSSAL), MF(MESSAGE_FONT_COLOSSAL), MF(COORD_FONT_COLOSSAL), MF(CONSOLE_FONT_COLOSSAL), MF(COMMENT_FONT_COLOSSAL), MF(EDITTAGS_FONT_COLOSSAL), MF(MOVEHISTORY_FONT_ALL) },
-  { MF(CLOCK_FONT_TITANIC), MF(MESSAGE_FONT_TITANIC), MF(COORD_FONT_TITANIC), MF(CONSOLE_FONT_TITANIC), MF(COMMENT_FONT_TITANIC), MF(EDITTAGS_FONT_TITANIC), MF(MOVEHISTORY_FONT_ALL) },
+  { MF(CLOCK_FONT_TINY), MF(MESSAGE_FONT_TINY), MF(COORD_FONT_TINY), MF(CONSOLE_FONT_TINY), MF(COMMENT_FONT_TINY), MF(EDITTAGS_FONT_TINY), MF(MOVEHISTORY_FONT_ALL) },\r
+  { MF(CLOCK_FONT_TEENY), MF(MESSAGE_FONT_TEENY), MF(COORD_FONT_TEENY), MF(CONSOLE_FONT_TEENY), MF(COMMENT_FONT_TEENY), MF(EDITTAGS_FONT_TEENY), MF(MOVEHISTORY_FONT_ALL) },\r
+  { MF(CLOCK_FONT_DINKY), MF(MESSAGE_FONT_DINKY), MF(COORD_FONT_DINKY), MF(CONSOLE_FONT_DINKY), MF(COMMENT_FONT_DINKY), MF(EDITTAGS_FONT_DINKY), MF(MOVEHISTORY_FONT_ALL) },\r
+  { MF(CLOCK_FONT_PETITE), MF(MESSAGE_FONT_PETITE), MF(COORD_FONT_PETITE), MF(CONSOLE_FONT_PETITE), MF(COMMENT_FONT_PETITE), MF(EDITTAGS_FONT_PETITE), MF(MOVEHISTORY_FONT_ALL) },\r
+  { MF(CLOCK_FONT_SLIM), MF(MESSAGE_FONT_SLIM), MF(COORD_FONT_SLIM), MF(CONSOLE_FONT_SLIM), MF(COMMENT_FONT_SLIM), MF(EDITTAGS_FONT_SLIM), MF(MOVEHISTORY_FONT_ALL) },\r
+  { MF(CLOCK_FONT_SMALL), MF(MESSAGE_FONT_SMALL), MF(COORD_FONT_SMALL), MF(CONSOLE_FONT_SMALL), MF(COMMENT_FONT_SMALL), MF(EDITTAGS_FONT_SMALL), MF(MOVEHISTORY_FONT_ALL) },\r
+  { MF(CLOCK_FONT_MEDIOCRE), MF(MESSAGE_FONT_MEDIOCRE), MF(COORD_FONT_MEDIOCRE), MF(CONSOLE_FONT_MEDIOCRE), MF(COMMENT_FONT_MEDIOCRE), MF(EDITTAGS_FONT_MEDIOCRE), MF(MOVEHISTORY_FONT_ALL) },\r
+  { MF(CLOCK_FONT_MIDDLING), MF(MESSAGE_FONT_MIDDLING), MF(COORD_FONT_MIDDLING), MF(CONSOLE_FONT_MIDDLING), MF(COMMENT_FONT_MIDDLING), MF(EDITTAGS_FONT_MIDDLING), MF(MOVEHISTORY_FONT_ALL) },\r
+  { MF(CLOCK_FONT_AVERAGE), MF(MESSAGE_FONT_AVERAGE), MF(COORD_FONT_AVERAGE), MF(CONSOLE_FONT_AVERAGE), MF(COMMENT_FONT_AVERAGE), MF(EDITTAGS_FONT_AVERAGE), MF(MOVEHISTORY_FONT_ALL) },\r
+  { MF(CLOCK_FONT_MODERATE), MF(MESSAGE_FONT_MODERATE), MF(COORD_FONT_MODERATE), MF(CONSOLE_FONT_MODERATE), MF(COMMENT_FONT_MODERATE), MF(EDITTAGS_FONT_MODERATE), MF(MOVEHISTORY_FONT_ALL) },\r
+  { MF(CLOCK_FONT_MEDIUM), MF(MESSAGE_FONT_MEDIUM), MF(COORD_FONT_MEDIUM), MF(CONSOLE_FONT_MEDIUM), MF(COMMENT_FONT_MEDIUM), MF(EDITTAGS_FONT_MEDIUM), MF(MOVEHISTORY_FONT_ALL) },\r
+  { MF(CLOCK_FONT_BULKY), MF(MESSAGE_FONT_BULKY), MF(COORD_FONT_BULKY), MF(CONSOLE_FONT_BULKY), MF(COMMENT_FONT_BULKY), MF(EDITTAGS_FONT_BULKY), MF(MOVEHISTORY_FONT_ALL) },\r
+  { MF(CLOCK_FONT_LARGE), MF(MESSAGE_FONT_LARGE), MF(COORD_FONT_LARGE), MF(CONSOLE_FONT_LARGE), MF(COMMENT_FONT_LARGE), MF(EDITTAGS_FONT_LARGE), MF(MOVEHISTORY_FONT_ALL) },\r
+  { MF(CLOCK_FONT_BIG), MF(MESSAGE_FONT_BIG), MF(COORD_FONT_BIG), MF(CONSOLE_FONT_BIG), MF(COMMENT_FONT_BIG), MF(EDITTAGS_FONT_BIG), MF(MOVEHISTORY_FONT_ALL) },\r
+  { MF(CLOCK_FONT_HUGE), MF(MESSAGE_FONT_HUGE), MF(COORD_FONT_HUGE), MF(CONSOLE_FONT_HUGE), MF(COMMENT_FONT_HUGE), MF(EDITTAGS_FONT_HUGE), MF(MOVEHISTORY_FONT_ALL) },\r
+  { MF(CLOCK_FONT_GIANT), MF(MESSAGE_FONT_GIANT), MF(COORD_FONT_GIANT), MF(CONSOLE_FONT_GIANT), MF(COMMENT_FONT_GIANT), MF(EDITTAGS_FONT_GIANT), MF(MOVEHISTORY_FONT_ALL) },\r
+  { MF(CLOCK_FONT_COLOSSAL), MF(MESSAGE_FONT_COLOSSAL), MF(COORD_FONT_COLOSSAL), MF(CONSOLE_FONT_COLOSSAL), MF(COMMENT_FONT_COLOSSAL), MF(EDITTAGS_FONT_COLOSSAL), MF(MOVEHISTORY_FONT_ALL) },\r
+  { MF(CLOCK_FONT_TITANIC), MF(MESSAGE_FONT_TITANIC), MF(COORD_FONT_TITANIC), MF(CONSOLE_FONT_TITANIC), MF(COMMENT_FONT_TITANIC), MF(EDITTAGS_FONT_TITANIC), MF(MOVEHISTORY_FONT_ALL) },\r
 };\r
 \r
 MyFont *font[NUM_SIZES][NUM_FONTS];\r
@@ -383,41 +385,42 @@ VOID APIENTRY MenuPopup(HWND hwnd, POINT pt, HMENU hmenu, UINT def);
 void ParseIcsTextMenu(char *icsTextMenuString);\r
 VOID PopUpMoveDialog(char firstchar);\r
 VOID UpdateSampleText(HWND hDlg, int id, MyColorizeAttribs *mca);\r
-
-/* [AS] */
-int NewGameFRC();
-int GameListOptions();
-
-HWND moveHistoryDialog = NULL;
-BOOLEAN moveHistoryDialogUp = FALSE;
-
-WindowPlacement wpMoveHistory;
-
-HWND evalGraphDialog = NULL;
-BOOLEAN evalGraphDialogUp = FALSE;
-
-WindowPlacement wpEvalGraph;
-
-HWND engineOutputDialog = NULL;
-BOOLEAN engineOutputDialogUp = FALSE;
-
-WindowPlacement wpEngineOutput;
-
-VOID MoveHistoryPopUp();
-VOID MoveHistoryPopDown();
-VOID MoveHistorySet( char movelist[][2*MOVE_LEN], int first, int last, int current, ChessProgramStats_Move * pvInfo );
-BOOL MoveHistoryIsUp();
-
-VOID EvalGraphSet( int first, int last, int current, ChessProgramStats_Move * pvInfo );
-VOID EvalGraphPopUp();
-VOID EvalGraphPopDown();
-BOOL EvalGraphIsUp();
-
-VOID EngineOutputPopUp();
-VOID EngineOutputPopDown();
-BOOL EngineOutputIsUp();
-VOID EngineOutputUpdate( FrontEndProgramStats * stats );
 \r
+/* [AS] */\r
+int NewGameFRC();\r
+int GameListOptions();\r
+\r
+HWND moveHistoryDialog = NULL;\r
+BOOLEAN moveHistoryDialogUp = FALSE;\r
+\r
+WindowPlacement wpMoveHistory;\r
+\r
+HWND evalGraphDialog = NULL;\r
+BOOLEAN evalGraphDialogUp = FALSE;\r
+\r
+WindowPlacement wpEvalGraph;\r
+\r
+HWND engineOutputDialog = NULL;\r
+BOOLEAN engineOutputDialogUp = FALSE;\r
+\r
+WindowPlacement wpEngineOutput;\r
+\r
+VOID MoveHistoryPopUp();\r
+VOID MoveHistoryPopDown();\r
+VOID MoveHistorySet( char movelist[][2*MOVE_LEN], int first, int last, int current, ChessProgramStats_Move * pvInfo );\r
+BOOL MoveHistoryIsUp();\r
+\r
+VOID EvalGraphSet( int first, int last, int current, ChessProgramStats_Move * pvInfo );\r
+VOID EvalGraphPopUp();\r
+VOID EvalGraphPopDown();\r
+BOOL EvalGraphIsUp();\r
+\r
+VOID EngineOutputPopUp();\r
+VOID EngineOutputPopDown();\r
+BOOL EngineOutputIsUp();\r
+VOID EngineOutputUpdate( FrontEndProgramStats * stats );\r
+\r
+VOID GothicPopUp(char *title);\r
 /*\r
  * Setting "frozen" should disable all user input other than deleting\r
  * the window.  We do this while engines are initializing themselves.\r
@@ -464,7 +467,7 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
        LPSTR lpCmdLine, int nCmdShow)\r
 {\r
   MSG msg;\r
-  HANDLE hAccelMain, hAccelNoAlt, hAccelNoICS;
+  HANDLE hAccelMain, hAccelNoAlt, hAccelNoICS;\r
 \r
   debugFP = stderr;\r
 \r
@@ -480,7 +483,7 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
 \r
   hAccelMain = LoadAccelerators (hInstance, szAppName);\r
   hAccelNoAlt = LoadAccelerators (hInstance, "NO_ALT");\r
-  hAccelNoICS = LoadAccelerators( hInstance, "NO_ICS"); /* [AS] No Ctrl-V on ICS!!! */
+  hAccelNoICS = LoadAccelerators( hInstance, "NO_ICS"); /* [AS] No Ctrl-V on ICS!!! */\r
 \r
   /* Acquire and dispatch messages until a WM_QUIT message is received. */\r
 \r
@@ -490,14 +493,14 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    0))   /* highest message to examine */\r
     {\r
       if (!(commentDialog && IsDialogMessage(commentDialog, &msg)) &&\r
-          !(moveHistoryDialog && IsDialogMessage(moveHistoryDialog, &msg)) &&
-          !(evalGraphDialog && IsDialogMessage(evalGraphDialog, &msg)) &&
-          !(engineOutputDialog && IsDialogMessage(engineOutputDialog, &msg)) &&
+          !(moveHistoryDialog && IsDialogMessage(moveHistoryDialog, &msg)) &&\r
+          !(evalGraphDialog && IsDialogMessage(evalGraphDialog, &msg)) &&\r
+          !(engineOutputDialog && IsDialogMessage(engineOutputDialog, &msg)) &&\r
          !(editTagsDialog && IsDialogMessage(editTagsDialog, &msg)) &&\r
          !(gameListDialog && IsDialogMessage(gameListDialog, &msg)) &&\r
          !(errorDialog && IsDialogMessage(errorDialog, &msg)) &&\r
          !(!frozen && TranslateAccelerator(hwndMain, hAccelMain, &msg)) &&\r
-          !(!hwndConsole && TranslateAccelerator(hwndMain, hAccelNoICS, &msg)) &&
+          !(!hwndConsole && TranslateAccelerator(hwndMain, hAccelNoICS, &msg)) &&\r
          !(!hwndConsole && TranslateAccelerator(hwndMain, hAccelNoAlt, &msg))) {\r
        TranslateMessage(&msg); /* Translates virtual key codes */\r
        DispatchMessage(&msg);  /* Dispatches message to window */\r
@@ -558,9 +561,12 @@ int screenHeight, screenWidth;
 void\r
 EnsureOnScreen(int *x, int *y)\r
 {\r
+  int gap = GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYCAPTION);\r
   /* Be sure window at (x,y) is not off screen (or even mostly off screen) */\r
   if (*x > screenWidth - 32) *x = 0;\r
   if (*y > screenHeight - 32) *y = 0;\r
+  if (*x < 10) *x = 10;\r
+  if (*y < gap) *y = gap;\r
 }\r
 \r
 BOOL\r
@@ -580,15 +586,15 @@ InitInstance(HINSTANCE hInstance, int nCmdShow, LPSTR lpCmdLine)
   }\r
   InitAppData(lpCmdLine);      /* Get run-time parameters */\r
   if (appData.debugMode) {\r
-    debugFP = fopen(appData.nameOfDebugFile, "w");
+    debugFP = fopen(appData.nameOfDebugFile, "w");\r
     setbuf(debugFP, NULL);\r
   }\r
 \r
   InitBackEnd1();\r
 \r
-  InitEngineUCI( installDir, &first );
-  InitEngineUCI( installDir, &second );
-
+  InitEngineUCI( installDir, &first );\r
+  InitEngineUCI( installDir, &second );\r
+\r
   /* Create a main window for this application instance. */\r
   hwnd = CreateWindow(szAppName, szTitle,\r
                      (WS_OVERLAPPEDWINDOW & ~WS_MAXIMIZEBOX),\r
@@ -612,7 +618,9 @@ InitInstance(HINSTANCE hInstance, int nCmdShow, LPSTR lpCmdLine)
        size that fits on this screen as the default. */\r
     InitDrawingSizes((BoardSize)ibs, 0);\r
     if (boardSize == (BoardSize)-1 &&\r
-       winHeight <= screenHeight && winWidth <= screenWidth) {\r
+        winHeight <= screenHeight\r
+           - GetSystemMetrics(SM_CYFRAME) - GetSystemMetrics(SM_CYCAPTION) - 10\r
+        && winWidth <= screenWidth) {\r
       boardSize = (BoardSize)ibs;\r
     }\r
   }\r
@@ -620,47 +628,47 @@ InitInstance(HINSTANCE hInstance, int nCmdShow, LPSTR lpCmdLine)
   InitMenuChecks();\r
   buttonCount = GetSystemMetrics(SM_CMOUSEBUTTONS);\r
 \r
-  /* [AS] Load textures if specified */
-  ZeroMemory( &backTextureSquareInfo, sizeof(backTextureSquareInfo) );
-
-  if( appData.liteBackTextureFile && appData.liteBackTextureFile[0] != NULLCHAR && appData.liteBackTextureFile[0] != '*' ) {
-      liteBackTexture = LoadImage( 0, appData.liteBackTextureFile, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );
-      liteBackTextureMode = appData.liteBackTextureMode;
-
-      if (liteBackTexture == NULL && appData.debugMode) {
-          fprintf( debugFP, "Unable to load lite texture bitmap '%s'\n", appData.liteBackTextureFile );
-      }
-  }
-
-  if( appData.darkBackTextureFile && appData.darkBackTextureFile[0] != NULLCHAR && appData.darkBackTextureFile[0] != '*' ) {
-      darkBackTexture = LoadImage( 0, appData.darkBackTextureFile, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );
-      darkBackTextureMode = appData.darkBackTextureMode;
-
-      if (darkBackTexture == NULL && appData.debugMode) {
-          fprintf( debugFP, "Unable to load dark texture bitmap '%s'\n", appData.darkBackTextureFile );
-      }
-  }
-
-  mysrandom( (unsigned) time(NULL) );
-
+  /* [AS] Load textures if specified */\r
+  ZeroMemory( &backTextureSquareInfo, sizeof(backTextureSquareInfo) );\r
+  \r
+  if( appData.liteBackTextureFile && appData.liteBackTextureFile[0] != NULLCHAR && appData.liteBackTextureFile[0] != '*' ) {\r
+      liteBackTexture = LoadImage( 0, appData.liteBackTextureFile, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );\r
+      liteBackTextureMode = appData.liteBackTextureMode;\r
+\r
+      if (liteBackTexture == NULL && appData.debugMode) {\r
+          fprintf( debugFP, "Unable to load lite texture bitmap '%s'\n", appData.liteBackTextureFile );\r
+      }\r
+  }\r
+  \r
+  if( appData.darkBackTextureFile && appData.darkBackTextureFile[0] != NULLCHAR && appData.darkBackTextureFile[0] != '*' ) {\r
+      darkBackTexture = LoadImage( 0, appData.darkBackTextureFile, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );\r
+      darkBackTextureMode = appData.darkBackTextureMode;\r
+\r
+      if (darkBackTexture == NULL && appData.debugMode) {\r
+          fprintf( debugFP, "Unable to load dark texture bitmap '%s'\n", appData.darkBackTextureFile );\r
+      }\r
+  }\r
+\r
+  mysrandom( (unsigned) time(NULL) );\r
+\r
   /* Make a console window if needed */\r
   if (appData.icsActive) {\r
     ConsoleCreate();\r
   }\r
 \r
-  /* [AS] Restore layout */
-  if( wpMoveHistory.visible ) {
-      MoveHistoryPopUp();
-  }
-
-  if( wpEvalGraph.visible ) {
-      EvalGraphPopUp();
-  }
-
-  if( wpEngineOutput.visible ) {
-      EngineOutputPopUp();
-  }
-
+  /* [AS] Restore layout */\r
+  if( wpMoveHistory.visible ) {\r
+      MoveHistoryPopUp();\r
+  }\r
+\r
+  if( wpEvalGraph.visible ) {\r
+      EvalGraphPopUp();\r
+  }\r
+\r
+  if( wpEngineOutput.visible ) {\r
+      EngineOutputPopUp();\r
+  }\r
+\r
   InitBackEnd2();\r
 \r
   /* Make the window visible; update its client area; and return "success" */\r
@@ -676,13 +684,19 @@ InitInstance(HINSTANCE hInstance, int nCmdShow, LPSTR lpCmdLine)
   SetWindowPlacement(hwndMain, &wp);\r
 \r
   SetWindowPos(hwndMain, alwaysOnTop ? HWND_TOPMOST : HWND_NOTOPMOST,\r
-              0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);\r
-
-  /* [AS] Disable the FRC stuff if not playing the proper variant */
-  if( gameInfo.variant != VariantFischeRandom ) {
-      EnableMenuItem( GetMenu(hwndMain), IDM_NewGameFRC, MF_GRAYED );
-  }
-
+               0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);\r
+\r
+  /* [AS] Disable the FRC stuff if not playing the proper variant */\r
+  if( gameInfo.variant != VariantFischeRandom ) {\r
+      EnableMenuItem( GetMenu(hwndMain), IDM_NewGameFRC, MF_GRAYED );\r
+  }\r
+#ifdef FAIRY\r
+#ifdef GOTHIC\r
+  /* [HGM] Gothic licensing requirement */\r
+  if(gameInfo.variant == VariantGothic)\r
+      GothicPopUp(GOTHIC);\r
+#endif // GOTHIC\r
+#endif // FAIRY\r
   if (hwndConsole) {\r
 #if AOT_CONSOLE\r
     SetWindowPos(hwndConsole, alwaysOnTop ? HWND_TOPMOST : HWND_NOTOPMOST,\r
@@ -876,7 +890,7 @@ ArgDescriptor argDescriptors[] = {
   { "tagsFont", ArgFont, (LPVOID) EDITTAGS_FONT, TRUE },\r
   { "commentFont", ArgFont, (LPVOID) COMMENT_FONT, TRUE },\r
   { "icsFont", ArgFont, (LPVOID) CONSOLE_FONT, TRUE },\r
-  { "moveHistoryFont", ArgFont, (LPVOID) MOVEHISTORY_FONT, TRUE }, /* [AS] */
+  { "moveHistoryFont", ArgFont, (LPVOID) MOVEHISTORY_FONT, TRUE }, /* [AS] */\r
   { "boardSize", ArgBoardSize, (LPVOID) &boardSize,\r
     TRUE }, /* must come after all fonts */\r
   { "size", ArgBoardSize, (LPVOID) &boardSize, FALSE },\r
@@ -1074,81 +1088,89 @@ ArgDescriptor argDescriptors[] = {
   { "initialMode", ArgString, (LPVOID) &appData.initialMode, FALSE },\r
   { "mode", ArgString, (LPVOID) &appData.initialMode, FALSE },\r
   { "variant", ArgString, (LPVOID) &appData.variant, FALSE },\r
-  { "firstProtocolVersion", ArgInt, (LPVOID) &appData.firstProtocolVersion, FALSE },
-  { "secondProtocolVersion", ArgInt, (LPVOID) &appData.secondProtocolVersion,FALSE },
+  { "firstProtocolVersion", ArgInt, (LPVOID) &appData.firstProtocolVersion, FALSE },\r
+  { "secondProtocolVersion", ArgInt, (LPVOID) &appData.secondProtocolVersion,FALSE },\r
   { "showButtonBar", ArgBoolean, (LPVOID) &appData.showButtonBar, TRUE },\r
   { "buttons", ArgTrue, (LPVOID) &appData.showButtonBar, FALSE },\r
   { "xbuttons", ArgFalse, (LPVOID) &appData.showButtonBar, FALSE },\r
   { "-buttons", ArgFalse, (LPVOID) &appData.showButtonBar, FALSE },\r
-  /* [AS] New features */
-  { "firstScoreAbs", ArgBoolean, (LPVOID) &appData.firstScoreIsAbsolute, FALSE },
-  { "secondScoreAbs", ArgBoolean, (LPVOID) &appData.secondScoreIsAbsolute, FALSE },
-  { "pgnExtendedInfo", ArgBoolean, (LPVOID) &appData.saveExtendedInfoInPGN, TRUE },
-  { "hideThinkingFromHuman", ArgBoolean, (LPVOID) &appData.hideThinkingFromHuman, TRUE },
-  { "liteBackTextureFile", ArgString, (LPVOID) &appData.liteBackTextureFile, TRUE },
-  { "darkBackTextureFile", ArgString, (LPVOID) &appData.darkBackTextureFile, TRUE },
-  { "liteBackTextureMode", ArgInt, (LPVOID) &appData.liteBackTextureMode, TRUE },
-  { "darkBackTextureMode", ArgInt, (LPVOID) &appData.darkBackTextureMode, TRUE },
-  { "renderPiecesWithFont", ArgString, (LPVOID) &appData.renderPiecesWithFont, TRUE },
-  { "fontPieceToCharTable", ArgString, (LPVOID) &appData.fontToPieceTable, TRUE },
-  { "fontPieceBackColorWhite", ArgColor, (LPVOID) &appData.fontBackColorWhite, TRUE },
-  { "fontPieceForeColorWhite", ArgColor, (LPVOID) &appData.fontForeColorWhite, TRUE },
-  { "fontPieceBackColorBlack", ArgColor, (LPVOID) &appData.fontBackColorBlack, TRUE },
-  { "fontPieceForeColorBlack", ArgColor, (LPVOID) &appData.fontForeColorBlack, TRUE },
-  { "fontPieceSize", ArgInt, (LPVOID) &appData.fontPieceSize, TRUE },
-  { "overrideLineGap", ArgInt, (LPVOID) &appData.overrideLineGap, TRUE },
-  { "adjudicateLossThreshold", ArgInt, (LPVOID) &appData.adjudicateLossThreshold, TRUE },
-  { "delayBeforeQuit", ArgInt, (LPVOID) &appData.delayBeforeQuit, TRUE },
-  { "delayAfterQuit", ArgInt, (LPVOID) &appData.delayAfterQuit, TRUE },
-  { "nameOfDebugFile", ArgFilename, (LPVOID) &appData.nameOfDebugFile, FALSE },
-  { "debugfile", ArgFilename, (LPVOID) &appData.nameOfDebugFile, FALSE },
-  { "pgnEventHeader", ArgString, (LPVOID) &appData.pgnEventHeader, TRUE },
-  { "defaultFrcPosition", ArgInt, (LPVOID) &appData.defaultFrcPosition, TRUE },
-  { "gameListTags", ArgString, (LPVOID) &appData.gameListTags, TRUE },
-  { "saveOutOfBookInfo", ArgBoolean, (LPVOID) &appData.saveOutOfBookInfo, TRUE },
-  { "showEvalInMoveHistory", ArgBoolean, (LPVOID) &appData.showEvalInMoveHistory, TRUE },
-  { "evalHistColorWhite", ArgColor, (LPVOID) &appData.evalHistColorWhite, TRUE },
-  { "evalHistColorBlack", ArgColor, (LPVOID) &appData.evalHistColorBlack, TRUE },
-  { "highlightMoveWithArrow", ArgBoolean, (LPVOID) &appData.highlightMoveWithArrow, TRUE },
-  { "highlightArrowColor", ArgColor, (LPVOID) &appData.highlightArrowColor, TRUE },
-  { "stickyWindows", ArgBoolean, (LPVOID) &appData.useStickyWindows, TRUE },
-  { "adjudicateDrawMoves", ArgInt, (LPVOID) &appData.adjudicateDrawMoves, TRUE },
-  { "autoDisplayComment", ArgBoolean, (LPVOID) &appData.autoDisplayComment, TRUE },
-  { "autoDisplayTags", ArgBoolean, (LPVOID) &appData.autoDisplayTags, TRUE },
-  { "firstIsUCI", ArgBoolean, (LPVOID) &appData.firstIsUCI, FALSE },
-  { "fUCI", ArgTrue, (LPVOID) &appData.firstIsUCI, FALSE },
-  { "secondIsUCI", ArgBoolean, (LPVOID) &appData.secondIsUCI, FALSE },
-  { "sUCI", ArgTrue, (LPVOID) &appData.secondIsUCI, FALSE },
-  { "firstHasOwnBookUCI", ArgBoolean, (LPVOID) &appData.firstHasOwnBookUCI, FALSE },
-  { "fNoOwnBookUCI", ArgFalse, (LPVOID) &appData.firstHasOwnBookUCI, FALSE },
-  { "secondHasOwnBookUCI", ArgBoolean, (LPVOID) &appData.secondHasOwnBookUCI, FALSE },
-  { "sNoOwnBookUCI", ArgFalse, (LPVOID) &appData.secondHasOwnBookUCI, FALSE },
-  { "polyglotDir", ArgFilename, (LPVOID) &appData.polyglotDir, TRUE },
-  { "usePolyglotBook", ArgBoolean, (LPVOID) &appData.usePolyglotBook, TRUE },
-  { "polyglotBook", ArgFilename, (LPVOID) &appData.polyglotBook, TRUE },
-  { "defaultHashSize", ArgInt, (LPVOID) &appData.defaultHashSize, TRUE },
-  { "defaultCacheSizeEGTB", ArgInt, (LPVOID) &appData.defaultCacheSizeEGTB, TRUE },
-  { "defaultPathEGTB", ArgFilename, (LPVOID) &appData.defaultPathEGTB, TRUE },
-
-  /* [AS] Layout stuff */
-  { "moveHistoryUp", ArgBoolean, (LPVOID) &wpMoveHistory.visible, TRUE },
-  { "moveHistoryX", ArgInt, (LPVOID) &wpMoveHistory.x, TRUE },
-  { "moveHistoryY", ArgInt, (LPVOID) &wpMoveHistory.y, TRUE },
-  { "moveHistoryW", ArgInt, (LPVOID) &wpMoveHistory.width, TRUE },
-  { "moveHistoryH", ArgInt, (LPVOID) &wpMoveHistory.height, TRUE },
-
-  { "evalGraphUp", ArgBoolean, (LPVOID) &wpEvalGraph.visible, TRUE },
-  { "evalGraphX", ArgInt, (LPVOID) &wpEvalGraph.x, TRUE },
-  { "evalGraphY", ArgInt, (LPVOID) &wpEvalGraph.y, TRUE },
-  { "evalGraphW", ArgInt, (LPVOID) &wpEvalGraph.width, TRUE },
-  { "evalGraphH", ArgInt, (LPVOID) &wpEvalGraph.height, TRUE },
-
-  { "engineOutputUp", ArgBoolean, (LPVOID) &wpEngineOutput.visible, TRUE },
-  { "engineOutputX", ArgInt, (LPVOID) &wpEngineOutput.x, TRUE },
-  { "engineOutputY", ArgInt, (LPVOID) &wpEngineOutput.y, TRUE },
-  { "engineOutputW", ArgInt, (LPVOID) &wpEngineOutput.width, TRUE },
-  { "engineOutputH", ArgInt, (LPVOID) &wpEngineOutput.height, TRUE },
-
+  /* [AS] New features */\r
+  { "firstScoreAbs", ArgBoolean, (LPVOID) &appData.firstScoreIsAbsolute, FALSE },\r
+  { "secondScoreAbs", ArgBoolean, (LPVOID) &appData.secondScoreIsAbsolute, FALSE },\r
+  { "pgnExtendedInfo", ArgBoolean, (LPVOID) &appData.saveExtendedInfoInPGN, TRUE },\r
+  { "hideThinkingFromHuman", ArgBoolean, (LPVOID) &appData.hideThinkingFromHuman, TRUE },\r
+  { "liteBackTextureFile", ArgString, (LPVOID) &appData.liteBackTextureFile, TRUE },\r
+  { "darkBackTextureFile", ArgString, (LPVOID) &appData.darkBackTextureFile, TRUE },\r
+  { "liteBackTextureMode", ArgInt, (LPVOID) &appData.liteBackTextureMode, TRUE },\r
+  { "darkBackTextureMode", ArgInt, (LPVOID) &appData.darkBackTextureMode, TRUE },\r
+  { "renderPiecesWithFont", ArgString, (LPVOID) &appData.renderPiecesWithFont, TRUE },\r
+  { "fontPieceToCharTable", ArgString, (LPVOID) &appData.fontToPieceTable, TRUE },\r
+  { "fontPieceBackColorWhite", ArgColor, (LPVOID) &appData.fontBackColorWhite, TRUE },\r
+  { "fontPieceForeColorWhite", ArgColor, (LPVOID) &appData.fontForeColorWhite, TRUE },\r
+  { "fontPieceBackColorBlack", ArgColor, (LPVOID) &appData.fontBackColorBlack, TRUE },\r
+  { "fontPieceForeColorBlack", ArgColor, (LPVOID) &appData.fontForeColorBlack, TRUE },\r
+  { "fontPieceSize", ArgInt, (LPVOID) &appData.fontPieceSize, TRUE },\r
+  { "overrideLineGap", ArgInt, (LPVOID) &appData.overrideLineGap, TRUE },\r
+  { "adjudicateLossThreshold", ArgInt, (LPVOID) &appData.adjudicateLossThreshold, TRUE },\r
+  { "delayBeforeQuit", ArgInt, (LPVOID) &appData.delayBeforeQuit, TRUE },\r
+  { "delayAfterQuit", ArgInt, (LPVOID) &appData.delayAfterQuit, TRUE },\r
+  { "nameOfDebugFile", ArgFilename, (LPVOID) &appData.nameOfDebugFile, FALSE },\r
+  { "debugfile", ArgFilename, (LPVOID) &appData.nameOfDebugFile, FALSE },\r
+  { "pgnEventHeader", ArgString, (LPVOID) &appData.pgnEventHeader, TRUE },\r
+  { "defaultFrcPosition", ArgInt, (LPVOID) &appData.defaultFrcPosition, TRUE },\r
+  { "gameListTags", ArgString, (LPVOID) &appData.gameListTags, TRUE },\r
+  { "saveOutOfBookInfo", ArgBoolean, (LPVOID) &appData.saveOutOfBookInfo, TRUE },\r
+  { "showEvalInMoveHistory", ArgBoolean, (LPVOID) &appData.showEvalInMoveHistory, TRUE },\r
+  { "evalHistColorWhite", ArgColor, (LPVOID) &appData.evalHistColorWhite, TRUE },\r
+  { "evalHistColorBlack", ArgColor, (LPVOID) &appData.evalHistColorBlack, TRUE },\r
+  { "highlightMoveWithArrow", ArgBoolean, (LPVOID) &appData.highlightMoveWithArrow, TRUE },\r
+  { "highlightArrowColor", ArgColor, (LPVOID) &appData.highlightArrowColor, TRUE },\r
+  { "stickyWindows", ArgBoolean, (LPVOID) &appData.useStickyWindows, TRUE },\r
+  { "adjudicateDrawMoves", ArgInt, (LPVOID) &appData.adjudicateDrawMoves, TRUE },\r
+  { "autoDisplayComment", ArgBoolean, (LPVOID) &appData.autoDisplayComment, TRUE },\r
+  { "autoDisplayTags", ArgBoolean, (LPVOID) &appData.autoDisplayTags, TRUE },\r
+  { "firstIsUCI", ArgBoolean, (LPVOID) &appData.firstIsUCI, FALSE },\r
+  { "fUCI", ArgTrue, (LPVOID) &appData.firstIsUCI, FALSE },\r
+  { "secondIsUCI", ArgBoolean, (LPVOID) &appData.secondIsUCI, FALSE },\r
+  { "sUCI", ArgTrue, (LPVOID) &appData.secondIsUCI, FALSE },\r
+  { "firstHasOwnBookUCI", ArgBoolean, (LPVOID) &appData.firstHasOwnBookUCI, FALSE },\r
+  { "fNoOwnBookUCI", ArgFalse, (LPVOID) &appData.firstHasOwnBookUCI, FALSE },\r
+  { "secondHasOwnBookUCI", ArgBoolean, (LPVOID) &appData.secondHasOwnBookUCI, FALSE },\r
+  { "sNoOwnBookUCI", ArgFalse, (LPVOID) &appData.secondHasOwnBookUCI, FALSE },\r
+  { "polyglotDir", ArgFilename, (LPVOID) &appData.polyglotDir, TRUE },\r
+  { "usePolyglotBook", ArgBoolean, (LPVOID) &appData.usePolyglotBook, TRUE },\r
+  { "polyglotBook", ArgFilename, (LPVOID) &appData.polyglotBook, TRUE },\r
+  { "defaultHashSize", ArgInt, (LPVOID) &appData.defaultHashSize, TRUE }, \r
+  { "defaultCacheSizeEGTB", ArgInt, (LPVOID) &appData.defaultCacheSizeEGTB, TRUE },\r
+  { "defaultPathEGTB", ArgFilename, (LPVOID) &appData.defaultPathEGTB, TRUE },\r
+\r
+  /* [AS] Layout stuff */\r
+  { "moveHistoryUp", ArgBoolean, (LPVOID) &wpMoveHistory.visible, TRUE },\r
+  { "moveHistoryX", ArgInt, (LPVOID) &wpMoveHistory.x, TRUE },\r
+  { "moveHistoryY", ArgInt, (LPVOID) &wpMoveHistory.y, TRUE },\r
+  { "moveHistoryW", ArgInt, (LPVOID) &wpMoveHistory.width, TRUE },\r
+  { "moveHistoryH", ArgInt, (LPVOID) &wpMoveHistory.height, TRUE },\r
+\r
+  { "evalGraphUp", ArgBoolean, (LPVOID) &wpEvalGraph.visible, TRUE },\r
+  { "evalGraphX", ArgInt, (LPVOID) &wpEvalGraph.x, TRUE },\r
+  { "evalGraphY", ArgInt, (LPVOID) &wpEvalGraph.y, TRUE },\r
+  { "evalGraphW", ArgInt, (LPVOID) &wpEvalGraph.width, TRUE },\r
+  { "evalGraphH", ArgInt, (LPVOID) &wpEvalGraph.height, TRUE },\r
+\r
+  { "engineOutputUp", ArgBoolean, (LPVOID) &wpEngineOutput.visible, TRUE },\r
+  { "engineOutputX", ArgInt, (LPVOID) &wpEngineOutput.x, TRUE },\r
+  { "engineOutputY", ArgInt, (LPVOID) &wpEngineOutput.y, TRUE },\r
+  { "engineOutputW", ArgInt, (LPVOID) &wpEngineOutput.width, TRUE },\r
+  { "engineOutputH", ArgInt, (LPVOID) &wpEngineOutput.height, TRUE },\r
+\r
+  /* [HGM] User-selectable board size */\r
+  { "boardWidth", ArgInt, (LPVOID) &appData.NrFiles, TRUE },\r
+  { "boardHeight", ArgInt, (LPVOID) &appData.NrRanks, TRUE },\r
+  { "matchPause", ArgInt, (LPVOID) &appData.matchPause, FALSE },\r
+  { "testClaims", ArgBoolean, (LPVOID) &appData.testClaims, TRUE },\r
+  { "ruleMoves", ArgInt, (LPVOID) &appData.ruleMoves, TRUE },\r
+  { "repeatsToDraw", ArgInt, (LPVOID) &appData.drawRepeats, TRUE },\r
+\r
 #ifdef ZIPPY\r
   { "zippyTalk", ArgBoolean, (LPVOID) &appData.zippyTalk, FALSE },\r
   { "zt", ArgTrue, (LPVOID) &appData.zippyTalk, FALSE },\r
@@ -1803,56 +1825,64 @@ InitAppData(LPSTR lpCmdLine)
   appData.firstProtocolVersion = PROTOVER;\r
   appData.secondProtocolVersion = PROTOVER;\r
   appData.showButtonBar = TRUE;\r
-
-   /* [AS] New properties (see comments in header file) */
-  appData.firstScoreIsAbsolute = FALSE;
-  appData.secondScoreIsAbsolute = FALSE;
-  appData.saveExtendedInfoInPGN = FALSE;
-  appData.hideThinkingFromHuman = FALSE;
-  appData.liteBackTextureFile = "";
-  appData.liteBackTextureMode = BACK_TEXTURE_MODE_PLAIN;
-  appData.darkBackTextureFile = "";
-  appData.darkBackTextureMode = BACK_TEXTURE_MODE_PLAIN;
-  appData.renderPiecesWithFont = "";
-  appData.fontToPieceTable = "";
-  appData.fontBackColorWhite = 0;
-  appData.fontForeColorWhite = 0;
-  appData.fontBackColorBlack = 0;
-  appData.fontForeColorBlack = 0;
-  appData.fontPieceSize = 80;
-  appData.overrideLineGap = 1;
-  appData.adjudicateLossThreshold = 0;
-  appData.delayBeforeQuit = 0;
-  appData.delayAfterQuit = 0;
-  appData.nameOfDebugFile = "winboard.debug";
-  appData.pgnEventHeader = "Computer Chess Game";
-  appData.defaultFrcPosition = -1;
-  appData.gameListTags = GLT_DEFAULT_TAGS;
-  appData.saveOutOfBookInfo = TRUE;
-  appData.showEvalInMoveHistory = TRUE;
-  appData.evalHistColorWhite = ParseColorName( "#FFFFB0" );
-  appData.evalHistColorBlack = ParseColorName( "#AD5D3D" );
-  appData.highlightMoveWithArrow = FALSE;
-  appData.highlightArrowColor = ParseColorName( "#FFFF80" );
-  appData.useStickyWindows = TRUE;
-  appData.adjudicateDrawMoves = 0;
-  appData.autoDisplayComment = TRUE;
-  appData.autoDisplayTags = TRUE;
-  appData.firstIsUCI = FALSE;
-  appData.secondIsUCI = FALSE;
-  appData.firstHasOwnBookUCI = TRUE;
-  appData.secondHasOwnBookUCI = TRUE;
-  appData.polyglotDir = "";
-  appData.usePolyglotBook = FALSE;
-  appData.polyglotBook = "";
-  appData.defaultHashSize = 64;
-  appData.defaultCacheSizeEGTB = 4;
-  appData.defaultPathEGTB = "c:\\egtb";
-
-  InitWindowPlacement( &wpMoveHistory );
-  InitWindowPlacement( &wpEvalGraph );
-  InitWindowPlacement( &wpEngineOutput );
-
+\r
+   /* [AS] New properties (see comments in header file) */\r
+  appData.firstScoreIsAbsolute = FALSE;\r
+  appData.secondScoreIsAbsolute = FALSE;\r
+  appData.saveExtendedInfoInPGN = FALSE;\r
+  appData.hideThinkingFromHuman = FALSE;\r
+  appData.liteBackTextureFile = "";\r
+  appData.liteBackTextureMode = BACK_TEXTURE_MODE_PLAIN;\r
+  appData.darkBackTextureFile = "";\r
+  appData.darkBackTextureMode = BACK_TEXTURE_MODE_PLAIN;\r
+  appData.renderPiecesWithFont = "";\r
+  appData.fontToPieceTable = "";\r
+  appData.fontBackColorWhite = 0;\r
+  appData.fontForeColorWhite = 0;\r
+  appData.fontBackColorBlack = 0;\r
+  appData.fontForeColorBlack = 0;\r
+  appData.fontPieceSize = 80;\r
+  appData.overrideLineGap = 1;\r
+  appData.adjudicateLossThreshold = 0;\r
+  appData.delayBeforeQuit = 0;\r
+  appData.delayAfterQuit = 0;\r
+  appData.nameOfDebugFile = "winboard.debug";\r
+  appData.pgnEventHeader = "Computer Chess Game";\r
+  appData.defaultFrcPosition = -1;\r
+  appData.gameListTags = GLT_DEFAULT_TAGS;\r
+  appData.saveOutOfBookInfo = TRUE;\r
+  appData.showEvalInMoveHistory = TRUE;\r
+  appData.evalHistColorWhite = ParseColorName( "#FFFFB0" );\r
+  appData.evalHistColorBlack = ParseColorName( "#AD5D3D" );\r
+  appData.highlightMoveWithArrow = FALSE;\r
+  appData.highlightArrowColor = ParseColorName( "#FFFF80" );\r
+  appData.useStickyWindows = TRUE;\r
+  appData.adjudicateDrawMoves = 0;\r
+  appData.autoDisplayComment = TRUE;\r
+  appData.autoDisplayTags = TRUE;\r
+  appData.firstIsUCI = FALSE;\r
+  appData.secondIsUCI = FALSE;\r
+  appData.firstHasOwnBookUCI = TRUE;\r
+  appData.secondHasOwnBookUCI = TRUE;\r
+  appData.polyglotDir = "";\r
+  appData.usePolyglotBook = FALSE;\r
+  appData.polyglotBook = "";\r
+  appData.defaultHashSize = 64;\r
+  appData.defaultCacheSizeEGTB = 4;\r
+  appData.defaultPathEGTB = "c:\\egtb";\r
+\r
+  InitWindowPlacement( &wpMoveHistory );\r
+  InitWindowPlacement( &wpEvalGraph );\r
+  InitWindowPlacement( &wpEngineOutput );\r
+\r
+  /* [HGM] User-selectable board size */\r
+  appData.NrFiles = 8;\r
+  appData.NrRanks = 8;\r
+  appData.matchPause  = 10000;\r
+  appData.testClaims  = FALSE;\r
+  appData.ruleMoves   = 51;\r
+  appData.drawRepeats = 6;\r
+\r
 #ifdef ZIPPY\r
   appData.zippyTalk = ZIPPY_TALK;\r
   appData.zippyPlay = ZIPPY_PLAY;\r
@@ -1891,6 +1921,11 @@ InitAppData(LPSTR lpCmdLine)
   /* Parse command line */\r
   ParseArgs(StringGet, &lpCmdLine);\r
 \r
+  /* [HGM] make sure board size is acceptable */\r
+  if(appData.NrFiles > BOARD_SIZE ||\r
+     appData.NrRanks > BOARD_SIZE   )\r
+      DisplayFatalError("Recompile with BOARD_SIZE > 12, to support this size", 0, 2);\r
+\r
   /* Propagate options that affect others */\r
   if (appData.matchMode || appData.matchGames) chessProgram = TRUE;\r
   if (appData.icsActive || appData.noChessProgram) {\r
@@ -2041,39 +2076,39 @@ SaveSettings(char* name)
     gameListH = wp.rcNormalPosition.bottom - wp.rcNormalPosition.top;\r
   }\r
 \r
-  /* [AS] Move history */
-  wpMoveHistory.visible = MoveHistoryIsUp();
-
-  if( moveHistoryDialog ) {
-    GetWindowPlacement(moveHistoryDialog, &wp);
-    wpMoveHistory.x = wp.rcNormalPosition.left;
-    wpMoveHistory.y = wp.rcNormalPosition.top;
-    wpMoveHistory.width = wp.rcNormalPosition.right - wp.rcNormalPosition.left;
-    wpMoveHistory.height = wp.rcNormalPosition.bottom - wp.rcNormalPosition.top;
-  }
-
-  /* [AS] Eval graph */
-  wpEvalGraph.visible = EvalGraphIsUp();
-
-  if( evalGraphDialog ) {
-    GetWindowPlacement(evalGraphDialog, &wp);
-    wpEvalGraph.x = wp.rcNormalPosition.left;
-    wpEvalGraph.y = wp.rcNormalPosition.top;
-    wpEvalGraph.width = wp.rcNormalPosition.right - wp.rcNormalPosition.left;
-    wpEvalGraph.height = wp.rcNormalPosition.bottom - wp.rcNormalPosition.top;
-  }
-
-  /* [AS] Engine output */
-  wpEngineOutput.visible = EngineOutputIsUp();
-
-  if( engineOutputDialog ) {
-    GetWindowPlacement(engineOutputDialog, &wp);
-    wpEngineOutput.x = wp.rcNormalPosition.left;
-    wpEngineOutput.y = wp.rcNormalPosition.top;
-    wpEngineOutput.width = wp.rcNormalPosition.right - wp.rcNormalPosition.left;
-    wpEngineOutput.height = wp.rcNormalPosition.bottom - wp.rcNormalPosition.top;
-  }
-
+  /* [AS] Move history */\r
+  wpMoveHistory.visible = MoveHistoryIsUp();\r
+  \r
+  if( moveHistoryDialog ) {\r
+    GetWindowPlacement(moveHistoryDialog, &wp);\r
+    wpMoveHistory.x = wp.rcNormalPosition.left;\r
+    wpMoveHistory.y = wp.rcNormalPosition.top;\r
+    wpMoveHistory.width = wp.rcNormalPosition.right - wp.rcNormalPosition.left;\r
+    wpMoveHistory.height = wp.rcNormalPosition.bottom - wp.rcNormalPosition.top;\r
+  }\r
+\r
+  /* [AS] Eval graph */\r
+  wpEvalGraph.visible = EvalGraphIsUp();\r
+\r
+  if( evalGraphDialog ) {\r
+    GetWindowPlacement(evalGraphDialog, &wp);\r
+    wpEvalGraph.x = wp.rcNormalPosition.left;\r
+    wpEvalGraph.y = wp.rcNormalPosition.top;\r
+    wpEvalGraph.width = wp.rcNormalPosition.right - wp.rcNormalPosition.left;\r
+    wpEvalGraph.height = wp.rcNormalPosition.bottom - wp.rcNormalPosition.top;\r
+  }\r
+\r
+  /* [AS] Engine output */\r
+  wpEngineOutput.visible = EngineOutputIsUp();\r
+\r
+  if( engineOutputDialog ) {\r
+    GetWindowPlacement(engineOutputDialog, &wp);\r
+    wpEngineOutput.x = wp.rcNormalPosition.left;\r
+    wpEngineOutput.y = wp.rcNormalPosition.top;\r
+    wpEngineOutput.width = wp.rcNormalPosition.right - wp.rcNormalPosition.left;\r
+    wpEngineOutput.height = wp.rcNormalPosition.bottom - wp.rcNormalPosition.top;\r
+  }\r
+\r
   for (ad = argDescriptors; ad->argName != NULL; ad++) {\r
     if (!ad->save) continue;\r
     switch (ad->argType) {\r
@@ -2180,436 +2215,552 @@ SaveSettings(char* name)
  *\r
 \*---------------------------------------------------------------------------*/\r
 \r
-/* [AS] Draw square using background texture */
-static void DrawTile( int dx, int dy, int dw, int dh, HDC dst, HDC src, int mode, int sx, int sy )
-{
-    XFORM   x;
-
-    if( mode == 0 ) {
-        return; /* Should never happen! */
-    }
-
-    SetGraphicsMode( dst, GM_ADVANCED );
-
-    switch( mode ) {
-    case 1:
-        /* Identity */
-        break;
-    case 2:
-        /* X reflection */
-        x.eM11 = -1.0;
-        x.eM12 = 0;
-        x.eM21 = 0;
-        x.eM22 = 1.0;
-        x.eDx = (FLOAT) dw + dx - 1;
-        x.eDy = 0;
-        dx = 0;
-        SetWorldTransform( dst, &x );
-        break;
-    case 3:
-        /* Y reflection */
-        x.eM11 = 1.0;
-        x.eM12 = 0;
-        x.eM21 = 0;
-        x.eM22 = -1.0;
-        x.eDx = 0;
-        x.eDy = (FLOAT) dh + dy - 1;
-        dy = 0;
-        SetWorldTransform( dst, &x );
-        break;
-    case 4:
-        /* X/Y flip */
-        x.eM11 = 0;
-        x.eM12 = 1.0;
-        x.eM21 = 1.0;
-        x.eM22 = 0;
-        x.eDx = (FLOAT) dx;
-        x.eDy = (FLOAT) dy;
-        dx = 0;
-        dy = 0;
-        SetWorldTransform( dst, &x );
-        break;
-    }
-
-    BitBlt( dst, dx, dy, dw, dh, src, sx, sy, SRCCOPY );
-
-    x.eM11 = 1.0;
-    x.eM12 = 0;
-    x.eM21 = 0;
-    x.eM22 = 1.0;
-    x.eDx = 0;
-    x.eDy = 0;
-    SetWorldTransform( dst, &x );
-
-    ModifyWorldTransform( dst, 0, MWT_IDENTITY );
-}
-
-/* [AS] */
-enum {
-    PM_WP = 0,
-    PM_WN = 1,
-    PM_WB = 2,
-    PM_WR = 3,
-    PM_WQ = 4,
-    PM_WK = 5,
-    PM_BP = 6,
-    PM_BN = 7,
-    PM_BB = 8,
-    PM_BR = 9,
-    PM_BQ = 10,
-    PM_BK = 11
-};
-
-static HFONT hPieceFont = NULL;
-static HBITMAP hPieceMask[12];
-static HBITMAP hPieceFace[12];
-static int fontBitmapSquareSize = 0;
-static char pieceToFontChar[12] = { 'p', 'n', 'b', 'r', 'q', 'k', 'o', 'm', 'v', 't', 'w', 'l' };
-
-static BOOL SetPieceToFontCharTable( const char * map )
-{
-    BOOL result = FALSE;
-
-    if( map != NULL && strlen(map) == 12 ) {
-        int i;
-
-        for( i=0; i<12; i++ ) {
-            pieceToFontChar[i] = map[i];
-        }
-
-        result = TRUE;
-    }
-
-    return result;
-}
-
-static void SetPieceBackground( HDC hdc, COLORREF color, int mode )
-{
-    HBRUSH hbrush;
-    BYTE r1 = GetRValue( color );
-    BYTE g1 = GetGValue( color );
-    BYTE b1 = GetBValue( color );
-    BYTE r2 = r1 / 2;
-    BYTE g2 = g1 / 2;
-    BYTE b2 = b1 / 2;
-    RECT rc;
-
-    /* Create a uniform background first */
-    hbrush = CreateSolidBrush( color );
-    SetRect( &rc, 0, 0, squareSize, squareSize );
-    FillRect( hdc, &rc, hbrush );
-    DeleteObject( hbrush );
-
-    if( mode == 1 ) {
-        /* Vertical gradient, good for pawn, knight and rook, less for queen and king */
-        int steps = squareSize / 2;
-        int i;
-
-        for( i=0; i<steps; i++ ) {
-            BYTE r = r1 - (r1-r2) * i / steps;
-            BYTE g = g1 - (g1-g2) * i / steps;
-            BYTE b = b1 - (b1-b2) * i / steps;
-
-            hbrush = CreateSolidBrush( RGB(r,g,b) );
-            SetRect( &rc, i + squareSize - steps, 0, i + squareSize - steps + 1, squareSize );
-            FillRect( hdc, &rc, hbrush );
-            DeleteObject(hbrush);
-        }
-    }
-    else if( mode == 2 ) {
-        /* Diagonal gradient, good more or less for every piece */
-        POINT triangle[3];
-        HPEN hpen = SelectObject( hdc, GetStockObject(NULL_PEN) );
-        HBRUSH hbrush_old;
-        int steps = squareSize;
-        int i;
-
-        triangle[0].x = squareSize - steps;
-        triangle[0].y = squareSize;
-        triangle[1].x = squareSize;
-        triangle[1].y = squareSize;
-        triangle[2].x = squareSize;
-        triangle[2].y = squareSize - steps;
-
-        for( i=0; i<steps; i++ ) {
-            BYTE r = r1 - (r1-r2) * i / steps;
-            BYTE g = g1 - (g1-g2) * i / steps;
-            BYTE b = b1 - (b1-b2) * i / steps;
-
-            hbrush = CreateSolidBrush( RGB(r,g,b) );
-            hbrush_old = SelectObject( hdc, hbrush );
-            Polygon( hdc, triangle, 3 );
-            SelectObject( hdc, hbrush_old );
-            DeleteObject(hbrush);
-            triangle[0].x++;
-            triangle[2].y++;
-        }
-
-        SelectObject( hdc, hpen );
-    }
-}
-
-/*
-    [AS] The method I use to create the bitmaps it a bit tricky, but it
-    seems to work ok. The main problem here is to find the "inside" of a chess
-    piece: follow the steps as explained below.
-*/
-static void CreatePieceMaskFromFont( HDC hdc_window, HDC hdc, int index )
-{
-    HBITMAP hbm;
-    HBITMAP hbm_old;
-    COLORREF chroma = RGB(0xFF,0x00,0xFF);
-    RECT rc;
-    SIZE sz;
-    POINT pt;
-    int backColor = whitePieceColor;
-    int foreColor = blackPieceColor;
-    int shapeIndex = index < 6 ? index+6 : index;
-
-    if( index < 6 && appData.fontBackColorWhite != appData.fontForeColorWhite ) {
-        backColor = appData.fontBackColorWhite;
-        foreColor = appData.fontForeColorWhite;
-    }
-    else if( index >= 6 && appData.fontBackColorBlack != appData.fontForeColorBlack ) {
-        backColor = appData.fontBackColorBlack;
-        foreColor = appData.fontForeColorBlack;
-    }
-
-    /* Mask */
-    hbm = CreateCompatibleBitmap( hdc_window, squareSize, squareSize );
-
-    hbm_old = SelectObject( hdc, hbm );
-
-    rc.left = 0;
-    rc.top = 0;
-    rc.right = squareSize;
-    rc.bottom = squareSize;
-
-    /* Step 1: background is now black */
-    FillRect( hdc, &rc, GetStockObject(BLACK_BRUSH) );
-
-    GetTextExtentPoint32( hdc, &pieceToFontChar[index], 1, &sz );
-
-    pt.x = (squareSize - sz.cx) / 2;
-    pt.y = (squareSize - sz.cy) / 2;
-
-    SetBkMode( hdc, TRANSPARENT );
-    SetTextColor( hdc, chroma );
-    /* Step 2: the piece has been drawn in purple, there are now black and purple in this bitmap */
-    TextOut( hdc, pt.x, pt.y, &pieceToFontChar[index], 1 );
-
-    SelectObject( hdc, GetStockObject(WHITE_BRUSH) );
-    /* Step 3: the area outside the piece is filled with white */
-    FloodFill( hdc, 0, 0, chroma );
-    SelectObject( hdc, GetStockObject(BLACK_BRUSH) );
-    /*
-        Step 4: this is the tricky part, the area inside the piece is filled with black,
-        but if the start point is not inside the piece we're lost!
-        There should be a better way to do this... if we could create a region or path
-        from the fill operation we would be fine for example.
-    */
-    FloodFill( hdc, squareSize / 2, squareSize / 2, RGB(0xFF,0xFF,0xFF) );
-
-    SetTextColor( hdc, 0 );
-    /*
-        Step 5: some fonts have "disconnected" areas that are skipped by the fill:
-        draw the piece again in black for safety.
-    */
-    TextOut( hdc, pt.x, pt.y, &pieceToFontChar[index], 1 );
-
-    SelectObject( hdc, hbm_old );
-
-    if( hPieceMask[index] != NULL ) {
-        DeleteObject( hPieceMask[index] );
-    }
-
-    hPieceMask[index] = hbm;
-
-    /* Face */
-    hbm = CreateCompatibleBitmap( hdc_window, squareSize, squareSize );
-
-    SelectObject( hdc, hbm );
-
-    {
-        HDC dc1 = CreateCompatibleDC( hdc_window );
-        HDC dc2 = CreateCompatibleDC( hdc_window );
-        HBITMAP bm2 = CreateCompatibleBitmap( hdc_window, squareSize, squareSize );
-
-        SelectObject( dc1, hPieceMask[index] );
-        SelectObject( dc2, bm2 );
-        FillRect( dc2, &rc, GetStockObject(WHITE_BRUSH) );
-        BitBlt( dc2, 0, 0, squareSize, squareSize, dc1, 0, 0, SRCINVERT );
-
-        /*
-            Now dc2 contains the inverse of the piece mask, i.e. a mask that preserves
-            the piece background and deletes (makes transparent) the rest.
-            Thanks to that mask, we are free to paint the background with the greates
-            freedom, as we'll be able to mask off the unwanted parts when finished.
-            We use this, to make gradients and give the pieces a "roundish" look.
-        */
-        SetPieceBackground( hdc, backColor, 2 );
-        BitBlt( hdc, 0, 0, squareSize, squareSize, dc2, 0, 0, SRCAND );
-
-        DeleteDC( dc2 );
-        DeleteDC( dc1 );
-        DeleteObject( bm2 );
-    }
-
-    SetTextColor( hdc, foreColor );
-    TextOut( hdc, pt.x, pt.y, &pieceToFontChar[index], 1 );
-
-    SelectObject( hdc, hbm_old );
-
-    if( hPieceFace[index] != NULL ) {
-        DeleteObject( hPieceFace[index] );
-    }
-
-    hPieceFace[index] = hbm;
-}
-
-static int TranslatePieceToFontPiece( int piece )
-{
-    switch( piece ) {
-    case BlackPawn:
-        return PM_BP;
-    case BlackKnight:
-        return PM_BN;
-    case BlackBishop:
-        return PM_BB;
-    case BlackRook:
-        return PM_BR;
-    case BlackQueen:
-        return PM_BQ;
-    case BlackKing:
-        return PM_BK;
-    case WhitePawn:
-        return PM_WP;
-    case WhiteKnight:
-        return PM_WN;
-    case WhiteBishop:
-        return PM_WB;
-    case WhiteRook:
-        return PM_WR;
-    case WhiteQueen:
-        return PM_WQ;
-    case WhiteKing:
-        return PM_WK;
-    }
-
-    return 0;
-}
-
-void CreatePiecesFromFont()
-{
-    LOGFONT lf;
-    HDC hdc_window = NULL;
-    HDC hdc = NULL;
-    HFONT hfont_old;
-    int fontHeight;
-    int i;
-
-    if( fontBitmapSquareSize < 0 ) {
-        /* Something went seriously wrong in the past: do not try to recreate fonts! */
-        return;
-    }
-
-    if( appData.renderPiecesWithFont == NULL || appData.renderPiecesWithFont[0] == NULLCHAR || appData.renderPiecesWithFont[0] == '*' ) {
-        fontBitmapSquareSize = -1;
-        return;
-    }
-
-    if( fontBitmapSquareSize != squareSize ) {
-        hdc_window = GetDC( hwndMain );
-        hdc = CreateCompatibleDC( hdc_window );
-
-        if( hPieceFont != NULL ) {
-            DeleteObject( hPieceFont );
-        }
-        else {
-            for( i=0; i<12; i++ ) {
-                hPieceMask[i] = NULL;
-                hPieceFace[i] = NULL;
-            }
-        }
-
-        fontHeight = 75;
-
-        if( appData.fontPieceSize >= 50 && appData.fontPieceSize <= 150 ) {
-            fontHeight = appData.fontPieceSize;
-        }
-
-        fontHeight = (fontHeight * squareSize) / 100;
-
-        lf.lfHeight = -MulDiv( fontHeight, GetDeviceCaps(hdc, LOGPIXELSY), 72 );
-        lf.lfWidth = 0;
-        lf.lfEscapement = 0;
-        lf.lfOrientation = 0;
-        lf.lfWeight = FW_NORMAL;
-        lf.lfItalic = 0;
-        lf.lfUnderline = 0;
-        lf.lfStrikeOut = 0;
-        lf.lfCharSet = DEFAULT_CHARSET;
-        lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
-        lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
-        lf.lfQuality = PROOF_QUALITY;
-        lf.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
-        strncpy( lf.lfFaceName, appData.renderPiecesWithFont, sizeof(lf.lfFaceName) );
-        lf.lfFaceName[ sizeof(lf.lfFaceName) - 1 ] = '\0';
-
-        hPieceFont = CreateFontIndirect( &lf );
-
-        if( hPieceFont == NULL ) {
-            fontBitmapSquareSize = -2;
-        }
-        else {
-            /* Setup font-to-piece character table */
-            if( ! SetPieceToFontCharTable(appData.fontToPieceTable) ) {
-                /* No (or wrong) global settings, try to detect the font */
-                if( strstr(lf.lfFaceName,"Alpha") != NULL ) {
-                    /* Alpha */
-                    SetPieceToFontCharTable("phbrqkojntwl");
-                }
-                else if( strstr(lf.lfFaceName,"DiagramTT") != NULL ) {
-                    /* DiagramTT* family */
-                    SetPieceToFontCharTable("PNLRQKpnlrqk");
-                }
-                else {
-                    /* Cases, Condal, Leipzig, Lucena, Marroquin, Merida, Usual */
-                    SetPieceToFontCharTable("pnbrqkomvtwl");
-                }
-            }
-
-            /* Create bitmaps */
-            hfont_old = SelectObject( hdc, hPieceFont );
-
-            CreatePieceMaskFromFont( hdc_window, hdc, PM_WP );
-            CreatePieceMaskFromFont( hdc_window, hdc, PM_WN );
-            CreatePieceMaskFromFont( hdc_window, hdc, PM_WB );
-            CreatePieceMaskFromFont( hdc_window, hdc, PM_WR );
-            CreatePieceMaskFromFont( hdc_window, hdc, PM_WQ );
-            CreatePieceMaskFromFont( hdc_window, hdc, PM_WK );
-            CreatePieceMaskFromFont( hdc_window, hdc, PM_BP );
-            CreatePieceMaskFromFont( hdc_window, hdc, PM_BN );
-            CreatePieceMaskFromFont( hdc_window, hdc, PM_BB );
-            CreatePieceMaskFromFont( hdc_window, hdc, PM_BR );
-            CreatePieceMaskFromFont( hdc_window, hdc, PM_BQ );
-            CreatePieceMaskFromFont( hdc_window, hdc, PM_BK );
-
-            SelectObject( hdc, hfont_old );
-
-            fontBitmapSquareSize = squareSize;
-        }
-    }
-
-    if( hdc != NULL ) {
-        DeleteDC( hdc );
-    }
-
-    if( hdc_window != NULL ) {
-        ReleaseDC( hwndMain, hdc_window );
-    }
-}
-
+/* [AS] Draw square using background texture */\r
+static void DrawTile( int dx, int dy, int dw, int dh, HDC dst, HDC src, int mode, int sx, int sy )\r
+{\r
+    XFORM   x;\r
+\r
+    if( mode == 0 ) {\r
+        return; /* Should never happen! */\r
+    }\r
+\r
+    SetGraphicsMode( dst, GM_ADVANCED );\r
+\r
+    switch( mode ) {\r
+    case 1:\r
+        /* Identity */\r
+        break;\r
+    case 2:\r
+        /* X reflection */\r
+        x.eM11 = -1.0;\r
+        x.eM12 = 0;\r
+        x.eM21 = 0;\r
+        x.eM22 = 1.0;\r
+        x.eDx = (FLOAT) dw + dx - 1;\r
+        x.eDy = 0;\r
+        dx = 0;\r
+        SetWorldTransform( dst, &x );\r
+        break;\r
+    case 3:\r
+        /* Y reflection */\r
+        x.eM11 = 1.0;\r
+        x.eM12 = 0;\r
+        x.eM21 = 0;\r
+        x.eM22 = -1.0;\r
+        x.eDx = 0;\r
+        x.eDy = (FLOAT) dh + dy - 1;\r
+        dy = 0;\r
+        SetWorldTransform( dst, &x );\r
+        break;\r
+    case 4:\r
+        /* X/Y flip */\r
+        x.eM11 = 0;\r
+        x.eM12 = 1.0;\r
+        x.eM21 = 1.0;\r
+        x.eM22 = 0;\r
+        x.eDx = (FLOAT) dx;\r
+        x.eDy = (FLOAT) dy;\r
+        dx = 0;\r
+        dy = 0;\r
+        SetWorldTransform( dst, &x );\r
+        break;\r
+    }\r
+\r
+    BitBlt( dst, dx, dy, dw, dh, src, sx, sy, SRCCOPY );\r
+\r
+    x.eM11 = 1.0;\r
+    x.eM12 = 0;\r
+    x.eM21 = 0;\r
+    x.eM22 = 1.0;\r
+    x.eDx = 0;\r
+    x.eDy = 0;\r
+    SetWorldTransform( dst, &x );\r
+\r
+    ModifyWorldTransform( dst, 0, MWT_IDENTITY );\r
+}\r
+\r
+/* [AS] [HGM] Make room for more piece types, so all pieces can be different */\r
+enum {\r
+    PM_WP = (int) WhitePawn, \r
+    PM_WN = (int) WhiteKnight, \r
+    PM_WB = (int) WhiteBishop, \r
+    PM_WR = (int) WhiteRook, \r
+#ifdef FAIRY\r
+    PM_WA  = (int) WhiteCardinal, \r
+    PM_WC  = (int) WhiteMarshall, \r
+    PM_WFP = (int) WhiteFairyPawn, \r
+    PM_WFN = (int) WhiteFairyKnight, \r
+    PM_WFB = (int) WhiteFairyBishop, \r
+    PM_WFR = (int) WhiteFairyRook, \r
+    PM_WFA = (int) WhiteFairyCardinal, \r
+    PM_WFC = (int) WhiteFairyMarshall, \r
+    PM_WFQ = (int) WhiteFairyQueen, \r
+    PM_WFK = (int) WhiteFairyKing, \r
+#endif\r
+    PM_WQ = (int) WhiteQueen, \r
+    PM_WK = (int) WhiteKing,\r
+    PM_BP = (int) BlackPawn, \r
+    PM_BN = (int) BlackKnight, \r
+    PM_BB = (int) BlackBishop, \r
+    PM_BR = (int) BlackRook, \r
+#ifdef FAIRY\r
+    PM_BA  = (int) BlackCardinal, \r
+    PM_BC  = (int) BlackMarshall, \r
+    PM_BFP = (int) BlackFairyPawn, \r
+    PM_BFN = (int) BlackFairyKnight, \r
+    PM_BFB = (int) BlackFairyBishop, \r
+    PM_BFR = (int) BlackFairyRook, \r
+    PM_BFA = (int) BlackFairyCardinal, \r
+    PM_BFC = (int) BlackFairyMarshall, \r
+    PM_BFQ = (int) BlackFairyQueen, \r
+    PM_BFK = (int) BlackFairyKing,\r
+#endif\r
+    PM_BQ = (int) BlackQueen, \r
+    PM_BK = (int) BlackKing\r
+};\r
+\r
+static HFONT hPieceFont = NULL;\r
+static HBITMAP hPieceMask[(int) EmptySquare];\r
+static HBITMAP hPieceFace[(int) EmptySquare];\r
+static int fontBitmapSquareSize = 0;\r
+static char pieceToFontChar[(int) EmptySquare] =\r
+                              { 'p', 'n', 'b', 'r',\r
+#ifdef FAIRY\r
+                      'n', 'b', 'p', 'n', 'b', 'r', 'b', 'r', 'q', 'k',\r
+#endif\r
+                      'q', 'k', 'o', 'm', 'v', 't', \r
+#ifdef FAIRY\r
+                      'v', 't', 'o', 'm', 'v', 't', 'v', 't', 'w', 'l',\r
+#endif\r
+                                                              'w', 'l' };\r
+\r
+static BOOL SetPieceToFontCharTable( const char * map )\r
+{\r
+    BOOL result = FALSE; int NrPieces;\r
+\r
+    if( map != NULL && (NrPieces=strlen(map)) <= (int) EmptySquare \r
+                    && NrPieces >= 12 && !(NrPieces&1)) {\r
+        int i; /* [HGM] Accept even length from 12 to 32 */\r
+\r
+        for( i=0; i<(int) EmptySquare; i++ ) pieceToFontChar[i] = 0;\r
+        for( i=0; i<NrPieces/2-2; i++ ) {\r
+            pieceToFontChar[i] = map[i];\r
+            pieceToFontChar[i + (int)BlackPawn - (int) WhitePawn] = map[i+NrPieces/2];\r
+        }\r
+        pieceToFontChar[(int) WhiteQueen] = map[NrPieces/2-2];\r
+        pieceToFontChar[(int) WhiteKing]  = map[NrPieces/2-1];\r
+        pieceToFontChar[(int) BlackQueen] = map[NrPieces-2];\r
+        pieceToFontChar[(int) BlackKing]  = map[NrPieces-1];\r
+\r
+        result = TRUE;\r
+    }\r
+\r
+    return result;\r
+}\r
+\r
+static void SetPieceBackground( HDC hdc, COLORREF color, int mode )\r
+{\r
+    HBRUSH hbrush;\r
+    BYTE r1 = GetRValue( color );\r
+    BYTE g1 = GetGValue( color );\r
+    BYTE b1 = GetBValue( color );\r
+    BYTE r2 = r1 / 2;\r
+    BYTE g2 = g1 / 2;\r
+    BYTE b2 = b1 / 2;\r
+    RECT rc;\r
+\r
+    /* Create a uniform background first */\r
+    hbrush = CreateSolidBrush( color );\r
+    SetRect( &rc, 0, 0, squareSize, squareSize );\r
+    FillRect( hdc, &rc, hbrush );\r
+    DeleteObject( hbrush );\r
+    \r
+    if( mode == 1 ) {\r
+        /* Vertical gradient, good for pawn, knight and rook, less for queen and king */\r
+        int steps = squareSize / 2;\r
+        int i;\r
+\r
+        for( i=0; i<steps; i++ ) {\r
+            BYTE r = r1 - (r1-r2) * i / steps;\r
+            BYTE g = g1 - (g1-g2) * i / steps;\r
+            BYTE b = b1 - (b1-b2) * i / steps;\r
+\r
+            hbrush = CreateSolidBrush( RGB(r,g,b) );\r
+            SetRect( &rc, i + squareSize - steps, 0, i + squareSize - steps + 1, squareSize );\r
+            FillRect( hdc, &rc, hbrush );\r
+            DeleteObject(hbrush);\r
+        }\r
+    }\r
+    else if( mode == 2 ) {\r
+        /* Diagonal gradient, good more or less for every piece */\r
+        POINT triangle[3];\r
+        HPEN hpen = SelectObject( hdc, GetStockObject(NULL_PEN) );\r
+        HBRUSH hbrush_old;\r
+        int steps = squareSize;\r
+        int i;\r
+\r
+        triangle[0].x = squareSize - steps;\r
+        triangle[0].y = squareSize;\r
+        triangle[1].x = squareSize;\r
+        triangle[1].y = squareSize;\r
+        triangle[2].x = squareSize;\r
+        triangle[2].y = squareSize - steps;\r
+\r
+        for( i=0; i<steps; i++ ) {\r
+            BYTE r = r1 - (r1-r2) * i / steps;\r
+            BYTE g = g1 - (g1-g2) * i / steps;\r
+            BYTE b = b1 - (b1-b2) * i / steps;\r
+\r
+            hbrush = CreateSolidBrush( RGB(r,g,b) );\r
+            hbrush_old = SelectObject( hdc, hbrush );\r
+            Polygon( hdc, triangle, 3 );\r
+            SelectObject( hdc, hbrush_old );\r
+            DeleteObject(hbrush);\r
+            triangle[0].x++;\r
+            triangle[2].y++;\r
+        }\r
+\r
+        SelectObject( hdc, hpen );\r
+    }\r
+}\r
+\r
+/*\r
+    [AS] The method I use to create the bitmaps it a bit tricky, but it\r
+    seems to work ok. The main problem here is to find the "inside" of a chess\r
+    piece: follow the steps as explained below.\r
+*/\r
+static void CreatePieceMaskFromFont( HDC hdc_window, HDC hdc, int index )\r
+{\r
+    HBITMAP hbm;\r
+    HBITMAP hbm_old;\r
+    COLORREF chroma = RGB(0xFF,0x00,0xFF);\r
+    RECT rc;\r
+    SIZE sz;\r
+    POINT pt;\r
+    int backColor = whitePieceColor; \r
+    int foreColor = blackPieceColor;\r
+    int shapeIndex = index < 6 ? index+6 : index;\r
+    \r
+    if( index < 6 && appData.fontBackColorWhite != appData.fontForeColorWhite ) {\r
+        backColor = appData.fontBackColorWhite;\r
+        foreColor = appData.fontForeColorWhite;\r
+    }\r
+    else if( index >= 6 && appData.fontBackColorBlack != appData.fontForeColorBlack ) {\r
+        backColor = appData.fontBackColorBlack;\r
+        foreColor = appData.fontForeColorBlack;\r
+    }\r
+\r
+    /* Mask */\r
+    hbm = CreateCompatibleBitmap( hdc_window, squareSize, squareSize );\r
+\r
+    hbm_old = SelectObject( hdc, hbm );\r
+\r
+    rc.left = 0;\r
+    rc.top = 0;\r
+    rc.right = squareSize;\r
+    rc.bottom = squareSize;\r
+\r
+    /* Step 1: background is now black */\r
+    FillRect( hdc, &rc, GetStockObject(BLACK_BRUSH) );\r
+\r
+    GetTextExtentPoint32( hdc, &pieceToFontChar[index], 1, &sz );\r
+\r
+    pt.x = (squareSize - sz.cx) / 2;\r
+    pt.y = (squareSize - sz.cy) / 2;\r
+\r
+    SetBkMode( hdc, TRANSPARENT );\r
+    SetTextColor( hdc, chroma );\r
+    /* Step 2: the piece has been drawn in purple, there are now black and purple in this bitmap */\r
+    TextOut( hdc, pt.x, pt.y, &pieceToFontChar[index], 1 );\r
+\r
+    SelectObject( hdc, GetStockObject(WHITE_BRUSH) );\r
+    /* Step 3: the area outside the piece is filled with white */\r
+    FloodFill( hdc, 0, 0, chroma );\r
+    SelectObject( hdc, GetStockObject(BLACK_BRUSH) );\r
+    /* \r
+        Step 4: this is the tricky part, the area inside the piece is filled with black,\r
+        but if the start point is not inside the piece we're lost!\r
+        There should be a better way to do this... if we could create a region or path\r
+        from the fill operation we would be fine for example.\r
+    */\r
+    FloodFill( hdc, squareSize / 2, squareSize / 2, RGB(0xFF,0xFF,0xFF) );\r
+\r
+    SetTextColor( hdc, 0 );\r
+    /* \r
+        Step 5: some fonts have "disconnected" areas that are skipped by the fill:\r
+        draw the piece again in black for safety.\r
+    */\r
+    TextOut( hdc, pt.x, pt.y, &pieceToFontChar[index], 1 );\r
+\r
+    SelectObject( hdc, hbm_old );\r
+\r
+    if( hPieceMask[index] != NULL ) {\r
+        DeleteObject( hPieceMask[index] );\r
+    }\r
+\r
+    hPieceMask[index] = hbm;\r
+\r
+    /* Face */\r
+    hbm = CreateCompatibleBitmap( hdc_window, squareSize, squareSize );\r
+\r
+    SelectObject( hdc, hbm );\r
+\r
+    {\r
+        HDC dc1 = CreateCompatibleDC( hdc_window );\r
+        HDC dc2 = CreateCompatibleDC( hdc_window );\r
+        HBITMAP bm2 = CreateCompatibleBitmap( hdc_window, squareSize, squareSize );\r
+\r
+        SelectObject( dc1, hPieceMask[index] );\r
+        SelectObject( dc2, bm2 );\r
+        FillRect( dc2, &rc, GetStockObject(WHITE_BRUSH) );\r
+        BitBlt( dc2, 0, 0, squareSize, squareSize, dc1, 0, 0, SRCINVERT );\r
+        \r
+        /* \r
+            Now dc2 contains the inverse of the piece mask, i.e. a mask that preserves\r
+            the piece background and deletes (makes transparent) the rest.\r
+            Thanks to that mask, we are free to paint the background with the greates\r
+            freedom, as we'll be able to mask off the unwanted parts when finished.\r
+            We use this, to make gradients and give the pieces a "roundish" look.\r
+        */\r
+        SetPieceBackground( hdc, backColor, 2 );\r
+        BitBlt( hdc, 0, 0, squareSize, squareSize, dc2, 0, 0, SRCAND );\r
+\r
+        DeleteDC( dc2 );\r
+        DeleteDC( dc1 );\r
+        DeleteObject( bm2 );\r
+    }\r
+\r
+    SetTextColor( hdc, foreColor );\r
+    TextOut( hdc, pt.x, pt.y, &pieceToFontChar[index], 1 );\r
+\r
+    SelectObject( hdc, hbm_old );\r
+\r
+    if( hPieceFace[index] != NULL ) {\r
+        DeleteObject( hPieceFace[index] );\r
+    }\r
+\r
+    hPieceFace[index] = hbm;\r
+}\r
+\r
+static int TranslatePieceToFontPiece( int piece )\r
+{\r
+    switch( piece ) {\r
+    case BlackPawn:\r
+        return PM_BP;\r
+    case BlackKnight:\r
+        return PM_BN;\r
+    case BlackBishop:\r
+        return PM_BB;\r
+    case BlackRook:\r
+        return PM_BR;\r
+    case BlackQueen:\r
+        return PM_BQ;\r
+    case BlackKing:\r
+        return PM_BK;\r
+    case WhitePawn:\r
+        return PM_WP;\r
+    case WhiteKnight:\r
+        return PM_WN;\r
+    case WhiteBishop:\r
+        return PM_WB;\r
+    case WhiteRook:\r
+        return PM_WR;\r
+    case WhiteQueen:\r
+        return PM_WQ;\r
+    case WhiteKing:\r
+        return PM_WK;\r
+#ifdef FAIRY\r
+    case BlackCardinal:\r
+        return PM_BA;\r
+    case BlackMarshall:\r
+        return PM_BC;\r
+    case BlackFairyPawn:\r
+        return PM_BFP;\r
+    case BlackFairyKnight:\r
+        return PM_BFN;\r
+    case BlackFairyBishop:\r
+        return PM_BFB;\r
+    case BlackFairyRook:\r
+        return PM_BFR;\r
+    case BlackFairyCardinal:\r
+        return PM_BFA;\r
+    case BlackFairyMarshall:\r
+        return PM_BFC;\r
+    case BlackFairyQueen:\r
+        return PM_BFQ;\r
+    case BlackFairyKing:\r
+        return PM_BFK;\r
+    case WhiteCardinal:\r
+        return PM_WA;\r
+    case WhiteMarshall:\r
+        return PM_WC;\r
+    case WhiteFairyPawn:\r
+        return PM_WFP;\r
+    case WhiteFairyKnight:\r
+        return PM_WFN;\r
+    case WhiteFairyBishop:\r
+        return PM_WFB;\r
+    case WhiteFairyRook:\r
+        return PM_WFR;\r
+    case WhiteFairyCardinal:\r
+        return PM_WFA;\r
+    case WhiteFairyMarshall:\r
+        return PM_WFC;\r
+    case WhiteFairyQueen:\r
+        return PM_WFQ;\r
+    case WhiteFairyKing:\r
+        return PM_WFK;\r
+#endif\r
+    }\r
+\r
+    return 0;\r
+}\r
+\r
+void CreatePiecesFromFont()\r
+{\r
+    LOGFONT lf;\r
+    HDC hdc_window = NULL;\r
+    HDC hdc = NULL;\r
+    HFONT hfont_old;\r
+    int fontHeight;\r
+    int i;\r
+\r
+    if( fontBitmapSquareSize < 0 ) {\r
+        /* Something went seriously wrong in the past: do not try to recreate fonts! */\r
+        return;\r
+    }\r
+\r
+    if( appData.renderPiecesWithFont == NULL || appData.renderPiecesWithFont[0] == NULLCHAR || appData.renderPiecesWithFont[0] == '*' ) {\r
+        fontBitmapSquareSize = -1;\r
+        return;\r
+    }\r
+\r
+    if( fontBitmapSquareSize != squareSize ) {\r
+        hdc_window = GetDC( hwndMain );\r
+        hdc = CreateCompatibleDC( hdc_window );\r
+\r
+        if( hPieceFont != NULL ) {\r
+            DeleteObject( hPieceFont );\r
+        }\r
+        else {\r
+            for( i=0; i<12; i++ ) {\r
+                hPieceMask[i] = NULL;\r
+                hPieceFace[i] = NULL;\r
+            }\r
+        }\r
+\r
+        fontHeight = 75;\r
+\r
+        if( appData.fontPieceSize >= 50 && appData.fontPieceSize <= 150 ) {\r
+            fontHeight = appData.fontPieceSize;\r
+        }\r
+\r
+        fontHeight = (fontHeight * squareSize) / 100;\r
+\r
+        lf.lfHeight = -MulDiv( fontHeight, GetDeviceCaps(hdc, LOGPIXELSY), 72 );\r
+        lf.lfWidth = 0;\r
+        lf.lfEscapement = 0;\r
+        lf.lfOrientation = 0;\r
+        lf.lfWeight = FW_NORMAL;\r
+        lf.lfItalic = 0;\r
+        lf.lfUnderline = 0;\r
+        lf.lfStrikeOut = 0;\r
+        lf.lfCharSet = DEFAULT_CHARSET;\r
+        lf.lfOutPrecision = OUT_DEFAULT_PRECIS;\r
+        lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;\r
+        lf.lfQuality = PROOF_QUALITY;\r
+        lf.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;\r
+        strncpy( lf.lfFaceName, appData.renderPiecesWithFont, sizeof(lf.lfFaceName) );\r
+        lf.lfFaceName[ sizeof(lf.lfFaceName) - 1 ] = '\0';\r
+\r
+        hPieceFont = CreateFontIndirect( &lf );\r
+\r
+        if( hPieceFont == NULL ) {\r
+            fontBitmapSquareSize = -2;\r
+        }\r
+        else {\r
+            /* Setup font-to-piece character table */\r
+            if( ! SetPieceToFontCharTable(appData.fontToPieceTable) ) {\r
+                /* No (or wrong) global settings, try to detect the font */\r
+                if( strstr(lf.lfFaceName,"Alpha") != NULL ) {\r
+                    /* Alpha */\r
+                    SetPieceToFontCharTable("phbrqkojntwl");\r
+                }\r
+                else if( strstr(lf.lfFaceName,"DiagramTT") != NULL ) {\r
+                    /* DiagramTT* family */\r
+                    SetPieceToFontCharTable("PNLRQKpnlrqk");\r
+                }\r
+#ifdef FAIRY\r
+                else if( strstr(lf.lfFaceName,"WinboardF") != NULL ) {\r
+                    /* Fairy symbols */\r
+                        SetPieceToFontCharTable("PNBRACFHEWUOGMQKpnbracfewuogmqk");\r
+                }\r
+#endif\r
+                else if( strstr(lf.lfFaceName,"GC2004D") != NULL ) {\r
+                    /* Good Companion (Some characters get warped as literal :-( */\r
+                    char s[] = "1cmWG0ñueOS¯®oYI23wgQU";\r
+                    s[0]=0xB9; s[1]=0xA9; s[6]=0xB1; s[11]=0xBB; s[12]=0xAB; s[17]=0xB3;\r
+                    SetPieceToFontCharTable(s);\r
+                }\r
+                else {\r
+                    /* Cases, Condal, Leipzig, Lucena, Marroquin, Merida, Usual */\r
+                    SetPieceToFontCharTable("pnbrqkomvtwl");\r
+                }\r
+            }\r
+\r
+            /* Create bitmaps */\r
+            hfont_old = SelectObject( hdc, hPieceFont );\r
+\r
+            CreatePieceMaskFromFont( hdc_window, hdc, PM_WP );\r
+            CreatePieceMaskFromFont( hdc_window, hdc, PM_WN );\r
+            CreatePieceMaskFromFont( hdc_window, hdc, PM_WB );\r
+            CreatePieceMaskFromFont( hdc_window, hdc, PM_WR );\r
+            CreatePieceMaskFromFont( hdc_window, hdc, PM_WQ );\r
+            CreatePieceMaskFromFont( hdc_window, hdc, PM_WK );\r
+            CreatePieceMaskFromFont( hdc_window, hdc, PM_BP );\r
+            CreatePieceMaskFromFont( hdc_window, hdc, PM_BN );\r
+            CreatePieceMaskFromFont( hdc_window, hdc, PM_BB );\r
+            CreatePieceMaskFromFont( hdc_window, hdc, PM_BR );\r
+            CreatePieceMaskFromFont( hdc_window, hdc, PM_BQ );\r
+            CreatePieceMaskFromFont( hdc_window, hdc, PM_BK );\r
+#ifdef FAIRY\r
+            CreatePieceMaskFromFont( hdc_window, hdc, PM_WA );\r
+            CreatePieceMaskFromFont( hdc_window, hdc, PM_WC );\r
+            CreatePieceMaskFromFont( hdc_window, hdc, PM_WFP );\r
+            CreatePieceMaskFromFont( hdc_window, hdc, PM_WFN );\r
+            CreatePieceMaskFromFont( hdc_window, hdc, PM_WFB );\r
+            CreatePieceMaskFromFont( hdc_window, hdc, PM_WFR );\r
+            CreatePieceMaskFromFont( hdc_window, hdc, PM_WFA );\r
+            CreatePieceMaskFromFont( hdc_window, hdc, PM_WFC );\r
+            CreatePieceMaskFromFont( hdc_window, hdc, PM_WFQ );\r
+            CreatePieceMaskFromFont( hdc_window, hdc, PM_WFK );\r
+            CreatePieceMaskFromFont( hdc_window, hdc, PM_BA );\r
+            CreatePieceMaskFromFont( hdc_window, hdc, PM_BC );\r
+            CreatePieceMaskFromFont( hdc_window, hdc, PM_BFP );\r
+            CreatePieceMaskFromFont( hdc_window, hdc, PM_BFN );\r
+            CreatePieceMaskFromFont( hdc_window, hdc, PM_BFB );\r
+            CreatePieceMaskFromFont( hdc_window, hdc, PM_BFR );\r
+            CreatePieceMaskFromFont( hdc_window, hdc, PM_BFA );\r
+            CreatePieceMaskFromFont( hdc_window, hdc, PM_BFC );\r
+            CreatePieceMaskFromFont( hdc_window, hdc, PM_BFQ );\r
+            CreatePieceMaskFromFont( hdc_window, hdc, PM_BFK );\r
+#endif\r
+\r
+            SelectObject( hdc, hfont_old );\r
+\r
+            fontBitmapSquareSize = squareSize;\r
+        }\r
+    }\r
+\r
+    if( hdc != NULL ) {\r
+        DeleteDC( hdc );\r
+    }\r
+\r
+    if( hdc_window != NULL ) {\r
+        ReleaseDC( hwndMain, hdc_window );\r
+    }\r
+}\r
+\r
 HBITMAP\r
 DoLoadBitmap(HINSTANCE hinst, char *piece, int squareSize, char *suffix)\r
 {\r
@@ -2681,25 +2832,25 @@ InitDrawingColors()
   whitePieceBrush = CreateSolidBrush(whitePieceColor);\r
   blackPieceBrush = CreateSolidBrush(blackPieceColor);\r
   iconBkgndBrush = CreateSolidBrush(GetSysColor(COLOR_BACKGROUND));\r
-
-  /* [AS] Force rendering of the font-based pieces */
-  if( fontBitmapSquareSize > 0 ) {
-    fontBitmapSquareSize = 0;
-  }
+\r
+  /* [AS] Force rendering of the font-based pieces */\r
+  if( fontBitmapSquareSize > 0 ) {\r
+    fontBitmapSquareSize = 0;\r
+  }\r
 }\r
 \r
 \r
 int\r
-BoardWidth(int boardSize)\r
-{\r
-  int lineGap = sizeInfo[boardSize].lineGap;
-
-  if( appData.overrideLineGap >= 0 && appData.overrideLineGap <= 5 ) {
-      lineGap = appData.overrideLineGap;
-  }
-
-  return (BOARD_SIZE + 1) * lineGap +
-         BOARD_SIZE * sizeInfo[boardSize].squareSize;\r
+BoardWidth(int boardSize, int n)\r
+{ /* [HGM] argument n added to allow different width and height */\r
+  int lineGap = sizeInfo[boardSize].lineGap;\r
+\r
+  if( appData.overrideLineGap >= 0 && appData.overrideLineGap <= 5 ) {\r
+      lineGap = appData.overrideLineGap;\r
+  }\r
+\r
+  return (n + 1) * lineGap +\r
+          n * sizeInfo[boardSize].squareSize;\r
 }\r
 \r
 /* Respond to board resize by dragging edge */\r
@@ -2726,7 +2877,7 @@ ResizeBoard(int newSizeX, int newSizeY, int flags)
 VOID\r
 InitDrawingSizes(BoardSize boardSize, int flags)\r
 {\r
-  int i, boardWidth;\r
+  int i, boardWidth, boardHeight; /* [HGM] height treated separately */\r
   ChessSquare piece;\r
   static int oldBoardSize = -1, oldTinyLayout = 0;\r
   HDC hdc;\r
@@ -2744,10 +2895,10 @@ InitDrawingSizes(BoardSize boardSize, int flags)
   squareSize = sizeInfo[boardSize].squareSize;\r
   lineGap = sizeInfo[boardSize].lineGap;\r
 \r
-  if( appData.overrideLineGap >= 0 && appData.overrideLineGap <= 5 ) {
-      lineGap = appData.overrideLineGap;
-  }
-
+  if( appData.overrideLineGap >= 0 && appData.overrideLineGap <= 5 ) {\r
+      lineGap = appData.overrideLineGap;\r
+  }\r
+\r
   if (tinyLayout != oldTinyLayout) {\r
     long style = GetWindowLong(hwndMain, GWL_STYLE);\r
     if (tinyLayout) {\r
@@ -2767,7 +2918,8 @@ InitDrawingSizes(BoardSize boardSize, int flags)
     DrawMenuBar(hwndMain);\r
   }\r
 \r
-  boardWidth = BoardWidth(boardSize);\r
+  boardWidth  = BoardWidth(boardSize, BOARD_WIDTH);\r
+  boardHeight = BoardWidth(boardSize, BOARD_HEIGHT);\r
 \r
   /* Get text area sizes */\r
   hdc = GetDC(hwndMain);\r
@@ -2808,7 +2960,7 @@ InitDrawingSizes(BoardSize boardSize, int flags)
   boardRect.left = whiteRect.left;\r
   boardRect.right = boardRect.left + boardWidth;\r
   boardRect.top = messageRect.bottom + INNER_MARGIN;\r
-  boardRect.bottom = boardRect.top + boardWidth;\r
+  boardRect.bottom = boardRect.top + boardHeight;\r
 \r
   sizeInfo[boardSize].cliWidth = boardRect.right + OUTER_MARGIN;\r
   sizeInfo[boardSize].cliHeight = boardRect.bottom + OUTER_MARGIN;\r
@@ -2896,18 +3048,23 @@ InitDrawingSizes(BoardSize boardSize, int flags)
       ExtCreatePen(PS_GEOMETRIC|PS_SOLID|PS_ENDCAP_FLAT|PS_JOIN_MITER,\r
                    lineGap, &logbrush, 0, NULL);\r
 \r
-    for (i = 0; i < BOARD_SIZE + 1; i++) {\r
+    /* [HGM] Loop had to be split in part for vert. and hor. lines */\r
+    for (i = 0; i < BOARD_HEIGHT + 1; i++) {\r
       gridEndpoints[i*2].x = boardRect.left + lineGap / 2;\r
-      gridEndpoints[i*2 + BOARD_SIZE*2 + 2].y = boardRect.top + lineGap / 2;\r
       gridEndpoints[i*2].y = gridEndpoints[i*2 + 1].y =\r
        boardRect.top + lineGap / 2 + (i * (squareSize + lineGap));\r
       gridEndpoints[i*2 + 1].x = boardRect.left + lineGap / 2 +\r
-       BOARD_SIZE * (squareSize + lineGap);\r
-      gridEndpoints[i*2 + BOARD_SIZE*2 + 2].x =\r
-       gridEndpoints[i*2 + 1 + BOARD_SIZE*2 + 2].x = boardRect.left +\r
+        BOARD_WIDTH * (squareSize + lineGap);\r
+       lineGap / 2 + (i * (squareSize + lineGap));\r
+      gridVertexCounts[i*2] = gridVertexCounts[i*2 + 1] = 2;\r
+    }\r
+    for (i = 0; i < BOARD_WIDTH + 1; i++) {\r
+      gridEndpoints[i*2 + BOARD_HEIGHT*2 + 2].y = boardRect.top + lineGap / 2;\r
+      gridEndpoints[i*2 + BOARD_HEIGHT*2 + 2].x =\r
+        gridEndpoints[i*2 + 1 + BOARD_HEIGHT*2 + 2].x = boardRect.left +\r
        lineGap / 2 + (i * (squareSize + lineGap));\r
-      gridEndpoints[i*2 + 1 + BOARD_SIZE*2 + 2].y =\r
-       boardRect.top + BOARD_SIZE * (squareSize + lineGap);\r
+      gridEndpoints[i*2 + 1 + BOARD_HEIGHT*2 + 2].y =\r
+        boardRect.top + BOARD_HEIGHT * (squareSize + lineGap);\r
       gridVertexCounts[i*2] = gridVertexCounts[i*2 + 1] = 2;\r
     }\r
   }\r
@@ -2919,7 +3076,7 @@ InitDrawingSizes(BoardSize boardSize, int flags)
   /* Load piece bitmaps for this board size */\r
   for (i=0; i<=2; i++) {\r
     for (piece = WhitePawn;\r
-        (int) piece <= (int) WhiteKing;\r
+         (int) piece < (int) BlackPawn;\r
         piece = (ChessSquare) ((int) piece + 1)) {\r
       if (pieceBitmap[i][piece] != NULL)\r
        DeleteObject(pieceBitmap[i][piece]);\r
@@ -2944,6 +3101,40 @@ InitDrawingSizes(BoardSize boardSize, int flags)
   pieceBitmap[2][WhiteRook] = DoLoadBitmap(hInst, "r", squareSize, "w");\r
   pieceBitmap[2][WhiteQueen] = DoLoadBitmap(hInst, "q", squareSize, "w");\r
   pieceBitmap[2][WhiteKing] = DoLoadBitmap(hInst, "k", squareSize, "w");\r
+#ifdef FAIRY\r
+  if(squareSize==72 || squareSize==49) { /* experiment with some home-made bitmaps */\r
+  pieceBitmap[0][WhiteCardinal] = DoLoadBitmap(hInst, "a", squareSize, "s");\r
+  pieceBitmap[0][WhiteMarshall] = DoLoadBitmap(hInst, "c", squareSize, "s");\r
+  pieceBitmap[0][WhiteFairyPawn] = DoLoadBitmap(hInst, "f", squareSize, "s");\r
+  pieceBitmap[0][WhiteFairyKnight] = DoLoadBitmap(hInst, "h", squareSize, "s");\r
+  pieceBitmap[0][WhiteFairyBishop] = DoLoadBitmap(hInst, "e", squareSize, "s");\r
+  pieceBitmap[0][WhiteFairyRook] = DoLoadBitmap(hInst, "w", squareSize, "s");\r
+  pieceBitmap[0][WhiteFairyQueen] = DoLoadBitmap(hInst, "g", squareSize, "s");\r
+  pieceBitmap[0][WhiteFairyCardinal] = DoLoadBitmap(hInst, "u", squareSize, "s");\r
+  pieceBitmap[0][WhiteFairyMarshall] = DoLoadBitmap(hInst, "o", squareSize, "s");\r
+  pieceBitmap[0][WhiteFairyKing] = DoLoadBitmap(hInst, "m", squareSize, "s");\r
+  pieceBitmap[1][WhiteCardinal] = DoLoadBitmap(hInst, "a", squareSize, "o");\r
+  pieceBitmap[1][WhiteMarshall] = DoLoadBitmap(hInst, "c", squareSize, "o");\r
+  pieceBitmap[1][WhiteFairyPawn] = DoLoadBitmap(hInst, "f", squareSize, "o");\r
+  pieceBitmap[1][WhiteFairyKnight] = DoLoadBitmap(hInst, "h", squareSize, "o");\r
+  pieceBitmap[1][WhiteFairyBishop] = DoLoadBitmap(hInst, "e", squareSize, "o");\r
+  pieceBitmap[1][WhiteFairyRook] = DoLoadBitmap(hInst, "w", squareSize, "o");\r
+  pieceBitmap[1][WhiteFairyQueen] = DoLoadBitmap(hInst, "g", squareSize, "o");\r
+  pieceBitmap[1][WhiteFairyCardinal] = DoLoadBitmap(hInst, "u", squareSize, "o");\r
+  pieceBitmap[1][WhiteFairyMarshall] = DoLoadBitmap(hInst, "o", squareSize, "o");\r
+  pieceBitmap[1][WhiteFairyKing] = DoLoadBitmap(hInst, "m", squareSize, "o");\r
+  pieceBitmap[2][WhiteCardinal] = DoLoadBitmap(hInst, "a", squareSize, "w");\r
+  pieceBitmap[2][WhiteMarshall] = DoLoadBitmap(hInst, "c", squareSize, "w");\r
+  pieceBitmap[2][WhiteFairyPawn] = DoLoadBitmap(hInst, "f", squareSize, "w");\r
+  pieceBitmap[2][WhiteFairyKnight] = DoLoadBitmap(hInst, "h", squareSize, "w");\r
+  pieceBitmap[2][WhiteFairyBishop] = DoLoadBitmap(hInst, "e", squareSize, "w");\r
+  pieceBitmap[2][WhiteFairyRook] = DoLoadBitmap(hInst, "w", squareSize, "w");\r
+  pieceBitmap[2][WhiteFairyQueen] = DoLoadBitmap(hInst, "g", squareSize, "w");\r
+  pieceBitmap[2][WhiteFairyCardinal] = DoLoadBitmap(hInst, "u", squareSize, "w");\r
+  pieceBitmap[2][WhiteFairyMarshall] = DoLoadBitmap(hInst, "o", squareSize, "w");\r
+  pieceBitmap[2][WhiteFairyKing] = DoLoadBitmap(hInst, "m", squareSize, "w");\r
+  }\r
+#endif\r
 \r
 }\r
 \r
@@ -2969,19 +3160,19 @@ VOID
 SquareToPos(int row, int column, int * x, int * y)\r
 {\r
   if (flipView) {\r
-    *x = boardRect.left + lineGap + ((BOARD_SIZE-1)-column) * (squareSize + lineGap);\r
+    *x = boardRect.left + lineGap + ((BOARD_WIDTH-1)-column) * (squareSize + lineGap);\r
     *y = boardRect.top + lineGap + row * (squareSize + lineGap);\r
   } else {\r
     *x = boardRect.left + lineGap + column * (squareSize + lineGap);\r
-    *y = boardRect.top + lineGap + ((BOARD_SIZE-1)-row) * (squareSize + lineGap);\r
+    *y = boardRect.top + lineGap + ((BOARD_HEIGHT-1)-row) * (squareSize + lineGap);\r
   }\r
 }\r
 \r
 VOID\r
 DrawCoordsOnDC(HDC hdc)\r
 {\r
-  static char files[16] = {'1','2','3','4','5','6','7','8','8','7','6','5','4','3','2','1'};\r
-  static char ranks[16] = {'h','g','f','e','d','c','b','a','a','b','c','d','e','f','g','h'};\r
+  static char files[24] = {'0', '1','2','3','4','5','6','7','8','9','0','1','1','0','9','8','7','6','5','4','3','2','1','0'};\r
+  static char ranks[24] = {'l', 'k','j','i','h','g','f','e','d','c','b','a','a','b','c','d','e','f','g','h','i','j','k','l'};\r
   char str[2] = { NULLCHAR, NULLCHAR };\r
   int oldMode, oldAlign, x, y, start, i;\r
   HFONT oldFont;\r
@@ -2990,7 +3181,7 @@ DrawCoordsOnDC(HDC hdc)
   if (!appData.showCoords)\r
     return;\r
 \r
-  start = flipView ? 0 : 8;\r
+  start = flipView ? 1-(ONE!='1') : 23+(ONE!='1')-BOARD_HEIGHT;\r
 \r
   oldBrush = SelectObject(hdc, GetStockObject(BLACK_BRUSH));\r
   oldMode = SetBkMode(hdc, (appData.monoMode ? OPAQUE : TRANSPARENT));\r
@@ -3001,14 +3192,16 @@ DrawCoordsOnDC(HDC hdc)
   x = boardRect.left + lineGap;\r
 \r
   SetTextAlign(hdc, TA_LEFT|TA_TOP);\r
-  for (i = 0; i < 8; i++) {\r
+  for (i = 0; i < BOARD_HEIGHT; i++) {\r
     str[0] = files[start + i];\r
     ExtTextOut(hdc, x + 2, y + 1, 0, NULL, str, 1, NULL);\r
     y += squareSize + lineGap;\r
   }\r
 \r
+  start = flipView ? 12-BOARD_WIDTH : 12;\r
+\r
   SetTextAlign(hdc, TA_RIGHT|TA_BOTTOM);\r
-  for (i = 0; i < 8; i++) {\r
+  for (i = 0; i < BOARD_WIDTH; i++) {\r
     str[0] = ranks[start + i];\r
     ExtTextOut(hdc, x + squareSize - 2, y - 1, 0, NULL, str, 1, NULL);\r
     x += squareSize + lineGap;\r
@@ -3027,7 +3220,7 @@ DrawGridOnDC(HDC hdc)
  \r
   if (lineGap != 0) {\r
     oldPen = SelectObject(hdc, gridPen);\r
-    PolyPolyline(hdc, gridEndpoints, gridVertexCounts, BOARD_SIZE*2 + 2);\r
+    PolyPolyline(hdc, gridEndpoints, gridVertexCounts, BOARD_WIDTH+BOARD_HEIGHT + 2);\r
     SelectObject(hdc, oldPen);\r
   }\r
 }\r
@@ -3043,14 +3236,14 @@ DrawHighlightOnDC(HDC hdc, BOOLEAN on, int x, int y, int pen)
   if (lineGap == 0) return;\r
   if (flipView) {\r
     x1 = boardRect.left +\r
-      lineGap/2 + ((BOARD_SIZE-1)-x) * (squareSize + lineGap);\r
+      lineGap/2 + ((BOARD_WIDTH-1)-x) * (squareSize + lineGap);\r
     y1 = boardRect.top +\r
       lineGap/2 + y * (squareSize + lineGap);\r
   } else {\r
     x1 = boardRect.left +\r
       lineGap/2 + x * (squareSize + lineGap);\r
     y1 = boardRect.top +\r
-      lineGap/2 + ((BOARD_SIZE-1)-y) * (squareSize + lineGap);\r
+      lineGap/2 + ((BOARD_HEIGHT-1)-y) * (squareSize + lineGap);\r
   }\r
   hPen = pen ? premovePen : highlightPen;\r
   oldPen = SelectObject(hdc, on ? hPen : gridPen);\r
@@ -3094,36 +3287,36 @@ DrawPieceOnDC(HDC hdc, ChessSquare piece, int color, int sqcolor, int x, int y,
 \r
   if (appData.blindfold) return;\r
 \r
-  /* [AS] Use font-based pieces if needed */
-  if( fontBitmapSquareSize >= 0 && squareSize > 32 ) {
-    /* Create piece bitmaps, or do nothing if piece set is up to date */
-    CreatePiecesFromFont();
-
-    if( fontBitmapSquareSize == squareSize ) {
-        int index = TranslatePieceToFontPiece( piece );
-
-        SelectObject( tmphdc, hPieceMask[ index ] );
-
-        BitBlt( hdc,
-            x, y,
-            squareSize, squareSize,
-            tmphdc,
-            0, 0,
-            SRCAND );
-
-        SelectObject( tmphdc, hPieceFace[ index ] );
-
-        BitBlt( hdc,
-            x, y,
-            squareSize, squareSize,
-            tmphdc,
-            0, 0,
-            SRCPAINT );
-
-        return;
-    }
-  }
-
+  /* [AS] Use font-based pieces if needed */\r
+  if( fontBitmapSquareSize >= 0 && squareSize > 32 ) {\r
+    /* Create piece bitmaps, or do nothing if piece set is up to date */\r
+    CreatePiecesFromFont();\r
+\r
+    if( fontBitmapSquareSize == squareSize ) {\r
+        int index = TranslatePieceToFontPiece( piece );\r
+\r
+        SelectObject( tmphdc, hPieceMask[ index ] );\r
+\r
+        BitBlt( hdc,\r
+            x, y,\r
+            squareSize, squareSize,\r
+            tmphdc,\r
+            0, 0,\r
+            SRCAND );\r
+\r
+        SelectObject( tmphdc, hPieceFace[ index ] );\r
+\r
+        BitBlt( hdc,\r
+            x, y,\r
+            squareSize, squareSize,\r
+            tmphdc,\r
+            0, 0,\r
+            SRCPAINT );\r
+\r
+        return;\r
+    }\r
+  }\r
+\r
   if (appData.monoMode) {\r
     SelectObject(tmphdc, PieceBitmap(piece, \r
       color == sqcolor ? OUTLINE_PIECE : SOLID_PIECE));\r
@@ -3171,391 +3364,397 @@ DrawPieceOnDC(HDC hdc, ChessSquare piece, int color, int sqcolor, int x, int y,
   }\r
 }\r
 \r
-/* [AS] Compute a drawing mode for a square, based on specified settings (see DrawTile) */
-int GetBackTextureMode( int algo )
-{
-    int result = BACK_TEXTURE_MODE_DISABLED;
-
-    switch( algo )
-    {
-        case BACK_TEXTURE_MODE_PLAIN:
-            result = 1; /* Always use identity map */
-            break;
-        case BACK_TEXTURE_MODE_FULL_RANDOM:
-            result = 1 + (myrandom() % 3); /* Pick a transformation at random */
-            break;
-    }
-
-    return result;
-}
-
-/*
-    [AS] Compute and save texture drawing info, otherwise we may not be able
-    to handle redraws cleanly (as random numbers would always be different).
-*/
-VOID RebuildTextureSquareInfo()
-{
-    BITMAP bi;
-    int lite_w = 0;
-    int lite_h = 0;
-    int dark_w = 0;
-    int dark_h = 0;
-    int row;
-    int col;
-
-    ZeroMemory( &backTextureSquareInfo, sizeof(backTextureSquareInfo) );
-
-    if( liteBackTexture != NULL ) {
-        if( GetObject( liteBackTexture, sizeof(bi), &bi ) > 0 ) {
-            lite_w = bi.bmWidth;
-            lite_h = bi.bmHeight;
-        }
-    }
-
-    if( darkBackTexture != NULL ) {
-        if( GetObject( darkBackTexture, sizeof(bi), &bi ) > 0 ) {
-            dark_w = bi.bmWidth;
-            dark_h = bi.bmHeight;
-        }
-    }
-
-    for( row=0; row<BOARD_SIZE; row++ ) {
-        for( col=0; col<BOARD_SIZE; col++ ) {
-            if( (col + row) & 1 ) {
-                /* Lite square */
-                if( lite_w >= squareSize && lite_h >= squareSize ) {
-                    backTextureSquareInfo[row][col].x = col * (lite_w - squareSize) / BOARD_SIZE;
-                    backTextureSquareInfo[row][col].y = row * (lite_h - squareSize) / BOARD_SIZE;
-                    backTextureSquareInfo[row][col].mode = GetBackTextureMode(liteBackTextureMode);
-                }
-            }
-            else {
-                /* Dark square */
-                if( dark_w >= squareSize && dark_h >= squareSize ) {
-                    backTextureSquareInfo[row][col].x = col * (dark_w - squareSize) / BOARD_SIZE;
-                    backTextureSquareInfo[row][col].y = row * (dark_h - squareSize) / BOARD_SIZE;
-                    backTextureSquareInfo[row][col].mode = GetBackTextureMode(darkBackTextureMode);
-                }
-            }
-        }
-    }
-}
-
-/* [AS] Arrow highlighting support */
-
-static int A_WIDTH = 5; /* Width of arrow body */
-
-#define A_HEIGHT_FACTOR 6   /* Length of arrow "point", relative to body width */
-#define A_WIDTH_FACTOR  3   /* Width of arrow "point", relative to body width */
-
-static double Sqr( double x )
-{
-    return x*x;
-}
-
-static int Round( double x )
-{
-    return (int) (x + 0.5);
-}
-
-/* Draw an arrow between two points using current settings */
-VOID DrawArrowBetweenPoints( HDC hdc, int s_x, int s_y, int d_x, int d_y )
-{
-    POINT arrow[7];
-    double dx, dy, j, k, x, y;
-
-    if( d_x == s_x ) {
-        int h = (d_y > s_y) ? +A_WIDTH*A_HEIGHT_FACTOR : -A_WIDTH*A_HEIGHT_FACTOR;
-
-        arrow[0].x = s_x + A_WIDTH;
-        arrow[0].y = s_y;
-
-        arrow[1].x = s_x + A_WIDTH;
-        arrow[1].y = d_y - h;
-
-        arrow[2].x = s_x + A_WIDTH*A_WIDTH_FACTOR;
-        arrow[2].y = d_y - h;
-
-        arrow[3].x = d_x;
-        arrow[3].y = d_y;
-
-        arrow[4].x = s_x - A_WIDTH*A_WIDTH_FACTOR;
-        arrow[4].y = d_y - h;
-
-        arrow[5].x = s_x - A_WIDTH;
-        arrow[5].y = d_y - h;
-
-        arrow[6].x = s_x - A_WIDTH;
-        arrow[6].y = s_y;
-    }
-    else if( d_y == s_y ) {
-        int w = (d_x > s_x) ? +A_WIDTH*A_HEIGHT_FACTOR : -A_WIDTH*A_HEIGHT_FACTOR;
-
-        arrow[0].x = s_x;
-        arrow[0].y = s_y + A_WIDTH;
-
-        arrow[1].x = d_x - w;
-        arrow[1].y = s_y + A_WIDTH;
-
-        arrow[2].x = d_x - w;
-        arrow[2].y = s_y + A_WIDTH*A_WIDTH_FACTOR;
-
-        arrow[3].x = d_x;
-        arrow[3].y = d_y;
-
-        arrow[4].x = d_x - w;
-        arrow[4].y = s_y - A_WIDTH*A_WIDTH_FACTOR;
-
-        arrow[5].x = d_x - w;
-        arrow[5].y = s_y - A_WIDTH;
-
-        arrow[6].x = s_x;
-        arrow[6].y = s_y - A_WIDTH;
-    }
-    else {
-        /* [AS] Needed a lot of paper for this! :-) */
-        dy = (double) (d_y - s_y) / (double) (d_x - s_x);
-        dx = (double) (s_x - d_x) / (double) (s_y - d_y);
-
-        j = sqrt( Sqr(A_WIDTH) / (1.0 + Sqr(dx)) );
-
-        k = sqrt( Sqr(A_WIDTH*A_HEIGHT_FACTOR) / (1.0 + Sqr(dy)) );
-
-        x = s_x;
-        y = s_y;
-
-        arrow[0].x = Round(x - j);
-        arrow[0].y = Round(y + j*dx);
-
-        arrow[1].x = Round(x + j);
-        arrow[1].y = Round(y - j*dx);
-
-        if( d_x > s_x ) {
-            x = (double) d_x - k;
-            y = (double) d_y - k*dy;
-        }
-        else {
-            x = (double) d_x + k;
-            y = (double) d_y + k*dy;
-        }
-
-        arrow[2].x = Round(x + j);
-        arrow[2].y = Round(y - j*dx);
-
-        arrow[3].x = Round(x + j*A_WIDTH_FACTOR);
-        arrow[3].y = Round(y - j*A_WIDTH_FACTOR*dx);
-
-        arrow[4].x = d_x;
-        arrow[4].y = d_y;
-
-        arrow[5].x = Round(x - j*A_WIDTH_FACTOR);
-        arrow[5].y = Round(y + j*A_WIDTH_FACTOR*dx);
-
-        arrow[6].x = Round(x - j);
-        arrow[6].y = Round(y + j*dx);
-    }
-
-    Polygon( hdc, arrow, 7 );
-}
-
-/* [AS] Draw an arrow between two squares */
-VOID DrawArrowBetweenSquares( HDC hdc, int s_col, int s_row, int d_col, int d_row )
-{
-    int s_x, s_y, d_x, d_y;
-    HPEN hpen;
-    HPEN holdpen;
-    HBRUSH hbrush;
-    HBRUSH holdbrush;
-    LOGBRUSH stLB;
-
-    if( s_col == d_col && s_row == d_row ) {
-        return;
-    }
-
-    /* Get source and destination points */
-    SquareToPos( s_row, s_col, &s_x, &s_y);
-    SquareToPos( d_row, d_col, &d_x, &d_y);
-
-    if( d_y > s_y ) {
-        d_y += squareSize / 4;
-    }
-    else if( d_y < s_y ) {
-        d_y += 3 * squareSize / 4;
-    }
-    else {
-        d_y += squareSize / 2;
-    }
-
-    if( d_x > s_x ) {
-        d_x += squareSize / 4;
-    }
-    else if( d_x < s_x ) {
-        d_x += 3 * squareSize / 4;
-    }
-    else {
-        d_x += squareSize / 2;
-    }
-
-    s_x += squareSize / 2;
-    s_y += squareSize / 2;
-
-    /* Adjust width */
-    A_WIDTH = squareSize / 14;
-
-    /* Draw */
-    stLB.lbStyle = BS_SOLID;
-    stLB.lbColor = appData.highlightArrowColor;
-    stLB.lbHatch = 0;
-
-    hpen = CreatePen( PS_SOLID, 2, RGB(0x00,0x00,0x00) );
-    holdpen = SelectObject( hdc, hpen );
-    hbrush = CreateBrushIndirect( &stLB );
-    holdbrush = SelectObject( hdc, hbrush );
-
-    DrawArrowBetweenPoints( hdc, s_x, s_y, d_x, d_y );
-
-    SelectObject( hdc, holdpen );
-    SelectObject( hdc, holdbrush );
-    DeleteObject( hpen );
-    DeleteObject( hbrush );
-}
-
-BOOL HasHighlightInfo()
-{
-    BOOL result = FALSE;
-
-    if( highlightInfo.sq[0].x >= 0 && highlightInfo.sq[0].y >= 0 &&
-        highlightInfo.sq[1].x >= 0 && highlightInfo.sq[1].y >= 0 )
-    {
-        result = TRUE;
-    }
-
-    return result;
-}
-
-BOOL IsDrawArrowEnabled()
-{
-    BOOL result = FALSE;
-
-    if( appData.highlightMoveWithArrow && squareSize >= 32 ) {
-        result = TRUE;
-    }
-
-    return result;
-}
-
-VOID DrawArrowHighlight( HDC hdc )
-{
-    if( IsDrawArrowEnabled() && HasHighlightInfo() ) {
-        DrawArrowBetweenSquares( hdc,
-            highlightInfo.sq[0].x, highlightInfo.sq[0].y,
-            highlightInfo.sq[1].x, highlightInfo.sq[1].y );
-    }
-}
-
-HRGN GetArrowHighlightClipRegion( HDC hdc )
-{
-    HRGN result = NULL;
-
-    if( HasHighlightInfo() ) {
-        int x1, y1, x2, y2;
-        int sx, sy, dx, dy;
-
-        SquareToPos(highlightInfo.sq[0].y, highlightInfo.sq[0].x, &x1, &y1 );
-        SquareToPos(highlightInfo.sq[1].y, highlightInfo.sq[1].x, &x2, &y2 );
-
-        sx = MIN( x1, x2 );
-        sy = MIN( y1, y2 );
-        dx = MAX( x1, x2 ) + squareSize;
-        dy = MAX( y1, y2 ) + squareSize;
-
-        result = CreateRectRgn( sx, sy, dx, dy );
-    }
-
-    return result;
-}
-
-/*
-    Warning: this function modifies the behavior of several other functions.
-
-    Basically, Winboard is optimized to avoid drawing the whole board if not strictly
-    needed. Unfortunately, the decision whether or not to perform a full or partial
-    repaint is scattered all over the place, which is not good for features such as
-    "arrow highlighting" that require a full repaint of the board.
-
-    So, I've tried to patch the code where I thought it made sense (e.g. after or during
-    user interaction, when speed is not so important) but especially to avoid errors
-    in the displayed graphics.
-
-    In such patched places, I always try refer to this function so there is a single
-    place to maintain knowledge.
-
-    To restore the original behavior, just return FALSE unconditionally.
-*/
-BOOL IsFullRepaintPreferrable()
-{
-    BOOL result = FALSE;
-
-    if( (appData.highlightLastMove || appData.highlightDragging) && IsDrawArrowEnabled() ) {
-        /* Arrow may appear on the board */
-        result = TRUE;
-    }
-
-    return result;
-}
-
-/*
-    This function is called by DrawPosition to know whether a full repaint must
-    be forced or not.
-
-    Only DrawPosition may directly call this function, which makes use of
-    some state information. Other function should call DrawPosition specifying
-    the repaint flag, and can use IsFullRepaintPreferrable if needed.
-*/
-BOOL DrawPositionNeedsFullRepaint()
-{
-    BOOL result = FALSE;
-
-    /*
-        Probably a slightly better policy would be to trigger a full repaint
-        when animInfo.piece changes state (i.e. empty -> non-empty and viceversa),
-        but animation is fast enough that it's difficult to notice.
-    */
-    if( animInfo.piece == EmptySquare ) {
-        if( (appData.highlightLastMove || appData.highlightDragging) && IsDrawArrowEnabled() && HasHighlightInfo() ) {
-            result = TRUE;
-        }
-    }
-
-    return result;
-}
-
+/* [AS] Compute a drawing mode for a square, based on specified settings (see DrawTile) */\r
+int GetBackTextureMode( int algo )\r
+{\r
+    int result = BACK_TEXTURE_MODE_DISABLED;\r
+\r
+    switch( algo ) \r
+    {\r
+        case BACK_TEXTURE_MODE_PLAIN:\r
+            result = 1; /* Always use identity map */\r
+            break;\r
+        case BACK_TEXTURE_MODE_FULL_RANDOM:\r
+            result = 1 + (myrandom() % 3); /* Pick a transformation at random */\r
+            break;\r
+    }\r
+\r
+    return result;\r
+}\r
+\r
+/* \r
+    [AS] Compute and save texture drawing info, otherwise we may not be able\r
+    to handle redraws cleanly (as random numbers would always be different).\r
+*/\r
+VOID RebuildTextureSquareInfo()\r
+{\r
+    BITMAP bi;\r
+    int lite_w = 0;\r
+    int lite_h = 0;\r
+    int dark_w = 0;\r
+    int dark_h = 0;\r
+    int row;\r
+    int col;\r
+\r
+    ZeroMemory( &backTextureSquareInfo, sizeof(backTextureSquareInfo) );\r
+\r
+    if( liteBackTexture != NULL ) {\r
+        if( GetObject( liteBackTexture, sizeof(bi), &bi ) > 0 ) {\r
+            lite_w = bi.bmWidth;\r
+            lite_h = bi.bmHeight;\r
+        }\r
+    }\r
+\r
+    if( darkBackTexture != NULL ) {\r
+        if( GetObject( darkBackTexture, sizeof(bi), &bi ) > 0 ) {\r
+            dark_w = bi.bmWidth;\r
+            dark_h = bi.bmHeight;\r
+        }\r
+    }\r
+\r
+    for( row=0; row<BOARD_HEIGHT; row++ ) {\r
+        for( col=0; col<BOARD_WIDTH; col++ ) {\r
+            if( (col + row) & 1 ) {\r
+                /* Lite square */\r
+                if( lite_w >= squareSize && lite_h >= squareSize ) {\r
+                    backTextureSquareInfo[row][col].x = col * (lite_w - squareSize) / BOARD_WIDTH;\r
+                    backTextureSquareInfo[row][col].y = row * (lite_h - squareSize) / BOARD_HEIGHT;\r
+                    backTextureSquareInfo[row][col].mode = GetBackTextureMode(liteBackTextureMode);\r
+                }\r
+            }\r
+            else {\r
+                /* Dark square */\r
+                if( dark_w >= squareSize && dark_h >= squareSize ) {\r
+                    backTextureSquareInfo[row][col].x = col * (dark_w - squareSize) / BOARD_WIDTH;\r
+                    backTextureSquareInfo[row][col].y = row * (dark_h - squareSize) / BOARD_HEIGHT;\r
+                    backTextureSquareInfo[row][col].mode = GetBackTextureMode(darkBackTextureMode);\r
+                }\r
+            }\r
+        }\r
+    }\r
+}\r
+\r
+/* [AS] Arrow highlighting support */\r
+\r
+static int A_WIDTH = 5; /* Width of arrow body */\r
+\r
+#define A_HEIGHT_FACTOR 6   /* Length of arrow "point", relative to body width */\r
+#define A_WIDTH_FACTOR  3   /* Width of arrow "point", relative to body width */\r
+\r
+static double Sqr( double x )\r
+{\r
+    return x*x;\r
+}\r
+\r
+static int Round( double x )\r
+{\r
+    return (int) (x + 0.5);\r
+}\r
+\r
+/* Draw an arrow between two points using current settings */\r
+VOID DrawArrowBetweenPoints( HDC hdc, int s_x, int s_y, int d_x, int d_y )\r
+{\r
+    POINT arrow[7];\r
+    double dx, dy, j, k, x, y;\r
+\r
+    if( d_x == s_x ) {\r
+        int h = (d_y > s_y) ? +A_WIDTH*A_HEIGHT_FACTOR : -A_WIDTH*A_HEIGHT_FACTOR;\r
+\r
+        arrow[0].x = s_x + A_WIDTH;\r
+        arrow[0].y = s_y;\r
+\r
+        arrow[1].x = s_x + A_WIDTH;\r
+        arrow[1].y = d_y - h;\r
+\r
+        arrow[2].x = s_x + A_WIDTH*A_WIDTH_FACTOR;\r
+        arrow[2].y = d_y - h;\r
+\r
+        arrow[3].x = d_x;\r
+        arrow[3].y = d_y;\r
+\r
+        arrow[4].x = s_x - A_WIDTH*A_WIDTH_FACTOR;\r
+        arrow[4].y = d_y - h;\r
+\r
+        arrow[5].x = s_x - A_WIDTH;\r
+        arrow[5].y = d_y - h;\r
+\r
+        arrow[6].x = s_x - A_WIDTH;\r
+        arrow[6].y = s_y;\r
+    }\r
+    else if( d_y == s_y ) {\r
+        int w = (d_x > s_x) ? +A_WIDTH*A_HEIGHT_FACTOR : -A_WIDTH*A_HEIGHT_FACTOR;\r
+\r
+        arrow[0].x = s_x;\r
+        arrow[0].y = s_y + A_WIDTH;\r
+\r
+        arrow[1].x = d_x - w;\r
+        arrow[1].y = s_y + A_WIDTH;\r
+\r
+        arrow[2].x = d_x - w;\r
+        arrow[2].y = s_y + A_WIDTH*A_WIDTH_FACTOR;\r
+\r
+        arrow[3].x = d_x;\r
+        arrow[3].y = d_y;\r
+\r
+        arrow[4].x = d_x - w;\r
+        arrow[4].y = s_y - A_WIDTH*A_WIDTH_FACTOR;\r
+\r
+        arrow[5].x = d_x - w;\r
+        arrow[5].y = s_y - A_WIDTH;\r
+\r
+        arrow[6].x = s_x;\r
+        arrow[6].y = s_y - A_WIDTH;\r
+    }\r
+    else {\r
+        /* [AS] Needed a lot of paper for this! :-) */\r
+        dy = (double) (d_y - s_y) / (double) (d_x - s_x);\r
+        dx = (double) (s_x - d_x) / (double) (s_y - d_y);\r
+  \r
+        j = sqrt( Sqr(A_WIDTH) / (1.0 + Sqr(dx)) );\r
+\r
+        k = sqrt( Sqr(A_WIDTH*A_HEIGHT_FACTOR) / (1.0 + Sqr(dy)) );\r
+\r
+        x = s_x;\r
+        y = s_y;\r
+\r
+        arrow[0].x = Round(x - j);\r
+        arrow[0].y = Round(y + j*dx);\r
+\r
+        arrow[1].x = Round(x + j);\r
+        arrow[1].y = Round(y - j*dx);\r
+\r
+        if( d_x > s_x ) {\r
+            x = (double) d_x - k;\r
+            y = (double) d_y - k*dy;\r
+        }\r
+        else {\r
+            x = (double) d_x + k;\r
+            y = (double) d_y + k*dy;\r
+        }\r
+\r
+        arrow[2].x = Round(x + j);\r
+        arrow[2].y = Round(y - j*dx);\r
+\r
+        arrow[3].x = Round(x + j*A_WIDTH_FACTOR);\r
+        arrow[3].y = Round(y - j*A_WIDTH_FACTOR*dx);\r
+\r
+        arrow[4].x = d_x;\r
+        arrow[4].y = d_y;\r
+\r
+        arrow[5].x = Round(x - j*A_WIDTH_FACTOR);\r
+        arrow[5].y = Round(y + j*A_WIDTH_FACTOR*dx);\r
+\r
+        arrow[6].x = Round(x - j);\r
+        arrow[6].y = Round(y + j*dx);\r
+    }\r
+\r
+    Polygon( hdc, arrow, 7 );\r
+}\r
+\r
+/* [AS] Draw an arrow between two squares */\r
+VOID DrawArrowBetweenSquares( HDC hdc, int s_col, int s_row, int d_col, int d_row )\r
+{\r
+    int s_x, s_y, d_x, d_y;\r
+    HPEN hpen;\r
+    HPEN holdpen;\r
+    HBRUSH hbrush;\r
+    HBRUSH holdbrush;\r
+    LOGBRUSH stLB;\r
+\r
+    if( s_col == d_col && s_row == d_row ) {\r
+        return;\r
+    }\r
+\r
+    /* Get source and destination points */\r
+    SquareToPos( s_row, s_col, &s_x, &s_y);\r
+    SquareToPos( d_row, d_col, &d_x, &d_y);\r
+\r
+    if( d_y > s_y ) {\r
+        d_y += squareSize / 4;\r
+    }\r
+    else if( d_y < s_y ) {\r
+        d_y += 3 * squareSize / 4;\r
+    }\r
+    else {\r
+        d_y += squareSize / 2;\r
+    }\r
+\r
+    if( d_x > s_x ) {\r
+        d_x += squareSize / 4;\r
+    }\r
+    else if( d_x < s_x ) {\r
+        d_x += 3 * squareSize / 4;\r
+    }\r
+    else {\r
+        d_x += squareSize / 2;\r
+    }\r
+\r
+    s_x += squareSize / 2;\r
+    s_y += squareSize / 2;\r
+\r
+    /* Adjust width */\r
+    A_WIDTH = squareSize / 14;\r
+\r
+    /* Draw */\r
+    stLB.lbStyle = BS_SOLID;\r
+    stLB.lbColor = appData.highlightArrowColor;\r
+    stLB.lbHatch = 0;\r
+\r
+    hpen = CreatePen( PS_SOLID, 2, RGB(0x00,0x00,0x00) );\r
+    holdpen = SelectObject( hdc, hpen );\r
+    hbrush = CreateBrushIndirect( &stLB );\r
+    holdbrush = SelectObject( hdc, hbrush );\r
+\r
+    DrawArrowBetweenPoints( hdc, s_x, s_y, d_x, d_y );\r
+\r
+    SelectObject( hdc, holdpen );\r
+    SelectObject( hdc, holdbrush );\r
+    DeleteObject( hpen );\r
+    DeleteObject( hbrush );\r
+}\r
+\r
+BOOL HasHighlightInfo()\r
+{\r
+    BOOL result = FALSE;\r
+\r
+    if( highlightInfo.sq[0].x >= 0 && highlightInfo.sq[0].y >= 0 &&\r
+        highlightInfo.sq[1].x >= 0 && highlightInfo.sq[1].y >= 0 )\r
+    {\r
+        result = TRUE;\r
+    }\r
+\r
+    return result;\r
+}\r
+\r
+BOOL IsDrawArrowEnabled()\r
+{\r
+    BOOL result = FALSE;\r
+\r
+    if( appData.highlightMoveWithArrow && squareSize >= 32 ) {\r
+        result = TRUE;\r
+    }\r
+\r
+    return result;\r
+}\r
+\r
+VOID DrawArrowHighlight( HDC hdc )\r
+{\r
+    if( IsDrawArrowEnabled() && HasHighlightInfo() ) {\r
+        DrawArrowBetweenSquares( hdc,\r
+            highlightInfo.sq[0].x, highlightInfo.sq[0].y,\r
+            highlightInfo.sq[1].x, highlightInfo.sq[1].y );\r
+    }\r
+}\r
+\r
+HRGN GetArrowHighlightClipRegion( HDC hdc )\r
+{\r
+    HRGN result = NULL;\r
+\r
+    if( HasHighlightInfo() ) {\r
+        int x1, y1, x2, y2;\r
+        int sx, sy, dx, dy;\r
+\r
+        SquareToPos(highlightInfo.sq[0].y, highlightInfo.sq[0].x, &x1, &y1 );\r
+        SquareToPos(highlightInfo.sq[1].y, highlightInfo.sq[1].x, &x2, &y2 );\r
+\r
+        sx = MIN( x1, x2 );\r
+        sy = MIN( y1, y2 );\r
+        dx = MAX( x1, x2 ) + squareSize;\r
+        dy = MAX( y1, y2 ) + squareSize;\r
+\r
+        result = CreateRectRgn( sx, sy, dx, dy );\r
+    }\r
+\r
+    return result;\r
+}\r
+\r
+/*\r
+    Warning: this function modifies the behavior of several other functions. \r
+    \r
+    Basically, Winboard is optimized to avoid drawing the whole board if not strictly\r
+    needed. Unfortunately, the decision whether or not to perform a full or partial\r
+    repaint is scattered all over the place, which is not good for features such as\r
+    "arrow highlighting" that require a full repaint of the board.\r
+\r
+    So, I've tried to patch the code where I thought it made sense (e.g. after or during\r
+    user interaction, when speed is not so important) but especially to avoid errors\r
+    in the displayed graphics.\r
+\r
+    In such patched places, I always try refer to this function so there is a single\r
+    place to maintain knowledge.\r
+    \r
+    To restore the original behavior, just return FALSE unconditionally.\r
+*/\r
+BOOL IsFullRepaintPreferrable()\r
+{\r
+    BOOL result = FALSE;\r
+\r
+    if( (appData.highlightLastMove || appData.highlightDragging) && IsDrawArrowEnabled() ) {\r
+        /* Arrow may appear on the board */\r
+        result = TRUE;\r
+    }\r
+\r
+    return result;\r
+}\r
+\r
+/* \r
+    This function is called by DrawPosition to know whether a full repaint must\r
+    be forced or not.\r
+\r
+    Only DrawPosition may directly call this function, which makes use of \r
+    some state information. Other function should call DrawPosition specifying \r
+    the repaint flag, and can use IsFullRepaintPreferrable if needed.\r
+*/\r
+BOOL DrawPositionNeedsFullRepaint()\r
+{\r
+    BOOL result = FALSE;\r
+\r
+    /* \r
+        Probably a slightly better policy would be to trigger a full repaint\r
+        when animInfo.piece changes state (i.e. empty -> non-empty and viceversa),\r
+        but animation is fast enough that it's difficult to notice.\r
+    */\r
+    if( animInfo.piece == EmptySquare ) {\r
+        if( (appData.highlightLastMove || appData.highlightDragging) && IsDrawArrowEnabled() && HasHighlightInfo() ) {\r
+            result = TRUE;\r
+        }\r
+    }\r
+\r
+    return result;\r
+}\r
+\r
 VOID\r
 DrawBoardOnDC(HDC hdc, Board board, HDC tmphdc)\r
 {\r
   int row, column, x, y, square_color, piece_color;\r
   ChessSquare piece;\r
   HBRUSH oldBrush;\r
-  HDC texture_hdc = NULL;
-
-  /* [AS] Initialize background textures if needed */
-  if( liteBackTexture != NULL || darkBackTexture != NULL ) {
-      if( backTextureSquareSize != squareSize ) {
-          backTextureSquareSize = squareSize;
-          RebuildTextureSquareInfo();
-      }
-
-      texture_hdc = CreateCompatibleDC( hdc );
-  }
-\r
-  for (row = 0; row < BOARD_SIZE; row++) {\r
-    for (column = 0; column < BOARD_SIZE; column++) {\r
+  HDC texture_hdc = NULL;\r
+\r
+  /* [AS] Initialize background textures if needed */\r
+  if( liteBackTexture != NULL || darkBackTexture != NULL ) {\r
+      if( backTextureSquareSize != squareSize ) {\r
+          backTextureSquareSize = squareSize;\r
+          RebuildTextureSquareInfo();\r
+      }\r
+\r
+      texture_hdc = CreateCompatibleDC( hdc );\r
+  }\r
+\r
+  for (row = 0; row < BOARD_HEIGHT; row++) {\r
+    for (column = 0; column < BOARD_WIDTH; column++) {\r
   \r
       SquareToPos(row, column, &x, &y);\r
 \r
       piece = board[row][column];\r
 \r
       square_color = ((column + row) % 2) == 1;\r
+      if(!strcmp(appData.variant, "xiangqi") ) {\r
+          square_color = 1;\r
+          if( (row < 3 || row > BOARD_HEIGHT-4) &&\r
+              column < (BOARD_WIDTH + 4)/2 &&\r
+              column > (BOARD_WIDTH - 5)/2 ) square_color = 0;\r
+      }\r
       piece_color = (int) piece < (int) BlackPawn;\r
 \r
       if (appData.monoMode) {\r
@@ -3565,26 +3764,26 @@ DrawBoardOnDC(HDC hdc, Board board, HDC tmphdc)
         } else {\r
           DrawPieceOnDC(hdc, piece, piece_color, square_color, x, y, tmphdc);\r
         }\r
-      }
-      else if( backTextureSquareInfo[row][column].mode > 0 ) {
-          /* [AS] Draw the square using a texture bitmap */
-          HBITMAP hbm = SelectObject( texture_hdc, square_color ? liteBackTexture : darkBackTexture );
-
-          DrawTile( x, y,
-              squareSize, squareSize,
-              hdc,
-              texture_hdc,
-              backTextureSquareInfo[row][column].mode,
-              backTextureSquareInfo[row][column].x,
-              backTextureSquareInfo[row][column].y );
-
-          SelectObject( texture_hdc, hbm );
-
-          if (piece != EmptySquare) {
-              DrawPieceOnDC(hdc, piece, piece_color, -1, x, y, tmphdc);
-          }
-      }
-      else {
+      } \r
+      else if( backTextureSquareInfo[row][column].mode > 0 ) {\r
+          /* [AS] Draw the square using a texture bitmap */\r
+          HBITMAP hbm = SelectObject( texture_hdc, square_color ? liteBackTexture : darkBackTexture );\r
+\r
+          DrawTile( x, y, \r
+              squareSize, squareSize, \r
+              hdc, \r
+              texture_hdc,\r
+              backTextureSquareInfo[row][column].mode,\r
+              backTextureSquareInfo[row][column].x,\r
+              backTextureSquareInfo[row][column].y );\r
+\r
+          SelectObject( texture_hdc, hbm );\r
+\r
+          if (piece != EmptySquare) {\r
+              DrawPieceOnDC(hdc, piece, piece_color, -1, x, y, tmphdc);\r
+          }\r
+      }\r
+      else {\r
         oldBrush = SelectObject(hdc, square_color ?\r
                                lightSquareBrush : darkSquareBrush);\r
         BitBlt(hdc, x, y, squareSize, squareSize, 0, 0, 0, PATCOPY);\r
@@ -3594,10 +3793,10 @@ DrawBoardOnDC(HDC hdc, Board board, HDC tmphdc)
       }\r
     }\r
   }\r
-
-  if( texture_hdc != NULL ) {
-    DeleteDC( texture_hdc );
-  }
+\r
+  if( texture_hdc != NULL ) {\r
+    DeleteDC( texture_hdc );\r
+  }\r
 }\r
 \r
 #define MAX_CLIPS 200   /* more than enough */\r
@@ -3628,21 +3827,21 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board)
    */\r
   Boolean fullrepaint = repaint;\r
 \r
-  if( DrawPositionNeedsFullRepaint() ) {
-      fullrepaint = TRUE;
-  }
-
-#if 0
-  if( fullrepaint ) {
-      static int repaint_count = 0;
-      char buf[128];
-
-      repaint_count++;
-      sprintf( buf, "FULL repaint: %d\n", repaint_count );
-      OutputDebugString( buf );
-  }
-#endif
-
+  if( DrawPositionNeedsFullRepaint() ) {\r
+      fullrepaint = TRUE;\r
+  }\r
+\r
+#if 0\r
+  if( fullrepaint ) {\r
+      static int repaint_count = 0;\r
+      char buf[128];\r
+\r
+      repaint_count++;\r
+      sprintf( buf, "FULL repaint: %d\n", repaint_count );\r
+      OutputDebugString( buf );\r
+  }\r
+#endif\r
+\r
   if (board == NULL) {\r
     if (!lastReqValid) {\r
       return;\r
@@ -3685,15 +3884,15 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board)
                     dragInfo.pos.x, dragInfo.pos.y,\r
                     dragInfo.lastpos.x, dragInfo.lastpos.y);\r
   fprintf(debugFP, "prev:  ");\r
-  for (row = 0; row < 8; row++) {\r
-    for (column = 0; column < 8; column++) {\r
+  for (row = 0; row < BOARD_HEIGHT; row++) {\r
+    for (column = 0; column < BOARD_WIDTH; column++) {\r
       fprintf(debugFP, "%d ", lastDrawn[row][column]);\r
     }\r
   }\r
   fprintf(debugFP, "\n");\r
   fprintf(debugFP, "board: ");\r
-  for (row = 0; row < 8; row++) {\r
-    for (column = 0; column < 8; column++) {\r
+  for (row = 0; row < BOARD_HEIGHT; row++) {\r
+    for (column = 0; column < BOARD_WIDTH; column++) {\r
       fprintf(debugFP, "%d ", board[row][column]);\r
     }\r
   }\r
@@ -3710,8 +3909,8 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board)
    * flipping has changed.\r
    */\r
   if (!fullrepaint && lastDrawnValid && lastDrawnFlipView == flipView) {\r
-    for (row = 0; row < 8; row++) {\r
-      for (column = 0; column < 8; column++) {\r
+    for (row = 0; row < BOARD_HEIGHT; row++) { /* [HGM] true size, not 8 */\r
+      for (column = 0; column < BOARD_WIDTH; column++) {\r
        if (lastDrawn[row][column] != board[row][column]) {\r
          SquareToPos(row, column, &x, &y);\r
          clips[num_clips++] =\r
@@ -3845,11 +4044,11 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board)
   DrawGridOnDC(hdcmem);\r
   DrawHighlightsOnDC(hdcmem);\r
   DrawBoardOnDC(hdcmem, board, tmphdc);\r
-
-  if( appData.highlightMoveWithArrow ) {
-    DrawArrowHighlight(hdcmem);
-  }
-
+\r
+  if( appData.highlightMoveWithArrow ) {\r
+    DrawArrowHighlight(hdcmem);\r
+  }\r
+\r
   DrawCoordsOnDC(hdcmem);\r
 \r
   /* Put the dragged piece back into place and draw it */\r
@@ -4027,9 +4226,9 @@ MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
   POINT pt;\r
   static int recursive = 0;\r
   HMENU hmenu;\r
-  BOOLEAN needsRedraw = FALSE;
+  BOOLEAN needsRedraw = FALSE;\r
   BOOLEAN saveAnimate;\r
-  BOOLEAN forceFullRepaint = IsFullRepaintPreferrable(); /* [AS] */
+  BOOLEAN forceFullRepaint = IsFullRepaintPreferrable(); /* [AS] */\r
   static BOOLEAN sameAgain = FALSE;\r
 \r
   if (recursive) {\r
@@ -4049,10 +4248,10 @@ MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
   x = EventToSquare(pt.x - boardRect.left);\r
   y = EventToSquare(pt.y - boardRect.top);\r
   if (!flipView && y >= 0) {\r
-    y = BOARD_SIZE - 1 - y;\r
+    y = BOARD_HEIGHT - 1 - y;\r
   }\r
   if (flipView && x >= 0) {\r
-    x = BOARD_SIZE - 1 - x;\r
+    x = BOARD_WIDTH - 1 - x;\r
   }\r
 \r
   switch (message) {\r
@@ -4078,7 +4277,7 @@ MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
       }\r
       if (!appData.highlightLastMove) {\r
         ClearHighlights();\r
-       DrawPosition(forceFullRepaint || FALSE, NULL);
+       DrawPosition(forceFullRepaint || FALSE, NULL);\r
       }\r
       fromX = fromY = -1;\r
       dragInfo.start.x = dragInfo.start.y = -1;\r
@@ -4089,18 +4288,18 @@ MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
     } else if (fromX == x && fromY == y) {\r
       /* Downclick on same square again */\r
       ClearHighlights();\r
-      DrawPosition(forceFullRepaint || FALSE, NULL);
+      DrawPosition(forceFullRepaint || FALSE, NULL);\r
       sameAgain = TRUE;  \r
     } else if (fromX != -1) {\r
       /* Downclick on different square */\r
       ChessSquare pdown, pup;\r
       pdown = boards[currentMove][fromY][fromX];\r
       pup = boards[currentMove][y][x];\r
-      if (gameMode == EditPosition ||\r
-         !((WhitePawn <= pdown && pdown <= WhiteKing &&\r
-            WhitePawn <= pup && pup <= WhiteKing) ||\r
-           (BlackPawn <= pdown && pdown <= BlackKing &&\r
-            BlackPawn <= pup && pup <= BlackKing))) {\r
+      if (gameMode == EditPosition || /* [HGM] max piece > King! */\r
+          !((WhitePawn <= pdown && pdown < BlackPawn &&\r
+             WhitePawn <= pup && pup < BlackPawn) ||\r
+            (BlackPawn <= pdown && pdown < EmptySquare &&\r
+             BlackPawn <= pup && pup < EmptySquare))) {\r
        /* EditPosition, empty square, or different color piece;\r
           click-click move is possible */\r
        toX = x;\r
@@ -4110,11 +4309,11 @@ MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
            UserMoveEvent(fromX, fromY, toX, toY, 'q');\r
            if (!appData.highlightLastMove) {\r
              ClearHighlights();\r
-             DrawPosition(forceFullRepaint || FALSE, NULL);
+             DrawPosition(forceFullRepaint || FALSE, NULL);\r
            }\r
          } else {\r
            SetHighlights(fromX, fromY, toX, toY);\r
-           DrawPosition(forceFullRepaint || FALSE, NULL);
+           DrawPosition(forceFullRepaint || FALSE, NULL);\r
            PromotionPopup(hwnd);\r
          }\r
        } else {        /* not a promotion */\r
@@ -4126,7 +4325,7 @@ MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
          UserMoveEvent(fromX, fromY, toX, toY, NULLCHAR);\r
          if (appData.animate && !appData.highlightLastMove) {\r
            ClearHighlights();\r
-           DrawPosition(forceFullRepaint || FALSE, NULL);
+           DrawPosition(forceFullRepaint || FALSE, NULL);\r
          }\r
        }\r
        if (gotPremove) SetPremoveHighlights(fromX, fromY, toX, toY);\r
@@ -4134,7 +4333,7 @@ MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
        break;\r
       }\r
       ClearHighlights();\r
-      DrawPosition(forceFullRepaint || FALSE, NULL);
+      DrawPosition(forceFullRepaint || FALSE, NULL);\r
     }\r
     /* First downclick, or restart on a square with same color piece */\r
     if (!frozen && OKToStartUserMove(x, y)) {\r
@@ -4149,7 +4348,7 @@ MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
       fromX = fromY = -1;\r
       dragInfo.start.x = dragInfo.start.y = -1;\r
       dragInfo.from = dragInfo.start;\r
-      DrawPosition(forceFullRepaint || FALSE, NULL); /* [AS] */
+      DrawPosition(forceFullRepaint || FALSE, NULL); /* [AS] */\r
     }\r
     break;\r
 \r
@@ -4168,7 +4367,7 @@ MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
        /* First square clicked: start click-click move */\r
        SetHighlights(fromX, fromY, -1, -1);\r
       }\r
-      DrawPosition(forceFullRepaint || FALSE, NULL);
+      DrawPosition(forceFullRepaint || FALSE, NULL);\r
     } else if (dragInfo.from.x < 0 || dragInfo.from.y < 0) {\r
       /* Errant click; ignore */\r
       break;\r
@@ -4183,7 +4382,7 @@ MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
        if (appData.alwaysPromoteToQueen) {\r
          UserMoveEvent(fromX, fromY, toX, toY, 'q');\r
        } else {\r
-         DrawPosition(forceFullRepaint || FALSE, NULL);
+         DrawPosition(forceFullRepaint || FALSE, NULL);\r
          PromotionPopup(hwnd);\r
        }\r
       } else {\r
@@ -4197,7 +4396,7 @@ MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
       }\r
       if (appData.animate || appData.animateDragging ||\r
          appData.highlightDragging || gotPremove) {\r
-       DrawPosition(forceFullRepaint || FALSE, NULL);
+       DrawPosition(forceFullRepaint || FALSE, NULL);\r
       }\r
     }\r
     dragInfo.start.x = dragInfo.start.y = -1; \r
@@ -4207,22 +4406,22 @@ MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
   case WM_MOUSEMOVE:\r
     if ((appData.animateDragging || appData.highlightDragging)\r
        && (wParam & MK_LBUTTON)\r
-       && dragInfo.from.x >= 0)
-    {
-      BOOL full_repaint = FALSE;
-
+       && dragInfo.from.x >= 0) \r
+    {\r
+      BOOL full_repaint = FALSE;\r
+\r
       if (appData.animateDragging) {\r
        dragInfo.pos = pt;\r
       }\r
       if (appData.highlightDragging) {\r
        SetHighlights(fromX, fromY, x, y);\r
-        if( IsDrawArrowEnabled() && (x < 0 || x > 7 || y < 0 || y > y) ) {
-            full_repaint = TRUE;
+        if( IsDrawArrowEnabled() && (x < 0 || x >= BOARD_WIDTH || y < 0 || y > BOARD_WIDTH) ) {\r
+            full_repaint = TRUE;\r
+        }\r
       }\r
-      }
-
-      DrawPosition( full_repaint, NULL);
-
+      \r
+      DrawPosition( full_repaint, NULL);\r
+      \r
       dragInfo.lastpos = dragInfo.pos;\r
     }\r
     break;\r
@@ -4368,6 +4567,17 @@ Promotion(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
       (!appData.testLegality || gameInfo.variant == VariantSuicide ||\r
        gameInfo.variant == VariantGiveaway) ?\r
               SW_SHOW : SW_HIDE);\r
+#ifdef FAIRY\r
+    /* [HGM] Only allow C & A promotions in Capablanca Chess */\r
+    ShowWindow(GetDlgItem(hDlg, PB_Archbishop),\r
+      (gameInfo.variant == VariantCapablanca || \r
+       gameInfo.variant == VariantGothic) ?\r
+              SW_SHOW : SW_HIDE);\r
+    ShowWindow(GetDlgItem(hDlg, PB_Chancellor), \r
+      (gameInfo.variant == VariantCapablanca || \r
+       gameInfo.variant == VariantGothic) ?\r
+              SW_SHOW : SW_HIDE);\r
+#endif\r
     return TRUE;\r
 \r
   case WM_COMMAND: /* message: received a command */\r
@@ -4389,6 +4599,14 @@ Promotion(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
     case PB_Bishop:\r
       promoChar = 'b';\r
       break;\r
+#ifdef FAIRY\r
+    case PB_Chancellor:\r
+      promoChar = 'c';\r
+      break;\r
+    case PB_Archbishop:\r
+      promoChar = 'a';\r
+      break;\r
+#endif\r
     case PB_Knight:\r
       promoChar = 'n';\r
       break;\r
@@ -4510,7 +4728,7 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
   FILE *f;\r
   UINT number;\r
   char fileTitle[MSG_SIZ];\r
-  static SnapData sd;
+  static SnapData sd;\r
 \r
   switch (message) {\r
 \r
@@ -4606,13 +4824,13 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
       AnalysisPopDown();\r
       break;\r
 \r
-    case IDM_NewGameFRC:
-      if( NewGameFRC() == 0 ) {
-        ResetGameEvent();
-        AnalysisPopDown();
-      }
-      break;
-
+    case IDM_NewGameFRC:\r
+      if( NewGameFRC() == 0 ) {\r
+        ResetGameEvent();\r
+        AnalysisPopDown();\r
+      }\r
+      break;\r
+\r
     case IDM_LoadGame:\r
       LoadGameDialog(hwnd, "Load Game from File");\r
       break;\r
@@ -4685,63 +4903,63 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
       PasteGameFromClipboard();\r
       break;\r
 \r
-    case IDM_CopyGameListToClipboard:
-      CopyGameListToClipboard();
-      break;
-
-    /* [AS] Autodetect FEN or PGN data */
-    case IDM_PasteAny:
-      PasteGameOrFENFromClipboard();
-      break;
-
-    /* [AS] Move history */
-    case IDM_ShowMoveHistory:
-        if( MoveHistoryIsUp() ) {
-            MoveHistoryPopDown();
-        }
-        else {
-            MoveHistoryPopUp();
-        }
-        break;
-
-    /* [AS] Eval graph */
-    case IDM_ShowEvalGraph:
-        if( EvalGraphIsUp() ) {
-            EvalGraphPopDown();
-        }
-        else {
-            EvalGraphPopUp();
-        }
-        break;
-
-    /* [AS] Engine output */
-    case IDM_ShowEngineOutput:
-        if( EngineOutputIsUp() ) {
-            EngineOutputPopDown();
-        }
-        else {
-            EngineOutputPopUp();
-        }
-        break;
-
-    /* [AS] User adjudication */
-    case IDM_UserAdjudication_White:
-        UserAdjudicationEvent( +1 );
-        break;
-
-    case IDM_UserAdjudication_Black:
-        UserAdjudicationEvent( -1 );
-        break;
-
-    case IDM_UserAdjudication_Draw:
-        UserAdjudicationEvent( 0 );
-        break;
-
-    /* [AS] Game list options dialog */
-    case IDM_GameListOptions:
-      GameListOptions();
-      break;
-
+    case IDM_CopyGameListToClipboard:\r
+      CopyGameListToClipboard();\r
+      break;\r
+\r
+    /* [AS] Autodetect FEN or PGN data */\r
+    case IDM_PasteAny:\r
+      PasteGameOrFENFromClipboard();\r
+      break;\r
+\r
+    /* [AS] Move history */\r
+    case IDM_ShowMoveHistory:\r
+        if( MoveHistoryIsUp() ) {\r
+            MoveHistoryPopDown();\r
+        }\r
+        else {\r
+            MoveHistoryPopUp();\r
+        }\r
+        break;\r
+\r
+    /* [AS] Eval graph */\r
+    case IDM_ShowEvalGraph:\r
+        if( EvalGraphIsUp() ) {\r
+            EvalGraphPopDown();\r
+        }\r
+        else {\r
+            EvalGraphPopUp();\r
+        }\r
+        break;\r
+\r
+    /* [AS] Engine output */\r
+    case IDM_ShowEngineOutput:\r
+        if( EngineOutputIsUp() ) {\r
+            EngineOutputPopDown();\r
+        }\r
+        else {\r
+            EngineOutputPopUp();\r
+        }\r
+        break;\r
+\r
+    /* [AS] User adjudication */\r
+    case IDM_UserAdjudication_White:\r
+        UserAdjudicationEvent( +1 );\r
+        break;\r
+\r
+    case IDM_UserAdjudication_Black:\r
+        UserAdjudicationEvent( -1 );\r
+        break;\r
+\r
+    case IDM_UserAdjudication_Draw:\r
+        UserAdjudicationEvent( 0 );\r
+        break;\r
+\r
+    /* [AS] Game list options dialog */\r
+    case IDM_GameListOptions:\r
+      GameListOptions();\r
+      break;\r
+\r
     case IDM_CopyPosition:\r
       CopyFENToClipboard();\r
       break;\r
@@ -4953,21 +5171,21 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 \r
     case IDM_GeneralOptions:\r
       GeneralOptionsPopup(hwnd);\r
-      DrawPosition(TRUE, NULL);
+      DrawPosition(TRUE, NULL);\r
       break;\r
 \r
     case IDM_BoardOptions:\r
       BoardOptionsPopup(hwnd);\r
       break;\r
 \r
-    case IDM_EnginePlayOptions:
-      EnginePlayOptionsPopup(hwnd);
-      break;
-
-    case IDM_OptionsUCI:
-      UciOptionsPopup(hwnd);
-      break;
-
+    case IDM_EnginePlayOptions:\r
+      EnginePlayOptionsPopup(hwnd);\r
+      break;\r
+\r
+    case IDM_OptionsUCI:\r
+      UciOptionsPopup(hwnd);\r
+      break;\r
+\r
     case IDM_IcsOptions:\r
       IcsOptionsPopup(hwnd);\r
       break;\r
@@ -5025,7 +5243,7 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
        char dir[MSG_SIZ];\r
        GetCurrentDirectory(MSG_SIZ, dir);\r
        SetCurrentDirectory(installDir);\r
-       debugFP = fopen(appData.nameOfDebugFile, "w");
+       debugFP = fopen(appData.nameOfDebugFile, "w");\r
         SetCurrentDirectory(dir);\r
         setbuf(debugFP, NULL);\r
       } else {\r
@@ -5218,31 +5436,31 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
     InputEvent(hwnd, message, wParam, lParam);\r
     break;\r
 \r
-  /* [AS] Also move "attached" child windows */
-  case WM_WINDOWPOSCHANGING:
-    if( hwnd == hwndMain && appData.useStickyWindows ) {
-        LPWINDOWPOS lpwp = (LPWINDOWPOS) lParam;
-
-        if( ((lpwp->flags & SWP_NOMOVE) == 0) && ((lpwp->flags & SWP_NOSIZE) != 0) ) {
-            /* Window is moving */
-            RECT rcMain;
-
-            GetWindowRect( hwnd, &rcMain );
-
-            ReattachAfterMove( &rcMain, lpwp->x, lpwp->y, moveHistoryDialog, &wpMoveHistory );
-            ReattachAfterMove( &rcMain, lpwp->x, lpwp->y, evalGraphDialog, &wpEvalGraph );
-            ReattachAfterMove( &rcMain, lpwp->x, lpwp->y, engineOutputDialog, &wpEngineOutput );
-        }
-    }
-    break;
-
-  /* [AS] Snapping */
+  /* [AS] Also move "attached" child windows */\r
+  case WM_WINDOWPOSCHANGING:\r
+    if( hwnd == hwndMain && appData.useStickyWindows ) {\r
+        LPWINDOWPOS lpwp = (LPWINDOWPOS) lParam;\r
+\r
+        if( ((lpwp->flags & SWP_NOMOVE) == 0) && ((lpwp->flags & SWP_NOSIZE) != 0) ) {\r
+            /* Window is moving */\r
+            RECT rcMain;\r
+\r
+            GetWindowRect( hwnd, &rcMain );\r
+            \r
+            ReattachAfterMove( &rcMain, lpwp->x, lpwp->y, moveHistoryDialog, &wpMoveHistory );\r
+            ReattachAfterMove( &rcMain, lpwp->x, lpwp->y, evalGraphDialog, &wpEvalGraph );\r
+            ReattachAfterMove( &rcMain, lpwp->x, lpwp->y, engineOutputDialog, &wpEngineOutput );\r
+        }\r
+    }\r
+    break;\r
+\r
+  /* [AS] Snapping */\r
   case WM_ENTERSIZEMOVE:\r
     if (hwnd == hwndMain) {\r
       doingSizing = TRUE;\r
       lastSizing = 0;\r
     }\r
-    return OnEnterSizeMove( &sd, hwnd, wParam, lParam );
+    return OnEnterSizeMove( &sd, hwnd, wParam, lParam );\r
     break;\r
 \r
   case WM_SIZING:\r
@@ -5251,9 +5469,9 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
     }\r
     break;\r
 \r
-  case WM_MOVING:
-      return OnMoving( &sd, hwnd, wParam, lParam );
-
+  case WM_MOVING:\r
+      return OnMoving( &sd, hwnd, wParam, lParam );\r
+\r
   case WM_EXITSIZEMOVE:\r
     if (hwnd == hwndMain) {\r
       RECT client;\r
@@ -5263,7 +5481,7 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
       ResizeBoard(client.right, client.bottom, lastSizing);\r
       lastSizing = 0;\r
     }\r
-    return OnExitSizeMove( &sd, hwnd, wParam, lParam );
+    return OnExitSizeMove( &sd, hwnd, wParam, lParam );\r
     break;\r
 \r
   case WM_DESTROY: /* message: window being destroyed */\r
@@ -5656,7 +5874,7 @@ ResizeEditPlusButtons(HWND hDlg, HWND hText, int sizeX, int sizeY, int newSizeX,
   EndDeferWindowPos(cl.hdwp);\r
 }\r
 \r
-BOOL CenterWindowEx(HWND hwndChild, HWND hwndParent, int mode)
+BOOL CenterWindowEx(HWND hwndChild, HWND hwndParent, int mode)\r
 {\r
     RECT    rChild, rParent;\r
     int     wChild, hChild, wParent, hParent;\r
@@ -5688,13 +5906,13 @@ BOOL CenterWindowEx(HWND hwndChild, HWND hwndParent, int mode)
     }\r
 \r
     /* Calculate new Y position, then adjust for screen */\r
-    if( mode == 0 ) {
-    yNew = rParent.top  + ((hParent - hChild) /2);\r
-    }
-    else {
-        yNew = rParent.top + GetSystemMetrics( SM_CYCAPTION ) * 2 / 3;
-    }
-
+    if( mode == 0 ) {\r
+        yNew = rParent.top  + ((hParent - hChild) /2);\r
+    }\r
+    else {\r
+        yNew = rParent.top + GetSystemMetrics( SM_CYCAPTION ) * 2 / 3;\r
+    }\r
+\r
     if (yNew < 0) {\r
        yNew = 0;\r
     } else if ((yNew+hChild) > hScreen) {\r
@@ -5706,12 +5924,12 @@ BOOL CenterWindowEx(HWND hwndChild, HWND hwndParent, int mode)
                         xNew, yNew, 0, 0, SWP_NOSIZE | SWP_NOZORDER);\r
 }\r
 \r
-/* Center one window over another */
-BOOL CenterWindow (HWND hwndChild, HWND hwndParent)
-{
-    return CenterWindowEx( hwndChild, hwndParent, 0 );
-}
-
+/* Center one window over another */\r
+BOOL CenterWindow (HWND hwndChild, HWND hwndParent)\r
+{\r
+    return CenterWindowEx( hwndChild, hwndParent, 0 );\r
+}\r
+\r
 /*---------------------------------------------------------------------------*\\r
  *\r
  * Startup Dialog functions\r
@@ -5847,17 +6065,17 @@ StartupDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
       SendMessage(hwndCombo, CB_SETCURSEL, (WPARAM) -1, (LPARAM) 0);\r
       SendMessage(hwndCombo, WM_SETTEXT, (WPARAM) 0, (LPARAM) buf);\r
     }\r
-
-    if (appData.icsActive) {
+\r
+    if (appData.icsActive) {\r
       CheckDlgButton(hDlg, OPT_ChessServer, BST_CHECKED);\r
-    }
-    else if (appData.noChessProgram) {
+    }\r
+    else if (appData.noChessProgram) {\r
       CheckDlgButton(hDlg, OPT_View, BST_CHECKED);\r
     }\r
-    else {
-      CheckDlgButton(hDlg, OPT_ChessEngine, BST_CHECKED);
-    }
-
+    else {\r
+      CheckDlgButton(hDlg, OPT_ChessEngine, BST_CHECKED);\r
+    }\r
+\r
     SetStartupDialogEnables(hDlg);\r
     return TRUE;\r
 \r
@@ -6132,7 +6350,7 @@ TypeInMoveDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
   case WM_INITDIALOG:\r
     move[0] = (char) lParam;\r
     move[1] = NULLCHAR;\r
-    CenterWindowEx(hDlg, GetWindow(hDlg, GW_OWNER), 1 );
+    CenterWindowEx(hDlg, GetWindow(hDlg, GW_OWNER), 1 );\r
     hInput = GetDlgItem(hDlg, OPT_Move);\r
     SetWindowText(hInput, move);\r
     SetFocus(hInput);\r
@@ -6251,21 +6469,21 @@ ErrorDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
   switch (message) {\r
   case WM_INITDIALOG:\r
     GetWindowRect(hDlg, &rChild);\r
-
-    /*
+\r
+    /*\r
     SetWindowPos(hDlg, NULL, rChild.left,\r
       rChild.top + boardRect.top - (rChild.bottom - rChild.top), \r
       0, 0, SWP_NOZORDER|SWP_NOSIZE);\r
-    */
-
-    /*
-        [AS] It seems that the above code wants to move the dialog up in the "caption
-        area" of the main window, but it uses the dialog height as an hard-coded constant,
-        and it doesn't work when you resize the dialog.
-        For now, just give it a default position.
-    */
-    SetWindowPos(hDlg, NULL, boardRect.left+8, boardRect.top+8, 0, 0, SWP_NOZORDER|SWP_NOSIZE);
-
+    */\r
+\r
+    /* \r
+        [AS] It seems that the above code wants to move the dialog up in the "caption\r
+        area" of the main window, but it uses the dialog height as an hard-coded constant,\r
+        and it doesn't work when you resize the dialog.\r
+        For now, just give it a default position.\r
+    */\r
+    SetWindowPos(hDlg, NULL, boardRect.left+8, boardRect.top+8, 0, 0, SWP_NOZORDER|SWP_NOSIZE);\r
+\r
     errorDialog = hDlg;\r
     SetWindowText(hDlg, errorTitle);\r
     hwndText = GetDlgItem(hDlg, OPT_ErrorText);\r
@@ -6288,6 +6506,66 @@ ErrorDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
   return FALSE;\r
 }\r
 \r
+#ifdef GOTHIC\r
+LRESULT CALLBACK\r
+GothicDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
+{\r
+  HANDLE hwndText;\r
+  RECT rChild;\r
+  int height = GetSystemMetrics(SM_CYCAPTION)+GetSystemMetrics(SM_CYFRAME);\r
+\r
+  switch (message) {\r
+  case WM_INITDIALOG:\r
+    GetWindowRect(hDlg, &rChild);\r
+\r
+    SetWindowPos(hDlg, NULL, boardX, boardY-height, winWidth, height,\r
+                                                             SWP_NOZORDER);\r
+\r
+    /* \r
+        [AS] It seems that the above code wants to move the dialog up in the "caption\r
+        area" of the main window, but it uses the dialog height as an hard-coded constant,\r
+        and it doesn't work when you resize the dialog.\r
+        For now, just give it a default position.\r
+    */\r
+\r
+    SetWindowText(hDlg, errorTitle);\r
+    hwndText = GetDlgItem(hDlg, OPT_ErrorText);\r
+    SetDlgItemText(hDlg, OPT_ErrorText, errorMessage);\r
+    return FALSE;\r
+\r
+  case WM_COMMAND:\r
+    switch (LOWORD(wParam)) {\r
+    case IDOK:\r
+    case IDCANCEL:\r
+      if (errorDialog == hDlg) errorDialog = NULL;\r
+      DestroyWindow(hDlg);\r
+      return TRUE;\r
+\r
+    default:\r
+      break;\r
+    }\r
+    break;\r
+  }\r
+  return FALSE;\r
+}\r
+\r
+VOID\r
+GothicPopUp(char *title)\r
+{\r
+  FARPROC lpProc;\r
+  char *p, *q;\r
+  BOOLEAN modal = hwndMain == NULL;\r
+\r
+  strncpy(errorTitle, title, sizeof(errorTitle));\r
+  errorTitle[sizeof(errorTitle) - 1] = '\0';\r
+  \r
+    lpProc = MakeProcInstance((FARPROC)GothicDialog, hInst);\r
+    CreateDialog(hInst, MAKEINTRESOURCE(DLG_Error),\r
+                hwndMain, (DLGPROC)lpProc);\r
+    FreeProcInstance(lpProc);\r
+}\r
+#endif\r
+\r
 /*---------------------------------------------------------------------------*\\r
  *\r
  *  Ics Interaction console functions\r
@@ -6791,7 +7069,7 @@ ConsoleInputSubclass(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 LRESULT CALLBACK\r
 ConsoleWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
 {\r
-  static SnapData sd;
+  static SnapData sd;\r
   static HWND hText, hInput, hFocus;\r
   InputSource *is = consoleInputSource;\r
   RECT rect;\r
@@ -6878,21 +7156,21 @@ ConsoleWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
     mmi->ptMinTrackSize.x = 100;\r
     mmi->ptMinTrackSize.y = 100;\r
     break;\r
-
-  /* [AS] Snapping */
-  case WM_ENTERSIZEMOVE:
-    return OnEnterSizeMove( &sd, hDlg, wParam, lParam );
-
-  case WM_SIZING:
-    return OnSizing( &sd, hDlg, wParam, lParam );
-
-  case WM_MOVING:
-    return OnMoving( &sd, hDlg, wParam, lParam );
-
-  case WM_EXITSIZEMOVE:
-    return OnExitSizeMove( &sd, hDlg, wParam, lParam );
-  }\r
-
+\r
+  /* [AS] Snapping */\r
+  case WM_ENTERSIZEMOVE:\r
+    return OnEnterSizeMove( &sd, hDlg, wParam, lParam );\r
+\r
+  case WM_SIZING:\r
+    return OnSizing( &sd, hDlg, wParam, lParam );\r
+\r
+  case WM_MOVING:\r
+    return OnMoving( &sd, hDlg, wParam, lParam );\r
+\r
+  case WM_EXITSIZEMOVE:\r
+    return OnExitSizeMove( &sd, hDlg, wParam, lParam );\r
+  }\r
+\r
   return DefWindowProc(hDlg, message, wParam, lParam);\r
 }\r
 \r
@@ -7001,7 +7279,7 @@ ConsoleOutput(char* data, int length, int forceVisible)
 \r
 void\r
 DisplayAClock(HDC hdc, int timeRemaining, int highlight,\r
-             RECT *rect, char *color)\r
+              RECT *rect, char *color, char *flagFell)\r
 {\r
   char buf[100];\r
   char *str;\r
@@ -7010,9 +7288,9 @@ DisplayAClock(HDC hdc, int timeRemaining, int highlight,
 \r
   if (appData.clockMode) {\r
     if (tinyLayout)\r
-      sprintf(buf, "%c %s", color[0], TimeString(timeRemaining));\r
+      sprintf(buf, "%c %s %s %s", color[0], TimeString(timeRemaining), flagFell);\r
     else\r
-      sprintf(buf, "%s: %s", color, TimeString(timeRemaining));\r
+      sprintf(buf, "%s: %s %s", color, TimeString(timeRemaining), flagFell);\r
     str = buf;\r
   } else {\r
     str = color;\r
@@ -7043,15 +7321,15 @@ DoReadFile(HANDLE hFile, char *buf, int count, DWORD *outCount,
 {\r
   int ok, err;\r
 \r
-  /* [AS]  */
-  if( count <= 0 ) {
-    if (appData.debugMode) {
-      fprintf( debugFP, "DoReadFile: trying to read past end of buffer, overflow = %d\n", count );
-    }
-
-    return ERROR_INVALID_USER_BUFFER;
-  }
-
+  /* [AS]  */\r
+  if( count <= 0 ) {\r
+    if (appData.debugMode) {\r
+      fprintf( debugFP, "DoReadFile: trying to read past end of buffer, overflow = %d\n", count );\r
+    }\r
+\r
+    return ERROR_INVALID_USER_BUFFER;\r
+  }\r
+\r
   ResetEvent(ovl->hEvent);\r
   ovl->Offset = ovl->OffsetHigh = 0;\r
   ok = ReadFile(hFile, buf, count, outCount, ovl);\r
@@ -7094,28 +7372,28 @@ DoWriteFile(HANDLE hFile, char *buf, int count, DWORD *outCount,
   return err;\r
 }\r
 \r
-/* [AS] If input is line by line and a line exceed the buffer size, force an error */
-void CheckForInputBufferFull( InputSource * is )
-{
-    if( is->lineByLine && (is->next - is->buf) >= INPUT_SOURCE_BUF_SIZE ) {
-        /* Look for end of line */
-        char * p = is->buf;
-
-        while( p < is->next && *p != '\n' ) {
-            p++;
-        }
-
-        if( p >= is->next ) {
-            if (appData.debugMode) {
-                fprintf( debugFP, "Input line exceeded buffer size (source id=%u)\n", is->id );
-            }
-
-            is->error = ERROR_BROKEN_PIPE; /* [AS] Just any non-successful code! */
-            is->count = (DWORD) -1;
-            is->next = is->buf;
-        }
-    }
-}
+/* [AS] If input is line by line and a line exceed the buffer size, force an error */\r
+void CheckForInputBufferFull( InputSource * is )\r
+{\r
+    if( is->lineByLine && (is->next - is->buf) >= INPUT_SOURCE_BUF_SIZE ) {\r
+        /* Look for end of line */\r
+        char * p = is->buf;\r
+        \r
+        while( p < is->next && *p != '\n' ) {\r
+            p++;\r
+        }\r
+\r
+        if( p >= is->next ) {\r
+            if (appData.debugMode) {\r
+                fprintf( debugFP, "Input line exceeded buffer size (source id=%u)\n", is->id );\r
+            }\r
+\r
+            is->error = ERROR_BROKEN_PIPE; /* [AS] Just any non-successful code! */\r
+            is->count = (DWORD) -1;\r
+            is->next = is->buf;\r
+        }\r
+    }\r
+}\r
 \r
 DWORD\r
 InputThread(LPVOID arg)\r
@@ -7138,27 +7416,27 @@ InputThread(LPVOID arg)
        is->count = 0;\r
       } else {\r
        is->count = (DWORD) -1;\r
-        /* [AS] The (is->count <= 0) check below is not useful for unsigned values! */
-        break;
+        /* [AS] The (is->count <= 0) check below is not useful for unsigned values! */\r
+        break; \r
       }\r
     }\r
-
-    CheckForInputBufferFull( is );
-
+\r
+    CheckForInputBufferFull( is );\r
+\r
     SendMessage(hwndMain, WM_USER_Input, 0, (LPARAM) is);\r
-
-    if( is->count == ((DWORD) -1) ) break; /* [AS] */
-
+\r
+    if( is->count == ((DWORD) -1) ) break; /* [AS] */\r
+\r
     if (is->count <= 0) break;  /* Quit on EOF or error */\r
   }\r
-
+\r
   CloseHandle(ovl.hEvent);\r
   CloseHandle(is->hFile);\r
-
-  if (appData.debugMode) {
-    fprintf( debugFP, "Input thread terminated (id=%u, error=%d, count=%d)\n", is->id, is->error, is->count );
-  }
-
+\r
+  if (appData.debugMode) {\r
+    fprintf( debugFP, "Input thread terminated (id=%u, error=%d, count=%d)\n", is->id, is->error, is->count );\r
+  }\r
+\r
   return 0;\r
 }\r
 \r
@@ -7208,13 +7486,13 @@ NonOvlInputThread(LPVOID arg)
        is->count = (DWORD) -1;\r
       }\r
     }\r
-
-    CheckForInputBufferFull( is );
-
+\r
+    CheckForInputBufferFull( is );\r
+\r
     SendMessage(hwndMain, WM_USER_Input, 0, (LPARAM) is);\r
-
-    if( is->count == ((DWORD) -1) ) break; /* [AS] */
-
+\r
+    if( is->count == ((DWORD) -1) ) break; /* [AS] */\r
+\r
     if (is->count < 0) break;  /* Quit on error */\r
   }\r
   CloseHandle(is->hFile);\r
@@ -7241,9 +7519,9 @@ SocketInputThread(LPVOID arg)
       }\r
     }\r
     SendMessage(hwndMain, WM_USER_Input, 0, (LPARAM) is);\r
-
-    if( is->count == ((DWORD) -1) ) break; /* [AS] */
-
+\r
+    if( is->count == ((DWORD) -1) ) break; /* [AS] */\r
+\r
     if (is->count <= 0) break;  /* Quit on EOF or error */\r
   }\r
   return 0;\r
@@ -7265,14 +7543,14 @@ InputEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
        p = q;\r
       }\r
     }\r
-
+    \r
     /* Move any partial line to the start of the buffer */\r
     q = is->buf;\r
     while (p < is->next) {\r
       *q++ = *p++;\r
     }\r
     is->next = q;\r
-
+\r
     if (is->error != NO_ERROR || is->count == 0) {\r
       /* Notify backend of the error.  Note: If there was a partial\r
         line at the end, it is not flushed through. */\r
@@ -7817,271 +8095,271 @@ AskQuestion(char* title, char *question, char *replyPrefix, ProcRef pr)
     FreeProcInstance(lpProc);\r
 }\r
 \r
-/* [AS] Pick FRC position */
-LRESULT CALLBACK NewGameFRC_Proc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
-{
-    static int * lpIndexFRC;
-    BOOL index_is_ok;
-    char buf[16];
-
-    switch( message )
-    {
-    case WM_INITDIALOG:
-        lpIndexFRC = (int *) lParam;
-
-        CenterWindow(hDlg, GetWindow(hDlg, GW_OWNER));
-
-        SendDlgItemMessage( hDlg, IDC_NFG_Edit, EM_SETLIMITTEXT, sizeof(buf)-1, 0 );
-        SetDlgItemInt( hDlg, IDC_NFG_Edit, *lpIndexFRC, TRUE );
-        SendDlgItemMessage( hDlg, IDC_NFG_Edit, EM_SETSEL, 0, -1 );
-        SetFocus(GetDlgItem(hDlg, IDC_NFG_Edit));
-
-        break;
-
-    case WM_COMMAND:
-        switch( LOWORD(wParam) ) {
-        case IDOK:
-            *lpIndexFRC = GetDlgItemInt(hDlg, IDC_NFG_Edit, &index_is_ok, TRUE );
-            EndDialog( hDlg, 0 );
-            return TRUE;
-        case IDCANCEL:
-            EndDialog( hDlg, 1 );
-            return TRUE;
-        case IDC_NFG_Edit:
-            if( HIWORD(wParam) == EN_CHANGE ) {
-                GetDlgItemInt(hDlg, IDC_NFG_Edit, &index_is_ok, TRUE );
-
-                EnableWindow( GetDlgItem(hDlg, IDOK), index_is_ok );
-            }
-            return TRUE;
-        case IDC_NFG_Random:
-            sprintf( buf, "%d", myrandom() % 960 );
-            SetDlgItemText(hDlg, IDC_NFG_Edit, buf );
-            return TRUE;
-        }
-
-        break;
-    }
-
-    return FALSE;
-}
-
-int NewGameFRC()
-{
-    int result;
-    int index = appData.defaultFrcPosition;
-    FARPROC lpProc = MakeProcInstance( (FARPROC) NewGameFRC_Proc, hInst );
-
-    result = DialogBoxParam( hInst, MAKEINTRESOURCE(DLG_NewGameFRC), hwndMain, (DLGPROC)lpProc, (LPARAM)&index );
-
-    if( result == 0 ) {
-        appData.defaultFrcPosition = index;
-    }
-
-    return result;
-}
-
-/* [AS] Game list options */
-typedef struct {
-    char id;
-    char * name;
-} GLT_Item;
-
-static GLT_Item GLT_ItemInfo[] = {
-    { GLT_EVENT,      "Event" },
-    { GLT_SITE,       "Site" },
-    { GLT_DATE,       "Date" },
-    { GLT_ROUND,      "Round" },
-    { GLT_PLAYERS,    "Players" },
-    { GLT_RESULT,     "Result" },
-    { GLT_WHITE_ELO,  "White Rating" },
-    { GLT_BLACK_ELO,  "Black Rating" },
-    { GLT_TIME_CONTROL,"Time Control" },
-    { GLT_VARIANT,    "Variant" },
-    { GLT_OUT_OF_BOOK,PGN_OUT_OF_BOOK },
-    { 0, 0 }
-};
-
-const char * GLT_FindItem( char id )
-{
-    const char * result = 0;
-
-    GLT_Item * list = GLT_ItemInfo;
-
-    while( list->id != 0 ) {
-        if( list->id == id ) {
-            result = list->name;
-            break;
-        }
-
-        list++;
-    }
-
-    return result;
-}
-
-void GLT_AddToList( HWND hDlg, int iDlgItem, char id, int index )
-{
-    const char * name = GLT_FindItem( id );
-
-    if( name != 0 ) {
-        if( index >= 0 ) {
-            SendDlgItemMessage( hDlg, iDlgItem, LB_INSERTSTRING, index, (LPARAM) name );
-        }
-        else {
-            SendDlgItemMessage( hDlg, iDlgItem, LB_ADDSTRING, 0, (LPARAM) name );
-        }
-    }
-}
-
-void GLT_TagsToList( HWND hDlg, char * tags )
-{
-    char * pc = tags;
-
-    SendDlgItemMessage( hDlg, IDC_GameListTags, LB_RESETCONTENT, 0, 0 );
-
-    while( *pc ) {
-        GLT_AddToList( hDlg, IDC_GameListTags, *pc, -1 );
-        pc++;
-    }
-
-    SendDlgItemMessage( hDlg, IDC_GameListTags, LB_ADDSTRING, 0, (LPARAM) "\t --- Hidden tags ---" );
-
-    pc = GLT_ALL_TAGS;
-
-    while( *pc ) {
-        if( strchr( tags, *pc ) == 0 ) {
-            GLT_AddToList( hDlg, IDC_GameListTags, *pc, -1 );
-        }
-        pc++;
-    }
-
-    SendDlgItemMessage( hDlg, IDC_GameListTags, LB_SETCURSEL, 0, 0 );
-}
-
-char GLT_ListItemToTag( HWND hDlg, int index )
-{
-    char result = '\0';
-    char name[128];
-
-    GLT_Item * list = GLT_ItemInfo;
-
-    if( SendDlgItemMessage( hDlg, IDC_GameListTags, LB_GETTEXT, index, (LPARAM) name ) != LB_ERR ) {
-        while( list->id != 0 ) {
-            if( strcmp( list->name, name ) == 0 ) {
-                result = list->id;
-                break;
-            }
-
-            list++;
-        }
-    }
-
-    return result;
-}
-
-void GLT_MoveSelection( HWND hDlg, int delta )
-{
-    int idx1 = (int) SendDlgItemMessage( hDlg, IDC_GameListTags, LB_GETCURSEL, 0, 0 );
-    int idx2 = idx1 + delta;
-    int count = (int) SendDlgItemMessage( hDlg, IDC_GameListTags, LB_GETCOUNT, 0, 0 );
-
-    if( idx1 >=0 && idx1 < count && idx2 >= 0 && idx2 < count ) {
-        char buf[128];
-
-        SendDlgItemMessage( hDlg, IDC_GameListTags, LB_GETTEXT, idx1, (LPARAM) buf );
-        SendDlgItemMessage( hDlg, IDC_GameListTags, LB_DELETESTRING, idx1, 0 );
-        SendDlgItemMessage( hDlg, IDC_GameListTags, LB_INSERTSTRING, idx2, (LPARAM) buf );
-        SendDlgItemMessage( hDlg, IDC_GameListTags, LB_SETCURSEL, idx2, 0 );
-    }
-}
-
-LRESULT CALLBACK GameListOptions_Proc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
-{
-    static char glt[64];
-    static char * lpUserGLT;
-
-    switch( message )
-    {
-    case WM_INITDIALOG:
-        lpUserGLT = (char *) lParam;
-
-        strcpy( glt, lpUserGLT );
-
-        CenterWindow(hDlg, GetWindow(hDlg, GW_OWNER));
-
-        /* Initialize list */
-        GLT_TagsToList( hDlg, glt );
-
-        SetFocus( GetDlgItem(hDlg, IDC_GameListTags) );
-
-        break;
-
-    case WM_COMMAND:
-        switch( LOWORD(wParam) ) {
-        case IDOK:
-            {
-                char * pc = lpUserGLT;
-                int idx = 0;
-                int cnt = (int) SendDlgItemMessage( hDlg, IDC_GameListTags, LB_GETCOUNT, 0, 0 );
-                char id;
-
-                do {
-                    id = GLT_ListItemToTag( hDlg, idx );
-
-                    *pc++ = id;
-                    idx++;
-                } while( id != '\0' );
-            }
-            EndDialog( hDlg, 0 );
-            return TRUE;
-        case IDCANCEL:
-            EndDialog( hDlg, 1 );
-            return TRUE;
-
-        case IDC_GLT_Default:
-            strcpy( glt, GLT_DEFAULT_TAGS );
-            GLT_TagsToList( hDlg, glt );
-            return TRUE;
-
-        case IDC_GLT_Restore:
-            strcpy( glt, lpUserGLT );
-            GLT_TagsToList( hDlg, glt );
-            return TRUE;
-
-        case IDC_GLT_Up:
-            GLT_MoveSelection( hDlg, -1 );
-            return TRUE;
-
-        case IDC_GLT_Down:
-            GLT_MoveSelection( hDlg, +1 );
-            return TRUE;
-        }
-
-        break;
-    }
-
-    return FALSE;
-}
-
-int GameListOptions()
-{
-    char glt[64];
-    int result;
-    FARPROC lpProc = MakeProcInstance( (FARPROC) GameListOptions_Proc, hInst );
-
-    strcpy( glt, appData.gameListTags );
-
-    result = DialogBoxParam( hInst, MAKEINTRESOURCE(DLG_GameListOptions), hwndMain, (DLGPROC)lpProc, (LPARAM)glt );
-
-    if( result == 0 ) {
-        /* [AS] Memory leak here! */
-        appData.gameListTags = strdup( glt );
-    }
-
-    return result;
-}
-
+/* [AS] Pick FRC position */\r
+LRESULT CALLBACK NewGameFRC_Proc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
+{\r
+    static int * lpIndexFRC;\r
+    BOOL index_is_ok;\r
+    char buf[16];\r
+\r
+    switch( message )\r
+    {\r
+    case WM_INITDIALOG:\r
+        lpIndexFRC = (int *) lParam;\r
+\r
+        CenterWindow(hDlg, GetWindow(hDlg, GW_OWNER));\r
+\r
+        SendDlgItemMessage( hDlg, IDC_NFG_Edit, EM_SETLIMITTEXT, sizeof(buf)-1, 0 );\r
+        SetDlgItemInt( hDlg, IDC_NFG_Edit, *lpIndexFRC, TRUE );\r
+        SendDlgItemMessage( hDlg, IDC_NFG_Edit, EM_SETSEL, 0, -1 );\r
+        SetFocus(GetDlgItem(hDlg, IDC_NFG_Edit));\r
+\r
+        break;\r
+\r
+    case WM_COMMAND:\r
+        switch( LOWORD(wParam) ) {\r
+        case IDOK:\r
+            *lpIndexFRC = GetDlgItemInt(hDlg, IDC_NFG_Edit, &index_is_ok, TRUE );\r
+            EndDialog( hDlg, 0 );\r
+            return TRUE;\r
+        case IDCANCEL:\r
+            EndDialog( hDlg, 1 );   \r
+            return TRUE;\r
+        case IDC_NFG_Edit:\r
+            if( HIWORD(wParam) == EN_CHANGE ) {\r
+                GetDlgItemInt(hDlg, IDC_NFG_Edit, &index_is_ok, TRUE );\r
+\r
+                EnableWindow( GetDlgItem(hDlg, IDOK), index_is_ok );\r
+            }\r
+            return TRUE;\r
+        case IDC_NFG_Random:\r
+            sprintf( buf, "%d", myrandom() % 960 );\r
+            SetDlgItemText(hDlg, IDC_NFG_Edit, buf );\r
+            return TRUE;\r
+        }\r
+\r
+        break;\r
+    }\r
+\r
+    return FALSE;\r
+}\r
+\r
+int NewGameFRC()\r
+{\r
+    int result;\r
+    int index = appData.defaultFrcPosition;\r
+    FARPROC lpProc = MakeProcInstance( (FARPROC) NewGameFRC_Proc, hInst );\r
+\r
+    result = DialogBoxParam( hInst, MAKEINTRESOURCE(DLG_NewGameFRC), hwndMain, (DLGPROC)lpProc, (LPARAM)&index );\r
+\r
+    if( result == 0 ) {\r
+        appData.defaultFrcPosition = index;\r
+    }\r
+\r
+    return result;\r
+}\r
+\r
+/* [AS] Game list options */\r
+typedef struct {\r
+    char id;\r
+    char * name;\r
+} GLT_Item;\r
+\r
+static GLT_Item GLT_ItemInfo[] = {\r
+    { GLT_EVENT,      "Event" },\r
+    { GLT_SITE,       "Site" },\r
+    { GLT_DATE,       "Date" },\r
+    { GLT_ROUND,      "Round" },\r
+    { GLT_PLAYERS,    "Players" },\r
+    { GLT_RESULT,     "Result" },\r
+    { GLT_WHITE_ELO,  "White Rating" },\r
+    { GLT_BLACK_ELO,  "Black Rating" },\r
+    { GLT_TIME_CONTROL,"Time Control" },\r
+    { GLT_VARIANT,    "Variant" },\r
+    { GLT_OUT_OF_BOOK,PGN_OUT_OF_BOOK },\r
+    { 0, 0 }\r
+};\r
+\r
+const char * GLT_FindItem( char id )\r
+{\r
+    const char * result = 0;\r
+\r
+    GLT_Item * list = GLT_ItemInfo;\r
+\r
+    while( list->id != 0 ) {\r
+        if( list->id == id ) {\r
+            result = list->name;\r
+            break;\r
+        }\r
+\r
+        list++;\r
+    }\r
+\r
+    return result;\r
+}\r
+\r
+void GLT_AddToList( HWND hDlg, int iDlgItem, char id, int index )\r
+{\r
+    const char * name = GLT_FindItem( id );\r
+\r
+    if( name != 0 ) {\r
+        if( index >= 0 ) {\r
+            SendDlgItemMessage( hDlg, iDlgItem, LB_INSERTSTRING, index, (LPARAM) name );\r
+        }\r
+        else {\r
+            SendDlgItemMessage( hDlg, iDlgItem, LB_ADDSTRING, 0, (LPARAM) name );\r
+        }\r
+    }\r
+}\r
+\r
+void GLT_TagsToList( HWND hDlg, char * tags )\r
+{\r
+    char * pc = tags;\r
+\r
+    SendDlgItemMessage( hDlg, IDC_GameListTags, LB_RESETCONTENT, 0, 0 );\r
+\r
+    while( *pc ) {\r
+        GLT_AddToList( hDlg, IDC_GameListTags, *pc, -1 );\r
+        pc++;\r
+    }\r
+\r
+    SendDlgItemMessage( hDlg, IDC_GameListTags, LB_ADDSTRING, 0, (LPARAM) "\t --- Hidden tags ---" );\r
+\r
+    pc = GLT_ALL_TAGS;\r
+\r
+    while( *pc ) {\r
+        if( strchr( tags, *pc ) == 0 ) {\r
+            GLT_AddToList( hDlg, IDC_GameListTags, *pc, -1 );\r
+        }\r
+        pc++;\r
+    }\r
+\r
+    SendDlgItemMessage( hDlg, IDC_GameListTags, LB_SETCURSEL, 0, 0 );\r
+}\r
+\r
+char GLT_ListItemToTag( HWND hDlg, int index )\r
+{\r
+    char result = '\0';\r
+    char name[128];\r
+\r
+    GLT_Item * list = GLT_ItemInfo;\r
+\r
+    if( SendDlgItemMessage( hDlg, IDC_GameListTags, LB_GETTEXT, index, (LPARAM) name ) != LB_ERR ) {\r
+        while( list->id != 0 ) {\r
+            if( strcmp( list->name, name ) == 0 ) {\r
+                result = list->id;\r
+                break;\r
+            }\r
+\r
+            list++;\r
+        }\r
+    }\r
+\r
+    return result;\r
+}\r
+\r
+void GLT_MoveSelection( HWND hDlg, int delta )\r
+{\r
+    int idx1 = (int) SendDlgItemMessage( hDlg, IDC_GameListTags, LB_GETCURSEL, 0, 0 );\r
+    int idx2 = idx1 + delta;\r
+    int count = (int) SendDlgItemMessage( hDlg, IDC_GameListTags, LB_GETCOUNT, 0, 0 );\r
+\r
+    if( idx1 >=0 && idx1 < count && idx2 >= 0 && idx2 < count ) {\r
+        char buf[128];\r
+\r
+        SendDlgItemMessage( hDlg, IDC_GameListTags, LB_GETTEXT, idx1, (LPARAM) buf );\r
+        SendDlgItemMessage( hDlg, IDC_GameListTags, LB_DELETESTRING, idx1, 0 );\r
+        SendDlgItemMessage( hDlg, IDC_GameListTags, LB_INSERTSTRING, idx2, (LPARAM) buf );\r
+        SendDlgItemMessage( hDlg, IDC_GameListTags, LB_SETCURSEL, idx2, 0 );\r
+    }\r
+}\r
+\r
+LRESULT CALLBACK GameListOptions_Proc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
+{\r
+    static char glt[64];\r
+    static char * lpUserGLT;\r
+\r
+    switch( message )\r
+    {\r
+    case WM_INITDIALOG:\r
+        lpUserGLT = (char *) lParam;\r
+        \r
+        strcpy( glt, lpUserGLT );\r
+\r
+        CenterWindow(hDlg, GetWindow(hDlg, GW_OWNER));\r
+\r
+        /* Initialize list */\r
+        GLT_TagsToList( hDlg, glt );\r
+\r
+        SetFocus( GetDlgItem(hDlg, IDC_GameListTags) );\r
+\r
+        break;\r
+\r
+    case WM_COMMAND:\r
+        switch( LOWORD(wParam) ) {\r
+        case IDOK:\r
+            {\r
+                char * pc = lpUserGLT;\r
+                int idx = 0;\r
+                int cnt = (int) SendDlgItemMessage( hDlg, IDC_GameListTags, LB_GETCOUNT, 0, 0 );\r
+                char id;\r
+\r
+                do {\r
+                    id = GLT_ListItemToTag( hDlg, idx );\r
+\r
+                    *pc++ = id;\r
+                    idx++;\r
+                } while( id != '\0' );\r
+            }\r
+            EndDialog( hDlg, 0 );\r
+            return TRUE;\r
+        case IDCANCEL:\r
+            EndDialog( hDlg, 1 );\r
+            return TRUE;\r
+\r
+        case IDC_GLT_Default:\r
+            strcpy( glt, GLT_DEFAULT_TAGS );\r
+            GLT_TagsToList( hDlg, glt );\r
+            return TRUE;\r
+\r
+        case IDC_GLT_Restore:\r
+            strcpy( glt, lpUserGLT );\r
+            GLT_TagsToList( hDlg, glt );\r
+            return TRUE;\r
+\r
+        case IDC_GLT_Up:\r
+            GLT_MoveSelection( hDlg, -1 );\r
+            return TRUE;\r
+\r
+        case IDC_GLT_Down:\r
+            GLT_MoveSelection( hDlg, +1 );\r
+            return TRUE;\r
+        }\r
+\r
+        break;\r
+    }\r
+\r
+    return FALSE;\r
+}\r
+\r
+int GameListOptions()\r
+{\r
+    char glt[64];\r
+    int result;\r
+    FARPROC lpProc = MakeProcInstance( (FARPROC) GameListOptions_Proc, hInst );\r
+\r
+    strcpy( glt, appData.gameListTags );\r
+\r
+    result = DialogBoxParam( hInst, MAKEINTRESOURCE(DLG_GameListOptions), hwndMain, (DLGPROC)lpProc, (LPARAM)glt );\r
+\r
+    if( result == 0 ) {\r
+        /* [AS] Memory leak here! */\r
+        appData.gameListTags = strdup( glt ); \r
+    }\r
+\r
+    return result;\r
+}\r
+\r
 \r
 VOID\r
 DisplayIcsInteractionTitle(char *str)\r
@@ -8263,8 +8541,10 @@ DisplayWhiteClock(long timeRemaining, int highlight)
 {\r
   HDC hdc;\r
   hdc = GetDC(hwndMain);\r
+  char *flag = whiteFlag && gameMode == TwoMachinesPlay ? "(!)" : "";\r
+\r
   if (!IsIconic(hwndMain)) {\r
-    DisplayAClock(hdc, timeRemaining, highlight, &whiteRect, "White");\r
+    DisplayAClock(hdc, timeRemaining, highlight, &whiteRect, "White", flag);\r
   }\r
   if (highlight && iconCurrent == iconBlack) {\r
     iconCurrent = iconWhite;\r
@@ -8282,9 +8562,11 @@ void
 DisplayBlackClock(long timeRemaining, int highlight)\r
 {\r
   HDC hdc;\r
+  char *flag = blackFlag && gameMode == TwoMachinesPlay ? "(!)" : "";\r
+\r
   hdc = GetDC(hwndMain);\r
   if (!IsIconic(hwndMain)) {\r
-    DisplayAClock(hdc, timeRemaining, highlight, &blackRect, "Black");\r
+    DisplayAClock(hdc, timeRemaining, highlight, &blackRect, "Black", flag);\r
   }\r
   if (highlight && iconCurrent == iconWhite) {\r
     iconCurrent = iconBlack;\r
@@ -8535,27 +8817,27 @@ DestroyChildProcess(ProcRef pr, int/*boolean*/ signal)
        we could arrange for this even though neither WinBoard\r
        nor the chess program uses a console for stdio? */\r
     /*!!if (signal) GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, cp->pid);*/\r
-
-    /* [AS] Special termination modes for misbehaving programs... */
-    if( signal == 9 ) {
-        if ( appData.debugMode) {
-            fprintf( debugFP, "Terminating process %u\n", cp->pid );
-        }
-
-        TerminateProcess( cp->hProcess, 0 );
-    }
-    else if( signal == 10 ) {
-        DWORD dw = WaitForSingleObject( cp->hProcess, 3*1000 ); // Wait 3 seconds at most
-
-        if( dw != WAIT_OBJECT_0 ) {
-            if ( appData.debugMode) {
-                fprintf( debugFP, "Process %u still alive after timeout, killing...\n", cp->pid );
-            }
-
-            TerminateProcess( cp->hProcess, 0 );
-        }
-    }
-
+\r
+    /* [AS] Special termination modes for misbehaving programs... */\r
+    if( signal == 9 ) {\r
+        if ( appData.debugMode) {\r
+            fprintf( debugFP, "Terminating process %u\n", cp->pid );\r
+        }\r
+\r
+        TerminateProcess( cp->hProcess, 0 );\r
+    }\r
+    else if( signal == 10 ) {\r
+        DWORD dw = WaitForSingleObject( cp->hProcess, 3*1000 ); // Wait 3 seconds at most\r
+\r
+        if( dw != WAIT_OBJECT_0 ) {\r
+            if ( appData.debugMode) {\r
+                fprintf( debugFP, "Process %u still alive after timeout, killing...\n", cp->pid );\r
+            }\r
+\r
+            TerminateProcess( cp->hProcess, 0 );\r
+        }\r
+    }\r
+\r
     CloseHandle(cp->hProcess);\r
     break;\r
 \r
@@ -8942,7 +9224,7 @@ InputSourceRef
 AddInputSource(ProcRef pr, int lineByLine,\r
               InputCallback func, VOIDSTAR closure)\r
 {\r
-  InputSource *is, *is2 = NULL;
+  InputSource *is, *is2 = NULL;\r
   ChildProc *cp = (ChildProc *) pr;\r
 \r
   is = (InputSource *) calloc(1, sizeof(InputSource));\r
@@ -8956,18 +9238,18 @@ AddInputSource(ProcRef pr, int lineByLine,
     consoleInputSource = is;\r
   } else {\r
     is->kind = cp->kind;\r
-    /*
-        [AS] Try to avoid a race condition if the thread is given control too early:
-        we create all threads suspended so that the is->hThread variable can be
-        safely assigned, then let the threads start with ResumeThread.
-    */
+    /* \r
+        [AS] Try to avoid a race condition if the thread is given control too early:\r
+        we create all threads suspended so that the is->hThread variable can be\r
+        safely assigned, then let the threads start with ResumeThread.\r
+    */\r
     switch (cp->kind) {\r
     case CPReal:\r
       is->hFile = cp->hFrom;\r
       cp->hFrom = NULL; /* now owned by InputThread */\r
       is->hThread =\r
        CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) NonOvlInputThread,\r
-                    (LPVOID) is, CREATE_SUSPENDED, &is->id);
+                    (LPVOID) is, CREATE_SUSPENDED, &is->id);\r
       break;\r
 \r
     case CPComm:\r
@@ -8975,14 +9257,14 @@ AddInputSource(ProcRef pr, int lineByLine,
       cp->hFrom = NULL; /* now owned by InputThread */\r
       is->hThread =\r
        CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) InputThread,\r
-                    (LPVOID) is, CREATE_SUSPENDED, &is->id);
+                    (LPVOID) is, CREATE_SUSPENDED, &is->id);\r
       break;\r
 \r
     case CPSock:\r
       is->sock = cp->sock;\r
       is->hThread =\r
        CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) SocketInputThread,\r
-                    (LPVOID) is, CREATE_SUSPENDED, &is->id);
+                    (LPVOID) is, CREATE_SUSPENDED, &is->id);\r
       break;\r
 \r
     case CPRcmd:\r
@@ -8994,22 +9276,22 @@ AddInputSource(ProcRef pr, int lineByLine,
       is2->second = is2;\r
       is->hThread =\r
        CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) SocketInputThread,\r
-                    (LPVOID) is, CREATE_SUSPENDED, &is->id);
+                    (LPVOID) is, CREATE_SUSPENDED, &is->id);\r
       is2->hThread =\r
        CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) SocketInputThread,\r
-                    (LPVOID) is2, CREATE_SUSPENDED, &is2->id);
+                    (LPVOID) is2, CREATE_SUSPENDED, &is2->id);\r
       break;\r
     }\r
-
-    if( is->hThread != NULL ) {
-        ResumeThread( is->hThread );
+\r
+    if( is->hThread != NULL ) {\r
+        ResumeThread( is->hThread );\r
+    }\r
+\r
+    if( is2 != NULL && is2->hThread != NULL ) {\r
+        ResumeThread( is2->hThread );\r
+    }\r
   }\r
-
-    if( is2 != NULL && is2->hThread != NULL ) {
-        ResumeThread( is2->hThread );
-    }
-  }
-
+\r
   return (InputSourceRef) is;\r
 }\r
 \r
@@ -9204,10 +9486,10 @@ AnalysisPopUp(char* title, char* str)
   FARPROC lpProc;\r
   char *p, *q;\r
 \r
-  /* [AS] */
-  EngineOutputPopUp();
-  return;
-
+  /* [AS] */\r
+  EngineOutputPopUp();\r
+  return;\r
+\r
   if (str == NULL) str = "";\r
   p = (char *) malloc(2 * strlen(str) + 2);\r
   q = p;\r
@@ -9368,11 +9650,11 @@ ScreenSquare(column, row, pt)
      int column; int row; POINT * pt;\r
 {\r
   if (flipView) {\r
-    pt->x = lineGap + ((BOARD_SIZE-1)-column) * (squareSize + lineGap);\r
+    pt->x = lineGap + ((BOARD_WIDTH-1)-column) * (squareSize + lineGap);\r
     pt->y = lineGap + row * (squareSize + lineGap);\r
   } else {\r
     pt->x = lineGap + column * (squareSize + lineGap);\r
-    pt->y = lineGap + ((BOARD_SIZE-1)-row) * (squareSize + lineGap);\r
+    pt->y = lineGap + ((BOARD_HEIGHT-1)-row) * (squareSize + lineGap);\r
   }\r
 }\r
 \r
@@ -9420,32 +9702,32 @@ Tween(start, mid, finish, factor, frames, nFrames)
 }\r
 \r
 void\r
-HistorySet( char movelist[][2*MOVE_LEN], int first, int last, int current )
-{\r
-#if 0
-    char buf[256];
-\r
-    sprintf( buf, "HistorySet: first=%d, last=%d, current=%d (%s)\n",
-        first, last, current, current >= 0 ? movelist[current] : "n/a" );
-\r
-    OutputDebugString( buf );
-#endif
-
-    MoveHistorySet( movelist, first, last, current, pvInfoList );
-
-    EvalGraphSet( first, last, current, pvInfoList );
-}
-
-void SetProgramStats( FrontEndProgramStats * stats )
-{
-#if 0
-    char buf[1024];
-
-    sprintf( buf, "SetStats for %d: depth=%d, nodes=%lu, score=%5.2f, time=%5.2f, pv=%s\n",
-        stats->which, stats->depth, stats->nodes, stats->score / 100.0, stats->time / 100.0, stats->pv == 0 ? "n/a" : stats->pv );
-
-    OutputDebugString( buf );
-#endif
-
-    EngineOutputUpdate( stats );
-}
+HistorySet( char movelist[][2*MOVE_LEN], int first, int last, int current )\r
+{\r
+#if 0\r
+    char buf[256];\r
+\r
+    sprintf( buf, "HistorySet: first=%d, last=%d, current=%d (%s)\n",\r
+        first, last, current, current >= 0 ? movelist[current] : "n/a" );\r
+\r
+    OutputDebugString( buf );\r
+#endif\r
+\r
+    MoveHistorySet( movelist, first, last, current, pvInfoList );\r
+\r
+    EvalGraphSet( first, last, current, pvInfoList );\r
+}\r
+\r
+void SetProgramStats( FrontEndProgramStats * stats )\r
+{\r
+#if 0\r
+    char buf[1024];\r
+\r
+    sprintf( buf, "SetStats for %d: depth=%d, nodes=%lu, score=%5.2f, time=%5.2f, pv=%s\n",\r
+        stats->which, stats->depth, stats->nodes, stats->score / 100.0, stats->time / 100.0, stats->pv == 0 ? "n/a" : stats->pv );\r
+\r
+    OutputDebugString( buf );\r
+#endif\r
+\r
+    EngineOutputUpdate( stats );\r
+}\r