summaryrefslogtreecommitdiff
path: root/apps/plugins/chessbox/chessbox.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/chessbox/chessbox.c')
-rw-r--r--apps/plugins/chessbox/chessbox.c168
1 files changed, 91 insertions, 77 deletions
diff --git a/apps/plugins/chessbox/chessbox.c b/apps/plugins/chessbox/chessbox.c
index 52a1f2789b..397fd0e559 100644
--- a/apps/plugins/chessbox/chessbox.c
+++ b/apps/plugins/chessbox/chessbox.c
@@ -74,6 +74,8 @@ extern const fb_data chessbox_pieces[];
74#define COMMAND_SELECT 10 74#define COMMAND_SELECT 10
75#define COMMAND_NEXT 11 75#define COMMAND_NEXT 11
76#define COMMAND_PREV 12 76#define COMMAND_PREV 12
77#define COMMAND_VIEW 13
78#define COMMAND_RETURN 14
77 79
78short plugin_mode; 80short plugin_mode;
79 81
@@ -360,7 +362,7 @@ static void cb_saveposition_dbg ( void )
360 sizeof(temp)); 362 sizeof(temp));
361 rb->write(fd, buf, ch_ct); 363 rb->write(fd, buf, ch_ct);
362 } 364 }
363 for (i = 0; i <= GameCnt; i++) { 365 for (i = 0; i < ((GameCnt + 1) & 0xFF); i++) {
364 ch_ct = rb->snprintf(buf,31,"GameCt %d, %d bytes\n",i, 366 ch_ct = rb->snprintf(buf,31,"GameCt %d, %d bytes\n",i,
365 sizeof(GameCnt)); 367 sizeof(GameCnt));
366 rb->write(fd, buf, ch_ct); 368 rb->write(fd, buf, ch_ct);
@@ -399,17 +401,21 @@ static void cb_saveposition_dbg ( void )
399} 401}
400#endif 402#endif
401 403
402/* ---- Save current position ---- */ 404/* ---- Save current position and game history ---- */
403static void cb_saveposition ( void ) { 405static void cb_saveposition ( struct pgn_game_node* game ) {
404 int fd; 406 int fd;
405 short sq,i,c; 407 short sq,i,c;
406 unsigned short temp; 408 unsigned short temp;
409 struct pgn_ply_node *ply;
410 char buf[4];
411
407#ifdef CHESSBOX_SAVE_FILE_DBG 412#ifdef CHESSBOX_SAVE_FILE_DBG
408 cb_saveposition_dbg(); 413 cb_saveposition_dbg();
409#endif 414#endif
415
410 rb->splash ( 0 , ID2P(LANG_CHESSBOX_SAVING_POSITION) ); 416 rb->splash ( 0 , ID2P(LANG_CHESSBOX_SAVING_POSITION) );
411 417
412 fd = rb->open(SAVE_FILE, O_WRONLY|O_CREAT, 0666); 418 fd = rb->open(SAVE_FILE, O_WRONLY|O_CREAT|O_TRUNC, 0666);
413 419
414 computer++; rb->write(fd, &(computer), sizeof(computer)); computer--; 420 computer++; rb->write(fd, &(computer), sizeof(computer)); computer--;
415 opponent++; rb->write(fd, &(opponent), sizeof(opponent)); opponent--; 421 opponent++; rb->write(fd, &(opponent), sizeof(opponent)); opponent--;
@@ -438,7 +444,9 @@ static void cb_saveposition ( void ) {
438 temp = 256*board[sq] + c ; 444 temp = 256*board[sq] + c ;
439 rb->write(fd, &(temp), sizeof(temp)); 445 rb->write(fd, &(temp), sizeof(temp));
440 } 446 }
441 for (i = 0; i <= GameCnt; i++) { 447 c = GameCnt;
448 rb->write(fd, &(c), sizeof(c));
449 for (i = 0; i < ((GameCnt + 1) & 0xFF); i++) {
442 if (GameList[i].color == neutral) 450 if (GameList[i].color == neutral)
443 c = 0; 451 c = 0;
444 else 452 else
@@ -451,14 +459,24 @@ static void cb_saveposition ( void ) {
451 rb->write(fd, &(GameList[i].piece), sizeof(GameList[i].piece)); 459 rb->write(fd, &(GameList[i].piece), sizeof(GameList[i].piece));
452 rb->write(fd, &(c), sizeof(c)); 460 rb->write(fd, &(c), sizeof(c));
453 } 461 }
462 for (ply=game->first_ply; ply!=NULL; ply=ply->next_node) {
463 buf[0] = ply->column_from + 'a';
464 buf[1] = ply->row_from + '1';
465 buf[2] = ply->column_to + 'a';
466 buf[3] = ply->row_to + '1';
467 rb->write(fd, buf, 4);
468 }
454 rb->close(fd); 469 rb->close(fd);
455} 470}
456 471
457/* ---- Restore saved position ---- */ 472/* ---- Restore saved position and game history ---- */
458static void cb_restoreposition ( void ) { 473static struct pgn_game_node* cb_restoreposition ( void ) {
459 int fd; 474 int fd;
460 short sq; 475 short sq;
461 unsigned short m; 476 unsigned short m;
477 short n;
478 char buf[4];
479 struct pgn_game_node* game = pgn_init_game();
462 480
463 if ( (fd = rb->open(SAVE_FILE, O_RDONLY)) >= 0 ) { 481 if ( (fd = rb->open(SAVE_FILE, O_RDONLY)) >= 0 ) {
464 rb->splash ( 0 , ID2P(LANG_CHESSBOX_LOADING_POSITION) ); 482 rb->splash ( 0 , ID2P(LANG_CHESSBOX_LOADING_POSITION) );
@@ -492,9 +510,12 @@ static void cb_restoreposition ( void ) {
492 else 510 else
493 --color[sq]; 511 --color[sq];
494 } 512 }
495 GameCnt = MAX_GAME_CNT - 1; /*uchar rollsover to 0 after 255*/ 513 rb->read(fd, &(n), sizeof(n));
496 while (rb->read(fd, &(GameList[++GameCnt].gmove), 514 n++;
497 sizeof(GameList[GameCnt].gmove)) > 0) { 515 n &= 0xFF;
516 for (GameCnt = 0; GameCnt < n; GameCnt++) {
517 rb->read(fd, &(GameList[GameCnt].gmove),
518 sizeof(GameList[GameCnt].gmove));
498 rb->read(fd, &(GameList[GameCnt].score), 519 rb->read(fd, &(GameList[GameCnt].score),
499 sizeof(GameList[GameCnt].score)); 520 sizeof(GameList[GameCnt].score));
500 rb->read(fd, &(GameList[GameCnt].depth), 521 rb->read(fd, &(GameList[GameCnt].depth),
@@ -506,7 +527,7 @@ static void cb_restoreposition ( void ) {
506 rb->read(fd, &(GameList[GameCnt].piece), 527 rb->read(fd, &(GameList[GameCnt].piece),
507 sizeof(GameList[GameCnt].piece)); 528 sizeof(GameList[GameCnt].piece));
508 rb->read(fd, &(GameList[GameCnt].color), 529 rb->read(fd, &(GameList[GameCnt].color),
509 sizeof(GameList[GameCnt].color)); 530 sizeof(GameList[GameCnt].color));
510 if (GameList[GameCnt].color == 0) 531 if (GameList[GameCnt].color == 0)
511 GameList[GameCnt].color = neutral; 532 GameList[GameCnt].color = neutral;
512 else 533 else
@@ -516,47 +537,45 @@ static void cb_restoreposition ( void ) {
516 if (TimeControl.clock[white] > 0) 537 if (TimeControl.clock[white] > 0)
517 TCflag = true; 538 TCflag = true;
518 computer--; opponent--; 539 computer--; opponent--;
540 n = 0;
541 while (rb->read(fd, buf, 4) > 0)
542 pgn_append_ply(game, ((n++) & 1) ? black : white, buf, false);
543 rb->close(fd);
519 } 544 }
520 rb->close(fd);
521 cb_setlevel(Level); 545 cb_setlevel(Level);
522 InitializeStats(); 546 InitializeStats();
523 Sdepth = 0; 547 Sdepth = 0;
548
549 return game;
524} 550}
525 551
526/* ---- show menu in viewer mode---- */ 552/* ---- show menu in viewer mode---- */
527static int cb_menu_viewer(void) 553static int cb_menu_viewer(void)
528{ 554{
529 int selection; 555 int selection;
530 int result = 0;
531 bool menu_quit = false;
532 556
533 MENUITEM_STRINGLIST(menu,"Chessbox Menu",NULL, 557 MENUITEM_STRINGLIST(menu,"Chessbox Menu",NULL,
534 ID2P(LANG_CHESSBOX_MENU_RESTART_GAME), 558 ID2P(LANG_CHESSBOX_MENU_RESTART_GAME),
535 ID2P(LANG_CHESSBOX_MENU_SELECT_OTHER_GAME), 559 ID2P(LANG_CHESSBOX_MENU_SELECT_OTHER_GAME),
560 ID2P(LANG_CHESSBOX_MENU_RESUME_GAME),
561 ID2P(LANG_RETURN),
536 ID2P(LANG_MENU_QUIT)); 562 ID2P(LANG_MENU_QUIT));
537 563
538 while(!menu_quit) 564 switch(rb->do_menu(&menu, &selection, NULL, false))
539 { 565 {
540 switch(rb->do_menu(&menu, &selection, NULL, false)) 566 case 0:
541 { 567 return COMMAND_RESTART;
542 case 0: 568 case 1:
543 menu_quit = true; 569 return COMMAND_SELECT;
544 result = COMMAND_RESTART; 570 case 3:
545 break; 571 return COMMAND_RETURN;
546 case 1: 572 case 4:
547 result = COMMAND_SELECT; 573 return COMMAND_QUIT;
548 menu_quit = true;
549 break;
550 case 2:
551 result = COMMAND_QUIT;
552 menu_quit = true;
553 break;
554 }
555 } 574 }
556 return result; 575 return COMMAND_RESUME;
557} 576}
558 577
559/* ---- get a command in game mode ---- */ 578/* ---- get a command in viewer mode ---- */
560static struct cb_command cb_get_viewer_command (void) { 579static struct cb_command cb_get_viewer_command (void) {
561 int button; 580 int button;
562 struct cb_command result = { 0, {0,0,0,0,0}, 0 }; 581 struct cb_command result = { 0, {0,0,0,0,0}, 0 };
@@ -592,17 +611,18 @@ static struct cb_command cb_get_viewer_command (void) {
592} 611}
593 612
594/* ---- viewer main loop ---- */ 613/* ---- viewer main loop ---- */
595static void cb_start_viewer(char* filename){ 614static bool cb_start_viewer(const char* filename){
596 struct pgn_game_node *first_game, *selected_game; 615 struct pgn_game_node *first_game, *selected_game;
597 struct pgn_ply_node *curr_ply; 616 struct pgn_ply_node *curr_ply;
598 bool exit_game = false; 617 bool exit_game = false;
599 bool exit_viewer = false; 618 bool exit_viewer = false;
619 bool exit_app = false;
600 struct cb_command command; 620 struct cb_command command;
601 621
602 first_game = pgn_list_games(filename); 622 first_game = pgn_list_games(filename);
603 if (first_game == NULL){ 623 if (first_game == NULL){
604 rb->splash ( HZ*2 , ID2P(LANG_CHESSBOX_NO_GAMES) ); 624 rb->splash ( HZ*2 , ID2P(LANG_CHESSBOX_NO_GAMES) );
605 return; 625 return exit_app;
606 } 626 }
607 627
608 do { 628 do {
@@ -759,6 +779,8 @@ static void cb_start_viewer(char* filename){
759 exit_game = true; 779 exit_game = true;
760 break; 780 break;
761 case COMMAND_QUIT: 781 case COMMAND_QUIT:
782 exit_app = true;
783 case COMMAND_RETURN:
762 exit_viewer = true; 784 exit_viewer = true;
763 break; 785 break;
764 } 786 }
@@ -767,57 +789,44 @@ static void cb_start_viewer(char* filename){
767 rb->splash ( HZ*2 , ID2P(LANG_CHESSBOX_PGN_PARSE_ERROR)); 789 rb->splash ( HZ*2 , ID2P(LANG_CHESSBOX_PGN_PARSE_ERROR));
768 } 790 }
769 } while (!exit_viewer); 791 } while (!exit_viewer);
792 return exit_app;
770} 793}
771 794
772/* ---- show menu ---- */ 795/* ---- show menu ---- */
773static int cb_menu(void) 796static int cb_menu(void)
774{ 797{
775 int selection; 798 int selection;
776 int result = 0;
777 bool menu_quit = false;
778 799
779 MENUITEM_STRINGLIST(menu,"Chessbox Menu",NULL, 800 MENUITEM_STRINGLIST(menu,"Chessbox Menu",NULL,
780 ID2P(LANG_CHESSBOX_MENU_NEW_GAME), 801 ID2P(LANG_CHESSBOX_MENU_NEW_GAME),
781 ID2P(LANG_CHESSBOX_MENU_RESUME_GAME), 802 ID2P(LANG_CHESSBOX_MENU_RESUME_GAME),
782 ID2P(LANG_CHESSBOX_MENU_SAVE_GAME), 803 ID2P(LANG_CHESSBOX_MENU_SAVE_GAME),
783 ID2P(LANG_CHESSBOX_MENU_RESTORE_GAME), 804 ID2P(LANG_CHESSBOX_MENU_RESTORE_GAME),
805 ID2P(LANG_CHESSBOX_MENU_VIEW_GAMES),
784#ifdef HAVE_PLAYBACK_CONTROL 806#ifdef HAVE_PLAYBACK_CONTROL
785 ID2P(LANG_PLAYBACK_CONTROL), 807 ID2P(LANG_PLAYBACK_CONTROL),
786#endif 808#endif
787 ID2P(LANG_MENU_QUIT)); 809 ID2P(LANG_MENU_QUIT));
788 810
789 while(!menu_quit) 811 switch(rb->do_menu(&menu, &selection, NULL, false))
790 { 812 {
791 switch(rb->do_menu(&menu, &selection, NULL, false)) 813 case 0:
792 { 814 return COMMAND_RESTART;
793 case 0: 815 case 2:
794 menu_quit = true; 816 return COMMAND_SAVE;
795 result = COMMAND_RESTART; 817 case 3:
796 break; 818 return COMMAND_RESTORE;
797 case 1: 819 case 4:
798 result = COMMAND_RESUME; 820 return COMMAND_VIEW;
799 menu_quit = true; 821 case 5:
800 break;
801 case 2:
802 result = COMMAND_SAVE;
803 menu_quit = true;
804 break;
805 case 3:
806 result = COMMAND_RESTORE;
807 menu_quit = true;
808 break;
809 case 4:
810#ifdef HAVE_PLAYBACK_CONTROL 822#ifdef HAVE_PLAYBACK_CONTROL
811 playback_control(NULL); 823 playback_control(NULL);
812 break; 824 break;
813 case 5: 825 case 6:
814#endif 826#endif
815 result = COMMAND_QUIT; 827 return COMMAND_QUIT;
816 menu_quit = true;
817 break;
818 }
819 } 828 }
820 return result; 829 return COMMAND_RESUME;
821} 830}
822 831
823/* ---- get a command in game mode ---- */ 832/* ---- get a command in game mode ---- */
@@ -1029,12 +1038,8 @@ static void cb_play_game(void) {
1029 /* init board */ 1038 /* init board */
1030 GNUChess_Initialize(); 1039 GNUChess_Initialize();
1031 1040
1032 /* init PGN history data structures */
1033 game = pgn_init_game();
1034
1035 /* restore saved position, if saved */ 1041 /* restore saved position, if saved */
1036 cb_restoreposition(); 1042 game = cb_restoreposition();
1037 /* TODO: save/restore the PGN history of unfinished games */
1038 1043
1039 /* draw the board */ 1044 /* draw the board */
1040 /* I don't like configscreens, start game inmediatly */ 1045 /* I don't like configscreens, start game inmediatly */
@@ -1097,7 +1102,7 @@ static void cb_play_game(void) {
1097 cb_drawboard(); 1102 cb_drawboard();
1098 break; 1103 break;
1099 case COMMAND_SAVE: 1104 case COMMAND_SAVE:
1100 cb_saveposition(); 1105 cb_saveposition(game);
1101 cb_drawboard(); 1106 cb_drawboard();
1102 break; 1107 break;
1103 case COMMAND_RESTORE: 1108 case COMMAND_RESTORE:
@@ -1106,14 +1111,23 @@ static void cb_play_game(void) {
1106 /* init board */ 1111 /* init board */
1107 GNUChess_Initialize(); 1112 GNUChess_Initialize();
1108 1113
1109 /* init PGN history data structures */
1110 game = pgn_init_game();
1111
1112 /* restore saved position, if saved */ 1114 /* restore saved position, if saved */
1113 cb_restoreposition(); 1115 game = cb_restoreposition();
1114 1116
1115 cb_drawboard(); 1117 cb_drawboard();
1116 break; 1118 break;
1119 case COMMAND_VIEW:
1120 if (rb->file_exists(pgn_file)) {
1121 cb_saveposition(game);
1122 if (cb_start_viewer(pgn_file))
1123 return;
1124 GNUChess_Initialize();
1125 game = cb_restoreposition();
1126 }else{
1127 rb->splash ( HZ*2 , ID2P(LANG_CHESSBOX_NO_GAMES) );
1128 }
1129 cb_drawboard();
1130 break;
1117 case COMMAND_PLAY: 1131 case COMMAND_PLAY:
1118 if (opponent == white) { 1132 if (opponent == white) {
1119 opponent = black; 1133 opponent = black;
@@ -1158,9 +1172,7 @@ static void cb_play_game(void) {
1158 } 1172 }
1159 } 1173 }
1160 1174
1161 cb_saveposition(); 1175 cb_saveposition(game);
1162 /* TODO: save/restore the PGN history of unfinished games */
1163 rb->lcd_setfont(FONT_UI);
1164 1176
1165} 1177}
1166 1178
@@ -1187,6 +1199,8 @@ enum plugin_status plugin_start(const void* parameter) {
1187 cb_play_game(); 1199 cb_play_game();
1188 } 1200 }
1189 1201
1202 rb->lcd_setfont(FONT_UI);
1203
1190 if (cb_sysevent) 1204 if (cb_sysevent)
1191 rb->default_event_handler(cb_sysevent); 1205 rb->default_event_handler(cb_sysevent);
1192 1206