Merge branch 'NetHack-3.6.2-beta01' into NetHack-3.6.2

This commit is contained in:
nhmall
2018-12-10 09:17:48 -05:00
35 changed files with 1685 additions and 419 deletions

View File

@@ -252,12 +252,22 @@ hero hit by something that causes inventory items to be destroyed with loss of
similar problem with more obvious symptom, an "object lost" panic when
the unholy water was wielded; the fix for that wasn't general enough]
add MM_ASLEEP makemon() flag and honor it when creating group for fill_zoo
at start of session (new game or restore), HILITE_STATUS for gold was ignored
if player creates any menu colors via 'O' while menucolors is off, issue a
reminder that it needs to be on in order for those to become effective
add MM_NOGRP makemon() flag as a means of suppressing groups of monsters in
a couple places that warrant it when a specific monster type isn't
specified on the call to makemon()
at start of session (new game or restore), HILITE_STATUS for gold was ignored
if player creates any menu colors via 'O' while menucolors is off, issue a
reminder that it needs to be on in order for those to become effective
setting second or later named fruit to value beginning with two or more spaces
followed by non-space gave "singular of null?" warning
when blocking/unblocking of levitation or flying was updated due to walking
onto different terrain, the relevant status condition wasn't updated
on the screen until some other status update happened
if levitating hero poly'd into pass-wall creature jumped or teleported from
terrain that allowed levitation to terrain that didn't or vice versa,
blocking of levitation wasn't updated properly
clairvoyance revealing underwater or under-lava objects left object displayed
instead of restoring the water or lava
Fixes to Post-3.6.1 Problems that Were Exposed Via git Repository

View File

@@ -25,6 +25,10 @@ E char SAVEF[];
E char SAVEP[];
#endif
/* max size of a windowtype option */
#define WINTYPELEN 16
E char chosen_windowtype[WINTYPELEN];
E NEARDATA int bases[MAXOCLASSES];
E NEARDATA int multi;

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 extern.h $NHDT-Date: 1543892214 2018/12/04 02:56:54 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.665 $ */
/* NetHack 3.6 extern.h $NHDT-Date: 1544401264 2018/12/10 00:21:04 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.666 $ */
/* Copyright (c) Steve Creps, 1988. */
/* NetHack may be freely redistributed. See license for details. */
@@ -854,6 +854,7 @@ E boolean NDECL(u_rooted);
E void NDECL(domove);
E boolean NDECL(overexertion);
E void NDECL(invocation_message);
E void NDECL(switch_terrain);
E boolean FDECL(pooleffects, (BOOLEAN_P));
E void FDECL(spoteffects, (BOOLEAN_P));
E char *FDECL(in_rooms, (XCHAR_P, XCHAR_P, int));

View File

