home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
games
/
volume6
/
ega-wanderer
/
patch1
/
scores.c
< prev
next >
Wrap
C/C++ Source or Header
|
1989-02-24
|
8KB
|
333 lines
#include "wand_head.h"
#ifdef EGA
extern char *EGAaddr;
#endif
#ifdef MSDOS /* M001 */
#define LOCK
#define UNLOCK
#else
/* MFC- lockfiles fixed: tries 5 times to get lock, with 1 second between
* tries, if after 5 seconds, no lock is gained, the lockfile is blown
* away.
*/
#define LOCK { int lc=5; \
while((lock = creat(LOCKPATH,0))<0 && lc) { \
sleep(1); lc--; } \
close(lock); \
}
#define UNLOCK (void) unlink(LOCKPATH)
#endif
#define ENTRIES 15
#ifndef MSDOS /* M001 */
extern int getuid();
#else
#define getuid() 0
#endif
typedef struct
{
char howdead[25];
char name[20];
long score;
int level;
int uid;
} score_entry;
#ifdef LINT_ARGS /* M001 */
void show_scores(score_entry *,int );
int readtable(score_entry *);
#else
void show_scores();
int readtable();
#endif
void show_scores(table,num)
score_entry *table;
int num;
{
int tot = num;
printf("\n\
No. Score Level Names How they died\n\
===============================================================================\n"); /*
xx xxxxxx xxxx xxxxxxxxxxxxxxxxxxxx killed by xxxxxxxxxxxxxxxxxxxxxxxxx */
while(num > 0)
{
num--;
printf("%2d %6ld %4d %-20s ",(tot - num),table->score,table->level,table->name);
if(*table->howdead)
printf("killed by %s\n",table->howdead);
else
printf("a total winner!\n");
table++;
}
printf("\n\n");
}
#ifdef EGA
#define vertical(x,y1,y2) egaline(x,y1, x,y2)
#define horizontal(y,x1,x2) egaline(x1,y, x2,y)
void egabox( x1,y1, x2,y2 )
{
horizontal( y1, x1,x2 );
vertical( x2, y1,y2 );
horizontal( y2, x1,x2 );
vertical( x1, y1,y2 );
}
#define X_MIN 0
#define X_NO X_MIN+4+4
#define X_SCORE X_NO+3*8+4+4
#define X_LEVEL X_SCORE+6*8+4+4
#define X_NAMES X_LEVEL+5*8+4+4
#define X_HOW X_NAMES+20*8+4+4
#define X_MAX 639
#define Y_MIN 50
#define Y_TITLE Y_MIN+4+4
#define Y_LINE1 Y_TITLE+1*8+4+1+4
#define Y_MAX Y_LINE1+ENTRIES*10+4+4
void ega_show_scores(header,table,tot)
char *header;
score_entry *table;
int tot;
{
int num;
clear();
egaputs( (640 - 8*strlen(header)) / 2, (50 - 8) / 2, header );
/*
No. Score Level Names How they died
xx xxxxxx xxxx xxxxxxxxxxxxxxxxxxxx killed by xxxxxxxxxxxxxxxxxxxxxxxxx
*/
egabox( X_MIN, Y_MIN, X_MAX, Y_MAX );
egabox( X_MIN+4, Y_MIN+4, X_MAX-4, Y_MAX-4 );
egaprintf(X_NO+2, Y_TITLE, "No." );
egaprintf(X_SCORE+(6*8-5*8)/2, Y_TITLE, "Score" );
egaprintf(X_LEVEL+1, Y_TITLE, "Level" );
egaprintf(X_NAMES, Y_TITLE, " Names How they died" );
horizontal(Y_LINE1-4, X_MIN+4, X_MAX-4);
vertical(X_SCORE-4, Y_MIN+4, Y_MAX-4);
vertical(X_LEVEL-4, Y_MIN+4, Y_MAX-4);
vertical(X_NAMES-4, Y_MIN+4, Y_MAX-4);
vertical(X_HOW-4, Y_MIN+4, Y_MAX-4);
for( num = 1; num <= tot; ++num, ++table ) {
egaprintf(X_NO+(3*8-2*8)/2, Y_LINE1+10*(num-1), "%2d",num);
egaprintf(X_SCORE, Y_LINE1+10*(num-1), "%6ld", table->score);
egaprintf(X_LEVEL+(5*8-4*8)/2, Y_LINE1+10*(num-1), "%4d", table->level);
egaprintf(X_NAMES, Y_LINE1+10*(num-1), "%-20s", table->name);
if(*table->howdead)
egaprintf(X_HOW, Y_LINE1+10*(num-1), "killed by %s", table->howdead);
else
egaprintf(X_HOW, Y_LINE1+10*(num-1), "a total winner!");
}
}
#endif
int readtable(table_ptr)
score_entry *table_ptr;
{
FILE *fp;
int numread;
if((fp = fopen(HISCOREPATH,R_BIN)) == NULL)
{
numread = 0;
}
else
{
numread = fread( VOIDSTAR table_ptr, sizeof(score_entry), ENTRIES, fp);
fclose(fp);
}
return numread;
}
savescore(howdead,score,level,name)
char *howdead, *name;
long score;
int level;
{
score_entry table[ENTRIES + 2],
*table_ptr = table,new_entry;
int numread,index = 1, numsaved, lock, already = 0, user_id;
char buffer[80];
FILE *fp;
LOCK;
numread = readtable(table);
if(name == NULL)
{
show_scores(table,numread);
UNLOCK;
return;
}
user_id = getuid();
strncpy(new_entry.howdead,howdead,25);
new_entry.howdead[24] = '\0'; /* M002 strncpy does not null terminate */
strncpy(new_entry.name,name,20);
new_entry.name[19] = '\0'; /* M002 strncpy does not null terminate */
new_entry.score = score;
new_entry.level = level;
new_entry.uid = user_id;
if (numread > 0)
{
/* insert new_entry at correct point */
for( table_ptr = &table[numread-1]; table_ptr >= table; --table_ptr ) {
if(table_ptr->score > score ||
(table_ptr->score == score && table_ptr->level >= level)) {
table_ptr[1] = new_entry;
break;
}
table_ptr[1] = table_ptr[0];
}
if ( ! (table_ptr >= table) )
table[0] = new_entry;
/* see if name now appears twice */
for( already = index = 0, table_ptr = &table[numread]; table_ptr >= table; --table_ptr ) {
#ifdef COMPARE_BY_NAME
#define SAMEUSER(p) (strcmp((p)->name, name) == 0)
#else
#define SAMEUSER(p) ((p)->uid == user_id)
#endif
if(SAMEUSER(table_ptr))
if(index > 0) {
already= 1;
break;
} else
index = table_ptr - table;
}
if(already)
/* remove duplicate */
while( index < numread ) {
table[index] = table[index + 1];
++index;
}
else
++numread;
}
else
{
#ifdef EGA
if(!EGAaddr)
#endif
printf("\nCreating new hiscore table.\n\n");
table[0] = new_entry;
numread = 1;
}
numread = ( (numread > ENTRIES) ? ENTRIES : numread );
if(howdead[0])
sprintf(buffer,"%s killed by %s with a score of %ld on level %d.",name,howdead,score,level);
else
sprintf(buffer,"%s a total winner with a score of %ld on level %d!",name,score,level);
#ifdef EGA
if(EGAaddr)
ega_show_scores(buffer,table,numread);
else
#endif
{
printf( "\n\n%s\n", buffer );
show_scores(table,numread);
}
fp = fopen(HISCOREPATH,W_BIN);
if (fp)
numsaved = fwrite( VOIDSTAR table, sizeof(score_entry), numread, fp);
else
numsaved = 0;
if(numsaved < numread)
#ifdef EGA
if(EGAaddr)
egaprintf(8,300,"ERROR! Only %d items saved from %d!",numsaved,numread);
else
#endif
printf("ERROR! Only %d items saved from %d !\n",numsaved,numread);
fclose(fp);
chmod(HISCOREPATH,0660);
UNLOCK;
}
void delete_entry(num)
int num;
{
score_entry table[ENTRIES + 22],
*table_ptr = table;
int numread,index = 1, numsaved, lock;
FILE *fp;
LOCK;
numread = readtable(table_ptr);
if (numread == 0) {
printf("Missing or unreadable hiscore table.\n\n");
UNLOCK;
exit(1);
}
if (num > numread) {
printf("Invalid entry, choose again\n");
UNLOCK;
return;
}
while(index < num) {
index++;
table_ptr++;
}
while(index < numread) {
index++;
*table_ptr = *(table_ptr+1);
table_ptr++;
}
numread--;
fp = fopen(HISCOREPATH,W_BIN);
table_ptr = table;
numsaved = fwrite( VOIDSTAR table_ptr, sizeof(score_entry), numread, fp);
chmod(HISCOREPATH,0660);
if(numsaved < numread)
printf("ERROR! Only %d items saved from %d !\n",numsaved,numread);
fclose(fp);
UNLOCK;
show_scores(table,numsaved);
}
erase_scores()
{
int erasenum,numread,index = 0;
char correct[20],c;
score_entry table[ENTRIES + 2],
*table_ptr = table;
printf("Please enter password:");
while((c = getchar()) != '\n' && index <19) {
correct[index++] = c;
}
correct[index] = 0;
if(strcmp(correct,MASTERPASSWORD)) {
printf("\nFoo, charlatan!\n");
return;
}
numread = readtable(table_ptr);
show_scores(table,numread);
printf("\n");
for(;;) {
printf("Number to erase (0 to exit): ");
scanf("%d",&erasenum);
printf("\n");
if(erasenum == 0)
break;
delete_entry(erasenum);
printf("\n");
}
printf("Byee!\n");
}