]> granicus.if.org Git - nethack/commitdiff
githib pull request #232 - curses symset
authorPatR <rankin@nethack.org>
Wed, 16 Oct 2019 22:52:00 +0000 (15:52 -0700)
committerPatR <rankin@nethack.org>
Wed, 16 Oct 2019 22:52:00 +0000 (15:52 -0700)
This time I'm putting things in as-is before making a few tweaks.

The pull request was three or four separate changes.  I used the
patch instead so they've been collected into one commit.

dat/symbols
include/rm.h
include/wincurs.h
src/drawing.c
src/options.c
win/curses/cursinit.c
win/curses/cursmain.c
win/curses/cursmisc.c
win/curses/cursmisc.h

index be27dad5de800b625eb977e28d69122990697c96..364c6db219de65011f472dfa0ec042157f391598 100644 (file)
 # NetHack encodes the request to use the alternate font here by
 # having the high bit set (in hexadecimal, \x80 is combined with
 # a character code between \x60 and \x7f).
+#
+# curses is an approximation of IBMgraphics which relies on DEC
+# mode of operation, with a few characters missing. It is based
+# on an old graphics mode for the Curses mode and is the default
+# on that windowport if no symset is specified.
 
 start: DECgraphics
        Handling: DEC
@@ -55,6 +60,35 @@ start: DECgraphics
        S_explode8: \xf3                # meta-s, low horizontal line
 finish
 
+start: curses
+       Handling: DEC
+       S_vwall: \xf8                   # meta-x, vertical rule
+       S_hwall: \xf1                   # meta-q, horizontal rule
+       S_tlcorn: \xec                  # meta-l, top left corner
+       S_trcorn: \xeb                  # meta-k, top right corner
+       S_blcorn: \xed                  # meta-m, bottom left
+       S_brcorn: \xea                  # meta-j, bottom right
+       S_crwall: \xee                  # meta-n, cross
+       S_tuwall: \xf6                  # meta-v, T up
+       S_tdwall: \xf7                  # meta-w, T down
+       S_tlwall: \xf5                  # meta-u, T left
+       S_trwall: \xf4                  # meta-t, T right
+       S_ndoor: \xfe                   # meta-z, centered dot
+       S_tree: \xf1                    # plus or minus symbol
+       S_room: \xfe                    # meta-z, centered dot
+       S_corr: \xe1                    # meta-a, solid block
+       S_litcorr: \xe1                 # meta-a, solid block
+       S_ice: \xfe                     # meta-z, centered dot
+       S_vodbridge: \xfe               # meta-z, centered dot
+       S_hodbridge: \xfe               # meta-z, centered dot
+       S_vbeam: \xf8                   # meta-3, vertical rule
+       S_hbeam: \xf1                   # meta-D, horizontal rule
+       S_sw_ml: \xf8                   # meta-3, vertical rule
+       S_sw_mr: \xf8                   # meta-3, vertical rule
+       S_explode4: \xf8                # meta-3, vertical rule
+       S_explode6: \xf8                # meta-3, vertical rule
+finish
+
 start: IBMgraphics
        Handling: IBM
        S_vwall: \xb3                   # meta-3, vertical rule
