Fix multi-leg promotions
[xboard.git] / evalgraph.c
index b5c18d0..1a8bd07 100644 (file)
@@ -5,6 +5,9 @@
  *
  * Copyright 2005 Alessandro Scotti
  *
+ * Enhancments Copyright 2009, 2010, 2011, 2012, 2013, 2014, 2015,
+ * 2016 Free Software Foundation, Inc.
+ *
  * ------------------------------------------------------------------------
  *
  * GNU XBoard is free software: you can redistribute it and/or modify
@@ -51,6 +54,7 @@ int currFirst = 0;
 int currLast = 0;
 int currCurrent = -1;
 int range = 1;
+int differentialView;
 
 int nWidthPB = 0;
 int nHeightPB = 0;
@@ -60,14 +64,16 @@ int MarginW = 4;
 int MarginH = 4;
 
 // back-end
-static void DrawLine( int x1, int y1, int x2, int y2, int penType )
+static void
+DrawLine (int x1, int y1, int x2, int y2, int penType)
 {
     DrawSegment( x1, y1, NULL, NULL, PEN_NONE );
     DrawSegment( x2, y2, NULL, NULL, penType );
 }
 
 // back-end
-static void DrawLineEx( int x1, int y1, int x2, int y2, int penType )
+static void
+DrawLineEx (int x1, int y1, int x2, int y2, int penType)
 {
     int savX, savY;
     DrawSegment( x1, y1, &savX, &savY, PEN_NONE );
@@ -76,15 +82,35 @@ static void DrawLineEx( int x1, int y1, int x2, int y2, int penType )
 }
 
 // back-end
-static int GetPvScore( int index )
+static int
+GetPvScore (int index)
 {
     int score = currPvInfo[ index ].score;
 
+    if(differentialView) score = index < currLast-1 ? -currPvInfo[ index+1 ].score - score : 0;
     if( index & 1 ) score = -score; /* Flip score for black */
 
     return score;
 }
 
+char *
+MakeEvalTitle (char *title)
+{
+    int score, depth;
+    static char buf[MSG_SIZ];
+
+    if( currCurrent <0 ) return title; // currCurrent = -1 crashed WB on start without ini file!
+    score = currPvInfo[ currCurrent ].score;
+    depth = currPvInfo[ currCurrent ].depth;
+
+    if( depth <=0 ) return title;
+    if( currCurrent & 1 ) score = -score; /* Flip score for black */
+    snprintf(buf, MSG_SIZ, "%s {%d: %s%.2f/%-2d %d}", title, currCurrent/2+1,
+                               score>0 ? "+" : " ", score/100., depth, (currPvInfo[currCurrent].time+50)/100);
+
+    return buf;
+}
+
 // back-end
 /*
     For a centipawn value, this function returns the height of the corresponding
@@ -92,17 +118,21 @@ static int GetPvScore( int index )
 
     Note: height can be negative!
 */
-static int GetValueY( int value )
+static int
+GetValueY (int value)
 {
     if( value < -range*700 ) value = -range*700;
     if( value > +range*700 ) value = +range*700;
-
-    return (nHeightPB / 2) - (int)(value * (nHeightPB - 2*MarginH) / (1400.*range));
+    if(value > 100*range)  value += (appData.zoom - 1)*100*range; else
+    if(value < -100*range) value -= (appData.zoom - 1)*100*range; else
+       value *= appData.zoom;
+    return (nHeightPB / 2) - (int)(value * (nHeightPB - 2*MarginH) / ((1200. + 200.*appData.zoom)*range));
 }
 
 // the brush selection is made part of the DrawLine, by passing a style argument
 // the wrapper for doing the text output makes this back-end
