[comp.windows.x] Using Xfonts for rogue

bloom@eniac.seas.upenn.edu (Marc Bloom) (07/19/88)

 I have tried to start up rogue using the rogue fonts for X10R4
but when I do I get beautiful pictures and unreadable text.
Can someone tell me how to run rogue with the pictoral fonts
and still be able to read the text?

hauck@faline.bellcore.com (Scott Hauck) (07/19/88)

In article <> bloom@eniac.seas.upenn.edu (Marc Bloom) writes:
>
> I have tried to start up rogue using the rogue fonts for X10R4
>but when I do I get beautiful pictures and unreadable text.
>Can someone tell me how to run rogue with the pictoral fonts
>and still be able to read the text?

I tried this once and quickly gave it up.  First of all, the rogue fonts
are incomplete.  There aren't symbols defined for all of the necessary
characters.  Also, to use the fonts and also be able to read the text
you have to do some hacking to the code.  Either the normal lettering or
the screen characters have to be changed into bold fonts - a major
undertacking.  If someone out there decides they want to spent the time
and effort good luck, and I'd like to get a copy.  However, remeber to
do it you have to either track down every message or every place a
monster, wall, corridor, and object is printed.

Scott Hauck
Hauck@faline.bellcore.com
Hauck@postgres.berkeley.edu

bph@buengc.BU.EDU (Blair P. Houghton) (07/19/88)

In article <5492@super.upenn.edu> bloom@eniac.seas.upenn.edu (Marc Bloom) writes:
>
> I have tried to start up rogue using the rogue fonts for X10R4
>but when I do I get beautiful pictures and unreadable text.
>Can someone tell me how to run rogue with the pictoral fonts
>and still be able to read the text?

Yeah, anyone know the *right* way to do this?

I've been forking rogue into a window with the graphics font and
teeing it back to the tty in a smaller window with a text font;
the result is that I appear to have the game running twice.

Another thing:  Does anyone else ever accidentally hit ctrl-Y?
Does anyone know how to recover from it?  This may be processor-
specific, but I don't know; just send me the answer if it's
the game and not the computer.

				--Blair

jkh@ardent.UUCP (07/20/88)

Actually, I had it working fine a few years ago (the last time I tried).

I just said: xterm -fn rogue-n -fb rogue-b

And cranked up a rogue. The rogue I have/had did print out its map in
bold. I don't know if someone hacked it awhile back to look better on vt100's or
what.. I didn't have to do anything to it.

					Jordan

jg@jumbo.dec.com (Jim Gettys) (07/20/88)

How fast they forget....

Actually, there is a file missing from the X11 distribution.  In the
X10R4 distribution was the following file: X.V10R4/hacks/misc/vrogue.c
It does the appropriate font shifts for rogue at the right time.
I had an alias for vrogue: xterm -fn rogue-n -fb rogue-b -e vrogue & 
but I haven't played rogue for years (made a good X demo early on though).
It also may need work for more recent versions of rogue; it worked fine
for the version which shipped on 4.2BSD.
					- Jim

-------------------------
#include <signal.h>
#include <stdio.h>
#include <sgtty.h>
#include <sys/wait.h>
#include <sys/time.h>
#define BUFLEN 1024

int got_a_signal;

