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
}
+void
+Sweep(int step)
+{
+ ChessSquare piece = boards[currentMove][toY][toX];
+ ChessSquare king = WhiteKing, pawn = WhitePawn, last = promoSweep;
+ if(gameInfo.variant == VariantKnightmate) king = WhiteUnicorn;
+ if(gameInfo.variant == VariantSuicide || gameInfo.variant == VariantGiveaway) king = EmptySquare;
+ if(promoSweep >= 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)
DrawPosition(TRUE, boards[currentMove]);
}
-static int lastX, lastY;
-
Boolean
LoadMultiPV(int x, int y, char *buf, int index, int *start, int *end)
{
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
*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) ||
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
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);
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;\r
case EditPosition:
if (xSqr == BOARD_LEFT-1 || xSqr == BOARD_RGHT) return -1;\r
- if (xSqr < 0 || ySqr < 0) return -1;\r
- 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;\r
case IcsObserving:
if(!appData.icsEngineAnalyze) return -1;
case IcsPlayingWhite:
{ // [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);
}
} 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);
} 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);