@@ -445,6 +445,9 @@ struct instance_flags {
short soko_prize_type2; /* amulet of reflection */
struct debug_flags debug;
boolean windowtype_locked; /* windowtype can't change from configfile */
boolean windowtype_deferred; /* pick a windowport and store it in
chosen_windowport[], but do not switch to
it in the midst of options processing */
};
/*

View File

@@ -375,4 +375,77 @@ struct chain_procs {
};
#endif /* WINCHAIN */
#ifdef SAFEPROCS
/*
* window port routines available in sys/share/safeproc.c
*/
extern struct window_procs *FDECL(get_safe_procs, (int));
extern void FDECL(safe_init_nhwindows, (int *, char **));
extern void NDECL(safe_player_selection);
extern void NDECL(safe_askname);
extern void NDECL(safe_get_nh_event);
extern void FDECL(safe_exit_nhwindows, (const char *));
extern void FDECL(safe_suspend_nhwindows, (const char *));
extern void NDECL(safe_resume_nhwindows);
extern winid FDECL(safe_create_nhwindow, (int));
extern void FDECL(safe_clear_nhwindow, (winid));
extern void FDECL(safe_display_nhwindow, (winid, BOOLEAN_P));
extern void FDECL(safe_destroy_nhwindow, (winid));
extern void FDECL(safe_curs, (winid, int, int));
extern void FDECL(safe_putstr, (winid, int, const char *));
extern void FDECL(safe_putmixed, (winid, int, const char *));
extern void FDECL(safe_display_file, (const char *, BOOLEAN_P));
extern void FDECL(safe_start_menu, (winid));
extern void FDECL(safe_add_menu, (winid, int, const ANY_P *, CHAR_P, CHAR_P,
int, const char *, BOOLEAN_P));
extern void FDECL(safe_end_menu, (winid, const char *));
extern int FDECL(safe_select_menu, (winid, int, MENU_ITEM_P **));
extern char FDECL(safe_message_menu, (CHAR_P, int, const char *));
extern void NDECL(safe_update_inventory);
extern void NDECL(safe_mark_synch);
extern void NDECL(safe_wait_synch);
#ifdef CLIPPING
extern void FDECL(safe_cliparound, (int, int));
#endif
#ifdef POSITIONBAR
extern void FDECL(safe_update_positionbar, (char *));
#endif
extern void FDECL(safe_print_glyph, (winid, XCHAR_P, XCHAR_P, int, int));
extern void FDECL(safe_raw_print, (const char *));
extern void FDECL(safe_raw_print_bold, (const char *));
extern int NDECL(safe_nhgetch);
extern int FDECL(safe_nh_poskey, (int *, int *, int *));
extern void NDECL(safe_nhbell);
extern int NDECL(safe_doprev_message);
extern char FDECL(safe_yn_function, (const char *, const char *, CHAR_P));
extern void FDECL(safe_getlin, (const char *, char *));
extern int NDECL(safe_get_ext_cmd);
extern void FDECL(safe_number_pad, (int));
extern void NDECL(safe_delay_output);
#ifdef CHANGE_COLOR
extern void FDECL(safe_change_color, (int, long, int));
#ifdef MAC
extern void FDECL(safe_change_background, (int));
extern short FDECL(safe_set_font_name, (winid, char *));
#endif
extern char *NDECL(safe_get_color_string);
#endif
extern void NDECL(safe_start_screen);
extern void NDECL(safe_end_screen);
extern void FDECL(safe_outrip, (winid, int, time_t));
extern void FDECL(safe_preference_update, (const char *));
extern char *FDECL(safe_getmsghistory, (BOOLEAN_P));
extern void FDECL(safe_putmsghistory, (const char *, BOOLEAN_P));
extern void NDECL(safe_status_init);
extern void NDECL(safe_status_finish);
extern void FDECL(safe_status_enablefield,
(int, const char *, const char *, BOOLEAN_P));
extern void FDECL(safe_status_update, (int, genericptr_t, int, int, int, unsigned long *));
extern boolean NDECL(safe_can_suspend);
extern void FDECL(stdio_raw_print, (const char *));
extern void FDECL(stdio_raw_print_bold, (const char *));
extern void NDECL(stdio_wait_synch);
extern int NDECL(stdio_nhgetch);
#endif /* SAFEPROCS */
#endif /* WINPROCS_H */

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 apply.c $NHDT-Date: 1542765339 2018/11/21 01:55:39 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.254 $ */
/* NetHack 3.6 apply.c $NHDT-Date: 1544442708 2018/12/10 11:51:48 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.269 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2012. */
/* NetHack may be freely redistributed. See license for details. */
@@ -418,7 +418,7 @@ register struct obj *obj;
return res;
case SCORR:
You_hear(hollow_str, "passage");
lev->typ = CORR;
lev->typ = CORR, lev->flags = 0;
unblock_point(rx, ry);
feel_newsym(rx, ry);
return res;
@@ -3394,7 +3394,7 @@ struct obj *obj;
*/
typ = fillholetyp(x, y, FALSE);
if (typ != ROOM) {
levl[x][y].typ = typ;
levl[x][y].typ = typ, levl[x][y].flags = 0;
liquid_flow(x, y, typ, t_at(x, y),
fillmsg
? (char *) 0

View File

@@ -234,7 +234,8 @@ do_statusline2()
void
bot()
{
if (youmonst.data && iflags.status_updates) {
/* dosave() flags completion by setting u.uhp to -1 */
if ((u.uhp != -1) && youmonst.data && iflags.status_updates) {
#ifdef STATUS_HILITES
bot_via_windowport();
#else

View File

@@ -17,6 +17,7 @@ int locknum = 0; /* max num of simultaneous users */
#ifdef DEF_PAGER
char *catmore = 0; /* default pager */
#endif
char chosen_windowtype[WINTYPELEN];
NEARDATA int bases[MAXOCLASSES] = DUMMY;

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 detect.c $NHDT-Date: 1542853884 2018/11/22 02:31:24 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.87 $ */
/* NetHack 3.6 detect.c $NHDT-Date: 1544437284 2018/12/10 10:21:24 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.91 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2018. */
/* NetHack may be freely redistributed. See license for details. */
@@ -1308,7 +1308,8 @@ struct obj *sobj; /* scroll--actually fake spellbook--object */
struct obj *otmp;
long save_EDetect_mons;
char save_viz_uyux;
boolean unconstrained, refresh = FALSE, mdetected = FALSE,
boolean unconstrained, refresh = FALSE,
mdetected = FALSE, odetected = FALSE,
/* fake spellbook 'sobj' implies hero has cast the spell;
when book is blessed, casting is skilled or expert level;
if already clairvoyant, non-skilled spell acts like skilled */
@@ -1363,6 +1364,10 @@ struct obj *sobj; /* scroll--actually fake spellbook--object */
if (extended)
otmp->dknown = 1;
map_object(otmp, TRUE);
newglyph = glyph_at(zx, zy);
/* if otmp is underwater, we'll need to redisplay the water */
if (newglyph != oldglyph && covers_objects(zx, zy))
odetected = TRUE;
}
/* if there is a monster here, see or detect it,
possibly as "remembered, unseen monster" */
@@ -1385,7 +1390,7 @@ struct obj *sobj; /* scroll--actually fake spellbook--object */
}
}
if (!level.flags.hero_memory || unconstrained || mdetected) {
if (!level.flags.hero_memory || unconstrained || mdetected || odetected) {
flush_screen(1); /* flush temp screen */
/* the getpos() prompt from browse_map() is only shown when
flags.verbose is set, but make this unconditional so that

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 dig.c $NHDT-Date: 1542765354 2018/11/21 01:55:54 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.115 $ */
/* NetHack 3.6 dig.c $NHDT-Date: 1544442710 2018/12/10 11:51:50 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.116 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Michael Allison, 2012. */
/* NetHack may be freely redistributed. See license for details. */
@@ -81,7 +81,7 @@ boolean waslit, rockit;
lev->horizontal = FALSE;
/* short-circuit vision recalc */
viz_array[y][x] = (dist < 3) ? (IN_SIGHT | COULD_SEE) : COULD_SEE;
lev->typ = (rockit ? STONE : ROOM);
lev->typ = (rockit ? STONE : ROOM); /* flags set via doormask above */
if (dist >= 3)
impossible("mkcavepos called with dist %d", dist);
feel_newsym(x, y);
@@ -129,7 +129,7 @@ register boolean rockit;
}
if (!rockit && levl[u.ux][u.uy].typ == CORR) {
levl[u.ux][u.uy].typ = ROOM;
levl[u.ux][u.uy].typ = ROOM; /* flags for CORR already 0 */
if (waslit)
levl[u.ux][u.uy].waslit = TRUE;
newsym(u.ux, u.uy); /* in case player is invisible */
@@ -361,9 +361,9 @@ dig(VOID_ARGS)
}
if (context.digging.effort > 100) {
register const char *digtxt, *dmgtxt = (const char *) 0;
register struct obj *obj;
register boolean shopedge = *in_rooms(dpx, dpy, SHOPBASE);
const char *digtxt, *dmgtxt = (const char *) 0;
struct obj *obj;
boolean shopedge = *in_rooms(dpx, dpy, SHOPBASE);
if ((obj = sobj_at(STATUE, dpx, dpy)) != 0) {
if (break_statue(obj))
@@ -397,12 +397,12 @@ dig(VOID_ARGS)
}
if (IS_TREE(lev->typ)) {
digtxt = "You cut down the tree.";
lev->typ = ROOM;
lev->typ = ROOM, lev->flags = 0;
if (!rn2(5))
(void) rnd_treefruit_at(dpx, dpy);
} else {
digtxt = "You succeed in cutting away some rock.";
lev->typ = CORR;
lev->typ = CORR, lev->flags = 0;
}
} else if (IS_WALL(lev->typ)) {
if (shopedge) {
@@ -410,12 +410,11 @@ dig(VOID_ARGS)
dmgtxt = "damage";
}
if (level.flags.is_maze_lev) {
lev->typ = ROOM;
lev->typ = ROOM, lev->flags = 0;
} else if (level.flags.is_cavernous_lev && !in_town(dpx, dpy)) {
lev->typ = CORR;
lev->typ = CORR, lev->flags = 0;
} else {
lev->typ = DOOR;
lev->doormask = D_NODOOR;
lev->typ = DOOR, lev->doormask = D_NODOOR;
}
digtxt = "You make an opening in the wall.";
} else if (lev->typ == SDOOR) {
@@ -573,6 +572,7 @@ int ttyp;
} else if (lev->typ == DRAWBRIDGE_DOWN
|| (is_drawbridge_wall(x, y) >= 0)) {
int bx = x, by = y;
/* if under the portcullis, the bridge is adjacent */
(void) find_drawbridge(&bx, &by);
destroy_drawbridge(bx, by);
@@ -853,6 +853,7 @@ coord *cc;
} else {
typ = fillholetyp(dig_x, dig_y, FALSE);
lev->flags = 0;
if (typ != ROOM) {
lev->typ = typ;
liquid_flow(dig_x, dig_y, typ, ttmp,
@@ -935,7 +936,7 @@ coord *cc;
pline_The("grave seems unused. Strange....");
break;
}
levl[dig_x][dig_y].typ = ROOM;
levl[dig_x][dig_y].typ = ROOM, levl[dig_x][dig_y].flags = 0;
del_engr_at(dig_x, dig_y);
newsym(dig_x, dig_y);
return;
@@ -1272,7 +1273,7 @@ register struct monst *mtmp;
newsym(mtmp->mx, mtmp->my);
return FALSE;
} else if (here->typ == SCORR) {
here->typ = CORR;
here->typ = CORR, here->flags = 0;
unblock_point(mtmp->mx, mtmp->my);
newsym(mtmp->mx, mtmp->my);
draft_message(FALSE); /* "You feel a draft." */
@@ -1297,20 +1298,19 @@ register struct monst *mtmp;
if (*in_rooms(mtmp->mx, mtmp->my, SHOPBASE))
add_damage(mtmp->mx, mtmp->my, 0L);
if (level.flags.is_maze_lev) {
here->typ = ROOM;
here->typ = ROOM, here->flags = 0;
} else if (level.flags.is_cavernous_lev
&& !in_town(mtmp->mx, mtmp->my)) {
here->typ = CORR;
here->typ = CORR, here->flags = 0;
} else {
here->typ = DOOR;
here->doormask = D_NODOOR;
here->typ = DOOR, here->doormask = D_NODOOR;
}
} else if (IS_TREE(here->typ)) {
here->typ = ROOM;
here->typ = ROOM, here->flags = 0;
if (pile && pile < 5)
(void) rnd_treefruit_at(mtmp->mx, mtmp->my);
} else {
here->typ = CORR;
here->typ = CORR, here->flags = 0;
if (pile && pile < 5)
(void) mksobj_at((pile == 1) ? BOULDER : ROCK, mtmp->mx, mtmp->my,
TRUE, FALSE);
@@ -1495,7 +1495,7 @@ zap_dig()
shopdoor = TRUE;
}
if (room->typ == SDOOR)
room->typ = DOOR;
room->typ = DOOR; /* doormask set below */
else if (cansee(zx, zy))
pline_The("door is razed!");
watch_dig((struct monst *) 0, zx, zy, TRUE);
@@ -1511,21 +1511,21 @@ zap_dig()
add_damage(zx, zy, SHOP_WALL_COST);
shopwall = TRUE;
}
room->typ = ROOM;
room->typ = ROOM, room->flags = 0;
unblock_point(zx, zy); /* vision */
} else if (!Blind)
pline_The("wall glows then fades.");
break;
} else if (IS_TREE(room->typ)) { /* check trees before stone */
if (!(room->wall_info & W_NONDIGGABLE)) {
room->typ = ROOM;
room->typ = ROOM, room->flags = 0;
unblock_point(zx, zy); /* vision */
} else if (!Blind)
pline_The("tree shudders but is unharmed.");
break;
} else if (room->typ == STONE || room->typ == SCORR) {
if (!(room->wall_info & W_NONDIGGABLE)) {
room->typ = CORR;
room->typ = CORR, room->flags = 0;
unblock_point(zx, zy); /* vision */
} else if (!Blind)
pline_The("rock glows then fades.");
@@ -1541,17 +1541,16 @@ zap_dig()
}
watch_dig((struct monst *) 0, zx, zy, TRUE);
if (level.flags.is_cavernous_lev && !in_town(zx, zy)) {
room->typ = CORR;
room->typ = CORR, room->flags = 0;
} else {
room->typ = DOOR;
room->doormask = D_NODOOR;
room->typ = DOOR, room->doormask = D_NODOOR;
}
digdepth -= 2;
} else if (IS_TREE(room->typ)) {
room->typ = ROOM;
room->typ = ROOM, room->flags = 0;
digdepth -= 2;
} else { /* IS_ROCK but not IS_WALL or SDOOR */
room->typ = CORR;
room->typ = CORR, room->flags = 0;
digdepth--;
}
unblock_point(zx, zy); /* vision */
@@ -1563,8 +1562,10 @@ zap_dig()
if (pitflow && isok(flow_x, flow_y)) {
struct trap *ttmp = t_at(flow_x, flow_y);
if (ttmp && is_pit(ttmp->ttyp)) {
schar filltyp = fillholetyp(ttmp->tx, ttmp->ty, TRUE);
if (filltyp != ROOM)
pit_flow(ttmp, filltyp);
}
@@ -1589,7 +1590,7 @@ char *msg;
int ltyp;
struct rm *room;
const char *foundation_msg =
"The foundation is too hard to dig through from this angle.";
"The foundation is too hard to dig through from this angle.";
if (!cc)
return FALSE;
@@ -1597,7 +1598,7 @@ char *msg;
return FALSE;
*msg = '\0';
room = &levl[cc->x][cc->y];
ltyp = room->typ;
ltyp = room->typ, room->flags = 0;
if (is_pool(cc->x, cc->y) || is_lava(cc->x, cc->y)) {
/* this is handled by the caller after we return FALSE */
@@ -1677,15 +1678,14 @@ pit_flow(trap, filltyp)
struct trap *trap;
schar filltyp;
{
if (trap && (filltyp != ROOM)
&& is_pit(trap->ttyp)) {
if (trap && filltyp != ROOM && is_pit(trap->ttyp)) {
struct trap t;
int idx;
t = *trap;
levl[trap->tx][trap->ty].typ = filltyp;
liquid_flow(trap->tx, trap->ty, filltyp, trap,
(trap->tx == u.ux && trap->ty == u.uy)
levl[t.tx][t.ty].typ = filltyp, levl[t.tx][t.ty].flags = 0;
liquid_flow(t.tx, t.ty, filltyp, trap,
(t.tx == u.ux && t.ty == u.uy)
? "Suddenly %s flows in from the adjacent pit!"
: (char *) 0);
for (idx = 0; idx < 8; ++idx) {

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 do.c $NHDT-Date: 1543972190 2018/12/05 01:09:50 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.176 $ */
/* NetHack 3.6 do.c $NHDT-Date: 1544442710 2018/12/10 11:51:50 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.177 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Derek S. Ray, 2015. */
/* NetHack may be freely redistributed. See license for details. */
@@ -67,7 +67,7 @@ boolean pushing;
levl[rx][ry].drawbridgemask &= ~DB_UNDER; /* clear lava */
levl[rx][ry].drawbridgemask |= DB_FLOOR;
} else
levl[rx][ry].typ = ROOM;
levl[rx][ry].typ = ROOM, levl[rx][ry].flags = 0;
if (ttmp)
(void) delfloortrap(ttmp);
@@ -276,22 +276,29 @@ STATIC_DCL void
polymorph_sink()
{
uchar sym = S_sink;
boolean sinklooted;
if (levl[u.ux][u.uy].typ != SINK)
return;
sinklooted = levl[u.ux][u.uy].looted != 0;
level.flags.nsinks--;
levl[u.ux][u.uy].doormask = 0;
levl[u.ux][u.uy].doormask = 0; /* levl[][].flags */
switch (rn2(4)) {
default:
case 0:
sym = S_fountain;
levl[u.ux][u.uy].typ = FOUNTAIN;
levl[u.ux][u.uy].blessedftn = 0;
if (sinklooted)
SET_FOUNTAIN_LOOTED(u.ux, u.uy);
level.flags.nfountains++;
break;
case 1:
sym = S_throne;
levl[u.ux][u.uy].typ = THRONE;
if (sinklooted)
levl[u.ux][u.uy].looted = T_LOOTED;
break;
case 2:
sym = S_altar;

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 dothrow.c $NHDT-Date: 1543892215 2018/12/04 02:56:55 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.152 $ */
/* NetHack 3.6 dothrow.c $NHDT-Date: 1544401268 2018/12/10 00:21:08 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.153 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2013. */
/* NetHack may be freely redistributed. See license for details. */
@@ -707,6 +707,11 @@ int x, y;
newsym(ox, oy); /* update old position */
vision_recalc(1); /* update for new position */
flush_screen(1);
/* if terrain type changes, levitation or flying might become blocked
or unblocked; might issue message, so do this after map+vision has
been updated for new location instead of right after u_on_newpos() */
if (levl[u.ux][u.uy].typ != levl[ox][oy].typ)
switch_terrain();
if (is_pool(x, y) && !u.uinwater) {
if ((Is_waterlevel(&u.uz) && levl[x][y].typ == WATER)

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 fountain.c $NHDT-Date: 1455402364 2016/02/13 22:26:04 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.56 $ */
/* NetHack 3.6 fountain.c $NHDT-Date: 1544442711 2018/12/10 11:51:51 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.60 $ */
/* Copyright Scott R. Turner, srt@ucla, 10/27/86 */
/* NetHack may be freely redistributed. See license for details. */
@@ -137,7 +137,7 @@ genericptr_t poolcnt;
pline("Water gushes forth from the overflowing fountain!");
/* Put a pool at x, y */
levl[x][y].typ = POOL;
levl[x][y].typ = POOL, levl[x][y].flags = 0;
/* No kelp! */
del_engr_at(x, y);
water_damage_chain(level.objects[x][y], TRUE);
@@ -205,8 +205,7 @@ boolean isyou;
return;
}
/* replace the fountain with ordinary floor */
levl[x][y].typ = ROOM;
levl[x][y].looted = 0;
levl[x][y].typ = ROOM, levl[x][y].flags = 0;
levl[x][y].blessedftn = 0;
if (cansee(x, y))
pline_The("fountain dries up!");
@@ -397,8 +396,7 @@ register struct obj *obj;
exercise(A_WIS, TRUE);
}
update_inventory();
levl[u.ux][u.uy].typ = ROOM;
levl[u.ux][u.uy].looted = 0;
levl[u.ux][u.uy].typ = ROOM, levl[u.ux][u.uy].flags = 0;
newsym(u.ux, u.uy);
level.flags.nfountains--;
if (in_town(u.ux, u.uy))
@@ -511,8 +509,9 @@ int x, y;
if (cansee(x, y) || (x == u.ux && y == u.uy))
pline_The("pipes break! Water spurts out!");
level.flags.nsinks--;
levl[x][y].doormask = 0;
levl[x][y].typ = FOUNTAIN;
levl[x][y].typ = FOUNTAIN, levl[x][y].looted = 0;
levl[x][y].blessedftn = 0;
SET_FOUNTAIN_LOOTED(x, y);
level.flags.nfountains++;
newsym(x, y);
}

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 hack.c $NHDT-Date: 1543972190 2018/12/05 01:09:50 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.200 $ */
/* NetHack 3.6 hack.c $NHDT-Date: 1544401269 2018/12/10 00:21:09 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.201 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Derek S. Ray, 2015. */
/* NetHack may be freely redistributed. See license for details. */
@@ -13,7 +13,6 @@ STATIC_DCL int FDECL(still_chewing, (XCHAR_P, XCHAR_P));
STATIC_DCL void NDECL(dosinkfall);
STATIC_DCL boolean FDECL(findtravelpath, (int));
STATIC_DCL boolean FDECL(trapmove, (int, int, struct trap *));
STATIC_DCL void NDECL(switch_terrain);
STATIC_DCL struct monst *FDECL(monstinroom, (struct permonst *, int));
STATIC_DCL boolean FDECL(doorless_door, (int, int));
STATIC_DCL void FDECL(move_update, (BOOLEAN_P));
@@ -1935,12 +1934,13 @@ invocation_message()
/* moving onto different terrain;
might be going into solid rock, inhibiting levitation or flight,
or coming back out of such, reinstating levitation/flying */
STATIC_OVL void
void
switch_terrain()
{
struct rm *lev = &levl[u.ux][u.uy];
boolean blocklev = (IS_ROCK(lev->typ) || closed_door(u.ux, u.uy)
|| (Is_waterlevel(&u.uz) && lev->typ == WATER));
|| (Is_waterlevel(&u.uz) && lev->typ == WATER)),
was_levitating = !!Levitation, was_flying = !!Flying;
if (blocklev) {
/* called from spoteffects(), stop levitating but skip float_down() */
@@ -1968,6 +1968,8 @@ switch_terrain()
if (Flying)
You("start flying.");
}
if ((!Levitation ^ was_levitating) || (!Flying ^ was_flying))
context.botl = TRUE; /* update Lev/Fly status condition */
}
/* extracted from spoteffects; called by spoteffects to check for entering or
@@ -2828,12 +2830,13 @@ const char *msg_override;
else if (!nomovemsg)
nomovemsg = You_can_move_again;
if (*nomovemsg)
pline1(nomovemsg);
pline("%s", nomovemsg);
nomovemsg = 0;
u.usleep = 0;
multi_reason = NULL;
if (afternmv) {
int NDECL((*f)) = afternmv;
/* clear afternmv before calling it (to override the
encumbrance hack for levitation--see weight_cap()) */
afternmv = (int NDECL((*))) 0;

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 lock.c $NHDT-Date: 1521499715 2018/03/19 22:48:35 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.80 $ */
/* NetHack 3.6 lock.c $NHDT-Date: 1544442712 2018/12/10 11:51:52 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.82 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2011. */
/* NetHack may be freely redistributed. See license for details. */
@@ -950,7 +950,7 @@ int x, y;
return FALSE;
}
block_point(x, y);
door->typ = SDOOR;
door->typ = SDOOR, door->doormask = D_NODOOR;
if (vis)
pline_The("doorway vanishes!");
newsym(x, y);

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 monmove.c $NHDT-Date: 1517877380 2018/02/06 00:36:20 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.96 $ */
/* NetHack 3.6 monmove.c $NHDT-Date: 1544442712 2018/12/10 11:51:52 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.109 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Michael Allison, 2006. */
/* NetHack may be freely redistributed. See license for details. */
@@ -1474,6 +1474,7 @@ dissolve_bars(x, y)
register int x, y;
{
levl[x][y].typ = (Is_special(&u.uz) || *in_rooms(x, y, 0)) ? ROOM : CORR;
levl[x][y].flags = 0;
newsym(x, y);
}

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 music.c $NHDT-Date: 1542765361 2018/11/21 01:56:01 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.56 $ */
/* NetHack 3.6 music.c $NHDT-Date: 1544442713 2018/12/10 11:51:53 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.57 $ */
/* Copyright (c) 1989 by Jean-Christophe Collet */
/* NetHack may be freely redistributed. See license for details. */
@@ -320,7 +320,7 @@ int force;
*/
filltype = fillholetyp(x, y, FALSE);
if (filltype != ROOM) {
levl[x][y].typ = filltype;
levl[x][y].typ = filltype; /* flags set via doormask */
liquid_flow(x, y, filltype, chasm, (char *) 0);
}

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 options.c $NHDT-Date: 1544174413 2018/12/07 09:20:13 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.339 $ */
/* NetHack 3.6 options.c $NHDT-Date: 1544396581 2018/12/09 23:03:01 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.340 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Michael Allison, 2008. */
/* NetHack may be freely redistributed. See license for details. */
@@ -20,7 +20,6 @@ NEARDATA struct instance_flags iflags; /* provide linkage */
#endif
#define BACKWARD_COMPAT
#define WINTYPELEN 16
#ifdef DEFAULT_WC_TILED_MAP
#define PREFER_TILED TRUE
@@ -873,16 +872,23 @@ initoptions_finish()
* 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 (iflags.hilite_delta && !wc2_supported("statushilites")) {
raw_printf("Status highlighting not supported for %s interface.",
windowprocs.name);
iflags.hilite_delta = 0;
if (!WINDOWPORT("safe-startup")) {
if (iflags.hilite_delta && !wc2_supported("statushilites")) {
raw_printf("Status highlighting not supported for %s interface.",
windowprocs.name);
iflags.hilite_delta = 0;
}
}
#endif
return;
}
/* copy up to maxlen-1 characters; 'dest' must be able to hold maxlen;
treat comma as alternate end of 'src' */
STATIC_OVL void
nmcpy(dest, src, maxlen)
char *dest;
@@ -896,7 +902,7 @@ int maxlen;
break; /*exit on \0 terminator*/
*dest++ = *src++;
}
*dest = 0;
*dest = '\0';
}
/*
@@ -2583,7 +2589,7 @@ boolean tinitial, tfrom_file;
if (duplicate)
complain_about_duplicate(opts, 1);
op = string_for_opt(opts, negated);
op = string_for_opt(opts, negated || !initial);
if (negated) {
if (op) {
bad_negation("fruit", TRUE);
@@ -2594,6 +2600,8 @@ boolean tinitial, tfrom_file;
}
if (!op)
return FALSE;
/* 3.6.2: strip leading and trailing spaces, condense internal ones */
mungspaces(op);
if (!initial) {
struct fruit *f;
int fnum = 0;
@@ -3514,10 +3522,14 @@ boolean tinitial, tfrom_file;
bad_negation(fullname, FALSE);
return FALSE;
} else if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0) {
char buf[WINTYPELEN];
if (!iflags.windowtype_deferred) {
char buf[WINTYPELEN];
nmcpy(buf, op, WINTYPELEN);
choose_windows(buf);
nmcpy(buf, op, WINTYPELEN);
choose_windows(buf);
} else {
nmcpy(chosen_windowtype, op, WINTYPELEN);
}
} else
return FALSE;
return retval;
@@ -4465,7 +4477,7 @@ doset() /* changing options via menu by Per Liboriussen */
/* boolean option */
Sprintf(buf, "%s%s", *boolopt[opt_indx].addr ? "!" : "",
boolopt[opt_indx].name);
parseoptions(buf, setinitial, fromfile);
(void) parseoptions(buf, setinitial, fromfile);
if (wc_supported(boolopt[opt_indx].name)
|| wc2_supported(boolopt[opt_indx].name))
preference_update(boolopt[opt_indx].name);
@@ -4481,7 +4493,7 @@ doset() /* changing options via menu by Per Liboriussen */
continue;
Sprintf(buf, "%s:%s", compopt[opt_indx].name, buf2);
/* pass the buck */
parseoptions(buf, setinitial, fromfile);
(void) parseoptions(buf, setinitial, fromfile);
}
if (wc_supported(compopt[opt_indx].name)
|| wc2_supported(compopt[opt_indx].name))
@@ -4639,7 +4651,8 @@ boolean setinitial, setfromfile;
destroy_nhwindow(tmpwin);
} else if (!strcmp("pickup_types", optname)) {
/* parseoptions will prompt for the list of types */
parseoptions(strcpy(buf, "pickup_types"), setinitial, setfromfile);
(void) parseoptions(strcpy(buf, "pickup_types"),
setinitial, setfromfile);
} else if (!strcmp("disclose", optname)) {
/* order of disclose_names[] must correspond to
disclosure_options in decl.c */

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 sit.c $NHDT-Date: 1458341129 2016/03/18 22:45:29 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.53 $ */
/* NetHack 3.6 sit.c $NHDT-Date: 1544442714 2018/12/10 11:51:54 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.59 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2012. */
/* NetHack may be freely redistributed. See license for details. */
@@ -281,7 +281,7 @@ dosit()
if (!rn2(3) && IS_THRONE(levl[u.ux][u.uy].typ)) {
/* may have teleported */
levl[u.ux][u.uy].typ = ROOM;
levl[u.ux][u.uy].typ = ROOM, levl[u.ux][u.uy].flags = 0;
pline_The("throne vanishes in a puff of logic.");
newsym(u.ux, u.uy);
}

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 teleport.c $NHDT-Date: 1523306912 2018/04/09 20:48:32 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.73 $ */
/* NetHack 3.6 teleport.c $NHDT-Date: 1544401270 2018/12/10 00:21:10 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.81 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2011. */
/* NetHack may be freely redistributed. See license for details. */
@@ -340,6 +340,11 @@ boolean allow_drag;
vision_full_recalc = 1;
nomul(0);
vision_recalc(0); /* vision before effects */
/* if terrain type changes, levitation or flying might become blocked
or unblocked; might issue message, so do this after map+vision has
been updated for new location instead of right after u_on_newpos() */
if (levl[u.ux][u.uy].typ != levl[u.ux0][u.uy0].typ)
switch_terrain();
if (telescroll) {
/* when teleporting by scroll, we need to handle discovery
now before getting feedback about any objects at our

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 zap.c $NHDT-Date: 1544230271 2018/12/08 00:51:11 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.301 $ */
/* NetHack 3.6 zap.c $NHDT-Date: 1544442714 2018/12/10 11:51:54 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.302 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2013. */
/* NetHack may be freely redistributed. See license for details. */
@@ -4374,7 +4374,7 @@ short exploding_wand_typ;
msgtxt = "Some water evaporates.";
} else {
rangemod -= 3;
lev->typ = ROOM;
lev->typ = ROOM, lev->flags = 0;
t = maketrap(x, y, PIT);
if (t)
t->tseen = 1;
@@ -4413,9 +4413,9 @@ short exploding_wand_typ;
lev->drawbridgemask &= ~DB_UNDER; /* clear lava */
lev->drawbridgemask |= (lava ? DB_FLOOR : DB_ICE);
} else {
if (!lava)
lev->icedpool = (lev->typ == POOL) ? ICED_POOL
: ICED_MOAT;
lev->icedpool = lava ? 0
: (lev->typ == POOL) ? ICED_POOL
: ICED_MOAT;
lev->typ = lava ? ROOM : ICE;
}
bury_objs(x, y);
@@ -4490,15 +4490,14 @@ short exploding_wand_typ;
Norep("The %s melt.", defsyms[S_bars].explanation);
if (*in_rooms(x, y, SHOPBASE)) {
/* in case we ever have a shop bounded by bars */
lev->typ = ROOM;
lev->typ = ROOM, lev->flags = 0;
if (see_it)
newsym(x, y);
add_damage(x, y, (type >= 0) ? SHOP_BARS_COST : 0L);
if (type >= 0)
*shopdamage = TRUE;
} else {
lev->typ = DOOR;
lev->doormask = D_NODOOR;
lev->typ = DOOR, lev->doormask = D_NODOOR;
if (see_it)
newsym(x, y);
}

View File

@@ -3,11 +3,7 @@
/*-Copyright (c) Derek S. Ray, 2015. */
/* NetHack may be freely redistributed. See license for details. */
/* main.c - MSDOS, OS/2, ST, Amiga, and Windows NetHack */
#ifdef WIN32
#include "win32api.h" /* for GetModuleFileName */
#endif
/* main.c - MSDOS, OS/2, ST, Amiga NetHack */
#include "hack.h"
#include "dlb.h"
@@ -47,29 +43,12 @@ void NDECL(preserve_icon);
STATIC_DCL void FDECL(process_options, (int argc, char **argv));
STATIC_DCL void NDECL(nhusage);
#if defined(MICRO) || defined(WIN32) || defined(OS2)
#if defined(MICRO) || defined(OS2)
extern void FDECL(nethack_exit, (int));
#else
#define nethack_exit exit
#endif
#ifdef WIN32
extern boolean getreturn_enabled; /* from sys/share/pcsys.c */
extern int redirect_stdout; /* from sys/share/pcsys.c */
extern int GUILaunched;
char *NDECL(exename);
char default_window_sys[] = "mswin";
#ifndef WIN32CON
HANDLE hStdOut;
boolean NDECL(fakeconsole);
void NDECL(freefakeconsole);
#endif
#endif
#if defined(MSWIN_GRAPHICS)
extern void NDECL(mswin_destroy_reg);
#endif
#ifdef EXEPATH
STATIC_DCL char *FDECL(exepath, (char *));
#endif
@@ -78,7 +57,7 @@ int FDECL(main, (int, char **));
extern boolean FDECL(pcmain, (int, char **));
#if defined(__BORLANDC__) && !defined(_WIN32)
#if defined(__BORLANDC__)
void NDECL(startup);
unsigned _stklen = STKSIZ;
#endif
@@ -98,21 +77,8 @@ char *argv[];
{
boolean resuming;
nethack_enter(argc, argv);
sys_early_init();
#if defined(WIN32) && defined(TTY_GRAPHICS)
Strcpy(default_window_sys, "tty");
#else
#if defined(CURSES_GRAPHICS)
Strcpy(default_window_sys, "curses");
#endif
#endif
resuming = pcmain(argc, argv);
#ifdef LAN_FEATURES
init_lan_features();
#endif
moveloop(resuming);
nethack_exit(EXIT_SUCCESS);
/*NOTREACHED*/
@@ -126,14 +92,10 @@ char *argv[];
{
register int fd;
register char *dir;
#if defined(WIN32) || defined(MSDOS)
#if defined(MSDOS)
char *envp = NULL;
char *sptr = NULL;
#endif
#if defined(WIN32)
char fnamebuf[BUFSZ], encodedfnamebuf[BUFSZ];
boolean save_getreturn_status = getreturn_enabled;
#endif
#ifdef NOCWD_ASSUMPTIONS
char failbuf[BUFSZ];
#endif
@@ -162,7 +124,7 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/
# endif
#endif
#if defined(__BORLANDC__) && !defined(_WIN32)
#if defined(__BORLANDC__)
startup();
#endif
@@ -175,15 +137,7 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/
#endif
hname = "NetHack"; /* used for syntax messages */
#ifndef WIN32
choose_windows(DEFAULT_WINDOW_SYS);
#else
choose_windows(default_window_sys);
if (argc >= 1
&& !strcmpi(default_window_sys, "mswin")
&& strstri(argv[0], "nethackw.exe"))
iflags.windowtype_locked = TRUE;
#endif
#if !defined(AMIGA) && !defined(GNUDOS)
/* Save current directory and make sure it gets restored when
@@ -243,7 +197,7 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/
for (prefcnt = 1; prefcnt < PREFIX_COUNT; prefcnt++)
fqn_prefix[prefcnt] = fqn_prefix[0];
#if defined(WIN32) || defined(MSDOS)
#if defined(MSDOS)
/* sysconf should be searched for in this location */
envp = nh_getenv("COMMONPROGRAMFILES");
if (envp) {
@@ -317,14 +271,6 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/
chdirx(HACKDIR, 1);
#endif
ami_wininit_data();
#endif
#ifdef WIN32
save_getreturn_status = getreturn_enabled;
#ifdef TTY_GRAPHICS
raw_clear_screen();
#endif
getreturn_enabled = TRUE;
check_recordfile((char *) 0);
#endif
initoptions();
@@ -355,13 +301,6 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/
argv++;
}
#ifdef WIN32
if (argcheck(argc, argv, ARG_WINDOWS) == 1) {
argc--;
argv++;
}
#endif
if (argc > 1 && !strncmp(argv[1], "-d", 2) && argv[1][2] != 'e') {
/* avoid matching "-dec" for DECgraphics; since the man page
* says -d directory, hope nobody's using -desomething_else
@@ -381,36 +320,11 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/
Strcpy(hackdir, dir);
}
if (argc > 1) {
#if defined(WIN32) && !defined(WIN32CON)
int sfd = 0;
boolean tmpconsole = FALSE;
hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
#endif
/*
* Now we know the directory containing 'record' and
* may do a prscore().
*/
if (!strncmp(argv[1], "-s", 2)) {
#if defined(WIN32) && !defined(WIN32CON)
#if 0
if (!hStdOut) {
tmpconsole = fakeconsole();
}
#endif
/*
* Check to see if we're redirecting to a file.
*/
sfd = (int) _fileno(stdout);
redirect_stdout = (sfd >= 0) ? !isatty(sfd) : 0;
if (!redirect_stdout && !hStdOut) {
raw_printf(
"-s is not supported for the Graphical Interface\n");
nethack_exit(EXIT_SUCCESS);
}
#endif
#if defined(CHDIR) && !defined(NOCWD_ASSUMPTIONS)
chdirx(hackdir, 0);
#endif
@@ -418,47 +332,16 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/
initoptions();
#endif
prscore(argc, argv);
#if defined(WIN32) && !defined(WIN32CON)
if (tmpconsole) {
getreturn("to exit");
freefakeconsole();
tmpconsole = FALSE;
}
#endif
nethack_exit(EXIT_SUCCESS);
}
#ifdef MSWIN_GRAPHICS
if (!strncmpi(argv[1], "-clearreg", 6)) { /* clear registry */
mswin_destroy_reg();
nethack_exit(EXIT_SUCCESS);
}
#endif
/* Don't initialize the window system just to print usage */
if (!strncmp(argv[1], "-?", 2) || !strncmp(argv[1], "/?", 2)) {
#if 0
if (!hStdOut) {
GUILaunched = 0;
tmpconsole = fakeconsole();
}
#endif
nhusage();
#if defined(WIN32) && !defined(WIN32CON)
if (tmpconsole) {
getreturn("to exit");
freefakeconsole();
tmpconsole = FALSE;
}
#endif
nethack_exit(EXIT_SUCCESS);
}
}
}
#ifdef WIN32
getreturn_enabled = save_getreturn_status;
#endif
/*
* It seems you really want to play.
*/
@@ -472,11 +355,7 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/
"\"%s\".%s",
copyright_banner_line(1), copyright_banner_line(2),
copyright_banner_line(3), copyright_banner_line(4), DLBFILE,
#ifdef WIN32
"\nAre you perhaps trying to run NetHack within a zip utility?");
#else
"");
#endif
error("dlb_init failure.");
}
@@ -490,41 +369,22 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/
chdirx(hackdir, 1);
#endif
#if defined(MSDOS) || defined(WIN32)
#if defined(MSDOS)
/* In 3.6.0, several ports process options before they init
* the window port. This allows settings that impact window
* ports to be specified or read from the sys or user config files.
*/
process_options(argc, argv);
#ifdef WIN32
/*
if (WINDOWPORT("mswin"))
NHWinMainInit();
else
*/
#ifdef TTY_GRAPHICS
if (WINDOWPORT("tty")) {
iflags.use_background_glyph = FALSE;
nttty_open(1);
} else {
iflags.use_background_glyph = TRUE;
}
#endif /* TTY_GRAPHICS */
#endif /* WIN32 */
#endif /* MSDOS || WIN32 */
#endif /* MSDOS */
#if defined(MSDOS) || defined(WIN32)
#if defined(MSDOS)
init_nhwindows(&argc, argv);
#else
init_nhwindows(&argc, argv);
process_options(argc, argv);
#endif
#if defined(WIN32) && defined(TTY_GRAPHICS)
toggle_mouse_support(); /* must come after process_options */
#endif
#ifdef MFLOPPY
set_lock_and_bones();
#ifndef AMIGA
@@ -561,19 +421,8 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/
* overwritten without confirmation when a user starts up
* another game with the same player name.
*/
#if defined(WIN32)
/* Obtain the name of the logged on user and incorporate
* it into the name. */
Sprintf(fnamebuf, "%s-%s", get_username(0), plname);
(void) fname_encode(
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_-.", '%',
fnamebuf, encodedfnamebuf, BUFSZ);
Sprintf(lock, "%s", encodedfnamebuf);
/* regularize(lock); */ /* we encode now, rather than substitute */
#else
Strcpy(lock, plname);
regularize(lock);
#endif
getlock();
#else /* What follows is !PC_LOCKING */
#ifdef AMIGA /* We'll put the bones & levels in the user specified directory \
@@ -599,11 +448,7 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/
if (fd < 0) {
raw_print("Cannot create lock file");
} else {
#ifdef WIN32
hackpid = GetCurrentProcessId();
#else
hackpid = 1;
#endif
write(fd, (genericptr_t) &hackpid, sizeof(hackpid));
nhclose(fd);
}
@@ -618,10 +463,6 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/
vision_init();
display_gamewindows();
#ifdef WIN32
getreturn_enabled = TRUE;
#endif
/*
* First, try to find and restore a save file for specified character.
* We'll return here if new game player_selection() renames the hero.
@@ -799,18 +640,6 @@ char *argv[];
case 'l':
bigscreen = -1;
break;
#endif
#ifdef WIN32
case 'w': /* windowtype */
#ifdef TTY_GRAPHICS
if (strncmpi(&argv[0][2], "tty", 3)) {
nttty_open(1);
}
#endif
config_error_init(FALSE, "command line", FALSE);
choose_windows(&argv[0][2]);
config_error_done();
break;
#endif
case '@':
flags.randomall = 1;
@@ -904,14 +733,14 @@ boolean wr;
#endif /* CHDIR */
#ifdef PORT_HELP
#if defined(MSDOS) || defined(WIN32)
#if defined(MSDOS)
void
port_help()
{
/* display port specific help file */
display_file(PORT_HELP, 1);
}
#endif /* MSDOS || WIN32 */
#endif /* MSDOS */
#endif /* PORT_HELP */
/* validate wizard mode if player has requested access to it */
@@ -930,71 +759,6 @@ authorize_wizard_mode()
#define PATH_SEPARATOR '\\'
#endif
#if defined(WIN32) && !defined(WIN32CON)
static char exenamebuf[PATHLEN];
extern HANDLE hConIn;
extern HANDLE hConOut;
boolean has_fakeconsole;
char *
exename()
{
int bsize = PATHLEN;
char *tmp = exenamebuf, *tmp2;
#ifdef UNICODE
{
TCHAR wbuf[PATHLEN * 4];
GetModuleFileName((HANDLE) 0, wbuf, PATHLEN * 4);
WideCharToMultiByte(CP_ACP, 0, wbuf, -1, tmp, bsize, NULL, NULL);
}
#else
*(tmp + GetModuleFileName((HANDLE) 0, tmp, bsize)) = '\0';
#endif
tmp2 = strrchr(tmp, PATH_SEPARATOR);
if (tmp2)
*tmp2 = '\0';
tmp2++;
return tmp2;
}
boolean
fakeconsole(void)
{
if (!hStdOut) {
HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
HANDLE hStdIn = GetStdHandle(STD_INPUT_HANDLE);
if (!hStdOut && !hStdIn) {
/* Bool rval; */
AllocConsole();
AttachConsole(GetCurrentProcessId());
/* rval = SetStdHandle(STD_OUTPUT_HANDLE, hWrite); */
freopen("CON", "w", stdout);
freopen("CON", "r", stdin);
}
has_fakeconsole = TRUE;
}
/* Obtain handles for the standard Console I/O devices */
hConIn = GetStdHandle(STD_INPUT_HANDLE);
hConOut = GetStdHandle(STD_OUTPUT_HANDLE);
#if 0
if (!SetConsoleCtrlHandler((PHANDLER_ROUTINE) CtrlHandler, TRUE)) {
/* Unable to set control handler */
cmode = 0; /* just to have a statement to break on for debugger */
}
#endif
return has_fakeconsole;
}
void freefakeconsole()
{
if (has_fakeconsole) {
FreeConsole();
}
}
#endif
#define EXEPATHBUFSZ 256
char exepathbuf[EXEPATHBUFSZ];
@@ -1009,19 +773,7 @@ char *str;
return (char *) 0;
bsize = EXEPATHBUFSZ;
tmp = exepathbuf;
#ifndef WIN32
Strcpy(tmp, str);
#else
#ifdef UNICODE
{
TCHAR wbuf[BUFSZ];
GetModuleFileName((HANDLE) 0, wbuf, BUFSZ);
WideCharToMultiByte(CP_ACP, 0, wbuf, -1, tmp, bsize, NULL, NULL);
}
#else
*(tmp + GetModuleFileName((HANDLE) 0, tmp, bsize)) = '\0';
#endif
#endif
tmp2 = strrchr(tmp, PATH_SEPARATOR);
if (tmp2)
*tmp2 = '\0';

