home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
High Voltage Shareware
/
high1.zip
/
high1
/
DIR2
/
CBUFF09.ZIP
/
SRC.ZIP
/
CBHEADER.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-11-16
|
5KB
|
262 lines
/* $Id: cbheader.c,v 1.1.1.1 1993/06/21 11:11:59 anjo Exp $
*
* File cbheader.c
* Part of ChessBase utilities file format (CBUFF)
* Author Anjo Anjewierden, anjo@swi.psy.uva.nl
* Purpose Representation of game header
* Works with GNU CC 2.4.5
*
* Notice Copyright (c) 1993 Anjo Anjewierden
*
* History 09/06/93 (Created)
* 03/11/93 (Last modified)
*/
/*------------------------------------------------------------
* Directives
*------------------------------------------------------------*/
#include "cbuff.h"
/*------------------------------------------------------------
* Initialisation
*------------------------------------------------------------*/
CbHeader
newCbHeader()
{ CbHeader ch;
ch = alloc(sizeof(struct cbheader));
resetCbHeader(ch);
return ch;
}
void
freeCbHeader(CbHeader ch)
{ unalloc(ch);
}
void
resetCbHeader(CbHeader ch)
{ ch->year = 0;
ch->result = 0;
ch->movesLength = 0;
ch->playersLength = 0;
ch->sourceLength = 0;
ch->commentLength = 0;
ch->whiteElo = 0;
ch->blackElo = 0;
ch->flags1 = 0;
ch->flags2 = 0;
ch->moves = 0;
ch->checksum = 0;
}
void
initCbHeader(CbHeader ch, unsigned char *h)
{ unsigned char k;
int i;
/* Unscramble the header.
*/
k = 101;
for (i=13; i>=0; i--)
{ h[i] ^= k;
k *= 3;
}
/* Manual copy to ensure possible differences
* in machine dependent byte order are handled correctly.
* (Suggested by Anders Thulin, ath@linkoping.trab.se).
*/
ch->year = h[0];
ch->result = h[1];
ch->movesLength = (h[2] << 8) | h[3];
ch->playersLength = h[4];
ch->sourceLength = h[5];
ch->commentLength = (h[6] << 8) | h[7];
ch->whiteElo = h[8];
ch->blackElo = h[9];
ch->flags1 = h[10];
ch->flags2 = h[11];
ch->moves = h[12];
ch->checksum = INCORRECT_CHECKSUM;
if ( ((h[0] * 0x25 + h[5] + h[9]) & 0xff) == h[13]
|| ((h[3] * 0x1ec1 * (h[8]+1) * h[0]) & 0xff) == h[13])
ch->checksum = CORRECT_CHECKSUM;
#if PROTECTED_GAMES
# include protect.h
#endif
ch->flags2 ^= 14 + (h[4] & 63) + (h[5] & 63);
/*
ch->flags2 ^= 14 + (playersLengthCbHeader(ch) & 63)
+ (sourceLengthCbHeader(ch) & 63);
*/
}
/*------------------------------------------------------------
* Extracting information
*------------------------------------------------------------*/
bool
fullGameCbHeaderP(CbHeader ch)
{ if ((ch->flags1 & FULL_GAME_MASK) == 0)
return TRUE;
return FALSE;
}
bool
deletedCbHeaderP(CbHeader ch)
{ if ((ch->flags1 & GAME_DELETED_MASK))
return TRUE;
return FALSE;
}
bool
markedCbHeaderP(CbHeader ch)
{ if ((ch->flags1 & GAME_MARKED_MASK))
return TRUE;
return FALSE;
}
int
yearCbHeader(CbHeader ch)
{ if (ch->year == YEAR_UNKNOWN)
return 0;
return 1900 + ch->year;
}
int
whiteEloCbHeader(CbHeader ch)
{ return (ch->whiteElo ? 1600+5*(int) ch->whiteElo : 0);
}
int
blackEloCbHeader(CbHeader ch)
{ return (ch->blackElo ? 1600+5*(int) ch->blackElo : 0);
}
int
movesLengthCbHeader(CbHeader ch)
{ return ch->movesLength - 1;
}
int
playersLengthCbHeader(CbHeader ch)
{ return ch->playersLength & PLAYERS_MASK;
}
int
sourceLengthCbHeader(CbHeader ch)
{ return ch->sourceLength & SOURCE_MASK;
}
int
commentLengthCbHeader(CbHeader ch)
{ return ch->commentLength;
}
int
movesCbHeader(CbHeader ch)
{ return ch->moves;
}
char *
ecoCbHeader(CbHeader ch)
{ static char eco[7];
unsigned int eco1;
unsigned int eco2;
if (!fullGameCbHeaderP(ch))
{ eco[0] = '\0';
return eco;
}
eco1 = ( ((ch->playersLength & ECO_PART1_MASK) >> 1)
| ((ch->sourceLength & ECO_PART2_MASK) << 1)
| ((ch->flags1 & ECO_PART3_MASK) >> 1)
);
eco2 = ( (ch->flags2 & ECO2_PART1_MASK)
| ((ch->flags2 & ECO2_PART2_MASK) >> 1)
);
eco[0] = '\0';
if (eco1)
{ if (eco2)
sprintf(eco, "%c%02d/%02d", 65+(eco1-1)/100, (eco1-1)%100, eco2);
else
sprintf(eco, "%c%02d", 65+(eco1-1)/100, (eco1-1)%100);
}
return eco;
}
bool
flags2bit6CbHeader(CbHeader ch)
{ return (ch->flags2 & 0x40 ? TRUE : FALSE);
}
void
decodeCbHeader(CbHeader ch)
{ if (!fullGameCbHeaderP(ch))
{ printf("Game has a starting position\n");
return;
}
printf("Year: %d\n", yearCbHeader(ch));
printf("Result: %d\n", ch->result);
printf("Move length: %d\n", movesLengthCbHeader(ch));
printf("Players length: %d\n", playersLengthCbHeader(ch));
printf("Source length: %d\n", sourceLengthCbHeader(ch));
printf("Comment length: %d\n", commentLengthCbHeader(ch));
printf("White ELO: %d\n", whiteEloCbHeader(ch));
printf("Black ELO: %d\n", blackEloCbHeader(ch));
printf("Flags 1: %x\n", ch->flags1);
printf("Flags 2: %x\n", ch->flags2);
printf("Moves: %d\n", ch->moves);
printf("Checksum: %x\n", ch->checksum);
}
/*------------------------------------------------------------
* Setting information
*------------------------------------------------------------*/
void
setYearCbHeader(CbHeader ch, int year)
{ ch->year = (year == 0 ? YEAR_UNKNOWN : 1900 - year);
}
void
setWhiteEloCbHeader(CbHeader ch, int elo)
{ ch->whiteElo = (elo <= 1600 ? 0 : (elo - 1600) / 5);
}
void
setBlackEloCbHeader(CbHeader ch, int elo)
{ ch->blackElo = (elo <= 1600 ? 0 : (elo - 1600) / 5);
}