/*************************************************************************** * __________ __ ___. * Open \______ \ ____ ____ | | _\_ |__ _______ ___ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * \/ \/ \/ \/ \/ * $Id$ * * Copyright (C) 2007 Mauricio Peccorini * * 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 software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * KIND, either express or implied. * ****************************************************************************/ #include "plugin.h" #include "gnuchess.h" /* button definitions */ #if (CONFIG_KEYPAD == IPOD_4G_PAD) || (CONFIG_KEYPAD == IPOD_3G_PAD) || \ (CONFIG_KEYPAD == IPOD_1G2G_PAD) #define CB_SELECT BUTTON_SELECT #define CB_UP BUTTON_MENU #define CB_DOWN BUTTON_PLAY #define CB_LEFT BUTTON_LEFT #define CB_RIGHT BUTTON_RIGHT #define CB_PLAY (BUTTON_SELECT | BUTTON_PLAY) #define CB_LEVEL (BUTTON_SELECT | BUTTON_RIGHT) #define CB_RESTART (BUTTON_SELECT | BUTTON_LEFT) #define CB_MENU (BUTTON_SELECT | BUTTON_MENU) #define CB_SCROLL_UP (BUTTON_SCROLL_FWD|BUTTON_REPEAT) #define CB_SCROLL_DOWN (BUTTON_SCROLL_BACK|BUTTON_REPEAT) #define CB_SCROLL_LEFT (BUTTON_LEFT|BUTTON_REPEAT) #define CB_SCROLL_RIGHT (BUTTON_RIGHT|BUTTON_REPEAT) #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD #define CB_SELECT BUTTON_SELECT #define CB_UP BUTTON_UP #define CB_DOWN BUTTON_DOWN #define CB_LEFT BUTTON_LEFT #define CB_RIGHT BUTTON_RIGHT #define CB_PLAY BUTTON_PLAY #define CB_LEVEL BUTTON_REC #define CB_RESTART (BUTTON_SELECT | BUTTON_PLAY) #define CB_MENU BUTTON_POWER #define CB_SCROLL_UP (BUTTON_UP|BUTTON_REPEAT) #define CB_SCROLL_DOWN (BUTTON_DOWN|BUTTON_REPEAT) #define CB_SCROLL_LEFT (BUTTON_LEFT|BUTTON_REPEAT) #define CB_SCROLL_RIGHT (BUTTON_RIGHT|BUTTON_REPEAT) #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || (CONFIG_KEYPAD == IRIVER_H300_PAD) #define CB_SELECT BUTTON_SELECT #define CB_UP BUTTON_UP #define CB_DOWN BUTTON_DOWN #define CB_LEFT BUTTON_LEFT #define CB_RIGHT BUTTON_RIGHT #define CB_PLAY BUTTON_ON #define CB_LEVEL BUTTON_MODE #define CB_RESTART BUTTON_REC #define CB_MENU BUTTON_OFF #define CB_RC_QUIT BUTTON_RC_STOP #define CB_SCROLL_UP (BUTTON_UP|BUTTON_REPEAT) #define CB_SCROLL_DOWN (BUTTON_DOWN|BUTTON_REPEAT) #define CB_SCROLL_LEFT (BUTTON_LEFT|BUTTON_REPEAT) #define CB_SCROLL_RIGHT (BUTTON_RIGHT|BUTTON_REPEAT) #elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD #define CB_SELECT BUTTON_SELECT #define CB_UP BUTTON_UP #define CB_DOWN BUTTON_DOWN #define CB_LEFT BUTTON_LEFT #define CB_RIGHT BUTTON_RIGHT #define CB_PLAY BUTTON_PLAY #define CB_LEVEL BUTTON_EQ #define CB_MENU BUTTON_MODE #define CB_SCROLL_UP (BUTTON_UP|BUTTON_REPEAT) #define CB_SCROLL_DOWN (BUTTON_DOWN|BUTTON_REPEAT) #define CB_SCROLL_LEFT (BUTTON_LEFT|BUTTON_REPEAT) #define CB_SCROLL_RIGHT (BUTTON_RIGHT|BUTTON_REPEAT) #elif CONFIG_KEYPAD == RECORDER_PAD #define CB_SELECT BUTTON_PLAY #define CB_UP BUTTON_UP #define CB_DOWN BUTTON_DOWN #define CB_LEFT BUTTON_LEFT #define CB_RIGHT BUTTON_RIGHT #define CB_PLAY BUTTON_ON #define CB_LEVEL BUTTON_F1 #define CB_RESTART BUTTON_F3 #define CB_MENU BUTTON_OFF #define CB_SCROLL_UP (BUTTON_UP|BUTTON_REPEAT) #define CB_SCROLL_DOWN (BUTTON_DOWN|BUTTON_REPEAT) #define CB_SCROLL_LEFT (BUTTON_LEFT|BUTTON_REPEAT) #define CB_SCROLL_RIGHT (BUTTON_RIGHT|BUTTON_REPEAT) #elif CONFIG_KEYPAD == ARCHOS_AV300_PAD #define CB_SELECT BUTTON_SELECT #define CB_UP BUTTON_UP #define CB_DOWN BUTTON_DOWN #define CB_LEFT BUTTON_LEFT #define CB_RIGHT BUTTON_RIGHT #define CB_PLAY BUTTON_ON #define CB_LEVEL BUTTON_F1 #define CB_RESTART BUTTON_F3 #define CB_MENU BUTTON_OFF #define CB_SCROLL_UP (BUTTON_UP|BUTTON_REPEAT) #define CB_SCROLL_DOWN (BUTTON_DOWN|BUTTON_REPEAT) #define CB_SCROLL_LEFT (BUTTON_LEFT|BUTTON_REPEAT) #define CB_SCROLL_RIGHT (BUTTON_RIGHT|BUTTON_REPEAT) #elif CONFIG_KEYPAD == ONDIO_PAD #define CB_SELECT_PRE BUTTON_MENU #define CB_SELECT (BUTTON_MENU|BUTTON_REL) #define CB_UP BUTTON_UP #define CB_DOWN BUTTON_DOWN #define CB_LEFT BUTTON_LEFT #define CB_RIGHT BUTTON_RIGHT #define CB_PLAY_PRE BUTTON_MENU #define CB_PLAY (BUTTON_MENU|BUTTON_REPEAT) #define CB_LEVEL (BUTTON_MENU|BUTTON_OFF) #define CB_RESTART (BUTTON_MENU|BUTTON_LEFT) #define CB_MENU BUTTON_OFF #define CB_SCROLL_UP (BUTTON_UP|BUTTON_REPEAT) #define CB_SCROLL_DOWN (BUTTON_DOWN|BUTTON_REPEAT) #define CB_SCROLL_LEFT (BUTTON_LEFT|BUTTON_REPEAT) #define CB_SCROLL_RIGHT (BUTTON_RIGHT|BUTTON_REPEAT) #elif (CONFIG_KEYPAD == GIGABEAT_PAD) #define CB_SELECT BUTTON_SELECT #define CB_UP BUTTON_UP #define CB_DOWN BUTTON_DOWN #define CB_LEFT BUTTON_LEFT #define CB_RIGHT BUTTON_RIGHT #define CB_PLAY BUTTON_A #define CB_LEVEL BUTTON_MENU #define CB_MENU BUTTON_POWER #define CB_SCROLL_UP (BUTTON_UP|BUTTON_REPEAT) #define CB_SCROLL_DOWN (BUTTON_DOWN|BUTTON_REPEAT) #define CB_SCROLL_LEFT (BUTTON_LEFT|BUTTON_REPEAT) #define CB_SCROLL_RIGHT (BUTTON_RIGHT|BUTTON_REPEAT) #elif (CONFIG_KEYPAD == GIGABEAT_S_PAD) #define CB_SELECT BUTTON_SELECT #define CB_UP BUTTON_UP #define CB_DOWN BUTTON_DOWN #define CB_LEFT BUTTON_LEFT #define CB_RIGHT BUTTON_RIGHT #define CB_PLAY BUTTON_PLAY #define CB_LEVEL BUTTON_MENU #define CB_MENU BUTTON_POWER #define CB_SCROLL_UP (BUTTON_UP|BUTTON_REPEAT) #define CB_SCROLL_DOWN (BUTTON_DOWN|BUTTON_REPEAT) #define CB_SCROLL_LEFT (BUTTON_LEFT|BUTTON_REPEAT) #define CB_SCROLL_RIGHT (BUTTON_RIGHT|BUTTON_REPEAT) #elif CONFIG_KEYPAD == IRIVER_H10_PAD #define CB_SELECT BUTTON_REW #define CB_UP BUTTON_SCROLL_UP #define CB_DOWN BUTTON_SCROLL_DOWN #define CB_LEFT BUTTON_LEFT #define CB_RIGHT BUTTON_RIGHT #define CB_PLAY BUTTON_PLAY #define CB_LEVEL BUTTON_FF #define CB_RESTART (BUTTON_REW | BUTTON_PLAY) #define CB_MENU BUTTON_POWER #define CB_SCROLL_UP (BUTTON_SCROLL_BACK|BUTTON_REPEAT) #define CB_SCROLL_DOWN (BUTTON_SCROLL_FWD|BUTTON_REPEAT) #define CB_SCROLL_LEFT (BUTTON_LEFT|BUTTON_REPEAT) #define CB_SCROLL_RIGHT (BUTTON_RIGHT|BUTTON_REPEAT) #elif CONFIG_KEYPAD == SANSA_E200_PAD #define CB_SELECT BUTTON_SELECT #define CB_UP BUTTON_UP #define CB_DOWN BUTTON_DOWN #define CB_LEFT BUTTON_LEFT #define CB_RIGHT BUTTON_RIGHT #define CB_PLAY (BUTTON_SELECT | BUTTON_RIGHT) #define CB_LEVEL BUTTON_REC #define CB_RESTART (BUTTON_SELECT | BUTTON_REPEAT) #define CB_MENU BUTTON_POWER #define CB_SCROLL_UP (BUTTON_SCROLL_UP|BUTTON_REPEAT) #define CB_SCROLL_DOWN (BUTTON_SCROLL_DOWN|BUTTON_REPEAT) #define CB_SCROLL_LEFT (BUTTON_LEFT|BUTTON_REPEAT) #define CB_SCROLL_RIGHT (BUTTON_RIGHT|BUTTON_REPEAT) #elif CONFIG_KEYPAD == SANSA_FUZE_PAD #define CB_SELECT BUTTON_SELECT #define CB_UP BUTTON_UP #define CB_DOWN BUTTON_DOWN #define CB_LEFT BUTTON_LEFT #define CB_RIGHT BUTTON_RIGHT #define CB_PLAY (BUTTON_SELECT | BUTTON_RIGHT) #define CB_LEVEL (BUTTON_SELECT|BUTTON_LEFT) #define CB_RESTART (BUTTON_SELECT | BUTTON_REPEAT) #define CB_MENU (BUTTON_HOME|BUTTON_REPEAT) #define CB_SCROLL_UP (BUTTON_SCROLL_UP|BUTTON_REPEAT) #define CB_SCROLL_DOWN (BUTTON_SCROLL_DOWN|BUTTON_REPEAT) #define CB_SCROLL_LEFT (BUTTON_LEFT|BUTTON_REPEAT) #define CB_SCROLL_RIGHT (BUTTON_RIGHT|BUTTON_REPEAT) #elif CONFIG_KEYPAD == SANSA_CLIP_PAD #define CB_SELECT BUTTON_SELECT #define CB_UP BUTTON_UP #define CB_DOWN BUTTON_DOWN #define CB_LEFT BUTTON_LEFT #define CB_RIGHT BUTTON_RIGHT #define CB_PLAY BUTTON_VOL_UP #define CB_LEVEL BUTTON_HOME #define CB_MENU BUTTON_POWER #define CB_SCROLL_UP (BUTTON_UP|BUTTON_REPEAT) #define CB_SCROLL_DOWN (BUTTON_DOWN|BUTTON_REPEAT) #define CB_SCROLL_LEFT (BUTTON_LEFT|BUTTON_REPEAT) #define CB_SCROLL_RIGHT (BUTTON_RIGHT|BUTTON_REPEAT) #elif CONFIG_KEYPAD == SANSA_M200_PAD #define CB_SELECT (BUTTON_SELECT | BUTTON_REPEAT) #define CB_UP BUTTON_UP #define CB_DOWN BUTTON_DOWN #define CB_LEFT BUTTON_LEFT #define CB_RIGHT BUTTON_RIGHT #define CB_PLAY BUTTON_VOL_UP #define CB_LEVEL (BUTTON_SELECT | BUTTON_UP) #define CB_MENU BUTTON_POWER #define CB_SCROLL_UP (BUTTON_UP|BUTTON_REPEAT) #define CB_SCROLL_DOWN (BUTTON_DOWN|BUTTON_REPEAT) #define CB_SCROLL_LEFT (BUTTON_LEFT|BUTTON_REPEAT) #define CB_SCROLL_RIGHT (BUTTON_RIGHT|BUTTON_REPEAT) #elif CONFIG_KEYPAD == SANSA_C200_PAD #define CB_SELECT BUTTON_SELECT #define CB_UP BUTTON_UP #define CB_DOWN BUTTON_DOWN #define CB_LEFT BUTTON_LEFT #define CB_RIGHT BUTTON_RIGHT #define CB_PLAY BUTTON_VOL_UP #define CB_LEVEL BUTTON_REC #define CB_MENU BUTTON_POWER #define CB_SCROLL_UP (BUTTON_UP|BUTTON_REPEAT) #define CB_SCROLL_DOWN (BUTTON_DOWN|BUTTON_REPEAT) #define CB_SCROLL_LEFT (BUTTON_LEFT|BUTTON_REPEAT) #define CB_SCROLL_RIGHT (BUTTON_RIGHT|BUTTON_REPEAT) #elif CONFIG_KEYPAD == MROBE500_PAD #elif (CONFIG_KEYPAD == MROBE100_PAD) #define CB_SELECT BUTTON_SELECT #define CB_UP BUTTON_UP #define CB_DOWN BUTTON_DOWN #define CB_LEFT BUTTON_LEFT #define CB_RIGHT BUTTON_RIGHT #define CB_PLAY BUTTON_PLAY #define CB_LEVEL BUTTON_DISPLAY #define CB_MENU BUTTON_POWER #define CB_SCROLL_UP (BUTTON_UP|BUTTON_REPEAT) #define CB_SCROLL_DOWN (BUTTON_DOWN|BUTTON_REPEAT) #define CB_SCROLL_LEFT (BUTTON_LEFT|BUTTON_REPEAT) #define CB_SCROLL_RIGHT (BUTTON_RIGHT|BUTTON_REPEAT) #elif CONFIG_KEYPAD == IAUDIO_M3_PAD #define CB_SELECT BUTTON_RC_PLAY #define CB_UP BUTTON_RC_VOL_UP #define CB_DOWN BUTTON_RC_VOL_DOWN #define CB_LEFT BUTTON_RC_REW #define CB_RIGHT BUTTON_RC_FF #define CB_PLAY BUTTON_RC_MODE #define CB_LEVEL BUTTON_RC_MENU #define CB_RESTART (BUTTON_RC_PLAY|BUTTON_REPEAT) #define CB_MENU BUTTON_RC_REC #define CB_SCROLL_UP (BUTTON_RC_VOL_UP|BUTTON_REPEAT) #define CB_SCROLL_DOWN (BUTTON_RC_VOL_DOWN|BUTTON_REPEAT) #define CB_SCROLL_LEFT (BUTTON_RC_REW|BUTTON_REPEAT) #define CB_SCROLL_RIGHT (BUTTON_RC_FF|BUTTON_REPEAT) #define CB_RC_QUIT BUTTON_REC #elif CONFIG_KEYPAD == COWON_D2_PAD #define CB_LEVEL BUTTON_PLUS #define CB_RESTART BUTTON_MINUS #define CB_MENU (BUTTON_MENU|BUTTON_REL) #elif CONFIG_KEYPAD == CREATIVEZVM_PAD #define CB_SELECT BUTTON_PLAY #define CB_UP BUTTON_UP #define CB_DOWN BUTTON_DOWN #define CB_LEFT BUTTON_LEFT #define CB_RIGHT BUTTON_RIGHT #define CB_PLAY BUTTON_SELECT #define CB_LEVEL BUTTON_CUSTOM #define CB_MENU BUTTON_MENU #elif CONFIG_KEYPAD == PHILIPS_HDD1630_PAD #define CB_SELECT BUTTON_SELECT #define CB_UP BUTTON_UP #define CB_DOWN BUTTON_DOWN #define CB_LEFT BUTTON_LEFT #define CB_RIGHT BUTTON_RIGHT #define CB_PLAY BUTTON_VIEW #define CB_LEVEL BUTTON_PLAYLIST #define CB_MENU BUTTON_MENU #elif CONFIG_KEYPAD == PHILIPS_HDD6330_PAD #define CB_SELECT BUTTON_PLAY #define CB_UP BUTTON_UP #define CB_DOWN BUTTON_DOWN #define CB_LEFT BUTTON_PREV #define CB_RIGHT BUTTON_NEXT #define CB_PLAY BUTTON_RIGHT #define CB_LEVEL BUTTON_LEFT #define CB_MENU BUTTON_MENU #elif CONFIG_KEYPAD == PHILIPS_SA9200_PAD #define CB_SELECT BUTTON_PLAY #define CB_UP BUTTON_UP #define CB_DOWN BUTTON_DOWN #define CB_LEFT BUTTON_PREV #define CB_RIGHT BUTTON_NEXT #define CB_PLAY BUTTON_RIGHT #define CB_LEVEL BUTTON_LEFT #define CB_MENU BUTTON_MENU #define CB_SCROLL_UP (BUTTON_UP|BUTTON_REPEAT) #define CB_SCROLL_DOWN (BUTTON_DOWN|BUTTON_REPEAT) #define CB_SCROLL_LEFT (BUTTON_LEFT|BUTTON_REPEAT) #define CB_SCROLL_RIGHT (BUTTON_RIGHT|BUTTON_REPEAT) #elif CONFIG_KEYPAD == ONDAVX747_PAD #define CB_LEVEL BUTTON_VOL_UP #define CB_RESTART BUTTON_VOL_DOWN #define CB_MENU (BUTTON_MENU|BUTTON_REL) #elif CONFIG_KEYPAD == ONDAVX777_PAD #define CB_MENU BUTTON_POWER #elif CONFIG_KEYPAD == SAMSUNG_YH_PAD #define CB_SELECT (BUTTON_FFWD|BUTTON_RIGHT) #define CB_UP BUTTON_UP #define CB_DOWN BUTTON_DOWN #define CB_LEFT BUTTON_LEFT #define CB_RIGHT BUTTON_RIGHT #define CB_PLAY BUTTON_PLAY #define CB_LEVEL (BUTTON_FFWD|BUTTON_UP) #define CB_MENU (BUTTON_FFWD|BUTTON_LEFT) #elif CONFIG_KEYPAD == PBELL_VIBE500_PAD #define CB_SELECT BUTTON_OK #define CB_UP BUTTON_UP #define CB_DOWN BUTTON_DOWN #define CB_LEFT BUTTON_PREV #define CB_RIGHT BUTTON_NEXT #define CB_PLAY BUTTON_PLAY #define CB_LEVEL BUTTON_CANCEL #define CB_MENU BUTTON_MENU #elif CONFIG_KEYPAD == MPIO_HD200_PAD #define CB_SELECT BUTTON_FUNC #define CB_UP BUTTON_REW #define CB_DOWN BUTTON_FF #define CB_LEFT BUTTON_VOL_DOWN #define CB_RIGHT BUTTON_VOL_UP #define CB_PLAY BUTTON_PLAY #define CB_LEVEL BUTTON_REC #define CB_MENU (BUTTON_FUNC | BUTTON_REPEAT) #elif CONFIG_KEYPAD == MPIO_HD300_PAD #define CB_SELECT BUTTON_ENTER #define CB_UP BUTTON_UP #define CB_DOWN BUTTON_DOWN #define CB_LEFT BUTTON_REW #define CB_RIGHT BUTTON_FF #define CB_PLAY BUTTON_PLAY #define CB_LEVEL BUTTON_REC #define CB_MENU (BUTTON_MENU | BUTTON_REPEAT) #elif CONFIG_KEYPAD == SANSA_FUZEPLUS_PAD #define CB_SELECT BUTTON_SELECT #define CB_UP BUTTON_UP #define CB_DOWN BUTTON_DOWN #define CB_LEFT BUTTON_LEFT #define CB_RIGHT BUTTON_RIGHT #define CB_PLAY BUTTON_PLAYPAUSE #define CB_LEVEL BUTTON_BACK #define CB_MENU (BUTTON_PLAYPAUSE | BUTTON_REPEAT) #elif CONFIG_KEYPAD == SANSA_CONNECT_PAD #define CB_SELECT BUTTON_SELECT #define CB_UP BUTTON_UP #define CB_DOWN BUTTON_DOWN #define CB_LEFT BUTTON_LEFT #define CB_RIGHT BUTTON_RIGHT #define CB_PLAY BUTTON_NEXT #define CB_LEVEL BUTTON_VOL_DOWN #define CB_RESTART BUTTON_PREV #define CB_MENU BUTTON_POWER #define CB_SCROLL_UP (BUTTON_SCROLL_UP|BUTTON_REPEAT) #define CB_SCROLL_DOWN (BUTTON_SCROLL_DOWN|BUTTON_REPEAT) #define CB_SCROLL_LEFT (BUTTON_LEFT|BUTTON_REPEAT) #define CB_SCROLL_RIGHT (BUTTON_RIGHT|BUTTON_REPEAT) #elif CONFIG_KEYPAD == SAMSUNG_YPR0_PAD #define CB_SELECT BUTTON_SELECT #define CB_UP BUTTON_UP #define CB_DOWN BUTTON_DOWN #define CB_LEFT BUTTON_LEFT #define CB_RIGHT BUTTON_RIGHT #define CB_PLAY BUTTON_USER #define CB_LEVEL BUTTON_BACK #define CB_MENU BUTTON_MENU #else #error No keymap defined! #endif #ifdef HAVE_TOUCHSCREEN #ifndef CB_LEVEL #define CB_LEVEL BUTTON_TOPLEFT #endif #ifndef CB_RESTART #define CB_RESTART BUTTON_TOPRIGHT #endif #ifndef CB_MENU #define CB_MENU (BUTTON_BOTTOMLEFT|BUTTON_REL) #endif #ifndef CB_PLAY #define CB_PLAY (BUTTON_CENTER|BUTTON_REPEAT) #endif #ifndef CB_SELECT #define CB_SELECT BUTTON_CENTER #endif #ifndef CB_UP #define CB_UP BUTTON_TOPMIDDLE #endif #ifndef CB_DOWN #define CB_DOWN BUTTON_BOTTOMMIDDLE #endif #ifndef CB_LEFT #define CB_LEFT BUTTON_MIDLEFT #endif #ifndef CB_RIGHT #define CB_RIGHT BUTTON_MIDRIGHT #endif #ifndef CB_SCROLL_UP #define CB_SCROLL_UP (BUTTON_TOPMIDDLE|BUTTON_REPEAT) #endif #ifndef CB_SCROLL_DOWN #define CB_SCROLL_DOWN (BUTTON_BOTTOMMIDDLE|BUTTON_REPEAT) #endif #ifndef CB_SCROLL_LEFT #define CB_SCROLL_LEFT (BUTTON_MIDLEFT|BUTTON_REPEAT) #endif #ifndef CB_SCROLL_RIGHT #define CB_SCROLL_RIGHT (BUTTON_MIDRIGHT|BUTTON_REPEAT) #endif #endif /* structure to represent the plies */ struct pgn_ply_node { unsigned short player; char pgn_text[9]; unsigned short row_from; unsigned short column_from; unsigned short row_to; unsigned short column_to; unsigned short taken_piece; unsigned short promotion_piece; bool enpassant; bool castle; bool promotion; bool checkmate; bool draw; struct pgn_ply_node* prev_node; struct pgn_ply_node* next_node; }; /* structure to list the games */ struct pgn_game_node { unsigned short game_number; char white_player[20]; char black_player[20]; char game_date[11]; char result[8]; int pgn_line; struct pgn_ply_node* first_ply; struct pgn_game_node* next_node; }; /* Return the list of games in a PGN file. * Parsing of the games themselves is postponed until * the user selects a game, that obviously saves processing * and speeds up response when the user selects the file */ struct pgn_game_node* pgn_list_games(const char* filename); /* Show the list of games found in a file and allow the user * to select a game to be parsed and showed */ struct pgn_game_node* pgn_show_game_list(struct pgn_game_node* first_game); /* Parse the pgn string of a game and assign it to the move * list in the structure */ void pgn_parse_game(const char* filename, struct pgn_game_node* selected_game); /* Initialize a new game structure with default values and make * it ready to store the history of a newly played match */ struct pgn_game_node* pgn_init_game(void); /* Add a new ply to the game structure based on the positions */ void pgn_append_ply(struct pgn_game_node* game, unsigned short ply_player, char *move_buffer, bool is_mate); /* Set the result of the game if it was reached during the opponent's ply */ void pgn_set_result(struct pgn_game_node* game, bool is_mate); /* Store a complete game in the PGN history file */ void pgn_store_game(struct pgn_game_node* game); pan class="hl opt">; AESAUXSIZE = 0x10; AESINSIZE = 0x10; AESSIZE3 = 0x10; for (ptr = 0; ptr < (size >> 2); ptr += 4) { AESOUTADDR = (uint32_t)data + (ptr << 2); AESINADDR = (uint32_t)data + (ptr << 2); AESAUXADDR = (uint32_t)data + (ptr << 2); if (ptr != 0) for (i = 0; i < 4; i++) ((uint32_t*)data)[ptr + i] ^= ((uint32_t*)data)[ptr + i - 4]; AESSTATUS = 6; AESGO = go; go = 3; while ((AESSTATUS & 6) == 0); } AESCONTROL = 0; PWRCONEXT |= 0x400; } static void aes_decrypt(void* data, uint32_t size) { uint32_t ptr, i; uint32_t go = 1; PWRCONEXT &= ~0x400; AESTYPE = 1; AESUNKREG0 = 1; AESUNKREG0 = 0; AESCONTROL = 1; AESKEYLEN = 8; AESOUTSIZE = size; AESAUXSIZE = 0x10; AESINSIZE = 0x10; AESSIZE3 = 0x10; for (ptr = (size >> 2) - 4; ; ptr -= 4) { AESOUTADDR = (uint32_t)data + (ptr << 2); AESINADDR = (uint32_t)data + (ptr << 2); AESAUXADDR = (uint32_t)data + (ptr << 2); AESSTATUS = 6; AESGO = go; go = 3; while ((AESSTATUS & 6) == 0); if (ptr == 0) break; for (i = 0; i < 4; i++) ((uint32_t*)data)[ptr + i] ^= ((uint32_t*)data)[ptr + i - 4]; } AESCONTROL = 0; PWRCONEXT |= 0x400; } static void calc_hash(uint32_t* data, uint32_t size, uint32_t* result) { uint32_t ptr, i; uint32_t ctrl = 2; PWRCONEXT &= ~0x4; for (ptr = 0; ptr < (size >> 2); ptr += 0x10) { for (i = 0; i < 0x10; i++) HASHDATAIN[i] = data[ptr + i]; HASHCTRL = ctrl; ctrl = 0xA; while ((HASHCTRL & 1) != 0); } for (i = 0; i < 5; i ++) result[i] = HASHRESULT[i]; PWRCONEXT |= 0x4; } static uint32_t get_uint32be(unsigned char* buf) { return (uint32_t)((buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]); } static void put_uint32be(unsigned char* buf, uint32_t x) { buf[0] = (x & 0xff000000) >> 24; buf[1] = (x & 0xff0000) >> 16; buf[2] = (x & 0xff00) >> 8; buf[3] = x & 0xff; } static uint32_t calc_checksum(uint32_t sum, unsigned char* buf, int len) { int i; for (i = 0; i < len ; i++) { sum += buf[i]; } return sum; } enum plugin_status plugin_start(const void* parameter) { int fd; int length; int n; ssize_t buf_size; uint32_t* buf; int size; uint32_t sum; uint32_t hash[0x200]; char outputfilename[MAX_PATH]; fd = rb->open(parameter,O_RDONLY); if (fd < 0) { rb->splash(HZ*2, "Cannot open file"); return PLUGIN_ERROR; } length = rb->filesize(fd); if (length < 12) { rb->splash(HZ*2, "File too small"); return PLUGIN_ERROR; } /* Get the audio buffer */ buf = rb->plugin_get_audio_buffer((size_t *)&buf_size); /* Use uncached alias for buf - equivalent to buf |= 0x40000000 */ buf += 0x10000000; if (length > buf_size) { rb->splash(HZ*2, "File too big"); return PLUGIN_ERROR; } n = rb->read(fd, buf, length); if (n < length) { rb->splash(HZ*2, "Cannot read file"); return PLUGIN_ERROR; } rb->close(fd); size = length - 8; /* Size of firmware image */ if (calc_checksum(MODEL_NUMBER, (unsigned char*)(buf + 2), size) != get_uint32be((unsigned char*)buf)) { rb->splash(HZ*2, "Bad checksum in input file"); return PLUGIN_ERROR; } n = rb->strlen(parameter); if (memcmp(buf+1,"nn2g",4)==0) { /* Encrypting - Input file should be .ipod, output file is .ipodx */ if ((n < 6) || (rb->strcmp(parameter+n-5,".ipod") != 0)) { rb->splash(HZ*2, "Input filename must be .ipod"); return PLUGIN_ERROR; } if (n + 2 > MAX_PATH) { rb->splash(HZ*2, "Filename too long"); return PLUGIN_ERROR; } size = (size + 0x3f) & ~0x3f; /* Pad to multiple of 64 bytes */ if (size > (length - 8)) { rb->memset(&buf[length/4], 0, size - (length - 8)); } rb->strlcpy(outputfilename, parameter, MAX_PATH); outputfilename[n] = 'x'; outputfilename[n+1] = 0; /* Everything is OK, now do the encryption */ /* 1 - Calculate hashes */ rb->memset(hash, 0, sizeof(hash)); hash[1] = 2; hash[2] = 1; hash[3] = 0x40; hash[5] = size; calc_hash(buf + 2, size, &hash[7]); calc_hash(hash, 0x200, &hash[0x75]); /* 2 - Do the encryption */ rb->splash(0, "Encrypting..."); aes_encrypt(buf + 2, size); /* 3 - Update the Rockbox header */ sum = calc_checksum(MODEL_NUMBER, (unsigned char*)hash, sizeof(hash)); sum = calc_checksum(sum, (unsigned char*)(buf + 2), size); put_uint32be((unsigned char*)buf, sum); memcpy(buf + 1, "nn2x", 4); /* 4 - Write to disk */ fd = rb->open(outputfilename,O_WRONLY|O_CREAT|O_TRUNC, 0666); if (fd < 0) { rb->splash(HZ*2, "Could not open output file"); return PLUGIN_ERROR; } n = rb->write(fd, buf, 8); n = rb->write(fd, hash, sizeof(hash)); n = rb->write(fd, buf + 2, size); rb->close(fd); } else if (memcmp(buf + 1,"nn2x",4)==0) { /* Decrypting - Input file should be .ipodx, output file is .ipod */ if ((n < 7) || (rb->strcmp(parameter+n-6,".ipodx") != 0)) { rb->splash(HZ*2, "Input filename must be .ipodx"); return PLUGIN_ERROR; } rb->strlcpy(outputfilename, parameter, MAX_PATH); outputfilename[n-1] = 0; /* Remove "x" at end of filename */ /* Everything is OK, now do the decryption */ size -= 0x800; /* Remove hash size from firmware size */ /* 1 - Decrypt */ rb->splash(0, "Decrypting..."); aes_decrypt(&buf[0x202], size); /* 2 - Calculate hashes to verify decryption */ rb->lcd_clear_display(); rb->splash(0, "Calculating hash..."); rb->memset(hash, 0, sizeof(hash)); hash[1] = 2; hash[2] = 1; hash[3] = 0x40; hash[5] = size; calc_hash(&buf[0x202], size, &hash[7]); calc_hash(hash, 0x200, &hash[0x75]); if ((memcmp(hash + 7, buf + 9, 20) != 0) || (memcmp(hash + 75, buf + 77, 20) != 0)) { rb->splash(HZ*2, "Decryption failed - bad hash"); return PLUGIN_ERROR; } /* 3 - Update the Rockbox header */ sum = calc_checksum(MODEL_NUMBER, (unsigned char*)(&buf[0x202]), size); put_uint32be((unsigned char*)buf, sum); memcpy(buf + 1, "nn2g", 4); /* 4 - Write to disk */ fd = rb->open(outputfilename,O_WRONLY|O_CREAT|O_TRUNC, 0666); if (fd < 0) { rb->splash(HZ*2, "Could not open output file"); return PLUGIN_ERROR; } n = rb->write(fd, buf, 8); n = rb->write(fd, &buf[0x202], size); rb->close(fd); } else { rb->splash(HZ*2,"Invalid input file"); return PLUGIN_ERROR; } return PLUGIN_OK; }