Use side-by-side boards to display background game
authorH.G. Muller <h.g.muller@hccnet.nl>
Sat, 20 Feb 2010 11:42:09 +0000 (12:42 +0100)
committerH.G. Muller <h.g.muller@hccnet.nl>
Tue, 23 Feb 2010 14:02:50 +0000 (15:02 +0100)
A game observed in the background (i.e. if -backgroundObserve true) will
be displayed right of the normal board in the same window if the new
(persistent) Boolean option -dualBoard is also set.
Very flakey hack, especially in XBoard, where clocks and messsage
field all get the wrong width (and resist adjustment in the strangest
ways). The clocks of the partner game are not yet displayed, and
disaster happens when the background and foreground games do not have
the same board format.

args.h
backend.c
common.h
winboard/winboard.c
xboard.c

diff --git a/args.h b/args.h
index 1b736cc..b16b963 100644 (file)
--- a/args.h
+++ b/args.h
@@ -561,6 +561,7 @@ ArgDescriptor argDescriptors[] = {
   { "ruleMoves", ArgInt, (void *) &appData.ruleMoves, TRUE, (ArgIniType) 51 },
   { "repeatsToDraw", ArgInt, (void *) &appData.drawRepeats, TRUE, (ArgIniType) 6 },
   { "backgroundObserve", ArgBoolean, (void *) &appData.bgObserve, TRUE, (ArgIniType) FALSE },
+  { "dualBoard", ArgBoolean, (void *) &appData.dualBoard, TRUE, (ArgIniType) FALSE },
   { "autoKibitz", ArgTrue, (void *) &appData.autoKibitz, FALSE, INVALID },
   { "engineDebugOutput", ArgInt, (void *) &appData.engineComments, FALSE, (ArgIniType) 1 },
   { "userName", ArgString, (void *) &appData.userName, FALSE, INVALID },
index efd709c..56049a8 100644 (file)
--- a/backend.c
+++ b/backend.c
@@ -246,6 +246,7 @@ Board partnerBoard;     /* [HGM] bughouse: for peeking at partner game
 char partnerStatus[MSG_SIZ];
 Boolean partnerUp;
 Boolean originalFlip;
+Boolean twoBoards = 0;
 char endingGame = 0;    /* [HGM] crash: flag to prevent recursion of GameEnds() */
 int whiteNPS, blackNPS; /* [HGM] nps: for easily making clocks aware of NPS     */
 VariantClass currentlyInitializedVariant; /* [HGM] variantswitch */
@@ -3661,7 +3662,9 @@ read_from_ics(isr, closure, data, count, error)
                         /* [HGM] copy holdings to partner-board holdings area */
                         CopyHoldings(partnerBoard, white_holding, WhitePawn);
                         CopyHoldings(partnerBoard, black_holding, BlackPawn);
+                        if(twoBoards) { partnerUp = 1; flipView = !flipView; } // [HGM] dual: always draw
                         if(partnerUp) DrawPosition(FALSE, partnerBoard);
+                        if(twoBoards) { partnerUp = 0; flipView = !flipView; DrawPosition(TRUE, boards[currentMove]); } // [HGM] dual: redraw own
                      }
                    }
                    /* Suppress following prompt */
@@ -3823,8 +3826,10 @@ ParseBoard12(string)
              board[k][1] = board[k][BOARD_WIDTH-2] = (ChessSquare) 0;;
         }
       }
+      if(appData.dualBoard) { twoBoards = partnerUp = 1; flipView = !flipView; InitDrawingSizes(-2,0); } // [HGM] dual
       CopyBoard(partnerBoard, board);
       if(partnerUp) DrawPosition(FALSE, partnerBoard);
+      if(twoBoards) { partnerUp = 0; flipView = !flipView; DrawPosition(TRUE, boards[currentMove]); } // [HGM] dual: redraw own game!
       sprintf(partnerStatus, "W: %d:%d B: %d:%d (%d-%d) %c", white_time/60000, (white_time%60000)/1000,
                 (black_time/60000), (black_time%60000)/1000, white_stren, black_stren, to_play);
       DisplayMessage(partnerStatus, "");
@@ -8893,6 +8898,7 @@ GameEnds(result, resultDetails, whosays)
 
     if(endingGame) return; /* [HGM] crash: forbid recursion */
     endingGame = 1;
+    if(twoBoards) { twoBoards = partnerUp = 0; InitDrawingSizes(-2, 0); } // [HGM] dual
 
     if (appData.debugMode) {
       fprintf(debugFP, "GameEnds(%d, %s, %d)\n",
index 01c2460..0e52ace 100644 (file)
--- a/common.h
+++ b/common.h
@@ -557,6 +557,7 @@ typedef struct {
     int highlightArrowColor;
     Boolean useStickyWindows;
     Boolean bgObserve;   /* [HGM] bughouse */
+    Boolean dualBoard;   /* [HGM] dual     */
     int adjudicateDrawMoves;
     Boolean autoDisplayComment;
     Boolean autoDisplayTags;
index e417559..6eca914 100644 (file)
@@ -1906,6 +1906,7 @@ ResizeBoard(int newSizeX, int newSizeY, int flags)
 }\r
 \r
 \r
+extern Boolean twoBoards, partnerUp; // [HGM] dual\r
 \r
 VOID\r
 InitDrawingSizes(BoardSize boardSize, int flags)\r
@@ -2041,6 +2042,7 @@ InitDrawingSizes(BoardSize boardSize, int flags)
   winW = 2 * GetSystemMetrics(SM_CXFRAME) + boardRect.right + OUTER_MARGIN;\r
   winH = 2 * GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYMENU) +\r
     GetSystemMetrics(SM_CYCAPTION) + boardRect.bottom + OUTER_MARGIN;\r
+  winW *= 1 + twoBoards;\r
   if(suppressVisibleEffects) return; // [HGM] when called for filling sizeInfo only\r
   wpMain.width = winW;  // [HGM] placement: set through temporary which can used by initial sizing choice\r
   wpMain.height = winH; //       without disturbing window attachments\r
@@ -3181,6 +3183,7 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board)
   if( DrawPositionNeedsFullRepaint() ) {\r
       fullrepaint = TRUE;\r
   }\r
