home *** CD-ROM | disk | FTP | other *** search
- /*
- PMICS -- PM interface for playing chess on internet chess server
- Copyright (C) 1994 Kevin Nomura
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- Author can be reached at email: chow@netcom.com
- */
- #define INCL_GPIPRIMITIVES
- #define INCL_GPI
- #include <os2.h>
- #include <string.h>
- #include <stdio.h>
- #include <ievtdata.hpp>
- #include "pmics.hh"
- #include "wboard.hh"
- #include "session.hh"
-
- extern ASession *aSession;
- IWindowHandle hBoard;
- extern int intOption(IString s);
-
- BoardWindow::BoardWindow(unsigned long windowId, //Constructor for this class
- IWindow *parent,
- int size) :
- IStaticText(windowId, parent, parent)
- {
- IFUNCTRACE_DEVELOP();
- // blackColor = blackc;
- //whiteColor = whitec;
- hBoard = handle(); // export handle for messaging
-
- IPaintHandler::handleEventsFor(this);
- IMouseClickHandler::handleEventsFor(this);
- boardHandler = new BoardHandler(this);
- boardHandler->handleEventsFor(this);
-
- orientation = 0; // 0 degrees relative to white at bottom
- promotePiece = 'Q';
-
- setup(size);
-
- setMinimumSize(ISize(squareSize*8, squareSize*8));
- sizeTo(ISize(squareSize*8, squareSize*8));
- show();
- } /* end PmicsWindow :: PmicsWindow(...) */
-
-
- //**************************************************************************
- //* mouseClicked: event handler for mouse
- //**************************************************************************
- Boolean BoardWindow::mouseClicked(IMouseClickEvent &mouevt)
- {
- static IPair from, to;
- static IString move;
-
- IFUNCTRACE_DEVELOP();
-
- if (mouevt.mouseNumber() == IMouseClickEvent::button2) { // reissue move
- aSession->write(move+"\n");
- return true;
- }
- else if (mouevt.mouseNumber() != IMouseClickEvent::button1)
- return false;
-
- switch (mouevt.mouseAction()) {
- case IMouseClickEvent::down:
- from = mouevt.mousePosition();
- from /= squareSize;
- ITRACE_DEVELOP(IString("mouse down at ") + from.asString());
- break;
- case IMouseClickEvent::up:
- {
- AGame::Piece p;
- int toFile, toRank;
-
- to = mouevt.mousePosition();
- to /= squareSize;
- ITRACE_DEVELOP(IString("mouse up at ") + to.asString());
- if (from == to) break; // mouse slipped, maybe?
- if (orientation) {
- from = IPair(7,7) - from;
- to = IPair(7,7) - to;
- }
- move = IString((char)('a' + from.coord1())) +
- IString(1 + (int)from.coord2()) +
- IString((char)('a' + (int)to.coord1())) +
- IString(1 + (int)to.coord2());
-
- /* pawn move to first or eighth rank? append pawn promotion (=Q, etc)*/
- /* because of wild 5 we append it for pawns moving backwards also. */
- toFile = to.coord1();
- toRank = to.coord2();
- p = AGame::current()->piece(from.coord1(), from.coord2());
- if ((toRank == 0 || toRank == 7) &&
- (p == AGame::W_PAW || p == AGame::B_PAW))
- move += "=" + IString(promotePiece);
-
- aSession->write(move+"\n");
- break;
- }
- default:
- return false; // event not handled, pass it along
- }
- return true; // event handled
- }
-
-
- //**************************************************************************
- // paintWindow: event handler for paint
- //**************************************************************************
- Boolean BoardWindow :: paintWindow(IPaintEvent & paintEvent)
- {
- IPresSpaceHandle hps; //Presentation Space Handle
- RECTL rect;
- HRGN hrgn;
- SIZEL sizel;
-
- IFUNCTRACE_DEVELOP();
- /* hps = paintEvent.presSpaceHandle() ; //Get the presentation space handle
-
- GpiSetPattern(hps, PATSYM_DENSE6);
- GpiQueryPS(hps, &sizel);
- rect.xLeft = 0;
- rect.yBottom = 0;
- rect.xRight = sizel.cx;
- rect.yTop = sizel.cy;
- GpiSetColor(hps, CLR_WHITE);
- GpiSetBackColor(hps, CLR_BLUE);
- hrgn = GpiCreateRegion(hps, 1, &rect);
- GpiPaintRegion(hps, hrgn);
- GpiDestroyRegion(hps, hrgn);*/
-
- plot(true);
- return true;
- }
-
-
- //**************************************************************************
- // event handler for user messages
- //**************************************************************************
- Boolean BoardHandler::dispatchHandlerEvent (IEvent &evt)
- {
- BoardWindow *boardWindow = (BoardWindow *)evt.window();
-
- switch (evt.eventId()) {
-
- case MSG_BOARD_FLIP:
- boardWindow->flip();
- boardWindow->plot(true);
- hMain.postEvent(MSG_STAT_WHITE_AT_OTHER);
- break;
-
- case MSG_BOARD_WHITE_AT_BOTTOM:
- if (! boardWindow->whiteAtBottom())
- boardWindow->flip();
- boardWindow->plot(true);
- hMain.postEvent(MSG_STAT_WHITE_AT_BOTTOM);
- break;
-
- case MSG_BOARD_WHITE_AT_TOP:
- if (boardWindow->whiteAtBottom())
- boardWindow->flip();
- boardWindow->plot(true);
- hMain.postEvent(MSG_STAT_WHITE_AT_TOP);
- break;
-
- case MSG_BOARD_REPLOT:
- boardWindow->plot(true);
- break;
-
- case MSG_BOARD_UPDATE:
- boardWindow->plot();
- break;
-
- case MI_PROMOTION_Q:
- boardWindow->setPromotePiece('Q');
- break;
-
- case MI_PROMOTION_R:
- boardWindow->setPromotePiece('R');
- break;
-
- case MI_PROMOTION_B:
- boardWindow->setPromotePiece('B');
- break;
-
- case MI_PROMOTION_N:
- boardWindow->setPromotePiece('N');
- break;
-
- default:
- return false;
- }
- return true;
- }
-
-
- void BoardWindow::plot(Boolean force)
- {
- int rank, file;
- AGame::Piece p;
-
- IFUNCTRACE_DEVELOP();
- for (rank=0; rank<8; rank++) {
- for (file=0; file<8; file++) {
- p = AGame::current()->piece(file,rank);
- if (force || prevGame.piece(file,rank) != p) {
- //ITRACE_DEVELOP("plot: ("+IString(file)+","+IString(rank));
- plotPiece(p,
- whiteAtBottom() ? rank : 7-rank,
- whiteAtBottom() ? file : 7-file);
- prevGame.setPiece(file,rank,p);
- }
- }
- }
- }
-
-
- //**************************************************************************
- // plotPiece: display bitmap of individual piece
- //**************************************************************************
- #define BITS_BYTES (squareSize*squareSize/8)
-
- void BoardWindow::plotPiece(AGame::Piece piece, char rank, char file)
- {
- HPS hps;
- POINTL p;
- SIZEL sizl;
- RECTL rect;
- HRGN hrgn;
- char rfile, rrank; // relative to board.atTop
- long alTable[] = {CLR_WHITE_SQUARE, 0xc8c365,
- CLR_BLACK_SQUARE, 0x77a26d,
- CLR_WHITE_PIECE, 0xffffcc,
- CLR_BLACK_PIECE, 0x202020};
-
- hps = presSpace();
-
- // modify color table for squares and pieces to values borrowed from xboard
- GpiCreateLogColorTable (hps, 0L, LCOLF_INDRGB, 0L, 4, alTable);
-
- sizl.cx = sizl.cy = squareSize;
- rfile = file;
- rrank = rank;
-
- // paint the square
- rect.xLeft = squareSize*rfile;
- rect.yBottom = squareSize*rrank;
- rect.xRight = rect.xLeft+squareSize;
- rect.yTop = rect.yBottom+squareSize;
- WinFillRect(hps, &rect, (rfile+rrank)&1? CLR_WHITE_SQUARE: CLR_BLACK_SQUARE);
-
- // paint the piece
- if (piece != AGame::EMPTY) {
- p.x = squareSize*rfile;
- p.y = squareSize*(rrank+1);
- GpiMove(hps, &p);
- GpiSetColor(hps, AGame::isBlack(piece) ? CLR_BLACK_PIECE: CLR_WHITE_PIECE);
- // set background color explicitly to fix (?) problem
- // of pieces appearing on a white background.
- GpiSetBackColor(hps, (rfile+rrank)&1 ? CLR_WHITE_SQUARE: CLR_BLACK_SQUARE);
- GpiImage(hps, 0L, &sizl, BITS_BYTES, (PBYTE)(pi_bits[(int)piece]));
- }
-
- releasePresSpace(hps);
- }
-
-
- //**************************************************************************
- // setup: configure board to a given size and colour
- //**************************************************************************
-
- void BoardWindow::setup(int size)
- {
- extern char xs_s_r_bits[], xs_s_kt_bits[], xs_s_b_bits[], xs_s_q_bits[],
- xs_s_p_bits[], xs_s_k_bits[],
- solid_bishop_bits[], solid_knight_bits[], solid_pawn_bits[],
- solid_queen_bits[], solid_rook_bits[], solid_king_bits[],
- bishop_small_bits[], king_small_bits[], knight_small_bits[],
- pawn_small_bits[], queen_small_bits[], rook_small_bits[];
- int i,j;
- struct
- {
- int b7:1,b6:1,b5:1,b4:1,b3:1,b2:1,b1:1,b0:1;
- } c1,c2;
-
- switch(size)
- {
- case 1: /* small */
- squareSize = 40;
- pi_bits[0] = (char *)NULL;
- pi_bits[1] = xs_s_r_bits;
- pi_bits[2] = xs_s_kt_bits;
- pi_bits[3] = xs_s_b_bits;
- pi_bits[4] = xs_s_q_bits;
- pi_bits[5] = xs_s_k_bits;
- pi_bits[6] = xs_s_p_bits;
- pi_bits[7] = xs_s_r_bits;
- pi_bits[8] = xs_s_kt_bits;
- pi_bits[9] = xs_s_b_bits;
- pi_bits[10] = xs_s_q_bits;
- pi_bits[11] = xs_s_k_bits;
- pi_bits[12] = xs_s_p_bits;
- break;
- case 2: /* medium */
- squareSize = 64;
- pi_bits[0] = (char *)NULL;
- pi_bits[1] = rook_small_bits;
- pi_bits[2] = knight_small_bits;
- pi_bits[3] = bishop_small_bits;
- pi_bits[4] = queen_small_bits;
- pi_bits[5] = king_small_bits;
- pi_bits[6] = pawn_small_bits;
- pi_bits[7] = rook_small_bits;
- pi_bits[8] = knight_small_bits;
- pi_bits[9] = bishop_small_bits;
- pi_bits[10] = queen_small_bits;
- pi_bits[11] = king_small_bits;
- pi_bits[12] = pawn_small_bits;
- break;
- case 3: /* large */
- squareSize = 80;
- pi_bits[0] = (char *)NULL;
- pi_bits[1] = solid_rook_bits;
- pi_bits[2] = solid_knight_bits;
- pi_bits[3] = solid_bishop_bits;
- pi_bits[4] = solid_queen_bits;
- pi_bits[5] = solid_king_bits;
- pi_bits[6] = solid_pawn_bits;
- pi_bits[7] = solid_rook_bits;
- pi_bits[8] = solid_knight_bits;
- pi_bits[9] = solid_bishop_bits;
- pi_bits[10] = solid_queen_bits;
- pi_bits[11] = solid_king_bits;
- pi_bits[12] = solid_pawn_bits;
- break;
- }
-
- for (i=1; i<=6; i++)
- for (j=0; j<BITS_BYTES; j++)
- {
- memcpy(&c1,pi_bits[i]+j,1);
- c2.b7=c1.b0;
- c2.b6=c1.b1;
- c2.b5=c1.b2;
- c2.b4=c1.b3;
- c2.b3=c1.b4;
- c2.b2=c1.b5;
- c2.b1=c1.b6;
- c2.b0=c1.b7;
- memcpy(pi_bits[i]+j,&c2,1);
- }
- }
-