{ "msLoginDelay", ArgInt, (void *) &appData.msLoginDelay, XBOARD, (ArgIniType) MS_LOGIN_DELAY },
{ "pasteSelection", ArgBoolean, (void *) &appData.pasteSelection, XBOARD, (ArgIniType) FALSE },
+ { "dropMenu", ArgBoolean, (void *) &appData.dropMenu, TRUE, (ArgIniType) FALSE },
{ "remoteShell", ArgFilename, (void *) &appData.remoteShell, FALSE, (ArgIniType) REMOTE_SHELL },
{ "rsh", ArgFilename, (void *) &appData.remoteShell, FALSE, INVALID },
{ "remoteUser", ArgString, (void *) &appData.remoteUser, FALSE, INVALID },
extern int tinyLayout, smallLayout;
ChessProgramStats programStats;
+char lastPV[2][2*MSG_SIZ]; /* [HGM] pv: last PV in thinking output of each engine */
+int endPV = -1;
static int exiting = 0; /* [HGM] moved to top */
static int setboardSpoiledMachineBlack = 0 /*, errorExitFlag = 0*/;
int startedFromPositionFile = FALSE; Board filePosition; /* [HGM] loadPos */
}
}
+
+void
+ParsePV(char *pv)
+{ // Parse a string of PV moves, and append to current game, behind forwardMostMove
+ int fromX, fromY, toX, toY; char promoChar;
+ ChessMove moveType;
+ Boolean valid;
+ int nr = 0;
+
+ endPV = forwardMostMove;
+ do {
+ while(*pv == ' ') pv++;
+ if(*pv == '(') pv++; // first (ponder) move can be in parentheses
+ valid = ParseOneMove(pv, endPV, &moveType, &fromX, &fromY, &toX, &toY, &promoChar);
+if(appData.debugMode){
+fprintf(debugFP,"parsePV: %d %c%c%c%c '%s'\n", valid, fromX+AAA, fromY+ONE, toX+AAA, toY+ONE, pv);
+}
+ if(!valid && nr == 0 &&
+ ParseOneMove(pv, endPV-1, &moveType, &fromX, &fromY, &toX, &toY, &promoChar)){
+ nr++; moveType = Comment; // First move has been played; kludge to make sure we continue
+ }
+ while(*pv && *pv++ != ' '); // skip what we parsed; assume space separators
+ if(moveType == Comment) { valid++; continue; } // allow comments in PV
+ nr++;
+ if(endPV+1 > framePtr) break; // no space, truncate
+ if(!valid) break;
+ endPV++;
+ CopyBoard(boards[endPV], boards[endPV-1]);
+ ApplyMove(fromX, fromY, toX, toY, promoChar, boards[endPV]);
+ moveList[endPV-1][0] = fromX + AAA;
+ moveList[endPV-1][1] = fromY + ONE;
+ moveList[endPV-1][2] = toX + AAA;
+ moveList[endPV-1][3] = toY + ONE;
+ parseList[endPV-1][0] = NULLCHAR;
+ } while(valid);
+}
+
+static int lastX, lastY;
+
+Boolean
+LoadPV(int x, int y)
+{ // called on right mouse click to load PV
+ int which = gameMode == TwoMachinesPlay && (WhiteOnMove(forwardMostMove) == (second.twoMachinesColor[0] == 'w'));
+ lastX = x; lastY = y;
+ ParsePV(lastPV[which]); // load the PV of the thinking engine in the boards array.
+ currentMove = endPV;
+ if(currentMove == forwardMostMove) ClearPremoveHighlights(); else
+ SetPremoveHighlights(moveList[currentMove-1][0]-AAA, moveList[currentMove-1][1]-ONE,
+ moveList[currentMove-1][2]-AAA, moveList[currentMove-1][3]-ONE);
+ DrawPosition(TRUE, boards[currentMove]);
+ return TRUE;
+}
+
+void
+UnLoadPV()
+{
+ if(endPV < 0) return;
+ endPV = -1;
+ currentMove = forwardMostMove;
+ ClearPremoveHighlights();
+ DrawPosition(TRUE, boards[currentMove]);
+}
+
+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;
+
+ 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(!step) return;
+ lastX = x; lastY = y;
+ if(currentMove + step > endPV || currentMove + step < forwardMostMove) step = 0;
+ currentMove += step;
+ if(currentMove == forwardMostMove) ClearPremoveHighlights(); else
+ SetPremoveHighlights(moveList[currentMove-1][0]-AAA, moveList[currentMove-1][1]-ONE,
+ moveList[currentMove-1][2]-AAA, moveList[currentMove-1][3]-ONE);
+ DrawPosition(FALSE, boards[currentMove]);
+}
+
+
// [HGM] shuffle: a general way to suffle opening setups, applicable to arbitrary variants.
// All positions will have equal probability, but the current method will not provide a unique
// numbering scheme for arrays that contain 3 or more pieces of the same kind.
stats.an_move_count = cpstats->nr_moves;
}
+ if(stats.pv && stats.pv[0]) strcpy(lastPV[stats.which], stats.pv); // [HGM] pv: remember last PV of each
+
SetProgramStats( &stats );
}
0, 1);
return;
}
+ UnLoadPV(); // [HGM] pv: if we are looking at a PV, abort this
if (commentList[forwardMostMove+1] != NULL) {
free(commentList[forwardMostMove+1]);
commentList[forwardMostMove+1] = NULL;
if(whiteNPS >= 0) lastTickLength = 0;
timeRemaining = whiteTimeRemaining -= lastTickLength;
DisplayWhiteClock(whiteTimeRemaining - fudge,
- WhiteOnMove(currentMove));
+ WhiteOnMove(currentMove < forwardMostMove ? currentMove : forwardMostMove));
} else {
if(blackNPS >= 0) lastTickLength = 0;
timeRemaining = blackTimeRemaining -= lastTickLength;
DisplayBlackClock(blackTimeRemaining - fudge,
- !WhiteOnMove(currentMove));
+ !WhiteOnMove(currentMove < forwardMostMove ? currentMove : forwardMostMove));
}
if (CheckFlags()) return;
void OutputChatMessage P((int partner, char *mess));
void EditPositionDone P((Boolean fakeRights));
Boolean GetArgValue P((char *name));
+Boolean LoadPV P((int x, int y));
+void UnLoadPV P(());
+void MovePV P((int x, int y, int h));
char *StrStr P((char *string, char *match));
char *StrCaseStr P((char *string, char *match));
Boolean useInternalWrap; /* use internal wrapping -- noJoin usurps this if set */
Boolean pasteSelection; /* paste X selection instead of clipboard */
int nrVariations; /* [HGM] multivar */
+ Boolean dropMenu;
} AppData, *AppDataPtr;
/* [AS] PGN tags (for showing in the game list) */
break;\r
\r
case WM_MOUSEMOVE:\r
+ MovePV(pt.x - boardRect.left, pt.y - boardRect.top, boardRect.bottom - boardRect.top);
if ((appData.animateDragging || appData.highlightDragging)\r
&& (wParam & MK_LBUTTON)\r
&& dragInfo.from.x >= 0) \r
}\r
break;\r
\r
+ case WM_MBUTTONUP:
+ case WM_RBUTTONUP:
+ ReleaseCapture();
+ UnLoadPV();
+ break;
+
case WM_MBUTTONDOWN:\r
case WM_RBUTTONDOWN:\r
ErrorPopDown();\r
MenuPopup(hwnd, pt, LoadMenu(hInst, "ShogiPieceMenu"), -1);\r
}\r
break;\r
- case IcsPlayingWhite:\r
- case IcsPlayingBlack:\r
- case EditGame:\r
- case MachinePlaysWhite:\r
- case MachinePlaysBlack:\r
- if (appData.testLegality &&\r
- gameInfo.variant != VariantBughouse &&\r
- gameInfo.variant != VariantCrazyhouse) break;\r
- if (x < 0 || y < 0) break;\r
+ case IcsObserving:
+ if(!appData.icsEngineAnalyze) break;
+ case IcsPlayingWhite:
+ case IcsPlayingBlack:
+ if(!appData.zippyPlay) goto noZip;
+ case MachinePlaysWhite:
+ case MachinePlaysBlack:
+ case TwoMachinesPlay:
+ case AnalyzeMode:
+ case AnalyzeFile:
+ if (!appData.dropMenu) {
+ SetCapture(hwndMain);
+ LoadPV(pt.x - boardRect.left, pt.y - boardRect.top);
+ break;
+ }
+ if(gameMode == TwoMachinesPlay || gameMode == AnalyzeMode ||
+ gameMode == AnalyzeFile || gameMode == IcsObserving) break;
+ case EditGame:
+ noZip:
+ if (x < 0 || y < 0) break;
+ if (!appData.dropMenu || appData.testLegality &&
+ gameInfo.variant != VariantBughouse &&
+ gameInfo.variant != VariantCrazyhouse) break;
fromX = x;\r
fromY = y;\r
hmenu = LoadMenu(hInst, "DropPieceMenu");\r
String *prms, Cardinal *nprms));
void AnimateUserMove P((Widget w, XEvent * event,
String * params, Cardinal * nParams));
+void HandlePV P((Widget w, XEvent * event,
+ String * params, Cardinal * nParams));
void WhiteClock P((Widget w, XEvent *event,
String *prms, Cardinal *nprms));
void BlackClock P((Widget w, XEvent *event,
{ "DrawPosition", DrawPositionProc },
{ "HandleUserMove", HandleUserMove },
{ "AnimateUserMove", AnimateUserMove },
+ { "HandlePV", HandlePV },
+ { "UnLoadPV", UnLoadPV },
{ "FileNameAction", FileNameAction },
{ "AskQuestionProc", AskQuestionProc },
{ "AskQuestionReplyAction", AskQuestionReplyAction },
"<Btn1Down>: HandleUserMove() \n \
<Btn1Up>: HandleUserMove() \n \
<Btn1Motion>: AnimateUserMove() \n \
+ <Btn3Motion>: HandlePV() \n \
+ <Btn3Up>: UnLoadPV() \n \
Shift<Btn2Down>: XawPositionSimpleMenu(menuB) XawPositionSimpleMenu(menuD)\
PieceMenuPopup(menuB) \n \
Any<Btn2Down>: XawPositionSimpleMenu(menuW) XawPositionSimpleMenu(menuD) \
Cardinal *num_params;
{
String whichMenu;
+
+ if (event->type != ButtonRelease) UnLoadPV(); // [HGM] pv
if (event->type != ButtonPress) return;
if (errorUp) ErrorPopDown();
switch (gameMode) {
case IcsExamining:
whichMenu = params[0];
break;
+ case IcsObserving:
+ if(!appData.icsEngineAnalyze) return;
case IcsPlayingWhite:
case IcsPlayingBlack:
- case EditGame:
+ if(!appData.zippyPlay) goto noZip;
+ case AnalyzeMode:
+ case AnalyzeFile:
case MachinePlaysWhite:
case MachinePlaysBlack:
- if (appData.testLegality &&
+ case TwoMachinesPlay: // [HGM] pv: use for showing PV
+ if (!appData.dropMenu) {
+ LoadPV(event->xbutton.x, event->xbutton.y);
+ return;
+ }
+ if(gameMode == TwoMachinesPlay || gameMode == AnalyzeMode ||
+ gameMode == AnalyzeFile || gameMode == IcsObserving) return;
+ case EditGame:
+ noZip:
+ if (!appData.dropMenu || appData.testLegality &&
gameInfo.variant != VariantBughouse &&
gameInfo.variant != VariantCrazyhouse) return;
SetupDropMenu();
DragPieceMove(event->xmotion.x, event->xmotion.y);
}
+void HandlePV (Widget w, XEvent * event,
+ String * params, Cardinal * nParams)
+{ // [HGM] pv: walk PV
+ MovePV(event->xmotion.x, event->xmotion.y, lineGap + BOARD_HEIGHT * (squareSize + lineGap));
+}
+
Widget CommentCreate(name, text, mutable, callback, lines)
char *name, *text;
int /*Boolean*/ mutable;