home *** CD-ROM | disk | FTP | other *** search
- /*
- * SvB score file
- */
- /*
- * Copyright 1992 David Lemke and Network Computing Devices
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Network Computing Devices not be
- * used in advertising or publicity pertaining to distribution of the
- * software without specific, written prior permission. Network Computing
- * Devices makes no representations about the suitability of this software
- * for any purpose. It is provided "as is" without express or implied
- * warranty.
- *
- * NETWORK COMPUTING DEVICES DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
- * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
- * IN NO EVENT SHALL NETWORK COMPUTING DEVICES BE LIABLE FOR ANY SPECIAL,
- * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
- * OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Author:
- * Dave Lemke
- * lemke@ncd.com
- *
- * Network Computing Devices, Inc
- * 350 North Bernardo Ave
- * Mountain View, CA 94043
- *
- * @(#)score.c 1.3 92/01/20
- *
- */
-
- #include <stdio.h>
- #include <X11/Xos.h>
- #include <X11/Xlib.h>
- #include <X11/Xutil.h>
- #include <sys/file.h>
-
- extern Display *dpy;
- extern Window game_win;
- extern GC text_gc;
-
- extern char user_name[];
- extern int highscore;
-
- extern char get_key();
-
- static void find_personal_best();
- static void draw_scores();
-
- void update_scores();
-
- #define NUM_TOP_SCORES 25
- #define SCORES_PER_USER 5
-
- #define SCORE_Y_INC 15
- #define TOP_SCORE_Y 30
- #define PERSONAL_SCORE_Y (3 * TOP_SCORE_Y + (NUM_TOP_SCORES * SCORE_Y_INC))
- #define SCORE_X 10
-
- #define MESSAGE_Y (PERSONAL_SCORE_Y + (SCORES_PER_USER + 1) * SCORE_Y_INC)
-
- #ifndef SCOREFILE
- #define SCOREFILE "/tmp/svb.scores"
- #endif
-
- typedef struct _score {
- char name[40];
- int score;
- int ledge;
- } Score;
-
- Score top_scores[NUM_TOP_SCORES];
- Score personal[SCORES_PER_USER];
- Bool read_scores = False;
-
- static void
- wait_for_key()
- {
- XEvent ev;
- char c;
-
- while (1) {
- XNextEvent(dpy, &ev);
- if (ev.type == Expose && ev.xexpose.count == 0)
- draw_scores();
- else if (ev.type == KeyPress) {
- c = get_key((XKeyPressedEvent *) & ev);
- if (c == 'q')
- exit(0);
- else if (c == 'h') {
- update_scores();
- draw_scores();
- } else if (c == ' ' || c == 's')
- return;
- }
- }
- }
-
- static void
- draw_scores()
- {
- int i,
- y;
- char scorebuf[256];
-
- XClearWindow(dpy, game_win);
- sprintf(scorebuf, "%40s", "Top Scores");
- XDrawImageString(dpy, game_win, text_gc, SCORE_X, 15,
- scorebuf, strlen(scorebuf));
- y = TOP_SCORE_Y;
- for (i = 0; i < NUM_TOP_SCORES; i++) {
- sprintf(scorebuf, " %2d %30s %7d Ledge %3d",
- i + 1, top_scores[i].name, top_scores[i].score,
- top_scores[i].ledge);
- XDrawImageString(dpy, game_win, text_gc, SCORE_X, y,
- scorebuf, strlen(scorebuf));
- y += SCORE_Y_INC;
- }
- sprintf(scorebuf, "%40s", "Personal Top Scores");
- y = PERSONAL_SCORE_Y;
- XDrawImageString(dpy, game_win, text_gc, SCORE_X, y - 2 * SCORE_Y_INC,
- scorebuf, strlen(scorebuf));
- for (i = 0; i < SCORES_PER_USER; i++) {
- sprintf(scorebuf, " %2d %30s %7d Ledge %3d",
- i + 1, personal[i].name, personal[i].score,
- personal[i].ledge);
- XDrawImageString(dpy, game_win, text_gc, SCORE_X, y,
- scorebuf, strlen(scorebuf));
- y += SCORE_Y_INC;
- }
-
- sprintf(scorebuf, " 'q' to Quit, 's' to Start");
- XDrawImageString(dpy, game_win, text_gc, SCORE_X, MESSAGE_Y,
- scorebuf, strlen(scorebuf));
- }
-
- static void
- find_personal_best()
- {
- int i,
- j;
-
- for (i = 0; i < SCORES_PER_USER; i++) {
- strcpy(personal[i].name, user_name);
- personal[i].score = 0;
- personal[i].ledge = 0;
- }
- for (i = 0, j = 0; i < NUM_TOP_SCORES; i++) {
- if (strcmp(top_scores[i].name, user_name) == 0) {
- personal[j].score = top_scores[i].score;
- personal[j].ledge = top_scores[i].ledge;
- j++;
- if (j == SCORES_PER_USER)
- return;;
- }
- }
- }
-
- /*
- * reads/inits score file
- */
- void
- update_scores()
- {
- FILE *fp;
- int i;
- char buf[256];
-
- fp = fopen(SCOREFILE, "r");
- if (fp) {
- #ifdef SYSV
- long fsize;
-
- fsize = fseek(fp, 0L, 2);
- (void) fseek(fp, 0L, 0);
- lockf(fileno(fp), F_LOCK, fsize);
- #else /*SYSV*/
- flock(fileno(fp), LOCK_EX);
- #endif /*SYSV*/
- i = 0;
- while (fgets(buf, 256, fp)) {
- sscanf(buf, "%s %d %d", top_scores[i].name, &top_scores[i].score,
- &top_scores[i].ledge);
- i++;
- }
- if (!read_scores)
- find_personal_best();
- fclose(fp);
- } else {
- /* do reinit if already running and unreadable file */
- if (read_scores)
- return;
- for (i = 0; i < NUM_TOP_SCORES; i++) {
- strcpy(top_scores[i].name, "Nobody");
- top_scores[i].score = 0;
- top_scores[i].ledge = 0;
- }
- for (i = 0; i < SCORES_PER_USER; i++) {
- strcpy(personal[i].name, user_name);
- personal[i].score = 0;
- personal[i].ledge = 0;
- }
- }
- read_scores = True;
- highscore = personal[0].score;
- }
-
- /*
- * displays all current scores
- */
- void
- show_scores()
- {
- update_scores();
- draw_scores();
- wait_for_key();
- }
-
- static void
- write_scores()
- {
- FILE *fp;
- int i;
-
- fp = fopen(SCOREFILE, "w");
- if (fp) {
- #ifdef SYSV
- long fsize;
-
- fsize = fseek(fp, 0L, 2);
- (void) fseek(fp, 0L, 0);
- lockf(fileno(fp), F_LOCK, fsize);
- #else /*SYSV*/
- flock(fileno(fp), LOCK_EX);
- #endif /*SYSV*/
- for (i = 0; i < NUM_TOP_SCORES; i++)
- fprintf(fp, "%s %d %d\n", top_scores[i].name,
- top_scores[i].score, top_scores[i].ledge);
- fclose(fp);
- }
- }
-
- /*
- * adds score to table
- */
- add_score(sc, ledge)
- int sc;
- int ledge;
- {
- int i,
- j;
- int user_count = 0;
- int replace;
- int low_user = 0;
-
- update_scores(); /* make sure they're up-to-date */
- for (i = 0; i < NUM_TOP_SCORES; i++) {
- if (strcmp(top_scores[i].name, user_name) == 0) {
- user_count++;
- low_user = top_scores[i].score;
- replace = i;
- }
- }
-
- /*
- * punt if we have the full number of scores && the new one is too low to
- * care about
- */
- if (user_count >= SCORES_PER_USER) {
- if (sc <= low_user) {
- return;
- }
- } else {
- replace = NUM_TOP_SCORES - 1;
- }
-
- for (i = 0; i < NUM_TOP_SCORES; i++) {
- if (sc > top_scores[i].score) {
- for (j = replace; j > i; j--) {
- strcpy(top_scores[j].name, top_scores[j - 1].name);
- top_scores[j].score = top_scores[j - 1].score;
- top_scores[j].ledge = top_scores[j - 1].ledge;
- }
- strcpy(top_scores[i].name, user_name);
- top_scores[i].score = sc;
- top_scores[i].ledge = ledge;
- break;
- }
- }
- for (i = 0; i < SCORES_PER_USER; i++) {
- if (sc > personal[i].score) {
- for (j = SCORES_PER_USER - 1; j > i; j--) {
- personal[j].score = personal[j - 1].score;
- personal[j].ledge = personal[j - 1].ledge;
- }
- personal[i].score = sc;
- personal[i].ledge = ledge;
- break;
- }
- }
- highscore = personal[0].score;
- write_scores();
- }
-