summaryrefslogtreecommitdiff
path: root/apps/plugins/chessbox/chessbox.c
diff options
context:
space:
mode:
authorHristo Kovachev <bger@rockbox.org>2006-02-22 14:24:54 +0000
committerHristo Kovachev <bger@rockbox.org>2006-02-22 14:24:54 +0000
commit91522721f4a6f4449e14e1b3ccb9f6f2add5d814 (patch)
treedbb2ee4d9e4ee752f8eaf6081204be2f44f20fa8 /apps/plugins/chessbox/chessbox.c
parentb12bcecb297ab8408b25bc9e539d78fa92e6589e (diff)
downloadrockbox-91522721f4a6f4449e14e1b3ccb9f6f2add5d814.tar.gz
rockbox-91522721f4a6f4449e14e1b3ccb9f6f2add5d814.zip
New chessbox plugin by Miguel A. ArГ©valo, based on GNU Chess v2
Not built yet because of a missing dependancy with the pieces' bitmaps. Someone with Makefile knowledge, please, look at it! git-svn-id: svn://svn.rockbox.org/rockbox/trunk@8778 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/plugins/chessbox/chessbox.c')
-rw-r--r--apps/plugins/chessbox/chessbox.c485
1 files changed, 485 insertions, 0 deletions
diff --git a/apps/plugins/chessbox/chessbox.c b/apps/plugins/chessbox/chessbox.c
new file mode 100644
index 0000000000..60dff81c31
--- /dev/null
+++ b/apps/plugins/chessbox/chessbox.c
@@ -0,0 +1,485 @@
1/***************************************************************************
2* __________ __ ___.
3* Open \______ \ ____ ____ | | _\_ |__ _______ ___
4* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7* \/ \/ \/ \/ \/
8*
9* Copyright (C) 2006 Miguel A. Arévalo
10* Color graphics from eboard
11* GNUChess v2 chess engine Copyright (c) 1988 John Stanback
12*
13* All files in this archive are subject to the GNU General Public License.
14* See the file COPYING in the source tree root for full license agreement.
15*
16* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17* KIND, either express or implied.
18*
19****************************************************************************/
20
21#include "plugin.h"
22
23#ifdef HAVE_LCD_BITMAP
24
25#include "gnuchess.h"
26
27/* type definitions */
28struct cb_command {
29 int type;
30 char mv_s[5];
31 unsigned short mv;
32};
33
34/* global rockbox api */
35static struct plugin_api* rb;
36
37/* External bitmaps */
38extern const fb_data chessbox_pieces[];
39
40
41PLUGIN_HEADER
42
43/* button definitions */
44#if (CONFIG_KEYPAD == IPOD_3G_PAD) || (CONFIG_KEYPAD == IPOD_4G_PAD)
45#define CB_SELECT BUTTON_SELECT
46#define CB_UP BUTTON_SCROLL_BACK
47#define CB_DOWN BUTTON_SCROLL_FWD
48#define CB_LEFT BUTTON_LEFT
49#define CB_RIGHT BUTTON_RIGHT
50#define CB_PLAY BUTTON_PLAY
51#define CB_LEVEL BUTTON_MENU
52#define CB_QUIT BUTTON_REL
53
54#elif CONFIG_KEYPAD == IAUDIO_X5_PAD
55#define CB_SELECT BUTTON_MENU
56#define CB_UP BUTTON_UP
57#define CB_DOWN BUTTON_DOWN
58#define CB_LEFT BUTTON_LEFT
59#define CB_RIGHT BUTTON_RIGHT
60#define CB_PLAY BUTTON_PLAY
61#define CB_LEVEL BUTTON_REC
62#define CB_QUIT BUTTON_POWER
63
64#elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || (CONFIG_KEYPAD == IRIVER_H300_PAD)
65#define CB_SELECT BUTTON_SELECT
66#define CB_UP BUTTON_UP
67#define CB_DOWN BUTTON_DOWN
68#define CB_LEFT BUTTON_LEFT
69#define CB_RIGHT BUTTON_RIGHT
70#define CB_PLAY BUTTON_ON
71#define CB_LEVEL BUTTON_MODE
72#define CB_QUIT BUTTON_OFF
73
74#elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD
75#define CB_SELECT BUTTON_SELECT
76#define CB_UP BUTTON_UP
77#define CB_DOWN BUTTON_DOWN
78#define CB_LEFT BUTTON_LEFT
79#define CB_RIGHT BUTTON_RIGHT
80#define CB_PLAY BUTTON_PLAY
81#define CB_LEVEL BUTTON_EQ
82#define CB_QUIT BUTTON_MODE
83
84#elif CONFIG_KEYPAD == RECORDER_PAD
85#define CB_SELECT BUTTON_PLAY
86#define CB_UP BUTTON_UP
87#define CB_DOWN BUTTON_DOWN
88#define CB_LEFT BUTTON_LEFT
89#define CB_RIGHT BUTTON_RIGHT
90#define CB_PLAY BUTTON_ON
91#define CB_LEVEL BUTTON_F1
92#define CB_QUIT BUTTON_OFF
93
94#elif CONFIG_KEYPAD == ONDIO_PAD
95#define CB_SELECT (BUTTON_MENU|BUTTON_REL)
96#define CB_UP BUTTON_UP
97#define CB_DOWN BUTTON_DOWN
98#define CB_LEFT BUTTON_LEFT
99#define CB_RIGHT BUTTON_RIGHT
100#define CB_PLAY BUTTON_MENU
101#define CB_LEVEL (BUTTON_MENU|BUTTON_OFF)
102#define CB_QUIT BUTTON_OFF
103
104#else
105 #error CHESSBOX: Unsupported keypad
106#endif
107
108/* use 30x30 tiles */
109#if (LCD_HEIGHT >= 240) && (LCD_WIDTH >= 240)
110#define TILE_WIDTH 30
111#define TILE_HEIGHT 30
112/* use 22x22 tiles */
113#elif (LCD_HEIGHT >= 176) && (LCD_WIDTH >= 176)
114#define TILE_WIDTH 22
115#define TILE_HEIGHT 22
116/* use 16x16 tiles */
117#elif (LCD_HEIGHT >= 128) && (LCD_WIDTH >= 128)
118#define TILE_WIDTH 16
119#define TILE_HEIGHT 16
120/* use 8x8 tiles */
121#elif (LCD_HEIGHT >= 64) && (LCD_WIDTH >= 64)
122#define TILE_WIDTH 8
123#define TILE_HEIGHT 8
124#else
125 #error BEJEWELED: Unsupported LCD
126#endif
127
128/* Calculate Offsets */
129#define XOFS ((LCD_WIDTH-8*TILE_WIDTH)/2)
130#define YOFS ((LCD_HEIGHT-8*TILE_HEIGHT)/2)
131
132/* commands enum */
133#define COMMAND_MOVE 1
134#define COMMAND_PLAY 2
135#define COMMAND_LEVEL 3
136/*#define COMMAND_RESTART 4*/
137#define COMMAND_QUIT 5
138
139/* ---- Get the board column and row (e2 f.e.) for a physical x y ---- */
140void xy2cr ( short x, short y, short *c, short *r ) {
141 if (computer == black ) {
142 *c = x ;
143 *r = y ;
144 } else {
145 *c = 7 - x ;
146 *r = 7 - y ;
147 }
148}
149
150/* ---- get physical x y for a board column and row (e2 f.e.) ---- */
151void cr2xy ( short c, short r, short *x, short *y ) {
152 if ( computer == black ) {
153 *x = c ;
154 *y = r ;
155 } else {
156 *x = 7 - c ;
157 *y = 7 - r ;
158 }
159}
160
161/* ---- Draw a complete board ---- */
162static void cb_drawboard (void) {
163 short r , c , x , y ;
164 short l , piece , p_color ;
165 int b_color=1;
166
167 rb->lcd_clear_display();
168
169 for (r = 0; r < 8; r++) {
170 for (c = 0; c < 8; c++) {
171 l = locn[r][c];
172 piece = board[l] ;
173 p_color = color[l] ;
174 cr2xy ( c , r , &x , &y );
175 if ( piece == no_piece ) {
176 rb->lcd_bitmap_part ( chessbox_pieces , 0 ,
177 TILE_HEIGHT * b_color ,
178 TILE_WIDTH ,
179 XOFS + x*TILE_WIDTH ,
180 YOFS + ( 7 - y )*TILE_HEIGHT ,
181 TILE_WIDTH ,
182 TILE_HEIGHT );
183 } else {
184 rb->lcd_bitmap_part ( chessbox_pieces ,
185 0 ,
186 2 * TILE_HEIGHT +
187 4 * TILE_HEIGHT * ( piece - 1 ) +
188 2 * TILE_HEIGHT * p_color +
189 TILE_HEIGHT * b_color ,
190 TILE_WIDTH ,
191 XOFS + x*TILE_WIDTH ,
192 YOFS + (7 - y)*TILE_HEIGHT ,
193 TILE_WIDTH ,
194 TILE_HEIGHT );
195 }
196 b_color = (b_color == 1) ? 0 : 1 ;
197 }
198 b_color = (b_color == 1) ? 0 : 1 ;
199 }
200
201 /* draw board limits */
202 if ( LCD_WIDTH > TILE_WIDTH*8 ) {
203 rb->lcd_set_drawmode ( DRMODE_FG );
204 rb->lcd_drawline ( XOFS - 1 , YOFS ,
205 XOFS - 1 , YOFS + TILE_HEIGHT*8 );
206 rb->lcd_drawline ( XOFS + 8*TILE_WIDTH , YOFS ,
207 XOFS + 8*TILE_WIDTH , YOFS + TILE_HEIGHT*8 );
208 }
209 if ( LCD_HEIGHT > TILE_HEIGHT*8 ) {
210 rb->lcd_set_drawmode ( DRMODE_FG );
211 rb->lcd_drawline ( XOFS , YOFS - 1 ,
212 XOFS + TILE_WIDTH*8 , YOFS - 1 );
213 rb->lcd_drawline ( XOFS , YOFS + TILE_HEIGHT*8 ,
214 XOFS + 8*TILE_WIDTH , YOFS + TILE_HEIGHT*8 );
215 }
216 rb->lcd_update();
217}
218
219/* ---- Switch mark on board ---- */
220void cb_switch ( short x , short y ) {
221 rb->lcd_set_drawmode ( DRMODE_COMPLEMENT );
222 rb->lcd_drawrect ( XOFS + x*TILE_WIDTH + 1 ,
223 YOFS + ( 7 - y )*TILE_HEIGHT +1 ,
224 TILE_WIDTH-2 , TILE_HEIGHT-2 );
225 rb->lcd_update();
226}
227
228/* ---- increase playing level ---- */
229void cb_levelup ( void ) {
230 Level ++;
231 if ( Level == 8 ) Level = 1;
232 switch (Level) {
233 case 1 :
234 TCmoves = 60;
235 TCminutes = 5;
236 rb->splash ( 50 , true , "Level 1: 60 moves / 5 min" );
237 break;
238 case 2 :
239 TCmoves = 60;
240 TCminutes = 15;
241 rb->splash ( 50 , true , "Level 2: 60 moves / 15 min" );
242 break;
243 case 3 :
244 TCmoves = 60;
245 TCminutes = 30;
246 rb->splash ( 50 , true , "Level 3: 60 moves / 30 min" );
247 break;
248 case 4 :
249 TCmoves = 40;
250 TCminutes = 30;
251 rb->splash ( 50 , true , "Level 4: 40 moves / 30 min" );
252 break;
253 case 5 :
254 TCmoves = 40;
255 TCminutes = 60;
256 rb->splash ( 50 , true , "Level 5: 40 moves / 60 min" );
257 break;
258 case 6 :
259 TCmoves = 40;
260 TCminutes = 120;
261 rb->splash ( 50 , true , "Level 6: 40 moves / 120 min" );
262 break;
263 case 7 :
264 TCmoves = 40;
265 TCminutes = 240;
266 rb->splash ( 50 , true , "Level 7: 40 moves / 240 min" );
267 break;
268 case 8 :
269 TCmoves = 1;
270 TCminutes = 15;
271 rb->splash ( 50 , true , "Level 8: 1 move / 15 min" );
272 break;
273 case 9 :
274 TCmoves = 1;
275 TCminutes = 60;
276 rb->splash ( 50 , true , "Level 9: 1 move / 60 min" );
277 break;
278 case 10 :
279 TCmoves = 1;
280 TCminutes = 600;
281 rb->splash ( 50 , true , "Level 10: 1 move / 600 min" );
282 break;
283 }
284 TCflag = (TCmoves > 1);
285 SetTimeControl();
286};
287
288/* ---- main user loop ---- */
289struct cb_command cb_getcommand (void) {
290 static short x = 4 , y = 4 ;
291 short c , r , l;
292 int button = BUTTON_NONE;
293 int marked = false , from_marked = false ;
294 short marked_x = 0 , marked_y = 0 ;
295 struct cb_command result;
296
297 cb_switch ( x , y );
298 /* main loop */
299 while ( true ) {
300 button = rb->button_get(true);
301 switch (button) {
302 case CB_QUIT:
303 result.type = COMMAND_QUIT;
304 return result;
305/* case CB_RESTART:
306 result.type = COMMAND_RESTART;
307 return result;*/
308 case CB_LEVEL:
309 result.type = COMMAND_LEVEL;
310 return result;
311 case CB_PLAY:
312 result.type = COMMAND_PLAY;
313 return result;
314 case CB_UP:
315 if ( !from_marked ) cb_switch ( x , y );
316 y++;
317 if ( y == 8 ) {
318 y = 0;
319 x--;
320 if ( x < 0 ) x = 7;
321 }
322 if ( marked && ( marked_x == x ) && ( marked_y == y ) ) {
323 from_marked = true ;
324 } else {
325 from_marked = false ;
326 cb_switch ( x , y );
327 }
328 break;
329 case CB_DOWN:
330 if ( !from_marked ) cb_switch ( x , y );
331 y--;
332 if ( y < 0 ) {
333 y = 7;
334 x++;
335 if ( x == 8 ) x = 0;
336 }
337 if ( marked && ( marked_x == x ) && ( marked_y == y ) ) {
338 from_marked = true ;
339 } else {
340 from_marked = false ;
341 cb_switch ( x , y );
342 }
343 break;
344 case CB_LEFT:
345 if ( !from_marked ) cb_switch ( x , y );
346 x--;
347 if ( x < 0 ) {
348 x = 7;
349 y++;
350 if ( y == 8 ) y = 0;
351 }
352 if ( marked && ( marked_x == x ) && ( marked_y == y ) ) {
353 from_marked = true ;
354 } else {
355 from_marked = false ;
356 cb_switch ( x , y );
357 }
358 break;
359 case CB_RIGHT:
360 if ( !from_marked ) cb_switch ( x , y );
361 x++;
362 if ( x == 8 ) {
363 x = 0;
364 y--;
365 if ( y < 0 ) y = 7;
366 }
367 if ( marked && ( marked_x == x ) && ( marked_y == y ) ) {
368 from_marked = true ;
369 } else {
370 from_marked = false ;
371 cb_switch ( x , y );
372 }
373 break;
374 case CB_SELECT:
375 if ( !marked ) {
376 xy2cr ( x , y , &c , &r );
377 l = locn[r][c];
378 if ( ( color[l]!=computer ) && ( board[l]!=no_piece ) ) {
379 marked = true;
380 from_marked = true ;
381 marked_x = x;
382 marked_y = y;
383 }
384 } else {
385 if ( ( marked_x == x ) && ( marked_y == y ) ) {
386 marked = false;
387 from_marked = false;
388 } else {
389 xy2cr ( marked_x , marked_y , &c , &r );
390 result.mv_s[0] = 'a' + c;
391 result.mv_s[1] = '1' + r;
392 xy2cr ( x , y , &c , &r );
393 result.mv_s[2] = 'a' + c;
394 result.mv_s[3] = '1' + r;
395 result.mv_s[4] = '\00';
396 result.type = COMMAND_MOVE;
397 return result;
398 }
399 }
400 break;
401 }
402 }
403
404}
405
406/*****************************************************************************
407* plugin entry point.
408******************************************************************************/
409enum plugin_status plugin_start(struct plugin_api* api, void* parameter) {
410 struct cb_command command;
411 /* init status */
412 bool exit = false;
413
414 /* plugin init */
415 (void)parameter;
416 rb = api;
417 /* end of plugin init */
418
419 /* load opening book, soon */
420
421 /* init board */
422 GNUChess_Initialize();
423
424 /* draw the board */
425 /* I don't like configscreens, start game inmediatly */
426 cb_drawboard();
427
428 while (!exit) {
429 if ( mate ) {
430 rb->splash ( 500 , true , "Checkmate!" );
431 rb->button_get(true);
432 GNUChess_Initialize();
433 cb_drawboard();
434 }
435 command = cb_getcommand ();
436 switch (command.type) {
437 case COMMAND_MOVE:
438 if ( ! VerifyMove ( command.mv_s , 0 , &command.mv ) ) {
439 rb->splash ( 50 , true , "Illegal move!" );
440 cb_drawboard();
441 } else {
442 cb_drawboard();
443 rb->splash ( 0 , true , "Thinking..." );
444#ifdef HAVE_ADJUSTABLE_CPU_FREQ
445 rb->cpu_boost ( true );
446#endif
447 SelectMove ( computer , 0 );
448#ifdef HAVE_ADJUSTABLE_CPU_FREQ
449 rb->cpu_boost ( false );
450#endif
451 cb_drawboard();
452 }
453 break;
454/* case COMMAND_RESTART:
455 GNUChess_Initialize();
456 cb_drawboard();
457 break;*/
458 case COMMAND_PLAY:
459 opponent = !opponent; computer = !computer;
460 rb->splash ( 0 , true , "Thinking..." );
461#ifdef HAVE_ADJUSTABLE_CPU_FREQ
462 rb->cpu_boost ( true );
463#endif
464 SelectMove ( computer , 0 );
465#ifdef HAVE_ADJUSTABLE_CPU_FREQ
466 rb->cpu_boost ( false );
467#endif
468 cb_drawboard();
469 break;
470 case COMMAND_LEVEL:
471 cb_levelup ( );
472 cb_drawboard();
473 break;
474 case COMMAND_QUIT:
475 /*cb_saveposition();*/
476 exit = true;
477 break;
478 }
479 }
480
481 rb->lcd_setfont(FONT_UI);
482 return PLUGIN_OK;
483}
484
485#endif /* HAVE_LCD_BITMAP */