/* $Id: dgtboard.cc,v 1.6 2007/01/22 17:57:27 bergo Exp $ */ /* eboard - chess client http://eboard.sourceforge.net Copyright (C) 2000-2007 Felipe Paulo Guazzi Bergo bergo@seul.org 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #ifdef WITH_DGT_BOARD #include #include #include #include #include #include #include "mainwindow.h" #include "global.h" #include "sound.h" #include "help.h" #include "eboard.h" #include "dgtnix.h" Board *DgtBoard = NULL; bool DgtInit = false; /* Main function for dgtnix support under eboard, * this function is called in the main event loop * each time something occur on the descriptor of the board * indentified by parameter channel * data is a pointer to the MainWindow mw. */ gboolean gtkDgtnixEvent(GIOChannel* channel, GIOCondition cond, gpointer data) { char msg[256]; // code : first char of any message char code; // number of chars read gsize read=0; // read one char one the descriptor to find out the message type g_io_channel_read_chars( channel, &code, 1,&read,NULL); MainWindow *mw=(MainWindow *)data; if(mw->notebook->getCurrentPageId() != -1) { g_strlcpy(msg,_("DGT support error: wrong page"),256); global.output->append(msg,global.Colors.TextBright,IM_NORMAL); return false; } // Code DGTNIX_MSG_MV_ADD or DGTNIX_MSG_MV_REMOVE // a piece was move on the board if((code == DGTNIX_MSG_MV_ADD) || (code == DGTNIX_MSG_MV_REMOVE)) { // Read and identify the move char column, piece; int color; int line; int x,y; // message : body of message with code DGTNIX_MSG_MV_ADD // or DGTNIX_MSG_MV_REMOVE char message[4]; read=0; gsize nread=0; while (read <3) { g_io_channel_read_chars(channel, message, 3, &nread, NULL); read += nread; nread = 3 -read; } column = message[0]; line = message[1]; piece = message[2]; if(islower(piece)) color = BLACK; else color = WHITE; y=8-line; x=column-'A'; // generate a button events equivalent to the move GdkEventButton be; be.button=1; be.state =0; Board *me=DgtBoard; // TODO: write a method in class Board to compute these. Joystick code needs it too. if (me->effectiveFlip()) {x=7-x; y=7-y;} be.x=(x*me->sqside)+me->borx; be.y=(y*me->sqside)+me->bory+me->morey; // END TODO if(DgtBoard->hasGame()) { int myColor=DgtBoard->getGame()->MyColor&COLOR_MASK; if(myColor==BLACK) { be.x=((7-x)*me->sqside)+me->borx; be.y=((7-y)*me->sqside)+me->bory+me->morey; } } board_button_press_event(DgtBoard->widget,&be,DgtBoard); board_button_release_event(DgtBoard->widget,&be,DgtBoard); // end of mouse move event generation // Test if the boards are synced if(DgtBoard->hasGame()) { char board[64]; int i,j; for(i=0; i<8; i++) { for(j=0; j<8; j++) { int p=DgtBoard->position.getPiece(j,i)&PIECE_MASK; int color=DgtBoard->position.getPiece(j,i)&COLOR_MASK; int indice =((7-i)*8)+j; switch(p) { case PAWN: if (color==WHITE)board[indice]='P'; else board[indice]='p'; break; case ROOK: if (color==WHITE)board[indice]='R'; else board[indice]='r'; break; case KNIGHT: if (color==WHITE)board[indice]='N'; else board[indice]='n'; break; case BISHOP: if (color==WHITE)board[indice]='B'; else board[indice]='b'; break; case QUEEN: if (color==WHITE)board[indice]='Q'; else board[indice]='q'; break; case KING: if (color==WHITE)board[indice]='K'; else board[indice]='k'; break; default: board[indice]=' '; break; } } } int myColor=DgtBoard->getGame()->MyColor&COLOR_MASK; if((myColor == color) && (code != DGTNIX_MSG_MV_REMOVE) && (dgtnixTestBoard(board) != 1)) { char aux[256]; g_strlcpy(msg,_("DGT warning: position mismatch between eboard and DGT board."),256); global.output->append(msg,global.Colors.TextBright,IM_NORMAL); dgtnixPrintBoard(dgtnixGetBoard(), aux); snprintf(msg,256,"DGT:\n%s",aux); global.output->append(msg,global.Colors.TextDefault,IM_NORMAL); dgtnixPrintBoard(board, aux); snprintf(msg,256,"eboard:\n%s",aux); global.output->append(msg,global.Colors.TextDefault,IM_NORMAL); } } return true; } // Code DGTNIX_MSG_TIME, time was sent by the DGT clock if(code == DGTNIX_MSG_TIME) { int wtime, btime, wturn; /* FIXME: dgtnix 1.7 doesn't have this, commented so I can compile eboard -- Felipe if(dgtnixGetClockData(&wtime, &btime, &wturn)) { cout << "White time :" << wtime ; cout << "s, Black time :" << btime; if(wturn) cout << ", white player turn\n"; else cout << ", black player turn\n"; } else cerr << "Error in dgtnix time event." <append(msg,global.Colors.TextBright,IM_NORMAL); } void dgtInit(const char *port, MainWindow *mainWindow) { char msg[512]; dgtnixSetDebugMode(2); snprintf(msg,512,_("dgtnix driver version %.1f"),dgtnixQueryDriverVersion()); global.output->append(msg,global.Colors.TextBright,IM_NORMAL); int fd = dgtnixInit(port); if(fd<0) { switch (fd) { case -1: snprintf(msg,512,_("Unable to find the DGT board on port %s: %s."), port,strerror(errno)); break; case -2: snprintf(msg,512,_("No response to DGT_SEND_BRD on port %s: %s."), port,strerror(errno)); break; default: snprintf(msg,512,_("Invalid answer to DGT_SEND_BRD on port %s: %s "), port,strerror(errno)); break; } global.output->append(msg,global.Colors.TextDefault,IM_NORMAL); DgtInit = false; } else { snprintf(msg,512,_("DGT board found on port %s."), port); global.output->append(msg,global.Colors.TextDefault,IM_NORMAL); snprintf(msg,512,_("Serial :%s"),dgtnixQueryString(DGTNIX_SERIAL_STRING) ); global.output->append(msg,global.Colors.TextDefault,IM_NORMAL); snprintf(msg,512,_("Bus address :%s"),dgtnixQueryString(DGTNIX_BUSADRESS_STRING)); global.output->append(msg,global.Colors.TextDefault,IM_NORMAL); snprintf(msg,512,_("Board version :%s"),dgtnixQueryString(DGTNIX_VERSION_STRING)); global.output->append(msg,global.Colors.TextDefault,IM_NORMAL); snprintf(msg,512,_("Trademark :%s"),dgtnixQueryString(DGTNIX_TRADEMARK_STRING) ); global.output->append(msg,global.Colors.TextDefault,IM_NORMAL); g_io_add_watch (g_io_channel_unix_new(fd),G_IO_IN ,gtkDgtnixEvent,mainWindow); DgtInit = true; } } void dgtSetBoard(Board *b) { if (DgtInit) DgtBoard = b; } #endif // WITH_DGT_BOARD