[net.sources.games] Galaxy - part 10 of 10

ejb@think.ARPA (Erik Bailey) (04/24/86)

#!/bin/sh
# shar:	Shell Archiver
#	Run the following text with /bin/sh to create:
#	use_term.c
#	wizard.c
#	write.c
# This archive created: Sat Jun  8 13:07:16 1985
echo shar: extracting use_term.c '(4340 characters)'
cat << \SHAR_EOF > use_term.c
/*
 * %W% (mrdch&amnnon) %G%
 */

# include "header"
# include <sgtty.h>
# include <signal.h>

/* LINTLIBRARY */

/**********************************************************************\
|   Ctrl library.   ctrlinit should be called before any of the        |
| other functions is called. it returnes 0 for error, 1 when           |
| everything is ok.  FUNCTIONS :                                       |
|                       ctrlinit        initialize                     |
|                       ctrlreset       reset tty state                |
|                       echo            select echo mode               |
|                       noecho          select noecho mode             |
|                       crmode          select cbreak mode             |
|                       nocrmode        select no cbreak mode          |
|                       raw             select raw mode                |
|                       noraw           select no raw mode             |
|                       dogetstr        get a string in raw | cbreak   |
|                                                                      |
|       All function calls work on the current player's terminal       |
|                                                                      |
\**********************************************************************/


struct sgttyb   oldsg[2];
struct sgttyb   newsg[2];
struct ltchars  oldch[2];
struct ltchars  newltchars = {
         -1, -1, -1, -1, -1, -1
 };
struct tchars   oldtch[2] ;
struct tchars   newtchars = {
        -1, -1, -1, -1, -1, -1
};

ctrlinit () {
    if (gtty (fileno (tty), &oldsg[player]) == -1)
        return (0);
    newsg[player] = oldsg[player];
    noecho ();
    setchrs ();
    return (1);
}

ctrlreset () {
    newsg[player] = oldsg[player];
    (void) stty (fileno (tty), &newsg[player]);
    ioctl (fileno (tty), TIOCSLTC, &oldch[player]);
    ioctl (fileno (tty), TIOCSETC, &oldtch[player]);
}

echo () {
    newsg[player].sg_flags |= ECHO;
    (void) stty (fileno (tty), &newsg[player]);
}

noecho () {
    newsg[player].sg_flags &= ~ECHO;
    (void) stty (fileno (tty), &newsg[player]);
}

crmode () {
    newsg[player].sg_flags |= CBREAK;
    (void) stty (fileno (tty), &newsg[player]);
}

nocrmode () {
    newsg[player].sg_flags &= ~CBREAK;
    (void) stty (fileno (tty), &newsg[player]);
}

raw () {
    newsg[player].sg_flags |= RAW;
    (void) stty (fileno (tty), &newsg[player]);
}

noraw () {
    newsg[player].sg_flags &= ~RAW;
    (void) stty (fileno (tty), &newsg[player]);
}

setchrs () {
    ioctl (fileno (tty), TIOCGLTC, &oldch[player]);
    ioctl (fileno (tty), TIOCGETC, &oldtch[player]);

    newtchars.t_startc = oldtch[player].t_startc;
    newtchars.t_stopc = oldtch[player].t_stopc;

    ioctl (fileno (tty), TIOCSLTC, &newltchars);
    ioctl (fileno (tty), TIOCSETC, &newtchars);
}

/*
 * this function is used in order to read strings from a terminal.
 * If it is back_space, it goes backwards in the buffer.
 * If it is cntrl/p it outputes the name of the current planet
 * by calling itself recursively.
 * Any other cntr char is ignored, and the terminal's bell is ringed.
 * Other char is echoed to the terminal, & inserted in the buffer.
 */

# define buf  bufs[player]
# define bufp bufsp[player]
extern char bufs[2][100];
extern int  bufsp[2];

dogetstr (c)
char    c;
{
    char        *topid ;

    if (c == '\b') {
        if (bufp == 0)
            ding ();
        else {
            fprintf (tty, "\b");
            ceol ();
            bufp--;
        }
        return ;
    }
      /* If a kill character is given, then remove entire input line */
      /* kill characters are ^X and ^] */
      if (c == '\030' || c == '\035') {
        if (bufp == 0)
            ding ();
        else {
            cleol (22, 11);
            bufp = 0;
        }
        return ;
      }
      else {
        if (c == '\020' ) {      /* cntr/p */
            topid = curpln -> pid ;
            dogetstr(*topid++) ;
            dogetstr(*topid++) ;
            dogetstr(*topid) ;
            dogetstr(' ');
            return ;
        }
        if (iscntrl (c)) {
            ding ();
            return;
        }
        else
            fprintf (tty, "%c", c);
        buf[bufp++] = c;
    }
}

