Merge branch 'NetHack-3.6'
This commit is contained in:
@@ -24,6 +24,7 @@ Fixes to Post-3.6.3 Problems that Were Exposed Via git Repository
|
|||||||
Platform- and/or Interface-Specific Fixes or Features
|
Platform- and/or Interface-Specific Fixes or Features
|
||||||
-----------------------------------------------------
|
-----------------------------------------------------
|
||||||
fix compilation on platforms that split the ncurses and tinfo libraries
|
fix compilation on platforms that split the ncurses and tinfo libraries
|
||||||
|
allow run-from-removable-device on Windows
|
||||||
|
|
||||||
|
|
||||||
General New Features
|
General New Features
|
||||||
|
|||||||
@@ -1887,6 +1887,7 @@ E boolean NDECL(authorize_wizard_mode);
|
|||||||
#endif /* MICRO || WIN32 */
|
#endif /* MICRO || WIN32 */
|
||||||
#if defined(WIN32)
|
#if defined(WIN32)
|
||||||
E int NDECL(getlock);
|
E int NDECL(getlock);
|
||||||
|
E const char *NDECL(get_portable_device);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* ### pcsys.c ### */
|
/* ### pcsys.c ### */
|
||||||
|
|||||||
@@ -17,6 +17,9 @@ struct sysopt {
|
|||||||
char *debugfiles; /* files to show debugplines in. '*' is all. */
|
char *debugfiles; /* files to show debugplines in. '*' is all. */
|
||||||
#ifdef DUMPLOG
|
#ifdef DUMPLOG
|
||||||
char *dumplogfile; /* where the dump file is saved */
|
char *dumplogfile; /* where the dump file is saved */
|
||||||
|
#endif
|
||||||
|
#ifdef WIN32
|
||||||
|
char *portable_device_top; /* nethack configuration for a portable drive */
|
||||||
#endif
|
#endif
|
||||||
int env_dbgfl; /* 1: debugfiles comes from getenv("DEBUGFILES")
|
int env_dbgfl; /* 1: debugfiles comes from getenv("DEBUGFILES")
|
||||||
* so sysconf's DEBUGFILES shouldn't override it;
|
* so sysconf's DEBUGFILES shouldn't override it;
|
||||||
|
|||||||
+16
@@ -2591,6 +2591,12 @@ char *origbuf;
|
|||||||
if (sysopt.dumplogfile)
|
if (sysopt.dumplogfile)
|
||||||
free((genericptr_t) sysopt.dumplogfile);
|
free((genericptr_t) sysopt.dumplogfile);
|
||||||
sysopt.dumplogfile = dupstr(bufp);
|
sysopt.dumplogfile = dupstr(bufp);
|
||||||
|
#endif
|
||||||
|
#ifdef WIN32
|
||||||
|
} else if (src == SET_IN_SYS && match_varname(buf, "portable_device_top", 8)) {
|
||||||
|
if (sysopt.portable_device_top)
|
||||||
|
free((genericptr_t) sysopt.portable_device_top);
|
||||||
|
sysopt.portable_device_top = dupstr(bufp);
|
||||||
#endif
|
#endif
|
||||||
} else if (src == SET_IN_SYS && match_varname(buf, "GENERICUSERS", 12)) {
|
} else if (src == SET_IN_SYS && match_varname(buf, "GENERICUSERS", 12)) {
|
||||||
if (sysopt.genericusers)
|
if (sysopt.genericusers)
|
||||||
@@ -4320,6 +4326,16 @@ reveal_paths(VOID_ARGS)
|
|||||||
#endif /* ?DUMPLOG */
|
#endif /* ?DUMPLOG */
|
||||||
raw_printf("No end-of-game disclosure file (%s).", nodumpreason);
|
raw_printf("No end-of-game disclosure file (%s).", nodumpreason);
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
if (sysopt.portable_device_top) {
|
||||||
|
const char *pd = get_portable_device();
|
||||||
|
|
||||||
|
raw_printf("Writable folder for portable device config (sysconf %s):",
|
||||||
|
"portable_device_top");
|
||||||
|
raw_printf(" \"%s\"", pd);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* personal configuration file */
|
/* personal configuration file */
|
||||||
|
|
||||||
buf[0] = '\0';
|
buf[0] = '\0';
|
||||||
|
|||||||
@@ -34,6 +34,9 @@ sys_early_init()
|
|||||||
#endif
|
#endif
|
||||||
#ifdef DUMPLOG
|
#ifdef DUMPLOG
|
||||||
sysopt.dumplogfile = (char *) 0;
|
sysopt.dumplogfile = (char *) 0;
|
||||||
|
#endif
|
||||||
|
#ifdef WIN32
|
||||||
|
sysopt.portable_device_top = (char *) 0;
|
||||||
#endif
|
#endif
|
||||||
sysopt.env_dbgfl = 0; /* haven't checked getenv("DEBUGFILES") yet */
|
sysopt.env_dbgfl = 0; /* haven't checked getenv("DEBUGFILES") yet */
|
||||||
sysopt.shellers = (char *) 0;
|
sysopt.shellers = (char *) 0;
|
||||||
@@ -105,6 +108,12 @@ sysopt_release()
|
|||||||
#ifdef DUMPLOG
|
#ifdef DUMPLOG
|
||||||
if (sysopt.dumplogfile)
|
if (sysopt.dumplogfile)
|
||||||
free((genericptr_t)sysopt.dumplogfile), sysopt.dumplogfile=(char *)0;
|
free((genericptr_t)sysopt.dumplogfile), sysopt.dumplogfile=(char *)0;
|
||||||
|
#endif
|
||||||
|
#ifdef WIN32
|
||||||
|
if (sysopt.portable_device_top) {
|
||||||
|
free((genericptr_t) sysopt.portable_device_top);
|
||||||
|
sysopt.portable_device_top = (char *) 0;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
if (sysopt.genericusers)
|
if (sysopt.genericusers)
|
||||||
free((genericptr_t) sysopt.genericusers),
|
free((genericptr_t) sysopt.genericusers),
|
||||||
|
|||||||
+9
-5
@@ -486,8 +486,8 @@ unsigned ftflags;
|
|||||||
; /* KMH -- You can't escape the Sokoban level traps */
|
; /* KMH -- You can't escape the Sokoban level traps */
|
||||||
else if (Levitation || u.ustuck
|
else if (Levitation || u.ustuck
|
||||||
|| (!Can_fall_thru(&u.uz) && !levl[u.ux][u.uy].candig)
|
|| (!Can_fall_thru(&u.uz) && !levl[u.ux][u.uy].candig)
|
||||||
|| (Flying && !(ftflags & TOOKPLUNGE))
|
|| ((Flying || is_clinger(g.youmonst.data))
|
||||||
|| is_clinger(g.youmonst.data)
|
&& !(ftflags & TOOKPLUNGE))
|
||||||
|| (Inhell && !u.uevent.invoked && newlevel == bottom)) {
|
|| (Inhell && !u.uevent.invoked && newlevel == bottom)) {
|
||||||
dont_fall = "don't fall in.";
|
dont_fall = "don't fall in.";
|
||||||
} else if (g.youmonst.data->msize >= MZ_HUGE) {
|
} else if (g.youmonst.data->msize >= MZ_HUGE) {
|
||||||
@@ -505,9 +505,13 @@ unsigned ftflags;
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (Flying && (ftflags & TOOKPLUNGE) && td && t)
|
if ((Flying || is_clinger(g.youmonst.data))
|
||||||
You("swoop down %s!", (t->ttyp == TRAPDOOR)
|
&& (ftflags & TOOKPLUNGE) && td && t)
|
||||||
? "through the trap door" : "into the gaping hole");
|
You("%s down %s!",
|
||||||
|
Flying ? "swoop" : "deliberately drop",
|
||||||
|
(t->ttyp == TRAPDOOR)
|
||||||
|
? "through the trap door"
|
||||||
|
: "into the gaping hole");
|
||||||
|
|
||||||
if (*u.ushops)
|
if (*u.ushops)
|
||||||
shopdig(1);
|
shopdig(1);
|
||||||
|
|||||||
+179
-28
@@ -61,6 +61,9 @@ int NDECL(other_self_recover_prompt);
|
|||||||
|
|
||||||
char orgdir[PATHLEN];
|
char orgdir[PATHLEN];
|
||||||
boolean getreturn_enabled;
|
boolean getreturn_enabled;
|
||||||
|
int windows_startup_state = 0; /* we flag whether to continue with this */
|
||||||
|
/* 0 = keep starting up, everything is good */
|
||||||
|
|
||||||
extern int redirect_stdout; /* from sys/share/pcsys.c */
|
extern int redirect_stdout; /* from sys/share/pcsys.c */
|
||||||
extern int GUILaunched;
|
extern int GUILaunched;
|
||||||
HANDLE hStdOut;
|
HANDLE hStdOut;
|
||||||
@@ -161,6 +164,134 @@ folder_file_exists(const char * folder, const char * file_name)
|
|||||||
return file_exists(path);
|
return file_exists(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean
|
||||||
|
test_portable_config(
|
||||||
|
const char *executable_path,
|
||||||
|
char *portable_device_top_path,
|
||||||
|
size_t portable_device_top_path_size)
|
||||||
|
{
|
||||||
|
boolean retval = FALSE,
|
||||||
|
save_initoptions_noterminate = iflags.initoptions_noterminate;
|
||||||
|
char tmppath[MAX_PATH], *toppath, *sysconftop;
|
||||||
|
#ifdef UNICODE
|
||||||
|
TCHAR wdrive[_MAX_DRIVE];
|
||||||
|
TCHAR wthisdir[_MAX_DIR];
|
||||||
|
TCHAR wfname[_MAX_FNAME];
|
||||||
|
TCHAR wext[_MAX_EXT];
|
||||||
|
#endif
|
||||||
|
char drive[_MAX_DRIVE];
|
||||||
|
char thisdir[_MAX_DIR];
|
||||||
|
char fname[_MAX_FNAME];
|
||||||
|
char ext[_MAX_EXT];
|
||||||
|
errno_t err;
|
||||||
|
|
||||||
|
if (portable_device_top_path && folder_file_exists(executable_path, "sysconf")) {
|
||||||
|
/*
|
||||||
|
There is a sysconf file (not just sysconf.template) present in
|
||||||
|
the exe path, which is not the way NetHack is initially distributed,
|
||||||
|
so assume it means that the admin/installer wants to override
|
||||||
|
something, perhaps set up for a fully-portable configuration that
|
||||||
|
leaves no traces behind elsewhere on this computer's hard drive -
|
||||||
|
delve into that...
|
||||||
|
*/
|
||||||
|
|
||||||
|
*portable_device_top_path = '\0';
|
||||||
|
(void) strncpy(tmppath, executable_path, sizeof tmppath - (1 + sizeof "sysconf"));
|
||||||
|
tmppath[sizeof tmppath - (1 + sizeof "sysconf")] = '\0';
|
||||||
|
(void) strcat(tmppath, "sysconf");
|
||||||
|
/* split the path up */
|
||||||
|
#ifdef UNICODE
|
||||||
|
{
|
||||||
|
int sz, wchars_num = MultiByteToWideChar( CP_ACP, 0, tmppath, -1, NULL, 0);
|
||||||
|
wchar_t *wstr;
|
||||||
|
|
||||||
|
if (wchars_num) {
|
||||||
|
wstr = (wchar_t *) alloc(wchars_num * sizeof(wchar_t));
|
||||||
|
MultiByteToWideChar( CP_ACP, 0, tmppath, -1, wstr, wchars_num);
|
||||||
|
err = _wsplitpath_s(wstr, wdrive, _MAX_DRIVE, wthisdir, _MAX_DIR,
|
||||||
|
wfname, _MAX_FNAME, wext, _MAX_EXT);
|
||||||
|
free(wstr);
|
||||||
|
}
|
||||||
|
sz = WideCharToMultiByte(CP_ACP, 0, wdrive, -1, drive,
|
||||||
|
0, NULL, NULL);
|
||||||
|
if (sz <= sizeof drive)
|
||||||
|
WideCharToMultiByte(CP_ACP, 0, wdrive, -1, drive,
|
||||||
|
sz, NULL, NULL);
|
||||||
|
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
err = _splitpath_s(tmppath, drive, _MAX_DRIVE, thisdir, _MAX_DIR,
|
||||||
|
fname, _MAX_FNAME, ext, _MAX_EXT);
|
||||||
|
#endif
|
||||||
|
if (err != 0)
|
||||||
|
goto done_test;
|
||||||
|
|
||||||
|
toppath = (char *) alloc(portable_device_top_path_size);
|
||||||
|
*toppath = '\0';
|
||||||
|
/* -2 because we need to append the path separator */
|
||||||
|
(void) strncpy(toppath, drive, portable_device_top_path_size - 2);
|
||||||
|
toppath[portable_device_top_path_size - 2] = '\0';
|
||||||
|
(void) strcat(toppath, "\\");
|
||||||
|
|
||||||
|
iflags.initoptions_noterminate = 1;
|
||||||
|
/* assure_syscf_file(); */
|
||||||
|
config_error_init(TRUE, tmppath, FALSE);
|
||||||
|
/* ... and _must_ parse correctly. */
|
||||||
|
if (read_config_file(tmppath, SET_IN_SYS)
|
||||||
|
&& sysopt.portable_device_top
|
||||||
|
&& (strlen(sysopt.portable_device_top) + strlen(toppath)
|
||||||
|
< portable_device_top_path_size - 3)) {
|
||||||
|
sysconftop = sysopt.portable_device_top;
|
||||||
|
if (sysconftop[1] == ':')
|
||||||
|
sysconftop += 2; /* skip the device if specified */
|
||||||
|
if (*sysconftop == '\\')
|
||||||
|
sysconftop += 1; /* skip the root folder if specified */
|
||||||
|
(void) strcat(toppath, sysconftop);
|
||||||
|
append_slash(toppath);
|
||||||
|
retval = TRUE;
|
||||||
|
} else {
|
||||||
|
if (config_error_done())
|
||||||
|
retval = FALSE;
|
||||||
|
}
|
||||||
|
iflags.initoptions_noterminate = save_initoptions_noterminate;
|
||||||
|
sysopt_release();
|
||||||
|
if (retval)
|
||||||
|
Strcpy(portable_device_top_path, toppath);
|
||||||
|
free(toppath);
|
||||||
|
}
|
||||||
|
done_test:
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char portable_device_top_path[MAX_PATH];
|
||||||
|
|
||||||
|
const char *get_portable_device()
|
||||||
|
{
|
||||||
|
return (const char *) portable_device_top_path;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean illegal_dir(const char *d1, const char *d2)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
char tmpbuf[MAX_PATH];
|
||||||
|
|
||||||
|
if (!strcmpi(d1, d2)) {
|
||||||
|
(void) strncpy(tmpbuf, &portable_device_top_path[3],
|
||||||
|
sizeof tmpbuf - 1);
|
||||||
|
tmpbuf[sizeof tmpbuf - 1] = '\0';
|
||||||
|
i = (int) strlen(tmpbuf) - 1;
|
||||||
|
if (tmpbuf[i] == '\\')
|
||||||
|
tmpbuf[i] = '\0';
|
||||||
|
raw_printf("Illegal \"portable_device_top = %s\" in your sysconf file",
|
||||||
|
tmpbuf);
|
||||||
|
raw_printf("because the exe is running from that folder.");
|
||||||
|
raw_printf("Point 'portable_device_top' to a different folder.");
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
set_default_prefix_locations(const char *programPath)
|
set_default_prefix_locations(const char *programPath)
|
||||||
{
|
{
|
||||||
@@ -177,29 +308,43 @@ set_default_prefix_locations(const char *programPath)
|
|||||||
strcpy(executable_path, get_executable_path());
|
strcpy(executable_path, get_executable_path());
|
||||||
append_slash(executable_path);
|
append_slash(executable_path);
|
||||||
|
|
||||||
build_known_folder_path(&FOLDERID_Profile, profile_path,
|
if (test_portable_config(executable_path, portable_device_top_path,
|
||||||
sizeof(profile_path), FALSE);
|
sizeof portable_device_top_path)) {
|
||||||
|
if (illegal_dir(portable_device_top_path, executable_path))
|
||||||
|
windows_startup_state = 2;
|
||||||
|
g.fqn_prefix[SYSCONFPREFIX] = executable_path;
|
||||||
|
g.fqn_prefix[CONFIGPREFIX] = portable_device_top_path;
|
||||||
|
g.fqn_prefix[HACKPREFIX] = portable_device_top_path;
|
||||||
|
g.fqn_prefix[SAVEPREFIX] = portable_device_top_path;
|
||||||
|
g.fqn_prefix[LEVELPREFIX] = portable_device_top_path;
|
||||||
|
g.fqn_prefix[BONESPREFIX] = portable_device_top_path;
|
||||||
|
g.fqn_prefix[SCOREPREFIX] = portable_device_top_path;
|
||||||
|
g.fqn_prefix[LOCKPREFIX] = portable_device_top_path;
|
||||||
|
g.fqn_prefix[TROUBLEPREFIX] = portable_device_top_path;
|
||||||
|
g.fqn_prefix[DATAPREFIX] = executable_path;
|
||||||
|
} else {
|
||||||
|
build_known_folder_path(&FOLDERID_Profile, profile_path,
|
||||||
|
sizeof(profile_path), FALSE);
|
||||||
|
|
||||||
build_known_folder_path(&FOLDERID_Profile, versioned_profile_path,
|
build_known_folder_path(&FOLDERID_Profile, versioned_profile_path,
|
||||||
sizeof(profile_path), TRUE);
|
sizeof(profile_path), TRUE);
|
||||||
|
|
||||||
build_known_folder_path(&FOLDERID_LocalAppData,
|
build_known_folder_path(&FOLDERID_LocalAppData,
|
||||||
versioned_user_data_path, sizeof(versioned_user_data_path), TRUE);
|
versioned_user_data_path, sizeof(versioned_user_data_path), TRUE);
|
||||||
|
|
||||||
build_known_folder_path(&FOLDERID_ProgramData,
|
|
||||||
versioned_global_data_path, sizeof(versioned_global_data_path), TRUE);
|
|
||||||
|
|
||||||
g.fqn_prefix[SYSCONFPREFIX] = versioned_global_data_path;
|
|
||||||
g.fqn_prefix[CONFIGPREFIX] = profile_path;
|
|
||||||
g.fqn_prefix[HACKPREFIX] = versioned_profile_path;
|
|
||||||
g.fqn_prefix[SAVEPREFIX] = versioned_user_data_path;
|
|
||||||
g.fqn_prefix[LEVELPREFIX] = versioned_user_data_path;
|
|
||||||
g.fqn_prefix[BONESPREFIX] = versioned_global_data_path;
|
|
||||||
g.fqn_prefix[SCOREPREFIX] = versioned_global_data_path;
|
|
||||||
g.fqn_prefix[LOCKPREFIX] = versioned_global_data_path;
|
|
||||||
g.fqn_prefix[TROUBLEPREFIX] = versioned_profile_path;
|
|
||||||
g.fqn_prefix[DATAPREFIX] = executable_path;
|
|
||||||
|
|
||||||
|
build_known_folder_path(&FOLDERID_ProgramData,
|
||||||
|
versioned_global_data_path, sizeof(versioned_global_data_path), TRUE);
|
||||||
|
g.fqn_prefix[SYSCONFPREFIX] = versioned_global_data_path;
|
||||||
|
g.fqn_prefix[CONFIGPREFIX] = profile_path;
|
||||||
|
g.fqn_prefix[HACKPREFIX] = versioned_profile_path;
|
||||||
|
g.fqn_prefix[SAVEPREFIX] = versioned_user_data_path;
|
||||||
|
g.fqn_prefix[LEVELPREFIX] = versioned_user_data_path;
|
||||||
|
g.fqn_prefix[BONESPREFIX] = versioned_global_data_path;
|
||||||
|
g.fqn_prefix[SCOREPREFIX] = versioned_global_data_path;
|
||||||
|
g.fqn_prefix[LOCKPREFIX] = versioned_global_data_path;
|
||||||
|
g.fqn_prefix[TROUBLEPREFIX] = versioned_profile_path;
|
||||||
|
g.fqn_prefix[DATAPREFIX] = executable_path;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* copy file if destination does not exist */
|
/* copy file if destination does not exist */
|
||||||
@@ -393,6 +538,12 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/
|
|||||||
copy_config_content();
|
copy_config_content();
|
||||||
process_options(argc, argv);
|
process_options(argc, argv);
|
||||||
|
|
||||||
|
/* did something earlier flag a need to exit without starting a game? */
|
||||||
|
if (windows_startup_state > 0) {
|
||||||
|
raw_printf("Exiting.");
|
||||||
|
nethack_exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
/* Finished processing options, lock all directory paths */
|
/* Finished processing options, lock all directory paths */
|
||||||
for(int i = 0; i < PREFIX_COUNT; i++)
|
for(int i = 0; i < PREFIX_COUNT; i++)
|
||||||
fqn_prefix_locked[i] = TRUE;
|
fqn_prefix_locked[i] = TRUE;
|
||||||
@@ -538,9 +689,9 @@ attempt_restore:
|
|||||||
You("are in non-scoring discovery mode.");
|
You("are in non-scoring discovery mode.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// iflags.debug_fuzzer = TRUE;
|
// iflags.debug_fuzzer = TRUE;
|
||||||
|
|
||||||
moveloop(resuming);
|
moveloop(resuming);
|
||||||
nethack_exit(EXIT_SUCCESS);
|
nethack_exit(EXIT_SUCCESS);
|
||||||
/*NOTREACHED*/
|
/*NOTREACHED*/
|
||||||
return 0;
|
return 0;
|
||||||
@@ -566,15 +717,15 @@ char *argv[];
|
|||||||
iflags.initoptions_noterminate = FALSE;
|
iflags.initoptions_noterminate = FALSE;
|
||||||
reveal_paths();
|
reveal_paths();
|
||||||
nethack_exit(EXIT_SUCCESS);
|
nethack_exit(EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
if (argcheck(argc, argv, ARG_DEBUG) == 1) {
|
if (argcheck(argc, argv, ARG_DEBUG) == 1) {
|
||||||
argc--;
|
argc--;
|
||||||
argv++;
|
argv++;
|
||||||
}
|
}
|
||||||
if (argcheck(argc, argv, ARG_WINDOWS) == 1) {
|
if (argcheck(argc, argv, ARG_WINDOWS) == 1) {
|
||||||
argc--;
|
argc--;
|
||||||
argv++;
|
argv++;
|
||||||
}
|
}
|
||||||
if (argc > 1 && !strncmp(argv[1], "-d", 2) && argv[1][2] != 'e') {
|
if (argc > 1 && !strncmp(argv[1], "-d", 2) && argv[1][2] != 'e') {
|
||||||
/* avoid matching "-dec" for DECgraphics; since the man page
|
/* avoid matching "-dec" for DECgraphics; since the man page
|
||||||
* says -d directory, hope nobody's using -desomething_else
|
* says -d directory, hope nobody's using -desomething_else
|
||||||
|
|||||||
Reference in New Issue
Block a user