+  if(twoBoards) fullrepaint = TRUE; // [HGM] dual: our memory of last-drawn will be all wrong\r
 \r
   if (board == NULL) {\r
     if (!lastReqValid) {\r
@@ -3486,7 +3489,7 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board)
    * This way we avoid any flickering\r
    */\r
   oldBitmap = SelectObject(tmphdc, bufferBitmap);\r
-  BitBlt(hdc, boardRect.left, boardRect.top,\r
+  BitBlt(hdc, boardRect.left + twoBoards*partnerUp*wpMain.width/2, boardRect.top, // [HGM] dual\r
         boardRect.right - boardRect.left,\r
         boardRect.bottom - boardRect.top,\r
         tmphdc, boardRect.left, boardRect.top, SRCCOPY);\r
index 1cf2ef2..2ce05c6 100644 (file)
--- a/xboard.c
+++ b/xboard.c
@@ -482,6 +482,8 @@ Widget shellWidget, layoutWidget, formWidget, boardWidget, messageWidget,
   menuBarWidget, buttonBarWidget, editShell, errorShell, analysisShell,
   ICSInputShell, fileNameShell, askQuestionShell;
 Widget historyShell, evalGraphShell, gameListShell;
+int hOffset; // [HGM] dual
+XSegment secondSegments[BOARD_RANKS + BOARD_FILES + 2];
 XSegment gridSegments[BOARD_RANKS + BOARD_FILES + 2];
 XSegment jailGridSegments[BOARD_RANKS + BOARD_FILES + 6];
 Font clockFontID, coordFontID, countFontID;
@@ -1546,6 +1548,8 @@ ConvertToLine(int argc, char **argv)
 
 //--------------------------------------------------------------------------------------------
 
+extern Boolean twoBoards, partnerUp;
+
 #ifdef IDSIZES
   // eventually, all layout determining code should go into a subroutine, but until then IDSIZE remains undefined
 #else
@@ -1566,7 +1570,7 @@ void InitDrawingSizes(BoardSize boardSize, int flags)
     shellArgs[1].value = (XtArgVal) &h;
     XtGetValues(shellWidget, shellArgs, 2);
 
-    shellArgs[4].value = 2*w; shellArgs[2].value = 10;
+    shellArgs[4].value = 3*w; shellArgs[2].value = 10;
     shellArgs[5].value = 2*h; shellArgs[3].value = 10;
     XtSetValues(shellWidget, &shellArgs[2], 4);
 
@@ -1576,6 +1580,12 @@ void InitDrawingSizes(BoardSize boardSize, int flags)
     boardWidth = lineGap + BOARD_WIDTH * (squareSize + lineGap);
     boardHeight = lineGap + BOARD_HEIGHT * (squareSize + lineGap);
     CreateGrid();
+    hOffset = boardWidth + 10;
+    for(i=0; i<BOARD_WIDTH+BOARD_HEIGHT+2; i++) { // [HGM] dual: grid for second board
+       secondSegments[i] = gridSegments[i];
+       secondSegments[i].x1 += hOffset;
+       secondSegments[i].x2 += hOffset;
+    }
 
     XtSetArg(args[0], XtNwidth, boardWidth);
     XtSetArg(args[1], XtNheight, boardHeight);
@@ -1614,7 +1624,7 @@ void InitDrawingSizes(BoardSize boardSize, int flags)
     /*
      * Inhibit shell resizing.
      */
-    shellArgs[0].value = w = (XtArgVal) boardWidth + marginW;
+    shellArgs[0].value = w = (XtArgVal) boardWidth + marginW + twoBoards*hOffset; // [HGM] dual
     shellArgs[1].value = h = (XtArgVal) boardHeight + marginH;
     shellArgs[4].value = shellArgs[2].value = w;
     shellArgs[5].value = shellArgs[3].value = h;
@@ -4186,6 +4196,8 @@ void DrawSquare(row, column, piece, do_flash)
          (squareSize + lineGap);
     }
 
+    if(twoBoards && partnerUp) x += hOffset; // [HGM] dual: draw second board
+
     square_color = SquareColor(row, column);
 
     if ( // [HGM] holdings: blank out area between board and holdings
@@ -4422,6 +4434,7 @@ void XDrawPosition(w, repaint, board)
     int rrow, rcol;
 
     if(DrawSeekGraph()) return; // [HGM] seekgraph: suppress any drawing if seek graph up
+    if(twoBoards) repaint = True;
 
     if (board == NULL) {
        if (!lastBoardValid) return;
@@ -4474,6 +4487,7 @@ void XDrawPosition(w, repaint, board)
     } else {
        if (lineGap > 0)
          XDrawSegments(xDisplay, xBoardWindow, lineGC,
+                       twoBoards & partnerUp ? secondSegments : // [HGM] dual
                        gridSegments, BOARD_HEIGHT + BOARD_WIDTH + 2);
 
        for (i = 0; i < BOARD_HEIGHT; i++)