view srogue/global.c @ 110:5f51f7d9805f

arogue5: fix some save/restore-related crashes. The save/restore code took the pointer intended as an argument for the doctor() daemon and wrote it to the savefile as an int. I don't know why it took so long to fail horribly. The problem has been avoided by replacing the value with &player when restoring. That seems to be the only argument ever actually used. The code also writes only four bytes for an unsigned long; if sizeof(long) == 8, it casts to unsigned int first. It failed to do the cast when reading back, with the result that four bytes were read and the other half of the number was effectively uninitialized. It apparently works now, but the save/restore code ought still to be regarded as decidedly unfortunate.
author John "Elwin" Edwards
date Mon, 06 Jan 2014 15:57:17 -0500
parents 34d7a614855e
children ee250e3646fd
line wrap: on
line source

/*
 * global variable declaration
 *
 * @(#)global.c	9.0	(rdk)	 7/17/84
 *
 * Super-Rogue
 * Copyright (C) 1984 Robert D. Kindelberger
 * All rights reserved.
 *
 * Based on "Rogue: Exploring the Dungeons of Doom"
 * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
 * All rights reserved.
 *
 * See the file LICENSE.TXT for full copyright and licensing information.
 */

#include "rogue.h"

struct room rooms[MAXROOMS];		/* One for each room -- A level */
struct room *oldrp;					/* Roomin(&oldpos) */
struct linked_list *mlist = NULL;	/* monsters on this level */
struct thing player;				/* The rogue */
struct stats max_stats;				/* The maximum for the player */
struct linked_list *lvl_obj = NULL;	/* objects on this level */
struct object *cur_weapon = NULL;	/* Which weapon he is weilding */
struct object *cur_armor = NULL;	/* the rogue's armor */
struct object *cur_ring[2];			/* Which rings are being worn */
struct stats *him;					/* pointer to hero stats */
struct trap traps[MAXTRAPS];		/* traps on this level */

int playuid;				/* uid of current player */
int playgid;				/* gid of current player */
int level = 1;				/* What level rogue is on */
int levcount = 0;			/* # of active mons this level */
int levtype = NORMLEV;		/* type of level this is, maze, etc. */
int trader = 0;				/* no. of purchases */
int curprice = -1;			/* current price of item */
int purse = 0;				/* How much gold the rogue has */
int mpos = 0;				/* Where cursor is on top line */
int ntraps;					/* # of traps on this level */
int packvol = 0;			/* volume of things in pack */
int total = 0;				/* Total dynamic memory bytes */
int demoncnt = 0;			/* number of active daemons */
int lastscore = -1;			/* Score before this turn */
int no_food = 0;			/* # of levels without food */
int seed;					/* Random number seed */
int dnum;					/* Dungeon number */
int count = 0;				/* # of times to repeat cmd */
int fung_hit = 0;			/* # of time fungi has hit */
int quiet = 0;				/* # of quiet turns */
int max_level = 1;			/* Deepest player has gone */
int food_left = HUNGERTIME;	/* Amount of food stomach */
int group = NEWGROUP;		/* Current group number */
int hungry_state = F_OKAY;	/* How hungry is he */
int foodlev = 1;			/* how fast he eats food */
int ringfood = 0;			/* rings affect on food consumption */
char take;					/* Thing the rogue is taking */
char runch;					/* Direction player is running */
char curpurch[15];			/* name of item ready to buy */

char prbuf[LINLEN];			/* Buffer for sprintfs */
char whoami[LINLEN];		/* Name of player */
char fruit[LINLEN];			/* Favorite fruit */
char huh[LINLEN];			/* The last message printed */
char file_name[LINLEN];		/* Save file name */
char scorefile[LINLEN];		/* place for scorefile */
char home[LINLEN];			/* User's home directory */
char outbuf[BUFSIZ];		/* Output buffer for stdout */

char *s_guess[MAXSCROLLS];		/* his guess at what scroll is */
char *p_guess[MAXPOTIONS];		/* his guess at what potion is */
char *r_guess[MAXRINGS];		/* his guess at what ring is */
char *ws_guess[MAXSTICKS];		/* his guess at what wand is */

