Revert "Change Windows startup"

This reverts commit acb85b18cf.

Some optlist issues arose on some platforms, but not all.
I need to investigate the cause of those.
This commit is contained in:
nhmall
2026-04-05 12:07:57 -04:00
parent acb85b18cf
commit db1f230772
23 changed files with 959 additions and 450 deletions

View File

@@ -1881,85 +1881,6 @@ vconfig_error_add(const char *str, va_list the_args)
config_erradd(buf);
}
void
rcfile(void)
{
char *opts = 0, *xtraopts = 0;
const char *envname, *namesrc, *nameval;
go.opt_phase = environ_opt;
/* getenv() instead of nhgetenv(): let total length of options be long;
parseoptions() will check each individually */
envname = "NETHACKOPTIONS";
opts = getenv(envname);
if (!opts) {
/* fall back to original name; discouraged */
envname = "HACKOPTIONS";
opts = getenv(envname);
}
if (gc.cmdline_rcfile) {
namesrc = "command line";
nameval = gc.cmdline_rcfile;
xtraopts = opts;
if (opts && (*opts == '/' || *opts == '\\' || *opts == '@'))
xtraopts = 0; /* NETHACKOPTIONS is a file name; ignore it */
} else if (opts && (*opts == '/' || *opts == '\\' || *opts == '@')) {
/* NETHACKOPTIONS is a file name; use that instead of the default */
if (*opts == '@')
++opts; /* @filename */
namesrc = envname;
nameval = opts;
xtraopts = 0;
} else {
/* either no NETHACKOPTIONS or it wasn't a file name;
read the default configuration file */
nameval = namesrc = 0;
xtraopts = opts;
}
go.opt_phase = rc_file_opt;
/* seemingly arbitrary name length restriction is to prevent error
messages, if any were to be delivered while accessing the file,
from potentially overflowing buffers */
if (nameval && (int) strlen(nameval) >= BUFSZ / 2) {
config_error_init(TRUE, namesrc, FALSE);
config_error_add(
"nethackrc file name \"%.40s\"... too long; using default",
nameval);
config_error_done();
nameval = namesrc = 0; /* revert to default nethackrc */
}
config_error_init(TRUE, nameval, nameval ? CONFIG_ERROR_SECURE : FALSE);
(void) read_config_file(nameval, set_in_config);
config_error_done();
if (xtraopts) {
/* NETHACKOPTIONS is present and not a file name */
go.opt_phase = environ_opt;
config_error_init(FALSE, envname, FALSE);
(void) parseoptions(xtraopts, TRUE, FALSE);
config_error_done();
}
if (gc.cmdline_rcfile)
free((genericptr_t) gc.cmdline_rcfile), gc.cmdline_rcfile = 0;
/*[end of nethackrc handling]*/
}
void
rcfile_interface_options(void)
{
allopt_array_init();
set_all_options_disregarded();
heed_this_option(opt_windowtype);
heed_this_option(opt_soundlib);
rcfile();
set_all_options_heeded();
disregard_this_option(opt_windowtype);
disregard_this_option(opt_soundlib);
}
#ifdef SYSCF
#ifdef SYSCF_FILE
void

View File

