A 37 character field for holding a unique identifier is added to the save file, as well as to an ancestor field in bones files. Since it requires installation of libuuid package on Linux, it requires an exlicit WANT_NHUUID=1 on the Make command line there. Without the libuuid support, the saved nhuuid is empty, which should be harmless. This also moves the save and restore of gm.moves higher up so that it already has a value the first time it is used against a relative saved timestamp. Invalidates savefiles and bones files due to new fields. I need to get this committed before I can test out the macOS portion, so there may be some build issues there briefly (hopefully), and follow-up commits to resolve them. Increments EDITLEVEL.
302 lines
6.5 KiB
C
302 lines
6.5 KiB
C
/* NetHack 3.7 pcsys.c $NHDT-Date: 1596498283 2020/08/03 23:44:43 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.42 $ */
|
|
/* Copyright (c) 2012 by Michael Allison */
|
|
/* NetHack may be freely redistributed. See license for details. */
|
|
|
|
/*
|
|
* System related functions for MSDOS, OS/2, TOS
|
|
*/
|
|
|
|
#define NEED_VARARGS
|
|
#include "hack.h"
|
|
#include "wintty.h"
|
|
|
|
#include <fcntl.h>
|
|
#if !defined(MSDOS) && !defined(WIN_CE) && !defined(CROSS_TO_AMIGA)
|
|
#include <process.h>
|
|
#endif
|
|
#if defined(__GO32__) || defined(CROSS_TO_AMIGA)
|
|
#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
|
|
|
|
static void msexit(void);
|
|
|
|
#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 */
|
|
FILE * fopenp(const char *name, const char *mode);
|
|
|
|
#if defined(MICRO)
|
|
|
|
void
|
|
flushout(void)
|
|
{
|
|
(void) fflush(stdout);
|
|
return;
|
|
}
|
|
|
|
static const char *COMSPEC =
|
|
#ifdef TOS
|
|
"SHELL";
|
|
#else
|
|
"COMSPEC";
|
|
#endif
|
|
|
|
#define getcomspec() nh_getenv(COMSPEC)
|
|
|
|
#ifdef SHELL
|
|
int
|
|
dosh(void)
|
|
{
|
|
#ifndef NOCWD_ASSUMPTIONS
|
|
extern char orgdir[];
|
|
#endif
|
|
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 */
|
|
#ifndef NOCWD_ASSUMPTIONS
|
|
chdirx(orgdir, 0);
|
|
#endif
|
|
#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
|
|
#ifndef NOCWD_ASSUMPTIONS
|
|
chdirx(hackdir, 0);
|
|
#endif
|
|
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 */
|
|
#endif /* MICRO */
|
|
|
|
/*
|
|
* Add a backslash to any name not ending in /, \ or : There must
|
|
* be room for the \
|
|
*/
|
|
void
|
|
append_slash(char *name)
|
|
{
|
|
char *ptr;
|
|
|
|
if (!*name)
|
|
return;
|
|
ptr = name + (strlen(name) - 1);
|
|
if (*ptr != '\\' && *ptr != '/' && *ptr != ':') {
|
|
*++ptr = '\\';
|
|
*++ptr = '\0';
|
|
}
|
|
return;
|
|
}
|
|
|
|
void
|
|
get_nhuuid(void)
|
|
{
|
|
unsigned char stmp[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
|
|
|
if (svn.nhuuid[0])
|
|
return;
|
|
|
|
/* FIXME: fill in a useful valie UUID somehow */
|
|
Snprintf(svn.nhuuid, sizeof svn.nhuuid, "%s", (char *) stmp);
|
|
}
|
|
|
|
void
|
|
free_nhuuid(void)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < SIZE(svn.nhuuid); i++) {
|
|
svn.nhuuid[i] = 0;
|
|
}
|
|
}
|
|
|
|
void
|
|
getreturn(const char *str)
|
|
{
|
|
#ifdef TOS
|
|
msmsg("Hit <Return> %s.", str);
|
|
#else
|
|
#ifdef CROSS_TO_AMIGA
|
|
(void) printf("Hit <Enter> %s.", str);
|
|
#else
|
|
msmsg("Hit <Enter> %s.", str);
|
|
#endif
|
|
#endif
|
|
while (pgetchar() != '\n')
|
|
;
|
|
return;
|
|
}
|
|
|
|
void msmsg
|
|
VA_DECL(const char *, fmt)
|
|
{
|
|
VA_START(fmt);
|
|
VA_INIT(fmt, const char *);
|
|
#if defined(MSDOS) && defined(NO_TERMS)
|
|
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(const char *name, const char *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 - ccnt - 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(OS2)
|
|
void
|
|
nethack_exit(int code)
|
|
{
|
|
msexit();
|
|
exit(code);
|
|
}
|
|
|
|
/* Chdir back to original directory
|
|
*/
|
|
#ifdef TOS
|
|
extern boolean run_from_desktop; /* set in pcmain.c */
|
|
#endif
|
|
|
|
static void
|
|
msexit(void)
|
|
{
|
|
#if defined(CHDIR) && !defined(NOCWD_ASSUMPTIONS)
|
|
extern char orgdir[];
|
|
#endif
|
|
|
|
flushout();
|
|
#ifndef TOS
|
|
enable_ctrlP(); /* in case this wasn't done */
|
|
#endif
|
|
#if defined(CHDIR) && !defined(NOCWD_ASSUMPTIONS)
|
|
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 */
|
|
if (colors_changed)
|
|
restore_colors();
|
|
#endif
|
|
wait_synch();
|
|
term_curs_set(1);
|
|
return;
|
|
}
|
|
#endif /* MICRO || OS2 */
|