bool isfight = FALSE;		/* true if player is fighting */
bool nlmove = FALSE;		/* true when transported to new level */
bool inpool = FALSE;		/* true if hero standing in pool */
bool inwhgt = FALSE;		/* true if from wghtchk() */
bool running = FALSE;		/* True if player is running */
bool playing = TRUE;		/* True until he quits */
bool wizard = FALSE;		/* True if he is a wizard */
bool after = TRUE;			/* True if we want after daemons */
bool door_stop = FALSE;		/* Stop run when we pass a door */
bool firstmove = FALSE;		/* First move after door_stop */
bool waswizard = FALSE;		/* Was a wizard sometime */
bool amulet = FALSE;		/* He found the amulet */
bool in_shell = FALSE;		/* True if executing a shell */
bool nochange = FALSE;		/* true if last stat same as now */
bool use_savedir = FALSE;	/* true if using system savefiles */

bool s_know[MAXSCROLLS];		/* Does he know about a scroll */
bool p_know[MAXPOTIONS];		/* Does he know about a potion */
bool r_know[MAXRINGS];			/* Does he know about a ring */
bool ws_know[MAXSTICKS];		/* Does he know about a stick */

char spacemsg[] =	{ "-- Press space to continue --" };
char morestr[] =	{ "-- More --" };
char retstr[] =		{ "[Press return to continue]" };
char wizstr[] =		{ "Wizards Password: " };
char illegal[] =	{ "Illegal command '%s'." };
char callit[] =		{ "Call it: " };
char starlist[] =	{ " (* for a list)" };

struct coord oldpos;		/* Pos before last look() call */
struct coord delta;			/* Change indicated to get_dir() */
struct coord stairs;		/* where the stairs are put */
struct coord rndspot = { -1, -1 };	/* for random teleporting */

struct monster *mtlev[MONRANGE];

#define _r {10,10,10,10}	/* real ability (unused) */
#define _p 0,0,0,0			/* hit points, pack, carry (unused) */
#define _c 10				/* constitution (unused) */

/*
 * NAME SHOW CARRY {LEVEL} FLAGS _r {STR DEX WIS _c} EXP LVL ARM _p DMG
 */