View File

@@ -391,19 +391,11 @@ char *name;
return;
}
#ifdef WIN32
boolean getreturn_enabled;
int redirect_stdout;
#endif
#ifndef WIN32
void
getreturn(str)
const char *str;
{
#ifdef WIN32
if (!getreturn_enabled)
return;
#endif
#ifdef TOS
msmsg("Hit <Return> %s.", str);
#else
@@ -414,7 +406,6 @@ const char *str;
return;
}
#ifndef WIN32
void msmsg
VA_DECL(const char *, fmt)
{
@@ -492,7 +483,7 @@ const char *name, *mode;
return (FILE *) 0;
}
#if defined(MICRO) || defined(WIN32) || defined(OS2)
#if defined(MICRO) || defined(OS2)
void
nethack_exit(code)
int code;
@@ -551,4 +542,4 @@ msexit()
wait_synch();
return;
}
#endif /* MICRO || WIN32 || OS2 */
#endif /* MICRO || OS2 */

View File

@@ -215,7 +215,7 @@ VOBJ06 = $(O)dothrow.o $(O)drawing.o $(O)dungeon.o $(O)eat.o
VOBJ07 = $(O)end.o $(O)engrave.o $(O)exper.o $(O)explode.o
VOBJ08 = $(O)extralev.o $(O)files.o $(O)fountain.o $(O)hack.o
VOBJ09 = $(O)hacklib.o $(O)invent.o $(O)light.o $(O)lock.o
VOBJ10 = $(O)mail.o $(O)pcmain.o $(O)makemon.o $(O)mapglyph.o $(O)mcastu.o
VOBJ10 = $(O)mail.o $(O)makemon.o $(O)mapglyph.o $(O)mcastu.o
VOBJ11 = $(O)mhitm.o $(O)mhitu.o $(O)minion.o $(O)mklev.o
VOBJ12 = $(O)mkmap.o $(O)mkmaze.o $(O)mkobj.o $(O)mkroom.o
VOBJ13 = $(O)mon.o $(O)mondata.o $(O)monmove.o $(O)monst.o
@@ -233,7 +233,7 @@ VOBJ24 = $(O)track.o $(O)trap.o $(O)u_init.o $(O)uhitm.o
VOBJ25 = $(O)vault.o $(O)vis_tab.o $(O)vision.o $(O)weapon.o
VOBJ26 = $(O)were.o $(O)wield.o $(O)windows.o $(O)wizard.o
VOBJ27 = $(O)worm.o $(O)worn.o $(O)write.o $(O)zap.o
VOBJ28 = $(O)win10.o
VOBJ28 = $(O)win10.o $(O)safeproc.o $(O)windmain.o
DLBOBJ = $(O)dlb.o
@@ -535,7 +535,7 @@ INCLDIR= /I..\include /I..\sys\winnt
# Util builds
#==========================================
cflagsBuild = $(cflags) $(INCLDIR) $(WINPFLAG) $(DLBFLG)
cflagsBuild = $(cflags) $(INCLDIR) $(WINPFLAG) $(DLBFLG) -DSAFEPROCS
lflagsBuild = $(lflags) $(conlibs) $(MACHINE)
#==========================================
@@ -1503,7 +1503,6 @@ $(O)\curswins.c: $(WCURSES)\curswins.c $(WCURSES)\curswins.h $(INCL)\wincurs.h
# * $(CFLAGS) replaced with $(cflagsBuild)
# * $(CC) replaced with @$(CC)
# * targets prefixed with $(O)
# * the single win32api.h reference uncommented
# but otherwise untouched.
# That means that there is some irrelevant stuff
# in here, but maintenance should be easier.
@@ -1511,8 +1510,7 @@ $(O)\curswins.c: $(WCURSES)\curswins.c $(WCURSES)\curswins.h $(INCL)\wincurs.h
$(O)tos.o: ..\sys\atari\tos.c $(HACK_H) $(INCL)\tcap.h
@$(CC) $(cflagsBuild) -Fo$@ ..\sys\atari\tos.c
$(O)pcmain.o: ..\sys\share\pcmain.c $(HACK_H) $(INCL)\dlb.h \
$(MSWSYS)\win32api.h
$(O)pcmain.o: ..\sys\share\pcmain.c $(HACK_H) $(INCL)\dlb.h
@$(CC) $(cflagsBuild) -Fo$@ ..\sys\share\pcmain.c
$(O)pcsys.o: ..\sys\share\pcsys.c $(HACK_H)
@$(CC) $(cflagsBuild) -Fo$@ ..\sys\share\pcsys.c