ding () {
    fprintf (tty, "\07");
}
SHAR_EOF
if test 4340 -ne "`wc -c use_term.c`"
then
echo shar: error transmitting use_term.c '(should have been 4340 characters)'
fi
echo shar: extracting wizard.c '(2678 characters)'
cat << \SHAR_EOF > wizard.c
/*
 * %W% (mrdch&amnnon) %G%
 */

# include "header"

extern  char    didchange[2] ;
extern  int     changestat;
extern  int     nulluser;
int     no_new_year = 0;

/*
 * get a string. see if exists within the wizards file.
 */
iswizard (u)
char   *u;
{
    char    s[BUFSIZ];
    FILE * wizf = fopen (WIZFIL, "r");

    if (wizf == NULL)
        return (0);

    while (xgets (s, wizf)) {
        if (strcmp (s, u) == 0) {
            (void) fclose (wizf);
            return (1);         /* oh, boy, i'm a wizard! */
        }
    }

    (void) fclose (wizf);
    return (0);
}

/* gather chars into string, return upon CR or EOF */
xgets (s, f)
FILE * f;
char   *s;
{
    int     c;

    for (;;) {
        c = getc (f);
        if (c == '\n' || c == EOF) {
            *s = '\0';
            return (c == EOF ? 0 : 1);
        }
        else
            *s++ = c;
    }
}

/*
 * function that chakes if you're a wizard.
 */
assert_wizard () {
    if ( (iswiz[player] != 1) && !changestat) {
        say ("But sir, where is your wizard hat?");
        longjmp (jparse, 1);
    }
}

toggle_wizard () {
    if (iswiz[player] == 1) {
        iswiz[player]++ ;
        say("Sir! You are no longer a wizard.") ;
        return ;
    }
    if (iswiz[player] == 2) {
        iswiz[player]-- ;
        say ("Sir! You have been nominated wizard again.") ;
        return ;
    }
}

/*
 * If playing agains oneself, or wizard, give the asking side
 * the opportunity to become the other side.
 */
changeplay () {
    if (!nulluser)
        assert_wizard ();
    curse_map (curpln);
    if (changestat) {
        player = !player;
        curpln = apntr;
    }
    else
        curpln = spntr;
    curse_com (curpln);
    didchange[player] = !didchange[player];
}

/*
 * gives a lot. needs a wizard.
 */
wizwiz () {
    int     j;

    assert_wizard ();
    feedpop ("5000");

    for (j = 0; j < CLASES; j++) {
        curpln -> inventar.popul[j] += 1000;
    }
    curpln -> inventar.metals += 100;
    curpln -> inventar.know = 5;
    for (j = 1; j <= MAXSHIPS; j++) {
        curpln -> ships[j - 1] += j * 11;
        curpln -> missile[j - 1] += j * 11;
    }
}

/*
 * function that gives a planet to a player. Needs wizard to
 * work.
 */
takepl (s)
char   *s;
{
    planet * pp;

    assert_wizard ();
    pp = getpl (s);
    skipword (s);
    assert_end (s);
    pp -> whos = player;
    say ("Planet %s surrenders.", pp -> pid);
    check_end ();
}
/* A  quick exit for those who are permitted */
getoutofhere ()
{
    assert_wizard ();
    endgame (-1);
}

debuggingmode() {
        if(iswiz[0] || iswiz[1])
                return(1);
        else
                return(0);
}
SHAR_EOF
if test 2678 -ne "`wc -c wizard.c`"
then
echo shar: error transmitting wizard.c '(should have been 2678 characters)'
fi
echo shar: extracting write.c '(5541 characters)'
cat << \SHAR_EOF > write.c
/*
 * %W% (mrdch&amnnon) %G%
 */

# include "header"

# define TORETURN 3
/* times to press '-' for a message to vanish */

extern  changestat;

/*
 * This tiny function exists only for the menu "write"
 * function. This fuction is called only with the
 * command string.
 */

write_enemy (s)
char   *s;
{
    /* THIS SHOULD NOT BE HERE BUT THIS WAS THE ONLY EDITED FILE */
    (void) chdir("/usr/games/lib/galaxy");
    skipwhite (s);
    dowrite_enemy (s, !player);
}

/*
 * Here we link a new piece of information to the list of
 * messages that apears on the status line beneath the map.
 * If this information is the first, the bell on the terminal
 * of the player that has received the message is ringed.
 * Here is the structure definition.
 *
 * typedef struct _info    info;
 * struct _info {
 *     int     owner;
 *     int          nmsg ;
 *     char    msg[MSGSIZ];
 *     info * next;
 * };
 */

