X-Git-Url: http://winboard.nl/cgi-bin?a=blobdiff_plain;f=backend.c;h=b5f24a4c1e89dd0e3c8446b4967d39a6dc842210;hb=8a375395a4cc09b1febaf64c4b2e7ce66c59a69b;hp=77a156433e311b0f0e4a3b738935240896367229;hpb=5e30372d0d5f7d8976c3affc2c4537c6538e4c11;p=xboard.git diff --git a/backend.c b/backend.c index 77a1564..b5f24a4 100644 --- a/backend.c +++ b/backend.c @@ -267,6 +267,8 @@ char chatPartner[MAX_CHAT][MSG_SIZ]; /* [HGM] chat: list of chatting partners */ extern int chatCount; int chattingPartner; char marker[BOARD_RANKS][BOARD_FILES]; /* [HGM] marks for target squares */ +ChessSquare pieceSweep = EmptySquare; +ChessSquare promoSweep = EmptySquare; /* States for ics_getting_history */ #define H_FALSE 0 @@ -4368,7 +4370,8 @@ ParseBoard12(string) safeStrCpy(moveList[moveNum - 1], currentMoveString, sizeof(moveList[moveNum - 1])/sizeof(moveList[moveNum - 1][0])); strcat(moveList[moveNum - 1], "\n"); - if(gameInfo.holdingsWidth && !appData.disguise) // inherit info that ICS does not give from previous board + if(gameInfo.holdingsWidth && !appData.disguise && gameInfo.variant != VariantSuper + && gameInfo.variant != VariantGreat) // inherit info that ICS does not give from previous board for(k=0; k= BlackPawn) king = WHITE_TO_BLACK king, pawn = WHITE_TO_BLACK pawn; + if(gameInfo.variant == VariantSpartan && pawn == BlackPawn) pawn = BlackLance, king = EmptySquare; + if(toY != BOARD_HEIGHT-1 && toY != 0) pawn = EmptySquare; + do { + promoSweep -= step; + if(promoSweep == EmptySquare) promoSweep = BlackPawn; // wrap + else if((int)promoSweep == -1) promoSweep = WhiteKing; + else if(promoSweep == BlackPawn && step < 0) promoSweep = WhitePawn; + else if(promoSweep == WhiteKing && step > 0) promoSweep = BlackKing; + if(!step) step = 1; + } while(PieceToChar(promoSweep) == '.' || PieceToChar(promoSweep) == '~' || promoSweep == pawn || + appData.testLegality && (promoSweep == king || + gameInfo.variant == VariantShogi && promoSweep != PROMOTED last && last != PROMOTED promoSweep && last != promoSweep)); + boards[currentMove][toY][toX] = promoSweep; + DrawPosition(FALSE, boards[currentMove]); + boards[currentMove][toY][toX] = piece; +} + +static int lastX, lastY; + +void PromoScroll(int x, int y) +{ + int step = 0; + if(abs(x - lastX) < 7 && abs(y - lastY) < 7) return; + if( y > lastY + 2 ) step = -1; else if(y < lastY - 2) step = 1; + if(!step) return; + lastX = x; lastY = y; + + if(promoSweep == EmptySquare) return; + Sweep(step); +} + +void +NextPiece(int step) +{ + ChessSquare piece = boards[currentMove][toY][toX]; + do { + pieceSweep -= step; + if(pieceSweep == EmptySquare) pieceSweep = WhitePawn; // wrap + if((int)pieceSweep == -1) pieceSweep = BlackKing; + if(!step) step = -1; + } while(PieceToChar(pieceSweep) == '.'); + boards[currentMove][toY][toX] = pieceSweep; + DrawPosition(FALSE, boards[currentMove]); + boards[currentMove][toY][toX] = piece; +} /* [HGM] Shogi move preprocessor: swap digits for letters, vice versa */ void AlphaRank(char *move, int n) @@ -5017,8 +5073,6 @@ fprintf(debugFP,"parsePV: %d %c%c%c%c yy='%s'\nPV = '%s'\n", valid, fromX+AAA, f DrawPosition(TRUE, boards[currentMove]); } -static int lastX, lastY; - Boolean LoadMultiPV(int x, int y, char *buf, int index, int *start, int *end) { @@ -5062,15 +5116,18 @@ UnLoadPV() void MovePV(int x, int y, int h) { // step through PV based on mouse coordinates (called on mouse move) - int margin = h>>3, step = 0; + int margin = h>>3, step = 0, dist; - if(endPV < 0) return; // we must somehow check if right button is still down (might be released off board!) - if(y < margin && (abs(x - lastX) > 6 || abs(y - lastY) > 6)) step = 1; else - if(y > h - margin && (abs(x - lastX) > 6 || abs(y - lastY) > 6)) step = -1; else - if( y > lastY + 6 ) step = -1; else if(y < lastY - 6) step = 1; + if(abs(x - lastX) < 7 && abs(y - lastY) < 7) return; + if( y > lastY + 2 ) step = -1; else if(y < lastY - 2) step = 1; if(!step) return; lastX = x; lastY = y; + + if(pieceSweep != EmptySquare) { NextPiece(step); return; } + if(endPV < 0) return; + if(y < margin) step = 1; else + if(y > h - margin) step = -1; if(currentMove + step > endPV || currentMove + step < forwardMostMove) step = 0; currentMove += step; if(currentMove == forwardMostMove) ClearPremoveHighlights(); else @@ -5730,12 +5787,16 @@ HasPromotionChoice(int fromX, int fromY, int toX, int toY, char *promoChoice) *promoChoice = PieceToChar(BlackQueen); // Queen as good as any return FALSE; } - if(autoQueen) { // predetermined - if(gameInfo.variant == VariantSuicide || gameInfo.variant == VariantLosers) - *promoChoice = PieceToChar(BlackKing); // in Suicide Q is the last thing we want - else *promoChoice = PieceToChar(BlackQueen); - return FALSE; - } + // give caller the default choice even if we will not make it + if(gameInfo.variant == VariantSuicide || gameInfo.variant == VariantGiveaway) + *promoChoice = PieceToChar(BlackKing); // in Suicide Q is the last thing we want + else if(gameInfo.variant == VariantSpartan) + *promoChoice = ToLower(PieceToChar(toY ? WhiteQueen : BlackAngel)); + else if(gameInfo.variant == VariantShogi) + *promoChoice = '+'; + else *promoChoice = ToLower(PieceToChar(toY ? WhiteQueen : BlackQueen)); + if(*promoChoice == '.') *promoChoice = ToLower(PieceToChar(piece)); // safety catch, to make sure promoChoice is a defined piece + if(autoQueen) return FALSE; // predetermined // suppress promotion popup on illegal moves that are not premoves premove = gameMode == IcsPlayingWhite && !WhiteOnMove(currentMove) || @@ -6369,6 +6430,18 @@ void LeftClick(ClickType clickType, int xPix, int yPix) x = BOARD_WIDTH - 1 - x; } + if(promoSweep != EmptySquare) { + char promoChar = ToLower(PieceToChar(promoSweep)); + if(gameInfo.variant == VariantShogi) promoChar = promoSweep == boards[currentMove][fromY][fromX] ? '=' : '+'; + saveAnimate = appData.animate; appData.animate = FALSE; + UserMoveEvent(fromX, fromY, toX, toY, promoChar); + appData.animate = saveAnimate; + promoSweep = EmptySquare; + DrawPosition(FALSE, boards[currentMove]); + fromX = fromY = -1; + return; + } + if(promotionChoice) { // we are waiting for a click to indicate promotion piece if(clickType == Release) return; // ignore upclick of click-click destination promotionChoice = FALSE; // only one chance: if click not OK it is interpreted as cancel @@ -6564,7 +6637,13 @@ void LeftClick(ClickType clickType, int xPix, int yPix) DisplayMessage("Click in holdings to choose piece", ""); return; } - PromotionPopUp(); + if(appData.sweepSelect && clickType == Press) { + lastX = xPix; lastY = yPix; + ChessSquare piece = boards[currentMove][fromY][fromX]; + promoSweep = CharToPiece((piece >= BlackPawn ? ToLower : ToUpper)(promoChoice)); + if(promoChoice == '+') promoSweep = PROMOTED piece; + Sweep(0); + } else PromotionPopUp(); } else { int oldMove = currentMove; UserMoveEvent(fromX, fromY, toX, toY, promoChoice); @@ -6612,16 +6691,25 @@ int RightClick(ClickType action, int x, int y, int *fromX, int *fromY) xSqr = EventToSquare(x, BOARD_WIDTH); ySqr = EventToSquare(y, BOARD_HEIGHT); - if (action == Release) UnLoadPV(); // [HGM] pv + if (action == Release) { + if(pieceSweep != EmptySquare) { + EditPositionMenuEvent(pieceSweep, toX, toY); + pieceSweep = EmptySquare; + } else UnLoadPV(); // [HGM] pv + } if (action != Press) return -2; // return code to be ignored switch (gameMode) { case IcsExamining: if(xSqr < BOARD_LEFT || xSqr >= BOARD_RGHT) return -1; case EditPosition: if (xSqr == BOARD_LEFT-1 || xSqr == BOARD_RGHT) return -1; - if (xSqr < 0 || ySqr < 0) return -1; - whichMenu = 0; // edit-position menu - break; + if (xSqr < 0 || ySqr < 0) return -1; + if(appData.pieceMenu) { whichMenu = 0; break; } // edit-position menu + pieceSweep = shiftKey ? BlackPawn : WhitePawn; // [HGM] sweep: prepare selecting piece by mouse sweep + toX = xSqr; toY = ySqr; lastX = x, lastY = y; + if(flipView) toX = BOARD_WIDTH - 1 - toX; else toY = BOARD_HEIGHT - 1 - toY; + NextPiece(0); + return -2; case IcsObserving: if(!appData.icsEngineAnalyze) return -1; case IcsPlayingWhite: @@ -10421,6 +10509,7 @@ LoadGame(f, gameNumber, title, useList) for (i = BOARD_HEIGHT - 1; i >= 0; i--) for (j = BOARD_LEFT; j < BOARD_RGHT; p++) switch (*p) { + case '{': case '[': case '-': case ' ': @@ -12612,6 +12701,7 @@ ClockClick(int which) { // [HGM] code moved to back-end from winboard.c if(which) { // black clock if (gameMode == EditPosition || gameMode == IcsExamining) { + if(!appData.pieceMenu && blackPlaysFirst) EditPositionMenuEvent(ClearBoard, 0, 0); SetBlackToPlayEvent(); } else if (gameMode == EditGame || shiftKey) { AdjustClock(which, -1); @@ -12621,6 +12711,7 @@ ClockClick(int which) } } else { // white clock if (gameMode == EditPosition || gameMode == IcsExamining) { + if(!appData.pieceMenu && !blackPlaysFirst) EditPositionMenuEvent(ClearBoard, 0, 0); SetWhiteToPlayEvent(); } else if (gameMode == EditGame || shiftKey) { AdjustClock(which, -1); @@ -13881,11 +13972,11 @@ ParseOption(Option *opt, ChessProgramState *cps) } else if((p = strstr(opt->name, " -file "))) { // for now -file is a synonym for -string, to already provide compatibility with future polyglots opt->textValue = p+7; - opt->type = TextBox; // FileName; + opt->type = FileName; // FileName; } else if((p = strstr(opt->name, " -path "))) { // for now -file is a synonym for -string, to already provide compatibility with future polyglots opt->textValue = p+7; - opt->type = TextBox; // PathName; + opt->type = PathName; // PathName; } else if(p = strstr(opt->name, " -check ")) { if(sscanf(p, " -check %d", &def) < 1) return FALSE; opt->value = (def != 0);