@@ -592,7 +592,7 @@ static const struct instance_globals_o g_init_o = {
/* o_init.c */
DUMMY, /* oclass_prob_totals */
/* options.c */
phase_not_set, /* opt_phase */
0, /* opt_phase */
FALSE, /* opt_initial */
FALSE, /* opt_from_file */
FALSE, /* opt_need_redraw */

View File

@@ -56,13 +56,21 @@ NEARDATA struct accessibility_data a11y;
#include "optlist.h"
#undef NHOPT_PROTO
#define NHOPT_ENUM
enum opt {
opt_prefix_only = -1,
#include "optlist.h"
OPTCOUNT
};
#undef NHOPT_ENUM
#define NHOPT_PARSE
static struct allopt_t allopt_init[] = {
#include "optlist.h"
{(const char *) 0, OptS_Advanced, 0, 0, 0, set_in_sysconf, BoolOpt,
No, No, No, No, Term_False, 0, (boolean *) 0,
(int (*)(int, int, boolean, char *, char *)) 0,
(char *) 0, (const char *) 0, (const char *) 0, 0, 0, 0, TRUE }
(char *) 0, (const char *) 0, (const char *) 0, 0, 0, 0 }
};
#undef NHOPT_PARSE
@@ -86,6 +94,16 @@ enum optn_result {
enum requests {
do_nothing, do_init, do_set, do_handler, get_val, get_cnf_val
};
/* these aren't the same as set_xxx in optlist.h */
enum option_phases {
builtin_opt=1,/* compiled-in default value of an option */
syscf_opt, /* sysconf setting of an option, overrides builtin */
rc_file_opt, /* player's run-time config file setting, overrides syscf */
environ_opt, /* player's environment NETHACKOPTIONS, overrides rc_file */
cmdline_opt, /* program invocation command-line, overrides environ */
play_opt, /* 'O' command, interactively set so overrides all */
num_opt_phases
};
static struct allopt_t allopt[SIZE(allopt_init)];
@@ -106,7 +124,6 @@ extern char ttycolors[CLR_MAX]; /* in sys/msdos/video.c */
static char empty_optstr[] = { '\0' };
static boolean duplicate, using_alias;
static boolean give_opt_msg = TRUE;
static boolean restricted_options_mode = FALSE;
enum { MAX_ROLEOPT = 4 }; /* 4: role,race,gend,algn */
static boolean opt_set_in_config[OPTCOUNT];
@@ -340,7 +357,6 @@ static const menu_cmd_t default_menu_cmd_info[] = {
static const char n_currently_set[] = "(%d currently set)";
staticfn void allopt_array_init(void);
staticfn void nmcpy(char *, const char *, int);
staticfn void escapes(const char *, char *);
staticfn void rejectoption(const char *);
@@ -579,7 +595,7 @@ parseoptions(
* placed that number into each option's allopt[n].minmatch.
*
*/
if (!got_match && allopt[i].name)
if (!got_match)
got_match = match_optname(opts, allopt[i].name,
allopt[i].minmatch, TRUE);
if (got_match) {
@@ -618,8 +634,7 @@ parseoptions(
/* allow optfn's to test whether they were called from parseoptions() */
program_state.in_parseoptions++;
if (got_match && (matchidx >= 0 && matchidx < OPTCOUNT)
&& !allopt[matchidx].disregarded) {
if (got_match && matchidx >= 0) {
duplicate = duplicate_opt_detection(matchidx);
if (duplicate && !allopt[matchidx].dupeok)
complain_about_duplicate(matchidx);
@@ -669,7 +684,7 @@ parseoptions(
}
}
if (optresult == optn_silenterr || restricted_options_mode)
if (optresult == optn_silenterr)
return FALSE;
if (pfx_match && optresult == optn_err) {
char pfxbuf[BUFSZ], *pfxp;
@@ -4956,20 +4971,17 @@ optfn_windowtype(
* _end_ because comma-separated option strings are processed from
* right to left.
*/
if (!iflags.window_inited) {
if (iflags.windowtype_locked)
return optn_ok;
if (iflags.windowtype_locked)
return optn_ok;
if ((op = string_for_env_opt(allopt[optidx].name, opts, FALSE))
!= empty_optstr) {
nmcpy(gc.chosen_windowtype, op, WINTYPELEN);
if (!iflags.windowtype_deferred) {
choose_windows(gc.chosen_windowtype);
}
} else {
return optn_err;
if ((op = string_for_env_opt(allopt[optidx].name, opts, FALSE))
!= empty_optstr) {
nmcpy(gc.chosen_windowtype, op, WINTYPELEN);
if (!iflags.windowtype_deferred) {
choose_windows(gc.chosen_windowtype);
}
}
} else
return optn_err;
return optn_ok;
}
if (req == get_val || req == get_cnf_val) {
@@ -7054,14 +7066,29 @@ txt2key(char *txt)
void
initoptions(void)
{
int i;
/*
* Most places that call initoptions_init()/initoptions() would
* have the calls next to each other, so instead of adding
* initoptions_init() everywhere, just add it where it's needed in
* a non-adjacent place and call it here for all the other cases.
*/
if (go.opt_phase != builtin_opt)
if(go.opt_phase != builtin_opt)
initoptions_init();
/*
* Call each option function with an init flag and give it a chance
* to make any preparations that it might require. We do this
* whether or not the option itself is ever specified; that's
* irrelevant for the init call. Doing this allows the prep code for
* option settings to remain adjacent to, and in the same function as,
* the code that processes those options.
*/
for (i = 0; i < OPTCOUNT; ++i) {
if (allopt[i].optfn)
(*allopt[i].optfn)(i, do_init, FALSE, empty_optstr, empty_optstr);
}
#ifdef SYSCF
/* someday there may be other SYSCF alternatives besides text file */
#ifdef SYSCF_FILE
@@ -7103,7 +7130,9 @@ initoptions_init(void)
go.opt_phase = builtin_opt; /* Did I need to move this here? */
/* initialize the function pointers for saving the game */
sf_init();
allopt_array_init();
memcpy(allopt, allopt_init, sizeof(allopt));
determine_ambiguities();
/* if windowtype has been specified on the command line, set it up
early so windowtype-specific options use it as their base */
if (gc.cmdline_windowsys) {
@@ -7257,28 +7286,6 @@ initoptions_init(void)
/* since this is done before init_objects(), do partial init here */
objects[SLIME_MOLD].oc_name_idx = SLIME_MOLD;
nmcpy(svp.pl_fruit, OBJ_NAME(objects[SLIME_MOLD]), PL_FSIZ);
#ifdef SYSCF
/* someday there may be other SYSCF alternatives besides text file */
#ifdef SYSCF_FILE
/* If SYSCF_FILE is specified, it _must_ exist... */
assure_syscf_file();
config_error_init(TRUE, SYSCF_FILE, FALSE);
/* ... and _must_ parse correctly. */
go.opt_phase = syscf_opt;
if (!read_config_file(SYSCF_FILE, set_in_sysconf)) {
if (config_error_done() && !iflags.initoptions_noterminate)
nh_terminate(EXIT_FAILURE);
}
config_error_done();
/*
* TODO [maybe]: parse the sysopt entries which are space-separated
* lists of usernames into arrays with one name per element.
*/
#endif
#endif /* SYSCF */
initoptions_finish();
}
/*
@@ -7299,69 +7306,72 @@ initoptions_init(void)
*/
void
initoptions_finish(void)
{ nhsym sym = 0;
{
nhsym sym = 0;
char *opts = 0, *xtraopts = 0;
#ifndef MAC
const char *envname, *namesrc, *nameval;
rcfile();
(void) fruitadd(svp.pl_fruit, (struct fruit *) 0);
/*
* Remove "slime mold" from list of object names. This will
* prevent it from being wished unless it's actually present
* as a named (or default) fruit. Wishing for "fruit" will
* result in the player's preferred fruit. [Once upon a time
* the override value used was "\033" which prevented wishing
* for the slime mold object at all except by asking for a
* specific named fruit.] Note that there are multiple fruit
* object types (apple, melon, &c) but the "fruit" object is
* slime mold or whatever custom name player assigns to that.
*/
obj_descr[SLIME_MOLD].oc_name = "fruit";
sym = get_othersym(SYM_BOULDER,
Is_rogue_level(&u.uz) ? ROGUESET : PRIMARYSET);
if (sym)
gs.showsyms[SYM_BOULDER + SYM_OFF_X] = sym;
reglyph_darkroom();
reset_glyphmap(gm_optionchange);
#ifdef STATUS_HILITES
/*
* A multi-interface binary might only support status highlighting
* for some of the interfaces; check whether we asked for it but are
* using one which doesn't.
*
* Option processing can take place before a user-decided WindowPort
* is even initialized, so check for that too.
*/
if (!WINDOWPORT(safestartup)) {
if (iflags.hilite_delta && !wc2_supported("statushilites")) {
raw_printf("Status highlighting not supported for %s interface.",
windowprocs.name);
iflags.hilite_delta = 0;
}
/* getenv() instead of nhgetenv(): let total length of options be long;
parseoptions() will check each individually */
envname = "NETHACKOPTIONS";
opts = getenv(envname);
if (!opts) {
/* fall back to original name; discouraged */
envname = "HACKOPTIONS";
opts = getenv(envname);
}
#endif
update_rest_on_space();
/* these can't rely on compile-time initialization for their defaults
because a multi-interface binary might need different values for
different interfaces; if neither tiled_map nor ascii_map pass the
wc_supported() test, assume ascii_map */
if (iflags.wc_tiled_map && !wc_supported("tiled_map"))
iflags.wc_tiled_map = FALSE, iflags.wc_ascii_map = TRUE;
else if (iflags.wc_ascii_map && !wc_supported("ascii_map")
&& wc_supported("tiled_map"))
iflags.wc_ascii_map = FALSE, iflags.wc_tiled_map = TRUE;
if (gc.cmdline_rcfile) {
namesrc = "command line";
nameval = gc.cmdline_rcfile;
xtraopts = opts;
if (opts && (*opts == '/' || *opts == '\\' || *opts == '@'))
xtraopts = 0; /* NETHACKOPTIONS is a file name; ignore it */
} else if (opts && (*opts == '/' || *opts == '\\' || *opts == '@')) {
/* NETHACKOPTIONS is a file name; use that instead of the default */
if (*opts == '@')
++opts; /* @filename */
namesrc = envname;
nameval = opts;
xtraopts = 0;
} else
#endif /* !MAC */
/*else*/ {
/* either no NETHACKOPTIONS or it wasn't a file name;
read the default configuration file */
nameval = namesrc = 0;
xtraopts = opts;
}
#ifdef ENHANCED_SYMBOLS
if (glyphid_cache_status())
free_glyphid_cache();
apply_customizations(gc.currentgraphics, do_custom_symbols);
#endif
go.opt_initial = FALSE;
return;
}
/* seemingly arbitrary name length restriction is to prevent error
messages, if any were to be delivered while accessing the file,
from potentially overflowing buffers */
if (nameval && (int) strlen(nameval) >= BUFSZ / 2) {
go.opt_phase = rc_file_opt;
config_error_init(TRUE, namesrc, FALSE);
config_error_add(
"nethackrc file name \"%.40s\"... too long; using default",
nameval);
config_error_done();
nameval = namesrc = 0; /* revert to default nethackrc */
}
config_error_init(TRUE, nameval, nameval ? CONFIG_ERROR_SECURE : FALSE);
(void) read_config_file(nameval, set_in_config);
config_error_done();
if (xtraopts) {
/* NETHACKOPTIONS is present and not a file name */
go.opt_phase = environ_opt;
config_error_init(FALSE, envname, FALSE);
(void) parseoptions(xtraopts, TRUE, FALSE);
config_error_done();
}
if (gc.cmdline_rcfile)
free((genericptr_t) gc.cmdline_rcfile), gc.cmdline_rcfile = 0;
/*[end of nethackrc handling]*/
#if 0
(void) fruitadd(svp.pl_fruit, (struct fruit *) 0);
/*
* Remove "slime mold" from list of object names. This will
@@ -7439,37 +7449,6 @@ initoptions_finish(void)
}
return;
}
#endif
void
allopt_array_init(void)
{
int i;
static boolean options_array_inited_already = FALSE;
if (!options_array_inited_already) {
memcpy(allopt, allopt_init, sizeof(allopt));
determine_ambiguities();
for (i = 0; allopt[i].name; i++) {
if (allopt[i].addr)
*(allopt[i].addr) = allopt[i].initval;
}
set_all_options_heeded();
/*
* Call each option function with an init flag and give it a chance
* to make any preparations that it might require. We do this
* whether or not the option itself is ever specified; that's
* irrelevant for the init call. Doing this allows the prep code for
* option settings to remain adjacent to, and in the same function as,
* the code that processes those options.
*/
for (i = 0; i < OPTCOUNT; ++i) {
if (allopt[i].optfn)
(*allopt[i].optfn)(i, do_init, FALSE, empty_optstr,
empty_optstr);
}
options_array_inited_already = TRUE;
}
}
/*
*******************************************
@@ -8987,7 +8966,6 @@ doset(void) /* changing options via menu by Per Liboriussen */
if (opt_indx < -1)
opt_indx++; /* -1 offset for select_menu() */
opt_indx -= indexoffset;
assert(IndexOk(opt_indx, allopt));
if (allopt[opt_indx].opttyp == BoolOpt) {
/* boolean option */
Sprintf(buf, "%s%s", *allopt[opt_indx].addr ? "!" : "",
@@ -10242,41 +10220,6 @@ enhance_menu_text(
return;
}
void
set_all_options_heeded(void)
{
int i;
for (i = 0; i < OPTCOUNT; i++)
allopt[i].disregarded = FALSE;
restricted_options_mode = FALSE;
}
void
set_all_options_disregarded(void)
{
int i;
for (i = 0; i < OPTCOUNT ; i++)
allopt[i].disregarded = TRUE;
restricted_options_mode = TRUE;
}
void
heed_this_option(enum opt optidx)
{
if (optidx >= 0 && optidx < (enum opt) OPTCOUNT)
allopt[optidx].disregarded = FALSE;
}
void
disregard_this_option(enum opt optidx)
{
if (optidx >= 0 && optidx < (enum opt) OPTCOUNT)
allopt[optidx].disregarded = TRUE;
if (!restricted_options_mode)
restricted_options_mode = TRUE;
}
#undef OPTIONS_HEADING
#undef CONFIG_SLOT