home *** CD-ROM | disk | FTP | other *** search
/ High Voltage Shareware / high1.zip / high1 / DIR2 / CBUFF09.ZIP / SRC.ZIP / CBHEADER.C < prev    next >
C/C++ Source or Header  |  1993-11-16  |  5KB  |  262 lines

  1. /*  $Id: cbheader.c,v 1.1.1.1 1993/06/21 11:11:59 anjo Exp $
  2.  *  
  3.  *  File    cbheader.c
  4.  *  Part of    ChessBase utilities file format (CBUFF)
  5.  *  Author    Anjo Anjewierden, anjo@swi.psy.uva.nl
  6.  *  Purpose    Representation of game header
  7.  *  Works with    GNU CC 2.4.5
  8.  *  
  9.  *  Notice    Copyright (c) 1993  Anjo Anjewierden
  10.  *  
  11.  *  History    09/06/93  (Created)
  12.  *          03/11/93  (Last modified)
  13.  */ 
  14.  
  15.  
  16. /*------------------------------------------------------------
  17.  *  Directives
  18.  *------------------------------------------------------------*/
  19.  
  20. #include "cbuff.h"
  21.  
  22.  
  23. /*------------------------------------------------------------
  24.  *  Initialisation
  25.  *------------------------------------------------------------*/
  26.  
  27. CbHeader
  28. newCbHeader()
  29. { CbHeader ch;
  30.  
  31.   ch = alloc(sizeof(struct cbheader));
  32.   resetCbHeader(ch);
  33.   return ch;
  34. }
  35.  
  36.  
  37. void
  38. freeCbHeader(CbHeader ch)
  39. { unalloc(ch);
  40. }
  41.  
  42.  
  43. void
  44. resetCbHeader(CbHeader ch)
  45. { ch->year = 0;
  46.   ch->result = 0;
  47.   ch->movesLength = 0;
  48.   ch->playersLength = 0;
  49.   ch->sourceLength = 0;
  50.   ch->commentLength = 0;
  51.   ch->whiteElo = 0;
  52.   ch->blackElo = 0;
  53.   ch->flags1 = 0;
  54.   ch->flags2 = 0;
  55.   ch->moves = 0;
  56.   ch->checksum = 0;
  57. }
  58.  
  59.  
  60. void
  61. initCbHeader(CbHeader ch, unsigned char *h)
  62. { unsigned char k;
  63.   int i;
  64.  
  65.       /* Unscramble the header.
  66.      */
  67.   k = 101;
  68.   for (i=13; i>=0; i--)
  69.   { h[i] ^= k;
  70.     k *= 3;
  71.   }
  72.  
  73.  
  74.     /* Manual copy to ensure possible differences
  75.      * in machine dependent byte order are handled correctly.
  76.      * (Suggested by Anders Thulin, ath@linkoping.trab.se).
  77.      */
  78.   ch->year = h[0];
  79.   ch->result = h[1];
  80.   ch->movesLength = (h[2] << 8) | h[3];
  81.   ch->playersLength = h[4];
  82.   ch->sourceLength = h[5];
  83.   ch->commentLength = (h[6] << 8) | h[7];
  84.   ch->whiteElo = h[8];
  85.   ch->blackElo = h[9];
  86.   ch->flags1 = h[10];
  87.   ch->flags2 = h[11];
  88.   ch->moves = h[12];
  89.  
  90.   ch->checksum = INCORRECT_CHECKSUM;
  91.  
  92.   if (   ((h[0] * 0x25 + h[5] + h[9]) & 0xff) == h[13]
  93.       || ((h[3] * 0x1ec1 * (h[8]+1) * h[0]) & 0xff) == h[13])
  94.     ch->checksum = CORRECT_CHECKSUM;
  95. #if PROTECTED_GAMES
  96. #    include protect.h
  97. #endif
  98.   ch->flags2 ^= 14 + (h[4] & 63) + (h[5] & 63);
  99. /*
  100.   ch->flags2 ^= 14 + (playersLengthCbHeader(ch) & 63)
  101.                    + (sourceLengthCbHeader(ch) & 63);
  102. */
  103. }
  104.  
  105.  
  106. /*------------------------------------------------------------
  107.  *  Extracting information
  108.  *------------------------------------------------------------*/
  109.  
  110. bool
  111. fullGameCbHeaderP(CbHeader ch)
  112. { if ((ch->flags1 & FULL_GAME_MASK) == 0)
  113.     return TRUE;
  114.   return FALSE;
  115. }
  116.  
  117.  
  118. bool
  119. deletedCbHeaderP(CbHeader ch)
  120. { if ((ch->flags1 & GAME_DELETED_MASK))
  121.     return TRUE;
  122.   return FALSE;
  123. }
  124.  
  125.  
  126. bool
  127. markedCbHeaderP(CbHeader ch)
  128. { if ((ch->flags1 & GAME_MARKED_MASK))
  129.     return TRUE;
  130.   return FALSE;
  131. }
  132.  
  133.  
  134. int
  135. yearCbHeader(CbHeader ch)
  136. { if (ch->year == YEAR_UNKNOWN)
  137.     return 0;
  138.   return 1900 + ch->year;
  139. }
  140.  
  141.  
  142. int
  143. whiteEloCbHeader(CbHeader ch)
  144. { return (ch->whiteElo ? 1600+5*(int) ch->whiteElo : 0);
  145. }
  146.  
  147.  
  148. int
  149. blackEloCbHeader(CbHeader ch)
  150. { return (ch->blackElo ? 1600+5*(int) ch->blackElo : 0);
  151. }
  152.  
  153.  
  154. int
  155. movesLengthCbHeader(CbHeader ch)
  156. { return ch->movesLength - 1;
  157. }
  158.  
  159.  
  160. int
  161. playersLengthCbHeader(CbHeader ch)
  162. { return ch->playersLength & PLAYERS_MASK;
  163. }
  164.  
  165.  
  166. int
  167. sourceLengthCbHeader(CbHeader ch)
  168. { return ch->sourceLength & SOURCE_MASK;
  169. }
  170.  
  171.  
  172. int
  173. commentLengthCbHeader(CbHeader ch)
  174. { return ch->commentLength;
  175. }
  176.  
  177.  
  178. int
  179. movesCbHeader(CbHeader ch)
  180. { return ch->moves;
  181. }
  182.  
  183.  
  184. char *
  185. ecoCbHeader(CbHeader ch)
  186. { static char eco[7];
  187.   unsigned int eco1;
  188.   unsigned int eco2;
  189.  
  190.   if (!fullGameCbHeaderP(ch))
  191.   { eco[0] = '\0';
  192.     return eco;
  193.   }
  194.  
  195.   eco1 = (  ((ch->playersLength & ECO_PART1_MASK) >> 1)
  196.       | ((ch->sourceLength & ECO_PART2_MASK) << 1)
  197.       | ((ch->flags1 & ECO_PART3_MASK) >> 1)
  198.      );
  199.   eco2 = (   (ch->flags2 & ECO2_PART1_MASK)
  200.       | ((ch->flags2 & ECO2_PART2_MASK) >> 1)
  201.      );
  202.   eco[0] = '\0';
  203.  
  204.   if (eco1)
  205.   { if (eco2)
  206.       sprintf(eco, "%c%02d/%02d", 65+(eco1-1)/100, (eco1-1)%100, eco2);
  207.     else
  208.       sprintf(eco, "%c%02d", 65+(eco1-1)/100, (eco1-1)%100);
  209.   }
  210.  
  211.   return eco;
  212. }
  213.  
  214.  
  215. bool
  216. flags2bit6CbHeader(CbHeader ch)
  217. { return (ch->flags2 & 0x40 ? TRUE : FALSE);
  218. }
  219.  
  220.  
  221. void
  222. decodeCbHeader(CbHeader ch)
  223. { if (!fullGameCbHeaderP(ch))
  224.   { printf("Game has a starting position\n");
  225.     return;
  226.   }
  227.   printf("Year:           %d\n", yearCbHeader(ch));
  228.   printf("Result:         %d\n", ch->result);
  229.   printf("Move length:    %d\n", movesLengthCbHeader(ch));
  230.   printf("Players length: %d\n", playersLengthCbHeader(ch));
  231.   printf("Source length:  %d\n", sourceLengthCbHeader(ch));
  232.   printf("Comment length: %d\n", commentLengthCbHeader(ch));
  233.   printf("White ELO:      %d\n", whiteEloCbHeader(ch));
  234.   printf("Black ELO:      %d\n", blackEloCbHeader(ch));
  235.   printf("Flags 1:        %x\n", ch->flags1);
  236.   printf("Flags 2:        %x\n", ch->flags2);
  237.   printf("Moves:          %d\n", ch->moves);
  238.   printf("Checksum:       %x\n", ch->checksum);
  239. }
  240.  
  241.  
  242. /*------------------------------------------------------------
  243.  *  Setting information
  244.  *------------------------------------------------------------*/
  245.  
  246. void
  247. setYearCbHeader(CbHeader ch, int year)
  248. { ch->year = (year == 0 ? YEAR_UNKNOWN : 1900 - year);
  249. }
  250.  
  251.  
  252. void
  253. setWhiteEloCbHeader(CbHeader ch, int elo)
  254. { ch->whiteElo = (elo <= 1600 ? 0 : (elo - 1600) / 5);
  255. }
  256.  
  257.  
  258. void
  259. setBlackEloCbHeader(CbHeader ch, int elo)
  260. { ch->blackElo = (elo <= 1600 ? 0 : (elo - 1600) / 5);
  261. }
  262.