Merge branch 'NetHack-3.7' into NetHack-3.7-Jan2020

This commit is contained in:
nhmall
2020-01-27 08:52:17 -05:00
25 changed files with 1438 additions and 530 deletions
+4
View File
@@ -3907,6 +3907,10 @@ Values are \(lqautodetect\(rq, \(lqdefault\(rq, or \(lqvga\(rq.
Setting \(lqvga\(rq (or \(lqautodetect\(rq with vga hardware present) Setting \(lqvga\(rq (or \(lqautodetect\(rq with vga hardware present)
will cause the game to display tiles. will cause the game to display tiles.
Cannot be set with the \(oqO\(cq command. Cannot be set with the \(oqO\(cq command.
.lp video_height
Set the VGA mode resolution height (MS-DOS only, with video:vga)
.lp video_width
Set the VGA mode resolution width (MS-DOS only, with video:vga)
.lp videocolors .lp videocolors
Set the color palette for PC systems using NO_TERMS Set the color palette for PC systems using NO_TERMS
(default 4-2-6-1-5-3-15-12-10-14-9-13-11, (PC NetHack only). (default 4-2-6-1-5-3-15-12-10-14-9-13-11, (PC NetHack only).
+6
View File
@@ -4342,6 +4342,12 @@ Setting {\it vga\/} (or {\it autodetect\/} with vga hardware present) will
cause the game to display tiles. cause the game to display tiles.
Cannot be set with the `{\tt O}' command. Cannot be set with the `{\tt O}' command.
%.lp %.lp
\item[\ib{video\verb+_+height}]
Set the VGA mode resolution height (MS-DOS only, with video:vga)
%.lp
\item[\ib{video\verb+_+width}]
Set the VGA mode resolution width (MS-DOS only, with video:vga)
%.lp
\item[\ib{videocolors}] \item[\ib{videocolors}]
\begin{sloppypar} \begin{sloppypar}
Set the color palette for PC systems using NO\verb+_+TERMS Set the color palette for PC systems using NO\verb+_+TERMS
+4 -3
View File
@@ -1,4 +1,4 @@
$NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.74 $ $NHDT-Date: 1579914040 2020/01/25 01:00:40 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.76 $ $NHDT-Date: 1580043420 2020/01/26 12:57:00 $
General Fixes and Modified Features General Fixes and Modified Features
----------------------------------- -----------------------------------
@@ -47,6 +47,7 @@ if at the edge of the map window, trying to move farther fails but used a turn
hero can no longer wear blindfold/towel/lenses when poly'd into headless form hero can no longer wear blindfold/towel/lenses when poly'd into headless form
revamp achievement tracking for exploring Mine's End and Sokoban (by acquiring revamp achievement tracking for exploring Mine's End and Sokoban (by acquiring
luckstone and bag of holding or amulet of reflection, respectively) luckstone and bag of holding or amulet of reflection, respectively)
throttle long worm growth rate and HP accumulation
Fixes to 3.7.0-x Problems that Were Exposed Via git Repository Fixes to 3.7.0-x Problems that Were Exposed Via git Repository
@@ -110,8 +111,8 @@ when hallucinating, see hallucinated liquids when looking at water or lava
on the map on the map
applying a spellbook hints about read charges left applying a spellbook hints about read charges left
wizard mode wishing for level topology can now create hidden doors (ask for wizard mode wishing for level topology can now create hidden doors (ask for
"secret door" when at a door or wall location) and hidden corridor "secret door" when at a door or wall location), hidden corridor
spots ("secret corridor" at a corridor location) spots ("secret corridor" at a corridor location), and clouds
tiny chance for randomly created spellbooks to be Discworld novels instead tiny chance for randomly created spellbooks to be Discworld novels instead
of having only one in the first book or scroll shop created (won't of having only one in the first book or scroll shop created (won't
occur in hero's initial inventory or NPC priest inventory or be occur in hero's initial inventory or NPC priest inventory or be
+2 -2
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 extern.h $NHDT-Date: 1578895332 2020/01/13 06:02:12 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.785 $ */ /* NetHack 3.6 extern.h $NHDT-Date: 1580044333 2020/01/26 13:12:13 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.786 $ */
/* 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. */
@@ -1437,7 +1437,7 @@ E int FDECL(mfndpos, (struct monst *, coord *, long *, long));
E boolean FDECL(monnear, (struct monst *, int, int)); E boolean FDECL(monnear, (struct monst *, int, int));
E void NDECL(dmonsfree); E void NDECL(dmonsfree);
E void FDECL(elemental_clog, (struct monst *)); E void FDECL(elemental_clog, (struct monst *));
E int FDECL(mcalcmove, (struct monst *)); E int FDECL(mcalcmove, (struct monst *, BOOLEAN_P));
E void NDECL(mcalcdistress); E void NDECL(mcalcdistress);
E void FDECL(replmon, (struct monst *, struct monst *)); E void FDECL(replmon, (struct monst *, struct monst *));
E void FDECL(relmon, (struct monst *, struct monst **)); E void FDECL(relmon, (struct monst *, struct monst **));
+4
View File
@@ -367,6 +367,10 @@ struct instance_flags {
int wc_map_mode; /* specify map viewing options, mostly int wc_map_mode; /* specify map viewing options, mostly
* for backward compatibility */ * for backward compatibility */
int wc_player_selection; /* method of choosing character */ int wc_player_selection; /* method of choosing character */
#if defined(MSDOS)
unsigned wc_video_width; /* X resolution of screen */
unsigned wc_video_height; /* Y resolution of screen */
#endif
boolean wc_splash_screen; /* display an opening splash screen or not */ boolean wc_splash_screen; /* display an opening splash screen or not */
boolean wc_popup_dialog; /* put queries in pop up dialogs instead of boolean wc_popup_dialog; /* put queries in pop up dialogs instead of
* in the message window */ * in the message window */
+1 -2
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 obj.h $NHDT-Date: 1508827590 2017/10/24 06:46:30 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.60 $ */ /* NetHack 3.6 obj.h $NHDT-Date: 1580036271 2020/01/26 10:57:51 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.66 $ */
/* 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. */
@@ -114,7 +114,6 @@ struct obj {
#define leashmon corpsenm /* gets m_id of attached pet */ #define leashmon corpsenm /* gets m_id of attached pet */
#define fromsink corpsenm /* a potion from a sink */ #define fromsink corpsenm /* a potion from a sink */
#define novelidx corpsenm /* 3.6 tribute - the index of the novel title */ #define novelidx corpsenm /* 3.6 tribute - the index of the novel title */
#define record_achieve_special corpsenm
int usecount; /* overloaded for various things that tally */ int usecount; /* overloaded for various things that tally */
#define spestudied usecount /* # of times a spellbook has been studied */ #define spestudied usecount /* # of times a spellbook has been studied */
unsigned oeaten; /* nutrition left in food, if partly eaten */ unsigned oeaten; /* nutrition left in food, if partly eaten */
+13 -10
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 rm.h $NHDT-Date: 1578258722 2020/01/05 21:12:02 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.77 $ */ /* NetHack 3.6 rm.h $NHDT-Date: 1580070206 2020/01/26 20:23:26 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.78 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Pasi Kallinen, 2017. */ /*-Copyright (c) Pasi Kallinen, 2017. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -528,16 +528,19 @@ struct rm {
#define SV7 0x80 #define SV7 0x80
#define SVALL 0xFF #define SVALL 0xFF
#define doormask flags /* if these get changed or expanded, make sure wizard-mode wishing becomes
#define altarmask flags aware of the new usage */
#define wall_info flags #define doormask flags /* door, sdoor (note conflict with wall_info) */
#define ladder flags #define altarmask flags /* alignment and maybe temple */
#define drawbridgemask flags #define wall_info flags /* wall, sdoor (note conflict with doormask) */
#define looted flags #define ladder flags /* up or down */
#define icedpool flags #define drawbridgemask flags /* what's underneath when the span is open */
#define looted flags /* used for throne, tree, fountain, sink, door */
#define icedpool flags /* used for ice (in case it melts) */
/* horizonal applies to walls, doors (including sdoor); also to iron bars
even though they don't have separate symbols for horizontal and vertical */
#define blessedftn horizontal /* a fountain that grants attribs */ #define blessedftn horizontal /* a fountain that grants attribs */
#define disturbed horizontal /* a grave that has been disturbed */ #define disturbed horizontal /* a grave that has been disturbed */
struct damage { struct damage {
struct damage *next; struct damage *next;
+6
View File
@@ -18,9 +18,15 @@ struct TileImage {
boolean FDECL(read_tiles, (const char *filename, BOOLEAN_P true_color)); boolean FDECL(read_tiles, (const char *filename, BOOLEAN_P true_color));
const struct Pixel *NDECL(get_palette); const struct Pixel *NDECL(get_palette);
boolean FDECL(set_tile_type, (BOOLEAN_P true_color));
void NDECL(free_tiles); void NDECL(free_tiles);
const struct TileImage *FDECL(get_tile, (unsigned tile_index)); const struct TileImage *FDECL(get_tile, (unsigned tile_index));
/* For resizing tiles */
struct TileImage *FDECL(stretch_tile, (const struct TileImage *,
unsigned, unsigned));
void FDECL(free_tile, (struct TileImage *));
/* Used internally by the tile set code */ /* Used internally by the tile set code */
struct TileSetImage { struct TileSetImage {
/* Image data */ /* Image data */
+3 -3
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 allmain.c $NHDT-Date: 1578448653 2020/01/08 01:57:33 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.137 $ */ /* NetHack 3.6 allmain.c $NHDT-Date: 1580044340 2020/01/26 13:12:20 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.138 $ */
/* 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. */
@@ -125,7 +125,7 @@ boolean resuming;
to skip dead monsters here because they will have to skip dead monsters here because they will have
been purged at end of their previous round of moving */ been purged at end of their previous round of moving */
for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) for (mtmp = fmon; mtmp; mtmp = mtmp->nmon)
mtmp->movement += mcalcmove(mtmp); mtmp->movement += mcalcmove(mtmp, TRUE);
/* occasionally add another monster; since this takes /* occasionally add another monster; since this takes
place after movement has been allotted, the new place after movement has been allotted, the new
@@ -139,7 +139,7 @@ boolean resuming;
/* calculate how much time passed. */ /* calculate how much time passed. */
if (u.usteed && u.umoved) { if (u.usteed && u.umoved) {
/* your speed doesn't augment steed's speed */ /* your speed doesn't augment steed's speed */
moveamt = mcalcmove(u.usteed); moveamt = mcalcmove(u.usteed, TRUE);
} else { } else {
moveamt = g.youmonst.data->mmove; moveamt = g.youmonst.data->mmove;
+16 -13
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 mon.c $NHDT-Date: 1577759850 2019/12/31 02:37:30 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.319 $ */ /* NetHack 3.6 mon.c $NHDT-Date: 1580044343 2020/01/26 13:12:23 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.320 $ */
/* 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. */
@@ -633,9 +633,11 @@ register struct monst *mtmp;
return 0; return 0;
} }
/* calculate 'mon's movement for current turn; called from moveloop() */
int int
mcalcmove(mon) mcalcmove(mon, m_moving)
struct monst *mon; struct monst *mon;
boolean m_moving; /* True: adjust for moving; False: just adjust for speed */
{ {
int mmove = mon->data->mmove; int mmove = mon->data->mmove;
int mmove_adj; int mmove_adj;
@@ -656,17 +658,18 @@ struct monst *mon;
mmove = ((rn2(2) ? 4 : 5) * mmove) / 3; mmove = ((rn2(2) ? 4 : 5) * mmove) / 3;
} }
/* Randomly round the monster's speed to a multiple of NORMAL_SPEED. if (m_moving) {
This makes it impossible for the player to predict when they'll get /* Randomly round the monster's speed to a multiple of NORMAL_SPEED.
a free turn (thus preventing exploits like "melee kiting"), while This makes it impossible for the player to predict when they'll
retaining guarantees about shopkeepers not being outsped by a get a free turn (thus preventing exploits like "melee kiting"),
normal-speed player, normal-speed players being unable to open up while retaining guarantees about shopkeepers not being outsped
a gap when fleeing a normal-speed monster, etc. */ by a normal-speed player, normal-speed players being unable
mmove_adj = mmove % NORMAL_SPEED; to open up a gap when fleeing a normal-speed monster, etc. */
mmove -= mmove_adj; mmove_adj = mmove % NORMAL_SPEED;
if (rn2(NORMAL_SPEED) < mmove_adj) mmove -= mmove_adj;
mmove += NORMAL_SPEED; if (rn2(NORMAL_SPEED) < mmove_adj)
mmove += NORMAL_SPEED;
}
return mmove; return mmove;
} }
+76 -19
View File
@@ -1,4 +1,4 @@
/* NetHack 3.7 objnam.c $NHDT-Date: 1579261291 2020/01/17 11:41:31 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.288 $ */ /* NetHack 3.7 objnam.c $NHDT-Date: 1580070220 2020/01/26 20:23:40 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.291 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2011. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -2952,8 +2952,8 @@ char *bp, *p;
int locked, trapped; int locked, trapped;
{ {
struct rm *lev; struct rm *lev;
boolean madeterrain = FALSE, badterrain = FALSE; boolean madeterrain = FALSE, badterrain = FALSE, didblock;
int trap, x = u.ux, y = u.uy; int trap, oldtyp, x = u.ux, y = u.uy;
for (trap = NO_TRAP + 1; trap < TRAPNUM; trap++) { for (trap = NO_TRAP + 1; trap < TRAPNUM; trap++) {
struct trap *t; struct trap *t;
@@ -2978,21 +2978,25 @@ int locked, trapped;
/* furniture and terrain (use at your own risk; can clobber stairs /* furniture and terrain (use at your own risk; can clobber stairs
or place furniture on existing traps which shouldn't be allowed) */ or place furniture on existing traps which shouldn't be allowed) */
lev = &levl[x][y]; lev = &levl[x][y];
oldtyp = lev->typ;
didblock = does_block(x, y, lev);
p = eos(bp); p = eos(bp);
if (!BSTRCMPI(bp, p - 8, "fountain")) { if (!BSTRCMPI(bp, p - 8, "fountain")) {
lev->typ = FOUNTAIN; lev->typ = FOUNTAIN;
g.level.flags.nfountains++; g.level.flags.nfountains++;
if (!strncmpi(bp, "magic ", 6)) lev->looted = 0; /* overlays 'flags' */
lev->blessedftn = 1; lev->blessedftn = !strncmpi(bp, "magic ", 6);
pline("A %sfountain.", lev->blessedftn ? "magic " : ""); pline("A %sfountain.", lev->blessedftn ? "magic " : "");
madeterrain = TRUE; madeterrain = TRUE;
} else if (!BSTRCMPI(bp, p - 6, "throne")) { } else if (!BSTRCMPI(bp, p - 6, "throne")) {
lev->typ = THRONE; lev->typ = THRONE;
lev->looted = 0; /* overlays 'flags' */
pline("A throne."); pline("A throne.");
madeterrain = TRUE; madeterrain = TRUE;
} else if (!BSTRCMPI(bp, p - 4, "sink")) { } else if (!BSTRCMPI(bp, p - 4, "sink")) {
lev->typ = SINK; lev->typ = SINK;
g.level.flags.nsinks++; g.level.flags.nsinks++;
lev->looted = 0; /* overlays 'flags' */
pline("A sink."); pline("A sink.");
madeterrain = TRUE; madeterrain = TRUE;
@@ -3000,6 +3004,7 @@ int locked, trapped;
} else if (!BSTRCMPI(bp, p - 4, "pool") } else if (!BSTRCMPI(bp, p - 4, "pool")
|| !BSTRCMPI(bp, p - 4, "moat")) { || !BSTRCMPI(bp, p - 4, "moat")) {
lev->typ = !BSTRCMPI(bp, p - 4, "pool") ? POOL : MOAT; lev->typ = !BSTRCMPI(bp, p - 4, "pool") ? POOL : MOAT;
lev->flags = 0;
del_engr_at(x, y); del_engr_at(x, y);
pline("A %s.", (lev->typ == POOL) ? "pool" : "moat"); pline("A %s.", (lev->typ == POOL) ? "pool" : "moat");
/* Must manually make kelp! */ /* Must manually make kelp! */
@@ -3009,6 +3014,7 @@ int locked, trapped;
/* also matches "molten lava" */ /* also matches "molten lava" */
} else if (!BSTRCMPI(bp, p - 4, "lava")) { } else if (!BSTRCMPI(bp, p - 4, "lava")) {
lev->typ = LAVAPOOL; lev->typ = LAVAPOOL;
lev->flags = 0;
del_engr_at(x, y); del_engr_at(x, y);
pline("A pool of molten lava."); pline("A pool of molten lava.");
if (!(Levitation || Flying)) if (!(Levitation || Flying))
@@ -3028,29 +3034,51 @@ int locked, trapped;
al = A_NONE; al = A_NONE;
else /* -1 - A_CHAOTIC, 0 - A_NEUTRAL, 1 - A_LAWFUL */ else /* -1 - A_CHAOTIC, 0 - A_NEUTRAL, 1 - A_LAWFUL */
al = !rn2(6) ? A_NONE : (rn2((int) A_LAWFUL + 2) - 1); al = !rn2(6) ? A_NONE : (rn2((int) A_LAWFUL + 2) - 1);
lev->altarmask = Align2amask(al); lev->altarmask = Align2amask(al); /* overlays 'flags' */
pline("%s altar.", An(align_str(al))); pline("%s altar.", An(align_str(al)));
madeterrain = TRUE; madeterrain = TRUE;
} else if (!BSTRCMPI(bp, p - 5, "grave") } else if (!BSTRCMPI(bp, p - 5, "grave")
|| !BSTRCMPI(bp, p - 9, "headstone")) { || !BSTRCMPI(bp, p - 9, "headstone")) {
make_grave(x, y, (char *) 0); make_grave(x, y, (char *) 0);
pline("%s.", IS_GRAVE(lev->typ) ? "A grave" if (IS_GRAVE(lev->typ)) {
: "Can't place a grave here"); lev->looted = 0; /* overlays 'flags' */
madeterrain = TRUE; lev->disturbed = !strncmpi(bp, "disturbed ", 10);
pline("A %sgrave.", lev->disturbed ? "disturbed " : "");
madeterrain = TRUE;
} else {
pline("Can't place a grave here");
badterrain = TRUE;
}
} else if (!BSTRCMPI(bp, p - 4, "tree")) { } else if (!BSTRCMPI(bp, p - 4, "tree")) {
lev->typ = TREE; lev->typ = TREE;
lev->looted = 0; /* overlays 'flags' */
pline("A tree."); pline("A tree.");
block_point(x, y);
madeterrain = TRUE; madeterrain = TRUE;
} else if (!BSTRCMPI(bp, p - 4, "bars")) { } else if (!BSTRCMPI(bp, p - 4, "bars")) {
lev->typ = IRONBARS; lev->typ = IRONBARS;
lev->flags = 0;
/* [FIXME: if this isn't a wall or door location where 'horizontal'
is already set up, that should be calculated for this spot.
Unforutnately, it can be tricky; placing one in open space
and then another adjacent might need to recalculate first one.] */
pline("Iron bars."); pline("Iron bars.");
madeterrain = TRUE; madeterrain = TRUE;
} else if (!BSTRCMPI(bp, p - 5, "cloud")) {
lev->typ = CLOUD;
lev->flags = 0;
pline("A cloud.");
madeterrain = TRUE;
} else if (!BSTRCMPI(bp, p - 11, "secret door")) { } else if (!BSTRCMPI(bp, p - 11, "secret door")) {
if (lev->typ == DOOR /* require door or wall so that the 'horizontal' flag will
|| (IS_WALL(lev->typ) && lev->typ != DBWALL)) { already have the correct value (it will matter once the
secret door is discovered and becomes a regular door);
player might choose to put SDOOR on top of existing SDOOR
to control its trapped state; iron bars are surrogate walls */
if (lev->typ == DOOR || lev->typ == SDOOR
|| (IS_WALL(lev->typ) && lev->typ != DBWALL)
|| lev->typ == IRONBARS) {
lev->typ = SDOOR; lev->typ = SDOOR;
lev->wall_info = 0; lev->wall_info = 0; /* overlays 'flags' */
/* lev->horizontal stays as-is */ /* lev->horizontal stays as-is */
/* no special handling for rogue level is necessary; /* no special handling for rogue level is necessary;
exposing a secret door there yields a doorless doorway */ exposing a secret door there yields a doorless doorway */
@@ -3068,7 +3096,6 @@ int locked, trapped;
#endif #endif
if (trapped) if (trapped)
lev->doormask |= D_TRAPPED; lev->doormask |= D_TRAPPED;
block_point(x, y);
pline("Secret door."); pline("Secret door.");
madeterrain = TRUE; madeterrain = TRUE;
} else { } else {
@@ -3078,7 +3105,7 @@ int locked, trapped;
} else if (!BSTRCMPI(bp, p - 15, "secret corridor")) { } else if (!BSTRCMPI(bp, p - 15, "secret corridor")) {
if (lev->typ == CORR) { if (lev->typ == CORR) {
lev->typ = SCORR; lev->typ = SCORR;
block_point(x, y); /* neither CORR nor SCORR uses 'flags' or 'horizontal' */
pline("Secret corridor."); pline("Secret corridor.");
madeterrain = TRUE; madeterrain = TRUE;
} else { } else {
@@ -3094,11 +3121,41 @@ int locked, trapped;
if (u.uinwater && !is_pool(u.ux, u.uy)) { if (u.uinwater && !is_pool(u.ux, u.uy)) {
u.uinwater = 0; /* leave the water */ u.uinwater = 0; /* leave the water */
docrt(); docrt();
g.vision_full_recalc = 1; /* [block/unblock_point was handled by docrt -> vision_recalc] */
} else if (u.utrap && u.utraptype == TT_LAVA } else {
&& !is_lava(u.ux, u.uy)) { if (u.utrap && u.utraptype == TT_LAVA && !is_lava(u.ux, u.uy))
reset_utrap(FALSE); reset_utrap(FALSE);
if (does_block(x, y, lev)) {
if (!didblock)
block_point(x, y);
} else {
if (didblock)
unblock_point(x, y);
}
} }
/* fixups for replaced terrain that aren't handled above;
for fountain placed on fountain or sink placed on sink, the
increment above gets canceled out by the decrement here;
otherwise if fountain or sink was replaced, there's one less */
if (IS_FOUNTAIN(oldtyp))
g.level.flags.nfountains--;
else if (IS_SINK(oldtyp))
g.level.flags.nsinks--;
/* horizontal is overlaid by fountain->blessedftn, grave->disturbed */
if (IS_FOUNTAIN(oldtyp) || IS_GRAVE(oldtyp)
|| IS_WALL(oldtyp) || oldtyp == IRONBARS
|| IS_DOOR(oldtyp) || oldtyp == SDOOR) {
/* when new terrain is a fountain, 'blessedftn' was explicitly
set above; likewise for grave and 'disturbed'; when it's a
secret door, the old type was a wall or a door and we retain
the 'horizontal' value from those */
if (!IS_FOUNTAIN(lev->typ) && !IS_GRAVE(lev->typ)
&& lev->typ != SDOOR)
lev->horizontal = 0; /* also clears blessedftn, disturbed */
}
/* note: lev->lit and lev->nondiggable retain their values even
though those might not make sense with the new terrain */
} }
if (madeterrain || badterrain) { if (madeterrain || badterrain) {
/* cast 'const' away; caller won't modify this */ /* cast 'const' away; caller won't modify this */
+24 -1
View File
@@ -3368,8 +3368,31 @@ boolean tinitial, tfrom_file;
return retval; return retval;
} }
#endif /* VIDEOSHADES */ #endif /* VIDEOSHADES */
#ifdef MSDOS #ifdef MSDOS
fullname = "video_width";
if (match_optname(opts, fullname, 7, TRUE)) {
if (duplicate)
complain_about_duplicate(opts, 1);
if (negated) {
bad_negation(fullname, FALSE);
return FALSE;
}
op = string_for_opt(opts, negated);
iflags.wc_video_width = strtol(op, NULL, 10);
return FALSE;
}
fullname = "video_height";
if (match_optname(opts, fullname, 7, TRUE)) {
if (duplicate)
complain_about_duplicate(opts, 1);
if (negated) {
bad_negation(fullname, FALSE);
return FALSE;
}
op = string_for_opt(opts, negated);
iflags.wc_video_height = strtol(op, NULL, 10);
return FALSE;
}
#ifdef NO_TERMS #ifdef NO_TERMS
/* video:string -- must be after longer tests */ /* video:string -- must be after longer tests */
fullname = "video"; fullname = "video";
+5 -2
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 sp_lev.c $NHDT-Date: 1574646949 2019/11/25 01:55:49 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.141 $ */ /* NetHack 3.6 sp_lev.c $NHDT-Date: 1580036285 2020/01/26 10:58:05 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.148 $ */
/* Copyright (c) 1989 by Jean-Christophe Collet */ /* Copyright (c) 1989 by Jean-Christophe Collet */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -1571,10 +1571,13 @@ struct mkroom *croom;
/* /*
* If this is a specific item of the right type and it is being * If this is a specific item of the right type and it is being
* created on the right level, flag it as the designated item * created on the right level, record its obj->o_id to be able
* to recognize it as the designated item
* used to detect a special achievement (to whit, reaching and * used to detect a special achievement (to whit, reaching and
* exploring the target level, although the exploration part * exploring the target level, although the exploration part
* might be short-circuited if a monster brings object to hero). * might be short-circuited if a monster brings object to hero).
* Achievement is accomplished and the recorded o_id is cleared
* if/when it gets added into hero's inventory.
* *
* Random items of the appropriate type won't trigger a false * Random items of the appropriate type won't trigger a false
* match--they'll fail the (id != -1) test above--but the level * match--they'll fail the (id != -1) test above--but the level
-1
View File
@@ -876,7 +876,6 @@ const char *status_fieldnm[MAXBLSTATS];
const char *status_fieldfmt[MAXBLSTATS]; const char *status_fieldfmt[MAXBLSTATS];
char *status_vals[MAXBLSTATS]; char *status_vals[MAXBLSTATS];
boolean status_activefields[MAXBLSTATS]; boolean status_activefields[MAXBLSTATS];
NEARDATA winid WIN_STATUS;
void void
genl_status_init() genl_status_init()
+62 -22
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 worm.c $NHDT-Date: 1579990313 2020/01/25 22:11:53 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.41 $ */ /* NetHack 3.6 worm.c $NHDT-Date: 1580043421 2020/01/26 12:57:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.42 $ */
/* 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. */
@@ -218,26 +218,65 @@ struct monst *worm;
seg->nseg = new_seg; /* attach it to the end of the list */ seg->nseg = new_seg; /* attach it to the end of the list */
wheads[wnum] = new_seg; /* move the end pointer */ wheads[wnum] = new_seg; /* move the end pointer */
/*
* [maybe] FIXME?
* scheduling wgrowtime[] seems to be based on normal movement
* speed (12) but long worms move at 1/4 of that (3), so they'll
* reach the scheduled 'moves' more quickly (in terms of their
* actual movement) and grow faster than was probably intended.
*/
if (wgrowtime[wnum] <= g.moves) { if (wgrowtime[wnum] <= g.moves) {
if (!wgrowtime[wnum]) int whplimit, whpcap, wsegs = count_wsegs(worm);
/* first set up for the next time to grow */
if (!wgrowtime[wnum]) {
/* new worm; usually grow a tail segment on its next turn */
wgrowtime[wnum] = g.moves + rnd(5); wgrowtime[wnum] = g.moves + rnd(5);
else } else {
wgrowtime[wnum] += rn1(15, 3); int mmove = mcalcmove(worm, FALSE),
worm->mhp += 3; /* prior to 3.7.0, next-grow increment was 3..17 but since
if (worm->mhp > MHPMAX) it got checked every 4th turn when the speed 3 worm got
worm->mhp = MHPMAX; to move, it was effectively 0..5; also, its usage was
if (worm->mhp > worm->mhpmax) 'wgrowtime += incr', so often 'wgrowtime' would be
worm->mhpmax = worm->mhp; exceeded by 'moves' on consecutive turns for the worm,
} else resulting in an excessively rapid growth cycle */
/* The worm doesn't grow, so the last segment goes away. */ incr = rn1(10, 2); /* 2..12; after adjusting for long worn
* speed of 3, effective value is 8..48 */
incr = (incr * NORMAL_SPEED) / max(mmove, 1);
wgrowtime[wnum] = g.moves + incr;
}
/* increase HP based on number of segments; if it has shrunk, it
won't gain new HP until regaining previous peak segment count;
when wounded (whether from damage or from shrinking), the HP
which might have been 'new' will heal */
whplimit = !worm->m_lev ? 4 : (8 * (int) worm->m_lev);
/* note: wsegs includes the hidden segment co-located with the head */
if (wsegs > 33)
whplimit += 2 * (wsegs - 33), wsegs = 33;
if (wsegs > 22)
whplimit += 4 * (wsegs - 22), wsegs = 22;
if (wsegs > 11)
whplimit += 6 * (wsegs - 11), wsegs = 11;
whplimit += 8 * wsegs;
if (whplimit > MHPMAX)
whplimit = MHPMAX;
worm->mhp += d(2, 2); /* 2..4, average 3 */
whpcap = max(whplimit, worm->mhpmax);
if (worm->mhp < whpcap) {
/* can't exceed segment-derived limit unless level increase after
peak tail growth has already done so; when that isn't the case,
if segment growth exceeds current max HP then increase it */
if (worm->mhp > whpcap)
worm->mhp = whpcap;
if (worm->mhp > worm->mhpmax)
worm->mhpmax = worm->mhp;
} else {
if (worm->mhp > worm->mhpmax)
worm->mhp = worm->mhpmax;
}
} else {
/* The worm doesn't grow, so the last segment goes away.
(Done after inserting an extra segment at the head, so it
isn't getting smaller here, just changing location without
having to move any of the intermediate segments.) */
shrink_worm(wnum); shrink_worm(wnum);
}
} }
/* /*
@@ -253,10 +292,11 @@ struct monst *worm;
{ {
shrink_worm((int) worm->wormno); /* shrink */ shrink_worm((int) worm->wormno); /* shrink */
if (worm->mhp > 3) if (worm->mhp > count_wsegs(worm)) {
worm->mhp -= 3; /* mhpmax not changed ! */ worm->mhp -= d(2, 2); /* 2..4, average 3; note: mhpmax not changed! */
else if (worm->mhp < 1)
worm->mhp = 1; worm->mhp = 1;
}
} }
/* /*
+5
View File
@@ -64,6 +64,11 @@ tgetch()
{ {
char ch; char ch;
#ifdef SCREEN_VESA
if (iflags.usevesa) {
vesa_flush_text();
}
#endif /*SCREEN_VESA*/
/* BIOSgetch can use the numeric key pad on IBM compatibles. */ /* BIOSgetch can use the numeric key pad on IBM compatibles. */
#ifdef SIMULATE_CURSOR #ifdef SIMULATE_CURSOR
if (iflags.grmode && cursor_flag) if (iflags.grmode && cursor_flag)
+8 -2
View File
@@ -181,6 +181,10 @@ struct overview_planar_cell_struct {
#define ATTRIB_VGA_INTENSE 14 /* Intense White 94/06/07 palette chg*/ #define ATTRIB_VGA_INTENSE 14 /* Intense White 94/06/07 palette chg*/
#endif /*SCREEN_VGA || SCREEN_8514*/ #endif /*SCREEN_VGA || SCREEN_8514*/
#if defined(SCREEN_VESA)
#define BACKGROUND_VESA_COLOR 240
#endif /*SCREEN_VESA*/
#if defined(PC9800) #if defined(PC9800)
static unsigned char attr98[CLR_MAX] = { static unsigned char attr98[CLR_MAX] = {
0xe1, /* 0 white */ 0xe1, /* 0 white */
@@ -249,6 +253,7 @@ E void FDECL(txt_xputc, (CHAR_P, int));
/* ### vidvga.c ### */ /* ### vidvga.c ### */
enum vga_pan_direction { pan_left, pan_up, pan_right, pan_down };
#ifdef SCREEN_VGA #ifdef SCREEN_VGA
E void NDECL(vga_backsp); E void NDECL(vga_backsp);
E void FDECL(vga_clear_screen, (int)); E void FDECL(vga_clear_screen, (int));
@@ -274,7 +279,7 @@ E void FDECL(vga_tty_startup, (int *, int *));
E void FDECL(vga_xputs, (const char *, int, int)); E void FDECL(vga_xputs, (const char *, int, int));
E void FDECL(vga_xputc, (CHAR_P, int)); E void FDECL(vga_xputc, (CHAR_P, int));
E void FDECL(vga_xputg, (int, int, unsigned)); E void FDECL(vga_xputg, (int, int, unsigned));
E void FDECL(vga_userpan, (BOOLEAN_P)); E void FDECL(vga_userpan, (enum vga_pan_direction));
E void FDECL(vga_overview, (BOOLEAN_P)); E void FDECL(vga_overview, (BOOLEAN_P));
E void FDECL(vga_traditional, (BOOLEAN_P)); E void FDECL(vga_traditional, (BOOLEAN_P));
E void NDECL(vga_refresh); E void NDECL(vga_refresh);
@@ -303,10 +308,11 @@ E void FDECL(vesa_tty_startup, (int *, int *));
E void FDECL(vesa_xputs, (const char *, int, int)); E void FDECL(vesa_xputs, (const char *, int, int));
E void FDECL(vesa_xputc, (CHAR_P, int)); E void FDECL(vesa_xputc, (CHAR_P, int));
E void FDECL(vesa_xputg, (int, int, unsigned)); E void FDECL(vesa_xputg, (int, int, unsigned));
E void FDECL(vesa_userpan, (BOOLEAN_P)); E void FDECL(vesa_userpan, (enum vga_pan_direction));
E void FDECL(vesa_overview, (BOOLEAN_P)); E void FDECL(vesa_overview, (BOOLEAN_P));
E void FDECL(vesa_traditional, (BOOLEAN_P)); E void FDECL(vesa_traditional, (BOOLEAN_P));
E void NDECL(vesa_refresh); E void NDECL(vesa_refresh);
E void NDECL(vesa_flush_text);
#endif /* SCREEN_VESA */ #endif /* SCREEN_VESA */
#endif /* NO_TERMS */ #endif /* NO_TERMS */
+1055 -425
View File
File diff suppressed because it is too large Load Diff
+6 -4
View File
@@ -502,18 +502,20 @@ boolean clearfirst;
#endif /* USE_TILES && CLIPPING */ #endif /* USE_TILES && CLIPPING */
void void
vga_userpan(left) vga_userpan(pan)
boolean left; enum vga_pan_direction pan;
{ {
int x; int x;
/* pline("Into userpan"); */ /* pline("Into userpan"); */
if (iflags.over_view || iflags.traditional_view) if (iflags.over_view || iflags.traditional_view)
return; return;
if (left) if (pan == pan_left)
x = min(COLNO - 1, clipxmax + 10); x = min(COLNO - 1, clipxmax + 10);
else else if (pan == pan_right)
x = max(0, clipx - 10); x = max(0, clipx - 10);
else
return;
vga_cliparound(x, 10); /* y value is irrelevant on VGA clipping */ vga_cliparound(x, 10); /* y value is irrelevant on VGA clipping */
positionbar(); positionbar();
vga_DrawCursor(); vga_DrawCursor();
+4
View File
@@ -27,6 +27,10 @@ OPTIONS=rawio,BIOS,symset:IBMGraphics_2,roguesymset:RogueEpyx
# To use VGA graphical tiles on an MS-DOS PC with VGA or better,uncomment # To use VGA graphical tiles on an MS-DOS PC with VGA or better,uncomment
# this: # this:
#OPTIONS=video:autodetect #OPTIONS=video:autodetect
# And to explicitly set the resolution:
#OPTIONS=video_width:1024
#OPTIONS=video_height:768
# If your machine is NEC PC-9800, use: # If your machine is NEC PC-9800, use:
#OPTIONS=rawio,BIOS,video:default #OPTIONS=rawio,BIOS,video:default
-3
View File
@@ -95,9 +95,6 @@ static XtSignalId X11_sig_id;
#endif #endif
#endif #endif
/* this is only needed until X11_status_* routines are written */
extern NEARDATA winid WIN_STATUS;
/* Interface definition, for windows.c */ /* Interface definition, for windows.c */
struct window_procs X11_procs = { struct window_procs X11_procs = {
"X11", "X11",
-3
View File
@@ -19,9 +19,6 @@ winid WIN_WORN = WIN_ERR;
extern void tty_raw_print(const char *); extern void tty_raw_print(const char *);
extern void tty_raw_print_bold(const char *); extern void tty_raw_print_bold(const char *);
/* this is only needed until gnome_status_* routines are written */
extern NEARDATA winid WIN_STATUS;
/* Interface definition, for windows.c */ /* Interface definition, for windows.c */
struct window_procs Gnome_procs = { struct window_procs Gnome_procs = {
"Gnome", WC_COLOR | WC_HILITE_PET | WC_INVERSE, 0L, "Gnome", WC_COLOR | WC_HILITE_PET | WC_INVERSE, 0L,
+2 -11
View File
@@ -107,15 +107,6 @@ struct TileSetImage *image;
if (!read_info_header(fp, &header2)) goto error; if (!read_info_header(fp, &header2)) goto error;
if (!check_info_header(&header2)) goto error; if (!check_info_header(&header2)) goto error;
#if 0 /* TODO */
if (header2.Compression == BI_PNG) {
/* Image data is an embedded PNG bit stream */
boolean ok = do_read_png_tiles(fp, image));
fclose(fp);
return ok;
}
#endif
/* header2.Height < 0 means the Y coordinate is reversed; the origin is /* header2.Height < 0 means the Y coordinate is reversed; the origin is
* top left rather than bottom left */ * top left rather than bottom left */
image->width = header2.Width; image->width = header2.Width;
@@ -300,7 +291,7 @@ struct TileSetImage *image;
break; break;
case 32: case 32:
for (x = 0; x < image->width; ++x) { for (x = 0; x < image->width; ++x) {
uint32 color = read_u32(row_bytes + x * 2); uint32 color = read_u32(row_bytes + x * 4);
row[x] = build_pixel(&header2, color); row[x] = build_pixel(&header2, color);
} }
break; break;
@@ -609,7 +600,7 @@ uint32 color;
if (mask == 0) return 0; if (mask == 0) return 0;
bits = 0xFFFF; /* 0xFF, 0xF, 0x3, 0x1 */ bits = 0xFFFF; /* 0xFF, 0xF, 0x3, 0x1 */
shift = 16; /* 8, 4, 2, 1 */ shift = 16; /* 8, 4, 2, 1 */
while (bits != 0) { while (shift != 0) {
if ((mask & bits) == 0) { if ((mask & bits) == 0) {
mask >>= shift; mask >>= shift;
color >>= shift; color >>= shift;
+130
View File
@@ -6,6 +6,7 @@
#include "tileset.h" #include "tileset.h"
static void FDECL(get_tile_map, (const char *)); static void FDECL(get_tile_map, (const char *));
static unsigned FDECL(gcd, (unsigned, unsigned));
static void FDECL(split_tiles, (const struct TileSetImage *)); static void FDECL(split_tiles, (const struct TileSetImage *));
static void FDECL(free_image, (struct TileSetImage *)); static void FDECL(free_image, (struct TileSetImage *));
@@ -100,6 +101,29 @@ error:
return FALSE; return FALSE;
} }
/* Free tile memory not required by the chosen display mode */
boolean
set_tile_type(true_color)
boolean true_color;
{
unsigned i;
if (tiles) {
if (true_color) {
for (i = 0; i < num_tiles; ++i) {
free((genericptr_t) tiles[i].indexes);
tiles[i].indexes = NULL;
}
have_palette = FALSE;
} else {
for (i = 0; i < num_tiles; ++i) {
free((genericptr_t) tiles[i].pixels);
tiles[i].pixels = NULL;
}
}
}
}
const struct Pixel * const struct Pixel *
get_palette() get_palette()
{ {
@@ -155,6 +179,112 @@ unsigned tile_index;
return &tiles[tile_index]; return &tiles[tile_index];
} }
/* Note that any tile returned by this function must be freed */
struct TileImage *
stretch_tile(inp_tile, out_width, out_height)
const struct TileImage *inp_tile;
unsigned out_width, out_height;
{
unsigned x_scale_inp, x_scale_out, y_scale_inp, y_scale_out;
unsigned divisor;
unsigned size;
struct TileImage *out_tile;
unsigned x_inp, y_inp, x2, y2, x_out, y_out;
unsigned pos;
/* Derive the scale factors */
divisor = gcd(out_width, inp_tile->width);
x_scale_inp = inp_tile->width / divisor;
x_scale_out = out_width / divisor;
divisor = gcd(out_height, inp_tile->height);
y_scale_inp = inp_tile->height / divisor;
y_scale_out = out_height / divisor;
/* Derive the stretched tile */
out_tile = (struct TileImage *) alloc(sizeof(struct TileImage));
out_tile->width = out_width;
out_tile->height = out_height;
size = out_width * out_height;
if (inp_tile->pixels != NULL) {
out_tile->pixels = (struct Pixel *) alloc(size * sizeof(struct Pixel));
divisor = x_scale_inp * y_scale_inp;
for (y_out = 0; y_out < out_height; ++y_out) {
for (x_out = 0; x_out < out_width; ++x_out) {
unsigned r, g, b, a;
/* Derive output pixels by blending input pixels */
r = 0;
g = 0;
b = 0;
a = 0;
for (y2 = 0; y2 < y_scale_inp; ++y2) {
y_inp = (y_out * y_scale_inp + y2) / y_scale_out;
for (x2 = 0; x2 < x_scale_inp; ++x2) {
x_inp = (x_out * x_scale_inp + x2) / x_scale_out;
pos = y_inp * inp_tile->width + x_inp;
r += inp_tile->pixels[pos].r;
g += inp_tile->pixels[pos].g;
b += inp_tile->pixels[pos].b;
a += inp_tile->pixels[pos].a;
}
}
pos = y_out * out_width + x_out;
out_tile->pixels[pos].r = r / divisor;
out_tile->pixels[pos].g = g / divisor;
out_tile->pixels[pos].b = b / divisor;
out_tile->pixels[pos].a = a / divisor;
}
}
} else {
out_tile->pixels = NULL;
}
/* If the output device uses a palette, we can't blend; just pick
a subset of the pixels */
if (inp_tile->indexes != NULL) {
out_tile->indexes = (unsigned char *) alloc(size);
for (y_out = 0; y_out < out_height; ++y_out) {
for (x_out = 0; x_out < out_width; ++x_out) {
pos = y_out * out_width + x_out;
x_inp = x_out * x_scale_inp / x_scale_out;
y_inp = y_out * y_scale_inp / y_scale_out;
out_tile->indexes[pos] =
inp_tile->indexes[y_inp * inp_tile->width + x_inp];
}
}
} else {
out_tile->indexes = NULL;
}
return out_tile;
}
/* Free a tile returned by stretch_tile */
/* Do NOT use this with tiles returned by get_tile */
void
free_tile(tile)
struct TileImage *tile;
{
if (tile != NULL) {
free(tile->indexes);
free(tile->pixels);
free(tile);
}
}
/* Return the greatest common divisor */
static unsigned
gcd(a, b)
unsigned a, b;
{
while (TRUE) {
if (b == 0) return a;
a %= b;
if (a == 0) return b;
b %= a;
}
}
static void static void
split_tiles(image) split_tiles(image)
const struct TileSetImage *image; const struct TileSetImage *image;
+2 -4
View File
@@ -72,9 +72,6 @@ extern short glyph2tile[];
#define HUPSKIP_RESULT(RES) /*empty*/ #define HUPSKIP_RESULT(RES) /*empty*/
#endif /* ?HANGUP_HANDLING */ #endif /* ?HANGUP_HANDLING */
/* this is only needed until tty_status_* routines are written */
extern NEARDATA winid WIN_STATUS;
/* Interface definition, for windows.c */ /* Interface definition, for windows.c */
struct window_procs tty_procs = { struct window_procs tty_procs = {
"tty", "tty",
@@ -155,11 +152,12 @@ char defmorestr[] = "--More--";
#if defined(USE_TILES) && defined(MSDOS) #if defined(USE_TILES) && defined(MSDOS)
boolean clipping = FALSE; /* clipping on? */ boolean clipping = FALSE; /* clipping on? */
int clipx = 0, clipxmax = 0; int clipx = 0, clipxmax = 0;
int clipy = 0, clipymax = 0;
#else #else
static boolean clipping = FALSE; /* clipping on? */ static boolean clipping = FALSE; /* clipping on? */
static int clipx = 0, clipxmax = 0; static int clipx = 0, clipxmax = 0;
#endif
static int clipy = 0, clipymax = 0; static int clipy = 0, clipymax = 0;
#endif
#endif /* CLIPPING */ #endif /* CLIPPING */
#if defined(USE_TILES) && defined(MSDOS) #if defined(USE_TILES) && defined(MSDOS)