home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / games / volume13 / xsokoban3 / part01 / main.c < prev    next >
C/C++ Source or Header  |  1992-02-11  |  8KB  |  292 lines

  1. #include <stdio.h>
  2. #include <pwd.h>
  3. #include "externs.h"
  4. #include "globals.h"
  5. #include "options.h"
  6. #include "errors.h"
  7.  
  8. /* useful globals */
  9. Boolean scoring = _true_;
  10. short level, packets, savepack, moves, pushes, rows, cols;
  11. short scorelevel, scoremoves, scorepushes;
  12. POS ppos;
  13. char map[MAXROW + 1][MAXCOL + 1];
  14. char *username = NULL, *progname = NULL, *bitpath = NULL;;
  15. static Boolean optshowscore = _false_, optmakescore = _false_,
  16.            optrestore = _false_, superuser = _false_;
  17. static short optlevel = 0, userlevel;
  18. struct passwd *pwd;
  19. XrmDatabase rdb;
  20.  
  21. extern Display *dpy;
  22. extern int scr;
  23. extern Boolean display_alloc;
  24.  
  25. /* do all the setup foo, and make sure command line gets parsed. */
  26. void main(int argc, char **argv)
  27. {
  28.   short ret = 0, ret2 = 0;
  29.  
  30. #ifdef VICE
  31.   Authenticate();
  32. #endif
  33.  
  34.   scorelevel = 0;
  35.   moves = pushes = packets = savepack = 0;
  36.  
  37.   /* make the program name be what it is invoked with */
  38.   progname = strrchr(argv[0], '/');
  39.   if(progname == NULL)
  40.     progname = argv[0];
  41.   else
  42.     progname++;
  43.  
  44.   /* find out who is playing us. (pwd will be kept around in case we need to
  45.    * build the Xresources stuff later.
  46.    */
  47.   pwd = getpwuid(getuid());
  48.   if(pwd == NULL)
  49.     /* we MUST be being played by somebody, sorry */
  50.     ret = E_NOUSER;
  51.   else {
  52.     /* find out who we are. */
  53.     username = pwd->pw_name;
  54.     /* see if we are the superuser */
  55.     superuser = (strcmp(username, SUPERUSER) == 0) ? _true_ : _false_;
  56.     /* Parse the command line */
  57.     ret = CheckCommandLine(&argc, argv);
  58.     if(ret == 0) {
  59.       if(optshowscore)
  60.     ret = OutputScore();
  61.       else if(optmakescore) {
  62.     if(superuser) {
  63.       /* make sure of that, shall we? */
  64.       ret = GetGamePassword();
  65.       if(ret == 0)
  66.         ret = MakeNewScore();
  67.     } else
  68.       /* sorry, BAD superuser */
  69.       ret = E_NOSUPER;
  70.       } else if(optrestore) {
  71.     ret = RestoreGame();
  72.       } else {
  73.     ret = GetUserLevel(&userlevel);
  74.     if(ret == 0) {
  75.       if(optlevel > 0) {
  76.         if(superuser) {
  77.           /* superusers can play any level (but not score) useful for
  78.            * testing out new boards.
  79.            */
  80.           level = optlevel;
  81.           scoring = _false_;
  82.         } else if (userlevel < optlevel)
  83.           ret = E_LEVELTOOHIGH;
  84.         else
  85.           level = optlevel;
  86.       } else
  87.         level = userlevel;
  88.     }
  89.       }
  90.     }
  91.   }
  92.   if(ret == 0) {
  93.     /* play till we drop, then nuke the good stuff */
  94.     ret = GameLoop();
  95.     DestroyDisplay();
  96.   }
  97.   /* always report here since the game returns E_ENDGAME when the user quits.
  98.    * Sigh.. it would be so much easier to just do it right.
  99.    */
  100.   Error(ret);
  101.   /* see if they score, and do it (again report an error */
  102.   if((scorelevel > 0) && scoring) {
  103.     ret2 = Score();
  104.     Error(ret2);
  105.   }
  106.   /* exit with whatever status we ended with */
  107.   exit(ret);
  108. }
  109.  
  110. /* Oh boy, the fun stuff.. Follow along boys and girls as we parse the command
  111.  * line up into little bitty pieces and merge in all the xdefaults that we
  112.  * need.
  113.  */
  114. short CheckCommandLine(int *argcP, char **argv)
  115. {
  116.   XrmDatabase command, temp;
  117.   char *res;
  118.   char buf[1024];
  119.   int option;
  120.  
  121.   /* let's do this the sensible way, Command line first! */
  122.   /* we will also OPEN the display here, though we won't do anything with it */
  123.   XrmInitialize();
  124.  
  125.   /* build an XrmDB from the command line based on the options (options.h) */
  126.   XrmParseCommand(&command, options, sizeof(options)/sizeof(*options),
  127.           progname, argcP, argv);
  128.  
  129.   /* okay, we now have the X command line options parsed, we might as well
  130.    * make sure we need to go further before we do.  These command line options
  131.    * are NOT caught by XrmParseCommand(), so we need to do them ourselves.
  132.    * Remember, they are all exclusive of one another.
  133.    */
  134.   for(option = 1; option < *argcP; option++) {
  135.     if(argv[option][0] == '-') {
  136.       switch(argv[option][1]) {
  137.     case 's':
  138.       if(optshowscore || optmakescore || optrestore || (optlevel > 0))
  139.         return E_USAGE;
  140.       optshowscore = _true_;
  141.       break;
  142.     case 'c':
  143.       if(optshowscore || optmakescore || optrestore || (optlevel > 0))
  144.         return E_USAGE;
  145.       optmakescore = _true_;
  146.       break;
  147.     case 'r':
  148.       if(optshowscore || optmakescore || optrestore || (optlevel > 0))
  149.         return E_USAGE;
  150.       optrestore = _true_;
  151.     default:
  152.       if(optshowscore || optrestore || optmakescore || (optlevel > 0))
  153.         return E_USAGE;
  154.       optlevel = atoi(argv[option]+1);
  155.       if(optlevel == 0)
  156.         return E_USAGE;
  157.       break;
  158.       }
  159.     } else
  160.       /* found an option that didn't begin with a - (oops) */
  161.       return E_USAGE;
  162.   }
  163.  
  164.   /* okay.. NOW, find out what display we are currently attached to. This
  165.    * allows us to put the display on another machine
  166.    */
  167.   res = GetDatabaseResource(command, "display");
  168.  
  169.   /* open up the display */
  170.   dpy = XOpenDisplay(res);
  171.   if(dpy == (Display *)NULL)
  172.     return E_NODISPLAY;
  173.   display_alloc = _true_;
  174.  
  175.   /* okay, we have a display, now we can get the std xdefaults and stuff */
  176.   res = XResourceManagerString(dpy);
  177.   if(res != NULL)
  178.     /* try to get it off the server first (ya gotta love R4) */
  179.     rdb = XrmGetStringDatabase(res);
  180.   else {
  181.     /* can't get it from the server, let's do it the slow way */
  182.     /* try HOME first in case you have people sharing accounts :) */
  183.     res = getenv("HOME");
  184.     if(res != NULL)
  185.       strcpy(buf, res);
  186.     else
  187.       /* no HOME, let's try and make one from the pwd (whee) */
  188.       strcpy(buf, pwd->pw_dir);
  189.     strcat(buf, "/.Xdefaults");
  190.     rdb = XrmGetFileDatabase(buf);
  191.   }
  192.  
  193.   /* let's merge in the X environment */
  194.   res = getenv("XENVIRONMENT");
  195.   if(res != NULL) {
  196.     temp = XrmGetFileDatabase(res);
  197.     XrmMergeDatabases(temp, &rdb);
  198.   }
  199.  
  200.   /* now merge in the rest of the X command line options! */
  201.   XrmMergeDatabases(command, &rdb);
  202.   return 0;
  203. }
  204.  
  205. /* we just sit here and keep playing level after level after level after .. */
  206. short GameLoop(void)
  207. {
  208.   short ret = 0;
  209.  
  210.   /* make sure X is all set up and ready for us */
  211.   ret = InitX();
  212.   if(ret != 0)
  213.     return ret;
  214.  
  215.   /* get where we are starting from */
  216.   if(!optrestore)
  217.     ret = ReadScreen();
  218.  
  219.   /* until we quit or get an error, just keep on going. */
  220.   while(ret == 0) {
  221.     ret = Play();
  222.     if(ret == 0) {
  223.       level++;
  224.       moves = pushes = packets = savepack = 0;
  225.       ret = ReadScreen();
  226.     }
  227.   }
  228.   return ret;
  229. }
  230.  
  231. /* Does this really need a comment :) */
  232. short GetGamePassword(void)
  233. {
  234.   return ((strcmp(getpass("Password: "), PASSWORD) == 0) ? 0 : E_ILLPASSWORD);
  235. }
  236.  
  237. /* display the correct error message based on the error number given us. 
  238.  * There are 2 special cases, E_ENDGAME (in which case we don't WANT a 
  239.  * silly error message cause it's not really an error, and E_USAGE, in which
  240.  * case we want to give a really nice list of all the legal options.
  241.  */
  242. void Error(short err)
  243. {
  244.   switch(err) {
  245.     case E_FOPENSCREEN:
  246.     case E_PLAYPOS1:
  247.     case E_ILLCHAR:
  248.     case E_PLAYPOS2:
  249.     case E_TOMUCHROWS:
  250.     case E_TOMUCHCOLS:
  251.     case E_NOUSER:
  252.     case E_FOPENSAVE:
  253.     case E_WRITESAVE:
  254.     case E_STATSAVE:
  255.     case E_READSAVE:
  256.     case E_ALTERSAVE:
  257.     case E_SAVED:
  258.     case E_TOMUCHSE:
  259.     case E_FOPENSCORE:
  260.     case E_READSCORE:
  261.     case E_WRITESCORE:
  262.     case E_USAGE:
  263.     case E_ILLPASSWORD:
  264.     case E_LEVELTOOHIGH:
  265.     case E_NOSUPER:
  266.     case E_NOSAVEFILE:
  267.     case E_NOBITMAP:
  268.     case E_NODISPLAY:
  269.     case E_NOFONT:
  270.     case E_NOMEM:
  271.     case E_NOCOLOR:
  272.       fprintf(stderr, "%s: %s\n", progname, errmess[err]);
  273.       if(err == E_USAGE)
  274.         Usage();
  275.       break;
  276.     default:
  277.       if(err != E_ENDGAME)
  278.     fprintf(stderr, "%s: %s\n", progname, errmess[0]);
  279.       break;
  280.   }
  281. }
  282.  
  283. /* this simply prints out the usage string nicely. */
  284. void Usage(void)
  285. {
  286.   short i;
  287.  
  288.   fprintf(stderr, USAGESTR, progname);
  289.   for (i = 0; usages[i] != NULL; i++)
  290.     fprintf(stderr, "%s", usages[i]);
  291. }
  292.