Changeset c0e674a in mainline


Ignore:
Timestamp:
2006-05-31T16:15:44Z (19 years ago)
Author:
Ondrej Palkovsky <ondrap@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
5052046
Parents:
b27a97bb
Message:

Fix incorrect timeout handling in async framework.
Start tweak the tetris code.

Files:
6 edited

Legend:

Unmodified
Added
Removed
  • console/console.c

    rb27a97bb rc0e674a  
    3939#include <async.h>
    4040
     41static void sysput(char c)
     42{
     43        __SYSCALL3(SYS_IO, 1, &c, 1);
     44
     45}
    4146//#define CONSOLE_COUNT VFB_CONNECTIONS
    4247#define CONSOLE_COUNT 6
     
    157162                case CONSOLE_GETCHAR:
    158163                        /* FIXME: Only temporary solution until request storage will be created  */
    159                        
    160164                        while (!keybuffer_pop(&(connections[active_client].keybuffer), (char *)&arg1)) {
    161165                                /* FIXME: buffer empty -> store request */
    162                                 usleep(10000);
     166                                async_usleep(100000);
    163167                        };
    164168                       
  • libc/generic/async.c

    rb27a97bb rc0e674a  
    165165        return 0;
    166166}
     167static int tv_gteq(struct timeval *tv1, struct timeval *tv2)
     168{
     169        if (tv1->tv_sec > tv2->tv_sec)
     170                return 1;
     171        if (tv1->tv_sec == tv2->tv_sec && tv1->tv_usec >= tv2->tv_usec)
     172                return 1;
     173        return 0;
     174}
    167175
    168176/* Hash table functions */
     
    241249        connection_t *conn;
    242250       
     251        assert(PS_connection);
     252
    243253        futex_down(&async_futex);
    244254
     
    436446                        amsg = list_get_instance(timeout_list.next,amsg_t,link);
    437447                        gettimeofday(&tv,NULL);
    438                         if (tv_gt(&tv, &amsg->expires)) {
     448                        if (tv_gteq(&tv, &amsg->expires)) {
    439449                                handle_expired_timeouts();
    440450                                continue;
     
    589599        while (tmp != &timeout_list) {
    590600                cur = list_get_instance(tmp, amsg_t, link);
    591                 if (tv_gt(&cur->expires, &msg->expires))
     601                if (tv_gteq(&cur->expires, &msg->expires))
    592602                        break;
    593603                tmp = tmp->next;
  • tetris/Makefile

    rb27a97bb rc0e674a  
    66
    77OUTPUT = tetris
    8 SOURCES = shapes.c tetris.c scores.c input.c screen.c
     8SOURCES = shapes.c scores.c input.c tetris.c screen.c
    99OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
    1010
  • tetris/input.c

    rb27a97bb rc0e674a  
    5050#include "tetris.h"
    5151
     52#include <async.h>
     53
    5254/* return true iff the given timeval is positive */
    5355#define TV_POS(tv) \
     
    6264                (res)->tv_sec--; \
    6365        }
     66
     67static aid_t getchar_inprog = 0;
    6468
    6569/*
  • tetris/scores.c

    rb27a97bb rc0e674a  
    4444 */
    4545#include <errno.h>
    46 #include <err.h>
    47 #include <fcntl.h>
    48 #include <pwd.h>
    49 #include <stdio.h>
    50 #include <stdlib.h>
    51 #include <string.h>
    52 #include <time.h>
    53 #include <term.h>
    54 #include <unistd.h>
    55 #include <sys/param.h>
    56 #include <sys/stat.h>
    57 #include <sys/types.h>
     46/* #include <err.h> */
     47/* #include <fcntl.h> */
     48/* #include <pwd.h> */
     49/* #include <stdio.h> */
     50/* #include <stdlib.h> */
     51/* #include <string.h> */
     52/* #include <time.h> */
     53/* #include <term.h> */
     54/* #include <unistd.h> */
     55/* #include <sys/param.h> */
     56/* #include <sys/stat.h> */
     57/* #include <sys/types.h> */
    5858
    5959#include "pathnames.h"
    6060#include "screen.h"
     61#include "tetris.h"
    6162#include "scores.h"
    62 #include "tetris.h"
    6363
    6464/*
     
    7373#define NLEVELS (MAXLEVEL + 1)
    7474
    75 static time_t now;
    76 static int nscores;
    77 static int gotscores;
    78 static struct highscore scores[NUMSPOTS];
    79 
    80 static int checkscores(struct highscore *, int);
    81 static int cmpscores(const void *, const void *);
    82 static void getscores(FILE **);
    83 static void printem(int, int, struct highscore *, int, const char *);
    84 static char *thisuser(void);
     75/* static time_t now; */
     76/* static int nscores; */
     77/* static int gotscores; */
     78/* static struct highscore scores[NUMSPOTS]; */
     79
     80/* static int checkscores(struct highscore *, int); */
     81/* static int cmpscores(const void *, const void *); */
     82/* static void getscores(FILE **); */
     83/* static void printem(int, int, struct highscore *, int, const char *); */
     84/* static char *thisuser(void); */
    8585
    8686/*
     
    9393 * Note, we assume closing the stdio file releases the lock.
    9494 */
    95 static void
    96 getscores(FILE **fpp)
    97 {
    98         int sd, mint, lck, mask, i;
    99         char *mstr, *human;
    100         FILE *sf;
    101 
    102         if (fpp != NULL) {
    103                 mint = O_RDWR | O_CREAT;
    104                 mstr = "r+";
    105                 human = "read/write";
    106                 lck = LOCK_EX;
    107         } else {
    108                 mint = O_RDONLY;
    109                 mstr = "r";
    110                 human = "reading";
    111                 lck = LOCK_SH;
    112         }
    113         setegid(egid);
    114         mask = umask(S_IWOTH);
    115         sd = open(_PATH_SCOREFILE, mint, 0666);
    116         (void)umask(mask);
    117         setegid(gid);
    118         if (sd < 0) {
    119                 if (fpp == NULL) {
    120                         nscores = 0;
    121                         return;
    122                 }
    123                 err(1, "cannot open %s for %s", _PATH_SCOREFILE, human);
    124         }
    125         setegid(egid);
    126         if ((sf = fdopen(sd, mstr)) == NULL)
    127                 err(1, "cannot fdopen %s for %s", _PATH_SCOREFILE, human);
    128         setegid(gid);
    129 
    130         /*
    131          * Grab a lock.
    132         */
    133         if (flock(sd, lck))
    134                 warn("warning: score file %s cannot be locked",
    135                     _PATH_SCOREFILE);
    136 
    137         nscores = fread(scores, sizeof(scores[0]), MAXHISCORES, sf);
    138         if (ferror(sf))
    139                 err(1, "error reading %s", _PATH_SCOREFILE);
    140         for (i = 0; i < nscores; i++)
    141                 if (scores[i].hs_level < MINLEVEL ||
    142                     scores[i].hs_level > MAXLEVEL)
    143                         errx(1, "scorefile %s corrupt", _PATH_SCOREFILE);
    144 
    145         if (fpp)
    146                 *fpp = sf;
    147         else
    148                 (void)fclose(sf);
    149 }
     95/* static void */
     96/* getscores(FILE **fpp) */
     97/* { */
     98/*      int sd, mint, lck, mask, i; */
     99/*      char *mstr, *human; */
     100/*      FILE *sf; */
     101
     102/*      if (fpp != NULL) { */
     103/*              mint = O_RDWR | O_CREAT; */
     104/*              mstr = "r+"; */
     105/*              human = "read/write"; */
     106/*              lck = LOCK_EX; */
     107/*      } else { */
     108/*              mint = O_RDONLY; */
     109/*              mstr = "r"; */
     110/*              human = "reading"; */
     111/*              lck = LOCK_SH; */
     112/*      } */
     113/*      setegid(egid); */
     114/*      mask = umask(S_IWOTH); */
     115/*      sd = open(_PATH_SCOREFILE, mint, 0666); */
     116/*      (void)umask(mask); */
     117/*      setegid(gid); */
     118/*      if (sd < 0) { */
     119/*              if (fpp == NULL) { */
     120/*                      nscores = 0; */
     121/*                      return; */
     122/*              } */
     123/*              err(1, "cannot open %s for %s", _PATH_SCOREFILE, human); */
     124/*      } */
     125/*      setegid(egid); */
     126/*      if ((sf = fdopen(sd, mstr)) == NULL) */
     127/*              err(1, "cannot fdopen %s for %s", _PATH_SCOREFILE, human); */
     128/*      setegid(gid); */
     129
     130/*      /\* */
     131/*       * Grab a lock. */
     132/*       *\/ */
     133/*      if (flock(sd, lck)) */
     134/*              warn("warning: score file %s cannot be locked", */
     135/*                  _PATH_SCOREFILE); */
     136
     137/*      nscores = fread(scores, sizeof(scores[0]), MAXHISCORES, sf); */
     138/*      if (ferror(sf)) */
     139/*              err(1, "error reading %s", _PATH_SCOREFILE); */
     140/*      for (i = 0; i < nscores; i++) */
     141/*              if (scores[i].hs_level < MINLEVEL || */
     142/*                  scores[i].hs_level > MAXLEVEL) */
     143/*                      errx(1, "scorefile %s corrupt", _PATH_SCOREFILE); */
     144
     145/*      if (fpp) */
     146/*              *fpp = sf; */
     147/*      else */
     148/*              (void)fclose(sf); */
     149/* } */
    150150
    151151void
    152152savescore(int level)
    153153{
    154         struct highscore *sp;
    155         int i;
    156         int change;
    157         FILE *sf;
    158         const char *me;
    159 
    160         getscores(&sf);
    161         gotscores = 1;
    162         (void)time(&now);
    163 
    164         /*
    165          * Allow at most one score per person per level -- see if we
    166          * can replace an existing score, or (easiest) do nothing.
    167          * Otherwise add new score at end (there is always room).
    168          */
    169         change = 0;
    170         me = thisuser();
    171         for (i = 0, sp = &scores[0]; i < nscores; i++, sp++) {
    172                 if (sp->hs_level != level || strcmp(sp->hs_name, me) != 0)
    173                         continue;
    174                 if (score > sp->hs_score) {
    175                         (void)printf("%s bettered %s %d score of %d!\n",
    176                             "\nYou", "your old level", level,
    177                             sp->hs_score * sp->hs_level);
    178                         sp->hs_score = score;   /* new score */
    179                         sp->hs_time = now;      /* and time */
    180                         change = 1;
    181                 } else if (score == sp->hs_score) {
    182                         (void)printf("%s tied %s %d high score.\n",
    183                             "\nYou", "your old level", level);
    184                         sp->hs_time = now;      /* renew it */
    185                         change = 1;             /* gotta rewrite, sigh */
    186                 } /* else new score < old score: do nothing */
    187                 break;
    188         }
    189         if (i >= nscores) {
    190                 strlcpy(sp->hs_name, me, sizeof sp->hs_name);
    191                 sp->hs_level = level;
    192                 sp->hs_score = score;
    193                 sp->hs_time = now;
    194                 nscores++;
    195                 change = 1;
    196         }
    197 
    198         if (change) {
    199                 /*
    200                  * Sort & clean the scores, then rewrite.
    201                  */
    202                 nscores = checkscores(scores, nscores);
    203                 rewind(sf);
    204                 if (fwrite(scores, sizeof(*sp), nscores, sf) != nscores ||
    205                     fflush(sf) == EOF)
    206                         warnx("error writing %s: %s\n\t-- %s",
    207                             _PATH_SCOREFILE, strerror(errno),
    208                             "high scores may be damaged");
    209         }
    210         (void)fclose(sf);       /* releases lock */
     154        return;
    211155}
     156/*      struct highscore *sp; */
     157/*      int i; */
     158/*      int change; */
     159/*      FILE *sf; */
     160/*      const char *me; */
     161
     162/*      getscores(&sf); */
     163/*      gotscores = 1; */
     164/*      (void)time(&now); */
     165
     166/*      /\* */
     167/*       * Allow at most one score per person per level -- see if we */
     168/*       * can replace an existing score, or (easiest) do nothing. */
     169/*       * Otherwise add new score at end (there is always room). */
     170/*       *\/ */
     171/*      change = 0; */
     172/*      me = thisuser(); */
     173/*      for (i = 0, sp = &scores[0]; i < nscores; i++, sp++) { */
     174/*              if (sp->hs_level != level || strcmp(sp->hs_name, me) != 0) */
     175/*                      continue; */
     176/*              if (score > sp->hs_score) { */
     177/*                      (void)printf("%s bettered %s %d score of %d!\n", */
     178/*                          "\nYou", "your old level", level, */
     179/*                          sp->hs_score * sp->hs_level); */
     180/*                      sp->hs_score = score;   /\* new score *\/ */
     181/*                      sp->hs_time = now;      /\* and time *\/ */
     182/*                      change = 1; */
     183/*              } else if (score == sp->hs_score) { */
     184/*                      (void)printf("%s tied %s %d high score.\n", */
     185/*                          "\nYou", "your old level", level); */
     186/*                      sp->hs_time = now;      /\* renew it *\/ */
     187/*                      change = 1;             /\* gotta rewrite, sigh *\/ */
     188/*              } /\* else new score < old score: do nothing *\/ */
     189/*              break; */
     190/*      } */
     191/*      if (i >= nscores) { */
     192/*              strlcpy(sp->hs_name, me, sizeof sp->hs_name); */
     193/*              sp->hs_level = level; */
     194/*              sp->hs_score = score; */
     195/*              sp->hs_time = now; */
     196/*              nscores++; */
     197/*              change = 1; */
     198/*      } */
     199
     200/*      if (change) { */
     201/*              /\* */
     202/*               * Sort & clean the scores, then rewrite. */
     203/*               *\/ */
     204/*              nscores = checkscores(scores, nscores); */
     205/*              rewind(sf); */
     206/*              if (fwrite(scores, sizeof(*sp), nscores, sf) != nscores || */
     207/*                  fflush(sf) == EOF) */
     208/*                      warnx("error writing %s: %s\n\t-- %s", */
     209/*                          _PATH_SCOREFILE, strerror(errno), */
     210/*                          "high scores may be damaged"); */
     211/*      } */
     212/*      (void)fclose(sf);       /\* releases lock *\/ */
     213/* } */
    212214
    213215/*
     
    215217 * The result is always trimmed to fit in a score.
    216218 */
    217 static char *
    218 thisuser(void)
    219 {
    220         const char *p;
    221         struct passwd *pw;
    222         static char u[sizeof(scores[0].hs_name)];
    223 
    224         if (u[0])
    225                 return (u);
    226         p = getlogin();
    227         if (p == NULL || *p == '\0') {
    228                 pw = getpwuid(getuid());
    229                 if (pw != NULL)
    230                         p = pw->pw_name;
    231                 else
    232                         p = "  ???";
    233         }
    234         strlcpy(u, p, sizeof(u));
    235         return (u);
    236 }
     219/* static char * */
     220/* thisuser(void) */
     221/* { */
     222/*      const char *p; */
     223/*      struct passwd *pw; */
     224/*      static char u[sizeof(scores[0].hs_name)]; */
     225
     226/*      if (u[0]) */
     227/*              return (u); */
     228/*      p = getlogin(); */
     229/*      if (p == NULL || *p == '\0') { */
     230/*              pw = getpwuid(getuid()); */
     231/*              if (pw != NULL) */
     232/*                      p = pw->pw_name; */
     233/*              else */
     234/*                      p = "  ???"; */
     235/*      } */
     236/*      strlcpy(u, p, sizeof(u)); */
     237/*      return (u); */
     238/* } */
    237239
    238240/*
     
    242244 * listed first in the highscore file.
    243245 */
    244 static int
    245 cmpscores(const void *x, const void *y)
    246 {
    247         const struct highscore *a, *b;
    248         long l;
    249 
    250         a = x;
    251         b = y;
    252         l = (long)b->hs_level * b->hs_score - (long)a->hs_level * a->hs_score;
    253         if (l < 0)
    254                 return (-1);
    255         if (l > 0)
    256                 return (1);
    257         if (a->hs_time < b->hs_time)
    258                 return (-1);
    259         if (a->hs_time > b->hs_time)
    260                 return (1);
    261         return (0);
    262 }
     246/* static int */
     247/* cmpscores(const void *x, const void *y) */
     248/* { */
     249/*      const struct highscore *a, *b; */
     250/*      long l; */
     251
     252/*      a = x; */
     253/*      b = y; */
     254/*      l = (long)b->hs_level * b->hs_score - (long)a->hs_level * a->hs_score; */
     255/*      if (l < 0) */
     256/*              return (-1); */
     257/*      if (l > 0) */
     258/*              return (1); */
     259/*      if (a->hs_time < b->hs_time) */
     260/*              return (-1); */
     261/*      if (a->hs_time > b->hs_time) */
     262/*              return (1); */
     263/*      return (0); */
     264/* } */
    263265
    264266/*
     
    271273 * Caveat:  the highest score on each level is always kept.
    272274 */
    273 static int
    274 checkscores(struct highscore *hs, int num)
    275 {
    276         struct highscore *sp;
    277         int i, j, k, numnames;
    278         int levelfound[NLEVELS];
    279         struct peruser {
    280                 char *name;
    281                 int times;
    282         } count[NUMSPOTS];
    283         struct peruser *pu;
    284 
    285         /*
    286          * Sort so that highest totals come first.
    287          *
    288          * levelfound[i] becomes set when the first high score for that
    289          * level is encountered.  By definition this is the highest score.
    290         */
    291         qsort((void *)hs, nscores, sizeof(*hs), cmpscores);
    292         for (i = MINLEVEL; i < NLEVELS; i++)
    293                 levelfound[i] = 0;
    294         numnames = 0;
    295         for (i = 0, sp = hs; i < num;) {
    296                 /*
    297                  * This is O(n^2), but do you think we care?
    298                 */
    299                 for (j = 0, pu = count; j < numnames; j++, pu++)
    300                         if (strcmp(sp->hs_name, pu->name) == 0)
    301                                 break;
    302                 if (j == numnames) {
    303                         /*
    304                          * Add new user, set per-user count to 1.
    305                         */
    306                         pu->name = sp->hs_name;
    307                         pu->times = 1;
    308                         numnames++;
    309                 } else {
    310                         /*
    311                          * Two ways to keep this score:
    312                          * - Not too many (per user), still has acct, &
    313                          *      score not dated; or
    314                          * - High score on this level.
    315                         */
    316                         if ((pu->times < MAXSCORES &&
    317                              getpwnam(sp->hs_name) != NULL &&
    318                              sp->hs_time + EXPIRATION >= now) ||
    319                             levelfound[sp->hs_level] == 0)
    320                                 pu->times++;
    321                         else {
    322                                 /*
    323                                  * Delete this score, do not count it,
    324                                  * do not pass go, do not collect $200.
    325                                 */
    326                                 num--;
    327                                 for (k = i; k < num; k++)
    328                                         hs[k] = hs[k + 1];
    329                                 continue;
    330                         }
    331                 }
    332                 levelfound[sp->hs_level] = 1;
    333                 i++, sp++;
    334         }
    335         return (num > MAXHISCORES ? MAXHISCORES : num);
    336 }
     275/* static int */
     276/* checkscores(struct highscore *hs, int num) */
     277/* { */
     278/*      struct highscore *sp; */
     279/*      int i, j, k, numnames; */
     280/*      int levelfound[NLEVELS]; */
     281/*      struct peruser { */
     282/*              char *name; */
     283/*              int times; */
     284/*      } count[NUMSPOTS]; */
     285/*      struct peruser *pu; */
     286
     287/*      /\* */
     288/*       * Sort so that highest totals come first. */
     289/*       * */
     290/*       * levelfound[i] becomes set when the first high score for that */
     291/*       * level is encountered.  By definition this is the highest score. */
     292/*       *\/ */
     293/*      qsort((void *)hs, nscores, sizeof(*hs), cmpscores); */
     294/*      for (i = MINLEVEL; i < NLEVELS; i++) */
     295/*              levelfound[i] = 0; */
     296/*      numnames = 0; */
     297/*      for (i = 0, sp = hs; i < num;) { */
     298/*              /\* */
     299/*               * This is O(n^2), but do you think we care? */
     300/*               *\/ */
     301/*              for (j = 0, pu = count; j < numnames; j++, pu++) */
     302/*                      if (strcmp(sp->hs_name, pu->name) == 0) */
     303/*                              break; */
     304/*              if (j == numnames) { */
     305/*                      /\* */
     306/*                       * Add new user, set per-user count to 1. */
     307/*                       *\/ */
     308/*                      pu->name = sp->hs_name; */
     309/*                      pu->times = 1; */
     310/*                      numnames++; */
     311/*              } else { */
     312/*                      /\* */
     313/*                       * Two ways to keep this score: */
     314/*                       * - Not too many (per user), still has acct, & */
     315/*                       *      score not dated; or */
     316/*                       * - High score on this level. */
     317/*                       *\/ */
     318/*                      if ((pu->times < MAXSCORES && */
     319/*                           getpwnam(sp->hs_name) != NULL && */
     320/*                           sp->hs_time + EXPIRATION >= now) || */
     321/*                          levelfound[sp->hs_level] == 0) */
     322/*                              pu->times++; */
     323/*                      else { */
     324/*                              /\* */
     325/*                               * Delete this score, do not count it, */
     326/*                               * do not pass go, do not collect $200. */
     327/*                               *\/ */
     328/*                              num--; */
     329/*                              for (k = i; k < num; k++) */
     330/*                                      hs[k] = hs[k + 1]; */
     331/*                              continue; */
     332/*                      } */
     333/*              } */
     334/*              levelfound[sp->hs_level] = 1; */
     335/*              i++, sp++; */
     336/*      } */
     337/*      return (num > MAXHISCORES ? MAXHISCORES : num); */
     338/* } */
    337339
    338340/*
     
    346348showscores(int level)
    347349{
    348         struct highscore *sp;
    349         int i, n, c;
    350         const char *me;
    351         int levelfound[NLEVELS];
    352 
    353         if (!gotscores)
    354                 getscores((FILE **)NULL);
    355         (void)printf("\n\t\t    Tetris High Scores\n");
    356 
    357         /*
    358          * If level == 0, the person has not played a game but just asked for
    359          * the high scores; we do not need to check for printing in highlight
    360          * mode.  If SOstr is null, we can't do highlighting anyway.
    361          */
    362         me = level && SOstr ? thisuser() : NULL;
    363 
    364         /*
    365          * Set times to 0 except for high score on each level.
    366          */
    367         for (i = MINLEVEL; i < NLEVELS; i++)
    368                 levelfound[i] = 0;
    369         for (i = 0, sp = scores; i < nscores; i++, sp++) {
    370                 if (levelfound[sp->hs_level])
    371                         sp->hs_time = 0;
    372                 else {
    373                         sp->hs_time = 1;
    374                         levelfound[sp->hs_level] = 1;
    375                 }
    376         }
    377 
    378         /*
    379          * Page each screenful of scores.
    380          */
    381         for (i = 0, sp = scores; i < nscores; sp += n) {
    382                 n = 20;
    383                 if (i + n > nscores)
    384                         n = nscores - i;
    385                 printem(level, i + 1, sp, n, me);
    386                 if ((i += n) < nscores) {
    387                         (void)printf("\nHit RETURN to continue.");
    388                         (void)fflush(stdout);
    389                         while ((c = getchar()) != '\n')
    390                                 if (c == EOF)
    391                                         break;
    392                         (void)printf("\n");
    393                 }
    394         }
    395 
    396         if (nscores == 0)
    397                 printf("\t\t\t      - none to date.\n");
     350        return;
    398351}
    399352
    400 static void
    401 printem(int level, int offset, struct highscore *hs, int n, const char *me)
    402 {
    403         struct highscore *sp;
    404         int row, highlight, i;
    405         char buf[100];
    406 #define TITLE "Rank  Score   Name                          (points/level)"
    407 #define TITL2 "=========================================================="
    408 
    409         printf("%s\n%s\n", TITLE, TITL2);
    410 
    411         highlight = 0;
    412 
    413         for (row = 0; row < n; row++) {
    414                 sp = &hs[row];
    415                 (void)snprintf(buf, sizeof(buf),
    416                     "%3d%c %6d  %-31s (%6d on %d)\n",
    417                     row + offset, sp->hs_time ? '*' : ' ',
    418                     sp->hs_score * sp->hs_level,
    419                     sp->hs_name, sp->hs_score, sp->hs_level);
    420                 /* Print leaders every three lines */
    421                 if ((row + 1) % 3 == 0) {
    422                         for (i = 0; i < sizeof(buf); i++)
    423                                 if (buf[i] == ' ')
    424                                         buf[i] = '_';
    425                 }
    426                 /*
    427                  * Highlight if appropriate.  This works because
    428                  * we only get one score per level.
    429                  */
    430                 if (me != NULL &&
    431                     sp->hs_level == level &&
    432                     sp->hs_score == score &&
    433                     strcmp(sp->hs_name, me) == 0) {
    434                         putpad(SOstr);
    435                         highlight = 1;
    436                 }
    437                 (void)printf("%s", buf);
    438                 if (highlight) {
    439                         putpad(SEstr);
    440                         highlight = 0;
    441                 }
    442         }
    443 }
     353/*      struct highscore *sp; */
     354/*      int i, n, c; */
     355/*      const char *me; */
     356/*      int levelfound[NLEVELS]; */
     357
     358/*      if (!gotscores) */
     359/*              getscores((FILE **)NULL); */
     360/*      (void)printf("\n\t\t    Tetris High Scores\n"); */
     361
     362/*      /\* */
     363/*       * If level == 0, the person has not played a game but just asked for */
     364/*       * the high scores; we do not need to check for printing in highlight */
     365/*       * mode.  If SOstr is null, we can't do highlighting anyway. */
     366/*       *\/ */
     367/*      me = level && SOstr ? thisuser() : NULL; */
     368
     369/*      /\* */
     370/*       * Set times to 0 except for high score on each level. */
     371/*       *\/ */
     372/*      for (i = MINLEVEL; i < NLEVELS; i++) */
     373/*              levelfound[i] = 0; */
     374/*      for (i = 0, sp = scores; i < nscores; i++, sp++) { */
     375/*              if (levelfound[sp->hs_level]) */
     376/*                      sp->hs_time = 0; */
     377/*              else { */
     378/*                      sp->hs_time = 1; */
     379/*                      levelfound[sp->hs_level] = 1; */
     380/*              } */
     381/*      } */
     382
     383/*      /\* */
     384/*       * Page each screenful of scores. */
     385/*       *\/ */
     386/*      for (i = 0, sp = scores; i < nscores; sp += n) { */
     387/*              n = 20; */
     388/*              if (i + n > nscores) */
     389/*                      n = nscores - i; */
     390/*              printem(level, i + 1, sp, n, me); */
     391/*              if ((i += n) < nscores) { */
     392/*                      (void)printf("\nHit RETURN to continue."); */
     393/*                      (void)fflush(stdout); */
     394/*                      while ((c = getchar()) != '\n') */
     395/*                              if (c == EOF) */
     396/*                                      break; */
     397/*                      (void)printf("\n"); */
     398/*              } */
     399/*      } */
     400
     401/*      if (nscores == 0) */
     402/*              printf("\t\t\t      - none to date.\n"); */
     403/* } */
     404
     405/* static void */
     406/* printem(int level, int offset, struct highscore *hs, int n, const char *me) */
     407/* { */
     408/*      struct highscore *sp; */
     409/*      int row, highlight, i; */
     410/*      char buf[100]; */
     411/* #define      TITLE "Rank  Score   Name                          (points/level)" */
     412/* #define      TITL2 "==========================================================" */
     413
     414/*      printf("%s\n%s\n", TITLE, TITL2); */
     415
     416/*      highlight = 0; */
     417
     418/*      for (row = 0; row < n; row++) { */
     419/*              sp = &hs[row]; */
     420/*              (void)snprintf(buf, sizeof(buf), */
     421/*                  "%3d%c %6d  %-31s (%6d on %d)\n", */
     422/*                  row + offset, sp->hs_time ? '*' : ' ', */
     423/*                  sp->hs_score * sp->hs_level, */
     424/*                  sp->hs_name, sp->hs_score, sp->hs_level); */
     425/*              /\* Print leaders every three lines *\/ */
     426/*              if ((row + 1) % 3 == 0) { */
     427/*                      for (i = 0; i < sizeof(buf); i++) */
     428/*                              if (buf[i] == ' ') */
     429/*                                      buf[i] = '_'; */
     430/*              } */
     431/*              /\* */
     432/*               * Highlight if appropriate.  This works because */
     433/*               * we only get one score per level. */
     434/*               *\/ */
     435/*              if (me != NULL && */
     436/*                  sp->hs_level == level && */
     437/*                  sp->hs_score == score && */
     438/*                  strcmp(sp->hs_name, me) == 0) { */
     439/*                      putpad(SOstr); */
     440/*                      highlight = 1; */
     441/*              } */
     442/*              (void)printf("%s", buf); */
     443/*              if (highlight) { */
     444/*                      putpad(SEstr); */
     445/*                      highlight = 0; */
     446/*              } */
     447/*      } */
     448/* } */
  • tetris/scores.h

    rb27a97bb rc0e674a  
    3939 * Tetris scores.
    4040 */
     41#include <sys/time.h>
     42#define MAXLOGNAME 10
    4143struct highscore {
    4244        char    hs_name[MAXLOGNAME];    /* login name */
     
    5052#define EXPIRATION      (5L * 365 * 24 * 60 * 60)
    5153
    52 void    savescore(int);
    53 void    showscores(int);
     54void savescore(int);
     55void showscores(int);
Note: See TracChangeset for help on using the changeset viewer.