home *** CD-ROM | disk | FTP | other *** search
/ Collection of Hack-Phreak Scene Programs / cleanhpvac.zip / cleanhpvac / ARASAN_S.ZIP / DISPLAY.CPP < prev    next >
C/C++ Source or Header  |  1994-08-05  |  14KB  |  481 lines

  1. // Copyright 1994 by Jon Dart.  All Rights Reserved.
  2.  
  3. #include "display.h"
  4. #include "square.h"
  5. #include "constant.h"
  6. #include <wpwin.h>
  7. #include <string.h>
  8. #include <stdio.h>
  9.  
  10. static WPBitmap *pawn_bitmap = NULL;
  11. static WPBitmap *pawn_outline = NULL;
  12. static WPBitmap *knight_bitmap = NULL;
  13. static WPBitmap *knight_outline = NULL;
  14. static WPBitmap *bishop_bitmap = NULL;
  15. static WPBitmap *bishop_outline = NULL;
  16. static WPBitmap *rook_bitmap = NULL;
  17. static WPBitmap *rook_outline = NULL;
  18. static WPBitmap *queen_bitmap = NULL;
  19. static WPBitmap *queen_outline = NULL;
  20. static WPBitmap *king_bitmap = NULL;
  21. static WPBitmap *king_outline = NULL;
  22.  
  23. #define DARK_SQUARE_COLOR     RGB(0,0x80,0)
  24. #define LIGHT_SQUARE_COLOR     RGB(0,0xFF,0)
  25. #define STATUS_AREA_WIDTH     80
  26. #define TEXT_OFFSET        75 /* from right edge */
  27. #define TIME_Y             80
  28. #define MOVE_Y             170
  29. #define PLY_Y             210
  30.  
  31. int Display::spacing = 0;
  32.  
  33. Display::Display( WPWin *pWin, const WPRect &initial_size )
  34. : turned(False)
  35. {
  36.      TEXTMETRIC my_tm;
  37.      WPWinDC dc = pWin;
  38.      GetTextMetrics(dc(),&my_tm);
  39.      char_width = my_tm.tmAveCharWidth;
  40.      max_char_width = my_tm.tmMaxCharWidth;
  41.      char_height = my_tm.tmHeight;
  42.      spacing = my_tm.tmHeight + my_tm.tmExternalLeading;
  43.      vertical_border_width = char_width + 6;
  44.      horiz_border_height = char_height + 4;
  45.  
  46.      set_size((WPRect)initial_size);
  47.      if (pawn_bitmap)
  48.         return;
  49.      pawn_bitmap = new WPBitmap("PAWN_BITMAP");
  50.      pawn_outline = new WPBitmap("PAWN_OUTLINE");
  51.      knight_bitmap = new WPBitmap("KNIGHT_BITMAP");
  52.      knight_outline = new WPBitmap("KNIGHT_OUTLINE");
  53.      bishop_bitmap = new WPBitmap("BISHOP_BITMAP");
  54.      bishop_outline = new WPBitmap("BISHOP_OUTLINE");
  55.      rook_bitmap = new WPBitmap("ROOK_BITMAP");
  56.      rook_outline = new WPBitmap("ROOK_OUTLINE");
  57.      queen_bitmap = new WPBitmap("QUEEN_BITMAP");
  58.      queen_outline = new WPBitmap("QUEEN_OUTLINE");
  59.      king_bitmap = new WPBitmap("KING_BITMAP");
  60.      king_outline = new WPBitmap("KING_OUTLINE");
  61.      
  62. }
  63.  
  64. Display::~Display()
  65. {
  66.      delete king_bitmap;
  67.      delete king_outline;
  68.      delete queen_bitmap;
  69.      delete queen_outline;
  70.      delete rook_bitmap;
  71.      delete rook_outline;
  72.      delete bishop_bitmap;
  73.      delete bishop_outline;
  74.      delete knight_bitmap;
  75.      delete knight_outline;
  76.      delete pawn_bitmap;
  77.      delete pawn_outline;
  78. }
  79.  
  80. void Display::draw_piece(WPDevContext &dc,
  81.                WPRect &square,WPBitmap *bitmap,WPRect &src_rect,
  82.                const ColorType color,WPBitmap *outline)
  83. {
  84.     // make dest square a little smaller, to avoid clobbering
  85.     // black space between squares:
  86.     WPRect new_area(square.left()+1,square.top()+1,
  87.          square.right()-1,square.bottom()-1);
  88.     if (color == Black)
  89.     {
  90.        WPMemDC memdc(&dc, bitmap);
  91.        dc.stretchBlt(new_area,memdc,src_rect,MERGECOPY);
  92.     }
  93.     else
  94.     {
  95.        {
  96.           WPMemDC memdc(&dc, bitmap);
  97.           dc.stretchBlt(new_area,memdc,src_rect,MERGEPAINT);
  98.        }
  99.        if (outline)
  100.        {
  101.       WPMemDC memdc(&dc,outline);
  102.           dc.stretchBlt(new_area,memdc,src_rect,SRCAND);
  103.        }
  104.     }
  105. }
  106.  
  107. void Display::draw_piece( WPDevContext &dc, WPRect &square, const Piece &piece)
  108. {
  109.       WPRect src_rect(1,1,62,62);
  110.       switch(piece.Type())
  111.       {
  112.           case Piece::Pawn:
  113.       {
  114.          draw_piece(dc,square,pawn_bitmap,src_rect,piece.Color(),
  115.            pawn_outline);
  116.          break;
  117.       }
  118.       case Piece::Rook:
  119.       {
  120.          draw_piece(dc,square,rook_bitmap,src_rect,piece.Color(),
  121.            rook_outline);
  122.          break;
  123.       }
  124.       case Piece::Knight:
  125.       {
  126.          draw_piece(dc,square,knight_bitmap,src_rect,piece.Color(),
  127.            knight_outline);
  128.          break;
  129.       }
  130.       case Piece::Bishop:
  131.       {
  132.          draw_piece(dc,square,bishop_bitmap,src_rect,piece.Color(),
  133.            bishop_outline);
  134.          break;
  135.       }
  136.       case Piece::Queen:
  137.       {
  138.          draw_piece(dc,square,queen_bitmap,src_rect,piece.Color(),
  139.            queen_outline);
  140.          break;
  141.       }
  142.       case Piece::King:
  143.       {
  144.          draw_piece(dc,square,king_bitmap,src_rect,piece.Color(),
  145.            king_outline);
  146.          break;
  147.       }
  148.           default:
  149.          break;
  150.        }
  151. }
  152.  
  153. void Display::set_size(WPRect &size)
  154. {
  155.     display_area = size;
  156.     width = size.width();
  157.     height = size.height() - horiz_border_height;
  158.     square_height = height/8;
  159.     square_width = (width - STATUS_AREA_WIDTH - vertical_border_width) / 8;
  160. }
  161.  
  162. void Display::draw_board( WPDevContext &dc, const Board &board, 
  163.     const WPRect *drawArea)
  164. {
  165.      HRGN drawRegion = CreateRectRgnIndirect((RECT *)drawArea);     
  166.      int vert_incr, vert_start, horiz_incr, horiz_start;
  167.      if (turned)
  168.      {
  169.         vert_incr = -square_height;
  170.     vert_start = 7*square_height;
  171.     horiz_incr = -square_width;
  172.     horiz_start = 7*square_width;
  173.      }
  174.      else
  175.      {
  176.         vert_incr = square_height;
  177.     vert_start = horiz_start = 0;
  178.     horiz_incr = square_width;
  179.      }
  180.      int vert = vert_start;
  181.      int horiz;
  182.      const int right_edge = square_width*8;
  183.      const int bottom_edge = square_height*8;
  184.      HRGN paintRegion = CreateRectRgn(0,0,0,0);
  185.      int mono = dc.getCap(NUMCOLORS) <= 2;
  186.      for (int i = 0; i < 8; i++)
  187.      {
  188.         horiz = horiz_start;
  189.  
  190.     // draw text in vertical border:
  191.     int text_start = (i*square_height) + square_height/2 - char_height/2; 
  192.     RECT rc;
  193.     SetRect(&rc,right_edge+3, text_start,
  194.             right_edge+vertical_border_width-3,
  195.             text_start+max_char_width);
  196.         char border_text[1];
  197.     *border_text = (turned) ? '1' + i : '8' - i;
  198.     DrawText(dc(),border_text,1,&rc,DT_LEFT);
  199.  
  200.     // draw text in horizontal border:
  201.     text_start = (i*square_width) + square_width/2 - char_width/2;
  202.     SetRect(&rc, text_start,bottom_edge+2,text_start+max_char_width,
  203.         bottom_edge+horiz_border_height);
  204.     *border_text = (turned) ? 'H' - i : 'A' + i;
  205.     DrawText(dc(),border_text,1,&rc,DT_LEFT);
  206.         
  207.         for (int j = 0; j < 8; j++)
  208.     {
  209.        Square sq(j+1,i+1,Black);
  210.        WPRect square(WPPoint(horiz,vert),
  211.                 WPPoint(horiz+square_width,vert+square_height));
  212.        HRGN squareRegion = CreateRectRgnIndirect((RECT*)&square);
  213.        if (CombineRgn(paintRegion,squareRegion,drawRegion,RGN_AND)
  214.         != NULLREGION)
  215.            {
  216.            if ((j + i) % 2)
  217.            {
  218.                if (mono)
  219.                dc.setBrushHatch(COLOR_BLACK,HS_DIAGCROSS);
  220.                else
  221.                    dc.setBrush(DARK_SQUARE_COLOR);
  222.            }
  223.            else
  224.            {
  225.                if (mono)
  226.                dc.setBrush(COLOR_WHITE);
  227.                else
  228.                    dc.setBrush(LIGHT_SQUARE_COLOR);
  229.            }
  230.                dc.rectangle(square);
  231.            Piece piece(board[sq]);
  232.            if (!piece.IsEmpty())
  233.            {
  234.                draw_piece(dc,square,piece);
  235.            }
  236.        }
  237.        horiz += horiz_incr;
  238.        DeleteObject(squareRegion);
  239.     }
  240.     vert += vert_incr;
  241.     
  242.      }
  243.      show_side(dc,board.Side());
  244.      DeleteObject(paintRegion);
  245.      DeleteObject(drawRegion);
  246. }
  247.  
  248. void Display::square_rect(const Square &sq, WPRect &out )
  249. {
  250.      WPRect size = get_size();
  251.      int rank = sq.Rank(Black);
  252.      int file = sq.File();
  253.      if (turned)
  254.      {
  255.         rank = 9-rank;
  256.     file = 9-file;
  257.      }
  258.      WPPoint orig(square_width*(file-1),square_height*(rank-1));
  259.      WPPoint end(square_width*file,square_height*rank);
  260.      out = WPRect(orig,end);
  261. }
  262.  
  263. void Display::draw_piece( WPDevContext &dc, const Square &loc, const Piece &p )
  264. {
  265.      WPRect area;
  266.      square_rect(loc,area);
  267.      draw_piece(dc,area,p);
  268. }
  269.  
  270. void Display::draw_square( WPDevContext &dc, const Square &loc )
  271. {
  272.      WPRect area;
  273.      square_rect(loc,area);
  274.      int mono = dc.getCap(NUMCOLORS) <= 2;
  275.      if ((loc.Rank(Black) + loc.File()) % 2)
  276.      {
  277.     if (mono)
  278.         dc.setBrushHatch(COLOR_BLACK,HS_DIAGCROSS);
  279.     else
  280.         dc.setBrush(DARK_SQUARE_COLOR);
  281.      }
  282.      else
  283.      {
  284.     if (mono)
  285.        dc.setBrush(COLOR_WHITE);
  286.     else
  287.            dc.setBrush(LIGHT_SQUARE_COLOR);
  288.      }
  289.      dc.rectangle(area);
  290. }
  291.  
  292. void Display::highlight_square( WPDevContext &, const Square & )
  293. {
  294.      // unimplemented
  295. }
  296.  
  297. void Display::unhighlight_square( WPDevContext &, const Square & )
  298. {
  299.      // unimplemented
  300. }
  301.  
  302. void Display::set_turned(Boolean turnit)
  303. {
  304.      turned = turnit;
  305. }
  306.  
  307. Square Display::mouse_loc( WPPoint &p)
  308. {
  309.      int x,y;
  310.      x = (p.x/square_width)+1;
  311.      if (turned)
  312.         x = 9-x;
  313.      y = (p.y/square_height)+1;
  314.      if (x > 8 || y > 8)
  315.         return Square(0);
  316.      else
  317.         return Square(x,y,turned ? White : Black);
  318. }
  319.  
  320. void Display::show_side( WPDevContext &dc, const ColorType side )
  321. {
  322.      static char *wstr = "WHITE to move";
  323.      static char *bstr = "BLACK to move";
  324.      RECT rcText;
  325.      int start = width - TEXT_OFFSET;
  326.      SetRect(&rcText,start,20,width-5,80);
  327.      DrawText(dc(),(side == White) ? wstr : bstr,
  328.        lstrlen(wstr), &rcText, DT_LEFT | DT_WORDBREAK);
  329. }
  330.  
  331. void Display::show_move( WPDevContext &dc, const char *move_image,
  332.   int number )
  333. {
  334.      RECT rcText;
  335.      int start = width - TEXT_OFFSET;
  336.      SetRect(&rcText,start,MOVE_Y,start+width-5,
  337.       MOVE_Y+spacing);
  338.      char text[80]; 
  339.      // erase any previous text:
  340.      HBRUSH brush = GetStockObject(WHITE_BRUSH);
  341.      FillRect(dc(),&rcText,brush);
  342.      int move_num = (number-1)/2;
  343.      if (number % 2)
  344.        wsprintf(text,"%d  %s",move_num+1,move_image);
  345.      else
  346.        wsprintf(text,"%d ... %s",move_num+1,move_image);
  347.      DrawText(dc(),text,strlen(text), &rcText, DT_LEFT | DT_WORDBREAK);
  348. }
  349.  
  350. void Display::clear_move_area( WPDevContext &dc)
  351. {
  352.      RECT rcText;
  353.      int start = width - TEXT_OFFSET;
  354.      SetRect(&rcText,start,MOVE_Y,start+width-5,
  355.       MOVE_Y+spacing);
  356.       // erase any previous text:
  357.      HBRUSH brush = GetStockObject(WHITE_BRUSH);
  358.      FillRect(dc(),&rcText,brush);
  359. }
  360.  
  361. void Display::clear_status_line( WPDevContext &dc )
  362. {
  363.      RECT rcText;
  364.      int start = width - TEXT_OFFSET;
  365.      SetRect(&rcText,start,MOVE_Y+spacing,width-5,
  366.          MOVE_Y+2*spacing);
  367.      HBRUSH brush = GetStockObject(WHITE_BRUSH);
  368.      // erase any previous contents of this field:
  369.      FillRect(dc(),&rcText,brush);
  370. }
  371.  
  372. void Display::show_status( WPDevContext &dc, const Search::Statistics stats)
  373. {
  374.      static char *images[] =
  375.      {
  376.         "         ",
  377.     "         ",
  378.     "Check!   ",
  379.     "Mate!    ",
  380.     "Stalemate",
  381.     "Draw!    ",
  382.     "I resign!"
  383.      };
  384.      RECT rcText;
  385.      int start = width - TEXT_OFFSET;
  386.      SetRect(&rcText,start,MOVE_Y+spacing,width-5,
  387.          MOVE_Y+2*spacing);
  388.      HBRUSH brush = GetStockObject(WHITE_BRUSH);
  389.      // erase any previous contents of this field:
  390.      FillRect(dc(),&rcText,brush);
  391.      char text[30];
  392.      if ((stats.state == Search::Normal || stats.state == Search::Check) &&
  393.           (stats.value > Constants::BIG-100))
  394.      {
  395.         if (stats.value == Constants::BIG-1)
  396.        strcpy(text,"Checkmate!");
  397.     else
  398.            wsprintf(text,"Mate in %d!",(Constants::BIG-stats.value-1)/2);
  399.      }
  400.      else
  401.         wsprintf(text,"%s",images[stats.state]);
  402.      DrawText(dc(),text,strlen(text), &rcText, DT_LEFT | DT_WORDBREAK);
  403. }
  404.  
  405. void Display::show_time( HWND handle, const time_t time,
  406.              const ColorType side )
  407. {
  408.      // all straight Windows code - because we have no access to
  409.      // Windows++ classes 
  410.  
  411.      HDC hdc = GetDC(handle);
  412.      assert(hdc);
  413.      char time_str[20];
  414.      unsigned hours = time/3600L;
  415.      unsigned minutes = (time - (hours*3600L))/60L;
  416.      unsigned seconds = (time - (hours*3600L) - (minutes*60L));
  417.      // convert time to ASCII:
  418.      wsprintf(time_str,"%02d:%02d:%02d",
  419.          (int)hours,(int)minutes,(int)seconds);
  420.      RECT rcText, client_rect, text_rect;
  421.      GetClientRect( handle, &client_rect );
  422.      int width = client_rect.right - client_rect.left;
  423.      int vbase = TIME_Y;
  424.      TEXTMETRIC tm;
  425.      if (side == White)
  426.      {
  427.     SetRect(&text_rect,width-TEXT_OFFSET,vbase,width-5,vbase+spacing);
  428.     DrawText(hdc,"WHITE:",6,&text_rect,DT_LEFT);
  429.         SetRect(&rcText,width-TEXT_OFFSET,vbase+spacing,width-5,vbase+2*spacing);
  430.      }
  431.      else
  432.      {
  433.     SetRect(&text_rect,width-TEXT_OFFSET,vbase+2*spacing,width-5,
  434.         vbase+3*spacing);
  435.     DrawText(hdc,"BLACK:",6,&text_rect,DT_LEFT);
  436.         SetRect(&rcText,width-TEXT_OFFSET,vbase+3*spacing,width-5,vbase+4*spacing);
  437.      }
  438.      DrawText(hdc,time_str,lstrlen(time_str),&rcText,
  439.              DT_LEFT | DT_WORDBREAK);
  440.      BOOL ret = ReleaseDC(handle,hdc);
  441.      assert(ret);
  442. }
  443.  
  444. void Display::clear_search_counts(  WPDevContext &dc )
  445. {
  446.      RECT rcText;
  447.      int start = width - TEXT_OFFSET;
  448.      SetRect(&rcText,start,PLY_Y,width-5,
  449.          PLY_Y+4*spacing);
  450.      HBRUSH brush = GetStockObject(WHITE_BRUSH);
  451.      // erase any previous contents of this field:
  452.      FillRect(dc(),&rcText,brush);
  453. }
  454.  
  455. void Display::show_search_counts( HWND handle, const int ply,
  456.      const long nodes)
  457. {
  458.      RECT rcText, client_rect, text_rect;
  459.      GetClientRect( handle, &client_rect );
  460.      int width = client_rect.right - client_rect.left;
  461.      int vbase = PLY_Y;
  462.      HDC hdc = GetDC(handle);
  463.      assert(hdc);
  464.      SetRect(&text_rect,width-TEXT_OFFSET,vbase,width-5,vbase+spacing);
  465.      char msg[20];
  466.      wsprintf(msg,"Ply: %d",ply);
  467.      DrawText(hdc,msg,lstrlen(msg),&text_rect,
  468.              DT_LEFT | DT_WORDBREAK);
  469.      text_rect.top += spacing;
  470.      text_rect.bottom += spacing;
  471.      DrawText(hdc,"Nodes:",6,&text_rect,
  472.              DT_LEFT | DT_WORDBREAK);
  473.      text_rect.top += spacing;
  474.      text_rect.bottom += spacing;
  475.      wsprintf(msg,"%ld",nodes);
  476.      DrawText(hdc,msg,lstrlen(msg),&text_rect,
  477.              DT_LEFT | DT_WORDBREAK);
  478.      BOOL ret = ReleaseDC(handle,hdc);
  479.      assert(ret);
  480. }
  481.