fixed long-algebraic form of drops
[xboard.git] / winboard / winboard.c
index fb317b7..48a6f3b 100644 (file)
@@ -103,7 +103,7 @@ void DisplayHoldingsCount(HDC hdc, int x, int y, int align, int copyNumber);
 VOID NewVariantPopup(HWND hwnd);\r
 int FinishMove P((ChessMove moveType, int fromX, int fromY, int toX, int toY,\r
                   /*char*/int promoChar));\r
-void AnimateAtomicCapture(int toX, int toY, int nFrames);\r
+void AnimateAtomicCapture(int fromX, int fromY, int toX, int toY, int nFrames);\r
 \r
 typedef struct {\r
   ChessSquare piece;  \r
@@ -132,10 +132,10 @@ static HighlightInfo highlightInfo        = { {{-1, -1}, {-1, -1}} };
 static HighlightInfo premoveHighlightInfo = { {{-1, -1}, {-1, -1}} };\r
 \r
 typedef struct { // [HGM] atomic\r
-  int x, y, radius;\r
+  int fromX, fromY, toX, toY, radius;\r
 } ExplodeInfo;\r
 \r
-static ExplodeInfo explodeInfo = {0, 0, 0};\r
+static ExplodeInfo explodeInfo;\r
 \r
 /* Window class names */\r
 char szAppName[] = "WinBoard";\r
@@ -201,6 +201,7 @@ static HICON iconWhite, iconBlack, iconCurrent;
 static int doingSizing = FALSE;\r
 static int lastSizing = 0;\r
 static int prevStderrPort;\r
+static HBITMAP userLogo;\r
 \r
 /* [AS] Support for background textures */\r
 #define BACK_TEXTURE_MODE_DISABLED      0\r
@@ -543,6 +544,21 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
  *\r
 \*---------------------------------------------------------------------------*/\r
 \r
+void\r
+SetUserLogo()\r
+{   // update user logo if necessary\r
+    static char oldUserName[MSG_SIZ], *curName;\r
+\r
+    if(appData.autoLogo) {\r
+         curName = UserName();\r
+         if(strcmp(curName, oldUserName)) {\r
+               sprintf(oldUserName, "logos\\%s.bmp", curName);\r
+               userLogo = LoadImage( 0, oldUserName, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );    \r
+               strcpy(oldUserName, curName);\r
+         }\r
+    }\r
+}\r
+\r
 BOOL\r
 InitApplication(HINSTANCE hInstance)\r
 {\r
@@ -658,13 +674,19 @@ InitInstance(HINSTANCE hInstance, int nCmdShow, LPSTR lpCmdLine)
           fprintf( debugFP, "Unable to load logo bitmap '%s'\n", appData.secondLogo );\r
       }\r
   } else if(appData.autoLogo) {\r
+      char buf[MSG_SIZ];\r
+      if(appData.icsActive) { // [HGM] logo: in ICS mode second can be used for ICS\r
+       sprintf(buf, "logos\\%s.bmp", appData.icsHost);\r
+       second.programLogo = LoadImage( 0, buf, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );\r
+      } else\r
       if(appData.secondDirectory && appData.secondDirectory[0]) {\r
-       char buf[MSG_SIZ];\r
        sprintf(buf, "%s\\logo.bmp", appData.secondDirectory);\r
        second.programLogo = LoadImage( 0, buf, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );  \r
       }\r
   }\r
 \r
+  SetUserLogo();\r
+\r
   iconWhite = LoadIcon(hInstance, "icon_white");\r
   iconBlack = LoadIcon(hInstance, "icon_black");\r
   iconCurrent = iconWhite;\r
