User:Furey/Box drawing problem

From NetHackWiki
< User:Furey
Revision as of 05:48, 7 December 2023 by Furey (talk | contribs) (hterm: typo fix)
Jump to navigation Jump to search

Introduction

When I watch other players on hardfought.org, and they are using curses, the boxes on screen are messed up. Nethack prints a couple of chars of a horizontal line segment and then omits printing the rest of the line segment.

Other users have reported this problem with ttyrec readers.

The problem happens when Player A is playing a game, but Player B is watching it, either through dgl or a ttyrec player. Usually, Player A has a TERM environment variable that works fine for whatever terminal emulator Player A is using. However, the raw bytestream that looks fine for Player A does not look fine for Player B. It usually works, but we have run into this issue where Player A has a TERM that offers the ANSI repeat character capability, and Player B is using a slightly different terminal emulator that does not support this sequence.

ECMA-48 standard

https://ecma-international.org/wp-content/uploads/ECMA-48_5th_edition_june_1991.pdf

This standard defines the relevant escape sequences.

Places where we could fix this

NetHack source

In the TNNT source (based on vanilla 3.6.7), the window subsystems are in win/. The file for the curses window system makes standard curses calls, particularly initscr to initialize the screen and box to draw boxes around the sub-windows.

NetHack hack 1: hack the code around the call to initscr to use a synthetic terminal type that has rep@ cancelled out. This is difficult because initscr takes no parameters at all, so we have to manipulate the environment variables around it.

NetHack hack 2: after initscr(), add a line: SP->_rep_cost = 999999;. This would dissuade ncurses runtime from using the terminfo capability for repeating characters. Need to use gdb on nethack to find out the actual name of SP, and need to finagle the headers to get the right private header file for the internal SP struct.

Advantages: we build NetHack from source already.

Disadvantages: hardfought has 21 versions of NetHack (as of this writing).

ncurses source

Internals of ncurses uses SP->_rep_cost to choose when to use repeated char capability. Just disable one block of code and rebuild ncurses from source.

Advantages: there is only one ncurses shared library per system.

Disadvantages: rebuilding system library from source.

terminfo source

Edit all the terminal descriptions to cancel the rep capability. Then rebuild the terminfo files.

Advantages: easy to do.

Disadvantages: again, touching a system database.

dgl source

I haven't looked at this one yet. However, if I understand correctly, dgl is small, built from source (as opposed to coming as system software, which is harder to customize), and already supports the 's' command for messing with the data stream.

We could filter the data stream for the ansi sequence char ESC [ digits b and replace it with b+1 copies of char.

Advantages: easy to do.

Disadvantages: works only for ansi based terminal types.

ttyrec players

Could do the hack described under dgl source.

Advantages: would work instantly on historical ttyrecs.

Disadvantages: I have no idea how many ttyrec players there are.

hterm

Dunno how popular hterm is. Both NAO and hardfought offer it, though, and it's nice for playing nethack without installing any software.

I looked at some hterm source. They have an "unimplemented, TBD" for char ESC [ digits b. Problem might be that in the context where the function handler for ESC [ digits b gets called, the digits are available, but the previous char may not be. I would have to look harder at the hterm source.