main(argc,argv)
int argc;
char *argv[];
{
    extern int  tstp_handler (), quit_handler (), chld_handler (),
    		int_handler ();
    extern int got_a_signal;
    struct ltchars   new_ltc, old_ltc;
    struct sigvec   vec;
    int     topipe[2], frompipe[2];
    int	    pipeflag, nfds, from_rogue, to_rogue, readfds;
    int     num, rogue_pid, old_mask;

    /* Since this IS a game, reduce our priority. */
    setpriority(0, getpid(), 4);

    /* Create the pipes that will connect us to rogue. */
    if (pipe (topipe) != 0) {
        printf ("Couldn't open pipe to rogue\n");
        exit (1);
    }
    if (pipe (frompipe) != 0) {
        printf ("Couldn't open pipe to rogue\n");
        exit (1);
    }

    if (rogue_pid = vfork ()) {
	/* Close the ends of the pipes that we don't need, and make better 
	   names for the ones we do. */
        close (topipe[0]);
        close (frompipe[1]);
        from_rogue = frompipe[0];
	to_rogue = topipe[1];

	/* Get the old interrupt chars and save them. */
        if (ioctl (0, TIOCGLTC, &old_ltc))
	    printf("Couldn't get old_ltc.\n");

	/* Copy the old interrupt chars and make the rest of them 
	   correspond to what rogue uses. */
        new_ltc = old_ltc;
        new_ltc.t_dsuspc = -1;
        if (ioctl (0, TIOCSLTC, &new_ltc))
	    printf("Couldn't remove ^Y.\n");

	/* Install our interrupt handlers */
        vec.sv_mask = 0;
        vec.sv_onstack = 0;
        vec.sv_handler = tstp_handler;
        if (sigvec (SIGTSTP, &vec, 0))
	    printf("Couldn't install TSTP handler.\n");
        vec.sv_handler = quit_handler;
        if (sigvec (SIGQUIT, &vec, 0))
	    printf("Couldn't install QUIT handler.\n");
        vec.sv_handler = int_handler;
        if (sigvec (SIGINT, &vec, 0))
	    printf("Couldn't install INT handler.\n");
        vec.sv_handler = chld_handler;
        if (sigvec (SIGCHLD, &vec, 0))
	    printf("Couldn't install CHLD handler.\n");

        pipeflag = 1 << from_rogue;
        nfds = from_rogue + 1;
        while (1) {
            readfds = pipeflag | 1;
            num = select (nfds, &readfds, 0, 0, 0);
	    if (num > 0)
                if (readfds & pipeflag) process_output(from_rogue);
                else process_input(to_rogue);

	    if (got_a_signal) {
                handle_signal(got_a_signal, rogue_pid, from_rogue, &old_ltc);
		got_a_signal = 0;
	    }
        }
    }
    else {
        /* We are the child process, so attach our ends of the pipe to stdin
	   and stdout. */
        if ((dup2 (topipe[0], 0)) == -1) {
            printf ("couldn't dup2 stdin pipe\n\n");
            exit (1);
        }
        if ((dup2 (frompipe[1], 1)) == -1) {
            printf ("couldn't dup2 stdout pipe\n\n");
            exit (1);
        }

	/* Close the ends of the pipe we don't need. */
        close (topipe[1]);
        close (frompipe[0]);

	/* Do it. */
        execv ("/usr/games/rogue", argv);
        printf ("Couldn't execv rogue!\n");
        exit (1);
    }
}

handle_signal(the_signal, rogue_pid, from_rogue, old_ltc)
int the_signal, rogue_pid, from_rogue;
struct ltchars *old_ltc;
{
    switch (the_signal) {
    case SIGQUIT:
        if (kill(rogue_pid, SIGQUIT)) {
	    normal_font();
	    printf("Couldn't QUIT rogue!\n");
	    exit(1);
	}
        break;
    case SIGTSTP:
        if (kill(rogue_pid, SIGTSTP)) {
	    normal_font();
	    printf("Couldn't TSTP rogue!\n");
	    exit(1);
	}
        break;
    case SIGINT:
        if (kill(rogue_pid, SIGINT)) {
	    normal_font();
	    printf("Couldn't INT rogue!\n");
	    exit(1);
	}
        break;
    case SIGCHLD: 
        {
            union wait status;
            int nfds, pipeflag;
            int num, readfds;
            struct timeval timeout;

	    /* For some reason, our child has stopped.  There is no need
	       (I think) to send it any more characters, so just finish
	       processing its output, and decide how we should stop. */


            nfds = from_rogue + 1;
            pipeflag = 1 << from_rogue;
            timeout.tv_sec = 0;
            timeout.tv_usec = 100000;
            do {
                readfds = pipeflag;
                num = select (nfds, &readfds, 0, 0, &timeout);
		if (num > 0) 
		    num = process_output(from_rogue);
            }
            while(num > 0);

	    normal_font();

            if (wait3(&status, WNOHANG | WUNTRACED, 0) > 0) {
                if (WIFSTOPPED(status)) {
                    if (kill(getpid(), SIGSTOP)) {
		        printf("Couldn't STOP myself!\n");
			exit(1);
		    }
                    if (kill(rogue_pid, SIGCONT)) {
		        printf("Couldn't CONT rogue!\n");
			exit(1);
		    }
                }
                else if (WIFEXITED(status)) {
		    ioctl(0,TIOCSLTC,old_ltc);
                    exit(status.w_retcode);
                }
                else if (WIFSIGNALED(status)) {
		    ioctl(0,TIOCSLTC,old_ltc);
                    printf("Rogue terminated.\n");
                    printf("termsig: %d\n",status.w_termsig);
                    printf("coredump: %d\n",status.w_coredump);
                    printf("retcode: %d\n",status.w_retcode);
		    exit(-1);
                }
                else {
		    ioctl(0,TIOCSLTC,old_ltc);
                    printf("Rogue's status is bizzare!\n");
                    exit(1);
                }
            }
        }
        break;
    default:
        break;
    }
}

