X-Git-Url: http://winboard.nl/cgi-bin?a=blobdiff_plain;f=backend.c;h=4ceb598a7e22b07315d54b463578094883218904;hb=6c20dd0e5e6c0354cdcd1f07a5645d0411f87a6d;hp=d1f3b04b605528051fb06c69e3f63b2ada2fee73;hpb=80e6f9d953e34c2f2ebf745a2e23e0eb6acf882b;p=xboard.git diff --git a/backend.c b/backend.c index d1f3b04..4ceb598 100644 --- a/backend.c +++ b/backend.c @@ -920,6 +920,7 @@ Load (ChessProgramState *cps, int i) p[-1] = 0; appData.directory[i] = strdup(engineName); p[-1] = SLASH; + if(SLASH == '/' && p - engineName > 1) *(p -= 2) = '.'; // for XBoard use ./exeName as command after split! } else appData.directory[i] = "."; if(params[0]) { if(strchr(p, ' ') && !strchr(p, '"')) snprintf(buf2, MSG_SIZ, "\"%s\"", p), p = buf2; // quote if it contains spaces @@ -6404,12 +6405,16 @@ int lastLoadGameNumber = 0, lastLoadPositionNumber = 0; int lastLoadGameUseList = FALSE; char lastLoadGameTitle[MSG_SIZ], lastLoadPositionTitle[MSG_SIZ]; ChessMove lastLoadGameStart = EndOfFile; +int doubleClick, mappedMove = -1; void UserMoveEvent(int fromX, int fromY, int toX, int toY, int promoChar) { ChessMove moveType; ChessSquare pdown, pup; + static char excludeMap[(BOARD_RANKS*BOARD_FILES*BOARD_RANKS*BOARD_FILES+7)/8]; // [HGM] exclude: bitmap for excluced moves + int ff=fromX, rf=fromY, ft=toX, rt=toY; + /* Check if the user is playing in turn. This is complicated because we let the user "pick up" a piece before it is his turn. So the piece he @@ -6545,6 +6550,18 @@ UserMoveEvent(int fromX, int fromY, int toX, int toY, int promoChar) return; } + if(doubleClick && (toX == -2 || toY == -2)) { // [HGM] exclude: off-board move means exclude all + int i; // note that drop moves still have holdings coords as from-square at this point + ChessMove moveType; char pc; + for(i=0; i<(BOARD_RANKS*BOARD_FILES*BOARD_RANKS*BOARD_FILES+7)/8; i++) excludeMap[i] = -(toY == -2); + mappedMove = currentMove; + if(toY != -2) { SendToProgram("include all\n", &first); return; } + SendToProgram("exclude all\n", &first); + i = ParseOneMove(lastPV[0], currentMove, &moveType, &fromX, &fromY, &toX, &toY, &pc); + ff=fromX, rf=fromY, ft=toX, rt=toY, promoChar = pc; // make copy that will survive drop encoding + if(!i) return; // kludge: continue with move changed to engine's last-reported best, so it gets included again. + } + if(toX < 0 || toY < 0) return; pdown = boards[currentMove][fromY][fromX]; pup = boards[currentMove][toY][toX]; @@ -6576,6 +6593,21 @@ UserMoveEvent(int fromX, int fromY, int toX, int toY, int promoChar) } } + if(doubleClick) { // [HGM] exclude: move entered with double-click on from square is for exclusion, not playing + int i=(BOARD_FILES*rf+ff)*BOARD_RANKS*BOARD_FILES + (BOARD_FILES*rt+ft), j; + char buf[MSG_SIZ]; + if(mappedMove != currentMove) + for(j=0; j<(BOARD_RANKS*BOARD_FILES*BOARD_RANKS*BOARD_FILES+7)/8; j++) excludeMap[j] = 0; + j = i%8; i >>= 3; + snprintf(buf, MSG_SIZ, "%sclude ", excludeMap[i] & 1<= gameInfo.holdingsSize) ) return; - if(gotPremove && clickType == Press) { // user starts something after premove has been entered: abort premove as side effect + if(gotPremove && x == premoveFromX && y == premoveFromY && clickType == Release) { + // could be static click on premove from-square: abort premove gotPremove = 0; ClearPremoveHighlights(); } - if(clickType == Press && fromX == x && fromY == y && promoDefaultAltered) + if(clickType == Press && fromX == x && fromY == y && promoDefaultAltered && SubtractTimeMarks(&lastClickTime, &prevClickTime) >= 200) fromX = fromY = -1; // second click on piece after altering default promo piece treated as first click if(!promoDefaultAltered) { // determine default promotion piece, based on the side the user is moving for @@ -6912,6 +6948,7 @@ LeftClick (ClickType clickType, int xPix, int yPix) } return; } + doubleClick = FALSE; fromX = x; fromY = y; toX = toY = -1; if(!appData.oneClick || !OnlyMove(&x, &y, FALSE) || // even if only move, we treat as normal when this would trigger a promotion popup, to allow sweep selection @@ -6958,6 +6995,10 @@ LeftClick (ClickType clickType, int xPix, int yPix) !(fromP == BlackKing && toP == BlackRook && frc))) { /* Clicked again on same color piece -- changed his mind */ second = (x == fromX && y == fromY); + if(second && gameMode == AnalyzeMode && SubtractTimeMarks(&lastClickTime, &prevClickTime) < 200) { + second = FALSE; // first double-click rather than scond click + doubleClick = first.excludeMoves; // used by UserMoveEvent to recognize exclude moves + } promoDefaultAltered = FALSE; MarkTargetSquares(1); if(!second || appData.oneClick && !OnlyMove(&x, &y, TRUE)) { @@ -6971,7 +7012,7 @@ LeftClick (ClickType clickType, int xPix, int yPix) (fromX == BOARD_LEFT-2 || fromX == BOARD_RGHT+1) && y == (toP < BlackPawn ? 0 : BOARD_HEIGHT-1)) gatingPiece = boards[currentMove][fromY][fromX]; - else gatingPiece = EmptySquare; + else gatingPiece = doubleClick ? fromP : EmptySquare; fromX = x; fromY = y; dragging = 1; MarkTargetSquares(0); @@ -7093,7 +7134,7 @@ LeftClick (ClickType clickType, int xPix, int yPix) // off-board moves should not be highlighted if(x < 0 || y < 0) ClearHighlights(); - if(gatingPiece != EmptySquare) promoChoice = ToLower(PieceToChar(gatingPiece)); + if(gatingPiece != EmptySquare && gameInfo.variant == VariantSChess) promoChoice = ToLower(PieceToChar(gatingPiece)); if (HasPromotionChoice(fromX, fromY, toX, toY, &promoChoice, appData.sweepSelect)) { SetHighlights(fromX, fromY, toX, toY); @@ -8362,7 +8403,7 @@ if(appData.debugMode) fprintf(debugFP, "nodes = %d, %lld\n", (int) programStats. /* * If chess program startup fails, exit with an error message. - * Attempts to recover here are futile. + * Attempts to recover here are futile. [HGM] Well, we try anyway */ if ((StrStr(message, "unknown host") != NULL) || (StrStr(message, "No remote directory") != NULL) @@ -8376,7 +8417,17 @@ if(appData.debugMode) fprintf(debugFP, "nodes = %d, %lld\n", (int) programStats. _(cps->which), cps->program, cps->host, message); RemoveInputSource(cps->isr); if(appData.icsActive) DisplayFatalError(buf1, 0, 1); else { - if(cps == &first) appData.noChessProgram = TRUE; + cps->isr = NULL; + DestroyChildProcess(cps->pr, 9 ); // just to be sure + cps->pr = NoProc; + if(cps == &first) { + appData.noChessProgram = TRUE; + gameMode = MachinePlaysBlack; ModeHighlight(); // kludge to unmark Machine Black menu + gameMode = BeginningOfGame; ModeHighlight(); + SetNCPMode(); + } + if(GetDelayedEvent()) CancelDelayedEvent(), ThawUI(); // [HGM] cancel remaining loading effort scheduled after feature timeout + DisplayMessage("", ""); // erase waiting message DisplayError(buf1, 0); } return; @@ -10702,6 +10753,7 @@ Reset (int redraw, int init) DisplayMessage("", ""); HistorySet(parseList, backwardMostMove, forwardMostMove, currentMove-1); lastSavedGame = 0; // [HGM] save: make sure next game counts as unsaved + mappedMove = -1; // [HGM] exclude: invalidate map } void @@ -13685,6 +13737,7 @@ EditPositionEvent () currentMove = forwardMostMove = backwardMostMove = 0; HistorySet(parseList, backwardMostMove, forwardMostMove, currentMove-1); DisplayMove(-1); + if(!appData.pieceMenu) DisplayMessage(_("Click clock to clear board"), ""); } void @@ -14291,6 +14344,7 @@ ForwardInner (int target) if ( !matchMode && gameMode != Training) { // [HGM] PV info: routine tests if empty DisplayComment(currentMove - 1, commentList[currentMove]); } + mappedMove = -1; // [HGM] exclude: invalidate map } @@ -14404,6 +14458,7 @@ BackwardInner (int target) HistorySet(parseList,backwardMostMove,forwardMostMove,currentMove-1); // [HGM] PV info: routine tests if comment empty DisplayComment(currentMove - 1, commentList[currentMove]); + mappedMove = -1; // [HGM] exclude: invalidate map } void @@ -15470,6 +15525,7 @@ ParseFeatures (char *args, ChessProgramState *cps) if (BoolFeature(&p, "playother", &cps->usePlayother, cps)) continue; if (BoolFeature(&p, "colors", &cps->useColors, cps)) continue; if (BoolFeature(&p, "usermove", &cps->useUsermove, cps)) continue; + if (BoolFeature(&p, "exclude", &cps->excludeMoves, cps)) continue; if (BoolFeature(&p, "ics", &cps->sendICS, cps)) continue; if (BoolFeature(&p, "name", &cps->sendName, cps)) continue; if (BoolFeature(&p, "pause", &val, cps)) continue; /* unused at present */