1 /*
2
3 eboard - chess client
4 http://www.bergo.eng.br/eboard
5 https://github.com/fbergo/eboard
6 Copyright (C) 2000-2016 Felipe Bergo
7 fbergo/at/gmail/dot/com
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22
23 */
24
25 #include <iostream>
26 #include <string.h>
27 #include "bugpane.h"
28 #include "global.h"
29 #include "eboard.h"
30
31 string BugPane::BugTell;
32
33 // ---------------- BareBoard
34
BareBoard()35 BareBoard::BareBoard() : WidgetProxy() {
36 global.addPieceClient(this);
37 Names[0]=_("None");
38 Names[1]=_("None");
39
40 widget=gtk_drawing_area_new();
41 gtk_widget_set_events(widget,GDK_EXPOSURE_MASK);
42 gtk_signal_connect(GTK_OBJECT(widget),"expose_event",
43 GTK_SIGNAL_FUNC(bareboard_expose),(gpointer)this);
44
45 pixbuf=0;
46
47 pset=0;
48 if (global.pieceset)
49 pset=new PieceSet(global.pieceset);
50
51 clock.setHost(this);
52
53 upending=false;
54 frozen=0;
55 }
56
~BareBoard()57 BareBoard::~BareBoard() {
58 global.removePieceClient(this);
59 if (pixbuf)
60 gdk_pixmap_unref(pixbuf);
61 }
62
setPosition(Position & pos)63 void BareBoard::setPosition(Position &pos) {
64 position = pos;
65 repaint();
66 }
67
addPTell(char * text)68 void BareBoard::addPTell(char *text) {
69 PTells.push_back(string(text));
70 if (PTells.size() > 15) PTells.pop_front();
71 }
72
setWhite(char * name)73 void BareBoard::setWhite(char *name) {
74 Names[0]=name;
75 repaint();
76 }
77
setBlack(char * name)78 void BareBoard::setBlack(char *name) {
79 Names[1]=name;
80 repaint();
81 }
82
update()83 void BareBoard::update() {
84 if (frozen>0)
85 upending=true;
86 else {
87 repaint();
88 upending=false;
89 }
90 }
91
updateClock()92 void BareBoard::updateClock() {
93 repaint();
94 }
95
setClock2(int wmsecs,int bmsecs,int actv,int cdown)96 void BareBoard::setClock2(int wmsecs,int bmsecs,int actv,int cdown) {
97 clock.setClock2(wmsecs,bmsecs,actv,cdown);
98 update();
99 }
100
pieceSetChanged()101 void BareBoard::pieceSetChanged() {
102 if (pset)
103 delete pset;
104 pset = new PieceSet(global.pieceset);
105 update();
106 }
107
reloadPieceSet()108 void BareBoard::reloadPieceSet() {
109 if (pset)
110 delete pset;
111 pset = new PieceSet(global.pieceset);
112 }
113
freeze()114 void BareBoard::freeze() {
115 ++frozen;
116 }
117
thaw()118 void BareBoard::thaw() {
119 --frozen;
120 if ( (frozen<1) && upending )
121 update();
122 }
123
bareboard_expose(GtkWidget * widget,GdkEventExpose * ee,gpointer data)124 gboolean bareboard_expose(GtkWidget *widget,GdkEventExpose *ee,
125 gpointer data) {
126
127 BareBoard *me;
128 int i,j,k,ww,wh,zh,x,y=0;
129 int sqside;
130 GdkGC *gc;
131 char z[256],t[64];
132 list<string>::iterator pti;
133 rgbptr tmp;
134 int rowsz;
135 bool flip;
136
137 static piece stock[5]={PAWN,ROOK,KNIGHT,BISHOP,QUEEN};
138
139 flip=global.BoardList.front()->effectiveFlip();
140 flip=!flip;
141
142 me=(BareBoard *)data;
143
144 gdk_window_get_size(widget->window,&ww,&wh);
145 zh=wh;
146 sqside=ww/8;
147
148 if ( (!global.UseVectorPieces) && (me->pset->extruded) )
149 wh-=wh/16;
150
151 if (wh<ww) sqside=wh/8;
152
153 if (me->pixbuf) {
154 if (ww != me->pixw || wh != me->pixh) {
155 gdk_pixmap_unref(me->pixbuf);
156 me->pixbuf=0;
157 me->pixw=ww;
158 me->pixh=wh;
159 }
160 }
161
162 if (! me->pixbuf)
163 me->pixbuf=gdk_pixmap_new(widget->window,ww,wh,-1);
164
165 gc=gdk_gc_new(me->pixbuf);
166 gdk_rgb_gc_set_foreground(gc,0);
167 gdk_draw_rectangle(me->pixbuf,gc,TRUE,0,0,ww,wh);
168
169 me->C.prepare(widget,me->pixbuf,gc,0,0,ww,wh);
170 me->C.setFont(0,global.InfoFont);
171
172 if (sqside > 8) {
173
174 if (global.UseVectorPieces) {
175 global.vpieces.drawSquares(me->pixbuf,gc,sqside);
176
177 for(i=0;i<8;i++)
178 for(j=0;j<8;j++)
179 global.vpieces.drawPiece(me->pixbuf,gc,sqside,
180 i*sqside, j*sqside,
181 me->position.getPiece(flip?7-i:i,
182 flip?j:7-j));
183 } else {
184 if (me->pset->extruded) y=sqside/2;
185 if (me->pset->side != sqside) {
186 me->reloadPieceSet();
187 me->pset->scale(sqside);
188 }
189
190 rowsz=sqside*8;
191 tmp=(rgbptr)g_malloc(rowsz * (rowsz+sqside/2) * 4);
192
193
194 me->pset->beginQueueing();
195 for(i=0;i<8;i++)
196 for(j=0;j<8;j++)
197 me->pset->drawPieceAndSquare(me->position.getPiece(flip?7-i:i,
198 flip?j:7-j),
199 tmp, i*sqside , y+j*sqside, rowsz,
200 (i+j)%2);
201 me->pset->endQueueing();
202
203 gdk_draw_rgb_image(me->pixbuf, gc, 0, 0, rowsz, rowsz+y,
204 GDK_RGB_DITHER_NORMAL, tmp, rowsz*3);
205
206 g_free(tmp);
207
208 }
209
210
211 x=sqside*8+10;
212
213 int fh = me->C.fontHeight(0);
214
215 me->C.setColor(0xffffff);
216 me->C.drawString(x,10,0,_("Bughouse: Partner Game"));
217 me->C.drawString(x+1,10,0,_("Bughouse: Partner Game"));
218
219 // white's clock
220
221 if (me->clock.getActive() == -1) {
222 //gdk_draw_rectangle(me->pixbuf,gc,TRUE,x-5,(flip?40:zh-5-fh), 150, 20);
223 me->C.setColor(0xff8800);
224 }
225
226 me->clockString(me->clock.getValue2(0),t,64);
227 snprintf(z,256,_("White: %s - %s"),me->Names[0].c_str(),t);
228
229 me->C.drawString(x,flip?40:zh-5-fh,0,z);
230
231 // black's clock
232
233 me->C.setColor(0xffffff);
234 if (me->clock.getActive() == 1) {
235 //gdk_draw_rectangle(me->pixbuf,gc,TRUE,x-5,(flip?zh-5-fh:40), 150, 20);
236 me->C.setColor(0xff8800);
237 }
238
239 me->clockString(me->clock.getValue2(1),t,64);
240 snprintf(z,256,_("Black: %s - %s"),me->Names[1].c_str(),t);
241 me->C.drawString(x,flip?zh-5-fh:40,0,z);
242
243 // paint stock
244
245 // white's stock
246
247 x=sqside*8+10;
248 for(i=0;i<5;i++) {
249 k=me->position.getStockCount(stock[i]|WHITE);
250 for(j=0;j<k;j++) {
251 global.vpieces.drawPiece(me->pixbuf,gc,sqside,x,flip?45:zh-5-sqside-20,
252 stock[i]|WHITE);
253 x+=sqside+2;
254 }
255 }
256
257 // black's stock
258
259 x=sqside*8+10;
260 for(i=0;i<5;i++) {
261 k=me->position.getStockCount(stock[i]|BLACK);
262 for(j=0;j<k;j++) {
263 global.vpieces.drawPiece(me->pixbuf,gc,sqside,x,flip?zh-5-sqside-20:45,
264 stock[i]|BLACK);
265 x+=sqside+2;
266 }
267 }
268
269 // paint ptells
270
271 x=sqside*8+10;
272 me->C.setColor(global.Colors.TextBright);
273 me->C.drawString(x,40+sqside,0,_("Partner Tells:"));
274
275 if (!me->PTells.empty()) {
276 me->C.setColor(global.Colors.PrivateTell);
277 i=zh-20-5-sqside;
278
279 pti=me->PTells.end();
280 for(pti--;i>(59+sqside);i-=20, pti--) {
281 me->C.drawString(x,i,0,(*pti).c_str() );
282 if (pti == me->PTells.begin())
283 break;
284 }
285 }
286 }
287 gdk_gc_destroy(gc);
288 gc=gdk_gc_new(widget->window);
289 gdk_draw_pixmap(widget->window,gc,me->pixbuf,0,0,0,0,ww,zh);
290 gdk_gc_destroy(gc);
291 return 1;
292 }
293
294 // ---------------- BugPane
295
BugPane()296 BugPane::BugPane() {
297 GtkWidget *v, *tbl, *qb[18];
298 GdkColor gray[5];
299 GtkStyle *style;
300 int i,c,r;
301 static const char *stuff[18]={"---","--","-","+","++","+++",
302 "P","N","B","R","Q","Diag",
303 "Sit","Go","Fast","Hard","Dead","Safe"};
304
305
306 widget = gtk_hbox_new(FALSE,0);
307
308 board = new BareBoard();
309 board->show();
310
311 gtk_box_pack_start(GTK_BOX(widget), board->widget, TRUE,TRUE, 0);
312
313 // vbox
314 v=gtk_vbox_new(FALSE,0);
315 gtk_box_pack_start(GTK_BOX(widget), v, FALSE, TRUE, 0);
316
317 // table
318 tbl=gtk_table_new(6,3,FALSE);
319 gray[0].red=gray[0].green=gray[0].blue=0xaaaa;
320 gray[1].red=gray[1].green=gray[1].blue=0x8888;
321 gray[2].red=gray[2].green=gray[2].blue=0xcccc;
322 gray[3].red=gray[3].green=gray[3].blue=0x8888;
323 gray[4].red=gray[4].green=gray[4].blue=0xaaaa;
324 style=gtk_style_copy( gtk_widget_get_default_style() );
325 for(i=0;i<5;i++)
326 style->bg[i]=gray[i];
327
328 // buttons
329 for(i=0;i<18;i++) {
330
331 qb[i]=gtk_button_new_with_label(stuff[i]);
332 if (i<6)
333 gtk_widget_set_style(qb[i],style);
334
335 c=i/6;
336 r=i%6;
337 gtk_table_attach_defaults(GTK_TABLE(tbl),qb[i],c,c+1,r,r+1);
338 gshow(qb[i]);
339 gtk_signal_connect(GTK_OBJECT(qb[i]),"clicked",
340 GTK_SIGNAL_FUNC(bug_ptell),(gpointer)(stuff[i]));
341 }
342
343 gtk_box_pack_start(GTK_BOX(v), tbl, FALSE, FALSE, 0);
344
345 Gtk::show(tbl,v,NULL);
346 }
347
stopClock()348 void BugPane::stopClock() {
349 board->setClock2(0,0,0,1);
350 }
351
reset()352 void BugPane::reset() {
353 Position p;
354
355 freeze();
356 board->setClock2(0,0,0,1);
357 board->setPosition(p);
358 board->setWhite(_("None"));
359 board->setBlack(_("None"));
360 thaw();
361
362 }
363
addBugText(char * text)364 void BugPane::addBugText(char *text) {
365 board->addPTell(text);
366 board->update();
367 }
368
setPlayerNames(char * white,char * black)369 void BugPane::setPlayerNames(char *white, char *black) {
370 board->setWhite(white);
371 board->setBlack(black);
372 board->update();
373 }
374
setPosition(Position & pos)375 void BugPane::setPosition(Position &pos) {
376 board->setPosition(pos);
377 board->update();
378 }
379
setClock2(int wmsecs,int bmsecs,int actv,int cdown)380 void BugPane::setClock2(int wmsecs,int bmsecs,int actv,int cdown) {
381 board->setClock2(wmsecs,bmsecs,actv,cdown);
382 }
383
freeze()384 void BugPane::freeze() { board->freeze(); }
thaw()385 void BugPane::thaw() { board->thaw(); }
386
bug_ptell(GtkWidget * b,gpointer data)387 void bug_ptell(GtkWidget *b,gpointer data) {
388 char z[256],x[256],c;
389
390 g_strlcpy(z,(char *)data,256);
391
392 if ((z[0]=='-')||(z[0]=='+')) {
393 BugPane::BugTell=z;
394 return;
395 } else {
396 if (BugPane::BugTell.empty())
397 BugPane::BugTell=z;
398 else {
399 g_strlcpy(x,BugPane::BugTell.c_str(),256);
400 c=x[strlen(x)-1];
401 if ((c=='+')||(c=='-'))
402 BugPane::BugTell+=z;
403 else
404 BugPane::BugTell=z;
405 }
406 }
407
408 if (global.protocol) {
409 snprintf(z,256,"ptell %s",BugPane::BugTell.c_str());
410 global.protocol->sendUserInput(z);
411 }
412 }
413