index 1190a355b4ed8f8c4a41e3a9aae1fb807f77ce4d..becdd21a01c904c33b88c0f490d38b1605a95fdc 100644 (file)
@@ -278,7 +278,8 @@ struct symsetentry {
     Bitfield(nocolor, 1);     /* don't use color if set               */
     Bitfield(primary, 1);     /* restricted for use as primary set    */
     Bitfield(rogue, 1);       /* restricted for use as rogue lev set  */
-                              /* 5 free bits */
+    Bitfield(fallback, 1);    /* no explicit symset set               */
+                              /* 4 free bits */
 };
 
 /*
index c7d16f9e515180c8e76c8d33d2244a7e17ec5d6b..8ae45e10ea4d46c84f1f9c1655fa5994c22437a7 100644 (file)
@@ -152,7 +152,7 @@ extern char *curses_break_str(const char *str, int width, int line_num);
 extern char *curses_str_remainder(const char *str, int width, int line_num);
 extern boolean curses_is_menu(winid wid);
 extern boolean curses_is_text(winid wid);
-extern int curses_convert_glyph(boolean decgraphics, int ch, int glyph);
+extern int curses_convert_glyph(int ch, int glyph);
 extern void curses_move_cursor(winid wid, int x, int y);
 extern void curses_prehousekeeping(void);
 extern void curses_posthousekeeping(void);
index e9a1e08e19ea5d62894141d69ed1b8e51ffc2ee1..f29dbf3a246bd5b35a4540f9774ef6c25599e0ae 100644 (file)
@@ -543,6 +543,7 @@ boolean name_too;
     /* initialize restriction bits */
     symset[which_set].primary = 0;
     symset[which_set].rogue = 0;
+    symset[which_set].fallback = TRUE;
 
     if (name_too) {
         if (symset[which_set].name)
index cc39f585be4b7895a85969cc6b52a59e845958e8..220f8f483d378886db60461b6117e8256796edd6 100644 (file)
@@ -2315,6 +2315,7 @@ boolean tinitial, tfrom_file;
             } else {
                 if (!initial && Is_rogue_level(&u.uz))
                     assign_graphics(ROGUESET);
+                symset[ROGUESET].fallback = FALSE;
                 need_redraw = TRUE;
             }
         } else
@@ -2339,6 +2340,7 @@ boolean tinitial, tfrom_file;
                 return FALSE;
             } else {
                 switch_symbols(symset[PRIMARY].name != (char *) 0);
+                symset[PRIMARY].fallback = FALSE;
                 need_redraw = TRUE;
             }
         } else
@@ -6008,8 +6010,10 @@ int which_set;
 
     if (read_sym_file(which_set)) {
         switch_symbols(TRUE);
+        symset[which_set].fallback = FALSE;
     } else {
         clear_symsetentry(which_set, TRUE);
+        symset[which_set].fallback = TRUE;
         return 0;
     }
     return 1;
index 7c5ac185b015c8e86edc0c5bfb81bfee0c84f1eb..77333485566a9b599c1ed47f60b3e01e5e9ab85a 100644 (file)
@@ -784,6 +784,11 @@ curses_init_options()
     /* Remove a few options that are irrelevant to this windowport */
     set_option_mod_status("eight_bit_tty", SET_IN_FILE);
 
+    /* If we don't have a symset defined, load the curses symset by default */
+    if (symset[PRIMARY].fallback) {
+        load_symset("curses", PRIMARY);
+        load_symset("default", ROGUESET);
+    }
 #ifdef PDCURSES
     /* PDCurses for SDL, win32 and OS/2 has the ability to set the
        terminal size programatically.  If the user does not specify a
index d252b5b6dbf2c6460743f6604033f5b99e4b0bf8..e0b69b42c487484d5ea5044d1b840f6dd759779d 100644 (file)
@@ -660,9 +660,7 @@ curses_print_glyph(winid wid, XCHAR_P x, XCHAR_P y, int glyph,
         attr = A_REVERSE;
     }
     if (SYMHANDLING(H_DEC))
-        ch = curses_convert_glyph(TRUE, ch, glyph);
-    else if (!symset[PRIMARY].name || !strcmpi(symset[PRIMARY].name, "curses"))
-        ch = curses_convert_glyph(FALSE, ch, glyph);
+        ch = curses_convert_glyph(ch, glyph);
 
     if (wid == NHW_MAP) {
 /* hilite stairs not in 3.6, yet
index 2a2dd8a7b622add13b655c2cf2f271487af295a7..df331667957bdaa1d229f706c466170a9bf27a87 100644 (file)
@@ -74,7 +74,7 @@ curses_read_char()
 #ifdef KEY_RESIZE
     /* Handle resize events via get_nh_event, not this code */
     if (ch == KEY_RESIZE) {
-        ch = '\033'; /* NetHack doesn't know what to do with KEY_RESIZE */
+        ch = C('r'); /* NetHack doesn't know what to do with KEY_RESIZE */
     }
 #endif
 
