diff --git a/nle/tests/2020-10-16.00_11_28.frame.5.txt b/nle/tests/2020-10-16.00_11_28.frame.5.txt new file mode 100644 index 000000000..bdc17c2f8 --- /dev/null +++ b/nle/tests/2020-10-16.00_11_28.frame.5.txt @@ -0,0 +1,24 @@ + It is written in the Book of Amaterasu Omikami: + + After the Creation, the cruel god Moloch rebelled + against the authority of Marduk the Creator. + -------------- Moloch stole from Marduk the most powerful of all + .............| the artifacts of the gods, the Amulet of Yendor, + |d..........{| and he hid it in the dark cavities of Gehennom, the + |...........d| Under World, where he now lurks, and bides his time. + |..........@.. + ---------+---- Your goddess Amaterasu Omikami seeks to possess the Amulet, and with it + to gain deserved ascendance over the other gods. + + You, a newly trained Hatamoto, have been heralded + from birth as the instrument of Amaterasu Omikami. You are destined + to recover the Amulet for your deity, or die in the + attempt. Your hour of destiny has come. For the sake + of us all: Go bravely with Amaterasu Omikami! + --More-- + + + + +[CodeMagic the Hatamoto ] St:16 Dx:14 Co:17 In:11 Wi:9 Ch:7 Lawful +Dlvl:1 $:0 HP:15(15) Pw:2(2) AC:4 Xp:1 T:1 \ No newline at end of file diff --git a/nle/tests/test_converter.py b/nle/tests/test_converter.py index 36b351569..75cad4595 100644 --- a/nle/tests/test_converter.py +++ b/nle/tests/test_converter.py @@ -30,6 +30,7 @@ # https://alt.org/nethack/trd/?file=https://s3.amazonaws.com/altorg/ttyrec/CodeMagic/2020-10-16.00:11:28.ttyrec.bz2 # noqa: B950 # This ttyrec uses DECGraphics (https://en.wikipedia.org/wiki/DEC_Special_Graphics) TTYREC_DECGRAPHICS = "2020-10-16.00_11_28.ttyrec.bz2" +TTYREC_DECGRAPHICS_FRAME_5 = "2020-10-16.00_11_28.frame.5.txt" SEQ_LENGTH = 20 ROWS = 25 @@ -237,7 +238,7 @@ def test_illegal_buffers(self): with pytest.raises(ValueError, match=r"Numpy array required"): converter.convert(chars, colors, cursors, timestamps, actions) - def _test_ibm_graphics(self): + def test_ibm_graphics(self): seq_length = 10 converter = Converter(ROWS, COLUMNS) @@ -254,3 +255,23 @@ def _test_ibm_graphics(self): for row, line in enumerate(f): actual = chars[-1][row].tobytes().decode("utf-8").rstrip() assert actual == line.rstrip() + + def test_dec_graphics(self): + seq_length = 10 + COLUMNS = 120 + converter = Converter(ROWS, COLUMNS) + + chars = np.zeros((seq_length, ROWS, COLUMNS), dtype=np.uint8) + colors = np.zeros((seq_length, ROWS, COLUMNS), dtype=np.int8) + cursors = np.zeros((seq_length, 2), dtype=np.uint16) + actions = np.zeros((seq_length), dtype=np.uint8) + timestamps = np.zeros((seq_length,), dtype=np.int64) + + converter.load_ttyrec(getfilename(TTYREC_DECGRAPHICS)) + assert converter.convert(chars, colors, cursors, timestamps, actions) == 0 + + with open(getfilename(TTYREC_DECGRAPHICS_FRAME_5)) as f: + for row, line in enumerate(f): + actual = chars[5][row].tobytes().decode("utf-8").rstrip() + # print(actual) + assert actual == line.rstrip() diff --git a/third_party/converter/converter.c b/third_party/converter/converter.c index f8ecf5c36..23fb07058 100644 --- a/third_party/converter/converter.c +++ b/third_party/converter/converter.c @@ -285,7 +285,7 @@ void write_to_buffers(Conversion *conv) { for (size_t c = 0; c < conv->cols; ++c) { assert(conv->chars.cur < conv->chars.end); assert(scr->lines[r]->chars[c].c < 256); - *conv->chars.cur++ = strip_gfx(scr->lines[r]->chars[c].c); + *conv->chars.cur++ = strip_gfx(scr->lines[r]->chars[c].c, scr->lines[r]->chars[c].a.dec); *conv->colors.cur++ = vt_char_color_extract(&(scr->lines[r]->chars[c])); } } diff --git a/third_party/converter/stripgfx.c b/third_party/converter/stripgfx.c index 9f2d9ea41..a7a108e93 100644 --- a/third_party/converter/stripgfx.c +++ b/third_party/converter/stripgfx.c @@ -11,7 +11,6 @@ unsigned char gfx_dec_map[256]; unsigned char gfx_ibm_map[256]; -unsigned int state = 0; /* clang-format off */ static unsigned char no_graphics[MAXPCHARS] = { @@ -348,7 +347,6 @@ static unsigned char dec_graphics[MAXPCHARS] = { void populate_gfx_arrays() { int i; - state = 0; memset(gfx_ibm_map, 0, 256); memset(gfx_dec_map, 0, 256); @@ -373,33 +371,11 @@ void populate_gfx_arrays() { } unsigned char -strip_gfx(unsigned char inchar) +strip_gfx(unsigned char inchar, int use_dec) { + if (use_dec && gfx_dec_map[inchar]) + return gfx_dec_map[inchar]; if (gfx_ibm_map[inchar]) return gfx_ibm_map[inchar]; - - if ((inchar == 0x0E) && (state == 0)) - { - state = 1; - return 0x00; - } - - if ((inchar == 0x0F) && (state == 1)) - { - state = 0; - return inchar; - } - - if ((inchar == 0x1B) && (state == 1)) - { - state = 0; - return inchar; - } - - if (gfx_dec_map[inchar] && (state == 1)) - { - return gfx_dec_map[inchar]; - } - return inchar; } diff --git a/third_party/converter/stripgfx.h b/third_party/converter/stripgfx.h index 0f9914165..4088e2bbb 100644 --- a/third_party/converter/stripgfx.h +++ b/third_party/converter/stripgfx.h @@ -2,6 +2,6 @@ #define INCLUDED_stripgfx_h void populate_gfx_arrays(); -unsigned char strip_gfx(unsigned char inchar); +unsigned char strip_gfx(unsigned char inchar, int use_dec); #endif /* !INCLUDED_stripgfx_h */ diff --git a/third_party/libtmt/tmt.c b/third_party/libtmt/tmt.c index 2035731e8..e18ce61b1 100644 --- a/third_party/libtmt/tmt.c +++ b/third_party/libtmt/tmt.c @@ -70,10 +70,10 @@ struct TMT{ size_t pars[PAR_MAX]; size_t npar; size_t arg; - enum {S_NUL, S_ESC, S_ARG} state; + enum {S_NUL, S_ESC, S_ARG, S_DEC} state; }; -static TMTATTRS defattrs = {.fg = TMT_COLOR_DEFAULT, .bg = TMT_COLOR_DEFAULT}; +static TMTATTRS defattrs = {.fg = TMT_COLOR_DEFAULT, .bg = TMT_COLOR_DEFAULT, .dec = 0}; static void writecharatcurs(TMT *vt, wchar_t w); static wchar_t @@ -273,7 +273,8 @@ handlechar(TMT *vt, char i) DO(S_ESC, "H", t[c->c].c = L'*') DO(S_ESC, "7", vt->oldcurs = vt->curs; vt->oldattrs = vt->attrs) DO(S_ESC, "8", vt->curs = vt->oldcurs; vt->attrs = vt->oldattrs) - ON(S_ESC, "+*()", vt->ignored = true; vt->state = S_ARG) + ON(S_ESC, "(", vt->state = S_DEC) + ON(S_ESC, "+*)", vt->ignored = true; vt->state = S_ARG) DO(S_ESC, "c", tmt_reset(vt)) ON(S_ESC, "[", vt->state = S_ARG) ON(S_ARG, "\x1b", vt->state = S_ESC) @@ -310,6 +311,9 @@ handlechar(TMT *vt, char i) DO(S_ARG, "s", vt->oldcurs = vt->curs; vt->oldattrs = vt->attrs) DO(S_ARG, "u", vt->curs = vt->oldcurs; vt->attrs = vt->oldattrs) DO(S_ARG, "@", ich(vt)) + ON(S_DEC, "\x1b", vt->state = S_ESC) + DO(S_DEC, "0", vt->attrs.dec = true) + DO(S_DEC, "B", vt->attrs.dec = false) return resetparser(vt), false; } diff --git a/third_party/libtmt/tmt.h b/third_party/libtmt/tmt.h index ae0ddbb97..386f46f23 100644 --- a/third_party/libtmt/tmt.h +++ b/third_party/libtmt/tmt.h @@ -87,6 +87,7 @@ struct TMTATTRS{ bool invisible; tmt_color_t fg; tmt_color_t bg; + bool dec; }; typedef struct TMTCHAR TMTCHAR;