/* Copyright (c) 2000 Jean-Marc Zucconi * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer * in this position and unchanged. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #define MAX_SCORES 10 #define LEN 28 #include "qix.h" struct { char date[LEN]; char name[LEN]; int score, level; } scores[MAX_SCORES]; int num_games; char *msgs[] = { "** What Utter Crap **", /*0-199*/ "** I don't believe it **", /*200-399*/ "** Rubbish !! **", /*400-599*/ "** What can I say **", /*600-799*/ "** Four figures one day **", /*800-999*/ "** Past the magic thousand **", /*1000-1199*/ "** Must try harder **", /*1200-1399*/ "** Well I suppose you're trying **", /*1400-1599*/ "** Come on **", /*1600-1799*/ "** Almost there **", /*1800-1999*/ "** WOW! over 2000 **", /*2000-2199*/ "** Are you a novice? **", /*2200-2399*/ "** Getting Better **", /*2400-2599*/ "** Keep on trying **", /*2600-2799*/ "** 3000 One of these days **", /*2800-2999*/ "** Practice makes perfect **", /*3000-3199*/ "** OK Now impress me **", /*3200-3399*/ "** You've played before **", /*3400-3599*/ "** I've seen worse **", /*3600-3799*/ "** Keep it up **", /*3800-3999*/ "** Hurrah! 4000 bust **", /*4000-4199*/ "** Not Bad **", /*4200-4399*/ "** Not bad at all **", /*4400-4599*/ "** Pretty fair **", /*4600-4799*/ "** Oh, So close **", /*4800-4999*/ "** I'm almost impressed **", /*5000-5199*/ "** Pretty Good **", /*5200-5399*/ "** OK I like it **", /*5400-5599*/ "** You've got style **", /*5600-5799*/ "** Come on, you can do it **", /*5800-5900*/ "** OK that wasn't bad **", /*6000 et seq*/ "** Congratulations Champ !! **", 0}; char file[1024]; FILE *open_score (); void read_scores (FILE *), top_init (), write_scores (FILE *); void TopTen (int score, int level) { FILE *f; time_t t; int i, j, hiscore, k; char *s, *p; f = open_score (); rewind (f); if (fread (file, 1, 1, f) == 0) { top_init (); write_scores (f); } rewind (f); read_scores (f); hiscore = scores[0].score; num_games++; j = -1; for (i = 0; i < MAX_SCORES; i++) if (score >= scores[i].score) { for (j = MAX_SCORES-1; j > i; j--) scores[j] = scores[j-1]; t = time (0); scores[i].score = score; scores[i].level = level; s = ctime (&t); p = strchr (s, '\n'); if (p) *p = 0; strcpy (scores[i].date, s); strcpy (scores[i].name, getlogin ()); break; } if (score > hiscore) top_header (msgs[31], num_games); else { k = score/200; if (k > 30) k = 30; top_header (msgs[k], num_games); } for (i = 0; i < MAX_SCORES; i++) top_entry (i, scores[i].score, scores[i].level, scores[i].name, scores[i].date, j == i ? 1 : 0); top_score (score); rewind (f); write_scores (f); unlink (LOCK_FILE); fclose (f); } FILE * open_score () { FILE *f; /* create tmp file */ strcpy (file, GAMEDIR); strcat (file, "/tmpXXXXXX"); if (mkstemp (file) < 0) terminate (file); while (link (file, LOCK_FILE)) wait_message (); unlink (file); f = fopen (SCORE_FILE, "r+"); if (!f) { f = fopen (SCORE_FILE, "w"); if (!f) { unlink (LOCK_FILE); terminate (SCORE_FILE); } } rewind (f); return f; } void read_scores (FILE *f) { int i; fread (&num_games, 4, 1, f); for (i = 0; i < MAX_SCORES; i++) { fread (&scores[i].score, 4, 1, f); fread (&scores[i].level, 4, 1, f); fread (scores[i].date, 1, LEN, f); fread (scores[i].name, 1, LEN, f); } } void write_scores (FILE *f) { int i; fwrite (&num_games, 4, 1, f); for (i = 0; i < MAX_SCORES; i++) { fwrite (&scores[i].score, 4, 1, f); fwrite (&scores[i].level, 4, 1, f); fwrite (scores[i].date, 1, LEN, f); fwrite (scores[i].name, 1, LEN, f); } } void top_init () { int i; num_games = 0; for (i = 0; i < MAX_SCORES; i++) { scores[i].score = (MAX_SCORES-i)*500; scores[i].level = 3 - i/4; strcpy (scores[i].date, ""); strcpy (scores[i].name, "Qix"); } }