View File

@@ -108,16 +108,16 @@ OPTIONS=suppress_alert:3.3.1
OPTIONS=map_mode:tiles,scroll_margin:10
# Message window settings
OPTIONS=font_message:Arial,font_size_message:9,align_message:top
OPTIONS=font_message:Arial,font_size_message:14,align_message:top
# Menu settings
OPTIONS=font_menu:Arial,font_size_menu:9
OPTIONS=font_menu:Arial,font_size_menu:14
# Text settings
OPTIONS=font_text:Courier New,font_size_text:9
OPTIONS=font_text:Courier New,font_size_text:14
# Status window settings
OPTIONS=font_status:Courier New,font_size_status:9
OPTIONS=font_status:Courier New,font_size_status:14
# Other
OPTIONS=hilite_pet,!toptenwin
@@ -136,7 +136,7 @@ OPTIONS=hilite_pet,!toptenwin
# "Nethack mode" colors
OPTIONS=windowcolors:status white/#000000 message white/#000000 text white/#000000 menu white/#000000 menutext white/#000000
OPTIONS=vary_msgcount:1
OPTIONS=vary_msgcount:4
# *** LOCATIONS ***
# IMPORTANT: If you change any of these locations, the directories they

View File

@@ -96,13 +96,11 @@ clear_screen()
return;
}
#ifdef TTY_GRAPHICS
void
backsp()
{
return;
}
#endif
int
has_color(int color)

