Merge branch 'win-minor' into win-fontmap

# Conflicts:
#	win/win32/mhmap.c
This commit is contained in:
Bart House
2018-12-09 14:02:57 -08:00
55 changed files with 2013 additions and 641 deletions
+25 -1
View File
@@ -236,6 +236,28 @@ to emphasize that it's not a light source, change description of wielded Sting
from "(glowing)" to nothing (not warm enough to feel) when blind from "(glowing)" to nothing (not warm enough to feel) when blind
glowing Sting quivers if hero becomes blind and quivering Sting glows if glowing Sting quivers if hero becomes blind and quivering Sting glows if
blindness ends; it worked for timed blindness but not for blindfold blindness ends; it worked for timed blindness but not for blindfold
weapon (wielded pie, egg, potion, boomerang) might be destroyed when hitting a
long worm, then freed memory was accessed to decide whether to cut it
level change after being interruped locking or unlocking a container might
access freed memory
if a restore attempt failed and a new game was started instead, it would use
stale context from old game if restoration got far enough to load that
if hero survives turning into slime (life-saving), survive as a green slime
hero hit by something that causes inventory items to be destroyed with loss of
any of those causing other inventory items to be dropped or destroyed,
inventory traversal became unreliable (known sequence: potions hit by
fire then breahing vapor from boiled unholy water triggering were
transformation to beast form; possible sequence: ring of levitation
blasted by lightning and dropping hero onto fire trap); [3.6.1 fixed a
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()
Fixes to Post-3.6.1 Problems that Were Exposed Via git Repository Fixes to Post-3.6.1 Problems that Were Exposed Via git Repository
@@ -258,6 +280,9 @@ buliding with EXTRA_SANITY_CHECKS enabled would issue "no monster to remove"
changing Sting's description to be "(weapon in hand) (light blue aura)" was changing Sting's description to be "(weapon in hand) (light blue aura)" was
too close to feedback when objects become blessed; change it again, too close to feedback when objects become blessed; change it again,
to "(weapon in hand, flickering/glimmering/gleaming light blue)" to "(weapon in hand, flickering/glimmering/gleaming light blue)"
fix bit-use collision between WC2_TERM_SIZE and WC2_RESET_STATUS in
include/winprocs.h following a recent merge
fix foxen pluralization again after underflow remedy reintroduced the problem
tty: turn off an optimization that is the suspected cause of Windows reported tty: turn off an optimization that is the suspected cause of Windows reported
partial status lines following level changes partial status lines following level changes
tty: ensure that current status fields are always copied to prior status tty: ensure that current status fields are always copied to prior status
@@ -360,7 +385,6 @@ make it clear when a leprechaun dodges your attack
wizard mode #wizidentify can now select individual items for permanent wizard mode #wizidentify can now select individual items for permanent
identification and don't display the selection to permanently identification and don't display the selection to permanently
identify everything if everything is already fully identified identify everything if everything is already fully identified
spiders will occasionally spin webs when moving around
make mine town "orctown" variation a multiple level feature of the mines make mine town "orctown" variation a multiple level feature of the mines
replace #monpolycontrol command with monpolycontrol boolean option replace #monpolycontrol command with monpolycontrol boolean option
replace #wizdebug_traveldisplay command with travel_debug boolean option replace #wizdebug_traveldisplay command with travel_debug boolean option
+2 -2
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 extern.h $NHDT-Date: 1543745352 2018/12/02 10:09:12 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.664 $ */ /* 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 $ */
/* Copyright (c) Steve Creps, 1988. */ /* Copyright (c) Steve Creps, 1988. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -2834,7 +2834,7 @@ E void FDECL(worm_move, (struct monst *));
E void FDECL(worm_nomove, (struct monst *)); E void FDECL(worm_nomove, (struct monst *));
E void FDECL(wormgone, (struct monst *)); E void FDECL(wormgone, (struct monst *));
E void FDECL(wormhitu, (struct monst *)); E void FDECL(wormhitu, (struct monst *));
E void FDECL(cutworm, (struct monst *, XCHAR_P, XCHAR_P, struct obj *)); E void FDECL(cutworm, (struct monst *, XCHAR_P, XCHAR_P, BOOLEAN_P));
E void FDECL(see_wsegs, (struct monst *)); E void FDECL(see_wsegs, (struct monst *));
E void FDECL(detect_wsegs, (struct monst *, BOOLEAN_P)); E void FDECL(detect_wsegs, (struct monst *, BOOLEAN_P));
E void FDECL(save_worm, (int, int)); E void FDECL(save_worm, (int, int));
+1 -3
View File
@@ -322,10 +322,8 @@ struct instance_flags {
#endif #endif
#endif #endif
uchar bouldersym; /* symbol for boulder display */ uchar bouldersym; /* symbol for boulder display */
#ifdef TTY_GRAPHICS
char prevmsg_window; /* type of old message window to use */
#endif
#if defined(TTY_GRAPHICS) || defined(CURSES_GRAPHICS) #if defined(TTY_GRAPHICS) || defined(CURSES_GRAPHICS)
char prevmsg_window; /* type of old message window to use */
boolean extmenu; /* extended commands use menu interface */ boolean extmenu; /* extended commands use menu interface */
#endif #endif
#ifdef MFLOPPY #ifdef MFLOPPY
+8 -6
View File
@@ -253,13 +253,15 @@ typedef struct sortloot_item Loot;
#define MM_IGNOREWATER 0x00008 /* ignore water when positioning */ #define MM_IGNOREWATER 0x00008 /* ignore water when positioning */
#define MM_ADJACENTOK \ #define MM_ADJACENTOK \
0x00010 /* it is acceptable to use adjacent coordinates */ 0x00010 /* it is acceptable to use adjacent coordinates */
#define MM_ANGRY 0x00020 /* monster is created angry */ #define MM_ANGRY 0x00020 /* monster is created angry */
#define MM_NONAME 0x00040 /* monster is not christened */ #define MM_NONAME 0x00040 /* monster is not christened */
#define MM_EGD 0x00100 /* add egd structure */ #define MM_EGD 0x00100 /* add egd structure */
#define MM_EPRI 0x00200 /* add epri structure */ #define MM_EPRI 0x00200 /* add epri structure */
#define MM_ESHK 0x00400 /* add eshk structure */ #define MM_ESHK 0x00400 /* add eshk structure */
#define MM_EMIN 0x00800 /* add emin structure */ #define MM_EMIN 0x00800 /* add emin structure */
#define MM_EDOG 0x01000 /* add edog structure */ #define MM_EDOG 0x01000 /* add edog structure */
#define MM_ASLEEP 0x02000 /* monsters should be generated asleep */
#define MM_NOGRP 0x04000 /* suppress creation of monster groups */
/* flags for make_corpse() and mkcorpstat() */ /* flags for make_corpse() and mkcorpstat() */
#define CORPSTAT_NONE 0x00 #define CORPSTAT_NONE 0x00
-3
View File
@@ -259,9 +259,6 @@ extern void curses_del_menu(winid wid);
extern void curses_status_init(void); extern void curses_status_init(void);
extern void curses_status_update(int, genericptr_t, int, int, int, unsigned long *); extern void curses_status_update(int, genericptr_t, int, int, int, unsigned long *);
/* extern attr_t curses_color_attr(int nh_color, int bg_color); */
/* extern void curses_update_stats(void); */
/* extern void curses_decrement_highlight(void); */
/* cursinvt.c */ /* cursinvt.c */
+77 -4
View File
@@ -216,10 +216,10 @@ extern
after updating status window fields */ after updating status window fields */
#define WC2_RESET_STATUS 0x0100L /* 09 call status_update(BL_RESET) to indicate #define WC2_RESET_STATUS 0x0100L /* 09 call status_update(BL_RESET) to indicate
draw everything */ draw everything */
#define WC2_TERM_SIZE 0x0100L /* 10 support setting terminal size */ #define WC2_TERM_SIZE 0x0200L /* 10 support setting terminal size */
#define WC2_WINDOWBORDERS 0x0200L /* 11 display borders on nh windows */ #define WC2_WINDOWBORDERS 0x0400L /* 11 display borders on nh windows */
#define WC2_PETATTR 0x0400L /* 12 attributes for hilite_pet */ #define WC2_PETATTR 0x0800L /* 12 attributes for hilite_pet */
#define WC2_GUICOLOR 0x0800L /* 13 display colours outside map win */ #define WC2_GUICOLOR 0x1000L /* 13 display colours outside map win */
/* 19 free bits */ /* 19 free bits */
#define ALIGN_LEFT 1 #define ALIGN_LEFT 1
@@ -375,4 +375,77 @@ struct chain_procs {
}; };
#endif /* WINCHAIN */ #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 */ #endif /* WINPROCS_H */
+11 -12
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 botl.c $NHDT-Date: 1527042178 2018/05/23 02:22:58 $ $NHDT-Branch: NetHack-3.6.2 $:$NHDT-Revision: 1.101 $ */ /* NetHack 3.6 botl.c $NHDT-Date: 1544229439 2018/12/08 00:37:19 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.129 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Michael Allison, 2006. */ /*-Copyright (c) Michael Allison, 2006. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -234,7 +234,8 @@ do_statusline2()
void void
bot() 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 #ifdef STATUS_HILITES
bot_via_windowport(); bot_via_windowport();
#else #else
@@ -732,17 +733,15 @@ boolean *valsetlist;
* NNNN = the glyph portion * NNNN = the glyph portion
* 25 = the gold amount * 25 = the gold amount
* *
* Setting 'chg = 2' is enough to render the field properly, but
* not to honor an initial highlight, so force 'update_all = TRUE'.
*/ */
if (fld == BL_GOLD
if (fld == BL_GOLD) { && (context.rndencode != oldrndencode
if (context.rndencode != oldrndencode) { || showsyms[COIN_CLASS + SYM_OFF_O] != oldgoldsym)) {
chg = 2; update_all = TRUE; /* chg = 2; */
oldrndencode = context.rndencode; oldrndencode = context.rndencode;
} oldgoldsym = showsyms[COIN_CLASS + SYM_OFF_O];
if (oldgoldsym != showsyms[COIN_CLASS + SYM_OFF_O]) {
chg = 2;
oldgoldsym = showsyms[COIN_CLASS + SYM_OFF_O];
}
} }
reset = FALSE; reset = FALSE;
+8 -3
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 cmd.c $NHDT-Date: 1543797825 2018/12/03 00:43:45 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.312 $ */ /* NetHack 3.6 cmd.c $NHDT-Date: 1544050555 2018/12/05 22:55:55 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.314 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2013. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -2740,7 +2740,12 @@ int final;
} }
if (Polymorph_control) if (Polymorph_control)
you_have("polymorph control", from_what(POLYMORPH_CONTROL)); you_have("polymorph control", from_what(POLYMORPH_CONTROL));
if (Upolyd && u.umonnum != u.ulycn) { if (Upolyd && u.umonnum != u.ulycn
/* if we've died from turning into slime, we're polymorphed
right now but don't want to list it as a temporary attribute
[we need a more reliable way to detect this situation] */
&& !(final == ENL_GAMEOVERDEAD
&& u.umonnum == PM_GREEN_SLIME && !Unchanging)) {
/* foreign shape (except were-form which is handled below) */ /* foreign shape (except were-form which is handled below) */
Sprintf(buf, "polymorphed into %s", an(youmonst.data->mname)); Sprintf(buf, "polymorphed into %s", an(youmonst.data->mname));
if (wizard) if (wizard)
@@ -5694,7 +5699,7 @@ dotravel(VOID_ARGS)
cmd[1] = 0; cmd[1] = 0;
cc.x = iflags.travelcc.x; cc.x = iflags.travelcc.x;
cc.y = iflags.travelcc.y; cc.y = iflags.travelcc.y;
if (cc.x == -1 && cc.y == -1) { if (cc.x == 0 && cc.y == 0) {
/* No cached destination, start attempt from current position */ /* No cached destination, start attempt from current position */
cc.x = u.ux; cc.x = u.ux;
cc.y = u.uy; cc.y = u.uy;
+12 -9
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 do.c $NHDT-Date: 1543052696 2018/11/24 09:44:56 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.175 $ */ /* 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 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Derek S. Ray, 2015. */ /*-Copyright (c) Derek S. Ray, 2015. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -1237,6 +1237,17 @@ boolean at_stairs, falling, portal;
if (fd < 0) if (fd < 0)
return; return;
/* discard context which applies to the level we're leaving;
for lock-picking, container may be carried, in which case we
keep context; if on the floor, it's about to be saved+freed and
maybe_reset_pick() needs to do its carried() check before that */
maybe_reset_pick();
reset_trapset(); /* even if to-be-armed trap obj is accompanying hero */
iflags.travelcc.x = iflags.travelcc.y = 0; /* travel destination cache */
context.polearm.hitmon = (struct monst *) 0; /* polearm target */
/* digging context is level-aware and can actually be resumed if
hero returns to the previous level without any intervening dig */
if (falling) /* assuming this is only trap door or hole */ if (falling) /* assuming this is only trap door or hole */
impact_drop((struct obj *) 0, u.ux, u.uy, newlevel->dlevel); impact_drop((struct obj *) 0, u.ux, u.uy, newlevel->dlevel);
@@ -1576,14 +1587,6 @@ boolean at_stairs, falling, portal;
/* assume this will always return TRUE when changing level */ /* assume this will always return TRUE when changing level */
(void) in_out_region(u.ux, u.uy); (void) in_out_region(u.ux, u.uy);
(void) pickup(1); (void) pickup(1);
/* discard context which applied to previous level */
maybe_reset_pick(); /* for door or for box not accompanying hero */
reset_trapset(); /* even if to-be-armed trap obj is accompanying hero */
iflags.travelcc.x = iflags.travelcc.y = -1; /* travel destination cache */
context.polearm.hitmon = (struct monst *) 0; /* polearm target */
/* digging context is level-aware and can actually be resumed if
hero returns to the previous level without any intervening dig */
} }
STATIC_OVL void STATIC_OVL void
+7 -3
View File
@@ -57,7 +57,9 @@ static const char *const gloc_descr[NUM_GLOCS][4] = {
{ "any unexplored areas", "unexplored area", "unexplored location", { "any unexplored areas", "unexplored area", "unexplored location",
"unexplored locations" }, "unexplored locations" },
{ "anything interesting", "interesting thing", "anything interesting", { "anything interesting", "interesting thing", "anything interesting",
"anything interesting" } "anything interesting" },
{ "any valid locations", "valid location", "valid location",
"valid locations" }
}; };
static const char *const gloc_filtertxt[NUM_GFILTER] = { static const char *const gloc_filtertxt[NUM_GFILTER] = {
@@ -378,6 +380,10 @@ int x, y, gloc;
|| IS_UNEXPLORED_LOC(x - 1, y) || IS_UNEXPLORED_LOC(x - 1, y)
|| IS_UNEXPLORED_LOC(x, y + 1) || IS_UNEXPLORED_LOC(x, y + 1)
|| IS_UNEXPLORED_LOC(x, y - 1))); || IS_UNEXPLORED_LOC(x, y - 1)));
case GLOC_VALID:
if (getpos_getvalid)
return (getpos_getvalid(x,y));
/*FALLTHRU*/
case GLOC_INTERESTING: case GLOC_INTERESTING:
return gather_locs_interesting(x,y, GLOC_DOOR) return gather_locs_interesting(x,y, GLOC_DOOR)
|| !(glyph_is_cmap(glyph) || !(glyph_is_cmap(glyph)
@@ -395,8 +401,6 @@ int x, y, gloc;
|| glyph_to_cmap(glyph) == S_darkroom || glyph_to_cmap(glyph) == S_darkroom
|| glyph_to_cmap(glyph) == S_corr || glyph_to_cmap(glyph) == S_corr
|| glyph_to_cmap(glyph) == S_litcorr)); || glyph_to_cmap(glyph) == S_litcorr));
case GLOC_VALID:
return (getpos_getvalid && getpos_getvalid(x,y));
} }
/*NOTREACHED*/ /*NOTREACHED*/
return FALSE; return FALSE;
+9 -5
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 dothrow.c $NHDT-Date: 1525012611 2018/04/29 14:36:51 $ $NHDT-Branch: master $:$NHDT-Revision: 1.137 $ */ /* 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 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2013. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -1652,13 +1652,16 @@ register struct obj *obj; /* thrownobj or kickedobj or uwep */
} }
if (tmp >= dieroll) { if (tmp >= dieroll) {
boolean wasthrown = (thrownobj != 0); boolean wasthrown = (thrownobj != 0),
/* remember weapon attribute; hmon() might destroy obj */
chopper = is_axe(obj);
/* attack hits mon */ /* attack hits mon */
if (hmode == HMON_APPLIED) if (hmode == HMON_APPLIED)
u.uconduct.weaphit++; u.uconduct.weaphit++;
if (hmon(mon, obj, hmode, dieroll)) { /* mon still alive */ if (hmon(mon, obj, hmode, dieroll)) { /* mon still alive */
cutworm(mon, bhitpos.x, bhitpos.y, obj); if (mon->wormno)
cutworm(mon, bhitpos.x, bhitpos.y, chopper);
} }
exercise(A_DEX, TRUE); exercise(A_DEX, TRUE);
/* if hero was swallowed and projectile killed the engulfer, /* if hero was swallowed and projectile killed the engulfer,
@@ -1668,8 +1671,9 @@ register struct obj *obj; /* thrownobj or kickedobj or uwep */
if (wasthrown && !thrownobj) if (wasthrown && !thrownobj)
return 1; return 1;
/* projectiles other than magic stones /* projectiles other than magic stones sometimes disappear
sometimes disappear when thrown */ when thrown; projectiles aren't among the types of weapon
that hmon() might have destroyed so obj is intact */
if (objects[otyp].oc_skill < P_NONE if (objects[otyp].oc_skill < P_NONE
&& objects[otyp].oc_skill > -P_BOOMERANG && objects[otyp].oc_skill > -P_BOOMERANG
&& !objects[otyp].oc_magic) { && !objects[otyp].oc_magic) {
+12 -4
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 end.c $NHDT-Date: 1542798619 2018/11/21 11:10:19 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.152 $ */ /* NetHack 3.6 end.c $NHDT-Date: 1544003110 2018/12/05 09:45:10 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.156 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2012. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -1184,7 +1184,12 @@ int how;
u.ugrave_arise = (NON_PM - 2); /* leave no corpse */ u.ugrave_arise = (NON_PM - 2); /* leave no corpse */
else if (how == STONING) else if (how == STONING)
u.ugrave_arise = (NON_PM - 1); /* statue instead of corpse */ u.ugrave_arise = (NON_PM - 1); /* statue instead of corpse */
else if (how == TURNED_SLIME) else if (how == TURNED_SLIME
/* it's possible to turn into slime even though green slimes
have been genocided: genocide could occur after hero is
already infected or hero could eat a glob of one created
before genocide; don't try to arise as one if they're gone */
&& !(mvitals[PM_GREEN_SLIME].mvflags & G_GENOD))
u.ugrave_arise = PM_GREEN_SLIME; u.ugrave_arise = PM_GREEN_SLIME;
if (how == QUIT) { if (how == QUIT) {
@@ -1310,11 +1315,14 @@ int how;
} }
} }
if (u.ugrave_arise >= LOW_PM && u.ugrave_arise != PM_GREEN_SLIME) { if (u.ugrave_arise >= LOW_PM) {
/* give this feedback even if bones aren't going to be created, /* give this feedback even if bones aren't going to be created,
so that its presence or absence doesn't tip off the player to so that its presence or absence doesn't tip off the player to
new bones or their lack; it might be a lie if makemon fails */ new bones or their lack; it might be a lie if makemon fails */
Your("body rises from the dead as %s...", Your("%s as %s...",
(u.ugrave_arise != PM_GREEN_SLIME)
? "body rises from the dead"
: "revenant persists",
an(mons[u.ugrave_arise].mname)); an(mons[u.ugrave_arise].mname));
display_nhwindow(WIN_MESSAGE, FALSE); display_nhwindow(WIN_MESSAGE, FALSE);
} }
+3 -3
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 hack.c $NHDT-Date: 1540591769 2018/10/26 22:09:29 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.194 $ */ /* 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 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Derek S. Ray, 2015. */ /*-Copyright (c) Derek S. Ray, 2015. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -923,7 +923,7 @@ int mode;
u.dx = u.tx - u.ux; u.dx = u.tx - u.ux;
u.dy = u.ty - u.uy; u.dy = u.ty - u.uy;
nomul(0); nomul(0);
iflags.travelcc.x = iflags.travelcc.y = -1; iflags.travelcc.x = iflags.travelcc.y = 0;
} }
return TRUE; return TRUE;
} }
@@ -1045,7 +1045,7 @@ int mode;
nomul(0); nomul(0);
/* reset run so domove run checks work */ /* reset run so domove run checks work */
context.run = 8; context.run = 8;
iflags.travelcc.x = iflags.travelcc.y = -1; iflags.travelcc.x = iflags.travelcc.y = 0;
} }
return TRUE; return TRUE;
} }
+13 -12
View File
@@ -18,15 +18,15 @@ STATIC_DCL boolean FDECL(uncommon, (int));
STATIC_DCL int FDECL(align_shift, (struct permonst *)); STATIC_DCL int FDECL(align_shift, (struct permonst *));
STATIC_DCL boolean FDECL(mk_gen_ok, (int, int, int)); STATIC_DCL boolean FDECL(mk_gen_ok, (int, int, int));
STATIC_DCL boolean FDECL(wrong_elem_type, (struct permonst *)); STATIC_DCL boolean FDECL(wrong_elem_type, (struct permonst *));
STATIC_DCL void FDECL(m_initgrp, (struct monst *, int, int, int)); STATIC_DCL void FDECL(m_initgrp, (struct monst *, int, int, int, int));
STATIC_DCL void FDECL(m_initthrow, (struct monst *, int, int)); STATIC_DCL void FDECL(m_initthrow, (struct monst *, int, int));
STATIC_DCL void FDECL(m_initweap, (struct monst *)); STATIC_DCL void FDECL(m_initweap, (struct monst *));
STATIC_DCL void FDECL(m_initinv, (struct monst *)); STATIC_DCL void FDECL(m_initinv, (struct monst *));
STATIC_DCL boolean FDECL(makemon_rnd_goodpos, (struct monst *, STATIC_DCL boolean FDECL(makemon_rnd_goodpos, (struct monst *,
unsigned, coord *)); unsigned, coord *));
#define m_initsgrp(mtmp, x, y) m_initgrp(mtmp, x, y, 3) #define m_initsgrp(mtmp, x, y, mmf) m_initgrp(mtmp, x, y, 3, mmf)
#define m_initlgrp(mtmp, x, y) m_initgrp(mtmp, x, y, 10) #define m_initlgrp(mtmp, x, y, mmf) m_initgrp(mtmp, x, y, 10, mmf)
#define toostrong(monindx, lev) (mons[monindx].difficulty > lev) #define toostrong(monindx, lev) (mons[monindx].difficulty > lev)
#define tooweak(monindx, lev) (mons[monindx].difficulty < lev) #define tooweak(monindx, lev) (mons[monindx].difficulty < lev)
@@ -76,9 +76,9 @@ struct permonst *ptr;
/* make a group just like mtmp */ /* make a group just like mtmp */
STATIC_OVL void STATIC_OVL void
m_initgrp(mtmp, x, y, n) m_initgrp(mtmp, x, y, n, mmflags)
register struct monst *mtmp; struct monst *mtmp;
register int x, y, n; int x, y, n, mmflags;
{ {
coord mm; coord mm;
register int cnt = rnd(n); register int cnt = rnd(n);
@@ -129,7 +129,7 @@ register int x, y, n;
* smaller group. * smaller group.
*/ */
if (enexto(&mm, mm.x, mm.y, mtmp->data)) { if (enexto(&mm, mm.x, mm.y, mtmp->data)) {
mon = makemon(mtmp->data, mm.x, mm.y, NO_MM_FLAGS); mon = makemon(mtmp->data, mm.x, mm.y, (mmflags | MM_NOGRP));
if (mon) { if (mon) {
mon->mpeaceful = FALSE; mon->mpeaceful = FALSE;
mon->mavenge = 0; mon->mavenge = 0;
@@ -1193,7 +1193,8 @@ int mmflags;
newemin(mtmp); newemin(mtmp);
if (mmflags & MM_EDOG) if (mmflags & MM_EDOG)
newedog(mtmp); newedog(mtmp);
if (mmflags & MM_ASLEEP)
mtmp->msleeping = 1;
mtmp->nmon = fmon; mtmp->nmon = fmon;
fmon = mtmp; fmon = mtmp;
mtmp->m_id = context.ident++; mtmp->m_id = context.ident++;
@@ -1364,14 +1365,14 @@ int mmflags;
: eminp->renegade; : eminp->renegade;
} }
set_malign(mtmp); /* having finished peaceful changes */ set_malign(mtmp); /* having finished peaceful changes */
if (anymon) { if (anymon && !(mmflags & MM_NOGRP)) {
if ((ptr->geno & G_SGROUP) && rn2(2)) { if ((ptr->geno & G_SGROUP) && rn2(2)) {
m_initsgrp(mtmp, mtmp->mx, mtmp->my); m_initsgrp(mtmp, mtmp->mx, mtmp->my, mmflags);
} else if (ptr->geno & G_LGROUP) { } else if (ptr->geno & G_LGROUP) {
if (rn2(3)) if (rn2(3))
m_initlgrp(mtmp, mtmp->mx, mtmp->my); m_initlgrp(mtmp, mtmp->mx, mtmp->my, mmflags);
else else
m_initsgrp(mtmp, mtmp->mx, mtmp->my); m_initsgrp(mtmp, mtmp->mx, mtmp->my, mmflags);
} }
} }
+1 -1
View File
@@ -803,7 +803,7 @@ skip0:
if (u.uhave.amulet || !rn2(3)) { if (u.uhave.amulet || !rn2(3)) {
x = somex(croom); x = somex(croom);
y = somey(croom); y = somey(croom);
tmonst = makemon((struct permonst *) 0, x, y, NO_MM_FLAGS); tmonst = makemon((struct permonst *) 0, x, y, (MM_NOGRP | MM_ASLEEP));
if (tmonst && tmonst->data == &mons[PM_GIANT_SPIDER] if (tmonst && tmonst->data == &mons[PM_GIANT_SPIDER]
&& !occupied(x, y)) && !occupied(x, y))
(void) maketrap(x, y, WEB); (void) maketrap(x, y, WEB);
+1 -1
View File
@@ -341,7 +341,7 @@ struct mkroom *sroom;
: (type == ANTHOLE) : (type == ANTHOLE)
? antholemon() ? antholemon()
: (struct permonst *) 0, : (struct permonst *) 0,
sx, sy, NO_MM_FLAGS); sx, sy, MM_ASLEEP);
if (mon) { if (mon) {
mon->msleeping = 1; mon->msleeping = 1;
if (type == COURT && mon->mpeaceful) { if (type == COURT && mon->mpeaceful) {
-40
View File
@@ -14,7 +14,6 @@ STATIC_DCL int FDECL(disturb, (struct monst *));
STATIC_DCL void FDECL(release_hero, (struct monst *)); STATIC_DCL void FDECL(release_hero, (struct monst *));
STATIC_DCL void FDECL(distfleeck, (struct monst *, int *, int *, int *)); STATIC_DCL void FDECL(distfleeck, (struct monst *, int *, int *, int *));
STATIC_DCL int FDECL(m_arrival, (struct monst *)); STATIC_DCL int FDECL(m_arrival, (struct monst *));
STATIC_DCL int FDECL(count_webbing_walls, (XCHAR_P, XCHAR_P));
STATIC_DCL boolean FDECL(stuff_prevents_passage, (struct monst *)); STATIC_DCL boolean FDECL(stuff_prevents_passage, (struct monst *));
STATIC_DCL int FDECL(vamp_shift, (struct monst *, struct permonst *, STATIC_DCL int FDECL(vamp_shift, (struct monst *, struct permonst *,
BOOLEAN_P)); BOOLEAN_P));
@@ -759,24 +758,6 @@ xchar nix,niy;
return FALSE; return FALSE;
} }
/* returns the number of walls in the four cardinal directions that could
hold up a web */
STATIC_OVL int
count_webbing_walls(x, y)
xchar x, y;
{
#define holds_up_web(X, Y) ((!isok((X), (Y)) \
|| IS_ROCK(levl[X][Y].typ) \
|| (levl[X][Y].typ == STAIRS \
&& (X) == xupstair && (Y) == yupstair) \
|| (levl[X][Y].typ == LADDER \
&& (X) == xupladder && (Y) == yupladder) \
|| levl[X][Y].typ == IRONBARS) ? 1 : 0)
return (holds_up_web(x, y - 1) + holds_up_web(x + 1, y)
+ holds_up_web(x, y + 1) + holds_up_web(x - 1, y));
#undef holds_up_web
}
/* Return values: /* Return values:
* 0: did not move, but can still attack and do other stuff. * 0: did not move, but can still attack and do other stuff.
* 1: moved, possibly can attack. * 1: moved, possibly can attack.
@@ -1472,27 +1453,6 @@ postmov:
} }
} }
/* maybe spin a web -- this needs work; if the spider is far away,
it might spin a lot of webs before hero encounters it */
if (webmaker(ptr) && !mtmp->mspec_used && !t_at(mtmp->mx, mtmp->my)) {
struct trap *trap;
int prob = ((ptr == &mons[PM_GIANT_SPIDER]) ? 15 : 5)
* (count_webbing_walls(mtmp->mx, mtmp->my) + 1);
if (rn2(1000) < prob
&& (trap = maketrap(mtmp->mx, mtmp->my, WEB)) != 0) {
mtmp->mspec_used = d(4, 4); /* 4..16 */
if (cansee(mtmp->mx, mtmp->my)) {
char mbuf[BUFSZ];
Strcpy(mbuf,
canspotmon(mtmp) ? y_monnam(mtmp) : something);
pline("%s spins a web.", upstart(mbuf));
trap->tseen = 1;
}
}
}
if (hides_under(ptr) || ptr->mlet == S_EEL) { if (hides_under(ptr) || ptr->mlet == S_EEL) {
/* Always set--or reset--mundetected if it's already hidden /* Always set--or reset--mundetected if it's already hidden
(just in case the object it was hiding under went away); (just in case the object it was hiding under went away);
+1 -1
View File
@@ -2115,7 +2115,7 @@ const char *const *alt_as_is; /* another set like as_is[] */
/* skip "ox" -> "oxen" entry when pluralizing "<something>ox" /* skip "ox" -> "oxen" entry when pluralizing "<something>ox"
unless it is muskox */ unless it is muskox */
if (to_plural && baselen > 2 && !strcmpi(endstring - 2, "ox") if (to_plural && baselen > 2 && !strcmpi(endstring - 2, "ox")
&& baselen > 5 && strcmpi(endstring - 6, "muskox")) { && !(baselen > 5 && !strcmpi(endstring - 6, "muskox"))) {
/* "fox" -> "foxes" */ /* "fox" -> "foxes" */
Strcasecpy(endstring, "es"); Strcasecpy(endstring, "es");
return TRUE; return TRUE;
+19 -12
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 options.c $NHDT-Date: 1543395749 2018/11/28 09:02:29 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.334 $ */ /* 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 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Michael Allison, 2008. */ /*-Copyright (c) Michael Allison, 2008. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -106,7 +106,7 @@ static struct Bool_Opt {
#endif #endif
{ "clicklook", &iflags.clicklook, FALSE, SET_IN_GAME }, { "clicklook", &iflags.clicklook, FALSE, SET_IN_GAME },
{ "cmdassist", &iflags.cmdassist, TRUE, SET_IN_GAME }, { "cmdassist", &iflags.cmdassist, TRUE, SET_IN_GAME },
#if defined(MICRO) || defined(WIN32) #if defined(MICRO) || defined(WIN32) || defined(CURSES_GRAPHICS)
{ "color", &iflags.wc_color, TRUE, SET_IN_GAME }, /*WC*/ { "color", &iflags.wc_color, TRUE, SET_IN_GAME }, /*WC*/
#else /* systems that support multiple terminals, many monochrome */ #else /* systems that support multiple terminals, many monochrome */
{ "color", &iflags.wc_color, FALSE, SET_IN_GAME }, /*WC*/ { "color", &iflags.wc_color, FALSE, SET_IN_GAME }, /*WC*/
@@ -747,8 +747,6 @@ initoptions_init()
warnsyms[i] = def_warnsyms[i].sym; warnsyms[i] = def_warnsyms[i].sym;
iflags.bouldersym = 0; iflags.bouldersym = 0;
iflags.travelcc.x = iflags.travelcc.y = -1;
/* for "special achievement" tracking (see obj.h, /* for "special achievement" tracking (see obj.h,
create_object(sp_lev.c), addinv_core1(invent.c) */ create_object(sp_lev.c), addinv_core1(invent.c) */
iflags.mines_prize_type = LUCKSTONE; iflags.mines_prize_type = LUCKSTONE;
@@ -875,11 +873,16 @@ initoptions_finish()
* A multi-interface binary might only support status highlighting * A multi-interface binary might only support status highlighting
* for some of the interfaces; check whether we asked for it but are * for some of the interfaces; check whether we asked for it but are
* using one which doesn't. * 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")) { if (!WINDOWPORT("safe-startup")) {
raw_printf("Status highlighting not supported for %s interface.", if (iflags.hilite_delta && !wc2_supported("statushilites")) {
windowprocs.name); raw_printf("Status highlighting not supported for %s interface.",
iflags.hilite_delta = 0; windowprocs.name);
iflags.hilite_delta = 0;
}
} }
#endif #endif
return; return;
@@ -4285,7 +4288,7 @@ static struct other_opts {
int NDECL((*othr_count_func)); int NDECL((*othr_count_func));
} othropt[] = { } othropt[] = {
{ "autopickup exceptions", SET_IN_GAME, OPT_OTHER_APEXC, count_apes }, { "autopickup exceptions", SET_IN_GAME, OPT_OTHER_APEXC, count_apes },
{ "menucolors", SET_IN_GAME, OPT_OTHER_MENUCOLOR, count_menucolors }, { "menu colors", SET_IN_GAME, OPT_OTHER_MENUCOLOR, count_menucolors },
{ "message types", SET_IN_GAME, OPT_OTHER_MSGTYPE, msgtype_count }, { "message types", SET_IN_GAME, OPT_OTHER_MSGTYPE, msgtype_count },
#ifdef STATUS_HILITES #ifdef STATUS_HILITES
{ "status hilite rules", SET_IN_GAME, OPT_OTHER_STATHILITE, { "status hilite rules", SET_IN_GAME, OPT_OTHER_STATHILITE,
@@ -4459,7 +4462,7 @@ doset() /* changing options via menu by Per Liboriussen */
} }
#endif #endif
} else if (opt_indx == OPT_OTHER_MENUCOLOR) { } else if (opt_indx == OPT_OTHER_MENUCOLOR) {
(void) special_handling("menucolors", setinitial, (void) special_handling("menu_colors", setinitial,
fromfile); fromfile);
} else if (opt_indx == OPT_OTHER_MSGTYPE) { } else if (opt_indx == OPT_OTHER_MSGTYPE) {
(void) special_handling("msgtype", setinitial, fromfile); (void) special_handling("msgtype", setinitial, fromfile);
@@ -5038,7 +5041,7 @@ boolean setinitial, setfromfile;
if (pick_cnt >= 0) if (pick_cnt >= 0)
goto msgtypes_again; goto msgtypes_again;
} }
} else if (!strcmp("menucolors", optname)) { } else if (!strcmp("menu_colors", optname)) {
int opt_idx, nmc, mcclr, mcattr; int opt_idx, nmc, mcclr, mcattr;
char mcbuf[BUFSZ] = DUMMY; char mcbuf[BUFSZ] = DUMMY;
@@ -5046,11 +5049,15 @@ boolean setinitial, setfromfile;
nmc = count_menucolors(); nmc = count_menucolors();
opt_idx = handle_add_list_remove("menucolor", nmc); opt_idx = handle_add_list_remove("menucolor", nmc);
if (opt_idx == 3) { /* done */ if (opt_idx == 3) { /* done */
menucolors_done:
if (nmc > 0 && !iflags.use_menu_color)
pline(
"To have menu colors become active, toggle 'menucolors' option to True.");
return TRUE; return TRUE;
} else if (opt_idx == 0) { /* add new */ } else if (opt_idx == 0) { /* add new */
getlin("What new menucolor pattern?", mcbuf); getlin("What new menucolor pattern?", mcbuf);
if (*mcbuf == '\033') if (*mcbuf == '\033')
return TRUE; goto menucolors_done;
if (*mcbuf if (*mcbuf
&& test_regex_pattern(mcbuf, (const char *)0) && test_regex_pattern(mcbuf, (const char *)0)
&& (mcclr = query_color((char *) 0)) != -1 && (mcclr = query_color((char *) 0)) != -1
+2
View File
@@ -187,6 +187,8 @@ struct obj **obj_p;
otmp->quan = 2L; /* to force pluralization */ otmp->quan = 2L; /* to force pluralization */
else if (otmp->otyp == SLIME_MOLD) else if (otmp->otyp == SLIME_MOLD)
otmp->spe = context.current_fruit; /* give it a type */ otmp->spe = context.current_fruit; /* give it a type */
else if (otmp->otyp == LEASH)
otmp->leashmon = 0;
if (mtmp && has_mcorpsenm(mtmp)) /* mimic as corpse/statue */ if (mtmp && has_mcorpsenm(mtmp)) /* mimic as corpse/statue */
otmp->corpsenm = MCORPSENM(mtmp); otmp->corpsenm = MCORPSENM(mtmp);
else if (otmp->otyp == CORPSE && glyph_is_body(glyph)) else if (otmp->otyp == CORPSE && glyph_is_body(glyph))
+11 -3
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 restore.c $NHDT-Date: 1542798626 2018/11/21 11:10:26 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.109 $ */ /* NetHack 3.6 restore.c $NHDT-Date: 1543972193 2018/12/05 01:09:53 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.128 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Michael Allison, 2009. */ /*-Copyright (c) Michael Allison, 2009. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -539,6 +539,7 @@ unsigned int *stuckid, *steedid;
#ifdef SYSFLAGS #ifdef SYSFLAGS
struct sysflag newgamesysflags; struct sysflag newgamesysflags;
#endif #endif
struct context_info newgamecontext; /* all 0, but has some pointers */
struct obj *otmp, *tmp_bc; struct obj *otmp, *tmp_bc;
char timebuf[15]; char timebuf[15];
unsigned long uid; unsigned long uid;
@@ -553,9 +554,15 @@ unsigned int *stuckid, *steedid;
if (!wizard) if (!wizard)
return FALSE; return FALSE;
} }
newgamecontext = context; /* copy statically init'd context */
mread(fd, (genericptr_t) &context, sizeof (struct context_info)); mread(fd, (genericptr_t) &context, sizeof (struct context_info));
if (context.warntype.speciesidx >= LOW_PM) context.warntype.species = (context.warntype.speciesidx >= LOW_PM)
context.warntype.species = &mons[context.warntype.speciesidx]; ? &mons[context.warntype.speciesidx]
: (struct permonst *) 0;
/* context.victual.piece, .tin.tin, .spellbook.book, and .polearm.hitmon
are pointers which get set to Null during save and will be recovered
via corresponding o_id or m_id while objs or mons are being restored */
/* we want to be able to revert to command line/environment/config /* we want to be able to revert to command line/environment/config
file option values instead of keeping old save file option values file option values instead of keeping old save file option values
@@ -625,6 +632,7 @@ unsigned int *stuckid, *steedid;
#ifdef SYSFLAGS #ifdef SYSFLAGS
sysflags = newgamesysflags; sysflags = newgamesysflags;
#endif #endif
context = newgamecontext;
return FALSE; return FALSE;
} }
/* in case hangup save occurred in midst of level change */ /* in case hangup save occurred in midst of level change */
+6 -21
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 save.c $NHDT-Date: 1489192905 2017/03/11 00:41:45 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.101 $ */ /* NetHack 3.6 save.c $NHDT-Date: 1543972194 2018/12/05 01:09:54 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.115 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Michael Allison, 2009. */ /*-Copyright (c) Michael Allison, 2009. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -1035,37 +1035,22 @@ register struct obj *otmp;
if (Has_contents(otmp)) if (Has_contents(otmp))
saveobjchn(fd, otmp->cobj, mode); saveobjchn(fd, otmp->cobj, mode);
if (release_data(mode)) { if (release_data(mode)) {
/* if (otmp->oclass == FOOD_CLASS)
* food_disappears(otmp);
*/
/* /*
* If these are on the floor, the discarding could * If these are on the floor, the discarding could be
* be because of a game save, or we could just be changing levels. * due to game save, or we could just be changing levels.
* Always invalidate the pointer, but ensure that we have * Always invalidate the pointer, but ensure that we have
* the o_id in order to restore the pointer on reload. * the o_id in order to restore the pointer on reload.
*/ */
if (otmp == context.victual.piece) { if (otmp == context.victual.piece) {
/* Store the o_id of the victual if mismatched */ context.victual.o_id = otmp->o_id;
if (context.victual.o_id != otmp->o_id)
context.victual.o_id = otmp->o_id;
/* invalidate the pointer; on reload it will get restored */
context.victual.piece = (struct obj *) 0; context.victual.piece = (struct obj *) 0;
} }
if (otmp == context.tin.tin) { if (otmp == context.tin.tin) {
/* Store the o_id of your tin */ context.tin.o_id = otmp->o_id;
if (context.tin.o_id != otmp->o_id)
context.tin.o_id = otmp->o_id;
/* invalidate the pointer; on reload it will get restored */
context.tin.tin = (struct obj *) 0; context.tin.tin = (struct obj *) 0;
} }
/* if (otmp->oclass == SPBOOK_CLASS)
* book_disappears(otmp);
*/
if (otmp == context.spbook.book) { if (otmp == context.spbook.book) {
/* Store the o_id of your spellbook */ context.spbook.o_id = otmp->o_id;
if (context.spbook.o_id != otmp->o_id)
context.spbook.o_id = otmp->o_id;
/* invalidate the pointer; on reload it will get restored */
context.spbook.book = (struct obj *) 0; context.spbook.book = (struct obj *) 0;
} }
otmp->where = OBJ_FREE; /* set to free so dealloc will work */ otmp->where = OBJ_FREE; /* set to free so dealloc will work */
+66 -12
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 timeout.c $NHDT-Date: 1541902953 2018/11/11 02:22:33 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.84 $ */ /* NetHack 3.6 timeout.c $NHDT-Date: 1544050558 2018/12/05 22:55:58 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.88 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2018. */ /*-Copyright (c) Robert Patrick Rankin, 2018. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -11,6 +11,7 @@ STATIC_DCL void NDECL(vomiting_dialogue);
STATIC_DCL void NDECL(choke_dialogue); STATIC_DCL void NDECL(choke_dialogue);
STATIC_DCL void NDECL(levitation_dialogue); STATIC_DCL void NDECL(levitation_dialogue);
STATIC_DCL void NDECL(slime_dialogue); STATIC_DCL void NDECL(slime_dialogue);
STATIC_DCL void FDECL(slimed_to_death, (struct kinfo *));
STATIC_DCL void NDECL(slip_or_trip); STATIC_DCL void NDECL(slip_or_trip);
STATIC_DCL void FDECL(see_lamp_flicker, (struct obj *, const char *)); STATIC_DCL void FDECL(see_lamp_flicker, (struct obj *, const char *));
STATIC_DCL void FDECL(lantern_message, (struct obj *)); STATIC_DCL void FDECL(lantern_message, (struct obj *));
@@ -310,6 +311,13 @@ slime_dialogue()
{ {
register long i = (Slimed & TIMEOUT) / 2L; register long i = (Slimed & TIMEOUT) / 2L;
if (i == 1L) {
/* display as green slime during "You have become green slime."
but don't worry about not being able to see self; if already
mimicking something else at the time, implicitly be revealed */
youmonst.m_ap_type = M_AP_MONSTER;
youmonst.mappearance = PM_GREEN_SLIME;
}
if (((Slimed & TIMEOUT) % 2L) && i >= 0L && i < SIZE(slime_texts)) { if (((Slimed & TIMEOUT) % 2L) && i >= 0L && i < SIZE(slime_texts)) {
char buf[BUFSZ]; char buf[BUFSZ];
@@ -357,6 +365,62 @@ burn_away_slime()
} }
} }
/* countdown timer for turning into green slime has run out; kill our hero */
STATIC_OVL void
slimed_to_death(kptr)
struct kinfo *kptr;
{
uchar save_mvflags;
/* redundant: polymon() cures sliming when polying into green slime */
if (Upolyd && youmonst.data == &mons[PM_GREEN_SLIME]) {
dealloc_killer(kptr);
return;
}
/* more sure killer reason is set up */
if (kptr && kptr->name[0]) {
killer.format = kptr->format;
Strcpy(killer.name, kptr->name);
} else {
killer.format = NO_KILLER_PREFIX;
Strcpy(killer.name, "turned into green slime");
}
dealloc_killer(kptr);
/*
* Polymorph into a green slime, which might destroy some worn armor
* (potentially affecting bones) and dismount from steed.
* Can't be Unchanging; wouldn't have turned into slime if we were.
* Despite lack of Unchanging, neither done() nor savelife() calls
* rehumanize() if hero dies while polymorphed.
* polymon() undoes the slime countdown's mimick-green-slime hack
* but does not perform polyself()'s light source bookkeeping.
* No longer need to manually increment uconduct.polyselfs to reflect
* [formerly implicit] change of form; polymon() takes care of that.
* Temporarily ungenocide if necessary.
*/
if (emits_light(youmonst.data))
del_light_source(LS_MONSTER, monst_to_any(&youmonst));
save_mvflags = mvitals[PM_GREEN_SLIME].mvflags;
mvitals[PM_GREEN_SLIME].mvflags = save_mvflags & ~G_GENOD;
(void) polymon(PM_GREEN_SLIME);
mvitals[PM_GREEN_SLIME].mvflags = save_mvflags;
done(TURNED_SLIME);
/* life-saved; even so, hero still has turned into green slime;
player may have genocided green slimes after being infected */
if ((mvitals[PM_GREEN_SLIME].mvflags & G_GENOD) != 0) {
killer.format = KILLED_BY;
Strcpy(killer.name, "slimicide");
/* immediately follows "OK, so you don't die." */
pline("Yes, you do. Green slime has been genocided...");
done(GENOCIDED);
/* could be life-saved again (only in explore or wizard mode)
but green slimes are gone; just stay in current form */
}
return;
}
/* Intrinsic Passes_walls is temporary when your god is trying to fix /* Intrinsic Passes_walls is temporary when your god is trying to fix
all troubles and then TROUBLE_STUCK_IN_WALL calls safe_teleds() but all troubles and then TROUBLE_STUCK_IN_WALL calls safe_teleds() but
it can't find anywhere to place you. If that happens you get a small it can't find anywhere to place you. If that happens you get a small
@@ -469,17 +533,7 @@ nh_timeout()
done(STONING); done(STONING);
break; break;
case SLIMED: case SLIMED:
if (kptr && kptr->name[0]) { slimed_to_death(kptr); /* done(TURNED_SLIME) */
killer.format = kptr->format;
Strcpy(killer.name, kptr->name);
} else {
killer.format = NO_KILLER_PREFIX;
Strcpy(killer.name, "turned into green slime");
}
dealloc_killer(kptr);
/* involuntarily break "never changed form" conduct */
u.uconduct.polyselfs++;
done(TURNED_SLIME);
break; break;
case VOMITING: case VOMITING:
make_vomiting(0L, TRUE); make_vomiting(0L, TRUE);
+5 -3
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 uhitm.c $NHDT-Date: 1542765366 2018/11/21 01:56:06 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.185 $ */ /* NetHack 3.6 uhitm.c $NHDT-Date: 1543892215 2018/12/04 02:56:55 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.195 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2012. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -449,7 +449,9 @@ int rollneeded, armorpenalty; /* for monks */
struct attack *uattk; struct attack *uattk;
int dieroll; int dieroll;
{ {
register boolean malive = TRUE; boolean malive = TRUE,
/* hmon() might destroy weapon; remember aspect for cutworm */
slice_or_chop = (weapon && (is_blade(weapon) || is_axe(weapon)));
if (override_confirmation) { if (override_confirmation) {
/* this may need to be generalized if weapons other than /* this may need to be generalized if weapons other than
@@ -490,7 +492,7 @@ int dieroll;
u.uconduct.weaphit = oldweaphit; u.uconduct.weaphit = oldweaphit;
} }
if (mon->wormno && *mhit) if (mon->wormno && *mhit)
cutworm(mon, x, y, weapon); cutworm(mon, x, y, slice_or_chop);
} }
} }
return malive; return malive;
+7 -9
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 worm.c $NHDT-Date: 1456528599 2016/02/26 23:16:39 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.20 $ */ /* NetHack 3.6 worm.c $NHDT-Date: 1543892216 2018/12/04 02:56:56 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.28 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2009. */ /*-Copyright (c) Robert Patrick Rankin, 2009. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -314,10 +314,10 @@ register struct monst *worm;
* that both halves will survive. * that both halves will survive.
*/ */
void void
cutworm(worm, x, y, weap) cutworm(worm, x, y, cuttier)
struct monst *worm; struct monst *worm;
xchar x, y; xchar x, y;
struct obj *weap; boolean cuttier; /* hit is by wielded blade or axe or by thrown axe */
{ {
register struct wseg *curr, *new_tail; register struct wseg *curr, *new_tail;
register struct monst *new_worm; register struct monst *new_worm;
@@ -330,12 +330,10 @@ struct obj *weap;
if (x == worm->mx && y == worm->my) if (x == worm->mx && y == worm->my)
return; /* hit on head */ return; /* hit on head */
/* cutting goes best with a bladed weapon */ /* cutting goes best with a cuttier weapon */
cut_chance = rnd(20); /* Normally 1-16 does not cut */ cut_chance = rnd(20); /* Normally 1-16 does not cut, 17-20 does, */
/* Normally 17-20 does */ if (cuttier)
cut_chance += 10; /* with a blade 1- 6 does not cut, 7-20 does. */
if (weap && is_blade(weap)) /* With a blade 1- 6 does not cut */
cut_chance += 10; /* 7-20 does */
if (cut_chance < 17) if (cut_chance < 17)
return; /* not good enough */ return; /* not good enough */
+220 -138
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 zap.c $NHDT-Date: 1543744276 2018/12/02 09:51:16 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.299 $ */ /* 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 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2013. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -28,11 +28,12 @@ STATIC_DCL void FDECL(zhitu, (int, int, const char *, XCHAR_P, XCHAR_P));
STATIC_DCL void FDECL(revive_egg, (struct obj *)); STATIC_DCL void FDECL(revive_egg, (struct obj *));
STATIC_DCL boolean FDECL(zap_steed, (struct obj *)); STATIC_DCL boolean FDECL(zap_steed, (struct obj *));
STATIC_DCL void FDECL(skiprange, (int, int *, int *)); STATIC_DCL void FDECL(skiprange, (int, int *, int *));
STATIC_DCL int FDECL(zap_hit, (int, int)); STATIC_DCL int FDECL(zap_hit, (int, int));
STATIC_OVL void FDECL(disintegrate_mon, (struct monst *, int, const char *)); STATIC_OVL void FDECL(disintegrate_mon, (struct monst *, int, const char *));
STATIC_DCL void FDECL(backfire, (struct obj *)); STATIC_DCL void FDECL(backfire, (struct obj *));
STATIC_DCL int FDECL(spell_hit_bonus, (int)); STATIC_DCL int FDECL(spell_hit_bonus, (int));
STATIC_DCL void FDECL(destroy_one_item, (struct obj *, int, int));
STATIC_DCL void FDECL(wishcmdassist, (int));
#define ZT_MAGIC_MISSILE (AD_MAGM - 1) #define ZT_MAGIC_MISSILE (AD_MAGM - 1)
#define ZT_FIRE (AD_FIRE - 1) #define ZT_FIRE (AD_FIRE - 1)
@@ -1846,6 +1847,10 @@ struct obj *obj, *otmp;
* menu_drop(), askchain() - inventory traversal where multiple * menu_drop(), askchain() - inventory traversal where multiple
* Drop can alter the invent chain while traversal * Drop can alter the invent chain while traversal
* is in progress (bhito isn't involved). * is in progress (bhito isn't involved).
* destroy_item(), destroy_mitem() - inventory traversal where
* item destruction can trigger drop or destruction of
* other item(s) and alter the invent or mon->minvent
* chain, possibly recursively.
* *
* The bypass bit on all objects is reset each turn, whenever * The bypass bit on all objects is reset each turn, whenever
* context.bypasses is set. * context.bypasses is set.
@@ -4715,160 +4720,234 @@ const char *const destroy_strings[][3] = {
{ "breaks apart and explodes", "", "exploding wand" }, { "breaks apart and explodes", "", "exploding wand" },
}; };
void /* guts of destroy_item(), which ought to be called maybe_destroy_items();
destroy_item(osym, dmgtyp) caller must decide whether obj is eligible */
register int osym, dmgtyp; STATIC_OVL void
destroy_one_item(obj, osym, dmgtyp)
struct obj *obj;
int osym, dmgtyp;
{ {
register struct obj *obj, *obj2;
int dmg, xresist, skip;
long i, cnt, quan; long i, cnt, quan;
int dindx; int dmg, xresist, skip, dindx;
const char *mult; const char *mult;
boolean physical_damage; boolean physical_damage;
for (obj = invent; obj; obj = obj2) { physical_damage = FALSE;
obj2 = obj->nobj; xresist = skip = 0;
physical_damage = FALSE; /* lint suppression */
if (obj->oclass != osym) dmg = dindx = 0;
continue; /* test only objs of type osym */ quan = 0L;
if (obj->oartifact)
continue; /* don't destroy artifacts */
if (obj->in_use && obj->quan == 1L)
continue; /* not available */
xresist = skip = 0;
/* lint suppression */
dmg = dindx = 0;
quan = 0L;
switch (dmgtyp) { switch (dmgtyp) {
case AD_COLD: case AD_COLD:
if (osym == POTION_CLASS && obj->otyp != POT_OIL) { if (osym == POTION_CLASS && obj->otyp != POT_OIL) {
quan = obj->quan;
dindx = 0;
dmg = rnd(4);
} else
skip++;
break;
case AD_FIRE:
xresist = (Fire_resistance && obj->oclass != POTION_CLASS
&& obj->otyp != GLOB_OF_GREEN_SLIME);
if (obj->otyp == SCR_FIRE || obj->otyp == SPE_FIREBALL)
skip++;
if (obj->otyp == SPE_BOOK_OF_THE_DEAD) {
skip++;
if (!Blind)
pline("%s glows a strange %s, but remains intact.",
The(xname(obj)), hcolor("dark red"));
}
quan = obj->quan; quan = obj->quan;
switch (osym) { dindx = 0;
case POTION_CLASS: dmg = rnd(4);
dindx = (obj->otyp != POT_OIL) ? 1 : 2; } else
dmg = rnd(6); skip++;
break; break;
case SCROLL_CLASS: case AD_FIRE:
dindx = 3; xresist = (Fire_resistance && obj->oclass != POTION_CLASS
dmg = 1; && obj->otyp != GLOB_OF_GREEN_SLIME);
break; if (obj->otyp == SCR_FIRE || obj->otyp == SPE_FIREBALL)
case SPBOOK_CLASS: skip++;
dindx = 4; if (obj->otyp == SPE_BOOK_OF_THE_DEAD) {
dmg = 1; skip++;
break; if (!Blind)
case FOOD_CLASS: pline("%s glows a strange %s, but remains intact.",
if (obj->otyp == GLOB_OF_GREEN_SLIME) { The(xname(obj)), hcolor("dark red"));
dindx = 1; /* boil and explode */ }
dmg = (obj->owt + 19) / 20; quan = obj->quan;
} else { switch (osym) {
skip++; case POTION_CLASS:
} dindx = (obj->otyp != POT_OIL) ? 1 : 2;
break; dmg = rnd(6);
default:
skip++;
break;
}
break; break;
case AD_ELEC: case SCROLL_CLASS:
xresist = (Shock_resistance && obj->oclass != RING_CLASS); dindx = 3;
quan = obj->quan; dmg = 1;
switch (osym) { break;
case RING_CLASS: case SPBOOK_CLASS:
if (obj->otyp == RIN_SHOCK_RESISTANCE) { dindx = 4;
skip++; dmg = 1;
break; break;
} case FOOD_CLASS:
dindx = 5; if (obj->otyp == GLOB_OF_GREEN_SLIME) {
dmg = 0; dindx = 1; /* boil and explode */
break; dmg = (obj->owt + 19) / 20;
case WAND_CLASS: } else {
if (obj->otyp == WAN_LIGHTNING) {
skip++;
break;
}
#if 0
if (obj == current_wand) { skip++; break; }
#endif
dindx = 6;
dmg = rnd(10);
break;
default:
skip++; skip++;
break;
} }
break; break;
default: default:
skip++; skip++;
break; break;
} }
if (!skip) { break;
if (obj->in_use) case AD_ELEC:
--quan; /* one will be used up elsewhere */ xresist = (Shock_resistance && obj->oclass != RING_CLASS);
for (i = cnt = 0L; i < quan; i++) quan = obj->quan;
if (!rn2(3)) switch (osym) {
cnt++; case RING_CLASS:
if (obj->otyp == RIN_SHOCK_RESISTANCE) {
if (!cnt) skip++;
continue; break;
mult = (cnt == 1L)
? (quan == 1L) ? "Your" /* 1 of 1 */
: "One of your" /* 1 of N */
: (cnt < quan) ? "Some of your" /* n of N */
: (quan == 2L) ? "Both of your" /* 2 of 2 */
: "All of your"; /* N of N */
pline("%s %s %s!", mult, xname(obj),
destroy_strings[dindx][(cnt > 1L)]);
if (osym == POTION_CLASS && dmgtyp != AD_COLD) {
if (!breathless(youmonst.data) || haseyes(youmonst.data))
potionbreathe(obj);
} }
if (obj->owornmask) { dindx = 5;
if (obj->owornmask & W_RING) /* ring being worn */ dmg = 0;
Ring_gone(obj); break;
else case WAND_CLASS:
setnotworn(obj); if (obj->otyp == WAN_LIGHTNING) {
skip++;
break;
} }
if (obj == current_wand) #if 0
current_wand = 0; /* destroyed */ if (obj == current_wand) { skip++; break; }
for (i = 0; i < cnt; i++) #endif
useup(obj); dindx = 6;
if (dmg) { dmg = rnd(10);
if (xresist) break;
You("aren't hurt!"); default:
else { skip++;
const char *how = destroy_strings[dindx][2]; break;
boolean one = (cnt == 1L); }
break;
default:
skip++;
break;
}
if (dmgtyp == AD_FIRE && osym == FOOD_CLASS) if (!skip) {
how = "exploding glob of slime"; if (obj->in_use)
if (physical_damage) --quan; /* one will be used up elsewhere */
dmg = Maybe_Half_Phys(dmg); for (i = cnt = 0L; i < quan; i++)
losehp(dmg, one ? how : (const char *) makeplural(how), if (!rn2(3))
one ? KILLED_BY_AN : KILLED_BY); cnt++;
exercise(A_STR, FALSE);
} if (!cnt)
return;
mult = (cnt == 1L)
? ((quan == 1L) ? "Your" /* 1 of 1 */
: "One of your") /* 1 of N */
: ((cnt < quan) ? "Some of your" /* n of N */
: (quan == 2L) ? "Both of your" /* 2 of 2 */
: "All of your"); /* N of N */
pline("%s %s %s!", mult, xname(obj),
destroy_strings[dindx][(cnt > 1L)]);
if (osym == POTION_CLASS && dmgtyp != AD_COLD) {
if (!breathless(youmonst.data) || haseyes(youmonst.data))
potionbreathe(obj);
}
if (obj->owornmask) {
if (obj->owornmask & W_RING) /* ring being worn */
Ring_gone(obj);
else
setnotworn(obj);
}
if (obj == current_wand)
current_wand = 0; /* destroyed */
for (i = 0; i < cnt; i++)
useup(obj);
if (dmg) {
if (xresist) {
You("aren't hurt!");
} else {
const char *how = destroy_strings[dindx][2];
boolean one = (cnt == 1L);
if (dmgtyp == AD_FIRE && osym == FOOD_CLASS)
how = "exploding glob of slime";
if (physical_damage)
dmg = Maybe_Half_Phys(dmg);
losehp(dmg, one ? how : (const char *) makeplural(how),
one ? KILLED_BY_AN : KILLED_BY);
exercise(A_STR, FALSE);
} }
} }
} }
}
/* target items of specified class for possible destruction */
void
destroy_item(osym, dmgtyp)
int osym, dmgtyp;
{
register struct obj *obj;
int i, deferral_indx = 0;
/* 1+52+1: try to handle a full inventory; it doesn't matter if
inventory actually has more, even if everything should be deferred */
unsigned short deferrals[1 + 52 + 1]; /* +1: gold, overflow */
(void) memset((genericptr_t) deferrals, 0, sizeof deferrals);
/*
* Sometimes destroying an item can change inventory aside from
* the item itself (cited case was a potion of unholy water; when
* boiled, potionbreathe() caused hero to transform into were-beast
* form and that resulted in dropping or destroying some worn armor).
*
* Unlike other uses of the object bybass mechanism, destroy_item()
* can be called multiple times for the same event. So we have to
* explicitly clear it before each use and hope no other section of
* code expects it to retain previous value.
*
* Destruction of a ring of levitation or form change which pushes
* off levitation boots could drop hero onto a fire trap that
* could destroy other items and we'll get called recursively. Or
* onto a trap which transports hero elsewhere, which won't disrupt
* traversal but could yield message sequencing issues. So we
* defer handling such things until after rest of inventory has
* been processed. If some other combination of items and events
* triggers a recursive call, rest of inventory after the triggering
* item will be skipped by the outer call since the inner one will
* have set the bypass bits of the whole list.
*
* [Unfortunately, death while poly'd into flyer and subsequent
* rehumanization could also drop hero onto a trap, and there's no
* straightforward way to defer that. Things could be improved by
* redoing this to use two passes, first to collect a list or array
* of o_id and quantity of what is targetted for destruction,
* second pass to handle the destruction.]
*/
bypass_objlist(invent, FALSE); /* clear bypass bit for invent */
while ((obj = nxt_unbypassed_obj(invent)) != 0) {
if (obj->oclass != osym)
continue; /* test only objs of type osym */
if (obj->oartifact)
continue; /* don't destroy artifacts */
if (obj->in_use && obj->quan == 1L)
continue; /* not available */
/* if loss of this item might dump us onto a trap, hold off
until later because potential recursive destroy_item() will
result in setting bypass bits on whole chain--we would skip
the rest as already processed once control returns here */
if (deferral_indx < SIZE(deferrals)
&& ((obj->owornmask != 0L
&& (objects[obj->otyp].oc_oprop == LEVITATION
|| objects[obj->otyp].oc_oprop == FLYING))
/* destroyed wands and potions of polymorph don't trigger
polymorph so don't need to be deferred */
|| (obj->otyp == POT_WATER && u.ulycn >= LOW_PM
&& (Upolyd ? obj->blessed : obj->cursed)))) {
deferrals[deferral_indx++] = obj->o_id;
continue;
}
/* obj is eligible; maybe destroy it */
destroy_one_item(obj, osym, dmgtyp);
}
/* if we saved some items for later (most likely just a worn ring
of levitation) and they're still in inventory, handle them now */
for (i = 0; i < deferral_indx; ++i) {
/* note: obj->nobj is only referenced when obj is skipped;
having obj be dropped or destroyed won't affect traversal */
for (obj = invent; obj; obj = obj->nobj)
if (obj->o_id == deferrals[i]) {
destroy_one_item(obj, osym, dmgtyp);
break;
}
}
return; return;
} }
@@ -4877,7 +4956,7 @@ destroy_mitem(mtmp, osym, dmgtyp)
struct monst *mtmp; struct monst *mtmp;
int osym, dmgtyp; int osym, dmgtyp;
{ {
struct obj *obj, *obj2; struct obj *obj;
int skip, tmp = 0; int skip, tmp = 0;
long i, cnt, quan; long i, cnt, quan;
int dindx; int dindx;
@@ -4889,8 +4968,11 @@ int osym, dmgtyp;
} }
vis = canseemon(mtmp); vis = canseemon(mtmp);
for (obj = mtmp->minvent; obj; obj = obj2) {
obj2 = obj->nobj; /* see destroy_item(); object destruction could disrupt inventory list */
bypass_objlist(mtmp->minvent, FALSE); /* clear bypass bit for minvent */
while ((obj = nxt_unbypassed_obj(mtmp->minvent)) != 0) {
if (obj->oclass != osym) if (obj->oclass != osym)
continue; /* test only objs of type osym */ continue; /* test only objs of type osym */
skip = 0; skip = 0;
+11 -259
View File
@@ -3,11 +3,7 @@
/*-Copyright (c) Derek S. Ray, 2015. */ /*-Copyright (c) Derek S. Ray, 2015. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
/* main.c - MSDOS, OS/2, ST, Amiga, and Windows NetHack */ /* main.c - MSDOS, OS/2, ST, Amiga NetHack */
#ifdef WIN32
#include "win32api.h" /* for GetModuleFileName */
#endif
#include "hack.h" #include "hack.h"
#include "dlb.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 FDECL(process_options, (int argc, char **argv));
STATIC_DCL void NDECL(nhusage); STATIC_DCL void NDECL(nhusage);
#if defined(MICRO) || defined(WIN32) || defined(OS2) #if defined(MICRO) || defined(OS2)
extern void FDECL(nethack_exit, (int)); extern void FDECL(nethack_exit, (int));
#else #else
#define nethack_exit exit #define nethack_exit exit
#endif #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 #ifdef EXEPATH
STATIC_DCL char *FDECL(exepath, (char *)); STATIC_DCL char *FDECL(exepath, (char *));
#endif #endif
@@ -78,7 +57,7 @@ int FDECL(main, (int, char **));
extern boolean FDECL(pcmain, (int, char **)); extern boolean FDECL(pcmain, (int, char **));
#if defined(__BORLANDC__) && !defined(_WIN32) #if defined(__BORLANDC__)
void NDECL(startup); void NDECL(startup);
unsigned _stklen = STKSIZ; unsigned _stklen = STKSIZ;
#endif #endif
@@ -98,21 +77,8 @@ char *argv[];
{ {
boolean resuming; boolean resuming;
nethack_enter(argc, argv);
sys_early_init(); 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); resuming = pcmain(argc, argv);
#ifdef LAN_FEATURES
init_lan_features();
#endif
moveloop(resuming); moveloop(resuming);
nethack_exit(EXIT_SUCCESS); nethack_exit(EXIT_SUCCESS);
/*NOTREACHED*/ /*NOTREACHED*/
@@ -126,14 +92,10 @@ char *argv[];
{ {
register int fd; register int fd;
register char *dir; register char *dir;
#if defined(WIN32) || defined(MSDOS) #if defined(MSDOS)
char *envp = NULL; char *envp = NULL;
char *sptr = NULL; char *sptr = NULL;
#endif #endif
#if defined(WIN32)
char fnamebuf[BUFSZ], encodedfnamebuf[BUFSZ];
boolean save_getreturn_status = getreturn_enabled;
#endif
#ifdef NOCWD_ASSUMPTIONS #ifdef NOCWD_ASSUMPTIONS
char failbuf[BUFSZ]; char failbuf[BUFSZ];
#endif #endif
@@ -162,7 +124,7 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/
# endif # endif
#endif #endif
#if defined(__BORLANDC__) && !defined(_WIN32) #if defined(__BORLANDC__)
startup(); startup();
#endif #endif
@@ -175,15 +137,7 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/
#endif #endif
hname = "NetHack"; /* used for syntax messages */ hname = "NetHack"; /* used for syntax messages */
#ifndef WIN32
choose_windows(DEFAULT_WINDOW_SYS); 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) #if !defined(AMIGA) && !defined(GNUDOS)
/* Save current directory and make sure it gets restored when /* 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++) for (prefcnt = 1; prefcnt < PREFIX_COUNT; prefcnt++)
fqn_prefix[prefcnt] = fqn_prefix[0]; fqn_prefix[prefcnt] = fqn_prefix[0];
#if defined(WIN32) || defined(MSDOS) #if defined(MSDOS)
/* sysconf should be searched for in this location */ /* sysconf should be searched for in this location */
envp = nh_getenv("COMMONPROGRAMFILES"); envp = nh_getenv("COMMONPROGRAMFILES");
if (envp) { if (envp) {
@@ -317,14 +271,6 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/
chdirx(HACKDIR, 1); chdirx(HACKDIR, 1);
#endif #endif
ami_wininit_data(); 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 #endif
initoptions(); initoptions();
@@ -355,13 +301,6 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/
argv++; 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') { if (argc > 1 && !strncmp(argv[1], "-d", 2) && argv[1][2] != 'e') {
/* avoid matching "-dec" for DECgraphics; since the man page /* avoid matching "-dec" for DECgraphics; since the man page
* says -d directory, hope nobody's using -desomething_else * says -d directory, hope nobody's using -desomething_else
@@ -381,36 +320,11 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/
Strcpy(hackdir, dir); Strcpy(hackdir, dir);
} }
if (argc > 1) { 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 * Now we know the directory containing 'record' and
* may do a prscore(). * may do a prscore().
*/ */
if (!strncmp(argv[1], "-s", 2)) { 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) #if defined(CHDIR) && !defined(NOCWD_ASSUMPTIONS)
chdirx(hackdir, 0); chdirx(hackdir, 0);
#endif #endif
@@ -418,47 +332,16 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/
initoptions(); initoptions();
#endif #endif
prscore(argc, argv); prscore(argc, argv);
#if defined(WIN32) && !defined(WIN32CON)
if (tmpconsole) {
getreturn("to exit");
freefakeconsole();
tmpconsole = FALSE;
}
#endif
nethack_exit(EXIT_SUCCESS); 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 */ /* Don't initialize the window system just to print usage */
if (!strncmp(argv[1], "-?", 2) || !strncmp(argv[1], "/?", 2)) { if (!strncmp(argv[1], "-?", 2) || !strncmp(argv[1], "/?", 2)) {
#if 0
if (!hStdOut) {
GUILaunched = 0;
tmpconsole = fakeconsole();
}
#endif
nhusage(); nhusage();
#if defined(WIN32) && !defined(WIN32CON)
if (tmpconsole) {
getreturn("to exit");
freefakeconsole();
tmpconsole = FALSE;
}
#endif
nethack_exit(EXIT_SUCCESS); nethack_exit(EXIT_SUCCESS);
} }
} }
} }
#ifdef WIN32
getreturn_enabled = save_getreturn_status;
#endif
/* /*
* It seems you really want to play. * It seems you really want to play.
*/ */
@@ -472,11 +355,7 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/
"\"%s\".%s", "\"%s\".%s",
copyright_banner_line(1), copyright_banner_line(2), copyright_banner_line(1), copyright_banner_line(2),
copyright_banner_line(3), copyright_banner_line(4), DLBFILE, 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."); error("dlb_init failure.");
} }
@@ -490,41 +369,22 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/
chdirx(hackdir, 1); chdirx(hackdir, 1);
#endif #endif
#if defined(MSDOS) || defined(WIN32) #if defined(MSDOS)
/* In 3.6.0, several ports process options before they init /* In 3.6.0, several ports process options before they init
* the window port. This allows settings that impact window * the window port. This allows settings that impact window
* ports to be specified or read from the sys or user config files. * ports to be specified or read from the sys or user config files.
*/ */
process_options(argc, argv); process_options(argc, argv);
#ifdef WIN32 #endif /* MSDOS */
/*
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 */
#if defined(MSDOS) || defined(WIN32) #if defined(MSDOS)
init_nhwindows(&argc, argv); init_nhwindows(&argc, argv);
#else #else
init_nhwindows(&argc, argv); init_nhwindows(&argc, argv);
process_options(argc, argv); process_options(argc, argv);
#endif #endif
#if defined(WIN32) && defined(TTY_GRAPHICS)
toggle_mouse_support(); /* must come after process_options */
#endif
#ifdef MFLOPPY #ifdef MFLOPPY
set_lock_and_bones(); set_lock_and_bones();
#ifndef AMIGA #ifndef AMIGA
@@ -561,19 +421,8 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/
* overwritten without confirmation when a user starts up * overwritten without confirmation when a user starts up
* another game with the same player name. * 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); Strcpy(lock, plname);
regularize(lock); regularize(lock);
#endif
getlock(); getlock();
#else /* What follows is !PC_LOCKING */ #else /* What follows is !PC_LOCKING */
#ifdef AMIGA /* We'll put the bones & levels in the user specified directory \ #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) { if (fd < 0) {
raw_print("Cannot create lock file"); raw_print("Cannot create lock file");
} else { } else {
#ifdef WIN32
hackpid = GetCurrentProcessId();
#else
hackpid = 1; hackpid = 1;
#endif
write(fd, (genericptr_t) &hackpid, sizeof(hackpid)); write(fd, (genericptr_t) &hackpid, sizeof(hackpid));
nhclose(fd); nhclose(fd);
} }
@@ -618,10 +463,6 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/
vision_init(); vision_init();
display_gamewindows(); display_gamewindows();
#ifdef WIN32
getreturn_enabled = TRUE;
#endif
/* /*
* First, try to find and restore a save file for specified character. * First, try to find and restore a save file for specified character.
* We'll return here if new game player_selection() renames the hero. * We'll return here if new game player_selection() renames the hero.
@@ -799,18 +640,6 @@ char *argv[];
case 'l': case 'l':
bigscreen = -1; bigscreen = -1;
break; 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 #endif
case '@': case '@':
flags.randomall = 1; flags.randomall = 1;
@@ -904,14 +733,14 @@ boolean wr;
#endif /* CHDIR */ #endif /* CHDIR */
#ifdef PORT_HELP #ifdef PORT_HELP
#if defined(MSDOS) || defined(WIN32) #if defined(MSDOS)
void void
port_help() port_help()
{ {
/* display port specific help file */ /* display port specific help file */
display_file(PORT_HELP, 1); display_file(PORT_HELP, 1);
} }
#endif /* MSDOS || WIN32 */ #endif /* MSDOS */
#endif /* PORT_HELP */ #endif /* PORT_HELP */
/* validate wizard mode if player has requested access to it */ /* validate wizard mode if player has requested access to it */
@@ -930,71 +759,6 @@ authorize_wizard_mode()
#define PATH_SEPARATOR '\\' #define PATH_SEPARATOR '\\'
#endif #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 #define EXEPATHBUFSZ 256
char exepathbuf[EXEPATHBUFSZ]; char exepathbuf[EXEPATHBUFSZ];
@@ -1009,19 +773,7 @@ char *str;
return (char *) 0; return (char *) 0;
bsize = EXEPATHBUFSZ; bsize = EXEPATHBUFSZ;
tmp = exepathbuf; tmp = exepathbuf;
#ifndef WIN32
Strcpy(tmp, str); 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); tmp2 = strrchr(tmp, PATH_SEPARATOR);
if (tmp2) if (tmp2)
*tmp2 = '\0'; *tmp2 = '\0';
+3 -12
View File
@@ -391,19 +391,11 @@ char *name;
return; return;
} }
#ifdef WIN32 #ifndef WIN32
boolean getreturn_enabled;
int redirect_stdout;
#endif
void void
getreturn(str) getreturn(str)
const char *str; const char *str;
{ {
#ifdef WIN32
if (!getreturn_enabled)
return;
#endif
#ifdef TOS #ifdef TOS
msmsg("Hit <Return> %s.", str); msmsg("Hit <Return> %s.", str);
#else #else
@@ -414,7 +406,6 @@ const char *str;
return; return;
} }
#ifndef WIN32
void msmsg void msmsg
VA_DECL(const char *, fmt) VA_DECL(const char *, fmt)
{ {
@@ -492,7 +483,7 @@ const char *name, *mode;
return (FILE *) 0; return (FILE *) 0;
} }
#if defined(MICRO) || defined(WIN32) || defined(OS2) #if defined(MICRO) || defined(OS2)
void void
nethack_exit(code) nethack_exit(code)
int code; int code;
@@ -551,4 +542,4 @@ msexit()
wait_synch(); wait_synch();
return; return;
} }
#endif /* MICRO || WIN32 || OS2 */ #endif /* MICRO || OS2 */
+4 -6
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 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 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 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 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 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 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 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 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 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 DLBOBJ = $(O)dlb.o
@@ -535,7 +535,7 @@ INCLDIR= /I..\include /I..\sys\winnt
# Util builds # Util builds
#========================================== #==========================================
cflagsBuild = $(cflags) $(INCLDIR) $(WINPFLAG) $(DLBFLG) cflagsBuild = $(cflags) $(INCLDIR) $(WINPFLAG) $(DLBFLG) -DSAFEPROCS
lflagsBuild = $(lflags) $(conlibs) $(MACHINE) lflagsBuild = $(lflags) $(conlibs) $(MACHINE)
#========================================== #==========================================
@@ -1503,7 +1503,6 @@ $(O)\curswins.c: $(WCURSES)\curswins.c $(WCURSES)\curswins.h $(INCL)\wincurs.h
# * $(CFLAGS) replaced with $(cflagsBuild) # * $(CFLAGS) replaced with $(cflagsBuild)
# * $(CC) replaced with @$(CC) # * $(CC) replaced with @$(CC)
# * targets prefixed with $(O) # * targets prefixed with $(O)
# * the single win32api.h reference uncommented
# but otherwise untouched. # but otherwise untouched.
# That means that there is some irrelevant stuff # That means that there is some irrelevant stuff
# in here, but maintenance should be easier. # 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 $(O)tos.o: ..\sys\atari\tos.c $(HACK_H) $(INCL)\tcap.h
@$(CC) $(cflagsBuild) -Fo$@ ..\sys\atari\tos.c @$(CC) $(cflagsBuild) -Fo$@ ..\sys\atari\tos.c
$(O)pcmain.o: ..\sys\share\pcmain.c $(HACK_H) $(INCL)\dlb.h \ $(O)pcmain.o: ..\sys\share\pcmain.c $(HACK_H) $(INCL)\dlb.h
$(MSWSYS)\win32api.h
@$(CC) $(cflagsBuild) -Fo$@ ..\sys\share\pcmain.c @$(CC) $(cflagsBuild) -Fo$@ ..\sys\share\pcmain.c
$(O)pcsys.o: ..\sys\share\pcsys.c $(HACK_H) $(O)pcsys.o: ..\sys\share\pcsys.c $(HACK_H)
@$(CC) $(cflagsBuild) -Fo$@ ..\sys\share\pcsys.c @$(CC) $(cflagsBuild) -Fo$@ ..\sys\share\pcsys.c
-2
View File
@@ -96,13 +96,11 @@ clear_screen()
return; return;
} }
#ifdef TTY_GRAPHICS
void void
backsp() backsp()
{ {
return; return;
} }
#endif
int int
has_color(int color) has_color(int color)
+768
View File
@@ -0,0 +1,768 @@
/* 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));
#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];
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 */
register int fd;
register char *dir;
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);
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);
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) {
#if 0
#if !defined(TTY_GRAPHICS)
int sfd = 0;
boolean tmpconsole = FALSE;
hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
#endif
#endif /* 0 */
/*
* Now we know the directory containing 'record' and
* may do a prscore().
*/
if (!strncmp(argv[1], "-s", 2)) {
#if 0
#if !defined(TTY_GRAPHICS)
/*
* 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
#endif /* 0 */
#ifdef SYSCF
initoptions();
#endif
prscore(argc, argv);
#if 0
#if !defined(TTY_GRAPHICS)
if (tmpconsole) {
getreturn("to exit");
freefakeconsole();
tmpconsole = FALSE;
}
#endif
#endif /* 0 */
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();
#if 0
#if !defined(TTY_GRAPHICS)
if (tmpconsole) {
getreturn("to exit");
freefakeconsole();
tmpconsole = FALSE;
}
#endif
#endif
nethack_exit(EXIT_SUCCESS);
}
}
}
/*
* It seems you really want to play.
*/
/* 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);
if (argc >= 1
&& !strcmpi(default_window_sys, "mswin")
&& (strstri(argv[0], "nethackw.exe") || GUILaunched))
iflags.windowtype_locked = TRUE;
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 */
}
choose_windows(default_window_sys);
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.
*/
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;
#if 0
case 'w': /* windowtype */
#if defined(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;
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*/
+57 -4
View File
@@ -43,10 +43,17 @@ boolean win32_cursorblink;
/* globals required within here */ /* globals required within here */
HANDLE ffhandle = (HANDLE) 0; HANDLE ffhandle = (HANDLE) 0;
WIN32_FIND_DATA ffd; WIN32_FIND_DATA ffd;
extern int GUILaunched;
boolean getreturn_enabled;
int redirect_stdout;
typedef HWND(WINAPI *GETCONSOLEWINDOW)(); typedef HWND(WINAPI *GETCONSOLEWINDOW)();
static HWND GetConsoleHandle(void); static HWND GetConsoleHandle(void);
static HWND GetConsoleHwnd(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 /* The function pointer nt_kbhit contains a kbhit() equivalent
* which varies depending on which window port is active. * 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); 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() void nethack_enter_winnt()
{ {
#ifdef TTY_GRAPHICS if (WINDOWPORT("tty"))
nethack_enter_nttty(); nethack_enter_nttty();
#endif
} }
/* CP437 to Unicode mapping according to the Unicode Consortium */ /* CP437 to Unicode mapping according to the Unicode Consortium */
+1 -1
View File
@@ -1,7 +1,7 @@
/* vim:set cin ft=c sw=4 sts=4 ts=8 et ai cino=Ls\:0t0(0 : -*- mode:c;fill-column:80;tab-width:8;c-basic-offset:4;indent-tabs-mode:nil;c-file-style:"k&r" -*-*/
/* NetHack 3.6 cursdial.c */ /* NetHack 3.6 cursdial.c */
/* Copyright (c) Karl Garrison, 2010. */ /* Copyright (c) Karl Garrison, 2010. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
/* vim:set cin ft=c sw=4 sts=4 ts=8 et ai cino=Ls\:0t0(0 : -*- mode:c;fill-column:80;tab-width:8;c-basic-offset:4;indent-tabs-mode:nil;c-file-style:"k&r" -*-*/
#include "curses.h" #include "curses.h"
#include "hack.h" #include "hack.h"
+1 -1
View File
@@ -1,7 +1,7 @@
/* vim:set cin ft=c sw=4 sts=4 ts=8 et ai cino=Ls\:0t0(0 : -*- mode:c;fill-column:80;tab-width:8;c-basic-offset:4;indent-tabs-mode:nil;c-file-style:"k&r" -*-*/
/* NetHack 3.6 cursdial.h */ /* NetHack 3.6 cursdial.h */
/* Copyright (c) Karl Garrison, 2010. */ /* Copyright (c) Karl Garrison, 2010. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
/* vim:set cin ft=c sw=4 sts=4 ts=8 et ai cino=Ls\:0t0(0 : -*- mode:c;fill-column:80;tab-width:8;c-basic-offset:4;indent-tabs-mode:nil;c-file-style:"k&r" -*-*/
#ifndef CURSDIAL_H #ifndef CURSDIAL_H
# define CURSDIAL_H # define CURSDIAL_H
+1 -1
View File
@@ -1,7 +1,7 @@
/* vim:set cin ft=c sw=4 sts=4 ts=8 et ai cino=Ls\:0t0(0 : -*- mode:c;fill-column:80;tab-width:8;c-basic-offset:4;indent-tabs-mode:nil;c-file-style:"k&r" -*-*/
/* NetHack 3.6 cursinit.c */ /* NetHack 3.6 cursinit.c */
/* Copyright (c) Karl Garrison, 2010. */ /* Copyright (c) Karl Garrison, 2010. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
/* vim:set cin ft=c sw=4 sts=4 ts=8 et ai cino=Ls\:0t0(0 : -*- mode:c;fill-column:80;tab-width:8;c-basic-offset:4;indent-tabs-mode:nil;c-file-style:"k&r" -*-*/
#include "curses.h" #include "curses.h"
#include "hack.h" #include "hack.h"
+1 -1
View File
@@ -1,7 +1,7 @@
/* vim:set cin ft=c sw=4 sts=4 ts=8 et ai cino=Ls\:0t0(0 : -*- mode:c;fill-column:80;tab-width:8;c-basic-offset:4;indent-tabs-mode:nil;c-file-style:"k&r" -*-*/
/* NetHack 3.6 cursinit.h */ /* NetHack 3.6 cursinit.h */
/* Copyright (c) Karl Garrison, 2010. */ /* Copyright (c) Karl Garrison, 2010. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
/* vim:set cin ft=c sw=4 sts=4 ts=8 et ai cino=Ls\:0t0(0 : -*- mode:c;fill-column:80;tab-width:8;c-basic-offset:4;indent-tabs-mode:nil;c-file-style:"k&r" -*-*/
#ifndef CURSINIT_H #ifndef CURSINIT_H
# define CURSINIT_H # define CURSINIT_H
+3 -3
View File
@@ -1,7 +1,7 @@
/* NetHack 3.6 cursinvt.c */
/* Copyright (c) Karl Garrison, 2010. */
/* NetHack may be freely redistributed. See license for details. */
/* vim:set cin ft=c sw=4 sts=4 ts=8 et ai cino=Ls\:0t0(0 : -*- mode:c;fill-column:80;tab-width:8;c-basic-offset:4;indent-tabs-mode:nil;c-file-style:"k&r" -*-*/ /* vim:set cin ft=c sw=4 sts=4 ts=8 et ai cino=Ls\:0t0(0 : -*- mode:c;fill-column:80;tab-width:8;c-basic-offset:4;indent-tabs-mode:nil;c-file-style:"k&r" -*-*/
/* NetHack 3.6 cursinvt.c */
/* Copyright (c) Fredrik Ljungdahl, 2017. */
/* NetHack may be freely redistributed. See license for details. */
#include "curses.h" #include "curses.h"
#include "hack.h" #include "hack.h"
+3 -3
View File
@@ -1,7 +1,7 @@
/* NetHack 3.6 cursinvt.h */
/* Copyright (c) Karl Garrison, 2010. */
/* NetHack may be freely redistributed. See license for details. */
/* vim:set cin ft=c sw=4 sts=4 ts=8 et ai cino=Ls\:0t0(0 : -*- mode:c;fill-column:80;tab-width:8;c-basic-offset:4;indent-tabs-mode:nil;c-file-style:"k&r" -*-*/ /* vim:set cin ft=c sw=4 sts=4 ts=8 et ai cino=Ls\:0t0(0 : -*- mode:c;fill-column:80;tab-width:8;c-basic-offset:4;indent-tabs-mode:nil;c-file-style:"k&r" -*-*/
/* NetHack 3.6 cursinvt.h */
/* Copyright (c) Fredrik Ljungdahl, 2017. */
/* NetHack may be freely redistributed. See license for details. */
#ifndef CURSINVT_H #ifndef CURSINVT_H
# define CURSINVT_H # define CURSINVT_H
+1 -1
View File
@@ -1,7 +1,7 @@
/* vim:set cin ft=c sw=4 sts=4 ts=8 et ai cino=Ls\:0t0(0 : -*- mode:c;fill-column:80;tab-width:8;c-basic-offset:4;indent-tabs-mode:nil;c-file-style:"k&r" -*-*/
/* NetHack 3.6 cursmain.c */ /* NetHack 3.6 cursmain.c */
/* Copyright (c) Karl Garrison, 2010. */ /* Copyright (c) Karl Garrison, 2010. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
/* vim:set cin ft=c sw=4 sts=4 ts=8 et ai cino=Ls\:0t0(0 : -*- mode:c;fill-column:80;tab-width:8;c-basic-offset:4;indent-tabs-mode:nil;c-file-style:"k&r" -*-*/
#include "curses.h" #include "curses.h"
#include "hack.h" #include "hack.h"
+1 -1
View File
@@ -1,7 +1,7 @@
/* vim:set cin ft=c sw=4 sts=4 ts=8 et ai cino=Ls\:0t0(0 : -*- mode:c;fill-column:80;tab-width:8;c-basic-offset:4;indent-tabs-mode:nil;c-file-style:"k&r" -*-*/
/* NetHack 3.6 cursmesg.c */ /* NetHack 3.6 cursmesg.c */
/* Copyright (c) Karl Garrison, 2010. */ /* Copyright (c) Karl Garrison, 2010. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
/* vim:set cin ft=c sw=4 sts=4 ts=8 et ai cino=Ls\:0t0(0 : -*- mode:c;fill-column:80;tab-width:8;c-basic-offset:4;indent-tabs-mode:nil;c-file-style:"k&r" -*-*/
#include "curses.h" #include "curses.h"
#include "hack.h" #include "hack.h"
+1 -1
View File
@@ -1,7 +1,7 @@
/* vim:set cin ft=c sw=4 sts=4 ts=8 et ai cino=Ls\:0t0(0 : -*- mode:c;fill-column:80;tab-width:8;c-basic-offset:4;indent-tabs-mode:nil;c-file-style:"k&r" -*-*/
/* NetHack 3.6 cursmesg.h */ /* NetHack 3.6 cursmesg.h */
/* Copyright (c) Karl Garrison, 2010. */ /* Copyright (c) Karl Garrison, 2010. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
/* vim:set cin ft=c sw=4 sts=4 ts=8 et ai cino=Ls\:0t0(0 : -*- mode:c;fill-column:80;tab-width:8;c-basic-offset:4;indent-tabs-mode:nil;c-file-style:"k&r" -*-*/
#ifndef CURSMESG_H #ifndef CURSMESG_H
# define CURSMESG_H # define CURSMESG_H
+1 -1
View File
@@ -1,7 +1,7 @@
/* vim:set cin ft=c sw=4 sts=4 ts=8 et ai cino=Ls\:0t0(0 : -*- mode:c;fill-column:80;tab-width:8;c-basic-offset:4;indent-tabs-mode:nil;c-file-style:"k&r" -*-*/
/* NetHack 3.6 cursmisc.c */ /* NetHack 3.6 cursmisc.c */
/* Copyright (c) Karl Garrison, 2010. */ /* Copyright (c) Karl Garrison, 2010. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
/* vim:set cin ft=c sw=4 sts=4 ts=8 et ai cino=Ls\:0t0(0 : -*- mode:c;fill-column:80;tab-width:8;c-basic-offset:4;indent-tabs-mode:nil;c-file-style:"k&r" -*-*/
#include "curses.h" #include "curses.h"
#include "hack.h" #include "hack.h"
+1 -1
View File
@@ -1,7 +1,7 @@
/* vim:set cin ft=c sw=4 sts=4 ts=8 et ai cino=Ls\:0t0(0 : -*- mode:c;fill-column:80;tab-width:8;c-basic-offset:4;indent-tabs-mode:nil;c-file-style:"k&r" -*-*/
/* NetHack 3.6 cursmisc.h */ /* NetHack 3.6 cursmisc.h */
/* Copyright (c) Karl Garrison, 2010. */ /* Copyright (c) Karl Garrison, 2010. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
/* vim:set cin ft=c sw=4 sts=4 ts=8 et ai cino=Ls\:0t0(0 : -*- mode:c;fill-column:80;tab-width:8;c-basic-offset:4;indent-tabs-mode:nil;c-file-style:"k&r" -*-*/
#ifndef CURSMISC_H #ifndef CURSMISC_H
# define CURSMISC_H # define CURSMISC_H
+3 -3
View File
@@ -1,7 +1,7 @@
/* NetHack 3.6 cursstat.c */
/* Copyright (c) Karl Garrison, 2010. */
/* NetHack may be freely redistributed. See license for details. */
/* vim:set cin ft=c sw=4 sts=4 ts=8 et ai cino=Ls\:0t0(0 : -*- mode:c;fill-column:80;tab-width:8;c-basic-offset:4;indent-tabs-mode:nil;c-file-style:"k&r" -*-*/ /* vim:set cin ft=c sw=4 sts=4 ts=8 et ai cino=Ls\:0t0(0 : -*- mode:c;fill-column:80;tab-width:8;c-basic-offset:4;indent-tabs-mode:nil;c-file-style:"k&r" -*-*/
/* NetHack 3.6 cursstat.c */
/* Copyright (c) Andy Thomson, 2018. */
/* NetHack may be freely redistributed. See license for details. */
#include <ctype.h> /* toupper() */ #include <ctype.h> /* toupper() */
#include "curses.h" #include "curses.h"
+3 -3
View File
@@ -1,7 +1,7 @@
/* NetHack 3.6 cursstat.c */
/* Copyright (c) Karl Garrison, 2010. */
/* NetHack may be freely redistributed. See license for details. */
/* vim:set cin ft=c sw=4 sts=4 ts=8 et ai cino=Ls\:0t0(0 : -*- mode:c;fill-column:80;tab-width:8;c-basic-offset:4;indent-tabs-mode:nil;c-file-style:"k&r" -*-*/ /* vim:set cin ft=c sw=4 sts=4 ts=8 et ai cino=Ls\:0t0(0 : -*- mode:c;fill-column:80;tab-width:8;c-basic-offset:4;indent-tabs-mode:nil;c-file-style:"k&r" -*-*/
/* NetHack 3.6 cursstat.h */
/* Copyright (c) Karl Garrison, 2010. */
/* NetHack may be freely redistributed. See license for details. */
#ifndef CURSSTAT_H #ifndef CURSSTAT_H
# define CURSSTAT_H # define CURSSTAT_H
+1 -1
View File
@@ -1,7 +1,7 @@
/* vim:set cin ft=c sw=4 sts=4 ts=8 et ai cino=Ls\:0t0(0 : -*- mode:c;fill-column:80;tab-width:8;c-basic-offset:4;indent-tabs-mode:nil;c-file-style:"k&r" -*-*/
/* NetHack 3.6 curswins.c */ /* NetHack 3.6 curswins.c */
/* Copyright (c) Karl Garrison, 2010. */ /* Copyright (c) Karl Garrison, 2010. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
/* vim:set cin ft=c sw=4 sts=4 ts=8 et ai cino=Ls\:0t0(0 : -*- mode:c;fill-column:80;tab-width:8;c-basic-offset:4;indent-tabs-mode:nil;c-file-style:"k&r" -*-*/
#include "curses.h" #include "curses.h"
#include "hack.h" #include "hack.h"
+1 -1
View File
@@ -1,7 +1,7 @@
/* vim:set cin ft=c sw=4 sts=4 ts=8 et ai cino=Ls\:0t0(0 : -*- mode:c;fill-column:80;tab-width:8;c-basic-offset:4;indent-tabs-mode:nil;c-file-style:"k&r" -*-*/
/* NetHack 3.6 curswins.h */ /* NetHack 3.6 curswins.h */
/* Copyright (c) Karl Garrison, 2010. */ /* Copyright (c) Karl Garrison, 2010. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
/* vim:set cin ft=c sw=4 sts=4 ts=8 et ai cino=Ls\:0t0(0 : -*- mode:c;fill-column:80;tab-width:8;c-basic-offset:4;indent-tabs-mode:nil;c-file-style:"k&r" -*-*/
#ifndef CURSWIN_H #ifndef CURSWIN_H
# define CURSWIN_H # define CURSWIN_H
+561
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 */
+1 -1
View File
@@ -2046,7 +2046,7 @@ struct WinDesc *cw;
tty_nhbell(); tty_nhbell();
break; break;
} else { } else {
char searchbuf[BUFSZ + 2], tmpbuf[BUFSZ]; char searchbuf[BUFSZ + 2], tmpbuf[BUFSZ] = DUMMY;
boolean on_curr_page = FALSE; boolean on_curr_page = FALSE;
int lineno = 0; int lineno = 0;
+3
View File
@@ -9,6 +9,9 @@
#include "winMS.h" #include "winMS.h"
#define MIN_FONT_WIDTH 9
#define MIN_FONT_HEIGHT 12
typedef struct cached_font { typedef struct cached_font {
int code; int code;
HFONT hFont; HFONT hFont;
+6 -8
View File
@@ -160,7 +160,8 @@ mswin_map_stretch(HWND hWnd, LPSIZE map_size, BOOL redraw)
// calculate back buffer scale // calculate back buffer scale
data->monitorScale = win10_monitor_scale(hWnd); data->monitorScale = win10_monitor_scale(hWnd);
boolean bText = data->bAsciiMode || (u.uz.dlevel != 0 && Is_rogue_level(&u.uz)); boolean bText = data->bAsciiMode ||
(u.uz.dlevel != 0 && Is_rogue_level(&u.uz));
if (bText && !data->bFitToScreenMode) if (bText && !data->bFitToScreenMode)
data->backScale = data->monitorScale; data->backScale = data->monitorScale;
@@ -217,12 +218,9 @@ mswin_map_stretch(HWND hWnd, LPSIZE map_size, BOOL redraw)
GetTextMetrics(data->backBufferDC, &textMetrics); GetTextMetrics(data->backBufferDC, &textMetrics);
if (textMetrics.tmHeight > data->yBackTile) { if ((textMetrics.tmHeight > data->yBackTile ||
lgfnt.lfHeight++; textMetrics.tmAveCharWidth > data->xBackTile) &&
continue; lgfnt.lfHeight < -MIN_FONT_HEIGHT) {
}
if (textMetrics.tmAveCharWidth > data->xBackTile) {
lgfnt.lfHeight++; lgfnt.lfHeight++;
continue; continue;
} }
@@ -283,7 +281,7 @@ mswin_map_stretch(HWND hWnd, LPSIZE map_size, BOOL redraw)
} else { } else {
if (data->bAsciiMode || Is_rogue_level(&u.uz)) { if (bText) {
data->frontScale = 1.0; data->frontScale = 1.0;
} else { } else {
data->frontScale = data->monitorScale; data->frontScale = data->monitorScale;
+7
View File
@@ -718,6 +718,13 @@ mswin_exit_nhwindows(const char *str)
/* Write Window settings to the registry */ /* Write Window settings to the registry */
mswin_write_reg(); 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. */ /* Prepare the window to be suspended. */
+4 -3
View File
@@ -34,7 +34,7 @@
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<OmitFramePointers>true</OmitFramePointers> <OmitFramePointers>true</OmitFramePointers>
<AdditionalIncludeDirectories>$(WinWin32Dir);$(IncDir);$(SysWinntDir);$(SysShareDir);$(WinShareDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <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> </ClCompile>
<Link> <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> <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="$(SrcDir)zap.c" />
<ClCompile Include="$(SysShareDir)cppregex.cpp" /> <ClCompile Include="$(SysShareDir)cppregex.cpp" />
<ClCompile Include="$(SysShareDir)nhlan.c" /> <ClCompile Include="$(SysShareDir)nhlan.c" />
<ClCompile Include="$(SysShareDir)pcmain.c" />
<ClCompile Include="$(SysShareDir)pcsys.c" /> <ClCompile Include="$(SysShareDir)pcsys.c" />
<ClCompile Include="$(SysShareDir)pcunix.c" /> <ClCompile Include="$(SysShareDir)pcunix.c" />
<ClCompile Include="$(SysShareDir)random.c" /> <ClCompile Include="$(SysShareDir)random.c" />
@@ -160,7 +159,9 @@
<ClCompile Include="$(SysWinntDir)stubs.c"> <ClCompile Include="$(SysWinntDir)stubs.c">
<PreprocessorDefinitions>GUISTUB;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>GUISTUB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile> </ClCompile>
<ClCompile Include="$(SysWinntDir)windmain.c" />
<ClCompile Include="$(SysWinntDir)winnt.c" /> <ClCompile Include="$(SysWinntDir)winnt.c" />
<ClCompile Include="$(WinShareDir)safeproc.c" />
<ClCompile Include="$(WinTtyDir)getline.c" /> <ClCompile Include="$(WinTtyDir)getline.c" />
<ClCompile Include="$(WinTtyDir)topl.c" /> <ClCompile Include="$(WinTtyDir)topl.c" />
<ClCompile Include="$(WinTtyDir)wintty.c" /> <ClCompile Include="$(WinTtyDir)wintty.c" />
@@ -254,4 +255,4 @@
<Target Name="AfterRebuild"> <Target Name="AfterRebuild">
<MSBuild Projects="afternethack.proj" Targets="Build" Properties="Configuration=$(Configuration)" /> <MSBuild Projects="afternethack.proj" Targets="Build" Properties="Configuration=$(Configuration)" />
</Target> </Target>
</Project> </Project>
+4 -3
View File
@@ -20,7 +20,7 @@
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<OmitFramePointers>true</OmitFramePointers> <OmitFramePointers>true</OmitFramePointers>
<AdditionalIncludeDirectories>$(WinWin32Dir);$(IncDir);$(SysWinntDir);$(SysShareDir);$(WinShareDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <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> </ClCompile>
<ResourceCompile> <ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
@@ -146,7 +146,6 @@
<ClCompile Include="$(SrcDir)zap.c" /> <ClCompile Include="$(SrcDir)zap.c" />
<ClCompile Include="$(SysShareDir)cppregex.cpp" /> <ClCompile Include="$(SysShareDir)cppregex.cpp" />
<ClCompile Include="$(SysShareDir)nhlan.c" /> <ClCompile Include="$(SysShareDir)nhlan.c" />
<ClCompile Include="$(SysShareDir)pcmain.c" />
<ClCompile Include="$(SysShareDir)pcsys.c" /> <ClCompile Include="$(SysShareDir)pcsys.c" />
<ClCompile Include="$(SysShareDir)pcunix.c" /> <ClCompile Include="$(SysShareDir)pcunix.c" />
<ClCompile Include="$(SysShareDir)random.c" /> <ClCompile Include="$(SysShareDir)random.c" />
@@ -154,8 +153,10 @@
<ClCompile Include="$(SysWinntDir)stubs.c"> <ClCompile Include="$(SysWinntDir)stubs.c">
<PreprocessorDefinitions>TTYSTUB;</PreprocessorDefinitions> <PreprocessorDefinitions>TTYSTUB;</PreprocessorDefinitions>
</ClCompile> </ClCompile>
<ClCompile Include="$(SysWinntDir)windmain.c" />
<ClCompile Include="$(SysWinntDir)winnt.c" /> <ClCompile Include="$(SysWinntDir)winnt.c" />
<ClCompile Include="$(SysWinntDir)win10.c" /> <ClCompile Include="$(SysWinntDir)win10.c" />
<ClCompile Include="$(WinShareDir)safeproc.c" />
<ClCompile Include="$(WinWin32Dir)mhaskyn.c" /> <ClCompile Include="$(WinWin32Dir)mhaskyn.c" />
<ClCompile Include="$(WinWin32Dir)mhdlg.c" /> <ClCompile Include="$(WinWin32Dir)mhdlg.c" />
<ClCompile Include="$(WinWin32Dir)mhfont.c" /> <ClCompile Include="$(WinWin32Dir)mhfont.c" />
@@ -200,4 +201,4 @@
<Target Name="AfterRebuild"> <Target Name="AfterRebuild">
<MSBuild Projects="afternethack.proj" Targets="Build" Properties="Configuration=$(Configuration)" /> <MSBuild Projects="afternethack.proj" Targets="Build" Properties="Configuration=$(Configuration)" />
</Target> </Target>
</Project> </Project>
+34 -9
View File
@@ -15,6 +15,10 @@
#include "mhmain.h" #include "mhmain.h"
#include "mhmap.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, /* Borland and MinGW redefine "boolean" in shlwapi.h,
so just use the little bit we need */ so just use the little bit we need */
typedef struct _DLLVERSIONINFO { typedef struct _DLLVERSIONINFO {
@@ -59,6 +63,8 @@ _nhapply_image_transparent(HDC hDC, int x, int y, int width, int height,
// Global Variables: // Global Variables:
NHWinApp _nethack_app; NHWinApp _nethack_app;
extern int GUILaunched; /* We tell shared startup code in windmain.c
that the GUI was launched via this */
#ifdef __BORLANDC__ #ifdef __BORLANDC__
#define _stricmp(s1, s2) stricmp(s1, s2) #define _stricmp(s1, s2) stricmp(s1, s2)
@@ -66,7 +72,7 @@ NHWinApp _nethack_app;
#endif #endif
// Foward declarations of functions included in this code module: // 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 *); static void __cdecl mswin_moveloop(void *);
#define MAX_CMDLINE_PARAM 255 #define MAX_CMDLINE_PARAM 255
@@ -82,24 +88,44 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine,
TCHAR *p; TCHAR *p;
TCHAR wbuf[BUFSZ]; TCHAR wbuf[BUFSZ];
char buf[BUFSZ]; char buf[BUFSZ];
DWORD major, minor; DWORD major, minor;
boolean resuming;
/* OSVERSIONINFO osvi; */ /* OSVERSIONINFO osvi; */
UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine); UNREFERENCED_PARAMETER(lpCmdLine);
UNREFERENCED_PARAMETER(nCmdShow); 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 = mswin_raw_print;
windowprocs.win_raw_print_bold = mswin_raw_print_bold; windowprocs.win_raw_print_bold = mswin_raw_print_bold;
windowprocs.win_wait_synch = mswin_wait_synch; windowprocs.win_wait_synch = mswin_wait_synch;
win10_init(); win10_init();
sys_early_init(); sys_early_init();
/* init applicatio structure */ /* init application structure */
_nethack_app.hApp = hInstance; _nethack_app.hApp = hInstance;
_nethack_app.hAccelTable = _nethack_app.hAccelTable =
LoadAccelerators(hInstance, (LPCTSTR) IDC_NETHACKW); LoadAccelerators(hInstance, (LPCTSTR) IDC_NETHACKW);
@@ -209,10 +235,9 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine,
} }
free(savefile); free(savefile);
} }
resuming = pcmain(argc, argv); GUILaunched = 1;
/* let main do the argument processing */
moveloop(resuming); (void) main(argc, argv);
return 0; return 0;
} }