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