724
sys/winnt/windmain.c Normal file
View File

@@ -0,0 +1,724 @@
/* NetHack 3.6 windmain.c $NHDT-Date: 1543465755 2018/11/29 04:29:15 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.101 $ */
/* Copyright (c) Derek S. Ray, 2015. */
/* NetHack may be freely redistributed. See license for details. */
/* main.c - Windows */
#include "win32api.h" /* for GetModuleFileName */
#include "hack.h"
#include "dlb.h"
#include <ctype.h>
#include <sys\stat.h>
#if !defined(SAFEPROCS)
#error You must #define SAFEPROCS to build windmain.c
#endif
#define E extern
static void FDECL(process_options, (int argc, char **argv));
static void NDECL(nhusage);
static char *FDECL(exepath, (char *));
char *NDECL(exename);
boolean NDECL(fakeconsole);
void NDECL(freefakeconsole);
E void FDECL(nethack_exit, (int));
E char chosen_windowtype[WINTYPELEN]; /* flag.h */
#if defined(MSWIN_GRAPHICS)
E void NDECL(mswin_destroy_reg);
#endif
#undef E
int NDECL(windows_nhgetch);
void NDECL(windows_nhbell);
int FDECL(windows_nh_poskey, (int *, int *, int *));
void FDECL(windows_raw_print, (const char *));
char FDECL(windows_yn_function, (const char *, const char *, CHAR_P));
void FDECL(windows_getlin, (const char *, char *));
extern int NDECL(windows_console_custom_nhgetch);
char orgdir[PATHLEN];
char *dir;
boolean getreturn_enabled;
extern int redirect_stdout; /* from sys/share/pcsys.c */
extern int GUILaunched;
HANDLE hStdOut;
#if defined(MSWIN_GRAPHICS)
char default_window_sys[] = "mswin";
#endif
/*
* __MINGW32__ Note
* If the graphics version is built, we don't need a main; it is skipped
* to help MinGW decide which entry point to choose. If both main and
* WinMain exist, the resulting executable won't work correctly.
*/
int
#ifndef __MINGW32__
main(argc, argv)
#else
mingw_main(argc, argv)
#endif
int argc;
char *argv[];
{
boolean resuming = FALSE; /* assume new game */
int fd;
char *windowtype = NULL;
char *envp = NULL;
char *sptr = NULL;
char fnamebuf[BUFSZ], encodedfnamebuf[BUFSZ];
char failbuf[BUFSZ];
/*
* Get a set of valid safe windowport function
* pointers during early startup initialization.
*/
if (!WINDOWPORT("safe-startup"))
windowprocs = *get_safe_procs(1);
if (!GUILaunched)
windowprocs.win_nhgetch = windows_console_custom_nhgetch;
sys_early_init();
#ifdef _MSC_VER
# ifdef DEBUG
/* set these appropriately for VS debugging */
_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_DEBUG);
_CrtSetReportMode(_CRT_ERROR,
_CRTDBG_MODE_DEBUG); /* | _CRTDBG_MODE_FILE);*/
_CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_DEBUG);
/*| _CRTDBG_MODE_FILE | _CRTDBG_MODE_WNDW);*/
/* use STDERR by default
_CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR);
_CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/
/* Heap Debugging
_CrtSetDbgFlag( _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG)
| _CRTDBG_ALLOC_MEM_DF
| _CRTDBG_CHECK_ALWAYS_DF
| _CRTDBG_CHECK_CRT_DF
| _CRTDBG_DELAY_FREE_MEM_DF
| _CRTDBG_LEAK_CHECK_DF);
_CrtSetBreakAlloc(1423);
*/
# endif
#endif
hname = "NetHack"; /* used for syntax messages */
/* Save current directory and make sure it gets restored when
* the game is exited.
*/
if (getcwd(orgdir, sizeof orgdir) == (char *) 0)
error("NetHack: current directory path too long");
dir = nh_getenv("NETHACKDIR");
if (dir == (char *) 0)
dir = nh_getenv("HACKDIR");
if (dir == (char *) 0)
dir = exepath(argv[0]);
#ifdef _MSC_VER
if (IsDebuggerPresent()) {
static char exepath[_MAX_PATH];
/* check if we're running under the debugger so we can get to the right folder anyway */
if (dir != (char *)0) {
char *top = (char *)0;
if (strlen(dir) < (_MAX_PATH - 1))
strcpy(exepath, dir);
top = strstr(exepath, "\\build\\.\\Debug");
if (!top) top = strstr(exepath, "\\build\\.\\Release");
if (top) {
*top = '\0';
if (strlen(exepath) < (_MAX_PATH - (strlen("\\binary\\") + 1))) {
Strcat(exepath, "\\binary\\");
if (strlen(exepath) < (PATHLEN - 1)) {
dir = exepath;
}
}
}
}
}
#endif
if (dir != (char *)0) {
int prefcnt;
int fd;
boolean have_syscf = FALSE;
(void) strncpy(hackdir, dir, PATHLEN - 1);
hackdir[PATHLEN - 1] = '\0';
fqn_prefix[0] = (char *) alloc(strlen(hackdir) + 2);
Strcpy(fqn_prefix[0], hackdir);
append_slash(fqn_prefix[0]);
for (prefcnt = 1; prefcnt < PREFIX_COUNT; prefcnt++)
fqn_prefix[prefcnt] = fqn_prefix[0];
/* sysconf should be searched for in this location */
envp = nh_getenv("COMMONPROGRAMFILES");
if (envp) {
if ((sptr = index(envp, ';')) != 0)
*sptr = '\0';
if (strlen(envp) > 0) {
fqn_prefix[SYSCONFPREFIX] =
(char *) alloc(strlen(envp) + 10);
Strcpy(fqn_prefix[SYSCONFPREFIX], envp);
append_slash(fqn_prefix[SYSCONFPREFIX]);
Strcat(fqn_prefix[SYSCONFPREFIX], "NetHack\\");
}
}
/* okay so we have the overriding and definitive locaton
for sysconf, but only in the event that there is not a
sysconf file there (for whatever reason), check a secondary
location rather than abort. */
/* Is there a SYSCF_FILE there? */
fd = open(fqname(SYSCF_FILE, SYSCONFPREFIX, 0), O_RDONLY);
if (fd >= 0) {
/* readable */
close(fd);
have_syscf = TRUE;
}
if (!have_syscf) {
/* No SYSCF_FILE where there should be one, and
without an installer, a user may not be able
to place one there. So, let's try somewhere else... */
fqn_prefix[SYSCONFPREFIX] = fqn_prefix[0];
/* Is there a SYSCF_FILE there? */
fd = open(fqname(SYSCF_FILE, SYSCONFPREFIX, 0), O_RDONLY);
if (fd >= 0) {
/* readable */
close(fd);
have_syscf = TRUE;
}
}
/* user's home directory should default to this - unless
* overridden */
envp = nh_getenv("USERPROFILE");
if (envp) {
if ((sptr = index(envp, ';')) != 0)
*sptr = '\0';
if (strlen(envp) > 0) {
fqn_prefix[CONFIGPREFIX] =
(char *) alloc(strlen(envp) + 2);
Strcpy(fqn_prefix[CONFIGPREFIX], envp);
append_slash(fqn_prefix[CONFIGPREFIX]);
}
}
}
if (GUILaunched || IsDebuggerPresent()) {
getreturn_enabled = TRUE;
}
check_recordfile((char *) 0);
iflags.windowtype_deferred = TRUE;
initoptions();
if (!validate_prefix_locations(failbuf)) {
raw_printf("Some invalid directory locations were specified:\n\t%s\n",
failbuf);
nethack_exit(EXIT_FAILURE);
}
if (!hackdir[0])
Strcpy(hackdir, orgdir);
process_options(argc, argv);
/*
* It seems you really want to play.
*/
if (argc >= 1
&& !strcmpi(default_window_sys, "mswin")
&& (strstri(argv[0], "nethackw.exe") || GUILaunched))
iflags.windowtype_locked = TRUE;
windowtype = default_window_sys;
if (!iflags.windowtype_locked) {
#if defined(TTY_GRAPHICS)
Strcpy(default_window_sys, "tty");
#else
#if defined(CURSES_GRAPHICS)
Strcpy(default_window_sys, "curses");
#endif /* CURSES */
#endif /* TTY */
if (iflags.windowtype_deferred && chosen_windowtype[0])
windowtype = chosen_windowtype;
}
choose_windows(windowtype);
if (!dlb_init()) {
pline(
"%s\n%s\n%s\n%s\n\nNetHack was unable to open the required file "
"\"%s\".%s",
copyright_banner_line(1), copyright_banner_line(2),
copyright_banner_line(3), copyright_banner_line(4), DLBFILE,
"\nAre you perhaps trying to run NetHack within a zip utility?");
error("dlb_init failure.");
}
u.uhp = 1; /* prevent RIP on early quits */
u.ux = 0; /* prevent flush_screen() */
nethack_enter(argc, argv);
iflags.use_background_glyph = FALSE;
if (WINDOWPORT("mswin"))
iflags.use_background_glyph = TRUE;
if (WINDOWPORT("tty"))
nttty_open(1);
init_nhwindows(&argc, argv);
if (WINDOWPORT("tty"))
toggle_mouse_support();
/* strip role,race,&c suffix; calls askname() if plname[] is empty
or holds a generic user name like "player" or "games" */
plnamesuffix();
set_playmode(); /* sets plname to "wizard" for wizard mode */
/* until the getlock code is resolved, override askname()'s
setting of renameallowed; when False, player_selection()
won't resent renaming as an option */
iflags.renameallowed = FALSE;
/* Obtain the name of the logged on user and incorporate
* it into the name. */
Sprintf(fnamebuf, "%s-%s", get_username(0), plname);
(void) fname_encode(
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_-.", '%',
fnamebuf, encodedfnamebuf, BUFSZ);
Sprintf(lock, "%s", encodedfnamebuf);
/* regularize(lock); */ /* we encode now, rather than substitute */
getlock();
/* Set up level 0 file to keep the game state.
*/
fd = create_levelfile(0, (char *) 0);
if (fd < 0) {
raw_print("Cannot create lock file");
} else {
hackpid = GetCurrentProcessId();
write(fd, (genericptr_t) &hackpid, sizeof(hackpid));
nhclose(fd);
}
/*
* Initialize the vision system. This must be before mklev() on a
* new game or before a level restore on a saved game.
*/
vision_init();
display_gamewindows();
/*
* First, try to find and restore a save file for specified character.
* We'll return here if new game player_selection() renames the hero.
*/
attempt_restore:
if ((fd = restore_saved_game()) >= 0) {
#ifdef NEWS
if (iflags.news) {
display_file(NEWS, FALSE);
iflags.news = FALSE;
}
#endif
pline("Restoring save file...");
mark_synch(); /* flush output */
if (dorecover(fd)) {
resuming = TRUE; /* not starting new game */
if (discover)
You("are in non-scoring discovery mode.");
if (discover || wizard) {
if (yn("Do you want to keep the save file?") == 'n')
(void) delete_savefile();
else {
nh_compress(fqname(SAVEF, SAVEPREFIX, 0));
}
}
}
}
if (!resuming) {
/* new game: start by choosing role, race, etc;
player might change the hero's name while doing that,
in which case we try to restore under the new name
and skip selection this time if that didn't succeed */
if (!iflags.renameinprogress) {
player_selection();
if (iflags.renameinprogress) {
/* player has renamed the hero while selecting role;
discard current lock file and create another for
the new character name */
goto attempt_restore;
}
}
newgame();
if (discover)
You("are in non-scoring discovery mode.");
}
moveloop(resuming);
nethack_exit(EXIT_SUCCESS);
/*NOTREACHED*/
return 0;
}
STATIC_OVL void
process_options(argc, argv)
int argc;
char *argv[];
{
int i;
/*
* Process options.
*/
if (argc > 1) {
if (argcheck(argc, argv, ARG_VERSION) == 2)
nethack_exit(EXIT_SUCCESS);
if (argcheck(argc, argv, ARG_DEBUG) == 1) {
argc--;
argv++;
}
if (argcheck(argc, argv, ARG_WINDOWS) == 1) {
argc--;
argv++;
}
if (argc > 1 && !strncmp(argv[1], "-d", 2) && argv[1][2] != 'e') {
/* avoid matching "-dec" for DECgraphics; since the man page
* says -d directory, hope nobody's using -desomething_else
*/
argc--;
argv++;
dir = argv[0] + 2;
if (*dir == '=' || *dir == ':')
dir++;
if (!*dir && argc > 1) {
argc--;
argv++;
dir = argv[0];
}
if (!*dir)
error("Flag -d must be followed by a directory name.");
Strcpy(hackdir, dir);
}
if (argc > 1) {
/*
* Now we know the directory containing 'record' and
* may do a prscore().
*/
if (!strncmp(argv[1], "-s", 2)) {
#ifdef SYSCF
initoptions();
#endif
prscore(argc, argv);
nethack_exit(EXIT_SUCCESS);
}
if (GUILaunched) {
if (!strncmpi(argv[1], "-clearreg", 6)) { /* clear registry */
mswin_destroy_reg();
nethack_exit(EXIT_SUCCESS);
}
}
/* Don't initialize the full window system just to print usage */
if (!strncmp(argv[1], "-?", 2) || !strncmp(argv[1], "/?", 2)) {
nhusage();
nethack_exit(EXIT_SUCCESS);
}
}
}
while (argc > 1 && argv[1][0] == '-') {
argv++;
argc--;
switch (argv[0][1]) {
case 'a':
if (argv[0][2]) {
if ((i = str2align(&argv[0][2])) >= 0)
flags.initalign = i;
} else if (argc > 1) {
argc--;
argv++;
if ((i = str2align(argv[0])) >= 0)
flags.initalign = i;
}
break;
case 'D':
wizard = TRUE, discover = FALSE;
break;
case 'X':
discover = TRUE, wizard = FALSE;
break;
#ifdef NEWS
case 'n':
iflags.news = FALSE;
break;
#endif
case 'u':
if (argv[0][2])
(void) strncpy(plname, argv[0] + 2, sizeof(plname) - 1);
else if (argc > 1) {
argc--;
argv++;
(void) strncpy(plname, argv[0], sizeof(plname) - 1);
} else
raw_print("Player name expected after -u");
break;
case 'g':
if (argv[0][2]) {
if ((i = str2gend(&argv[0][2])) >= 0)
flags.initgend = i;
} else if (argc > 1) {
argc--;
argv++;
if ((i = str2gend(argv[0])) >= 0)
flags.initgend = i;
}
break;
case 'p': /* profession (role) */
if (argv[0][2]) {
if ((i = str2role(&argv[0][2])) >= 0)
flags.initrole = i;
} else if (argc > 1) {
argc--;
argv++;
if ((i = str2role(argv[0])) >= 0)
flags.initrole = i;
}
break;
case 'r': /* race */
if (argv[0][2]) {
if ((i = str2race(&argv[0][2])) >= 0)
flags.initrace = i;
} else if (argc > 1) {
argc--;
argv++;
if ((i = str2race(argv[0])) >= 0)
flags.initrace = i;
}
break;
case 'w': /* windowtype */
config_error_init(FALSE, "command line", FALSE);
if (strlen(&argv[0][2]) < (WINTYPELEN - 1))
Strcpy(chosen_windowtype, &argv[0][2]);
config_error_done();
break;
case '@':
flags.randomall = 1;
break;
default:
if ((i = str2role(&argv[0][1])) >= 0) {
flags.initrole = i;
break;
} else
raw_printf("\nUnknown switch: %s", argv[0]);
/* FALL THROUGH */
case '?':
nhusage();
nethack_exit(EXIT_SUCCESS);
}
}
}
STATIC_OVL void
nhusage()
{
char buf1[BUFSZ], buf2[BUFSZ], *bufptr;
buf1[0] = '\0';
bufptr = buf1;
#define ADD_USAGE(s) \
if ((strlen(buf1) + strlen(s)) < (BUFSZ - 1)) \
Strcat(bufptr, s);
/* -role still works for those cases which aren't already taken, but
* is deprecated and will not be listed here.
*/
(void) Sprintf(buf2, "\nUsage:\n%s [-d dir] -s [-r race] [-p profession] "
"[maxrank] [name]...\n or",
hname);
ADD_USAGE(buf2);
(void) Sprintf(
buf2, "\n%s [-d dir] [-u name] [-r race] [-p profession] [-[DX]]",
hname);
ADD_USAGE(buf2);
#ifdef NEWS
ADD_USAGE(" [-n]");
#endif
if (!iflags.window_inited)
raw_printf("%s\n", buf1);
else
(void) printf("%s\n", buf1);
#undef ADD_USAGE
}
#ifdef PORT_HELP
void
port_help()
{
/* display port specific help file */
display_file(PORT_HELP, 1);
}
#endif /* PORT_HELP */
/* validate wizard mode if player has requested access to it */
boolean
authorize_wizard_mode()
{
if (!strcmp(plname, WIZARD_NAME))
return TRUE;
return FALSE;
}
#define PATH_SEPARATOR '\\'
#if defined(WIN32) && !defined(WIN32CON)
static char exenamebuf[PATHLEN];
extern HANDLE hConIn;
extern HANDLE hConOut;
boolean has_fakeconsole;
char *
exename()
{
int bsize = PATHLEN;
char *tmp = exenamebuf, *tmp2;
#ifdef UNICODE
{
TCHAR wbuf[PATHLEN * 4];
GetModuleFileName((HANDLE) 0, wbuf, PATHLEN * 4);
WideCharToMultiByte(CP_ACP, 0, wbuf, -1, tmp, bsize, NULL, NULL);
}
#else
*(tmp + GetModuleFileName((HANDLE) 0, tmp, bsize)) = '\0';
#endif
tmp2 = strrchr(tmp, PATH_SEPARATOR);
if (tmp2)
*tmp2 = '\0';
tmp2++;
return tmp2;
}
boolean
fakeconsole(void)
{
if (!hStdOut) {
HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
HANDLE hStdIn = GetStdHandle(STD_INPUT_HANDLE);
if (!hStdOut && !hStdIn) {
/* Bool rval; */
AllocConsole();
AttachConsole(GetCurrentProcessId());
/* rval = SetStdHandle(STD_OUTPUT_HANDLE, hWrite); */
freopen("CON", "w", stdout);
freopen("CON", "r", stdin);
}
has_fakeconsole = TRUE;
}
/* Obtain handles for the standard Console I/O devices */
hConIn = GetStdHandle(STD_INPUT_HANDLE);
hConOut = GetStdHandle(STD_OUTPUT_HANDLE);
#if 0
if (!SetConsoleCtrlHandler((PHANDLER_ROUTINE) CtrlHandler, TRUE)) {
/* Unable to set control handler */
cmode = 0; /* just to have a statement to break on for debugger */
}
#endif
return has_fakeconsole;
}
void freefakeconsole()
{
if (has_fakeconsole) {
FreeConsole();
}
}
#endif
#define EXEPATHBUFSZ 256
char exepathbuf[EXEPATHBUFSZ];
char *
exepath(str)
char *str;
{
char *tmp, *tmp2;
int bsize;
if (!str)
return (char *) 0;
bsize = EXEPATHBUFSZ;
tmp = exepathbuf;
#ifdef UNICODE
{
TCHAR wbuf[BUFSZ];
GetModuleFileName((HANDLE) 0, wbuf, BUFSZ);
WideCharToMultiByte(CP_ACP, 0, wbuf, -1, tmp, bsize, NULL, NULL);
}
#else
*(tmp + GetModuleFileName((HANDLE) 0, tmp, bsize)) = '\0';
#endif
tmp2 = strrchr(tmp, PATH_SEPARATOR);
if (tmp2)
*tmp2 = '\0';
return tmp;
}
/*ARGSUSED*/
void
windows_raw_print(str)
const char *str;
{
if (str)
fprintf(stdout, "%s\n", str);
windows_nhgetch();
return;
}
/*ARGSUSED*/
void
windows_raw_print_bold(str)
const char *str;
{
windows_raw_print(str);
return;
}
int
windows_nhgetch()
{
return getchar();
}
void
windows_nhbell()
{
return;
}
/*ARGSUSED*/
int
windows_nh_poskey(x, y, mod)
int *x, *y, *mod;
{
return '\033';
}
/*ARGSUSED*/
char
windows_yn_function(query, resp, def)
const char *query;
const char *resp;
char def;
{
return '\033';
}
/*ARGSUSED*/
static void
windows_getlin(prompt, outbuf)
const char *prompt UNUSED;
char *outbuf;
{
Strcpy(outbuf, "\033");
}
/*pcmain.c*/

