Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save jtmcdole/fec0ee859034b592e5f0 to your computer and use it in GitHub Desktop.
Save jtmcdole/fec0ee859034b592e5f0 to your computer and use it in GitHub Desktop.
From e7129ae561b328301ddbccddd08b98b8097cee3d Mon Sep 17 00:00:00 2001
From: John Thomas McDole <john@mcdole.org>
Date: Thu, 5 Nov 2015 18:37:32 -0800
Subject: [PATCH] Curses Wide Character & UTF8 Support
---
README.cursesw | 14 +++++++++++
include/config.h | 2 +-
include/wincurs.h | 2 --
src/drawing.c | 9 +++++--
sys/unix/Makefile.src | 2 +-
win/curses/cursdial.c | 3 ++-
win/curses/cursinit.c | 3 ++-
win/curses/cursmain.c | 8 ++----
win/curses/cursmesg.c | 3 ++-
win/curses/cursmisc.c | 69 ++-------------------------------------------------
win/curses/cursmisc.h | 2 --
win/curses/cursstat.c | 3 ++-
win/curses/curswins.c | 23 +++++++++++++++--
13 files changed, 56 insertions(+), 87 deletions(-)
create mode 100644 README.cursesw
diff --git a/README.cursesw b/README.cursesw
new file mode 100644
index 0000000..193e907
--- /dev/null
+++ b/README.cursesw
@@ -0,0 +1,14 @@
+To get curses working with UTF8graphics, the system must be compiled against the
+cursesw library. On my system, this is distributed through the following
+packages:
+ libncursesw5:amd64
+ libncursesw5-dev:amd64
+
+With wide characters, there is no reason to rely on curses' limited glyphs, so
+I removed curses_convert_glyph. All glyphs can be overriden with the normal
+UTF8graphics symbols via the nethackrc file.
+
+--
+John Thomas McDole
+john@mcdole.org
+
diff --git a/include/config.h b/include/config.h
index 4084297..226c046 100644
--- a/include/config.h
+++ b/include/config.h
@@ -290,7 +290,7 @@ typedef unsigned char uchar;
typedef long glyph_t;
#define UTF8_GLYPHS /* Allow UTF8 glyphs for monsters, objects and dungeon */
-/* #define HAVE_SETLOCALE */ /* Query locale, if UTF8 is supported? */
+#define HAVE_SETLOCALE /* Query locale, if UTF8 is supported? */
/*
* Various structures have the option of using bitfields to save space.
diff --git a/include/wincurs.h b/include/wincurs.h
index 3db6c5a..a3cf092 100644
--- a/include/wincurs.h
+++ b/include/wincurs.h
@@ -206,8 +206,6 @@ extern boolean curses_is_menu(winid wid);
extern boolean curses_is_text(winid wid);
-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);
diff --git a/src/drawing.c b/src/drawing.c
index 9a7fdc2..32df6f5 100644
--- a/src/drawing.c
+++ b/src/drawing.c
@@ -638,8 +638,8 @@ static glyph_t utf8_graphics[MAXPCHARS] = {
0x2261, /* S_bars: IDENTICAL TO */
0x03a8, /* S_tree: GREEK CAPITAL LETTER PSI */
0x00b7, /* S_room: MIDDLE DOT */
- g_FILLER(S_corr),
- g_FILLER(S_litcorr),
+ 0x2591, /* S_corr: LIGHT SHADE */
+ 0x2592, /* S_litcorr: MEDIUM SHADE */
g_FILLER(S_upstair),
g_FILLER(S_dnstair),
0x2264, /* S_upladder: LESS-THAN OR EQUAL TO */
@@ -835,7 +835,12 @@ int gr_set_flag;
#endif
#ifdef CURSES_GRAPHICS
case CURS_GRAPHICS:
+# ifdef UTF8_GLYPHS
+ assign_graphics(utf8_graphics, SIZE(utf8_graphics), MAXPCHARS, 0);
+ iflags.UTF8graphics = TRUE;
+# else
assign_graphics((glyph_t *)0, 0, MAXPCHARS, 0);
+# endif /* UTF8_GLYPHS */
iflags.cursesgraphics = TRUE;
iflags.IBMgraphics = FALSE;
iflags.DECgraphics = FALSE;
diff --git a/sys/unix/Makefile.src b/sys/unix/Makefile.src
index 0106422..9a2d90a 100644
--- a/sys/unix/Makefile.src
+++ b/sys/unix/Makefile.src
@@ -238,7 +238,7 @@ WINOBJ = $(WINTTYOBJ) $(WINCURSESOBJ)
# WINTTYLIB = -ltermcap
# WINTTYLIB = -lcurses
# WINTTYLIB = -lcurses16
-WINTTYLIB = -lncurses
+WINTTYLIB = -lncursesw
# WINTTYLIB = -ltermlib
#
# libraries for X11
diff --git a/win/curses/cursdial.c b/win/curses/cursdial.c
index d155dd3..aaa4a1f 100644
--- a/win/curses/cursdial.c
+++ b/win/curses/cursdial.c
@@ -1,4 +1,5 @@
-#include "curses.h"
+#define _XOPEN_SOURCE_EXTENDED 1
+#include <ncursesw/curses.h>
#include "hack.h"
#include "wincurs.h"
#include "cursdial.h"
diff --git a/win/curses/cursinit.c b/win/curses/cursinit.c
index 4155a2d..4f5aa28 100644
--- a/win/curses/cursinit.c
+++ b/win/curses/cursinit.c
@@ -1,4 +1,5 @@
-#include "curses.h"
+#define _XOPEN_SOURCE_EXTENDED 1
+#include <ncursesw/curses.h>
#include "hack.h"
#include "wincurs.h"
#include "cursinit.h"
diff --git a/win/curses/cursmain.c b/win/curses/cursmain.c
index ff2a47c..62ed158 100644
--- a/win/curses/cursmain.c
+++ b/win/curses/cursmain.c
@@ -1,4 +1,5 @@
-#include "curses.h"
+#define _XOPEN_SOURCE_EXTENDED 1
+#include <ncursesw/curses.h>
#include "hack.h"
#include "patchlevel.h"
#include "color.h"
@@ -508,11 +509,6 @@ void curses_print_glyph(winid wid, XCHAR_P x, XCHAR_P y, int glyph)
{
attr = A_REVERSE;
}
- if (iflags.cursesgraphics)
- {
- ch = curses_convert_glyph(ch, glyph);
- }
-
if (wid == NHW_MAP) {
if ((special & MG_STAIRS) && iflags.hilite_hidden_stairs) {
color = 16 + (color*2);
diff --git a/win/curses/cursmesg.c b/win/curses/cursmesg.c
index b64c568..a789c96 100644
--- a/win/curses/cursmesg.c
+++ b/win/curses/cursmesg.c
@@ -1,4 +1,5 @@
-#include "curses.h"
+#define _XOPEN_SOURCE_EXTENDED 1
+#include <ncursesw/curses.h>
#include "hack.h"
#include "wincurs.h"
#include "cursmesg.h"
diff --git a/win/curses/cursmisc.c b/win/curses/cursmisc.c
index 9dd7fc0..e8ab60a 100644
--- a/win/curses/cursmisc.c
+++ b/win/curses/cursmisc.c
@@ -1,4 +1,5 @@
-#include "curses.h"
+#define _XOPEN_SOURCE_EXTENDED 1
+#include <ncursesw/curses.h>
#include "hack.h"
#include "wincurs.h"
#include "cursmisc.h"
@@ -459,72 +460,6 @@ boolean curses_is_text(winid wid)
}
-/* Replace certain characters with portable drawing characters if
-cursesgraphics option is enabled */
-
-int curses_convert_glyph(int ch, int glyph)
-{
- int symbol;
-
-#ifdef REINCARNATION
- if (Is_rogue_level(&u.uz))
- {
- return ch;
- }
-#endif
-
- /* 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);
-
- /* If user selected a custom character for this object, don't
- override this. */
- if (((glyph_is_cmap(glyph)) && (ch != showsyms[symbol])))
- {
- return ch;
- }
-
- switch (symbol)
- {
- case S_vwall:
- return ACS_VLINE;
- case S_hwall:
- return ACS_HLINE;
- case S_tlcorn:
- return ACS_ULCORNER;
- case S_trcorn:
- return ACS_URCORNER;
- case S_blcorn:
- return ACS_LLCORNER;
- case S_brcorn:
- return ACS_LRCORNER;
- case S_crwall:
- return ACS_PLUS;
- case S_tuwall:
- return ACS_BTEE;
- case S_tdwall:
- return ACS_TTEE;
- case S_tlwall:
- return ACS_RTEE;
- case S_trwall:
- return ACS_LTEE;
- case S_tree:
- return ACS_PLMINUS;
- case S_corr:
- return ACS_CKBOARD;
- case S_litcorr:
- return ACS_CKBOARD;
- }
-
- return ch;
-}
-
-
/* Move text cursor to specified coordinates in the given NetHack window */
void curses_move_cursor(winid wid, int x, int y)
diff --git a/win/curses/cursmisc.h b/win/curses/cursmisc.h
index 0f03246..18a49e1 100644
--- a/win/curses/cursmisc.h
+++ b/win/curses/cursmisc.h
@@ -23,8 +23,6 @@ boolean curses_is_menu(winid wid);
boolean curses_is_text(winid wid);
-int curses_convert_glyph(int ch, int glyph);
-
void curses_move_cursor(winid wid, int x, int y);
void curses_prehousekeeping(void);
diff --git a/win/curses/cursstat.c b/win/curses/cursstat.c
index f96c36b..64d94ca 100644
--- a/win/curses/cursstat.c
+++ b/win/curses/cursstat.c
@@ -1,4 +1,5 @@
-#include "curses.h"
+#define _XOPEN_SOURCE_EXTENDED 1
+#include <ncursesw/curses.h>
#include "hack.h"
#include "wincurs.h"
#include "cursstat.h"
diff --git a/win/curses/curswins.c b/win/curses/curswins.c
index a4029dc..944df14 100644
--- a/win/curses/curswins.c
+++ b/win/curses/curswins.c
@@ -1,4 +1,5 @@
-#include "curses.h"
+#define _XOPEN_SOURCE_EXTENDED 1
+#include <ncursesw/curses.h>
#include "hack.h"
#include "wincurs.h"
#include "curswins.h"
@@ -44,6 +45,7 @@ static nethack_wid *nhwids = NULL; /* NetHack wid array */
static boolean is_main_window(winid wid);
static void write_char(WINDOW *win, int x, int y, nethack_char ch);
+static void write_wchar(WINDOW *win, int x, int y, nethack_char ch);
static void clear_map(void);
@@ -425,7 +427,7 @@ void curses_putch(winid wid, int x, int y, int ch, int color, int attr)
y++;
}
- write_char(mapwin, x - sx, y - sy, nch);
+ write_wchar(mapwin, x - sx, y - sy, nch);
}
wrefresh(mapwin);
@@ -592,6 +594,23 @@ static void write_char(WINDOW *win, int x, int y, nethack_char nch)
curses_toggle_color_attr(win, nch.color, nch.attr, OFF);
}
+/* Unconditionally write a single wide character to a window at the given
+coordinates without a refresh. Currently only used for the map. */
+static void write_wchar(WINDOW *win, int x, int y, nethack_char nch)
+{
+ static cchar_t wide = {0};
+ static boolean init = false;
+ if (!init) {
+ wide.attr = 0;
+ int i;
+ for (i = 0; i < CCHARW_MAX; i++) wide.chars[i] = 0;
+ init = true;
+ }
+ curses_toggle_color_attr(win, nch.color, nch.attr, ON);
+ wide.chars[0] = nch.ch;
+ mvwadd_wch(win, y, x, &wide);
+ curses_toggle_color_attr(win, nch.color, nch.attr, OFF);
+}
/* Draw the entire visible map onto the screen given the visible map
boundaries */
--
1.9.1
@jtmcdole
Copy link
Author

jtmcdole commented Nov 6, 2015

NOTE
This is a patch from the head of NAO (nethack.alt.org) from d643449940304015319bef4749c16c65c5141ee1. This will enable support for UTF8graphics and curses. This requires the cursesw library.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment