Example #1
0
void
EngineOutputPopUp ()
{
    static int  needInit = TRUE;
    static char *title = N_("Engine output");

    if (GenericPopUp(engoutOptions, _(title), EngOutDlg, BoardWindow, NONMODAL, appData.topLevel)) {
	if(engoutOptions[STRIDE-1].type != Break)
	    DisplayFatalError(_("Mismatch of STRIDE in nengineoutput.c\nChange and recompile!"), 0, 2);
	AddHandler(&engoutOptions[MEMO], EngOutDlg, 6);
	AddHandler(&engoutOptions[MEMO+STRIDE], EngOutDlg, 6);
	if( needInit ) {
	    InitEngineOutput(&engoutOptions[0], &engoutOptions[MEMO]); // make icon bitmaps
	    needInit = FALSE;
	}
        SetEngineColorIcon( 0 );
        SetEngineColorIcon( 1 );
        SetEngineState( 0, STATE_IDLE, "" );
        SetEngineState( 1, STATE_IDLE, "" );
    } else {
	SetIconName(EngOutDlg, _(title));
	SetDialogTitle(EngOutDlg, _(title));
    }

    MarkMenu("View.EngineOutput", EngOutDlg);

    ShowThinkingEvent(); // [HGM] thinking: might need to prompt engine for thinking output
}
void CTcpSymbianEngine::ResetL(enum TEchoEngineState aDuring)
{
   DBG("ResetL(%d)", aDuring);
   SetEngineState(aDuring);   //temporary state
   iEchoSocket.Close();       //close the socket..
   CloseLinkLayer();          //..and the link layer
   SetEngineState(EComplete); //ready for new connection attempts
}
void CTcpSymbianEngine::ResetL(enum TEchoEngineState aDuring, 
                         enum isab::Module::ConnectionNotifyReason aReason)
{
   SetEngineState(aDuring);
   iConsole.ConnectionNotify(isab::Module::DISCONNECTING, aReason);
   ResetL(aDuring);
}
void CTcpSymbianEngine::StartLookupL()
{
   DBG("StartLookupL");
   SetEngineState(ELookingUp);
   // Initiate DNS
   if(KErrNone == 
#if defined NAV2_CLIENT_SERIES60_V3  && !defined __WINS__ && !defined __WINSCW__
      iResolver.Open(iSocketServ, KAfInet,
                     KProtocolInetUdp, iConnection)
#else
      iResolver.Open(iSocketServ, KAfInet, KProtocolInetUdp)
#endif
      ){

      if(KErrNone == iDNSCache.CacheHostLookup(*iHostName, iNameEntry, iPort)){
         DBG("Host found in cache");
         CompleteSelf(KErrNone);
      } else {
         DBG("Host not found in cache, looking up in DNS");
         // DNS request for name resolution
         iResolver.GetByName(*iHostName, iNameEntry, iStatus);
         SetActive();
      }
      // Request time out
      iTimer->After(iTimeOut);
      //signal state
      iConsole.ConnectionNotify(isab::Module::CONNECTING,
                                 isab::Module::REQUESTED);
      DBG("Starting asynchronous name lookup");
   } else {
      WARN("Lookup failed");
      ResetL(ELookUpFailed, isab::Module::LOOKUP_FAILED);
   }
}
Example #5
0
// back end, due to front-end wrapper for SetWindowText, and new SetIcon arguments
void
SetEngineState (int which, enum ENGINE_STATE state, char * state_data)
{
    int x_which = 1 - which;

    if( engineState[ which ] != state ) {
        engineState[ which ] = state;

        switch( state ) {
        case STATE_THINKING:
            SetIcon( which, nStateIcon, nThinking );
            if( engineState[ x_which ] == STATE_THINKING ) {
                SetEngineState( x_which, STATE_IDLE, "" );
            }
            break;
        case STATE_PONDERING:
            SetIcon( which, nStateIcon, nPondering );
            break;
        case STATE_ANALYZING:
            SetIcon( which, nStateIcon, nAnalyzing );
            break;
        default:
            SetIcon( which, nStateIcon, nClear );
            break;
        }
    }

    if( state_data != 0 ) {
        DoSetWindowText( which, nStateData, state_data );
    }
}
Example #6
0
void
EngineOutputPopUp ()
{
    Arg args[16];
    int j;
    Widget edit;
    static int  needInit = TRUE;
    static char *title = N_("Engine output"), *text = N_("This feature is experimental");

    if (engineOutputShell == NULL) {
	engineOutputShell =
	  EngineOutputCreate(_(title), _(text));
	XtRealizeWidget(engineOutputShell);
	CatchDeleteWindow(engineOutputShell, "EngineOutputPopDown");
	if( needInit ) {
	    InitializeEngineOutput();
	    needInit = FALSE;
	}
        SetEngineColorIcon( 0 );
        SetEngineColorIcon( 1 );
        SetEngineState( 0, STATE_IDLE, "" );
        SetEngineState( 1, STATE_IDLE, "" );
    } else {
	edit = XtNameToWidget(engineOutputShell, "*form.text");
	j = 0;
	XtSetArg(args[j], XtNstring, text); j++;
	XtSetValues(edit, args, j);
	j = 0;
	XtSetArg(args[j], XtNiconName, (XtArgVal) _(title));   j++;
	XtSetArg(args[j], XtNtitle, (XtArgVal) _(title));      j++;
	XtSetValues(engineOutputShell, args, j);
    }

    XtPopup(engineOutputShell, XtGrabNone);
    XSync(xDisplay, False);

    j=0;
    XtSetArg(args[j], XtNleftBitmap, xMarkPixmap); j++;
    XtSetValues(XtNameToWidget(menuBarWidget, "menuView.Show Engine Output"),
		args, j);

    engineOutputDialogUp = True;
    ShowThinkingEvent(); // [HGM] thinking: might need to prompt engine for thinking output
}
void CTcpSymbianEngine::Stop(enum TEchoEngineState aState)
{
   enum TEchoEngineState state = EngineState();
   DBG("Stop, Enginestate: %d, aState: %d", state, aState);
   if(state != EComplete){
      iConsole.BlockEvents();
   }
   switch (state){
   case EConnected:
      // Stop live connection
      iEchoRead->Cancel();
      iEchoWrite->Cancel();
      SetEngineState(aState);
      iEchoSocket.Shutdown(RSocket::EImmediate, iStatus);
      SetActive();
      iTimer->After(iTimeOut);
      break;
   case EConnecting:
   case ELookingUp:
   case ELinking:
      // if request to CTcpSymbianEngine, then stop it
      Cancel();
      break;
   case ESwitching:
      SetEngineState(EClosing);
      break;
   case EClosing:
      ///already closing. 
      break;
   case EComplete:
      //all set.
      if(!IsActive()){
         DBG("Signal OperationComplete");
         iConsole.OperationComplete();
         DBG("Signaled OperationComplete");
      }
      break;
   default:
      ERR("PANIC KEchoEngine EBadEngineStopState (%d)", EBadEngineStopState);
      User::Panic(KEchoEngine, EBadEngineStopState);
      break;
   }
}
void CTcpSymbianEngine::OpenLinkLayerL()
{
   DBG("OpenLinkLayerL");
   // Select IAP
   SetEngineState(ELinking);
#if defined RCONNECTION || defined RAGENT
   if(iIAP == -1){
      iConsole.ConnectionNotify(isab::Module::WAITING_FOR_USER,
                                 isab::Module::REQUESTED);
   }
#endif

#ifdef RCONNECTION
   OpenLinkLayerConnectionL(); //setactive here
#elif defined RAGENT
   OpenLinkLayerAgentL();
#else
   OpenFakeLinkLayerL();
#endif
   SetEngineState(ELinking);
   // Request time out
   iTimer->After(iTimeOut);
}
void CTcpSymbianEngine::Connect(TUint32 aAddr, TUint aPort)
   // Connect to an Echo Socket by IP address	
{
   DBG("Connect(0x%"PRIx32", %u)", aAddr, aPort);
   iAddress.SetPort(aPort);
   iAddress.SetAddress(aAddr);

   iEchoSocket.Connect(iAddress, iStatus);
   SetEngineState(EConnecting);
   //beware deadlocks! notify outside critical regions. 
   iConsole.ConnectionNotify(isab::Module::CONNECTING,
                              isab::Module::REQUESTED);

   SetActive();
   iTimer->After(iTimeOut);
}
void CVehicleEntity::Reset()
{
	// Check vehicle iv ptr
	if(!m_pVehicle)
		return;

	// Turn the engine off
	SetEngineState(false);
	
	// Reset Indicators
	SetIndicatorState(false,false,false,false);

	// Disable damage
	//m_pVehicle->SetCarCanBeDamaged(false);
	//m_pVehicle->SetCanBeVisiblyDamaged(false);

}
void CTcpSymbianEngine::RunL()
{
   DBG("RunL, EngineState: %d, iStatus: %d", EngineState(), iStatus.Int());
   iTimer->Cancel(); // Cancel TimeOut timer before handling completion
   switch(EngineState()){
   case EConnecting:
      // IP connection request
      if (iStatus == KErrNone){
         DBG("Connection completed Ok");
         // Connection completed sucessfully   
         iConsole.ConnectionNotify(isab::Module::CONNECTED,
                                    isab::Module::REQUESTED);
         SetEngineState(EConnected);
         Read(); //Start CTcpSymbianRead Active object
      } else {
         WARN("Unable to connect, removing host from cache.");
         iDNSCache.Remove(*iHostName);
         if (iStatus == KErrCouldNotConnect){
            ResetL(EConnectFailed, isab::Module::NO_RESPONSE);
         } else if (iStatus == KErrTimedOut) {
            ResetL(ETimedOut, isab::Module::NO_RESPONSE);
         } else{
            WARN("EConnectFailed, INTERNAL_ERROR");
            ResetL(EConnectFailed, isab::Module::INTERNAL_ERROR);
            //XXX handle the different cases
         }
      }
      break;
   case ELookingUp:
      iResolver.Close();
      if (iStatus == KErrNone) {
         DBG("Name lookup ok");
         // DNS look up successful
         // Extract domain name and IP address from name record
         class TInetAddr addr = TInetAddr::Cast(iNameEntry().iAddr);
         //cache the ip for later.
         TInt cacheStat = iDNSCache.CacheHost(*iHostName, addr.Address());
         DBG("Host cached with result %d", cacheStat);
         cacheStat = cacheStat;
         // And connect to the IP address
         Connect(addr.Address(), iPort); //setactive here
      } else { //includes KErrTimedOut
         WARN("Lookup failed");
         ResetL(ELookUpFailed, isab::Module::LOOKUP_FAILED);
      }
      break;
   case ELinking:
      if(iStatus == KErrNone){
         DBG("Link layer setup ok");
         OpenSocketL();  //cannot open socket until here. We need RConnection.
         StartLookupL(); //setactive here
      } else { //includes KErrCanceled and KErrTimedOut
         WARN("Link layer setup failed");
         ResetL(ELinkFailed, isab::Module::TRANSPORT_FAILED);
      }
      break;
   case EBroken:
      DBG("Broken");
      ResetL( EngineState(), isab::Module::CHANNEL_FAILED );
      break;
   case EClosing:
      if(iStatus == KErrNone){
         DBG("Closing ok");
         ResetL(EComplete, isab::Module::REQUESTED);
      } else if(iStatus == KErrTimedOut){
         ResetL(ETimedOut);
      } else {
         ResetL(EngineState());
         //XXX ???
      }
      break;
   case ESwitching:
      if(iStatus == KErrNone){
         //the connection has been closed, start a new connection
         //using the values in iHostName, iPort, and iIAP.
         SetEngineState(EComplete);
         ConnectL();
      } else if(iStatus == KErrTimedOut){
         ResetL(ETimedOut);
      } else {
         ResetL(EngineState());
      }
      break;
   case EClosed:
      DBG("Closed");
      ResetL( EngineState(), isab::Module::BY_PEER );
      break;
   default:
      ERR("PANIC KEchoEngine EBadEngineState (%d)", TInt(EBadEngineState));
      User::Panic(KEchoEngine, EBadEngineState);
      break;
   };
   if(!IsActive()){
      DBG("Signal OperationComplete");
      iConsole.OperationComplete();
      DBG("Signaled OperationComplete");
   }
}
Example #12
0
// This seems pure front end
LRESULT CALLBACK EngineOutputProc( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam )
{
    static SnapData sd;

    switch (message) {
    case WM_INITDIALOG:
        if( engineOutputDialog == NULL ) {
            engineOutputDialog = hDlg;

            Translate(hDlg, DLG_EngineOutput);
            RestoreWindowPlacement( hDlg, &wpEngineOutput ); /* Restore window placement */

            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, "" );
        }

        return FALSE;

    case WM_COMMAND:
        switch (LOWORD(wParam)) {
        case IDOK:
          EndDialog(hDlg, TRUE);
          return TRUE;

        case IDCANCEL:
          EndDialog(hDlg, FALSE);
          return TRUE;

        default:
          break;
        }

        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 | MK_SHIFT)) == 0 ) {
                currentPV = (wParam == IDC_EngineMemo2);
                GetMemoLine(hDlg, LOWORD(lpMF->lParam), HIWORD(lpMF->lParam));
            }
        }
        break;

    case WM_GETMINMAXINFO:
        {
            MINMAXINFO * mmi = (MINMAXINFO *) lParam;
        
            mmi->ptMinTrackSize.x = 100;
            mmi->ptMinTrackSize.y = 160;
        }
        break;

    case WM_CLOSE:
        EngineOutputPopDown();
        break;

    case WM_SIZE:
        ResizeWindowControls( windowMode );
        break;

    case WM_ENTERSIZEMOVE:
        return OnEnterSizeMove( &sd, hDlg, wParam, lParam );

    case WM_SIZING:
        return OnSizing( &sd, hDlg, wParam, lParam );

    case WM_MOVING:
        return OnMoving( &sd, hDlg, wParam, lParam );

    case WM_EXITSIZEMOVE:
        return OnExitSizeMove( &sd, hDlg, wParam, lParam );
    }

    return FALSE;
}
bool CVehicleEntity::Create()
{
	if (!m_pModelInfo)
		return false;

	// Is the vehicle already spawned?
	if(IsSpawned())
		return false;

	m_pModelInfo->AddReference(true);

	EFLC::IVehicle * pVehicle = pIVehicleFactory->Create(m_pModelInfo->GetIndex(), 1, 0, 0);
	if (pVehicle)
	{
		pVehicle->Function76(0);
		//pVehicle->m_byteFlags1 |= 4u;
		//pVehicle->m_dwFlags1 |= 8u; // set fixed wait for collision/

		CWorld__AddEntity(pVehicle, false);
		CVehicleModelInfo__AddReference(m_pModelInfo->GetModelInfo());
		// we dont want to turn on the engine
		// CVehicle__TurnEngineOn(pVehicle, true);
		pVehicle->m_byteFlags10 |= 8u;

		// This maybe cause pool overflow if much vehicles are created and destroyed [NEED TEST]
		// If this cause overflow try to delete the create physics before call or disable the call in VehicleFactory::Create
		// Using this above *(WORD*) (g_pCore->GetBase() + 0x4B48D5) = 0x9090; before call to vehiclefactory [TESTED => crash]
		// Can someone confirm if this cause pool overflow or not
		if (*(DWORD*) pVehicle != COffsets::VAR_CBoat__VFTable) // Otherwise client crash if boat is on ground (not in water)
		{
			pVehicle->CreatePhysics();
			pVehicle->ProcessInput();
		}

		m_pModelInfo->RemoveReference();

		m_pVehicle = new EFLC::CVehicle(pVehicle);

		//set the vehicle's color
		SetColors(m_dwColor[0], m_dwColor[1], m_dwColor[2], m_dwColor[3], m_dwColor[4]);

		//fix: no more random components
		for (int i = 0; i < 9; ++i)
			SetComponentState(i, false);

		// Mark as spawned
		m_bSpawned = true;

		// Reset the vehicle
		//Reset();

		SetPosition(m_vecSpawnPosition);
		SetRotation(m_vecRotation);
		SetEngineState(GetEngineState());
		m_pVehicle->SetHeadlights(GetLightsState());
		if (GetSirenState()) SetSirenState(true);
		if (GetTaxiLightsState()) SetTaxiLightsState(true);

		CLogFile::Printf("Created vehicle! (Id: %d, Handle: %X)", m_vehicleId, g_pCore->GetGame()->GetPools()->GetVehiclePool()->HandleOf(pVehicle));
		return true;
	}
	else
	{
		CLogFile::Printf("Created vehicle failed!");
		return false;
	}
}
Example #14
0
// pure back end, now SetWindowText is called via wrapper DoSetWindowText
static void
UpdateControls (EngineOutputData *ed)
{
//    int isPondering = FALSE;

    char s_label[MAX_NAME_LENGTH + 32];
    int h;
    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
	  || (gameMode == IcsObserving && appData.icsEngineAnalyze)) { // [HGM] ICS-analyze
        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';

            snprintf( buf, sizeof(buf)/sizeof(buf[0]), "[%d] %d/%d: %s [%02d:%02d:%02d]", ed->depth, 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

    DoSetWindowText( ed->which, nLabel, 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 ) {
	  snprintf( s_label, sizeof(s_label)/sizeof(s_label[0]), "%s: %lu", _("NPS"), nps_100 * 100 );
        }
        else {
	  snprintf( s_label, sizeof(s_label)/sizeof(s_label[0]), "%s: %.1fk", _("NPS"), nps_100 / 10.0 );
        }
    }

    DoSetWindowText( ed->which, nLabelNPS, 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 ) {
            snprintf( s_nodes, sizeof(s_nodes)/sizeof(s_nodes[0]), u64Display, ed->nodes );
        }
        else {
            snprintf( s_nodes, sizeof(s_nodes)/sizeof(s_nodes[0]), "%.1fM", u64ToDouble(ed->nodes) / 1000000.0 );
        }

        /* Score */
        h = ((gameMode == AnalyzeMode && appData.whitePOV || appData.scoreWhite) && !WhiteOnMove(currentMove) ? -1 : 1) * ed->score;
        if( h > 0 ) {
	  snprintf( s_score, sizeof(s_score)/sizeof(s_score[0]), "+%.2f", h / 100.0 );
        }
        else {
	  snprintf( s_score, sizeof(s_score)/sizeof(s_score[0]), "%.2f", h / 100.0 );
        }

        /* Time */
        snprintf( s_time, sizeof(s_time)/sizeof(s_time[0]), "%d:%02d.%02d", time_secs / 60, time_secs % 60, time_cent );

        /* Put all together... */
	if(ed->nodes == 0 && ed->score == 0 && ed->time == 0)
	  snprintf( buf, sizeof(buf)/sizeof(buf[0]), "%3d\t", ed->depth );
	else
	  snprintf( buf, sizeof(buf)/sizeof(buf[0]), "%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->which, buf, InsertionPoint(strlen(buf), ed) );
        strncpy(lastLine[ed->which], buf, MSG_SIZ);
    }

    /* Colors */
    SetEngineColorIcon( ed->which );
}
Example #15
0
// back end, now the front-end wrapper ClearMemo is used, and ed no longer contains handles.
void
SetProgramStats (FrontEndProgramStats * stats) // now directly called by back-end
{
    EngineOutputData ed;
    int clearMemo = FALSE;
    int which, depth, multi;
    ChessMove moveType;
    int ff, ft, rf, rt;
    char pc;

    if( stats == 0 ) {
        SetEngineState( 0, STATE_IDLE, "" );
        SetEngineState( 1, STATE_IDLE, "" );
        return;
    }

    if(gameMode == IcsObserving && !appData.icsEngineAnalyze)
	return; // [HGM] kibitz: shut up engine if we are observing an ICS game

    which = stats->which;
    depth = stats->depth;

    if( which < 0 || which > 1 || depth < 0 || stats->time < 0 || stats->pv == 0 ) {
        return;
    }

    if( !EngineOutputDialogExists() ) {
        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. [HGM] this is moved to front end, which get them from a table */
    if( which == 0 ) {
        ed.name = first.tidy;
    }
    else {
        ed.name = second.tidy;
    }

    if( ed.pv != 0 && ed.pv[0] == ' ' ) {
        if( strncmp( ed.pv, " no PV", 6 ) == 0 ) { /* Hack on hack! :-O */
            ed.pv = "";
        }
    }

    /* Clear memo if needed */
    if( lastDepth[which] > depth || (lastDepth[which] == depth && depth <= 1 && ed.pv[0]) ) { // no reason to clear if we won't add line
        clearMemo = TRUE;
    }

    if( lastForwardMostMove[which] != forwardMostMove ) {
        clearMemo = TRUE;
    }

    if( clearMemo ) {
        DoClearMemo(which); nrVariations[which] = 0;
        header[which][0] = NULLCHAR;
        if(gameMode == AnalyzeMode) {
          ChessProgramState *cps = (which ? &second : &first);
          if((multi = MultiPV(cps)) >= 0) {
            snprintf(header[which], MSG_SIZ, "\t%s viewpoint\t\tfewer / Multi-PV setting = %d / more\n",
                                       appData.whitePOV || appData.scoreWhite ? "white" : "mover", cps->option[multi].value);
	  }
          if(!which) snprintf(header[which]+strlen(header[which]), MSG_SIZ-strlen(header[which]), "%s", exclusionHeader);
          InsertIntoMemo( which, header[which], 0);
        } else
        if(appData.ponderNextMove && lastLine[which][0]) {
            InsertIntoMemo( which, lastLine[which], 0 );
            InsertIntoMemo( which, "\n", 0 );
        }
    }

    if(ed.pv && ed.pv[0] && ParseOneMove(ed.pv, currentMove, &moveType, &ff, &rf, &ft, &rt, &pc))
	ed.moveKey = (ff<<24 | rf << 16 | ft << 8 | rt) ^ pc*87161;
    else ed.moveKey = ed.nodes; // kludge to get unique key unlikely to match any move

    /* Update */
    lastDepth[which] = depth == 1 && ed.nodes == 0 ? 0 : depth; // [HGM] info-line kudge
    lastForwardMostMove[which] = forwardMostMove;

    UpdateControls( &ed );
}