1 /* SCCS Id: @(#)pcsys.c 3.4 2002/01/22 */
2 /* NetHack may be freely redistributed. See license for details. */
5 * System related functions for MSDOS, OS/2, TOS, and Windows NT
14 #if !defined(MSDOS) && !defined(WIN_CE) /* already done */
24 #if defined(MSDOS) && !defined(__GO32__)
25 #define findfirst findfirst_file
26 #define findnext findnext_file
27 #define filesize filesize_nh
31 #if defined(MICRO) || defined(WIN32) || defined(OS2)
32 void FDECL(nethack_exit,(int));
34 #define nethack_exit exit
36 static void NDECL(msexit);
40 extern void __far __cdecl _movepause( void );
41 extern void __far __cdecl _moveresume( void );
42 extern unsigned short __far __cdecl _movefpause;
43 extern unsigned short __far __cdecl _movefpaused;
44 #define __MOVE_PAUSE_DISK 2 /* Represents the executable file */
45 #define __MOVE_PAUSE_CACHE 4 /* Represents the cache memory */
49 STATIC_DCL boolean NDECL(record_exists);
51 STATIC_DCL boolean NDECL(comspec_exists);
56 extern int GUILaunched; /* from nttty.c */
59 #if defined(MICRO) || defined(WIN32)
64 (void) fflush(stdout);
68 static const char *COMSPEC =
75 #define getcomspec() nh_getenv(COMSPEC)
86 #if defined(MSDOS) && defined(NO_TERMS)
87 int grmode = iflags.grmode;
89 if ((comspec = getcomspec())) {
90 # ifndef TOS /* TOS has a variety of shells */
91 suspend_nhwindows("To return to NetHack, enter \"exit\" at the system prompt.\n");
93 # if defined(MSDOS) && defined(NO_TERMS)
94 grmode = iflags.grmode;
96 suspend_nhwindows((char *)0);
98 # ifndef NOCWD_ASSUMPTIONS
102 if (system(comspec) < 0) { /* wsu@eecs.umich.edu */
105 /* Free the cache memory used by overlays, close .exe */
106 _movefpause |= __MOVE_PAUSE_DISK;
107 _movefpause |= __MOVE_PAUSE_CACHE;
110 spawnstat = spawnl(P_WAIT, comspec, comspec, (char *)0);
115 if ( spawnstat < 0) {
117 raw_printf("Can't spawn \"%s\"!", comspec);
118 getreturn("to continue");
121 /* Some shells (e.g. Gulam) turn the cursor off when they exit */
123 (void)Cursconf(1, -1);
125 # ifndef NOCWD_ASSUMPTIONS
128 get_scr_size(); /* maybe the screen mode changed (TH) */
129 # if defined(MSDOS) && defined(NO_TERMS)
130 if (grmode) gr_init();
134 pline("Can't find %s.",COMSPEC);
142 eraseall(path, files)
143 const char *path, *files;
148 foundfile = foundfile_buffer();
149 Sprintf(buf, "%s%s", path, files);
152 Sprintf(buf, "%s%s", path, foundfile);
154 } while (findnext());
159 * Rewritten for version 3.3 to be faster
165 char from[PATHLEN], to[PATHLEN], last[13];
166 char *frompath, *topath;
170 char copy[8], *comspec;
176 /* Find the name of the last file to be transferred
178 frompath = (mode != TOPERM) ? permbones : levels;
179 foundfile = foundfile_buffer();
181 Sprintf(from, "%s%s", frompath, allbones);
182 topath = (mode == TOPERM) ? permbones : levels;
184 eraseall(topath, allbones);
189 Sprintf(from, "%s%s", frompath, foundfile);
190 Sprintf(to, "%s%s", topath, foundfile);
191 if (_copyfile(from, to))
194 Strcpy(last, foundfile);
195 } while (findnext());
201 Sprintf(copy, "%cC copy",switchar());
203 /* Remove any bones files in `to' directory.
205 eraseall(topath, allbones);
207 /* Copy `from' to `to' */
208 Sprintf(to, "%s%s", topath, allbones);
209 comspec = getcomspec();
210 status =spawnl(P_WAIT, comspec, comspec, copy, from,
211 to, "> nul", (char *)0);
216 /* See if the last file got there. If so, remove the ramdisk bones
219 Sprintf(to, "%s%s", topath, last);
222 eraseall(frompath, allbones);
229 /* Last file didn't get there.
231 Sprintf(to, "%s%s", topath, allbones);
232 msmsg("Can't copy \"%s\" to \"%s\" -- ", from, to);
235 msmsg("can't spawn \"%s\"!", comspec);
238 msmsg((freediskspace(topath) < filesize(from)) ?
239 "insufficient disk space." : "bad path(s)?");
240 if (mode == TOPERM) {
241 msmsg("Bones will be left in \"%s\"\n",
242 *levels ? levels : hackdir);
244 /* Remove all bones files on the RAMdisk */
245 eraseall(levels, allbones);
256 msmsg("Do you wish to play without a RAMdisk? [yn] (n)");
258 /* Set ramdisk false *before* exit-ing (because msexit calls
262 c = tgetch(); if (c == 'Y') c = 'y';
264 settty("Be seeing you...\n");
265 nethack_exit(EXIT_SUCCESS);
267 set_lock_and_bones();
272 saveDiskPrompt(start)
275 char buf[BUFSIZ], *bp;
280 if (flags.asksavedisk) {
281 /* Don't prompt if you can find the save file */
282 if ((fd = open_savefile()) >= 0) {
286 clear_nhwindow(WIN_MESSAGE);
287 pline("If save file is on a save disk, insert that disk now.");
289 Sprintf(qbuf,"File name (default \"%s\"%s) ?", SAVEF,
290 start ? "" : ", <Esc> cancels save");
292 clear_nhwindow(WIN_MESSAGE);
293 if (!start && *buf == '\033')
296 /* Strip any whitespace. Also, if nothing was entered except
297 * whitespace, do not change the value of SAVEF.
299 for (bp = buf; *bp; bp++)
301 strncpy(SAVEF, bp, PATHLEN);
308 /* Return 1 if the record file was found */
314 fp = fopen_datafile(RECORD, "r", TRUE);
324 #define comspec_exists() 1
327 /* Return 1 if the comspec was found */
334 if ((comspec = getcomspec()))
335 if ((fd = open(comspec, O_RDONLY)) >= 0) {
341 # endif /* MFLOPPY */
346 /* Prompt for game disk, then check for record file.
351 if (flags.asksavedisk) {
352 if (record_exists() && comspec_exists())
354 (void) putchar('\n');
355 getreturn("when the game disk has been inserted");
357 if (comspec_exists() && record_exists())
360 if (!comspec_exists())
361 msmsg("\n\nWARNING: can't find command processor \"%s\"!\n", getcomspec());
362 if (!record_exists())
363 msmsg("\n\nWARNING: can't find record file \"%s\"!\n", RECORD);
364 msmsg("If the game disk is not in, insert it now.\n");
365 getreturn("to continue");
368 # endif /* MFLOPPY */
372 * Add a backslash to any name not ending in /, \ or : There must
383 ptr = name + (strlen(name) - 1);
384 if (*ptr != '\\' && *ptr != '/' && *ptr != ':') {
392 boolean getreturn_enabled;
400 if (!getreturn_enabled) return;
403 msmsg("Hit <Return> %s.", str);
405 msmsg("Hit <Enter> %s.", str);
407 while (Getchar() != '\n') ;
413 msmsg VA_DECL(const char *, fmt)
415 VA_INIT(fmt, const char *);
416 # if defined(MSDOS) && defined(NO_TERMS)
420 Vprintf(fmt, VA_ARGS);
428 * Follow the PATH, trying to fopen the file.
442 const char *name, *mode;
444 char buf[BUFSIZ], *bp, *pp, lastch = 0;
447 /* Try the default directory first. Then look along PATH.
449 (void) strncpy(buf, name, BUFSIZ - 1);
450 buf[BUFSIZ-1] = '\0';
451 if ((fp = fopen(buf, mode)))
458 while (*pp && *pp != PATHSEP) {
459 lastch = *bp++ = *pp++;
462 if (lastch != '\\' && lastch != '/') {
466 (void) strncpy(bp, name, (BUFSIZ - ccnt) - 2);
467 bp[BUFSIZ - ccnt - 1] = '\0';
468 if ((fp = fopen(buf, mode)))
474 #ifdef OS2_CODEVIEW /* one more try for hackdir */
475 (void) strncpy(buf, hackdir, BUFSZ);
477 if ((strlen(name) + 1 + strlen(buf)) < BUFSZ - 1) {
481 impossible("fopenp() buffer too small for complete filename!");
482 if(fp = fopen(buf,mode))
488 #if defined(MICRO) || defined(WIN32) || defined(OS2)
489 void nethack_exit(code)
496 /* Chdir back to original directory
499 extern boolean run_from_desktop; /* set in pcmain.c */
505 extern char orgdir[];
511 enable_ctrlP(); /* in case this wasn't done */
515 if (ramdisk) copybones(TOPERM);
517 #if defined(CHDIR) && !defined(NOCWD_ASSUMPTIONS)
518 chdir(orgdir); /* chdir, not chdirx */
522 if (run_from_desktop)
523 getreturn("to continue"); /* so the user can read the score list */
530 /* Only if we started from the GUI, not the command prompt,
531 * we need to get one last return, so the score board does
532 * not vanish instantly after being created.
533 * GUILaunched is defined and set in nttty.c.
536 if (GUILaunched) getreturn("to end");
541 #endif /* MICRO || WIN32 || OS2 */