home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / gnu / nethack-3.1 / sys / share / pcmain.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-01-23  |  9.6 KB  |  474 lines

  1. /*    SCCS Id: @(#)pcmain.c    3.1    92/12/04    */
  2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  3. /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5. /* main.c - MSDOS, OS/2, ST, and Amiga NetHack */
  6.  
  7. #include "hack.h"
  8.  
  9. #ifndef NO_SIGNAL
  10. #include <signal.h>
  11. #endif
  12.  
  13. #include <ctype.h>
  14.  
  15. #if !defined(AMIGA) && !defined(GNUDOS)
  16. #include <sys\stat.h>
  17. #else
  18. # ifdef GNUDOS
  19. #include <sys/stat.h>
  20. # endif
  21. #endif
  22.  
  23. #if !defined(LATTICE)
  24. char orgdir[PATHLEN];
  25. #endif
  26.  
  27. #ifdef MFLOPPY
  28. struct finfo    zfinfo = ZFINFO;
  29. int i;
  30. #endif /* MFLOPPY */
  31.  
  32. #ifdef TOS
  33. boolean run_from_desktop = TRUE;    /* should we pause before exiting?? */
  34. # ifdef __GNUC__
  35. long _stksize = 16*1024;
  36. # endif
  37. #endif
  38.  
  39. #ifdef AMIGA
  40. extern int bigscreen;
  41. #endif
  42.  
  43. static void FDECL(process_options,(int argc,char **argv));
  44.  
  45. int FDECL(main, (int,char **));
  46.  
  47. const char *classes = "ABCEHKPRSTVW";
  48.  
  49. int
  50. main(argc,argv)
  51. int argc;
  52. char *argv[];
  53. {
  54.     register int fd;
  55.     register char *dir;
  56. #ifdef TOS
  57.     long clock_time;
  58.     if (*argv[0]) {            /* only a CLI can give us argv[0] */
  59.         hname = argv[0];
  60.         run_from_desktop = FALSE;
  61.     } else
  62. #endif
  63.         hname = "NetHack";    /* used for syntax messages */
  64.  
  65.     choose_windows(DEFAULT_WINDOW_SYS);
  66.  
  67. #if !defined(AMIGA) && !defined(GNUDOS)
  68.     /* Save current directory and make sure it gets restored when
  69.      * the game is exited.
  70.      */
  71.     if (getcwd(orgdir, sizeof orgdir) == NULL)
  72.         error("NetHack: current directory path too long");
  73. # ifndef NO_SIGNAL
  74.     signal(SIGINT, (SIG_RET_TYPE) exit);    /* restore original directory */
  75. # endif
  76. #endif /* !AMIGA && !GNUDOS */
  77.  
  78.     dir = getenv("NETHACKDIR");
  79.     if (dir == NULL)
  80.         dir = getenv("HACKDIR");
  81.     if (dir != NULL) {
  82.         Strcpy(hackdir, dir);
  83. #ifdef CHDIR
  84.         chdirx (dir, 1);
  85. #endif
  86.     }
  87. #if defined(AMIGA) && defined(CHDIR)
  88.     /*
  89.      * If we're dealing with workbench, change the directory.  Otherwise
  90.      * we could get "Insert disk in drive 0" messages. (Must be done
  91.      * before initoptions())....
  92.      */
  93.     if(argc == 0)
  94.         chdirx(HACKDIR, 1);
  95. #endif
  96.  
  97. #ifdef MFLOPPY
  98.     /* zero "fileinfo" array to prevent crashes on level change */
  99.     for (i = 0 ; i <= MAXLEVEL; i++) {
  100.         fileinfo[i] = zfinfo;
  101.     }
  102. #endif /* MFLOPPY */
  103. #ifdef AMIGA
  104.     ami_argc=argc;
  105.     ami_argv=argv;
  106. #endif
  107.     initoptions();
  108.  
  109. #if defined(TOS) && defined(TEXTCOLOR)
  110.     if (flags.BIOS && flags.use_color)
  111.         set_colors();
  112. #endif
  113.     if (!hackdir[0])
  114. #if !defined(LATTICE) && !defined(AMIGA)
  115.         Strcpy(hackdir, orgdir);
  116. #else
  117.         Strcpy(hackdir, HACKDIR);
  118. #endif
  119.     if(argc > 1) {
  120.         if (!strncmp(argv[1], "-d", 2) && argv[1][2] != 'e') {
  121.         /* avoid matching "-dec" for DECgraphics; since the man page
  122.          * says -d directory, hope nobody's using -desomething_else
  123.          */
  124.         argc--;
  125.         argv++;
  126.         dir = argv[0]+2;
  127.         if(*dir == '=' || *dir == ':') dir++;
  128.         if(!*dir && argc > 1) {
  129.             argc--;
  130.             argv++;
  131.             dir = argv[0];
  132.         }
  133.         if(!*dir)
  134.             error("Flag -d must be followed by a directory name.");
  135.         Strcpy(hackdir, dir);
  136.         } else
  137.  
  138.     /*
  139.      * Now we know the directory containing 'record' and
  140.      * may do a prscore().
  141.      */
  142.         if (!strncmp(argv[1], "-s", 2)) {
  143. #ifdef CHDIR
  144.         chdirx(hackdir,0);
  145. #endif
  146.         prscore(argc, argv);
  147.         exit(0);
  148.         }
  149.     }
  150.  
  151.     /*
  152.      * It seems you really want to play.
  153.      */
  154.     setrandom();
  155.  
  156. #ifdef TOS
  157.     if (comp_times((long)time(&clock_time)))
  158.         error("Your clock is incorrectly set!");
  159. #endif
  160.     u.uhp = 1;    /* prevent RIP on early quits */
  161.     u.ux = 0;    /* prevent flush_screen() */
  162.  
  163.     /*
  164.      * Find the creation date of this game,
  165.      * so as to avoid restoring outdated savefiles.
  166.      */
  167.     /* gethdate(hname); */
  168.  
  169.     /*
  170.      * We cannot do chdir earlier, otherwise gethdate will fail.
  171.      */
  172. #ifdef CHDIR
  173.     chdirx(hackdir,1);
  174. #endif
  175.  
  176.     process_options(argc, argv);
  177.  
  178. #ifdef AMIGA
  179.     ami_wbench_args();
  180. #endif
  181.     init_nhwindows();
  182. #ifdef MFLOPPY
  183.     set_lock_and_bones();
  184. # ifndef AMIGA
  185.     copybones(FROMPERM);
  186. # endif
  187. #endif
  188. #ifdef WIZARD
  189.     if (wizard)
  190.         Strcpy(plname, "wizard");
  191.     else
  192. #endif
  193.     if (!*plname)
  194.         askname();
  195.     plnamesuffix();        /* strip suffix from name; calls askname() */
  196.                 /* again if suffix was whole name */
  197.                 /* accepts any suffix */
  198. #ifndef MFLOPPY
  199.     Strcpy(lock,plname);
  200.     Strcat(lock,".99");
  201.     regularize(lock);    /* is this necessary? */
  202. #endif
  203.  
  204.     /* set up level 0 file to keep game state in */
  205.     /* this will have to be expanded to something like the
  206.      * UNIX/VMS getlock() to allow networked PCs in any case
  207.      */
  208.     fd = create_levelfile(0);
  209.     if (fd < 0) {
  210.         raw_print("Cannot create lock file");
  211.     } else {
  212.         hackpid = 1;
  213.         write(fd, (genericptr_t) &hackpid, sizeof(hackpid));
  214.         close(fd);
  215.     }
  216. #ifdef MFLOPPY
  217.         fileinfo[0].where = ACTIVE;
  218. #endif
  219.  
  220.     /*
  221.      * Initialisation of the boundaries of the mazes
  222.      * Both boundaries have to be even.
  223.      */
  224.  
  225.     x_maze_max = COLNO-1;
  226.     if (x_maze_max % 2)
  227.         x_maze_max--;
  228.     y_maze_max = ROWNO-1;
  229.     if (y_maze_max % 2)
  230.         y_maze_max--;
  231.  
  232.     /*
  233.      *  Initialize the vision system.  This must be before mklev() on a
  234.      *  new game or before a level restore on a saved game.
  235.      */
  236.     vision_init();
  237.  
  238.     display_gamewindows();
  239.  
  240.     set_savefile_name();
  241.  
  242.     if (
  243. #ifdef MFLOPPY
  244. # ifdef AMIGA
  245.         (FromWBench || saveDiskPrompt(1)) &&
  246. # else
  247.         saveDiskPrompt(1) &&
  248. # endif
  249. #endif /* MFLOPPY */
  250.         ((fd = open_savefile()) >= 0) &&
  251.        /* if not up-to-date, quietly unlink file via false condition */
  252.        (uptodate(fd) || ((void)close(fd), delete_savefile()))) {
  253. #ifdef WIZARD
  254.         /* Since wizard is actually flags.debug, restoring might
  255.          * overwrite it.
  256.          */
  257.         boolean remember_wiz_mode = wizard;
  258. #endif
  259. #ifndef NO_SIGNAL
  260.         (void) signal(SIGINT, (SIG_RET_TYPE) done1);
  261. #endif
  262. #ifdef NEWS
  263.         if(flags.news) display_file(NEWS, FALSE);
  264. #endif
  265.         pline("Restoring save file...");
  266.         mark_synch();    /* flush output */
  267.  
  268.         if(!dorecover(fd))
  269.             goto not_recovered;
  270. #ifdef WIZARD
  271.         if(!wizard && remember_wiz_mode) wizard = TRUE;
  272. #endif
  273.         pline("Hello %s, welcome back to NetHack!", plname);
  274.         check_special_room(FALSE);
  275.  
  276. #ifdef EXPLORE_MODE
  277.         if (discover)
  278.             You("are in non-scoring discovery mode.");
  279. #endif
  280. #if defined(EXPLORE_MODE) || defined(WIZARD)
  281.         if (discover || wizard) {
  282.             if(yn("Do you want to keep the save file?") == 'n'){
  283.                 (void) delete_savefile();
  284.             }
  285. #ifdef AMIGA
  286.             else
  287.                 preserve_icon();
  288. #endif
  289.         }
  290. #endif
  291.         flags.move = 0;
  292.     } else {
  293. not_recovered:
  294.         player_selection();
  295.         newgame();
  296.         /* give welcome message before pickup messages */
  297.         pline("Hello %s, welcome to NetHack!", plname);
  298. #ifdef EXPLORE_MODE
  299.         if (discover)
  300.             You("are in non-scoring discovery mode.");
  301. #endif
  302.         flags.move = 0;
  303.         set_wear();
  304.         pickup(1);
  305.         read_engr_at(u.ux,u.uy);
  306.     }
  307.     
  308.     flags.moonphase = phase_of_the_moon();
  309.     if(flags.moonphase == FULL_MOON) {
  310.         You("are lucky!  Full moon tonight.");
  311.         change_luck(1);
  312.     } else if(flags.moonphase == NEW_MOON) {
  313.         pline("Be careful!  New moon tonight.");
  314.     }
  315.     if(flags.friday13 = friday_13th()) {
  316.         pline("Watch out!  Bad things can happen on Friday the 13th.");
  317.         change_luck(-1);
  318.     }
  319.  
  320.     initrack();
  321. #ifndef NO_SIGNAL
  322.     (void) signal(SIGINT, SIG_IGN);
  323. #endif
  324. #ifdef OS2
  325.     gettty(); /* somehow ctrl-P gets turned back on during startup ... */
  326. #endif
  327.  
  328.     moveloop();
  329.     return 0;
  330. }
  331.  
  332. static void
  333. process_options(argc, argv)
  334. int argc;
  335. char *argv[];
  336. {
  337.     /*
  338.      * Process options.
  339.      */
  340.     while(argc > 1 && argv[1][0] == '-'){
  341.         argv++;
  342.         argc--;
  343.         switch(argv[0][1]){
  344. #if defined(WIZARD) || defined(EXPLORE_MODE)
  345. # ifndef EXPLORE_MODE
  346.         case 'X':
  347. # endif
  348.         case 'D':
  349. # ifdef WIZARD
  350.             /* Must have "name" set correctly by NETHACK.CNF,
  351.              * NETHACKOPTIONS, or -u
  352.              * before this flag to enter wizard mode. */
  353. #  ifdef KR1ED
  354.             if(!strcmp(plname, WIZARD_NAME)) {
  355. #  else
  356.             if(!strcmp(plname, WIZARD)) {
  357. #  endif
  358.                 wizard = TRUE;
  359.                 break;
  360.             }
  361.             /* otherwise fall thru to discover */
  362. # endif
  363. # ifdef EXPLORE_MODE
  364.         case 'X':
  365.             discover = TRUE;
  366. # endif
  367.             break;
  368. #endif
  369. #ifdef NEWS
  370.         case 'n':
  371.             flags.news = FALSE;
  372.             break;
  373. #endif
  374.         case 'u':
  375.             if(argv[0][2])
  376.               (void) strncpy(plname, argv[0]+2, sizeof(plname)-1);
  377.             else if(argc > 1) {
  378.               argc--;
  379.               argv++;
  380.               (void) strncpy(plname, argv[0], sizeof(plname)-1);
  381.             } else
  382.                 raw_print("Player name expected after -u");
  383.             break;
  384. #ifndef AMIGA
  385.         case 'I':
  386.         case 'i':
  387.             if (!strncmpi(argv[0]+1, "IBM", 3))
  388.                 switch_graphics(IBM_GRAPHICS);
  389.             break;
  390.         /*  case 'D': */
  391.         case 'd':
  392.             if (!strncmpi(argv[0]+1, "DEC", 3))
  393.                 switch_graphics(DEC_GRAPHICS);
  394.             break;
  395. #endif
  396. #ifdef MFLOPPY
  397. # ifndef AMIGA
  398.         /* Player doesn't want to use a RAM disk
  399.          */
  400.         case 'r':
  401.             ramdisk = FALSE;
  402.             break;
  403. # endif
  404. #endif
  405. #ifdef AMIGA
  406.             /* interlaced and non-interlaced screens */
  407.         case 'L':
  408.             bigscreen = 1;
  409.             break;
  410.         case 'l':
  411.             bigscreen = -1;
  412.             break;
  413. #endif
  414.         default:
  415.             if (index(classes, toupper(argv[0][1]))) {
  416.                 /* allow -T for Tourist, etc. */
  417.                 (void) strncpy(pl_character, argv[0]+1,
  418.                            sizeof(pl_character)-1);
  419.                 break;
  420.             } else raw_printf("\nUnknown switch: %s", argv[0]);
  421.         case '?':
  422.             (void) printf(
  423.             "\nUsage: %s [-d dir] -s [-[%s]] [maxrank] [name]...",
  424.             hname, classes);
  425.             (void) printf("\n       or");
  426.             (void) printf("\n       %s [-d dir] [-u name] [-[%s]]",
  427.             hname, classes);
  428. #if defined(WIZARD) || defined(EXPLORE_MODE)
  429.             (void) printf(" [-[DX]]");
  430. #endif
  431. #ifdef NEWS
  432.             (void) printf(" [-n]");
  433. #endif
  434. #ifdef MFLOPPY
  435. # ifndef AMIGA
  436.             (void) printf(" [-r]");
  437. # endif
  438. #endif
  439.             putchar('\n');
  440.             exit(0);
  441.         }
  442.     }
  443. }
  444.  
  445. #ifdef CHDIR
  446. void
  447. chdirx(dir, wr)
  448. char *dir;
  449. boolean wr;
  450. {
  451. #ifdef AMIGA
  452.     static char thisdir[] = "";
  453. #else
  454.     static char thisdir[] = ".";
  455. #endif
  456.     if(dir && chdir(dir) < 0) {
  457.         error("Cannot chdir to %s.", dir);
  458.     }
  459.  
  460.     /* Change the default drive as well.
  461.      */
  462. #ifndef AMIGA
  463.     chdrive(dir);
  464. #endif
  465.  
  466.     /* warn the player if we can't write the record file */
  467.     /* perhaps we should also test whether . is writable */
  468.     /* unfortunately the access system-call is worthless */
  469.     if (wr) check_recordfile(dir ? dir : thisdir);
  470. }
  471. #endif /* CHDIR */
  472.  
  473. /*pcmain.c*/
  474.