*\r
* Author: Alessandro Scotti (Dec 2005)\r
*\r
+ * Copyright 2005 Alessandro Scotti\r
+ *\r
* ------------------------------------------------------------------------\r
*\r
* GNU XBoard is free software: you can redistribute it and/or modify\r
#include <dlgs.h>\r
\r
#include "common.h"\r
-#include "winboard.h"\r
#include "frontend.h"\r
#include "backend.h"\r
+#include "winboard.h"\r
\r
#include "wsnap.h"\r
\r
\r
HWND outputField[2][7]; // [HGM] front-end array to translate output field to window handle\r
\r
-void EngineOutputPopUp();\r
-void EngineOutputPopDown();\r
-int EngineOutputIsUp();\r
-\r
#define SHOW_PONDERING\r
\r
-/* Imports from backend.c */\r
-char * SavePart(char *str);\r
-extern int opponentKibitzes;\r
-\r
-/* Imports from winboard.c */\r
-extern HWND engineOutputDialog;\r
-extern int engineOutputDialogUp;\r
-\r
-extern HINSTANCE hInst;\r
-extern HWND hwndMain;\r
-\r
-extern WindowPlacement wpEngineOutput;\r
-\r
/* Module variables */\r
#define H_MARGIN 2\r
#define V_MARGIN 2\r
#define STATE_ANALYZING 3\r
\r
static int windowMode = 1;\r
-\r
static int needInit = TRUE;\r
-\r
static int lastDepth[2] = { -1, -1 };\r
static int lastForwardMostMove[2] = { -1, -1 };\r
static int engineState[2] = { -1, -1 };\r
+static BOOLEAN engineOutputDialogUp = FALSE;\r
\r
typedef struct {\r
// HWND hColorIcon; // [HGM] the output-control handles are no loger passed,\r
int an_move_count;\r
} EngineOutputData;\r
\r
-static VerifyDisplayMode();\r
+static void VerifyDisplayMode();\r
static void UpdateControls( EngineOutputData * ed );\r
-static SetEngineState( int which, int state, char * state_data );\r
+static void SetEngineState( int which, int state, char * state_data );\r
\r
// front end\r
static HICON LoadIconEx( int id )\r
{\r
RECT rc;\r
int headerHeight = GetHeaderHeight();\r
- int labelHeight = GetControlHeight( hDlg, IDC_EngineLabel1 );\r
- int labelOffset = H_MARGIN + ICON_SIZE + H_MARGIN;\r
- int labelDeltaY = ICON_SIZE - labelHeight;\r
+// int labelHeight = GetControlHeight( hDlg, IDC_EngineLabel1 );\r
+// int labelOffset = H_MARGIN + ICON_SIZE + H_MARGIN;\r
+// int labelDeltaY = ICON_SIZE - labelHeight;\r
int clientWidth;\r
int clientHeight;\r
int maxControlWidth;\r
}\r
\r
// front end. Actual printing of PV lines into the output field\r
-static void InsertIntoMemo( int which, char * text )\r
+static void InsertIntoMemo( int which, char * text, int where )\r
{\r
- SendMessage( outputField[which][nMemo], EM_SETSEL, 0, 0 );\r
+ SendMessage( outputField[which][nMemo], EM_SETSEL, where, where ); // [HGM] multivar: choose insertion point\r
\r
SendMessage( outputField[which][nMemo], EM_REPLACESEL, (WPARAM) FALSE, (LPARAM) text );\r
}\r
\r
ResizeWindowControls( hDlg, windowMode );\r
\r
+ /* Set font */\r
+ SendDlgItemMessage( engineOutputDialog, IDC_EngineMemo1, WM_SETFONT, (WPARAM)font[boardSize][MOVEHISTORY_FONT]->hf, MAKELPARAM(TRUE, 0 ));\r
+ SendDlgItemMessage( engineOutputDialog, IDC_EngineMemo2, WM_SETFONT, (WPARAM)font[boardSize][MOVEHISTORY_FONT]->hf, MAKELPARAM(TRUE, 0 ));\r
+\r
SetEngineState( 0, STATE_IDLE, "" );\r
SetEngineState( 1, STATE_IDLE, "" );\r
}\r
\r
//------------------------ pure back-end routines -------------------------------\r
\r
+#define MAX_VAR 400\r
+static int scores[MAX_VAR], textEnd[MAX_VAR], curDepth[2], nrVariations[2];\r
\r
// back end, due to front-end wrapper for SetWindowText, and new SetIcon arguments\r
-static SetEngineState( int which, int state, char * state_data )\r
+static void SetEngineState( int which, int state, char * state_data )\r
{\r
int x_which = 1 - which;\r
\r
clearMemo = TRUE;\r
}\r
\r
- if( clearMemo ) DoClearMemo(which);\r
+ if( clearMemo ) { DoClearMemo(which); nrVariations[which] = 0; }\r
\r
/* Update */\r
- lastDepth[which] = depth;\r
+ lastDepth[which] = depth == 1 && ed.nodes == 0 ? 0 : depth; // [HGM] info-line kudge\r
lastForwardMostMove[which] = forwardMostMove;\r
\r
if( ed.pv != 0 && ed.pv[0] == ' ' ) {\r
result = cps->twoMachinesColor[0];\r
result = result == 'w' ? ENGINE_COLOR_WHITE : ENGINE_COLOR_BLACK;\r
break;\r
+ default: ; // does not happen, but suppresses pedantic warnings\r
}\r
}\r
\r
if( GetEngineColor( which ) != GetActiveEngineColor() ) result = TRUE;\r
}\r
break;\r
+ default: ; // does not happen, but suppresses pedantic warnings\r
}\r
\r
return result;\r
}\r
\r
// pure back end\r
-static VerifyDisplayMode()\r
+static void VerifyDisplayMode()\r
{\r
int mode;\r
\r
\r
#define MAX_NAME_LENGTH 32\r
\r
+// [HGM] multivar: sort Thinking Output within one depth on score\r
+\r
+static int InsertionPoint( int len, EngineOutputData * ed )\r
+{\r
+ int i, offs = 0, newScore = ed->score, n = ed->which;\r
+\r
+ if(ed->nodes == 0 && ed->score == 0 && ed->time == 0)\r
+ newScore = 1e6; // info lines inserted on top\r
+ if(ed->depth != curDepth[n]) { // depth has changed\r
+ curDepth[n] = ed->depth;\r
+ nrVariations[n] = 0; // throw away everything we had\r
+ }\r
+ // loop through all lines. Note even / odd used for different panes\r
+ for(i=nrVariations[n]-2; i>=0; i-=2) {\r
+ // put new item behind those we haven't looked at\r
+ offs = textEnd[i+n];\r
+ textEnd[i+n+2] = offs + len;\r
+ scores[i+n+2] = newScore;\r
+ if(newScore < scores[i+n]) break;\r
+ // if it had higher score as previous, move previous in stead\r
+ scores[i+n+2] = scores[i+n];\r
+ textEnd[i+n+2] = textEnd[i+n] + len;\r
+ }\r
+ if(i<0) {\r
+ offs = 0;\r
+ textEnd[n] = offs + len;\r
+ scores[n] = newScore;\r
+ }\r
+ nrVariations[n] += 2;\r
+ return offs;\r
+}\r
+\r
// pure back end, now SetWindowText is called via wrapper DoSetWindowText\r
static void UpdateControls( EngineOutputData * ed )\r
{\r
- int isPondering = FALSE;\r
+// int isPondering = FALSE;\r
\r
char s_label[MAX_NAME_LENGTH + 32];\r
\r
SetEngineState( ed->which, STATE_THINKING, "" );\r
}\r
else if( gameMode == AnalyzeMode || gameMode == AnalyzeFile\r
- || gameMode == IcsObserving && appData.icsEngineAnalyze) { // [HGM] ICS-analyze\r
+ || (gameMode == IcsObserving && appData.icsEngineAnalyze)) { // [HGM] ICS-analyze\r
char buf[64];\r
int time_secs = ed->time / 100;\r
int time_mins = time_secs / 60;\r
sprintf( s_time, "%d:%02d.%02d", time_secs / 60, time_secs % 60, time_cent );\r
\r
/* Put all together... */\r
- sprintf( buf, "%3d\t%s\t%s\t%s\t", ed->depth, s_score, s_nodes, s_time );\r
+ if(ed->nodes == 0 && ed->score == 0 && ed->time == 0) sprintf( buf, "%3d\t", ed->depth ); else \r
+ sprintf( buf, "%3d\t%s\t%s\t%s\t", ed->depth, s_score, s_nodes, s_time );\r
\r
/* Add PV */\r
buflen = strlen(buf);\r
strcat( buf + buflen, "\r\n" );\r
\r
/* Update memo */\r
- InsertIntoMemo( ed->which, buf );\r
+ InsertIntoMemo( ed->which, buf, InsertionPoint(strlen(buf), ed) );\r
}\r
\r
/* Colors */\r
DoSetWindowText(1, nLabel, gameMode == IcsPlayingBlack ? gameInfo.white : gameInfo.black); // opponent name\r
SetIcon( 1, nColorIcon, gameMode == IcsPlayingBlack ? nColorWhite : nColorBlack);\r
SetIcon( 1, nStateIcon, nClear);\r
- InsertIntoMemo(window-1, text);\r
+ InsertIntoMemo(window-1, text, 0); // [HGM] multivar: always at top\r
}\r