W343-3/Original patch

From NetHackWiki
Jump to navigation Jump to search

This post to rec.games.roguelike.nethack describes the original fix for W343-3.

The complete thread can be found in the Wayback Machine's archive of Google Groups. Google Groups itself only sporadically allows reading of direct links to posts. This post contains a patch, and Google Groups' mangling of whitespace is a problem. The text below is recovered from the Internet Archive.

Path: number1.nntp.dca.giganews.com!border1.nntp.dca.giganews.com!nntp.giganews.com!newshub.sdsu.edu!headwall.stanford.edu!newsfeed.stanford.edu!newsfeed.berkeley.edu!ucberkeley!sn-xit-02!sn-xit-06!sn-post-01!supernews.com!corp.supernews.com!not-for-mail
From: Ray Chason <long-defunct email address redacted>
Newsgroups: rec.games.roguelike.nethack
Subject: [PATCH] Fix for bug W343-3, part 3:  The patch
Date: Sat, 05 Nov 2005 11:45:39 +0000
Organization: Not Bloody Likely
Message-ID: <11mpohghs0v5ub2@corp.supernews.com>
User-Agent: KNode/0.7.7
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7Bit
X-Windows-95: Where do you want to go today?
X-Windows-XP: All your base are belong to us.
X-Complaints-To: abuse@supernews.com
Lines: 806
Xref: number1.nntp.dca.giganews.com rec.games.roguelike.nethack:300894

Bug W343-3 really consists of two distinct and unrelated bugs.  This
post is the third of a four part series, and presents a patch that
contains a proposed fix for both bugs.

--CUT HERE--CUT HERE--CUT HERE--CUT HERE--CUT HERE--CUT HERE--CUT HERE--
diff -U 3 -r nethack-3.4.3/include/extern.h nethack-3.4.3-w343-3/include/extern.h
--- nethack-3.4.3/include/extern.h      2003-12-07 18:39:14.000000000 -0500
+++ nethack-3.4.3-w343-3/include/extern.h       2005-10-28 22:55:26.000000000 -0400
@@ -453,7 +453,7 @@
 E int FDECL(def_char_to_monclass, (CHAR_P));
 #if !defined(MAKEDEFS_C) && !defined(LEV_LEX_C)
 E void FDECL(assign_graphics, (uchar *,int,int,int));
-E void FDECL(switch_graphics, (int));
+E void FDECL(switch_graphics, (int, int));
 #ifdef REINCARNATION
 E void FDECL(assign_rogue_graphics, (BOOLEAN_P));
 #endif
diff -U 3 -r nethack-3.4.3/include/flag.h nethack-3.4.3-w343-3/include/flag.h
--- nethack-3.4.3/include/flag.h        2003-12-07 18:39:14.000000000 -0500
+++ nethack-3.4.3-w343-3/include/flag.h 2005-10-28 22:17:22.000000000 -0400
@@ -158,7 +158,8 @@
        boolean  cbreak;        /* in cbreak mode, rogue format */
        boolean  DECgraphics;   /* use DEC VT-xxx extended character set */
        boolean  echo;          /* 1 to echo characters */
-       boolean  IBMgraphics;   /* use IBM extended character set */
+       unsigned IBMgraphics;   /* use IBM extended character set */
+       boolean  unicode;       /* true if Unicode in use */
        unsigned msg_history;   /* hint: # of top lines to save */
        boolean  num_pad;       /* use numbers for movement commands */
        boolean  news;          /* print news */
diff -U 3 -r nethack-3.4.3/src/drawing.c nethack-3.4.3-w343-3/src/drawing.c
--- nethack-3.4.3/src/drawing.c 2003-12-07 18:39:14.000000000 -0500
+++ nethack-3.4.3-w343-3/src/drawing.c  2005-10-28 23:42:40.000000000 -0400
@@ -314,6 +314,209 @@
 void NDECL((*ibmgraphics_mode_callback)) = 0;  /* set in tty_start_screen() */
 #endif /* PC9800 */
 