dowrite_enemy (s, p)
char   *s;
int     p;
{
    FILE * newtty = tty;        /* keep the current terminal     */
    info * head = info_head[p];
    info * ialloc ();
    info * inf = ialloc ();     /* get a new chunk of space      */
    char * cp = s;

    inf -> owner = player;
    if ( !*s )
        return ;                /* return on empty lines        */
    if(*s < 15) {
        s[MSGSIZ-1] = '\0';     /* truncate too long msgs        */
        flip();
        print("WRITE BOGUS FOUND %d AT END OF STRING\n\r", s[MSGSIZ-1]);
        print("string is %s\n", s);
        print("s[0]=%d s[1]=%d s[2]=%d s[3]=%d s[4]=%d s[5]=%d\n\r",
        s[0],s[1],s[2],s[3],s[4],s[5]);
        while(*cp < 15)
                cp++;
        print("first knowledgable character begins at %d\n\r", cp-s);
        flip();
    }
    (void) strcpy (inf -> msg, s);

    if (head == 0) {            /* NO -More- */
        if (changestat)
            tty = ttys[!p];
        else
            tty = ttys[p];      /* the correct terminal to ring */
        disch ('\07');          /* ring it                       */
        tty = newtty;           /* restore the previous one      */
    }
    dolink (&head, inf);
    info_head[p] = head;
}

/* actively display the messages gathered on screen */
/* REWRITE */
putmsgs (cc)
char    cc;
{
    static int  nreturns = TORETURN;
    static int  nid = 1;        /* flag to indicate repeated request */
    info * i = info_head[player];

    if (cc == '-')
        nreturns = TORETURN;    /* he wants to see NOW */
    if (nreturns++ < TORETURN)
        return;
    if (i == 0) {               /* no msgs */
        if (nid)
            return;             /* nothing there to show or clear */
        nreturns = TORETURN;
        cleol (21, 0);          /* clear the last one */
        nid = 1;
        return;
    }
    nreturns = 0;
    nid = 0;
    cleol (21, 0);              /* clear the last one */
    msg ("%s", i -> msg);               /* display that message */
    if (i -> next != 0)
        so (20, 5, "--More--"); /* show that more are pending */
    else
        cleol (20, 5);          /* erase the -more- message      */
    info_head[player] = i -> next;/* advance to the next one     */
    ifree (i);                  /* and throw the last    */
}

/*
 * This part contains all functions dealing with linked lists.
 * linked list of type `info' are used by : ps, en, wr, newyear.
 */

# define        HEAD    (*head)

/*
 * perform linking of a new info structure.
 * only the nmsg is updated here.
 */
dolink (head, inf)
info ** head;
info * inf;
{
    info * i = HEAD;

    inf -> next = 0;            /* after it? nothing yet */
    if (HEAD == 0) {            /* if list empty-        */
        HEAD = inf;             /* point to the first    */
        inf -> nmsg = 1;        /* and declare it so     */
        return;
    } else {
        while (i -> next)       /* search to it's end    */
            i = i -> next;

        inf -> nmsg = i -> nmsg + 1;
        i -> next = inf;        /* and link it there     */
    }
}

spy_msg (msg, own, pl, lvl)
char   *msg;
int     own;
planet * pl;
int     lvl;
{
    info * ialloc ();
    info * inf = ialloc ();

    (void) sprintf (inf -> msg, "Y: %d L: %d %s", year,
            lvl, msg);
    inf -> owner = own;

    dolink (&(pl -> reports), inf);
}

/*
 * delete the first few msgs in order to scroll old msgs.
 */
scroll_msgs (head, player)
info ** head;
{
    info * h = HEAD;
    info * x, *x1;

    int     nmsgs = count_msgs (h, player);

    if (nmsgs <= N_PSI)
        return;

    x1 = 0;
    x = HEAD;
    while (nmsgs > N_PSI && x -> next)  {
        if(x->owner == player) {                /* remove it. */
                if(x == HEAD) {
                        x = x->next;
                        ifree(HEAD);
                        HEAD = x;
                        nmsgs--;
                } else {
                        x1 ->next = x->next;
                        ifree(x);
                        nmsgs--;
                        x = x1 -> next;
                }
        } else {
                x1 = x;
                x = x->next;
        }
    }
}

/*
 * allocate space for info structure.
 */
info *
ialloc () {
    char   *malloc ();
    char   *p = malloc (sizeof (info));

    if (p == 0)
        (void) bug ("Unable to allocate space for messages.");

    ((info *) p) -> next = 0;
    return ((info *) p);
}

ifree (i)
info * i;
{
# ifndef ENQDBG
# define ENQDBG 0
# else
# undef ENQDBG
# define ENQDBG 1
# endif

    if(!(debuggingmode() || ENQDBG))
        free ((char *) i);
}
SHAR_EOF
if test 5541 -ne "`wc -c write.c`"
then
echo shar: error transmitting write.c '(should have been 5541 characters)'
fi
#	End of shell archive
exit 0
-- 

Erik Bailey        -- 7 Oak Knoll                 (USENET courtesy of
ihnp4!think!ejb       Arlington, MA  02174        Thinking Machines Corp.
ejb@think.com         (617) 643-0732              Cambridge, MA)

	   It takes thought to make a program that thinks.
	   But it takes work to make a program that works.