diff -Naurd ../nethack-3.4.0/sys/share/NetHack.cnf ./sys/share/NetHack.cnf
--- ../nethack-3.4.0/sys/share/NetHack.cnf Wed Mar 20 23:43:47 2002
+++ ./sys/share/NetHack.cnf Mon Feb 24 15:25:05 2003
@@ -61,16 +61,34 @@
 #OPTIONS=suppress_alert:3.3.1
 #
 #
+# *** LOCATIONS ***
+# Some platforms allow you to change the location where various things are kept.
+# IMPORTANT: If you change any of these locations, the directories they
+# point at must exist.  NetHack will not create them for you.
+#
+# The default location for everything.
+# Note: On Windows HACKDIR defaults to the location 
+#       of the NetHack.exe or NetHackw.exe file so
+#       setting HACKDIR below to override that is 
+#       not usually necessary or recommended.
 #HACKDIR=c:\games\nethack
-# 
-# Note: Under MSDOS ports HACKDIR defaults to the location 
-#       of the NetHack.exe file. Setting HACKDIR above will override that.
 #
-#   LEVELS and SAVE default to HACKDIR
+# The location that level files in progress are stored (default=HACKDIR, writeable)
+#LEVELDIR=c:\nethack\levels
+#
+# The location where saved games are kept (default=HACKDIR, writeable)
+#SAVEDIR=c:\nethack\save
+#
+# The location that bones files are kept (default=HACKDIR, writeable)
+#BONESDIR=c:\nethack\save
+#
+# The location that file synchronization locks are stored (default=HACKDIR, writeable)
+#LOCKDIR=c:\nethack\levels
+#
+# The location that a record of game aborts and self-diagnosed game problems
+# is kept (default=HACKDIR, writeable)
+#TROUBLEDIR=c:\nethack\trouble
 #
-#LEVELS=c:\games\nethack\bones
-#SAVE=c:\games\nethack\bones
-
 # *** CHARACTER GRAPHICS ***
 #
 # See the on-line help or the Guidebook for which symbols are in which
diff -Naurd ../nethack-3.4.0/sys/share/pcmain.c ./sys/share/pcmain.c
--- ../nethack-3.4.0/sys/share/pcmain.c Wed Mar 20 23:43:47 2002
+++ ./sys/share/pcmain.c Mon Feb 24 15:25:05 2003
@@ -80,6 +80,11 @@
 #endif
 
 #ifdef OVL0
+/* If the graphics version is built, we don't need a main; it is skipped
+ * to help MinGW decide which entry point to choose. If both main and 
+ * WinMain exist, the resulting executable won't work correctly.
+ */
+#ifndef MSWIN_GRAPHICS
 int
 main(argc,argv)
 int argc;
@@ -94,6 +99,7 @@
      /*NOTREACHED*/
      return 0;
 }
+#endif /*MSWIN_GRAPHICS*/
 #endif /*OVL0*/
 #ifdef OVL1
 
@@ -105,6 +111,12 @@
 
 	register int fd;
 	register char *dir;
+#if defined(WIN32)
+	char fnamebuf[BUFSZ], encodedfnamebuf[BUFSZ];
+#endif
+#ifdef NOCWD_ASSUMPTIONS
+	char failbuf[BUFSZ];
+#endif
 
 #if defined(__BORLANDC__) && !defined(_WIN32)
 	startup();
@@ -171,6 +183,14 @@
 #endif
 	initoptions();
 
+#ifdef NOCWD_ASSUMPTIONS
+	if (!validate_prefix_locations(failbuf)) {
+		raw_printf("Some invalid directory locations were specified:\n\t%s\n",
+				failbuf);
+		 nethack_exit(EXIT_FAILURE);
+	}
+#endif
+
 #if defined(TOS) && defined(TEXTCOLOR)
 	if (iflags.BIOS && iflags.use_color)
 		set_colors();
@@ -206,12 +226,17 @@
 		 * may do a prscore().
 		 */
 		if (!strncmp(argv[1], "-s", 2)) {
-#ifdef CHDIR
+#if !defined(MSWIN_GRAPHICS)
+# if defined(CHDIR) && !defined(NOCWD_ASSUMPTIONS)
 			chdirx(hackdir,0);
-#endif
+# endif
 			prscore(argc, argv);
+#else
+			raw_printf("-s is not supported for the Graphical Interface\n");
+#endif /*MSWIN_GRAPHICS*/
 			nethack_exit(EXIT_SUCCESS);
 		}