struct monster monsters[MAXMONS + 1] = {
{"giant ant",'A',0,{3,12,1},ISMEAN,{_r,{10,16,5,_c},10,2,3,_p,"1d6"}},
{"bat",'B',0,{1,6,1},ISHUH,{_r,{10,10,10,_c},1,1,3,_p,"1d2"}},
{"centaur",'C',15,{8,17,1},0,{_r,{16,10,15,_c},15,4,4,_p,"1d6/1d6"}},
{"red dragon",'D',100,{21,500,0},ISGREED,{_r,{17,10,17,_c},9000,11,-1,_p,"1d8/1d8/3d10"}},
{"floating eye",'E',0,{2,11,0},0,{_r,{10,10,10,_c},5,1,9,_p,"0d0"}},
{"violet fungi",'F',0,{15,24,0},ISMEAN|ISSTUCK,{_r,{10,5,3,_c},85,8,2,_p,"000d0"}},
{"gnome",'G',10,{6,15,1},0,{_r,{10,10,11,_c},8,1,5,_p,"1d6"}},
{"hobgoblin",'H',0,{1,8,1},ISMEAN,{_r,{10,10,10,_c},3,1,5,_p,"1d8"}},
{"invisible stalker",'I',0,{16,25,1},ISINVIS|ISHUH,{_r,{10,15,15,_c},120,8,2,_p,"4d4"}},
{"jackal",'J',0,{1,6,1},ISMEAN,{_r,{10,10,10,_c},2,1,7,_p,"1d2"}},
{"kobold",'K',0,{1,6,1},ISMEAN,{_r,{10,10,10,_c},1,1,8,_p,"1d4"}},
{"leprechaun",'L',0,{7,16,0},0,{_r,{10,15,16,_c},10,3,8,_p,"1d1"}},
{"mimic",'M',30,{19,500,0},0,{_r,{10,10,10,_c},140,8,7,_p,"3d4"}},
{"nymph",'N',100,{11,20,0},0,{_r,{10,18,18,_c},40,3,9,_p,"0d0"}},
{"orc",'O',15,{4,13,1},0,{_r,{10,10,10,10},5,1,6,_p,"1d8"}},
{"purple worm",'P',70,{22,500,0},0,{_r,{18,5,10,_c},7000,15,6,_p,"2d12/2d4"}},
{"quasit",'Q',30,{10,19,1},ISMEAN,{_r,{10,15,16,_c},35,3,2,_p,"1d2/1d2/1d4"}},
{"rust monster",'R',0,{9,18,1},ISMEAN,{_r,{10,10,10,_c},25,5,2,_p,"0d0/0d0"}},
{"snake",'S',0,{1,7,1},ISMEAN,{_r,{10,10,10,_c},3,1,5,_p,"1d3"}},
{"troll",'T',50,{13,22,0},ISMEAN|ISREGEN,{_r,{10,10,11,_c},55,6,4,_p,"1d8/1d8/2d6"}},
{"umber hulk",'U',40,{18,500,1},ISMEAN,{_r,{17,10,10,_c},130,8,2,_p,"3d4/3d4/2d5"}},
{"vampire",'V',20,{20,500,1},ISMEAN|ISREGEN,{_r,{21,16,16,_c},380,8,1,_p,"1d10"}},
{"wraith",'W',0,{14,23,1},ISMEAN,{_r,{10,10,10,_c},55,5,4,_p,"1d6"}},
{"xorn",'X',0,{17,26,1},ISMEAN,{_r,{17,6,11,_c},120,7,-2,_p,"1d3/1d3/1d3/4d6"}},
{"yeti",'Y',30,{12,21,1},ISMEAN,{_r,{10,10,10,_c},50,4,6,_p,"1d6/1d6"}},
{"zombie",'Z',0,{5,14,1},ISMEAN,{_r,{10,10,10,_c},7,2,8,_p,"1d8"}},
{"anhkheg",'a',10,{7,16,1},ISMEAN,{_r,{10,15,3,_c},20,3,2,_p,"3d6"}},
{"giant beetle",'b',0,{9,18,1},ISMEAN,{_r,{10,15,10,_c},30,5,3,_p,"4d4"}},
{"cockatrice",'c',100,{8,17,0},0,{_r,{10,10,11,_c},200,5,6,_p,"1d3"}},
{"bone devil",'d',0,{27,500,1},ISMEAN,{_r,{18,10,16,_c},8000,12,-1,_p,"5d4"}},
{"elasmosaurus",'e',0,{28,500,1},ISMEAN,{_r,{17,5,3,_c},4500,12,7,_p,"4d6"}},
{"killer frog",'f',0,{3,8,1},ISMEAN,{_r,{10,10,10,_c},4,3,8,_p,"2d3/1d4"}},
{"green dragon",'g',50,{25,500,1},0,{_r,{18,10,18,_c},7500,10,2,_p,"1d6/1d6/2d10"}},
{"hell hound",'h',20,{10,19,1},ISMEAN,{_r,{10,15,10,_c},30,5,4,_p,"1d10"}},
{"imp",'i',20,{2,9,1},ISMEAN|ISREGEN,{_r,{10,14,11,_c},6,2,1,_p,"1d4"}},
{"jaguar",'j',0,{10,19,0},0,{_r,{10,10,11,_c},25,8,6,_p,"2d3/2d5"}},
{"koppleganger",'k',20,{8,17,1},ISMEAN,{_r,{10,10,16,_c},35,4,5,_p,"1d12"}},
{"lonchu",'l',15,{2,9,1},ISMEAN,{_r,{10,4,18,_c},5,2,1,_p,"1d4/1d4"}},
{"minotaur",'m',0,{12,21,1},ISMEAN,{_r,{10,10,11,_c},40,8,6,_p,"1d3/2d4"}},
{"neotyugh",'n',10,{14,23,1},ISMEAN,{_r,{10,6,4,_c},50,6,3,_p,"1d8/1d8/2d3"}},
{"ogre",'o',50,{7,16,1},0,{_r,{20,10,10,_c},15,4,5,_p,"2d6"}},
{"pseudo dragon",'p',50,{9,18,1},0,{_r,{10,10,16,_c},20,4,2,_p,"2d3/1d6"}},
{"quellit",'q',85,{30,500,1},0,{_r,{17,10,10,_c},12500,17,0,_p,"2d10/2d6"}},
{"rhynosphinx",'r',40,{26,500,0},0,{_r,{19,6,18,_c},5000,13,-1,_p,"2d10/2d8"}},
{"shadow",'s',15,{5,14,1},ISMEAN|ISREGEN|ISINVIS,{_r,{10,17,18,_c},6,3,5,_p,"1d6"}},
{"titanothere",'t',0,{19,500,0},0,{_r,{17,6,3,_c},750,14,6,_p,"2d8/1d6"}},
{"ulodyte",'u',10,{2,8,1},ISMEAN,{_r,{10,10,10,_c},3,2,5,_p,"1d3/1d3"}},
{"vrock",'v',0,{4,13,1},ISMEAN,{_r,{10,10,11,_c},8,3,2,_p,"1d4/1d6"}},
{"wuccubi",'w',0,{14,23,1},ISMEAN,{_r,{10,10,10,_c},90,6,0,_p,"1d4/1d10"}},
{"xonoclon",'x',0,{20,500,0},0,{_r,{19,10,4,_c},1750,14,0,_p,"3d8"}},
{"yeenoghu",'y',10,{15,24,1},ISMEAN,{_r,{17,15,10,_c},250,8,1,_p,"3d6"}},
{"zemure",'z',0,{1,6,1},ISMEAN|ISREGEN,{_r,{10,10,10,_c},4,2,7,_p,"1d4"}},
{"devil Asmodeus",'A',-1,{1,500,1},ISMEAN|ISREGEN,{_r,{24,18,18,_c},500000,40,-10,_p,"4d10/4d10"}},
};

