changeset 0:527e2150eaf0

Import Rogue 3.6 from the Roguelike Restoration Project (r1490)
author edwarj4
date Tue, 13 Oct 2009 13:33:34 +0000
parents
children b4856d4d4c4e
files rogue3/LICENSE.TXT rogue3/Makefile rogue3/armor.c rogue3/chase.c rogue3/command.c rogue3/daemon.c rogue3/daemons.c rogue3/fight.c rogue3/init.c rogue3/io.c rogue3/list.c rogue3/machdep.h rogue3/main.c rogue3/mdport.c rogue3/mdport.h rogue3/misc.c rogue3/monsters.c rogue3/move.c rogue3/newlevel.c rogue3/options.c rogue3/pack.c rogue3/passages.c rogue3/potions.c rogue3/readme36.html rogue3/rings.c rogue3/rip.c rogue3/rogue.6 rogue3/rogue.h rogue3/rogue.r rogue3/rogue36.cat rogue3/rogue36.doc rogue3/rogue36.html rogue3/rogue36.sln rogue3/rogue36.vcproj rogue3/rooms.c rogue3/save.c rogue3/scrolls.c rogue3/state.c rogue3/sticks.c rogue3/things.c rogue3/vers.c rogue3/weapons.c rogue3/wizard.c rogue3/xcrypt.c
diffstat 44 files changed, 15930 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rogue3/LICENSE.TXT	Tue Oct 13 13:33:34 2009 +0000
@@ -0,0 +1,92 @@
+Rogue: Exploring the Dungeons of Doom
+Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. Neither the name(s) of the author(s) nor the names of other contributors
+   may be used to endorse or promote products derived from this software
+   without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+===========================================================================
+
+Portions of this software (state.c/mdport.c/mdport.h) are based on the work 
+of Nicholas J. Kisseberth. Used under license:
+
+Copyright (C) 1999, 2000, 2006, 2007, 2008 Nicholas J. Kisseberth
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. Neither the name(s) of the author(s) nor the names of other contributors
+   may be used to endorse or promote products derived from this software
+   without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+===========================================================================
+
+Portions of this software (xcrypt.c) are based on the work 
+of David Burren. Used under license:
+
+FreeSec: libcrypt
+
+Copyright (C) 1994 David Burren
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. Neither the name(s) of the author(s) nor the names of other contributors
+   may be used to endorse or promote products derived from this software
+   without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rogue3/Makefile	Tue Oct 13 13:33:34 2009 +0000
@@ -0,0 +1,151 @@
+#
+# Makefile for rogue
+# %W% (Berkeley) %G%
+#
+# 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.
+#
+
+DISTNAME=rogue3.6.4
+PROGRAM=rogue
+
+O=o
+
+HDRS= 	rogue.h machdep.h
+
+OBJS1 = vers.$(O) armor.$(O) chase.$(O) command.$(O) daemon.$(O) daemons.$(O) \
+        fight.$(O) init.$(O) io.$(O) list.$(O) main.$(O) mdport.$(O) \
+	misc.$(O) monsters.$(O) move.$(O) newlevel.$(O) options.$(O) 
+OBJS2 =	pack.$(O) passages.$(O) potions.$(O) rings.$(O) rip.$(O) rooms.$(O) \
+	save.$(O) scrolls.$(O) state.$(O) sticks.$(O) things.$(O) \
+	weapons.$(O) wizard.$(O) xcrypt.$(O)
+OBJS  = $(OBJS1) $(OBJS2)
+
+CFILES= vers.c armor.c chase.c command.c daemon.c daemons.c fight.c \
+	init.c io.c list.c main.c mdport.c misc.c monsters.c move.c newlevel.c \
+	options.c pack.c passages.c potions.c rings.c rip.c rooms.c \
+	save.c scrolls.c state.c sticks.c things.c weapons.c wizard.c xcrypt.c
+
+
+MISC_C=
+DOCSRC= rogue.6 rogue.r
+DOCS  = $(PROGRAM).doc $(PROGRAM).cat $(PROGRAM).html readme36.html
+MISC  =	Makefile $(MISC_C) LICENSE.TXT $(PROGRAM).sln $(PROGRAM).vcproj $(DOCS)\
+	$(DOCSRC)
+
+CC    = gcc
+ROPTS =
+COPTS = -O3
+CFLAGS= $(COPTS) $(ROPTS) -DSCOREFILE=\"rogue36.scr\"
+LIBS  = -lcurses
+RM    = rm -f
+LD    = $(CC)
+LDOUT = -o 
+
+.SUFFIXES: .obj
+
+.c.obj:
+	$(CC) $(CFLAGS) /c $*.c
+
+$(PROGRAM)$(EXE): $(HDRS) $(OBJS)
+	$(LD) $(LDFLAGS) $(OBJS) $(LIBS) $(LDOUT)$@
+
+clean:
+	$(RM) $(OBJS1)
+	$(RM) $(OBJS2)
+	$(RM) core $(PROGRAM) $(PROGRAM).exe $(DISTNAME).tar $(DISTNAME).tar.gz 
+	$(RM) $(DISTNAME).zip
+
+dist.src:
+	make clean
+	tar cf $(DISTNAME)-src.tar $(CFILES) $(HDRS) $(MISC) $(DOCS)
+	gzip -f $(DISTNAME)-src.tar
+
+dist.irix:
+	@$(MAKE) clean
+	@$(MAKE) CC=cc CFLAGS="-woff 1116 -O3" $(PROGRAM)
+#	tbl rogue.r | nroff -ms | colcrt - > $(PROGRAM).doc
+#	nroff -man rogue.6 | colcrt - > $(PROGRAM).cat
+	tar cf $(DISTNAME)-irix.tar $(PROGRAM) LICENSE.TXT $(DOCS)
+	gzip -f $(DISTNAME)-irix.tar
+
+dist.aix:
+	@$(MAKE) clean
+	@$(MAKE) CC=xlc CFLAGS="-qmaxmem=16768 -O3 -qstrict" $(PROGRAM)
+#	tbl rogue.r | nroff -ms | colcrt - > $(ROGUE).doc
+#	nroff -man rogue.6 | colcrt - > $(ROGUE).cat
+	tar cf $(DISTNAME)-aix.tar $(PROGRAM) LICENSE.TXT $(DOCS)
+	gzip -f $(DISTNAME)-aix.tar
+
+dist.linux:
+	@$(MAKE) clean
+	@$(MAKE) $(PROGRAM)
+#	groff -P-c -t -ms -Tascii rogue.r | sed -e 's/.\x08//g' > $(PROGRAM).doc
+#	groff -man rogue.6 | sed -e 's/.\x08//g' > $(PROGRAM).cat
+	tar cf $(DISTNAME)-linux.tar $(PROGRAM) LICENSE.TXT $(DOCS)
+	gzip -f $(DISTNAME)-linux.tar
+	
+debug.linux:
+	@$(MAKE) clean
+	@$(MAKE) COPTS="-g" $(PROGRAM)
+#	groff -P-c -t -ms -Tascii rogue.r | sed -e 's/.\x08//g' > $(PROGRAM).doc
+#	groff -man rogue.6 | sed -e 's/.\x08//g' > $(PROGRAM).cat
+	
+dist.interix: 
+	@$(MAKE) clean
+	@$(MAKE) COPTS="-ansi" $(PROGRAM)
+#	groff -P-b -P-u -t -ms -Tascii rogue.r > $(PROGRAM).doc
+#	groff -P-b -P-u -man -Tascii rogue.6 > $(PROGRAM).cat
+	tar cf $(DISTNAME)-interix.tar $(PROGRAM) LICENSE.TXT $(DOCS)
+	gzip -f $(DISTNAME)-interix.tar	
+
+dist.cygwin:
+	@$(MAKE) --no-print-directory clean
+	@$(MAKE) COPTS="-I/usr/include/ncurses" --no-print-directory $(PROGRAM)
+#	groff -P-c -t -ms -Tascii rogue.r | sed -e 's/.\x08//g' > $(PROGRAM).doc
+#	groff -P-c -man -Tascii rogue.6 | sed -e 's/.\x08//g' > $(PROGRAM).cat
+	tar cf $(DISTNAME)-cygwin.tar $(PROGRAM).exe LICENSE.TXT $(DOCS)
+	gzip -f $(DISTNAME)-cygwin.tar
+
+#
+# Use MINGW32-MAKE to build this target
+#
+dist.mingw32:
+	@$(MAKE) --no-print-directory RM="cmd /c del" clean
+	@$(MAKE) --no-print-directory COPTS="-I../pdcurses" LIBS="../pdcurses/pdcurses.a" $(PROGRAM)
+	cmd /c del $(DISTNAME)-mingw32.zip
+	zip $(DISTNAME)-mingw32.zip $(PROGRAM).exe LICENSE.TXT $(DOCS)
+	
+#
+# Seperate doc targets for DJGPP prevent strange SIGSEGV in groff
+# in that environment.
+#
+doc.djgpp:
+	groff -t -ms -Tascii rogue.r | sed -e 's/.\x08//g' > $(PROGRAM).doc
+
+cat.djgpp:
+	groff -man -Tascii rogue.6 | sed -e 's/.\x08//g' > $(PROGRAM).cat
+
+dist.djgpp: 
+	@$(MAKE) --no-print-directory clean
+	@$(MAKE) --no-print-directory LDFLAGS="-L$(DJDIR)/LIB" \
+		LIBS="-lpdcur" $(PROGRAM)
+#	@$(MAKE) --no-print-directory doc.djgpp
+#	@$(MAKE) --no-print-directory cat.djgpp
+	rm -f $(DISTNAME)-djgpp.zip
+	zip $(DISTNAME)-djgpp.zip $(PROGRAM) LICENSE.TXT $(DOCS)
+
+#
+# Use NMAKE to build this target
+#
+dist.win32:
+	@$(MAKE) /NOLOGO O="obj" RM="-del" clean
+	@$(MAKE) /NOLOGO O="obj" CC="@CL" LD="link" LDOUT="/OUT:" EXE=".exe"\
+	    LIBS="/NODEFAULTLIB:LIBC ..\pdcurses\pdcurses.lib shell32.lib user32.lib Advapi32.lib" \
+	    COPTS="-nologo -D_CRT_SECURE_NO_DEPRECATE -I..\pdcurses \
+	    -Ox -wd4033 -wd4716" $(PROGRAM).exe
+	-del $(DISTNAME)-win32.zip
+	zip $(DISTNAME)-win32.zip $(PROGRAM).exe LICENSE.TXT $(DOCS)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rogue3/armor.c	Tue Oct 13 13:33:34 2009 +0000
@@ -0,0 +1,93 @@
+/*
+ * This file contains misc functions for dealing with armor
+ * @(#)armor.c	3.9 (Berkeley) 6/15/81
+ * 
+ * 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 "curses.h"
+#include "rogue.h"
+
+/*
+ * wear:
+ *	The player wants to wear something, so let him/her put it on.
+ */
+
+void
+wear()
+{
+    register struct linked_list *item;
+    register struct object *obj;
+
+    if (cur_armor != NULL)
+    {
+	addmsg("You are already wearing some");
+	if (!terse)
+	    addmsg(".  You'll have to take it off first");
+	endmsg();
+	after = FALSE;
+	return;
+    }
+    if ((item = get_item("wear", ARMOR)) == NULL)
+	return;
+    obj = (struct object *) ldata(item);
+    if (obj->o_type != ARMOR)
+    {
+	msg("You can't wear that.");
+	return;
+    }
+    waste_time();
+    if (!terse)
+	addmsg("You are now w");
+    else
+	addmsg("W");
+    msg("earing %s.", a_names[obj->o_which]);
+    cur_armor = obj;
+    obj->o_flags |= ISKNOW;
+}
+
+/*
+ * take_off:
+ *	Get the armor off of the players back
+ */
+
+void
+take_off()
+{
+    register struct object *obj;
+
+    if ((obj = cur_armor) == NULL)
+    {
+	if (terse)
+		msg("Not wearing armor");
+	else
+		msg("You aren't wearing any armor");
+	return;
+    }
+    if (!dropcheck(cur_armor))
+	return;
+    cur_armor = NULL;
+    if (terse)
+	addmsg("Was");
+    else
+	addmsg("You used to be ");
+    msg(" wearing %c) %s", pack_char(obj), inv_name(obj, TRUE));
+}
+
+/*
+ * waste_time:
+ *	Do nothing but let other things happen
+ */
+
+void
+waste_time()
+{
+    do_daemons(BEFORE);
+    do_fuses(BEFORE);
+    do_daemons(AFTER);
+    do_fuses(AFTER);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rogue3/chase.c	Tue Oct 13 13:33:34 2009 +0000
@@ -0,0 +1,319 @@
+/*
+ * Code for one object to chase another
+ *
+ * @(#)chase.c	3.17 (Berkeley) 6/15/81
+ *
+ * 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 "curses.h"
+#include "rogue.h"
+
+coord ch_ret;				/* Where chasing takes you */
+
+/*
+ * runners:
+ *	Make all the running monsters move.
+ */
+
+void
+runners()
+{
+    struct linked_list *item;
+    struct thing *tp;
+
+    for (item = mlist; item != NULL;)
+    {
+	tp = (struct thing *) ldata(item);
+        item = next(item);
+	if (off(*tp, ISHELD) && on(*tp, ISRUN))
+	{
+	    if (off(*tp, ISSLOW) || tp->t_turn)
+		if (do_chase(tp) == -1)
+                    continue;
+	    if (on(*tp, ISHASTE))
+		if (do_chase(tp) == -1)
+                    continue;
+	    tp->t_turn ^= TRUE;
+	}
+    }
+}
+
+/*
+ * do_chase:
+ *	Make one thing chase another.
+ */
+
+int
+do_chase(struct thing *th)
+{
+    struct room *rer, *ree;	/* room of chaser, room of chasee */
+    int mindist = 32767, i, dist;
+    int stoprun = FALSE;	/* TRUE means we are there */
+    int sch;
+    coord this;				/* Temporary destination for chaser */
+
+    rer = roomin(&th->t_pos);	/* Find room of chaser */
+    ree = roomin(th->t_dest);	/* Find room of chasee */
+    /*
+     * We don't count doors as inside rooms for this routine
+     */
+    if (mvwinch(stdscr, th->t_pos.y, th->t_pos.x) == DOOR)
+	rer = NULL;
+    this = *th->t_dest;
+    /*
+     * If the object of our desire is in a different room, 
+     * than we are and we ar not in a corridor, run to the
+     * door nearest to our goal.
+     */
+    if (rer != NULL && rer != ree)
+	for (i = 0; i < rer->r_nexits; i++)	/* loop through doors */
+	{
+	    dist = DISTANCE(th->t_dest->y, th->t_dest->x,
+			    rer->r_exit[i].y, rer->r_exit[i].x);
+	    if (dist < mindist)			/* minimize distance */
+	    {
+		this = rer->r_exit[i];
+		mindist = dist;
+	    }
+	}
+    /*
+     * this now contains what we want to run to this time
+     * so we run to it.  If we hit it we either want to fight it
+     * or stop running
+     */
+    if (!chase(th, &this))
+    {
+	if (ce(this, hero))
+	{
+	    return( attack(th) );
+	}
+	else if (th->t_type != 'F')
+	    stoprun = TRUE;
+    }
+    else if (th->t_type == 'F')
+	return(0);
+    mvwaddch(cw, th->t_pos.y, th->t_pos.x, th->t_oldch);
+    sch = mvwinch(cw, ch_ret.y, ch_ret.x);
+    if (rer != NULL && (rer->r_flags & ISDARK) && sch == FLOOR
+	&& DISTANCE(ch_ret.y, ch_ret.x, th->t_pos.y, th->t_pos.x) < 3
+	&& off(player, ISBLIND))
+	    th->t_oldch = ' ';
+    else
+	th->t_oldch = sch;
+
+    if (cansee(unc(ch_ret)) && !on(*th, ISINVIS))
+        mvwaddch(cw, ch_ret.y, ch_ret.x, th->t_type);
+    mvwaddch(mw, th->t_pos.y, th->t_pos.x, ' ');
+    mvwaddch(mw, ch_ret.y, ch_ret.x, th->t_type);
+    th->t_pos = ch_ret;
+    /*
+     * And stop running if need be
+     */
+    if (stoprun && ce(th->t_pos, *(th->t_dest)))
+	th->t_flags &= ~ISRUN;
+
+    return(0);
+}
+
+/*
+ * runto:
+ *	Set a mosnter running after something
+ *	or stop it from running (for when it dies)
+ */
+
+void
+runto(coord *runner, coord *spot)
+{
+    struct linked_list *item;
+    struct thing *tp;
+
+    /*
+     * If we couldn't find him, something is funny
+     */
+    if ((item = find_mons(runner->y, runner->x)) == NULL)
+    {
+	msg("CHASER '%s'", unctrl(winat(runner->y, runner->x)));
+	return;
+    }
+    tp = (struct thing *) ldata(item);
+    /*
+     * Start the beastie running
+     */
+    tp->t_dest = spot;
+    tp->t_flags |= ISRUN;
+    tp->t_flags &= ~ISHELD;
+}
+
+/*
+ * chase:
+ *	Find the spot for the chaser(er) to move closer to the
+ *	chasee(ee).  Returns TRUE if we want to keep on chasing later
+ *	FALSE if we reach the goal.
+ */
+
+int
+chase(struct thing *tp, coord *ee)
+{
+    int x, y;
+    int dist, thisdist;
+    struct linked_list *item;
+    struct object *obj;
+    coord *er = &tp->t_pos;
+    int ch;
+
+    /*
+     * If the thing is confused, let it move randomly. Invisible
+     * Stalkers are slightly confused all of the time, and bats are
+     * quite confused all the time
+     */
+    if ((on(*tp, ISHUH) && rnd(10) < 8) || (tp->t_type == 'I' && rnd(100) < 20)
+	|| (tp->t_type == 'B' && rnd(100) < 50))
+    {
+	/*
+	 * get a valid random move
+	 */
+	ch_ret = *rndmove(tp);
+	dist = DISTANCE(ch_ret.y, ch_ret.x, ee->y, ee->x);
+	/*
+	 * Small chance that it will become un-confused 
+	 */
+	if (rnd(1000) < 50)
+	    tp->t_flags &= ~ISHUH;
+    }
+    /*
+     * Otherwise, find the empty spot next to the chaser that is
+     * closest to the chasee.
+     */
+    else
+    {
+	int ey, ex;
+	/*
+	 * This will eventually hold where we move to get closer
+	 * If we can't find an empty spot, we stay where we are.
+	 */
+	dist = DISTANCE(er->y, er->x, ee->y, ee->x);
+	ch_ret = *er;
+
+	ey = er->y + 1;
+	ex = er->x + 1;
+	for (x = er->x - 1; x <= ex; x++)
+	    for (y = er->y - 1; y <= ey; y++)
+	    {
+		coord tryp;
+
+		tryp.x = x;
+		tryp.y = y;
+		if (!diag_ok(er, &tryp))
+		    continue;
+		ch = winat(y, x);
+		if (step_ok(ch))
+		{
+		    /*
+		     * If it is a scroll, it might be a scare monster scroll
+		     * so we need to look it up to see what type it is.
+		     */
+		    if (ch == SCROLL)
+		    {
+			for (item = lvl_obj; item != NULL; item = next(item))
+			{
+			    obj = (struct object *) ldata(item);
+			    if (y == obj->o_pos.y && x == obj->o_pos.x)
+				break;
+			}
+			if (item != NULL && obj->o_which == S_SCARE)
+			    continue;
+		    }
+		    /*
+		     * If we didn't find any scrolls at this place or it
+		     * wasn't a scare scroll, then this place counts
+		     */
+		    thisdist = DISTANCE(y, x, ee->y, ee->x);
+		    if (thisdist < dist)
+		    {
+			ch_ret = tryp;
+			dist = thisdist;
+		    }
+		}
+	    }
+    }
+    return (dist != 0);
+}
+
+/*
+ * roomin:
+ *	Find what room some coordinates are in. NULL means they aren't
+ *	in any room.
+ */
+
+struct room *
+roomin(coord *cp)
+{
+    struct room *rp;
+
+    for (rp = rooms; rp <= &rooms[MAXROOMS-1]; rp++)
+	if (inroom(rp, cp))
+	    return rp;
+    return NULL;
+}
+
+/*
+ * find_mons:
+ *	Find the monster from his corrdinates
+ */
+
+struct linked_list *
+find_mons(int y, int x)
+{
+    struct linked_list *item;
+    struct thing *th;
+
+    for (item = mlist; item != NULL; item = next(item))
+    {
+	th = (struct thing *) ldata(item);
+	if (th->t_pos.y == y && th->t_pos.x == x)
+	    return item;
+    }
+    return NULL;
+}
+
+/*
+ * diag_ok:
+ *	Check to see if the move is legal if it is diagonal
+ */
+
+int
+diag_ok(coord *sp, coord *ep)
+{
+    if (ep->x == sp->x || ep->y == sp->y)
+	return TRUE;
+    return (step_ok(mvinch(ep->y, sp->x)) && step_ok(mvinch(sp->y, ep->x)));
+}
+
+/*
+ * cansee:
+ *	returns true if the hero can see a certain coordinate.
+ */
+
+int
+cansee(int y, int x)
+{
+    struct room *rer;
+    coord tp;
+
+    if (on(player, ISBLIND))
+	return FALSE;
+    tp.y = y;
+    tp.x = x;
+    rer = roomin(&tp);
+    /*
+     * We can only see if the hero in the same room as
+     * the coordinate and the room is lit or if it is close.
+     */
+    return (rer != NULL && rer == roomin(&hero) && !(rer->r_flags&ISDARK)) ||
+	    DISTANCE(y, x, hero.y, hero.x) < 3;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rogue3/command.c	Tue Oct 13 13:33:34 2009 +0000
@@ -0,0 +1,645 @@
+/*
+ * Read and execute the user commands
+ *
+ * @(#)command.c	3.45 (Berkeley) 6/15/81
+ *
+ * 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 <stdlib.h>
+#include <ctype.h>
+#include <signal.h>
+#include <string.h>
+#include "curses.h"
+#include "machdep.h"
+#include "rogue.h"
+
+/*
+ * command:
+ *	Process the user commands
+ */
+
+void
+command()
+{
+    int ch;
+    int ntimes = 1;			/* Number of player moves */
+    static int countch, direction, newcount = FALSE;
+
+
+    if (on(player, ISHASTE)) ntimes++;
+    /*
+     * Let the daemons start up
+     */
+    do_daemons(BEFORE);
+    do_fuses(BEFORE);
+    while (ntimes--)
+    {
+	look(TRUE);
+	if (!running)
+	    door_stop = FALSE;
+	status();
+	lastscore = purse;
+	wmove(cw, hero.y, hero.x);
+	if (!((running || count) && jump))
+	    draw(cw);			/* Draw screen */
+	take = 0;
+	after = TRUE;
+	/*
+	 * Read command or continue run
+	 */
+	if (wizard)
+	    waswizard = TRUE;
+	if (!no_command)
+	{
+	    if (running) ch = runch;
+	    else if (count) ch = countch;
+	    else
+	    {
+		ch = readchar(cw);
+		if (mpos != 0 && !running)	/* Erase message if its there */
+		    msg("");
+	    }
+	}
+	else ch = ' ';
+	if (no_command)
+	{
+	    if (--no_command == 0)
+		msg("You can move again.");
+	}
+	else
+	{
+	    /*
+	     * check for prefixes
+	     */
+	    if (isdigit(ch))
+	    {
+		count = 0;
+		newcount = TRUE;
+		while (isdigit(ch))
+		{
+		    count = count * 10 + (ch - '0');
+		    ch = readchar(cw);
+		}
+		countch = ch;
+		/*
+		 * turn off count for commands which don't make sense
+		 * to repeat
+		 */
+		switch (ch) {
+		    case 'h': case 'j': case 'k': case 'l':
+		    case 'y': case 'u': case 'b': case 'n':
+		    case 'H': case 'J': case 'K': case 'L':
+		    case 'Y': case 'U': case 'B': case 'N':
+		    case 'q': case 'r': case 's': case 'f':
+		    case 't': case 'C': case 'I': case ' ':
+		    case 'z': case 'p':
+			break;
+		    default:
+			count = 0;
+		}
+	    }
+	    switch (ch)
+	    {
+		case 'f':
+		    if (!on(player, ISBLIND))
+		    {
+			door_stop = TRUE;
+			firstmove = TRUE;
+		    }
+		    if (count && !newcount)
+			ch = direction;
+		    else
+			ch = readchar(cw);
+		    switch (ch)
+		    {
+			case 'h': case 'j': case 'k': case 'l':
+			case 'y': case 'u': case 'b': case 'n':
+			    ch = toupper(ch);
+		    }
+		    direction = ch;
+	    }
+	    newcount = FALSE;
+	    /*
+	     * execute a command
+	     */
+	    if (count && !running)
+		count--;
+	    switch (ch)
+	    {
+		case '!' : shell();
+		when 'h' : do_move(0, -1);
+		when 'j' : do_move(1, 0);
+		when 'k' : do_move(-1, 0);
+		when 'l' : do_move(0, 1);
+		when 'y' : do_move(-1, -1);
+		when 'u' : do_move(-1, 1);
+		when 'b' : do_move(1, -1);
+		when 'n' : do_move(1, 1);
+		when 'H' : do_run('h');
+		when 'J' : do_run('j');
+		when 'K' : do_run('k');
+		when 'L' : do_run('l');
+		when 'Y' : do_run('y');
+		when 'U' : do_run('u');
+		when 'B' : do_run('b');
+		when 'N' : do_run('n');
+		when 't':
+		    if (!get_dir())
+			after = FALSE;
+		    else
+			missile(delta.y, delta.x);
+		when 'Q' : after = FALSE; quit(0);
+		when 'i' : after = FALSE; inventory(pack, 0);
+		when 'I' : after = FALSE; picky_inven();
+		when 'd' : drop();
+		when 'q' : quaff();
+		when 'r' : read_scroll();
+		when 'e' : eat();
+		when 'w' : wield();
+		when 'W' : wear();
+		when 'T' : take_off();
+		when 'P' : ring_on();
+		when 'R' : ring_off();
+		when 'o' : option();
+		when 'c' : call();
+		when '>' : after = FALSE; d_level();
+		when '<' : after = FALSE; u_level();
+		when '?' : after = FALSE; help();
+		when '/' : after = FALSE; identify();
+		when 's' : search();
+		when 'z' : do_zap(FALSE);
+		when 'p':
+		    if (get_dir())
+			do_zap(TRUE);
+		    else
+			after = FALSE;
+		when 'v' : msg("Rogue version %s. (mctesq was here)", release);
+		when CTRL('L') : after = FALSE; clearok(curscr,TRUE);draw(curscr);
+		when CTRL('R') : after = FALSE; msg(huh);
+		when 'S' : 
+		    after = FALSE;
+		    if (save_game())
+		    {
+			wmove(cw, LINES-1, 0); 
+			wclrtoeol(cw);
+			draw(cw);
+			endwin();
+			exit(0);
+		    }
+		when ' ' : ;			/* Rest command */
+		when CTRL('P') :
+		    after = FALSE;
+		    if (wizard)
+		    {
+			wizard = FALSE;
+			msg("Not wizard any more");
+		    }
+		    else
+		    {
+			if (wizard = passwd())
+			{
+			    msg("You are suddenly as smart as Ken Arnold in dungeon #%d", dnum);
+ 			    wizard = TRUE;
+			    waswizard = TRUE;
+			}
+			else
+			    msg("Sorry");
+		    }
+		when ESCAPE :	/* Escape */
+		    door_stop = FALSE;
+		    count = 0;
+		    after = FALSE;
+		otherwise :
+		    after = FALSE;
+		    if (wizard) switch (ch)
+		    {
+			case '@' : msg("@ %d,%d", hero.y, hero.x);
+			when 'C' : create_obj();
+			when CTRL('I') : inventory(lvl_obj, 0);
+			when CTRL('W') : whatis();
+			when CTRL('D') : level++; new_level();
+			when CTRL('U') : level--; new_level();
+			when CTRL('F') : show_win(stdscr, "--More (level map)--");
+			when CTRL('X') : show_win(mw, "--More (monsters)--");
+			when CTRL('T') : teleport();
+			when CTRL('E') : msg("food left: %d", food_left);
+			when CTRL('A') : msg("%d things in your pack", inpack);
+			when CTRL('C') : add_pass();
+			when CTRL('N') :
+			{
+			    struct linked_list *item;
+
+			    if ((item = get_item("charge", STICK)) != NULL)
+				((struct object *) ldata(item))->o_charges = 10000;
+			}
+			when CTRL('H') :
+			{
+			    int i;
+			    struct linked_list *item;
+			    struct object *obj;
+
+			    for (i = 0; i < 9; i++)
+				raise_level();
+			    /*
+			     * Give the rogue a sword (+1,+1)
+			     */
+			    item = new_item(sizeof *obj);
+			    obj = (struct object *) ldata(item);
+			    obj->o_type = WEAPON;
+			    obj->o_which = TWOSWORD;
+			    init_weapon(obj, SWORD);
+			    obj->o_hplus = 1;
+			    obj->o_dplus = 1;
+			    add_pack(item, TRUE);
+			    cur_weapon = obj;
+			    /*
+			     * And his suit of armor
+			     */
+			    item = new_item(sizeof *obj);
+			    obj = (struct object *) ldata(item);
+			    obj->o_type = ARMOR;
+			    obj->o_which = PLATE_MAIL;
+			    obj->o_ac = -5;
+			    obj->o_flags |= ISKNOW;
+			    cur_armor = obj;
+			    add_pack(item, TRUE);
+			}
+			otherwise :
+			    msg("Illegal command '%s'.", unctrl(ch));
+			    count = 0;
+		    }
+		    else
+		    {
+			msg("Illegal command '%s'.", unctrl(ch));
+			count = 0;
+		    }
+	    }
+	    /*
+	     * turn off flags if no longer needed
+	     */
+	    if (!running)
+		door_stop = FALSE;
+	}
+	/*
+	 * If he ran into something to take, let him pick it up.
+	 */
+	if (take != 0)
+	    pick_up(take);
+	if (!running)
+	    door_stop = FALSE;
+	if (!after)     
+	    ntimes++;
+    }
+    /*
+     * Kick off the rest if the daemons and fuses
+     */
+    if (after)
+    {
+	look(FALSE);
+	do_daemons(AFTER);
+	do_fuses(AFTER);
+	if (ISRING(LEFT, R_SEARCH))
+	    search();
+	else if (ISRING(LEFT, R_TELEPORT) && rnd(100) < 2)
+	    teleport();
+	if (ISRING(RIGHT, R_SEARCH))
+	    search();
+	else if (ISRING(RIGHT, R_TELEPORT) && rnd(100) < 2)
+	    teleport();
+    }
+}
+
+/*
+ * quit:
+ *	Have player make certain, then exit.
+ */
+
+void
+quit(int p)
+{
+    /*
+     * Reset the signal in case we got here via an interrupt
+     */
+    if (signal(SIGINT, quit) != &quit)
+	mpos = 0;
+    msg("Really quit?");
+    draw(cw);
+    if (readchar(cw) == 'y')
+    {
+	clear();
+	move(LINES-1, 0);
+	draw(stdscr);
+	endwin();
+	score(purse, 1, 0);
+	exit(0);
+    }
+    else
+    {
+	signal(SIGINT, quit);
+	wmove(cw, 0, 0);
+	wclrtoeol(cw);
+	status();
+	draw(cw);
+	mpos = 0;
+	count = 0;
+    }
+}
+
+/*
+ * search:
+ *	Player gropes about him to find hidden things.
+ */
+
+void
+search()
+{
+    int x, y;
+    int ch;
+
+    /*
+     * Look all around the hero, if there is something hidden there,
+     * give him a chance to find it.  If its found, display it.
+     */
+    if (on(player, ISBLIND))
+	return;
+    for (x = hero.x - 1; x <= hero.x + 1; x++)
+	for (y = hero.y - 1; y <= hero.y + 1; y++)
+	{
+	    ch = winat(y, x);
+	    switch (ch)
+	    {
+		case SECRETDOOR:
+		    if (rnd(100) < 20) {
+			mvaddch(y, x, DOOR);
+			count = 0;
+		    }
+		    break;
+		case TRAP:
+		{
+		    struct trap *tp;
+
+		    if (mvwinch(cw, y, x) == TRAP)
+			break;
+		    if (rnd(100) > 50)
+			break;
+		    tp = trap_at(y, x);
+		    tp->tr_flags |= ISFOUND;
+		    mvwaddch(cw, y, x, TRAP);
+		    count = 0;
+		    running = FALSE;
+		    msg(tr_name(tp->tr_type));
+		}
+	    }
+	}
+}
+
+/*
+ * help:
+ *	Give single character help, or the whole mess if he wants it
+ */
+
+void
+help()
+{
+    struct h_list *strp = helpstr;
+    int helpch;
+    int cnt;
+
+    msg("Character you want help for (* for all): ");
+    helpch = readchar(cw);
+    mpos = 0;
+    /*
+     * If its not a *, print the right help string
+     * or an error if he typed a funny character.
+     */
+    if (helpch != '*')
+    {
+	wmove(cw, 0, 0);
+	while (strp->h_ch)
+	{
+	    if (strp->h_ch == helpch)
+	    {
+		msg("%s%s", unctrl(strp->h_ch), strp->h_desc);
+		break;
+	    }
+	    strp++;
+	}
+	if (strp->h_ch != helpch)
+	    msg("Unknown character '%s'", unctrl(helpch));
+	return;
+    }
+    /*
+     * Here we print help for everything.
+     * Then wait before we return to command mode
+     */
+    wclear(hw);
+    cnt = 0;
+    while (strp->h_ch)
+    {
+	mvwaddstr(hw, cnt % 23, cnt > 22 ? 40 : 0, unctrl(strp->h_ch));
+	waddstr(hw, strp->h_desc);
+	cnt++;
+	strp++;
+    }
+    wmove(hw, LINES-1, 0);
+    wprintw(hw, "--Press space to continue--");
+    draw(hw);
+    wait_for(hw,' ');
+    wclear(hw);
+    draw(hw);
+    wmove(cw, 0, 0);
+    wclrtoeol(cw);
+    status();
+    touchwin(cw);
+}
+
+/*
+ * identify:
+ *	Tell the player what a certain thing is.
+ */
+
+void
+identify()
+{
+    int ch;
+    char *str;
+
+    msg("What do you want identified? ");
+    ch = readchar(cw);
+    mpos = 0;
+    if (ch == ESCAPE)
+    {
+	msg("");
+	return;
+    }
+    if (isalpha(ch) && isupper(ch))
+	str = monsters[ch-'A'].m_name;
+    else switch(ch)
+    {
+	case '|':
+	case '-':
+	    str = "wall of a room";
+	when GOLD: str = "gold";
+	when STAIRS : str = "passage leading down";
+	when DOOR: str = "door";
+	when FLOOR: str = "room floor";
+	when PLAYER: str = "you";
+	when PASSAGE: str = "passage";
+	when TRAP: str = "trap";
+	when POTION: str = "potion";
+	when SCROLL: str = "scroll";
+	when FOOD: str = "food";
+	when WEAPON: str = "weapon";
+	when ' ' : str = "solid rock";
+	when ARMOR: str = "armor";
+	when AMULET: str = "The Amulet of Yendor";
+	when RING: str = "ring";
+	when STICK: str = "wand or staff";
+	otherwise: str = "unknown character";
+    }
+    msg("'%s' : %s", unctrl(ch), str);
+}
+
+/*
+ * d_level:
+ *	He wants to go down a level
+ */
+
+void
+d_level()
+{
+    if (winat(hero.y, hero.x) != STAIRS)
+	msg("I see no way down.");
+    else
+    {
+	level++;
+	new_level();
+    }
+}
+
+/*
+ * u_level:
+ *	He wants to go up a level
+ */
+
+void
+u_level()
+{
+    if (winat(hero.y, hero.x) == STAIRS)
+    {
+	if (amulet)
+	{
+	    level--;
+	    if (level == 0)
+		total_winner();
+	    new_level();
+	    msg("You feel a wrenching sensation in your gut.");
+	    return;
+	}
+    }
+    msg("I see no way up.");
+}
+
+/*
+ * Let him escape for a while
+ */
+
+void
+shell()
+{
+    /*
+     * Set the terminal back to original mode
+     */
+    wclear(hw);
+    wmove(hw, LINES-1, 0);
+    draw(hw);
+    endwin();
+    in_shell = TRUE;
+    fflush(stdout);
+
+    md_shellescape();
+
+    printf("\n[Press return to continue]");
+    fflush(stdout);
+    noecho();
+    crmode();
+    in_shell = FALSE;
+    wait_for(cw,'\n');
+    clearok(cw, TRUE);
+    touchwin(cw);
+    draw(cw);
+}
+
+/*
+ * allow a user to call a potion, scroll, or ring something
+ */
+void
+call()
+{
+    struct object *obj;
+    struct linked_list *item;
+    char **guess, *elsewise;
+    int *know;
+
+    item = get_item("call", CALLABLE);
+    /*
+     * Make certain that it is somethings that we want to wear
+     */
+    if (item == NULL)
+	return;
+    obj = (struct object *) ldata(item);
+    switch (obj->o_type)
+    {
+	case RING:
+	    guess = r_guess;
+	    know = r_know;
+	    elsewise = (r_guess[obj->o_which] != NULL ?
+			r_guess[obj->o_which] : r_stones[obj->o_which]);
+	when POTION:
+	    guess = p_guess;
+	    know = p_know;
+	    elsewise = (p_guess[obj->o_which] != NULL ?
+			p_guess[obj->o_which] : p_colors[obj->o_which]);
+	when SCROLL:
+	    guess = s_guess;
+	    know = s_know;
+	    elsewise = (s_guess[obj->o_which] != NULL ?
+			s_guess[obj->o_which] : s_names[obj->o_which]);
+	when STICK:
+	    guess = ws_guess;
+	    know = ws_know;
+	    elsewise = (ws_guess[obj->o_which] != NULL ?
+			ws_guess[obj->o_which] : ws_made[obj->o_which]);
+	otherwise:
+	    msg("You can't call that anything");
+	    return;
+    }
+    if (know[obj->o_which])
+    {
+	msg("That has already been identified");
+	return;
+    }
+    if (terse)
+	addmsg("C");
+    else
+	addmsg("Was c");
+    msg("alled \"%s\"", elsewise);
+    if (terse)
+	msg("Call it: ");
+    else
+	msg("What do you want to call it? ");
+    strcpy(prbuf, elsewise);
+    if (get_str(prbuf, cw) == NORM)
+    {
+        if (guess[obj->o_which] != NULL)
+	    free(guess[obj->o_which]);
+	guess[obj->o_which] = malloc((unsigned int) strlen(prbuf) + 1);
+	if (guess[obj->o_which] != NULL)
+	    strcpy(guess[obj->o_which], prbuf);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rogue3/daemon.c	Tue Oct 13 13:33:34 2009 +0000
@@ -0,0 +1,199 @@
+/*
+ * Contains functions for dealing with things that happen in the
+ * future.
+ *
+ * @(#)daemon.c	3.3 (Berkeley) 6/15/81
+ *
+ * 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 "curses.h"
+#include "rogue.h"
+
+#define EMPTY 0
+#define DAEMON -1
+#define MAXDAEMONS 20
+
+#define _X_ { EMPTY }
+
+struct delayed_action d_list[MAXDAEMONS] = {
+    _X_, _X_, _X_, _X_, _X_, _X_, _X_, _X_, _X_, _X_,
+    _X_, _X_, _X_, _X_, _X_, _X_, _X_, _X_, _X_, _X_, 
+};
+
+/*
+ * d_slot:
+ *	Find an empty slot in the daemon/fuse list
+ */
+struct delayed_action *
+d_slot()
+{
+    register int i;
+    register struct delayed_action *dev;
+
+    for (i = 0, dev = d_list; i < MAXDAEMONS; i++, dev++)
+	if (dev->d_type == EMPTY)
+	    return dev;
+    debug("Ran out of fuse slots");
+    return NULL;
+}
+
+/*
+ * find_slot:
+ *	Find a particular slot in the table
+ */
+
+struct delayed_action *
+find_slot(void (*func)())
+{
+    register int i;
+    register struct delayed_action *dev;
+
+    for (i = 0, dev = d_list; i < MAXDAEMONS; i++, dev++)
+	if (dev->d_type != EMPTY && func == dev->d_func)
+	    return dev;
+    return NULL;
+}
+
+/*
+ * daemon:
+ *	Start a daemon, takes a function.
+ */
+
+void
+start_daemon(void (*func)(), int arg, int type)
+{
+    register struct delayed_action *dev;
+
+    dev = d_slot();
+ 
+    if (dev != NULL) 
+    {
+        dev->d_type = type;
+        dev->d_func = func;
+        dev->d_arg = arg;
+        dev->d_time = DAEMON;
+    }
+}
+
+/*
+ * kill_daemon:
+ *	Remove a daemon from the list
+ */
+
+void
+kill_daemon(void (*func)())
+{
+    register struct delayed_action *dev;
+
+    if ((dev = find_slot(func)) == NULL)
+	return;
+    /*
+     * Take it out of the list
+     */
+    dev->d_type = EMPTY;
+}
+
+/*
+ * do_daemons:
+ *	Run all the daemons that are active with the current flag,
+ *	passing the argument to the function.
+ */
+
+void
+do_daemons(int flag)
+{
+    register struct delayed_action *dev;
+
+    /*
+     * Loop through the devil list
+     */
+    for (dev = d_list; dev <= &d_list[MAXDAEMONS-1]; dev++)
+	/*
+	 * Executing each one, giving it the proper arguments
+	 */
+	if (dev->d_type == flag && dev->d_time == DAEMON)
+	    (*dev->d_func)(dev->d_arg);
+}
+
+/*
+ * fuse:
+ *	Start a fuse to go off in a certain number of turns
+ */
+
+void
+fuse(void (*func)(), int arg, int time, int type)
+{
+    register struct delayed_action *wire;
+
+    wire = d_slot();
+
+    if (wire != NULL)
+    {
+        wire->d_type = type;
+        wire->d_func = func;
+        wire->d_arg = arg;
+        wire->d_time = time;
+    }
+}
+
+/*
+ * lengthen:
+ *	Increase the time until a fuse goes off
+ */
+
+void
+lengthen(void (*func)(), int xtime)
+{
+    register struct delayed_action *wire;
+
+    if ((wire = find_slot(func)) == NULL)
+	return;
+    wire->d_time += xtime;
+}
+
+/*
+ * extinguish:
+ *	Put out a fuse
+ */
+
+void
+extinguish(void (*func)())
+{
+    register struct delayed_action *wire;
+
+    if ((wire = find_slot(func)) == NULL)
+	return;
+    wire->d_type = EMPTY;
+}
+
+/*
+ * do_fuses:
+ *	Decrement counters and start needed fuses
+ */
+
+void
+do_fuses(int flag)
+{
+    register struct delayed_action *wire;
+
+    /*
+     * Step though the list
+     */
+    for (wire = d_list; wire <= &d_list[MAXDAEMONS-1]; wire++)
+    {
+	/*
+	 * Decrementing counters and starting things we want.  We also need
+	 * to remove the fuse from the list once it has gone off.
+	 */
+	if (flag == wire->d_type && wire->d_time > 0 && --wire->d_time == 0)
+	{
+	    wire->d_type = EMPTY;
+	    (*wire->d_func)(wire->d_arg);
+	}
+     }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rogue3/daemons.c	Tue Oct 13 13:33:34 2009 +0000
@@ -0,0 +1,177 @@
+/*
+ * All the daemon and fuse functions are in here
+ *
+ * @(#)daemons.c	3.7 (Berkeley) 6/15/81
+ *
+ * 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 "curses.h"
+#include "rogue.h"
+
+/*
+ * doctor:
+ *	A healing daemon that restors hit points after rest
+ */
+
+void
+doctor()
+{
+    register int lv, ohp;
+
+    lv = pstats.s_lvl;
+    ohp = pstats.s_hpt;
+    quiet++;
+    if (lv < 8)
+    {
+	if (quiet > 20 - lv*2)
+	    pstats.s_hpt++;
+    }
+    else
+	if (quiet >= 3)
+	    pstats.s_hpt += rnd(lv - 7)+1;
+    if (ISRING(LEFT, R_REGEN))
+	pstats.s_hpt++;
+    if (ISRING(RIGHT, R_REGEN))
+	pstats.s_hpt++;
+    if (ohp != pstats.s_hpt)
+    {
+	if (pstats.s_hpt > max_hp)
+	    pstats.s_hpt = max_hp;
+	quiet = 0;
+    }
+}
+
+/*
+ * Swander:
+ *	Called when it is time to start rolling for wandering monsters
+ */
+
+void
+swander()
+{
+    start_daemon(rollwand, 0, BEFORE);
+}
+
+/*
+ * rollwand:
+ *	Called to roll to see if a wandering monster starts up
+ */
+
+int between = 0;
+
+void
+rollwand()
+{
+    if (++between >= 4)
+    {
+	if (roll(1, 6) == 4)
+	{
+	    wanderer();
+	    kill_daemon(rollwand);
+	    fuse(swander, 0, WANDERTIME, BEFORE);
+	}
+	between = 0;
+    }
+}
+
+/*
+ * unconfuse:
+ *	Release the poor player from his confusion
+ */
+
+void
+unconfuse()
+{
+    player.t_flags &= ~ISHUH;
+    msg("You feel less confused now");
+}
+
+
+/*
+ * unsee:
+ *	He lost his see invisible power
+ */
+
+void
+unsee()
+{
+    player.t_flags &= ~CANSEE;
+}
+
+/*
+ * sight:
+ *	He gets his sight back
+ */
+
+void
+sight()
+{
+    if (on(player, ISBLIND))
+    {
+	extinguish(sight);
+	player.t_flags &= ~ISBLIND;
+	light(&hero);
+	msg("The veil of darkness lifts");
+    }
+}
+
+/*
+ * nohaste:
+ *	End the hasting
+ */
+
+void
+nohaste()
+{
+    player.t_flags &= ~ISHASTE;
+    msg("You feel yourself slowing down.");
+}
+
+/*
+ * digest the hero's food
+ */
+void
+stomach()
+{
+    register int oldfood;
+
+    if (food_left <= 0)
+    {
+	/*
+	 * the hero is fainting
+	 */
+	if (no_command || rnd(100) > 20)
+	    return;
+	no_command = rnd(8)+4;
+	if (!terse)
+	    addmsg("You feel too weak from lack of food.  ");
+	msg("You faint");
+	running = FALSE;
+	count = 0;
+	hungry_state = 3;
+    }
+    else
+    {
+	oldfood = food_left;
+	food_left -= ring_eat(LEFT) + ring_eat(RIGHT) + 1 - amulet;
+
+	if (food_left < MORETIME && oldfood >= MORETIME)
+	{
+	    msg("You are starting to feel weak");
+	    hungry_state = 2;
+	}
+	else if (food_left < 2 * MORETIME && oldfood >= 2 * MORETIME)
+	{
+	    if (!terse)
+		msg("You are starting to get hungry");
+	    else
+		msg("Getting hungry");
+	    hungry_state = 1;
+	}
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rogue3/fight.c	Tue Oct 13 13:33:34 2009 +0000
@@ -0,0 +1,737 @@
+/*
+ * All the fighting gets done here
+ *
+ * @(#)fight.c	3.28 (Berkeley) 6/15/81
+ *
+ * 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 "curses.h"
+#include <ctype.h>
+#include <string.h>
+#include <stdlib.h>
+#include "rogue.h"
+
+int e_levels[] = {
+    10,20,40,80,160,320,640,1280,2560,5120,10240,20480,
+    40920, 81920, 163840, 327680, 655360, 1310720, 2621440, 0 };
+
+/*
+ * fight:
+ *	The player attacks the monster.
+ */
+
+int
+fight(coord *mp, int mn, struct object *weap, int thrown)
+{
+    struct thing *tp;
+    struct linked_list *item;
+    int did_hit = TRUE;
+
+    /*
+     * Find the monster we want to fight
+     */
+    if ((item = find_mons(mp->y, mp->x)) == NULL)
+    {
+	debug("Fight what @ %d,%d", mp->y, mp->x);
+	return(0);
+    }
+    tp = (struct thing *) ldata(item);
+    /*
+     * Since we are fighting, things are not quiet so no healing takes
+     * place.
+     */
+    quiet = 0;
+    runto(mp, &hero);
+    /*
+     * Let him know it was really a mimic (if it was one).
+     */
+    if (tp->t_type == 'M' && tp->t_disguise != 'M' && off(player, ISBLIND))
+    {
+	msg("Wait! That's a mimic!");
+	tp->t_disguise = 'M';
+	did_hit = thrown;
+    }
+    if (did_hit)
+    {
+	char *mname;
+
+	did_hit = FALSE;
+	if (on(player, ISBLIND))
+	    mname = "it";
+	else
+	    mname = monsters[mn-'A'].m_name;
+	if (roll_em(&pstats, &tp->t_stats, weap, thrown))
+	{
+	    did_hit = TRUE;
+	    if (thrown)
+		thunk(weap, mname);
+	    else
+		hit(NULL, mname);
+	    if (on(player, CANHUH))
+	    {
+		msg("Your hands stop glowing red");
+		msg("The %s appears confused.", mname);
+		tp->t_flags |= ISHUH;
+		player.t_flags &= ~CANHUH;
+	    }
+	    if (tp->t_stats.s_hpt <= 0)
+		killed(item, TRUE);
+	}
+	else
+	    if (thrown)
+		bounce(weap, mname);
+	    else
+		miss(NULL, mname);
+    }
+    count = 0;
+    return did_hit;
+}
+
+/*
+ * attack:
+ *	The monster attacks the player
+ */
+
+int
+attack(struct thing *mp)
+{
+    char *mname;
+
+    /*
+     * Since this is an attack, stop running and any healing that was
+     * going on at the time.
+     */
+    running = FALSE;
+    quiet = 0;
+    if (mp->t_type == 'M' && off(player, ISBLIND))
+	mp->t_disguise = 'M';
+    if (on(player, ISBLIND))
+	mname = "it";
+    else
+	mname = monsters[mp->t_type-'A'].m_name;
+    if (roll_em(&mp->t_stats, &pstats, NULL, FALSE))
+    {
+	if (mp->t_type != 'E')
+	    hit(mname, NULL);
+	if (pstats.s_hpt <= 0)
+	    death(mp->t_type);	/* Bye bye life ... */
+	if (off(*mp, ISCANC))
+	    switch (mp->t_type)
+	    {
+		case 'R':
+		    /*
+		     * If a rust monster hits, you lose armor
+		     */
+		    if (cur_armor != NULL && cur_armor->o_ac < 9)
+		    {
+			if (!terse)
+			    msg("Your armor appears to be weaker now. Oh my!");
+			else
+			    msg("Your armor weakens");
+			cur_armor->o_ac++;
+		    }
+		when 'E':
+		    /*
+		     * The gaze of the floating eye hypnotizes you
+		     */
+		    if (on(player, ISBLIND))
+			break;
+		    if (!no_command)
+		    {
+			addmsg("You are transfixed");
+			if (!terse)
+			    addmsg(" by the gaze of the floating eye.");
+			endmsg();
+		    }
+		    no_command += rnd(2)+2;
+		    if (no_command > 100 && food_left <= 0)
+		    	death('E');
+		when 'A':
+		    /*
+		     * Ants have poisonous bites
+		     */
+		    if (!save(VS_POISON))
+			if (!ISWEARING(R_SUSTSTR))
+			{
+			    chg_str(-1);
+			    if (!terse)
+				msg("You feel a sting in your arm and now feel weaker");
+			    else
+				msg("A sting has weakened you");
+			}
+			else
+			    if (!terse)
+				msg("A sting momentarily weakens you");
+			    else
+				msg("Sting has no effect");
+		when 'W':
+		    /*
+		     * Wraiths might drain energy levels
+		     */
+		    if (rnd(100) < 15)
+		    {
+			int fewer;
+
+			if (pstats.s_exp == 0)
+			    death('W');		/* All levels gone */
+			msg("You suddenly feel weaker.");
+			if (--pstats.s_lvl == 0)
+			{
+			    pstats.s_exp = 0;
+			    pstats.s_lvl = 1;
+			}
+			else
+			    pstats.s_exp = e_levels[pstats.s_lvl-1]+1;
+			fewer = roll(1, 10);
+			pstats.s_hpt -= fewer;
+			max_hp -= fewer;
+			if (pstats.s_hpt < 1)
+			    pstats.s_hpt = 1;
+			if (max_hp < 1)
+			    death('W');
+		    }
+		when 'F':
+		    /*
+		     * Violet fungi stops the poor guy from moving
+		     */
+		    player.t_flags |= ISHELD;
+		    sprintf(monsters['F'-'A'].m_stats.s_dmg,"%dd1",++fung_hit);
+		when 'L':
+		{
+		    /*
+		     * Leperachaun steals some gold
+		     */
+		    int lastpurse;
+
+		    lastpurse = purse;
+		    purse -= GOLDCALC;
+		    if (!save(VS_MAGIC))
+			purse -= GOLDCALC + GOLDCALC + GOLDCALC + GOLDCALC;
+		    if (purse < 0)
+			purse = 0;
+		    if (purse != lastpurse)
+			msg("Your purse feels lighter");
+		    remove_monster(&mp->t_pos, find_mons(mp->t_pos.y, mp->t_pos.x));
+		    mp = NULL;
+		}
+		when 'N':
+		{
+		    struct linked_list *list, *steal;
+		    struct object *obj;
+		    int nobj;
+
+		    /*
+		     * Nymph's steal a magic item, look through the pack
+		     * and pick out one we like.
+		     */
+		    steal = NULL;
+		    for (nobj = 0, list = pack; list != NULL; list = next(list))
+		    {
+			obj = (struct object *) ldata(list);
+			if (obj != cur_armor && 
+                            obj != cur_weapon &&
+                            obj != cur_ring[LEFT] &&
+                            obj != cur_ring[RIGHT] && /* Nymph bug fix */
+			    is_magic(obj) && 
+                            rnd(++nobj) == 0)
+				steal = list;
+		    }
+		    if (steal != NULL)
+		    {
+			struct object *sobj;
+
+			sobj = (struct object *) ldata(steal);
+			remove_monster(&mp->t_pos, find_mons(mp->t_pos.y, mp->t_pos.x));
+			mp = NULL;
+			if (sobj->o_count > 1 && sobj->o_group == 0)
+			{
+			    int oc;
+
+			    oc = sobj->o_count;
+			    sobj->o_count = 1;
+			    msg("She stole %s!", inv_name(sobj, TRUE));
+			    sobj->o_count = oc - 1;
+			}
+			else
+			{
+			    msg("She stole %s!", inv_name(sobj, TRUE));
+			    detach(pack, steal);
+			    discard(steal);
+			}
+			inpack--;
+		    }
+		}
+		otherwise:
+		    break;
+	    }
+    }
+    else if (mp->t_type != 'E')
+    {
+	if (mp->t_type == 'F')
+	{
+	    pstats.s_hpt -= fung_hit;
+	    if (pstats.s_hpt <= 0)
+		death(mp->t_type);	/* Bye bye life ... */
+	}
+	miss(mname, NULL);
+    }
+    /*
+     * Check to see if this is a regenerating monster and let it heal if
+     * it is.
+     */
+    if ((mp != NULL) && (on(*mp, ISREGEN) && rnd(100) < 33))
+	mp->t_stats.s_hpt++;
+    if (fight_flush)
+    {
+	flush_type();	/* flush typeahead */
+    }
+    count = 0;
+    status();
+
+    if (mp == NULL)
+        return(-1);
+    else
+        return(0);
+}
+
+/*
+ * swing:
+ *	returns true if the swing hits
+ */
+
+int
+swing(int at_lvl, int op_arm, int wplus)
+{
+    int res = rnd(20)+1;
+    int need = (21-at_lvl)-op_arm;
+
+    return (res+wplus >= need);
+}
+
+/*
+ * check_level:
+ *	Check to see if the guy has gone up a level.
+ */
+
+void
+check_level()
+{
+    int i, add;
+
+    for (i = 0; e_levels[i] != 0; i++)
+	if (e_levels[i] > pstats.s_exp)
+	    break;
+    i++;
+    if (i > pstats.s_lvl)
+    {
+	add = roll(i-pstats.s_lvl,10);
+	max_hp += add;
+	if ((pstats.s_hpt += add) > max_hp)
+	    pstats.s_hpt = max_hp;
+	msg("Welcome to level %d", i);
+    }
+    pstats.s_lvl = i;
+}
+
+/*
+ * roll_em:
+ *	Roll several attacks
+ */
+
+int
+roll_em(struct stats *att, struct stats *def, struct object *weap, int hurl)
+{
+    char *cp;
+    int ndice, nsides, def_arm;
+    int did_hit = FALSE;
+    int prop_hplus, prop_dplus;
+
+    prop_hplus = prop_dplus = 0;
+    if (weap == NULL)
+	cp = att->s_dmg;
+    else if (hurl)
+	if ((weap->o_flags&ISMISL) && cur_weapon != NULL &&
+	  cur_weapon->o_which == weap->o_launch)
+	{
+	    cp = weap->o_hurldmg;
+	    prop_hplus = cur_weapon->o_hplus;
+	    prop_dplus = cur_weapon->o_dplus;
+	}
+	else
+	    cp = (weap->o_flags&ISMISL ? weap->o_damage : weap->o_hurldmg);
+    else
+    {
+	cp = weap->o_damage;
+	/*
+	 * Drain a staff of striking
+	 */
+	if (weap->o_type == STICK && weap->o_which == WS_HIT
+	    && weap->o_charges == 0)
+		{
+		    strcpy(weap->o_damage,"0d0");
+		    weap->o_hplus = weap->o_dplus = 0;
+		}
+    }
+    for (;;)
+    {
+	int damage;
+	int hplus = prop_hplus + (weap == NULL ? 0 : weap->o_hplus);
+	int dplus = prop_dplus + (weap == NULL ? 0 : weap->o_dplus);
+
+	if (weap == cur_weapon)
+	{
+	    if (ISRING(LEFT, R_ADDDAM))
+		dplus += cur_ring[LEFT]->o_ac;
+	    else if (ISRING(LEFT, R_ADDHIT))
+		hplus += cur_ring[LEFT]->o_ac;
+	    if (ISRING(RIGHT, R_ADDDAM))
+		dplus += cur_ring[RIGHT]->o_ac;
+	    else if (ISRING(RIGHT, R_ADDHIT))
+		hplus += cur_ring[RIGHT]->o_ac;
+	}
+	ndice = atoi(cp);
+	if ((cp = strchr(cp, 'd')) == NULL)
+	    break;
+	nsides = atoi(++cp);
+	if (def == &pstats)
+	{
+	    if (cur_armor != NULL)
+		def_arm = cur_armor->o_ac;
+	    else
+		def_arm = def->s_arm;
+	    if (ISRING(LEFT, R_PROTECT))
+		def_arm -= cur_ring[LEFT]->o_ac;
+	    else if (ISRING(RIGHT, R_PROTECT))
+		def_arm -= cur_ring[RIGHT]->o_ac;
+	}
+	else
+	    def_arm = def->s_arm;
+	if (swing(att->s_lvl, def_arm, hplus+str_plus(&att->s_str)))
+	{
+	    int proll;
+
+	    proll = roll(ndice, nsides);
+	    if (ndice + nsides > 0 && proll < 1)
+		debug("Damage for %dd%d came out %d.", ndice, nsides, proll);
+	    damage = dplus + proll + add_dam(&att->s_str);
+	    def->s_hpt -= max(0, damage);
+	    did_hit = TRUE;
+	}
+	if ((cp = strchr(cp, '/')) == NULL)
+	    break;
+	cp++;
+    }
+    return did_hit;
+}
+
+/*
+ * prname:
+ *	The print name of a combatant
+ */
+
+char *
+prname(who, upper)
+char *who;
+int upper;
+{
+    static char tbuf[80];
+
+    *tbuf = '\0';
+    if (who == 0)
+	strcpy(tbuf, "you"); 
+    else if (on(player, ISBLIND))
+	strcpy(tbuf, "it");
+    else
+    {
+	strcpy(tbuf, "the ");
+	strcat(tbuf, who);
+    }
+    if (upper)
+	*tbuf = toupper(*tbuf);
+    return tbuf;
+}
+
+/*
+ * hit:
+ *	Print a message to indicate a succesful hit
+ */
+
+void
+hit(char *er, char *ee)
+{
+    char *s = "";
+
+    addmsg(prname(er, TRUE));
+    if (terse)
+	s = " hit.";
+    else
+	switch (rnd(4))
+	{
+	    case 0: s = " scored an excellent hit on ";
+	    when 1: s = " hit ";
+	    when 2: s = (er == 0 ? " have injured " : " has injured ");
+	    when 3: s = (er == 0 ? " swing and hit " : " swings and hits ");
+	}
+    addmsg(s);
+    if (!terse)
+	addmsg(prname(ee, FALSE));
+    endmsg();
+}
+
+/*
+ * miss:
+ *	Print a message to indicate a poor swing
+ */
+
+void
+miss(char *er, char *ee)
+{
+    char *s = "";
+
+    addmsg(prname(er, TRUE));
+    switch (terse ? 0 : rnd(4))
+    {
+	case 0: s = (er == 0 ? " miss" : " misses");
+	when 1: s = (er == 0 ? " swing and miss" : " swings and misses");
+	when 2: s = (er == 0 ? " barely miss" : " barely misses");
+	when 3: s = (er == 0 ? " don't hit" : " doesn't hit");
+    }
+    addmsg(s);
+    if (!terse)
+	addmsg(" %s", prname(ee, FALSE));
+    endmsg();
+}
+
+/*
+ * save_throw:
+ *	See if a creature save against something
+ */
+int
+save_throw(int which, struct thing *tp)
+{
+    int need;
+
+    need = 14 + which - tp->t_stats.s_lvl / 2;
+    return (roll(1, 20) >= need);
+}
+
+/*
+ * save:
+ *	See if he saves against various nasty things
+ */
+
+int
+save(int which)
+{
+    return save_throw(which, &player);
+}
+
+/*
+ * str_plus:
+ *	compute bonus/penalties for strength on the "to hit" roll
+ */
+
+int
+str_plus(str_t *str)
+{
+    if (str->st_str == 18)
+    {
+	if (str->st_add == 100)
+	    return 3;
+	if (str->st_add > 50)
+	    return 2;
+    }
+    if (str->st_str >= 17)
+	return 1;
+    if (str->st_str > 6)
+	return 0;
+    return str->st_str - 7;
+}
+
+/*
+ * add_dam:
+ *	compute additional damage done for exceptionally high or low strength
+ */
+
+ int
+ add_dam(str_t *str)
+ {
+    if (str->st_str == 18)
+    {
+	if (str->st_add == 100)
+	    return 6;
+	if (str->st_add > 90)
+	    return 5;
+	if (str->st_add > 75)
+	    return 4;
+	if (str->st_add != 0)
+	    return 3;
+	return 2;
+    }
+    if (str->st_str > 15)
+	return 1;
+    if (str->st_str > 6)
+	return 0;
+    return str->st_str - 7;
+}
+
+/*
+ * raise_level:
+ *	The guy just magically went up a level.
+ */
+
+void
+raise_level()
+{
+    pstats.s_exp = e_levels[pstats.s_lvl-1] + 1L;
+    check_level();
+}
+
+/*
+ * thunk:
+ *	A missile hits a monster
+ */
+
+void
+thunk(struct object *weap, char *mname)
+{
+    if (weap->o_type == WEAPON)
+	msg("The %s hits the %s", w_names[weap->o_which], mname);
+    else
+	msg("You hit the %s.", mname);
+}
+
+/*
+ * bounce:
+ *	A missile misses a monster
+ */
+
+void
+bounce(struct object *weap, char *mname)
+{
+    if (weap->o_type == WEAPON)
+	msg("The %s misses the %s", w_names[weap->o_which], mname);
+    else
+	msg("You missed the %s.", mname);
+}
+
+/*
+ * remove a monster from the screen
+ */
+void
+remove_monster(coord *mp, struct linked_list *item)
+{
+    mvwaddch(mw, mp->y, mp->x, ' ');
+    mvwaddch(cw, mp->y, mp->x, ((struct thing *) ldata(item))->t_oldch);
+    detach(mlist, item);
+    discard(item);
+}
+
+/*
+ * is_magic:
+ *	Returns true if an object radiates magic
+ */
+
+int
+is_magic(struct object *obj)
+{
+    switch (obj->o_type)
+    {
+	case ARMOR:
+	    return obj->o_ac != a_class[obj->o_which];
+	when WEAPON:
+	    return obj->o_hplus != 0 || obj->o_dplus != 0;
+	when POTION:
+	case SCROLL:
+	case STICK:
+	case RING:
+	case AMULET:
+	    return TRUE;
+    }
+    return FALSE;
+}
+
+/*
+ * killed:
+ *	Called to put a monster to death
+ */
+
+void
+killed(struct linked_list *item, int pr)
+{
+    struct thing *tp;
+    struct linked_list *pitem, *nexti;
+
+    tp = (struct thing *) ldata(item);
+    if (pr)
+    {
+	addmsg(terse ? "Defeated " : "You have defeated ");
+	if (on(player, ISBLIND))
+	    msg("it.");
+	else
+	{
+	    if (!terse)
+		addmsg("the ");
+	    msg("%s.", monsters[tp->t_type-'A'].m_name);
+	}
+    }
+    pstats.s_exp += tp->t_stats.s_exp;
+    /*
+     * Do adjustments if he went up a level
+     */
+    check_level();
+    /*
+     * If the monster was a violet fungi, un-hold him
+     */
+    switch (tp->t_type)
+    {
+	case 'F':
+	    player.t_flags &= ~ISHELD;
+	    fung_hit = 0;
+	    strcpy(monsters['F'-'A'].m_stats.s_dmg, "000d0");
+	when 'L':
+	{
+	    struct room *rp;
+
+	    if ((rp = roomin(&tp->t_pos)) == NULL)
+		break;
+	    if (rp->r_goldval != 0 || fallpos(&tp->t_pos,&rp->r_gold,FALSE))
+	    {
+		rp->r_goldval += GOLDCALC;
+		if (save(VS_MAGIC))
+		    rp->r_goldval += GOLDCALC + GOLDCALC
+				   + GOLDCALC + GOLDCALC;
+		mvwaddch(stdscr, rp->r_gold.y, rp->r_gold.x, GOLD);
+		if (!(rp->r_flags & ISDARK))
+		{
+		    light(&hero);
+		    mvwaddch(cw, hero.y, hero.x, PLAYER);
+		}
+	    }
+	}
+    }
+    /*
+     * Empty the monsters pack
+     */
+    pitem = tp->t_pack;
+    while (pitem != NULL)
+    {
+	struct object *obj;
+
+	nexti = next(tp->t_pack);
+	obj = (struct object *) ldata(pitem);
+	obj->o_pos = tp->t_pos;
+	detach(tp->t_pack, pitem);
+	fall(pitem, FALSE);
+	pitem = nexti;
+    }
+    /*
+     * Get rid of the monster.
+     */
+    remove_monster(&tp->t_pos, item);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rogue3/init.c	Tue Oct 13 13:33:34 2009 +0000
@@ -0,0 +1,596 @@
+/*
+ * global variable initializaton
+ *
+ * @(#)init.c	3.33 (Berkeley) 6/15/81
+ *
+ * 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 "curses.h"
+#include <ctype.h>
+#include <string.h>
+#include <stdlib.h>
+#include "machdep.h"
+#include "rogue.h"
+
+int playing = TRUE, running = FALSE, wizard = FALSE;
+int notify = TRUE, fight_flush = FALSE, terse = FALSE, door_stop = FALSE;
+int jump = FALSE, slow_invent = FALSE, firstmove = FALSE, askme = FALSE;
+int amulet = FALSE;
+int in_shell = FALSE;
+struct linked_list *lvl_obj = NULL, *mlist = NULL;
+struct object *cur_weapon = NULL;
+int mpos = 0, no_move = 0, no_command = 0, level = 1, purse = 0, inpack = 0;
+int total = 0, no_food = 0, count = 0, fung_hit = 0, quiet = 0;
+int food_left = HUNGERTIME, group = 1, hungry_state = 0;
+int lastscore = -1;
+
+struct thing player;
+struct room rooms[MAXROOMS];
+struct room *oldrp;
+struct stats max_stats; 
+struct object *cur_armor;
+struct object *cur_ring[2];
+int after;
+int waswizard;
+coord oldpos;                            /* Position before last look() call */
+coord delta;                             /* Change indicated to get_dir()    */
+
+int s_know[MAXSCROLLS];         /* Does he know what a scroll does */
+int p_know[MAXPOTIONS];         /* Does he know what a potion does */
+int r_know[MAXRINGS];                   /* Does he know what a ring does
+ */
+int ws_know[MAXSTICKS];         /* Does he know what a stick does */
+
+int  take;                               /* Thing the rogue is taking */
+int  runch;                              /* Direction player is running */
+char whoami[80];                 /* Name of player */
+char fruit[80];                          /* Favorite fruit */
+char huh[80];                            /* The last message printed */
+int dnum;                                /* Dungeon number */
+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 */
+char *a_names[MAXARMORS];                /* Names of armor types */
+char *ws_made[MAXSTICKS];                /* What sticks are made of */
+char *s_guess[MAXSCROLLS];               /* Players guess at what scroll is */
+char *p_guess[MAXPOTIONS];               /* Players guess at what potion is */
+char *r_guess[MAXRINGS];         /* Players guess at what ring is */
+char *ws_guess[MAXSTICKS];               /* Players guess at what wand is */
+char *ws_type[MAXSTICKS];                /* Is it a wand or a staff */
+char file_name[80];                      /* Save file name */
+char home[PATH_MAX];                     /* User's home directory */
+unsigned char prbuf[80];                 /* Buffer for sprintfs */
+int max_hp;                              /* Player's max hit points */
+int ntraps;                              /* Number of traps on this level */
+int max_level;                           /* Deepest player has gone */
+int seed;                                /* Random number seed */
+
+struct trap  traps[MAXTRAPS];
+
+
+#define ___ 1
+#define _x {1,1}
+struct monster monsters[26] = {
+	/* Name		 CARRY	FLAG    str, exp, lvl, amr, hpt, dmg */
+	{ "giant ant",	 0,	ISMEAN,	{ _x, 10,   2,   3, ___, "1d6" } },
+	{ "bat",	 0,	0,	{ _x,  1,   1,   3, ___, "1d2" } },
+	{ "centaur",	 15,	0,	{ _x, 15,   4,   4, ___, "1d6/1d6" } },
+	{ "dragon",	 100,	ISGREED,{ _x,9000, 10,  -1, ___, "1d8/1d8/3d10" } },
+	{ "floating eye",0,	0,	{ _x,  5,   1,   9, ___, "0d0" } },
+	{ "violet fungi",0,	ISMEAN,	{ _x, 85,   8,   3, ___, "000d0" } },
+	{ "gnome",	 10,	0,	{ _x,  8,   1,   5, ___, "1d6" } },
+	{ "hobgoblin",	 0,	ISMEAN,	{ _x,  3,   1,   5, ___, "1d8" } },
+	{ "invisible stalker",0,ISINVIS,{ _x,120,   8,   3, ___, "4d4" } },
+	{ "jackal",	 0,	ISMEAN,	{ _x,  2,   1,   7, ___, "1d2" } },
+	{ "kobold",	 0,	ISMEAN,	{ _x,  1,   1,   7, ___, "1d4" } },
+	{ "leprechaun",	 0,	0,	{ _x, 10,   3,   8, ___, "1d1" } },
+	{ "mimic",	 30,	0,	{ _x,140,   7,   7, ___, "3d4" } },
+	{ "nymph",	 100,	0,	{ _x, 40,   3,   9, ___, "0d0" } },
+	{ "orc",	 15,	ISBLOCK,{ _x,  5,   1,   6, ___, "1d8" } },
+	{ "purple worm", 70,	0,	{ _x,7000, 15,   6, ___, "2d12/2d4" } },
+	{ "quasit",	 30,	ISMEAN,	{ _x, 35,   3,   2, ___, "1d2/1d2/1d4" } },
+	{ "rust monster",0,	ISMEAN,	{ _x, 25,   5,   2, ___, "0d0/0d0" } },
+	{ "snake",	 0,	ISMEAN,	{ _x,  3,   1,   5, ___, "1d3" } },
+	{ "troll",	 50,	ISREGEN|ISMEAN,{ _x, 55,   6,   4, ___, "1d8/1d8/2d6" } },
+	{ "umber hulk",	 40,	ISMEAN,	{ _x,130,   8,   2, ___, "3d4/3d4/2d5" } },
+	{ "vampire",	 20,	ISREGEN|ISMEAN,{ _x,380,   8,   1, ___, "1d10" } },
+	{ "wraith",	 0,	0,	{ _x, 55,   5,   4, ___, "1d6" } },
+	{ "xorn",	 0,	ISMEAN,	{ _x,120,   7,  -2, ___, "1d3/1d3/1d3/4d6" } },
+	{ "yeti",	 30,	0,	{ _x, 50,   4,   6, ___, "1d6/1d6" } },
+	{ "zombie",	 0,	ISMEAN,	{ _x,  7,   2,   8, ___, "1d8" } }
+};
+#undef ___
+
+/*
+ * init_player:
+ *	roll up the rogue
+ */
+
+void
+init_player()
+{
+    pstats.s_lvl = 1;
+    pstats.s_exp = 0L;
+    max_hp = pstats.s_hpt = 12;
+    if (rnd(100) == 7)
+    {
+	pstats.s_str.st_str = 18;
+	pstats.s_str.st_add = rnd(100) + 1;
+    }
+    else
+    {
+	pstats.s_str.st_str = 16;
+	pstats.s_str.st_add = 0;
+    }
+    strcpy(pstats.s_dmg,"1d4");
+    pstats.s_arm = 10;
+    max_stats = pstats;
+    pack = NULL;
+}
+
+/*
+ * Contains defintions and functions for dealing with things like
+ * potions and scrolls
+ */
+
+char *rainbow[] = {
+    "red",
+    "blue",
+    "green",
+    "yellow",
+    "black",
+    "brown",
+    "orange",
+    "pink",
+    "purple",
+    "grey",
+    "white",
+    "silver",
+    "gold",
+    "violet",
+    "clear",
+    "vermilion",
+    "ecru",
+    "turquoise",
+    "magenta",
+    "amber",
+    "topaz",
+    "plaid",
+    "tan",
+    "tangerine"
+};
+
+#define NCOLORS (sizeof rainbow / sizeof (char *))
+int cNCOLORS = NCOLORS;
+
+char *sylls[] = {
+    "a", "ab", "ag", "aks", "ala", "an", "ankh", "app", "arg", "arze",
+    "ash", "ban", "bar", "bat", "bek", "bie", "bin", "bit", "bjor",
+    "blu", "bot", "bu", "byt", "comp", "con", "cos", "cre", "dalf",
+    "dan", "den", "do", "e", "eep", "el", "eng", "er", "ere", "erk",
+    "esh", "evs", "fa", "fid", "for", "fri", "fu", "gan", "gar",
+    "glen", "gop", "gre", "ha", "he", "hyd", "i", "ing", "ion", "ip",
+    "ish", "it", "ite", "iv", "jo", "kho", "kli", "klis", "la", "lech",
+    "man", "mar", "me", "mi", "mic", "mik", "mon", "mung", "mur",
+    "nej", "nelg", "nep", "ner", "nes", "nes", "nih", "nin", "o", "od",
+    "ood", "org", "orn", "ox", "oxy", "pay", "pet", "ple", "plu", "po",
+    "pot", "prok", "re", "rea", "rhov", "ri", "ro", "rog", "rok", "rol",
+    "sa", "san", "sat", "see", "sef", "seh", "shu", "ski", "sna",
+    "sne", "snik", "sno", "so", "sol", "sri", "sta", "sun", "ta",
+    "tab", "tem", "ther", "ti", "tox", "trol", "tue", "turs", "u",
+    "ulk", "um", "un", "uni", "ur", "val", "viv", "vly", "vom", "wah",
+    "wed", "werg", "wex", "whon", "wun", "xo", "y", "yot", "yu",
+    "zant", "zap", "zeb", "zim", "zok", "zon", "zum",
+};
+
+char *stones[] = {
+    "agate",
+    "alexandrite",
+    "amethyst",
+    "carnelian",
+    "diamond",
+    "emerald",
+    "granite",
+    "jade",
+    "kryptonite",
+    "lapus lazuli",
+    "moonstone",
+    "obsidian",
+    "onyx",
+    "opal",
+    "pearl",
+    "ruby",
+    "saphire",
+    "tiger eye",
+    "topaz",
+    "turquoise",
+};
+
+#define NSTONES (sizeof stones / sizeof (char *))
+int cNSTONES = NSTONES;
+
+char *wood[] = {
+    "avocado wood",
+    "balsa",
+    "banyan",
+    "birch",
+    "cedar",
+    "cherry",
+    "cinnibar",
+    "driftwood",
+    "ebony",
+    "eucalyptus",
+    "hemlock",
+    "ironwood",
+    "mahogany",
+    "manzanita",
+    "maple",
+    "oak",
+    "persimmon wood",
+    "redwood",
+    "rosewood",
+    "teak",
+    "walnut",
+    "zebra wood",
+};
+
+#define NWOOD (sizeof wood / sizeof (char *))
+int cNWOOD = NWOOD;
+
+char *metal[] = {
+    "aluminium",
+    "bone",
+    "brass",
+    "bronze",
+    "copper",
+    "iron",
+    "lead",
+    "pewter",
+    "steel",
+    "tin",
+    "zinc",
+};
+
+#define NMETAL (sizeof metal / sizeof (char *))
+int cNMETAL = NMETAL;
+
+struct magic_item things[NUMTHINGS] = {
+    { "",			27 },	/* potion */
+    { "",			27 },	/* scroll */
+    { "",			18 },	/* food */
+    { "",			 9 },	/* weapon */
+    { "",			 9 },	/* armor */
+    { "",			 5 },	/* ring */
+    { "",			 5 },	/* stick */
+};
+
+struct magic_item s_magic[MAXSCROLLS] = {
+    { "monster confusion",	 8, 170 },
+    { "magic mapping",		 5, 180 },
+    { "light",			10, 100 },
+    { "hold monster",		 2, 200 },
+    { "sleep",			 5,  50 },
+    { "enchant armor",		 8, 130 },
+    { "identify",		21, 100 },
+    { "scare monster",		 4, 180 },
+    { "gold detection",		 4, 110 },
+    { "teleportation",		 7, 175 },
+    { "enchant weapon",		10, 150 },
+    { "create monster",		 5,  75 },
+    { "remove curse",		 8, 105 },
+    { "aggravate monsters",	 1,  60 },
+    { "blank paper",		 1,  50 },
+    { "genocide",		 1, 200 },
+};
+
+struct magic_item p_magic[MAXPOTIONS] = {
+    { "confusion",		 8,  50 },
+    { "paralysis",		10,  50 },
+    { "poison",			 8,  50 },
+    { "gain strength",		15, 150 },
+    { "see invisible",		 2, 170 },
+    { "healing",		15, 130 },
+    { "monster detection",	 6, 120 },
+    { "magic detection",	 6, 105 },
+    { "raise level",		 2, 220 },
+    { "extra healing",		 5, 180 },
+    { "haste self",		 4, 200 },
+    { "restore strength",	14, 120 },
+    { "blindness",		 4,  50 },
+    { "thirst quenching",	 1,  50 },
+};
+
+struct magic_item r_magic[MAXRINGS] = {
+    { "protection",		 9, 200 },
+    { "add strength",		 9, 200 },
+    { "sustain strength",	 5, 180 },
+    { "searching",		10, 200 },
+    { "see invisible",		10, 175 },
+    { "adornment",		 1, 100 },
+    { "aggravate monster",	11, 100 },
+    { "dexterity",		 8, 220 },
+    { "increase damage",	 8, 220 },
+    { "regeneration",		 4, 260 },
+    { "slow digestion",		 9, 240 },
+    { "teleportation",		 9, 100 },
+    { "stealth",		 7, 100 },
+};
+
+struct magic_item ws_magic[MAXSTICKS] = {
+    { "light",			12, 120 },
+    { "striking",		 9, 115 },
+    { "lightning",		 3, 200 },
+    { "fire",			 3, 200 },
+    { "cold",			 3, 200 },
+    { "polymorph",		15, 210 },
+    { "magic missile",		10, 170 },
+    { "haste monster",		 9,  50 },
+    { "slow monster",		11, 220 },
+    { "drain life",		 9, 210 },
+    { "nothing",		 1,  70 },
+    { "teleport away",		 5, 140 },
+    { "teleport to",		 5,  60 },
+    { "cancellation",		 5, 130 },
+};
+
+int a_class[MAXARMORS] = {
+    8,
+    7,
+    7,
+    6,
+    5,
+    4,
+    4,
+    3,
+};
+
+char *a_names[MAXARMORS] = {
+    "leather armor",
+    "ring mail",
+    "studded leather armor",
+    "scale mail",
+    "chain mail",
+    "splint mail",
+    "banded mail",
+    "plate mail",
+};
+
+int a_chances[MAXARMORS] = {
+    20,
+    35,
+    50,
+    63,
+    75,
+    85,
+    95,
+    100
+};
+
+#define MAX3(a,b,c)     (a > b ? (a > c ? a : c) : (b > c ? b : c))
+static int used[MAX3(NCOLORS, NSTONES, NWOOD)];
+
+/*
+ * init_things
+ *	Initialize the probabilities for types of things
+ */
+void
+init_things()
+{
+    struct magic_item *mp;
+
+    for (mp = &things[1]; mp <= &things[NUMTHINGS-1]; mp++)
+	mp->mi_prob += (mp-1)->mi_prob;
+    badcheck("things", things, NUMTHINGS);
+}
+
+/*
+ * init_colors:
+ *	Initialize the potion color scheme for this time
+ */
+
+void
+init_colors()
+{
+    int i, j;
+
+    for (i = 0; i < NCOLORS; i++)
+	used[i] = 0;
+    for (i = 0; i < MAXPOTIONS; i++)
+    {
+	do
+	    j = rnd(NCOLORS);
+	until (!used[j]);
+	used[j] = TRUE;
+	p_colors[i] = rainbow[j];
+	p_know[i] = FALSE;
+	p_guess[i] = NULL;
+	if (i > 0)
+		p_magic[i].mi_prob += p_magic[i-1].mi_prob;
+    }
+    badcheck("potions", p_magic, MAXPOTIONS);
+}
+
+/*
+ * init_names:
+ *	Generate the names of the various scrolls
+ */
+
+void
+init_names()
+{
+    int nsyl;
+    char *cp, *sp;
+    int i, nwords;
+
+    for (i = 0; i < MAXSCROLLS; i++)
+    {
+	cp = prbuf;
+	nwords = rnd(4)+2;
+	while(nwords--)
+	{
+	    nsyl = rnd(3)+1;
+	    while(nsyl--)
+	    {
+		sp = sylls[rnd((sizeof sylls) / (sizeof (char *)))];
+		while(*sp)
+		    *cp++ = *sp++;
+	    }
+	    *cp++ = ' ';
+	}
+	*--cp = '\0';
+	s_names[i] = (char *) _new(strlen(prbuf)+1);
+	s_know[i] = FALSE;
+	s_guess[i] = NULL;
+	strcpy(s_names[i], prbuf);
+	if (i > 0)
+		s_magic[i].mi_prob += s_magic[i-1].mi_prob;
+    }
+    badcheck("scrolls", s_magic, MAXSCROLLS);
+}
+
+/*
+ * init_stones:
+ *	Initialize the ring stone setting scheme for this time
+ */
+
+void
+init_stones()
+{
+    int i, j;
+
+    for (i = 0; i < NSTONES; i++)
+	used[i] = FALSE;
+    for (i = 0; i < MAXRINGS; i++)
+    {
+	do
+	    j = rnd(NSTONES);
+	until (!used[j]);
+	used[j] = TRUE;
+	r_stones[i] = stones[j];
+	r_know[i] = FALSE;
+	r_guess[i] = NULL;
+	if (i > 0)
+		r_magic[i].mi_prob += r_magic[i-1].mi_prob;
+    }
+    badcheck("rings", r_magic, MAXRINGS);
+}
+
+/*
+ * init_materials:
+ *	Initialize the construction materials for wands and staffs
+ */
+
+void
+init_materials()
+{
+    int i, j;
+    static int metused[NMETAL];
+
+    for (i = 0; i < NWOOD; i++)
+	used[i] = FALSE;
+    for (i = 0; i < NMETAL; i++)
+	metused[i] = FALSE;
+
+    for (i = 0; i < MAXSTICKS; i++)
+    {
+	for (;;)
+	    if (rnd(100) > 50)
+	    {
+		j = rnd(NMETAL);
+		if (!metused[j])
+		{
+		    metused[j] = TRUE;
+		    ws_made[i] = metal[j];
+		    ws_type[i] = "wand";
+		    break;
+		}
+	    }
+	    else
+	    {
+		j = rnd(NWOOD);
+		if (!used[j])
+		{
+		    used[j] = TRUE;
+		    ws_made[i] = wood[j];
+		    ws_type[i] = "staff";
+		    break;
+		}
+	    }
+
+	ws_know[i] = FALSE;
+	ws_guess[i] = NULL;
+	if (i > 0)
+		ws_magic[i].mi_prob += ws_magic[i-1].mi_prob;
+    }
+    badcheck("sticks", ws_magic, MAXSTICKS);
+}
+
+void
+badcheck(char *name, struct magic_item *magic, int bound)
+{
+    struct magic_item *end;
+
+    if (magic[bound - 1].mi_prob == 100)
+	return;
+    printf("\nBad percentages for %s:\n", name);
+    for (end = &magic[bound]; magic < end; magic++)
+	printf("%3d%% %s\n", magic->mi_prob, magic->mi_name);
+    printf("[hit RETURN to continue]");
+    fflush(stdout);
+    while (getchar() != '\n')
+	continue;
+}
+
+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",
+    ' ',	"	(space) rest for a while",
+    'i',	"	inventory",
+    'I',	"	inventory single item",
+    'q',	"	quaff potion",
+    'r',	"	read paper",
+    '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",
+    CTRL('L'),	"	redraw screen",
+    CTRL('R'),	"	repeat last message",
+    ESCAPE,	"	cancel command",
+    'v',	"	print program version number",
+    '!',	"	shell escape",
+    'S',	"	save game",
+    'Q',	"	quit",
+    0, 0
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rogue3/io.c	Tue Oct 13 13:33:34 2009 +0000
@@ -0,0 +1,248 @@
+/*
+ * Various input/output functions
+ *
+ * @(#)io.c	3.10 (Berkeley) 6/15/81
+ *
+ * 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 <stdlib.h>
+#include "curses.h"
+#include <ctype.h>
+#include <stdarg.h>
+#include <string.h>
+#include "machdep.h"
+#include "rogue.h"
+
+/*
+ * msg:
+ *	Display a message at the top of the screen.
+ */
+
+static char msgbuf[BUFSIZ];
+static int newpos = 0;
+
+/*VARARGS1*/
+void
+msg(char *fmt, ...)
+{
+    va_list ap;
+    /*
+     * if the string is "", just clear the line
+     */
+    if (*fmt == '\0')
+    {
+	wmove(cw, 0, 0);
+	wclrtoeol(cw);
+	mpos = 0;
+	return;
+    }
+    /*
+     * otherwise add to the message and flush it out
+     */
+    va_start(ap, fmt);
+    doadd(fmt, ap);
+    va_end(ap);
+    endmsg();
+}
+
+/*
+ * add things to the current message
+ */
+void
+addmsg(char *fmt, ...)
+{
+    va_list ap;
+
+    va_start(ap, fmt);
+    doadd(fmt, ap);
+    va_end(ap);
+}
+
+/*
+ * Display a new msg (giving him a chance to see the previous one if it
+ * is up there with the --More--)
+ */
+void
+endmsg()
+{
+    strncpy(huh, msgbuf, 80);
+    huh[79] = 0;
+
+    if (mpos)
+    {
+	wmove(cw, 0, mpos);
+	waddstr(cw, "--More--");
+	draw(cw);
+	wait_for(cw,' ');
+    }
+    mvwaddstr(cw, 0, 0, msgbuf);
+    wclrtoeol(cw);
+    mpos = newpos;
+    newpos = 0;
+    draw(cw);
+}
+
+void
+doadd(char *fmt, va_list ap)
+{
+    vsprintf(&msgbuf[newpos], fmt, ap);
+    newpos = (int) strlen(msgbuf);
+}
+
+/*
+ * step_ok:
+ *	returns true if it is ok to step on ch
+ */
+
+int
+step_ok(int ch)
+{
+    switch (ch)
+    {
+	case ' ':
+	case '|':
+	case '-':
+	case SECRETDOOR:
+	    return FALSE;
+	default:
+	    return (!isalpha(ch));
+    }
+}
+
+/*
+ * readchar:
+ *	flushes stdout so that screen is up to date and then returns
+ *	getchar.
+ */
+
+int
+readchar(WINDOW *win)
+{
+    int ch;
+
+    ch = md_readchar(win);
+
+    if ((ch == 3) || (ch == 0))
+    {
+	quit(0);
+        return(27);
+    }
+
+    return(ch);
+}
+
+/*
+ * status:
+ *	Display the important stats line.  Keep the cursor where it was.
+ */
+
+void
+status()
+{
+    int oy, ox, temp;
+    char *pb;
+    static char buf[80];
+    static int hpwidth = 0, s_hungry = -1;
+    static int s_lvl = -1, s_pur, s_hp = -1, s_str, s_add, s_ac = 0;
+    static long s_exp = 0;
+
+    /*
+     * If nothing has changed since the last status, don't
+     * bother.
+     */
+    if (s_hp == pstats.s_hpt && s_exp == pstats.s_exp && s_pur == purse
+	&& s_ac == (cur_armor != NULL ? cur_armor->o_ac : pstats.s_arm)
+	&& s_str == pstats.s_str.st_str && s_add == pstats.s_str.st_add
+	&& s_lvl == level && s_hungry == hungry_state)
+	    return;
+	
+    getyx(cw, oy, ox);
+    if (s_hp != max_hp)
+    {
+	temp = s_hp = max_hp;
+	for (hpwidth = 0; temp; hpwidth++)
+	    temp /= 10;
+    }
+    sprintf(buf, "Level: %d  Gold: %-5d  Hp: %*d(%*d)  Str: %-2d",
+	level, purse, hpwidth, pstats.s_hpt, hpwidth, max_hp,
+	pstats.s_str.st_str);
+    if (pstats.s_str.st_add != 0)
+    {
+	pb = &buf[strlen(buf)];
+	sprintf(pb, "/%d", pstats.s_str.st_add);
+    }
+    pb = &buf[strlen(buf)];
+    sprintf(pb, "  Ac: %-2d  Exp: %d/%d",
+	cur_armor != NULL ? cur_armor->o_ac : pstats.s_arm, pstats.s_lvl,
+	pstats.s_exp);
+    /*
+     * Save old status
+     */
+    s_lvl = level;
+    s_pur = purse;
+    s_hp = pstats.s_hpt;
+    s_str = pstats.s_str.st_str;
+    s_add = pstats.s_str.st_add;
+    s_exp = pstats.s_exp; 
+    s_ac = (cur_armor != NULL ? cur_armor->o_ac : pstats.s_arm);
+    mvwaddstr(cw, LINES - 1, 0, buf);
+    switch (hungry_state)
+    {
+	case 0: ;
+	when 1:
+	    waddstr(cw, "  Hungry");
+	when 2:
+	    waddstr(cw, "  Weak");
+	when 3:
+	    waddstr(cw, "  Fainting");
+    }
+    wclrtoeol(cw);
+    s_hungry = hungry_state;
+    wmove(cw, oy, ox);
+}
+
+/*
+ * wait_for
+ *	Sit around until the guy types the right key
+ */
+
+void
+wait_for(WINDOW *win, int ch)
+{
+    int c;
+
+    if (ch == '\n')
+        while ((c = readchar(win)) != '\n' && c != '\r')
+	    continue;
+    else
+        while (readchar(win) != ch)
+	    continue;
+}
+
+/*
+ * show_win:
+ *	function used to display a window and wait before returning
+ */
+
+void
+show_win(WINDOW *scr, char *message)
+{
+    mvwaddstr(scr, 0, 0, message);
+    touchwin(scr);
+    wmove(scr, hero.y, hero.x);
+    draw(scr);
+    wait_for(scr,' ');
+    clearok(cw, TRUE);
+    touchwin(cw);
+}
+
+void
+flush_type()
+{
+	flushinp();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rogue3/list.c	Tue Oct 13 13:33:34 2009 +0000
@@ -0,0 +1,129 @@
+/*
+ * Functions for dealing with linked lists of goodies
+ *
+ * @(#)list.c	3.3 (Berkeley) 6/15/81
+ *
+ * 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 "curses.h"
+#include <stdlib.h>
+#include <string.h>
+#include "machdep.h"
+#include "rogue.h"
+
+/*
+ * detach:
+ *	Takes an item out of whatever linked list it might be in
+ */
+
+void
+_detach(struct linked_list **list, struct linked_list *item)
+{
+    if (*list == item)
+	*list = next(item);
+    if (prev(item) != NULL) item->l_prev->l_next = next(item);
+    if (next(item) != NULL) item->l_next->l_prev = prev(item);
+    item->l_next = NULL;
+    item->l_prev = NULL;
+}
+
+/*
+ * _attach:
+ *	add an item to the head of a list
+ */
+
+void
+_attach(struct linked_list **list, struct linked_list *item)
+{
+    if (*list != NULL)
+    {
+	item->l_next = *list;
+	(*list)->l_prev = item;
+	item->l_prev = NULL;
+    }
+    else
+    {
+	item->l_next = NULL;
+	item->l_prev = NULL;
+    }
+
+    *list = item;
+}
+
+/*
+ * _free_list:
+ *	Throw the whole blamed thing away
+ */
+
+void
+_free_list(struct linked_list **ptr)
+{
+    struct linked_list *item;
+
+    while (*ptr != NULL)
+    {
+	item = *ptr;
+	*ptr = next(item);
+	discard(item);
+    }
+}
+
+/*
+ * discard:
+ *	free up an item
+ */
+
+void
+discard(struct linked_list *item)
+{
+    total -= 2;
+    FREE(item->l_data);
+    FREE(item);
+}
+
+/*
+ * new_item
+ *	get a new item with a specified size
+ */
+
+struct linked_list *
+new_item(int size)
+{
+    struct linked_list *item;
+
+    if ((item = (struct linked_list *) _new(sizeof *item)) == NULL)
+    {
+	msg("Ran out of memory for header after %d items", total);
+	return NULL;
+    }
+
+    if ((item->l_data = _new(size)) == NULL)
+    {
+	msg("Ran out of memory for data after %d items", total);
+	free(item);
+	return NULL;
+    }
+
+    item->l_next = item->l_prev = NULL;
+    memset(item->l_data,0,size);
+    return item;
+}
+
+char *
+_new(size_t size)
+{
+    char *space = ALLOC(size);
+
+    if (space == NULL)
+    {
+	sprintf(prbuf, "Rogue ran out of memory (%d).  Fatal error!", md_memused());
+        fatal(prbuf);
+    }
+    total++;
+    return space;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rogue3/machdep.h	Tue Oct 13 13:33:34 2009 +0000
@@ -0,0 +1,21 @@
+/*
+ * machine dependicies
+ *
+ * %G% (Berkeley) %W%
+ *
+ * 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.
+ */
+
+/*
+ * Variables for checking to make sure the system isn't too loaded
+ * for people to play
+ */
+
+#define AUTHORUID        0
+#define	MAXUSERS	25	/* max number of users for this game */
+#define	MAXLOAD		40	/* 10 * max 15 minute load average */
+#define	CHECKTIME	15	/* number of minutes between load checks */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rogue3/main.c	Tue Oct 13 13:33:34 2009 +0000
@@ -0,0 +1,475 @@
+/*
+ * @(#)main.c	3.27 (Berkeley) 6/15/81
+ *
+ * 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 "curses.h"
+#include <time.h>
+#include <signal.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include "machdep.h"
+#include "rogue.h"
+
+int num_checks = 0;			/* times we've gone over in checkout() */
+WINDOW *cw;                              /* Window that the player sees */
+WINDOW *hw;                              /* Used for the help command */
+WINDOW *mw;                              /* Used to store mosnters */
+FILE   *scoreboard = NULL;
+
+main(argc, argv, envp)
+char **argv;
+char **envp;
+{
+    char *env;
+    struct linked_list *item;
+    struct object *obj;
+    int lowtime;
+    time_t now;
+
+    md_init(MD_STRIP_CTRL_KEYPAD);
+
+    open_score();
+
+    /* 
+     * Drop setuid/setgid after opening the scoreboard file. 
+     */
+
+    md_normaluser();
+
+    /*
+     * check for print-score option
+     */
+    if (argc == 2 && strcmp(argv[1], "-s") == 0)
+    {
+	waswizard = TRUE;
+	score(0, -1, 0);
+	exit(0);
+    }
+    /*
+     * Check to see if he is a wizard
+     */
+    if (argc >= 2 && argv[1][0] == '\0')
+	if (strcmp(PASSWD, crypt(md_getpass("Wizard's password: "), "mT")) == 0)
+	{
+	    wizard = TRUE;
+	    argv++;
+	    argc--;
+	}
+
+    /*
+     * get home and options from environment
+     */
+    strcpy(home, md_gethomedir());
+    
+    if (strlen(home) > PATH_MAX - strlen("rogue.save") - 1)
+        *home = 0;
+    
+    strcpy(file_name, home);
+    strcat(file_name, "rogue.save");
+
+    if ((env = getenv("ROGUEOPTS")) != NULL)
+	parse_opts(env);
+    if (env == NULL || whoami[0] == '\0')
+	strucpy(whoami, md_getusername(), strlen(md_getusername()));
+    if (env == NULL || fruit[0] == '\0')
+	strcpy(fruit, "slime-mold");
+
+    if (too_much() && !wizard && !author())
+    {
+	printf("Sorry, %s, but the system is too loaded now.\n", whoami);
+	printf("Try again later.  Meanwhile, why not enjoy a%s %s?\n",
+	    vowelstr(fruit), fruit);
+	exit(1);
+    }
+
+    if (argc == 2)
+	if (!restore(argv[1], envp)) /* Note: restore will never return */
+	    exit(1);
+
+    time(&now);
+    lowtime = (int) now;
+
+    env = getenv("SEED");
+
+    if (env)
+        seed = atoi(env);
+    else
+        seed = 0;
+
+    if (seed > 0)
+    {
+        waswizard = 1; /* don't save scores if SEED specified */
+        dnum = seed;
+    }
+    else
+        dnum = lowtime + md_getpid();
+
+    if (wizard || env)
+	printf("Hello %s, welcome to dungeon #%d", whoami, dnum);
+    else
+	printf("Hello %s, just a moment while I dig the dungeon...", whoami);
+
+    fflush(stdout);
+    seed = dnum;
+    init_player();			/* Roll up the rogue */
+    init_things();			/* Set up probabilities of things */
+    init_names();			/* Set up names of scrolls */
+    init_colors();			/* Set up colors of potions */
+    init_stones();			/* Set up stone settings of rings */
+    init_materials();			/* Set up materials of wands */
+    initscr();				/* Start up cursor package */
+
+    if (COLS < 70)
+    {
+	endwin();
+	printf("\n\nSorry, %s, but your terminal window has too few columns.\n", whoami);
+	printf("Your terminal has %d columns, needs 70.\n",COLS);
+	exit(1);
+    }
+    if (LINES < 22)
+    {
+	endwin();
+	printf("\n\nSorry, %s, but your terminal window has too few lines.\n", whoami);
+	printf("Your terminal has %d lines, needs 22.\n",LINES);
+	exit(1);
+    }
+    
+
+    setup();
+    /*
+     * Set up windows
+     */
+    cw = newwin(LINES, COLS, 0, 0);
+    mw = newwin(LINES, COLS, 0, 0);
+    hw = newwin(LINES, COLS, 0, 0);
+    keypad(cw,1);
+    waswizard = wizard;
+    new_level();			/* Draw current level */
+    /*
+     * Start up daemons and fuses
+     */
+    start_daemon(doctor, 0, AFTER);
+    fuse(swander, 0, WANDERTIME, AFTER);
+    start_daemon(stomach, 0, AFTER);
+    start_daemon(runners, 0, AFTER);
+    /*
+     * Give the rogue his weaponry.  First a mace.
+     */
+    item = new_item(sizeof *obj);
+    obj = (struct object *) ldata(item);
+    obj->o_type = WEAPON;
+    obj->o_which = MACE;
+    init_weapon(obj, MACE);
+    obj->o_hplus = 1;
+    obj->o_dplus = 1;
+    obj->o_flags |= ISKNOW;
+    add_pack(item, TRUE);
+    cur_weapon = obj;
+    /*
+     * Now a +1 bow
+     */
+    item = new_item(sizeof *obj);
+    obj = (struct object *) ldata(item);
+    obj->o_type = WEAPON;
+    obj->o_which = BOW;
+    init_weapon(obj, BOW);
+    obj->o_hplus = 1;
+    obj->o_dplus = 0;
+    obj->o_flags |= ISKNOW;
+    add_pack(item, TRUE);
+    /*
+     * Now some arrows
+     */
+    item = new_item(sizeof *obj);
+    obj = (struct object *) ldata(item);
+    obj->o_type = WEAPON;
+    obj->o_which = ARROW;
+    init_weapon(obj, ARROW);
+    obj->o_count = 25+rnd(15);
+    obj->o_hplus = obj->o_dplus = 0;
+    obj->o_flags |= ISKNOW;
+    add_pack(item, TRUE);
+    /*
+     * And his suit of armor
+     */
+    item = new_item(sizeof *obj);
+    obj = (struct object *) ldata(item);
+    obj->o_type = ARMOR;
+    obj->o_which = RING_MAIL;
+    obj->o_ac = a_class[RING_MAIL] - 1;
+    obj->o_flags |= ISKNOW;
+    cur_armor = obj;
+    add_pack(item, TRUE);
+    /*
+     * Give him some food too
+     */
+    item = new_item(sizeof *obj);
+    obj = (struct object *) ldata(item);
+    obj->o_type = FOOD;
+    obj->o_count = 1;
+    obj->o_which = 0;
+    add_pack(item, TRUE);
+    playit();
+}
+
+/*
+ * endit:
+ *	Exit the program abnormally.
+ */
+
+void
+endit(int p)
+{
+    fatal("Ok, if you want to exit that badly, I'll have to allow it\n");
+}
+
+/*
+ * fatal:
+ *	Exit the program, printing a message.
+ */
+
+void
+fatal(char *s)
+{
+    clear();
+    move(LINES-2, 0);
+    printw("%s", s);
+    draw(stdscr);
+    endwin();
+    exit(0);
+}
+
+/*
+ * rnd:
+ *	Pick a very random number.
+ */
+
+int
+rnd(int range)
+{
+    return range == 0 ? 0 : abs(RN) % range;
+}
+
+/*
+ * roll:
+ *	roll a number of dice
+ */
+
+int
+roll(int number, int sides)
+{
+    int dtotal = 0;
+
+    while(number--)
+	dtotal += rnd(sides)+1;
+    return dtotal;
+}
+/*
+ * handle stop and start signals
+ */
+
+void
+tstp(int p)
+{
+#ifdef SIGTSTP
+    signal(SIGTSTP, SIG_IGN);
+#endif
+    mvcur(0, COLS - 1, LINES - 1, 0);
+    endwin();
+    fflush(stdout);
+#ifdef SIGTSTP
+    signal(SIGTSTP, SIG_DFL);
+    kill(0, SIGTSTP);
+    signal(SIGTSTP, tstp);
+#endif
+    crmode();
+    noecho();
+    clearok(curscr, TRUE);
+    touchwin(cw);
+    draw(cw);
+    flush_type();	/* flush input */
+}
+
+void
+setup()
+{
+#ifdef SIGHUP
+    signal(SIGHUP, auto_save);
+#endif
+    signal(SIGILL, auto_save);
+#ifdef SIGTRAP
+    signal(SIGTRAP, auto_save);
+#endif
+#ifdef SIGIOT
+    signal(SIGIOT, auto_save);
+#endif
+#ifdef SIGEMT
+    signal(SIGEMT, auto_save);
+#endif
+    signal(SIGFPE, auto_save);
+#ifdef SIGBUS
+    signal(SIGBUS, auto_save);
+#endif
+    signal(SIGSEGV, auto_save);
+#ifdef SIGSYS
+    signal(SIGSYS, auto_save);
+#endif
+#ifdef SIGPIPE
+    signal(SIGPIPE, auto_save);
+#endif
+    signal(SIGTERM, auto_save);
+    signal(SIGINT, quit);
+#ifdef SIGQUIT
+    signal(SIGQUIT, endit);
+#endif
+#ifdef SIGTSTP
+    signal(SIGTSTP, tstp);
+#endif
+
+    if (!author())
+    {
+#ifdef SIGALRM
+	signal(SIGALRM, checkout);
+	alarm(CHECKTIME * 60);
+#endif
+	num_checks = 0;
+    }
+
+    crmode();				/* Cbreak mode */
+    noecho();				/* Echo off */
+}
+
+/*
+ * playit:
+ *	The main loop of the program.  Loop until the game is over,
+ * refreshing things and looking at the proper times.
+ */
+
+void
+playit()
+{
+    char *opts;
+
+    /*
+     * set up defaults for slow terminals
+     */
+
+
+    if (baudrate() < 1200)
+    {
+	terse = TRUE;
+	jump = TRUE;
+    }
+
+    /*
+     * parse environment declaration of options
+     */
+    if ((opts = getenv("ROGUEOPTS")) != NULL)
+	parse_opts(opts);
+
+
+    oldpos = hero;
+    oldrp = roomin(&hero);
+    while (playing)
+	command();			/* Command execution */
+    endit(-1);
+}
+
+/*
+ * see if the system is being used too much for this game
+ */
+int
+too_much()
+{
+    double avec[3];
+
+    if (md_loadav(avec) == 0)
+    	return (avec[2] > (MAXLOAD / 10.0));
+    else
+        return (md_ucount() > MAXUSERS);
+}
+
+/*
+ * see if a user is an author of the program
+ */
+int
+author()
+{
+    switch (md_getuid())
+    {
+	case AUTHORUID:
+	    return TRUE;
+	default:
+	    return FALSE;
+    }
+}
+
+void
+checkout(int p)
+{
+    static char *msgs[] = {
+	"The load is too high to be playing.  Please leave in %d minutes",
+	"Please save your game.  You have %d minutes",
+	"Last warning.  You have %d minutes to leave",
+    };
+    int checktime;
+#ifdef SIGALRM
+    signal(SIGALRM, checkout);
+#endif
+    if (too_much())
+    {
+	if (num_checks >= 3)
+	    fatal("Sorry.  You took to long.  You are dead\n");
+	checktime = CHECKTIME / (num_checks + 1);
+	if (num_checks < 3)
+		chmsg(msgs[num_checks++], checktime);
+#ifdef SIGALRM
+	alarm(checktime * 60);
+#endif
+    }
+    else
+    {
+	if (num_checks)
+	{
+	    chmsg("The load has dropped back down.  You have a reprieve.");
+	    num_checks = 0;
+	}
+#ifdef SIGALRM
+	alarm(CHECKTIME * 60);
+#endif
+    }
+}
+
+/*
+ * checkout()'s version of msg.  If we are in the middle of a shell, do a
+ * printf instead of a msg to avoid the refresh.
+ */
+void
+chmsg(char *fmt, ...)
+{
+    va_list args;
+
+    if (in_shell)
+    {
+	va_start(args, fmt);
+	vprintf(fmt, args);
+	va_end(args);
+	putchar('\n');
+	fflush(stdout);
+    }
+    else
+    {
+        va_start(args, fmt);
+        doadd(fmt, args);
+        va_end(args);
+	endmsg();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rogue3/mdport.c	Tue Oct 13 13:33:34 2009 +0000
@@ -0,0 +1,1603 @@
+/*
+    mdport.c - Machine Dependent Code for Porting Unix/Curses games
+
+    Copyright (C) 2005 Nicholas J. Kisseberth
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+    3. Neither the name(s) of the author(s) nor the names of other contributors
+       may be used to endorse or promote products derived from this software
+       without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS ``AS IS'' AND
+    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+    ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+    OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+    SUCH DAMAGE.
+*/
+
+#include <stdlib.h>
+#include <string.h>
+
+#if defined(_WIN32)
+#include <Windows.h>
+#include <io.h>
+#include <sys/locking.h>
+#include <Lmcons.h>
+#include <conio.h>
+#pragma warning( disable: 4201 ) 
+#include <shlobj.h>
+#pragma warning( default: 4201 ) 
+#include <Shlwapi.h>
+#undef MOUSE_MOVED
+#endif
+
+#include <curses.h>
+
+#include "mdport.h"
+
+#if defined(HAVE_SYS_TYPES)
+#include <sys/types.h>
+#endif
+
+#if defined(HAVE_PROCESS_H)
+#include <process.h>
+#endif
+
+#if defined(HAVE_PWD_H)
+#include <pwd.h>
+#endif
+
+#if defined(HAVE_SYS_UTSNAME)
+#include <sys/utsname.h>
+#endif
+
+#if defined(HAVE_ARPA_INET_H)
+#include <arpa/inet.h> /* Solaris 2.8 required this for htonl() and ntohl() */
+#endif
+
+#if defined(HAVE_TERMIOS_H)
+#include <termios.h>
+#endif
+
+#if defined(HAVE_UNISTD_H)
+#ifndef __USE_GNU
+#define __USE_GNU
+#include <unistd.h>
+#undef __USE_GNU
+#else
+#include <unistd.h>
+#endif
+#endif
+
+#if defined(HAVE_TERM_H)
+#include <term.h>
+#elif defined(HAVE_NCURSES_TERM_H)
+#include <ncurses/term.h>
+#endif
+
+#if defined(HAVE_WORKING_FORK)
+#include <sys/wait.h>
+#endif
+
+#ifdef HAVE_UTMPX_H
+#include <utmpx.h>
+#endif
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+#include <ctype.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <sys/stat.h>
+#include <signal.h>
+
+#define NOOP(x) (x += 0)
+
+static int pass_ctrl_keypad = 1;
+
+void
+md_init(int options)
+{
+#if defined(__INTERIX)
+    char *term;
+
+    term = getenv("TERM");
+
+    if (term == NULL)
+        setenv("TERM","interix");
+#elif defined(__DJGPP__)
+    _fmode = _O_BINARY;
+#elif defined(_WIN32)
+    _fmode = _O_BINARY;
+#endif
+
+#if defined(HAVE_ESCDELAY) || defined(NCURSES_VERSION)
+    ESCDELAY=64;
+#endif
+
+#if defined(DUMP)
+    md_onsignal_default();
+#else
+    md_onsignal_exit();
+#endif
+
+    if (options & MD_STRIP_CTRL_KEYPAD)
+        pass_ctrl_keypad = 0;
+    else
+        pass_ctrl_keypad = 1;
+}
+
+void
+md_onsignal_default(void)
+{
+#ifdef SIGHUP
+    signal(SIGHUP, SIG_DFL);
+#endif
+#ifdef SIGQUIT
+    signal(SIGQUIT, SIG_DFL);
+#endif
+#ifdef SIGILL
+    signal(SIGILL, SIG_DFL);
+#endif
+#ifdef SIGTRAP
+    signal(SIGTRAP, SIG_DFL);
+#endif
+#ifdef SIGIOT
+    signal(SIGIOT, SIG_DFL);
+#endif
+#ifdef SIGEMT
+    signal(SIGEMT, SIG_DFL);
+#endif
+#ifdef SIGFPE
+    signal(SIGFPE, SIG_DFL);
+#endif
+#ifdef SIGBUS
+    signal(SIGBUS, SIG_DFL);
+#endif
+#ifdef SIGSEGV
+    signal(SIGSEGV, SIG_DFL);
+#endif
+#ifdef SIGSYS
+    signal(SIGSYS, SIG_DFL);
+#endif
+#ifdef SIGTERM
+    signal(SIGTERM, SIG_DFL);
+#endif
+}
+
+void
+md_onsignal_exit(void)
+{
+#ifdef SIGHUP
+    signal(SIGHUP, SIG_DFL);
+#endif
+#ifdef SIGQUIT
+    signal(SIGQUIT, exit);
+#endif
+#ifdef SIGILL
+    signal(SIGILL, exit);
+#endif
+#ifdef SIGTRAP
+    signal(SIGTRAP, exit);
+#endif
+#ifdef SIGIOT
+    signal(SIGIOT, exit);
+#endif
+#ifdef SIGEMT
+    signal(SIGEMT, exit);
+#endif
+#ifdef SIGFPE
+    signal(SIGFPE, exit);
+#endif
+#ifdef SIGBUS
+    signal(SIGBUS, exit);
+#endif
+#ifdef SIGSEGV
+    signal(SIGSEGV, exit);
+#endif
+#ifdef SIGSYS
+    signal(SIGSYS, exit);
+#endif
+#ifdef SIGTERM
+    signal(SIGTERM, exit);
+#endif
+}
+
+extern void auto_save(int sig);
+extern void endit(int sig);
+extern void quit(int sig);
+
+void
+md_onsignal_autosave(void)
+{
+
+#ifdef SIGHUP
+    signal(SIGHUP, auto_save);
+#endif
+#ifdef SIGQUIT
+	signal(SIGQUIT, endit);
+#endif
+#ifdef SIGILL
+    signal(SIGILL, auto_save);
+#endif
+#ifdef SIGTRAP
+    signal(SIGTRAP, auto_save);
+#endif
+#ifdef SIGIOT
+    signal(SIGIOT, auto_save);
+#endif
+#ifdef SIGEMT
+    signal(SIGEMT, auto_save);
+#endif
+#ifdef SIGFPE
+    signal(SIGFPE, auto_save);
+#endif
+#ifdef SIGBUS
+    signal(SIGBUS, auto_save);
+#endif
+#ifdef SIGSEGV
+    signal(SIGSEGV, auto_save);
+#endif
+#ifdef SIGSYS
+    signal(SIGSYS, auto_save);
+#endif
+#ifdef SIGTERM
+    signal(SIGTERM, auto_save);
+#endif
+#ifdef SIGINT
+    signal(SIGINT, quit);
+#endif
+}
+
+int
+md_hasclreol(void)
+{
+#if defined(clr_eol)
+#ifdef NCURSES_VERSION
+    if (cur_term == NULL)
+	return(0);
+    if (cur_term->type.Strings == NULL)
+	return(0);
+#endif
+    return((clr_eol != NULL) && (*clr_eol != 0));
+#elif defined(__PDCURSES__)
+    return(TRUE);
+#else
+    return((CE != NULL) && (*CE != 0));
+#endif
+}
+
+void
+md_putchar(int c)
+{
+    putchar(c);
+}
+
+#ifdef _WIN32
+static int md_standout_mode = 0;
+#endif
+
+void
+md_raw_standout(void)
+{
+#ifdef _WIN32
+    CONSOLE_SCREEN_BUFFER_INFO csbiInfo; 
+    HANDLE hStdout;
+    WORD fgattr,bgattr;
+
+    if (md_standout_mode == 0)
+    {
+        hStdout = GetStdHandle(STD_OUTPUT_HANDLE); 
+        GetConsoleScreenBufferInfo(hStdout, &csbiInfo);
+        fgattr = (csbiInfo.wAttributes & 0xF);
+        bgattr = (csbiInfo.wAttributes & 0xF0);
+        SetConsoleTextAttribute(hStdout,(fgattr << 4) | (bgattr >> 4));
+        md_standout_mode = 1;
+    }
+#elif defined(SO)
+    tputs(SO,0,md_putchar);
+    fflush(stdout);
+#endif
+}
+
+void
+md_raw_standend(void)
+{
+#ifdef _WIN32
+    CONSOLE_SCREEN_BUFFER_INFO csbiInfo; 
+    HANDLE hStdout;
+    WORD fgattr,bgattr;
+
+    if (md_standout_mode == 1)
+    {
+        hStdout = GetStdHandle(STD_OUTPUT_HANDLE); 
+        GetConsoleScreenBufferInfo(hStdout, &csbiInfo);
+        fgattr = (csbiInfo.wAttributes & 0xF);
+        bgattr = (csbiInfo.wAttributes & 0xF0);
+        SetConsoleTextAttribute(hStdout,(fgattr << 4) | (bgattr >> 4));
+        md_standout_mode = 0;
+    }
+#elif defined(SE)
+    tputs(SE,0,md_putchar);
+    fflush(stdout);
+#endif
+}
+
+int
+md_unlink_open_file(const char *file, FILE *inf)
+{
+#ifdef _WIN32
+    fclose(inf);
+    (void) _chmod(file, 0600);
+    return( _unlink(file) );
+#else
+    return(unlink(file));
+#endif
+}
+
+int
+md_unlink(char *file)
+{
+#ifdef _WIN32
+    (void) _chmod(file, 0600);
+    return( _unlink(file) );
+#else
+    return(unlink(file));
+#endif
+}
+
+int
+md_chmod(const char *filename, int mode)
+{
+#ifdef _WIN32
+    return( _chmod(filename, mode) );
+#else
+    return( chmod(filename, mode) );
+#endif
+}
+
+void
+md_normaluser(void)
+{
+#if defined(HAVE_GETGID) && defined(HAVE_GETUID)
+	gid_t realgid = getgid();
+	uid_t realuid = getuid();
+
+#if defined(HAVE_SETRESGID)
+    if (setresgid(-1, realgid, realgid) != 0) {
+#elif defined (HAVE_SETREGID) 
+    if (setregid(realgid, realgid) != 0) {
+#elif defined (HAVE_SETGID)
+	if (setgid(realgid) != 0) {
+#else
+	if (0) {
+#endif
+		perror("Could not drop setgid privileges.  Aborting.");
+		exit(1);
+    }
+
+#if defined(HAVE_SETRESUID)
+    if (setresuid(-1, realuid, realuid) != 0) {
+#elif defined(HAVE_SETREUID)
+    if (setreuid(realuid, realuid) != 0) {
+#elif defined(HAVE_SETUID)
+	if (setuid(realuid) != 0) {
+#else
+	if (0) {
+#endif
+	perror("Could not drop setuid privileges.  Aborting.");
+	exit(1);
+    }
+#endif
+}
+
+uid_t
+md_getuid(void)
+{
+#ifdef HAVE_GETUID
+    return( getuid() );
+#else
+    return(42);
+#endif
+}
+
+pid_t
+md_getpid(void)
+{
+#ifdef _WIN32
+    return( _getpid() );
+#else
+    return( getpid() );
+#endif
+}
+
+char *
+md_getusername(void)
+{
+    static char login[80];
+    char *l = NULL;
+#ifdef _WIN32
+    LPSTR mybuffer;
+    DWORD size = UNLEN + 1;
+    TCHAR buffer[UNLEN + 1];
+
+    mybuffer = buffer;
+    GetUserName(mybuffer,&size);
+    l = mybuffer;
+#elif defined(HAVE_GETPWUID)&& !defined(__DJGPP__)
+    struct passwd *pw;
+
+    pw = getpwuid(getuid());
+
+    l = pw->pw_name;
+#endif
+
+    if ((l == NULL) || (*l == '\0'))
+        if ( (l = getenv("USERNAME")) == NULL )
+            if ( (l = getenv("LOGNAME")) == NULL )
+                if ( (l = getenv("USER")) == NULL )
+                    l = "nobody";
+
+    strncpy(login,l,80);
+    login[79] = 0;
+
+    return(login);
+}
+
+char *
+md_gethomedir(void)
+{
+    static char homedir[PATH_MAX];
+    char *h = NULL;
+    size_t len;
+#if defined(_WIN32)
+    TCHAR szPath[PATH_MAX];
+#endif
+#if defined(_WIN32) || defined(DJGPP)
+        char slash = '\\';
+#else
+    char slash = '/';
+    struct passwd *pw;
+    pw = getpwuid(getuid());
+
+    h = pw->pw_dir;
+
+    if (strcmp(h,"/") == 0)
+        h = NULL;
+#endif
+    homedir[0] = 0;
+#ifdef _WIN32
+    if(SUCCEEDED(SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, 0, szPath)))
+        h = szPath;
+#endif
+
+    if ( (h == NULL) || (*h == '\0') )
+    {
+        if ( (h = getenv("HOME")) == NULL )
+	{
+            if ( (h = getenv("HOMEDRIVE")) == NULL)
+                h = "";
+            else
+            {
+                strncpy(homedir,h,PATH_MAX-1);
+                homedir[PATH_MAX-1] = 0;
+
+                if ( (h = getenv("HOMEPATH")) == NULL)
+                    h = "";
+            }
+	}
+    }
+
+
+    len = strlen(homedir);
+    strncat(homedir,h,PATH_MAX-len-1);
+    len = strlen(homedir);
+
+    if ((len > 0) && (homedir[len-1] != slash)) {
+        homedir[len] = slash;
+        homedir[len+1] = 0;
+    }
+
+    return(homedir);
+}
+
+void
+md_sleep(int s)
+{
+#ifdef _WIN32
+    Sleep(s);
+#else
+    sleep(s);
+#endif
+}
+
+char *
+md_getshell(void)
+{
+    static char shell[PATH_MAX];
+    char *s = NULL;
+#ifdef _WIN32
+    char *def = "C:\\WINDOWS\\SYSTEM32\\CMD.EXE";
+#elif defined(__DJGPP__)
+    char *def = "C:\\COMMAND.COM";
+#else
+    char *def = "/bin/sh";
+    struct passwd *pw;
+    pw = getpwuid(getuid());
+    s = pw->pw_shell;
+#endif
+    if ((s == NULL) || (*s == '\0'))
+        if ( (s = getenv("COMSPEC")) == NULL)
+            if ( (s = getenv("SHELL")) == NULL)
+                if ( (s = getenv("SystemRoot")) == NULL)
+                    s = def;
+
+    strncpy(shell,s,PATH_MAX);
+    shell[PATH_MAX-1] = 0;
+
+    return(shell);
+}
+
+int
+md_shellescape(void)
+{
+#if defined(HAVE_WORKING_FORK)
+    int ret_status;
+    int pid;
+    void (*myquit)(int);
+    void (*myend)(int);
+    char *sh;
+
+    sh = md_getshell();
+
+    while((pid = fork()) < 0)
+        sleep(1);
+
+    if (pid == 0) /* Shell Process */
+    {
+        /*
+         * Set back to original user, just in case
+         */
+        md_normaluser();
+        execl(sh == NULL ? "/bin/sh" : sh, "shell", "-i", NULL);
+        perror("No shelly");
+        _exit(-1);
+    }
+    else /* Application */
+    {
+    	myend = signal(SIGINT, SIG_IGN);
+#ifdef SIGQUIT
+        myquit = signal(SIGQUIT, SIG_IGN);
+#endif  
+        while (wait(&ret_status) != pid)
+            continue;
+	    
+        signal(SIGINT, myquit);
+#ifdef SIGQUIT
+        signal(SIGQUIT, myend);
+#endif
+    }
+    return(ret_status);
+#elif defined(HAVE__SPAWNL) 
+    return((int)_spawnl(_P_WAIT,md_getshell(),"shell",NULL,0));
+#elif defined(HAVE_SPAWNL)
+    return ( spawnl(P_WAIT,md_getshell(),"shell",NULL,0) );
+#else
+	return(0);
+#endif
+}
+
+int
+directory_exists(char *dirname)
+{
+    struct stat sb;
+
+    if (stat(dirname, &sb) == 0) /* path exists */
+        return (sb.st_mode & S_IFDIR);
+
+    return(0);
+}
+
+char *
+md_getrealname(uid_t uid)
+{
+    static char uidstr[20];
+#if !defined(_WIN32) && !defined(DJGPP)
+    struct passwd *pp;
+
+	if ((pp = getpwuid(uid)) == NULL)
+    {
+        sprintf(uidstr,"%d", uid);
+        return(uidstr);
+    }
+	else
+	    return(pp->pw_name);
+#else
+   sprintf(uidstr,"%d", uid);
+   return(uidstr);
+#endif
+}
+
+char *
+md_getpass(char *prompt)
+{
+#ifndef HAVE_GETPASS
+    static char password_buffer[9];
+    char *p = password_buffer;
+    int c, count = 0;
+    int max_length = 9;
+
+    fflush(stdout);
+    /* If we can't prompt, abort */
+    if (fputs(prompt, stderr) < 0)
+    {
+        *p = '\0';
+        return NULL;
+    }
+
+    for(;;)
+    {
+        /* Get a character with no echo */
+        c = _getch();
+
+        /* Exit on interrupt (^c or ^break) */
+        if (c == '\003' || c == 0x100)
+            exit(1);
+
+        /* Terminate on end of line or file (^j, ^m, ^d, ^z) */
+        if (c == '\r' || c == '\n' || c == '\004' || c == '\032')
+            break;
+
+        /* Back up on backspace */
+        if (c == '\b')
+        {
+            if (count)
+                count--;
+            else if (p > password_buffer)
+                p--;
+            continue;
+        }
+
+        /* Ignore DOS extended characters */
+        if ((c & 0xff) != c)
+            continue;
+
+        /* Add to password if it isn't full */
+        if (p < password_buffer + max_length - 1)
+            *p++ = (char) c;
+        else
+            count++;
+    }
+   *p = '\0';
+
+   fputc('\n', stderr);
+
+   return password_buffer;
+#else
+   return( getpass(prompt) );
+#endif
+}
+
+int
+md_erasechar(void)
+{
+#ifdef HAVE_ERASECHAR
+    return( erasechar() ); /* process erase character */
+#elif defined(VERASE)
+    return(_tty.c_cc[VERASE]); /* process erase character */
+#else
+    return(_tty.sg_erase); /* process erase character */
+#endif
+}
+
+int
+md_killchar(void)
+{
+#ifdef HAVE_KILLCHAR
+    return( killchar() );
+#elif defined(VKILL)
+    return(_tty.c_cc[VKILL]);
+#else
+    return(_tty.sg_kill);
+#endif
+}
+
+int
+md_dsuspchar(void)
+{
+#if defined(VDSUSP)			/* POSIX has priority */
+    struct termios attr;
+    tcgetattr(STDIN_FILENO, &attr);
+    return( attr.c_cc[VDSUSP] );
+#elif defined(TIOCGLTC)
+    struct ltchars ltc;
+    ioctl(1, TIOCGLTC, &ltc);
+    return(ltc.t_dsuspc);
+#elif defined(_POSIX_VDISABLE)
+    return(_POSIX_VDISABLE);
+#else
+    return(0);
+#endif
+}
+
+int
+md_setdsuspchar(int c)
+{
+#if defined(VDSUSP)			/* POSIX has priority */
+    struct termios attr;
+    tcgetattr(STDIN_FILENO, &attr);
+    attr.c_cc[VDSUSP] = c;
+    tcgetattr(STDIN_FILENO, &attr);
+#elif defined(TIOCSLTC)
+    struct ltchars ltc;
+    ioctl(1, TIOCGLTC, &ltc);
+    ltc.t_dsuspc = c;
+    ioctl(1, TIOCSLTC, &ltc);
+#else
+    NOOP(c);
+#endif
+    return(0);
+}
+
+int
+md_suspchar(void)
+{
+#if defined(VSUSP)			/* POSIX has priority */
+    struct termios attr;
+    tcgetattr(STDIN_FILENO, &attr);
+    return( attr.c_cc[VSUSP] );
+#elif defined(TIOCGLTC)
+    struct ltchars ltc;
+    ioctl(1, TIOCGLTC, &ltc);
+    return(ltc.t_suspc);
+#elif defined(_POSIX_VDISABLE)
+    return(_POSIX_VDISABLE);
+#else
+    return(0);
+#endif
+}
+
+int
+md_setsuspchar(int c)
+{
+#if defined(VSUSP)			/* POSIX has priority */
+    struct termios attr;
+    tcgetattr(STDIN_FILENO, &attr);
+    attr.c_cc[VSUSP] = c;
+    tcgetattr(STDIN_FILENO, &attr);
+#elif defined(TIOCSLTC)
+    struct ltchars ltc;
+    ioctl(1, TIOCGLTC, &ltc);
+    ltc.t_suspc = c;
+    ioctl(1, TIOCSLTC, &ltc);
+#else
+    NOOP(c);
+#endif
+
+    return(0);
+}
+
+/*
+    Cursor/Keypad Support
+
+    Sadly Cursor/Keypad support is less straightforward than it should be.
+    
+    The various terminal emulators/consoles choose to differentiate the 
+    cursor and keypad keys (with modifiers) in different ways (if at all!). 
+    Furthermore they use different code set sequences for each key only
+    a subset of which the various curses libraries recognize. Partly due
+    to incomplete termcap/terminfo entries and partly due to inherent 
+    limitations of those terminal capability databases.
+
+    I give curses first crack at decoding the sequences. If it fails to decode
+    it we check for common ESC-prefixed sequences.
+
+    All cursor/keypad results are translated into standard rogue movement 
+    commands.
+
+    Unmodified keys are translated to walk commands: hjklyubn
+    Modified (shift,control,alt) are translated to run commands: HJKLYUBN
+
+    Console and supported (differentiated) keys
+    Interix:  Cursor Keys, Keypad, Ctl-Keypad
+    Cygwin:   Cursor Keys, Keypad, Alt-Cursor Keys
+    MSYS:     Cursor Keys, Keypad, Ctl-Cursor Keys, Ctl-Keypad
+    Win32:    Cursor Keys, Keypad, Ctl/Shift/Alt-Cursor Keys, Ctl/Alt-Keypad
+    DJGPP:    Cursor Keys, Keypad, Ctl/Shift/Alt-Cursor Keys, Ctl/Alt-Keypad
+
+    Interix Console (raw, ncurses)
+    ==============================
+    normal	shift		ctrl	    alt
+    ESC [D,	ESC F^,		ESC [D,	    ESC [D	    /# Left	    #/
+    ESC [C,	ESC F$,		ESC [C,	    ESC [C	    /# Right	    #/
+    ESC [A,	ESC F-,		local win,  ESC [A	    /# Up	    #/
+    ESC [B,	ESC F+,		local win,  ESC [B	    /# Down	    #/
+    ESC [H,	ESC [H,		ESC [H,	    ESC [H	    /# Home	    #/
+    ESC [S,	local win,	ESC [S,	    ESC [S	    /# Page Up	    #/
+    ESC [T,	local win,	ESC [T,	    ESC [T	    /# Page Down    #/
+    ESC [U,	ESC [U,		ESC [U,	    ESC [U	    /# End	    #/
+    ESC [D,	ESC F^,		ESC [D,	    O		    /# Keypad Left  #/
+    ESC [C,	ESC F$,		ESC [C,	    O		    /# Keypad Right #/
+    ESC [A,	ESC [A,		ESC [-1,    O		    /# Keypad Up    #/
+    ESC [B,	ESC [B,		ESC [-2,    O		    /# Keypad Down  #/
+    ESC [H,	ESC [H,		ESC [-263,  O		    /# Keypad Home  #/
+    ESC [S,	ESC [S,		ESC [-19,   O		    /# Keypad PgUp  #/
+    ESC [T,	ESC [T,		ESC [-20,   O		    /# Keypad PgDn  #/
+    ESC [U,	ESC [U,		ESC [-21,   O		    /# Keypad End   #/
+    nothing,	nothing,	nothing,    O		    /# Kaypad 5     #/
+
+    Interix Console (term=interix, ncurses)
+    ==============================
+    KEY_LEFT,	ESC F^,		KEY_LEFT,   KEY_LEFT	    /# Left	    #/
+    KEY_RIGHT,	ESC F$,		KEY_RIGHT,  KEY_RIGHT	    /# Right	    #/
+    KEY_UP,	0x146,		local win,  KEY_UP	    /# Up	    #/
+    KEY_DOWN,	0x145,		local win,  KEY_DOWN	    /# Down	    #/
+    ESC [H,	ESC [H,		ESC [H,	    ESC [H	    /# Home	    #/
+    KEY_PPAGE,	local win,	KEY_PPAGE,  KEY_PPAGE	    /# Page Up	    #/
+    KEY_NPAGE,	local win,	KEY_NPAGE,  KEY_NPAGE	    /# Page Down    #/
+    KEY_LL,	KEY_LL,		KEY_LL,	    KEY_LL	    /# End	    #/
+    KEY_LEFT,	ESC F^,		ESC [-4,    O		    /# Keypad Left  #/
+    KEY_RIGHT,	ESC F$,		ESC [-3,    O		    /# Keypad Right #/
+    KEY_UP,	KEY_UP,		ESC [-1,    O		    /# Keypad Up    #/
+    KEY_DOWN,	KEY_DOWN,	ESC [-2,    O		    /# Keypad Down  #/
+    ESC [H,	ESC [H,		ESC [-263,  O		    /# Keypad Home  #/
+    KEY_PPAGE,	KEY_PPAGE,	ESC [-19,   O		    /# Keypad PgUp  #/
+    KEY_NPAGE,	KEY_NPAGE,	ESC [-20,   O		    /# Keypad PgDn  #/
+    KEY_LL,	KEY_LL,		ESC [-21,   O		    /# Keypad End   #/
+    nothing,	nothing,	nothing,    O		    /# Keypad 5     #/
+
+    Cygwin Console (raw, ncurses)
+    ==============================
+    normal	shift		ctrl	    alt
+    ESC [D,	ESC [D,		ESC [D,	    ESC ESC [D	    /# Left	    #/
+    ESC [C,	ESC [C,		ESC [C,	    ESC ESC [C	    /# Rght	    #/
+    ESC [A,	ESC [A,		ESC [A,	    ESC ESC [A	    /# Up	    #/
+    ESC [B,	ESC [B,		ESC [B,	    ESC ESC [B	    /# Down	    #/
+    ESC [1~,	ESC [1~,	ESC [1~,    ESC ESC [1~	    /# Home	    #/
+    ESC [5~,	ESC [5~,	ESC [5~,    ESC ESC [5~	    /# Page Up	    #/
+    ESC [6~,	ESC [6~,	ESC [6~,    ESC ESC [6~	    /# Page Down    #/
+    ESC [4~,	ESC [4~,	ESC [4~,    ESC ESC [4~	    /# End	    #/
+    ESC [D,	ESC [D,		ESC [D,	    ESC ESC [D,O    /# Keypad Left  #/
+    ESC [C,	ESC [C,		ESC [C,	    ESC ESC [C,O    /# Keypad Right #/
+    ESC [A,	ESC [A,		ESC [A,	    ESC ESC [A,O    /# Keypad Up    #/
+    ESC [B,	ESC [B,		ESC [B,	    ESC ESC [B,O    /# Keypad Down  #/
+    ESC [1~,	ESC [1~,	ESC [1~,    ESC ESC [1~,O   /# Keypad Home  #/
+    ESC [5~,	ESC [5~,	ESC [5~,    ESC ESC [5~,O   /# Keypad PgUp  #/
+    ESC [6~,	ESC [6~,	ESC [6~,    ESC ESC [6~,O   /# Keypad PgDn  #/
+    ESC [4~,	ESC [4~,	ESC [4~,    ESC ESC [4~,O   /# Keypad End   #/
+    ESC [-71,	nothing,	nothing,    O	            /# Keypad 5	    #/
+
+    Cygwin Console (term=cygwin, ncurses)
+    ==============================
+    KEY_LEFT,	KEY_LEFT,	KEY_LEFT,   ESC-260	    /# Left	    #/
+    KEY_RIGHT,	KEY_RIGHT,	KEY_RIGHT,  ESC-261	    /# Rght	    #/
+    KEY_UP,	KEY_UP,		KEY_UP,	    ESC-259	    /# Up	    #/
+    KEY_DOWN,	KEY_DOWN,	KEY_DOWN,   ESC-258	    /# Down	    #/
+    KEY_HOME,	KEY_HOME,	KEY_HOME,   ESC-262	    /# Home	    #/
+    KEY_PPAGE,	KEY_PPAGE,	KEY_PPAGE,  ESC-339	    /# Page Up	    #/
+    KEY_NPAGE,	KEY_NPAGE,	KEY_NPAGE,  ESC-338	    /# Page Down    #/
+    KEY_END,	KEY_END,	KEY_END,    ESC-360	    /# End	    #/
+    KEY_LEFT,	KEY_LEFT,	KEY_LEFT,   ESC-260,O	    /# Keypad Left  #/
+    KEY_RIGHT,	KEY_RIGHT,	KEY_RIGHT,  ESC-261,O	    /# Keypad Right #/
+    KEY_UP,	KEY_UP,		KEY_UP,	    ESC-259,O       /# Keypad Up    #/
+    KEY_DOWN,	KEY_DOWN,	KEY_DOWN,   ESC-258,O       /# Keypad Down  #/
+    KEY_HOME,	KEY_HOME,	KEY_HOME,   ESC-262,O       /# Keypad Home  #/
+    KEY_PPAGE,	KEY_PPAGE,	KEY_PPAGE,  ESC-339,O	    /# Keypad PgUp  #/
+    KEY_NPAGE,	KEY_NPAGE,	KEY_NPAGE,  ESC-338,O	    /# Keypad PgDn  #/
+    KEY_END,	KEY_END,	KEY_END,    ESC-360,O       /# Keypad End   #/
+    ESC [G,	nothing,	nothing,    O	            /# Keypad 5	    #/
+
+    MSYS Console (raw, ncurses)
+    ==============================
+    normal	shift		ctrl	    alt
+    ESC OD,	ESC [d,		ESC Od	    nothing	    /# Left	    #/
+    ESC OE,	ESC [e,		ESC Oe,	    nothing	    /# Right	    #/
+    ESC OA,	ESC [a,		ESC Oa,	    nothing	    /# Up	    #/
+    ESC OB,	ESC [b,		ESC Ob,	    nothing	    /# Down	    #/
+    ESC [7~,	ESC [7$,	ESC [7^,    nothing	    /# Home	    #/
+    ESC [5~,	local window,   ESC [5^,    nothing	    /# Page Up      #/
+    ESC [6~,	local window,   ESC [6^,    nothing	    /# Page Down    #/
+    ESC [8~,	ESC [8$,	ESC [8^,    nothing	    /# End	    #/
+    ESC OD,	ESC [d,		ESC Od	    O		    /# Keypad Left  #/
+    ESC OE,	ESC [c,		ESC Oc,	    O		    /# Keypad Right #/
+    ESC OA,	ESC [a,		ESC Oa,	    O		    /# Keypad Up    #/
+    ESC OB,	ESC [b,		ESC Ob,	    O		    /# Keypad Down  #/
+    ESC [7~,	ESC [7$,	ESC [7^,    O		    /# Keypad Home  #/
+    ESC [5~,	local window,   ESC [5^,    O		    /# Keypad PgUp  #/
+    ESC [6~,	local window,   ESC [6^,    O		    /# Keypad PgDn  #/
+    ESC [8~,	ESC [8$,	ESC [8^,    O		    /# Keypad End   #/
+    11,		11,		11,	    O		    /# Keypad 5     #/
+
+    MSYS Console (term=rxvt, ncurses)
+    ==============================
+    normal	shift		ctrl	    alt
+    KEY_LEFT,	KEY_SLEFT,	514	    nothing	    /# Left	    #/
+    KEY_RIGHT,	KEY_SRIGHT,	516,	    nothing	    /# Right	    #/
+    KEY_UP,	518,		519,	    nothing	    /# Up	    #/
+    KEY_DOWN,	511,		512,	    nothing	    /# Down	    #/
+    KEY_HOME,	KEY_SHOME,	ESC [7^,    nothing	    /# Home	    #/
+    KEY_PPAGE,	local window,   ESC [5^,    nothing	    /# Page Up      #/
+    KEY_NPAGE,	local window,   ESC [6^,    nothing	    /# Page Down    #/
+    KEY_END,	KEY_SEND,	KEY_EOL,    nothing	    /# End	    #/
+    KEY_LEFT,	KEY_SLEFT,	514	    O		    /# Keypad Left  #/
+    KEY_RIGHT,	KEY_SRIGHT,	516,	    O		    /# Keypad Right #/
+    KEY_UP,	518,		519,	    O		    /# Keypad Up    #/
+    KEY_DOWN,	511,		512,	    O		    /# Keypad Down  #/
+    KEY_HOME,	KEY_SHOME,	ESC [7^,    O		    /# Keypad Home  #/
+    KEY_PPAGE,	local window,   ESC [5^,    O		    /# Keypad PgUp  #/
+    KEY_NPAGE,	local window,   ESC [6^,    O		    /# Keypad PgDn  #/
+    KEY_END,	KEY_SEND,	KEY_EOL,    O		    /# Keypad End   #/
+    11,		11,		11,	    O		    /# Keypad 5     #/
+
+    Win32 Console (raw, pdcurses)
+    DJGPP Console (raw, pdcurses)
+    ==============================
+    normal	shift		ctrl	    alt
+    260,	391,		443,	    493		    /# Left	    #/
+    261,	400,		444,	    492		    /# Right	    #/
+    259,	547,		480,	    490		    /# Up	    #/
+    258,	548,		481,	    491		    /# Down	    #/
+    262,	388,		447,	    524	    	    /# Home	    #/
+    339,	396,		445,	    526	    	    /# Page Up	    #/
+    338,	394,		446,	    520		    /# Page Down    #/
+    358,	384,		448,	    518	 	    /# End	    #/
+    452,	52('4'),	511,	    521		    /# Keypad Left  #/
+    454,	54('6'),	513,	    523		    /# Keypad Right #/
+    450,	56('8'),	515,	    525		    /# Keypad Up    #/
+    456,	50('2'),	509,	    519		    /# Keypad Down  #/
+    449,	55('7'),	514,	    524		    /# Keypad Home  #/
+    451,	57('9'),	516,	    526		    /# Keypad PgUp  #/
+    457,	51('3'),	510,	    520		    /# Keypad PgDn  #/
+    455,	49('1'),	508,	    518		    /# Keypad End   #/
+    453,	53('5'),	512,	    522		    /# Keypad 5     #/
+
+    Win32 Console (pdcurses, MSVC/MingW32)
+    DJGPP Console (pdcurses)
+    ==============================
+    normal	shift		ctrl	    alt
+    KEY_LEFT,	KEY_SLEFT,	CTL_LEFT,   ALT_LEFT	    /# Left	    #/
+    KEY_RIGHT,	KEY_SRIGHT,	CTL_RIGHT,  ALT_RIGHT	    /# Right	    #/
+    KEY_UP,	KEY_SUP,	CTL_UP,	    ALT_UP	    /# Up	    #/
+    KEY_DOWN,	KEY_SDOWN,	CTL_DOWN,   ALT_DOWN	    /# Down	    #/
+    KEY_HOME,	KEY_SHOME,	CTL_HOME,   ALT_HOME	    /# Home	    #/
+    KEY_PPAGE,	KEY_SPREVIOUS,  CTL_PGUP,   ALT_PGUP	    /# Page Up      #/
+    KEY_NPAGE,	KEY_SNEXTE,	CTL_PGDN,   ALT_PGDN	    /# Page Down    #/
+    KEY_END,	KEY_SEND,	CTL_END,    ALT_END	    /# End	    #/
+    KEY_B1,	52('4'),	CTL_PAD4,   ALT_PAD4	    /# Keypad Left  #/
+    KEY_B3,	54('6'),	CTL_PAD6,   ALT_PAD6	    /# Keypad Right #/
+    KEY_A2,	56('8'),	CTL_PAD8,   ALT_PAD8	    /# Keypad Up    #/
+    KEY_C2,	50('2'),	CTL_PAD2,   ALT_PAD2	    /# Keypad Down  #/
+    KEY_A1,	55('7'),	CTL_PAD7,   ALT_PAD7	    /# Keypad Home  #/
+    KEY_A3,	57('9'),	CTL_PAD9,   ALT_PAD9	    /# Keypad PgUp  #/
+    KEY_C3,	51('3'),	CTL_PAD3,   ALT_PAD3	    /# Keypad PgDn  #/
+    KEY_C1,	49('1'),	CTL_PAD1,   ALT_PAD1	    /# Keypad End   #/
+    KEY_B2,	53('5'),	CTL_PAD5,   ALT_PAD5	    /# Keypad 5     #/
+
+    Windows Telnet (raw)
+    ==============================
+    normal	shift		ctrl	    alt
+    ESC [D,	ESC [D,		ESC [D,	    ESC [D	    /# Left	    #/
+    ESC [C,	ESC [C,		ESC [C,	    ESC [C	    /# Right	    #/
+    ESC [A,	ESC [A,		ESC [A,	    ESC [A	    /# Up	    #/
+    ESC [B,	ESC [B,		ESC [B,	    ESC [B	    /# Down	    #/
+    ESC [1~,	ESC [1~,	ESC [1~,    ESC [1~	    /# Home	    #/
+    ESC [5~,	ESC [5~,	ESC [5~,    ESC [5~	    /# Page Up	    #/
+    ESC [6~,	ESC [6~,	ESC [6~,    ESC [6~	    /# Page Down    #/
+    ESC [4~,	ESC [4~,	ESC [4~,    ESC [4~	    /# End	    #/
+    ESC [D,	ESC [D,		ESC [D,	    ESC [D	    /# Keypad Left  #/
+    ESC [C,	ESC [C,		ESC [C,	    ESC [C	    /# Keypad Right #/
+    ESC [A,	ESC [A,		ESC [A,	    ESC [A	    /# Keypad Up    #/
+    ESC [B,	ESC [B,		ESC [B,	    ESC [B	    /# Keypad Down  #/
+    ESC [1~,	ESC [1~,	ESC [1~,    ESC [1~	    /# Keypad Home  #/
+    ESC [5~,	ESC [5~,	ESC [5~,    ESC [5~	    /# Keypad PgUp  #/
+    ESC [6~,	ESC [6~,	ESC [6~,    ESC [6~	    /# Keypad PgDn  #/
+    ESC [4~,	ESC [4~,	ESC [4~,    ESC [4~	    /# Keypad End   #/
+    nothing,	nothing,	nothing,    nothing	    /# Keypad 5     #/
+
+    Windows Telnet (term=xterm)
+    ==============================
+    normal	shift		ctrl	    alt
+    KEY_LEFT,	KEY_LEFT,	KEY_LEFT,   KEY_LEFT	    /# Left	    #/
+    KEY_RIGHT,	KEY_RIGHT,	KEY_RIGHT,  KEY_RIGHT	    /# Right	    #/
+    KEY_UP,	KEY_UP,		KEY_UP,	    KEY_UP	    /# Up	    #/
+    KEY_DOWN,	KEY_DOWN,	KEY_DOWN,   KEY_DOWN	    /# Down	    #/
+    ESC [1~,	ESC [1~,	ESC [1~,    ESC [1~	    /# Home	    #/
+    KEY_PPAGE,	KEY_PPAGE,	KEY_PPAGE,  KEY_PPAGE	    /# Page Up	    #/
+    KEY_NPAGE,	KEY_NPAGE,	KEY_NPAGE,  KEY_NPAGE	    /# Page Down    #/
+    ESC [4~,	ESC [4~,	ESC [4~,    ESC [4~	    /# End	    #/
+    KEY_LEFT,	KEY_LEFT,	KEY_LEFT,   O		    /# Keypad Left  #/
+    KEY_RIGHT,	KEY_RIGHT,	KEY_RIGHT,  O		    /# Keypad Right #/
+    KEY_UP,	KEY_UP,		KEY_UP,	    O		    /# Keypad Up    #/
+    KEY_DOWN,	KEY_DOWN,	KEY_DOWN,   O		    /# Keypad Down  #/
+    ESC [1~,	ESC [1~,	ESC [1~,    ESC [1~	    /# Keypad Home  #/
+    KEY_PPAGE,	KEY_PPAGE,	KEY_PPAGE,  KEY_PPAGE	    /# Keypad PgUp  #/
+    KEY_NPAGE,	KEY_NPAGE,	KEY_NPAGE,  KEY_NPAGE	    /# Keypad PgDn  #/
+    ESC [4~,	ESC [4~,	ESC [4~,    O		    /# Keypad End   #/
+    ESC [-71,	nothing,	nothing,    O	            /# Keypad 5	    #/
+
+    PuTTY
+    ==============================
+    normal	shift		ctrl	    alt
+    ESC [D,	ESC [D,		ESC OD,	    ESC [D	    /# Left	    #/
+    ESC [C,	ESC [C,		ESC OC,	    ESC [C	    /# Right	    #/
+    ESC [A,	ESC [A,		ESC OA,	    ESC [A	    /# Up	    #/
+    ESC [B,	ESC [B,		ESC OB,	    ESC [B	    /# Down	    #/
+    ESC [1~,	ESC [1~,	local win,  ESC [1~	    /# Home	    #/
+    ESC [5~,	local win,	local win,  ESC [5~	    /# Page Up	    #/
+    ESC [6~,	local win,	local win,  ESC [6~	    /# Page Down    #/
+    ESC [4~,	ESC [4~,	local win,  ESC [4~	    /# End	    #/
+    ESC [D,	ESC [D,		ESC [D,	    O		    /# Keypad Left  #/
+    ESC [C,	ESC [C,		ESC [C,	    O		    /# Keypad Right #/
+    ESC [A,	ESC [A,		ESC [A,	    O		    /# Keypad Up    #/
+    ESC [B,	ESC [B,		ESC [B,	    O		    /# Keypad Down  #/
+    ESC [1~,	ESC [1~,	ESC [1~,    O		    /# Keypad Home  #/
+    ESC [5~,	ESC [5~,	ESC [5~,    O		    /# Keypad PgUp  #/
+    ESC [6~,	ESC [6~,	ESC [6~,    O		    /# Keypad PgDn  #/
+    ESC [4~,	ESC [4~,	ESC [4~,    O		    /# Keypad End   #/
+    nothing,	nothing,	nothing,    O		    /# Keypad 5	    #/
+
+    PuTTY
+    ==============================
+    normal	shift		ctrl	    alt
+    KEY_LEFT,	KEY_LEFT,	ESC OD,	    ESC KEY_LEFT    /# Left	    #/
+    KEY_RIGHT	KEY_RIGHT,	ESC OC,	    ESC KEY_RIGHT   /# Right	    #/
+    KEY_UP,	KEY_UP,		ESC OA,	    ESC KEY_UP	    /# Up	    #/
+    KEY_DOWN,	KEY_DOWN,	ESC OB,	    ESC KEY_DOWN    /# Down	    #/
+    ESC [1~,	ESC [1~,	local win,  ESC ESC [1~	    /# Home	    #/
+    KEY_PPAGE	local win,	local win,  ESC KEY_PPAGE   /# Page Up	    #/
+    KEY_NPAGE	local win,	local win,  ESC KEY_NPAGE   /# Page Down    #/
+    ESC [4~,	ESC [4~,	local win,  ESC ESC [4~	    /# End	    #/
+    ESC Ot,	ESC Ot,		ESC Ot,	    O		    /# Keypad Left  #/
+    ESC Ov,	ESC Ov,		ESC Ov,	    O		    /# Keypad Right #/
+    ESC Ox,	ESC Ox,		ESC Ox,	    O		    /# Keypad Up    #/
+    ESC Or,	ESC Or,		ESC Or,	    O		    /# Keypad Down  #/
+    ESC Ow,	ESC Ow,		ESC Ow,     O		    /# Keypad Home  #/
+    ESC Oy,	ESC Oy,		ESC Oy,     O		    /# Keypad PgUp  #/
+    ESC Os,	ESC Os,		ESC Os,     O		    /# Keypad PgDn  #/
+    ESC Oq,	ESC Oq,		ESC Oq,     O		    /# Keypad End   #/
+    ESC Ou,	ESC Ou,		ESC Ou,	    O		    /# Keypad 5	    #/
+*/
+
+#define M_NORMAL 0
+#define M_ESC    1
+#define M_KEYPAD 2
+#define M_TRAIL  3
+
+#ifndef CTRL
+#define CTRL(ch) (ch & 0x1F)
+#endif
+
+int undo[5];
+int uindex = -1;
+
+int
+reread()
+{
+    int redo;
+
+    if (uindex < 0)
+        return 0;
+
+    redo = undo[0];
+    undo[0] = undo[1];
+    undo[1] = undo[2];
+    undo[2] = undo[3];
+    undo[3] = undo[4];
+    uindex--;
+    return redo;
+}
+
+void
+unread(int c)
+{
+    if (uindex >= 4)
+        abort();
+
+    undo[++uindex] = c;
+}
+
+int
+md_readchar(WINDOW *win)
+{
+    int ch = 0;
+    int lastch = 0;
+    int wch = 0;
+    int mode = M_NORMAL;
+    int mode2 = M_NORMAL;
+    int nodelayf = 0;
+    int count = 0;
+
+    for(;;)
+    {
+        if (mode == M_NORMAL && uindex >= 0)
+        {
+	    wch = ch = reread();
+	    break;
+	}
+
+	wch = ch = wgetch(win);
+
+	if (ch == ERR) /* timed out  or error */
+	{
+	    if (nodelayf)               /* likely timed out, switch to */
+	    {                           /* normal mode and block on    */
+	        mode = M_NORMAL;        /* next read                   */
+	    	nodelayf = 0;
+		nodelay(win,0);
+	    }
+	    else if (count > 10)        /* after 10 errors assume      */
+	        auto_save(0);           /* input stream is broken and  */
+	    else                        /* auto save and exit          */
+	    	count++;
+
+	    continue;
+	}
+
+        count = 0;			/* reset input error count     */
+
+	if (mode == M_TRAIL)
+	{
+	    if (ch == '^')		/* msys console  : 7,5,6,8: modified*/
+		ch = CTRL( toupper(lastch) );
+	    else if (ch == '~')		/* cygwin console: 1,5,6,4: normal  */
+		ch = tolower(lastch);   /* windows telnet: 1,5,6,4: normal  */
+					/* msys console  : 7,5,6,8: normal  */
+	    else if (mode2 == M_ESC)		/* cygwin console: 1,5,6,4: modified*/
+		ch = CTRL( toupper(ch) );
+            else
+            {
+                mode = M_NORMAL;
+                unread(ch);
+                continue;
+            }
+
+	    break;
+	}
+
+	if (mode == M_ESC) 
+	{
+	    if (ch == 27)
+	    {
+		mode2 = M_ESC;
+		unread(ch);
+		continue;
+	    }
+
+	    if ((ch == 'F') || (ch == 'O') || (ch == '['))
+	    {
+		mode = M_KEYPAD;
+		unread(ch);
+		continue;
+	    }
+
+
+	    switch(ch)
+	    {
+		/* Cygwin Console   */
+		/* PuTTY	    */
+		case KEY_LEFT :	ch = CTRL('H'); break;
+		case KEY_RIGHT: ch = CTRL('L'); break;
+		case KEY_UP   : ch = CTRL('K'); break;
+		case KEY_DOWN : ch = CTRL('J'); break;
+		case KEY_HOME : ch = CTRL('Y'); break;
+		case KEY_PPAGE: ch = CTRL('U'); break;
+		case KEY_NPAGE: ch = CTRL('N'); break;
+		case KEY_END  : ch = CTRL('B'); break;
+
+	        default: mode = M_NORMAL;
+                         mode2 = M_NORMAL;
+                         unread(ch);
+                         continue;}
+
+	    break;
+	}
+
+	if (mode == M_KEYPAD)
+	{
+	    switch(ch)
+	    {
+		/* ESC F - Interix Console codes */
+		case   '^': ch = CTRL('H'); break;	/* Shift-Left	    */
+		case   '$': ch = CTRL('L'); break;	/* Shift-Right	    */
+
+		/* ESC [ - Interix Console codes */
+		case   'H': ch = 'y'; break;		/* Home		    */
+		case     1: ch = CTRL('K'); break;	/* Ctl-Keypad Up    */
+		case     2: ch = CTRL('J'); break;	/* Ctl-Keypad Down  */
+		case     3: ch = CTRL('L'); break;	/* Ctl-Keypad Right */
+		case     4: ch = CTRL('H'); break;	/* Ctl-Keypad Left  */
+		case   263: ch = CTRL('Y'); break;	/* Ctl-Keypad Home  */
+		case    19: ch = CTRL('U'); break;	/* Ctl-Keypad PgUp  */
+		case    20: ch = CTRL('N'); break;	/* Ctl-Keypad PgDn  */
+		case    21: ch = CTRL('B'); break;	/* Ctl-Keypad End   */
+
+		/* ESC [ - Cygwin Console codes */
+		case   'G': ch = '.'; break;		/* Keypad 5	    */
+		case   '7': lastch = 'Y'; mode=M_TRAIL; break;	/* Ctl-Home */
+		case   '5': lastch = 'U'; mode=M_TRAIL; break;	/* Ctl-PgUp */
+		case   '6': lastch = 'N'; mode=M_TRAIL; break;	/* Ctl-PgDn */
+
+		/* ESC [ - Win32 Telnet, PuTTY */
+		case   '1': lastch = 'y'; mode=M_TRAIL; break;	/* Home	    */
+		case   '4': lastch = 'b'; mode=M_TRAIL; break;	/* End	    */
+
+		/* ESC O - PuTTY */
+		case   'D': ch = CTRL('H'); break;
+		case   'C': ch = CTRL('L'); break;
+		case   'A': ch = CTRL('K'); break;
+		case   'B': ch = CTRL('J'); break;
+		case   't': ch = 'h'; break;
+		case   'v': ch = 'l'; break;
+		case   'x': ch = 'k'; break;
+		case   'r': ch = 'j'; break;
+		case   'w': ch = 'y'; break;
+		case   'y': ch = 'u'; break;
+		case   's': ch = 'n'; break;
+		case   'q': ch = 'b'; break;
+		case   'u': ch = '.'; break;
+	    }
+
+	    if (mode != M_KEYPAD)
+	    {
+		unread(ch);
+		continue;
+	    }
+	}
+
+	if (ch == 27)
+	{
+	    nodelay(win,1);
+	    mode = M_ESC;
+	    nodelayf = 1;
+	    unread(ch);
+	    continue;
+	}
+
+	switch(ch)
+	{
+	    case KEY_LEFT   : ch = 'h'; break;
+	    case KEY_DOWN   : ch = 'j'; break;
+	    case KEY_UP     : ch = 'k'; break;
+	    case KEY_RIGHT  : ch = 'l'; break;
+	    case KEY_HOME   : ch = 'y'; break;
+	    case KEY_PPAGE  : ch = 'u'; break;
+	    case KEY_END    : ch = 'b'; break;
+#ifdef KEY_LL
+	    case KEY_LL	    : ch = 'b'; break;
+#endif
+	    case KEY_NPAGE  : ch = 'n'; break;
+
+#ifdef KEY_B1
+	    case KEY_B1	    : ch = 'h'; break;
+	    case KEY_C2     : ch = 'j'; break;
+	    case KEY_A2     : ch = 'k'; break;
+	    case KEY_B3	    : ch = 'l'; break;
+#endif
+	    case KEY_A1     : ch = 'y'; break;
+	    case KEY_A3     : ch = 'u'; break;
+	    case KEY_C1     : ch = 'b'; break;
+	    case KEY_C3     : ch = 'n'; break;
+            /* next should be '.', but for problem with putty/linux */
+	    case KEY_B2	    : ch = 'u'; break;
+
+#ifdef KEY_SLEFT
+	    case KEY_SRIGHT  : ch = CTRL('L'); break;
+	    case KEY_SLEFT   : ch = CTRL('H'); break;
+#ifdef KEY_SUP
+	    case KEY_SUP     : ch = CTRL('K'); break;
+	    case KEY_SDOWN   : ch = CTRL('J'); break;
+#endif
+	    case KEY_SHOME   : ch = CTRL('Y'); break;
+	    case KEY_SPREVIOUS:ch = CTRL('U'); break;
+	    case KEY_SEND    : ch = CTRL('B'); break;
+	    case KEY_SNEXT   : ch = CTRL('N'); break;
+#endif
+	    case 0x146       : ch = CTRL('K'); break; 	/* Shift-Up	*/
+	    case 0x145       : ch = CTRL('J'); break; 	/* Shift-Down	*/
+
+#ifdef CTL_RIGHT
+	    case CTL_RIGHT   : ch = CTRL('L'); break;
+	    case CTL_LEFT    : ch = CTRL('H'); break;
+	    case CTL_UP      : ch = CTRL('K'); break;
+	    case CTL_DOWN    : ch = CTRL('J'); break;
+	    case CTL_HOME    : ch = CTRL('Y'); break;
+	    case CTL_PGUP    : ch = CTRL('U'); break;
+	    case CTL_END     : ch = CTRL('B'); break;
+	    case CTL_PGDN    : ch = CTRL('N'); break;
+#endif
+#ifdef KEY_EOL
+	    case KEY_EOL     : ch = CTRL('B'); break;
+#endif
+
+#ifndef CTL_PAD1
+	    /* MSYS rxvt console */
+	    case 511	     : ch = CTRL('J'); break; /* Shift Dn */
+	    case 512         : ch = CTRL('J'); break; /* Ctl Down */
+	    case 514	     : ch = CTRL('H'); break; /* Ctl Left */
+	    case 516	     : ch = CTRL('L'); break; /* Ctl Right*/
+	    case 518	     : ch = CTRL('K'); break; /* Shift Up */
+	    case 519	     : ch = CTRL('K'); break; /* Ctl Up   */
+#endif
+
+#ifdef CTL_PAD1
+	    case CTL_PAD1   : ch = CTRL('B'); break;
+	    case CTL_PAD2   : ch = CTRL('J'); break;
+	    case CTL_PAD3   : ch = CTRL('N'); break;
+	    case CTL_PAD4   : ch = CTRL('H'); break;
+	    case CTL_PAD5   : ch = '.'; break;
+	    case CTL_PAD6   : ch = CTRL('L'); break;
+	    case CTL_PAD7   : ch = CTRL('Y'); break;
+	    case CTL_PAD8   : ch = CTRL('K'); break;
+	    case CTL_PAD9   : ch = CTRL('U'); break;
+#endif
+
+#ifdef ALT_RIGHT
+	    case ALT_RIGHT  : ch = CTRL('L'); break;
+	    case ALT_LEFT   : ch = CTRL('H'); break;
+	    case ALT_DOWN   : ch = CTRL('J'); break;
+	    case ALT_HOME   : ch = CTRL('Y'); break;
+	    case ALT_PGUP   : ch = CTRL('U'); break;
+	    case ALT_END    : ch = CTRL('B'); break;
+	    case ALT_PGDN   : ch = CTRL('N'); break;
+#endif
+
+#ifdef ALT_PAD1
+	    case ALT_PAD1   : ch = CTRL('B'); break;
+	    case ALT_PAD2   : ch = CTRL('J'); break;
+	    case ALT_PAD3   : ch = CTRL('N'); break;
+	    case ALT_PAD4   : ch = CTRL('H'); break;
+	    case ALT_PAD5   : ch = '.'; break;
+	    case ALT_PAD6   : ch = CTRL('L'); break;
+	    case ALT_PAD7   : ch = CTRL('Y'); break;
+	    case ALT_PAD8   : ch = CTRL('K'); break;
+	    case ALT_PAD9   : ch = CTRL('U'); break;
+#endif
+#ifdef KEY_BACKSPACE /* NCURSES in Keypad mode sends this for Ctrl-H */
+            case KEY_BACKSPACE: ch = CTRL('H'); break;
+#endif
+	}
+
+	break;
+    }
+
+
+    if (nodelayf)
+        nodelay(win,0);
+
+    uindex = -1;
+
+    if (!pass_ctrl_keypad && (ch != wch))
+        switch(ch) 
+        {
+	    case CTRL('H'):
+	    case CTRL('L'):
+	    case CTRL('K'):
+	    case CTRL('J'):
+	    case CTRL('Y'):
+	    case CTRL('U'):
+	    case CTRL('N'):
+	    case CTRL('B'):
+                return(ch + 0x40);
+        }
+
+    return(ch & 0x7F);
+}
+
+#if defined(LOADAV) && defined(HAVE_NLIST_H) && defined(HAVE_NLIST)
+/*
+ * loadav:
+ *	Looking up load average in core (for system where the loadav()
+ *	system call isn't defined
+ */
+
+#include <nlist.h>
+
+struct nlist avenrun = {
+    "_avenrun"
+};
+
+int
+md_loadav(double *avg)
+{
+    int kmem;
+
+    if ((kmem = open("/dev/kmem", 0)) < 0)
+	goto bad;
+    nlist(NAMELIST, &avenrun);
+    if (avenrun.n_type == 0)
+    {
+	close(kmem);
+bad:
+	avg[0] = 0.0;
+	avg[1] = 0.0;
+	avg[2] = 0.0;
+	return -1;
+    }
+
+    lseek(kmem, avenrun.n_value, 0);
+    read(kmem, (char *) avg, 3 * sizeof (double));
+    close(kmem);
+    return 0;
+}
+#else
+int
+md_loadav(double *avg)
+{
+#if defined(HAVE_LOADAV)
+    loadav(avg);
+    return(0);
+#elif defined(HAVE_GETLOADAVG)
+    int ret;
+    ret = getloadavg(avg,3);
+    return (ret == 3) ? 0 : -1;
+#else
+    avg[0] = avg[1] = avg[2] = 0;
+    return(-1);
+#endif
+}
+#endif
+
+#ifndef NSIG
+#define NSIG 32
+#endif
+
+void
+md_ignoreallsignals(void)
+{
+	int i;
+
+	for (i = 0; i < NSIG; i++)
+		signal(i, SIG_IGN);
+}
+
+void
+md_tstphold(void)
+{
+#ifdef SIGTSTP
+    /*
+     * If a process can be suspended, this code wouldn't work
+     */
+# ifdef SIG_HOLD
+    signal(SIGTSTP, SIG_HOLD);
+# else
+    signal(SIGTSTP, SIG_IGN);
+# endif
+#endif
+}
+
+void
+md_tstpresume(void (*tstp)(int))
+{
+#ifdef SIGTSTP
+    signal(SIGTSTP, tstp);
+#endif
+}
+
+void
+md_tstpsignal(void)
+{
+#ifdef SIGTSTP
+    kill(0, SIGTSTP);		/* send actual signal and suspend process */
+#endif
+}
+
+#if defined(CHECKTIME)
+void
+md_start_checkout_timer(int time)
+{
+    int  checkout();
+
+#if defined(HAVE_ALARM) && defined(SIGALRM)
+    signal(SIGALRM, checkout);
+	alarm(time);
+#endif
+}
+
+void
+md_stop_checkout_timer(void)
+{
+#if defined(SIGALRM)
+    signal(SIGALRM, SIG_IGN);
+#endif
+}
+#endif
+
+long
+md_memused()
+{
+#ifdef _WIN32
+    MEMORYSTATUS stat;
+
+    GlobalMemoryStatus(&stat);
+
+    return((long)stat.dwTotalPageFile);
+#else
+    return( (long)sbrk(0) );
+#endif
+}
+
+int
+md_ucount()
+{
+#if defined(HAVE_UTMPX_H)
+    struct utmpx *up=NULL;
+    int count=0;
+
+    setutxent();
+    do
+    {
+        up = getutxent();
+        if (up && up->ut_type == USER_PROCESS)
+            count++;
+    } while(up != NULL);
+
+   endutxent();
+
+   return(count);
+#else
+   return(1)
+#endif
+}
+
+int
+md_lockfile(FILE *fp)
+{
+    int fd;
+    int ret;
+
+    fflush(fp);
+    rewind(fp);
+
+#ifdef _WIN32
+    fd = _fileno(fp);
+    ret = _locking(fd,_LK_LOCK,1);
+#else
+    fd = fileno(fp);
+
+    while((ret = lockf(fd, F_LOCK, 1)) == -1)
+	if (errno != EINTR)
+            break;
+#endif
+
+    return ret;
+}
+
+int
+md_unlockfile(FILE *fp)
+{
+    int fd;
+    int ret;
+
+    fflush(fp);
+    rewind(fp);
+
+
+#ifdef _WIN32
+    fd = _fileno(fp);
+    ret = _locking(fd,_LK_UNLCK,1);
+#else
+    fd = fileno(fp);
+    
+    while( (ret = lockf(fd, F_ULOCK, 1)) == -1)
+        if (errno != EINTR)
+            break;
+#endif
+
+    return ret;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rogue3/mdport.h	Tue Oct 13 13:33:34 2009 +0000
@@ -0,0 +1,193 @@
+/*
+    mdport.h - Machine Dependent Code for Porting Unix/Curses games
+
+    Copyright (C) 2008 Nicholas J. Kisseberth
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+    3. Neither the name(s) of the author(s) nor the names of other contributors
+       may be used to endorse or promote products derived from this software
+       without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS ``AS IS'' AND
+    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+    ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+    OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+    SUCH DAMAGE.
+*/
+
+#ifdef HAVE_CONFIG_H
+#ifdef PDCURSES
+#undef HAVE_UNISTD_H
+#undef HAVE_LIMITS_H
+#undef HAVE_MEMORY_H
+#undef HAVE_STRING_H
+#endif
+#include "config.h"
+
+#elif defined(__DJGPP__)
+#define HAVE_SYS_TYPES_H 1
+#define HAVE_PROCESS_H 1
+#define HAVE_PWD_H 1
+#define HAVE_TERMIOS_H 1
+#define HAVE_SETGID 1
+#define HAVE_GETGID 1
+#define HAVE_SETUID 1
+#define HAVE_GETUID 1
+#define HAVE_GETPASS 1
+#define HAVE_SPAWNL 1
+#define HAVE_ALARM 1
+#define HAVE_ERASECHAR 1
+#define HAVE_KILLCHAR 1
+#define HAVE_CRYPT
+
+#elif defined(_WIN32)
+#define HAVE_CURSES_H
+#define HAVE_TERM_H
+#define HAVE__SPAWNL
+#define HAVE_SYS_TYPES_H
+#define HAVE_PROCESS_H
+#define HAVE_ERASECHAR 1
+#define HAVE_KILLCHAR 1
+#ifndef uid_t
+typedef unsigned int uid_t;
+#endif
+#ifndef pid_t
+typedef unsigned int pid_t;
+#endif
+
+#elif defined(__CYGWIN__)
+#define HAVE_SYS_TYPES_H 1
+#define HAVE_PWD_H 1
+#define HAVE_PWD_H 1
+#define HAVE_SYS_UTSNAME_H 1
+#define HAVE_ARPA_INET_H 1
+#define HAVE_UNISTD_H 1
+#define HAVE_TERMIOS_H 1
+#define HAVE_NCURSES_TERM_H 1
+#define HAVE_ESCDELAY
+#define HAVE_SETGID 1
+#define HAVE_GETGID 1
+#define HAVE_SETUID 1
+#define HAVE_GETUID 1
+#define HAVE_GETPASS 1
+#define HAVE_GETPWUID 1
+#define HAVE_WORKING_FORK 1
+#define HAVE_ALARM 1
+#define HAVE_SPAWNL 1
+#define HAVE__SPAWNL 1
+#define HAVE_ERASECHAR 1
+#define HAVE_KILLCHAR 1
+#define HAVE_CRYPT 1
+
+#else /* standards based unix */
+#define HAVE_SYS_TYPES_H 1
+#define HAVE_PWD_H 1
+#define HAVE_SYS_UTSNAME_H 1
+#define HAVE_ARPA_INET_H 1
+#define HAVE_UNISTD_H 1
+#define HAVE_CRYPT_H 1
+#define HAVE_LIMITS_H 1
+#define HAVE_TERMIOS_H 1
+#define HAVE_UTMPX_H 1
+#define HAVE_ERRNO_H 1
+#define HAVE_TERM_H 1
+#define HAVE_SETGID 1
+#define HAVE_GETGID 1
+#define HAVE_SETUID 1
+#define HAVE_GETUID 1
+#define HAVE_SETREUID 1
+#define HAVE_SETREGID 1
+#define HAVE_CRYPT 1
+#define HAVE_GETPASS 1
+#define HAVE_GETPWUID 1
+#define HAVE_WORKING_FORK 1
+#define HAVE_ERASECHAR 1
+#define HAVE_KILLCHAR 1
+#ifndef _AIX
+#define HAVE_GETLOADAVG 1
+#endif
+#define HAVE_ALARM 1
+#endif
+
+#ifdef __DJGPP__
+#undef HAVE_GETPWUID /* DJGPP's limited version doesn't even work as documented */
+#endif
+
+#define MD_STRIP_CTRL_KEYPAD 1
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+
+#if !defined(PATH_MAX) && defined(_MAX_PATH)
+#define PATH_MAX _MAX_PATH
+#endif
+
+#if !defined(PATH_MAX) && defined(_PATH_MAX)
+#define PATH_MAX _PATH_MAX
+#endif
+
+#ifndef HAVE_CRYPT
+char *	crypt(const char *key, const char *setting);
+#else
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_CRYPT_H
+#include <crypt.h>
+#endif
+#endif
+
+int	md_chmod(const char *filename, int mode);
+int	md_dsuspchar(void);
+int	md_erasechar(void);
+char *	md_gethomedir(void);
+char *	md_getusername(void);
+uid_t	md_getuid(void);
+char *	md_getpass(char *prompt);
+pid_t	md_getpid(void);
+char *	md_getrealname(uid_t uid);
+void	md_init(int options);
+int	md_killchar(void);
+void	md_normaluser(void);
+void	md_raw_standout(void);
+void	md_raw_standend(void);
+int	md_readchar(WINDOW *win);
+int	md_setdsuspchar(int c);
+int	md_shellescape(void);
+void	md_sleep(int s);
+int	md_suspchar(void);
+int	md_hasclreol(void);
+int	md_unlink(char *file);
+int	md_unlink_open_file(const char *file, FILE *inf);
+void	md_tstpsignal(void);
+void	md_tstphold(void);
+void	md_tstpresume(void (*tstp)(int));
+void	md_ignoreallsignals(void);
+void	md_onsignal_autosave(void);
+void	md_onsignal_exit(void);
+void	md_onsignal_default(void);
+int	md_issymlink(char *sp);
+int     md_loadav(double *avg);
+long    md_memused(void);
+int     md_ucount(void);
+int     md_unlockfile(FILE *fp);
+int     md_lockfile(FILE *fp);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rogue3/misc.c	Tue Oct 13 13:33:34 2009 +0000
@@ -0,0 +1,431 @@
+/*
+ * all sorts of miscellaneous routines
+ *
+ * @(#)misc.c	3.13 (Berkeley) 6/15/81
+ *
+ * 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 "curses.h"
+#include "rogue.h"
+#include <ctype.h>
+
+/*
+ * tr_name:
+ *	print the name of a trap
+ */
+
+char *
+tr_name(int ch)
+{
+    char *s = "";
+
+    switch (ch)
+    {
+	case TRAPDOOR:
+	    s = terse ? "A trapdoor." : "You found a trapdoor.";
+	when BEARTRAP:
+	    s = terse ? "A beartrap." : "You found a beartrap.";
+	when SLEEPTRAP:
+	    s = terse ? "A sleeping gas trap.":"You found a sleeping gas trap.";
+	when ARROWTRAP:
+	    s = terse ? "An arrow trap." : "You found an arrow trap.";
+	when TELTRAP:
+	    s = terse ? "A teleport trap." : "You found a teleport trap.";
+	when DARTTRAP:
+	    s = terse ? "A dart trap." : "You found a poison dart trap.";
+    }
+    return s;
+}
+
+/*
+ * Look:
+ *	A quick glance all around the player
+ */
+
+void
+look(int wakeup)
+{
+    int x, y;
+    int ch;
+    int oldx, oldy;
+    int inpass;
+    int passcount = 0;
+    struct room *rp;
+    int ey, ex;
+
+    getyx(cw, oldy, oldx);
+    if (oldrp != NULL && (oldrp->r_flags & ISDARK) && off(player, ISBLIND))
+    {
+	for (x = oldpos.x - 1; x <= oldpos.x + 1; x++)
+	    for (y = oldpos.y - 1; y <= oldpos.y + 1; y++)
+		if ((y != hero.y || x != hero.x) && show(y, x) == FLOOR)
+		    mvwaddch(cw, y, x, ' ');
+    }
+    inpass = ((rp = roomin(&hero)) == NULL);
+    ey = hero.y + 1;
+    ex = hero.x + 1;
+    for (x = hero.x - 1; x <= ex; x++)
+	if (x >= 0 && x < COLS) for (y = hero.y - 1; y <= ey; y++)
+	{
+	    if (y <= 0 || y >= LINES - 1)
+		continue;
+	    if (isupper(mvwinch(mw, y, x)))
+	    {
+		struct linked_list *it;
+		struct thing *tp;
+
+		if (wakeup)
+		    it = wake_monster(y, x);
+		else
+		    it = find_mons(y, x);
+		tp = (struct thing *) ldata(it);
+		if ((tp->t_oldch = mvinch(y, x)) == TRAP)
+		    tp->t_oldch =
+			(trap_at(y,x)->tr_flags&ISFOUND) ? TRAP : FLOOR;
+		if (tp->t_oldch == FLOOR && (rp != NULL) && (rp->r_flags & ISDARK)
+		    && off(player, ISBLIND))
+			tp->t_oldch = ' ';
+	    }
+	    /*
+	     * Secret doors show as walls
+	     */
+	    if ((ch = show(y, x)) == SECRETDOOR)
+		ch = secretdoor(y, x);
+	    /*
+	     * Don't show room walls if he is in a passage
+	     */
+	    if (off(player, ISBLIND))
+	    {
+		if (y == hero.y && x == hero.x
+		 || (inpass && (ch == '-' || ch == '|')))
+			continue;
+	    }
+	    else if (y != hero.y || x != hero.x)
+		continue;
+	    wmove(cw, y, x);
+	    waddch(cw, ch);
+	    if (door_stop && !firstmove && running)
+	    {
+		switch (runch)
+		{
+		    case 'h':
+			if (x == ex)
+			    continue;
+		    when 'j':
+			if (y == hero.y - 1)
+			    continue;
+		    when 'k':
+			if (y == ey)
+			    continue;
+		    when 'l':
+			if (x == hero.x - 1)
+			    continue;
+		    when 'y':
+			if ((x + y) - (hero.x + hero.y) >= 1)
+			    continue;
+		    when 'u':
+			if ((y - x) - (hero.y - hero.x) >= 1)
+			    continue;
+		    when 'n':
+			if ((x + y) - (hero.x + hero.y) <= -1)
+			    continue;
+		    when 'b':
+			if ((y - x) - (hero.y - hero.x) <= -1)
+			    continue;
+		}
+		switch (ch)
+		{
+		    case DOOR:
+			if (x == hero.x || y == hero.y)
+			    running = FALSE;
+			break;
+		    case PASSAGE:
+			if (x == hero.x || y == hero.y)
+			    passcount++;
+			break;
+		    case FLOOR:
+		    case '|':
+		    case '-':
+		    case ' ':
+			break;
+		    default:
+			running = FALSE;
+			break;
+		}
+	    }
+	}
+    if (door_stop && !firstmove && passcount > 1)
+	running = FALSE;
+    mvwaddch(cw, hero.y, hero.x, PLAYER);
+    wmove(cw, oldy, oldx);
+    oldpos = hero;
+    oldrp = rp;
+}
+
+/*
+ * secret_door:
+ *	Figure out what a secret door looks like.
+ */
+
+int
+secretdoor(int y, int x)
+{
+    int i;
+    struct room *rp;
+    coord *cpp;
+    static coord cp;
+
+    cp.y = y;
+    cp.x = x;
+    cpp = &cp;
+    for (rp = rooms, i = 0; i < MAXROOMS; rp++, i++)
+	if (inroom(rp, cpp))
+	    if (y == rp->r_pos.y || y == rp->r_pos.y + rp->r_max.y - 1)
+		return('-');
+	    else
+		return('|');
+
+    return('p');
+}
+
+/*
+ * find_obj:
+ *	find the unclaimed object at y, x
+ */
+
+struct linked_list *
+find_obj(int y, int x)
+{
+    struct linked_list *obj;
+    struct object *op;
+
+    for (obj = lvl_obj; obj != NULL; obj = next(obj))
+    {
+	op = (struct object *) ldata(obj);
+	if (op->o_pos.y == y && op->o_pos.x == x)
+		return obj;
+    }
+    sprintf(prbuf, "Non-object %d,%d", y, x);
+    debug(prbuf);
+    return NULL;
+}
+
+/*
+ * eat:
+ *	She wants to eat something, so let her try
+ */
+
+void
+eat()
+{
+    struct linked_list *item;
+    struct object *obj;
+
+    if ((item = get_item("eat", FOOD)) == NULL)
+	return;
+    obj = (struct object *) ldata(item);
+    if (obj->o_type != FOOD)
+    {
+	if (!terse)
+	    msg("Ugh, you would get ill if you ate that.");
+	else
+	    msg("That's Inedible!");
+	return;
+    }
+    inpack--;
+    if (obj->o_which == 1)
+	msg("My, that was a yummy %s", fruit);
+    else
+	if (rnd(100) > 70)
+	{
+	    msg("Yuk, this food tastes awful");
+	    pstats.s_exp++;
+	    check_level();
+	}
+	else
+	    msg("Yum, that tasted good");
+    if ((food_left += HUNGERTIME + rnd(400) - 200) > STOMACHSIZE)
+	food_left = STOMACHSIZE;
+    hungry_state = 0;
+    if (obj == cur_weapon)
+	cur_weapon = NULL;
+    if (--obj->o_count < 1)
+    {
+	detach(pack, item);
+	discard(item);
+    }
+}
+
+/*
+ * Used to modify the playes strength
+ * it keeps track of the highest it has been, just in case
+ */
+
+void
+chg_str(int amt)
+{
+    if (amt == 0)
+	return;
+    if (amt > 0)
+    {
+	while (amt--)
+	{
+	    if (pstats.s_str.st_str < 18)
+		pstats.s_str.st_str++;
+	    else if (pstats.s_str.st_add == 0)
+		pstats.s_str.st_add = rnd(50) + 1;
+	    else if (pstats.s_str.st_add <= 50)
+		pstats.s_str.st_add = 51 + rnd(24);
+	    else if (pstats.s_str.st_add <= 75)
+		pstats.s_str.st_add = 76 + rnd(14);
+	    else if (pstats.s_str.st_add <= 90)
+		pstats.s_str.st_add = 91;
+	    else if (pstats.s_str.st_add < 100)
+		pstats.s_str.st_add++;
+	}
+	if (pstats.s_str.st_str > max_stats.s_str.st_str ||
+	    (pstats.s_str.st_str == 18 &&
+	     pstats.s_str.st_add > max_stats.s_str.st_add))
+		max_stats.s_str = pstats.s_str;
+    }
+    else
+    {
+	while (amt++)
+	{
+	    if (pstats.s_str.st_str < 18 || pstats.s_str.st_add == 0)
+		pstats.s_str.st_str--;
+	    else if (pstats.s_str.st_add < 51)
+		pstats.s_str.st_add = 0;
+	    else if (pstats.s_str.st_add < 76)
+		pstats.s_str.st_add = 1 + rnd(50);
+	    else if (pstats.s_str.st_add < 91)
+		pstats.s_str.st_add = 51 + rnd(25);
+	    else if (pstats.s_str.st_add < 100)
+		pstats.s_str.st_add = 76 + rnd(14);
+	    else
+		pstats.s_str.st_add = 91 + rnd(8);
+	}
+	if (pstats.s_str.st_str < 3)
+	    pstats.s_str.st_str = 3;
+    }
+}
+
+/*
+ * add_haste:
+ *	add a haste to the player
+ */
+
+void
+add_haste(int potion)
+{
+    if (on(player, ISHASTE))
+    {
+	msg("You faint from exhaustion.");
+	no_command += rnd(8);
+	extinguish(nohaste);
+    }
+    else
+    {
+	player.t_flags |= ISHASTE;
+	if (potion)
+	    fuse(nohaste, 0, rnd(4)+4, AFTER);
+    }
+}
+
+/*
+ * aggravate:
+ *	aggravate all the monsters on this level
+ */
+
+void
+aggravate()
+{
+    struct linked_list *mi;
+
+    for (mi = mlist; mi != NULL; mi = next(mi))
+	runto(&((struct thing *) ldata(mi))->t_pos, &hero);
+}
+
+/*
+ * for printfs: if string starts with a vowel, return "n" for an "an"
+ */
+char *
+vowelstr(char *str)
+{
+    switch (*str)
+    {
+	case 'a':
+	case 'e':
+	case 'i':
+	case 'o':
+	case 'u':
+	    return "n";
+	default:
+	    return "";
+    }
+}
+
+/* 
+ * see if the object is one of the currently used items
+ */
+int
+is_current(struct object *obj)
+{
+    if (obj == NULL)
+	return FALSE;
+    if (obj == cur_armor || obj == cur_weapon || obj == cur_ring[LEFT]
+	|| obj == cur_ring[RIGHT])
+    {
+	msg(terse ? "In use." : "That's already in use.");
+	return TRUE;
+    }
+    return FALSE;
+}
+
+/*
+ * set up the direction co_ordinate for use in varios "prefix" commands
+ */
+int
+get_dir()
+{
+    char *prompt;
+    int gotit;
+
+    if (!terse)
+	msg(prompt = "Which direction? ");
+    else
+	prompt = "Direction: ";
+    do
+    {
+	gotit = TRUE;
+	switch (readchar(cw))
+	{
+	    case 'h': case'H': delta.y =  0; delta.x = -1;
+	    when 'j': case'J': delta.y =  1; delta.x =  0;
+	    when 'k': case'K': delta.y = -1; delta.x =  0;
+	    when 'l': case'L': delta.y =  0; delta.x =  1;
+	    when 'y': case'Y': delta.y = -1; delta.x = -1;
+	    when 'u': case'U': delta.y = -1; delta.x =  1;
+	    when 'b': case'B': delta.y =  1; delta.x = -1;
+	    when 'n': case'N': delta.y =  1; delta.x =  1;
+	    when ESCAPE: return FALSE;
+	    otherwise:
+		mpos = 0;
+		msg(prompt);
+		gotit = FALSE;
+	}
+    } until (gotit);
+    if (on(player, ISHUH) && rnd(100) > 80)
+	do
+	{
+	    delta.y = rnd(3) - 1;
+	    delta.x = rnd(3) - 1;
+	} while (delta.y == 0 && delta.x == 0);
+    mpos = 0;
+    return TRUE;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rogue3/monsters.c	Tue Oct 13 13:33:34 2009 +0000
@@ -0,0 +1,243 @@
+/*
+ * File with various monster functions in it
+ *
+ * @(#)monsters.c	3.18 (Berkeley) 6/15/81
+ *
+ * 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 "curses.h"
+#include "rogue.h"
+#include <string.h>
+#include <ctype.h>
+
+/*
+ * List of monsters in rough order of vorpalness
+ */
+char lvl_mons[27] =  "KJBSHEAOZGLCRQNYTWFIXUMVDP";
+char wand_mons[27] = "KJBSH AOZG CRQ Y W IXU V  ";
+
+/*
+ * randmonster:
+ *	Pick a monster to show up.  The lower the level,
+ *	the meaner the monster.
+ */
+
+int
+randmonster(int wander)
+{
+    int d;
+    char *mons;
+
+    mons = wander ? wand_mons : lvl_mons;
+    do
+    {
+	d = level + (rnd(10) - 5);
+	if (d < 1)
+	    d = rnd(5) + 1;
+	if (d > 26)
+	    d = rnd(5) + 22;
+    } while (mons[--d] == ' ');
+    return mons[d];
+}
+
+/*
+ * new_monster:
+ *	Pick a new monster and add it to the list
+ */
+
+void
+new_monster(struct linked_list *item, int type, coord *cp)
+{
+    struct thing *tp;
+    struct monster *mp;
+
+    attach(mlist, item);
+    tp = (struct thing *) ldata(item);
+    tp->t_type = type;
+    tp->t_pos = *cp;
+    tp->t_oldch = mvwinch(cw, cp->y, cp->x);
+    mvwaddch(mw, cp->y, cp->x, tp->t_type);
+    mp = &monsters[tp->t_type-'A'];
+    tp->t_stats.s_hpt = roll(mp->m_stats.s_lvl, 8);
+    tp->t_stats.s_lvl = mp->m_stats.s_lvl;
+    tp->t_stats.s_arm = mp->m_stats.s_arm;
+    strcpy(tp->t_stats.s_dmg,mp->m_stats.s_dmg);
+    tp->t_stats.s_exp = mp->m_stats.s_exp;
+    tp->t_stats.s_str.st_str = 10;
+    tp->t_flags = mp->m_flags;
+    tp->t_turn = TRUE;
+    tp->t_pack = NULL;
+    if (ISWEARING(R_AGGR))
+	runto(cp, &hero);
+    if (type == 'M')
+    {
+	int mch = 0;
+
+	if (tp->t_pack != NULL)
+	    mch = ((struct object *) ldata(tp->t_pack))->o_type;
+	else
+	    switch (rnd(level > 25 ? 9 : 8))
+	    {
+		case 0: mch = GOLD;
+		when 1: mch = POTION;
+		when 2: mch = SCROLL;
+		when 3: mch = STAIRS;
+		when 4: mch = WEAPON;
+		when 5: mch = ARMOR;
+		when 6: mch = RING;
+		when 7: mch = STICK;
+		when 8: mch = AMULET;
+	    }
+	tp->t_disguise = mch;
+    }
+}
+
+/*
+ * wanderer:
+ *	A wandering monster has awakened and is headed for the player
+ */
+
+void
+wanderer()
+{
+    int i, ch;
+    struct room *rp, *hr = roomin(&hero);
+    struct linked_list *item;
+    struct thing *tp;
+    coord cp;
+
+    item = new_item(sizeof *tp);
+    do
+    {
+	i = rnd_room();
+	if ((rp = &rooms[i]) == hr)
+	    continue;
+	rnd_pos(rp, &cp);
+	if ((ch = mvwinch(stdscr, cp.y, cp.x)) == ERR)
+	{
+	    debug("Routine wanderer: mvwinch failed to %d,%d", cp.y, cp.x);
+	    if (wizard)
+		wait_for(cw,'\n');
+	    return;
+	}
+    } until(hr != rp && step_ok(ch));
+    new_monster(item, randmonster(TRUE), &cp);
+    tp = (struct thing *) ldata(item);
+    tp->t_flags |= ISRUN;
+    tp->t_pos = cp;
+    tp->t_dest = &hero;
+    if (wizard)
+	msg("Started a wandering %s", monsters[tp->t_type-'A'].m_name);
+}
+
+/*
+ * what to do when the hero steps next to a monster
+ */
+struct linked_list *
+wake_monster(int y, int x)
+{
+    struct thing *tp;
+    struct linked_list *it;
+    struct room *rp;
+    int ch;
+
+    if ((it = find_mons(y, x)) == NULL)
+    {
+	fatal("Can't find monster in wake");
+	return NULL;
+    }
+        
+    tp = (struct thing *) ldata(it);
+    ch = tp->t_type;
+    /*
+     * Every time he sees mean monster, it might start chasing him
+     */
+    if (rnd(100) > 33 && on(*tp, ISMEAN) && off(*tp, ISHELD)
+	&& !ISWEARING(R_STEALTH))
+    {
+	tp->t_dest = &hero;
+	tp->t_flags |= ISRUN;
+    }
+    if (ch == 'U' && off(player, ISBLIND))
+    {
+        rp = roomin(&hero);
+	if ((rp != NULL && !(rp->r_flags&ISDARK))
+	    || DISTANCE(y, x, hero.y, hero.x) < 3)
+	{
+	    if (off(*tp, ISFOUND) && !save(VS_MAGIC))
+	    {
+		msg("The umber hulk's gaze has confused you.");
+		if (on(player, ISHUH))
+		    lengthen(unconfuse, rnd(20)+HUHDURATION);
+		else
+		    fuse(unconfuse, 0, rnd(20)+HUHDURATION, AFTER);
+		player.t_flags |= ISHUH;
+	    }
+	    tp->t_flags |= ISFOUND;
+	}
+    }
+    /*
+     * Hide invisible monsters
+     */
+    if (on(*tp, ISINVIS) && off(player, CANSEE))
+	ch = mvwinch(stdscr, y, x);
+    /*
+     * Let greedy ones guard gold
+     */
+    if (on(*tp, ISGREED) && off(*tp, ISRUN))
+    {
+        rp = roomin(&hero);
+
+	if (rp != NULL && rp->r_goldval)
+	{
+	    tp->t_dest = &rp->r_gold;
+	    tp->t_flags |= ISRUN;
+	}
+    }
+
+    return it;
+}
+
+void
+genocide()
+{
+    struct linked_list *ip;
+    struct thing *mp;
+    int c;
+    int i;
+    struct linked_list *nip;
+
+    addmsg("Which monster");
+    if (!terse)
+	addmsg(" do you wish to wipe out");
+    msg("? ");
+    while (!isalpha(c = readchar(cw)))
+	if (c == ESCAPE)
+	    return;
+	else
+	{
+	    mpos = 0;
+	    msg("Please specify a letter between 'A' and 'Z'");
+	}
+    if (islower(c))
+	c = toupper(c);
+    for (ip = mlist; ip; ip = nip)
+    {
+	mp = (struct thing *) ldata(ip);
+	nip = next(ip);
+	if (mp->t_type == c)
+	    remove_monster(&mp->t_pos, ip);
+    }
+    for (i = 0; i < 26; i++)
+	if (lvl_mons[i] == c)
+	{
+	    lvl_mons[i] = ' ';
+	    wand_mons[i] = ' ';
+	    break;
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rogue3/move.c	Tue Oct 13 13:33:34 2009 +0000
@@ -0,0 +1,384 @@
+/*
+ * Hero movement commands
+ *
+ * @(#)move.c	3.26 (Berkeley) 6/15/81
+ *
+ * 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 "curses.h"
+#include <ctype.h>
+#include "rogue.h"
+
+/*
+ * Used to hold the new hero position
+ */
+
+coord nh;
+
+/*
+ * do_run:
+ *	Start the hero running
+ */
+
+void
+do_run(int ch)
+{
+    running = TRUE;
+    after = FALSE;
+    runch = ch;
+}
+
+/*
+ * do_move:
+ *	Check to see that a move is legal.  If it is handle the
+ * consequences (fighting, picking up, etc.)
+ */
+
+void
+do_move(int dy, int dx)
+{
+    int ch;
+
+    firstmove = FALSE;
+    if (no_move)
+    {
+	no_move--;
+	msg("You are still stuck in the bear trap");
+	return;
+    }
+    /*
+     * Do a confused move (maybe)
+     */
+    if (rnd(100) < 80 && on(player, ISHUH))
+	nh = *rndmove(&player);
+    else
+    {
+	nh.y = hero.y + dy;
+	nh.x = hero.x + dx;
+    }
+
+    /*
+     * Check if he tried to move off the screen or make an illegal
+     * diagonal move, and stop him if he did.
+     */
+    if (nh.x < 0 || nh.x > COLS-1 || nh.y < 0 || nh.y > LINES - 1
+	|| !diag_ok(&hero, &nh))
+    {
+	after = FALSE;
+	running = FALSE;
+	return;
+    }
+    if (running && ce(hero, nh))
+	after = running = FALSE;
+    ch = winat(nh.y, nh.x);
+    if (on(player, ISHELD) && ch != 'F')
+    {
+	msg("You are being held");
+	return;
+    }
+    switch(ch)
+    {
+	case ' ':
+	case '|':
+	case '-':
+	case SECRETDOOR:
+	    after = running = FALSE;
+	    return;
+	case TRAP:
+	    ch = be_trapped(&nh);
+	    if (ch == TRAPDOOR || ch == TELTRAP)
+		return;
+	    goto move_stuff;
+	case GOLD:
+	case POTION:
+	case SCROLL:
+	case FOOD:
+	case WEAPON:
+	case ARMOR:
+	case RING:
+	case AMULET:
+	case STICK:
+	    running = FALSE;
+	    take = ch;
+	default:
+move_stuff:
+	    if (ch == PASSAGE && winat(hero.y, hero.x) == DOOR)
+		light(&hero);
+	    else if (ch == DOOR)
+	    {
+		running = FALSE;
+		if (winat(hero.y, hero.x) == PASSAGE)
+		    light(&nh);
+	    }
+	    else if (ch == STAIRS)
+		running = FALSE;
+	    else if (isupper(ch))
+	    {
+		running = FALSE;
+		fight(&nh, ch, cur_weapon, FALSE);
+		return;
+	    }
+	    ch = winat(hero.y, hero.x);
+	    wmove(cw, unc(hero));
+	    waddch(cw, ch);
+	    hero = nh;
+	    wmove(cw, unc(hero));
+	    waddch(cw, PLAYER);
+    }
+}
+
+/*
+ * Called to illuminate a room.
+ * If it is dark, remove anything that might move.
+ */
+
+void
+light(coord *cp)
+{
+    struct room *rp;
+    int j, k;
+    int ch;
+    int rch;
+    struct linked_list *item;
+
+    if ((rp = roomin(cp)) != NULL && !on(player, ISBLIND))
+    {
+	for (j = 0; j < rp->r_max.y; j++)
+	{
+	    for (k = 0; k < rp->r_max.x; k++)
+	    {
+		ch = show(rp->r_pos.y + j, rp->r_pos.x + k);
+		wmove(cw, rp->r_pos.y + j, rp->r_pos.x + k);
+		/*
+		 * Figure out how to display a secret door
+		 */
+		if (ch == SECRETDOOR)
+		{
+		    if (j == 0 || j == rp->r_max.y - 1)
+			ch = '-';
+		    else
+			ch = '|';
+		}
+		/*
+		 * If the room is a dark room, we might want to remove
+		 * monsters and the like from it (since they might
+		 * move)
+		 */
+		if (isupper(ch))
+		{
+		    item = wake_monster(rp->r_pos.y+j, rp->r_pos.x+k);
+		    if (((struct thing *) ldata(item))->t_oldch == ' ')
+			if (!(rp->r_flags & ISDARK))
+			    ((struct thing *) ldata(item))->t_oldch =
+				mvwinch(stdscr, rp->r_pos.y+j, rp->r_pos.x+k);
+		}
+		if (rp->r_flags & ISDARK)
+		{
+		    rch = mvwinch(cw, rp->r_pos.y+j, rp->r_pos.x+k);
+		    switch (rch)
+		    {
+			case DOOR:
+			case STAIRS:
+			case TRAP:
+			case '|':
+			case '-':
+			case ' ':
+			    ch = rch;
+			when FLOOR:
+			    ch = (on(player, ISBLIND) ? FLOOR : ' ');
+			otherwise:
+			    ch = ' ';
+		    }
+		}
+		mvwaddch(cw, rp->r_pos.y+j, rp->r_pos.x+k, ch);
+	    }
+	}
+    }
+}
+
+/*
+ * show:
+ *	returns what a certain thing will display as to the un-initiated
+ */
+
+int
+show(int y, int x)
+{
+    int ch = winat(y, x);
+    struct linked_list *it;
+    struct thing *tp;
+
+    if (ch == TRAP)
+	return (trap_at(y, x)->tr_flags & ISFOUND) ? TRAP : FLOOR;
+    else if (ch == 'M' || ch == 'I')
+    {
+	if ((it = find_mons(y, x)) == NULL)
+	    fatal("Can't find monster in show");
+	tp = (struct thing *) ldata(it);
+	if (ch == 'M')
+	    ch = tp->t_disguise;
+	/*
+	 * Hide invisible monsters
+	 */
+	else if (off(player, CANSEE))
+	    ch = mvwinch(stdscr, y, x);
+    }
+    return ch;
+}
+
+/*
+ * be_trapped:
+ *	The guy stepped on a trap.... Make him pay.
+ */
+
+int
+be_trapped(coord *tc)
+{
+    struct trap *tp;
+    int ch;
+
+    tp = trap_at(tc->y, tc->x);
+    count = running = FALSE;
+    mvwaddch(cw, tp->tr_pos.y, tp->tr_pos.x, TRAP);
+    tp->tr_flags |= ISFOUND;
+    switch (ch = tp->tr_type)
+    {
+	case TRAPDOOR:
+	    level++;
+	    new_level();
+	    msg("You fell into a trap!");
+	when BEARTRAP:
+	    no_move += BEARTIME;
+	    msg("You are caught in a bear trap");
+	when SLEEPTRAP:
+	    no_command += SLEEPTIME;
+	    msg("A strange white mist envelops you and you fall asleep");
+	when ARROWTRAP:
+	    if (swing(pstats.s_lvl-1, pstats.s_arm, 1))
+	    {
+		msg("Oh no! An arrow shot you");
+		if ((pstats.s_hpt -= roll(1, 6)) <= 0)
+		{
+		    msg("The arrow killed you.");
+		    death('a');
+		}
+	    }
+	    else
+	    {
+		struct linked_list *item;
+		struct object *arrow;
+
+		msg("An arrow shoots past you.");
+		item = new_item(sizeof *arrow);
+		arrow = (struct object *) ldata(item);
+		arrow->o_type = WEAPON;
+		arrow->o_which = ARROW;
+		init_weapon(arrow, ARROW);
+		arrow->o_count = 1;
+		arrow->o_pos = hero;
+		arrow->o_hplus = arrow->o_dplus = 0; /* "arrow bug" FIX */
+		fall(item, FALSE);
+	    }
+	when TELTRAP:
+	    teleport();
+	when DARTTRAP:
+	    if (swing(pstats.s_lvl+1, pstats.s_arm, 1))
+	    {
+		msg("A small dart just hit you in the shoulder");
+		if ((pstats.s_hpt -= roll(1, 4)) <= 0)
+		{
+		    msg("The dart killed you.");
+		    death('d');
+		}
+		if (!ISWEARING(R_SUSTSTR))
+		    chg_str(-1);
+	    }
+	    else
+		msg("A small dart whizzes by your ear and vanishes.");
+    }
+    flush_type();	/* flush typeahead */
+    return(ch);
+}
+
+/*
+ * trap_at:
+ *	find the trap at (y,x) on screen.
+ */
+
+struct trap *
+trap_at(int y, int x)
+{
+    struct trap *tp, *ep;
+
+    ep = &traps[ntraps];
+    for (tp = traps; tp < ep; tp++)
+	if (tp->tr_pos.y == y && tp->tr_pos.x == x)
+	    break;
+    if (tp == ep)
+    {
+	sprintf(prbuf, "Trap at %d,%d not in array", y, x);
+	fatal(prbuf);
+    }
+    return tp;
+}
+
+/*
+ * rndmove:
+ *	move in a random direction if the monster/person is confused
+ */
+
+coord *
+rndmove(struct thing *who)
+{
+    int x, y;
+    int ch;
+    int ex, ey, nopen = 0;
+    struct linked_list *item;
+    struct object *obj;
+    static coord ret;  /* what we will be returning */
+    static coord dest;
+
+    ret = who->t_pos;
+    /*
+     * Now go through the spaces surrounding the player and
+     * set that place in the array to true if the space can be
+     * moved into
+     */
+    ey = ret.y + 1;
+    ex = ret.x + 1;
+    for (y = who->t_pos.y - 1; y <= ey; y++)
+	if (y >= 0 && y < LINES)
+	    for (x = who->t_pos.x - 1; x <= ex; x++)
+	    {
+		if (x < 0 || x >= COLS)
+		    continue;
+		ch = winat(y, x);
+		if (step_ok(ch))
+		{
+		    dest.y = y;
+		    dest.x = x;
+		    if (!diag_ok(&who->t_pos, &dest))
+			continue;
+		    if (ch == SCROLL)
+		    {
+			item = NULL;
+			for (item = lvl_obj; item != NULL; item = next(item))
+			{
+			    obj = (struct object *) ldata(item);
+			    if (y == obj->o_pos.y && x == obj->o_pos.x)
+				break;
+			}
+			if (item != NULL && obj->o_which == S_SCARE)
+			    continue;
+		    }
+		    if (rnd(++nopen) == 0)
+			ret = dest;
+		}
+	    }
+    return &ret;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rogue3/newlevel.c	Tue Oct 13 13:33:34 2009 +0000
@@ -0,0 +1,176 @@
+/*
+ * new_level:
+ *	Dig and draw a new level
+ *
+ * @(#)new_level.c	3.7 (Berkeley) 6/2/81
+ *
+ * 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 "curses.h"
+#include "rogue.h"
+
+#include <string.h>
+
+void
+new_level()
+{
+    int rm, i;
+    int ch = 0;
+    coord stairs;
+
+    if (level > max_level)
+	max_level = level;
+    wclear(cw);
+    wclear(mw);
+    clear();
+    status();
+    /*
+     * Free up the monsters on the last level
+     */
+    free_list(mlist);
+    do_rooms();				/* Draw rooms */
+    do_passages();			/* Draw passages */
+    no_food++;
+    put_things();			/* Place objects (if any) */
+    /*
+     * Place the staircase down.
+     */
+    do {
+        rm = rnd_room();
+	rnd_pos(&rooms[rm], &stairs);
+    } until (winat(stairs.y, stairs.x) == FLOOR);
+    addch(STAIRS);
+    /*
+     * Place the traps
+     */
+    if (rnd(10) < level)
+    {
+	ntraps = rnd(level/4)+1;
+	if (ntraps > MAXTRAPS)
+	    ntraps = MAXTRAPS;
+	i = ntraps;
+	while (i--)
+	{
+	    do
+	    {
+		rm = rnd_room();
+		rnd_pos(&rooms[rm], &stairs);
+	    } until (winat(stairs.y, stairs.x) == FLOOR);
+	    switch(rnd(6))
+	    {
+		case 0: ch = TRAPDOOR;
+		when 1: ch = BEARTRAP;
+		when 2: ch = SLEEPTRAP;
+		when 3: ch = ARROWTRAP;
+		when 4: ch = TELTRAP;
+		when 5: ch = DARTTRAP;
+	    }
+	    addch(TRAP);
+	    traps[i].tr_type = ch;
+	    traps[i].tr_flags = 0;
+	    traps[i].tr_pos = stairs;
+	}
+    }
+    do
+    {
+	rm = rnd_room();
+	rnd_pos(&rooms[rm], &hero);
+    }
+    until(winat(hero.y, hero.x) == FLOOR);
+    light(&hero);
+    wmove(cw, hero.y, hero.x);
+    waddch(cw, PLAYER);
+}
+
+/*
+ * Pick a room that is really there
+ */
+
+int
+rnd_room()
+{
+    int rm;
+
+    do
+    {
+	rm = rnd(MAXROOMS);
+    } while (rooms[rm].r_flags & ISGONE);
+    return rm;
+}
+
+/*
+ * put_things:
+ *	put potions and scrolls on this level
+ */
+
+void
+put_things()
+{
+    int i;
+    struct linked_list *item;
+    struct object *cur;
+    int rm;
+    coord tp;
+
+    /*
+     * Throw away stuff left on the previous level (if anything)
+     */
+    free_list(lvl_obj);
+    /*
+     * Once you have found the amulet, the only way to get new stuff is
+     * go down into the dungeon.
+     */
+    if (amulet && level < max_level)
+	return;
+    /*
+     * Do MAXOBJ attempts to put things on a level
+     */
+    for (i = 0; i < MAXOBJ; i++)
+	if (rnd(100) < 35)
+	{
+	    /*
+	     * Pick a new object and link it in the list
+	     */
+	    item = new_thing();
+	    attach(lvl_obj, item);
+	    cur = (struct object *) ldata(item);
+	    /*
+	     * Put it somewhere
+	     */
+	    do {
+	        rm = rnd_room();
+		rnd_pos(&rooms[rm], &tp);
+	    } until (winat(tp.y, tp.x) == FLOOR);
+	    mvaddch(tp.y, tp.x, cur->o_type);
+	    cur->o_pos = tp;
+	}
+    /*
+     * If he is really deep in the dungeon and he hasn't found the
+     * amulet yet, put it somewhere on the ground
+     */
+    if (level > 25 && !amulet)
+    {
+	item = new_item(sizeof *cur);
+	attach(lvl_obj, item);
+	cur = (struct object *) ldata(item);
+	cur->o_hplus = cur->o_dplus = 0;
+	strcpy(cur->o_damage, "0d0");
+	strcpy(cur->o_hurldmg, "0d0");
+	cur->o_ac = 11;
+	cur->o_type = AMULET;
+	/*
+	 * Put it somewhere
+	 */
+	do {
+	    rm = rnd_room();
+	    rnd_pos(&rooms[rm], &tp);
+	} until (winat(tp.y, tp.x) == FLOOR);
+	mvaddch(tp.y, tp.x, cur->o_type);
+	cur->o_pos = tp;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rogue3/options.c	Tue Oct 13 13:33:34 2009 +0000
@@ -0,0 +1,353 @@
+/*
+ * This file has all the code for the option command.
+ * I would rather this command were not necessary, but
+ * it is the only way to keep the wolves off of my back.
+ *
+ * @(#)options.c	3.3 (Berkeley) 5/25/81
+ *
+ * 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 <stdlib.h>
+#include "curses.h"
+#include <ctype.h>
+#include <string.h>
+#include "machdep.h"
+#include "rogue.h"
+
+#define	NUM_OPTS	(sizeof optlist / sizeof (OPTION))
+
+/*
+ * description of an option and what to do with it
+ */
+struct optstruct {
+    char	*o_name;	/* option name */
+    char	*o_prompt;	/* prompt for interactive entry */
+    void	*o_opt;		/* pointer to thing to set */
+    void	(*o_putfunc)();	/* function to print value */
+    int		(*o_getfunc)();	/* function to get value interactively */
+};
+
+typedef struct optstruct	OPTION;
+
+OPTION	optlist[] = {
+    {"terse",	 "Terse output: ",
+		 (int *) &terse,	put_bool,	get_bool	},
+    {"flush",	 "Flush typeahead during battle: ",
+		 (int *) &fight_flush,	put_bool,	get_bool	},
+    {"jump",	 "Show position only at end of run: ",
+		 (int *) &jump,		put_bool,	get_bool	},
+    {"step",	"Do inventories one line at a time: ",
+		(int *) &slow_invent,	put_bool,	get_bool	},
+    {"askme",	"Ask me about unidentified things: ",
+		(int *) &askme,		put_bool,	get_bool	},
+    {"name",	 "Name: ",
+		 (int *) whoami,	put_str,	get_str		},
+    {"fruit",	 "Fruit: ",
+		 (int *) fruit,		put_str,	get_str		},
+    {"file",	 "Save file: ",
+		 (int *) file_name,	put_str,	get_str		}
+};
+
+/*
+ * print and then set options from the terminal
+ */
+void
+option()
+{
+    OPTION	*op;
+    int	retval;
+
+    wclear(hw);
+    touchwin(hw);
+    /*
+     * Display current values of options
+     */
+    for (op = optlist; op <= &optlist[NUM_OPTS-1]; op++)
+    {
+	waddstr(hw, op->o_prompt);
+	(*op->o_putfunc)(op->o_opt);
+	waddch(hw, '\n');
+    }
+    /*
+     * Set values
+     */
+    wmove(hw, 0, 0);
+    for (op = optlist; op <= &optlist[NUM_OPTS-1]; op++)
+    {
+	waddstr(hw, op->o_prompt);
+	if ((retval = (*op->o_getfunc)(op->o_opt, hw)))
+	    if (retval == QUIT)
+		break;
+	    else if (op > optlist) {	/* MINUS */
+		wmove(hw, (int)(op - optlist) - 1, 0);
+		op -= 2;
+	    }
+	    else	/* trying to back up beyond the top */
+	    {
+		beep();
+		wmove(hw, 0, 0);
+		op--;
+	    }
+    }
+    /*
+     * Switch back to original screen
+     */
+    mvwaddstr(hw, LINES-1, 0, "--Press space to continue--");
+    draw(hw);
+    wait_for(hw,' ');
+    clearok(cw, TRUE);
+    touchwin(cw);
+    after = FALSE;
+}
+
+/*
+ * put out a boolean
+ */
+void
+put_bool(void *b)
+{
+    waddstr(hw, *(int *)b ? "True" : "False");
+}
+
+/*
+ * put out a string
+ */
+void
+put_str(void *str)
+{
+    waddstr(hw, (char *) str);
+}
+
+/*
+ * allow changing a boolean option and print it out
+ */
+
+int
+get_bool(void *vp, WINDOW *win)
+{
+    int *bp = (int *) vp;
+    int oy, ox;
+    int op_bad;
+
+    op_bad = TRUE;
+    getyx(win, oy, ox);
+    waddstr(win, *bp ? "True" : "False");
+    while(op_bad)	
+    {
+	wmove(win, oy, ox);
+	draw(win);
+	switch (readchar(win))
+	{
+	    case 't':
+	    case 'T':
+		*bp = TRUE;
+		op_bad = FALSE;
+		break;
+	    case 'f':
+	    case 'F':
+		*bp = FALSE;
+		op_bad = FALSE;
+		break;
+	    case '\n':
+	    case '\r':
+		op_bad = FALSE;
+		break;
+	    case '\033':
+	    case '\007':
+		return QUIT;
+	    case '-':
+		return MINUS;
+	    default:
+		mvwaddstr(win, oy, ox + 10, "(T or F)");
+	}
+    }
+    wmove(win, oy, ox);
+    waddstr(win, *bp ? "True" : "False");
+    waddch(win, '\n');
+    return NORM;
+}
+
+/*
+ * set a string option
+ */
+int
+get_str(void *vopt, WINDOW *win)
+{
+    char *opt = (char *) vopt;
+    char *sp;
+    int c, oy, ox;
+    char buf[80];
+
+    draw(win);
+    getyx(win, oy, ox);
+    /*
+     * loop reading in the string, and put it in a temporary buffer
+     */
+    for (sp = buf;
+	(c = readchar(win)) != '\n' && c != '\r' && c != '\033' && c != '\007';
+	wclrtoeol(win), draw(win))
+    {
+	if (c == -1)
+	    continue;
+	else if (c == md_erasechar())	/* process erase character */
+	{
+	    if (sp > buf)
+	    {
+		int i;
+		int myx, myy;
+
+		sp--;
+
+		for (i = (int) strlen(unctrl(*sp)); i; i--)
+		{
+		    getyx(win,myy,myx);
+		    if ((myx == 0)&& (myy > 0))
+		    {
+			wmove(win,myy-1,getmaxx(win)-1);
+			waddch(win,' ');
+			wmove(win,myy-1,getmaxx(win)-1);
+		    }
+		    else
+			waddch(win, '\b');
+		}
+	    }
+	    continue;
+	}
+	else if (c == md_killchar())	/* process kill character */
+	{
+	    sp = buf;
+	    wmove(win, oy, ox);
+	    continue;
+	}
+	else if (sp == buf)
+	    if (c == '-')
+		break;
+	    else if (c == '~')
+	    {
+		strcpy(buf, home);
+		waddstr(win, home);
+		sp += strlen(home);
+		continue;
+	    }
+
+	if ((sp - buf) < 78) /* Avoid overflow */
+	{
+	    *sp++ = c;
+	    waddstr(win, unctrl(c));
+	}
+    }
+    *sp = '\0';
+    if (sp > buf)	/* only change option if something has been typed */
+	strucpy(opt, buf, strlen(buf));
+    wmove(win, oy, ox);
+    waddstr(win, opt);
+    waddch(win, '\n');
+    draw(win);
+    if (win == cw)
+	mpos += (int)(sp - buf);
+    if (c == '-')
+	return MINUS;
+    else if (c == '\033' || c == '\007')
+	return QUIT;
+    else
+	return NORM;
+}
+
+/*
+ * parse options from string, usually taken from the environment.
+ * the string is a series of comma seperated values, with booleans
+ * being stated as "name" (true) or "noname" (false), and strings
+ * being "name=....", with the string being defined up to a comma
+ * or the end of the entire option string.
+ */
+
+void
+parse_opts(char *str)
+{
+    char *sp;
+    OPTION *op;
+    int len;
+
+    while (*str)
+    {
+	/*
+	 * Get option name
+	 */
+	for (sp = str; isalpha(*sp); sp++)
+	    continue;
+	len = (int)(sp - str);
+	/*
+	 * Look it up and deal with it
+	 */
+	for (op = optlist; op <= &optlist[NUM_OPTS-1]; op++)
+	    if (EQSTR(str, op->o_name, len))
+	    {
+		if (op->o_putfunc == put_bool)	/* if option is a boolean */
+		    *(int *)op->o_opt = TRUE;
+		else				/* string option */
+		{
+		    char *start;
+		    /*
+		     * Skip to start of string value
+		     */
+		    for (str = sp + 1; *str == '='; str++)
+			continue;
+		    if (*str == '~')
+		    {
+			strcpy((char *) op->o_opt, home);
+			start = (char *) op->o_opt + strlen(home);
+			while (*++str == '/')
+			    continue;
+		    }
+		    else
+			start = (char *) op->o_opt;
+		    /*
+		     * Skip to end of string value
+		     */
+		    for (sp = str + 1; *sp && *sp != ','; sp++)
+			continue;
+		    strucpy(start, str, sp - str);
+		}
+		break;
+	    }
+	    /*
+	     * check for "noname" for booleans
+	     */
+	    else if (op->o_putfunc == put_bool
+	      && EQSTR(str, "no", 2) && EQSTR(str + 2, op->o_name, len - 2))
+	    {
+		*(int *)op->o_opt = FALSE;
+		break;
+	    }
+
+	/*
+	 * skip to start of next option name
+	 */
+	while (*sp && !isalpha(*sp))
+	    sp++;
+	str = sp;
+    }
+}
+
+/*
+ * copy string using unctrl for things
+ */
+void
+strucpy(char *s1, char *s2, size_t len)
+{
+    const char *sp;
+
+    while (len--)
+    {
+    	sp = unctrl(*s2);
+	strcpy(s1, sp);
+	s1 += strlen(sp);
+	s2++;
+    }
+    *s1 = '\0';
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rogue3/pack.c	Tue Oct 13 13:33:34 2009 +0000
@@ -0,0 +1,399 @@
+/*
+ * Routines to deal with the pack
+ *
+ * @(#)pack.c	3.6 (Berkeley) 6/15/81
+ *
+ * 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 "curses.h"
+#include <ctype.h>
+#include "rogue.h"
+
+/*
+ * add_pack:
+ *	Pick up an object and add it to the pack.  If the argument is non-null
+ * use it as the linked_list pointer instead of gettting it off the ground.
+ */
+void
+add_pack(struct linked_list *item, int silent)
+{
+    struct linked_list *ip, *lp;
+    struct object *obj, *op;
+    int exact, from_floor;
+
+    if (item == NULL)
+    {
+	from_floor = TRUE;
+	if ((item = find_obj(hero.y, hero.x)) == NULL)
+	    return;
+    }
+    else
+	from_floor = FALSE;
+    obj = (struct object *) ldata(item);
+    /*
+     * Link it into the pack.  Search the pack for a object of similar type
+     * if there isn't one, stuff it at the beginning, if there is, look for one
+     * that is exactly the same and just increment the count if there is.
+     * it  that.  Food is always put at the beginning for ease of access, but
+     * is not ordered so that you can't tell good food from bad.  First check
+     * to see if there is something in thr same group and if there is then
+     * increment the count.
+     */
+    if (obj->o_group)
+    {
+	for (ip = pack; ip != NULL; ip = next(ip))
+	{
+	    op = (struct object *) ldata(ip);
+	    if (op->o_group == obj->o_group)
+	    {
+		/*
+		 * Put it in the pack and notify the user
+		 */
+		op->o_count++;
+		if (from_floor)
+		{
+		    detach(lvl_obj, item);
+		    mvaddch(hero.y, hero.x,
+			(roomin(&hero) == NULL ? PASSAGE : FLOOR));
+		}
+		discard(item);
+		item = ip;
+		goto picked_up;
+	    }
+	}
+    }
+    /*
+     * Check if there is room
+     */
+    if (inpack == MAXPACK-1)
+    {
+	msg("You can't carry anything else.");
+	return;
+    }
+    /*
+     * Check for and deal with scare monster scrolls
+     */
+    if (obj->o_type == SCROLL && obj->o_which == S_SCARE)
+	if (obj->o_flags & ISFOUND)
+	{
+	    msg("The scroll turns to dust as you pick it up.");
+	    detach(lvl_obj, item);
+	    mvaddch(hero.y, hero.x, FLOOR);
+	    return;
+	}
+	else
+	    obj->o_flags |= ISFOUND;
+
+    inpack++;
+    if (from_floor)
+    {
+	detach(lvl_obj, item);
+	mvaddch(hero.y, hero.x, (roomin(&hero) == NULL ? PASSAGE : FLOOR));
+    }
+    /*
+     * Search for an object of the same type
+     */
+    exact = FALSE;
+    for (ip = pack; ip != NULL; ip = next(ip))
+    {
+	op = (struct object *) ldata(ip);
+	if (obj->o_type == op->o_type)
+	    break;
+    }
+    if (ip == NULL)
+    {
+	/*
+	 * Put it at the end of the pack since it is a new type
+	 */
+	for (ip = pack; ip != NULL; ip = next(ip))
+	{
+	    op = (struct object *) ldata(ip);
+	    if (op->o_type != FOOD)
+		break;
+	    lp = ip;
+	}
+    }
+    else
+    {
+	/*
+	 * Search for an object which is exactly the same
+	 */
+	while (ip != NULL && op->o_type == obj->o_type)
+	{
+	    if (op->o_which == obj->o_which)
+	    {
+		exact = TRUE;
+		break;
+	    }
+	    lp = ip;
+	    if ((ip = next(ip)) == NULL)
+		break;
+	    op = (struct object *) ldata(ip);
+	}
+    }
+    if (ip == NULL)
+    {
+	/*
+	 * Didn't find an exact match, just stick it here
+	 */
+	if (pack == NULL)
+	    pack = item;
+	else
+	{
+	    lp->l_next = item;
+	    item->l_prev = lp;
+	    item->l_next = NULL;
+	}
+    }
+    else
+    {
+	/*
+	 * If we found an exact match.  If it is a potion, food, or a 
+	 * scroll, increase the count, otherwise put it with its clones.
+	 */
+	if (exact && ISMULT(obj->o_type))
+	{
+	    op->o_count++;
+	    discard(item);
+	    item = ip;
+	    goto picked_up;
+	}
+	if ((item->l_prev = prev(ip)) != NULL)
+	    item->l_prev->l_next = item;
+	else
+	    pack = item;
+	item->l_next = ip;
+	ip->l_prev = item;
+    }
+picked_up:
+    /*
+     * Notify the user
+     */
+    obj = (struct object *) ldata(item);
+    if (notify && !silent)
+    {
+	if (!terse)
+	    addmsg("You now have ");
+	msg("%s (%c)", inv_name(obj, !terse), pack_char(obj));
+    }
+    if (obj->o_type == AMULET)
+	amulet = TRUE;
+}
+
+/*
+ * inventory:
+ *	list what is in the pack
+ */
+int
+inventory(struct linked_list *list, int type)
+{
+    struct object *obj;
+    int ch;
+    int n_objs;
+    char inv_temp[80];
+
+    n_objs = 0;
+    for (ch = 'a'; list != NULL; ch++, list = next(list))
+    {
+	obj = (struct object *) ldata(list);
+	if (type && type != obj->o_type && !(type == CALLABLE &&
+	    (obj->o_type == SCROLL || obj->o_type == POTION ||
+	     obj->o_type == RING || obj->o_type == STICK)))
+		continue;
+	switch (n_objs++)
+	{
+	    /*
+	     * For the first thing in the inventory, just save the string
+	     * in case there is only one.
+	     */
+	    case 0:
+		sprintf(inv_temp, "%c) %s", ch, inv_name(obj, FALSE));
+		break;
+	    /*
+	     * If there is more than one, clear the screen, print the
+	     * saved message and fall through to ...
+	     */
+	    case 1:
+		if (slow_invent)
+		    msg(inv_temp);
+		else
+		{
+		    wclear(hw);
+		    waddstr(hw, inv_temp);
+		    waddch(hw, '\n');
+		}
+	    /*
+	     * Print the line for this object
+	     */
+	    default:
+		if (slow_invent)
+		    msg("%c) %s", ch, inv_name(obj, FALSE));
+		else
+		    wprintw(hw, "%c) %s\n", ch, inv_name(obj, FALSE));
+	}
+    }
+    if (n_objs == 0)
+    {
+	if (terse)
+	    msg(type == 0 ? "Empty handed." :
+			    "Nothing appropriate");
+	else
+	    msg(type == 0 ? "You are empty handed." :
+			    "You don't have anything appropriate");
+	return FALSE;
+    }
+    if (n_objs == 1)
+    {
+	msg(inv_temp);
+	return TRUE;
+    }
+    if (!slow_invent)
+    {
+	mvwaddstr(hw, LINES-1, 0, "--Press space to continue--");
+	draw(hw);
+	wait_for(hw,' ');
+	clearok(cw, TRUE);
+	touchwin(cw);
+    }
+    return TRUE;
+}
+
+/*
+ * pick_up:
+ *	Add something to characters pack.
+ */
+void
+pick_up(int ch)
+{
+    switch(ch)
+    {
+	case GOLD:
+	    money();
+	    break;
+	default:
+	    debug("Where did you pick that up???");
+	case ARMOR:
+	case POTION:
+	case FOOD:
+	case WEAPON:
+	case SCROLL:	
+	case AMULET:
+	case RING:
+	case STICK:
+	    add_pack(NULL, FALSE);
+	    break;
+    }
+}
+
+/*
+ * picky_inven:
+ *	Allow player to inventory a single item
+ */
+void
+picky_inven()
+{
+    struct linked_list *item;
+    int ch, mch;
+
+    if (pack == NULL)
+	msg("You aren't carrying anything");
+    else if (next(pack) == NULL)
+	msg("a) %s", inv_name((struct object *) ldata(pack), FALSE));
+    else
+    {
+	msg(terse ? "Item: " : "Which item do you wish to inventory: ");
+	mpos = 0;
+	if ((mch = readchar(cw)) == ESCAPE)
+	{
+	    msg("");
+	    return;
+	}
+	for (ch = 'a', item = pack; item != NULL; item = next(item), ch++)
+	    if (ch == mch)
+	    {
+		msg("%c) %s",ch,inv_name((struct object *) ldata(item), FALSE));
+		return;
+	    }
+	if (!terse)
+	    msg("'%s' not in pack", unctrl(mch));
+	msg("Range is 'a' to '%c'", --ch);
+    }
+}
+
+/*
+ * get_item:
+ *	pick something out of a pack for a purpose
+ */
+struct linked_list *
+get_item(char *purpose, int type)
+{
+    struct linked_list *obj;
+    int ch, och;
+
+    if (pack == NULL)
+	msg("You aren't carrying anything.");
+    else
+    {
+	for (;;)
+	{
+	    if (!terse)
+		addmsg("Which object do you want to ");
+	    addmsg(purpose);
+	    if (terse)
+		addmsg(" what");
+	    msg("? (* for list): ");
+	    ch = readchar(cw);
+	    mpos = 0;
+	    /*
+	     * Give the poor player a chance to abort the command
+	     */
+	    if (ch == ESCAPE || ch == CTRL('G'))
+	    {
+		after = FALSE;
+		msg("");
+		return NULL;
+	    }
+	    if (ch == '*')
+	    {
+		mpos = 0;
+		if (inventory(pack, type) == 0)
+		{
+		    after = FALSE;
+		    return NULL;
+		}
+		continue;
+	    }
+	    for (obj = pack, och = 'a'; obj != NULL; obj = next(obj), och++)
+		if (ch == och)
+		    break;
+	    if (obj == NULL)
+	    {
+		msg("Please specify a letter between 'a' and '%c'", och-1);
+		continue;
+	    }
+	    else 
+		return obj;
+	}
+    }
+    return NULL;
+}
+
+int
+pack_char(struct object *obj)
+{
+    struct linked_list *item;
+    int c;
+
+    c = 'a';
+    for (item = pack; item != NULL; item = next(item))
+	if ((struct object *) ldata(item) == obj)
+	    return c;
+	else
+	    c++;
+    return 'z';
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rogue3/passages.c	Tue Oct 13 13:33:34 2009 +0000
@@ -0,0 +1,289 @@
+/*
+ * Draw the connecting passages
+ *
+ * @(#)passages.c	3.4 (Berkeley) 6/15/81
+ *
+ * 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 <stdlib.h>
+#include "curses.h"
+#include "rogue.h"
+
+/*
+ * do_passages:
+ *	Draw all the passages on a level.
+ */
+
+void
+do_passages()
+{
+    struct rdes *r1, *r2;
+    int i, j;
+    int roomcount;
+    static struct rdes
+    {
+	bool	conn[MAXROOMS];		/* possible to connect to room i? */
+	bool	isconn[MAXROOMS];	/* connection been made to room i? */
+	bool	ingraph;		/* this room in graph already? */
+    } rdes[MAXROOMS] = {
+	{ { 0, 1, 0, 1, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 },
+	{ { 1, 0, 1, 0, 1, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 },
+	{ { 0, 1, 0, 0, 0, 1, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 },
+	{ { 1, 0, 0, 0, 1, 0, 1, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 },
+	{ { 0, 1, 0, 1, 0, 1, 0, 1, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 },
+	{ { 0, 0, 1, 0, 1, 0, 0, 0, 1 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 },
+	{ { 0, 0, 0, 1, 0, 0, 0, 1, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 },
+	{ { 0, 0, 0, 0, 1, 0, 1, 0, 1 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 },
+	{ { 0, 0, 0, 0, 0, 1, 0, 1, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 },
+    };
+
+    /*
+     * reinitialize room graph description
+     */
+    for (r1 = rdes; r1 <= &rdes[MAXROOMS-1]; r1++)
+    {
+	for (j = 0; j < MAXROOMS; j++)
+	    r1->isconn[j] = FALSE;
+	r1->ingraph = FALSE;
+    }
+
+    /*
+     * starting with one room, connect it to a random adjacent room and
+     * then pick a new room to start with.
+     */
+    roomcount = 1;
+    r1 = &rdes[rnd(MAXROOMS)];
+    r1->ingraph = TRUE;
+    do
+    {
+	/*
+	 * find a room to connect with
+	 */
+	j = 0;
+	for (i = 0; i < MAXROOMS; i++)
+	    if (r1->conn[i] && !rdes[i].ingraph && rnd(++j) == 0)
+		r2 = &rdes[i];
+	/*
+	 * if no adjacent rooms are outside the graph, pick a new room
+	 * to look from
+	 */
+	if (j == 0)
+	{
+	    do
+		r1 = &rdes[rnd(MAXROOMS)];
+	    until (r1->ingraph);
+	}
+	/*
+	 * otherwise, connect new room to the graph, and draw a tunnel
+	 * to it
+	 */
+	else
+	{
+	    r2->ingraph = TRUE;
+	    i = (int)(r1 - rdes);
+	    j = (int)(r2 - rdes);
+	    conn(i, j);
+	    r1->isconn[j] = TRUE;
+	    r2->isconn[i] = TRUE;
+	    roomcount++;
+	}
+    } while (roomcount < MAXROOMS);
+
+    /*
+     * attempt to add passages to the graph a random number of times so
+     * that there isn't just one unique passage through it.
+     */
+    for (roomcount = rnd(5); roomcount > 0; roomcount--)
+    {
+	r1 = &rdes[rnd(MAXROOMS)];	/* a random room to look from */
+	/*
+	 * find an adjacent room not already connected
+	 */
+	j = 0;
+	for (i = 0; i < MAXROOMS; i++)
+	    if (r1->conn[i] && !r1->isconn[i] && rnd(++j) == 0)
+		r2 = &rdes[i];
+	/*
+	 * if there is one, connect it and look for the next added
+	 * passage
+	 */
+	if (j != 0)
+	{
+	    i = (int)(r1 - rdes);
+	    j = (int)(r2 - rdes);
+	    conn(i, j);
+	    r1->isconn[j] = TRUE;
+	    r2->isconn[i] = TRUE;
+	}
+    }
+}
+
+/*
+ * conn:
+ *	Draw a corridor from a room in a certain direction.
+ */
+
+void
+conn(int r1, int r2)
+{
+    struct room *rpf, *rpt;
+    int rmt;
+    int distance, turn_spot, turn_distance;
+    int rm;
+    int direc;
+    coord pdelta, curr, turn_delta, spos, epos;
+
+    if (r1 < r2)
+    {
+	rm = r1;
+	if (r1 + 1 == r2)
+	    direc = 'r';
+	else
+	    direc = 'd';
+    }
+    else
+    {
+	rm = r2;
+	if (r2 + 1 == r1)
+	    direc = 'r';
+	else
+	    direc = 'd';
+    }
+    rpf = &rooms[rm];
+    /*
+     * Set up the movement variables, in two cases:
+     * first drawing one down.
+     */
+    if (direc == 'd')
+    {
+	rmt = rm + 3;				/* room # of dest */
+	rpt = &rooms[rmt];			/* room pointer of dest */
+	pdelta.x = 0;				/* direction of move */
+	pdelta.y = 1;
+	spos.x = rpf->r_pos.x;			/* start of move */
+	spos.y = rpf->r_pos.y;
+	epos.x = rpt->r_pos.x;			/* end of move */
+	epos.y = rpt->r_pos.y;
+	if (!(rpf->r_flags & ISGONE))		/* if not gone pick door pos */
+	{
+	    spos.x += rnd(rpf->r_max.x-2)+1;
+	    spos.y += rpf->r_max.y-1;
+	}
+	if (!(rpt->r_flags & ISGONE))
+	    epos.x += rnd(rpt->r_max.x-2)+1;
+	distance = abs(spos.y - epos.y) - 1;	/* distance to move */
+	turn_delta.y = 0;			/* direction to turn */
+	turn_delta.x = (spos.x < epos.x ? 1 : -1);
+	turn_distance = abs(spos.x - epos.x);	/* how far to turn */
+	turn_spot = rnd(distance-1) + 1;		/* where turn starts */
+    }
+    else if (direc == 'r')			/* setup for moving right */
+    {
+	rmt = rm + 1;
+	rpt = &rooms[rmt];
+	pdelta.x = 1;
+	pdelta.y = 0;
+	spos.x = rpf->r_pos.x;
+	spos.y = rpf->r_pos.y;
+	epos.x = rpt->r_pos.x;
+	epos.y = rpt->r_pos.y;
+	if (!(rpf->r_flags & ISGONE))
+	{
+	    spos.x += rpf->r_max.x-1;
+	    spos.y += rnd(rpf->r_max.y-2)+1;
+	}
+	if (!(rpt->r_flags & ISGONE))
+	    epos.y += rnd(rpt->r_max.y-2)+1;
+	distance = abs(spos.x - epos.x) - 1;
+	turn_delta.y = (spos.y < epos.y ? 1 : -1);
+	turn_delta.x = 0;
+	turn_distance = abs(spos.y - epos.y);
+	turn_spot = rnd(distance-1) + 1;
+    }
+    else
+	fatal("error in connection tables");
+    /*
+     * Draw in the doors on either side of the passage or just put #'s
+     * if the rooms are gone.
+     */
+    if (!(rpf->r_flags & ISGONE)) door(rpf, &spos);
+    else
+    {
+	cmov(spos);
+	addch('#');
+    }
+    if (!(rpt->r_flags & ISGONE)) door(rpt, &epos);
+    else
+    {
+	cmov(epos);
+	addch('#');
+    }
+    /*
+     * Get ready to move...
+     */
+    curr.x = spos.x;
+    curr.y = spos.y;
+    while(distance)
+    {
+	/*
+	 * Move to new position
+	 */
+	curr.x += pdelta.x;
+	curr.y += pdelta.y;
+	/*
+	 * Check if we are at the turn place, if so do the turn
+	 */
+	if (distance == turn_spot && turn_distance > 0)
+	    while(turn_distance--)
+	    {
+		cmov(curr);
+		addch(PASSAGE);
+		curr.x += turn_delta.x;
+		curr.y += turn_delta.y;
+	    }
+	/*
+	 * Continue digging along
+	 */
+	cmov(curr);
+	addch(PASSAGE);
+	distance--;
+    }
+    curr.x += pdelta.x;
+    curr.y += pdelta.y;
+    if (!ce(curr, epos))
+	msg("Warning, connectivity problem on this level.");
+}
+
+/*
+ * Add a door or possibly a secret door
+ * also enters the door in the exits array of the room.
+ */
+
+void
+door(struct room *rm, coord *cp)
+{
+    cmov(*cp);
+    addch( (rnd(10) < level - 1 && rnd(100) < 20 ? SECRETDOOR : DOOR) );
+    rm->r_exit[rm->r_nexits++] = *cp;
+}
+
+/*
+ * add_pass:
+ *	add the passages to the current window (wizard command)
+ */
+
+void
+add_pass()
+{
+    int y, x, ch;
+
+    for (y = 1; y < LINES - 2; y++)
+	for (x = 0; x < COLS; x++)
+	    if ((ch=mvinch(y, x)) == PASSAGE || ch == DOOR || ch == SECRETDOOR)
+		mvwaddch(cw, y, x, ch);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rogue3/potions.c	Tue Oct 13 13:33:34 2009 +0000
@@ -0,0 +1,212 @@
+/*
+ * 	@(#)potions.c	3.1	3.1	5/7/81
+ * Function(s) for dealing with potions
+ *
+ * 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 "curses.h"
+#include <stdlib.h>
+#include <string.h>
+#include "rogue.h"
+
+void
+quaff()
+{
+    struct object *obj;
+    struct linked_list *item, *titem;
+    struct thing *th;
+    char buf[80];
+
+    item = get_item("quaff", POTION);
+    /*
+     * Make certain that it is somethings that we want to drink
+     */
+    if (item == NULL)
+	return;
+    obj = (struct object *) ldata(item);
+    if (obj->o_type != POTION)
+    {
+	if (!terse)
+	    msg("Yuk! Why would you want to drink that?");
+	else
+	    msg("That's undrinkable");
+	return;
+    }
+    if (obj == cur_weapon)
+	cur_weapon = NULL;
+
+    /*
+     * Calculate the effect it has on the poor guy.
+     */
+    switch(obj->o_which)
+    {
+	case P_CONFUSE:
+	    if (off(player, ISHUH))
+		msg("Wait, what's going on here. Huh? What? Who?");
+
+	    if (on(player, ISHUH))
+		lengthen(unconfuse, rnd(8)+HUHDURATION);
+	    else
+	        fuse(unconfuse, 0, rnd(8)+HUHDURATION, AFTER);
+
+	    player.t_flags |= ISHUH;
+	    p_know[P_CONFUSE] = TRUE;
+	when P_POISON:
+	    if (!ISWEARING(R_SUSTSTR))
+	    {
+		chg_str(-(rnd(3)+1));
+		msg("You feel very sick now.");
+	    }
+	    else
+		msg("You feel momentarily sick");
+	    p_know[P_POISON] = TRUE;
+	when P_HEALING:
+	    if ((pstats.s_hpt += roll(pstats.s_lvl, 4)) > max_hp)
+		pstats.s_hpt = ++max_hp;
+	    msg("You begin to feel better.");
+	    sight();
+	    p_know[P_HEALING] = TRUE;
+	when P_STRENGTH:
+	    msg("You feel stronger, now.  What bulging muscles!");
+	    chg_str(1);
+	    p_know[P_STRENGTH] = TRUE;
+	when P_MFIND:
+	    /*
+	     * Potion of monster detection, if there are monters, detect them
+	     */
+	    if (mlist != NULL)
+	    {
+		wclear(hw);
+		overwrite(mw, hw);
+		show_win(hw,
+		    "You begin to sense the presence of monsters.--More--");
+		p_know[P_MFIND] = TRUE;
+	    }
+	    else
+		msg("You have a strange feeling for a moment, then it passes.");
+	when P_TFIND:
+	    /*
+	     * Potion of magic detection.  Show the potions and scrolls
+	     */
+	    if (lvl_obj != NULL)
+	    {
+		struct linked_list *mobj;
+		struct object *tp;
+		int show;
+
+		show = FALSE;
+		wclear(hw);
+		for (mobj = lvl_obj; mobj != NULL; mobj = next(mobj))
+		{
+		    tp = (struct object *) ldata(mobj);
+		    if (is_magic(tp))
+		    {
+			show = TRUE;
+			mvwaddch(hw, tp->o_pos.y, tp->o_pos.x, MAGIC);
+		    }
+		    p_know[P_TFIND] = TRUE;
+		}
+		for (titem = mlist; titem != NULL; titem = next(titem))
+		{
+		    struct linked_list *pitem;
+
+		    th = (struct thing *) ldata(titem);
+		    for (pitem = th->t_pack; pitem != NULL; pitem = next(pitem))
+		    {
+			if (is_magic(OBJPTR(pitem)))
+			{
+			    show = TRUE;
+			    mvwaddch(hw, th->t_pos.y, th->t_pos.x, MAGIC);
+			}
+			p_know[P_TFIND] = TRUE;
+		    }
+		}
+		if (show)
+		{
+		    show_win(hw, 
+			"You sense the presence of magic on this level.--More--");
+		    break;
+		}
+	    }
+	    msg("You have a strange feeling for a moment, then it passes.");
+	when P_PARALYZE:
+	    msg("You can't move.");
+	    no_command = HOLDTIME;
+	    p_know[P_PARALYZE] = TRUE;
+	when P_SEEINVIS:
+	    msg("This potion tastes like %s juice.", fruit);
+	    if (off(player, CANSEE))
+	    {
+		player.t_flags |= CANSEE;
+		fuse(unsee, 0, SEEDURATION, AFTER);
+		light(&hero);
+	    }
+	    sight();
+	when P_RAISE:
+	    msg("You suddenly feel much more skillful");
+	    p_know[P_RAISE] = TRUE;
+	    raise_level();
+	when P_XHEAL:
+	    if ((pstats.s_hpt += roll(pstats.s_lvl, 8)) > max_hp)
+		pstats.s_hpt = ++max_hp;
+	    msg("You begin to feel much better.");
+	    p_know[P_XHEAL] = TRUE;
+	    sight();
+	when P_HASTE:
+	    add_haste(TRUE);
+	    msg("You feel yourself moving much faster.");
+	    p_know[P_HASTE] = TRUE;
+	when P_RESTORE:
+	    msg("Hey, this tastes great.  It make you feel warm all over.");
+	    if (pstats.s_str.st_str < max_stats.s_str.st_str ||
+		(pstats.s_str.st_str == 18 &&
+		 pstats.s_str.st_add < max_stats.s_str.st_add))
+	    pstats.s_str = max_stats.s_str;
+	when P_BLIND:
+	    msg("A cloak of darkness falls around you.");
+	    if (off(player, ISBLIND))
+	    {
+		player.t_flags |= ISBLIND;
+		fuse(sight, 0, SEEDURATION, AFTER);
+		look(FALSE);
+	    }
+	    p_know[P_BLIND] = TRUE;
+	when P_NOP:
+	    msg("This potion tastes extremely dull.");
+	otherwise:
+	    msg("What an odd tasting potion!");
+	    return;
+    }
+    status();
+    if (p_know[obj->o_which] && p_guess[obj->o_which])
+    {
+	free(p_guess[obj->o_which]);
+	p_guess[obj->o_which] = NULL;
+    }
+    else if (!p_know[obj->o_which] && askme && p_guess[obj->o_which] == NULL)
+    {
+	msg(terse ? "Call it: " : "What do you want to call it? ");
+	if (get_str(buf, cw) == NORM)
+	{
+	    p_guess[obj->o_which] = malloc((unsigned int) strlen(buf) + 1);
+	    if (p_guess[obj->o_which] != NULL)
+		strcpy(p_guess[obj->o_which], buf);
+	}
+    }
+    /*
+     * Throw the item away
+     */
+    inpack--;
+    if (obj->o_count > 1)
+	obj->o_count--;
+    else
+    {
+	detach(pack, item);
+        discard(item);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rogue3/readme36.html	Tue Oct 13 13:33:34 2009 +0000
@@ -0,0 +1,78 @@
+<html>
+<head>
+<title>ROGUE</title>
+</head>
+<body>
+
+<h1 align=center>ROGUE 3.6</h1>
+
+<hr>
+
+<h2>NAME</h2>
+<blockquote>
+	<p>rogue36 &minus; Exploring The Dungeons of Doom</p>
+</blockquote>
+
+<h2>SYNOPSIS</h2>
+<blockquote>
+	<p><b>rogue36</b> [ <i>save_file</i> ]</p>
+</blockquote>
+
+<h2>DESCRIPTION</h2>
+<blockquote>
+
+	<p align="justify"><u>Rogue</u> is a computer fantasy game with a new twist. It is crt oriented and the object of the game is to survive the attacks of various 
+	monsters and get a lot of gold, rather than the puzzle solving orientation
+	of most computer fantasy games.</p>
+
+	<p align="justify">To get started you really only need to know two commands. 
+	The command ? will give you a list of the available commands and the command /
+	will identify the things you see on the screen.</p>
+
+	<p align="justify">To win the game (as opposed to merely playing to beat 
+	other people high scores) you must locate the Amulet of Yendor which is 
+	somewhere below the 20th level of the dungeon and get it out. Nobody has 
+	achieved this yet and if somebody does, they will probably go down in history
+	as a hero among heros.</p>
+
+	<p align="justify">When the game ends, either by your death, when you quit, 
+	or if you (by some miracle) manage to win, <u>rogue</u> will give you a list of the 
+	top-ten scorers. The scoring is based entirely upon how much gold you get.
+	There is a 10% penalty for getting yourself killed.</p>
+
+	<p align="justify">For more detailed directions, read the document A Guide 
+	to the Dungeons of Doom.</p>
+
+</blockquote>
+
+<h2>FILES</h2>
+<blockquote>
+	<table border="0" id="table1">
+		<tr>
+			<td>rogue36.scr</td>
+			<td width="50">&nbsp;</td>
+			<td>Score file</td>
+		</tr>
+		<tr>
+			<td>rogue36.sav</td>
+			<td>&nbsp;</td>
+			<td>Default save file</td>
+		</tr>
+	</table>
+</blockquote>
+
+<h2>SEE ALSO</h2>
+<p>Michael C. Toy, <u>A Guide to the Dungeons of Doom</u></p>
+
+<h2>BUGS</h2>
+<p>Probably infinite. Currently known bugs are: Sometimes you are still
+hungry even after you eat food and sometimes you get a monster on the
+screen in reverse video which may or may not cause a core dump.</p>
+
+<h2>COPYRIGHT</h2>
+Rogue: Exploring the Dungeons of Doom<br>
+Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman <br>
+All rights reserved.
+
+</body>
+</html>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rogue3/rings.c	Tue Oct 13 13:33:34 2009 +0000
@@ -0,0 +1,213 @@
+/*
+ * routines dealing specifically with rings
+ *
+ * @(#)rings.c	3.17 (Berkeley) 6/15/81
+ *
+ * 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 "curses.h"
+#include <stdlib.h>
+#include <string.h>
+#include "rogue.h"
+
+void
+ring_on()
+{
+    struct object *obj;
+    struct linked_list *item;
+    int ring;
+    str_t save_max;
+    char buf[80];
+
+    item = get_item("put on", RING);
+    /*
+     * Make certain that it is somethings that we want to wear
+     */
+    if (item == NULL)
+	return;
+    obj = (struct object *) ldata(item);
+    if (obj->o_type != RING)
+    {
+	if (!terse)
+	    msg("It would be difficult to wrap that around a finger");
+	else
+	    msg("Not a ring");
+	return;
+    }
+
+    /*
+     * find out which hand to put it on
+     */
+    if (is_current(obj))
+	return;
+
+    if (cur_ring[LEFT] == NULL && cur_ring[RIGHT] == NULL)
+    {
+	if ((ring = gethand()) < 0)
+	    return;
+    }
+    else if (cur_ring[LEFT] == NULL)
+	ring = LEFT;
+    else if (cur_ring[RIGHT] == NULL)
+	ring = RIGHT;
+    else
+    {
+	if (!terse)
+	    msg("You already have a ring on each hand");
+	else
+	    msg("Wearing two");
+	return;
+    }
+    cur_ring[ring] = obj;
+
+    /*
+     * Calculate the effect it has on the poor guy.
+     */
+    switch (obj->o_which)
+    {
+	case R_ADDSTR:
+	    save_max = max_stats.s_str;
+	    chg_str(obj->o_ac);
+	    max_stats.s_str = save_max;
+	    break;
+	case R_SEEINVIS:
+	    player.t_flags |= CANSEE;
+	    light(&hero);
+	    mvwaddch(cw, hero.y, hero.x, PLAYER);
+	    break;
+	case R_AGGR:
+	    aggravate();
+	    break;
+    }
+    status();
+
+    if (obj->o_which >= MAXRINGS)
+        return;
+
+    if (r_know[obj->o_which] && r_guess[obj->o_which])
+    {
+	free(r_guess[obj->o_which]);
+	r_guess[obj->o_which] = NULL;
+    }
+    else if (!r_know[obj->o_which] && askme && r_guess[obj->o_which] == NULL)
+    {
+	mpos = 0;
+	msg(terse ? "Call it: " : "What do you want to call it? ");
+	if (get_str(buf, cw) == NORM)
+	{
+	    r_guess[obj->o_which] = malloc(strlen(buf) + 1);
+	    if (r_guess[obj->o_which] != NULL)
+		strcpy(r_guess[obj->o_which], buf);
+	}
+	msg("");
+    }
+}
+
+void
+ring_off()
+{
+    int ring;
+    struct object *obj;
+
+    if (cur_ring[LEFT] == NULL && cur_ring[RIGHT] == NULL)
+    {
+	if (terse)
+	    msg("No rings");
+	else
+	    msg("You aren't wearing any rings");
+	return;
+    }
+    else if (cur_ring[LEFT] == NULL)
+	ring = RIGHT;
+    else if (cur_ring[RIGHT] == NULL)
+	ring = LEFT;
+    else
+	if ((ring = gethand()) < 0)
+	    return;
+    mpos = 0;
+    obj = cur_ring[ring];
+    if (obj == NULL)
+    {
+	msg("Not wearing such a ring");
+	return;
+    }
+    if (dropcheck(obj))
+	msg("Was wearing %s", inv_name(obj, TRUE));
+}
+
+int
+gethand()
+{
+    int c;
+
+    for (;;)
+    {
+	if (terse)
+	    msg("Left or Right ring? ");
+	else
+	    msg("Left hand or right hand? ");
+	if ((c = readchar(cw)) == 'l' || c == 'L')
+	    return LEFT;
+	else if (c == 'r' || c == 'R')
+	    return RIGHT;
+	else if (c == ESCAPE)
+	    return -1;
+	mpos = 0;
+	if (terse)
+	    msg("L or R");
+	else
+	    msg("Please type L or R");
+    }
+}
+
+/*
+ * how much food does this ring use up?
+ */
+int
+ring_eat(int hand)
+{
+    if (cur_ring[hand] == NULL)
+	return 0;
+    switch (cur_ring[hand]->o_which)
+    {
+	case R_REGEN:
+	    return 2;
+	case R_SUSTSTR:
+	    return 1;
+	case R_SEARCH:
+	    return (rnd(100) < 33);
+	case R_DIGEST:
+	    return -(rnd(100) < 50);
+	default:
+	    return 0;
+    }
+}
+
+/*
+ * print ring bonuses
+ */
+char *
+ring_num(struct object *obj)
+{
+    static char buf[5];
+
+    if (!(obj->o_flags & ISKNOW))
+	return "";
+    switch (obj->o_which)
+    {
+	case R_PROTECT:
+	case R_ADDSTR:
+	case R_ADDDAM:
+	case R_ADDHIT:
+	    buf[0] = ' ';
+	    strcpy(&buf[1], num(obj->o_ac, 0));
+	otherwise:
+	    return "";
+    }
+    return buf;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rogue3/rip.c	Tue Oct 13 13:33:34 2009 +0000
@@ -0,0 +1,407 @@
+/*
+ * File for the fun ends
+ * Death or a total win
+ *
+ * @(#)rip.c	3.13 (Berkeley) 6/16/81
+ *
+ * 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 <stdlib.h>
+#include <errno.h>
+#include <time.h>
+#include <signal.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <string.h>
+#include "curses.h"
+#include "machdep.h"
+#include "rogue.h"
+
+static char *rip[] = {
+"                       __________",
+"                      /          \\",
+"                     /    REST    \\",
+"                    /      IN      \\",
+"                   /     PEACE      \\",
+"                  /                  \\",
+"                  |                  |",
+"                  |                  |",
+"                  |   killed by a    |",
+"                  |                  |",
+"                  |       1980       |",
+"                 *|     *  *  *      | *",
+"         ________)/\\\\_//(\\/(/\\)/\\//\\/|_)_______",
+    0
+};
+
+char	*killname();
+
+/*
+ * death:
+ *	Do something really fun when he dies
+ */
+
+void
+death(int monst)
+{
+    char **dp = rip, *killer;
+    struct tm *lt;
+    time_t date;
+    char buf[80];
+
+    time(&date);
+    lt = localtime(&date);
+    clear();
+    move(8, 0);
+    while (*dp)
+	printw("%s\n", *dp++);
+    mvaddstr(14, 28-(((int)strlen(whoami)+1)/2), whoami);
+    purse -= purse/10;
+    sprintf(buf, "%d Au", purse);
+    mvaddstr(15, 28-(((int)strlen(buf)+1)/2), buf);
+    killer = killname(monst);
+    mvaddstr(17, 28-(((int)strlen(killer)+1)/2), killer);
+    mvaddstr(16, 33, vowelstr(killer));
+    sprintf(prbuf, "%4d", 1900+lt->tm_year);
+    mvaddstr(18, 26, prbuf);
+    move(LINES-1, 0);
+    draw(stdscr);
+    score(purse, 0, monst);
+    exit(0);
+}
+
+/*
+ * score -- figure score and post it.
+ */
+
+void
+open_score(void)
+{
+#ifdef SCOREFILE
+    char *scorefile = SCOREFILE;
+
+    if (scoreboard != NULL) {
+        rewind(scoreboard);
+        return;
+    }
+
+    scoreboard = fopen(scorefile, "r+");
+
+    if ((scoreboard == NULL) && (errno == ENOENT))
+    {
+        scoreboard = fopen(scorefile, "w+");
+        md_chmod(scorefile,0664);
+    }
+
+    if (scoreboard == NULL) {
+         fprintf(stderr, "Could not open %s for writing: %s\n", scorefile, strerror(errno));
+         fflush(stderr);
+    }
+#else
+    scoreboard = NULL;
+#endif
+}
+
+/* VARARGS2 */
+void
+score(int amount, int flags, int monst)
+{
+    static struct sc_ent {
+	int sc_score;
+	char sc_name[80];
+	int sc_flags;
+	int sc_level;
+	char sc_login[8];
+	int sc_monster;
+    } top_ten[10];
+    struct sc_ent *scp;
+    int i;
+    struct sc_ent *sc2;
+    FILE *outf;
+    char *killer;
+    int prflags = 0;
+    static char *reason[] = {
+	"killed",
+	"quit",
+	"A total winner",
+    };
+    char scoreline[100];
+    int rogue_ver = 0, scorefile_ver = 0;
+
+    /*
+     * Open file and read list
+     */
+
+    if (scoreboard == NULL)
+        return;
+    
+    outf = scoreboard;
+
+    for (scp = top_ten; scp <= &top_ten[9]; scp++)
+    {
+	scp->sc_score = 0;
+	for (i = 0; i < 80; i++)
+	    scp->sc_name[i] = rnd(255);
+	scp->sc_flags = RN;
+	scp->sc_level = RN;
+	scp->sc_monster = RN;
+	scp->sc_login[0] = '\0';
+    }
+
+    signal(SIGINT, SIG_DFL);
+    if ((flags != -1) && (flags != 1))
+    {
+	mvaddstr(LINES-1, 0, "[Press return to continue]");
+	draw(stdscr);
+	prbuf[0] = 0;
+	get_str(prbuf, stdscr);
+	endwin();
+    }
+    if (wizard)
+	if (strcmp(prbuf, "names") == 0)
+	    prflags = 1;
+	else if (strcmp(prbuf, "edit") == 0)
+	    prflags = 2;
+
+    md_lockfile(outf);
+
+    encread(scoreline, 100, outf);
+    (void) sscanf(scoreline, "R%d %d\n", &rogue_ver, &scorefile_ver);
+
+    if ((rogue_ver == 36) && (scorefile_ver == 2))
+        for(i = 0; i < 10; i++)
+	{
+	    encread(&top_ten[i].sc_name, 80, outf);
+	    encread(&top_ten[i].sc_login, 8, outf);
+	    encread(scoreline, 100, outf);
+	    (void) sscanf(scoreline, " %d %d %d %d \n",
+		&top_ten[i].sc_score,  &top_ten[i].sc_flags,
+		&top_ten[i].sc_level,  &top_ten[i].sc_monster);
+	}
+
+    /*
+     * Insert her in list if need be
+     */
+    if (!waswizard)
+    {
+	for (scp = top_ten; scp <= &top_ten[9]; scp++)
+	    if (amount > scp->sc_score)
+		break;
+	if (scp <= &top_ten[9])
+	{
+	    for (sc2 = &top_ten[9]; sc2 > scp; sc2--)
+		*sc2 = *(sc2-1);
+	    scp->sc_score = amount;
+	    strcpy(scp->sc_name, whoami);
+	    scp->sc_flags = flags;
+	    if (flags == 2)
+		scp->sc_level = max_level;
+	    else
+		scp->sc_level = level;
+	    scp->sc_monster = monst;
+	    strncpy(scp->sc_login, md_getusername(), 8);
+	}
+    }
+    /*
+     * Print the list
+     */
+    if (flags != -1)
+	printf("\n\n\n");
+    printf("Top Ten Adventurers:\nRank\tScore\tName\n");
+    for (scp = top_ten; scp <= &top_ten[9]; scp++) {
+	if (scp->sc_score) {
+	    printf("%d\t%d\t%s: %s on level %d", scp - top_ten + 1,
+		scp->sc_score, scp->sc_name, reason[scp->sc_flags],
+		scp->sc_level);
+	    if (scp->sc_flags == 0) {
+		printf(" by a");
+		killer = killname(scp->sc_monster);
+		if (*killer == 'a' || *killer == 'e' || *killer == 'i' ||
+		    *killer == 'o' || *killer == 'u')
+			putchar('n');
+		printf(" %s", killer);
+	    }
+	    if (prflags == 1)
+	    {
+		printf(" (%s)", scp->sc_login);
+		putchar('\n');
+	    }
+	    else if (prflags == 2)
+	    {
+		fflush(stdout);
+		fgets(prbuf,80,stdin);
+		if (prbuf[0] == 'd')
+		{
+		    for (sc2 = scp; sc2 < &top_ten[9]; sc2++)
+			*sc2 = *(sc2 + 1);
+		    top_ten[9].sc_score = 0;
+		    for (i = 0; i < 80; i++)
+			top_ten[9].sc_name[i] = rnd(255);
+		    top_ten[9].sc_flags = RN;
+		    top_ten[9].sc_level = RN;
+		    top_ten[9].sc_monster = RN;
+		    scp--;
+		}
+	    }
+	    else
+		printf(".\n");
+	}
+    }
+
+    /*
+     * Update the list file
+     */
+
+    rewind(outf);
+
+    strcpy(scoreline, "R36 2\n");
+    encwrite(scoreline, 100, outf);
+
+    for(i = 0; i < 10; i++)
+    {
+        encwrite(&top_ten[i].sc_name, 80, outf);
+        encwrite(&top_ten[i].sc_login, 8, outf);
+        sprintf(scoreline, " %d %d %d %d \n",
+            top_ten[i].sc_score,  top_ten[i].sc_flags,
+            top_ten[i].sc_level,  top_ten[i].sc_monster);
+        encwrite(scoreline, 100, outf);
+    }
+
+    md_unlockfile(outf);
+
+    fclose(outf);
+}
+
+void 
+total_winner()
+{
+    struct linked_list *item;
+    struct object *obj;
+    int worth = 0;
+    int c;
+    int oldpurse;
+
+    clear();
+    standout();
+    addstr("                                                               \n");
+    addstr("  @   @               @   @           @          @@@  @     @  \n");
+    addstr("  @   @               @@ @@           @           @   @     @  \n");
+    addstr("  @   @  @@@  @   @   @ @ @  @@@   @@@@  @@@      @  @@@    @  \n");
+    addstr("   @@@@ @   @ @   @   @   @     @ @   @ @   @     @   @     @  \n");
+    addstr("      @ @   @ @   @   @   @  @@@@ @   @ @@@@@     @   @     @  \n");
+    addstr("  @   @ @   @ @  @@   @   @ @   @ @   @ @         @   @  @     \n");
+    addstr("   @@@   @@@   @@ @   @   @  @@@@  @@@@  @@@     @@@   @@   @  \n");
+    addstr("                                                               \n");
+    addstr("     Congratulations, you have made it to the light of day!    \n");
+    standend();
+    addstr("\nYou have joined the elite ranks of those who have escaped the\n");
+    addstr("Dungeons of Doom alive.  You journey home and sell all your loot at\n");
+    addstr("a great profit and are admitted to the fighters guild.\n");
+    mvaddstr(LINES - 1, 0, "--Press space to continue--");
+    refresh();
+    wait_for(stdscr, ' ');
+    clear();
+    mvaddstr(0, 0, "   Worth  Item");
+    oldpurse = purse;
+    for (c = 'a', item = pack; item != NULL; c++, item = next(item))
+    {
+	obj = (struct object *) ldata(item);
+	switch (obj->o_type)
+	{
+	    case FOOD:
+		worth = 2 * obj->o_count;
+	    when WEAPON:
+		switch (obj->o_which)
+		{
+		    case MACE: worth = 8;
+		    when SWORD: worth = 15;
+		    when BOW: worth = 75;
+		    when ARROW: worth = 1;
+		    when DAGGER: worth = 2;
+		    when ROCK: worth = 1;
+		    when TWOSWORD: worth = 30;
+		    when SLING: worth = 1;
+		    when DART: worth = 1;
+		    when CROSSBOW: worth = 15;
+		    when BOLT: worth = 1;
+		    when SPEAR: worth = 2;
+		    otherwise: worth = 0;
+		}
+		worth *= (1 + (10 * obj->o_hplus + 10 * obj->o_dplus));
+		worth *= obj->o_count;
+		obj->o_flags |= ISKNOW;
+	    when ARMOR:
+		switch (obj->o_which)
+		{
+		    case LEATHER: worth = 5;
+		    when RING_MAIL: worth = 30;
+		    when STUDDED_LEATHER: worth = 15;
+		    when SCALE_MAIL: worth = 3;
+		    when CHAIN_MAIL: worth = 75;
+		    when SPLINT_MAIL: worth = 80;
+		    when BANDED_MAIL: worth = 90;
+		    when PLATE_MAIL: worth = 400;
+		    otherwise: worth = 0;
+		}
+		if (obj->o_which >= MAXARMORS)
+                    break;
+		worth *= (1 + (10 * (a_class[obj->o_which] - obj->o_ac)));
+		obj->o_flags |= ISKNOW;
+	    when SCROLL:
+		s_know[obj->o_which] = TRUE;
+		worth = s_magic[obj->o_which].mi_worth;
+		worth *= obj->o_count;
+	    when POTION:
+		p_know[obj->o_which] = TRUE;
+		worth = p_magic[obj->o_which].mi_worth;
+		worth *= obj->o_count;
+	    when RING:
+		obj->o_flags |= ISKNOW;
+		r_know[obj->o_which] = TRUE;
+		worth = r_magic[obj->o_which].mi_worth;
+		if (obj->o_which == R_ADDSTR || obj->o_which == R_ADDDAM ||
+		    obj->o_which == R_PROTECT || obj->o_which == R_ADDHIT)
+			if (obj->o_ac > 0)
+			    worth += obj->o_ac * 20;
+			else
+			    worth = 50;
+	    when STICK:
+		obj->o_flags |= ISKNOW;
+		ws_know[obj->o_which] = TRUE;
+		worth = ws_magic[obj->o_which].mi_worth;
+		worth += 20 * obj->o_charges;
+	    when AMULET:
+		worth = 1000;
+	}
+	mvprintw(c - 'a' + 1, 0, "%c) %5d  %s", c, worth, inv_name(obj, FALSE));
+	purse += worth;
+    }
+    mvprintw(c - 'a' + 1, 0,"   %5d  Gold Peices          ", oldpurse);
+    refresh();
+    score(purse, 2, 0);
+    exit(0);
+}
+
+char *
+killname(int monst)
+{
+    if (isupper(monst))
+	return monsters[monst-'A'].m_name;
+    else
+	switch (monst)
+	{
+	    case 'a':
+		return "arrow";
+	    case 'd':
+		return "dart";
+	    case 'b':
+		return "bolt";
+	}
+    return("");
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rogue3/rogue.6	Tue Oct 13 13:33:34 2009 +0000
@@ -0,0 +1,58 @@
+.TH ROGUE 6
+.UC
+.SH NAME
+rogue \- Exploring The Dungeons of Doom
+.SH SYNOPSIS
+.B rogue
+[
+.I save_file
+]
+.SH DESCRIPTION
+.PP
+.I Rogue
+is a computer fantasy game with a new twist.  It is crt oriented and the
+object of the game is to survive the attacks of various monsters and get
+a lot of gold, rather than the puzzle solving orientation of most computer
+fantasy games.
+.PP
+To get started you really only need to know two commands.  The command
+.B ?
+will give you a list of the available commands and the command
+.B /
+will identify the things you see on the screen.
+.PP
+To win the game (as opposed to merely playing to beat other people high
+scores) you must locate the Amulet of Yendor which is somewhere below
+the 20th level of the dungeon and get it out.  Nobody has achieved this
+yet and if somebody does, they will probably go down in history as a hero
+among heros.
+.PP
+When the game ends, either by your death, when you quit, or if you (by
+some miracle) manage to win,
+.I rogue
+will give you alist of the top-ten scorers.  The scoring is based entirely
+upon how much gold you get.  There is a 10% penalty for getting yourself
+killed.
+.PP
+For more detailed directions, read the document
+.I "A Guide to the Dungeons of Doom."
+.SH FILES
+.ta 2i
+rogue36.scr                  Score file
+.br
+~/rogue36.sav                Default save file
+.DT
+.SH SEE ALSO
+Michael C. Toy,
+.I "A Guide to the Dungeons of Doom"
+.SH BUGS
+.PP
+Probably infinite.  Currently known bugs are: Sometimes you are still hungry
+even after you eat food and sometimes you get a monster on the screen in
+reverse video which may or may not cause a core dump.
+.SH COPYRIGHT
+Rogue: Exploring the Dungeons of Doom
+.br
+Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
+.br
+All rights reserved.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rogue3/rogue.h	Tue Oct 13 13:33:34 2009 +0000
@@ -0,0 +1,685 @@
+/*
+ * Rogue definitions and variable declarations
+ *
+ * @(#)rogue.h	3.38 (Berkeley) 6/15/81
+ *
+ * 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 "mdport.h"
+
+/*
+ * Maximum number of different things
+ */
+#define MAXROOMS 9
+#define MAXTHINGS 9
+#define MAXOBJ 9
+#define MAXPACK 23
+#define MAXTRAPS 10
+#define	NUMTHINGS 7	/* number of types of things (scrolls, rings, etc.) */
+
+/*
+ * return values for get functions
+ */
+#define	NORM	0	/* normal exit */
+#define	QUIT	1	/* quit option setting */
+#define	MINUS	2	/* back up one option */
+
+/*
+ * All the fun defines
+ */
+#define next(ptr) (*ptr).l_next
+#define prev(ptr) (*ptr).l_prev
+#define ldata(ptr) (*ptr).l_data
+#define inroom(rp, cp) (\
+    (cp)->x <= (rp)->r_pos.x + ((rp)->r_max.x - 1) && (rp)->r_pos.x <= (cp)->x \
+ && (cp)->y <= (rp)->r_pos.y + ((rp)->r_max.y - 1) && (rp)->r_pos.y <= (cp)->y)
+#define winat(y, x) (mvwinch(mw,y,x)==' '?mvwinch(stdscr,y,x):winch(mw))
+#define debug if (wizard) msg
+#define RN (((seed = seed*11109+13849) & 0x7fff) >> 1)
+#define unc(cp) (cp).y, (cp).x
+#define cmov(xy) move((xy).y, (xy).x)
+#define DISTANCE(y1, x1, y2, x2) ((x2 - x1)*(x2 - x1) + (y2 - y1)*(y2 - y1))
+#define OBJPTR(what)    (struct object *)((*what).l_data)
+#define THINGPTR(what)  (struct thing *)((*what).l_data)
+#define when break;case
+#define otherwise break;default
+#define until(expr) while(!(expr))
+#define ce(a, b) ((a).x == (b).x && (a).y == (b).y)
+#define draw(window) wrefresh(window)
+#define hero player.t_pos
+#define pstats player.t_stats
+#define pack player.t_pack
+#define attach(a,b) _attach(&a,b)
+#define detach(a,b) _detach(&a,b)
+#define free_list(a) _free_list(&a)
+#ifndef max
+#define max(a, b) ((a) > (b) ? (a) : (b))
+#endif
+#define on(thing, flag) (((thing).t_flags & flag) != 0)
+#define off(thing, flag) (((thing).t_flags & flag) == 0)
+#undef  CTRL
+#define CTRL(ch) (ch & 037)
+#define ALLOC(x) malloc((unsigned int) x)
+#define FREE(x) free((char *) x)
+#define	EQSTR(a, b, c)	(strncmp(a, b, c) == 0)
+#define GOLDCALC (rnd(50 + 10 * level) + 2)
+#define ISRING(h,r) (cur_ring[h] != NULL && cur_ring[h]->o_which == r)
+#define ISWEARING(r) (ISRING(LEFT, r) || ISRING(RIGHT, r))
+#define newgrp() ++group
+#define o_charges o_ac
+#define ISMULT(type) (type == POTION || type == SCROLL || type == FOOD)
+
+/*
+ * Things that appear on the screens
+ */
+#define PASSAGE '#'
+#define DOOR '+'
+#define FLOOR '.'
+#define PLAYER '@'
+#define TRAP '^'
+#define TRAPDOOR '>'
+#define ARROWTRAP '{'
+#define SLEEPTRAP '$'
+#define BEARTRAP '}'
+#define TELTRAP '~'
+#define DARTTRAP '`'
+#define SECRETDOOR '&'
+#define STAIRS '%'
+#define GOLD '*'
+#define POTION '!'
+#define SCROLL '?'
+#define MAGIC '$'
+#define FOOD ':'
+#define WEAPON ')'
+#define ARMOR ']'
+#define AMULET ','
+#define RING '='
+#define STICK '/'
+#define CALLABLE -1
+
+/*
+ * Various constants
+ */
+#define	PASSWD		"mTBellIQOsLNA"
+#define BEARTIME 3
+#define SLEEPTIME 5
+#define HEALTIME 30
+#define HOLDTIME 2
+#define STPOS 0
+#define WANDERTIME 70
+#define BEFORE 1
+#define AFTER 2
+#define HUHDURATION 20
+#define SEEDURATION 850
+#define HUNGERTIME 1300
+#define MORETIME 150
+#define STOMACHSIZE 2000
+#define ESCAPE 27
+#define LEFT 0
+#define RIGHT 1
+#define BOLT_LENGTH 6
+
+/*
+ * Save against things
+ */
+#define VS_POISON 00
+#define VS_PARALYZATION 00
+#define VS_DEATH 00
+#define VS_PETRIFICATION 01
+#define VS_BREATH 02
+#define VS_MAGIC  03
+
+/*
+ * Various flag bits
+ */
+#define ISDARK	0000001
+#define ISCURSED 000001
+#define ISBLIND 0000001
+#define ISGONE	0000002
+#define ISKNOW  0000002
+#define ISRUN	0000004
+#define ISFOUND 0000010
+#define ISINVIS 0000020
+#define ISMEAN  0000040
+#define ISGREED 0000100
+#define ISBLOCK 0000200
+#define ISHELD  0000400
+#define ISHUH   0001000
+#define ISREGEN 0002000
+#define CANHUH  0004000
+#define CANSEE  0010000
+#define ISMISL  0020000
+#define ISCANC	0020000
+#define ISMANY  0040000
+#define ISSLOW	0040000
+#define ISHASTE 0100000
+
+/*
+ * Potion types
+ */
+#define P_CONFUSE 0
+#define P_PARALYZE 1
+#define P_POISON 2
+#define P_STRENGTH 3
+#define P_SEEINVIS 4
+#define P_HEALING 5
+#define P_MFIND 6
+#define P_TFIND 7
+#define P_RAISE 8
+#define P_XHEAL 9
+#define P_HASTE 10
+#define P_RESTORE 11
+#define P_BLIND 12
+#define P_NOP 13
+#define MAXPOTIONS 14
+
+/*
+ * Scroll types
+ */
+#define S_CONFUSE 0
+#define S_MAP 1
+#define S_LIGHT 2
+#define S_HOLD 3
+#define S_SLEEP 4
+#define S_ARMOR 5
+#define S_IDENT 6
+#define S_SCARE 7
+#define S_GFIND 8
+#define S_TELEP 9
+#define S_ENCH 10
+#define S_CREATE 11
+#define S_REMOVE 12
+#define S_AGGR 13
+#define S_NOP 14
+#define S_GENOCIDE 15
+#define MAXSCROLLS 16
+
+/*
+ * Weapon types
+ */
+#define MACE 0
+#define SWORD 1
+#define BOW 2
+#define ARROW 3
+#define DAGGER 4
+#define ROCK 5
+#define TWOSWORD 6
+#define SLING 7
+#define DART 8
+#define CROSSBOW 9
+#define BOLT 10
+#define SPEAR 11
+#define MAXWEAPONS 12
+
+/*
+ * Armor types
+ */
+#define LEATHER 0
+#define RING_MAIL 1
+#define STUDDED_LEATHER 2
+#define SCALE_MAIL 3
+#define CHAIN_MAIL 4
+#define SPLINT_MAIL 5
+#define BANDED_MAIL 6
+#define PLATE_MAIL 7
+#define MAXARMORS 8
+
+/*
+ * Ring types
+ */
+#define R_PROTECT 0
+#define R_ADDSTR 1
+#define R_SUSTSTR 2
+#define R_SEARCH 3
+#define R_SEEINVIS 4
+#define R_NOP 5
+#define R_AGGR 6
+#define R_ADDHIT 7
+#define R_ADDDAM 8
+#define R_REGEN 9
+#define R_DIGEST 10
+#define R_TELEPORT 11
+#define R_STEALTH 12
+#define MAXRINGS 13
+
+/*
+ * Rod/Wand/Staff types
+ */
+
+#define WS_LIGHT 0
+#define WS_HIT 1
+#define WS_ELECT 2
+#define WS_FIRE 3
+#define WS_COLD 4
+#define WS_POLYMORPH 5
+#define WS_MISSILE 6
+#define WS_HASTE_M 7
+#define WS_SLOW_M 8
+#define WS_DRAIN 9
+#define WS_NOP 10
+#define WS_TELAWAY 11
+#define WS_TELTO 12
+#define WS_CANCEL 13
+#define MAXSTICKS 14
+
+/*
+ * Now we define the structures and types
+ */
+
+/*
+ * Help list
+ */
+
+struct h_list {
+    int h_ch;
+    char *h_desc;
+};
+
+extern struct h_list helpstr[];
+
+/*
+ * Coordinate data type
+ */
+typedef struct {
+    int x;
+    int y;
+} coord;
+
+typedef struct {
+    int st_str;
+    int st_add;
+} str_t;
+
+/*
+ * Linked list data type
+ */
+struct linked_list {
+    struct linked_list *l_next;
+    struct linked_list *l_prev;
+    char *l_data;			/* Various structure pointers */
+};
+
+/*
+ * Stuff about magic items
+ */
+
+struct magic_item {
+    char mi_name[30];
+    int mi_prob;
+    int mi_worth;
+};
+
+/*
+ * Room structure
+ */
+struct room {
+    coord r_pos;			/* Upper left corner */
+    coord r_max;			/* Size of room */
+    coord r_gold;			/* Where the gold is */
+    int r_goldval;			/* How much the gold is worth */
+    int r_flags;			/* Info about the room */
+    int r_nexits;			/* Number of exits */
+    coord r_exit[4];			/* Where the exits are */
+};
+
+/*
+ * Array of all traps on this level
+ */
+struct trap {
+    coord tr_pos;			/* Where trap is */
+    int tr_type;			/* What kind of trap */
+    int tr_flags;			/* Info about trap (i.e. ISFOUND) */
+};
+
+extern struct trap  traps[MAXTRAPS];
+
+/*
+ * Structure describing a fighting being
+ */
+struct stats {
+    str_t s_str;			/* Strength */
+    int s_exp;				/* Experience */
+    int s_lvl;				/* Level of mastery */
+    int s_arm;				/* Armor class */
+    int s_hpt;				/* Hit points */
+    char s_dmg[30];			/* String describing damage done */
+};
+
+/*
+ * Structure for monsters and player
+ */
+struct thing {
+    coord t_pos;			/* Position */
+    int t_turn;			/* If slowed, is it a turn to move */
+    int t_type;			/* What it is */
+    int t_disguise;			/* What mimic looks like */
+    int t_oldch;			/* Character that was where it was */
+    coord *t_dest;			/* Where it is running to */
+    int t_flags;			/* State word */
+    struct stats t_stats;		/* Physical description */
+    struct linked_list *t_pack;		/* What the thing is carrying */
+	int t_reserved;         /* reserved for save/restore code */
+};
+
+/*
+ * Array containing information on all the various types of mosnters
+ */
+struct monster {
+    char m_name[20];			/* What to call the monster */
+    int m_carry;			/* Probability of carrying something */
+    int m_flags;			/* Things about the monster */
+    struct stats m_stats;		/* Initial stats */
+};
+
+/*
+ * Structure for a thing that the rogue can carry
+ */
+
+struct object {
+    int o_type;				/* What kind of object it is */
+    coord o_pos;			/* Where it lives on the screen */
+    int o_launch;			/* What you need to launch it */
+    char o_damage[8];			/* Damage if used like sword */
+    char o_hurldmg[8];			/* Damage if thrown */
+    int o_count;			/* Count for plural objects */
+    int o_which;			/* Which object of a type it is */
+    int o_hplus;			/* Plusses to hit */
+    int o_dplus;			/* Plusses to damage */
+    int o_ac;				/* Armor class */
+    int o_flags;			/* Information about objects */
+    int o_group;			/* Group number for this object */
+};
+
+struct delayed_action {
+    int d_type;
+    void (*d_func)();
+    int d_arg;
+    int d_time;
+};
+
+/*
+ * Now all the global variables
+ */
+
+extern int                   a_chances[MAXARMORS];	/* Probabilities for armor */
+extern int                   a_class[MAXARMORS];	/* Armor class for various armors */
+extern char *                a_names[MAXARMORS];	/* Names of armor types */
+extern int                   after;			/* True if we want after daemons */
+extern int                   amulet;			/* He found the amulet */
+extern int                   askme;			/* Ask about unidentified things */
+extern int                   between;
+extern coord                 ch_ret;
+extern int                   count;			/* Number of times to repeat command */
+extern int                   cNCOLORS;
+extern int                   cNMETAL;
+extern int                   cNSTONES;
+extern int                   cNWOOD;
+extern struct object *       cur_armor;			/* What a well dresssed rogue wears */
+extern struct object *       cur_ring[2];		/* Which rings are being worn */
+extern struct object *       cur_weapon;		/* Which weapon he is weilding */
+extern WINDOW *              cw;			/* Window that the player sees */
+extern coord                 delta;			/* Change indicated to get_dir() */
+extern int                   dnum;			/* Dungeon number */
+extern int                   door_stop;			/* Stop running when we pass a door */
+extern struct delayed_action d_list[20];
+extern int                   fight_flush;		/* True if toilet input */
+extern char                  file_name[80];		/* Save file name */
+extern int                   firstmove;			/* First move after setting door_stop */
+extern int                   food_left;			/* Amount of food in hero's stomach */
+extern char                  fruit[80];			/* Favorite fruit */
+extern int                   fung_hit;			/* Number of time fungi has hit */
+extern int                   group;			/* Current group number */
+extern char                  home[];			/* User's home directory */
+extern WINDOW *              hw;			/* Used for the help command */
+extern char                  huh[80];			/* The last message printed */
+extern int                   hungry_state;		/* How hungry is he */
+extern int                   in_shell;			/* True if executing a shell */
+extern int                   inpack;			/* Number of things in pack */
+extern int                   jump;			/* Show running as series of jumps */
+extern int                   lastscore;			/* Score before this turn */
+extern int                   level;			/* What level rogue is on */
+extern char                  lvl_mons[27];
+extern struct linked_list *  lvl_obj;			/* List of objects on this level */
+extern int                   max_hp;			/* Player's max hit points */
+extern int                   max_level;			/* Deepest player has gone */
+extern struct stats          max_stats;			/* The maximum for the player */
+extern char *                metal[];
+extern struct linked_list *  mlist;			/* List of monsters on the level */
+extern struct monster        monsters[26];		/* The initial monster states */
+extern int                   mpos;			/* Where cursor is on top line */
+extern WINDOW *              mw;			/* Used to store mosnters */
+extern coord                 nh;
+extern int                   no_command;		/* Number of turns asleep */
+extern int                   no_food;			/* Number of levels without food */
+extern int                   no_move;			/* Number of turns held in place */
+extern int                   notify;			/* True if player wants to know */
+extern int                   ntraps;			/* Number of traps on this level */
+extern int                   num_checks;
+extern coord                 oldpos;			/* Position before last look() call */
+extern struct room *         oldrp;			/* Roomin(&oldpos) */
+extern char *                p_colors[MAXPOTIONS];	/* Colors of the potions */
+extern char *                p_guess[MAXPOTIONS];	/* Players guess at what potion is */
+extern int                   p_know[MAXPOTIONS];	/* Does he know what a potion does */
+extern struct magic_item     p_magic[MAXPOTIONS];	/* Names and chances for potions */
+extern struct thing          player;			/* The rogue */
+extern int                   playing;			/* True until he quits */
+extern unsigned char         prbuf[80];			/* Buffer for sprintfs */
+extern int                   purse;			/* How much gold the rogue has */
+extern int                   quiet;			/* Number of quiet turns */
+extern char *                r_guess[MAXRINGS];		/* Players guess at what ring is */
+extern int                   r_know[MAXRINGS];		/* Does he know what a ring does */
+extern struct magic_item     r_magic[MAXRINGS];		/* Names and chances for rings */
+extern char *                r_stones[MAXRINGS];	/* Stone settings of the rings */
+extern char *                rainbow[];
+extern char *                release;			/* Release number of rogue */
+extern struct room           rooms[MAXROOMS];		/* One for each room -- A level */
+extern int                   runch;			/* Direction player is running */
+extern int                   running;			/* True if player is running */
+extern int                   seed;			/* Random number seed */
+extern char *                s_guess[MAXSCROLLS];	/* Players guess at what scroll is */
+extern int                   s_know[MAXSCROLLS];	/* Does he know what a scroll does */
+extern struct magic_item     s_magic[MAXSCROLLS];	/* Names and chances for scrolls */
+extern char *                s_names[MAXSCROLLS];	/* Names of the scrolls */
+extern FILE *                scoreboard;
+extern int                   slow_invent;		/* Inventory one line at a time */
+extern char *                stones[];
+extern int                   take;			/* Thing the rogue is taking */
+extern int                   terse;			/* True if we should be int */
+extern struct magic_item     things[NUMTHINGS];		/* Chances for each type of item */
+extern int                   total;			/* Total dynamic memory bytes */
+extern char *                w_names[MAXWEAPONS];	/* Names of the various weapons */
+extern char                  wand_mons[27];
+extern int                   waswizard;			/* Was a wizard sometime */
+extern char                  whoami[80];		/* Name of player */
+extern int                   wizard;			/* True if allows wizard commands */
+extern char *                wood[];
+extern char *                ws_guess[MAXSTICKS];	/* Players guess at what wand is */
+extern int                   ws_know[MAXSTICKS];	/* Does he know what a stick does */
+extern char *                ws_made[MAXSTICKS];	/* What sticks are made of */
+extern struct magic_item     ws_magic[MAXSTICKS];	/* Names and chances for sticks */
+extern char *                ws_type[MAXSTICKS];	/* Is it a wand or a staff */
+
+void                    _attach(struct linked_list **list, struct linked_list *item);
+void                    _detach(struct linked_list **list, struct linked_list *item);
+void                    _free_list(struct linked_list **ptr);
+char *                  _new(size_t size);
+int                     add_dam(str_t *str);
+void                    add_haste(int potion);
+void                    add_pack(struct linked_list *item, int silent);
+void                    add_pass(void);
+void                    addmsg(char *fmt, ...);
+void                    aggravate(void);
+int                     attack(struct thing *mp);
+int                     author(void);
+void                    auto_save(int p);
+void                    badcheck(char *name, struct magic_item *magic, int bound);
+int                     be_trapped(coord *tc);
+void                    bounce(struct object *weap, char *mname);
+void                    call(void);
+int                     cansee(int y, int x);
+char *                  charge_str(struct object *obj);
+int                     chase(struct thing *tp, coord *ee);
+void                    check_level(void);
+void                    checkout(int p);
+void                    chg_str(int amt);
+void                    chmsg(char *fmt, ...);
+void                    command(void);
+void                    conn(int r1, int r2);
+void                    create_obj(void);
+void                    death(int monst);
+int                     diag_ok(coord *sp, coord *ep);
+void                    discard(struct linked_list *item);
+void                    d_level(void);
+int                     do_chase(struct thing *th);
+void                    do_daemons(int flag);
+void                    do_fuses(int flag);
+void                    do_motion(struct object *obj, int ydelta, int xdelta);
+void                    do_move(int dy, int dx);
+void                    do_passages(void);
+void                    do_rooms(void);
+void                    do_run(int ch);
+void                    do_zap(int gotdir);
+void                    doadd(char *fmt, va_list ap);
+void                    doctor(void);
+void                    door(struct room *rm, coord *cp);
+void                    drain(int ymin, int ymax, int xmin, int xmax);
+void                    draw_room(struct room *rp);
+void                    drop(void);
+int                     dropcheck(struct object *op);
+void                    eat(void);
+int	                encerror(void);
+void                    encseterr(int err);
+int                     encclearerr(void);
+size_t                  encread(void *buf, size_t size, FILE *inf);
+size_t                  encwrite(const void *buf, size_t size, FILE *outf);
+void                    endmsg(void);
+void                    extinguish(void (*func)());
+void                    fall(struct linked_list *item, int pr);
+int                     fallpos(coord *pos, coord *newpos, int passages);
+void                    fatal(char *s);
+struct linked_list *    find_mons(int y, int x);
+struct linked_list *    find_obj(int y, int x);
+struct delayed_action * find_slot(void (*func)());
+int                     fight(coord *mp, int mn, struct object *weap, int thrown);
+void                    fix_stick(struct object *cur);
+void                    flush_type(void);
+void                    fuse(void (*func)(), int arg, int time, int type);
+void                    genocide(void);
+int                     get_bool(void *vp, WINDOW *win);
+int                     get_dir(void);
+struct linked_list *    get_item(char *purpose, int type);
+int                     get_str(void *vopt, WINDOW *win);
+int                     gethand(void);
+void                    help(void);
+void                    hit(char *er, char *ee);
+int                     hit_monster(int y, int x, struct object *obj);
+void                    horiz(int cnt);
+void                    identify(void);
+void                    init_colors(void);
+void                    init_materials(void);
+void                    init_names(void);
+void                    init_player(void);
+void                    init_stones(void);
+void                    init_things(void);
+void                    init_weapon(struct object *weap, int type);
+char *                  inv_name(struct object *obj, int drop);
+int                     inventory(struct linked_list *list, int type);
+int                     is_current(struct object *obj);
+int                     is_magic(struct object *obj);
+void                    kill_daemon(void (*func)());
+void                    killed(struct linked_list *item, int pr);
+char *                  killname(int monst);
+void                    lengthen(void (*func)(), int xtime);
+void                    light(coord *cp);
+void                    look(int wakeup);
+void                    miss(char *er, char *ee);
+void                    missile(int ydelta, int xdelta);
+void                    money(void);
+void                    msg(char *fmt, ...);
+void                    new_level(void);
+struct linked_list *    new_item(int size);
+void                    new_monster(struct linked_list *item, int type, coord *cp);
+struct linked_list *    new_thing(void);
+char *                  num(int n1, int n2);
+void                    nohaste(void);
+void                    open_score(void);
+void                    option(void);
+int                     pack_char(struct object *obj);
+void                    parse_opts(char *str);
+int                     passwd(void);
+int                     pick_one(struct magic_item *magic, int nitems);
+void                    pick_up(int ch);
+void                    picky_inven(void);
+void                    playit(void);
+void                    put_bool(void *b);
+void                    put_str(void *str);
+void                    put_things(void);
+int                     readchar(WINDOW *win);
+int                     restore(char *file, char **envp);
+int                     roll(int number, int sides);
+struct room *           roomin(coord *cp);
+int                     step_ok(int ch);
+void                    strucpy(char *s1, char *s2, size_t len);
+void                    swander(void);
+void                    take_off(void);
+void                    tstp(int p);
+void                    quaff(void);
+void                    quit(int p);
+void                    raise_level(void);
+int                     randmonster(int wander);
+void                    read_scroll(void);
+void                    remove_monster(coord *mp, struct linked_list *item);
+int                     ring_eat(int hand);
+void                    ring_off(void);
+void                    ring_on(void);
+char *                  ring_num(struct object *obj);
+int                     rnd(int range);
+void                    rnd_pos(struct room *rp, coord *cp);
+int                     rnd_room(void);
+coord *                 rndmove(struct thing *who);
+int                     roll_em(struct stats *att, struct stats *def, struct object *weap, int hurl);
+void                    rollwand(void);
+int                     rs_save_file(FILE *savef);
+int                     rs_restore_file(FILE *inf);
+void                    runners(void);
+void                    runto(coord *runner, coord *spot);
+int                     save(int which);
+int                     save_file(FILE *savef);
+int                     save_game(void);
+int                     save_throw(int which, struct thing *tp);
+void                    score(int amount, int flags, int monst);
+void                    shell(void);
+int                     show(int y, int x);
+void                    sight(void);
+void                    search(void);
+int                     secretdoor(int y, int x);
+void                    setup(void);
+void                    show_win(WINDOW *scr, char *message);
+void                    start_daemon(void (*func)(), int arg, int type);
+void                    status(void);
+void                    stomach(void);
+int                     str_plus(str_t *str);
+int                     swing(int at_lvl, int op_arm, int wplus);
+int                     teleport(void);
+int                     too_much(void);
+void                    total_winner(void);
+char *                  tr_name(int ch);
+struct trap *           trap_at(int y, int x);
+void                    thunk(struct object *weap, char *mname);
+void                    u_level(void);
+void                    unconfuse(void);
+void                    unsee(void);
+void                    vert(int cnt);
+char *                  vowelstr(char *str);
+void                    wait_for(WINDOW *win, int ch);
+struct linked_list *    wake_monster(int y, int x);
+void                    wanderer(void);
+void                    waste_time(void);
+void                    wear(void);
+void                    whatis(void);
+void                    wield(void);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rogue3/rogue.r	Tue Oct 13 13:33:34 2009 +0000
@@ -0,0 +1,411 @@
+.RP
+.ds RH A Guide to the Dungeons of Doom
+.ds CH
+.ds CF - % -
+.TL
+A Guide to the Dungeons of Doom
+.AU
+Michael C. Toy
+.AI
+Computer Systems Research Group
+Department of Electrical Engineering and Computer Science
+University of California
+Berkeley, California  94720
+.AB
+Rogue is a visual CRT based fantasy game which runs
+under the UNIX timesharing system.  This paper describes
+how to play rogue and gives a few hints for those who might
+otherwise get lost in the Dungeons of Doom.
+.AE
+.NH
+Introduction
+.PP
+You have just finished your years as a student at the local fighter's guild.
+After much practice and sweat you have finally completed your training and
+are ready to embark upon a perilous adventure.  As a test of your skills,
+the local guildmasters have sent you into the Dungeons of Doom.  Your
+task is to return with the Amulet of Yendor.  Your reward for the completion
+of this task will be a full membership in the local guild. In addition, you are
+allowed to keep all the loot you bring back from the dungeons.
+.PP
+In preparation for your journey, you are given an enchanted sword, taken
+from a dragon's hoard in the far off Dark Mountains.  You are also outfitted
+with elf-crafted armor and given enough food to reach the dungeons.  You
+say goodbye to family and friends for what may be the last time and head
+up the road.
+.PP
+You set out on your way to the dungeons and after several days of uneventful
+travel, you see the ancient ruins that mark the entrance to the Dungeons
+of Doom.  It is late at night so you make camp at the entrance and spend
+the night sleeping under the open skies.  In the morning you gather
+your sword, put on your armor, eat what is almost your last food and enter
+the dungeons.
+.NH
+What is going on here?
+.PP
+You have just begun a game of rogue.  Your goal is to grab as much treasure
+as you can, find the Amulet of Yendor, and get out of the Dungeons of Doom
+alive.  On the screen, a map of where you have been and what you have seen on
+the current dungeon level is kept.  As you explore more of the level,
+it appears on the screen in front of you.
+.PP
+Rogue differs from most computer fantasy games in that it is screen
+oriented.  Commands are all one or two keystrokes\(dg
+.FS
+\(dgAs opposed to pseudo English sentences.
+.FE
+and the results of your commands are displayed
+graphically on the screen rather than being explained in words.
+.PP
+Another major difference between rogue and other computer fantasy games
+is that once you have solved all the puzzles in a standard fantasy game,
+it has lost most of its excitement and it ceases to be fun.  Rogue on the
+other hand generates a new dungeon every time you play it and
+even the author finds it an entertaining and exciting game.
+.NH
+What do all those things on the screen mean?
+.PP
+In order to understand what is going on in rogue you have to first get
+some grasp of what rogue is doing with the screen.
+The rogue screen is intended to replace the "You can see ..." descriptions
+of standard fantasy games.  Here is a sample of what a rogue screen might
+look like.
+.in +1i
+.nf
+.cs R 15
+                  ---------------------
+                  |...................+
+                  |...@...........[...|
+                  |........B..........|
+                  |...................|
+                  --------+------------
+
+
+.cs R
+Level: 1  Gold: 0      Hp: 12(12)  Str: 16  Ac: 6  Exp: 1/0
+.fi
+.in 0
+.NH 2
+The bottom line
+.PP
+At the bottom line of the screen is a few pieces of cryptic information,
+describing your current status.  Here is an explanation of what these
+things mean:
+.IP Level 8
+This number indicates how deep you have gone in the dungeon.  It starts
+at one and goes up forever\(dg.
+.FS
+\(dgOr until you get killed or decide to quit.
+.FE
+.IP Gold
+The number of gold pieces you have managed to find and keep with
+you so far.
+.IP Hp
+Your current and maximum hit points.  Hit points indicate how much
+damage you can take before you die.  The more you get hit in a
+fight, the lower they
+get.  You can regain hit points by resting. The number in parentheses is
+the maximum number your hit points can reach.
+.IP Str
+Your current strength.  This can be any integer less than or
+equal to eighteen.  The higher the number, the stronger you are.
+.IP Ac
+Your current armor class.  This number indicates how effective
+your armor is in stopping blows from unfriendly creatures.  The lower
+this number is, the more effective the armor.
+.IP Exp
+These two numbers give your current experience level and experience points.
+As you do things, you gain experience points.  At certain experience point
+totals, you gain an experience level.  The more experienced you are, the
+better you are able to fight and to withstand magical attacks.
+.NH 2
+The top line
+.PP
+The top line of the screen is reserved for printing messages that describe
+things that are impossible to represent visually.  If you see a
+"--More--" on the top line, this means that rogue wants to print another
+message on the screen, but it wants to make certain that you have read
+the one that is there first.  To read the next message, just press a
+space.
+.NH 2
+The rest of the screen
+.PP
+The rest of the screen is the map of the level as you have explored it so far.
+Each symbol on the screen represents something.  Here is a list of what
+the various symbols mean:
+.IP @
+This symbol represents you, the adventurer.
+.IP "-|" 6
+These symbols represent the walls of rooms.
+.IP +
+A door to/from a room.
+.IP .
+The floor of a room.
+.IP #
+The floor of a passage between rooms.
+.IP *
+A pile or pot of gold.
+.IP )
+A weapon of some sort.
+.IP ]
+A piece of armor.
+.IP !
+A flask containing a magic potion.
+.IP ?
+A piece of paper, usually a magic scroll.
+.IP ^
+A trap, watch out for these.
+.IP %
+The passage leading down to the next level.
+.IP :
+A piece of food.
+.IP A-Z
+The uppercase letters represent the various inhabitants of the
+Dungeons of Doom.  Watch out, they can be mean.
+.NH
+Commands
+.PP
+Commands are given to rogue by pressing single letters.  Most commands can
+be preceded by a count to repeat them (e.g. typing "10s" will do ten searches)
+The list of commands is rather long, but it can be read at any time during
+the game with the ? command.  Here it is for reference, with a short
+explanation of each command.
+.IP ? 6
+The help command.  Asks for a character to give help on.  If you type
+a "*", it will list all the commands, otherwise it will explain what the
+character you typed does.
+.IP /
+This is the "What is that on the screen?" command. A "/" followed by any
+character that you see on the level, will tell you what that character
+is.  For instance, typing "/@" will tell you that the @ symbol represents
+you, the player.
+.IP "h , H"
+Move left.  You move one space to the left.  If you use upper case
+h, you will continue to move left until you run into something.  This
+works for all movement commands (e.g. "L" means run in direction "l")
+.IP j
+Move down.
+.IP k
+Move up.
+.IP l
+Move right.
+.IP y
+Move diagonally up and left.
+.IP u
+Move diagonally up and right.
+.IP b
+Move diagonally down and left.
+.IP n
+Move diagonally down and right.
+.IP f
+Find prefix.  When followed by a direction it means to continue moving
+in the specified direction until you pass something interesting or
+run into a wall.
+.IP t
+Throw an object.  This is a prefix command.  Follow it with a direction and
+you throw an object in the specified direction.  (e.g. type "th" to throw
+something left.)
+.IP >
+If you are standing over the passage down to the next level, this command
+means to climb down.
+.IP s
+Search for traps and secret doors.  Examine each space immediately adjacent
+to you for the existence of a trap or secret door.  There is a large chance
+that even if there is something there, you won't find it so you might
+have to search a while before you find something.
+.IP " "
+(space) Rest.  This is the "do nothing" command.
+This is good for waiting and healing.
+.IP i
+Inventory.  List what you are carrying in your pack.
+.IP I
+Selective inventory.  Tells you what a single item in your pack is.
+.IP q
+Quaff.  Drink one of the potions you are carrying.
+.IP r
+Read.  Read one of the scrolls in your pack.
+.IP e
+Eat food.  Take some food out of your pack and eat it.
+.IP w
+Wield a weapon.  Take a weapon out of your pack and carry it.  You must be
+wielding  weapon to use it (except to throw things).  To fire an arrow,
+you must wield the bow.  You can only wield one weapon at a time.
+.IP W
+Wear armor.  Take a piece of armor out of your pack and put it on.  You can
+only wear one suit of armor at a time.
+.IP T
+Take armor off.  You can't remove armor that is cursed.
+This takes extra time.
+.IP d
+Drop an object.  Take something out of your pack and leave it lying
+on the floor.  Only one object can occupy each space.
+.IP o
+Examine and set options.  This command is further explained in the section
+on options.
+.IP ^L
+REdraws the screen. Useful if spurious messages or transmission errors
+have messed up the display.
+.IP v
+Prints the program version number.
+.IP Q
+Quit.  Leave the game.
+.IP R
+Repeat last message.  Useful when a message disappears before you can
+read it.
+.IP S
+Save the current game in a file.  Caveat: Rogue won't let you start
+up a copy of a saved game, and it removes the save file as soon as
+you start up a restored game.  This is to prevent people from saving
+a game just before a dangerous position and then restarting it
+if they die.  To restore a saved game, give the file name as an argument
+to rogue. As in
+.ti +1i
+.nf
+% rogue save_file
+.NH
+Dealing with objects
+.PP
+When you find something in the dungeon, it is common to want to pick the
+object up.  This is accomplished in rogue by walking over the object.  If
+you are carrying too many things, the program will tell you and it won't pick
+up the object, otherwise it will add it to your pack and if the notify
+option is set, tell you what you just picked up.
+.PP
+Many of the commands that operate on objects must prompt you to find
+out which object you want to use.  If you change your mind and don't want to
+do that command after all, just press an escape and the command will be
+aborted.
+.NH
+Light
+.PP
+Rooms in the dungeons are either lit or dark.  If you walk into a lit room,
+the entire room will be drawn on the screen as soon as you enter.  If you
+walk into a dark room, it will only be displayed as you explore it.  Upon
+leaving a dark room, all objects inside the room which might move are
+removed from the screen.  In the darkness you can only see one space
+in all directions around you.
+.NH
+Fighting
+.PP
+If you see a monster and you wish to fight it, just attempt to run into it.
+Many times a monster you find will mind its own business unless you attack
+it.  It is often the case that discretion is the better part of valor.
+.NH
+Armor
+.PP
+There are various sorts of armor lying around in the dungeon.  Some of it
+is enchanted, some is cursed and some is just normal.  Different armor
+types have different armor classes.  The lower the armor class, the
+more protection the armor affords against the blows of monsters.
+If a piece of armor is enchanted or
+cursed, its armor class will be higher or lower than normal.  Here is
+a list of the various armor types and their normal armor class.
+.TS
+center box;
+c c
+l | c.
+Type	Class
+=
+Leather armor	8
+Studded leather / Ring mail	7
+Scale mail	6
+Chain mail	5
+Banded mail / Splint mail	4
+Plate mail	3
+.TE
+.NH
+Options
+.PP
+Due to variations in personal tastes and conceptions of the way rogue
+should do things, there are a set of options you can set that cause
+rogue to behave in various different ways.
+.NH 2
+Setting the options
+.PP
+There are basically two ways to set the options.  The first is with the
+"o" command of rogue, the second is with the ROGUEOPTS environment
+variable.  On Version 6 systems, there is no equivalent of
+the ROGUEOPTS feature.
+.NH 3
+Using the "o" command
+.PP
+When you press "o" in rogue, it clears the screen and displays the current
+settings for all the options.  It then places the cursor by the value of the
+first option and waits for you to type.  You can type a RETURN which means to
+go to the next option, a "\-" which means to go to the previous option, an
+escape which means to return to the game, or you can give the option a
+value.  For boolean options this merely involves pressing "t" for true or
+"f" for false.  For string options, type the new value followed by a
+return.
+.NH 3
+Using the ROGUEOPTS variable
+.PP
+The ROGUEOPTS variable is a string containing a comma separated list of
+initial values for the various options.  Boolean variables can be turned
+on by listing their name and turned off by putting a "no" in front of the
+name.  Thus to set up an environment variable so that jump is on, terse is
+off, the name is set to "Conan the Barbarian" and the fruit is "mango",
+use the command
+.nf
+.nf
+.ti +3
+% setenv ROGUEOPTS "jump,noterse,name=Conan the Barbarian,fruit=mango" \(dg
+.fi
+.ti +3
+% setenv ROGUEOPTS "jump,noterse,name=Conan the Barbarian,fruit=mango" \(dg
+.fi
+.FS
+\(dgFor those of you who use the bourne shell, the commands would be
+.in +3
+.nf
+$ ROGUEOPTS="jump,noterse,name=Conan the Barbarian,fruit=mango"
+$ export ROGUEOPTS
+.fi
+.in +0
+.FE
+.NH 2
+Option list
+.PP
+Here is a list of the options and an explanation of what each one is for.
+The default value for each is enclosed in square brackets.
+.IP "terse [noterse]" 25
+Useful for those who are tired of the sometimes lengthy messages of rogue.
+This is a useful option for those on slow terminals.  This option defaults to
+on if your are on a slow (under 1200 baud) terminal.
+.IP "jump [nojump]"
+If this option is set, running moves will not be displayed until you
+reach the end of the move.  This saves considerable cpu time and
+display time.  This option defaults to on if you are using a slow terminal.
+.IP "step [nostep]
+When step is set, lists of things, like inventories or "*" responses to
+"Which item do you wish to xxxx? " questions, are displayed one item
+at a time on the top of the screen, rather than clearing the screen,
+displaying the list, then re-displaying the dungeon level.
+.IP "flush [noflush]"
+If flush is set, all typeahead is thrown away after each round of battle.
+This is useful for those who type way ahead and watch to their dismay as
+a Kobold kills them.
+.IP "askme [noaskme]"
+Upon reading a scroll or quaffing a potion which does not automatically
+identify it upon use, rogue will ask you what to name it so you can
+recognize it in the future.
+.IP "name [account name]"
+This is the name of your character.  It is used if you get on the top ten
+scorer's list.  It should be less than eighty characters long.
+.IP "fruit [slime-mold]"
+This should hold the name of a fruit that you enjoy eating.  It is basically
+a whimsy that the program uses in a couple of places.
+.IP "file [rogue.save]"
+The default file name for saving the game.  If your phone is hung up by
+accident, rogue will automatically save the game in this file.  The
+file name may contain the special character "~" which expands to be
+your home directory.
+.NH
+Acknowledgements
+.PP
+Rogue was originally conceived of by Glenn Wichman and Michael Toy.  The
+help of Ken Arnold in making the program easier to use and putting the
+finishing touches on is greatly appreciated.  I would also like to thank
+Marty McNary, Scott Nelson, Daniel Jensen, Kipp Hickman, Joe Kalash,
+Steve Maurer, Bill Joy, Mark Horton and Jan Miller for their ideas
+and assistance.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rogue3/rogue36.cat	Tue Oct 13 13:33:34 2009 +0000
@@ -0,0 +1,54 @@
+ROGUE(6)                                                              ROGUE(6)
+
+
+
+NAME
+       rogue - Exploring The Dungeons of Doom
+
+SYNOPSIS
+       rogue [ save_file ]
+
+DESCRIPTION
+       Rogue  is a computer fantasy game with a new twist.  It is crt oriented
+       and the object of the game is to survive the attacks  of  various  mon-
+       sters and get a lot of gold, rather than the puzzle solving orientation
+       of most computer fantasy games.
+
+       To get started you really only need to know two commands.  The  command
+       ?   will  give  you  a list of the available commands and the command /
+       will identify the things you see on the screen.
+
+       To win the game (as opposed to merely playing to beat other people high
+       scores)  you  must locate the Amulet of Yendor which is somewhere below
+       the 20th level of the dungeon and get it out.  Nobody has achieved this
+       yet  and  if  somebody does, they will probably go down in history as a
+       hero among heros.
+
+       When the game ends, either by your death, when you quit, or if you  (by
+       some  miracle)  manage to win, rogue will give you alist of the top-ten
+       scorers.  The scoring is based entirely upon how  much  gold  you  get.
+       There is a 10% penalty for getting yourself killed.
+
+       For more detailed directions, read the document A Guide to the Dungeons
+       of Doom.
+
+FILES
+       rogue36.scr                  Score file
+       ~/rogue36.sav                Default save file
+
+SEE ALSO
+       Michael C. Toy, A Guide to the Dungeons of Doom
+
+BUGS
+       Probably infinite.  Currently known bugs are: Sometimes you  are  still
+       hungry  even  after you eat food and sometimes you get a monster on the
+       screen in reverse video which may or may not cause a core dump.
+
+COPYRIGHT
+       Rogue: Exploring the Dungeons of Doom
+       Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
+       All rights reserved.
+
+
+
+3rd Berkeley Distribution                                             ROGUE(6)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rogue3/rogue36.doc	Tue Oct 13 13:33:34 2009 +0000
@@ -0,0 +1,660 @@
+
+
+
+
+
+
+
+
+
+              A Guide to the Dungeons of Doom
+
+                       Michael C. Toy
+              Computer Systems Research Group
+ Department of Electrical Engineering and Computer Science
+                  University of California
+                Berkeley, California  94720
+
+
+
+                          ABSTRACT
+
+          Rogue  is  a  visual  CRT  based fantasy game
+     which runs  under  the  UNIX  timesharing  system.
+     This paper describes how to play rogue and gives a
+     few hints for those who might otherwise  get  lost
+     in the Dungeons of Doom.
+
+
+
+11 July 2006
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+              A Guide to the Dungeons of Doom
+
+                       Michael C. Toy
+              Computer Systems Research Group
+ Department of Electrical Engineering and Computer Science
+                  University of California
+                Berkeley, California  94720
+
+
+1.  Introduction
+
+     You  have  just finished your years as a student at the
+local fighter's guild.  After much practice  and  sweat  you
+have finally completed your training and are ready to embark
+upon a perilous adventure.  As a test of  your  skills,  the
+local  guildmasters have sent you into the Dungeons of Doom.
+Your task is to return with  the  Amulet  of  Yendor.   Your
+reward  for  the completion of this task will be a full mem-
+bership in the local guild. In addition, you are allowed  to
+keep all the loot you bring back from the dungeons.
+
+     In  preparation  for  your  journey,  you  are given an
+enchanted sword, taken from a dragon's hoard in the far  off
+Dark  Mountains.   You  are  also outfitted with elf-crafted
+armor and given enough food to reach the dungeons.  You  say
+goodbye  to family and friends for what may be the last time
+and head up the road.
+
+     You set out on your way to the dungeons and after  sev-
+eral  days  of  uneventful travel, you see the ancient ruins
+that mark the entrance to the Dungeons of Doom.  It is  late
+at  night  so  you  make  camp at the entrance and spend the
+night sleeping under the open skies.   In  the  morning  you
+gather  your  sword,  put  on your armor, eat what is almost
+your last food and enter the dungeons.
+
+2.  What is going on here?
+
+     You have just begun a game of rogue.  Your goal  is  to
+grab as much treasure as you can, find the Amulet of Yendor,
+and get out of the Dungeons of Doom alive.  On the screen, a
+map  of  where  you  have been and what you have seen on the
+current dungeon level is kept.  As you explore more  of  the
+level, it appears on the screen in front of you.
+
+     Rogue  differs from most computer fantasy games in that
+it  is  screen  oriented.   Commands  are  all  one  or  two
+keystrokes  and  the  results of your commands are displayed
+graphically on the screen rather  than  being  explained  in
+-----------
+As opposed to pseudo English sentences.
+
+
+
+                            - 1 -
+
+
+
+
+
+                             A Guide to the Dungeons of Doom
+
+
+words.
+
+     Another  major  difference between rogue and other com-
+puter fantasy games is that once you  have  solved  all  the
+puzzles  in a standard fantasy game, it has lost most of its
+excitement and it ceases to be fun.  Rogue on the other hand
+generates  a new dungeon every time you play it and even the
+author finds it an entertaining and exciting game.
+
+3.  What do all those things on the screen mean?
+
+     In order to understand what is going on  in  rogue  you
+have to first get some grasp of what rogue is doing with the
+screen.  The rogue screen is intended to  replace  the  "You
+can  see  ..." descriptions of standard fantasy games.  Here
+is a sample of what a rogue screen might look like.
+                            ---------------------
+                            |...................+
+                            |...@...........[...|
+                            |........B..........|
+                            |...................|
+                            --------+------------
+
+
+          Level: 1  Gold: 0      Hp: 12(12)  Str: 16  Ac: 6  Exp: 1/0
+
+3.1.  The bottom line
+
+     At the bottom line of the screen is  a  few  pieces  of
+cryptic  information,  describing your current status.  Here
+is an explanation of what these things mean:
+
+Level   This number indicates how deep you have gone in  the
+        dungeon.  It starts at one and goes up forever.
+
+Gold    The  number  of gold pieces you have managed to find
+        and keep with you so far.
+
+Hp      Your current and maximum  hit  points.   Hit  points
+        indicate  how  much  damage  you can take before you
+        die.  The more you get hit in  a  fight,  the  lower
+        they get.  You can regain hit points by resting. The
+        number in parentheses is the maximum number your hit
+        points can reach.
+
+Str     Your current strength.  This can be any integer less
+        than or equal to eighteen.  The higher  the  number,
+        the stronger you are.
+
+Ac      Your current armor class.  This number indicates how
+        effective your  armor  is  in  stopping  blows  from
+        unfriendly creatures.  The lower this number is, the
+-----------
+Or until you get killed or decide to quit.
+
+
+
+                            - 2 -
+
+
+
+
+
+                             A Guide to the Dungeons of Doom
+
+
+        more effective the armor.
+
+Exp     These two numbers give your current experience level
+        and  experience  points.  As you do things, you gain
+        experience  points.   At  certain  experience  point
+        totals,  you  gain  an  experience  level.  The more
+        experienced you are, the  better  you  are  able  to
+        fight and to withstand magical attacks.
+
+3.2.  The top line
+
+     The  top  line  of  the screen is reserved for printing
+messages that describe things that are impossible to  repre-
+sent  visually.   If  you  see a "--More--" on the top line,
+this means that rogue wants to print another message on  the
+screen,  but it wants to make certain that you have read the
+one that is there first.  To read  the  next  message,  just
+press a space.
+
+3.3.  The rest of the screen
+
+     The  rest  of the screen is the map of the level as you
+have explored it so far.  Each symbol on the  screen  repre-
+sents something.  Here is a list of what the various symbols
+mean:
+
+@    This symbol represents you, the adventurer.
+
+-|    These symbols represent the walls of rooms.
+
++     A door to/from a room.
+
+.     The floor of a room.
+
+#     The floor of a passage between rooms.
+
+*     A pile or pot of gold.
+
+)     A weapon of some sort.
+
+]     A piece of armor.
+
+!     A flask containing a magic potion.
+
+?     A piece of paper, usually a magic scroll.
+
+^     A trap, watch out for these.
+
+%     The passage leading down to the next level.
+
+:     A piece of food.
+
+A-Z   The uppercase letters represent  the  various  inhabi-
+      tants of the Dungeons of Doom.  Watch out, they can be
+
+
+
+                            - 3 -
+
+
+
+
+
+                             A Guide to the Dungeons of Doom
+
+
+      mean.
+
+4.  Commands
+
+     Commands are given to rogue by pressing single letters.
+Most  commands  can  be  preceded  by a count to repeat them
+(e.g. typing "10s" will do ten searches) The  list  of  com-
+mands  is rather long, but it can be read at any time during
+the game with the ? command.  Here it is for reference, with
+a short explanation of each command.
+
+?     The  help  command.  Asks for a character to give help
+      on.  If you type a "*", it will list all the commands,
+      otherwise it will explain what the character you typed
+      does.
+
+/     This is the "What is that on the screen?"  command.  A
+      "/"  followed  by  any  character  that you see on the
+      level, will tell you  what  that  character  is.   For
+      instance,  typing "/@" will tell you that the @ symbol
+      represents you, the player.
+
+h , H Move left.  You move one space to the  left.   If  you
+      use upper case h, you will continue to move left until
+      you run into something.  This works for  all  movement
+      commands (e.g. "L" means run in direction "l")
+
+j     Move down.
+
+k     Move up.
+
+l     Move right.
+
+y     Move diagonally up and left.
+
+u     Move diagonally up and right.
+
+b     Move diagonally down and left.
+
+n     Move diagonally down and right.
+
+f     Find prefix.  When followed by a direction it means to
+      continue moving in the specified direction  until  you
+      pass something interesting or run into a wall.
+
+t     Throw an object.  This is a prefix command.  Follow it
+      with a direction and you throw an object in the speci-
+      fied  direction.   (e.g.  type "th" to throw something
+      left.)
+
+>     If you are standing over the passage down to the  next
+      level, this command means to climb down.
+
+
+
+
+
+                            - 4 -
+
+
+
+
+
+                             A Guide to the Dungeons of Doom
+
+
+s     Search for traps and secret doors.  Examine each space
+      immediately adjacent to you for  the  existence  of  a
+      trap  or  secret  door.   There is a large chance that
+      even if there is something there, you won't find it so
+      you might have to search a while before you find some-
+      thing.
+
+      (space) Rest.  This is the "do nothing" command.  This
+      is good for waiting and healing.
+
+i     Inventory.  List what you are carrying in your pack.
+
+I     Selective  inventory.  Tells you what a single item in
+      your pack is.
+
+q     Quaff.  Drink one of the potions you are carrying.
+
+r     Read.  Read one of the scrolls in your pack.
+
+e     Eat food.  Take some food out of your pack and eat it.
+
+w     Wield  a  weapon.   Take a weapon out of your pack and
+      carry it.  You must be  wielding   weapon  to  use  it
+      (except  to throw things).  To fire an arrow, you must
+      wield the bow.  You can only wield  one  weapon  at  a
+      time.
+
+W     Wear  armor.   Take  a piece of armor out of your pack
+      and put it on.  You can only wear one suit of armor at
+      a time.
+
+T     Take  armor  off.   You  can't  remove  armor  that is
+      cursed.  This takes extra time.
+
+d     Drop an object.  Take something out of your  pack  and
+      leave  it  lying  on  the  floor.  Only one object can
+      occupy each space.
+
+o     Examine and set  options.   This  command  is  further
+      explained in the section on options.
+
+^L    REdraws  the  screen.  Useful  if spurious messages or
+      transmission errors have messed up the display.
+
+v     Prints the program version number.
+
+Q     Quit.  Leave the game.
+
+R     Repeat last message.  Useful when a message disappears
+      before you can read it.
+
+S     Save  the current game in a file.  Caveat: Rogue won't
+      let you start up a  copy  of  a  saved  game,  and  it
+      removes  the  save  file  as  soon  as  you start up a
+
+
+
+                            - 5 -
+
+
+
+
+
+                             A Guide to the Dungeons of Doom
+
+
+      restored game.  This is to prevent people from  saving
+      a  game  just  before  a  dangerous  position and then
+      restarting it if they die.  To restore a  saved  game,
+      give the file name as an argument to rogue. As in
+                % rogue save_file
+
+5.  Dealing with objects
+
+     When you find something in the dungeon, it is common to
+want to pick the object up.  This is accomplished  in  rogue
+by  walking  over  the object.  If you are carrying too many
+things, the program will tell you and it won't pick  up  the
+object,  otherwise  it  will  add it to your pack and if the
+notify option is set, tell you what you just picked up.
+
+     Many of the  commands  that  operate  on  objects  must
+prompt you to find out which object you want to use.  If you
+change your mind and don't want to  do  that  command  after
+all, just press an escape and the command will be aborted.
+
+6.  Light
+
+     Rooms  in  the dungeons are either lit or dark.  If you
+walk into a lit room, the entire room will be drawn  on  the
+screen  as soon as you enter.  If you walk into a dark room,
+it will only be displayed as you explore it.  Upon leaving a
+dark  room, all objects inside the room which might move are
+removed from the screen.  In the darkness you can  only  see
+one space in all directions around you.
+
+7.  Fighting
+
+     If  you  see  a  monster and you wish to fight it, just
+attempt to run into it.  Many times a monster you find  will
+mind its own business unless you attack it.  It is often the
+case that discretion is the better part of valor.
+
+8.  Armor
+
+     There are various sorts of armor lying  around  in  the
+dungeon.   Some  of it is enchanted, some is cursed and some
+is just normal.  Different armor types have different  armor
+classes.  The lower the armor class, the more protection the
+armor affords against the blows of monsters.  If a piece  of
+armor is enchanted or cursed, its armor class will be higher
+or lower than normal.  Here is a list of the  various  armor
+types and their normal armor class.
+
+
+
+
+
+
+
+
+
+
+                            - 6 -
+
+
+
+
+
+                             A Guide to the Dungeons of Doom
+
+
+           +------------------------------------+
+           |           Type               Class |
+           +----------------------------+-------+
+           |Leather armor               |   8   |
+           |Studded leather / Ring mail |   7   |
+           |Scale mail                  |   6   |
+           |Chain mail                  |   5   |
+           |Banded mail / Splint mail   |   4   |
+           |Plate mail                  |   3   |
+           +----------------------------+-------+
+
+9.  Options
+
+     Due to variations in personal tastes and conceptions of
+the way rogue should do things, there are a set  of  options
+you  can set that cause rogue to behave in various different
+ways.
+
+9.1.  Setting the options
+
+     There are basically two ways to set the  options.   The
+first  is  with the "o" command of rogue, the second is with
+the ROGUEOPTS environment variable.  On Version  6  systems,
+there is no equivalent of the ROGUEOPTS feature.
+
+9.1.1.  Using the "o" command
+
+     When  you  press "o" in rogue, it clears the screen and
+displays the current settings for all the options.  It  then
+places the cursor by the value of the first option and waits
+for you to type.  You can type a RETURN which means to go to
+the  next  option,  a  "-" which means to go to the previous
+option, an escape which means to return to the game, or  you
+can  give  the  option  a  value.   For boolean options this
+merely involves pressing "t" for true or "f" for false.  For
+string options, type the new value followed by a return.
+
+9.1.2.  Using the ROGUEOPTS variable
+
+     The  ROGUEOPTS  variable is a string containing a comma
+separated list of initial values for  the  various  options.
+Boolean variables can be turned on by listing their name and
+turned off by putting a "no" in front of the name.  Thus  to
+set  up an environment variable so that jump is on, terse is
+off, the name is set to "Conan the Barbarian" and the  fruit
+is "mango", use the command
+   % setenv ROGUEOPTS "jump,noterse,name=Conan the Barbarian,fruit=mango"
+   %  setenv  ROGUEOPTS "jump,noterse,name=Conan the Barbar-
+ian,fruit=mango"
+
+-----------
+For those of you who use  the  bourne  shell,  the
+commands would be
+   $ ROGUEOPTS="jump,noterse,name=Conan the Barbarian,fruit=mango"
+
+
+
+                            - 7 -
+
+
+
+
+
+                             A Guide to the Dungeons of Doom
+
+
+9.2.  Option list
+
+     Here  is  a  list  of the options and an explanation of
+what each one  is  for.   The  default  value  for  each  is
+enclosed in square brackets.
+
+terse [noterse]          Useful  for  those who are tired of
+                         the sometimes lengthy  messages  of
+                         rogue.  This is a useful option for
+                         those  on  slow  terminals.    This
+                         option  defaults  to on if your are
+                         on a slow (under 1200 baud)  termi-
+                         nal.
+
+jump [nojump]            If  this  option  is  set,  running
+                         moves will not be  displayed  until
+                         you  reach  the  end  of  the move.
+                         This saves  considerable  cpu  time
+                         and   display  time.   This  option
+                         defaults to on if you are  using  a
+                         slow terminal.
+
+step [nostep]            When  step is set, lists of things,
+                         like inventories or  "*"  responses
+                         to "Which item do you wish to xxxx?
+                         " questions, are displayed one item
+                         at a time on the top of the screen,
+                         rather than  clearing  the  screen,
+                         displaying  the  list, then re-dis-
+                         playing the dungeon level.
+
+flush [noflush]          If flush is set, all  typeahead  is
+                         thrown  away  after  each  round of
+                         battle.  This is useful  for  those
+                         who  type  way  ahead  and watch to
+                         their  dismay  as  a  Kobold  kills
+                         them.
+
+askme [noaskme]          Upon reading a scroll or quaffing a
+                         potion which does not automatically
+                         identify  it  upon  use, rogue will
+                         ask you what to name it so you  can
+                         recognize it in the future.
+
+name [account name]      This is the name of your character.
+                         It is used if you get  on  the  top
+                         ten  scorer's  list.   It should be
+                         less than eighty characters long.
+
+fruit [slime-mold]       This should  hold  the  name  of  a
+                         fruit that you enjoy eating.  It is
+                         basically a whimsy that the program
+-----------
+   $ export ROGUEOPTS
+
+
+
+                            - 8 -
+
+
+
+
+
+                             A Guide to the Dungeons of Doom
+
+
+                         uses in a couple of places.
+
+file [rogue.save]        The  default  file  name for saving
+                         the game.  If your phone is hung up
+                         by  accident,  rogue will automati-
+                         cally save the game in  this  file.
+                         The  file name may contain the spe-
+                         cial character "~" which expands to
+                         be your home directory.
+
+10.  Acknowledgements
+
+     Rogue  was originally conceived of by Glenn Wichman and
+Michael Toy.  The help of Ken Arnold in making  the  program
+easier  to  use  and  putting  the  finishing  touches on is
+greatly appreciated.  I  would  also  like  to  thank  Marty
+McNary,  Scott  Nelson,  Daniel  Jensen,  Kipp  Hickman, Joe
+Kalash, Steve Maurer, Bill Joy, Mark Horton and  Jan  Miller
+for their ideas and assistance.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+                            - 9 -
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rogue3/rogue36.html	Tue Oct 13 13:33:34 2009 +0000
@@ -0,0 +1,633 @@
+<html>
+<head>
+<title></title>
+</head>
+<body>
+
+<h1 align=center><b>A Guide to the Dungeons of Doom</b></h1>
+
+<h2 align=center><i>Michael C. Toy</i></h2>
+
+<h3 align=center>
+Computer Systems Research Group<br>
+Department of Electrical Engineering and Computer Science<br>
+University of California<br>
+Berkeley, California 94720</h3>
+
+<h2 align=center><i>ABSTRACT</i></h2>
+
+<blockquote>
+	<blockquote>
+		<p align="justify"><font size="2">Rogue is a visual CRT based fantasy game which runs under the 
+		UNIX timesharing system. This paper describes how to play rogue, and gives a few hints for 
+		those who might otherwise get 
+		lost in the Dungeons of Doom.</font></p>
+	</blockquote>
+</blockquote>
+
+<h2 align="justify"><b>1. Introduction</b></h2>
+
+<p align="justify">You have just finished your years as a
+student at the local fighter&rsquo;s guild. After much
+practice and sweat you have finally completed your training
+and are ready to embark upon a perilous adventure. As a test
+of your skills, the local guildmasters have sent you into
+the Dungeons of Doom. Your task is to return with the Amulet
+of Yendor. Your reward for the completion of this task will
+be a full membership in the local guild. In addition, you
+are allowed to keep all the loot you bring back from the
+dungeons.</p>
+
+<p align="justify">In preparation for your journey, you are
+given an enchanted sword, taken
+from a dragon&rsquo;s hoard in the far off Dark Mountains.
+You are also outfitted with elf-crafted armor and given
+enough food to reach the dungeons. You say goodbye to family
+and friends for what may be the last time and head up the
+road.</p>
+
+<p align="justify">You set out on your way to the dungeons and
+after several days of uneventful travel, you see the
+ancient ruins that mark the entrance to the Dungeons of
+Doom. It is late at night so you make camp at the entrance
+and spend the night sleeping under the open skies. In the
+morning you gather your sword, put on your armor, eat what
+is almost your last food and enter the
+dungeons.</p>
+
+<h2 align="justify"><b>2. What is going on here?</b></h2>
+
+<p align="justify">You have just begun a game of rogue. Your
+goal is to grab as much treasure as you can, find the Amulet
+of Yendor, and get out of the Dungeons of Doom alive. On the
+screen, a map of where you have been and what you have seen
+on the current dungeon level is kept. As you explore more of
+the level, it appears on the screen in front of
+you.</p>
+
+<p align="justify">Rogue differs from most computer fantasy
+games in that it is screen oriented. Commands are all one or
+two keystrokes<sup>1 </sup>and the
+results of your commands are displayed graphically on the
+screen rather than being explained in words<sup>2</sup>.</p>
+
+<p align="justify">Another major difference between rogue and 
+other computer fantasy games is that once you have solved
+all the puzzles in a standard fantasy game, it has lost most
+of its excitement and it ceases to be fun. Rogue on the
+other hand generates a new dungeon every time you play it
+and even the author finds it an entertaining and exciting
+game.</p>
+
+<h2 align="justify"><b>3. What do all those things on the screen mean?</b></h2>
+
+<p align="justify">In order to understand what is going on in
+rogue you have to first get some grasp of what rogue is
+doing with the screen. The rogue screen is intended to
+replace the &ldquo;You can see ...&rdquo; descriptions of
+standard fantasy games. Here is a sample of what a 
+rogue screen might look like.</p>
+
+<div align="center"><pre>
+                  ---------------------
+                  |...................+
+                  |...@...........[...|
+                  |........B..........|
+                  |...................|
+                  --------+------------
+
+Level: 1  Gold: 0      Hp: 12(12)  Str: 16  Ac: 6  Exp: 1/0
+</pre></div>
+
+<h3 align="justify"><b>3.1. The bottom line</b></h3>
+
+<p align="justify">At the bottom line of the screen is a few
+pieces of cryptic information describing your current
+status. Here is an explanation of what these things
+mean:</p>
+
+<table border="0" width="100%" id="table1" cellspacing="3" cellpadding="3">
+	<tr>
+		<td><p align="justify">Level&nbsp;&nbsp;</p></td>
+		<td><p align="justify">This number indicates how deep you have gone in the 
+		dungeon. It starts at one and goes up forever<sup>2</sup>.</p></td>
+	</tr>
+	<tr>
+		<td><p align="justify">Gold</p></td>
+		<td><p align="justify">The number of gold pieces you have managed to find 
+		and keep with you so far.</td>
+	</tr>
+	<tr>
+		<td><p align="justify">Hp</p></td>
+		<td><p align="justify">Your current and maximum hit points.
+		Health points indicate how much damage you can take before
+		you die. The more you get hit in a fight, the lower they
+		get. You can regain health points by resting. The number in
+		parentheses is the maximum number your hit points can
+		reach.</p></td>
+	</tr>
+	<tr>
+		<td><p align="justify">Str</p></td>
+		<td><p align="justify">Your current strength. This can be any 
+		integer less than or equal to eighteen. The higher the number, 
+		the stronger you are.</td>
+	</tr>
+	<tr>
+		<td><p align="justify">Ac</p></td>
+		<td><p align="justify">Your current armor class. This number 
+		indicates how effective your armor is in stopping blows from 
+		unfriendly creatures. The lower this number is, the more 
+		effective the armor.</p></td>
+	</tr>
+	<tr>
+		<td><p align="justify">Exp</p></td>
+		<td><p align="justify">These two numbers give your current experience 
+		level and experience points. As you do things, you gain experience
+		points. At certain experience point totals, you gain an
+		experience level. The more experienced you are, the better
+		you are able to fight and to withstand magical attacks.</p></td>
+	</tr>
+</table>
+
+<h3 align="justify"><b>3.2. The top line</b></h3>
+
+<p align="justify">The top line of the screen is reserved for
+printing messages that describe things that are impossible
+to represent visually. If you see a &ldquo;--More--&rdquo;
+on the top line, this means that rogue wants to print
+another message on the screen, but it wants to make certain
+that you have read the one that is there first. To read the
+next message, just type a space.</p>
+
+<h3 align="justify"><b>3.3. The rest of the screen</b></h3>
+
+<p align="justify">The rest of the screen is the map of the
+level as you have explored it so far. Each symbol on the
+screen represents something. Here is a list of what the
+various symbols mean:</p>
+
+<table border="0" width="100%" id="table2" cellspacing="3" cellpadding="3">
+	<tr>
+		<td>@</td>
+		<td><p align="justify">This symbol represents you, the adventurer.</p></td>
+	</tr>
+	<tr>
+		<td>- |</td>
+		<td><p align="justify">These symbols represent the walls of rooms.</p></td>
+	</tr>
+	<tr>
+		<td>+</td>
+		<td>
+		<p align="justify">A door to/from a room.</p></td>
+	</tr>
+	<tr>
+		<td>.</td>
+		<td><p align="justify">The floor of a room.</p></td>
+	</tr>
+	<tr>
+		<td>#</td>
+		<td><p align="justify">The floor of a passage between rooms.</p></td>
+	</tr>
+	<tr>
+		<td>*</td>
+		<td><p align="justify">A pile or pot of gold.</p></td>
+	</tr>
+	<tr>
+		<td>)</td>
+		<td><p align="justify">A weapon of some sort.</p></td>
+	</tr>
+	<tr>
+		<td>]</td>
+		<td><p align="justify">A piece of armor.</p></td>
+	</tr>
+	<tr>
+		<td>!</td>
+		<td><p align="justify">A flask containing a magic potion.</p></td>
+	</tr>
+	<tr>
+		<td>?</td>
+		<td><p align="justify">A piece of paper, usually a magic scroll.</p></td>
+	</tr>
+	<tr>
+		<td>^</td>
+		<td><p align="justify">A trap, watch out for these.</p></td>
+	</tr>
+	<tr>
+		<td>%</td>
+		<td><p align="justify">The passage leading down to the next level.</p></td>
+	</tr>
+	<tr>
+		<td>:</td>
+		<td><p align="justify">A piece of food.</p></td>
+	</tr>
+	<tr>
+		<td>A-Z&nbsp;&nbsp;</td>
+		<td><p align="justify">The uppercase letters represent the various 
+		inhabitants of the Dungeons of Doom. Watch out, they can be mean.</p></td>
+	</tr>
+</table>
+
+<h2 align="justify"><b>4. Commands</b></h2>
+
+<p align="justify">Commands are given to rogue by pressing single letters.
+Most commands can be preceded by a count to repeat them
+(e.g. typing &quot;10s&quot; will do ten searches) The list
+of commands is rather long, but it can be read at any time
+during the game with the ? command. Here it is for
+reference, with a short explanation of each command.</p>
+
+<div align="center">
+<table border="0" cellspacing="3" cellpadding="3" id="table3">
+	<tr>
+		<td>?</td>
+		<td><p align="justify">The help command. Asks for a character to give help 
+		on. If you type a &quot;*&quot;, it will list all the commands,
+		otherwise it will explain what the character you typed
+		does.</p></td>
+	</tr>
+	<tr>
+		<td>/</td>
+		<td align="justify"><p>This is the &quot;What is that on the screen?&quot;
+		command. A &quot;/&quot; followed by any character that you
+		see on the level, will tell you what that character is. For
+		instance, typing &quot;/@&quot; will tell you that the @
+		symbol represents you, the player.</p></td>
+	</tr>
+	<tr>
+		<td colspan="2">h, H</td>
+	</tr>
+	<tr>
+		<td>&nbsp;</td>
+		<td><p align="justify">Move left. You move one space to the left. If you use
+		upper case h, you will continue to move left until you run into something. 
+		This works for all movement commands (e.g. &quot;L&quot; means run in direction
+		&quot;l&quot;)</p></td>
+	</tr>
+	<tr>
+		<td>j</td>