*** empty log message ***
This commit is contained in:
552
sys/share/pcsys.c
Normal file
552
sys/share/pcsys.c
Normal file
@@ -0,0 +1,552 @@
|
||||
/* SCCS Id: @(#)pcsys.c 3.3 1999/12/10 */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
/*
|
||||
* System related functions for MSDOS, OS/2, TOS, and Windows NT
|
||||
*/
|
||||
|
||||
#define NEED_VARARGS
|
||||
#include "hack.h"
|
||||
#include "wintty.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <fcntl.h>
|
||||
#ifndef MSDOS /* already done */
|
||||
#include <process.h>
|
||||
#endif
|
||||
#ifdef __GO32__
|
||||
#define P_WAIT 0
|
||||
#define P_NOWAIT 1
|
||||
#endif
|
||||
#ifdef TOS
|
||||
#include <osbind.h>
|
||||
#endif
|
||||
#if defined(MSDOS) && !defined(__GO32__)
|
||||
#define findfirst findfirst_file
|
||||
#define findnext findnext_file
|
||||
#define filesize filesize_nh
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(MICRO) || defined(WIN32) || defined(OS2)
|
||||
void FDECL(nethack_exit,(int));
|
||||
#else
|
||||
#define nethack_exit exit
|
||||
#endif
|
||||
static void NDECL(msexit);
|
||||
|
||||
|
||||
#ifdef MOVERLAY
|
||||
extern void __far __cdecl _movepause( void );
|
||||
extern void __far __cdecl _moveresume( void );
|
||||
extern unsigned short __far __cdecl _movefpause;
|
||||
extern unsigned short __far __cdecl _movefpaused;
|
||||
#define __MOVE_PAUSE_DISK 2 /* Represents the executable file */
|
||||
#define __MOVE_PAUSE_CACHE 4 /* Represents the cache memory */
|
||||
#endif /* MOVERLAY */
|
||||
|
||||
#ifdef MFLOPPY
|
||||
STATIC_DCL boolean NDECL(record_exists);
|
||||
# ifndef TOS
|
||||
STATIC_DCL boolean NDECL(comspec_exists);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef WIN32CON
|
||||
extern int GUILaunched; /* from nttty.c */
|
||||
#endif
|
||||
|
||||
#ifdef MICRO
|
||||
|
||||
void
|
||||
flushout()
|
||||
{
|
||||
(void) fflush(stdout);
|
||||
return;
|
||||
}
|
||||
|
||||
static const char *COMSPEC =
|
||||
# ifdef TOS
|
||||
"SHELL";
|
||||
# else
|
||||
"COMSPEC";
|
||||
# endif
|
||||
|
||||
#define getcomspec() nh_getenv(COMSPEC)
|
||||
|
||||
# ifdef SHELL
|
||||
int
|
||||
dosh()
|
||||
{
|
||||
extern char orgdir[];
|
||||
char *comspec;
|
||||
# ifndef __GO32__
|
||||
int spawnstat;
|
||||
# endif
|
||||
#if defined(MSDOS) && defined(NO_TERMS)
|
||||
int grmode = iflags.grmode;
|
||||
#endif
|
||||
if ((comspec = getcomspec())) {
|
||||
# ifndef TOS /* TOS has a variety of shells */
|
||||
suspend_nhwindows("To return to NetHack, enter \"exit\" at the system prompt.\n");
|
||||
# else
|
||||
# if defined(MSDOS) && defined(NO_TERMS)
|
||||
grmode = iflags.grmode;
|
||||
# endif
|
||||
suspend_nhwindows((char *)0);
|
||||
# endif /* TOS */
|
||||
chdirx(orgdir, 0);
|
||||
# ifdef __GO32__
|
||||
if (system(comspec) < 0) { /* wsu@eecs.umich.edu */
|
||||
# else
|
||||
# ifdef MOVERLAY
|
||||
/* Free the cache memory used by overlays, close .exe */
|
||||
_movefpause |= __MOVE_PAUSE_DISK;
|
||||
_movefpause |= __MOVE_PAUSE_CACHE;
|
||||
_movepause();
|
||||
# endif
|
||||
spawnstat = spawnl(P_WAIT, comspec, comspec, (char *)0);
|
||||
# ifdef MOVERLAY
|
||||
_moveresume();
|
||||
# endif
|
||||
|
||||
if ( spawnstat < 0) {
|
||||
# endif
|
||||
raw_printf("Can't spawn \"%s\"!", comspec);
|
||||
getreturn("to continue");
|
||||
}
|
||||
# ifdef TOS
|
||||
/* Some shells (e.g. Gulam) turn the cursor off when they exit */
|
||||
if (iflags.BIOS)
|
||||
(void)Cursconf(1, -1);
|
||||
# endif
|
||||
chdirx(hackdir, 0);
|
||||
get_scr_size(); /* maybe the screen mode changed (TH) */
|
||||
# if defined(MSDOS) && defined(NO_TERMS)
|
||||
if (grmode) gr_init();
|
||||
# endif
|
||||
resume_nhwindows();
|
||||
} else
|
||||
pline("Can't find %s.",COMSPEC);
|
||||
return 0;
|
||||
}
|
||||
# endif /* SHELL */
|
||||
|
||||
# ifdef MFLOPPY
|
||||
|
||||
void
|
||||
eraseall(path, files)
|
||||
const char *path, *files;
|
||||
{
|
||||
char buf[PATHLEN];
|
||||
char *foundfile;
|
||||
|
||||
foundfile = foundfile_buffer();
|
||||
Sprintf(buf, "%s%s", path, files);
|
||||
if (findfirst(buf))
|
||||
do {
|
||||
Sprintf(buf, "%s%s", path, foundfile);
|
||||
(void) unlink(buf);
|
||||
} while (findnext());
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Rewritten for version 3.3 to be faster
|
||||
*/
|
||||
void
|
||||
copybones(mode)
|
||||
int mode;
|
||||
{
|
||||
char from[PATHLEN], to[PATHLEN], last[13];
|
||||
char *frompath, *topath;
|
||||
char *foundfile;
|
||||
# ifndef TOS
|
||||
int status;
|
||||
char copy[8], *comspec;
|
||||
# endif
|
||||
|
||||
if (!ramdisk)
|
||||
return;
|
||||
|
||||
/* Find the name of the last file to be transferred
|
||||
*/
|
||||
frompath = (mode != TOPERM) ? permbones : levels;
|
||||
foundfile = foundfile_buffer();
|
||||
last[0] = '\0';
|
||||
Sprintf(from, "%s%s", frompath, allbones);
|
||||
topath = (mode == TOPERM) ? permbones : levels;
|
||||
# ifdef TOS
|
||||
eraseall(topath, allbones);
|
||||
# endif
|
||||
if (findfirst(from))
|
||||
do {
|
||||
# ifdef TOS
|
||||
Sprintf(from, "%s%s", frompath, foundfile);
|
||||
Sprintf(to, "%s%s", topath, foundfile);
|
||||
if (_copyfile(from, to))
|
||||
goto error_copying;
|
||||
# endif
|
||||
Strcpy(last, foundfile);
|
||||
} while (findnext());
|
||||
# ifdef TOS
|
||||
else
|
||||
return;
|
||||
# else
|
||||
if (last[0]) {
|
||||
Sprintf(copy, "%cC copy",switchar());
|
||||
|
||||
/* Remove any bones files in `to' directory.
|
||||
*/
|
||||
eraseall(topath, allbones);
|
||||
|
||||
/* Copy `from' to `to' */
|
||||
Sprintf(to, "%s%s", topath, allbones);
|
||||
comspec = getcomspec();
|
||||
status =spawnl(P_WAIT, comspec, comspec, copy, from,
|
||||
to, "> nul", (char *)0);
|
||||
} else
|
||||
return;
|
||||
# endif /* TOS */
|
||||
|
||||
/* See if the last file got there. If so, remove the ramdisk bones
|
||||
* files.
|
||||
*/
|
||||
Sprintf(to, "%s%s", topath, last);
|
||||
if (findfirst(to)) {
|
||||
if (mode == TOPERM)
|
||||
eraseall(frompath, allbones);
|
||||
return;
|
||||
}
|
||||
|
||||
# ifdef TOS
|
||||
error_copying:
|
||||
# endif
|
||||
/* Last file didn't get there.
|
||||
*/
|
||||
Sprintf(to, "%s%s", topath, allbones);
|
||||
msmsg("Can't copy \"%s\" to \"%s\" -- ", from, to);
|
||||
# ifndef TOS
|
||||
if (status < 0)
|
||||
msmsg("can't spawn \"%s\"!", comspec);
|
||||
else
|
||||
# endif
|
||||
msmsg((freediskspace(topath) < filesize(from)) ?
|
||||
"insufficient disk space." : "bad path(s)?");
|
||||
if (mode == TOPERM) {
|
||||
msmsg("Bones will be left in \"%s\"\n",
|
||||
*levels ? levels : hackdir);
|
||||
} else {
|
||||
/* Remove all bones files on the RAMdisk */
|
||||
eraseall(levels, allbones);
|
||||
playwoRAMdisk();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
playwoRAMdisk()
|
||||
{
|
||||
int c;
|
||||
|
||||
msmsg("Do you wish to play without a RAMdisk? [yn] (n)");
|
||||
|
||||
/* Set ramdisk false *before* exit-ing (because msexit calls
|
||||
* copybones)
|
||||
*/
|
||||
ramdisk = FALSE;
|
||||
c = tgetch(); if (c == 'Y') c = 'y';
|
||||
if (c != 'y') {
|
||||
settty("Be seeing you...\n");
|
||||
nethack_exit(EXIT_SUCCESS);
|
||||
}
|
||||
set_lock_and_bones();
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
saveDiskPrompt(start)
|
||||
int start;
|
||||
{
|
||||
char buf[BUFSIZ], *bp;
|
||||
char qbuf[QBUFSZ];
|
||||
|
||||
int fd;
|
||||
|
||||
if (flags.asksavedisk) {
|
||||
/* Don't prompt if you can find the save file */
|
||||
if ((fd = open_savefile()) >= 0) {
|
||||
(void) close(fd);
|
||||
return 1;
|
||||
}
|
||||
clear_nhwindow(WIN_MESSAGE);
|
||||
pline("If save file is on a save disk, insert that disk now.");
|
||||
mark_synch();
|
||||
Sprintf(qbuf,"File name (default \"%s\"%s) ?", SAVEF,
|
||||
start ? "" : ", <Esc> cancels save");
|
||||
getlin(qbuf, buf);
|
||||
clear_nhwindow(WIN_MESSAGE);
|
||||
if (!start && *buf == '\033')
|
||||
return 0;
|
||||
|
||||
/* Strip any whitespace. Also, if nothing was entered except
|
||||
* whitespace, do not change the value of SAVEF.
|
||||
*/
|
||||
for (bp = buf; *bp; bp++)
|
||||
if (!isspace(*bp)) {
|
||||
strncpy(SAVEF, bp, PATHLEN);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Return 1 if the record file was found */
|
||||
STATIC_OVL boolean
|
||||
record_exists()
|
||||
{
|
||||
FILE *fp;
|
||||
|
||||
fp = fopen_datafile(RECORD, "r", TRUE);
|
||||
if (fp) {
|
||||
fclose(fp);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
#endif /* MFLOPPY */
|
||||
|
||||
# ifdef TOS
|
||||
#define comspec_exists() 1
|
||||
# else
|
||||
# ifdef MFLOPPY
|
||||
/* Return 1 if the comspec was found */
|
||||
STATIC_OVL boolean
|
||||
comspec_exists()
|
||||
{
|
||||
int fd;
|
||||
char *comspec;
|
||||
|
||||
if ((comspec = getcomspec()))
|
||||
if ((fd = open(comspec, O_RDONLY)) >= 0) {
|
||||
(void) close(fd);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
# endif /* MFLOPPY */
|
||||
# endif
|
||||
|
||||
|
||||
# ifdef MFLOPPY
|
||||
/* Prompt for game disk, then check for record file.
|
||||
*/
|
||||
void
|
||||
gameDiskPrompt()
|
||||
{
|
||||
if (flags.asksavedisk) {
|
||||
if (record_exists() && comspec_exists())
|
||||
return;
|
||||
(void) putchar('\n');
|
||||
getreturn("when the game disk has been inserted");
|
||||
}
|
||||
if (comspec_exists() && record_exists())
|
||||
return;
|
||||
|
||||
if (!comspec_exists())
|
||||
msmsg("\n\nWARNING: can't find command processor \"%s\"!\n", getcomspec());
|
||||
if (!record_exists())
|
||||
msmsg("\n\nWARNING: can't find record file \"%s\"!\n", RECORD);
|
||||
msmsg("If the game disk is not in, insert it now.\n");
|
||||
getreturn("to continue");
|
||||
return;
|
||||
}
|
||||
# endif /* MFLOPPY */
|
||||
#endif /* MICRO */
|
||||
|
||||
/*
|
||||
* Add a backslash to any name not ending in /, \ or : There must
|
||||
* be room for the \
|
||||
*/
|
||||
void
|
||||
append_slash(name)
|
||||
char *name;
|
||||
{
|
||||
char *ptr;
|
||||
|
||||
if (!*name)
|
||||
return;
|
||||
ptr = name + (strlen(name) - 1);
|
||||
if (*ptr != '\\' && *ptr != '/' && *ptr != ':') {
|
||||
*++ptr = '\\';
|
||||
*++ptr = '\0';
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
getreturn(str)
|
||||
const char *str;
|
||||
{
|
||||
#ifdef TOS
|
||||
msmsg("Hit <Return> %s.", str);
|
||||
#else
|
||||
msmsg("Hit <Enter> %s.", str);
|
||||
#endif
|
||||
while (Getchar() != '\n') ;
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
msmsg VA_DECL(const char *, fmt)
|
||||
VA_START(fmt);
|
||||
VA_INIT(fmt, const char *);
|
||||
# if defined(MSDOS)
|
||||
if (iflags.grmode)
|
||||
gr_finish();
|
||||
# endif
|
||||
Vprintf(fmt, VA_ARGS);
|
||||
flushout();
|
||||
VA_END();
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Follow the PATH, trying to fopen the file.
|
||||
*/
|
||||
#ifdef TOS
|
||||
# ifdef __MINT__
|
||||
#define PATHSEP ':'
|
||||
# else
|
||||
#define PATHSEP ','
|
||||
# endif
|
||||
#else
|
||||
#define PATHSEP ';'
|
||||
#endif
|
||||
|
||||
FILE *
|
||||
fopenp(name, mode)
|
||||
const char *name, *mode;
|
||||
{
|
||||
char buf[BUFSIZ], *bp, *pp, lastch = 0;
|
||||
FILE *fp;
|
||||
|
||||
/* Try the default directory first. Then look along PATH.
|
||||
*/
|
||||
(void) strncpy(buf, name, BUFSIZ - 1);
|
||||
buf[BUFSIZ-1] = '\0';
|
||||
if ((fp = fopen(buf, mode)))
|
||||
return fp;
|
||||
else {
|
||||
int ccnt = 0;
|
||||
pp = getenv("PATH");
|
||||
while (pp && *pp) {
|
||||
bp = buf;
|
||||
while (*pp && *pp != PATHSEP) {
|
||||
lastch = *bp++ = *pp++;
|
||||
ccnt++;
|
||||
}
|
||||
if (lastch != '\\' && lastch != '/') {
|
||||
*bp++ = '\\';
|
||||
ccnt++;
|
||||
}
|
||||
(void) strncpy(bp, name, (BUFSIZ - ccnt) - 2);
|
||||
bp[BUFSIZ-1] = '\0';
|
||||
if ((fp = fopen(buf, mode)))
|
||||
return fp;
|
||||
if (*pp)
|
||||
pp++;
|
||||
}
|
||||
}
|
||||
#ifdef OS2_CODEVIEW /* one more try for hackdir */
|
||||
(void) strncpy(buf, hackdir, BUFSZ);
|
||||
buf[BUFSZ-1] = '\0';
|
||||
if ((strlen(name) + 1 + strlen(buf)) < BUFSZ - 1) {
|
||||
append_slash(buf);
|
||||
Strcat(buf,name);
|
||||
} else
|
||||
impossible("fopenp() buffer too small for complete filename!");
|
||||
if(fp = fopen(buf,mode))
|
||||
return fp;
|
||||
#endif
|
||||
return (FILE *)0;
|
||||
}
|
||||
|
||||
#if defined(MICRO) || defined(WIN32) || defined(OS2)
|
||||
void nethack_exit(code)
|
||||
int code;
|
||||
{
|
||||
msexit();
|
||||
#ifdef MTHREAD_VIEW
|
||||
if (iflags.mthreaded) nh_thread_exit(code); /* no return from this */
|
||||
else
|
||||
#endif
|
||||
exit(code);
|
||||
}
|
||||
|
||||
/* Chdir back to original directory
|
||||
*/
|
||||
#ifdef TOS
|
||||
extern boolean run_from_desktop; /* set in pcmain.c */
|
||||
#endif
|
||||
|
||||
static void msexit()
|
||||
{
|
||||
#ifdef CHDIR
|
||||
extern char orgdir[];
|
||||
#endif
|
||||
|
||||
flushout();
|
||||
#ifndef TOS
|
||||
# ifndef WIN32
|
||||
enable_ctrlP(); /* in case this wasn't done */
|
||||
# endif
|
||||
#endif
|
||||
#ifdef MFLOPPY
|
||||
if (ramdisk) copybones(TOPERM);
|
||||
#endif
|
||||
#ifdef CHDIR
|
||||
chdir(orgdir); /* chdir, not chdirx */
|
||||
chdrive(orgdir);
|
||||
#endif
|
||||
#ifdef TOS
|
||||
if (run_from_desktop)
|
||||
getreturn("to continue"); /* so the user can read the score list */
|
||||
# ifdef TEXTCOLOR
|
||||
if (colors_changed)
|
||||
restore_colors();
|
||||
# endif
|
||||
#endif
|
||||
#ifdef WIN32CON
|
||||
/* Only if we started from the GUI, not the command prompt,
|
||||
* we need to get one last return, so the score board does
|
||||
* not vanish instantly after being created.
|
||||
* GUILaunched is defined and set in nttty.c.
|
||||
*/
|
||||
|
||||
if (GUILaunched) getreturn("to end");
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
#ifdef WIN32
|
||||
/*
|
||||
* This is a kludge. Just before the release of 3.3.0 the latest
|
||||
* version of a popular MAPI mail product was found to exhibit
|
||||
* a strange result where the current directory was changed out
|
||||
* from under NetHack resulting in a failure of all subsequent
|
||||
* file operations in NetHack. This routine is called prior
|
||||
* to all file open/renames/deletes in file.c.
|
||||
*
|
||||
* A more elegant solution will be sought after 3.3.0 is released.
|
||||
*/
|
||||
void dircheck()
|
||||
{
|
||||
char dirbuf[BUFSZ];
|
||||
dirbuf[0] = '\0';
|
||||
if (getcwd(dirbuf, sizeof dirbuf) != (char *)0)
|
||||
/* pline("%s,%s",dirbuf,hackdir); */
|
||||
if (strcmp(dirbuf,hackdir) != 0)
|
||||
chdir(hackdir); /* chdir, not chdirx */
|
||||
}
|
||||
#endif
|
||||
#endif /* MICRO || WIN32 || OS2 */
|
||||
Reference in New Issue
Block a user