#undef _p		/* erase these definitions */
#undef _c
#undef _r

struct h_list helpstr[] = {
	'?',	"	prints help",
	'/',	"	identify object",
	'h',	"	left",
	'j',	"	down",
	'k',	"	up",
	'l',	"	right",
	'y',	"	up & left",
	'u',	"	up & right",
	'b',	"	down & left",
	'n',	"	down & right",
	'H',	"	run left",
	'J',	"	run down",
	'K',	"	run up",
	'L',	"	run right",
	'Y',	"	run up & left",
	'U',	"	run up & right",
	'B',	"	run down & left",
	'N',	"	run down & right",
	't',	"<dir>	throw something",
	'f',	"<dir>	forward until find something",
	'p',	"<dir>	zap a wand in a direction",
	'z',	"	zap a wand or staff",
	'>',	"	go down a staircase",
	's',	"	search for trap/secret door",
	'.',	"	(dot) rest for a while",
	'i',	"	inventory pack",
	'I',	"	inventory single item",
	'q',	"	quaff potion",
	'r',	"	read a scroll",
	'e',	"	eat food",
	'w',	"	wield a weapon",
	'W',	"	wear armor",
	'T',	"	take armor off",
	'P',	"	put on ring",
	'R',	"	remove ring",
	'd',	"	drop object",
	'c',	"	call object",
	'O',	"	examine/set options",
	'a',	"	display maximum stats",
	'D',	"	dip object in pool",
	CTRL('L'),"	redraw screen",
	ESCAPE,	"	cancel command",
	'!',	"	shell escape",
	'S',	"	save game",
	'Q',	"	quit",
	0, 0
};

char *s_names[MAXSCROLLS];		/* Names of the scrolls */
char *p_colors[MAXPOTIONS];		/* Colors of the potions */
char *r_stones[MAXRINGS];		/* Stone settings of the rings */
struct rod ws_stuff[MAXSTICKS];	/* Stuff for sticks */

struct magic_item things[NUMTHINGS + 1] = {
	{ "potion",	257,	 5, },
	{ "scroll",	250,	30, },
	{ "food",	185,	 7, },
	{ "weapon",	 92,	 0, },
	{ "armor",	 92,	 0, },
	{ "ring",	 62,	 5, },
	{ "stick",	 62,	 0, },
	{ "amulet",	 0,   -250, },
	{ NULL,		 0,		 0,	},
};