-static void DrawAxisSegmentHoriz( int value, Boolean drawValue )
+static void
+DrawAxisSegmentHoriz (int value, Boolean drawValue)
 {
     int y = GetValueY( range*value*100 );
 
@@ -121,20 +151,17 @@ static void DrawAxisSegmentHoriz( int value, Boolean drawValue )
 
 // The DrawLines again must select their own brush.
 // the initial brush selection is useless? BkMode needed for dotted line and text
-static void DrawAxis()
+static void
+DrawAxis ()
 {
-    int cy = nHeightPB / 2;
-    
-//    SelectObject( hdcPB, GetStockObject(NULL_BRUSH) );
-
-//    SetBkMode( hdcPB, TRANSPARENT );
+    int cy = nHeightPB / 2, space = nHeightPB/(6 + appData.zoom);
 
     DrawAxisSegmentHoriz( +5, TRUE );
-    DrawAxisSegmentHoriz( +3, FALSE );
-    DrawAxisSegmentHoriz( +1, FALSE );
+    DrawAxisSegmentHoriz( +3, space >= 20 );
+    DrawAxisSegmentHoriz( +1, space >= 20 && space*appData.zoom >= 40 );
     DrawAxisSegmentHoriz(  0, TRUE );
-    DrawAxisSegmentHoriz( -1, FALSE );
-    DrawAxisSegmentHoriz( -3, FALSE );
+    DrawAxisSegmentHoriz( -1, space >= 20 && space*appData.zoom >= 40 );
+    DrawAxisSegmentHoriz( -3, space >= 20 );
     DrawAxisSegmentHoriz( -5, TRUE );
 
     DrawLine( MarginX + MarginW, cy, nWidthPB - MarginW, cy, PEN_BLACK ); // x-axis
@@ -142,11 +169,12 @@ static void DrawAxis()
 }
 
 // back-end
-static void DrawHistogram( int x, int y, int width, int value, int side )
+static void
+DrawHistogram (int x, int y, int width, int value, int side)
 {
     int left, top, right, bottom;
 
-    if( value > -25 && value < +25 ) return;
+    if( value > -appData.evalThreshold*range && value < +appData.evalThreshold*range ) return;
 
     left = x;
     right = left + width + 1;
@@ -171,7 +199,8 @@ static void DrawHistogram( int x, int y, int width, int value, int side )
 }
 
 // back-end
-static void DrawSeparator( int index, int x )
+static void
+DrawSeparator (int index, int x)
 {
     if( index > 0 ) {
         if( index == currCurrent ) {
@@ -185,7 +214,8 @@ static void DrawSeparator( int index, int x )
 
 // made back-end by replacing MoveToEx and LineTo by DrawSegment
 /* Actually draw histogram as a diagram, cause there's too much data */
-static void DrawHistogramAsDiagram( int cy, int paint_width, int hist_count )
+static void
+DrawHistogramAsDiagram (int cy, int paint_width, int hist_count)
 {
     double step;
     int i;
@@ -218,7 +248,7 @@ static void DrawHistogramAsDiagram( int cy, int paint_width, int hist_count )
 
             /* Extend line up to current point */
             if( currPvInfo[index].depth > 0 ) {
-                DrawSegment((int) x, GetValueY( GetPvScore(index) ), NULL, NULL, PEN_BOLD + side );
+             DrawSegment((int) x, GetValueY( GetPvScore(index) ), NULL, NULL, (side==0 ? PEN_BOLDWHITE: PEN_BOLDBLACK) );
             }
 
             index += 2;
@@ -227,7 +257,8 @@ static void DrawHistogramAsDiagram( int cy, int paint_width, int hist_count )
 }
 
 // back-end, delete pen selection
-static void DrawHistogramFull( int cy, int hist_width, int hist_count )
+static void
+DrawHistogramFull (int cy, int hist_width, int hist_count)
 {
     int i;
 
@@ -255,7 +286,8 @@ typedef struct {
 } VisualizationData;
 
 // back-end
-static Boolean InitVisualization( VisualizationData * vd )
+static Boolean
+InitVisualization (VisualizationData *vd)
 {
     Boolean result = FALSE;
 
@@ -279,22 +311,35 @@ static Boolean InitVisualization( VisualizationData * vd )
 }
 
 // back-end
-static void DrawHistograms()
+static void
+DrawHistograms ()
 {
     VisualizationData vd;
+    int i; double step = 1;
 
     if( InitVisualization( &vd ) ) {
         if( vd.hist_width < MIN_HIST_WIDTH ) {
             DrawHistogramAsDiagram( vd.cy, vd.paint_width, vd.hist_count );
+            step = 0.5*vd.paint_width / (((vd.hist_count | 7) + 1)/2 + 1.);
         }
         else {
-            DrawHistogramFull( vd.cy, vd.hist_width, vd.hist_count );
+            DrawHistogramFull( vd.cy, step = vd.hist_width, vd.hist_count );
         }
     }
+    if(!differentialView) return;
+    differentialView = 0;
+    DrawSegment( MarginX + MarginW, vd.cy, NULL, NULL, PEN_NONE );
+    for( i=0; i<vd.hist_count; i++ ) {
+        int index = currFirst + i;
+        int x = MarginX + MarginW + index * step + step/2;
+        DrawSegment((int) x, GetValueY( GetPvScore(index) ), NULL, NULL, PEN_ANY );
+    }
+    differentialView = 1;
 }
 
 // back-end
-int GetMoveIndexFromPoint( int x, int y )
+int
+GetMoveIndexFromPoint (int x, int y)
 {
     int result = -1;
     int start_x = MarginX + MarginW;
@@ -327,13 +372,13 @@ int GetMoveIndexFromPoint( int x, int y )
 }
 
 // init and display part split of so they can be moved to front end
-void PaintEvalGraph( void )
+void
+PaintEvalGraph (void)
 {
     VariantClass v = gameInfo.variant;
-    range = (gameInfo.holdingsWidth && v != VariantSuper && v != VariantGreat) ? 2 : 1; // [HGM] double range in drop games
+    range = (gameInfo.holdingsWidth && v != VariantSuper && v != VariantGreat && v != VariantSChess) ? 2 : 1; // [HGM] double range in drop games
     /* Draw */
     DrawRectangle(0, 0, nWidthPB, nHeightPB, 2, FILLED);
     DrawAxis();
     DrawHistograms();
 }
-