home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Games / NetHack 3.1.3 / source / sys / share / pcsys.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-08-01  |  9.1 KB  |  482 lines  |  [TEXT/R*ch]

  1. /*    SCCS Id: @(#)pcsys.c    3.1    93/05/24
  2. /* NetHack may be freely redistributed.  See license for details. */
  3.  
  4. /*
  5.  *  System related functions for MSDOS, OS/2, TOS, and Windows NT
  6.  */
  7.  
  8. #define NEED_VARARGS
  9. #include "hack.h"
  10. #include "wintty.h"
  11.  
  12. #include <ctype.h>
  13. #include <fcntl.h>
  14. #ifndef __GO32__
  15. #include <process.h>
  16. #else
  17. #define P_WAIT          0
  18. #define P_NOWAIT        1
  19. #endif
  20. #ifdef TOS
  21. #include <osbind.h>
  22. #endif
  23.  
  24. #ifdef MOVERLAY
  25. extern void __far __cdecl _movepause( void );
  26. extern void __far __cdecl _moveresume( void );
  27. extern unsigned short __far __cdecl _movefpause;
  28. extern unsigned short __far __cdecl _movefpaused;
  29. #define     __MOVE_PAUSE_DISK     2   /* Represents the executable file */
  30. #define     __MOVE_PAUSE_CACHE    4   /* Represents the cache memory */
  31. #endif /* MOVERLAY */
  32.  
  33. static boolean NDECL(record_exists);
  34. #ifndef TOS
  35. static boolean NDECL(comspec_exists);
  36. #endif
  37.  
  38. #ifdef WIN32CON
  39. extern int ProgmanLaunched;    /* from nttty.c */
  40. #endif
  41.  
  42. #ifdef MICRO
  43.  
  44. void
  45. flushout()
  46. {
  47.     (void) fflush(stdout);
  48.     return;
  49. }
  50.  
  51. static const char *COMSPEC = 
  52. # ifdef TOS
  53. "SHELL";
  54. # else
  55. "COMSPEC";
  56. # endif
  57.  
  58. #define getcomspec() getenv(COMSPEC)
  59.  
  60. # ifdef SHELL
  61. int
  62. dosh()
  63. {
  64.     extern char orgdir[];
  65.     char *comspec;
  66.      int spawnstat;
  67.  
  68.     if (comspec = getcomspec()) {
  69. #  ifndef TOS    /* TOS has a variety of shells */
  70.         suspend_nhwindows("To return to NetHack, enter \"exit\" at the system prompt.\n");
  71. #  else
  72.         suspend_nhwindows((char *)0);
  73. #  endif /* TOS */
  74.         chdirx(orgdir, 0);
  75. #  ifdef __GO32__
  76.         if (system(comspec) < 0) {  /* wsu@eecs.umich.edu */
  77. #  else
  78. #   ifdef MOVERLAY          
  79.        /* Free the cache memory used by overlays, close .exe */ 
  80.     _movefpause |= __MOVE_PAUSE_DISK;
  81.     _movefpause |= __MOVE_PAUSE_CACHE;
  82.     _movepause();
  83. #   endif
  84.          spawnstat = spawnl(P_WAIT, comspec, comspec, NULL);
  85. #   ifdef MOVERLAY
  86.                  _moveresume();
  87. #   endif
  88.  
  89.          if ( spawnstat < 0) {
  90. #  endif
  91.             raw_printf("Can't spawn \"%s\"!", comspec);
  92.             getreturn("to continue");
  93.         }
  94. #  ifdef TOS
  95. /* Some shells (e.g. Gulam) turn the cursor off when they exit */
  96.         if (flags.BIOS)
  97.             (void)Cursconf(1, -1);
  98. #  endif
  99.         get_scr_size(); /* maybe the screen mode changed (TH) */
  100.         resume_nhwindows();
  101.         chdirx(hackdir, 0);
  102.     } else
  103.         pline("Can't find %s.",COMSPEC);
  104.     return 0;
  105. }
  106. # endif /* SHELL */
  107.  
  108. # ifdef MFLOPPY
  109.  
  110. void
  111. eraseall(path, files)
  112. const char *path, *files;
  113. {
  114.     char buf[PATHLEN];
  115.     char *foundfile;
  116.  
  117.     foundfile = foundfile_buffer(); 
  118.         Sprintf(buf, "%s%s", path, files);
  119.     if (findfirst(buf))
  120.         do {
  121.                Sprintf(buf, "%s%s", path, foundfile); 
  122.         (void) unlink(buf);
  123.         } while (findnext());
  124.     return;
  125. }
  126.  
  127. /*
  128.  * Rewritten for version 3.3 to be faster
  129.  */
  130. void
  131. copybones(mode)
  132. int mode;
  133. {
  134.     char from[PATHLEN], to[PATHLEN], last[13];
  135.     char *frompath, *topath;
  136.     char *foundfile;
  137. #  ifndef TOS
  138.     int status;
  139.     char copy[8], *comspec;
  140. #  endif
  141.  
  142.     if (!ramdisk)
  143.         return;
  144.  
  145.     /* Find the name of the last file to be transferred
  146.      */
  147.     frompath = (mode != TOPERM) ? permbones : levels;
  148.     foundfile = foundfile_buffer();
  149.     last[0] = '\0';
  150.     Sprintf(from, "%s%s", frompath, allbones);
  151.     topath = (mode == TOPERM) ? permbones : levels;
  152. #  ifdef TOS
  153.     eraseall(topath, allbones);
  154. #  endif
  155.     if (findfirst(from))
  156.         do {
  157. #  ifdef TOS
  158.             Sprintf(from, "%s%s", frompath, foundfile); 
  159.             Sprintf(to, "%s%s", topath, foundfile);
  160.             if (_copyfile(from, to))
  161.                 goto error_copying;
  162. #  endif
  163.             Strcpy(last, foundfile);
  164.         } while (findnext());
  165. #  ifdef TOS
  166.     else
  167.         return;
  168. #  else
  169.     if (last[0]) {
  170.         Sprintf(copy, "%cC copy",switchar());
  171.  
  172.         /* Remove any bones files in `to' directory.
  173.          */
  174.         eraseall(topath, allbones);
  175.  
  176.         /* Copy `from' to `to' */
  177.         Sprintf(to, "%s%s", topath, allbones);
  178.         comspec = getcomspec();
  179.         status =spawnl(P_WAIT, comspec, comspec, copy, from,
  180.             to, "> nul", NULL);
  181.     } else
  182.         return;
  183. #  endif /* TOS */
  184.  
  185.     /* See if the last file got there.  If so, remove the ramdisk bones
  186.      * files.
  187.      */
  188.     Sprintf(to, "%s%s", topath, last);
  189.     if (findfirst(to)) {
  190.         if (mode == TOPERM)
  191.             eraseall(frompath, allbones);
  192.         return;
  193.     }
  194.  
  195. #  ifdef TOS
  196. error_copying:
  197. #  endif
  198.     /* Last file didn't get there.
  199.      */
  200.     Sprintf(to, "%s%s", topath, allbones);
  201.     msmsg("Can't copy \"%s\" to \"%s\" -- ", from, to);
  202. #  ifndef TOS
  203.     if (status < 0)
  204.         msmsg("can't spawn \"%s\"!", comspec);
  205.     else
  206. #  endif
  207.         msmsg((freediskspace(topath) < filesize(from)) ?
  208.             "insufficient disk space." : "bad path(s)?");
  209.     if (mode == TOPERM) {
  210.         msmsg("Bones will be left in \"%s\"\n",
  211.             *levels ? levels : hackdir);
  212.     } else {
  213.         /* Remove all bones files on the RAMdisk */
  214.         eraseall(levels, allbones);
  215.         playwoRAMdisk();
  216.     }
  217.     return;
  218. }
  219.  
  220. void
  221. playwoRAMdisk()
  222. {
  223.     int c;
  224.  
  225.     msmsg("Do you wish to play without a RAMdisk? [yn] (n)");
  226.  
  227.     /* Set ramdisk false *before* exit-ing (because msexit calls
  228.      * copybones)
  229.      */
  230.     ramdisk = FALSE;
  231.     c = tgetch(); if (c == 'Y') c = 'y';
  232.     if (c != 'y') {
  233.         settty("Be seeing you...\n");
  234.         exit(0);
  235.     }
  236.     set_lock_and_bones();
  237.     return;
  238. }
  239.  
  240. int
  241. saveDiskPrompt(start)
  242. int start;
  243. {
  244.     char buf[BUFSIZ], *bp;
  245.     char qbuf[QBUFSZ];
  246.  
  247.     int fd;
  248.  
  249.     if (flags.asksavedisk) {
  250.         /* Don't prompt if you can find the save file */
  251.         if ((fd = open_savefile()) >= 0) {
  252.             (void) close(fd);
  253.             return 1;
  254.         }
  255.         clear_nhwindow(WIN_MESSAGE);
  256.         pline("If save file is on a save disk, insert that disk now.");
  257.         mark_synch();
  258.         Sprintf(qbuf,"File name (default \"%s\"%s) ?", SAVEF,
  259.             start ? "" : ", <Esc> cancels save");
  260.         getlin(qbuf, buf);
  261.         clear_nhwindow(WIN_MESSAGE);
  262.         if (!start && *buf == '\033')
  263.             return 0;
  264.  
  265.         /* Strip any whitespace. Also, if nothing was entered except
  266.          * whitespace, do not change the value of SAVEF.
  267.          */
  268.         for (bp = buf; *bp; bp++)
  269.             if (!isspace(*bp)) {
  270.                 strncpy(SAVEF, bp, PATHLEN);
  271.                 break;
  272.             }
  273.     }
  274.     return 1;
  275. }
  276.  
  277. # endif /* MFLOPPY */
  278.  
  279. /* Return 1 if the record file was found */
  280. static boolean
  281. record_exists()
  282. {
  283.     FILE *fp;
  284.  
  285.     fp = fopen_datafile(RECORD, "r");
  286.     if (fp) {
  287.         fclose(fp);
  288.         return TRUE;
  289.     }
  290.     return FALSE;
  291. }
  292.  
  293. # ifdef TOS
  294. #define comspec_exists() 1
  295. # else
  296. /* Return 1 if the comspec was found */
  297. static boolean
  298. comspec_exists()
  299. {
  300.     int fd;
  301.     char *comspec;
  302.  
  303.     if (comspec = getcomspec())
  304.         if ((fd = open(comspec, O_RDONLY)) >= 0) {
  305.             (void) close(fd);
  306.             return TRUE;
  307.         }
  308.     return FALSE;
  309. }
  310. # endif
  311.  
  312. # ifdef MFLOPPY
  313. /* Prompt for game disk, then check for record file.
  314.  */
  315. void
  316. gameDiskPrompt()
  317. {
  318.     if (flags.asksavedisk) {
  319.         if (record_exists() && comspec_exists())
  320.             return;
  321.         (void) putchar('\n');
  322.         getreturn("when the game disk has been inserted");
  323.     }
  324.     if (comspec_exists() && record_exists())
  325.         return;
  326.  
  327.     if (!comspec_exists())
  328.         msmsg("\n\nWARNING: can't find command processor \"%s\"!\n", getcomspec());
  329.         if (!record_exists())
  330.         msmsg("\n\nWARNING: can't find record file \"%s\"!\n", RECORD);
  331.     msmsg("If the game disk is not in, insert it now.\n");
  332.     getreturn("to continue");
  333.     return;
  334. }
  335. # endif /* MFLOPPY */
  336. #endif /* MICRO */
  337.  
  338. /*
  339.  * Add a backslash to any name not ending in /, \ or :   There must
  340.  * be room for the \
  341.  */
  342. void
  343. append_slash(name)
  344. char *name;
  345. {
  346.     char *ptr;
  347.  
  348.     if (!*name)
  349.         return;
  350.     ptr = name + (strlen(name) - 1);
  351.     if (*ptr != '\\' && *ptr != '/' && *ptr != ':') {
  352.         *++ptr = '\\';
  353.         *++ptr = '\0';
  354.     }
  355.     return;
  356. }
  357.  
  358. void
  359. getreturn(str)
  360. const char *str;
  361. {
  362. #ifdef TOS
  363.     msmsg("Hit <Return> %s.", str);
  364. #else
  365.     msmsg("Hit <Enter> %s.", str);
  366. #endif
  367.     while (Getchar() != '\n') ;
  368.     return;
  369. }
  370.  
  371. void
  372. msmsg VA_DECL(const char *, fmt)
  373.     VA_START(fmt);
  374.     VA_INIT(fmt, const char *);
  375.     Vprintf(fmt, VA_ARGS);
  376.     flushout();
  377.     VA_END();
  378.     return;
  379. }
  380.  
  381. /*
  382.  * Follow the PATH, trying to fopen the file.
  383.  */
  384. #ifdef TOS
  385. # ifdef __MINT__
  386. #define PATHSEP ':'
  387. # else
  388. #define PATHSEP    ','
  389. # endif
  390. #else
  391. #define PATHSEP    ';'
  392. #endif
  393.  
  394. FILE *
  395. fopenp(name, mode)
  396. const char *name, *mode;
  397. {
  398.     char buf[BUFSIZ], *bp, *pp, lastch = 0;
  399.     FILE *fp;
  400.  
  401.     /* Try the default directory first.  Then look along PATH.
  402.      */
  403.     Strcpy(buf, name);
  404.     if (fp = fopen(buf, mode))
  405.         return fp;
  406.     else {
  407.         pp = getenv("PATH");
  408.         while (pp && *pp) {
  409.             bp = buf;
  410.             while (*pp && *pp != PATHSEP)
  411.                 lastch = *bp++ = *pp++;
  412.             if (lastch != '\\' && lastch != '/')
  413.                 *bp++ = '\\';
  414.             Strcpy(bp, name);
  415.             if (fp = fopen(buf, mode))
  416.                 return fp;
  417.             if (*pp)
  418.                 pp++;
  419.         }
  420.     }
  421. #ifdef OS2_CODEVIEW /* one more try for hackdir */
  422.     Strcpy(buf,hackdir);
  423.     append_slash(buf);
  424.     Strcat(buf,name);
  425.     if(fp = fopen(buf,mode))
  426.         return fp;
  427. #endif
  428.     return (FILE *)0;
  429. }
  430.  
  431. /* Chdir back to original directory
  432.  */
  433. #undef exit
  434. #ifdef TOS
  435. extern boolean run_from_desktop;    /* set in pcmain.c */
  436. #endif
  437.  
  438. void exit(int);
  439.  
  440. void
  441. msexit(code)
  442. int code;
  443. {
  444. #ifdef CHDIR
  445.     extern char orgdir[];
  446. #endif
  447.  
  448.     flushout();
  449. #ifndef TOS
  450. # ifndef WIN32
  451.     enable_ctrlP();        /* in case this wasn't done */
  452. # endif
  453. #endif
  454. #ifdef MFLOPPY
  455.     if (ramdisk) copybones(TOPERM);
  456. #endif
  457. #ifdef CHDIR
  458.     chdir(orgdir);        /* chdir, not chdirx */
  459.     chdrive(orgdir);
  460. #endif
  461. #ifdef TOS
  462.     if (run_from_desktop)
  463.         getreturn("to continue"); /* so the user can read the score list */
  464. # ifdef TEXTCOLOR
  465.     if (colors_changed)
  466.         restore_colors();
  467. # endif
  468. #endif
  469. #ifdef WIN32CON
  470.     /* Only if we started from Progman, not command prompt,
  471.      * we need to get one last return, so the score board does
  472.      * not vanish instantly after being created.
  473.      * ProgmanLaunched is defined and set in nttty.c.
  474.          */
  475.      
  476.     if (ProgmanLaunched) getreturn("to end");
  477. #endif
  478.     exit(code);
  479.     return;
  480. }
  481.  
  482.