home *** CD-ROM | disk | FTP | other *** search
/ Dream 52 / Amiga_Dream_52.iso / Linux / Divers / xgalaga-2_0_tar.gz / xgalaga-2_0_tar / xgalaga-2.0 / highscore.c < prev    next >
C/C++ Source or Header  |  1998-04-30  |  12KB  |  487 lines

  1. /* $Id: highscore.c,v 1.2 1998/04/30 05:11:55 mrogre Exp $ */
  2. /* Copyright (c) 1998 Joe Rumsey (mrogre@mediaone.net) */
  3. #include "copyright.h"
  4.  
  5. #include <config.h>
  6.  
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <sys/types.h>
  10. #ifdef HAVE_UNISTD_H
  11. # include <unistd.h>
  12. #endif
  13. #include <sys/stat.h>
  14. #ifdef HAVE_FCNTL_H
  15. # include <fcntl.h>
  16. #endif
  17. #include <ctype.h>
  18. #include <pwd.h>
  19. #include <string.h>
  20. #ifdef _AIX
  21. #include <net/nh.h>
  22. #else /* This is for ntohl, htonl.  
  23.      This file is correct for hpux and linux for sure, 
  24.      probably others as well. */
  25. #include <netinet/in.h>
  26. #endif
  27.  
  28. #include "Wlib.h"
  29. #include "defs.h"
  30. #include "struct.h"
  31. #include "proto.h"
  32. #include "data.h"
  33.  
  34. #define NUM_GLOBAL_SCORES 20
  35. #define NUM_MY_SCORES 10
  36.  
  37. static char new_name[20];
  38. static int nnpos=0;
  39. static int thisplace = -1, my_thisplace = -1;
  40.  
  41. static struct high_score {
  42. #ifdef NOSCOREHOGS
  43.     long uid;
  44. #endif
  45.     char name[20];
  46.     long score;
  47.     long level;
  48. } global_scores[NUM_GLOBAL_SCORES], my_scores[NUM_MY_SCORES];
  49.  
  50. void undo_name()
  51. {
  52.     W_ClearArea(baseWin, 
  53.         WINWIDTH/2-(20*W_Textwidth), 200,
  54.         (40*W_Textwidth), W_Textheight*2);
  55. }
  56.  
  57. void do_name()
  58. {
  59.     char buf[21];
  60.     static int init = 0;
  61.  
  62.     if(!init) {
  63.     strcpy(new_name, getUsersFullName());
  64.     nnpos = strlen(new_name);
  65.     init = 1;
  66.     }
  67.     center_text("Great score! Enter your name:", 200, W_Red);
  68.     sprintf(buf, "%s_", new_name);
  69.     center_text(buf, 200 + W_Textheight, W_Cyan);
  70. }
  71.  
  72. char *getUsersFullName()
  73. {
  74.     struct passwd *pass;
  75.     char *comma;
  76.     char *cp1, *cp2;
  77.     static char fullname[80];
  78.  
  79.     /* Get user information from password file */
  80.     if (!(pass = getpwuid(getuid())))
  81.         return("Anonymous?");       /* Unknown user oops. */
  82.  
  83.     /* find a comma indicating further info after name */
  84.     comma = strchr(pass->pw_gecos, ',');
  85.  
  86.     /* NULL out the comma */
  87.     if (comma) *comma = '\0';
  88.  
  89.     /* Use the nickname if not null otherwise password file name */
  90.     cp1 = pass->pw_gecos;
  91.     cp2 = fullname;
  92.  
  93.     /* Search through the gecos field looking for an '&' which on very
  94.      * old UNIX systems is supposed to be the users user name with the
  95.      * first letter uppercased.
  96.      */
  97.     while(*cp1)
  98.     {
  99.         /* Look for the '&' symbol */
  100.         if(*cp1 != '&')
  101.             *cp2++ = *cp1++;
  102.         else
  103.         {
  104.             /* A ha. Now copy the users name to be in place of '&' */
  105.             strcpy(cp2, pass->pw_name);
  106.        
  107.             /* Convert the first letter to uppercase. */
  108.             if(islower(*cp2))
  109.                 *cp2 = toupper(*cp2);
  110.  
  111.             /* Continue with the remaining string */
  112.             while(*cp2) cp2++;
  113.                 cp1++;
  114.         }
  115.     }
  116.  
  117.     /* shorten to 20 chars */
  118.     fullname[20] = 0;
  119.  
  120.     /* Return their name without any trailing stuff */
  121.     return(fullname);
  122. }
  123.  
  124. static void save_scores()
  125. {
  126.     int i;
  127.     int hsf;
  128.     long x;
  129.     char my_file_name [256], *home;
  130.  
  131.     hsf = open(SCOREFILE, O_WRONLY | O_TRUNC | O_CREAT, 0666);
  132.     if(hsf < 0) {
  133.     printf("Couldn't write scores file %s\n", SCOREFILE);
  134.     return;
  135.     }
  136.     for(i=0;i<NUM_GLOBAL_SCORES;i++) {
  137. #ifdef NOSCOREHOGS
  138.         x=htonl(global_scores[i].uid);
  139.     if(write(hsf, &x, sizeof(long)) < sizeof(long))
  140.         goto error;
  141. #endif
  142.     if(write(hsf, global_scores[i].name, 20) < 20)
  143.         goto error;
  144.     x=htonl(global_scores[i].score);
  145.     if(write(hsf, &x, sizeof(long)) < sizeof(long))
  146.         goto error;
  147.     x=htonl(global_scores[i].level);
  148.     if(write(hsf, &x, sizeof(long)) < sizeof(long))
  149.         goto error;
  150.     }
  151.     close(hsf);
  152.  
  153.     if((home = getenv("HOME"))) {
  154.     sprintf(my_file_name, "%s/.xgalscores", home);
  155.     hsf = open(my_file_name, O_WRONLY | O_TRUNC | O_CREAT, 0644);
  156.     if(hsf < 0) {
  157.         printf("Couldn't write scores file %s\n", my_file_name);
  158.         return;
  159.     }
  160.     for(i=0;i<NUM_MY_SCORES;i++) {
  161.         if(write(hsf, my_scores[i].name, 20) < 20)
  162.         goto error2;
  163.         x=htonl(my_scores[i].score);
  164.         if(write(hsf, &x, sizeof(long)) < sizeof(long))
  165.         goto error2;
  166.         x=htonl(my_scores[i].level);
  167.         if(write(hsf, &x, sizeof(long)) < sizeof(long))
  168.         goto error2;
  169.     }
  170.     }
  171.     close(hsf);
  172.     
  173.     return;
  174.   error:
  175.     printf("Error saving high scores file %s\n", SCOREFILE);
  176.     return;
  177.   error2:
  178.     printf("Error saving high scores file %s\n", my_file_name);
  179.     return;
  180. }
  181.  
  182. void add_score(char *name, int score)
  183. {
  184.     int i,j,k;
  185.  
  186.     thisplace = my_thisplace = -1;
  187.  
  188.     load_scores();
  189.  
  190. #ifdef NOSCOREHOGS
  191.     /* /lib 27jul95: want to allow only one global high-score per person,
  192.      * by uid (getuid)
  193.      */
  194.     for(i=0;i<NUM_GLOBAL_SCORES;i++) {
  195.     if(score > global_scores[i].score) {
  196.         /* /lib 27jul95 uniq-global-highscore: */
  197.         /* find old position of high-score: */
  198.         for(k=i;k<NUM_GLOBAL_SCORES;k++) {
  199.         if(global_scores[k].uid == getuid()) {
  200.             break;
  201.         }
  202.         }
  203.         if(k==NUM_GLOBAL_SCORES) {
  204.         k--;
  205.         }
  206.         /* found old pos, copy from i..k-1 to i+1..k */
  207.         for(j=k;j>i;j--) {
  208.         global_scores[j].uid = global_scores[j-1].uid;
  209.         strcpy(global_scores[j].name, global_scores[j-1].name);
  210.         global_scores[j].score = global_scores[j-1].score;
  211.         global_scores[j].level = global_scores[j-1].level;
  212.         }
  213.         global_scores[i].uid = getuid();
  214.         strcpy(global_scores[i].name, name);
  215.         global_scores[i].score = score;
  216.         global_scores[i].level = level;
  217.         thisplace = i;
  218.         break;
  219.     }
  220.     /* high-score stuff by /lib (uid is found, score is too low): */
  221.     else if(global_scores[i].uid == getuid()) {
  222.         break;
  223.     }
  224.     }
  225.  
  226. #else /* NOSCOREHOGS */
  227.     for(i=0;i<NUM_GLOBAL_SCORES;i++) {
  228.     if(score > global_scores[i].score) {
  229.         for(j=NUM_GLOBAL_SCORES-1;j>i;j--) {
  230.         strcpy(global_scores[j].name, global_scores[j-1].name);
  231.         global_scores[j].score = global_scores[j-1].score;
  232.         global_scores[j].level = global_scores[j-1].level;
  233.         }
  234.         strcpy(global_scores[i].name, name);
  235.         global_scores[i].score = score;
  236.         global_scores[i].level = level;
  237.         thisplace = i;
  238.         break;
  239.     }
  240.     }
  241. #endif /* NOSCOREHOGS */
  242.  
  243.     for(i=0;i<NUM_MY_SCORES;i++) {
  244.     if(score > my_scores[i].score) {
  245.         for(j=NUM_MY_SCORES-1;j>i;j--) {
  246.         strcpy(my_scores[j].name, my_scores[j-1].name);
  247.         my_scores[j].score = my_scores[j-1].score;
  248.         my_scores[j].level = my_scores[j-1].level;
  249.         }
  250.         strcpy(my_scores[i].name, name);
  251.         my_scores[i].score = score;
  252.         my_scores[i].level = level;
  253.         my_thisplace = i;
  254.         break;
  255.     }
  256.     }
  257.     save_scores();
  258. }
  259.  
  260. int score_key(W_Event *ev)
  261. {
  262.     if(getting_name) {
  263.     switch(ev->key) {
  264.       case 13:
  265.       case 10:
  266.         getting_name = 0;
  267.         add_score(new_name, score);
  268.         title_page = 1;
  269.         pagetimer = 300;
  270.         W_ClearWindow(baseWin);
  271.         break;
  272.       case 8:
  273.       case 127:
  274.         if(nnpos > 0) {
  275.         nnpos--;
  276.         new_name[nnpos] = 0;
  277.         }
  278.         break;
  279.       case 'u'+128:
  280.         nnpos = 0;
  281.         new_name[nnpos] = 0;
  282.         break;
  283.       default:
  284.         if(nnpos < 19) {
  285.         new_name[nnpos++] = ev->key;
  286.         new_name[nnpos] = 0;
  287.         }
  288.         break;
  289.     }
  290.  
  291.     return 1;
  292.     }
  293.     return 0;
  294. }
  295.  
  296.  
  297. int check_score(int score)
  298. {
  299.     int i;
  300.  
  301.     load_scores(); /* in case someone else has gotten a high score */
  302.     for(i=0;i<NUM_GLOBAL_SCORES;i++) {
  303.     if(score > global_scores[i].score) {
  304.         return 1;
  305.     }
  306. #ifdef NOSCOREHOGS
  307.      if(global_scores[i].uid == getuid()) {
  308.         break;
  309.      }
  310. #endif
  311.     }
  312.  
  313.     for(i=0;i<NUM_MY_SCORES;i++) {
  314.     if(score > my_scores[i].score)
  315.         return 1;
  316.     }
  317.  
  318.     my_thisplace = -1;
  319.     thisplace = -1;
  320.     return 0;
  321. }
  322.  
  323.  
  324. void show_scores()
  325. {
  326.     int i;
  327.     char buf[60];
  328.     W_Color color;
  329.  
  330.     W_SetRGB16(W_DarkGrey, random()%65535,random()%65535,random()%65535);
  331.  
  332.     color = W_DarkGrey;
  333.  
  334.     
  335.     center_text("Global high scores", 90, W_Yellow);
  336.     sprintf(buf, "Rank  Name                      Score   Level");
  337.     center_text(buf, 100, W_Yellow);
  338.     W_MakeLine(baseWin, WINWIDTH/2-((strlen(buf)*W_Textwidth)/2), 111,
  339.            WINWIDTH/2 + ((strlen(buf)*W_Textwidth)/2), 111, W_Red);
  340.     for(i=0;i<NUM_GLOBAL_SCORES;i++) {
  341.     sprintf(buf, "  %2d. %-20s     %7ld %5ld", i+1, 
  342.         global_scores[i].name, global_scores[i].score,global_scores[i].level);
  343.     center_text(buf, 112+i*W_Textheight, (i==thisplace ? color : W_Grey));
  344.     }
  345.  
  346.     center_text("Your high scores", 112+NUM_GLOBAL_SCORES*W_Textheight, W_Yellow);
  347.     sprintf(buf, "Rank  Name                      Score   Level");
  348.     center_text(buf, 112+(NUM_GLOBAL_SCORES+1)*W_Textheight, W_Yellow);
  349.     W_MakeLine(baseWin, WINWIDTH/2-((strlen(buf)*W_Textwidth)/2), 123+(NUM_GLOBAL_SCORES+1)*W_Textheight,
  350.            WINWIDTH/2 + ((strlen(buf)*W_Textwidth)/2), 123+(NUM_GLOBAL_SCORES+1)*W_Textheight, W_Red);
  351.     for(i=0;i<NUM_MY_SCORES;i++) {
  352.     sprintf(buf, "  %2d. %-20s     %7ld %5ld", i+1, 
  353.         my_scores[i].name, my_scores[i].score,my_scores[i].level);
  354.     center_text(buf, 124+(NUM_GLOBAL_SCORES+1)*W_Textheight + i*W_Textheight, 
  355.             (i==my_thisplace ? color : W_Grey));
  356.     }
  357. }
  358.  
  359. void load_scores()
  360. {
  361.     int i;
  362.     int hsf;
  363.     char my_file_name[256], *home;
  364.  
  365.     hsf = open(SCOREFILE, O_RDONLY);
  366.     if(hsf <0 ) {
  367.     printf("Trouble opening high scores file '%s'\n", SCOREFILE);
  368.     for(i=0;i<NUM_GLOBAL_SCORES;i++) {
  369. #ifdef NOSCOREHOGS
  370.         global_scores[i].uid = 0;
  371. #endif
  372.         global_scores[i].name[0]=0;
  373.         global_scores[i].score = 0;
  374.         global_scores[i].level = 0;
  375.     }
  376.     } else {
  377.     for(i=0;i<NUM_GLOBAL_SCORES;i++) {
  378. #ifdef NOSCOREHOGS
  379.         if(read(hsf, &global_scores[i].uid, sizeof(long)) < sizeof(long))
  380.         goto error;
  381. #endif
  382.         if(read(hsf, global_scores[i].name, 20) < 20)
  383.         goto error;
  384.         if(read(hsf, &global_scores[i].score, sizeof(long)) < sizeof(long))
  385.         goto error;
  386.         if(read(hsf, &global_scores[i].level, sizeof(long)) < sizeof(long))
  387.         goto error;
  388. #ifdef NOSCOREHOGS
  389.         global_scores[i].uid = ntohl(global_scores[i].uid);
  390. #endif
  391.         global_scores[i].score = ntohl(global_scores[i].score);
  392.          global_scores[i].level = ntohl(global_scores[i].level);
  393.     }
  394.     }
  395.     close(hsf);
  396.  
  397.     if((home = getenv("HOME"))) {
  398.     sprintf(my_file_name, "%s/.xgalscores", home);
  399.     hsf = open(my_file_name, O_RDONLY);
  400.     if(hsf <0 ) {
  401.         printf("Trouble opening high scores file '%s'\n", my_file_name);
  402.         for(i=0;i<NUM_MY_SCORES;i++) {
  403.         my_scores[i].name[0]=0;
  404.         my_scores[i].score = 0;
  405.         my_scores[i].level = 0;
  406.         }
  407.     } else {
  408.         for(i=0;i<NUM_MY_SCORES;i++) {
  409.         if(read(hsf, my_scores[i].name, 20) < 20)
  410.             goto error2;
  411.         if(read(hsf, &my_scores[i].score, sizeof(long)) < sizeof(long))
  412.             goto error2;
  413.         if(read(hsf, &my_scores[i].level, sizeof(long)) < sizeof(long))
  414.             goto error2;
  415.         my_scores[i].score = ntohl(my_scores[i].score);
  416.         my_scores[i].level = ntohl(my_scores[i].level);
  417.         }
  418.     }
  419.     close(hsf);
  420.     } else {
  421.     printf("No HOME variable, so no personal score file.\n");
  422.     for(i=0;i<NUM_MY_SCORES;i++) {
  423.         my_scores[i].name[0]=0;
  424.         my_scores[i].score = 0;
  425.         my_scores[i].level = 0;
  426.     }
  427.     }
  428.     return;
  429.   error:
  430.     if(i>0)
  431.     printf("Error reading high scores file '%s'\n", SCOREFILE);
  432.     for(i=0;i<NUM_GLOBAL_SCORES;i++) {
  433. #ifdef NOSCOREHOGS
  434.     global_scores[i].uid = 0;
  435. #endif
  436.     global_scores[i].name[0]=0;
  437.     global_scores[i].score = 0;
  438.     global_scores[i].level = 0;
  439.     }
  440.     close(hsf);
  441.     return;
  442.   error2:
  443.     if(i>0)
  444.     printf("Error reading high scores file '%s'\n", my_file_name);
  445.     for(i=0;i<NUM_MY_SCORES;i++) {
  446.     my_scores[i].name[0]=0;
  447.     my_scores[i].score = 0;
  448.     my_scores[i].level = 0;
  449.     }
  450.     close(hsf);
  451. }
  452.  
  453. void print_scores() {
  454.     int i;
  455.     
  456.     load_scores();
  457.     printf("\nGlobal High Scores:\n");
  458.     printf("-----------------------------------------------\n");
  459.     printf("%8s %-20s %8s %8s\n", "uid", "name", "score", "level");
  460.     printf("-----------------------------------------------\n");
  461.     for(i=0;i<NUM_GLOBAL_SCORES;i++) {
  462.     if(global_scores[i].score == 0)
  463.         break;
  464. #ifdef NOSCOREHOGS
  465.     printf("%8ld %-20s %8ld %8ld\n", global_scores[i].uid, 
  466.            global_scores[i].name, global_scores[i].score, 
  467.            global_scores[i].level);
  468. #else
  469.     printf("      -- %-20s %8ld %8ld\n",
  470.            global_scores[i].name, global_scores[i].score,
  471.            global_scores[i].level);
  472. #endif
  473.     }
  474.     printf("-----------------------------------------------\n");
  475.     printf("\nYour High Scores:\n");
  476.     printf("--------------------------------------\n");
  477.     printf("%-20s %8s %8s\n", "name", "score", "level");
  478.     printf("--------------------------------------\n");
  479.     for(i=0;i<NUM_MY_SCORES;i++) {
  480.     if(my_scores[i].score == 0)
  481.         break;
  482.     printf("%-20s %8ld %8ld\n", my_scores[i].name, 
  483.            my_scores[i].score, my_scores[i].level);
  484.     }
  485.     printf("--------------------------------------\n");
  486. }
  487.