View File

@@ -43,10 +43,17 @@ boolean win32_cursorblink;
/* globals required within here */
HANDLE ffhandle = (HANDLE) 0;
WIN32_FIND_DATA ffd;
extern int GUILaunched;
boolean getreturn_enabled;
int redirect_stdout;
typedef HWND(WINAPI *GETCONSOLEWINDOW)();
static HWND GetConsoleHandle(void);
static HWND GetConsoleHwnd(void);
#if !defined(TTY_GRAPHICS)
extern void NDECL(backsp);
#endif
int NDECL(windows_console_custom_nhgetch);
/* The function pointer nt_kbhit contains a kbhit() equivalent
* which varies depending on which window port is active.
@@ -492,12 +499,58 @@ void nhassert_failed(const char * exp, const char * file, int line)
error(message);
}
/* nethack_enter_winnt() is the first thing called from main */
void
nethack_exit(code)
int code;
{
/* 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) {
windowprocs = *get_safe_procs(1);
/* use our custom version which works
a little cleaner than the stdio one */
windowprocs.win_nhgetch = windows_console_custom_nhgetch;
}
if (getreturn_enabled)
wait_synch();
exit(code);
}
#undef kbhit
#include <conio.h>
int
windows_console_custom_nhgetch(VOID_ARGS)
{
return _getch();
}
void
getreturn(str)
const char *str;
{
char buf[BUFSZ];
if (!getreturn_enabled)
return;
Sprintf(buf,"Hit <Enter> %s.", str);
raw_print(buf);
wait_synch();
return;
}
/* nethack_enter_winnt() is called from main immediately after
initializing the window port */
void nethack_enter_winnt()
{
#ifdef TTY_GRAPHICS
nethack_enter_nttty();
#endif
if (WINDOWPORT("tty"))
nethack_enter_nttty();
}
/* CP437 to Unicode mapping according to the Unicode Consortium */