struct magic_item a_magic[MAXARMORS + 1] = {
	{ "leather armor",			170,   5 },
	{ "ring mail",				130,  30 },
	{ "studded leather armor",	130,  20 },
	{ "scale mail",				120,   3 },
	{ "padded armor",			100, 250 },
	{ "chain mail",				 90,  75 },
	{ "splint mail",			 90,  80 },
	{ "banded mail",			 90,  90 },
	{ "plate mail",		 		 50, 400 },
	{ "plate armor",			 30, 650 },
	{ NULL,						  0,   0 },
};
struct init_armor armors[MAXARMORS] = {
	{ 8,	150,	500,	},
	{ 7,	250,	650,	},
	{ 7,	200,	550,	},
	{ 6,	400,	900,	},
	{ 6,	100,	450,	},
	{ 5,	300,	650,	},
	{ 4,	400,	700,	},
	{ 4,	350,	600,	},
	{ 3,	450,	950,	},
	{ 2,	350,	750,	},
};
struct magic_item w_magic[MAXWEAPONS + 1] = {
	{ "mace",				 70,  25 },
	{ "long sword",			 70,  60 },
	{ "short bow",			 60, 150 },
	{ "arrow",				 60,   2 },
	{ "dagger",				 20,   5 },
	{ "rock",				 20,   1 },
	{ "two-handed sword",	 50, 120 },
	{ "sling",				 20,   5 },
	{ "dart",				 30,   3 },
	{ "crossbow",			 60,  70 },
	{ "crossbow bolt",		 60,   3 },
	{ "spear",				 70,   8 },
	{ "trident",			 70,  90 },
	{ "spetum",				 70,  50 },
	{ "bardiche",			 70,  30 },
	{ "pike",				 70,  75 },
	{ "bastard sword",		 60, 100 },
	{ "halberd",			 70,  40 },
	{ NULL,					  0,   0 },
};

struct init_weps weaps[MAXWEAPONS] = {
	{ "2d4",  "1d3", 0, 100, 300, NONE },
	{ "1d10", "1d2", 0,  60, 180, NONE },
	{ "1d1",  "1d1", 0,  40, 190, NONE },
	{ "1d1",  "1d6", ISMANY|ISMISL, 5, 8, BOW },
	{ "1d6",  "1d4", ISMISL, 10, 30, NONE },
	{ "1d2",  "1d4", ISMANY|ISMISL, 5, 10, SLING },
	{ "3d6",  "1d2", 0, 250, 550, NONE },
	{ "0d0",  "0d0", 0,   5, 7, NONE },
	{ "1d1",  "1d3", ISMANY|ISMISL, 5, 5, NONE },
	{ "1d1",  "1d1", 0, 100, 250, NONE },
	{ "1d2", "1d10", ISMANY|ISMISL, 7, 11, CROSSBOW },
	{ "1d8",  "1d6", ISMISL, 50, 200, NONE },
	{ "3d4",  "1d4", 0,  50, 220, NONE },
	{ "2d5",  "1d3", 0,  50, 200, NONE },
	{ "3d3",  "1d2", 0, 125, 270, NONE },
	{ "1d12", "1d8", 0,  80, 260, NONE },
	{ "2d7",  "1d2", 0, 100, 400, NONE },
	{ "2d6",  "1d3", 0, 175, 370, NONE },
};

struct magic_item s_magic[MAXSCROLLS + 1] = {
	{ "monster confusion",	 50, 200 },
	{ "magic mapping",		 52, 200 },
	{ "light",				 80, 100 },
	{ "hold monster",		 25, 200 },
	{ "sleep",				 41,  50 },
	{ "enchant armor",		 75, 175 },
	{ "identify",			211, 150 },
	{ "scare monster",		 42, 300 },
	{ "gold detection",		 32, 100 },
	{ "teleportation",		 73, 200 },
	{ "enchant weapon",		 91, 175 },
	{ "create monster",		 34,  75 },
	{ "remove curse",		 82, 100 },
	{ "aggravate monsters",	 10,  50 },
	{ "blank paper",		 11,  50 },
	{ "genocide",			  5, 350 },
	{ "item knowledge",		 14, 250 },
	{ "item protection",	  9, 250 },
	{ "demons curse",		  5,  25 },
	{ "transport",			 11, 100 },
	{ "enchantment",		  3, 300 },
	{ "gods blessing",		  4, 450 },
	{ "aquirement",			  3, 450 },
	{ "banishment",			  5,  25 },
	{ "recharge wand",		 14, 250 },
	{ "locate traps",		 18, 185 },
	{ NULL,					  0,   0 },
};