+/* [RLC]  The font used by a non-English-speaking user may sacrifice some
+   graphics to accommodate the accented characters.  To allow more flexibility
+   in choice of fonts, IBMgraphics is changed from a boolean to an integer from
+   0 to 3, where:
+        0 is no IBM graphics
+        1 is box drawing only
+        2 is box drawing plus a set of 38 symbols common to most PC code pages
+        3 is all IBM graphics as implemented in the original Nethack
+
+   ibm_graphics_1 and ibm_graphics_2 implement the reduced IBM graphics.
+   ibm_graphics implements the original IBM graphics.
+*/
+
+static uchar ibm_graphics_1[MAXPCHARS] = {
+/* 0*/ g_FILLER(S_stone),
+       0xb3,   /* S_vwall:     meta-3, vertical rule */
+       0xc4,   /* S_hwall:     meta-D, horizontal rule */
+       0xda,   /* S_tlcorn:    meta-Z, top left corner */
+       0xbf,   /* S_trcorn:    meta-?, top right corner */
+       0xc0,   /* S_blcorn:    meta-@, bottom left */
+       0xd9,   /* S_brcorn:    meta-Y, bottom right */
+       0xc5,   /* S_crwall:    meta-E, cross */
+       0xc1,   /* S_tuwall:    meta-A, T up */
+       0xc2,   /* S_tdwall:    meta-B, T down */
+/*10*/ 0xb4,   /* S_tlwall:    meta-4, T left */
+       0xc3,   /* S_trwall:    meta-C, T right */
+       g_FILLER(S_ndoor),
+       g_FILLER(S_vodoor),
+       g_FILLER(S_hodoor),
+       g_FILLER(S_vcdoor),
+       g_FILLER(S_hcdoor),
+       g_FILLER(S_bars),
+       g_FILLER(S_tree),
+       g_FILLER(S_room),
+/*20*/ g_FILLER(S_corr),
+       g_FILLER(S_litcorr),
+       g_FILLER(S_upstair),
+       g_FILLER(S_dnstair),
+       g_FILLER(S_upladder),
+       g_FILLER(S_dnladder),
+       g_FILLER(S_altar),
+       g_FILLER(S_grave),
+       g_FILLER(S_throne),
+       g_FILLER(S_sink),
+/*30*/ g_FILLER(S_fountain),
+       g_FILLER(S_pool),
+       g_FILLER(S_ice),
+       g_FILLER(S_lava),
+       g_FILLER(S_vodbridge),
+       g_FILLER(S_hodbridge),
+       g_FILLER(S_vcdbridge),
+       g_FILLER(S_hcdbridge),
+       g_FILLER(S_air),
+       g_FILLER(S_cloud),
+/*40*/ g_FILLER(S_water),
+       g_FILLER(S_arrow_trap),
+       g_FILLER(S_dart_trap),
+       g_FILLER(S_falling_rock_trap),
+       g_FILLER(S_squeaky_board),
+       g_FILLER(S_bear_trap),
+       g_FILLER(S_land_mine),
+       g_FILLER(S_rolling_boulder_trap),
+       g_FILLER(S_sleeping_gas_trap),
+       g_FILLER(S_rust_trap),
+/*50*/ g_FILLER(S_fire_trap),
+       g_FILLER(S_pit),
+       g_FILLER(S_spiked_pit),
+       g_FILLER(S_hole),
+       g_FILLER(S_trap_door),
+       g_FILLER(S_teleportation_trap),
+       g_FILLER(S_level_teleporter),
+       g_FILLER(S_magic_portal),
+       g_FILLER(S_web),
+       g_FILLER(S_statue_trap),
+/*60*/ g_FILLER(S_magic_trap),
+       g_FILLER(S_anti_magic_trap),
+       g_FILLER(S_polymorph_trap),
+       0xb3,   /* S_vbeam:     meta-3, vertical rule */
+       0xc4,   /* S_hbeam:     meta-D, horizontal rule */
+       g_FILLER(S_lslant),
+       g_FILLER(S_rslant),
+       g_FILLER(S_digbeam),
+       g_FILLER(S_flashbeam),
+       g_FILLER(S_boomleft),
+/*70*/ g_FILLER(S_boomright),
+       g_FILLER(S_ss1),
+       g_FILLER(S_ss2),
+       g_FILLER(S_ss3),
+       g_FILLER(S_ss4),
+       g_FILLER(S_sw_tl),
+       g_FILLER(S_sw_tc),
+       g_FILLER(S_sw_tr),
+       0xb3,   /* S_sw_ml:     meta-3, vertical rule */
+       0xb3,   /* S_sw_mr:     meta-3, vertical rule */
+/*80*/ g_FILLER(S_sw_bl),
+       g_FILLER(S_sw_bc),
+       g_FILLER(S_sw_br),
+       g_FILLER(S_explode1),
+       g_FILLER(S_explode2),
+       g_FILLER(S_explode3),
+       0xb3,   /* S_explode4:  meta-3, vertical rule */
+       g_FILLER(S_explode5),
+       0xb3,   /* S_explode6:  meta-3, vertical rule */
+       g_FILLER(S_explode7),
+/*90*/ g_FILLER(S_explode8),
+       g_FILLER(S_explode9)
+};
+
+static uchar ibm_graphics_2[MAXPCHARS] = {
+/* 0*/ g_FILLER(S_stone),
+       0xb3,   /* S_vwall:     meta-3, vertical rule */
+       0xc4,   /* S_hwall:     meta-D, horizontal rule */
+       0xda,   /* S_tlcorn:    meta-Z, top left corner */
+       0xbf,   /* S_trcorn:    meta-?, top right corner */
+       0xc0,   /* S_blcorn:    meta-@, bottom left */
+       0xd9,   /* S_brcorn:    meta-Y, bottom right */
+       0xc5,   /* S_crwall:    meta-E, cross */
+       0xc1,   /* S_tuwall:    meta-A, T up */
+       0xc2,   /* S_tdwall:    meta-B, T down */
+/*10*/ 0xb4,   /* S_tlwall:    meta-4, T left */
+       0xc3,   /* S_trwall:    meta-C, T right */
+       g_FILLER(S_ndoor),
+       0xfe,   /* S_vodoor:    meta-~, small centered square */
+       0xfe,   /* S_hodoor:    meta-~, small centered square */
+       g_FILLER(S_vcdoor),
+       g_FILLER(S_hcdoor),
+       g_FILLER(S_bars),
+       g_FILLER(S_tree),
+       g_FILLER(S_room),
+/*20*/ 0xb0,   /* S_corr:      meta-0, light shading */
+       0xb1,   /* S_litcorr:   meta-1, medium shading */
+       g_FILLER(S_upstair),
+       g_FILLER(S_dnstair),
+       g_FILLER(S_upladder),
+       g_FILLER(S_dnladder),
+       g_FILLER(S_altar),
+       g_FILLER(S_grave),
+       g_FILLER(S_throne),
+       g_FILLER(S_sink),
+/*30*/ g_FILLER(S_fountain),
+       g_FILLER(S_pool),
+       g_FILLER(S_ice),
+       g_FILLER(S_lava),
+       g_FILLER(S_vodbridge),
+       g_FILLER(S_hodbridge),
+       g_FILLER(S_vcdbridge),
+       g_FILLER(S_hcdbridge),
+       g_FILLER(S_air),
+       g_FILLER(S_cloud),
+/*40*/ g_FILLER(S_water),
+       g_FILLER(S_arrow_trap),
+       g_FILLER(S_dart_trap),
+       g_FILLER(S_falling_rock_trap),
+       g_FILLER(S_squeaky_board),
+       g_FILLER(S_bear_trap),
+       g_FILLER(S_land_mine),
+       g_FILLER(S_rolling_boulder_trap),
+       g_FILLER(S_sleeping_gas_trap),
+       g_FILLER(S_rust_trap),
+/*50*/ g_FILLER(S_fire_trap),
+       g_FILLER(S_pit),
+       g_FILLER(S_spiked_pit),
+       g_FILLER(S_hole),
+       g_FILLER(S_trap_door),
+       g_FILLER(S_teleportation_trap),
+       g_FILLER(S_level_teleporter),
+       g_FILLER(S_magic_portal),
+       g_FILLER(S_web),
+       g_FILLER(S_statue_trap),
+/*60*/ g_FILLER(S_magic_trap),
+       g_FILLER(S_anti_magic_trap),
+       g_FILLER(S_polymorph_trap),
+       0xb3,   /* S_vbeam:     meta-3, vertical rule */
+       0xc4,   /* S_hbeam:     meta-D, horizontal rule */
+       g_FILLER(S_lslant),
+       g_FILLER(S_rslant),
+       g_FILLER(S_digbeam),
+       g_FILLER(S_flashbeam),
+       g_FILLER(S_boomleft),
+/*70*/ g_FILLER(S_boomright),
+       g_FILLER(S_ss1),
+       g_FILLER(S_ss2),
+       g_FILLER(S_ss3),
+       g_FILLER(S_ss4),
+       g_FILLER(S_sw_tl),
+       g_FILLER(S_sw_tc),
+       g_FILLER(S_sw_tr),
+       0xb3,   /* S_sw_ml:     meta-3, vertical rule */
+       0xb3,   /* S_sw_mr:     meta-3, vertical rule */
+/*80*/ g_FILLER(S_sw_bl),
+       g_FILLER(S_sw_bc),
+       g_FILLER(S_sw_br),
+       g_FILLER(S_explode1),
+       g_FILLER(S_explode2),
+       g_FILLER(S_explode3),
+       0xb3,   /* S_explode4:  meta-3, vertical rule */
+       g_FILLER(S_explode5),
+       0xb3,   /* S_explode6:  meta-3, vertical rule */
+       g_FILLER(S_explode7),
+/*90*/ g_FILLER(S_explode8),
+       g_FILLER(S_explode9)
+};
+
 static uchar ibm_graphics[MAXPCHARS] = {
 /* 0*/ g_FILLER(S_stone),
        0xb3,   /* S_vwall:     meta-3, vertical rule */
@@ -652,12 +855,17 @@
 }
 
 void