561
win/share/safeproc.c Normal file
View File

@@ -0,0 +1,561 @@
/* NetHack 3.6 safeproc.c */
/* Copyright (c) Michael Allison, 2018 */
/* NetHack may be freely redistributed. See license for details. */
#include "hack.h"
#include <stdio.h>
/*
* ***********************************************************
* This is a complete WindowPort implementation that can be
* assigned to the windowproc function pointers very early
* in the startup initialization, perhaps immediately even.
* It requires only the following call:
* windowprocs = *get_safe_procs(0);
*
* The game startup can trigger functions in other modules
* that make assumptions on a WindowPort being available
* and bad things can happen if any function pointers are
* null at that time.
*
* Some ports prior to 3.6.2 made attempts to early init
* various pieces of one of their WindowPorts, but that
* caused conflicts if that particular WindowPort wasn't
* the one that the user ended up selecting in their
* config file later. The WindowPort interfaced was designed
* to allow multiple WindowPorts to be linked into the same
* game binary.
*
* The base functions established by a call to get_safe_procs()
* accomplish the goal of preventing crashes, but not much
* else.
*
* There are also a few additional functions provided in here
* that can be selected optionally to provide some startup
* functionality for getting messages out to the user about
* issues that are being experienced during startup in
* general or during options parsing. The ones in here are
* deliberately free from any platforms or OS specific code.
* Please leave them using stdio C routines as much as
* possible. That isn't to say you can't do fancier functions
* prior to initialization of the primary WindowPort, but you
* can provide those platform-specific functions elsewhere,
* and assign them the same way that these more generic versions
* are assigned.
*
* The additional platform-independent, but more functional
* routines provided in here should be assigned after the
* windowprocs = *get_safe_procs(n)
* call.
*
* Usage:
*
* windowprocs = *get_safe_procs(0);
* initializes a set of winprocs function pointers that ensure
* none of the function pointers are left null, but that's all
* it does.
*
* windowprocs = *get_safe_procs(1);
* initializes a set of winprocs functions pointers that ensure
* none of the function pointers are left null, but also
* provides some basic output and input functionality using
* nothing other than C stdio routines (no platform-specific
* or OS-specific code).
*
* ***********************************************************
*/
struct window_procs safe_procs = {
"safe-startup", 0L, 0L,
safe_init_nhwindows, safe_player_selection, safe_askname, safe_get_nh_event,
safe_exit_nhwindows, safe_suspend_nhwindows, safe_resume_nhwindows,
safe_create_nhwindow, safe_clear_nhwindow, safe_display_nhwindow,
safe_destroy_nhwindow, safe_curs, safe_putstr, genl_putmixed,
safe_display_file, safe_start_menu, safe_add_menu, safe_end_menu,
safe_select_menu, safe_message_menu, safe_update_inventory, safe_mark_synch,
safe_wait_synch,
#ifdef CLIPPING
safe_cliparound,
#endif
#ifdef POSITIONBAR
safe_update_positionbar,
#endif
safe_print_glyph, safe_raw_print, safe_raw_print_bold, safe_nhgetch,
safe_nh_poskey, safe_nhbell, safe_doprev_message, safe_yn_function,
safe_getlin, safe_get_ext_cmd, safe_number_pad, safe_delay_output,
#ifdef CHANGE_COLOR /* the Mac uses a palette device */
safe_change_color,
#ifdef MAC
safe_change_background, set_safe_font_name,
#endif
safe_get_color_string,
#endif
safe_start_screen, safe_end_screen, genl_outrip,
safe_preference_update,
safe_getmsghistory, safe_putmsghistory,
safe_status_init,
safe_status_finish, safe_status_enablefield,
#ifdef STATUS_HILITES
safe_status_update,
#else
safe_status_update,
#endif
safe_can_suspend,
};
struct window_procs *
get_safe_procs(optn)
int optn;
{
if (optn) {
/* include the slightly more functional stdc versions */
safe_procs.win_raw_print = stdio_raw_print;
safe_procs.win_raw_print_bold = stdio_raw_print_bold;
safe_procs.win_nhgetch = stdio_nhgetch;
safe_procs.win_wait_synch = stdio_wait_synch;
}
return &safe_procs;
}
/*ARGSUSED*/
void
safe_init_nhwindows(argcp, argv)
int *argcp UNUSED;
char **argv UNUSED;
{
return;
}
void
safe_player_selection()
{
return;
}
void
safe_askname()
{
return;
}
void
safe_get_nh_event()
{
return;
}
void
safe_suspend_nhwindows(str)
const char *str;
{
return;
}
void
safe_resume_nhwindows()
{
return;
}
void
safe_exit_nhwindows(str)
const char *str;
{
return;
}
winid
safe_create_nhwindow(type)
int type;
{
return WIN_ERR;
}
void
safe_clear_nhwindow(window)
winid window;
{
return;
}
/*ARGSUSED*/
void
safe_display_nhwindow(window, blocking)
winid window;
boolean blocking;
{
return;
}
void
safe_dismiss_nhwindow(window)
winid window;
{
return;
}
void
safe_destroy_nhwindow(window)
winid window;
{
return;
}
void
safe_curs(window, x, y)
winid window;
int x, y;
{
return;
}
void
safe_putstr(window, attr, str)
winid window;
int attr;
const char *str;
{
return;
}
void
safe_display_file(fname, complain)
const char *fname;
boolean complain;
{
return;
}
void
safe_start_menu(window)
winid window;
{
return;
}
/*ARGSUSED*/
/*
* Add a menu item to the beginning of the menu list. This list is reversed
* later.
*/
void
safe_add_menu(window, glyph, identifier, ch, gch, attr, str, preselected)
winid window; /* window to use, must be of type NHW_MENU */
int glyph UNUSED; /* glyph to display with item (not used) */
const anything *identifier; /* what to return if selected */
char ch; /* keyboard accelerator (0 = pick our own) */
char gch; /* group accelerator (0 = no group) */
int attr; /* attribute for string (like safe_putstr()) */
const char *str; /* menu string */
boolean preselected; /* item is marked as selected */
{
return;
}
/*
* End a menu in this window, window must a type NHW_MENU.
*/
void
safe_end_menu(window, prompt)
winid window; /* menu to use */
const char *prompt; /* prompt to for menu */
{
return;
}
int
safe_select_menu(window, how, menu_list)
winid window;
int how;
menu_item **menu_list;
{
return 0;
}
/* special hack for treating top line --More-- as a one item menu */
char
safe_message_menu(let, how, mesg)
char let;
int how;
const char *mesg;
{
return '\033';
}
void
safe_update_inventory()
{
return;
}
void
safe_mark_synch()
{
}
void
safe_wait_synch()
{
}
#ifdef CLIPPING
void
safe_cliparound(x, y)
int x, y;
{
}
#endif /* CLIPPING */
/*
* safe_print_glyph
*
* Print the glyph to the output device. Don't flush the output device.
*/
void
safe_print_glyph(window, x, y, glyph, bkglyph)
winid window;
xchar x, y;
int glyph;
int bkglyph UNUSED;
{
return;
}
void
safe_raw_print(str)
const char *str;
{
return;
}
void
safe_raw_print_bold(str)
const char *str;
{
return;
}
int
safe_nhgetch()
{
return '\033';
}
/*
* return a key, or 0, in which case a mouse button was pressed
* mouse events should be returned as character postitions in the map window.
* Since normal tty's don't have mice, just return a key.
*/
/*ARGSUSED*/
int
safe_nh_poskey(x, y, mod)
int *x, *y, *mod;
{
return '\033';
}
void
win_safe_init(dir)
int dir;
{
return;
}
#ifdef POSITIONBAR
void
safe_update_positionbar(posbar)
char *posbar;
{
return;
}
#endif /* POSITIONBAR */
/*
* safe_status_init()
* -- initialize the port-specific data structures.
*/
void
safe_status_init()
{
return;
}
void
safe_can_suspend()
{
return;
}
void
safe_nhbell()
{
return;
}
int
safe_doprev_message()
{
return 0;
}
char
safe_yn_function(query, resp, def)
const char *query;
const char *resp;
char def;
{
return '\033';
}
/*ARGSUSED*/
static void
safe_getlin(prompt, outbuf)
const char *prompt UNUSED;
char *outbuf;
{
Strcpy(outbuf, "\033");
}
int
safe_get_ext_cmd()
{
return '\033';
}
void
safe_number_pad(mode)
int mode;
{
return;
}
void
safe_delay_output()
{
return;
}
void
safe_start_screen()
{
return;
}
void
safe_end_screen()
{
return;
}
void
safe_outrip(tmpwin, how, when)
winid tmpwin;
int how;
time_t when;
{
return;
}
/*ARGSUSED*/
void
safe_preference_update(pref)
const char *pref UNUSED;
{
return;
}
char *
safe_getmsghistory(init)
boolean init UNUSED;
{
return (char *) 0;
}
void
safe_putmsghistory(msg, is_restoring)
const char *msg;
boolean is_restoring;
{
}
void
safe_status_finish()
{
}
void
safe_status_enablefield(fieldidx, nm, fmt, enable)
int fieldidx;
const char *nm;
const char *fmt;
boolean enable;
{
}
#ifdef STATUS_HILITES
/* call once for each field, then call with BL_FLUSH to output the result */
void
safe_status_update(idx, ptr, chg, percent, color, colormasks)
int idx;
genericptr_t ptr;
int chg UNUSED, percent UNUSED, color UNUSED;
unsigned long *colormasks UNUSED;
{
}
#endif /* STATUS_HILITES */
/**************************************************************
* These are some optionally selectable routines that add
* some base functionality over the safe_* versions above.
* The safe_* versions are primarily designed to ensure that
* there are no null function pointers remaining at early
* game startup/initialization time.
*
* The slightly more functional versions in here should be kept
* free of platform-specific code or OS-specific code. If you
* want to use versions that involve platform-specific or
* OS-specific code, go right ahead but use your own replacement
* version of the functions in a platform-specific or
* OS-specific source file, not in here.
***************************************************************/
/* Add to your code: windowprocs.win_raw_print = stdio_wait_synch; */
void
stdio_wait_synch()
{
char valid[] = {' ', '\n', '\r', '\033', '\0'};
fprintf(stdout, "--More--");
(void) fflush(stdout);
while (!index(valid, nhgetch()))
;
}
/* Add to your code: windowprocs.win_raw_print = stdio_raw_print; */
void
stdio_raw_print(str)
const char *str;
{
if (str)
fprintf(stdout, "%s\n", str);
return;
}
/* Add to your code: windowprocs.win_raw_print_bold = stdio_raw_print_bold; */
void
stdio_raw_print_bold(str)
const char *str;
{
stdio_raw_print(str);
return;
}
/* Add to your code: windowprocs.win_nhgetch = stdio_nhgetch; */
int
stdio_nhgetch()
{
return getchar();
}
/* safeprocs.c */