quit_handler() {
    extern int got_a_signal;
    got_a_signal = SIGQUIT;
}

tstp_handler() {
    extern int got_a_signal;
    got_a_signal = SIGTSTP;
}

int_handler() {
    extern int got_a_signal;
    got_a_signal = SIGINT;
}

chld_handler() {
    extern int got_a_signal;
    got_a_signal = SIGCHLD;
}

normal_font() {
    write(1, "[0m", 3);
}

special_font() {
    write (1, "[1m", 4);
}

int process_input(to_rogue)
int to_rogue;
{
    static char buf[BUFLEN];
    register int num, old_mask;

    old_mask = sigblock(1 << (SIGCHLD - 1));
    num = read (0, buf, BUFLEN);
    if (num <= 0) {
        printf("Error reading keyboard!\n");
	exit(1);
    }
    write (to_rogue, buf, num);
    sigsetmask(old_mask);
    return(num);
}

int process_output(from_rogue)
int from_rogue;
{
    static char buf[BUFLEN];
    static int state = 0;
    static int linenum = 1;
    static int special = 0;
    static int force = 0;
    static int accum = 0;
    int chr, i, start, num, something_changed, old_mask;

    old_mask = sigblock(1 << (SIGCHLD - 1));
    num = read (from_rogue, buf, BUFLEN);

    if (num <= 0) {
	sigsetmask(old_mask);
        return(num);
    }

    start = 0;
    for (i = 0; i < num; i++) {
        chr = buf[i];
        switch (state) {
        case 0: 
	/* State 0 is the normal idle state. */
            switch (chr) {
            case '': 
                state = 1;
                break;
            case '\n': 
                linenum++;
                something_changed = 1;
                break;
            case 'a': 
            case 'b': 
            case 'c': 
            case 'd': /* e is left out on purpose */
            case 'f': 
            case 'g': 
            case 'h': 
            case 'i': 
            case 'j': 
            case 'k': 
            case 'l': 
            case 'm': 
            case 'n': 
            case 'o': 
            case 'p': 
            case 'q': 
            case 'r': 
            case 's': 
            case 't': 
            case 'u': 
            case 'v': 
            case 'w': 
            case 'x': 
            case 'y': 
            case 'z': 
                if ((linenum > 1) && (linenum < 24) && (!force)) {
                    force = 1;
                    something_changed = 1;
                }
                break;
            case 'e': 
                if (force) {
                    state = 5;
                }
                if ((linenum > 1) && (linenum < 24) && (!force)) {
		    state = 5;
                    force = 1;
                    something_changed = 1;
                }
                break;
            default: 
                break;
            }
            break;
        case 1: 
	/* We've begun an escape sequence. */
            switch (chr) {
            case '[': 
                state = 2;
                break;
            default: 
                state = 0;
                break;
            }
            break;
        case 2: 
	/* We've seen "<esc>[" */
            switch (chr) {
            case '0': 
            case '1': 
            case '2': 
            case '3': 
            case '4': 
            case '5': 
            case '6': 
            case '7': 
            case '8': 
            case '9': 
                state = 3;
                accum = chr - '0';
                break;
            case ';': 
                state = 4;
                accum = 1;
                break;
            case 'A': 
                state = 0;
                linenum--;
                something_changed = 1;
                break;
            case 'H': 
                state = 0;
                linenum = 1;
                something_changed = 1;
                break;
	    case 'm':
		/* We've seen "<esc>[m"
	           Rogue is trying to get out of reverse video. */
		state = 0;
		break;
            default: 
                state = 0;
                break;
            }
            break;
        case 3: 
	/* We've seen "<esc>[n"
	   Continue parsing the argument. */
            switch (chr) {
            case '0': 
	    case '1': 
	    case '2': 
	    case '3': 
	    case '4': 
	    case '5': 
	    case '6': 
	    case '7': 
	    case '8': 
	    case '9': 
                accum = (10 * accum) + chr - '0';
                break;
            case ';': 
                state = 4;
                break;
	    case 'm':
	    /* Rogue is trying to use reverse video or something. */
	        state = 0;
		break;
            default: 
                state = 0;
                break;
            }
            break;
        case 4: 
	/* We've seen "<esc>[nn;"
	   Ignore the rest of the digits until the magic H completes the
	   sequence. */
            switch (chr) {
            case 'H': 
                state = 0;
                linenum = accum;
                something_changed = 1;
                break;
            case '0': 
            case '1': 
            case '2': 
            case '3': 
            case '4': 
            case '5': 
            case '6': 
            case '7': 
            case '8': 
            case '9': 
                break;
            default: 
                state = 0;
                break;
            }
            break;
        case 5: 
	/* We've seen an "e" on lines 2-23.   This means that we're in
           an inventory or something.  We're hoping for "e--", the end of
	   "--more--" or "--Press space to continue--". */
            switch (chr) {
            case '-': 
                state = 6;
                break;
            case '': 
                state = 1;
                break;
            case '\n': 
                state = 0;
                linenum++;
                something_changed = 1;
                break;
            default: 
                break;
            }
            break;
        case 6: 
	/* We've seen "e-".  If we see another "-" we can stop forcing. */
            switch (chr) {
            case '-': 
                state = 0;
                force = 0;
                something_changed = 1;
                break;
            case '': 
                state = 1;
                break;
            case '\n': 
                state = 0;
                linenum++;
                something_changed = 1;
                break;
            default: 
                break;
            }
            break;
        default: 
            break;
        }
        if (something_changed) {
            something_changed = 0;
	    if (force) {
	        /* Since we're just starting for force, force before outputting
		   the character just looked at. */
		if (special) {
		    write(1, buf + start, i - start);
		    normal_font();
		    start = i;
		    special = 0;
		}
            }
            else if ((linenum == 1) || (linenum >= 24)) {
                if (special) {
                    write (1, buf + start, i - start + 1);
		    normal_font();
                    start = i + 1;
                    special = 0;
                }
            }
            else {
                if (!special) {
                    write (1, buf + start, i - start + 1);
		    special_font();
                    start = i + 1;
                    special = 1;
                }
            }
        }
    }

    /* Output any characters remaining in the buffer. */
    if (i != start)
        write (1, buf + start, i - start);

    sigsetmask(old_mask);

    return(num);
}

bph@buengc.BU.EDU (Blair P. Houghton) (07/21/88)

In article <1998@faline.bellcore.com> hauck@faline.UUCP (Scott Hauck) writes:
>In article <> bloom@eniac.seas.upenn.edu (Marc Bloom) writes:
>>
>> I have tried to start up rogue using the rogue fonts for X10R4
[...]
>
>I tried this once and quickly gave it up.  First of all, the rogue fonts
>are incomplete.  There aren't symbols defined for all of the necessary

What's Missing!?  I've been playing for a long time (no, I still have
to tee all output to a non-graphics-font window to read anything)
and I have yet to run into anything "invisible" that shouldn't be
(e.g. the Phantom _should_).

				--Blair