X-Git-Url: http://winboard.nl/cgi-bin?a=blobdiff_plain;f=winboard%2Fwengineoutput.c;h=b9d13f59a051c6d42497377d9fadce54eae6d0eb;hb=HEAD;hp=0623e3d9daf20dcd14afb66fdbfde4e208c3c5ec;hpb=74025874f2010f84fd4f7f2e120e84b56ee9781b;p=xboard.git diff --git a/winboard/wengineoutput.c b/winboard/wengineoutput.c index 0623e3d..b9d13f5 100644 --- a/winboard/wengineoutput.c +++ b/winboard/wengineoutput.c @@ -1,24 +1,31 @@ /* - * Engine output (PV) + * wengineoutput.c - split-off front-end of Engine output (PV) by HGM * * Author: Alessandro Scotti (Dec 2005) * + * Copyright 2005 Alessandro Scotti + * + * Enhancements Copyright 2009, 2010, 2011, 2012, 2013, 2014, 2015, + * 2016 Free Software Foundation, Inc. + * * ------------------------------------------------------------------------ - * This program is free software; you can redistribute it and/or modify + * + * GNU XBoard is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU XBoard is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * ------------------------------------------------------------------------ - */ + * along with this program. If not, see http://www.gnu.org/licenses/. * + * + *------------------------------------------------------------------------ + ** See the file ChangeLog for a revision history. */ + #include "config.h" #include /* required for all Windows applications */ @@ -30,99 +37,58 @@ #include #include "common.h" -#include "winboard.h" #include "frontend.h" #include "backend.h" +#include "winboard.h" #include "wsnap.h" - -VOID EngineOutputPopUp(); -VOID EngineOutputPopDown(); -BOOL EngineOutputIsUp(); - -#define SHOW_PONDERING - -/* Imports from backend.c */ -char * SavePart(char *str); - -/* Imports from winboard.c */ -extern HWND engineOutputDialog; -extern BOOLEAN engineOutputDialogUp; - -extern HINSTANCE hInst; -extern HWND hwndMain; - -extern WindowPlacement wpEngineOutput; +#include "engineoutput.h" /* Module variables */ -#define H_MARGIN 2 -#define V_MARGIN 2 -#define LABEL_V_DISTANCE 1 /* Distance between label and memo */ -#define SPLITTER_SIZE 4 /* Distance between first memo and second label */ - -#define ICON_SIZE 14 - -#define STATE_UNKNOWN -1 -#define STATE_THINKING 0 -#define STATE_IDLE 1 -#define STATE_PONDERING 2 -#define STATE_ANALYZING 3 - -static int windowMode = 1; - -static BOOL needInit = TRUE; - -static HICON hiColorBlack = NULL; -static HICON hiColorWhite = NULL; -static HICON hiColorUnknown = NULL; -static HICON hiClear = NULL; -static HICON hiPondering = NULL; -static HICON hiThinking = NULL; -static HICON hiAnalyzing = NULL; - -static int lastDepth[2] = { -1, -1 }; -static int lastForwardMostMove[2] = { -1, -1 }; -static int engineState[2] = { -1, -1 }; - -typedef struct { - HWND hColorIcon; - HWND hLabel; - HWND hStateIcon; - HWND hStateData; - HWND hLabelNPS; - HWND hMemo; - char * name; - int which; - int depth; - unsigned long nodes; - int score; - int time; - char * pv; - char * hint; - int an_move_index; - int an_move_count; -} EngineOutputData; +int windowMode = 1; +static BOOLEAN engineOutputDialogUp = FALSE; +HICON icons[8]; // [HGM] this front-end array translates back-end icon indicator to handle +HWND outputField[2][7]; // [HGM] front-end array to translate output field to window handle +// front end static HICON LoadIconEx( int id ) { return LoadImage( hInst, MAKEINTRESOURCE(id), IMAGE_ICON, ICON_SIZE, ICON_SIZE, 0 ); } -static VOID InitializeEngineOutput() +// [HGM] the platform-dependent way of indicating where output should go is now all +// concentrated here, where a table of platform-dependent handles are initialized. +// This cleanses most other routines of front-end stuff, so they can go into the back end. +static void InitializeEngineOutput() { - if( needInit ) { - hiColorBlack = LoadIconEx( IDI_BLACK_14 ); - hiColorWhite = LoadIconEx( IDI_WHITE_14 ); - hiColorUnknown = LoadIconEx( IDI_UNKNOWN_14 ); - hiClear = LoadIconEx( IDI_TRANS_14 ); - hiPondering = LoadIconEx( IDI_PONDER_14 ); - hiThinking = LoadIconEx( IDI_CLOCK_14 ); - hiAnalyzing = LoadIconEx( IDI_ANALYZE2_14 ); - needInit = FALSE; - } + // [HGM] made this into a table, rather than separate global variables + icons[nColorBlack] = LoadIconEx( IDI_BLACK_14 ); + icons[nColorWhite] = LoadIconEx( IDI_WHITE_14 ); + icons[nColorUnknown] = LoadIconEx( IDI_UNKNOWN_14 ); + icons[nClear] = LoadIconEx( IDI_TRANS_14 ); + icons[nPondering] = LoadIconEx( IDI_PONDER_14 ); + icons[nThinking] = LoadIconEx( IDI_CLOCK_14 ); + icons[nAnalyzing] = LoadIconEx( IDI_ANALYZE2_14 ); + + // [HGM] also make a table of handles to output controls + // Note that engineOutputDialog must be defined first! + outputField[0][nColorIcon] = GetDlgItem( engineOutputDialog, IDC_Color1 ); + outputField[0][nLabel] = GetDlgItem( engineOutputDialog, IDC_EngineLabel1 ); + outputField[0][nStateIcon] = GetDlgItem( engineOutputDialog, IDC_StateIcon1 ); + outputField[0][nStateData] = GetDlgItem( engineOutputDialog, IDC_StateData1 ); + outputField[0][nLabelNPS] = GetDlgItem( engineOutputDialog, IDC_Engine1_NPS ); + outputField[0][nMemo] = GetDlgItem( engineOutputDialog, IDC_EngineMemo1 ); + + outputField[1][nColorIcon] = GetDlgItem( engineOutputDialog, IDC_Color2 ); + outputField[1][nLabel] = GetDlgItem( engineOutputDialog, IDC_EngineLabel2 ); + outputField[1][nStateIcon] = GetDlgItem( engineOutputDialog, IDC_StateIcon2 ); + outputField[1][nStateData] = GetDlgItem( engineOutputDialog, IDC_StateData2 ); + outputField[1][nLabelNPS] = GetDlgItem( engineOutputDialog, IDC_Engine2_NPS ); + outputField[1][nMemo] = GetDlgItem( engineOutputDialog, IDC_EngineMemo2 ); } -static VOID SetControlPos( HWND hDlg, int id, int x, int y, int width, int height ) +// front end +static void SetControlPos( HWND hDlg, int id, int x, int y, int width, int height ) { HWND hControl = GetDlgItem( hDlg, id ); @@ -132,7 +98,8 @@ static VOID SetControlPos( HWND hDlg, int id, int x, int y, int width, int heigh #define HIDDEN_X 20000 #define HIDDEN_Y 20000 -static VOID HideControl( HWND hDlg, int id ) +// front end +static void HideControl( HWND hDlg, int id ) { HWND hControl = GetDlgItem( hDlg, id ); RECT rc; @@ -148,6 +115,7 @@ static VOID HideControl( HWND hDlg, int id ) } } +// front end, although we might make GetWindowRect front end instead static int GetControlWidth( HWND hDlg, int id ) { RECT rc; @@ -157,6 +125,7 @@ static int GetControlWidth( HWND hDlg, int id ) return rc.right - rc.left; } +// front end? static int GetControlHeight( HWND hDlg, int id ) { RECT rc; @@ -175,76 +144,9 @@ static int GetHeaderHeight() return result; } -#define ENGINE_COLOR_WHITE 'w' -#define ENGINE_COLOR_BLACK 'b' -#define ENGINE_COLOR_UNKNOWN ' ' - -char GetEngineColor( int which ) -{ - char result = ENGINE_COLOR_UNKNOWN; - - if( which == 0 || which == 1 ) { - ChessProgramState * cps; - - switch (gameMode) { - case MachinePlaysBlack: - case IcsPlayingBlack: - result = ENGINE_COLOR_BLACK; - break; - case MachinePlaysWhite: - case IcsPlayingWhite: - result = ENGINE_COLOR_WHITE; - break; - case AnalyzeMode: - case AnalyzeFile: - result = WhiteOnMove(forwardMostMove) ? ENGINE_COLOR_WHITE : ENGINE_COLOR_BLACK; - break; - case TwoMachinesPlay: - cps = (which == 0) ? &first : &second; - result = cps->twoMachinesColor[0]; - result = result == 'w' ? ENGINE_COLOR_WHITE : ENGINE_COLOR_BLACK; - break; - } - } - - return result; -} - -char GetActiveEngineColor() -{ - char result = ENGINE_COLOR_UNKNOWN; - - if( gameMode == TwoMachinesPlay ) { - result = WhiteOnMove(forwardMostMove) ? ENGINE_COLOR_WHITE : ENGINE_COLOR_BLACK; - } - - return result; -} - -static int IsEnginePondering( int which ) -{ - int result = FALSE; - - switch (gameMode) { - case MachinePlaysBlack: - case IcsPlayingBlack: - if( WhiteOnMove(forwardMostMove) ) result = TRUE; - break; - case MachinePlaysWhite: - case IcsPlayingWhite: - if( ! WhiteOnMove(forwardMostMove) ) result = TRUE; - break; - case TwoMachinesPlay: - if( GetActiveEngineColor() != ENGINE_COLOR_UNKNOWN ) { - if( GetEngineColor( which ) != GetActiveEngineColor() ) result = TRUE; - } - break; - } - - return result; -} - -static VOID PositionControlSet( HWND hDlg, int x, int y, int clientWidth, int memoHeight, int idColor, int idEngineLabel, int idNPS, int idMemo, int idStateIcon, int idStateData ) +// The size calculations should be backend? If setControlPos is a platform-dependent way of doing things, +// a platform-independent wrapper for it should be supplied. +static void PositionControlSet( HWND hDlg, int x, int y, int clientWidth, int memoHeight, int idColor, int idEngineLabel, int idNPS, int idMemo, int idStateIcon, int idStateData ) { int label_x = x + ICON_SIZE + H_MARGIN; int label_h = GetControlHeight( hDlg, IDC_EngineLabel1 ); @@ -265,13 +167,15 @@ static VOID PositionControlSet( HWND hDlg, int x, int y, int clientWidth, int me SetControlPos( hDlg, idMemo, x, memo_y, max_w, memoHeight ); } -static VOID ResizeWindowControls( HWND hDlg, int mode ) +// Also here some of the size calculations should go to the back end, and their actual application to a front-end routine +void ResizeWindowControls( int mode ) { + HWND hDlg = engineOutputDialog; // [HGM] used to be parameter, but routine is called from back-end RECT rc; int headerHeight = GetHeaderHeight(); - int labelHeight = GetControlHeight( hDlg, IDC_EngineLabel1 ); - int labelOffset = H_MARGIN + ICON_SIZE + H_MARGIN; - int labelDeltaY = ICON_SIZE - labelHeight; +// int labelHeight = GetControlHeight( hDlg, IDC_EngineLabel1 ); +// int labelOffset = H_MARGIN + ICON_SIZE + H_MARGIN; +// int labelDeltaY = ICON_SIZE - labelHeight; int clientWidth; int clientHeight; int maxControlWidth; @@ -322,237 +226,64 @@ static VOID ResizeWindowControls( HWND hDlg, int mode ) InvalidateRect( GetDlgItem(hDlg,IDC_EngineMemo2), NULL, FALSE ); } -static VOID SetDisplayMode( int mode ) -{ - if( windowMode != mode ) { - windowMode = mode; - - ResizeWindowControls( engineOutputDialog, mode ); - } +static int currentPV; +int highTextStart[2], highTextEnd[2]; +extern RECT boardRect; + +VOID +GetMemoLine(HWND hDlg, int x, int y) +{ // [HGM] pv: translate click to PV line, and load it for display + char buf[10000]; + int index, start, end, memo; + POINT pt; + + pt.x = x; pt.y = y; + memo = currentPV ? IDC_EngineMemo2 : IDC_EngineMemo1; + index = SendDlgItemMessage( hDlg, memo, EM_CHARFROMPOS, 0, (LPARAM) &pt ); + GetDlgItemText(hDlg, memo, buf, sizeof(buf)); + if(LoadMultiPV(x, y, buf, index, &start, &end, currentPV)) { + SetCapture(hDlg); + SendMessage( outputField[currentPV][nMemo], EM_SETSEL, (WPARAM)start, (LPARAM)end ); + highTextStart[currentPV] = start; highTextEnd[currentPV] = end; + SetFocus(outputField[currentPV][nMemo]); + } } -static VOID VerifyDisplayMode() +// front end. Actual printing of PV lines into the output field +void InsertIntoMemo( int which, char * text, int where ) { - int mode; - - /* Get proper mode for current game */ - switch( gameMode ) { - case AnalyzeMode: - case AnalyzeFile: - case MachinePlaysWhite: - case MachinePlaysBlack: - case IcsPlayingWhite: - case IcsPlayingBlack: - mode = 0; - break; - case TwoMachinesPlay: - mode = 1; - break; - default: - /* Do not change */ - return; - } + SendMessage( outputField[which][nMemo], EM_SETSEL, where, where ); // [HGM] multivar: choose insertion point - SetDisplayMode( mode ); + SendMessage( outputField[which][nMemo], EM_REPLACESEL, (WPARAM) FALSE, (LPARAM) text ); + if(where < highTextStart[which]) { // [HGM] multiPVdisplay: move highlighting + int len = strlen(text); + highTextStart[which] += len; highTextEnd[which] += len; + SendMessage( outputField[which][nMemo], EM_SETSEL, highTextStart[which], highTextEnd[which] ); + } } -static VOID InsertIntoMemo( HWND hMemo, char * text ) +// front end. Associates an icon with an output field ("control" in Windows jargon). +// [HGM] let it find out the output field from the 'which' number by itself +void SetIcon( int which, int field, int nIcon ) { - SendMessage( hMemo, EM_SETSEL, 0, 0 ); - SendMessage( hMemo, EM_REPLACESEL, (WPARAM) FALSE, (LPARAM) text ); -} - -static VOID SetIcon( HWND hControl, HICON hIcon ) -{ - if( hIcon != NULL ) { - SendMessage( hControl, STM_SETICON, (WPARAM) hIcon, 0 ); + if( nIcon != 0 ) { + SendMessage( outputField[which][field], STM_SETICON, (WPARAM) icons[nIcon], 0 ); } } -static VOID SetEngineColorIcon( HWND hControl, int which ) +// front end wrapper for SetWindowText, taking control number in stead of handle +void DoSetWindowText(int which, int field, char *s_label) { - char color = GetEngineColor(which); - HICON hicon = NULL; - - if( color == ENGINE_COLOR_BLACK ) - hicon = hiColorBlack; - else if( color == ENGINE_COLOR_WHITE ) - hicon = hiColorWhite; - else - hicon = hiColorUnknown; - - SetIcon( hControl, hicon ); + SetWindowText( outputField[which][field], s_label ); } -static SetEngineState( int which, int state, char * state_data ) +void SetEngineOutputTitle(char *title) { - int x_which = 1 - which; - HWND hStateIcon = GetDlgItem( engineOutputDialog, which == 0 ? IDC_StateIcon1 : IDC_StateIcon2 ); - HWND hStateData = GetDlgItem( engineOutputDialog, which == 0 ? IDC_StateData1 : IDC_StateData2 ); - - if( engineState[ which ] != state ) { - engineState[ which ] = state; - - switch( state ) { - case STATE_THINKING: - SetIcon( hStateIcon, hiThinking ); - if( engineState[ x_which ] == STATE_THINKING ) { - SetEngineState( x_which, STATE_IDLE, "" ); - } - break; - case STATE_PONDERING: - SetIcon( hStateIcon, hiPondering ); - break; - case STATE_ANALYZING: - SetIcon( hStateIcon, hiAnalyzing ); - break; - default: - SetIcon( hStateIcon, hiClear ); - break; - } - } - - if( state_data != 0 ) { - SetWindowText( hStateData, state_data ); - } -} - -#define MAX_NAME_LENGTH 32 - -static VOID UpdateControls( EngineOutputData * ed ) -{ - BOOL isPondering = FALSE; - - char s_label[MAX_NAME_LENGTH + 32]; - - char * name = ed->name; - - /* Label */ - if( name == 0 || *name == '\0' ) { - name = "?"; - } - - strncpy( s_label, name, MAX_NAME_LENGTH ); - s_label[ MAX_NAME_LENGTH-1 ] = '\0'; - -#ifdef SHOW_PONDERING - if( IsEnginePondering( ed->which ) ) { - char buf[8]; - - buf[0] = '\0'; - - if( ed->hint != 0 && *ed->hint != '\0' ) { - strncpy( buf, ed->hint, sizeof(buf) ); - buf[sizeof(buf)-1] = '\0'; - } - else if( ed->pv != 0 && *ed->pv != '\0' ) { - char * sep = strchr( ed->pv, ' ' ); - int buflen = sizeof(buf); - - if( sep != NULL ) { - buflen = sep - ed->pv + 1; - if( buflen > sizeof(buf) ) buflen = sizeof(buf); - } - - strncpy( buf, ed->pv, buflen ); - buf[ buflen-1 ] = '\0'; - } - - SetEngineState( ed->which, STATE_PONDERING, buf ); - } - else if( gameMode == TwoMachinesPlay ) { - SetEngineState( ed->which, STATE_THINKING, "" ); - } - else if( gameMode == AnalyzeMode || gameMode == AnalyzeFile ) { - char buf[64]; - int time_secs = ed->time / 100; - int time_mins = time_secs / 60; - - buf[0] = '\0'; - - if( ed->an_move_index != 0 && ed->an_move_count != 0 && *ed->hint != '\0' ) { - char mov[16]; - - strncpy( mov, ed->hint, sizeof(mov) ); - mov[ sizeof(mov)-1 ] = '\0'; - - sprintf( buf, "%d/%d: %s [%02d:%02d:%02d]", ed->an_move_index, ed->an_move_count, mov, time_mins / 60, time_mins % 60, time_secs % 60 ); - } - - SetEngineState( ed->which, STATE_ANALYZING, buf ); - } - else { - SetEngineState( ed->which, STATE_IDLE, "" ); - } -#endif - - SetWindowText( ed->hLabel, s_label ); - - s_label[0] = '\0'; - - if( ed->time > 0 && ed->nodes > 0 ) { - unsigned long nps_100 = ed->nodes / ed->time; - - if( nps_100 < 100000 ) { - sprintf( s_label, "NPS: %lu", nps_100 * 100 ); - } - else { - sprintf( s_label, "NPS: %.1fk", nps_100 / 10.0 ); - } - } - - SetWindowText( ed->hLabelNPS, s_label ); - - /* Memo */ - if( ed->pv != 0 && *ed->pv != '\0' ) { - char s_nodes[24]; - char s_score[16]; - char s_time[24]; - char buf[256]; - int buflen; - int time_secs = ed->time / 100; - int time_cent = ed->time % 100; - - /* Nodes */ - if( ed->nodes < 1000000 ) { - sprintf( s_nodes, "%lu", ed->nodes ); - } - else { - sprintf( s_nodes, "%.1fM", ed->nodes / 1000000.0 ); - } - - /* Score */ - if( ed->score > 0 ) { - sprintf( s_score, "+%.2f", ed->score / 100.0 ); - } - else { - sprintf( s_score, "%.2f", ed->score / 100.0 ); - } - - /* Time */ - sprintf( s_time, "%d:%02d.%02d", time_secs / 60, time_secs % 60, time_cent ); - - /* Put all together... */ - sprintf( buf, "%3d\t%s\t%s\t%s\t", ed->depth, s_score, s_nodes, s_time ); - - /* Add PV */ - buflen = strlen(buf); - - strncpy( buf + buflen, ed->pv, sizeof(buf) - buflen ); - - buf[ sizeof(buf) - 3 ] = '\0'; - - strcat( buf + buflen, "\r\n" ); - - /* Update memo */ - InsertIntoMemo( ed->hMemo, buf ); - } - - /* Colors */ - SetEngineColorIcon( ed->hColorIcon, ed->which ); + SetWindowText( engineOutputDialog, title ); } +// This seems pure front end LRESULT CALLBACK EngineOutputProc( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam ) { static SnapData sd; @@ -562,9 +293,17 @@ LRESULT CALLBACK EngineOutputProc( HWND hDlg, UINT message, WPARAM wParam, LPARA if( engineOutputDialog == NULL ) { engineOutputDialog = hDlg; + Translate(hDlg, DLG_EngineOutput); RestoreWindowPlacement( hDlg, &wpEngineOutput ); /* Restore window placement */ - ResizeWindowControls( hDlg, windowMode ); + ResizeWindowControls( windowMode ); + + SendDlgItemMessage( hDlg, IDC_EngineMemo1, EM_SETEVENTMASK, 0, ENM_MOUSEEVENTS ); + SendDlgItemMessage( hDlg, IDC_EngineMemo2, EM_SETEVENTMASK, 0, ENM_MOUSEEVENTS ); + + /* Set font */ + SendDlgItemMessage( engineOutputDialog, IDC_EngineMemo1, WM_SETFONT, (WPARAM)font[boardSize][MOVEHISTORY_FONT]->hf, MAKELPARAM(TRUE, 0 )); + SendDlgItemMessage( engineOutputDialog, IDC_EngineMemo2, WM_SETFONT, (WPARAM)font[boardSize][MOVEHISTORY_FONT]->hf, MAKELPARAM(TRUE, 0 )); SetEngineState( 0, STATE_IDLE, "" ); SetEngineState( 1, STATE_IDLE, "" ); @@ -588,6 +327,28 @@ LRESULT CALLBACK EngineOutputProc( HWND hDlg, UINT message, WPARAM wParam, LPARA break; + case WM_MOUSEMOVE: + MovePV(LOWORD(lParam) - boardRect.left, HIWORD(lParam) - boardRect.top, boardRect.bottom - boardRect.top); + break; + + case WM_RBUTTONUP: + ReleaseCapture(); + SendMessage( outputField[currentPV][nMemo], EM_SETSEL, 0, 0 ); + highTextStart[currentPV] = highTextEnd[currentPV] = 0; + UnLoadPV(); + break; + + case WM_NOTIFY: + if( wParam == IDC_EngineMemo1 || wParam == IDC_EngineMemo2 ) { + MSGFILTER * lpMF = (MSGFILTER *) lParam; + if( lpMF->msg == WM_RBUTTONDOWN && (lpMF->wParam & (MK_CONTROL)) == 0 ) { + shiftKey = (lpMF->wParam & MK_SHIFT) != 0; // [HGM] remember last shift status + currentPV = (wParam == IDC_EngineMemo2); + GetMemoLine(hDlg, LOWORD(lpMF->lParam), HIWORD(lpMF->lParam)); + } + } + break; + case WM_GETMINMAXINFO: { MINMAXINFO * mmi = (MINMAXINFO *) lParam; @@ -602,7 +363,7 @@ LRESULT CALLBACK EngineOutputProc( HWND hDlg, UINT message, WPARAM wParam, LPARA break; case WM_SIZE: - ResizeWindowControls( hDlg, windowMode ); + ResizeWindowControls( windowMode ); break; case WM_ENTERSIZEMOVE: @@ -621,13 +382,11 @@ LRESULT CALLBACK EngineOutputProc( HWND hDlg, UINT message, WPARAM wParam, LPARA return FALSE; } -VOID EngineOutputPopUp() +// front end +void EngineOutputPopUp() { FARPROC lpProc; - - if( needInit ) { - InitializeEngineOutput(); - } + static int needInit = TRUE; CheckMenuItem(GetMenu(hwndMain), IDM_ShowEngineOutput, MF_CHECKED); @@ -647,11 +406,17 @@ VOID EngineOutputPopUp() FreeProcInstance(lpProc); } + // [HGM] displaced to after creation of dialog, to allow initialization of output fields + if( needInit ) { + InitializeEngineOutput(); + needInit = FALSE; + } + engineOutputDialogUp = TRUE; - ShowThinkingEvent(); // [HGM] thinking: might need to prompt engine for thinking output } -VOID EngineOutputPopDown() +// front end +void EngineOutputPopDown() { CheckMenuItem(GetMenu(hwndMain), IDM_ShowEngineOutput, MF_UNCHECKED); @@ -660,92 +425,22 @@ VOID EngineOutputPopDown() } engineOutputDialogUp = FALSE; - ShowThinkingEvent(); // [HGM] thinking: might need to shut off thinking output } -BOOL EngineOutputIsUp() +// front end. [HGM] Takes handle of output control from table, so only number is passed +void DoClearMemo(int which) { - return engineOutputDialogUp; + SendMessage( outputField[which][nMemo], WM_SETTEXT, 0, (LPARAM) "" ); } -VOID EngineOutputUpdate( FrontEndProgramStats * stats ) +// front end (because only other front-end wants to know) +int EngineOutputIsUp() { - EngineOutputData ed; - BOOL clearMemo = FALSE; - int which; - int depth; - - if( stats == 0 ) { - SetEngineState( 0, STATE_IDLE, "" ); - SetEngineState( 1, STATE_IDLE, "" ); - return; - } - - which = stats->which; - depth = stats->depth; - - if( which < 0 || which > 1 || depth < 0 || stats->time < 0 || stats->pv == 0 ) { - return; - } - - if( engineOutputDialog == NULL ) { - return; - } - - VerifyDisplayMode(); - - ed.which = which; - ed.depth = depth; - ed.nodes = stats->nodes; - ed.score = stats->score; - ed.time = stats->time; - ed.pv = stats->pv; - ed.hint = stats->hint; - ed.an_move_index = stats->an_move_index; - ed.an_move_count = stats->an_move_count; - - /* Get target control */ - if( which == 0 ) { - ed.hColorIcon = GetDlgItem( engineOutputDialog, IDC_Color1 ); - ed.hLabel = GetDlgItem( engineOutputDialog, IDC_EngineLabel1 ); - ed.hStateIcon = GetDlgItem( engineOutputDialog, IDC_StateIcon1 ); - ed.hStateData = GetDlgItem( engineOutputDialog, IDC_StateData1 ); - ed.hLabelNPS = GetDlgItem( engineOutputDialog, IDC_Engine1_NPS ); - ed.hMemo = GetDlgItem( engineOutputDialog, IDC_EngineMemo1 ); - ed.name = first.tidy; - } - else { - ed.hColorIcon = GetDlgItem( engineOutputDialog, IDC_Color2 ); - ed.hLabel = GetDlgItem( engineOutputDialog, IDC_EngineLabel2 ); - ed.hStateIcon = GetDlgItem( engineOutputDialog, IDC_StateIcon2 ); - ed.hStateData = GetDlgItem( engineOutputDialog, IDC_StateData2 ); - ed.hLabelNPS = GetDlgItem( engineOutputDialog, IDC_Engine2_NPS ); - ed.hMemo = GetDlgItem( engineOutputDialog, IDC_EngineMemo2 ); - ed.name = second.tidy; - } - - /* Clear memo if needed */ - if( lastDepth[which] > depth || (lastDepth[which] == depth && depth <= 1) ) { - clearMemo = TRUE; - } - - if( lastForwardMostMove[which] != forwardMostMove ) { - clearMemo = TRUE; - } - - if( clearMemo ) { - SendMessage( ed.hMemo, WM_SETTEXT, 0, (LPARAM) "" ); - } - - /* Update */ - lastDepth[which] = depth; - lastForwardMostMove[which] = forwardMostMove; - - if( ed.pv != 0 && ed.pv[0] == ' ' ) { - if( strncmp( ed.pv, " no PV", 6 ) == 0 ) { /* Hack on hack! :-O */ - ed.pv = ""; - } - } + return engineOutputDialogUp; +} - UpdateControls( &ed ); +// front end, to give back-end access to engineOutputDialog +int EngineOutputDialogExists() +{ + return engineOutputDialog != NULL; }