@@ -467,161 +467,113 @@ curses_is_text(winid wid)
    cursesgraphics option is enabled, or special curses handling for
    DECgraphics */
 int
-curses_convert_glyph(boolean decgraphics, int ch, int glyph)
+curses_convert_glyph(int ch, int glyph)
 {
-    static int cursesglyphs[MAXPCHARS], cursesglyphsinited = 0;
     int retch, symbol;
 
     /* FIXME?  we don't support any special characters in roguesymset */
     if (Is_rogue_level(&u.uz))
         return ch;
 
-    /* Save some processing time by returning if the glyph represents
-       an object that we don't have custom characters for */
-    if (!glyph_is_cmap(glyph))
-        return ch;
-
     symbol = glyph_to_cmap(glyph);
 
-    /*
-     * FIXME:
-     *  'cursesgraphics' should be a symbol set so that users can
-     *  modify it without having to edit this source file and rebuild
-     *  the program.  Unfortunately these ACS values are 32-bit ones
-     *  and not user-friendly.
-     */
-    if (!cursesglyphsinited) { /* one-time initialization */
-        cursesglyphsinited = 1;
-        cursesglyphs[S_vwall] = ACS_VLINE;
-        cursesglyphs[S_hwall] = ACS_HLINE;
-        cursesglyphs[S_tlcorn] = ACS_ULCORNER;
-        cursesglyphs[S_trcorn] = ACS_URCORNER;
-        cursesglyphs[S_blcorn] = ACS_LLCORNER;
-        cursesglyphs[S_brcorn] = ACS_LRCORNER;
-        cursesglyphs[S_crwall] = ACS_PLUS;
-        cursesglyphs[S_tuwall] = ACS_BTEE;
-        cursesglyphs[S_tdwall] = ACS_TTEE;
-        /* yes, the left/right Ts are inverted nethack vs curses */
-        cursesglyphs[S_tlwall] = ACS_RTEE;
-        cursesglyphs[S_trwall] = ACS_LTEE;
-        cursesglyphs[S_tree] = ACS_PLMINUS;
-        cursesglyphs[S_corr] = ACS_CKBOARD;
-        cursesglyphs[S_litcorr] = ACS_CKBOARD;
-    }
-
     /* Curses has complete access to all characters that DECgraphics uses.
        However, their character value isn't consistent between terminals
        and implementations.  For actual DEC terminals and faithful emulators,
        line-drawing characters are specified as lowercase letters (mostly)
        and a control code is sent to the terminal telling it to switch
        character sets (that's how the tty interface handles them).
-       Curses remaps the characters instead. */
-    if (decgraphics) {
-        /* the DEC line drawing characters use 0x5f through 0x7e instead
-           of the much more straightforward 0x60 through 0x7f, possibly
-           because 0x7f is effectively a control character (Rubout);
-           nethack ORs 0x80 to flag line drawing--that's stripped below */
-        static int decchars[33]; /* for chars 0x5f through 0x7f (95..127) */
-
-        /* one-time initialization; some ACS_x aren't compile-time constant */
-        if (!decchars[0]) {
-            /* [0] is non-breakable space; irrelevant to nethack */
-            decchars[0x5f - 0x5f] = ' '; /* NBSP */
-            decchars[0x60 - 0x5f] = ACS_DIAMOND; /* [1] solid diamond */
-            decchars[0x61 - 0x5f] = ACS_CKBOARD; /* [2] checkerboard */
-            /* several "line drawing" characters are two-letter glyphs
-               which could be substituted for invisible control codes;
-               nethack's DECgraphics doesn't use any of them so we're
-               satisfied with conversion to a simple letter;
-               [3] "HT" as one char, with small raised upper case H over
-               and/or preceding small lowered upper case T */
-            decchars[0x62 - 0x5f] = 'H'; /* "HT" (horizontal tab) */
-            decchars[0x63 - 0x5f] = 'F'; /* "FF" as one char (form feed) */
-            decchars[0x64 - 0x5f] = 'C'; /* "CR" as one (carriage return) */
-            decchars[0x65 - 0x5f] = 'L'; /* [6] "LF" as one (line feed) */
-            decchars[0x66 - 0x5f] = ACS_DEGREE; /* small raised circle */
-            /* [8] plus or minus sign, '+' with horizontal line below */
-            decchars[0x67 - 0x5f] = ACS_PLMINUS;
-            decchars[0x68 - 0x5f] = 'N'; /* [9] "NL" as one char (new line) */
-            decchars[0x69 - 0x5f] = 'V'; /* [10] "VT" as one (vertical tab) */
-            decchars[0x6a - 0x5f] = ACS_LRCORNER; /* lower right corner */
-            decchars[0x6b - 0x5f] = ACS_URCORNER; /* upper right corner */
-            decchars[0x6c - 0x5f] = ACS_ULCORNER; /* upper left corner */
-            decchars[0x6d - 0x5f] = ACS_LLCORNER; /* lower left corner, 'L' */
-            /* [15] center cross, like big '+' sign */
-            decchars[0x6e - 0x5f] = ACS_PLUS;
-            decchars[0x6f - 0x5f] = ACS_S1; /* very high horizontal line */
-            decchars[0x70 - 0x5f] = ACS_S3; /* medium high horizontal line */
-            decchars[0x71 - 0x5f] = ACS_HLINE; /* centered horizontal line */
-            decchars[0x72 - 0x5f] = ACS_S7; /* medium low horizontal line */
-            decchars[0x73 - 0x5f] = ACS_S9; /* very low horizontal line */
-            /* [21] left tee, 'H' with right-hand vertical stroke removed;
-               note on left vs right:  the ACS name (also DEC's terminal
-               documentation) refers to vertical bar rather than cross stroke,
-               nethack's left/right refers to direction of the cross stroke */
-            decchars[0x74 - 0x5f] = ACS_LTEE; /* ACS left tee, NH right tee */
-            /* [22] right tee, 'H' with left-hand vertical stroke removed */
-            decchars[0x75 - 0x5f] = ACS_RTEE; /* ACS right tee, NH left tee */
-            /* [23] bottom tee, '+' with lower half of vertical stroke
-               removed and remaining stroke pointed up (unside-down 'T');
-               nethack is inconsistent here--unlike with left/right, its
-               bottom/top directions agree with ACS */
-            decchars[0x76 - 0x5f] = ACS_BTEE; /* bottom tee, stroke up */
-            /* [24] top tee, '+' with upper half of vertical stroke removed */
-            decchars[0x77 - 0x5f] = ACS_TTEE; /* top tee, stroke down, 'T' */
-            decchars[0x78 - 0x5f] = ACS_VLINE; /* centered vertical line */
-            decchars[0x79 - 0x5f] = ACS_LEQUAL; /* less than or equal to */
-            /* [27] greater than or equal to, '>' with underscore */
-            decchars[0x7a - 0x5f] = ACS_GEQUAL;
-            /* [28] Greek pi ('n'-like; case is ambiguous: small size
-               suggests lower case but flat top suggests upper case) */
-            decchars[0x7b - 0x5f] = ACS_PI;
-            /* [29] not equal sign, combination of '=' and '/' */
-            decchars[0x7c - 0x5f] = ACS_NEQUAL;
-            /* [30] British pound sign (curly 'L' with embellishments) */
-            decchars[0x7d - 0x5f] = ACS_STERLING;
-            decchars[0x7e - 0x5f] = ACS_BULLET; /* [31] centered dot */
-            /* [32] is not used for DEC line drawing but is a potential
-               value for someone who assumes that 0x60..0x7f is the valid
-               range, so we're prepared to accept--and sanitize--it */
-            decchars[0x7f - 0x5f] = '?';
-        }
+       Curses remaps the characters instead.
+
+       The DEC line drawing characters use 0x5f through 0x7e instead
+       of the much more straightforward 0x60 through 0x7f, possibly
+       because 0x7f is effectively a control character (Rubout);
+       nethack ORs 0x80 to flag line drawing--that's stripped below */
+    static int decchars[33]; /* for chars 0x5f through 0x7f (95..127) */
+
+    /* one-time initialization; some ACS_x aren't compile-time constant */
+    if (!decchars[0]) {
+        /* [0] is non-breakable space; irrelevant to nethack */
+        decchars[0x5f - 0x5f] = ' '; /* NBSP */
+        decchars[0x60 - 0x5f] = ACS_DIAMOND; /* [1] solid diamond */
+        decchars[0x61 - 0x5f] = ACS_CKBOARD; /* [2] checkerboard */
+        /* several "line drawing" characters are two-letter glyphs
+           which could be substituted for invisible control codes;
+           nethack's DECgraphics doesn't use any of them so we're
+           satisfied with conversion to a simple letter;
+           [3] "HT" as one char, with small raised upper case H over
+           and/or preceding small lowered upper case T */
+        decchars[0x62 - 0x5f] = 'H'; /* "HT" (horizontal tab) */
+        decchars[0x63 - 0x5f] = 'F'; /* "FF" as one char (form feed) */
+        decchars[0x64 - 0x5f] = 'C'; /* "CR" as one (carriage return) */
+        decchars[0x65 - 0x5f] = 'L'; /* [6] "LF" as one (line feed) */
+        decchars[0x66 - 0x5f] = ACS_DEGREE; /* small raised circle */
+        /* [8] plus or minus sign, '+' with horizontal line below */
+        decchars[0x67 - 0x5f] = ACS_PLMINUS;
+        decchars[0x68 - 0x5f] = 'N'; /* [9] "NL" as one char (new line) */
+        decchars[0x69 - 0x5f] = 'V'; /* [10] "VT" as one (vertical tab) */
+        decchars[0x6a - 0x5f] = ACS_LRCORNER; /* lower right corner */
+        decchars[0x6b - 0x5f] = ACS_URCORNER; /* upper right corner */
+        decchars[0x6c - 0x5f] = ACS_ULCORNER; /* upper left corner */
+        decchars[0x6d - 0x5f] = ACS_LLCORNER; /* lower left corner, 'L' */
+        /* [15] center cross, like big '+' sign */
+        decchars[0x6e - 0x5f] = ACS_PLUS;
+        decchars[0x6f - 0x5f] = ACS_S1; /* very high horizontal line */
+        decchars[0x70 - 0x5f] = ACS_S3; /* medium high horizontal line */
+        decchars[0x71 - 0x5f] = ACS_HLINE; /* centered horizontal line */
+        decchars[0x72 - 0x5f] = ACS_S7; /* medium low horizontal line */
+        decchars[0x73 - 0x5f] = ACS_S9; /* very low horizontal line */
+        /* [21] left tee, 'H' with right-hand vertical stroke removed;
+           note on left vs right:  the ACS name (also DEC's terminal
+           documentation) refers to vertical bar rather than cross stroke,
+           nethack's left/right refers to direction of the cross stroke */
+        decchars[0x74 - 0x5f] = ACS_LTEE; /* ACS left tee, NH right tee */
+        /* [22] right tee, 'H' with left-hand vertical stroke removed */
+        decchars[0x75 - 0x5f] = ACS_RTEE; /* ACS right tee, NH left tee */
+        /* [23] bottom tee, '+' with lower half of vertical stroke
+           removed and remaining stroke pointed up (unside-down 'T');
+           nethack is inconsistent here--unlike with left/right, its
+           bottom/top directions agree with ACS */
+        decchars[0x76 - 0x5f] = ACS_BTEE; /* bottom tee, stroke up */
+        /* [24] top tee, '+' with upper half of vertical stroke removed */
+        decchars[0x77 - 0x5f] = ACS_TTEE; /* top tee, stroke down, 'T' */
+        decchars[0x78 - 0x5f] = ACS_VLINE; /* centered vertical line */
+        decchars[0x79 - 0x5f] = ACS_LEQUAL; /* less than or equal to */
+        /* [27] greater than or equal to, '>' with underscore */
+        decchars[0x7a - 0x5f] = ACS_GEQUAL;
+        /* [28] Greek pi ('n'-like; case is ambiguous: small size
+           suggests lower case but flat top suggests upper case) */
+        decchars[0x7b - 0x5f] = ACS_PI;
+        /* [29] not equal sign, combination of '=' and '/' */
+        decchars[0x7c - 0x5f] = ACS_NEQUAL;
+        /* [30] British pound sign (curly 'L' with embellishments) */
+        decchars[0x7d - 0x5f] = ACS_STERLING;
+        decchars[0x7e - 0x5f] = ACS_BULLET; /* [31] centered dot */
+        /* [32] is not used for DEC line drawing but is a potential
+           value for someone who assumes that 0x60..0x7f is the valid
+           range, so we're prepared to accept--and sanitize--it */
+        decchars[0x7f - 0x5f] = '?';
+    }
 
-        /* high bit set means special handling */
-        if (ch & 0x80) {
-            int convindx;
-
-            ch &= ~0x80; /* force plain ASCII for last resort */
-            convindx = ch - 0x5f;
-            /* if it's in the lower case block of ASCII (which includes
-               a few punctuation characters), use the conversion table */
-            if (convindx >= 0 && convindx < SIZE(decchars)) {
-                ch = decchars[convindx];
-                /* in case ACS_foo maps to 0 when current terminal is unable
-                   to handle a particular character; if so, revert to default
-                   rather than using DECgr value with high bit stripped */
-                if (!ch)
-                    ch = (int) defsyms[symbol].sym;
-            }
+    /* high bit set means special handling */
+    if (ch & 0x80) {
+        int convindx;
+
+        ch &= ~0x80; /* force plain ASCII for last resort */
+        convindx = ch - 0x5f;
+        /* if it's in the lower case block of ASCII (which includes
+           a few punctuation characters), use the conversion table */
+        if (convindx >= 0 && convindx < SIZE(decchars)) {
+            ch = decchars[convindx];
+            /* in case ACS_foo maps to 0 when current terminal is unable
+               to handle a particular character; if so, revert to default
+               rather than using DECgr value with high bit stripped */
+            if (!ch)
+                ch = (int) defsyms[symbol].sym;
         }
-        return ch;
     }
 
-    /*
-     * [Is this correct?  How did mapglyph() supply the value if it
-     * isn't coming from showsyms[]?  glyph_is_cmap() test commented
-     * out because of the nothing-else-gets-here optimization above.]
-     */
-    /* If user selected a custom character for this object, don't
-       override this. */
-    if (/*glyph_is_cmap(glyph) &&*/ ch != showsyms[symbol]) {
-        retch = ch;
-    } else {
-        retch = (symbol >= 0 && symbol < MAXPCHARS) ? cursesglyphs[symbol] : 0;
-        if (!retch)
-            retch = ch;
-    }
-    return retch;
+    return ch;
 }
 
 
index 9a5b8033bb834c909fcdcc12b15b293ebbb845c3..d7634618481c799d638dc87023a6d5e78cee68ae 100644 (file)
@@ -19,7 +19,7 @@ char *curses_break_str(const char *str, int width, int line_num);
 char *curses_str_remainder(const char *str, int width, int line_num);
 boolean curses_is_menu(winid wid);
 boolean curses_is_text(winid wid);
-int curses_convert_glyph(boolean decgraphics, int ch, int glyph);
+int curses_convert_glyph(int ch, int glyph);
 void curses_move_cursor(winid wid, int x, int y);
 void curses_prehousekeeping(void);
 void curses_posthousekeeping(void);