1 /* NetHack 3.6 pcsys.c $NHDT-Date: 1524689500 2018/04/25 20:51:40 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.31 $ */
2 /* Copyright (c) 2012 by Michael Allison */
3 /* NetHack may be freely redistributed. See license for details. */
6 * System related functions for MSDOS, OS/2, TOS, and Windows NT
15 #if !defined(MSDOS) && !defined(WIN_CE) /* already done */
25 #if defined(MSDOS) && !defined(__GO32__)
26 #define findfirst findfirst_file
27 #define findnext findnext_file
28 #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_DCL void NDECL(msexit);
39 extern void __far __cdecl _movepause(void);
40 extern void __far __cdecl _moveresume(void);
41 extern unsigned short __far __cdecl _movefpause;
42 extern unsigned short __far __cdecl _movefpaused;
43 #define __MOVE_PAUSE_DISK 2 /* Represents the executable file */
44 #define __MOVE_PAUSE_CACHE 4 /* Represents the cache memory */
48 STATIC_DCL boolean NDECL(record_exists);
50 STATIC_DCL boolean NDECL(comspec_exists);
55 extern int GUILaunched; /* from nttty.c */
58 #if defined(MICRO) || defined(WIN32)
63 (void) fflush(stdout);
67 static const char *COMSPEC =
74 #define getcomspec() nh_getenv(COMSPEC)
85 #if defined(MSDOS) && defined(NO_TERMS)
86 int grmode = iflags.grmode;
88 if ((comspec = getcomspec())) {
89 #ifndef TOS /* TOS has a variety of shells */
91 "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);
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)
135 pline("Can't find %s.", COMSPEC);
143 eraseall(path, files)
144 const char *path, *files;
149 foundfile = foundfile_buffer();
150 Sprintf(buf, "%s%s", path, files);
153 Sprintf(buf, "%s%s", path, foundfile);
155 } while (findnext());
160 * Rewritten for version 3.3 to be faster
166 char from[PATHLEN], to[PATHLEN], last[13];
167 char *frompath, *topath;
171 char copy[8], *comspec;
177 /* Find the name of the last file to be transferred
179 frompath = (mode != TOPERM) ? permbones : levels;
180 foundfile = foundfile_buffer();
182 Sprintf(from, "%s%s", frompath, allbones);
183 topath = (mode == TOPERM) ? permbones : levels;
185 eraseall(topath, allbones);
190 Sprintf(from, "%s%s", frompath, foundfile);
191 Sprintf(to, "%s%s", topath, foundfile);
192 if (_copyfile(from, to))
195 Strcpy(last, foundfile);
196 } while (findnext());
202 Sprintf(copy, "%cC copy", switchar());
204 /* Remove any bones files in `to' directory.
206 eraseall(topath, allbones);
208 /* Copy `from' to `to' */
209 Sprintf(to, "%s%s", topath, allbones);
210 comspec = getcomspec();
211 status = spawnl(P_WAIT, comspec, comspec, copy, from, to, "> nul",
217 /* See if the last file got there. If so, remove the ramdisk bones
220 Sprintf(to, "%s%s", topath, last);
223 eraseall(frompath, allbones);
230 /* Last file didn't get there.
232 Sprintf(to, "%s%s", topath, allbones);
233 msmsg("Can't copy \"%s\" to \"%s\" -- ", from, to);
236 msmsg("can't spawn \"%s\"!", comspec);
239 msmsg((freediskspace(topath) < filesize(from))
240 ? "insufficient disk space."
242 if (mode == TOPERM) {
243 msmsg("Bones will be left in \"%s\"\n", *levels ? levels : hackdir);
245 /* Remove all bones files on the RAMdisk */
246 eraseall(levels, allbones);
257 msmsg("Do you wish to play without a RAMdisk? [yn] (n)");
259 /* Set ramdisk false *before* exit-ing (because msexit calls
267 settty("Be seeing you...\n");
268 nethack_exit(EXIT_SUCCESS);
270 set_lock_and_bones();
275 saveDiskPrompt(start)
278 char buf[BUFSIZ], *bp;
283 if (sysflags.asksavedisk) {
284 /* Don't prompt if you can find the save file */
285 if ((fd = open_savefile()) >= 0) {
289 clear_nhwindow(WIN_MESSAGE);
290 pline("If save file is on a save disk, insert that disk now.");
292 Sprintf(qbuf, "File name (default \"%s\"%s) ?", SAVEF,
293 start ? "" : ", <Esc> cancels save");
295 clear_nhwindow(WIN_MESSAGE);
296 if (!start && *buf == '\033')
299 /* Strip any whitespace. Also, if nothing was entered except
300 * whitespace, do not change the value of SAVEF.
302 for (bp = buf; *bp; bp++)
303 if (!isspace((uchar) *bp)) {
304 strncpy(SAVEF, bp, PATHLEN);
311 /* Return 1 if the record file was found */
317 fp = fopen_datafile(RECORD, "r", TRUE);
327 #define comspec_exists() 1
330 /* Return 1 if the comspec was found */
337 if ((comspec = getcomspec()))
338 if ((fd = open(comspec, O_RDONLY)) >= 0) {
348 /* Prompt for game disk, then check for record file.
353 if (sysflags.asksavedisk) {
354 if (record_exists() && comspec_exists())
356 (void) putchar('\n');
357 getreturn("when the game disk has been inserted");
359 if (comspec_exists() && record_exists())
362 if (!comspec_exists())
363 msmsg("\n\nWARNING: can't find command processor \"%s\"!\n",
365 if (!record_exists())
366 msmsg("\n\nWARNING: can't find record file \"%s\"!\n", RECORD);
367 msmsg("If the game disk is not in, insert it now.\n");
368 getreturn("to continue");
375 * Add a backslash to any name not ending in /, \ or : There must
386 ptr = name + (strlen(name) - 1);
387 if (*ptr != '\\' && *ptr != '/' && *ptr != ':') {
395 boolean getreturn_enabled;
404 if (!getreturn_enabled)
408 msmsg("Hit <Return> %s.", str);
410 msmsg("Hit <Enter> %s.", str);
412 while (pgetchar() != '\n')
419 VA_DECL(const char *, fmt)
422 VA_INIT(fmt, const char *);
423 #if defined(MSDOS) && defined(NO_TERMS)
427 Vprintf(fmt, VA_ARGS);
435 * Follow the PATH, trying to fopen the file.
449 const char *name, *mode;
451 char buf[BUFSIZ], *bp, *pp, lastch = 0;
454 /* Try the default directory first. Then look along PATH.
456 (void) strncpy(buf, name, BUFSIZ - 1);
457 buf[BUFSIZ - 1] = '\0';
458 if ((fp = fopen(buf, mode)))
465 while (*pp && *pp != PATHSEP) {
466 lastch = *bp++ = *pp++;
469 if (lastch != '\\' && lastch != '/') {
473 (void) strncpy(bp, name, (BUFSIZ - ccnt) - 2);
474 bp[BUFSIZ - ccnt - 1] = '\0';
475 if ((fp = fopen(buf, mode)))
481 #ifdef OS2_CODEVIEW /* one more try for hackdir */
482 (void) strncpy(buf, hackdir, BUFSZ);
483 buf[BUFSZ - 1] = '\0';
484 if ((strlen(name) + 1 + strlen(buf)) < BUFSZ - 1) {
488 impossible("fopenp() buffer too small for complete filename!");
489 if (fp = fopen(buf, mode))
495 #if defined(MICRO) || defined(WIN32) || defined(OS2)
504 /* Chdir back to original directory
507 extern boolean run_from_desktop; /* set in pcmain.c */
514 extern char orgdir[];
520 enable_ctrlP(); /* in case this wasn't done */
527 #if defined(CHDIR) && !defined(NOCWD_ASSUMPTIONS)
528 chdir(orgdir); /* chdir, not chdirx */
532 if (run_from_desktop)
533 getreturn("to continue"); /* so the user can read the score list */
540 /* Only if we started from the GUI, not the command prompt,
541 * we need to get one last return, so the score board does
542 * not vanish instantly after being created.
543 * GUILaunched is defined and set in nttty.c.
550 getreturn_enabled = TRUE;
554 #endif /* MICRO || WIN32 || OS2 */