[rec.games.hack] Alternate-font mods to nethack for X3.64 compatible machines

eric@snark.UUCP (Eric S. Raymond) (01/06/88)

Don Joslyn's hack for prettier nethack graphics on the 3B1 gave me the push
I needed to get back to what I'd intended to do with the GRAPHICS option on
my 3B1.

The following changes convert Don G. Kneller's DECRainbow code into a general
facility for using loadable font 1 on UNIX machines with X3.64-compatible
displays featuring loadable fonts such as the 3B1. This capability is switched
on by the new 'altfont' option. The altfont code is used to implement font
switching on the 3B1 via the -h option.

What -h does is force every non-alphanumeric character emitted to the display
portion of the screen (not characters sent to the prompt line or pager) into
alternate font 1 (the SI/SO font). It may take a graphics string argument.

The trouble with this is that it's an ugly kluge. What I really want to do
is rip loose the connection between the internal object class symbols and their
external representations. This would mean adding a bunch more slots to struct
symbols and major changes in the graphics option processing, among other
things, and that's too risky with the code in flux. When Mike sends me a
stable 2.3 alpha I'll do it.

I supply a somewhat elaborated version of Joslyn's font for use with -h on
a 3b1. I munged his door graphic a bit (I've been in *real* medieval dungeons
complete with pit traps and skeletons when I lived in Europe, and they
don't have rectangular doors with knobs!) and added a sort of gammadion or
maltese cross for traps (as in 'X marks the spot'). And I added a 'book'
graphic, and sword and shield graphics for armor and weapons. Also my font has
real corners!

Note that the GRAPHICS string is now escape-processed in conventional C
fashion. This means your GRAPHICS strings for 2.2 and older versions may
break after a \. It has to be doubled now. The special escape form \~ switches
on the meta bit in the following character. Note that the interpretation of
the GRAPHICS string may change in the next version.

This file is *not* a shar. It's a collection of diffs to nethack source, except
for the two files marked with * which are given in their entirety.

	  nethack.6	-- explains the new feature
	  Guidebook.mn	-- more explanation
	* nethack.3b1	-- replacement for nethack.sh on the 3b1
	  flags.h	-- add 'altfont' flag
	  options.c	-- corresponding changes in options processing
	  pri.c		-- arrange for altfont escape emission
	  rm.h		-- add symbols entry for worm segment
	  decl.c	-- arrange for initialization of above
	  unixmain.c	-- implement -h option
	  msdos.c	-- add wormseg character handling
	  worm.c	-- make it use the WORMSEG_SYM
	* 3b1font	-- changes to the 3b1 system.8 font

To use the font on a 3B1, do the following:

	1.	make an ascii copy of /usr/lib/wfont/system.8.ft by typing:

		cfont /usr/lib/wfont/system.8.ft > hack.ascii

	2.	Add the new characters to hack.ascii with an
		editor.

	3.	Test your new font by typing:

		cfont hack.ascii > hack.ft
		setf 1
		setf hack.ft 1
		!*-|<>=?@\`{}~.+	(To see the new chars)
		setf 1

	4.	If everything looks ok, you can install the new font by typing:

		cp hack.ft /usr/lib/games/nethack

	5.	replace your nethack.sh with nethack.3b1

Sorry about these not being context diffs, but I'm a System V site and don't
have a context differ. If you apply them against unmodified 2.2 sources they
should work OK.

nethack.6:
1c1
< .TH NETHACK 6 "21 September 1987"
---
> .TH NETHACK 6 "4 January 1988"
11a12,14
> .B \-h
> ]
> [
71a75,82
> .B \-h
> On machines with X3.64-compatible displays featuring loadable fonts (such as
> the AT&T 3B1) this arranges for all non-alphanumeric output to the dungeon
> level display to be emitted in alternate font 1 (the SI/SO font), enabling
> you to use your own choice of characters for dungeon features and objects.
> This option may take a graphics string as argument, which then overrides
> any graphics string supplied in HACKOPTIONS or your .cnf file.
> .PP
107,108c118,119
< Don Kneller, Gil Neiger, Scott Turner and Ken Arromdee deserve special
< mention in this regard.
---
> Don Kneller, Gil Neiger, Scott Turner, Ken Arromdee, Richard Creps and
> Eric Raymond deserve special mention in this regard.

Guidebook.mn:
610a611,614
> .lp altfont\ \ \ \ 
> emit any character with the meta bit on via an X3.64-compatible escape sequence
> invoking alternate font 1. Useful if you've included such chars in your
> graphics string.
678c682,708
< 
---
> .hn
> Custom graphics: the -h option
> The new -h option is a
> facility for using loadable font 1 on UNIX machines with X3.64-compatible
> displays featuring loadable fonts such as the 3B1.
> .pg
> What -h does is force every non-alphanumeric character emitted to the display
> portion of the screen (not characters sent to the prompt line or pager) into
> alternate font 1 (the SI/SO font). It may take a graphics string argument,
> which will then override anything supported via HACKOPTIONS. It's up to you to
> design and load the font.
> .pg
> The trouble with this is that it's an ugly kluge. What we should really do
> is rip loose the connection between the internal object class symbols and their
> external representations. Look for this change in future versions. If it
> happens, the -h option will go away and be replaced by some more elegant
> character-mapping scheme.
> .hn
> Caveats
> .pg
> Note that the graphics option string is now escape-processed in conventional C
> fashion. This means your graphics strings for 2.2 and older versions may
> break after a \\; it has to be doubled now. The special escape form \\~
> switches on the meta bit in the following character.
> .pg
> Note also that the interpretation of the graphics option string may change in
> the next version.

nethack.3b1:
-----------------------------------------------------------------------
#!/bin/sh
HACKDIR=/usr/games/lib/nethackdir
HACK=$HACKDIR/nethack
MAXNROFPLAYERS=4

NAME=`tty`
cd $HACKDIR
case $1 in
	-s*)
		exec $HACK $@
		;;
	*)
		if [ "`expr $NAME : '/dev/w' `" != "0" ]
		then
			setf $HACKDIR/hack.ft 1
			$HACK -h ' |-\~A\~B\~C\~D\~E' $@ $MAXNROFPLAYERS
			setf 1
		else
			exec $HACK $@ $MAXNROFPLAYERS
		fi
		;;
esac
-----------------------------------------------------------------------

flag.h: add 'altfont' flag
56c56,58
< 	unsigned extra2;
---
> #endif
> #ifdef GRAPHICS
> 	unsigned altfont;	/* output graphics chars in alternate font? */

options.c: ditto, move graphics option processing into setpgraphics() 
35a36,38
> #ifdef GRAPHICS
> 	flags.altfont = FALSE;
> #endif
41a45,113
> void setpgraphics(opts)
> char *opts;
> {
>     char *cp, *tp, *dp, *hex = "0123456789abcdef";
> 
>     /* interpret escapes in GRAPHICS string */
>     for (tp = cp = opts; *cp;)
>     {
> 	if (*cp != '\\')
> 	    *tp++ = *cp++;
> 	else if (strchr("0123456789x~", *++cp))
> 	{
> 	    int	cval = 0;
> 
> 	    if (*cp == '~')
> 	    {
> 		++cp;
> 		cval = (*cp | 0x80);
> 		++cp;
> 	    }
> 	    else if (*cp == 'x')
> 		for (++cp; dp = strchr(hex, *cp); cp++)
> 		    cval += (cval * 16) + (dp - hex);
> 	    else if (*cp == '0')
> 		while (strchr("01234567", *cp))
> 		    cval += (cval * 8) + (*cp++ - '0');
> 	    else
> 		while (strchr("0123456789", *cp))
> 		    cval += (cval * 10) + (*cp++ - '0');
> 	    *tp++ = cval;
> 	}
> 	else
> 	    *tp++ = *cp++;
>     }
>     *tp = '\0';
> /*
>  * You could have problems here if you configure FOUNTAINS, SPIDERS or NEWCLASS
>  * in or out and forget to change the tail entries in your graphics string.
>  */
> #define SETPCHAR(f, n)	showsyms.f = (strlen(opts) > n) ? opts[n] : defsyms.f
>     SETPCHAR(stone, 0);
>     SETPCHAR(vwall, 1);
>     SETPCHAR(hwall, 2);
>     SETPCHAR(tlcorn, 3);
>     SETPCHAR(trcorn, 4);
>     SETPCHAR(blcorn, 5);
>     SETPCHAR(brcorn, 6);
>     SETPCHAR(door, 7);
>     SETPCHAR(room, 8);
>     SETPCHAR(corr, 9);
>     SETPCHAR(upstair, 10);
>     SETPCHAR(dnstair, 11);
>     SETPCHAR(trap, 12);
> #ifdef FOUNTAINS
>     SETPCHAR(pool, 13);
>     SETPCHAR(fountain, 14);
> #endif
> #ifdef NEWCLASS
>     SETPCHAR(throne, 15);
> #endif
> #ifdef SPIDERS
>     SETPCHAR(web, 16);
> #endif
> #ifndef NOWORM
>     SETPCHAR(wormseg, 17);
> #endif
> #undef SETPCHAR
> }
> 
121a194
> 		if (flags.DECRainbow) then flags.altfont = 1;
125a199,205
> #ifdef GRAPHICS
> 	if (!strncmp(opts, "altfont", 4)) {
> 		flags.altfont = !negated;
> 		return;
> 	}
> #endif
> 
235,263c315,316
< /*
<  * You could have problems here if you configure FOUNTAINS, SPIDERS or NEWCLASS
<  * in or out and forget to change the tail entries in your graphics string.
<  */
< #define SETPCHAR(f, n)	showsyms.f = (strlen(opts) > n) ? opts[n] : defsyms.f
< 		SETPCHAR(stone, 0);
< 		SETPCHAR(vwall, 1);
< 		SETPCHAR(hwall, 2);
< 		SETPCHAR(tlcorn, 3);
< 		SETPCHAR(trcorn, 4);
< 		SETPCHAR(blcorn, 5);
< 		SETPCHAR(brcorn, 6);
< 		SETPCHAR(door, 7);
< 		SETPCHAR(room, 8);
< 		SETPCHAR(corr, 9);
< 		SETPCHAR(upstair, 10);
< 		SETPCHAR(dnstair, 11);
< 		SETPCHAR(trap, 12);
< #ifdef FOUNTAINS
< 		SETPCHAR(pool, 13);
< 		SETPCHAR(fountain, 14);
< #endif
< #ifdef NEWCLASS
< 		SETPCHAR(throne, 15);
< #endif
< #ifdef SPIDERS
< 		SETPCHAR(web, 16);
< #endif
< #undef SETPCHAR
---
> 
> 		setpgraphics(opts);
369d421
< 	    if (flags.IBMBIOS) (void) strcat(buf,"IBMBIOS,");
370a423,426
> 	    if (flags.IBMBIOS) (void) strcat(buf,"IBMBIOS,");
> #endif
> #ifdef GRAPHICS
> 	    if (flags.altfont) (void) strcat(buf,"altfont,");

pri.c: change DGK code for DECRainbow to GRAPHICS code for altfont,
	also arrange that everything non-alphameric gets metaed if altfont=2 
4a5
> #include <ctype.h>
12a14,16
> #define ismeta(ch)	((ch) & 0x80)
> #define stripmeta(ch)	((ch) ^ 0x80)
> 
44c48
< #ifdef DGK
---
> #ifdef GRAPHICS
46c50
< static int DECgraphics;		/* The graphics mode toggle */
---
> static int altfont;		/* The graphics mode toggle */
48,50c52,54
< #define DECgraphicsON() ((void) putchar('\16'), DECgraphics = TRUE)
< #define DECgraphicsOFF() ((void) putchar('\17'), DECgraphics = FALSE)
< #endif
---
> #define altfontON() ((void) putchar('\16'), altfont = TRUE)
> #define altfontOFF() ((void) putchar('\17'), altfont = FALSE)
> #endif /* GRAPHICS */
69,70c73,74
< #ifdef DGK
< 	if (flags.DECRainbow) {
---
> #ifdef GRAPHICS
> 	if (flags.altfont) {
76,79c80,84
< 			if (ch & 0x80) {
< 				if (!DECgraphics)
< 					DECgraphicsON();
< 				(void) putchar(ch ^ 0x80); /* Strip 8th bit */
---
> 			if (ismeta(ch) || (!isalpha(ch) && flags.altfont == 2))
> 			{
> 				if (!altfont)
> 					altfontON();
> 				(void) putchar(stripmeta(ch));
81,82c86,87
< 				if (DECgraphics)
< 					DECgraphicsOFF();
---
> 				if (altfont)
> 					altfontOFF();
90,93c95,99
< 			if (ch & 0x80) {
< 				DECgraphicsON();
< 				(void) putchar(ch ^ 0x80); /* Strip 8th bit */
< 				DECgraphicsOFF();
---
> 			if (ismeta(ch) || (!isalpha(ch) && flags.altfont == 2))
> 			{
> 				altfontON();
> 				(void) putchar(stripmeta(ch));
> 				altfontOFF();
101c107
< #else
---
> #else /* GRAPHICS */
103c109
< #endif
---
> #endif /* GRAPHICS */
142c148
< #if defined(DGK) && !defined(MSDOSCOLOR)
---
> #if defined(GRAPHICS) && !defined(MSDOSCOLOR)
149c155
< 	if (flags.DECRainbow) {
---
> 	if (flags.altfont) {
159,160c165,166
< 		if (DECgraphics)
< 			DECgraphicsOFF();
---
> 		if (altfont)
> 			altfontOFF();
191c197
< #else
---
> #else /* !defined(GRAPHICS) || defined(MSDOSCOLOR) */
199c205
< #endif
---
> #endif /* defined(GRAPHICS) && !defined(MSDOSCOLOR) */
223,224c229,230
< #ifdef DGK
< 	if (flags.DECRainbow)
---
> #ifdef GRAPHICS
> 	if (flags.altfont)
226c232
< #endif
---
> #endif /* GRAPHICS */
242,243c248,249
< #ifdef DGK
< 	if (flags.DECRainbow) {
---
> #ifdef GRAPHICS
> 	if (flags.altfont) {
245,246c251,252
< 		if (DECgraphics)
< 			DECgraphicsOFF();
---
> 		if (altfont)
> 			altfontOFF();
248c254
< #endif
---
> #endif /* GRAPHICS */

rm.h: add symbols entry for worm segment
86a87,89
> #ifndef NOWORM
>     unsigned char wormseg;
> #endif
106a110
> #define WORMSEG_SYM     showsyms.wormseg

decl.h: arrange for initialization of above
919a20,22
> #ifndef NOWORM
>     '~',
> #endif

unixmain.c:
151a152,163
> #ifdef GRAPHICS
> 		case 'h':	/* meta all non-alphameric at() output */
> 			flags.altfont = 2;
> 			if(argv[0][2])
> 			  (void) setpgraphics(argv[0] + 2);
> 			else if(argc > 1) {
> 			  argc--;
> 			  argv++;
> 			  (void) setpgraphics(argv[0]);
> 			}
> 			break;
> #endif /* GRAPHICS */

msdos.c: add wormseg character handling
564a565,567
> #ifndef NOWORM
> 			SETPCHAR(wormseg, 17);
> #endif

worm.c: make it use the WORMSEG_SYM #define
47c47
< 		atl(whd->wx, whd->wy, '~');
---
> 		atl(whd->wx, whd->wy, WORMSEG_SYM);
106c106
< 		atl(wtmp->wx, wtmp->wy, '~');
---
> 		atl(wtmp->wx, wtmp->wy, WORMSEG_SYM);

3b1font: changes to the 3b1 system.8 font
-----------------------------------------------------------------------
# magic 0x18e
# flags 0x0
hs    9
vs    12
basel 10

############### Character 0x21, 041, 33   ! ! ! ! ! ! ! ! ! !
char 33
hs   9
vs   10
ha   0
va   -10
hi   9
vi   0
bits   *****  
bits    * *   
bits    * *   
bits    * *   
bits    * *   
bits   *   *  
bits  *     * 
bits *       *
bits *       *
bits  ******* 

############### Character 0x29, 051, 41   ) ) ) ) ) ) ) ) ) )
char 41
hs   9
vs   12
ha   0
va   -10
hi   9
vi   0
bits          
bits     *    
bits     *    
bits     *    
bits     *    
bits     *    
bits  *  *  * 
bits   *****  
bits     *    
bits     *    
bits    ***   
bits          

############### Character 0x2a, 052, 42   * * * * * * * * * *
char 42
hs   9
vs   7
ha   0
va   -8
hi   9
vi   0
bits   *****  
bits  *     * 
bits *       *
bits  *     * 
bits   *   *  
bits    * *   
bits     *    

############### Character 0x2b, 053, 43   + + + + + + + + + +
char 43
hs   8
vs   4
ha   1
va   -5
hi   9
vi   0
bits  *******
bits *     * 
bits *     * 
bits  *******

############### Character 0x2d, 055, 45   - - - - - - - - - -
char 45
hs   9
vs   1
ha   0
va   -5
hi   9
vi   0
bits *********

############### Character 0x2e, 056, 46   . . . . . . . . . .
char 46
hs   9
vs   1
ha   0
va   -5
hi   9
vi   0
bits     *    

############### Character 0x3c, 074, 60   < < < < < < < < < <
char 60
hs   9
vs   12
ha   0
va   -10
hi   9
vi   0
bits   *      
bits  ***     
bits * * *    
bits   *   ***
bits   *   *  
bits       *  
bits    ****  
bits    *     
bits    *     
bits ****     
bits *        
bits *        

############### Character 0x3d, 075, 61   = = = = = = = = = =
char 61
hs   9
vs   10
ha   0
va   -10
hi   9
vi   0
bits   * * *  
bits    * *   
bits     *    
bits   *****  
bits  *     * 
bits *       *
bits *       *
bits *       *
bits  *     * 
bits   *****  


############### Character 0x3e, 076, 62   > > > > > > > > > >
char 62
hs   9
vs   12
ha   0
va   -10
hi   9
vi   0
bits   *      
bits   *      
bits * * *    
bits  ***  ***
bits   *   *  
bits       *  
bits    ****  
bits    *     
bits    *     
bits ****     
bits *        
bits *        

############### Character 0x3f, 077, 63   ? ? ? ? ? ? ? ? ? ?
char 63
hs   9
vs   12
ha   0
va   -10
hi   9
vi   0
bits     *    
bits     *    
bits *********
bits *   *   *
bits  * * * * 
bits  *   * * 
bits  *  *  * 
bits  *     * 
bits *   *   *
bits *********
bits     *    
bits     *    


############### Character 0x40, 0100, 64   @ @ @ @ @ @ @ @ @ @
char 64
hs   7
vs   10
ha   1
va   -10
hi   9
vi   0
bits   **   
bits  *  *  
bits  *  *  
bits   **   
bits ****** 
bits * ** * 
bits * ** * 
bits   **   
bits   **   
bits **  ** 

############### Character 0x41, 0101, 65   A A A A A A A A A A
char 65
hs   8
vs   10
ha   1
va   -8
hi   9
vi   0
bits         
bits         
bits         
bits    *****
bits    **   
bits    **   
bits    **   
bits    **   
bits    **   
bits    **   

############### Character 0x42, 0102, 66   B B B B B B B B B B
char 66
hs   9
vs   10
ha   0
va   -8
hi   9
vi   0
bits          
bits          
bits          
bits ******   
bits     **   
bits     **   
bits     **   
bits     **   
bits     **   
bits     **   

############### Character 0x43, 0103, 67   C C C C C C C C C C
char 67
hs   9
vs   9
ha   0
va   -10
hi   9
vi   0
bits     **   
bits     **   
bits     **   
bits     **   
bits     **   
bits     *****
bits          
bits          
bits          

############### Character 0x44, 0104, 68   D D D D D D D D D D
char 68
hs   9
vs   9
ha   0
va   -10
hi   9
vi   0
bits     **   
bits     **   
bits     **   
bits     **   
bits     **   
bits ******   
bits          
bits          
bits          

############### Character 0x45, 0105, 69   E E E E E E E E E E
char 69
hs   9
vs   12
ha   0
va   -10
hi   9
vi   0
bits   *****  
bits  *     * 
bits *       *
bits * ***** *
bits * * * * *
bits * ***** *
bits *       *
bits *       *
bits *       *
bits *       *
bits *       *
bits *********

############### Character 0x5b, 0133, 91   [ [ [ [ [ [ [ [ [ [
char 91
hs   9
vs   12
ha   0
va   -10
hi   9
vi   0
bits *   *   *
bits **** ****
bits *       *
bits *       *
bits *       *
bits *       *
bits *       *
bits *       *
bits *       *
bits  *     * 
bits   *   *  
bits    ***   

############### Character 0x5c, 0134, 92   \ \ \ \ \ \ \ \ \ \
char 92
hs   9
vs   12
ha   0
va   -10
hi   9
vi   0
bits *        
bits **       
bits **       
bits **       
bits *        
bits *******  
bits *   *    
bits ******** 
bits *      * 
bits *      * 
bits *      * 
bits          

############### Character 0x5e, 0136, 94   ^ ^ ^ ^ ^ ^ ^ ^ ^ ^
char 94
hs   7
vs   7
ha   1
va   -8
hi   9
vi   0
bits   ***  
bits    *   
bits *  *  *
bits *******
bits *  *  *
bits    *   
bits   ***  

############### Character 0x60, 0140, 96   ` ` ` ` ` ` ` ` ` `
char 96
hs   9
vs   10
ha   0
va   -10
hi   9
vi   0
bits    ***   
bits  **   ** 
bits  *   *  *
bits *   *   *
bits *  *    *
bits *  *    *
bits *       *
bits *      * 
bits *      * 
bits  ******  

############### Character 0x7b, 0173, 123   { { { { { { { { { {
char 123
hs   9
vs   9
ha   0
va   -9
hi   9
vi   0
bits   *   *  
bits  * * * * 
bits  *  *  * 
bits     *    
bits *  ***  *
bits  ******* 
bits     *    
bits    ***   
bits  ******* 

############### Character 0x7c, 0174, 124   | | | | | | | | | |
char 124
hs   9
vs   12
ha   0
va   -10
hi   9
vi   0
bits     **   
bits     **   
bits     **   
bits     **   
bits     **   
bits     **   
bits     **   
bits     **   
bits     **   
bits     **   
bits     **   
bits     **   

############### Character 0x7d, 0175, 125   } } } } } } } } } }
char 125
hs   9
vs   2
ha   0
va   -2
hi   9
vi   0
bits  *  *  * 
bits * ** ** *
-----------------------------------------------------------------------
-- 
      Eric S. Raymond
      UUCP:  {{seismo,ihnp4,rutgers}!cbmvax,sdcrdcf!burdvax,vu-vlsi}!snark!eric
      Post:  22 South Warren Avenue, Malvern, PA 19355    Phone: (215)-296-5718

darren@bacchus.UUCP (Darren Friedlein) (01/08/88)

ARGH!!!!!  I hate myself now!  I've spent the past 5 days (spare time, of
course) working on this exact same project!  Oh well - I'll get over it in
a minute... My patches didn't use the DECgraphics stuff (though I thought
about it) - other that that, it's almost exactly the same.  I devised
characters for all the objects and some of the monsters.  If I have any
that aren't included in Mr. Raymond's font (I haven't seen it yet, but
it sounds good) I'll post them along with a short program I wrote to
insert them in an existing font.

BTW:  To get a context diff on the 3b1, use 'diff -c'

(Loud, banging noise as if someone were beating his head against the
wall...)

-Darren

/******                      /*****       {edo}             Darren G. Friedlein
 *     *      /******        *            {mcnc}  Rt 4 Box 416, Durham NC 27703
 *     *      *              *            {ethos}    data(bacchus):919/596-7746
 *     *urham \*****\        *     ompany {gladys}           voice:919/596-9492
\******             *oftware \*****       {bakerst}!bacchus!darren
              ******/