+		
 		/* Don't initialize the window system just to print usage */
 		if (!strncmp(argv[1], "-?", 2) || !strncmp(argv[1], "/?", 2)) {
 			nhusage();
@@ -233,7 +258,7 @@
 	/* chdir shouldn't be called before this point to keep the
 	 * code parallel to other ports.
 	 */
-#ifdef CHDIR
+#if defined(CHDIR) && !defined(NOCWD_ASSUMPTIONS)
 	chdirx(hackdir,1);
 #endif
 
@@ -245,6 +270,10 @@
 	process_options(argc, argv);
 #endif
 
+#ifdef WIN32CON
+	toggle_mouse_support();	/* must come after process_options */
+#endif
+
 #ifdef MFLOPPY
 	set_lock_and_bones();
 # ifndef AMIGA
@@ -286,13 +315,17 @@
 # if defined(WIN32)
 	/* Obtain the name of the logged on user and incorporate
 	 * it into the name. */
-	Sprintf(lock, "%s-%s",get_username(0),plname);
+	Sprintf(fnamebuf, "%s-%s", get_username(0), plname);
+	(void)fname_encode("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_-.",
+				'%', fnamebuf, encodedfnamebuf, BUFSZ);
+	Sprintf(lock, "%s",encodedfnamebuf);
+	/* regularize(lock); */ /* we encode now, rather than substitute */
 # else
 	Strcpy(lock,plname);
 	regularize(lock);
 # endif
 	getlock();
-#else   /* PC_LOCKING */
+#else   /* What follows is !PC_LOCKING */
 # ifdef AMIGA /* We'll put the bones & levels in the user specified directory -jhsa */
 	Strcat(lock,plname);
 	Strcat(lock,".99");
@@ -311,11 +344,15 @@
 
 	/* Set up level 0 file to keep the game state.
 	 */
-	fd = create_levelfile(0);
+	fd = create_levelfile(0, (char *)0);
 	if (fd < 0) {
 		raw_print("Cannot create lock file");
 	} else {
+#ifdef WIN32
+		hackpid = GetCurrentProcessId();
+#else
 		hackpid = 1;
+#endif
 		write(fd, (genericptr_t) &hackpid, sizeof(hackpid));
 		close(fd);
 	}
@@ -539,39 +576,44 @@
 STATIC_OVL void 
 nhusage()
 {
-	char buf1[BUFSZ];
+	char buf1[BUFSZ], buf2[BUFSZ], *bufptr;
+
+	buf1[0] = '\0';
+	bufptr = buf1;
+
+#define ADD_USAGE(s)	if ((strlen(buf1) + strlen(s)) < (BUFSZ - 1)) Strcat(bufptr, s);
 
 	/* -role still works for those cases which aren't already taken, but
 	 * is deprecated and will not be listed here.
 	 */
-	(void) Sprintf(buf1,
-"\nUsage: %s [-d dir] -s [-r race] [-p profession] [maxrank] [name]...\n       or",
+	(void) Sprintf(buf2,
+"\nUsage:\n%s [-d dir] -s [-r race] [-p profession] [maxrank] [name]...\n       or",
 		hname);
-	if (!iflags.window_inited)
-		raw_printf(buf1);
-	else
-		(void)	printf(buf1);
-	(void) Sprintf(buf1,
-	 "\n       %s [-d dir] [-u name] [-r race] [-p profession] [-[DX]]",
+	ADD_USAGE(buf2);
+
+	(void) Sprintf(buf2,
+	 "\n%s [-d dir] [-u name] [-r race] [-p profession] [-[DX]]",
 		hname);
+	ADD_USAGE(buf2);
 #ifdef NEWS
-	Strcat(buf1," [-n]");
+	ADD_USAGE(" [-n]");
 #endif
 #ifndef AMIGA
-	Strcat(buf1," [-I] [-i] [-d]");
+	ADD_USAGE(" [-I] [-i] [-d]");
 #endif
 #ifdef MFLOPPY
 # ifndef AMIGA
-	Strcat(buf1," [-R]");
+	ADD_USAGE(" [-R]");
 # endif
 #endif
 #ifdef AMIGA
-	Strcat(buf1," [-[lL]]");
+	ADD_USAGE(" [-[lL]]");
 #endif
 	if (!iflags.window_inited)
 		raw_printf("%s\n",buf1);
 	else
 		(void) printf("%s\n",buf1);
+#undef ADD_USAGE
 }
 
 #ifdef CHDIR
diff -Naurd ../nethack-3.4.0/sys/share/pcsys.c ./sys/share/pcsys.c
--- ../nethack-3.4.0/sys/share/pcsys.c Wed Mar 20 23:43:48 2002
+++ ./sys/share/pcsys.c Mon Feb 24 15:25:05 2003
@@ -56,7 +56,7 @@
 extern int GUILaunched;    /* from nttty.c */
 #endif
 
-#ifdef MICRO
+#if defined(MICRO) || defined(WIN32)
 
 void
 flushout()
@@ -95,7 +95,9 @@
 #   endif
 		suspend_nhwindows((char *)0);
 #  endif /* TOS */
+#  ifndef NOCWD_ASSUMPTIONS
 		chdirx(orgdir, 0);
+#  endif
 #  ifdef __GO32__
 		if (system(comspec) < 0) {  /* wsu@eecs.umich.edu */
 #  else
@@ -120,7 +122,9 @@
 		if (iflags.BIOS)
 			(void)Cursconf(1, -1);
 #  endif
+#  ifndef NOCWD_ASSUMPTIONS
 		chdirx(hackdir, 0);
+#  endif
 		get_scr_size(); /* maybe the screen mode changed (TH) */
 #  if defined(MSDOS) && defined(NO_TERMS)
 		if (grmode) gr_init();
@@ -384,10 +388,17 @@
 	return;
 }
 
+#ifdef WIN32
+boolean getreturn_disable;
+#endif
+
 void
 getreturn(str)
 const char *str;
 {
+#ifdef WIN32
+	if (getreturn_disable) return;
+#endif
 #ifdef TOS
 	msmsg("Hit <Return> %s.", str);
 #else
@@ -401,7 +412,7 @@
 msmsg VA_DECL(const char *, fmt)
 	VA_START(fmt);
 	VA_INIT(fmt, const char *);
-# if defined(MSDOS)
+# if defined(MSDOS) && defined(NO_TERMS)
 	if (iflags.grmode)
 		gr_finish();
 # endif
@@ -505,7 +516,7 @@
 #ifdef MFLOPPY
 	if (ramdisk) copybones(TOPERM);
 #endif
-#ifdef CHDIR
+#if defined(CHDIR) && !defined(NOCWD_ASSUMPTIONS)
 	chdir(orgdir);		/* chdir, not chdirx */
 	chdrive(orgdir);
 #endif
@@ -528,25 +539,4 @@
 #endif
 	return;
 }
-#ifdef WIN32
-/*
- * This is a kludge.  Just before the release of 3.3.0 the latest
- * version of a popular MAPI mail product was found to exhibit
- * a strange result where the current directory was changed out
- * from under NetHack resulting in a failure of all subsequent
- * file operations in NetHack.  This routine is called prior
- * to all file open/renames/deletes in file.c.
- *
- * A more elegant solution will be sought after 3.3.0 is released.
- */
-void dircheck()
-{
-	char dirbuf[BUFSZ];
-	dirbuf[0] = '\0';
-	if (getcwd(dirbuf, sizeof dirbuf) != (char *)0)
-		/* pline("%s,%s",dirbuf,hackdir); */
-		if (strcmp(dirbuf,hackdir) != 0)
-			chdir(hackdir);		/* chdir, not chdirx */
-}
-#endif
 #endif /* MICRO || WIN32 || OS2 */
diff -Naurd ../nethack-3.4.0/sys/share/pcunix.c ./sys/share/pcunix.c
--- ../nethack-3.4.0/sys/share/pcunix.c Wed Mar 20 23:43:48 2002
+++ ./sys/share/pcunix.c Mon Feb 24 15:25:05 2003
@@ -48,14 +48,14 @@
 	return(0);
     }
 # else
-#  if defined(MICRO) && !defined(NO_FSTAT)
+#  if (defined(MICRO) || defined(WIN32)) && !defined(NO_FSTAT)
     if(fstat(fd, &buf)) {
 	if(moves > 1) pline("Cannot get status of saved level? ");
-	else pline("Cannot get status of saved game");
+	else pline("Cannot get status of saved game.");
 	return(0);
     } 
     if(comp_times(buf.st_mtime)) { 
-	if(moves > 1) pline("Saved level is out of date");
+	if(moves > 1) pline("Saved level is out of date.");
 	else pline("Saved game is out of date. ");
 	/* This problem occurs enough times we need to give the player
 	 * some more information about what causes it, and how to fix.
@@ -88,6 +88,9 @@
 		(void) unlink(fqname(lock, LEVELPREFIX, 0));
 	}
 	set_levelfile_name(lock, 0);
+#ifdef HOLD_LOCKFILE_OPEN
+	really_close();
+#endif
 	if(unlink(fqname(lock, LEVELPREFIX, 0)))
 		return 0;				/* cannot remove it */
 	return(1);					/* success! */
@@ -96,7 +99,7 @@
 void
 getlock()
 {
-	register int fd, c, ci, ct;
+	register int fd, c, ci, ct, ern;
 	char tbuf[BUFSZ];
 	const char *fq_lock;
 # if defined(MSDOS) && defined(NO_TERMS)
@@ -106,18 +109,42 @@
 	/* we ignore QUIT and INT at this point */
 	if (!lock_file(HLOCK, LOCKPREFIX, 10)) {
 		wait_synch();
+# if defined(CHDIR) && !defined(NOCWD_ASSUMPTIONS)
 		chdirx(orgdir, 0);
+# endif
 		error("Quitting.");
 	}
 
 	/* regularize(lock); */ /* already done in pcmain */
-	Sprintf(tbuf,fqname(lock, LEVELPREFIX, 0));
+	Sprintf(tbuf,"%s",fqname(lock, LEVELPREFIX, 0));
 	set_levelfile_name(lock, 0);
 	fq_lock = fqname(lock, LEVELPREFIX, 1);
 	if((fd = open(fq_lock,0)) == -1) {
 		if(errno == ENOENT) goto gotlock;    /* no such file */
+# if defined(CHDIR) && !defined(NOCWD_ASSUMPTIONS)
 		chdirx(orgdir, 0);
+# endif
+# if defined(WIN32) || defined(HOLD_LOCKFILE_OPEN)
+#  if defined(HOLD_LOCKFILE_OPEN)
+ 		if(errno == EACCES) {
+#define OOPS_BUFSZ 512
+ 		    char oops[OOPS_BUFSZ];
+ 		    Strcpy(oops,
+			     "\nThere are files from a game in progress under your name.");
+		    Strcat(oops, "\nThe files are locked or inaccessible.");
+		    Strcat(oops, " Is the other game still running?\n");
+		    if (strlen(fq_lock) < ((OOPS_BUFSZ -16) - strlen(oops)))
+			    Sprintf(eos(oops), "Cannot open %s", fq_lock);
+		    Strcat(oops, "\n");
+		    unlock_file(HLOCK);
+		    error(oops);
+ 		} else
+#  endif
+		error("Bad directory or name: %s\n%s\n",
+				fq_lock, strerror(errno));
+# else
 		perror(fq_lock);
+# endif
 		unlock_file(HLOCK); 
 		error("Cannot open %s", fq_lock);
 	}
@@ -125,9 +152,13 @@
 	(void) close(fd);
 
 	if(iflags.window_inited) { 
+# ifdef SELF_RECOVER
+	  c = yn("There are files from a game in progress under your name. Recover?");
+# else
 	  pline("There is already a game in progress under your name.");
 	  pline("You may be able to use \"recover %s\" to get it back.\n",tbuf);
 	  c = yn("Do you want to destroy the old game?");
+# endif
 	} else {
 # if defined(MSDOS) && defined(NO_TERMS)
 		grmode = iflags.grmode;
@@ -135,14 +166,21 @@
 # endif
 		c = 'n';
 		ct = 0;
+# ifdef SELF_RECOVER
+		msmsg(
+		"There are files from a game in progress under your name. Recover? [yn]");
+# else
 		msmsg("\nThere is already a game in progress under your name.\n");
 		msmsg("If this is unexpected, you may be able to use \n");
 		msmsg("\"recover %s\" to get it back.",tbuf);
 		msmsg("\nDo you want to destroy the old game? [yn] ");
+# endif
 		while ((ci=nhgetch()) != '\n') {
 		    if (ct > 0) {
 # if defined(WIN32CON)
 			backsp();       /* \b is visible on NT */
+			(void) putchar(' ');
+			backsp();
 # else
 			msmsg("\b \b");
 # endif
@@ -157,36 +195,68 @@
 		}
 	}
 	if(c == 'y' || c == 'Y')
+# ifndef SELF_RECOVER
 		if(eraseoldlocks()) {
-# if defined(WIN32CON)
+#  if defined(WIN32CON)
 			clear_screen();		/* display gets fouled up otherwise */
-# endif
+#  endif
 			goto gotlock;
 		} else {
 			unlock_file(HLOCK);
+#  if defined(CHDIR) && !defined(NOCWD_ASSUMPTIONS)
 			chdirx(orgdir, 0);
+#  endif
 			error("Couldn't destroy old game.");
 		}
+# else /*SELF_RECOVER*/
+		if(recover_savefile()) {
+#  if defined(WIN32CON)
+			clear_screen();		/* display gets fouled up otherwise */
+#  endif
+			goto gotlock;
+		} else {
+			unlock_file(HLOCK);
+#  if defined(CHDIR) && !defined(NOCWD_ASSUMPTIONS)
+			chdirx(orgdir, 0);
+#  endif
+			error("Couldn't recover old game.");
+		}
+# endif /*SELF_RECOVER*/
 	else {
 		unlock_file(HLOCK);
+# if defined(CHDIR) && !defined(NOCWD_ASSUMPTIONS)
 		chdirx(orgdir, 0);
-		error("%s", "");
+# endif
+		error("%s", "Cannot start a new game.");
 	}
 
 gotlock:
 	fd = creat(fq_lock, FCMASK);
+	if (fd == -1) ern = errno;
 	unlock_file(HLOCK);
 	if(fd == -1) {
+# if defined(CHDIR) && !defined(NOCWD_ASSUMPTIONS)
 		chdirx(orgdir, 0);
-		error("cannot creat lock file (%s.)", fq_lock);
+# endif
+# if defined(WIN32)
+		error("cannot creat file (%s.)\n%s\n%s\"%s\" exists?\n", 
+				fq_lock, strerror(ern), " Are you sure that the directory",
+				fqn_prefix[LEVELPREFIX]);
+# else
+		error("cannot creat file (%s.)", fq_lock);
+# endif
 	} else {
 		if(write(fd, (char *) &hackpid, sizeof(hackpid))
 		    != sizeof(hackpid)){
+# if defined(CHDIR) && !defined(NOCWD_ASSUMPTIONS)
 			chdirx(orgdir, 0);
+# endif
 			error("cannot write lock (%s)", fq_lock);
 		}
 		if(close(fd) == -1) {
+# if defined(CHDIR) && !defined(NOCWD_ASSUMPTIONS)
 			chdirx(orgdir, 0);
+# endif
 			error("cannot close lock (%s)", fq_lock);
 		}
 	}
@@ -194,7 +264,7 @@
 	if (grmode) gr_init();
 # endif
 }	
-# endif /* PC_LOCKING */
+#endif /* PC_LOCKING */
 
 # ifndef WIN32
 void
diff -Naurd ../nethack-3.4.0/sys/share/uudecode.c ./sys/share/uudecode.c
--- ../nethack-3.4.0/sys/share/uudecode.c Wed Mar 20 23:43:49 2002
+++ ./sys/share/uudecode.c Mon Feb 24 15:25:05 2003
@@ -164,6 +164,8 @@
 		exit(5);
 	}
 	exit(0);
+	/*NOTREACHED*/
+	return 0;
 }
 
 /*