-switch_graphics(gr_set_flag)
+switch_graphics(gr_set_flag, level)
 int gr_set_flag;
+int level;
 {
+    if (gr_set_flag==IBM_GRAPHICS && level<=0)
+       gr_set_flag = ASCII_GRAPHICS;
     switch (gr_set_flag) {
        default:
        case ASCII_GRAPHICS:
+           iflags.IBMgraphics = 0;
+           iflags.DECgraphics = FALSE;
            assign_graphics((uchar *)0, 0, MAXPCHARS, 0);
 #ifdef PC9800
            if (ascgraphics_mode_callback) (*ascgraphics_mode_callback)();
@@ -672,9 +880,16 @@
  * to the ISO 8859 character set.  We should probably do a VioSetCp() call to
  * set the codepage to 437.
  */
-           iflags.IBMgraphics = TRUE;
+           if (level < 0) level = 0;
+           if (level > 3) level = 3;
+           iflags.IBMgraphics = level;
            iflags.DECgraphics = FALSE;
-           assign_graphics(ibm_graphics, SIZE(ibm_graphics), MAXPCHARS, 0);
+           if (level == 1)
+               assign_graphics(ibm_graphics_1, SIZE(ibm_graphics_1), MAXPCHARS, 0);
+           else if (level == 2)
+               assign_graphics(ibm_graphics_2, SIZE(ibm_graphics_2), MAXPCHARS, 0);
+           else
+               assign_graphics(ibm_graphics, SIZE(ibm_graphics), MAXPCHARS, 0);
 #ifdef PC9800
            if (ibmgraphics_mode_callback) (*ibmgraphics_mode_callback)();
 #endif
@@ -773,6 +988,42 @@
        CHAIN_SYM,
        VENOM_SYM
 };
+
+static const uchar IBM2_r_oc_syms[MAXOCLASSES] = {     /* a la EPYX Rogue */
+/* 0*/ '\0',
+       ILLOBJ_SYM,
+#  if defined(MSDOS) || defined(OS2) || ( defined(WIN32) && !defined(MSWIN_GRAPHICS) )
+       0x18,                   /* weapon: up arrow */
+/*     0x0a, */ ARMOR_SYM,     /* armor:  Vert rect with o */
+/*     0x09, */ RING_SYM,      /* ring:   circle with arrow */
+/* 5*/ 0x0c,                   /* amulet: "female" symbol */
+       TOOL_SYM,
+       0x05,                   /* food:   club (as in cards) */
+       POTION_SYM,
+       0x0e,                   /* scroll: musical note */
+/*10*/ SPBOOK_SYM,
+       WAND_SYM,
+       0x0f,                   /* gold:   yes it's the same as gems */
+       0x0f,                   /* gems:   fancy '*' */
+#  else
+       ')',                    /* weapon  */
+       ARMOR_SYM,              /* armor */
+       RING_SYM,               /* ring */
+/* 5*/ ',',                    /* amulet  */
+       TOOL_SYM,
+       ':',                    /* food    */
+       POTION_SYM,
+       SCROLL_SYM,             /* scroll  */
+/*10*/ SPBOOK_SYM,
+       WAND_SYM,
+       GEM_SYM,                /* gold:   yes it's the same as gems */
+       GEM_SYM,                /* gems    */
+#  endif
+       ROCK_SYM,
+/*15*/ BALL_SYM,
+       CHAIN_SYM,
+       VENOM_SYM
+};
 # endif /* ASCIIGRAPH */
 
 void
@@ -783,6 +1034,7 @@
 
     if (is_rlevel) {
        register int i;
+       const uchar *symbols;
 
        (void) memcpy((genericptr_t)save_showsyms,
                      (genericptr_t)showsyms, sizeof showsyms);
@@ -795,7 +1047,7 @@
        for (i = 0; i < MAXMCLASSES; i++)
            monsyms[i] = def_monsyms[i];
 # if defined(ASCIIGRAPH) && !defined(MSWIN_GRAPHICS)
-       if (iflags.IBMgraphics
+       if (iflags.IBMgraphics >= 2
 #  if defined(USE_TILES) && defined(MSDOS)
                && !iflags.grmode
 #  endif
@@ -811,17 +1063,14 @@
  * all of this info and to simply initialize it via a for() loop like r_oc_syms.
  */
 
+       showsyms[S_vodoor]  = showsyms[S_hodoor]  = showsyms[S_ndoor] = '+';
+       showsyms[S_upstair] = showsyms[S_dnstair] = '%';
 # ifdef ASCIIGRAPH
-       if (!iflags.IBMgraphics
+       if (iflags.IBMgraphics
 #  if defined(USE_TILES) && defined(MSDOS)
-               || iflags.grmode
+               && !iflags.grmode
 #  endif
                                ) {
-# endif
-           showsyms[S_vodoor]  = showsyms[S_hodoor]  = showsyms[S_ndoor] = '+';
-           showsyms[S_upstair] = showsyms[S_dnstair] = '%';
-# ifdef ASCIIGRAPH
-       } else {
            /* a la EPYX Rogue */
            showsyms[S_vwall]   = 0xba; /* all walls now use    */
            showsyms[S_hwall]   = 0xcd; /* double line graphics */
@@ -837,49 +1086,59 @@
            showsyms[S_ndoor]   = 0xce;
            showsyms[S_vodoor]  = 0xce;
            showsyms[S_hodoor]  = 0xce;
-           showsyms[S_room]    = 0xfa; /* centered dot */
-           showsyms[S_corr]    = 0xb1;
-           showsyms[S_litcorr] = 0xb2;
-           showsyms[S_upstair] = 0xf0; /* Greek Xi */
-           showsyms[S_dnstair] = 0xf0;
+           if (iflags.IBMgraphics >= 2) {
+               showsyms[S_corr]    = 0xb1;
+               showsyms[S_litcorr] = 0xb2;
+           }
+           if (iflags.IBMgraphics >= 3) {
+               showsyms[S_room]    = 0xfa; /* centered dot */
+               showsyms[S_upstair] = 0xf0; /* Greek Xi */
+               showsyms[S_dnstair] = 0xf0;
+           }
+
 #ifndef MSWIN_GRAPHICS
-           showsyms[S_arrow_trap] = 0x04; /* diamond (cards) */
-           showsyms[S_dart_trap] = 0x04;
-           showsyms[S_falling_rock_trap] = 0x04;
-           showsyms[S_squeaky_board] = 0x04;
-           showsyms[S_bear_trap] = 0x04;
-           showsyms[S_land_mine] = 0x04;
-           showsyms[S_rolling_boulder_trap] = 0x04;
-           showsyms[S_sleeping_gas_trap] = 0x04;
-           showsyms[S_rust_trap] = 0x04;
-           showsyms[S_fire_trap] = 0x04;
-           showsyms[S_pit] = 0x04;
-           showsyms[S_spiked_pit] = 0x04;
-           showsyms[S_hole] = 0x04;
-           showsyms[S_trap_door] = 0x04;
-           showsyms[S_teleportation_trap] = 0x04;
-           showsyms[S_level_teleporter] = 0x04;
-           showsyms[S_magic_portal] = 0x04;
-           showsyms[S_web] = 0x04;
-           showsyms[S_statue_trap] = 0x04;
-           showsyms[S_magic_trap] = 0x04;
-           showsyms[S_anti_magic_trap] = 0x04;
-           showsyms[S_polymorph_trap] = 0x04;
+           if (iflags.IBMgraphics >= 2) {
+               showsyms[S_arrow_trap] = 0x04; /* diamond (cards) */
+               showsyms[S_dart_trap] = 0x04;
+               showsyms[S_falling_rock_trap] = 0x04;
+               showsyms[S_squeaky_board] = 0x04;
+               showsyms[S_bear_trap] = 0x04;
+               showsyms[S_land_mine] = 0x04;
+               showsyms[S_rolling_boulder_trap] = 0x04;
+               showsyms[S_sleeping_gas_trap] = 0x04;
+               showsyms[S_rust_trap] = 0x04;
+               showsyms[S_fire_trap] = 0x04;
+               showsyms[S_pit] = 0x04;
+               showsyms[S_spiked_pit] = 0x04;
+               showsyms[S_hole] = 0x04;
+               showsyms[S_trap_door] = 0x04;
+               showsyms[S_teleportation_trap] = 0x04;
+               showsyms[S_level_teleporter] = 0x04;
+               showsyms[S_magic_portal] = 0x04;
+               showsyms[S_web] = 0x04;
+               showsyms[S_statue_trap] = 0x04;
+               showsyms[S_magic_trap] = 0x04;
+               showsyms[S_anti_magic_trap] = 0x04;
+               showsyms[S_polymorph_trap] = 0x04;
+           }
 #endif
        }
 #endif /* ASCIIGRAPH */
 
-       for (i = 0; i < MAXOCLASSES; i++) {
+       symbols = r_oc_syms;
 #ifdef ASCIIGRAPH
-           if (iflags.IBMgraphics
 # if defined(USE_TILES) && defined(MSDOS)
-               && !iflags.grmode
+       if (!iflags.grmode)
 # endif
-               )
-               oc_syms[i] = IBM_r_oc_syms[i];
-           else
-#endif /* ASCIIGRAPH */
-               oc_syms[i] = r_oc_syms[i];
+       {
+           if (iflags.IBMgraphics == 2)
+               symbols = IBM2_r_oc_syms;
+           else if (iflags.IBMgraphics >= 3)
+               symbols = IBM_r_oc_syms;
+       }
+#endif
+       for (i = 0; i < MAXOCLASSES; i++) {
+           oc_syms[i] = symbols[i];
        }
 #if defined(MSDOS) && defined(USE_TILES)
        if (iflags.grmode) tileview(FALSE);
diff -U 3 -r nethack-3.4.3/src/options.c nethack-3.4.3-w343-3/src/options.c
--- nethack-3.4.3/src/options.c 2003-12-07 18:39:14.000000000 -0500
+++ nethack-3.4.3-w343-3/src/options.c  2005-10-28 22:49:18.000000000 -0400
@@ -101,11 +101,6 @@
        {"fullscreen", &iflags.wc2_fullscreen, FALSE, SET_IN_FILE},
        {"help", &flags.help, TRUE, SET_IN_GAME},
        {"hilite_pet",    &iflags.wc_hilite_pet, FALSE, SET_IN_GAME},   /*WC*/
-#ifdef ASCIIGRAPH
-       {"IBMgraphics", &iflags.IBMgraphics, FALSE, SET_IN_GAME},
-#else
-       {"IBMgraphics", (boolean *)0, FALSE, SET_IN_FILE},
-#endif
 #ifndef MAC
        {"ignintr", &flags.ignintr, FALSE, SET_IN_GAME},
 #else
@@ -245,6 +240,10 @@
                                                8, DISP_IN_GAME },
        { "horsename", "the name of your (first) horse (e.g., horsename:Silver)",
                                                PL_PSIZ, DISP_IN_GAME },
+#ifdef ASCIIGRAPH
+       {"IBMgraphics", "The set of IBM symbols to show the map (0, 1, 2 or 3)",
+                                               1, SET_IN_GAME },
+#endif
        { "map_mode", "map display mode under Windows", 20, DISP_IN_GAME },     /*WC*/
        { "menustyle", "user interface for object selection",
                                                MENUTYPELEN, SET_IN_GAME },
@@ -540,7 +539,7 @@
 
        for (i = 0; i < NUM_DISCLOSURE_OPTIONS; i++)
                flags.end_disclose[i] = DISCLOSE_PROMPT_DEFAULT_NO;
-       switch_graphics(ASCII_GRAPHICS);        /* set default characters */
+       switch_graphics(ASCII_GRAPHICS, 0);     /* set default characters */
 #if defined(UNIX) && defined(TTY_GRAPHICS)
        /*
         * Set defaults for some options depending on what we can
@@ -551,7 +550,7 @@
         */
        /* this detects the IBM-compatible console on most 386 boxes */
        if ((opts = nh_getenv("TERM")) && !strncmp(opts, "AT", 2)) {
-               switch_graphics(IBM_GRAPHICS);
+               switch_graphics(IBM_GRAPHICS, 3);
 # ifdef TEXTCOLOR
                iflags.use_color = TRUE;
 # endif
@@ -563,13 +562,13 @@
        if ((opts = nh_getenv("TERM")) &&
            !strncmpi(opts, "vt", 2) && AS && AE &&
            index(AS, '\016') && index(AE, '\017')) {
-               switch_graphics(DEC_GRAPHICS);
+               switch_graphics(DEC_GRAPHICS, 0);
        }
 # endif
 #endif /* UNIX || VMS */
 
 #ifdef MAC_GRAPHICS_ENV
-       switch_graphics(MAC_GRAPHICS);
+       switch_graphics(MAC_GRAPHICS, 0);
 #endif /* MAC_GRAPHICS_ENV */
        flags.menu_style = MENU_FULL;
 
@@ -1911,6 +1910,35 @@
        }
 #endif /* MSDOS */
 
+#ifdef ASCIIGRAPH
+       fullname = "IBMgraphics";
+       if (match_optname(opts, fullname, sizeof("IBMgraphics")-1, TRUE)) {
+               int level;
+
+               op = string_for_opt(opts, TRUE);
+               /* For backward compatibility, !IBMgraphics is mapped to 0
+                  and IBMgraphics without a parameter is mapped to 3 */
+               if (negated)
+                       level = 0;
+               else if (!op)
+                       level = 3;
+               else
+                       level = atoi(op);
+# ifdef REINCARNATION
+               if (!initial && Is_rogue_level(&u.uz))
+                   assign_rogue_graphics(FALSE);
+# endif
+               need_redraw = TRUE;
+               switch_graphics(level ?
+                               IBM_GRAPHICS : ASCII_GRAPHICS, level);
+# ifdef REINCARNATION
+               if (!initial && Is_rogue_level(&u.uz))
+                   assign_rogue_graphics(TRUE);
+# endif
+               return;
+       }
+#endif /* ASCIIGRAPH */
+
        /* WINCAP
         * map_mode:[tiles|ascii4x6|ascii6x8|ascii8x8|ascii16x8|ascii7x12|ascii8x12|
                        ascii16x12|ascii12x16|ascii10x18|fit_to_screen] */
@@ -2154,9 +2182,6 @@
 # ifdef TERMLIB
                                 || (boolopt[i].addr) == &iflags.DECgraphics
 # endif
-# ifdef ASCIIGRAPH
-                                || (boolopt[i].addr) == &iflags.IBMgraphics
-# endif
 # ifdef MAC_GRAPHICS_ENV
                                 || (boolopt[i].addr) == &iflags.MACgraphics
 # endif
@@ -2169,17 +2194,12 @@
 # ifdef TERMLIB
                            if ((boolopt[i].addr) == &iflags.DECgraphics)
                                switch_graphics(iflags.DECgraphics ?
-                                               DEC_GRAPHICS : ASCII_GRAPHICS);
-# endif
-# ifdef ASCIIGRAPH
-                           if ((boolopt[i].addr) == &iflags.IBMgraphics)
-                               switch_graphics(iflags.IBMgraphics ?
-                                               IBM_GRAPHICS : ASCII_GRAPHICS);
+                                               DEC_GRAPHICS : ASCII_GRAPHICS, 0);
 # endif
 # ifdef MAC_GRAPHICS_ENV
                            if ((boolopt[i].addr) == &iflags.MACgraphics)
                                switch_graphics(iflags.MACgraphics ?
-                                               MAC_GRAPHICS : ASCII_GRAPHICS);
+                                               MAC_GRAPHICS : ASCII_GRAPHICS, 0);
 # endif
 # ifdef REINCARNATION
                            if (!initial && Is_rogue_level(&u.uz))
@@ -2974,6 +2994,8 @@
                Sprintf(buf, "%s", rolestring(flags.initgend, genders, adj));
        else if (!strcmp(optname, "horsename")) 
                Sprintf(buf, "%s", horsename[0] ? horsename : none);
+       else if (!strcmp(optname,"IBMgraphics"))
+               Sprintf(buf, "%d", iflags.IBMgraphics);
        else if (!strcmp(optname, "map_mode"))
                Sprintf(buf, "%s",
                        iflags.wc_map_mode == MAP_MODE_TILES      ? "tiles" :
diff -U 3 -r nethack-3.4.3/sys/msdos/vidvga.c nethack-3.4.3-w343-3/sys/msdos/vidvga.c
--- nethack-3.4.3/sys/msdos/vidvga.c    2003-12-07 18:39:14.000000000 -0500
+++ nethack-3.4.3-w343-3/sys/msdos/vidvga.c     2005-10-28 23:45:48.000000000 -0400
@@ -580,7 +580,7 @@
 {
 /*     vga_HideCursor(); */
        if (on) {
-/*             switch_graphics(ASCII_GRAPHICS); */
+/*             switch_graphics(ASCII_GRAPHICS, 0); */
                iflags.traditional_view = TRUE;
                clipx = 0;
                clipxmax = CO - 1;
diff -U 3 -r nethack-3.4.3/sys/share/pcmain.c nethack-3.4.3-w343-3/sys/share/pcmain.c
--- nethack-3.4.3/sys/share/pcmain.c    2003-12-07 18:39:14.000000000 -0500
+++ nethack-3.4.3-w343-3/sys/share/pcmain.c     2005-10-28 23:53:26.000000000 -0400
@@ -513,13 +513,19 @@
 #ifndef AMIGA
                case 'I':
                case 'i':
-                       if (!strncmpi(argv[0]+1, "IBM", 3))
-                               switch_graphics(IBM_GRAPHICS);
+                       if (!strncmpi(argv[0]+1, "IBM", 3)) {
+                               int level = argv[0][4];
+                               if ('0' <= level && level <= '3')
+                                       level -= '0';
+                               else if (level != 0)
+                                       level = 3;
+                               switch_graphics(IBM_GRAPHICS, level);
+            }
                        break;
            /*  case 'D': */
                case 'd':
                        if (!strncmpi(argv[0]+1, "DEC", 3))
-                               switch_graphics(DEC_GRAPHICS);
+                               switch_graphics(DEC_GRAPHICS, 0);
                        break;
 #endif
                case 'g':
diff -U 3 -r nethack-3.4.3/sys/share/unixtty.c nethack-3.4.3-w343-3/sys/share/unixtty.c
--- nethack-3.4.3/sys/share/unixtty.c   2003-12-07 18:39:14.000000000 -0500
+++ nethack-3.4.3-w343-3/sys/share/unixtty.c    2005-10-28 23:50:30.000000000 -0400
@@ -365,7 +365,7 @@
        if (!strcmp(windowprocs.name, "tty") && sco_flag_console) {
                atexit(sco_mapon);
                sco_mapoff();
-               switch_graphics(IBM_GRAPHICS);
+               switch_graphics(IBM_GRAPHICS, 3);
 #  ifdef TEXTCOLOR
                if (has_colors())
                        iflags.use_color = TRUE;
diff -U 3 -r nethack-3.4.3/sys/unix/unixmain.c nethack-3.4.3-w343-3/sys/unix/unixmain.c
--- nethack-3.4.3/sys/unix/unixmain.c   2003-12-07 18:39:14.000000000 -0500
+++ nethack-3.4.3-w343-3/sys/unix/unixmain.c    2005-10-28 23:54:12.000000000 -0400
@@ -355,13 +355,19 @@
                        break;
                case 'I':
                case 'i':
-                       if (!strncmpi(argv[0]+1, "IBM", 3))
-                               switch_graphics(IBM_GRAPHICS);
+                       if (!strncmpi(argv[0]+1, "IBM", 3)) {
+                               int level = argv[0][4];
+                               if ('0' <= level && level <= '3')
+                                       level -= '0';
+                               else if (level != 0)
+                                       level = 3;
+                               switch_graphics(IBM_GRAPHICS, level);
+            }
                        break;
            /*  case 'D': */
                case 'd':
                        if (!strncmpi(argv[0]+1, "DEC", 3))
-                               switch_graphics(DEC_GRAPHICS);
+                               switch_graphics(DEC_GRAPHICS, 0);
                        break;
                case 'p': /* profession (role) */
                        if (argv[0][2]) {
diff -U 3 -r nethack-3.4.3/sys/vms/vmsmain.c nethack-3.4.3-w343-3/sys/vms/vmsmain.c
--- nethack-3.4.3/sys/vms/vmsmain.c     2003-12-07 18:39:14.000000000 -0500
+++ nethack-3.4.3-w343-3/sys/vms/vmsmain.c      2005-10-28 23:54:18.000000000 -0400
@@ -273,13 +273,19 @@
                        break;
                case 'I':
                case 'i':
-                       if (!strncmpi(argv[0]+1, "IBM", 3))
-                               switch_graphics(IBM_GRAPHICS);
+                       if (!strncmpi(argv[0]+1, "IBM", 3)) {
+                               int level = argv[0][4];
+                               if ('0' <= level && level <= '3')
+                                       level -= '0';
+                               else if (level != 0)
+                                       level = 3;
+                               switch_graphics(IBM_GRAPHICS, level);
+            }
                        break;
            /*  case 'D': */
                case 'd':
                        if (!strncmpi(argv[0]+1, "DEC", 3))
-                               switch_graphics(DEC_GRAPHICS);
+                               switch_graphics(DEC_GRAPHICS, 0);
                        break;
                case 'p': /* profession (role) */
                        if (argv[0][2]) {
diff -U 3 -r nethack-3.4.3/sys/winnt/nttty.c nethack-3.4.3-w343-3/sys/winnt/nttty.c
--- nethack-3.4.3/sys/winnt/nttty.c     2003-12-07 18:39:14.000000000 -0500
+++ nethack-3.4.3-w343-3/sys/winnt/nttty.c      2005-10-29 00:00:28.000000000 -0400
@@ -8,6 +8,7 @@
  * Initial Creation                            M. Allison      1993/01/31 
  * Switch to low level console output routines M. Allison      2003/10/01
  * Restrict cursor movement until input pending        M. Lehotay      2003/10/02
+ * Call Unicode version of output API on NT    R. Chason       2005/10/28
  *
  */
 
@@ -37,6 +38,7 @@
  * ReadConsoleInput
  * WriteConsoleOutputCharacter
  * FillConsoleOutputAttribute
+ * GetConsoleOutputCP
  */
 
 /* Win32 Console handles for input and output */
@@ -166,6 +168,7 @@
 setftty()
 {
        start_screen();
+       iflags.unicode = (GetVersion() & 0x80000000) == 0;
 }
 
 void
@@ -429,8 +432,22 @@
            default:
                        WriteConsoleOutputAttribute(hConOut,&attr,1,
                                                        cursor,&acount);
-                       WriteConsoleOutputCharacter(hConOut,&ch,1,
+                       if (iflags.unicode) {
+                               /* Avoid bug in ANSI API on WinNT */
+                               WCHAR c2[2];
+                               int rc;
+                               rc = MultiByteToWideChar(
+                                       GetConsoleOutputCP(),
+                                       0,
+                                       &ch, 1,
+                                       c2, 2);
+                               WriteConsoleOutputCharacterW(hConOut,c2,rc,
                                                        cursor,&ccount);
+                       }
+                       else {
+                               WriteConsoleOutputCharacterA(hConOut,&ch,1,
+                                                       cursor,&ccount);
+                       }
                        cursor.X++;
        }
 }
@@ -471,12 +488,51 @@
 g_putch(in_ch)
 int in_ch;
 {
-       char ch = (char)in_ch;
+       /* CP437 to Unicode mapping according to the Unicode Consortium */
+       static const WCHAR cp437[] =
+       {
+           0x0020, 0x263A, 0x263B, 0x2665, 0x2666, 0x2663, 0x2660, 0x2022,
+           0x25D8, 0x25CB, 0x25D9, 0x2642, 0x2640, 0x266A, 0x266B, 0x263C,
+           0x25BA, 0x25C4, 0x2195, 0x203C, 0x00B6, 0x00A7, 0x25AC, 0x21A8,
+           0x2191, 0x2193, 0x2192, 0x2190, 0x221F, 0x2194, 0x25B2, 0x25BC,
+           0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
+           0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
+           0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
+           0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
+           0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
+           0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
+           0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
+           0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f,
+           0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
+           0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f,
+           0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
+           0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x2302,
+           0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, 0x00e7,
+           0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x00ec, 0x00c4, 0x00c5,
+           0x00c9, 0x00e6, 0x00c6, 0x00f4, 0x00f6, 0x00f2, 0x00fb, 0x00f9,
+           0x00ff, 0x00d6, 0x00dc, 0x00a2, 0x00a3, 0x00a5, 0x20a7, 0x0192,
+           0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, 0x00ba,
+           0x00bf, 0x2310, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb,
+           0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
+           0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510,
+           0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f,
+           0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567,
+           0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b,
+           0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580,
+           0x03b1, 0x00df, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x00b5, 0x03c4,
+           0x03a6, 0x0398, 0x03a9, 0x03b4, 0x221e, 0x03c6, 0x03b5, 0x2229,
+           0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248,
+           0x00b0, 0x2219, 0x00b7, 0x221a, 0x207f, 0x00b2, 0x25a0, 0x00a0
+       };
+       unsigned char ch = (unsigned char)in_ch;
 
        cursor.X = ttyDisplay->curx;
        cursor.Y = ttyDisplay->cury;
        WriteConsoleOutputAttribute(hConOut,&attr,1,cursor,&acount);
-       WriteConsoleOutputCharacter(hConOut,&ch,1,cursor,&ccount);
+       if (iflags.unicode)
+           WriteConsoleOutputCharacterW(hConOut,&cp437[ch],1,cursor,&ccount);
+       else
+           WriteConsoleOutputCharacterA(hConOut,&ch,1,cursor,&ccount);
 }
 
 void
--CUT HERE--CUT HERE--CUT HERE--CUT HERE--CUT HERE--CUT HERE--CUT HERE--

-- 
 --------------===============<[ Ray Chason ]>===============--------------
                  The War on Terra is not meant to be won.
                    Delendae sunt RIAA, MPAA et Windoze