struct magic_item p_magic[MAXPOTIONS + 1] = {
	{ "confusion",			 69,  50 },
	{ "paralysis",			 69,  50 },
	{ "poison",				 55,  50 },
	{ "gain strength",		130, 150 },
	{ "see invisible",		 25, 175 },
	{ "healing",			120, 130 },
	{ "monster detection",	 59, 120 },
	{ "magic detection",	 54, 105 },
	{ "raise level",		 25, 300 },
	{ "extra healing",		 52, 175 },
	{ "haste self",			 41, 200 },
	{ "restore strength",	140, 200 },
	{ "blindness",			 25,  50 },
	{ "thirst quenching",	 10,  50 },
	{ "increase dexterity",	 50, 175 },
	{ "etherealness",		 20, 150 },
	{ "increase wisdom",	 35, 175 },
	{ "regeneration",		 10, 175 },
	{ "super ability",		  3, 500 },
	{ "decrepedness",		  4,  25 },
	{ "invincibility",		  4, 500 },
	{ NULL,					  0,   0 },
};

struct magic_item r_magic[MAXRINGS + 1] = {
	{ "protection",			 71, 200 },
	{ "strength",			 70, 200 },
	{ "sustain strength",	 45, 250 },
	{ "searching",			 70, 150 },
	{ "see invisible",		 77, 175 },
	{ "constitution",		 13, 350 },
	{ "aggravate monster",	 60, 100 },
	{ "agility",			 75, 250 },
	{ "increase damage",	 61, 250 },
	{ "regeneration",		 41, 250 },
	{ "digestion",			 60, 225 },
	{ "teleportation",		 60, 100 },
	{ "stealth",			 75, 200 },
	{ "speed",				 40, 225 },
	{ "find traps",			 27, 200 },
	{ "delusion",			 18, 100 },
	{ "sustain ability",	  9, 450 },
	{ "blindness",			 10,  50 },
	{ "lethargy",			 14,  75 },
	{ "ogre strength",		  8, 350 },
	{ "enfeeblement",		  5,  25 },
	{ "burden",				 10,  50 },
	{ "illumination",		 16, 100 },
	{ "fire protection",	  5, 225 },
	{ "wisdom",				 25, 200 },
	{ "dexterity",			 35, 200 },
	{ NULL,					  0,   0 },
};

struct magic_item ws_magic[MAXSTICKS + 1] = {
	{ "light",				 95, 120 },
	{ "striking",			 75, 115 },
	{ "lightning",			 30, 200 },
	{ "fire",				 30, 200 },
	{ "cold",				 30, 200 },
	{ "polymorph",			 95, 210 },
	{ "magic missile",		 70, 170 },
	{ "haste monster",		 80,  50 },
	{ "slow monster",		 90, 220 },
	{ "drain life",			 80, 210 },
	{ "nothing",			 10,  70 },
	{ "teleport away",		 55, 140 },
	{ "teleport to",		 50,  60 },
	{ "cancellation",		 55, 130 },
	{ "sap life",			 20,  50 },
	{ "curing",				 25, 250 },
	{ "pyromania",			 15,  25 },
	{ "annihilate monster",	  5, 750 },
	{ "paralyze monster",	 10, 650 },
	{ "food absorption",	 10,  75 },
	{ "regenerate monster",	 15,  25 },
	{ "hide monster",		 10,  50 },
	{ "anti-matter",		  5,  25 },
	{ "clone monster",		 10,  10 },
	{ "confuse monster",	 15, 150 },
	{ "degenerate monster",	 15, 150 },
	{ NULL,					  0,   0 },
};

struct magic_info thnginfo[NUMTHINGS] = {
	{ MAXPOTIONS,	V_POTION,	POTION,	p_magic,	},
	{ MAXSCROLLS,	V_SCROLL,	SCROLL,	s_magic,	},
	{ MAXFOODS,		V_FOOD,		FOOD,	NULL,		},
	{ MAXWEAPONS,	V_WEAPON,	WEAPON,	w_magic,	},
	{ MAXARMORS,	V_ARMOR,	ARMOR,	a_magic,	},
	{ MAXRINGS,		V_RING,		RING,	r_magic,	},
	{ MAXSTICKS,	V_STICK,	STICK,	ws_magic,	},
	{ MAXAMULETS,	V_AMULET,	AMULET,	NULL,		},
};

long e_levels[] = {
    10L,20L,40L,80L,160L,320L,640L,1280L,2560L,5120L,10240L,20480L,
    40920L, 81920L, 163840L, 327680L, 655360L, 1310720L, 2621440L,
	3932160L, 5242880L, 7864320L, 10485760L, 15728640L, 20971520L,
	41943040L, 83886080L, 167772160L, 335544320L, 0L,
};

WINDOW *cw;		/* what the hero sees */
WINDOW *hw;		/* utility window */
WINDOW *mw;		/* monster window */