home *** CD-ROM | disk | FTP | other *** search
/ The Pier Shareware 6 / The_Pier_Shareware_Number_6_(The_Pier_Exchange)_(1995).iso / 035 / pmics.zip / wboard.cc < prev    next >
C/C++ Source or Header  |  1994-12-10  |  11KB  |  368 lines

  1. /*
  2.     PMICS -- PM interface for playing chess on internet chess server
  3.     Copyright (C) 1994  Kevin Nomura
  4.  
  5.     This program is free software; you can redistribute it and/or modify
  6.     it under the terms of the GNU General Public License as published by
  7.     the Free Software Foundation; either version 2 of the License, or
  8.     (at your option) any later version.
  9.  
  10.     This program is distributed in the hope that it will be useful,
  11.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.     GNU General Public License for more details.
  14.  
  15.     You should have received a copy of the GNU General Public License
  16.     along with this program; if not, write to the Free Software
  17.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  
  19.     Author can be reached at email: chow@netcom.com
  20. */
  21. #define INCL_GPIPRIMITIVES
  22. #define INCL_GPI
  23. #include <os2.h>
  24. #include <string.h>
  25. #include <stdio.h>
  26. #include <ievtdata.hpp>
  27. #include "pmics.hh"
  28. #include "wboard.hh"
  29. #include "session.hh"
  30.  
  31. extern ASession *aSession;
  32. IWindowHandle    hBoard;
  33. extern int       intOption(IString s);
  34.  
  35. BoardWindow::BoardWindow(unsigned long windowId, //Constructor for this class
  36.              IWindow *parent) :
  37.          IStaticText(windowId, parent, parent)
  38. {
  39.   IFUNCTRACE_DEVELOP();
  40. //  blackColor = blackc;
  41.   //whiteColor = whitec;
  42.   hBoard = handle(); // export handle for messaging
  43.  
  44.   IPaintHandler::handleEventsFor(this);
  45.   IMouseClickHandler::handleEventsFor(this);
  46.   boardHandler = new BoardHandler(this);
  47.   boardHandler->handleEventsFor(this);
  48.  
  49.   orientation = 0;        // 0 degrees relative to white at bottom
  50.   promotePiece = 'Q';
  51.  
  52.   if (intOption("big")) setup(3);
  53.   else if (intOption("medium")) setup(2);
  54.   else setup(1);
  55.  
  56.   setMinimumSize(ISize(squareSize*8, squareSize*8));
  57.   sizeTo(ISize(squareSize*8, squareSize*8));
  58.   show();
  59. } /* end PmicsWindow :: PmicsWindow(...) */
  60.  
  61.  
  62. //**************************************************************************
  63. //* mouseClicked: event handler for mouse
  64. //**************************************************************************
  65. Boolean BoardWindow::mouseClicked(IMouseClickEvent &mouevt)
  66. {
  67.   static IPair     from, to;
  68.   static IString   move;
  69.  
  70.   IFUNCTRACE_DEVELOP();
  71.  
  72.   if (mouevt.mouseNumber() == IMouseClickEvent::button2) { // reissue move
  73.     aSession->write(move+"\n");
  74.     return true;
  75.   }
  76.   else if (mouevt.mouseNumber() != IMouseClickEvent::button1)
  77.     return false;
  78.  
  79.   switch (mouevt.mouseAction()) {
  80.   case IMouseClickEvent::down:
  81.     from = mouevt.mousePosition();
  82.     from /= squareSize;
  83.     ITRACE_DEVELOP(IString("mouse down at ") + from.asString());
  84.     break;
  85.   case IMouseClickEvent::up:
  86.     {
  87.       AGame::Piece p;
  88.       int toFile, toRank;
  89.  
  90.       to = mouevt.mousePosition();
  91.       to /= squareSize;
  92.       ITRACE_DEVELOP(IString("mouse up at ") + to.asString());
  93.       if (from == to) break;    // mouse slipped, maybe?
  94.       if (orientation) {
  95.     from = IPair(7,7) - from;
  96.     to = IPair(7,7) - to;
  97.       }
  98.       move = IString((char)('a' + from.coord1())) +
  99.     IString(1 + (int)from.coord2()) +
  100.       IString((char)('a' + (int)to.coord1())) +
  101.         IString(1 + (int)to.coord2());
  102.  
  103.       /* pawn move to first or eighth rank?  append pawn promotion (=Q, etc)*/
  104.       /* because of wild 5 we append it for pawns moving backwards also. */
  105.       toFile = to.coord1();
  106.       toRank = to.coord2();
  107.       p = AGame::current()->piece(from.coord1(), from.coord2());
  108.       if ((toRank == 0 || toRank == 7) &&
  109.       (p == AGame::W_PAW || p == AGame::B_PAW))
  110.     move += "=" + IString(promotePiece);
  111.  
  112.       aSession->write(move+"\n");
  113.       break;
  114.     }
  115.   default:
  116.     return false;        // event not handled, pass it along
  117.   }
  118.   return true;            // event handled
  119. }
  120.  
  121.  
  122. //**************************************************************************
  123. // paintWindow: event handler for paint
  124. //**************************************************************************
  125. Boolean BoardWindow :: paintWindow(IPaintEvent & paintEvent)
  126. {
  127.   IPresSpaceHandle hps;                //Presentation Space Handle
  128.   RECTL   rect;
  129.   HRGN    hrgn;
  130.   SIZEL   sizel;
  131.  
  132.   IFUNCTRACE_DEVELOP();
  133. /*  hps = paintEvent.presSpaceHandle() ;  //Get the presentation space handle
  134.  
  135.   GpiSetPattern(hps, PATSYM_DENSE6);
  136.   GpiQueryPS(hps, &sizel);
  137.   rect.xLeft = 0;
  138.   rect.yBottom = 0;
  139.   rect.xRight = sizel.cx;
  140.   rect.yTop = sizel.cy;
  141.   GpiSetColor(hps, CLR_WHITE);
  142.   GpiSetBackColor(hps, CLR_BLUE);
  143.   hrgn = GpiCreateRegion(hps, 1, &rect);
  144.   GpiPaintRegion(hps, hrgn);
  145.   GpiDestroyRegion(hps, hrgn);*/
  146.  
  147.   plot(true);
  148.   return true;
  149. }
  150.  
  151.  
  152. //**************************************************************************
  153. // event handler for user messages
  154. //**************************************************************************
  155. Boolean BoardHandler::dispatchHandlerEvent (IEvent &evt)
  156. {
  157.   BoardWindow     *boardWindow = (BoardWindow *)evt.window();
  158.  
  159.   switch (evt.eventId()) {
  160.  
  161.   case MSG_BOARD_FLIP:
  162.     boardWindow->flip();
  163.     boardWindow->plot(true);
  164.     hMain.postEvent(MSG_STAT_WHITE_AT_OTHER);
  165.     break;
  166.  
  167.   case MSG_BOARD_WHITE_AT_BOTTOM:
  168.     if (! boardWindow->whiteAtBottom())
  169.       boardWindow->flip();
  170.     boardWindow->plot(true);
  171.     hMain.postEvent(MSG_STAT_WHITE_AT_BOTTOM);
  172.     break;
  173.  
  174.   case MSG_BOARD_WHITE_AT_TOP:
  175.     if (boardWindow->whiteAtBottom())
  176.       boardWindow->flip();
  177.     boardWindow->plot(true);
  178.     hMain.postEvent(MSG_STAT_WHITE_AT_TOP);
  179.     break;
  180.  
  181.   case MSG_BOARD_REPLOT:
  182.     boardWindow->plot(true);
  183.     break;
  184.  
  185.   case MSG_BOARD_UPDATE:
  186.     boardWindow->plot();
  187.     break;
  188.  
  189.   case MI_PROMOTION_Q:
  190.     boardWindow->setPromotePiece('Q');
  191.     break;
  192.  
  193.   case MI_PROMOTION_R:
  194.     boardWindow->setPromotePiece('R');
  195.     break;
  196.  
  197.   case MI_PROMOTION_B:
  198.     boardWindow->setPromotePiece('B');
  199.     break;
  200.  
  201.   case MI_PROMOTION_N:
  202.     boardWindow->setPromotePiece('N');
  203.     break;
  204.  
  205.   default:
  206.     return false;
  207.   }
  208.   return true;
  209. }
  210.  
  211.  
  212. void BoardWindow::plot(Boolean force)
  213. {
  214.   int rank, file;
  215.   AGame::Piece p;
  216.  
  217.   IFUNCTRACE_DEVELOP();
  218.   for (rank=0; rank<8; rank++) {
  219.     for (file=0; file<8; file++) {
  220.       p = AGame::current()->piece(file,rank);
  221.       if (force || prevGame.piece(file,rank) != p) {
  222.     //ITRACE_DEVELOP("plot: ("+IString(file)+","+IString(rank));
  223.     plotPiece(p,
  224.           whiteAtBottom() ? rank : 7-rank,
  225.           whiteAtBottom() ? file : 7-file);
  226.     prevGame.setPiece(file,rank,p);
  227.       }
  228.     }
  229.   }
  230. }
  231.  
  232.  
  233. //**************************************************************************
  234. //  plotPiece: display bitmap of individual piece
  235. //**************************************************************************
  236. #define BITS_BYTES (squareSize*squareSize/8)
  237.  
  238. void BoardWindow::plotPiece(AGame::Piece piece, char rank, char file)
  239. {
  240.   HPS           hps;
  241.   POINTL        p;
  242.   SIZEL         sizl;
  243.   RECTL         rect;
  244.   HRGN          hrgn;
  245.   char          rfile, rrank;    // relative to board.atTop
  246.   long          alTable[] = {CLR_WHITE_SQUARE, 0xc8c365,
  247.                  CLR_BLACK_SQUARE, 0x77a26d,
  248.                  CLR_WHITE_PIECE,  0xffffcc,
  249.                  CLR_BLACK_PIECE,  0x202020};
  250.  
  251.   hps = presSpace();
  252.  
  253.   // modify color table for squares and pieces to values borrowed from xboard
  254.   GpiCreateLogColorTable (hps, 0L, LCOLF_INDRGB, 0L, 4, alTable);
  255.  
  256.   sizl.cx = sizl.cy = squareSize;
  257.   rfile = file;
  258.   rrank = rank;
  259.  
  260.   // paint the square
  261.   rect.xLeft    = squareSize*rfile;
  262.   rect.yBottom  = squareSize*rrank;
  263.   rect.xRight   = rect.xLeft+squareSize;
  264.   rect.yTop     = rect.yBottom+squareSize;
  265.   WinFillRect(hps, &rect, (rfile+rrank)&1? CLR_WHITE_SQUARE: CLR_BLACK_SQUARE);
  266.  
  267.   // paint the piece
  268.   if (piece != AGame::EMPTY) {
  269.     p.x = squareSize*rfile;
  270.     p.y = squareSize*(rrank+1);
  271.     GpiMove(hps, &p);
  272.     GpiSetColor(hps, AGame::isBlack(piece) ? CLR_BLACK_PIECE: CLR_WHITE_PIECE);
  273.     // set background color explicitly to fix (?) problem
  274.     // of pieces appearing on a white background.
  275.     GpiSetBackColor(hps, (rfile+rrank)&1 ? CLR_WHITE_SQUARE: CLR_BLACK_SQUARE);
  276.     GpiImage(hps, 0L, &sizl, BITS_BYTES, (PBYTE)(pi_bits[(int)piece]));
  277.   }
  278.  
  279.   releasePresSpace(hps);
  280. }
  281.  
  282.  
  283. //**************************************************************************
  284. //  setup: configure board to a given size and colour
  285. //**************************************************************************
  286.  
  287. void BoardWindow::setup(int size)
  288. {
  289.   extern char xs_s_r_bits[], xs_s_kt_bits[], xs_s_b_bits[], xs_s_q_bits[],
  290.   xs_s_p_bits[], xs_s_k_bits[],
  291.   solid_bishop_bits[], solid_knight_bits[], solid_pawn_bits[],
  292.   solid_queen_bits[], solid_rook_bits[], solid_king_bits[],
  293.   bishop_small_bits[], king_small_bits[], knight_small_bits[],
  294.   pawn_small_bits[], queen_small_bits[], rook_small_bits[];
  295.   int i,j;
  296.   struct
  297.     {
  298.       int b7:1,b6:1,b5:1,b4:1,b3:1,b2:1,b1:1,b0:1;
  299.     } c1,c2;
  300.   
  301.   switch(size)
  302.     {
  303.     case 1:   /* small */
  304.       squareSize = 40;
  305.       pi_bits[0] = (char *)NULL;
  306.       pi_bits[1] = xs_s_r_bits;
  307.       pi_bits[2] = xs_s_kt_bits;
  308.       pi_bits[3] = xs_s_b_bits;
  309.       pi_bits[4] = xs_s_q_bits;
  310.       pi_bits[5] = xs_s_k_bits;
  311.       pi_bits[6] = xs_s_p_bits;
  312.       pi_bits[7] = xs_s_r_bits;
  313.       pi_bits[8] = xs_s_kt_bits;
  314.       pi_bits[9] = xs_s_b_bits;
  315.       pi_bits[10] = xs_s_q_bits;
  316.       pi_bits[11] = xs_s_k_bits;
  317.       pi_bits[12] = xs_s_p_bits;
  318.       break;
  319.     case 2:   /* medium */
  320.       squareSize = 64;
  321.       pi_bits[0] = (char *)NULL;
  322.       pi_bits[1] = rook_small_bits;
  323.       pi_bits[2] = knight_small_bits;
  324.       pi_bits[3] = bishop_small_bits;
  325.       pi_bits[4] = queen_small_bits;
  326.       pi_bits[5] = king_small_bits;
  327.       pi_bits[6] = pawn_small_bits;
  328.       pi_bits[7] = rook_small_bits;
  329.       pi_bits[8] = knight_small_bits;
  330.       pi_bits[9] = bishop_small_bits;
  331.       pi_bits[10] = queen_small_bits;
  332.       pi_bits[11] = king_small_bits;
  333.       pi_bits[12] = pawn_small_bits;
  334.       break;
  335.     case 3:   /* large */
  336.       squareSize = 80;
  337.       pi_bits[0] = (char *)NULL;
  338.       pi_bits[1] = solid_rook_bits;
  339.       pi_bits[2] = solid_knight_bits;
  340.       pi_bits[3] = solid_bishop_bits;
  341.       pi_bits[4] = solid_queen_bits;
  342.       pi_bits[5] = solid_king_bits;
  343.       pi_bits[6] = solid_pawn_bits;
  344.       pi_bits[7] = solid_rook_bits;
  345.       pi_bits[8] = solid_knight_bits;
  346.       pi_bits[9] = solid_bishop_bits;
  347.       pi_bits[10] = solid_queen_bits;
  348.       pi_bits[11] = solid_king_bits;
  349.       pi_bits[12] = solid_pawn_bits;
  350.       break;
  351.     }
  352.  
  353.   for (i=1; i<=6; i++)
  354.     for (j=0; j<BITS_BYTES; j++)
  355.       {
  356.     memcpy(&c1,pi_bits[i]+j,1);
  357.     c2.b7=c1.b0;
  358.     c2.b6=c1.b1;
  359.     c2.b5=c1.b2;
  360.     c2.b4=c1.b3;
  361.     c2.b3=c1.b4;
  362.     c2.b2=c1.b5;
  363.     c2.b1=c1.b6;
  364.     c2.b0=c1.b7;
  365.     memcpy(pi_bits[i]+j,&c2,1);
  366.       }
  367. }
  368.