View File

@@ -9,6 +9,9 @@
#include "winMS.h"
#define MIN_FONT_WIDTH 9
#define MIN_FONT_HEIGHT 12
typedef struct cached_font {
int code;
HFONT hFont;

View File

@@ -15,7 +15,7 @@
#include "color.h"
#include "patchlevel.h"
#define NHMAP_FONT_NAME TEXT("Terminal")
#define NHMAP_FONT_NAME TEXT("Courier New")
#define MAXWINDOWTEXT 255
#define CURSOR_BLINK_INTERVAL 1000 // milliseconds
@@ -160,25 +160,33 @@ mswin_map_stretch(HWND hWnd, LPSIZE map_size, BOOL redraw)
// calculate back buffer scale
data->monitorScale = win10_monitor_scale(hWnd);
if (data->bAsciiMode || Is_rogue_level(&u.uz)) {
boolean bText = data->bAsciiMode ||
(u.uz.dlevel != 0 && Is_rogue_level(&u.uz));
if (bText && !data->bFitToScreenMode)
data->backScale = data->monitorScale;
} else {
else
data->backScale = 1.0;
}
/* set back buffer tile size */
data->xBackTile = (int) (data->tileWidth * data->backScale);
data->yBackTile = (int) (data->tileHeight * data->backScale);
if (bText && data->bFitToScreenMode) {
data->xBackTile = wnd_size.cx / COLNO;
data->yBackTile = wnd_size.cy / ROWNO;
data->yBackTile = max(data->yBackTile, 12);
} else {
data->xBackTile = (int)(data->tileWidth * data->backScale);
data->yBackTile = (int)(data->tileHeight * data->backScale);
}
if (data->bAsciiMode || Is_rogue_level(&u.uz)) {
if (bText) {
LOGFONT lgfnt;
ZeroMemory(&lgfnt, sizeof(lgfnt));
lgfnt.lfHeight = -data->yBackTile; // height of font
lgfnt.lfWidth = -data->xBackTile; // average character width
lgfnt.lfHeight = -data->yBackTile; // height of font
lgfnt.lfWidth = 0; // average character width
lgfnt.lfEscapement = 0; // angle of escapement
lgfnt.lfOrientation = 0; // base-line orientation angle
lgfnt.lfWeight = FW_NORMAL; // font weight
lgfnt.lfWeight = FW_SEMIBOLD; // font weight
lgfnt.lfItalic = FALSE; // italic attribute option
lgfnt.lfUnderline = FALSE; // underline attribute option
lgfnt.lfStrikeOut = FALSE; // strikeout attribute option
@@ -195,25 +203,26 @@ mswin_map_stretch(HWND hWnd, LPSIZE map_size, BOOL redraw)
}
TEXTMETRIC textMetrics;
HFONT font;
HFONT font = NULL;
while (1) {
if (font != NULL)
DeleteObject(font);
font = CreateFontIndirect(&lgfnt);
SelectObject(data->backBufferDC, font);
GetTextMetrics(data->backBufferDC, &textMetrics);
if (textMetrics.tmHeight > data->yBackTile) {
if ((textMetrics.tmHeight > data->yBackTile ||
textMetrics.tmAveCharWidth > data->xBackTile) &&
lgfnt.lfHeight < -MIN_FONT_HEIGHT) {
lgfnt.lfHeight++;
continue;
}
if (textMetrics.tmAveCharWidth > data->xBackTile) {
lgfnt.lfWidth++;
continue;
}
break;
}
@@ -256,7 +265,7 @@ mswin_map_stretch(HWND hWnd, LPSIZE map_size, BOOL redraw)
/* calculate front buffer tile size */
if (wnd_size.cx > 0 && wnd_size.cy > 0 && data->bFitToScreenMode) {
if (wnd_size.cx > 0 && wnd_size.cy > 0 && !bText && data->bFitToScreenMode) {
double windowAspectRatio =
(double) wnd_size.cx / (double) wnd_size.cy;
@@ -270,7 +279,7 @@ mswin_map_stretch(HWND hWnd, LPSIZE map_size, BOOL redraw)
} else {
if (data->bAsciiMode || Is_rogue_level(&u.uz)) {
if (bText) {
data->frontScale = 1.0;
} else {
data->frontScale = data->monitorScale;
@@ -893,9 +902,22 @@ paintGlyph(PNHMapWindow data, int i, int j, RECT * rect)
#endif
if (data->bUnicodeFont) {
wch = winos_ascii_to_wide(ch);
DrawTextW(data->backBufferDC, &wch, 1, rect,
DT_CENTER | DT_VCENTER | DT_NOPREFIX
| DT_SINGLELINE);
if (wch == 0x2591 || wch == 0x2592) {
int level = 80;
HBRUSH brush = CreateSolidBrush(RGB(level, level, level));
FillRect(data->backBufferDC, rect, brush);
DeleteObject(brush);
level = (wch == 0x2591 ? 100 : 200);
brush = CreateSolidBrush(RGB(level, level, level));
RECT smallRect = { rect->left + 1, rect->top + 1,
rect->right - 1, rect->bottom - 1 };
FillRect(data->backBufferDC, &smallRect, brush);
DeleteObject(brush);
} else {
DrawTextW(data->backBufferDC, &wch, 1, rect,
DT_CENTER | DT_VCENTER | DT_NOPREFIX
| DT_SINGLELINE);
}
} else {
DrawTextA(data->backBufferDC, &ch, 1, rect,
DT_CENTER | DT_VCENTER | DT_NOPREFIX

View File

@@ -718,6 +718,13 @@ mswin_exit_nhwindows(const char *str)
/* Write Window settings to the registry */
mswin_write_reg();
/* set things back to failsafes */
windowprocs = *get_safe_procs(0);
/* and make sure there is still a way to communicate something */
windowprocs.win_raw_print = mswin_raw_print;
windowprocs.win_raw_print_bold = mswin_raw_print_bold;
windowprocs.win_wait_synch = mswin_wait_synch;
}
/* Prepare the window to be suspended. */

View File

@@ -34,7 +34,7 @@
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<OmitFramePointers>true</OmitFramePointers>
<AdditionalIncludeDirectories>$(WinWin32Dir);$(IncDir);$(SysWinntDir);$(SysShareDir);$(WinShareDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>TILES;WIN32CON;DLB;MSWIN_GRAPHICS;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>TILES;WIN32CON;DLB;MSWIN_GRAPHICS;SAFEPROCS;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;winmm.lib;Winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
@@ -151,7 +151,6 @@
<ClCompile Include="$(SrcDir)zap.c" />
<ClCompile Include="$(SysShareDir)cppregex.cpp" />
<ClCompile Include="$(SysShareDir)nhlan.c" />
<ClCompile Include="$(SysShareDir)pcmain.c" />
<ClCompile Include="$(SysShareDir)pcsys.c" />
<ClCompile Include="$(SysShareDir)pcunix.c" />
<ClCompile Include="$(SysShareDir)random.c" />
@@ -160,7 +159,9 @@
<ClCompile Include="$(SysWinntDir)stubs.c">
<PreprocessorDefinitions>GUISTUB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="$(SysWinntDir)windmain.c" />
<ClCompile Include="$(SysWinntDir)winnt.c" />
<ClCompile Include="$(WinShareDir)safeproc.c" />
<ClCompile Include="$(WinTtyDir)getline.c" />
<ClCompile Include="$(WinTtyDir)topl.c" />
<ClCompile Include="$(WinTtyDir)wintty.c" />
@@ -254,4 +255,4 @@
<Target Name="AfterRebuild">
<MSBuild Projects="afternethack.proj" Targets="Build" Properties="Configuration=$(Configuration)" />
</Target>
</Project>
</Project>

View File

@@ -20,7 +20,7 @@
<Optimization>Disabled</Optimization>
<OmitFramePointers>true</OmitFramePointers>
<AdditionalIncludeDirectories>$(WinWin32Dir);$(IncDir);$(SysWinntDir);$(SysShareDir);$(WinShareDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>TILES;_WINDOWS;DLB;MSWIN_GRAPHICS;NOTTYGRAPHICS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>TILES;_WINDOWS;DLB;MSWIN_GRAPHICS;SAFEPROCS;NOTTYGRAPHICS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
@@ -146,7 +146,6 @@
<ClCompile Include="$(SrcDir)zap.c" />
<ClCompile Include="$(SysShareDir)cppregex.cpp" />
<ClCompile Include="$(SysShareDir)nhlan.c" />
<ClCompile Include="$(SysShareDir)pcmain.c" />
<ClCompile Include="$(SysShareDir)pcsys.c" />
<ClCompile Include="$(SysShareDir)pcunix.c" />
<ClCompile Include="$(SysShareDir)random.c" />
@@ -154,8 +153,10 @@
<ClCompile Include="$(SysWinntDir)stubs.c">
<PreprocessorDefinitions>TTYSTUB;</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="$(SysWinntDir)windmain.c" />
<ClCompile Include="$(SysWinntDir)winnt.c" />
<ClCompile Include="$(SysWinntDir)win10.c" />
<ClCompile Include="$(WinShareDir)safeproc.c" />
<ClCompile Include="$(WinWin32Dir)mhaskyn.c" />
<ClCompile Include="$(WinWin32Dir)mhdlg.c" />
<ClCompile Include="$(WinWin32Dir)mhfont.c" />
@@ -200,4 +201,4 @@
<Target Name="AfterRebuild">
<MSBuild Projects="afternethack.proj" Targets="Build" Properties="Configuration=$(Configuration)" />
</Target>
</Project>
</Project>

View File

@@ -15,6 +15,10 @@
#include "mhmain.h"
#include "mhmap.h"
#if !defined(SAFEPROCS)
#error You must #define SAFEPROCS to build winhack.c
#endif
/* Borland and MinGW redefine "boolean" in shlwapi.h,
so just use the little bit we need */
typedef struct _DLLVERSIONINFO {
@@ -59,6 +63,8 @@ _nhapply_image_transparent(HDC hDC, int x, int y, int width, int height,
// Global Variables:
NHWinApp _nethack_app;
extern int GUILaunched; /* We tell shared startup code in windmain.c
that the GUI was launched via this */
#ifdef __BORLANDC__
#define _stricmp(s1, s2) stricmp(s1, s2)
@@ -66,7 +72,7 @@ NHWinApp _nethack_app;
#endif
// Foward declarations of functions included in this code module:
extern boolean FDECL(pcmain, (int, char **));
extern boolean FDECL(main, (int, char **));
static void __cdecl mswin_moveloop(void *);
#define MAX_CMDLINE_PARAM 255
@@ -82,24 +88,44 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine,
TCHAR *p;
TCHAR wbuf[BUFSZ];
char buf[BUFSZ];
DWORD major, minor;
boolean resuming;
/* OSVERSIONINFO osvi; */
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
UNREFERENCED_PARAMETER(nCmdShow);
/* We must initialize state sufficiently to support calls to panic */
/*
* Get a set of valid safe windowport function
* pointers during early startup initialization.
*
* When get_safe_procs is called with 0 as the param,
* non-functional, but safe function pointers are set
* for all windowport routines.
*
* When get_safe_procs is called with 1 as the param,
* raw_print, raw_print_bold, and wait_synch, and nhgetch
* are set to use C stdio routines via stdio_raw_print,
* stdio_raw_print_bold, stdio_wait_synch, and
* stdio_nhgetch.
*/
windowprocs = *get_safe_procs(0);
/*
* Now we are going to override a couple
* of the windowprocs functions so that
* error messages are handled in a suitable
* way for the graphical version.
*/
windowprocs.win_raw_print = mswin_raw_print;
windowprocs.win_raw_print_bold = mswin_raw_print_bold;
windowprocs.win_wait_synch = mswin_wait_synch;
win10_init();
sys_early_init();
/* init applicatio structure */
/* init application structure */
_nethack_app.hApp = hInstance;
_nethack_app.hAccelTable =
LoadAccelerators(hInstance, (LPCTSTR) IDC_NETHACKW);
@@ -209,10 +235,9 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine,
}
free(savefile);
}
resuming = pcmain(argc, argv);
moveloop(resuming);
GUILaunched = 1;
/* let main do the argument processing */
(void) main(argc, argv);
return 0;
}