@@ -1286,6 +1308,7 @@ ArgDescriptor argDescriptors[] = {
   { "zippyVariants", ArgString, (LPVOID) &appData.zippyVariants, FALSE },\r
   { "zippyMaxGames", ArgInt, (LPVOID)&appData.zippyMaxGames, FALSE },\r
   { "zippyReplayTimeout", ArgInt, (LPVOID)&appData.zippyReplayTimeout, FALSE },\r
+  { "zippyShortGame", ArgInt, (LPVOID)&appData.zippyShortGame, FALSE },\r
   /* Kludge to allow winboard.ini files from buggy 4.0.4 to be read: */\r
   { "zippyReplyTimeout", ArgInt, (LPVOID)&junk, FALSE },\r
 #endif\r
@@ -3135,7 +3158,7 @@ InitDrawingSizes(BoardSize boardSize, int flags)
   ReleaseDC(hwndMain, hdc);\r
 \r
   /* Compute where everything goes */\r
-  if(first.programLogo || second.programLogo) {\r
+  if((first.programLogo || second.programLogo) && !tinyLayout) {\r
         /* [HGM] logo: if either logo is on, reserve space for it */\r
        logoHeight =  2*clockSize.cy;\r
        leftLogoRect.left   = OUTER_MARGIN;\r
@@ -3149,19 +3172,19 @@ InitDrawingSizes(BoardSize boardSize, int flags)
        rightLogoRect.bottom = OUTER_MARGIN + logoHeight;\r
 \r
 \r
-    blackRect.left = leftLogoRect.right;\r
-    blackRect.right = rightLogoRect.left;\r
-    blackRect.top = OUTER_MARGIN;\r
-    blackRect.bottom = blackRect.top + clockSize.cy;\r
+    whiteRect.left = leftLogoRect.right;\r
+    whiteRect.right = OUTER_MARGIN + boardWidth/2 - INNER_MARGIN/2;\r
+    whiteRect.top = OUTER_MARGIN;\r
+    whiteRect.bottom = whiteRect.top + logoHeight;\r
 \r
-    whiteRect.left = blackRect.left ;\r
-    whiteRect.right = blackRect.right;\r
-    whiteRect.top = blackRect.bottom;\r
-    whiteRect.bottom = leftLogoRect.bottom;\r
+    blackRect.right = rightLogoRect.left;\r
+    blackRect.left = whiteRect.right + INNER_MARGIN;\r
+    blackRect.top = whiteRect.top;\r
+    blackRect.bottom = whiteRect.bottom;\r
   } else {\r
     whiteRect.left = OUTER_MARGIN;\r
     whiteRect.right = whiteRect.left + boardWidth/2 - INNER_MARGIN/2;\r
-    whiteRect.top = OUTER_MARGIN + logoHeight;\r
+    whiteRect.top = OUTER_MARGIN;\r
     whiteRect.bottom = whiteRect.top + clockSize.cy;\r
 \r
     blackRect.left = whiteRect.right + INNER_MARGIN;\r
@@ -4233,7 +4256,7 @@ void fputDW(FILE *f, int x)
 #define MAX_CLIPS 200   /* more than enough */\r
 \r
 VOID\r
-DrawLogoOnDC(HDC hdc, RECT logoRect, ChessProgramState *cps)\r
+DrawLogoOnDC(HDC hdc, RECT logoRect, HBITMAP logo)\r
 {\r
 //  HBITMAP bufferBitmap;\r
   BITMAP bi;\r
@@ -4242,13 +4265,13 @@ DrawLogoOnDC(HDC hdc, RECT logoRect, ChessProgramState *cps)
   HBITMAP hbm;\r
   int w = 100, h = 50;\r
 \r
-  if(cps->programLogo == NULL) return;\r
+  if(logo == NULL) return;\r
 //  GetClientRect(hwndMain, &Rect);\r
 //  bufferBitmap = CreateCompatibleBitmap(hdc, Rect.right-Rect.left+1,\r
 //                                     Rect.bottom-Rect.top+1);\r
   tmphdc = CreateCompatibleDC(hdc);\r
-  hbm = SelectObject(tmphdc, (HBITMAP) cps->programLogo);\r
-  if( GetObject( cps->programLogo, sizeof(bi), &bi ) > 0 ) {\r
+  hbm = SelectObject(tmphdc, logo);\r
+  if( GetObject( logo, sizeof(bi), &bi ) > 0 ) {\r
             w = bi.bmWidth;\r
             h = bi.bmHeight;\r
   }\r
@@ -4511,7 +4534,8 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board)
   if(explodeInfo.radius) { // [HGM] atomic\r
        HBRUSH oldBrush;\r
        int x, y, r=(explodeInfo.radius * squareSize)/100;\r
-       SquareToPos(explodeInfo.y, explodeInfo.x, &x, &y);\r
+        board[explodeInfo.fromY][explodeInfo.fromX] = EmptySquare; // suppress display of capturer\r
+       SquareToPos(explodeInfo.toY, explodeInfo.toX, &x, &y);\r
        x += squareSize/2;\r
        y += squareSize/2;\r
         if(!fullrepaint) {\r
@@ -4530,8 +4554,39 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board)
     DrawBoardOnDC(hdcmem, board, tmphdc);\r
   }\r
   if(logoHeight) {\r
-       DrawLogoOnDC(hdc, leftLogoRect, flipClock ? &second : &first);\r
-       DrawLogoOnDC(hdc, rightLogoRect, flipClock ? &first : &second);\r
+       HBITMAP whiteLogo = (HBITMAP) first.programLogo, blackLogo = (HBITMAP) second.programLogo;\r
+       if(appData.autoLogo) {\r
+         \r
+         switch(gameMode) { // pick logos based on game mode\r
+           case IcsObserving:\r
+               whiteLogo = second.programLogo; // ICS logo\r
+               blackLogo = second.programLogo;\r
+           default:\r
+               break;\r
+           case IcsPlayingWhite:\r
+               if(!appData.zippyPlay) whiteLogo = userLogo;\r
+               blackLogo = second.programLogo; // ICS logo\r
+               break;\r
+           case IcsPlayingBlack:\r
+               whiteLogo = second.programLogo; // ICS logo\r
+               blackLogo = appData.zippyPlay ? first.programLogo : userLogo;\r
+               break;\r
+           case TwoMachinesPlay:\r
+               if(first.twoMachinesColor[0] == 'b') {\r
+                   whiteLogo = second.programLogo;\r
+                   blackLogo = first.programLogo;\r
+               }\r
+               break;\r
+           case MachinePlaysWhite:\r
+               blackLogo = userLogo;\r
+               break;\r
+           case MachinePlaysBlack:\r
+               whiteLogo = userLogo;\r
+               blackLogo = first.programLogo;\r
+         }\r
+       }\r
+       DrawLogoOnDC(hdc, leftLogoRect, flipClock ? blackLogo : whiteLogo);\r
+       DrawLogoOnDC(hdc, rightLogoRect, flipClock ? whiteLogo : blackLogo);\r
   }\r
 \r
   if( appData.highlightMoveWithArrow ) {\r
@@ -4875,7 +4930,7 @@ MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
                   gameMode == MachinePlaysWhite) {\r
          CallFlagEvent();\r
         } else if (gameMode == EditGame) {\r
-          AdjustClock((logoHeight > 0 ? flipView: flipClock), -1);\r
+          AdjustClock(flipClock, -1);\r
         }\r
       } else if (PtInRect((LPRECT) &blackRect, pt)) {\r
        if (gameMode == EditPosition) {\r
@@ -4884,7 +4939,7 @@ MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
                   gameMode == MachinePlaysBlack) {\r
          CallFlagEvent();\r
         } else if (gameMode == EditGame) {\r
-          AdjustClock(!(logoHeight > 0 ? flipView: flipClock), -1);\r
+          AdjustClock(!flipClock, -1);\r
        }\r
       }\r
       if (!appData.highlightLastMove) {\r
@@ -5055,7 +5110,10 @@ MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
                PromotionPopup(hwnd); /* [HGM] Popup now calls FinishMove */\r
           } else {\r
            if(saveAnimate /* ^$!%@#$!$ */  && gameInfo.variant == VariantAtomic \r
-                       && boards[currentMove][toY][toX] != EmptySquare) AnimateAtomicCapture(toX, toY, 20);\r
+                         && (boards[currentMove][toY][toX] != EmptySquare || \r
+                                       moveType == WhiteCapturesEnPassant || \r
+                                       moveType == BlackCapturesEnPassant   ) )\r
+               AnimateAtomicCapture(fromX, fromY, toX, toY, 20);\r
            FinishMove(moveType, fromX, fromY, toX, toY, NULLCHAR);\r
          }\r
       }\r
@@ -5128,9 +5186,9 @@ MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
     if(y == -2) {\r
       /* [HGM] right mouse button in clock area edit-game mode ups clock */\r
       if (PtInRect((LPRECT) &whiteRect, pt)) {\r
-          if (gameMode == EditGame) AdjustClock((logoHeight > 0 ? flipView: flipClock), 1);\r
+          if (gameMode == EditGame) AdjustClock(flipClock, 1);\r
       } else if (PtInRect((LPRECT) &blackRect, pt)) {\r
-          if (gameMode == EditGame) AdjustClock(!(logoHeight > 0 ? flipView: flipClock), 1);\r
+          if (gameMode == EditGame) AdjustClock(!flipClock, 1);\r
       }\r
     }\r
     DrawPosition(TRUE, NULL);\r
@@ -5936,6 +5994,7 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
     case IDM_FlipClock:\r
       flipClock = !flipClock;\r
       DisplayBothClocks();\r
+      DrawPosition(FALSE, NULL);\r
       break;\r
 \r
     case IDM_GeneralOptions:\r
@@ -7284,6 +7343,7 @@ TypeInNameDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
     case IDOK:\r
       GetDlgItemText(hDlg, OPT_Name, move, sizeof(move));\r
       appData.userName = strdup(move);\r
+      SetUserLogo();\r
 \r
       EndDialog(hDlg, TRUE);\r
       return TRUE;\r
@@ -8253,7 +8313,7 @@ DisplayAClock(HDC hdc, int timeRemaining, int highlight,
     if (tinyLayout)\r
       sprintf(buf, "%c %s %s", color[0], TimeString(timeRemaining), flagFell);\r
     else\r
-      sprintf(buf, "%s: %s %s", color, TimeString(timeRemaining), flagFell);\r
+      sprintf(buf, "%s:%c%s %s", color, (logoHeight>0 ? 0 : ' '), TimeString(timeRemaining), flagFell);\r
     str = buf;\r
   } else {\r
     str = color;\r
@@ -8271,7 +8331,17 @@ DisplayAClock(HDC hdc, int timeRemaining, int highlight,
   ExtTextOut(hdc, rect->left + MESSAGE_LINE_LEFTMARGIN,\r
             rect->top, ETO_CLIPPED|ETO_OPAQUE,\r
             rect, str, strlen(str), NULL);\r
-\r
+  if(logoHeight > 0 && appData.clockMode) {\r
+      RECT r;\r
+      sprintf(buf, "%s %s", TimeString(timeRemaining), flagFell);\r
+      r.top = rect->top + logoHeight/2;\r
+      r.left = rect->left;\r
+      r.right = rect->right;\r
+      r.bottom = rect->bottom;\r
+      ExtTextOut(hdc, rect->left + MESSAGE_LINE_LEFTMARGIN,\r
+                r.top, ETO_CLIPPED|ETO_OPAQUE,\r
+                &r, str, strlen(str), NULL);\r
+  }\r
   (void) SetTextColor(hdc, oldFg);\r
   (void) SetBkColor(hdc, oldBg);\r
   (void) SelectObject(hdc, oldFont);\r
@@ -9527,7 +9597,7 @@ DisplayWhiteClock(long timeRemaining, int highlight)
   hdc = GetDC(hwndMain);\r
   if (!IsIconic(hwndMain)) {\r
     DisplayAClock(hdc, timeRemaining, highlight, \r
-                       (logoHeight > 0 ? flipView: flipClock) ? &blackRect : &whiteRect, "White", flag);\r
+                       flipClock ? &blackRect : &whiteRect, "White", flag);\r
   }\r
   if (highlight && iconCurrent == iconBlack) {\r
     iconCurrent = iconWhite;\r
@@ -9551,7 +9621,7 @@ DisplayBlackClock(long timeRemaining, int highlight)
   hdc = GetDC(hwndMain);\r
   if (!IsIconic(hwndMain)) {\r
     DisplayAClock(hdc, timeRemaining, highlight, \r
-                       (logoHeight > 0 ? flipView: flipClock) ? &whiteRect : &blackRect, "Black", flag);\r
+                       flipClock ? &whiteRect : &blackRect, "Black", flag);\r
   }\r
   if (highlight && iconCurrent == iconWhite) {\r
     iconCurrent = iconBlack;\r
@@ -10595,13 +10665,15 @@ static void Tween( POINT * start, POINT * mid, POINT * finish, int factor,
 \r
 \r
 void\r
-AnimateAtomicCapture(int toX, int toY, int nFrames)\r
+AnimateAtomicCapture(int fromX, int fromY, int toX, int toY, int nFrames)\r
 {      // [HGM] atomic: animate blast wave\r
        int i;\r
 if(appData.debugMode) fprintf(debugFP, "exploding (%d,%d)\n", toX, toY);\r
-       explodeInfo.x = toX;\r
-       explodeInfo.y = toY;\r
-       for(i=0; i<nFrames; i++) {\r
+       explodeInfo.fromX = fromX;\r
+       explodeInfo.fromY = fromY;\r
+       explodeInfo.toX = toX;\r
+       explodeInfo.toY = toY;\r
+       for(i=1; i<nFrames; i++) {\r
            explodeInfo.radius = (i*180)/(nFrames-1);\r
            DrawPosition(FALSE, NULL);\r
            Sleep(appData.animSpeed);\r
@@ -10670,8 +10742,9 @@ AnimateMove(board, fromX, fromY, toX, toY)
   animInfo.pos = finish;\r
   DrawPosition(FALSE, NULL);\r
   animInfo.piece = EmptySquare;\r
-  if(gameInfo.variant == VariantAtomic && board[toY][toX] != EmptySquare)\r
-    AnimateAtomicCapture(toX, toY, 2*nFrames);\r
+  if(gameInfo.variant == VariantAtomic && \r
+     (board[toY][toX] != EmptySquare || fromX != toX && (piece == WhitePawn || piece == BlackPawn) ) )\r
+       AnimateAtomicCapture(fromX, fromY, toX, toY, 2*nFrames);\r
 }\r
 \r
 /*      Convert board position to corner of screen rect and color       */\r