X-Git-Url: http://winboard.nl/cgi-bin?a=blobdiff_plain;f=backend.c;h=80211026275e9d512ea58756da70ce9a13d58235;hb=25b9dd471b02847a646237ad5888f0f1186917ad;hp=38c3533e2558261492dca1d1bea98980e46b62e4;hpb=e3af409047e1992a08e296c1475c94b8a1e5f7b1;p=xboard.git diff --git a/backend.c b/backend.c index 38c3533..8021102 100644 --- a/backend.c +++ b/backend.c @@ -450,15 +450,15 @@ int adjudicateLossPlies = 6; char white_holding[64], black_holding[64]; TimeMark lastNodeCountTime; long lastNodeCount=0; -int shiftKey; // [HGM] set by mouse handler +int shiftKey, controlKey; // [HGM] set by mouse handler int have_sent_ICS_logon = 0; int movesPerSession; int suddenDeath, whiteStartMove, blackStartMove; /* [HGM] for implementation of 'any per time' sessions, as in first part of byoyomi TC */ -long whiteTimeRemaining, blackTimeRemaining, timeControl, timeIncrement, lastWhite, lastBlack; +long whiteTimeRemaining, blackTimeRemaining, timeControl, timeIncrement, lastWhite, lastBlack, activePartnerTime; Boolean adjustedClock; long timeControl_2; /* [AS] Allow separate time controls */ -char *fullTimeControlString = NULL, *nextSession, *whiteTC, *blackTC; /* [HGM] secondary TC: merge of MPS, TC and inc */ +char *fullTimeControlString = NULL, *nextSession, *whiteTC, *blackTC, activePartner; /* [HGM] secondary TC: merge of MPS, TC and inc */ long timeRemaining[2][MAX_MOVES]; int matchGame = 0, nextGame = 0, roundNr = 0; Boolean waitingForGame = FALSE; @@ -920,7 +920,7 @@ Load (ChessProgramState *cps, int i) while(q = strchr(p, SLASH)) p = q+1; if(*p== NULLCHAR) { DisplayError(_("You did not specify the engine executable"), 0); return; } if(engineDir[0] != NULLCHAR) { - ASSIGN(appData.directory[i], engineDir); + ASSIGN(appData.directory[i], engineDir); p = engineName; } else if(p != engineName) { // derive directory from engine path, when not given p[-1] = 0; ASSIGN(appData.directory[i], engineName); @@ -4244,6 +4244,7 @@ ParseBoard12 (char *string) if((gameMode == IcsPlayingWhite || gameMode == IcsPlayingBlack) && newGameMode == IcsObserving && gamenum != ics_gamenum && appData.bgObserve) { // [HGM] bughouse: don't act on alien boards while we play. Just parse the board and save it */ + int fac = strchr(elapsed_time, '.') ? 1 : 1000; char *toSqr; for (k = 0; k < ranks; k++) { for (j = 0; j < files; j++) @@ -4266,11 +4267,13 @@ ParseBoard12 (char *string) if(twoBoards) { partnerUp = 1; flipView = !flipView; } // [HGM] dual if(partnerUp) DrawPosition(FALSE, partnerBoard); if(twoBoards) { - DisplayWhiteClock(white_time, to_play == 'W'); - DisplayBlackClock(black_time, to_play != 'W'); + DisplayWhiteClock(white_time*fac, to_play == 'W'); + DisplayBlackClock(black_time*fac, to_play != 'W'); + activePartner = to_play; + activePartnerTime = to_play == 'W' ? white_time*fac : black_time*fac; partnerUp = 0; flipView = !flipView; } // [HGM] dual - snprintf(partnerStatus, MSG_SIZ,"W: %d:%02d B: %d:%02d (%d-%d) %c", white_time/60000, (white_time%60000)/1000, - (black_time/60000), (black_time%60000)/1000, white_stren, black_stren, to_play); + snprintf(partnerStatus, MSG_SIZ,"W: %d:%02d B: %d:%02d (%d-%d) %c", white_time*fac/60000, (white_time*fac%60000)/1000, + (black_time*fac/60000), (black_time*fac%60000)/1000, white_stren, black_stren, to_play); DisplayMessage(partnerStatus, ""); partnerBoardValid = TRUE; return; @@ -6664,7 +6667,7 @@ UserMoveEvent(int fromX, int fromY, int toX, int toY, int promoChar) if(boards[0][fromY][BOARD_WIDTH-2] == 0) boards[0][fromY][BOARD_WIDTH-1] = EmptySquare; } } else - boards[0][fromY][fromX] = EmptySquare; + boards[0][fromY][fromX] = gatingPiece; DrawPosition(FALSE, boards[currentMove]); return; } @@ -6916,11 +6919,11 @@ void MarkTargetSquares (int clear) { int x, y; + if(clear) // no reason to ever suppress clearing + for(x=0; xinitDone) return FALSE; + cps->isr = NULL; // this should suppress further error popups from breaking pipes + 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 + if(errmess) DisplayError(errmess, 0); // announce reason, if given + return TRUE; +} + char *savedMessage; ChessProgramState *savedState; void @@ -7937,7 +7960,7 @@ HandleMachineMove (char *message, ChessProgramState *cps) ChessMove moveType; char promoChar; char *p, *pv=buf1; - int machineWhite; + int machineWhite, oldError; char *bookHit; if(cps == &pairing && sscanf(message, "%d-%d", &savedWhitePlayer, &savedBlackPlayer) == 2) { @@ -7951,7 +7974,7 @@ HandleMachineMove (char *message, ChessProgramState *cps) return; // Skim the pairing messages here. } - cps->userError = 0; + oldError = cps->userError; cps->userError = 0; FakeBookMove: // [HGM] book: we jump here to simulate machine moves after book hit /* @@ -8520,18 +8543,8 @@ 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 { - 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); + if(LoadError(oldError ? NULL : buf1, cps)) return; // error has then been handled by LoadError + if(!oldError) DisplayError(buf1, 0); // if reason neatly announced, suppress general error popup } return; } @@ -12147,7 +12160,7 @@ LoadGame (FILE *f, int gameNumber, char *title, int useList) AnalyzeFileEvent(); } - if (!matchMode && pos >= 0) { + if (!matchMode && pos > 0) { ToNrEvent(pos); // [HGM] no autoplay if selected on position } else if (matchMode || appData.timeDelay == 0) { @@ -15261,10 +15274,10 @@ ReceiveFromProgram (InputSourceRef isr, VOIDSTAR closure, char *message, int cou if (count <= 0) { if (count == 0) { RemoveInputSource(cps->isr); - if(!cps->initDone) return; // [HGM] should not generate fatal error during engine load snprintf(buf, MSG_SIZ, _("Error: %s chess program (%s) exited unexpectedly"), _(cps->which), cps->program); - if(gameInfo.resultDetails==NULL) { /* [HGM] crash: if game in progress, give reason for abort */ + if(LoadError(cps->userError ? NULL : buf, cps)) return; // [HGM] should not generate fatal error during engine load + if(gameInfo.resultDetails==NULL) { /* [HGM] crash: if game in progress, give reason for abort */ if((signed char)boards[forwardMostMove][EP_STATUS] <= EP_DRAWS) { snprintf(buf, MSG_SIZ, _("%s program exits in draw position (%s)"), _(cps->which), cps->program); if(matchMode && appData.tourneyFile[0]) { cps->pr = NoProc; GameEnds(GameIsDrawn, buf, GE_XBOARD); return; } @@ -16203,6 +16216,16 @@ DecrementClocks () } if (CheckFlags()) return; + if(twoBoards) { // count down secondary board's clocks as well + activePartnerTime -= lastTickLength; + partnerUp = 1; + if(activePartner == 'W') + DisplayWhiteClock(activePartnerTime, TRUE); // the counting clock is always the highlighted one! + else + DisplayBlackClock(activePartnerTime, TRUE); + partnerUp = 0; + } + tickStartTM = now; intendedTickLength = NextTickLength(timeRemaining - fudge) + fudge; StartClockTimer(intendedTickLength);