home *** CD-ROM | disk | FTP | other *** search
/ vsiftp.vmssoftware.com / VSIPUBLIC@vsiftp.vmssoftware.com.tar / FREEWARE / FREEWARE40.ZIP / xsokoban-31 / main.c < prev    next >
C/C++ Source or Header  |  1997-06-16  |  16KB  |  383 lines

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