#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of shell archive."
# Contents:  corewar.h sim.c clparse.c asm_lex.flex asm_parse.y
#   clparse.h ldaddr.c di_recalc.c di_draw.c cwdisp.h di_load.c
#   build_siminstr sim.h asm.h koth.1 README mkbuild disp.c cwmain.c
#   di_timer.c di_input.c di_dis.c gbut.c di_but.c gbut.h
# Wrapped by wms@iwarpe26 on Sun Nov  1 18:36:50 1992
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'corewar.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'corewar.h'\"
else
echo shar: Extracting \"'corewar.h'\" \(3279 characters\)
sed "s/^X//" >'corewar.h' <<'END_OF_FILE'
X/* corewar.h */
X
X/* This program was written by Bill Shubert.  Give it away all you want and
X *   modify it all you want, but just to be nice keep my name around.
X */
X
X#define  STR_MAXLEN  80
X#define  STR_ERRLEN  1024
X
X#define  VERSION  "KotH Corewar V3.1 by Bill Shubert - 1 November 1992"
X
X#define  FALSE  0
X#define  TRUE   1
X
Xtypedef enum {
X	op_dat, op_mov, op_add, op_sub, op_jmp, op_jmz, op_jmn, op_djn, op_cmp,
X	op_spl, op_slt, op_end, op_equ, op_nogood} op_t;
X#define  op_realop(x)  ((op_t)x <= op_slt)
X
Xtypedef enum  {
X	am_imm, am_dir, am_ind, am_dec, am_inc} amode_t;
X
X#define  JTINDEX(op, am1, am2) \
X	(((((unsigned)op * 5) + (unsigned)am1) * 5) + (unsigned)am2)
X#define  JTOP(index)   (op_t)(index / 25)
X#define  JTAM1(index)  (amode_t)((index / 5) % 5)
X#define  JTAM2(index)  (amode_t)(index % 5)
X
Xtypedef unsigned  aval_t;
X#define  AVAL_NOGOOD  ((aval_t)-1)
X#define  AVAL_PROGID  ((aval_t)-2)
X
Xtypedef struct  thread_struct  {
X	aval_t  addr;
X	struct thread_struct  *next, *prev;
X} thread_t;
X
Xtypedef struct  core_el_struct  {
X  int  (*instr)(thread_t *th, struct core_el_struct *core,
X	              aval_t w_radius, aval_t coresize, aval_t xeq_addr,
X	              aval_t op1, aval_t op2);
X	aval_t val1;
X	aval_t val2;
X	unsigned  index;
X} core_el_t;
X
Xtypedef int  intfunc(thread_t *th, core_el_t *core,
X										 aval_t w_radius, aval_t coresize, aval_t xeq_addr,
X										 aval_t op1, aval_t op2);
Xtypedef intfunc  *pintfunc;
X
Xtypedef struct  program_struct  {
X	aval_t  startaddr;
X	aval_t  proglen;
X	core_el_t  *listing;
X	char  author[STR_MAXLEN], retaddr[STR_MAXLEN], pname[STR_MAXLEN],
X	      fname[STR_MAXLEN];
X} program_t;
X
X/* Data tables useful in more than one module. */
Xextern char  cwerrstr[STR_ERRLEN];
Xextern char  *opnames[], *amodenames[];
Xextern core_el_t  *core;
Xextern pintfunc  jmptable[];
X
X
X/* Display stuff. */
X#define  DI_MAXPLAYERS  6
X#define  DI_PLSIZ  3
X#define  DI_EMPTY  0
X#define  DI_DEAD   1
X#define  DI_DAT    2
X#define  DI_RAN    3
X#define  DI_XEQ    4
X
X
X/* Options that affect play */
Xextern aval_t  coresize;
Xextern aval_t  maxprogsize;
Xextern unsigned  maxthreads;
Xextern unsigned  max_cycles;
Xextern unsigned  amode_restrict;
Xextern unsigned  postinc;
Xextern unsigned  rounds;
Xextern unsigned  w_radius;
Xextern unsigned  interactive;
Xextern unsigned  split_id;
X
X/* From "asm.c" */
Xextern unsigned  assemble(program_t *prog, char *scfname);
X
X/* From "cwmain.c" */
Xextern void  disasm(core_el_t *listing, aval_t len, aval_t start);
Xextern void  *tmalloc(int size);
X
X/* From "sim.c" */
Xextern unsigned  new_core(),
X                 load_core(program_t *prog, aval_t addr, unsigned id),
X	               sim_cyc();
Xextern int  simulate(unsigned cycles, unsigned progs);
Xextern int  proc_count(unsigned id);
Xextern aval_t  proc_exec(unsigned id);
Xextern void  free_core(), clear_core(aval_t start, unsigned len, int id),
X             set_first(int id);
Xextern aval_t  sim_nextaddr();
Xextern int   sim_nextplayer();
X
X/* From "ldaddr.c" */
Xextern void  ld_init(unsigned maxloads);
Xextern aval_t  ld_addr(unsigned ldnum), ld_undo(unsigned ldnum);
X
X/* From "disp.c" */
Xextern void  di_init(char *progname, char *geometry, char *dpyname, int iconic,
X                     unsigned fightlen);
Xextern void  di_drawaddr(aval_t addr, int picid);
END_OF_FILE
if test 3279 -ne `wc -c <'corewar.h'`; then
    echo shar: \"'corewar.h'\" unpacked with wrong size!
fi
# end of 'corewar.h'
fi
if test -f 'sim.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'sim.c'\"
else
echo shar: Extracting \"'sim.c'\" \(15890 characters\)
sed "s/^X//" >'sim.c' <<'END_OF_FILE'
X/* sim.c */
X
X#include <stdio.h>
X#include <string.h>
X#include "corewar.h"
X#include "sim.h"
X
X#define  THR_LEAF  2
X
X#define  INRANGE\
X    ((((unsigned)(addr2 - xeq_addr + w_radius) <= (unsigned)(2*w_radius))) ||\
X     ((unsigned)(addr2 - xeq_addr + (coresize - w_radius)) >=\
X      (unsigned)(2*(coresize-w_radius))))
X
Xtypedef struct  arg_struct  {
X	aval_t   addr, val;
X} arg_t;
X
Xstatic tblock_t  *new_tblock();
Xstatic tlist_t  *free_tlist(tlist_t  *tl);
Xstatic void  free_tblock(tblock_t *tb);
Xstatic arg_t  fetch_arg(amode_t am, aval_t val, aval_t cur_addr, int cur_id);
Xstatic int  instruction(thread_t *th, op_t op, amode_t am1, aval_t val1,
X                        amode_t am2, aval_t val2);
X
Xtlist_t  *sim_tlist = NULL;
X
Xstatic core_el_t  empty_core = {NULL, 0, 0, JTINDEX(op_dat, am_dir, am_dir)};
X
X
Xunsigned  new_core()  {
X	unsigned  i;
X
X	empty_core.instr = jmptable[empty_core.index];
X
X	if (core != NULL)
X		free(core);
X	
X	while (sim_tlist != NULL)
X		sim_tlist = free_tlist(sim_tlist);
X	core = (core_el_t *)tmalloc(coresize * sizeof(core_el_t));
X	for (i = 0;  i < coresize;  ++i)
X		core[i] = empty_core;
X	return(TRUE);
X}
X
X
Xvoid  set_first(int  id)  {
X	while (sim_tlist->id != id)
X		sim_tlist = sim_tlist->next;
X}
X
X
Xvoid  clear_core(aval_t start, unsigned len, int id)  {
X	tlist_t  *idt = sim_tlist, *new_idt;
X
X	while (len--)  {
X		core[start] = empty_core;
X#ifndef  NO_DISP
X		if (interactive)
X			di_drawaddr(start, DI_EMPTY);
X#endif  /* NO_DISP */
X		if (++start == coresize)
X			start = 0;
X	}
X	while (idt->id != id)
X		idt = idt->next;
X	new_idt = free_tlist(idt);
X	if (idt == sim_tlist)
X		sim_tlist = new_idt;
X}
X
X
Xstatic tlist_t  *free_tlist(tlist_t  *tl)  {
X	tlist_t  *ntl = tl->next;
X
X	tl->prev->next = ntl;
X	ntl->prev = tl->prev;
X	free_tblock(tl->tblock);
X	free(tl);
X	if (tl == ntl)
X		return(NULL);
X	else
X		return(ntl);
X}
X
X
Xstatic void  free_tblock(tblock_t *tb)  {
X	if (tb != NULL)  {
X		free_tblock(tb->next);
X		free(tb);
X	}
X}
X
X
Xunsigned  load_core(program_t *prog, aval_t ld_start, unsigned id)  {
X	aval_t  addr = ld_start;
X	unsigned  i;
X	tlist_t  *new_tlist, *old_tlist;
X
X	new_tlist = sim_tlist;
X	if (new_tlist == NULL)  {
X		new_tlist = sim_tlist = (tlist_t *)tmalloc(sizeof(tlist_t));
X		sim_tlist->next = sim_tlist;
X		sim_tlist->prev = sim_tlist;
X	} else  {
X		while (new_tlist->next != sim_tlist)  {
X			if (new_tlist->id == id)  {
X				sprintf(cwerrstr, "id %d is taken already.", id);
X				return(FALSE);
X			}
X			if ((new_tlist->id < id) && (new_tlist->next->id > id))
X				break;
X			new_tlist = new_tlist->next;
X		}
X		if (new_tlist->id == id)  {
X			sprintf(cwerrstr, "id %d is taken already.", id);
X			return(FALSE);
X		}
X		old_tlist = new_tlist->next;
X		new_tlist->next = (tlist_t *)tmalloc(sizeof(tlist_t));
X		new_tlist = new_tlist->next;
X		new_tlist->next = old_tlist;
X		new_tlist->prev = old_tlist->prev;
X		old_tlist->prev = new_tlist;
X		if (id < sim_tlist->id)
X			sim_tlist = new_tlist;
X	}
X
X	new_tlist->tblock = new_tblock();
X	new_tlist->tblock->threads[0].next = new_tlist->tblock->threads + 0;
X	new_tlist->tblock->threads[0].prev = new_tlist->tblock->threads + 0;
X
X	new_tlist->head = new_tlist->tblock->threads + 0;
X	new_tlist->empty = new_tlist->tblock->threads + 1;
X
X	new_tlist->count = 1;
X	new_tlist->id = id;
X	new_tlist->ld_start = ld_start;
X
X	if ((new_tlist->tblock->threads[0].addr = addr + prog->startaddr) >=
X			coresize)
X		new_tlist->tblock->threads[0].addr -= coresize;
X
X	for (i = 0;  i < prog->proglen;  ++i)  {
X		int  cindex;
X
X		core[addr] = prog->listing[i];
X		if (core[addr].val1 == AVAL_PROGID)
X			core[addr].val1 = ld_start;
X		if (core[addr].val2 == AVAL_PROGID)
X			core[addr].val2 = ld_start;
X		cindex = core[addr].index;
X#ifndef  NO_DISP
X		if (interactive && ((JTOP(cindex) != op_dat) ||
X												(JTAM1(cindex) > am_ind) ||
X												(JTAM2(cindex) > am_ind) ||
X												core[addr].val1 || core[addr].val2))
X			di_drawaddr(addr, DI_DAT + (id * DI_PLSIZ));
X#endif  /* NO_DISP */
X		if (++addr >= coresize)
X			addr -= coresize;
X	}
X#ifndef  NO_DISP
X	if (interactive)
X		di_drawaddr(new_tlist->tblock->threads[0].addr, (id * DI_PLSIZ) + DI_XEQ);
X#endif  /* NO_DISP */
X	return(TRUE);
X}
X
X
Xstatic tblock_t  *new_tblock()  {
X	tblock_t  *ntb;
X	unsigned  i;
X
X	ntb = (tblock_t *)tmalloc(sizeof(tblock_t));
X	for (i = 0;  i < TBLOCK_SIZE - 1;  ++i)
X		ntb->threads[i].next = ntb->threads + i + 1;
X	ntb->threads[TBLOCK_SIZE - 1].next = NULL;
X	ntb->next = NULL;
X	return(ntb);
X}
X
X
Xint  simulate(unsigned cycles, unsigned progs)  {
X	unsigned  cycleft, procs;
X	thread_t  *th, *nxt_th;
X	core_el_t  *tcore = core;
X	aval_t  tw_radius = w_radius, tcoresize = coresize;
X
X	cycleft = cycles * progs;
X	for (cycleft = cycles * progs;  cycleft > 0;  --cycleft)  {
X		th = sim_tlist->head;
X		nxt_th = th->next;
X		procs = tcore[th->addr].instr(th, tcore, tw_radius, tcoresize,
X																	th->addr,
X																	tcore[th->addr].val1, tcore[th->addr].val2);
X		sim_tlist->head = nxt_th;
X		if ((sim_tlist->count += procs) == 0)  {
X			int  newprogs = progs - 1;
X
X			sim_tlist = free_tlist(sim_tlist);
X			if (newprogs <= 1)
X				break;
X			cycleft = ((cycleft * newprogs + newprogs) / progs);
X			progs = newprogs;
X		} else
X			sim_tlist = sim_tlist->next;
X	}
X	return(cycles - (cycleft / progs));
X}
X
X
Xaval_t  sim_nextaddr()  {
X	return(sim_tlist->head->addr);
X}
X
X
Xint  sim_nextplayer()  {
X	return(sim_tlist->id);
X}
X
X
Xunsigned  sim_cyc()  {
X	thread_t  *th, *nxt_th;
X	unsigned  nprocs;
X
X	th = sim_tlist->head;
X	nprocs = sim_tlist->count;
X	nxt_th = th->next;
X	nprocs += instruction(th, JTOP(core[th->addr].index),
X												JTAM1(core[th->addr].index),
X												core[th->addr].val1,
X												JTAM2(core[th->addr].index),
X												core[th->addr].val2);
X	if (nprocs == 0)
X		sim_tlist = free_tlist(sim_tlist);
X	else  {
X		sim_tlist->head = nxt_th;
X		sim_tlist->count = nprocs;
X		sim_tlist = sim_tlist->next;
X	}
X	return(nprocs);
X}
X
X
X#define  IMM1  (am1 == am_imm)
X#define  IMM2  (am2 == am_imm)
X#define  INTERACTIVE  TRUE
X#ifdef  NO_DISP
X#define  DRAW(a, b)
X#else  /* NO_DISP */
X#define  DRAW(a, b)  di_drawaddr(a, b)
X#endif  /* NO_DISP */
X
Xstatic int  instruction(thread_t *th, op_t op, amode_t am1, aval_t argval1,
X                        amode_t am2, aval_t argval2)  {
X	arg_t  arg;
X	aval_t  xeq_addr = th->addr, addr1, val1, addr2, val2;
X	int  id = sim_tlist->id;
X
X	arg = fetch_arg(am1, argval1, xeq_addr, id);
X	addr1 = arg.addr;  val1 = arg.val;
X	arg = fetch_arg(am2, argval2, xeq_addr, id);
X	addr2 = arg.addr;  val2 = arg.val;
X	switch(op)  {
X	case op_dat:
X		/* instruction op_dat US_NONE US_NONE */
X		DRAW(xeq_addr, DI_DEAD);
X		th->next->prev = th->prev;
X		th->prev->next = th->next;
X		th->next = sim_tlist->empty;
X		sim_tlist->empty = th;
X		return(-1);
X		/* instruction done */
X	case op_mov:
X		/* instruction op_mov US_VAL (US_ADDR|US_RANGE) */
X		if (INRANGE)  {
X			core[addr2].val2 = val1;
X			if (!IMM1 && !IMM2)  {
X				core[addr2].instr = core[addr1].instr;
X				core[addr2].val1 = core[addr1].val1;
X				if (INTERACTIVE)
X					core[addr2].index = core[addr1].index;
X			}
X			DRAW(addr2, DI_DAT + (id * DI_PLSIZ));
X		}
X		DRAW(xeq_addr, DI_RAN + (id * DI_PLSIZ));
X		if (++xeq_addr == coresize)
X			xeq_addr = 0;
X		DRAW(xeq_addr, DI_XEQ + (id * DI_PLSIZ));
X		th->addr = xeq_addr;
X		return(0);
X		/* instruction done */
X	case op_add:
X		/* instruction op_add US_VAL (US_VAL|US_RANGE) */
X		if (INRANGE)  {
X			if ((val2 += val1) >= coresize)
X				val2 -= coresize;
X			core[addr2].val2 = val2;
X			if (!IMM1 && !IMM2)  {
X				if ((core[addr2].val1 += core[addr1].val1) >= coresize)
X					core[addr2].val1 -= coresize;
X			}
X			DRAW(addr2, DI_DAT + (id * DI_PLSIZ));
X		}
X		DRAW(xeq_addr, DI_RAN + (id * DI_PLSIZ));
X		if (++xeq_addr == coresize)
X			xeq_addr = 0;
X		DRAW(xeq_addr, DI_XEQ + (id * DI_PLSIZ));
X		th->addr = xeq_addr;
X		return(0);
X		/* instruction done */
X		break;
X	case op_sub:
X		/* instruction op_sub US_VAL (US_VAL|US_RANGE) */
X		if (INRANGE)  {
X			if ((int)(val2 -= val1) < 0)
X				val2 += coresize;
X			core[addr2].val2 = val2;
X			if (!IMM1 && !IMM2)  {
X				if ((int)(core[addr2].val1 -= core[addr1].val1) < 0)
X					core[addr2].val1 += coresize;
X			}
X			DRAW(addr2, DI_DAT + (id * DI_PLSIZ));
X		}
X		DRAW(xeq_addr, DI_RAN + (id * DI_PLSIZ));
X		if (++xeq_addr == coresize)
X			xeq_addr = 0;
X		th->addr = xeq_addr;
X		DRAW(xeq_addr, DI_XEQ + (id * DI_PLSIZ));
X		return(0);
X		/* instruction done */
X		break;
X	case op_jmp:
X		/* instruction op_jmp US_ADDR US_NONE */
X		if (!IMM1)  {
X			if (INTERACTIVE && (xeq_addr != addr1))
X				DRAW(xeq_addr, DI_RAN + (id * DI_PLSIZ));
X			th->addr = addr1;
X		}
X		DRAW(addr1, DI_XEQ + (id * DI_PLSIZ));
X		return(0);
X		/* instruction done */
X		break;
X	case op_jmz:
X		/* instruction op_jmz US_ADDR US_VAL */
X		if (val2 == 0)  {
X			if (!IMM1)  {
X				if (INTERACTIVE && (addr1 != xeq_addr))
X					DRAW(xeq_addr, DI_RAN + (id * DI_PLSIZ));
X				th->addr = addr1;
X			}
X			DRAW(addr1, DI_XEQ + (id * DI_PLSIZ));
X		} else  {
X			DRAW(xeq_addr, DI_RAN + (id * DI_PLSIZ));
X			if (++xeq_addr >= coresize)
X				xeq_addr -= coresize;
X			th->addr = xeq_addr;
X			DRAW(xeq_addr, DI_XEQ + (id * DI_PLSIZ));
X		}
X		return(0);
X		/* instruction done */
X		break;
X	case op_jmn:
X		/* instruction op_jmn US_ADDR US_VAL */
X		if (val2 != 0)  {
X			if (!IMM1)  {
X				if (INTERACTIVE && (addr1 != xeq_addr))
X					DRAW(xeq_addr, DI_RAN + (id * DI_PLSIZ));
X				th->addr = addr1;
X			}
X			DRAW(addr1, DI_XEQ + (id * DI_PLSIZ));
X		} else  {
X			DRAW(xeq_addr, DI_RAN + (id * DI_PLSIZ));
X			if (++xeq_addr >= coresize)
X				xeq_addr -= coresize;
X			th->addr = xeq_addr;
X			DRAW(xeq_addr, DI_XEQ + (id * DI_PLSIZ));
X		}
X		return(0);
X		/* instruction done */
X		break;
X	case op_djn:
X		/* instruction op_djn US_ADDR (US_VAL|US_RANGE) */
X		if (val2 == 0)
X			val2 = coresize;
X		--val2;
X		if (INRANGE)  {
X			core[addr2].val2 = val2;
X			DRAW(addr2, DI_DAT + (id * DI_PLSIZ));
X		}
X		if (val2 != 0)  {
X			if (!IMM1)  {
X				if (INTERACTIVE && (addr1 != xeq_addr))
X					DRAW(xeq_addr, DI_RAN + (id * DI_PLSIZ));
X				th->addr = addr1;
X			}
X			DRAW(addr1, DI_XEQ + (id * DI_PLSIZ));
X		} else  {
X			DRAW(xeq_addr, DI_RAN + (id * DI_PLSIZ));
X			if (++xeq_addr >= coresize)
X				xeq_addr -= coresize;
X			th->addr = xeq_addr;
X			DRAW(xeq_addr, DI_XEQ + (id * DI_PLSIZ));
X		}
X		return(0);
X		/* instruction done */
X		break;
X	case op_cmp:
X		/* instruction op_cmp US_VAL US_VAL */
X		DRAW(xeq_addr, DI_RAN + (id * DI_PLSIZ));
X		++xeq_addr;
X		if (IMM1 || IMM2)  {
X			if (val1 == val2)
X				++xeq_addr;
X		} else  {
X			if ((val1 == val2) && (core[addr1].val1 == core[addr2].val1) &&
X					(core[addr1].instr == core[addr2].instr))
X				++xeq_addr;
X		}
X		if (xeq_addr >= coresize)
X			xeq_addr -= coresize;
X		DRAW(xeq_addr, DI_XEQ + (id * DI_PLSIZ));
X		th->addr = xeq_addr;
X		return(0);
X		/* instruction done */
X		break;
X	case op_spl:
X		/* instruction op_spl US_ADDR US_VAL */
X		if (INTERACTIVE)  {
X			if ((xeq_addr != addr1) || (sim_tlist->count >= maxthreads))
X				DRAW(xeq_addr, DI_RAN + (id * DI_PLSIZ));
X			if (sim_tlist->count < maxthreads)
X				DRAW(addr1, DI_RAN + (id * DI_PLSIZ));
X		}
X		if (++xeq_addr >= coresize)
X			xeq_addr -= coresize;
X		DRAW(xeq_addr, DI_XEQ + (id * DI_PLSIZ));
X		th->addr = xeq_addr;
X		if (split_id && (val2 != sim_tlist->ld_start))
X			return(0);
X		else
X			return(sim_create_thread(th, addr1));
X		/* instruction done */
X		break;
X	case op_slt:
X		/* instruction op_slt US_VAL US_VAL */
X		DRAW(xeq_addr, DI_RAN + (id * DI_PLSIZ));
X		++xeq_addr;
X		if (val1 < val2)
X			++xeq_addr;
X		if (xeq_addr >= coresize)
X			xeq_addr -= coresize;
X		DRAW(xeq_addr, DI_XEQ + (id * DI_PLSIZ));
X		th->addr = xeq_addr;
X		return(0);
X		/* instruction done */
X		break;
X	}
X}
X
X
Xint  sim_create_thread(thread_t  *th, aval_t addr)  {
X	thread_t  *oldn = th->next, *newth;
X
X	if (sim_tlist->count >= maxthreads)
X		return(0);
X	if (sim_tlist->empty == NULL)  {
X		tblock_t  *lblock = sim_tlist->tblock, *newblock;
X	
X		newblock = new_tblock();
X		sim_tlist->tblock = newblock;
X		newblock->next = lblock;
X		sim_tlist->empty = newblock->threads + 0;
X	}
X	newth = sim_tlist->empty;
X	sim_tlist->empty = newth->next;
X	th->next = newth;
X	newth->prev = th;
X	oldn->prev = newth;
X	newth->next = oldn;
X	newth->addr = addr;
X	return(1);
X}
X
X
X#define  USAGE  US_VAL
X#define  ADDR   result.addr
X#define  VAL    result.val
X#define  ARG    val
X#define  TMP1   tmp1
X#define  TMP2   tmp2
Xstatic arg_t  fetch_arg(amode_t am, aval_t val, aval_t xeq_addr, int cur_id)  {
X	aval_t  ival;
X	arg_t  result;
X	aval_t  tmp1, tmp2;
X
X	if ((ival = val + xeq_addr) >= coresize)
X		ival -= coresize;
X	switch(am)  {
X	case am_imm:
X		/* fetch am_imm notmp */
X		if (USAGE != US_NONE)  {
X			ADDR = xeq_addr;
X			if (USAGE & US_VAL)
X				VAL = ARG;
X		}
X#if (USAGE & US_RANGE)
X#undef  INRANGE
X#define  INRANGE  TRUE
X#endif
X		/* fetch done */
X		break;
X	case am_dir:
X		/* fetch am_dir notmp */
X		if (USAGE != US_NONE)  {
X			if ((ADDR = xeq_addr + ARG) >= coresize)
X				ADDR -= coresize;
X			if (USAGE & US_VAL)
X				VAL = core[ADDR].val2;
X		}
X#if (USAGE & US_RANGE)
X#undef  INRANGE
X#define  INRANGE  ((arg2 <= w_radius) || (arg2 >= coresize - w_radius))
X#endif
X		/* fetch done */
X		break;
X	case am_ind:
X		/* fetch am_ind */
X		if (USAGE != US_NONE)  {
X			if ((ADDR = xeq_addr + ARG) >= coresize)
X				ADDR -= coresize;
X			if ((ADDR += core[ADDR].val2) >= coresize)
X				ADDR -= coresize;
X			if (USAGE & US_VAL)
X				VAL = core[ADDR].val2;
X		}
X#if (USAGE & US_RANGE)
X#undef  INRANGE
X#define  INRANGE\
X    ((((unsigned)(addr2 - xeq_addr + w_radius) <= (unsigned)(2*w_radius))) ||\
X     ((unsigned)(addr2 - xeq_addr + (coresize - w_radius)) >=\
X      (unsigned)(2*(coresize-w_radius))))
X#endif
X		/* fetch done */
X		break;
X	case am_dec:
X		/* fetch am_dec tmp */
X		if ((TMP1 = xeq_addr + ARG) >= coresize)
X			TMP1 -= coresize;
X		if (USAGE == US_NONE)  {
X			if ((ARG <= w_radius) || (ARG >= coresize - w_radius))  {
X				if ((int)(TMP2 = core[TMP1].val2 - 1) < 0)
X					TMP2 += coresize;
X				core[TMP1].val2 = TMP2;
X			}
X		} else  {
X			if ((int)(TMP2 = core[TMP1].val2 - 1) < 0)
X				TMP2 += coresize;
X			if ((ARG <= w_radius) || (ARG >= coresize - w_radius))  {
X				core[TMP1].val2 = TMP2;
X				DRAW(TMP1, DI_DAT + (cur_id * DI_PLSIZ));
X			}
X			if ((ADDR = TMP1 + TMP2) >= coresize)
X				ADDR -= coresize;
X			if (USAGE & US_VAL)
X				VAL = core[ADDR].val2;
X		}
X#if (USAGE & US_RANGE)
X#undef  INRANGE
X#define  INRANGE\
X    ((((unsigned)(addr2 - xeq_addr + w_radius) <= (unsigned)(2*w_radius))) ||\
X     ((unsigned)(addr2 - xeq_addr + (coresize - w_radius)) >=\
X      (unsigned)(2*(coresize-w_radius))))
X#endif
X		/* fetch done */
X		break;
X	case am_inc:
X		/* fetch am_inc tmp */
X		if ((TMP1 = xeq_addr + ARG) >= coresize)
X			TMP1 -= coresize;
X		if (USAGE == US_NONE)  {
X			if ((ARG <= w_radius) || (ARG >= coresize - w_radius))  {
X				if ((TMP2 = core[TMP1].val2 + 1) == coresize)
X					TMP2 = 0;
X				core[TMP1].val2 = TMP2;
X			}
X		} else  {
X			ADDR = core[TMP1].val2;
X			if ((ARG <= w_radius) || (ARG >= coresize - w_radius))  {
X				if ((TMP2 = ADDR + 1) == coresize)
X					TMP2 = 0;
X				core[TMP1].val2 = TMP2;
X				DRAW(TMP1, DI_DAT + (cur_id * DI_PLSIZ));
X			}
X			if ((ADDR += TMP1) >= coresize)
X				ADDR -= coresize;
X			if (USAGE & US_VAL)
X				VAL = core[ADDR].val2;
X		}
X#if (USAGE & US_RANGE)
X#undef  INRANGE
X#define  INRANGE\
X    ((((unsigned)(addr2 - xeq_addr + w_radius) <= (unsigned)(2*w_radius))) ||\
X     ((unsigned)(addr2 - xeq_addr + (coresize - w_radius)) >=\
X      (unsigned)(2*(coresize-w_radius))))
X#endif
X		/* fetch done */
X		break;
X	}
X	return(result);
X}
X
X
Xint  proc_count(unsigned  id)  {
X	tlist_t  *tl = sim_tlist;
X
X	if (tl == NULL)
X		return(0);
X	while ((tl->id != id) && (tl->next != sim_tlist))
X		tl = tl->next;
X	if (tl->id != id)  {
X		sprintf(cwerrstr, "id %d is not in use.", id);
X		return(0);
X	}
X	return(tl->count);
X}
X
X
Xaval_t  proc_exec(unsigned  id)  {
X	tlist_t  *tl = sim_tlist;
X
X	while ((tl->id != id) && (tl->next != sim_tlist))
X		tl = tl->next;
X	if (tl->id != id)  {
X		sprintf(cwerrstr, "id %d is not in use.", id);
X		return(AVAL_NOGOOD);
X	}
X	return(tl->head->addr);
X}
END_OF_FILE
if test 15890 -ne `wc -c <'sim.c'`; then
    echo shar: \"'sim.c'\" unpacked with wrong size!
fi
# end of 'sim.c'
fi
if test -f 'clparse.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'clparse.c'\"
else
echo shar: Extracting \"'clparse.c'\" \(1706 characters\)
sed "s/^X//" >'clparse.c' <<'END_OF_FILE'
X/* clparse.c - Command Line Parse. */
X
X#include <stdio.h>
X#include <string.h>
X#include "clparse.h"
X
Xstatic void  strip(char *argv[]);
X
Xstatic char  *describe[] = {"#", "", "", "<...>"};
X
Xint  clp_parse(char *argv[], clp_info_t cltab[])  {
X	char  *progname = argv[0];
X	int  argc = 0;
X	clp_info_t  *clip;
X	unsigned  match;
X
X	while (*argv != NULL)  {
X		if (*argv[0] == '-')  {
X			match = 0;
X			for (clip = cltab;  (clip->word != NULL) && (argv[0] != NULL);
X					 ++clip)  {
X				if (!strcmp(argv[0], clip->word))  { /* A match! */
X					match = 1;
X					if (clip->dtype == clp_true)
X						*(unsigned *)clip->storage = 1;
X					else if (clip->dtype == clp_false)
X						*(unsigned *)clip->storage = 0;
X					else  {
X						if (argv[1] == NULL)  {
X							fprintf(stderr, "%s: No argument for \"%s\" switch.\n",
X											progname, clip->word);
X							return(CLP_NOGOOD);
X						}
X						if (clip->dtype == clp_int)
X							*(int *)clip->storage = atoi(argv[1]);
X						else
X							strcpy((char *)clip->storage, argv[1]);
X						strip(argv+1);
X					}
X				}
X			}
X			if (!match)  {
X				if (strcmp(*argv, "-help"))
X					fprintf(stderr, "%s: Unknown switch \"%s\".\n", progname, *argv);
X				fprintf(stderr, "Legal switches:\n");
X				for (clip = cltab;  clip->word != NULL;  ++clip)  {
X					if (clip->description != NULL)  {
X						char  wordntype[21];
X
X						sprintf(wordntype, "%s %s", clip->word, describe[clip->dtype]);
X						fprintf(stderr, "  %-20s %s\n", wordntype, clip->description);
X					}
X				}
X				return(CLP_NOGOOD);
X			} else  {
X				strip(argv);
X			}
X		} else  {
X			++argv;
X			++argc;
X		}
X	}
X	return(argc);
X}
X
X
Xstatic void  strip(char *argv[])  {
X	do  {
X		argv[0] = argv[1];
X		++argv;
X	} while (argv[0] != NULL);
X}
END_OF_FILE
if test 1706 -ne `wc -c <'clparse.c'`; then
    echo shar: \"'clparse.c'\" unpacked with wrong size!
fi
# end of 'clparse.c'
fi
if test -f 'asm_lex.flex' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'asm_lex.flex'\"
else
echo shar: Extracting \"'asm_lex.flex'\" \(3908 characters\)
sed "s/^X//" >'asm_lex.flex' <<'END_OF_FILE'
X%{
X#include <ctype.h>
X#include "corewar.h"
X#include "asm.h"
X#include "asm_parse.h"
X
X#ifdef  YACC
Xextern YYSTYPE  yylval;  /* With Bison, this line isn't necessary. */
X#endif  YACC
X
X/* Flex can be done case independant.  Lex isn't so nifty.  Grrr. */
X/* And while I'm at it, the whole way lex handles EOF really ticks me off. */
X#ifdef  LEX
X#undef  input
X#define  input()  (((yytchar=yysptr>yysbuf?U(*--yysptr):getc(yyin))==10?(yylineno++,yytchar):yytchar)==EOF?0:(isupper(yytchar)?tolower(yytchar):yytchar))
X
Xint  yyrestart()  {
X	return(1);
X}
X#endif  /* LEX */
X%}
X
XDIGIT	[0-9]
XID	[a-z_][a-z0-9_]*
X
X%%
X
X{DIGIT}+	{
X	int  i, sum, oldsum;
X
X	if (yyleng > STR_MAXLEN-2)  {
X		yytext[STR_MAXLEN-1] = '\0';
X		sprintf(cwerrstr, "String \"%s\" too long.  "
X		        "Maximum length is %d characters.", yytext, STR_MAXLEN - 2);
X		return(tt_nogood);
X	}
X	for (i = 0, sum = 0;  i < yyleng;  ++i)  {
X		oldsum = sum;
X		sum = (sum * 10) + yytext[i] - '0';
X		if (sum/10 != oldsum)  {
X			sprintf(cwerrstr, "Overflow on \"%s\".", yytext);
X			return(tt_nogood);
X		}
X	}
X	yylval.val = sum;
X	return(tt_id);
X	}
X
X
X^"id"	{
X	if (split_id)
X		return(tt_progid);
X	else
X		return(tt_label);
X}
X
X"id"	{
X	if (split_id)
X		return(tt_progid);
X	else {
X		yylval.val = AVAL_NOGOOD;
X		return(tt_id);
X	}
X}
X
X
Xdat	{ yylval.op = op_dat;  return(tt_op); }
X
Xmov	{ yylval.op = op_mov;  return(tt_op); }
X
Xadd	{ yylval.op = op_add;  return(tt_op); }
X
Xsub	{ yylval.op = op_sub;  return(tt_op); }
X
Xjmp	{ yylval.op = op_jmp;  return(tt_op); }
X
Xjmz	{ yylval.op = op_jmz;  return(tt_op); }
X
Xjmn	{ yylval.op = op_jmn;  return(tt_op); }
X
Xdjn	{ yylval.op = op_djn;  return(tt_op); }
X
Xcmp	{ yylval.op = op_cmp;  return(tt_op); }
X
Xspl	{ yylval.op = op_spl;  return(tt_op); }
X
Xslt	{ yylval.op = op_slt;  return(tt_op); }
X
Xequ	{ yylval.op = op_equ;  return(tt_op); }
X
Xend	{ yylval.op = op_end;  return(tt_op); }
X
X^{ID}":"?	{
X	if (yyleng > STR_MAXLEN-1)  {
X		yytext[STR_MAXLEN-1] = '\0';
X		sprintf(cwerrstr, "String \"%s\" too long.  "
X		        "Maximum length is %d characters.", yytext, STR_MAXLEN - 2);
X		return(tt_nogood);
X	}
X	return(tt_label);
X}
X
X{ID}	{
X	if (yyleng > STR_MAXLEN-2)  {
X		yytext[STR_MAXLEN-1] = '\0';
X		sprintf(cwerrstr, "String \"%s\" too long.  "
X		        "Maximum length is %d characters.", yytext, STR_MAXLEN - 2);
X		return(tt_nogood);
X	}
X	yylval.val = AVAL_NOGOOD;
X	return(tt_id); }
X
X"+"	return(tt_add);
X
X"-"	return(tt_sub);
X
X"*"	return(tt_mul);
X
X"/"	return(tt_div);
X
X"("	return(tt_oparen);
X
X")"	return(tt_cparen);
X
X"@"	{ yylval.am = am_ind;  return(tt_am); }
X
X"<"	{ yylval.am = am_dec;  return(tt_am); }
X
X"#"	{ yylval.am = am_imm;  return(tt_am); }
X
X">"	{
X	if (!postinc)  {
X		sprintf(cwerrstr, "Postincrement addressing is not enabled.\n");
X		return(tt_nogood);
X	}
X	yylval.am = am_inc;
X	return(tt_am); }
X
X","	return(tt_comma);
X
X^";name".*$	{
X	if (yyleng > STR_MAXLEN-2)  {
X		yytext[STR_MAXLEN-1] = '\0';
X		sprintf(cwerrstr, "String \"%s\" too long.  "
X		        "Maximum length is %d characters.", yytext, STR_MAXLEN - 2);
X		return(tt_nogood);
X	}
X	return(tt_name);
X	}
X
X^";author".*$	{
X	if (yyleng > STR_MAXLEN-1)  {
X		yytext[STR_MAXLEN-1] = '\0';
X		sprintf(cwerrstr, "String \"%s\" too long.  "
X		        "Maximum length is %d characters.", yytext, STR_MAXLEN - 2);
X		return(tt_nogood);
X	}
X	return(tt_author);
X	}
X
X^";address".*$	{
X	if (yyleng > STR_MAXLEN-2)  {
X		yytext[STR_MAXLEN-1] = '\0';
X		sprintf(cwerrstr, "String \"%s\" too long.  "
X		        "Maximum length is %d characters.", yytext, STR_MAXLEN - 2);
X		return(tt_nogood);
X	}
X	return(tt_address);
X	}
X
X";".*$	{ /* Comment.  Strip it out. */ }
X
X"\n"	{ ++asm_line_number; return(tt_eoln); }
X
X[ \t]+	{ /* Whitespace.  Do nothing. */ }
X
X":"	{
X	return(tt_nogood); }
X
X.	{
X	if (isprint(yytext[0]))
X		sprintf(cwerrstr, "Illegal character %d (\"%s\").",
X			yytext[0], yytext);
X	else
X		sprintf(cwerrstr, "Illegal character %d.", yytext[0]);
X	asm_error_loc(asm_line_number);
X	return(tt_nogood); }
END_OF_FILE
if test 3908 -ne `wc -c <'asm_lex.flex'`; then
    echo shar: \"'asm_lex.flex'\" unpacked with wrong size!
fi
# end of 'asm_lex.flex'
fi
if test -f 'asm_parse.y' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'asm_parse.y'\"
else
echo shar: Extracting \"'asm_parse.y'\" \(15056 characters\)
sed "s/^X//" >'asm_parse.y' <<'END_OF_FILE'
X%{
X#include <stdio.h>
X#include <string.h>
X#include "corewar.h"
X#include "asm.h"
X
X/*
X * I apologize for how bad this stuff is.  It's the first Bison/Yacc program
X *   I've ever written and the first Flex program I've ever written.
X */
X
Xstatic char  *errstr_end;
Xstatic stmt_t  *newprog;
Xunsigned  asm_line_number;
Xstatic char  name_str[STR_MAXLEN], author_str[STR_MAXLEN],
X             address_str[STR_MAXLEN], *prog_fname;
X
X#define  INT_BAD  (1 << ((sizeof(int)*8)-1))
X
Xstatic stmt_t  *stail(stmt_t *s), *newstmt(), *stcat(stmt_t *s1, stmt_t *s2);
Xstatic ptree_t  *newptree();
Xstatic aval_t  pass1(stmt_t *s), pass2(stmt_t *s, core_el_t *listing);
Xstatic aval_t  mk_aval(int ival);
Xstatic int  fetchaddr(ptree_t *pt, aval_t curaddr);
Xstatic int  strfetch(char *str, aval_t curaddr, unsigned line);
Xstatic void  clearstmt(stmt_t *s);
Xstatic void  clearpt(ptree_t *pt);
Xstatic void  yyerror(char *str);
X%}
X
X%token tt_op
X%token tt_label
X%token tt_id
X%token tt_progid
X%token tt_oparen
X%token tt_cparen
X%token tt_am
X%token tt_comma
X%token tt_name
X%token tt_author
X%token tt_address
X%token tt_eoln
X%token tt_nogood
X%token tt_add
X%token tt_sub
X%token tt_mul
X%token tt_div
X
X%%
Xprogram	:	program line tt_eoln	{
X		$$.stmt = (newprog = stcat($1.stmt, $2.stmt)); }
X	| error tt_eoln {
X		$$.stmt = newstmt();
X		/*
X		 * OK, this is a LAME error message, but it only happens when something
X		 *   goes wrong and none of the other, useful error messages cover it.
X		 */
X		strcat(cwerrstr, "Invalid assembly code.");
X		asm_error_loc(asm_line_number);
X		YYABORT; }
X	|	{ $$.stmt = newstmt(); }
X;
X
Xline	: oplab			{ $$.stmt = $1.stmt; }
X	| oplab tt_op arg tt_comma arg {
X		stmt_t  *temp = $1.stmt;
X		$$.stmt = $1.stmt;
X		temp->op = $2.op;
X		temp->a = $3.argtop;
X		temp->b = $5.argtop; }
X	| oplab tt_op arg {
X		stmt_t  *temp = $1.stmt;
X		$$.stmt = $1.stmt;
X		temp->op = $2.op;
X		temp->a = $3.argtop; }
X	| oplab tt_op {
X		stmt_t  *temp = $1.stmt;
X		$$.stmt = $1.stmt;
X		temp->op = $2.op; }
X	| tt_author {
X		$$.stmt = newstmt();
X		strncpy(author_str, yytext, STR_MAXLEN - 1); }
X	| tt_address {
X		$$.stmt = newstmt();
X		strncpy(address_str, yytext, STR_MAXLEN - 1); }
X	| tt_name {
X		$$.stmt = newstmt();
X		strncpy(name_str, yytext, STR_MAXLEN - 1); }
X	| tt_id {
X		sprintf(cwerrstr, "Id \"%s\" must be preceded by an operator.", yytext);
X		asm_error_loc(asm_line_number);
X		YYABORT; }
X	| oplab tt_op arg bad_newarg {
X		sprintf(cwerrstr, "A \",\" is needed between arguments.");
X		asm_error_loc(asm_line_number);
X		YYABORT; }
X;
X
Xbad_newarg : tt_am | tt_id ;
X
Xoplab	: tt_label	{
X		char  *tcp;
X
X		$$.stmt = newstmt();
X		strcat(tcp = ($$.stmt)->str, yytext);
X		while ((*tcp != ':') && (*tcp != '\0'))
X			++tcp;
X		*tcp = '\0';  /* Strip off the colon. */ }
X	|		{
X		$$.stmt = newstmt(); }
X;
X
Xarg	: tt_am expr	{
X		$$.argtop = (argtop_t *)tmalloc(sizeof(argtop_t));
X		($$.argtop)->mode = $1.am;
X		($$.argtop)->pt = $2.ptree; }
X	| expr	{
X		$$.argtop = (argtop_t *)tmalloc(sizeof(argtop_t));
X		($$.argtop)->mode = am_dir;
X		($$.argtop)->pt = $1.ptree; }
X  | tt_nogood  {
X		asm_error_loc(asm_line_number);
X		YYABORT; }
X;
X
Xexpr	: factor	{ $$.ptree = $1.ptree; }
X	| noid_expr tt_add factor	{
X		$$.ptree = newptree();
X		($$.ptree)->parsetype = pt_add;
X		($$.ptree)->left = $1.ptree;
X		($$.ptree)->right = $3.ptree; }
X	| noid_expr tt_sub factor  {
X		$$.ptree = newptree();
X		($$.ptree)->parsetype = pt_sub;
X		($$.ptree)->left = $1.ptree;
X		($$.ptree)->right = $3.ptree; }
X  | tt_progid {
X		$$.ptree = newptree();
X		($$.ptree)->parsetype = pt_end;
X		($$.ptree)->val = AVAL_PROGID;
X	}
X;
X
Xnoid_expr	: factor	{ $$.ptree = $1.ptree; }
X	| noid_expr tt_add factor	{
X		$$.ptree = newptree();
X		($$.ptree)->parsetype = pt_add;
X		($$.ptree)->left = $1.ptree;
X		($$.ptree)->right = $3.ptree; }
X	| noid_expr tt_sub factor  {
X		$$.ptree = newptree();
X		($$.ptree)->parsetype = pt_sub;
X		($$.ptree)->left = $1.ptree;
X		($$.ptree)->right = $3.ptree; }
X  | tt_progid {
X		sprintf(cwerrstr, "The \"id\" value cannot be used in expressions.\n");
X		asm_error_loc(asm_line_number);
X		YYABORT;	}
X;
X
Xfactor	: unit	{ $$.ptree = $1.ptree; }
X	| factor tt_mul unit	{
X		$$.ptree = newptree();
X		($$.ptree)->parsetype = pt_mul;
X		($$.ptree)->left = $1.ptree;
X		($$.ptree)->right = $3.ptree; }
X	| factor tt_div unit	{
X		$$.ptree = newptree();
X		($$.ptree)->parsetype = pt_div;
X		($$.ptree)->left = $1.ptree;
X		($$.ptree)->right = $3.ptree; }
X;
X
Xunit	: tt_id	{
X		$$.ptree = newptree();
X		($$.ptree)->parsetype = pt_end;
X		($$.ptree)->val = $1.val;
X		strcpy(($$.ptree)->str, yytext); }
X	| tt_sub tt_id {
X		$$.ptree = newptree();
X		($$.ptree)->parsetype = pt_uminus;
X		($$.ptree)->left = newptree();
X		($$.ptree)->left->parsetype = pt_end;
X		($$.ptree)->left->val = $2.val;
X		strcpy(($$.ptree)->left->str, yytext); }
X	| tt_oparen noid_expr tt_cparen	{ $$.ptree = $2.ptree; }
X;
X
X%%
X
Xunsigned  assemble(program_t *prog, char *fname)  {
X	stmt_t  *s;
X	aval_t  plen;
X	unsigned  i;
X	FILE  *infile;
X	static int  firstparse = TRUE;
X
X#if  YYDEBUG
X	yydebug = 1;
X#endif
X	cwerrstr[0] = '\0';
X	prog_fname = fname;
X	newprog = NULL;
X	strcpy(name_str, "x Unknown");
X	strcpy(address_str, "x Unknown");
X	strcpy(author_str, "x Unknown");
X	strcpy(prog->pname, "Unknown");
X	strcpy(prog->fname, fname);
X	asm_line_number = 1;
X	errstr_end = NULL;
X	infile = fopen(fname, "r");
X	if (infile == NULL)  {
X		sprintf(cwerrstr, "Cannot open file \"%s\".", fname);
X		return(FALSE);
X	}
X	if (firstparse)  {
X		firstparse = FALSE;
X		yyin = infile;
X	} else
X		yyrestart(infile);
X	if (yyparse())  {
X		fclose(infile);
X		clearstmt(newprog);
X		if (errstr_end != NULL)
X			*errstr_end = '\0';
X		return(FALSE);
X	}
X	fclose(infile);
X
X	sscanf(address_str, "%*s%s", prog->retaddr);
X
X	for (i = 0;  !isspace(author_str[i]) && author_str[i];  ++i);
X	while (isspace(author_str[i]) && author_str[i])
X		++i;
X	strcpy(prog->author, author_str + i);
X
X	for (i = 0;  !isspace(name_str[i]) && name_str[i];  ++i);
X	while (isspace(name_str[i]) && name_str[i])
X		++i;
X	strcpy(prog->pname, name_str + i);
X
X	s = newprog;
X	if ((plen = pass1(s)) == AVAL_NOGOOD)  {
X		clearstmt(newprog);
X		if (errstr_end != NULL)
X			*errstr_end = '\0';
X		return(FALSE);
X	}
X	if (plen > maxprogsize)  {
X		clearstmt(newprog);
X		sprintf(cwerrstr, "Program is %d words long.  "
X						"This exceeds the maximum allowed of %d words.",
X						plen, maxprogsize);
X		return(FALSE);
X	}
X	prog->proglen = plen;
X	prog->listing = (core_el_t *)tmalloc(plen * sizeof(core_el_t));
X	if ((prog->startaddr = pass2(s, prog->listing)) == AVAL_NOGOOD)  {
X		clearstmt(newprog);
X		if (errstr_end != NULL)
X			*errstr_end = '\0';
X		return(FALSE);
X	}
X	clearstmt(newprog);
X	return(TRUE);
X}
X
X
Xstatic aval_t  pass1(stmt_t *s)  {
X	aval_t  cur_addr = 0;
X
X	while (s != NULL)  {
X		s->addr = cur_addr;
X		if (op_realop(s->op))
X			++cur_addr;
X		s = s->next;
X	}
X	return(cur_addr);
X}
X
X
Xstatic aval_t  pass2(stmt_t *s, core_el_t *listing)  {
X	aval_t  start = AVAL_NOGOOD, cur_addr = 0;
X#define  ARG_OPTIONAL  0x8000
X	static unsigned  invalid_modes[][2] = {
X		{ARG_OPTIONAL|(1<<am_dir)|(1<<am_ind), (1<<am_dir)|(1<<am_ind)}, /* dat */
X		{0, 1<<am_imm}, /* mov */
X		{0, 1<<am_imm}, /* add */
X		{0, 1<<am_imm}, /* sub */
X		{1<<am_imm, ARG_OPTIONAL}, /* jmp */
X		{1<<am_imm, 0}, /* jmz */
X		{1<<am_imm, 0}, /* jmn */
X		{1<<am_imm, 0}, /* djn */
X		{0, 1<<am_imm}, /* cmp */
X		{1<<am_imm, ARG_OPTIONAL}, /* spl */
X		{0, 1<<am_imm}};  /* slt */
X
X	while (s != NULL)  {
X		switch(s->op)  {
X		case op_equ:
X			if (!s->str[0])  {
X				sprintf(cwerrstr, "An \"EQU\" pseudo-op must have a label.");
X				asm_error_loc(s->line);
X				return(AVAL_NOGOOD);
X			}
X			if (s->b != NULL)  {
X				sprintf(cwerrstr, "An \"EQU\" pseudo-op can only have one argument.");
X				asm_error_loc(s->line);
X				return(AVAL_NOGOOD);
X			}
X			if (s->a == NULL)  {
X				sprintf(cwerrstr, "An \"EQU\" pseudo-op must have an argument.");
X				asm_error_loc(s->line);
X				return(AVAL_NOGOOD);
X			}
X			if (s->a->mode != am_dir)  {
X				sprintf(cwerrstr, "The argument of an \"EQU\" pseudo-op must be "
X								"direct mode.");
X				asm_error_loc(s->line);
X				return(AVAL_NOGOOD);
X			}
X			break;
X		case op_end:
X			if (s->b != NULL)  {
X				sprintf(cwerrstr, "An \"END\" pseudo-op can only have one argument.");
X				asm_error_loc(s->line);
X				return(AVAL_NOGOOD);
X			}
X			if (s->a == NULL)
X				start = 0;
X			else  {
X				if (s->a->mode != am_dir)  {
X					sprintf(cwerrstr, "The argument of an \"END\" pseudo-op must be "
X									"direct mode.");
X					asm_error_loc(s->line);
X					return(AVAL_NOGOOD);
X				}
X				start = mk_aval(fetchaddr(s->a->pt, 0));
X				if (start == AVAL_NOGOOD)
X					return(AVAL_NOGOOD);
X			}
X			break;
X		case op_nogood:
X			break;
X		default:
X			if (start != AVAL_NOGOOD)  {
X				sprintf(cwerrstr, "Program continued after \"END\" pseudo-op.");
X				asm_error_loc(s->line);
X				return(AVAL_NOGOOD);
X			}
X			if (s->a == NULL)  {
X				if ((invalid_modes[s->op][0] & ARG_OPTIONAL) ||
X						(invalid_modes[s->op][1] & ARG_OPTIONAL))
X					sprintf(cwerrstr, "The \"%s\" operator needs at least one argument.",
X									opnames[s->op]);
X				else
X					sprintf(cwerrstr, "The \"%s\" operator needs two arguments.",
X									opnames[s->op]);
X				asm_error_loc(s->line);
X				return(AVAL_NOGOOD);
X			}
X			if ((s->b == NULL) && (invalid_modes[s->op][0] & ARG_OPTIONAL))  {
X				s->b = s->a;
X				s->a = NULL;
X			}
X			if (s->a == NULL)  {
X				s->a = (argtop_t *)tmalloc(sizeof(argtop_t));
X				s->a->mode = am_imm;
X				s->a->pt = NULL;
X				listing[cur_addr].val1 = 0;
X			} else  {
X				if (amode_restrict && (invalid_modes[s->op][0] & (1 << s->a->mode)))  {
X					sprintf(cwerrstr, "Operator \"%s\" cannot use %s addressing "
X									"with argument A.", opnames[s->op], amodenames[s->a->mode]);
X					asm_error_loc(s->line);
X					return(AVAL_NOGOOD);
X				}
X				if ((listing[cur_addr].val1 = mk_aval(fetchaddr(s->a->pt, cur_addr)))
X						== AVAL_NOGOOD)
X					return(AVAL_NOGOOD);
X			}
X			if (s->b == NULL)  {
X				if (!(invalid_modes[s->op][1] & ARG_OPTIONAL))  {
X					sprintf(cwerrstr, "The \"%s\" operator needs two arguments.",
X									opnames[s->op]);
X					asm_error_loc(s->line);
X					return(AVAL_NOGOOD);
X				}
X				s->b = (argtop_t *)tmalloc(sizeof(argtop_t));
X				s->b->mode = am_imm;
X				s->b->pt = NULL;
X				listing[cur_addr].val2 = 0;
X			} else  {
X				if (amode_restrict && (invalid_modes[s->op][1] & (1 << s->b->mode)))  {
X					sprintf(cwerrstr, "Operator \"%s\" cannot use %s addressing "
X									"with argument B.", opnames[s->op], amodenames[s->b->mode]);
X					asm_error_loc(s->line);
X					return(AVAL_NOGOOD);
X				}
X				if ((listing[cur_addr].val2 = mk_aval(fetchaddr(s->b->pt, cur_addr)))
X						== AVAL_NOGOOD)
X					return(AVAL_NOGOOD);
X			}
X			listing[cur_addr].index = JTINDEX(s->op, s->a->mode, s->b->mode);
X			listing[cur_addr].instr = jmptable[listing[cur_addr].index];
X			++cur_addr;
X			break;
X		}
X		s = s->next;
X	}
X	if (start == AVAL_NOGOOD)
X		return(0);
X	return(start);
X}
X
X
Xstatic void  yyerror(char *str)  {
X	if (!cwerrstr[0])  {
X		if (str[0] == '\n')  {
X			sprintf(cwerrstr, "Error near end of line: %s.", str);
X			asm_error_loc(asm_line_number - 1);
X		} else  {
X			sprintf(cwerrstr, "Error near string \"%s\": %s.",
X							yytext, str);
X			asm_error_loc(asm_line_number);
X		}
X	}
X}
X
X
Xvoid  asm_error_loc(unsigned line)  {
X	char  tempbuf[200];
X	FILE  *f;
X	int  c, cline = 1;
X	char  *cindex;
X
X	if (errstr_end != NULL)
X		return;
X	sprintf(tempbuf, "\nError around line %d:\n", line);
X	strcat(cwerrstr, tempbuf);
X	for (cindex = cwerrstr;  *cindex;  ++cindex);
X	f = fopen(prog_fname, "r");
X	while (cline < line)  {
X		c = getc(f);
X		if (c == '\n')
X			++cline;
X		if (c == EOF)
X			break;
X	}
X	c = getc(f);
X	while ((cindex < cwerrstr+sizeof(cwerrstr)-1) &&
X				 (c != '\n') && (c != EOF) && (isprint(c) || isspace(c)))  {
X		*(cindex++) = c;
X		c = getc(f);
X	}
X	fclose(f);
X	*cindex = '\0';
X	errstr_end = cindex;
X}
X
X
Xstatic stmt_t  *stail(stmt_t *s)  {
X	if (s->next == NULL)
X		return(s);
X	return(stail(s->next));
X}
X
X
Xstatic stmt_t  *newstmt()  {
X	stmt_t  *ns = (stmt_t *)tmalloc(sizeof(stmt_t));
X
X	ns->line = asm_line_number;
X	ns->op = op_nogood;
X	ns->a = ns->b = NULL;
X	ns->marked = FALSE;
X	ns->next = NULL;
X	ns->str[0] = '\0';
X	return(ns);
X}
X
Xstatic stmt_t  *stcat(stmt_t *s1, stmt_t *s2)  {
X	stail(s1)->next = s2;
X	return(s1);
X}
X
X
Xstatic ptree_t  *newptree()  {
X	ptree_t  *npt;
X
X	npt = (ptree_t *)tmalloc(sizeof(ptree_t));
X	npt->line = asm_line_number;
X	npt->str[0] = '\0';
X	npt->left = npt->right = NULL;
X	return(npt);
X}
X
X
Xstatic int  fetchaddr(ptree_t *pt, aval_t curaddr)  {
X	int  l, r, c;
X
X	if (pt->left != NULL)  {
X		l = fetchaddr(pt->left, curaddr);
X		if (l == INT_BAD)
X			return(INT_BAD);
X	}
X	if (pt->right != NULL)  {
X		r = fetchaddr(pt->right, curaddr);
X		if (r == INT_BAD)
X			return(INT_BAD);
X	}
X	switch(pt->parsetype)  {
X	case pt_uminus:
X		return(-l);
X		break;
X	case pt_add:
X		c = l + r;
X		if (((l < 0) && (r < 0) && (c > 0)) ||
X				((l > 0) && (r > 0) && (c < 0)) ||
X				(c == INT_BAD))  {
X			sprintf(cwerrstr, "Additive overflow.\n");
X			asm_error_loc(pt->line);
X			return(INT_BAD);
X		}
X		return(c);
X		break;
X	case pt_sub:
X		c = l - r;
X		if (((l < 0) && (r > 0) && (c > 0)) ||
X				((l > 0) && (r < 0) && (c < 0)) ||
X				(c == INT_BAD))  {
X			sprintf(cwerrstr, "Subtractive overflow.\n");
X			asm_error_loc(pt->line);
X			return(INT_BAD);
X		}
X		return(c);
X		break;
X	case pt_mul:
X		c = l * r;
X		if (((r != 0) && (c / r != l)) || (c == INT_BAD))  {
X			sprintf(cwerrstr, "Multiplicative overflow.\n");
X			asm_error_loc(pt->line);
X			return(INT_BAD);
X		}
X		return(c);
X		break;
X	case pt_div:
X		if (r == 0)  {
X			sprintf(cwerrstr, "Division by zero.");
X			asm_error_loc(pt->line);
X			return(AVAL_NOGOOD);
X		}
X		return(mk_aval(l / r));
X		break;
X	case pt_end:
X		if (pt->val != AVAL_NOGOOD)
X			return(pt->val);
X		return(strfetch(pt->str, curaddr, pt->line));
X		break;
X	}
X}
X
X
Xstatic int  strfetch(char *str, aval_t curaddr, unsigned line)  {
X	stmt_t  *s = newprog;
X	int  result;
X
X	while (s != NULL)  {
X		if (!strcmp(str, s->str))  {
X			if (s->op != op_equ)
X				return(s->addr - curaddr);
X			else  {
X				if (s->marked)  {
X					sprintf(cwerrstr, "Recursive \"EQU\" definition of label \"%s\".",
X									str);
X					asm_error_loc(s->line);
X					return(INT_BAD);
X				}
X				s->marked = TRUE;
X				result = fetchaddr(s->a->pt, curaddr);
X				s->marked = FALSE;
X				return(result);
X			}
X		}
X		s = s->next;
X	}
X	sprintf(cwerrstr, "Unknown label \"%s\".", str);
X	asm_error_loc(line);
X	return(INT_BAD);
X}
X
X
Xstatic void  clearstmt(stmt_t *s)  {
X	if (s != NULL)  {
X		clearstmt(s->next);
X		if (s->a != NULL)  {
X			clearpt(s->a->pt);
X			free(s->a);
X		}
X		if (s->b != NULL)  {
X			clearpt(s->b->pt);
X			free(s->b);
X		}
X		free(s);
X	}
X}
X
X
Xstatic void  clearpt(ptree_t *pt)  {
X	if (pt != NULL)  {
X		clearpt(pt->left);
X		clearpt(pt->right);
X		free(pt);
X	}
X}
X
X
X/* I'm always kinda hazy on how strict C compilers are about modulus of
X *   negative numbers so I do things extra careful here.
X */
Xstatic aval_t  mk_aval(int ival)  {
X	if (ival == INT_BAD)
X		return(AVAL_NOGOOD);
X	if (ival < 0)  {
X		ival = -ival % coresize;
X		if (ival == 0)
X			return(0);
X		else
X			return(coresize - ival);
X	} else
X		return(ival % coresize);
X}
X
END_OF_FILE
if test 15056 -ne `wc -c <'asm_parse.y'`; then
    echo shar: \"'asm_parse.y'\" unpacked with wrong size!
fi
# end of 'asm_parse.y'
fi
if test -f 'clparse.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'clparse.h'\"
else
echo shar: Extracting \"'clparse.h'\" \(471 characters\)
sed "s/^X//" >'clparse.h' <<'END_OF_FILE'
X/* clparse.h - Command Line Parse */
X
X#ifndef  _CLPARSE_
X#define  _CLPARSE_
X
X#ifndef  CLP_MAXSTRLEN
X#define  CLP_MAXSTRLEN  80
X#endif
X
Xtypedef enum  {
X	clp_int, clp_true, clp_false, clp_string}
Xclp_dtype_t;
X
Xtypedef struct clp_info_struct  {
X	char  *word;
X	clp_dtype_t  dtype;
X	void  *storage;
X	char  *description;
X} clp_info_t;
X
X#define  CLP_END  {NULL, 0, NULL, NULL}
X
Xextern int  clp_parse(char *argv[], clp_info_t cltab[]);
X#define  CLP_NOGOOD  -1
X
X#endif  _CLPARSE_
END_OF_FILE
if test 471 -ne `wc -c <'clparse.h'`; then
    echo shar: \"'clparse.h'\" unpacked with wrong size!
fi
# end of 'clparse.h'
fi
if test -f 'ldaddr.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'ldaddr.c'\"
else
echo shar: Extracting \"'ldaddr.c'\" \(1512 characters\)
sed "s/^X//" >'ldaddr.c' <<'END_OF_FILE'
X/* ldaddr.c */
X
X#include <stdio.h>
X#include "corewar.h"
X
Xstatic unsigned  ldlen = -1;
Xstatic aval_t  *plist;
X
Xstatic unsigned  ld_conflict(aval_t addr1, aval_t addr2);
X
X
Xvoid  ld_init(unsigned maxloads)  {
X	unsigned  i;
X
X	if (ldlen != maxloads)  {
X		if (ldlen != -1)
X			free(plist);
X		plist = (aval_t *)tmalloc(maxloads * sizeof(aval_t));
X	}
X	ldlen = maxloads;
X	for (i = 0;  i < maxloads;  ++i)
X		plist[i] = AVAL_NOGOOD;
X}
X
X	
Xaval_t  ld_addr(unsigned ldnum)  {
X	aval_t  newaddr;
X	unsigned  i, good_load;
X	unsigned  andmask;
X
X	if (plist[ldnum] != AVAL_NOGOOD)
X		return(plist[ldnum]);
X	for (andmask = 0;  (andmask & (coresize-1)) != (coresize-1);
X	     andmask = ((andmask << 1) | 1));
X	do  {
X		good_load = TRUE;
X		do  {  /* Get a perfectly even distribution of load addresses. */
X			newaddr = ((unsigned)random() & andmask);
X		} while (newaddr >= coresize);
X		for (i = 0;  i < ldlen;  ++i)
X			if (ld_conflict(newaddr, plist[i]))
X				good_load = FALSE;
X	} while (!good_load);
X	plist[ldnum] = newaddr;
X	return(newaddr);
X}
X
X
Xstatic unsigned  ld_conflict(aval_t addr1, aval_t addr2)  {
X	aval_t  temp;
X
X	if ((addr1 == AVAL_NOGOOD) || (addr2 == AVAL_NOGOOD))
X		return(FALSE);
X	if (addr1 > addr2)  {
X		temp = addr1;
X		addr1 = addr2;
X		addr2 = temp;
X	}
X	if (addr1 + maxprogsize > addr2)
X		return(TRUE);
X	if (addr1 + coresize < addr2 + maxprogsize)
X		return(TRUE);
X	return(FALSE);
X}
X
X
Xaval_t  ld_undo(unsigned ldnum)  {
X	aval_t  old_ldaddr;
X
X	old_ldaddr = plist[ldnum];
X	plist[ldnum] = AVAL_NOGOOD;
X	return(old_ldaddr);
X}
END_OF_FILE
if test 1512 -ne `wc -c <'ldaddr.c'`; then
    echo shar: \"'ldaddr.c'\" unpacked with wrong size!
fi
# end of 'ldaddr.c'
fi
if test -f 'di_recalc.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'di_recalc.c'\"
else
echo shar: Extracting \"'di_recalc.c'\" \(21360 characters\)
sed "s/^X//" >'di_recalc.c' <<'END_OF_FILE'
X/*
X * di_redraw.c
X */
X
X#ifdef  X11_DISP
X
X#include <stdio.h>
X#include <X11/Xlib.h>
X#include <X11/Xutil.h>
X#include "corewar.h"
X#include "cwdisp.h"
X
X
Xgbut_info  di_but[DI_NBUT] = {
X	{0,0,0,0,0, GBUT_DRAWABLE, ":0: :\n:",
X		 di_draw_ctbut, gbut_true, (void *)"Step"},      /* DI_BSTOP */
X	{0,0,0,0,0, GBUT_DRAWABLE, ":1:2:3:4:5:6:7:8:",
X		 di_draw_sfbut, gbut_true, (void *)&di_slopos},  /* DI_BSLOW */
X	{0,0,0,0,0, GBUT_DRAWABLE, ":9:",
X		 di_draw_ctbut, gbut_true, (void *)"Go"},        /* DI_BGO   */
X	{0,0,0,0,0, GBUT_DRAWABLE|GBUT_PRESSABLE, ":q:Q:",
X		 di_draw_ctbut, gbut_true, (void *)"Quit"},      /* DI_BQUIT */
X	{0,0,0,0,0, GBUT_DRAWABLE, ":",
X		 di_draw_ctbut, gbut_true, (void *)"Reset"},     /* DI_BRESTART */
X	{0,0,0,0,0, 0, ":\n:",
X		 di_draw_ctbut, gbut_true, (void *)"OK"},        /* DI_BWIN2OK */
X	{0,0,0,0,0, GBUT_DRAWABLE|GBUT_PRESSABLE|GBUT_TWITCHABLE, ":",
X		 di_dis_cpdraw, di_dis_cpcheck, NULL},           /* DI_BCOREPIC */
X
X	{0,0,0,0,0, GBUT_DRAWABLE|GBUT_PRESSABLE, ":",
X		 di_draw_ctbut, gbut_true, (void *)"Load"},
X	{0,0,0,0,0, GBUT_DRAWABLE|GBUT_PRESSABLE, ":",
X		 di_draw_ctbut, gbut_true, (void *)"Load"},
X	{0,0,0,0,0, GBUT_DRAWABLE|GBUT_PRESSABLE, ":",
X		 di_draw_ctbut, gbut_true, (void *)"Load"},
X	{0,0,0,0,0, GBUT_DRAWABLE|GBUT_PRESSABLE, ":",
X		 di_draw_ctbut, gbut_true, (void *)"Load"},
X	{0,0,0,0,0, GBUT_DRAWABLE|GBUT_PRESSABLE, ":",
X		 di_draw_ctbut, gbut_true, (void *)"Load"},
X	{0,0,0,0,0, GBUT_DRAWABLE|GBUT_PRESSABLE, ":",
X		 di_draw_ctbut, gbut_true, (void *)"Load"}};
X	
Xstatic char  *backup_sfonts[] = {
X	"-adobe-times-medium-r-normal--8-*",
X	"-adobe-times-medium-r-normal--8-*",
X	"-adobe-times-medium-r-normal--8-*",
X	"-adobe-times-medium-r-normal--10-*",
X	"-adobe-times-medium-r-normal--12-*",
X	"-adobe-times-medium-r-normal--14-*",
X	"-adobe-times-medium-r-normal--20-*",
X	"-adobe-times-medium-r-normal--20-*",
X	"-adobe-times-medium-r-normal--25-*"};
Xstatic char  *backup_ffonts[] = {
X	"-adobe-courier-medium-r-normal--8-*",
X	"-adobe-courier-medium-r-normal--8-*",
X	"-adobe-courier-medium-r-normal--8-*",
X	"-adobe-courier-medium-r-normal--10-*",
X	"-adobe-courier-medium-r-normal--12-*",
X	"-adobe-courier-medium-r-normal--14-*",
X	"-adobe-courier-medium-r-normal--20-*",
X	"-adobe-courier-medium-r-normal--20-*",
X	"-adobe-courier-medium-r-normal--25-*"};
Xstatic char  *backup_bfonts[] = {
X	"-adobe-times-medium-r-normal--8-*",
X	"-adobe-times-medium-r-normal--8-*",
X	"-adobe-times-medium-r-normal--14-*",
X	"-adobe-times-medium-r-normal--20-*",
X	"-adobe-times-medium-r-normal--25-*",
X	"-adobe-times-medium-r-normal--34-*"};
X
X
X
Xstatic int  recalc_ov(Display *dpy, Window win, XWindowAttributes *xwa);
Xstatic void  recalc_co(Display *dpy, Window win, int remap);
Xstatic void  recalc_pls(Display *dpy, Window win, int remap);
Xstatic void  recalc_ti(Display *dpy, Window win, int remap);
Xstatic void  recalc_cy(Display *dpy, Window win, int remap);
Xstatic void  draw_bitmap(int oc, int ic, unsigned picsize, char *pics);
Xstatic void  recalc_but(Display *dpy, Window win, int remap);
X
Xunsigned long  di_colors[4+DI_MAXPLAYERS*2];
Xstatic int  cyth, butth, titth, emptyslot;
XPixmap  di_grey50pixmap, di_grey75pixmap;
X
Xvoid  di_redraw(Display *dpy, Window win, XWindowAttributes *xwa,
X								int x, int y, int w, int h)  {
X	int  size_change = FALSE;
X
X	if ((xwa->width < 150) || (xwa->height < 125))
X		return;
X	if ((di_winw != xwa->width) || (di_winh != xwa->height))  {
X		/* Recalculate values. */
X		int  remap;
X
X		size_change = TRUE;
X		remap = recalc_ov(dpy, win, xwa);
X		recalc_co(dpy, win, remap);
X		recalc_pls(dpy, win, remap);
X		recalc_ti(dpy, win, remap);
X		recalc_cy(dpy, win, remap);
X		recalc_but(dpy, win, remap);
X		if (remap)  {
X			/* Redraw all the debugging windows. */
X			win3  *w3p;
X			int   winnum;
X			XWindowAttributes  xwa;
X
X			for (winnum = 0, w3p = di_win3list.next;
X					 winnum < di_numwin3;
X					 ++winnum, w3p = w3p->next)  {
X				XGetWindowAttributes(dpy, w3p->win, &xwa);
X				di_redraw3(dpy, w3p->win, xwa.x,xwa.y, xwa.width,xwa.height);
X			}
X		}
X	}
X	di_draw_ov(dpy, win, x, y, w, h);
X	di_draw_co(dpy, win, x, y, w, h);
X	di_draw_pls(dpy, win, -1);
X	di_draw_cy(dpy, win);
X	gbut_redraw(win, 0, 0, 1<<30,1<<30);
X	if (size_change && (di_win2w != 0))  {
X		di_killwin2(TRUE);
X		di_mkwin2("Corewar");
X	}
X	XFlush(dpy);
X}
X
X
Xstatic int  recalc_ov(Display *dpy, Window win, XWindowAttributes *xwa)  {
X	int  oldps = di_picsize, remap;
X
X	if (di_color)  {
X		static float  cmult[] = {0.0, 0.0, 0.0,
X															 0.75, 0.75, 0.75,
X															 1.0, 1.0, 1.0,
X															 0.5, 0.5, 0.5,
X															 1.0, 0.64286, 0.64286,
X															 1.0, 0.28571, 0.28571,
X															 0.39024, 1.0, 0.39024,
X															 0.0, 0.84746, 0.0,
X															 0.71910, 0.71910, 1.0,
X															 0.43820, 0.43820, 1.0,
X															 0.16667, 1.0, 1.0,
X															 0.0, 0.71429, 0.71429,
X															 1.0, 0.57627, 1.0,
X															 1.0, 0.15254, 1.0,
X															 0.84270, 0.84270, 0,
X															 0.56180, 0.56180, 0};
X		XColor  clr;
X		int  i;
X
X		for (i = 0;  i < 4 + DI_MAXPLAYERS*2;  ++i)  {
X			clr.red   = MAX_CVAL * cmult[i*3 + 0];
X			clr.green = MAX_CVAL * cmult[i*3 + 1];
X			clr.blue  = MAX_CVAL * cmult[i*3 + 2];
X			clr.flags = DoRed | DoGreen | DoBlue;
X			XAllocColor(dpy, di_cmap, &clr);
X			di_colors[i] = clr.pixel;
X		}
X	}
X	di_width  = di_winw = xwa->width;
X	di_height = di_winh = xwa->height;
X	if (di_height > (int)((double)di_width / WHRATIO))
X		di_height = (int)((double)di_width / WHRATIO);
X	di_picsize = (di_height * 4) / (5 * 80);
X	di_butbw = (di_picsize + 1) / 2;
X	di_height = di_picsize * 100;  /* Actually * 80 * 4 / 4. */
X	di_width = (int)(di_height * WHRATIO + 0.99999);
X	remap = (oldps != di_picsize);
X	/* Build the fonts. */
X	if (remap)  {
X		static int  need_free = FALSE;
X		int  nfonts, asc, desc;
X		XFontStruct  *flist;
X		char  **fnames, fname[200];
X		XCharStruct  size;
X		static int  sfloaded = FALSE, bfloaded = FALSE, ffloaded = FALSE;
X
X		if (need_free)  {
X			if (sfloaded)
X				XFreeFont(dpy, di_sfontstr);
X			if (bfloaded)
X				XFreeFont(dpy, di_bfontstr);
X			if (ffloaded)
X				XFreeFont(dpy, di_ffontstr);
X		}
X		need_free = TRUE;
X
X		sprintf(fname, FONTNAME, di_height / 30);
X		fnames = XListFontsWithInfo(dpy, fname, 1, &nfonts, &flist);
X		if (nfonts < 1)  {  /* X11R4 compatibility.  NO scalable fonts! */
X			XFreeFontInfo(fnames, flist, nfonts);
X			if (di_picsize >= sizeof(backup_sfonts) / sizeof(*backup_sfonts))
X				strcpy(fname, backup_sfonts[(sizeof(backup_sfonts) /
X																		 sizeof(*backup_sfonts)) - 1]);
X			else
X				strcpy(fname, backup_sfonts[di_picsize]);
X			fnames = XListFontsWithInfo(dpy, fname, 1, &nfonts, &flist);
X		}
X		if (nfonts < 1)  {
X			GC  dummy_gc;
X			XGCValues  vals;
X
X			dummy_gc = XCreateGC(dpy, win, 0, &vals);
X			XGetGCValues(dpy, dummy_gc, GCFont, &vals);
X			XFreeGC(dpy, dummy_gc);
X			di_sfont = vals.font;
X			di_sfontstr = XQueryFont(dpy, XGContextFromGC(DefaultGC(dpy,
X			              DefaultScreen(dpy))));
X			sfloaded = FALSE;
X		} else  {
X			di_sfontstr = XLoadQueryFont(dpy, fnames[0]);
X			di_sfont = di_sfontstr->fid;
X			sfloaded = TRUE;
X		}
X		XFreeFontInfo(fnames, flist, nfonts);
X		XTextExtents(di_sfontstr, "Cycles: 0", 9, &nfonts, &asc, &desc, &size);
X		cyth = asc + desc;
X		XTextExtents(di_sfontstr, "StopelwFasG", 11, &nfonts, &asc, &desc, &size);
X		butth = asc + desc;
X
X		sprintf(fname, FFONTNAME, di_height / 30);
X		fnames = XListFontsWithInfo(dpy, fname, 1, &nfonts, &flist);
X		if (nfonts < 1)  {  /* X11R4 compatibility.  NO scalable fonts! */
X			XFreeFontInfo(fnames, flist, nfonts);
X			if (di_picsize >= sizeof(backup_ffonts) / sizeof(*backup_ffonts))
X				strcpy(fname, backup_ffonts[(sizeof(backup_ffonts) /
X																		 sizeof(*backup_ffonts)) - 1]);
X			else
X				strcpy(fname, backup_ffonts[di_picsize]);
X			fnames = XListFontsWithInfo(dpy, fname, 1, &nfonts, &flist);
X		}
X		if (nfonts < 1)  {
X			di_ffont = di_sfont;
X			di_ffontstr = di_sfontstr;
X			ffloaded = FALSE;
X		} else  {
X			di_ffontstr = XLoadQueryFont(dpy, fnames[0]);
X			di_ffont = di_ffontstr->fid;
X			ffloaded = TRUE;
X		}
X		XFreeFontInfo(fnames, flist, nfonts);
X
X		sprintf(fname, FONTNAME, di_height - (di_picsize * 85 + cyth + butth));
X		fnames = XListFontsWithInfo(dpy, fname, 1, &nfonts, &flist);
X		if (nfonts < 1)  {  /* X11R4 compatibility.  NO scalable fonts! */
X			XFreeFontInfo(fnames, flist, nfonts);
X			if (di_picsize >= sizeof(backup_bfonts) / sizeof(*backup_bfonts))
X				strcpy(fname, backup_bfonts[(sizeof(backup_bfonts) /
X																		 sizeof(*backup_bfonts)) - 1]);
X			else
X				strcpy(fname, backup_bfonts[di_picsize]);
X			fnames = XListFontsWithInfo(dpy, fname, 1, &nfonts, &flist);
X		}
X		if (nfonts < 1)  {
X			di_bfont = di_sfont;
X			di_bfontstr = di_sfontstr;
X			bfloaded = FALSE;
X		} else  {
X			di_bfontstr = XLoadQueryFont(dpy, fnames[0]);
X			di_bfont = di_bfontstr->fid;
X			bfloaded = TRUE;
X		}
X		XFreeFontInfo(fnames, flist, nfonts);
X		XTextExtents(di_bfontstr, "The Core", 8, &nfonts, &asc, &desc, &size);
X		titth = asc + desc;
X		emptyslot = di_height - (titth + butth + cyth + di_picsize * 82);
X	}
X	return(remap);
X}
X
X
Xstatic void  recalc_co(Display *dpy, Window win, int remap)  {
X	int  i;
X
X	di_co_xoff = di_winw / 2 - 50 * di_picsize;
X	di_co_yoff = (di_winh - di_height) / 2 + titth + (emptyslot * 3) / 8;
X	if (remap)  {
X		static int  need_free = FALSE;
X		static int  oc[MAXPICS] = {2,2, 2,3,4, 2,1,0, 2,3,4, 2,1,0, 2,3,4, 2,1,0},
X		            ic[MAXPICS] = {2,2, 4,4,4, 0,0,0, 4,4,4, 0,0,0, 4,4,4, 0,0,0},
X		            cof[MAXPICS] = {3,0, 4,4,4, 6,6,6, 8,8,8,
X																	10,10,10, 12,12,12, 14,14,14},
X                cob[MAXPICS] = {3,0, 3,5,4, 3,7,6, 3,9,8,
X																	3,11,10, 3,13,12, 3,15,14};
X		XGCValues  vals;
X		char  *pics, *bigpics;
X		int  bpsize = di_ffontstr->ascent + di_ffontstr->descent;
X
X		if (need_free)  {
X			for (i = 0;  i < MAXPICS;  ++i)  {
X				XFreeGC(dpy, di_picgc[i]);
X				XFreePixmap(dpy, di_pixmaps[i]);
X				XFreePixmap(dpy, di_bigpixmaps[i]);
X			}
X		}
X		need_free = TRUE;
X		pics = (char *)tmalloc(di_picsize*2 * ((di_picsize*2 + 7) / 8) *
X													 sizeof(char));
X		bigpics = (char *)tmalloc(bpsize*2 * ((bpsize*2 + 7) / 8) *
X															sizeof(char));
X		vals.function = GXcopy;
X		if (di_color)  {
X			draw_bitmap(0, 4, di_picsize, pics);
X			draw_bitmap(0, 4, bpsize, bigpics);
X		}
X		for (i = 0;  i < MAXPICS;  ++i)  {
X			if (di_color)  {
X				vals.foreground = di_colors[cof[i]];
X				vals.background = di_colors[cob[i]];
X			} else  {
X				vals.foreground = di_stdfg;
X				vals.background = di_stdbg;
X				draw_bitmap(oc[i], ic[i], di_picsize, pics);
X				draw_bitmap(oc[i], ic[i], bpsize, bigpics);
X			}
X			di_pixmaps[i] = XCreatePixmapFromBitmapData(dpy, win, pics,
X																									di_picsize * 2,
X																									di_picsize * 2,
X																									vals.foreground,
X																									vals.background,
X																									di_depth);
X			di_bigpixmaps[i] = XCreatePixmapFromBitmapData(dpy, win, bigpics,
X																										 bpsize*2, bpsize*2,
X																										 vals.foreground,
X																										 vals.background,
X																										 di_depth);
X			vals.tile = di_pixmaps[i];
X			if ((di_color && (vals.foreground == vals.background)) ||
X					(!di_color && (oc[i] == 4) && (ic[i] == 4)))
X				vals.fill_style = FillSolid;
X			else if (!di_color && (oc[i] == 0) && (ic[i] == 0))  {
X				vals.fill_style = FillSolid;
X				vals.foreground = vals.background;
X			} else
X				vals.fill_style = FillTiled;
X			di_picgc[i] = XCreateGC(dpy, win, GCFunction | GCForeground |
X															GCBackground | GCFillStyle | GCTile, &vals);
X		}
X		free(pics);
X		free(bigpics);
X	}
X	for (i = 0;  i < MAXPICS;  ++i)
X		XSetTSOrigin(dpy, di_picgc[i], di_co_xoff, di_co_yoff);
X}
X
X
Xstatic void  recalc_pls(Display *dpy, Window win, int remap)  {
X	int  i, asc, desc;
X	XCharStruct size;
X	char  mtstr[40];
X
X	sprintf(mtstr, "%d", maxthreads);
X	XTextExtents(di_sfontstr, mtstr, strlen(mtstr), &i, &asc, &desc, &size);
X	for (i = 0;  i < DI_MAXPLAYERS;  ++i)  {
X		if (!(i & 1))
X			di_plstat[i].nbox_x = (di_winw - di_width) / 2 + di_picsize;
X		else
X			di_plstat[i].nbox_x = (di_winw / 2) + (di_picsize * 51);
X		di_plstat[i].nbox_y = (i / 2) * (di_picsize + (di_picsize * 76) / 3) +
X			di_co_yoff + di_picsize;
X		di_plstat[i].nbox_w = (di_winw / 2 - di_picsize * 51) -
X			((di_winw - di_width) / 2 + di_picsize);
X		di_plstat[i].nbox_h = (di_picsize * 76) / 3;
X		di_plstat[i].score_y = di_plstat[i].nbox_y + di_plstat[i].nbox_h -
X			desc - di_picsize - di_butbw;
X		di_plstat[i].sbox_y = di_plstat[i].score_y - asc;
X		di_plstat[i].sbox_w = size.width;
X		di_plstat[i].sbox_h = asc + desc;
X		if (!(i & 1))  {
X			di_plstat[i].score_x = di_plstat[i].nbox_x + di_plstat[i].nbox_w -
X				di_picsize - di_butbw;
X			di_plstat[i].sbox_x = di_plstat[i].score_x - di_plstat[i].sbox_w;
X		} else  {
X			di_plstat[i].score_x = di_plstat[i].nbox_x + di_picsize + di_butbw;
X			di_plstat[i].sbox_x = di_plstat[i].score_x;
X		}
X	}
X	if (remap)  {
X		static int  need_free = FALSE;
X		XGCValues  vals;
X
X		if (need_free)  {
X			for (i = 0;  i < DI_MAXPLAYERS;  ++i)
X				XFreeGC(dpy, di_plstat[i].sboxgc);
X		}
X		need_free = TRUE;
X		vals.font = di_sfont;
X		vals.function = GXcopy;
X		for (i = 0;  i < DI_MAXPLAYERS;  ++i)  {
X			if (di_color)  {
X				vals.foreground = di_stdfg;
X				vals.background = di_colors[i*2+4];
X			} else  {
X				if (!(i & 1))  {
X					vals.foreground = di_stdbg;
X					vals.background = di_stdfg;
X				} else  {
X					vals.foreground = di_stdfg;
X					vals.background = di_stdbg;
X				}
X			}
X			if (di_color)
X				vals.foreground = vals.background;
X			else  {
X				if (!(i & 1))
X					vals.foreground = di_stdfg;
X				else
X					vals.foreground = di_stdbg;
X			}
X			di_plstat[i].sboxgc = XCreateGC(dpy, win, (GCForeground | GCFunction),
X																	 &vals);
X		}
X	}
X	for (i = 0;  i < DI_MAXPLAYERS;  ++i)  {
X	}
X}
X
X
Xstatic void  recalc_ti(Display *dpy, Window win, int remap)  {
X	int  dummy, asc, desc;
X	XCharStruct  size;
X
X	XTextExtents(di_bfontstr, "The Core", 8, &dummy, &asc, &desc, &size);
X	di_ti_x = (di_winw - size.width) / 2;
X	di_ti_y = asc + (di_winh - di_height) / 2 + emptyslot / 8;
X}
X
X
Xstatic void  recalc_cy(Display *dpy, Window win, int remap)  {
X	char  cystr[80];
X	int  maxlen, tlen, xr, i;
X	XCharStruct  size;
X	int  asc, desc, dummy;
X
X	sprintf(cystr, "Cycles: %d", max_cycles);
X	tlen = strlen(cystr);
X	maxlen = tlen - 8;
X	XTextExtents(di_sfontstr, cystr, tlen, &dummy, &asc, &desc, &size);
X	di_cyby = di_co_yoff + di_picsize*80 + emptyslot/4;
X	di_cyty = di_cyby + asc;
X	di_cyh = asc + desc;
X	xr = (di_winw + size.width) / 2;
X	if (di_cyx != NULL)  {
X		free(di_cyx);
X		free(di_cyw);
X	}
X	di_cyx = (int *)tmalloc((maxlen + 1) * sizeof(int));
X	di_cyw = (int *)tmalloc((maxlen + 1) * sizeof(int));
X	for (i = 1;  i <= maxlen;  ++i)  {
X		XTextExtents(di_sfontstr, cystr+tlen-i, i, &dummy, &asc, &desc, &size);
X		di_cyx[i] = xr - size.width;
X		di_cyw[i] = size.width;
X	}
X	if (remap)  {
X		static int  need_redraw = FALSE;
X		XGCValues  vals;
X
X		if (need_redraw)  {
X			XFreeGC(dpy, di_cytgc);
X			XFreeGC(dpy, di_cybgc);
X		}
X		need_redraw = TRUE;
X		vals.foreground = di_stdfg;
X		vals.background = di_stdbg;
X		vals.font = di_sfont;
X		vals.function = GXcopy;
X		di_cytgc = XCreateGC(dpy, win, (GCForeground | GCBackground | GCFont |
X																		GCFunction),
X												 &vals);
X		vals.foreground = di_stdbg;
X		vals.font = di_sfont;
X		di_cybgc = XCreateGC(dpy, win, (GCForeground | GCFunction | GCFont),
X												 &vals);
X	}
X}
X
X
Xstatic void  draw_bitmap(int oc, int ic, unsigned picsize, char *pics)  {
X	unsigned  i, j, ti, tj, pin = ((picsize * 2) + 7) / 8;
X	static unsigned  min[2][2] = {{1, 3}, {4, 2}};
X	unsigned  inwidx, inwidy, inwidxs, inwidys;
X
X	for (i = 0;  i < picsize*2*pin;  ++i)
X		pics[i] = 0;
X	for (j = 0;  j < picsize*2;  ++j)  {
X		for (i = 0;  i < picsize*2;  ++i)  {
X			if (oc >= min[i&1][j&1])  {
X				pics[i/8 + j*pin] |= (1 << (i & 7));
X			}
X		}
X	}
X	inwidx = (picsize + 1) / 2;
X	inwidy = picsize / 2;
X	inwidxs = (picsize-inwidx)/2;
X	inwidys = (picsize-inwidy)/2;
X	for (j = inwidys;  j < inwidys+inwidy;  ++j)  {
X		for (i = inwidxs;  i < inwidxs+inwidx;  ++i)  {
X			ti = i;  tj = j;
X			if (ic >= min[ti&1][tj&1])
X				pics[ti/8 + tj*pin] |= (1 << (ti & 7));
X			else
X				pics[ti/8 + tj*pin] &= ~(1 << (ti & 7));
X			ti = i + picsize;  tj = j;
X			if (ic >= min[ti&1][tj&1])
X				pics[ti/8 + tj*pin] |= (1 << (ti & 7));
X			else
X				pics[ti/8 + tj*pin] &= ~(1 << (ti & 7));
X			ti = i + picsize;  tj = j + picsize;
X			if (ic >= min[ti&1][tj&1])
X				pics[ti/8 + tj*pin] |= (1 << (ti & 7));
X			else
X				pics[ti/8 + tj*pin] &= ~(1 << (ti & 7));
X			ti = i;  tj = j + picsize;
X			if (ic >= min[ti&1][tj&1])
X				pics[ti/8 + tj*pin] |= (1 << (ti & 7));
X			else
X				pics[ti/8 + tj*pin] &= ~(1 << (ti & 7));
X		}
X	}
X}
X
X
Xstatic void  recalc_but(Display *dpy, Window win, int remap)  {
X	int  i;
X	XCharStruct  size1[DI_NBUT], size2[DI_NBUT];
X	int  asc, desc, width, widest = -1;
X	static char  *btext[] = {"Stop", "Step", "Go", "OK"};
X	unsigned  butbw = (di_picsize + 1) / 2;
X	static Pixmap  grey_pixmap;
X
X	for (i = 0;  i < sizeof(btext) / sizeof(char *);  ++i)  {
X		width = XTextWidth(di_sfontstr, btext[i], strlen(btext[i]));
X		if (width > widest)
X			widest = width;
X	}
X	di_but[DI_BSTOP].win = win;
X	di_but[DI_BSTOP].w = widest + 2*di_picsize;
X	di_but[DI_BSTOP].h = di_sfontstr->ascent + di_sfontstr->descent +
X		2*di_picsize;
X	di_but[DI_BSTOP].x = (di_winw - di_picsize * 50) / 2;
X	di_but[DI_BSTOP].y = (di_winh + di_height) / 2 - (emptyslot / 8) -
X		di_but[DI_BSTOP].h;
X
X	di_but[DI_BGO].win = win;
X	di_but[DI_BGO].w = di_but[DI_BSTOP].w;
X	di_but[DI_BGO].h = di_but[DI_BSTOP].h;
X	di_but[DI_BGO].x = (di_winw + di_picsize * 50) / 2 -
X		di_but[DI_BGO].w;
X	di_but[DI_BGO].y = di_but[DI_BSTOP].y;
X
X	di_but[DI_BSLOW].win = win;
X	di_but[DI_BSLOW].w = di_but[DI_BGO].x - (di_but[DI_BSTOP].x +
X		di_but[DI_BSTOP].w);
X	di_but[DI_BSLOW].h = di_but[DI_BSTOP].h;
X	di_but[DI_BSLOW].x = di_but[DI_BSTOP].x + di_but[DI_BSTOP].w;
X	di_but[DI_BSLOW].y = di_but[DI_BSTOP].y;
X
X	di_but[DI_BQUIT].win = win;
X	di_but[DI_BQUIT].x = di_plstat[0].nbox_x;
X	di_but[DI_BQUIT].y = di_but[DI_BSTOP].y;
X	di_but[DI_BQUIT].w = di_plstat[0].nbox_w;
X	di_but[DI_BQUIT].h = di_but[DI_BSTOP].h;
X
X	di_but[DI_BRESTART].win = win;
X	di_but[DI_BRESTART].x = di_plstat[1].nbox_x;
X	di_but[DI_BRESTART].y = di_but[DI_BSTOP].y;
X	di_but[DI_BRESTART].w = di_plstat[1].nbox_w;
X	di_but[DI_BRESTART].h = di_but[DI_BSTOP].h;
X
X	di_but[DI_BWIN2OK].win = di_win2;
X	di_but[DI_BWIN2OK].w = 
X		XTextWidth(di_sfontstr, "OK", 2) + di_picsize * 2;
X	di_but[DI_BWIN2OK].h = di_but[DI_BSTOP].h;
X
X	di_but[DI_BCOREPIC].win = win;
X	di_but[DI_BCOREPIC].x = di_co_xoff;
X	di_but[DI_BCOREPIC].y = di_co_yoff;
X	di_but[DI_BCOREPIC].w = di_picsize * 100;
X	di_but[DI_BCOREPIC].h = di_picsize * 80;
X/*
X	di_but[DI_BWIN3OK].win = di_win3;
X	di_but[DI_BWIN3OK].w = di_but[DI_BWIN2OK].w;
X	di_but[DI_BWIN3OK].h = di_but[DI_BWIN2OK].h;
X*/
X	widest = XTextWidth(di_sfontstr, "Unload", 6);
X	width = XTextWidth(di_sfontstr, "Load", 4);
X	if (width > widest)
X		widest = width;
X	for (i = 0;  i < DI_MAXPLAYERS;  ++i)  {
X		di_but[DI_BPLAY(i)].win = win;
X		di_but[DI_BPLAY(i)].w = widest + di_picsize * 2;
X		di_but[DI_BPLAY(i)].h = di_but[DI_BSTOP].h;
X		di_but[DI_BPLAY(i)].x = di_plstat[i].nbox_x +
X			(di_plstat[i].nbox_w - di_but[DI_BPLAY(i)].w) / 2;
X		di_but[DI_BPLAY(i)].y = di_plstat[i].nbox_y +
X			(di_plstat[i].nbox_h - di_but[DI_BPLAY(i)].h) / 2;
X	}
X
X	if (di_state == DS_RUNSLOW)
X		if (di_slopos >= di_but[DI_BSLOW].w)
X			di_slopos = di_but[DI_BSLOW].w - 1;
X
X	if (remap)  {
X		static int  need_free = FALSE;
X		XGCValues  vals;
X
X		if (need_free)  {
X			XFreeGC(dpy, di_butgc);
X		} else  {  /* Create the border GCs...they never need a recalc. */
X			static char  grey50_bits[] = {1, 2}, grey75_bits[] = {1, 4};
X
X			vals.function = GXcopy;
X			vals.foreground = di_stdfg;
X			vals.background = di_stdbg;
X			vals.line_width = 1;
X			vals.line_style = LineSolid;
X			di_grey50pixmap = XCreatePixmapFromBitmapData(dpy, win, grey50_bits,
X																										2, 2, di_stdfg, di_stdbg,
X																										di_depth);
X			di_grey75pixmap = XCreatePixmapFromBitmapData(dpy, win, grey75_bits,
X																										4, 2, di_stdfg, di_stdbg,
X																										di_depth);
X			vals.tile = di_grey50pixmap;
X			if (di_color)  {
X				vals.foreground = di_colors[2];
X				vals.fill_style = FillSolid;
X				vals.background = di_colors[2];
X			} else
X				vals.fill_style = FillTiled;
X			di_butlgc = XCreateGC(dpy, win, GCFunction | GCForeground |
X														GCBackground | GCFillStyle | GCTile |
X														GCLineStyle | GCLineWidth, &vals);
X			if (di_color)
X				vals.foreground = vals.background = di_colors[0];
X			vals.fill_style = FillSolid;
X			di_butdgc = XCreateGC(dpy, win, GCFunction | GCForeground |
X														GCLineStyle | GCLineWidth |
X														GCBackground | GCFillStyle, &vals);
X		}
X		need_free = TRUE;
X		vals.function = GXcopy;
X		vals.foreground = di_stdfg;
X		vals.background = di_stdbg;
X		vals.fill_style = FillSolid;
X		vals.line_width = 1;
X		vals.line_style = LineSolid;
X		vals.tile = di_grey50pixmap;
X		vals.font = di_sfont;
X		di_butgc = XCreateGC(dpy, win, (GCFunction | GCForeground | GCBackground |
X																		GCLineStyle | GCLineWidth |
X																		GCFillStyle | GCFont | GCTile), &vals);
X	}
X
X	for (i = 0;  i < DI_NBUT;  ++i)  {
X		gbut_create(i, di_but+i);
X	}
X}
X
X#endif  /* X11_DISP */
END_OF_FILE
if test 21360 -ne `wc -c <'di_recalc.c'`; then
    echo shar: \"'di_recalc.c'\" unpacked with wrong size!
fi
# end of 'di_recalc.c'
fi
if test -f 'di_draw.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'di_draw.c'\"
else
echo shar: Extracting \"'di_draw.c'\" \(4792 characters\)
sed "s/^X//" >'di_draw.c' <<'END_OF_FILE'
X/*
X * di_draw.c
X */
X
X#ifdef  X11_DISP
X
X#include <stdio.h>
X#include <X11/Xlib.h>
X#include <X11/Xutil.h>
X#include "corewar.h"
X#include "cwdisp.h"
X
X
Xstatic int  cycno = 0;
Xstatic char  cycstr[20], *cycend;
X
X
Xvoid  di_draw_ov(Display *dpy, Window win, int x, int y, int w, int h)  {
X	XFillRectangle(dpy, win, di_cybgc, x, y, w, h);
X	XSetFont(dpy, di_cytgc, di_bfont);
X	XDrawString(dpy, win, di_cytgc, di_ti_x, di_ti_y, "The Core", 8);
X	XSetFont(dpy, di_cytgc, di_sfont);
X}
X
X
Xvoid  di_draw_co(Display *dpy, Window win, int x, int y, int w, int h)  {
X	int  i, j, cx1, cy1, cx2, cy2, picv;
X
X	if ((x+w <= di_co_xoff) || (x > di_co_xoff + di_picsize * 100) ||
X			(y+h <= di_co_yoff) || (y > di_co_yoff + di_picsize * 80))
X		return;
X	cx1 = (int)(x - di_co_xoff) / (int)di_picsize;
X	if (cx1 < 0)
X		cx1 = 0;
X	cx2 = (x+w+di_picsize-1-di_co_xoff) / di_picsize;
X	if (cx2 > 99)
X		cx2 = 99;
X	cy1 = (int)(y - di_co_yoff) / (int)di_picsize;
X	if (cy1 < 0)
X		cy1 = 0;
X	cy2 = (y+h+di_picsize-1-di_co_yoff) / di_picsize;
X	if (cy2 > 79)
X		cy2 = 79;
X	for (j = cy1;  j <= cy2;  ++j)
X		for (i = cx1;  i <= cx2;  ++i)  {
X			picv = di_picmap[i+j*100];
X			XFillRectangle(dpy, win, di_picgc[picv & ~CP_M],
X										 i * di_picsize + di_co_xoff,
X										 j * di_picsize + di_co_yoff,
X										 di_picsize, di_picsize);
X			if (picv & CP_M)
X				di_drawoutline(i+j*100, picv);
X		}
X}
X
X
Xvoid  di_draw_pls(Display *dpy, Window win, unsigned plno)  {
X	int  p, dummy, asc, desc;
X	XCharStruct  size;
X	
X	if (plno == -1)  {
X		p = 0;
X		plno = DI_MAXPLAYERS - 1;
X	} else
X		p = plno;
X	for (;  p <= plno;  ++p)  {
X		XRectangle  rect[1];
X		int  slen;
X
X		rect[0].x = di_plstat[p].nbox_x;
X		rect[0].y = di_plstat[p].nbox_y;
X		rect[0].width = di_plstat[p].nbox_w;
X		rect[0].height = di_plstat[p].nbox_h;
X		XSetClipRectangles(dpy, di_cytgc, 0, 0, rect, 1, Unsorted);
X		XFillRectangle(dpy, win, di_plstat[p].sboxgc,
X									 di_plstat[p].nbox_x,di_plstat[p].nbox_y,
X									 di_plstat[p].nbox_w,di_plstat[p].nbox_h);
X		di_outline_box(dpy, win, di_plstat[p].nbox_x, di_plstat[p].nbox_y,
X									 di_plstat[p].nbox_w + 1, di_plstat[p].nbox_h + 1,
X									 BUT_POPUP);
X		if (di_nprocs[p] != NOTLOADED)  {
X			di_draw_nprocs(p, di_nprocs[p], dpy, win);
X			slen = strlen(di_plstat[p].name);
X			XTextExtents(di_sfontstr, di_plstat[p].name, slen,
X									 &dummy, &asc, &desc, &size);
X			if (!(p & 1))  {
X				if (!di_color)
X					XSetForeground(dpy, di_cytgc, di_stdbg);
X				XDrawString(dpy, win, di_cytgc,
X										di_plstat[p].nbox_x + di_plstat[p].nbox_w - di_picsize -
X										size.width - di_butbw, di_plstat[p].nbox_y + di_picsize +
X										asc + di_butbw, di_plstat[p].name, slen);
X				if (!di_color)
X					XSetForeground(dpy, di_cytgc, di_stdfg);
X			} else  {
X				XDrawString(dpy, win, di_cytgc,
X										di_plstat[p].nbox_x + di_picsize + di_butbw,
X										di_plstat[p].nbox_y + di_picsize + asc + di_butbw,
X										di_plstat[p].name, slen);
X			}
X		}
X		gbut_draw(DI_BPLAY(p));
X	}
X	XSetClipMask(dpy, di_cytgc, None);
X}
X
X
Xvoid  di_draw_nprocs(int plnum, unsigned nprocs, Display *dpy, Window win)  {
X	char  scstr[10];
X	int  slen;
X
X	XFillRectangle(dpy, win, di_plstat[plnum].sboxgc,
X								 di_plstat[plnum].sbox_x, di_plstat[plnum].sbox_y,
X								 di_plstat[plnum].sbox_w, di_plstat[plnum].sbox_h);
X	sprintf(scstr, "%d", nprocs);
X	slen = strlen(scstr);
X	if (!(plnum & 1))  {
X		XCharStruct  size;
X		int  dummy;
X					
X		XTextExtents(di_sfontstr, scstr, slen, &dummy, &dummy,
X								 &dummy, &size);
X		if (!di_color)
X			XSetForeground(dpy, di_cytgc, di_stdbg);
X		XDrawString(dpy, win, di_cytgc,
X								di_plstat[plnum].score_x - size.width,
X								di_plstat[plnum].score_y, scstr, slen);
X		if (!di_color)
X			XSetForeground(dpy, di_cytgc, di_stdfg);
X	} else  {
X		XDrawString(dpy, win, di_cytgc,
X								di_plstat[plnum].score_x,
X								di_plstat[plnum].score_y, scstr, slen);
X	}
X}
X
X
Xvoid  di_draw_cy(Display *dpy, Window win)  {
X	int  slen, dummy, asc, desc;
X	XCharStruct  size;
X	char  tmpstr[40];
X
X	XFillRectangle(dpy, win, di_cybgc, di_cyx[cycend-cycstr], di_cyby,
X								 di_cyw[cycend-cycstr], di_cyh);
X	sprintf(tmpstr, "Cycles: %s", cycstr);
X	slen = strlen(tmpstr);
X	XTextExtents(di_sfontstr, tmpstr, slen, &dummy, &asc, &desc, &size);
X	XDrawString(dpy, win, di_cytgc,	(di_winw - size.width) / 2, di_cyty, tmpstr,
X							slen);
X}
X
X
Xvoid  di_reset_cy()  {
X	int  i;
X
X	cycno = 0;
X	sprintf(cycstr, "%d", max_cycles);
X	for (i = 0;  cycstr[i];  ++i)
X		cycstr[i] = '0';
X	cycend = cycstr + i;
X}
X
X
Xvoid  di_update_cy(Display *dpy, Window win)  {
X	int  uplen = 1;
X	char  *tend = cycend - 1;
X
X	while ((*tend == '9') && (tend != cycstr))  {
X		*tend = '0';
X		--tend;
X		++uplen;
X	}
X	if (*tend == '9')
X		*tend = '0';
X	else
X		++*tend;
X	XDrawImageString(dpy, win, di_cytgc, di_cyx[uplen], di_cyty, tend, uplen);
X}
X
X#endif  /* X11_DISP */
END_OF_FILE
if test 4792 -ne `wc -c <'di_draw.c'`; then
    echo shar: \"'di_draw.c'\" unpacked with wrong size!
fi
# end of 'di_draw.c'
fi
if test -f 'cwdisp.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'cwdisp.h'\"
else
echo shar: Extracting \"'cwdisp.h'\" \(6208 characters\)
sed "s/^X//" >'cwdisp.h' <<'END_OF_FILE'
X/* cwdisp.h */
X
X/* Parts of the display:
X *
X * ov  Overall display - The window, the display, etc.
X * co  The core picture
X * pls The player info
X * ti  The title
X * cy  The cycle display
X * but The control buttons
X */
X
X#include "gbut.h"  /* Needed for win3 data structure. */
X
X#define  FONTNAME  "-bitstream-charter-medium-r-normal--%d-*-*-*-*-*-*-*"
X#define  FFONTNAME "-bitstream-courier-medium-r-normal--%d-*-*-*-*-*-*-*"
X#define  MAXPICS  (DI_PLSIZ * (DI_MAXPLAYERS - 1) + DI_XEQ + 1)
X#define  WHRATIO  1.618033989  /* The golden mean. */
X#define  MAX_CVAL  65535
X#define  NOTLOADED  -1
X#define  DS_STOPPED  0
X#define  DS_RUNFAST  1
X#define  DS_RUNSLOW  2
X#define  DS_STEP     3
X
X/* Values for the overall display. */
Xextern aval_t di_next_move;
Xextern int  di_next_player;
Xextern unsigned long  di_stdfg, di_stdbg;
Xextern unsigned  di_depth, di_picsize;
Xextern Window  di_win;
Xextern XFontStruct  *di_bfontstr, *di_sfontstr, *di_ffontstr;
Xextern Font  di_bfont, di_sfont, di_ffont;
Xextern Display  *di_dpy;
Xextern unsigned  di_winw, di_winh, di_width, di_height;
Xextern Colormap  di_cmap;
Xextern int  di_color;  /* TRUE or FALSE */
X
X/* Values for the core display. */
Xextern int  *di_picmap;
Xextern unsigned  di_co_xoff, di_co_yoff;
Xextern char  *di_co_pics;
Xextern Pixmap  di_pixmaps[MAXPICS], di_bigpixmaps[MAXPICS];
Xextern Pixmap  di_grey50pixmap, di_grey75pixmap;
Xextern GC  di_picgc[MAXPICS];
Xextern int  di_nprocs[DI_MAXPLAYERS], di_nalive;
Xextern int  di_state, di_last_cyc, di_slopos;
Xextern float  di_speed;
X
X/* Values describing the player status windows. */
Xtypedef struct  {
X	unsigned  name_x, name_y;
X	unsigned  score_x, score_y;
X	unsigned  sbox_x, sbox_y, sbox_w, sbox_h;
X	unsigned  nbox_x, nbox_y, nbox_w, nbox_h;
X	char  *name;
X	GC  sboxgc;
X	char  istring[STR_MAXLEN];
X} di_plstatinfo;
Xextern di_plstatinfo   di_plstat[DI_MAXPLAYERS];
X
X/* The title. */
Xextern int  di_ti_x, di_ti_y;
X
X/* The cycle display. */
Xextern int  *di_cyx, di_cyty, di_cyby, *di_cyw, di_cyh;
Xextern GC  di_cytgc, di_cybgc;
X
X/* The buttons. */
X#define  DI_BSTOP     0
X#define  DI_BSLOW     1
X#define  DI_BGO       2
X#define  DI_BQUIT     3
X#define  DI_BRESTART  4
X#define  DI_BWIN2OK   5
X#define  DI_BCOREPIC  6
X#define  DI_BPLAY(pnum)  (7 + (pnum))
X#define  DI_NBUT      (DI_BPLAY(DI_MAXPLAYERS))
X#define  DI_BWIN3OK      DI_NBUT
X#define  DI_BWIN3UP      (DI_NBUT+1)
X#define  DI_BWIN3DOWN    (DI_NBUT+2)
X#define  DI_BWIN3SCROLL  (DI_NBUT+3)
X#define  DI_B3WIN(but)  (((but)-DI_BWIN3OK)>>2)
X#define  DI_B3BUT(but)  ((((but)-DI_BWIN3OK)&3)+DI_BWIN3OK)
X#define  DI_W3BUT(win,but)  ((but)+((win)*4))
X
Xtypedef struct win3  {
X	Window  win;
X	int  h, w;
X	aval_t  startaddr;
X	int  lines;
X	struct win3  *next, *prev;
X	gbut_info  okbut, upbut, downbut, scrollbut;
X} win3;
Xextern int   di_numwin3;
Xextern win3  di_win3list;
Xextern int   *di_indis;
X
X/* Borders on the core picture. */
X#define  CP_U  0x100
X#define  CP_D  0x200
X#define  CP_R  0x400
X#define  CP_L  0x800
X#define  CP_M  0xf00  /* I just had to make up this name. */
X
Xextern unsigned  di_butbw;
Xextern gbut_info  di_but[DI_NBUT];
Xextern GC  di_butgc, di_butlgc, di_butdgc;
X
X/* General stuff. */
Xextern unsigned  di_cycles;
Xextern program_t  di_progs[DI_MAXPLAYERS];
X
X/* Window #2; the load window. */
Xextern Window  di_win2;
Xextern unsigned  di_win2w, di_win2h;
Xextern int  di_ldplayer, di_curon;
X
X
X/* From "disp.c" */
Xextern void  di_drawaddr(aval_t addr, int val),
X             di_newoutline(aval_t addr, int val),
X             di_changestate(Display *dpy, Window win, int newstate),
X             di_exit(int exitval);
X
X/* From "di_timer.c" */
Xextern void  di_set_timer(float freq), di_unset_timer(void),
X             di_undo_wait(void);
Xextern int   di_timer_wait(Display *dpy);
X
X/* From "di_recalc.c" */
Xextern unsigned long  di_colors[4+DI_MAXPLAYERS*2];
Xextern void  di_redraw(Display *dpy, Window win, XWindowAttributes *xwa,
X											 int x, int y, int w, int h);
X
X/* From "di_draw.c" */
Xextern void  di_draw_ov(Display *dpy, Window win, int x, int y, int w, int h),
X             di_draw_co(Display *dpy, Window win, int x, int y, int w, int h),
X             di_draw_pls(Display *dpy, Window win, unsigned plno),
X             di_draw_nprocs(int plnum, unsigned nprocs, Display *dpy,
X														Window win),
X             di_draw_cy(Display *dpy, Window win),
X             di_reset_cy(void), di_update_cy(Display *dpy, Window win);
X
X/* From "di_but.c" */
Xextern void  di_draw_ctbut(int butnum, gbut_info *info),
X             di_draw_sfbut(int butnum, gbut_info *info),
X             di_outline_box(Display *dpy, Window win, int x, int y,
X														int w, int h, int bstate),
X	           di_draw_upbut(int butnum, gbut_info *info),
X             di_draw_downbut(int butnum, gbut_info *info),
X             di_draw_sbar(int butnum, gbut_info *info);
X#define  BUT_POPUP     0
X#define  BUT_PUSHDOWN  GBUT_TWITCHED
X
X/* From "di_input.c" */
Xextern void  di_in_init(void);
Xextern void  di_butpress(Display *dpy, Window win, XButtonPressedEvent *evt);
Xextern void  di_butrelease(Display *dpy, Window win,
X                           XButtonReleasedEvent *evt);
Xextern void  di_keypress(Display *dpy, Window win, XKeyPressedEvent *evt);
Xextern void  di_keyrelease(Display *dpy, Window win, XKeyReleasedEvent *evt);
Xextern void  di_input_m(Display *dpy, Window win, XMotionEvent *evt);
X
X/* From "di_load.c" */
Xextern void  di_loadbut(unsigned pnum), di_reset(void),
X             di_redraw2(Display *dpy, Window win2, XWindowAttributes *xwa),
X             di_killwin2(int absolute),
X             di_keypress2(Display *dpy, Window win, XKeyPressedEvent *evt),
X             di_cursor(Display *dpy, Window win, int visible),
X             di_mkwin2(char *name);
X
X/* From "di_dis.c" */
Xextern void  di_redraw3(Display *dpy, Window win3, int x, int y, int w, int h),
X             di_killwin3(int winnum), di_mkwin3(aval_t location),
X             di_fixline(aval_t lineaddr),
X             di_dis_newstart(int winnum, aval_t newloc),
X             di_dis_init(void);
Xextern void  di_drawoutline(aval_t addr, int format);
Xextern int  di_dis_cpcheck(int butnum, gbut_info *info, int checktype,
X										int x, int y);
Xextern void  di_dis_cpdraw(int butnum, gbut_info *info);
END_OF_FILE
if test 6208 -ne `wc -c <'cwdisp.h'`; then
    echo shar: \"'cwdisp.h'\" unpacked with wrong size!
fi
# end of 'cwdisp.h'
fi
if test -f 'di_load.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'di_load.c'\"
else
echo shar: Extracting \"'di_load.c'\" \(9686 characters\)
sed "s/^X//" >'di_load.c' <<'END_OF_FILE'
X/* di_load.c */
X
X#ifdef  X11_DISP
X
X#include <stdio.h>
X#include <string.h>
X#include <X11/Xlib.h>
X#include <X11/Xutil.h>
X#include <X11/keysym.h>
X#include "corewar.h"
X#include "cwdisp.h"
X
Xunsigned  di_win2w = 0, di_win2h = 0;
Xint  di_ldplayer, di_curon;
XWindow  di_win2;
X
Xstatic char  *cur_msg = NULL, *istring;
Xstatic int  start_x, start_y;
Xstatic XPoint  cursor[6];
X
Xstatic void  di_loadprog(unsigned pnum), di_unloadprog(unsigned pnum),
X             di_fillwin2(Display *dpy, Window win2);
X
X
Xvoid  di_loadbut(unsigned pnum)  {
X	if (di_nprocs[pnum] == NOTLOADED)
X		di_loadprog(pnum);
X	else
X		di_unloadprog(pnum);
X}
X
X
Xvoid  di_reset()  {
X	unsigned  i;
X	aval_t  old_nextmove = di_next_move;
X
X	new_core();
X	for (i = 0;  i < coresize;  ++i)  {
X		if (di_indis[i])
X			di_fixline(i);
X	}
X	XFillRectangle(di_dpy, di_win, di_picgc[DI_EMPTY],
X								 di_co_xoff, di_co_yoff,
X								 100*di_picsize, 80*di_picsize);
X	for (i = 0;  i < 8000;  ++i)  {
X		if ((di_picmap[i] & CP_M) == 0)
X			di_picmap[i] = DI_EMPTY;
X		else  {
X			di_picmap[i] = DI_EMPTY | (di_picmap[i] & CP_M);
X			di_drawoutline(i, di_picmap[i]);
X		}
X	}
X	di_reset_cy();
X	di_draw_cy(di_dpy, di_win);
X	for (i = 0;  i < DI_MAXPLAYERS;  ++i)  {
X		gbut_setflags(DI_BPLAY(i), GBUT_PRESSABLE);
X	}
X	ld_init(DI_MAXPLAYERS);
X	di_nalive = 0;
X	di_cycles = -1;
X	for (i = 0;  i < DI_MAXPLAYERS;  ++i)  {
X		if (di_nprocs[i] != NOTLOADED)  {
X			load_core(di_progs + i, ld_addr(i), i);
X			di_nprocs[i] = 1;
X			++di_nalive;
X			di_draw_pls(di_dpy, di_win, i);
X		}
X	}
X	if ((di_ldplayer == -1) && (di_nalive > 0))  {
X		gbut_setflags(DI_BSTOP, GBUT_PRESSABLE);
X		gbut_setflags(DI_BSLOW, GBUT_PRESSABLE);
X		gbut_setflags(DI_BGO, GBUT_PRESSABLE);
X	}
X	di_changestate(di_dpy, di_win, DS_STOPPED);
X	di_next_move = sim_nextaddr();
X	di_next_player = sim_nextplayer();
X	if (di_indis[old_nextmove])
X		di_fixline(old_nextmove);
X	if (di_indis[di_next_move])
X		di_fixline(di_next_move);
X}
X
X
Xstatic void  di_unloadprog(unsigned pnum)  {
X	aval_t  ldaddr;
X	unsigned  ldcnt = di_progs[pnum].proglen;
X	aval_t  old_nextmove = di_next_move;
X
X	ldaddr = ld_undo(pnum);
X	di_nprocs[pnum] = NOTLOADED;
X	free(di_progs[pnum].listing);
X	--di_nalive;
X	di_but[DI_BPLAY(pnum)].packet = (void *)"Load";
X	gbut_draw(DI_BPLAY(pnum));
X	clear_core(ldaddr, ldcnt, pnum);
X	di_draw_pls(di_dpy, di_win, pnum);
X	if (di_nalive == 0)  {
X		gbut_setflags(DI_BSTOP, GBUT_NOPRESS);
X		gbut_setflags(DI_BSLOW, GBUT_NOPRESS);
X		gbut_setflags(DI_BGO, GBUT_NOPRESS);
X		gbut_setflags(DI_BRESTART, GBUT_NOPRESS);
X		di_next_move = AVAL_NOGOOD;
X		if (di_indis[old_nextmove])
X			di_fixline(old_nextmove);
X	} else  {
X		di_next_move = sim_nextaddr();
X		di_next_player = sim_nextplayer();
X		if (di_indis[old_nextmove])
X			di_fixline(old_nextmove);
X		if (di_indis[di_next_move])
X			di_fixline(di_next_move);
X	}
X}
X
X
Xstatic void  di_loadprog(unsigned pnum)  {
X	if (di_win2w != 0)
X		di_killwin2(TRUE);
X	cur_msg = "Enter the file name of the program:";
X	di_draw_pls(di_dpy, di_win, pnum);
X	di_ldplayer = pnum;
X	istring = di_plstat[pnum].istring;
X	di_mkwin2("Corewar");
X}
X
X
Xstatic void  di_gotprog(unsigned pnum, char *fname)  {
X	aval_t  ldaddr;
X
X	di_ldplayer = -1;
X	if (!fname[0] || !assemble(di_progs + pnum, fname))  {
X		static char  new_errstr[STR_ERRLEN + STR_MAXLEN + 20];
X		XWindowAttributes  xwa;
X
X		if (fname[0] == '\0')
X			strcpy(cwerrstr, "\"\" is not a legal file name!\n");
X		sprintf(new_errstr, "Error assembling \"%s\":\n\n%s",
X						fname, cwerrstr);
X		cur_msg = new_errstr;
X		di_ldplayer = -1;
X		XGetWindowAttributes(di_dpy, di_win2, &xwa);
X		di_redraw2(di_dpy, di_win2, &xwa);
X	} else  {
X		aval_t  old_nextmove;
X
X		di_killwin2(FALSE);
X		if (strcmp(di_progs[pnum].pname, "Unknown"))
X			di_plstat[pnum].name = di_progs[pnum].pname;
X		else
X			di_plstat[pnum].name = di_progs[pnum].fname;
X		++di_nalive;
X		di_but[DI_BPLAY(pnum)].packet = (void *)"Unload";
X		gbut_draw(DI_BPLAY(pnum));
X		ldaddr = ld_addr(pnum);
X		old_nextmove = di_next_move;
X		load_core(di_progs + pnum, ldaddr, pnum);
X		di_next_move = sim_nextaddr();
X		di_next_player = sim_nextplayer();
X		if ((old_nextmove != AVAL_NOGOOD) && di_indis[old_nextmove])
X			di_fixline(old_nextmove);
X		if (di_indis[di_next_move])
X			di_fixline(di_next_move);
X		di_nprocs[pnum] = 1;
X		di_draw_pls(di_dpy, di_win, pnum);
X	}
X	if (di_nalive > 0)  {
X		gbut_setflags(DI_BSTOP, GBUT_PRESSABLE);
X		gbut_setflags(DI_BSLOW, GBUT_PRESSABLE);
X		gbut_setflags(DI_BGO, GBUT_PRESSABLE);
X		gbut_setflags(DI_BRESTART, GBUT_PRESSABLE);
X	}
X}
X
X
Xvoid  di_mkwin2(char *name)  {
X	XSizeHints  xsh;
X	Window  win2;
X
X	/* Make sure that the "Go", etc. buttons are disabled! */
X	gbut_setflags(DI_BSTOP, GBUT_NOPRESS);
X	gbut_setflags(DI_BSLOW, GBUT_NOPRESS);
X	gbut_setflags(DI_BGO, GBUT_NOPRESS);
X	if (di_win2w == 0)  {
X		xsh.width = di_width / 2;
X		xsh.height = di_height / 2;
X		xsh.flags = PSize;
X		win2 = XCreateSimpleWindow(di_dpy, di_win,
X															 (di_winw-xsh.width)/2,
X															 (di_co_yoff + (80*di_picsize-xsh.height)/3),
X															 xsh.width, xsh.height, 0, di_stdbg, di_stdfg);
X		XSetStandardProperties(di_dpy, di_win, name, name, None, NULL, 0, &xsh);
X		di_win2 = win2;
X		XSelectInput(di_dpy, win2, ExposureMask | StructureNotifyMask |
X								 PointerMotionMask | ButtonPressMask | KeyPressMask |
X								 ButtonReleaseMask | KeyReleaseMask);
X		XMapWindow(di_dpy, win2);
X		di_win2w = 1;
X	}
X}
X
X
Xstatic void  di_fillwin2(Display *dpy, Window win2)  {
X	char  *cp = cur_msg, *np;
X	unsigned  cur_y = di_picsize + di_sfontstr->ascent;
X	int  is_prog_line = FALSE;
X
X	XFillRectangle(dpy, win2, di_cybgc, 0, 0, di_win2w, di_win2h);
X	while (*cp)  {
X		for (np = cp;  (*np != '\n') && (*np != '\0');  ++np)
X			if (*np == '\t')
X				*np = ' ';
X		if (is_prog_line)
X			XSetFont(dpy, di_cytgc, di_ffont);
X		XDrawString(dpy, win2, di_cytgc, di_picsize, cur_y, cp, np-cp);
X		if (is_prog_line)
X			XSetFont(dpy, di_cytgc, di_sfont);
X		if (strncmp(cp, "Error around line", 16) == 0)
X			is_prog_line = TRUE;
X		cp = np;
X		if (*cp == '\n')
X			++cp;
X		cur_y += di_sfontstr->ascent + di_sfontstr->descent;
X	}
X	if (di_ldplayer != -1)  {
X		di_outline_box(dpy, win2, start_x - di_butbw*2,
X									 start_y - di_butbw*2 - di_sfontstr->ascent,
X									 di_win2w - di_picsize*2 - di_butbw*2,
X									 di_sfontstr->ascent + di_sfontstr->descent +
X									 di_butbw * 4, BUT_PUSHDOWN);
X		XDrawString(dpy, win2, di_cytgc, start_x, start_y,
X								istring, strlen(istring));
X	}
X	if (di_curon)
X		di_cursor(dpy, win2, TRUE);
X}
X
X
Xvoid  di_cursor(Display *dpy, Window win, int visible)  {
X	GC  gc;
X
X	if (di_ldplayer != -1)  {
X		if (visible)
X			gc = di_cytgc;
X		else
X			gc = di_cybgc;
X		XFillPolygon(dpy, win, gc, cursor, 6, Nonconvex, CoordModePrevious);
X	}
X}
X
X
Xvoid  di_killwin2(int absolute)  {
X	if (di_win2w != 0)  {
X		if (!absolute && (di_ldplayer != -1))
X			di_gotprog(di_ldplayer, istring);
X		else  {
X			di_win2w = 0;
X			di_win2h = 0;
X			gbut_setflags(DI_BWIN2OK, GBUT_NODRAW|GBUT_NOPRESS);
X			gbut_badwindow(di_win2);
X			XDestroyWindow(di_dpy, di_win2);
X		}
X	}
X}
X
X
Xvoid  di_redraw2(Display *dpy, Window win2, XWindowAttributes *xwa)  {
X	int  cwid = di_butbw;
X
X	if (di_sfontstr->descent < cwid)
X		cwid = di_sfontstr->descent;
X	di_win2w = xwa->width;
X	di_win2h = xwa->height;
X	start_x = di_picsize + 3*di_butbw;
X	start_y = di_win2h / 2;
X	cursor[0].x = start_x + XTextWidth(di_sfontstr, istring, strlen(istring));
X	cursor[0].y = start_y;
X	cursor[1].x = cwid;
X	cursor[1].y = di_sfontstr->descent;
X	cursor[2].x = -(cwid / 2);
X	cursor[2].y = 0;
X	cursor[3].x = -(cursor[1].x + cursor[2].x);
X	cursor[3].y = -(di_sfontstr->descent / 2);
X	cursor[4].x = cursor[3].x;
X	cursor[4].y = -cursor[3].y;
X	cursor[5].x = cursor[2].x;
X	cursor[5].y = 0;
X	di_curon = FALSE;
X	di_fillwin2(dpy, win2);
X	di_but[DI_BWIN2OK].flags = GBUT_DRAWABLE | GBUT_PRESSABLE;
X	di_but[DI_BWIN2OK].win = win2;
X	di_but[DI_BWIN2OK].x = (di_win2w - di_but[DI_BWIN2OK].w) / 2;
X	di_but[DI_BWIN2OK].y = di_win2h - di_but[DI_BWIN2OK].h - di_picsize*2;
X	gbut_create(DI_BWIN2OK, di_but+DI_BWIN2OK);
X}
X
X
Xvoid  di_keypress2(Display *dpy, Window win, XKeyPressedEvent *evt)  {
X	char  buffer[STR_MAXLEN];
X	KeySym  keysym;
X	int  length, count;
X
X	if (di_ldplayer == -1)  {
X		if (XKeysymToKeycode(dpy, XK_Return) == evt->keycode)
X			di_killwin2(FALSE);
X		else
X			XBell(dpy, 0);
X		return;
X	}
X	count = XLookupString(evt, buffer, STR_MAXLEN-1, &keysym, NULL);
X	buffer[count] = '\0';
X	if ((keysym == XK_Return) || (keysym == XK_KP_Enter) ||
X			(keysym == XK_Linefeed))  {
X		di_gotprog(di_ldplayer, istring);
X		return;
X	} else if (((keysym >= XK_KP_Space) && (keysym <= XK_KP_9)) ||
X						 ((keysym >= XK_space) && (keysym <= XK_asciitilde)))  {
X		if ((strlen(istring) + strlen(buffer)) >= STR_MAXLEN)
X			XBell(dpy, 0);
X		else
X			strcat(istring, buffer);
X	} else if ((keysym >= XK_Shift_L) && (keysym <= XK_Hyper_R))  {
X	}	else if ((keysym >= XK_F1) && (keysym <= XK_F35))  {
X		if (buffer == NULL)
X			XBell(dpy, 0);
X		else if ((strlen(istring) + strlen(buffer)) >= STR_MAXLEN)
X			XBell(dpy, 0);
X		else
X			strcat(istring, buffer);
X	} else if ((keysym == XK_BackSpace) || (keysym == XK_Delete))  {
X		if ((length = strlen(istring)) > 0)  {
X			istring[length - 1] = '\0';
X			XFillRectangle(dpy, di_win2, di_cybgc,
X										 start_x, start_y - di_sfontstr->ascent,
X										 di_win2w - di_picsize*2 - di_butbw*5,
X										 di_sfontstr->ascent + di_sfontstr->descent);
X			XDrawString(dpy, di_win2, di_cytgc, start_x, start_y, istring, length-1);
X		} else
X			XBell(dpy, 0);
X	} else {
X		XBell(dpy, 0);
X	}
X	di_cursor(dpy, di_win2, FALSE);
X	XDrawString(dpy, di_win2, di_cytgc, start_x, start_y,
X							istring, count = strlen(istring));
X	cursor[0].x = start_x + XTextWidth(di_sfontstr, istring, count);
X	di_cursor(dpy, di_win2, TRUE);
X}
X
X#endif  /* X11_DISP */
END_OF_FILE
if test 9686 -ne `wc -c <'di_load.c'`; then
    echo shar: \"'di_load.c'\" unpacked with wrong size!
fi
# end of 'di_load.c'
fi
if test -f 'build_siminstr' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'build_siminstr'\"
else
echo shar: Extracting \"'build_siminstr'\" \(2539 characters\)
sed "s/^X//" >'build_siminstr' <<'END_OF_FILE'
X#!/bin/csh -f
X
Xset noglob
X
Xset oplist = (dat mov add sub jmp jmz jmn djn cmp spl slt)
Xset amlist = (imm dir ind dec inc)
X
Xcat <<END_OF_TOP
X#include <stdio.h>
X#include "corewar.h"
X#include "sim.h"
X
X#define  INRANGE
X#define  DRAW(a, b)
X#define  INTERACTIVE  FALSE
X#define  IMM1  FALSE
X#define  IMM2  FALSE
X
XEND_OF_TOP
X
Xforeach op ($oplist)
X  sed -n "/instruction op_$op/,/instruction done/p" <sim.c >/tmp/op_$op
Xend
X
Xforeach ama ($amlist)
X  sed -n "/fetch am_$ama/,/fetch done/p" <sim.c >/tmp/am_$ama
Xend
X
Xforeach op ($oplist)
X  set opinfo = `grep "instruction op_$op" sim.c`
X  foreach ama ($amlist)
X    if ("$ama" == "imm") then
X      cat <<IMM1_SETUP
X#undef   IMM1
X#define  IMM1  TRUE
XIMM1_SETUP
X    endif
X    foreach amb ($amlist)
X      cat <<END_OF_FPROLOG
Xstatic int  ${op}_${ama}_${amb}(thread_t *th,
X                        core_el_t *core,
X                        aval_t w_radius,
X                        aval_t coresize,
X                        aval_t xeq_addr,
X                        aval_t arg1,
X                        aval_t arg2)  {
X	aval_t  addr1, val1;
X	aval_t  addr2, val2;
X#define  USAGE  $opinfo[4]
X#define  ADDR   addr1
X#define  VAL    val1
X#define  ARG    arg1
X#define  TMP1   tmp11
X#define  TMP2   tmp12
XEND_OF_FPROLOG
X      if (("$ama" == "dec") || ("$ama" == "inc")) echo "	aval_t  tmp11, tmp12;"
X      if (("$amb" == "dec") || ("$amb" == "inc")) echo "	aval_t  tmp21, tmp22;"
X      cat </tmp/am_$ama
X      cat <<END_OF_ARG1
X#undef   USAGE
X#undef   ADDR
X#undef   VAL
X#undef   ARG
X#undef   TMP1
X#undef   TMP2
X#define  USAGE  $opinfo[5]
X#define  ADDR   addr2
X#define  VAL    val2
X#define  ARG    arg2
X#define  TMP1   tmp21
X#define  TMP2   tmp22
XEND_OF_ARG1
X      cat </tmp/am_$amb
X      cat <<END_OF_ARG2
X#undef  USAGE
X#undef  ADDR
X#undef  VAL
X#undef  ARG
XEND_OF_ARG2
X      if ("$amb" == "imm") then
X        cat <<IMM2_SETUP
X#undef   IMM2
X#define  IMM2  TRUE
XIMM2_SETUP
X      endif
X      cat </tmp/op_$op
X      if ("$amb" == "imm") then
X        cat <<IMM2_TEARDOWN
X#undef   IMM2
X#define  IMM2  FALSE
XIMM2_TEARDOWN
X      endif
X      cat <<END_OF_FTRAILER
X#undef  TMP1
X#undef  TMP2
X}
XEND_OF_FTRAILER
X    end
X    if ("$ama" == "imm") then
X      cat <<IMM1_TEARDOWN
X#undef   IMM1
X#define  IMM1  FALSE
XIMM1_TEARDOWN
X    endif
X  end
Xend
X
Xforeach op ($oplist)
X  rm /tmp/op_$op
Xend
X
Xforeach ama ($amlist)
X  rm /tmp/am_$ama
Xend
X
X
Xcat <<END_OF_JTHEAD
X
X
Xpintfunc  jmptable[] = {
XEND_OF_JTHEAD
X
Xforeach op ($oplist)
X  foreach ama ($amlist)
X    foreach amb ($amlist)
X      echo ${op}_${ama}_${amb},
X    end
X  end
Xend
Xecho 'NULL};'
END_OF_FILE
if test 2539 -ne `wc -c <'build_siminstr'`; then
    echo shar: \"'build_siminstr'\" unpacked with wrong size!
fi
chmod +x 'build_siminstr'
# end of 'build_siminstr'
fi
if test -f 'sim.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'sim.h'\"
else
echo shar: Extracting \"'sim.h'\" \(487 characters\)
sed "s/^X//" >'sim.h' <<'END_OF_FILE'
X/* sim.h */
X
X#define  TBLOCK_SIZE  100
X
Xtypedef struct  tblock_struct  {
X	thread_t  threads[TBLOCK_SIZE];
X	struct tblock_struct  *next;
X} tblock_t;
X
Xtypedef struct  tlist_struct  {
X	thread_t  *head, *empty;
X	tblock_t  *tblock;
X	unsigned  count, id;
X	aval_t  ld_start;
X	struct tlist_struct  *next, *prev;
X} tlist_t;
X
X#define  US_NONE   0
X#define  US_ADDR   1
X#define  US_VAL    2
X#define  US_RANGE  4
X
Xextern tlist_t  *sim_tlist;
Xextern int  sim_create_thread(thread_t *th, aval_t addr);
END_OF_FILE
if test 487 -ne `wc -c <'sim.h'`; then
    echo shar: \"'sim.h'\" unpacked with wrong size!
fi
# end of 'sim.h'
fi
if test -f 'asm.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'asm.h'\"
else
echo shar: Extracting \"'asm.h'\" \(848 characters\)
sed "s/^X//" >'asm.h' <<'END_OF_FILE'
X/* asm.h */
X
Xextern void  asm_error_loc(unsigned line);
X
Xextern unsigned  asm_line_number;
X#ifdef  LEX
Xextern char  yytext[];
X#else  /* LEX */
Xextern char  *yytext;
X#endif  /* LEX */
Xextern FILE  *yyin;
X
Xtypedef struct ptree_struct  {
X	enum {pt_uminus, pt_add, pt_sub, pt_mul, pt_div, pt_end}  parsetype;
X	aval_t  val;
X	char  str[STR_MAXLEN];
X	struct ptree_struct  *left, *right;
X	unsigned  line;
X} ptree_t;
X
Xtypedef struct argtop_struct  {
X	amode_t  mode;
X	ptree_t  *pt;
X} argtop_t;
X
Xtypedef struct stmt_struct  {
X	op_t  op;
X	char  str[STR_MAXLEN];
X	argtop_t  *a;
X	argtop_t  *b;
X	aval_t  addr;
X	unsigned  marked, line;  /* To prevent recursive EQUs. */
X	struct stmt_struct  *next;
X} stmt_t;
X
Xtypedef union  {
X	stmt_t  *stmt;
X  op_t  op;
X	amode_t  am;
X	argtop_t  *argtop;
X	ptree_t  *ptree;
X	aval_t  val;
X} asm_yytype;
X
X#define  YYSTYPE  asm_yytype
END_OF_FILE
if test 848 -ne `wc -c <'asm.h'`; then
    echo shar: \"'asm.h'\" unpacked with wrong size!
fi
# end of 'asm.h'
fi
if test -f 'koth.1' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'koth.1'\"
else
echo shar: Extracting \"'koth.1'\" \(6028 characters\)
sed "s/^X//" >'koth.1' <<'END_OF_FILE'
X.\" I really don't like to write man pages.
X.ds ]W Koth V3.1
X.TH KOTH 1 "1 November 1992"
X.SH NAME
Xkoth \- Corewar, the assembly language programming game
X.SH SYNOPSIS
X.LP
X.B koth -help
X.LP
X.B koth
X[
X.I <options>
X]
X.I file1 file2 ... filen
X.SH DESCRIPTION
XThis is a very brief overview of the King of the Hill corewar program.  It was
Xoriginally written purely to be used in an automated, continuous corewar
Xtournament but has since been expanded to have a graphic interface.  This is
Xan ICWS '88 compatible version of corewar with the exceptions listed at the
Xend of this document.
X.LP
XThis document assumes that the reader is already familiar with corewar.  For
Xa good introduction, see the two original documents on corewar.  They can
Xbe found in the ``Computer Recreations'' column of Scientific American, issues;
Xsee the end of this man page for the exact issues.
X.SS Redcode Test Assembler
XIf only one file is listed on the command line,
X.B koth
Xwill test assemble
Xthe file listed.  If assembly is successful, a post-assembly version of the
Xprogram will be written to stdout and
X.B koth
Xwill terminate with an exit code of 0.  If assembly fails, an error message
Xwill be printed instead and
X.B koth
Xwill exit with a nonzero exit code.
X.SS Tournament Play
XWhen running
X.B koth
Xas a tournament system, simply specify the
X.B \-rounds
X.I n
Xswitch.  All other switches are legal with the
X.B \-rounds
Xswitch.  When in this mode, all programs listed will be placed into core and
Xa will fight until one is left or the specified number of rounds expire.
XAfter, a printout of the scores will arrive; the format is
X.I n
Xrows of
X.I n
Xcolumns, where
X.I n
Xis the number of programs competing.  Each row is the results for a fighter;
Xthe first number is how many times this fighter was the only program left,
Xthe second number is how many times it and one other program tied, etc.
XFor example:
X.nf
X.ft B
X% koth \-rounds 4 dwarf.rc gemini.rc imp.rc
X1 2 1
X0 1 1
X0 1 1
X%
X.ft
X.fi
XThe first line indicates that
X.B dwarf.rc
Xwas the only program left once; there were two rounds where
X.B dwarf.rc
Xand one other program were left alive at the end of the round; and one round
Xwhere both programs were left alive with
X.B dwarf.rc
Xat the end.  The second and third line describe the results for
X.B gemini.rc
Xand
X.B imp.rc
Xin similar ways.
X.SS Interactive play
XOn an X-windows system corewar can be played interactively.  This is extremely
Xuseful for debugging corewar programs being written.  To play interactively,
Xsimply do not use the
X.B \-rounds
Xswitch and do not list any program to run.  The display for interactive
Xcorewar contains, in the center, a map of the core (8000 cells are displayed;
Xif the
X.B \-coresize
Xswitch is used, this may not be the entire core).  On the map different
Xprograms will be displayed in different colors.  Also, there are slight
Xdifferences between cells last used as data or program; cells where execution
Xis pending are also slightly different.  Each program will have it's name
Xdisplayed in a box beside the core (to set the name of a program, include a
Xline
X.RB `` ;Name
X.IR Program_name ''
Xin the listing.)  Below the program name is the number of processes from the
Xprogram left alive.  At the very bottom of the display are the current cycle
Xnumber and a set of control buttons.  Using the buttons it is possible to
Xset through the rounds or proceed at variable rates.
X.LP
XWhile in interactive play, there are keyboard shortcuts to the buttons on
Xthe screen.  Pressing ``q'' is equivalent to the ``Quit'' button, ``1'' through
X``9'' are nine different speeds of simulation, and ``Return'', ``Space'', and
X``0'' are all equivalent to the ``Stop/Step'' button.
X.LP
XDissasembling the programs currently in core is also possible.  When the
Xmouse button is in the central core display, a rectangle will be drawn around
Xa number of instructions.  Clicking with the mouse will pop up a window
Xcontaining a disassembly of these instructions.  On this window there will
Xalso be an "OK" button which closes the window and a scroll bar to move the
Xregion that is disassembled.  Any number of disassembly windows may be
Xopened at a time; the only limit is the number of windows that the system
Xyou are using can support.
X.SH OPTIONS
XFor a complete list of options, try:
X.nf
X.ft B
Xkoth \-help
X.ft
X.fi
X.LP
XSome options need more explanation.
X.B \-wdist
X.I dist
Xsets the maximum distance a process can write.  When this switch is in effect,
Xany time a program attemts to write to the core, if that write is more than
X.I dist
Xinstructions from the process itself, the core will be left unmodified.  The
Xinstruction continues executing as usual, however.  This will affect all
Xwrites to core, including predecrements, postincrements, etc.
X.LP
X.B \-splitid
Xis intended to weaken ``vampiric'' captures - that is, where a program forces
Xa process to jump to a section of code that splits off so many processes that
Xthe opponent is completely crippled.  If
X.B \-splitid
Xis in effect, any
X.B SPL
Xinstruction must have the proper ID number in it's B argument.  To insert this
XID number into your program, just use ID.  For example:
X.nf
X.ft B
X	spl newproc,#id
X.ft
X.fi
Xwill split off a new process.  Since the opponent will not know your id, it
Xwill not easily be able to force your program to split off new processes.
XThe id chosen will be the loading address of your program; thus it will
Xchange with each game, but it will be repeatable.
X.SH DEVIATIONS FROM ICWS '88 STANDARD
XThe greatest deviation from the ICWS '88 standard (besides the options
Xprovided) is that commas are required between the A and B arguments to an
Xoperator.  Another difference is that ICWS '88 vaguely implies that all
Xprocessing is done in-memory, while this program does processing in-register.
XIf you don't know what in-memory and in-register mean, then it doesn't matter;
Xit's a very nitpicky detail of MARS processing.
X.SH SEE ALSO
X.na
XScientific American, May 1984
XScientific American, sometime in 1986
X.SH AUTHOR
XBill Shubert (wms@ssd.intel.com)
END_OF_FILE
if test 6028 -ne `wc -c <'koth.1'`; then
    echo shar: \"'koth.1'\" unpacked with wrong size!
fi
# end of 'koth.1'
fi
if test -f 'README' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'README'\"
else
echo shar: Extracting \"'README'\" \(2908 characters\)
sed "s/^X//" >'README' <<'END_OF_FILE'
X   OK, here are the sources to KotH corewar.  It is the program used by the
XKotH tournament corewar server.  It can be useful for testing corewar programs;
Xit has no extensive debugging capabilities, but it is a graphic interface for
Xcorewar.
X
X
XCOMPILING KOTH COREWAR:
X
X   KotH requires an ANSI C compiler.  "gcc" is recommended.  It is available
Xfree of charge from the Free Software Foundation via anonymous FTP to
X"prep.ai.mit.edu" in the directories /pub/gnu/...
X
X   In addition, if "flex" and "bison" are available on your system they are
Xrecommended for use.  Typically they produce better code than "lex" and
X"yacc", although if flex and/or bison are unavailable lex and yacc will work.
Xflex and bison are also available from the Free Software Foundation.
X
X   To compile, type the command "mkbuild".  This will create a makefile and
Xcompile koth.  It should work as is on most systems.  If the compilation
Xfails with a message "To compile koth you must have an ANSI C compiler",
Xit means that if it did find a C compile it was not ANSI compatible.
X   If your system DOES have an ANSI C compiler but "mkbuild" didn't find it,
Xyou can try "mkbuild" again and type the C compiler name and arguments
Xneeded on the "mkbuild" line.  For example,
X
X	% mkbuild my_cc -O5
X
Xwill tell mkbuild to create a Makefile that uses "my_cc" as the C compiler
Xand uses "-O5" as a switch to "my_cc".  In general, you should always turn
Xoptimization up as high as it can go.
X
X   PLEASE mail any bugs you come across to me.  I am trying to make KotH
Xrun on as many different systems as possible, so any information you have on
Xfunctions that aren't found, etc. would be very helpful.
X
X   Suggestions are also welcome.
X
X
XA GUIDE TO THE VERSIONS OF KOTH:
X
XPre-2.0: No graphic interface.  Used only for tournament play.  Never widely
X     released.
X
X2.0: First version with a graphic interface, and first version released by
X     a notice on rec.games.corewar.
X
X2.1: Added stop/slow/fast buttons, capability for more than two programs at
X     once, "-killkids", "-wdist", and "-postinc" options.  Minor bug fixes.
X
X2.2: Added load/unload/quit/restart buttons.  More minor bug fixes.
X
X2.3: Fixed bug in program loading.  Added color.  Minor display improvements.
X
X2.4: Made tournament play 3 to 4 times faster.  Added code for standard X
X     switches ("-geometry", "-iconic", etc.).  Fixed bugs that made program
X     fail on X11R3 and X11R4.
X
X2.5: Fixed bug in ">" introduced in V2.4.  Minor bug fixes to user interface.
X
X2.5.1: This is not a real release.  It is a test version of KotH mailed to
X     a few sites to test the "mkbuild" system.
X
X3.0: More portable (no longer needs Flex, Bison or X), split IDs, plus first
X     primitive disassembly on the fly feature.
X
X3.1: Read disassembly windows.
X
XPlanned:  Minor improvements to disassembly windows (breakpoints, better
X   scroll bars, etc.)
X
X				-Bill (wms@ssd.intel.com)
END_OF_FILE
if test 2908 -ne `wc -c <'README'`; then
    echo shar: \"'README'\" unpacked with wrong size!
fi
# end of 'README'
fi
if test -f 'mkbuild' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'mkbuild'\"
else
echo shar: Extracting \"'mkbuild'\" \(4593 characters\)
sed "s/^X//" >'mkbuild' <<'END_OF_FILE'
X#!/bin/csh -f
X
Xrm Makefile
Xset cfound = 0
Xset clibs = ""
Xif ($#argv > 0) then
X  set cfound = 1
X  set cc = $argv[1]
X  set cflags = "$argv[2-]"
Xendif
X
Xecho Building the Makefile for koth.
Xecho " "
Xecho Looking for an Ansi C compiler
X
Xcat <<EOF >ansi_test.c
Xmain(int argc, char *argv[])  {
X	printf("Hello," " world");
X	exit(0);
X}
XEOF
X
Xif (! $cfound) then
X  # Find your own.
X  echo '  Trying for "gcc"...'
X  set cc = gcc
X  set cflags = "-O2"
X  ${cc} ${cflags} ansi_test.c -c -o ansi_test >& /dev/null
X  if ($status == 0) then
X    echo "  gcc found."
X    set cfound = 1
X  else
X    echo '  gcc not found.  Trying for "cc"...'
X    set cc = "cc"
X    set cflags = "-O"
X    if (`uname` == "HP/UX") then
X      set cflags = ($cflags "-Aa -D_HPUX_SOURCE")
X      set clibs = ($clibs "-lBSD")
X    endif
X  endif
Xendif
X
X${cc} ${cflags} ansi_test.c -c -o ansi_test >& /dev/null
Xif ($status == 0) then
X  echo ' ' \"$cc\" is ANSI C.
Xelse
X  echo ' ' \"$cc\" is either not found or is not Ansi C.  To compile koth
X  echo "    you must have an ANSI C compiler.  Please see the README file"
X  echo "    for directions on how to specify the location of an Ansi C"
X  echo "    compiler."
X  exit 1
Xendif
X
Xecho " "
Xecho Looking for a lexer generator.
Xecho '  Trying for "flex"...'
Xset lex = flex
Xset lexfound = `which $lex`
Xif ($#lexfound > 1) then
X  set cflags = ($cflags "-DLEX")
X  echo '  Trying for "lex"...'
X  set lex = lex
X  set lexfound = `which $lex`
X  if ($#lexfound > 1) then
X    echo "  No lexer found.  To compile koth you must have a lexer."
X    exit 1
X  else
X    set clibs = ($clibs "-ll")
X  endif
Xelse
X  set cflags = ($cflags "-DFLEX")
Xendif
Xecho "  $lex found."
X
Xif ($lex == "flex") then
X  set lex = "flex -i"
Xendif
X
Xecho " "
Xecho Looking for a parser generator.
Xecho '  Trying for "bison"...'
Xset parse = bison
Xset pfound = `which $parse`
Xif ($#pfound > 1) then
X  set cflags = ($cflags "-DYACC")
X  echo '  Trying for "yacc"...'
X  set parse = yacc
X  set pfound = `which $parse`
X  if ($#pfound > 1) then
X    echo "  No parser found.  To compile koth you must have a parser."
X    exit 1
X  endif
Xelse
X  set cflags = ($cflags "-DBISON")
Xendif
Xecho "  $parse found."
X
Xecho " "
Xecho "Looking for X11."
X${cc} ${cflags} ansi_test.c -o ansi_test -lX11 >& /dev/null
Xif ($status == 0) then
X  set cflags = ($cflags "-DX11_DISP")
X  echo "  X11 found."
X  set clibs = ($clibs "-lX11" "-lm")
Xelse
X  set cflags = ($cflags "-DNO_DISP")
X  echo "  X11 not found.  No display code will be built."
Xendif
X
Xrm ansi_test.c ansi_test
X
Xcat <<EOF >Makefile
X# This program uses Flex, Bison, and Gnu CC to build the assembler.
X# All are available free of charge from the Free Software Foundation.
X# Get them by anonymous FTP to prep.ai.mit.edu in the directories
X#   /pub/gnu/...
XCC = $cc
XCFLAGS = $cflags
X
XPROGNAME = koth
X
XOBJS = cwmain.o asm_parse.o sim.o clparse.o disp.o di_timer.o di_recalc.o  \\
X       di_draw.o di_input.o ldaddr.o di_load.o siminstr.o asm_lex.o gbut.o \\
X       di_dis.o di_but.o
X
XSOURCES = corewar.h sim.c clparse.c asm_lex.flex asm_parse.y clparse.h     \\
X          ldaddr.c di_recalc.c di_draw.c cwdisp.h di_load.c build_siminstr \\
X          sim.h asm.h koth.1 README mkbuild disp.c cwmain.c di_timer.c     \\
X          di_input.c di_dis.c gbut.c di_but.c gbut.h
X
X\$(PROGNAME):	\$(OBJS)
X	\$(CC) -o \$(PROGNAME) \$(CFLAGS) \$(OBJS) ${clibs}
X
X\$(PROGNAME).shar:	\${SOURCES}
X	shar \${SOURCES} > \$(PROGNAME).shar
X
Xasm_lex.c:	asm_lex.flex
X	${lex} asm_lex.flex
X	mv lex.yy.c asm_lex.c
X
XEOF
X
Xif ($parse == "bison") then
X  cat <<EOF >>Makefile
Xasm_parse.h asm_parse.c:	asm_parse.y
X	bison asm_parse.y -d -o asm_parse.c
X
XEOF
Xelse
X  cat <<EOF >>Makefile
Xasm_parse.h asm_parse.c:	asm_parse.y
X	yacc -d asm_parse.y
X	mv y.tab.h asm_parse.h
X	mv y.tab.c asm_parse.c
X
XEOF
Xendif
X
Xcat <<EOF >>Makefile
Xsiminstr.c:	build_siminstr sim.c
X	@echo Building siminstr.c: This may take a long time.
X	build_siminstr > siminstr.c
X
X.c.o:
X	\$(CC) -c \$(CFLAGS) \$<
X
Xcwmain.o:	corewar.h clparse.h
Xasm_parse.o:	corewar.h asm.h
Xasm_lex.o:	corewar.h asm_parse.h asm.h
Xsim.o:	corewar.h sim.h
Xclparse.o:	corewar.h clparse.h
Xdisp.o:	corewar.h cwdisp.h gbut.h
Xdi_timer.o:	corewar.h cwdisp.h gbut.h
Xdi_recalc.o:	corewar.h cwdisp.h gbut.h
Xdi_draw.o:	corewar.h cwdisp.h gbut.h
Xdi_input.o:	corewar.h cwdisp.h gbut.h
Xldaddr.o:	corewar.h
Xdi_load.o:	corewar.h cwdisp.h gbut.h
Xsiminstr.o:	corewar.h sim.h
Xdi_dis.o:	corewar.h cwdisp.h gbut.h
Xdi_but.o:	corewar.h cwdisp.h gbut.h
Xgbut.o:	gbut.h
X
Xclean:
X	rm \$(OBJS) asm_parse.c asm_lex.c \$(PROGNAME).shar asm_parse.h \\
X		siminstr.c
XEOF
X
Xecho 'Makefile built.  Running make.'
X
Xmake clean >& /dev/null
Xmake
END_OF_FILE
if test 4593 -ne `wc -c <'mkbuild'`; then
    echo shar: \"'mkbuild'\" unpacked with wrong size!
fi
chmod +x 'mkbuild'
# end of 'mkbuild'
fi
if test -f 'disp.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'disp.c'\"
else
echo shar: Extracting \"'disp.c'\" \(17926 characters\)
sed "s/^X//" >'disp.c' <<'END_OF_FILE'
X/*
X * disp.c
X */
X
X#ifdef  X11_DISP
X
X#include <stdio.h>
X#include <signal.h>
X#include <sys/ioctl.h>
X#include <X11/Xlib.h>
X#include <X11/Xutil.h>
X#include "corewar.h"
X#include "cwdisp.h"
X
X/*
X * Values that describe the X environment that I keep around as globals.
X * Shame on me!
X */
Xaval_t di_next_move = AVAL_NOGOOD;
Xint  di_next_player;
Xunsigned long  di_stdfg, di_stdbg;
Xunsigned  di_depth, di_picsize;
XWindow  di_win;
XXFontStruct  *di_bfontstr, *di_sfontstr, *di_ffontstr;
XFont  di_bfont, di_sfont, di_ffont;
XDisplay  *di_dpy;
Xunsigned  di_winw = -1, di_winh = -1, di_width, di_height;
Xint  di_ti_x, di_ti_y, di_color;
XColormap  di_cmap;
X
X/* Local stuff, used for the overall init only. */
X#define kothicon_width 51
X#define kothicon_height 51
Xstatic char kothicon_bits[] = {
X   0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
X   0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
X   0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xf0, 0x00, 0x00, 0x00, 0x00,
X   0x00, 0x07, 0x00, 0x07, 0x20, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x18, 0x10,
X   0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x08, 0x00, 0x00, 0x18, 0x00, 0x00,
X   0xc0, 0x04, 0x00, 0x00, 0x04, 0x00, 0x07, 0x00, 0x03, 0x00, 0x00, 0x02,
X   0xf0, 0x7a, 0x00, 0x02, 0x00, 0x00, 0x01, 0x0c, 0x82, 0x01, 0x04, 0x00,
X   0x00, 0x01, 0x03, 0x02, 0x06, 0x04, 0x00, 0x80, 0x80, 0x00, 0x02, 0x08,
X   0x08, 0x00, 0x40, 0x40, 0x00, 0x02, 0x10, 0x10, 0x00, 0x40, 0x20, 0x00,
X   0x02, 0x28, 0x10, 0x00, 0x20, 0x10, 0x00, 0x02, 0x44, 0x20, 0x00, 0x20,
X   0x10, 0x00, 0x02, 0x42, 0x20, 0x00, 0x20, 0x08, 0x80, 0x0a, 0x81, 0x20,
X   0x00, 0x10, 0x08, 0x40, 0x92, 0x80, 0x40, 0x00, 0x10, 0x04, 0xa0, 0x4a,
X   0x00, 0x41, 0x00, 0x10, 0x04, 0x50, 0x22, 0x00, 0x41, 0x00, 0x10, 0x04,
X   0xa8, 0x92, 0x00, 0x41, 0x00, 0x08, 0x04, 0x54, 0x4a, 0x01, 0x81, 0x00,
X   0x08, 0x02, 0x00, 0x06, 0x00, 0x82, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
X   0x83, 0x07, 0x08, 0x02, 0x00, 0x03, 0x00, 0x82, 0x00, 0x08, 0x44, 0x95,
X   0x52, 0x15, 0x81, 0x00, 0x10, 0xa4, 0x4a, 0xaa, 0x2a, 0x41, 0x00, 0x10,
X   0x54, 0x25, 0x52, 0x55, 0x41, 0x00, 0x10, 0xa4, 0x92, 0xaa, 0x2a, 0x41,
X   0x00, 0x10, 0x48, 0x49, 0x52, 0x95, 0x40, 0x00, 0x20, 0xa8, 0xa4, 0xaa,
X   0xaa, 0x20, 0x00, 0x20, 0x50, 0x52, 0x52, 0x55, 0x20, 0x00, 0x20, 0x10,
X   0xa9, 0xaa, 0x4a, 0x20, 0x00, 0x40, 0xa0, 0x54, 0x52, 0x25, 0x10, 0x00,
X   0x40, 0x40, 0xaa, 0xaa, 0x12, 0x10, 0x00, 0x80, 0xa0, 0x54, 0x52, 0x09,
X   0x08, 0x00, 0x00, 0x11, 0xa3, 0x2a, 0x06, 0x04, 0x00, 0x00, 0x09, 0x0c,
X   0x82, 0x01, 0x04, 0x00, 0x00, 0x06, 0xf0, 0x7a, 0x00, 0x02, 0x00, 0x00,
X   0x06, 0x00, 0x07, 0x00, 0x01, 0x00, 0x00, 0x19, 0x00, 0x02, 0xc0, 0x00,
X   0x00, 0x80, 0x20, 0x00, 0x02, 0x20, 0x00, 0x00, 0x40, 0xc0, 0x00, 0x02,
X   0x18, 0x00, 0x00, 0x20, 0x00, 0x07, 0x02, 0x07, 0x00, 0x00, 0x00, 0x00,
X   0x78, 0xf2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0f, 0x00, 0x00, 0x00,
X   0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
X   0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00};
X#define kothmask_width 51
X#define kothmask_height 51
Xstatic char kothmask_bits[] = {
X   0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00,
X   0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
X   0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0x00, 0x00, 0x00, 0x00,
X   0x00, 0xff, 0xff, 0x07, 0x30, 0x00, 0x00, 0xc0, 0xff, 0xff, 0x1f, 0x18,
X   0x00, 0x00, 0xe0, 0xff, 0xff, 0x3f, 0x0c, 0x00, 0x00, 0xf8, 0xff, 0xff,
X   0xff, 0x06, 0x00, 0x00, 0xfc, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0xfe,
X   0xff, 0xfb, 0xff, 0x03, 0x00, 0x00, 0xff, 0x0f, 0x83, 0xff, 0x07, 0x00,
X   0x00, 0xff, 0x03, 0x03, 0xfe, 0x07, 0x00, 0x80, 0xff, 0x00, 0x03, 0xf8,
X   0x0f, 0x00, 0xc0, 0x7f, 0x00, 0x03, 0xf8, 0x1f, 0x00, 0xc0, 0x3f, 0x00,
X   0x03, 0xec, 0x1f, 0x00, 0xe0, 0x1f, 0x00, 0x03, 0xc6, 0x3f, 0x00, 0xe0,
X   0x1f, 0x00, 0x07, 0xc3, 0x3f, 0x00, 0xe0, 0x0f, 0x80, 0x8f, 0x81, 0x3f,
X   0x00, 0xf0, 0x0f, 0xc0, 0xdf, 0x80, 0x7f, 0x00, 0xf0, 0x07, 0xe0, 0x7f,
X   0x00, 0x7f, 0x00, 0xf0, 0x07, 0xf0, 0x7f, 0x00, 0x7f, 0x00, 0xf0, 0x07,
X   0xf8, 0xff, 0x00, 0x7f, 0x00, 0xf8, 0x07, 0xfc, 0xff, 0x01, 0xff, 0x00,
X   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff,
X   0xff, 0x07, 0xf8, 0x83, 0xff, 0xff, 0x0f, 0xfe, 0x00, 0xf8, 0xc7, 0xff,
X   0xff, 0x1f, 0xff, 0x00, 0xf0, 0xe7, 0xff, 0xff, 0x3f, 0x7f, 0x00, 0xf0,
X   0xf7, 0xff, 0xff, 0x7f, 0x7f, 0x00, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x7f,
X   0x00, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0xe0, 0xff, 0xff, 0xff,
X   0xff, 0x3f, 0x00, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0xe0, 0xff,
X   0xff, 0xff, 0xff, 0x3f, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00,
X   0xc0, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff,
X   0x0f, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0xff, 0xff,
X   0xff, 0xff, 0x07, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00,
X   0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x80, 0xf9, 0xff, 0xff, 0xff, 0x00,
X   0x00, 0xc0, 0xe0, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x60, 0xc0, 0xff, 0xff,
X   0x1f, 0x00, 0x00, 0x30, 0x00, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00,
X   0xf8, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0f, 0x00, 0x00, 0x00,
X   0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00,
X   0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00};
Xstatic int  last_cyc = 0;
X
X/* Values describing the core display of the screen. */
Xunsigned  di_co_xoff, di_co_yoff;
Xchar  *di_co_pics = NULL;
XPixmap  di_pixmaps[MAXPICS];
XPixmap  di_bigpixmaps[MAXPICS];
XGC  di_picgc[MAXPICS];
Xint  *di_picmap;
Xint  di_nprocs[DI_MAXPLAYERS], di_nalive;
Xint  di_state = DS_STOPPED, di_slopos;
Xfloat  di_speed;
X
X/* Values describing the player status windows. */
Xdi_plstatinfo  di_plstat[DI_MAXPLAYERS];
X
X/* Values describing the cycles display. */
Xint  *di_cyx = NULL, di_cyty, di_cyby, *di_cyw = NULL, di_cyh;
XGC  di_cytgc, di_cybgc;
X
X/* Buttons! */
Xunsigned  di_butbw;
XGC  di_butgc, di_butlgc, di_butdgc;
X
X/* Global info. */
Xprogram_t  di_progs[DI_MAXPLAYERS];
Xunsigned  di_cycles = 0;
X
Xstatic void  ehandle(Display *dpy), stealth();
Xstatic void  di_mainloop(Display *dpy, Window win, int fightlen);
X
X
Xvoid  di_init(char *progname, char *geometry, char *dpyname, int iconic,
X              unsigned fightlen)  {
X	Window  win;
X	int  win_x, win_y;  /* Window position on screen. */
X	unsigned  win_w, win_h;
X	Display  *dpy;
X	char  *display_name;
X	XSizeHints  xsh;
X	XWMHints  wm_hints;
X	XClassHint  class_hints;
X	XTextProperty  windowName, iconName;
X	XWindowAttributes  xwa;
X	unsigned  i, hintmask;
X	int  defscr;
X	XVisualInfo  xvi;
X	Pixmap  koth_pixmap, mask_pixmap;
X	XSizeHints  size_hints;
X	char  *cw_name = "Corewar";
X
X	if ((dpy = di_dpy = XOpenDisplay(dpyname)) == NULL)  {
X		fprintf(stderr, "%s: Can't open display \"%s\".\n", progname,
X		        XDisplayName(dpyname));
X		exit(1);
X	}
X	defscr = DefaultScreen(dpy);
X	di_depth = DefaultDepth(dpy, defscr);
X	di_cmap = DefaultColormap(dpy, defscr);
X	di_color = (XMatchVisualInfo(dpy, defscr, di_depth, StaticColor, &xvi) ||
X	            XMatchVisualInfo(dpy, defscr, di_depth, TrueColor, &xvi) ||
X	            XMatchVisualInfo(dpy, defscr, di_depth, PseudoColor, &xvi) ||
X	            XMatchVisualInfo(dpy, defscr, di_depth, DirectColor, &xvi));
X	di_stdfg = BlackPixel(dpy, defscr);
X	if (di_color)  {
X		XColor  grey75;
X
X		grey75.red = grey75.green = grey75.blue = 0.75 * MAX_CVAL;
X		grey75.flags = DoRed | DoGreen | DoBlue;
X		XAllocColor(dpy, di_cmap, &grey75);
X		di_stdbg = grey75.pixel;
X	} else
X		di_stdbg = WhitePixel(dpy, defscr);
X	hintmask = 0;
X	win_x = 0;
X	win_y = 0;
X	win_w = 700;
X	win_h = (int)((double)win_w / WHRATIO);
X	if (geometry != NULL)  {
X		char  xdir = '+', ydir = '+';
X		int  pcount;
X
X		if (geometry[0] == '=')
X			++geometry;
X		if ((geometry[0] == '+') || (geometry[0] == '-'))  {
X			hintmask |= USPosition;
X			pcount = sscanf(geometry, "%c%d%c%d", &xdir, &win_x, &ydir, &win_y);
X			if ((pcount != 4) ||
X					((xdir != '-') && (xdir != '+')) ||
X					((ydir != '-') && (ydir != '+')))  {
X				fprintf(stderr, "%s: Cannot understand geometry \"%s\".\n",
X				        progname, geometry);
X				exit(-1);
X			}
X		} else  {
X			hintmask |= USSize;
X			pcount = sscanf(geometry, "%dx%d%c%d%c%d", &win_w, &win_h,
X			                &xdir, &win_x, &ydir, &win_y);
X			if (pcount != 2)
X				hintmask |= USPosition;
X			if ((pcount != 2) && (pcount != 6) ||
X					((xdir != '-') && (xdir != '+')) ||
X					((ydir != '-') && (ydir != '+')))  {
X				fprintf(stderr, "%s: Cannot understand geometry \"%s\".\n",
X				        progname, geometry);
X				exit(-1);
X			}
X		}
X		if (xdir == '-')
X			win_x = DisplayWidth(dpy, defscr) - win_x - win_w;
X		if (ydir == '-')
X			win_y = DisplayHeight(dpy, defscr) - win_y - win_h;
X	}
X
X	win = XCreateSimpleWindow(dpy, RootWindow(dpy, defscr), win_x, win_y,
X	                          win_w, win_h, 0, di_stdbg, di_stdfg);
X	koth_pixmap = XCreateBitmapFromData(dpy, win, kothicon_bits,
X	                                    kothicon_width, kothicon_height);
X	mask_pixmap = XCreateBitmapFromData(dpy, win, kothmask_bits,
X	                                    kothmask_width, kothmask_height);
X	size_hints.flags = PPosition | PSize | PMinSize | hintmask;
X	size_hints.min_width = 200;
X	size_hints.min_height = 150;
X#ifdef  X11R3
X	size_hints.x = win_x;
X	size_hints.y = win_y;
X	size_hints.width = win_w;
X	size_hints.height = win_h;
X	XSetStandardProperties(dpy, win, "Corewar", "Corewar", koth_pixmap,
X												 NULL, 0, &size_hints);
X#else  /* X11R4 or later. */
X	{
X		XWMHints  wm_hints;
X		XClassHint  class_hints;
X		XTextProperty windowName, iconName;
X		char  *dumb_argv[] = {NULL};
X
X		if (XStringListToTextProperty(&cw_name, 1, &windowName) == 0)  {
X			fprintf(stderr, "Cannot allocate windowName.\n");
X			exit(-1);
X		}
X		if (XStringListToTextProperty(&cw_name, 1, &iconName) == 0)  {
X			fprintf(stderr, "Cannot allocate windowName.\n");
X			exit(-1);
X		}
X		if (iconic)
X			wm_hints.initial_state = IconicState;
X		else
X			wm_hints.initial_state = NormalState;
X		wm_hints.input = TRUE;
X		wm_hints.icon_pixmap = koth_pixmap;
X		wm_hints.icon_mask = mask_pixmap;
X		wm_hints.flags = StateHint | IconPixmapHint | IconMaskHint | InputHint;
X		class_hints.res_name = "koth";
X		class_hints.res_class = "Basicwin";
X		XSetWMProperties(dpy, win, &windowName, &iconName, dumb_argv, 0,
X										 &size_hints, &wm_hints, &class_hints);
X	}
X#endif  X11R3
X	di_win = win;
X	XSelectInput(dpy, win, ExposureMask | StructureNotifyMask |
X							 PointerMotionMask | ButtonPressMask | KeyPressMask |
X							 ButtonReleaseMask | KeyReleaseMask);
X	XMapWindow(dpy, win);
X	gbut_init(dpy, win);
X	di_in_init();
X	di_dis_init();
X	XGetWindowAttributes(dpy, win, &xwa);
X	di_nalive = 0;
X	for (i = 0;  i < DI_MAXPLAYERS;  ++i)
X		di_nprocs[i] = NOTLOADED;
X	di_reset_cy();
X	interactive = TRUE;
X	di_redraw(dpy, win, &xwa, 0, 0, xwa.width, xwa.height);
X	signal(SIGQUIT, di_exit);
X	/* OK, window is opened.  Time to go stealth, as xantfarm did. */
X	stealth();
X	for (;;)  {
X		if ((di_nalive == 0) || (di_cycles == -1))  {
X			last_cyc = 0;
X			di_cycles = 0;
X		}
X		do  {
X			di_mainloop(dpy, win, fightlen);
X		} while ((di_state != DS_STOPPED) && !XPending(dpy));
X		if (di_state == DS_STOPPED)  {
X			XEvent  dummy;
X
X			XPeekEvent(dpy, &dummy);  /* Wait for an event. */
X		}
X		ehandle(dpy);
X	}
X}
X
X
Xstatic void  di_mainloop(Display *dpy, Window win, int fightlen)  {
X	int  cycle, n;
X	aval_t  old_nextmove;
X
X	if (di_state == DS_RUNSLOW)
X		if (!di_timer_wait(dpy))
X			return;
X	if (!di_nalive)  {
X		di_changestate(dpy, win, DS_STOPPED);
X		gbut_setflags(DI_BSTOP, GBUT_NOPRESS);
X		gbut_setflags(DI_BSLOW, GBUT_NOPRESS);
X		gbut_setflags(DI_BGO, GBUT_NOPRESS);
X		return;
X	}
X	for (cycle = last_cyc;  cycle < DI_MAXPLAYERS;  ++cycle)  {
X		if ((di_nprocs[cycle] == 0) || (di_nprocs[cycle] == NOTLOADED))
X			continue;
X		if ((di_state == DS_STOPPED) || XPending(dpy))  {
X			last_cyc = cycle;
X			return;
X		}
X		old_nextmove = di_next_move;
X		n = sim_cyc();
X		di_next_move = sim_nextaddr();
X		di_next_player = sim_nextplayer();
X		if (di_indis[old_nextmove])
X			di_fixline(old_nextmove);
X		if (di_indis[di_next_move])
X			di_fixline(di_next_move);
X		if (n != di_nprocs[cycle])  {
X			if (n == 0)  {
X				--di_nalive;
X				if (di_nalive <= 1)  {
X					di_changestate(dpy, win, DS_STOPPED);
X					if (di_nalive < 1)  {
X						gbut_setflags(DI_BSTOP, GBUT_NOPRESS);
X						gbut_setflags(DI_BSLOW, GBUT_NOPRESS);
X						gbut_setflags(DI_BGO, GBUT_NOPRESS);
X					}
X					di_draw_nprocs(cycle, di_nprocs[cycle] = n, dpy, win);
X					last_cyc = cycle;
X					return;
X				}
X			}
X			di_draw_nprocs(cycle, di_nprocs[cycle] = n, dpy, win);
X		}
X		if (di_state == DS_STEP)
X			di_state = DS_STOPPED;
X	}
X	if (cycle >= DI_MAXPLAYERS)  {
X		if (++di_cycles == fightlen)
X			di_changestate(dpy, win, DS_STOPPED);
X		di_update_cy(dpy, win);
X		last_cyc = 0;
X	}
X}
X
X
Xvoid  di_changestate(Display *dpy, Window win, int newstate)  {
X	int  oldstate = di_state, i;
X
X	if ((newstate == oldstate) && (newstate != DS_RUNSLOW))
X		return;
X	di_state = newstate;
X	switch(oldstate)  {
X	case DS_STOPPED:
X	case DS_STEP:
X		for (i = 0;  i < DI_MAXPLAYERS;  ++i)  {
X			gbut_setflags(DI_BPLAY(i), GBUT_NOPRESS);
X		}
X		if ((newstate != DS_STEP) && (newstate != DS_STOPPED))  {
X			di_but[DI_BSTOP].packet = (void *)"Stop";
X			gbut_draw(DI_BSTOP);
X			if (newstate == DS_RUNSLOW)
X				gbut_draw(DI_BSLOW);
X		}
X		break;
X	case DS_RUNSLOW:
X		di_unset_timer();
X	case DS_RUNFAST:
X		if ((newstate == DS_RUNSLOW) || (oldstate == DS_RUNSLOW))
X			gbut_draw(DI_BSLOW);
X		if ((newstate != DS_RUNFAST) && (newstate != DS_RUNSLOW))  {
X			di_but[DI_BSTOP].packet = (void *)"Step";
X			gbut_draw(DI_BSTOP);
X		}
X		break;
X	}
X}
X
X		
Xstatic void  ehandle(Display *dpy)  {
X	XEvent  event;
X	XWindowAttributes  xwa;
X	int  redraw_needed = FALSE, rdrw2 = FALSE, rdrw3 = FALSE, wagot = FALSE;
X	unsigned  rx1 = -1, ry1 = -1, rx2 = 0, ry2 = 0;
X
X	while (XPending(dpy))  {
X		XNextEvent(dpy, &event);
X		switch(event.type)  {
X		case Expose:
X			if (event.xexpose.window == di_win)  {
X				if (event.xexpose.x < rx1)
X					rx1 = event.xexpose.x;
X				if (event.xexpose.y < ry1)
X					ry1 = event.xexpose.y;
X				if (event.xexpose.x + event.xexpose.width > rx2)
X					rx2 = event.xexpose.x + event.xexpose.width;
X				if (event.xexpose.y + event.xexpose.height > ry2)
X					ry2 = event.xexpose.y + event.xexpose.height;
X				redraw_needed = TRUE;
X			} else if ((di_win2w != 0) && (event.xexpose.window == di_win2))
X				rdrw2 = TRUE;
X			else  { /* Must be a win3. */
X				XGetWindowAttributes(dpy, event.xexpose.window, &xwa);
X				di_redraw3(dpy, event.xexpose.window, xwa.x,xwa.y,
X									 xwa.width,xwa.height);
X			}
X			break;
X		case ConfigureNotify:
X			if (event.xexpose.window == di_win)  {
X				if (!wagot)  {
X					XGetWindowAttributes(dpy, di_win, &xwa);
X					wagot = TRUE;
X				}
X				if ((xwa.width != di_winw) || (xwa.height != di_winh))  {
X					redraw_needed = TRUE;
X					rx1 = 0;
X					ry1 = 0;
X					rx2 = xwa.width;
X					ry2 = xwa.height;
X				}
X			} else if ((di_win2w != 0) && (event.xexpose.window == di_win2))
X				rdrw2 = TRUE;
X			else  { /* Must be a win3. */
X				XGetWindowAttributes(dpy, event.xexpose.window, &xwa);
X				di_redraw3(dpy, event.xexpose.window, xwa.x,xwa.y,
X									 xwa.width,xwa.height);
X			}
X			break;
X		case MapNotify:  /* Who cares about these? */
X		case ReparentNotify:
X		case UnmapNotify:
X			break;
X		case DestroyNotify:  /* I should handle this correctly. */
X/*
X			fprintf(stderr, "koth: Window destroyed unexpectedly.\n");
X			exit(1);
X*/
X			break;
X		case ButtonPress:
X			di_butpress(dpy, event.xbutton.window, &(event.xbutton));
X			break;
X		case ButtonRelease:
X			di_butrelease(dpy, event.xbutton.window, &(event.xbutton));
X			break;
X		case KeyPress:
X			di_keypress(dpy, event.xkey.window, &(event.xkey));
X			break;
X		case KeyRelease:
X			di_keyrelease(dpy, event.xkey.window, &(event.xkey));
X			break;
X		case MotionNotify:
X			if (XPending(dpy))  {
X				XEvent  ev2;
X
X				XPeekEvent(dpy, &ev2);
X				if (ev2.type == MotionNotify)
X					break;
X			}
X			di_input_m(dpy, event.xmotion.window, &(event.xmotion));
X			break;
X		}
X	}
X	if (redraw_needed)  {
X		if (!wagot)
X			XGetWindowAttributes(dpy, di_win, &xwa);
X		if (rx1 == -1)  {
X			rx1 = 0;
X			ry1 = 0;
X			rx2 = xwa.width;
X			ry2 = xwa.height;
X		}
X		di_redraw(dpy, di_win, &xwa, rx1, ry1, rx2-rx1, ry2-ry1);
X	}
X	if (rdrw2)  {
X		XGetWindowAttributes(dpy, di_win2, &xwa);
X		if (xwa.map_state == IsViewable)
X			di_redraw2(dpy, di_win2, &xwa);
X	}
X}
X
X
Xvoid  di_drawaddr(aval_t addr, int val)  {
X	if (((di_picmap[addr]&~CP_M) != val) && (addr < 8000))  {
X		XFillRectangle(di_dpy, di_win, di_picgc[val],
X									 (addr % 100) * di_picsize + di_co_xoff,
X									 (addr / 100) * di_picsize + di_co_yoff,
X									 di_picsize, di_picsize);
X		if (di_picmap[addr]&CP_M)
X			di_drawoutline(addr, di_picmap[addr]);
X		di_picmap[addr] = (di_picmap[addr] & CP_M) | val;
X	}
X	if (di_indis[addr])
X		di_fixline(addr);
X}
X
X
Xvoid  di_newoutline(aval_t addr, int val)  {
X	int  oldval, pic;
X
X	addr = (addr + coresize) % coresize;
X	oldval = di_picmap[addr] & CP_M;
X	if ((oldval && val) || (!oldval && !val))
X		return;
X	pic = di_picmap[addr] & ~CP_M;
X	XFillRectangle(di_dpy, di_win, di_picgc[pic],
X								 (addr % 100) * di_picsize + di_co_xoff,
X								 (addr / 100) * di_picsize + di_co_yoff,
X								 di_picsize, di_picsize);
X	if (val)
X		di_drawoutline(addr, val);
X	di_picmap[addr] = pic | val;
X}
X
X		
Xvoid  di_exit(int  exval)  {
X	XFlush(di_dpy);
X	XCloseDisplay(di_dpy);
X	exit(exval);
X}
X
X
Xstatic void  stealth()  {
X	int pid, tty;
X
X#ifndef  DEBUG
X	pid = fork();
X	if (pid < 0)  {
X		perror("koth: fork() failed");
X		exit(1);
X	} else if (pid > 0)
X		/* Parent just exits. */
X		exit(0);
X	/* Go stealth (ditch our controlling tty). */
X	tty = open("/dev/tty", 0);
X	if (tty < 0)  {
X		perror("koth: open(\"/dev/tty\", 0) failed");
X		exit(1);
X	} else  {
X		if (ioctl(tty, TIOCNOTTY, 0) < 0)  {
X	    perror("koth: ioctl(tty, TIOCNOTTY, 0) failed");
X	    exit(1);
X		}
X		close(tty);
X	}
X#endif  DEBUG
X}
X
X
X#endif  /* X11_DISP */
END_OF_FILE
if test 17926 -ne `wc -c <'disp.c'`; then
    echo shar: \"'disp.c'\" unpacked with wrong size!
fi
# end of 'disp.c'
fi
if test -f 'cwmain.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'cwmain.c'\"
else
echo shar: Extracting \"'cwmain.c'\" \(6232 characters\)
sed "s/^X//" >'cwmain.c' <<'END_OF_FILE'
X/* cwmain.c */
X
X#include <stdio.h>
X#include "corewar.h"
X#include "clparse.h"
X
X
X/* Globals. */
Xchar  cwerrstr[STR_ERRLEN] = "";
Xchar  *opnames[] = {
X	"DAT", "MOV", "ADD", "SUB", "JMP", "JMZ", "JMN", "DJN", "CMP", "SPL", "SLT",
X	"END", "EQU", NULL};
Xchar  *amodenames[] = {
X	"immediate", "direct", "indirect", "predecrement", "postincrement"};
Xcore_el_t  *core = NULL;
X
Xaval_t  coresize = 8000;
Xaval_t  maxprogsize = 100;
Xunsigned  maxthreads = 8000;
Xunsigned  max_cycles;
Xunsigned  amode_restrict = TRUE;  /* TRUE is ICWS '88 */
Xunsigned  postinc = FALSE;  /* FALSE is ICWS '88 */
Xunsigned  rounds = 0;  /* Nonzero here means a tournament game. */
Xunsigned  w_radius, w_radius_set = FALSE; /* Maximum distance to do a write. */
Xunsigned  interactive = FALSE;
Xunsigned  split_id = FALSE;
X
Xstatic unsigned  fl_set = FALSE;
Xstatic unsigned  *wins;
Xstatic char  geometry[CLP_MAXSTRLEN + 1] = "";
Xstatic char  display[CLP_MAXSTRLEN + 1] = "";
Xstatic unsigned  iconic = FALSE;
X
Xstatic clp_info_t  cmdline[] = {
X	{"", clp_true, NULL, VERSION},
X	{"-coresize", clp_int, &coresize, "Set size of core (default = 8000)"},
X	{"-maxprogsize", clp_int, &maxprogsize,
X		 "Maximum program size (default = 100)"},
X	{"-maxprocs", clp_int, &maxthreads,
X		 "Maximum processes per program (default = 8000)"},
X	{"-fightlength", clp_int, &max_cycles,
X		 "Cycles until tie is declared (default = 10 * coresize)"},
X	{"-fightlength", clp_true, &fl_set, NULL},
X	{"-rounds", clp_int, &rounds, "Number of tournament games to play"},
X	{"", clp_true, NULL, ""},
X	{"-noall_modes", clp_true, &amode_restrict,
X		 "ICWS '88 addressing mode restrictions (default)"},
X	{"-all_modes", clp_false, &amode_restrict, "Remove restrictions"},
X	{"", clp_true, NULL, ""},
X	{"-splitid", clp_true, &split_id, "ID matching needed on SPL"},
X	{"-nosplitid", clp_false, &split_id, "No ID matching on SPL (default)"},
X	{"", clp_true, NULL, ""},
X	{"-nopostinc", clp_false, &postinc,
X		 "Disallow \">\" addressing mode (default)"},
X	{"-postinc", clp_true, &postinc, "Allow \">\" addressing mode"},
X	{"", clp_true, NULL, ""},
X	{"-wdist", clp_int, &w_radius,
X		 "Set maximum distance for a write (default = coresize)"},
X	{"-wdist", clp_true, &w_radius_set, NULL},
X#ifdef  X11_DISP
X	{"-geometry", clp_string, geometry, NULL},
X	{"-geom", clp_string, geometry, NULL},
X	{"-iconic", clp_true, &iconic, NULL},
X	{"-display", clp_string, display, NULL},
X#endif  /* X11_DISP */
X	CLP_END};
X
Xstatic void  fight(program_t *progs, unsigned nprogs), err(char *pname),
X             interact(char *progname);
X
Xstatic char  usage[] =
X	"Usage:\n"
X	"   %s -help\n"
X#ifndef  NO_DISP
X	"   %s [options]\n"
X#endif  /* NO_DISP */
X	"   %s [options] <test program>\n"
X	"   %s [options] -rounds n <fighter 1> ... <fighter n>\n";
X
Xint  main(int argc, char *argv[])  {
X	program_t  *prog = NULL;
X	int  i, j;
X
X	srandom(time(0L) + getpid());
X	argc = clp_parse(argv, cmdline);
X	if (!w_radius_set)
X		w_radius = coresize / 2;
X	if (argc == CLP_NOGOOD)
X		exit(1);
X	if (!fl_set)
X		max_cycles = coresize * 10;
X	--argc;
X
X#ifdef  NO_DISP
X	if (!rounds)  {
X		printf("This KotH was compiled without display code.  "
X		       "\"-rounds 1\" has been assumed.\n");
X		rounds = 1;
X	}
X#endif  /* NO_DISP */
X
X	if (rounds && (argc < 2))  {
X		fprintf(stderr, "Tournament games must specify "
X						"at least two program files.\n");
X		fprintf(stderr, usage, argv[0], argv[0], argv[0], argv[0]);
X		exit(1);
X	}
X	if (!rounds && (argc > 1))  {
X		fprintf(stderr, "Interactive games cannot pre-load programs.\n");
X		fprintf(stderr, usage, argv[0], argv[0], argv[0], argv[0]);
X		exit(1);
X	}
X	if ((argc >= coresize / (maxprogsize * 2 - 1)) && rounds)  {
X		fprintf(stderr, "Sorry; %d fighters will not fit in a core of size %d.\n",
X						argc, coresize);
X		exit(1);
X	}
X
X	if (argc)  {
X		prog = (program_t *)tmalloc(argc * sizeof(program_t));
X		wins = (unsigned *)tmalloc(argc * argc * sizeof(unsigned));
X	}
X	if (argc == 1)  {
X		if (!assemble(prog, argv[1]))
X			err(prog[0].pname);
X		else  {
X			printf("Program \"%s\" (length %d) by \"%s\"\n"
X						 "(contact address \"%s\"):\n", prog->pname, prog->proglen,
X						 prog->author, prog->retaddr);
X			disasm(prog->listing, prog->proglen, prog->startaddr);
X			exit(0);
X		}
X	}
X	for (i = 0;  i < argc * argc;  ++i)
X		wins[i] = 0;
X	for (i = 0;  i < argc;  ++i)  {
X		if (!assemble(prog+i, argv[i+1]))
X			err(prog[i].pname);
X	}
X	if (argc > 0)  {
X		for (i = 0;  i < rounds;  ++i)
X			fight(prog, argc);
X		for (i = 0;  i < argc;  ++i)  {
X			for (j = i*argc;  j < i*argc + argc;  ++j)
X				printf("%d ", wins[j]);
X			putchar('\n');
X		}
X	} else  {
X#ifndef  NO_DISP
X		ld_init(DI_MAXPLAYERS);
X		interact(argv[0]);
X#endif  /* NO_DISP */
X	}
X	exit(0);
X}
X
X
Xstatic void  err(char *pname)  {
X	fprintf(stderr, "Error in program \"%s\":\n", pname);
X	fprintf(stderr, "%s\n", cwerrstr);
X	exit(1);
X}
X
X
X#ifndef  NO_DISP
Xstatic void  interact(char *progname)  {
X	char  *geom, *dpynm;
X
X	new_core();
X	if (geometry[0])
X		geom = geometry;
X	else
X		geom = NULL;
X	if (display[0])
X		dpynm = display;
X	else
X		dpynm = NULL;
X	di_init(progname, geom, dpynm, iconic, max_cycles);
X}
X#endif  /* NO_DISP */
X
X
Xstatic void  fight(program_t *progs, unsigned nprogs)  {
X	int  simlen, i, j;
X
X	ld_init(nprogs);
X	new_core();
X	for (i = 0;  i < nprogs;  ++i)
X		load_core(progs+i, ld_addr(i), i);
X	simlen = simulate(max_cycles, nprogs);
X	for (i = 0, j = -1;  i < nprogs;  ++i)
X		if (proc_count(i))
X			++j;
X	for (i = 0;  i < nprogs;  ++i)
X		if (proc_count(i))
X			++wins[i*nprogs + j];
X}
X
X
Xvoid  disasm(core_el_t *listing, aval_t len, aval_t start)  {
X	static char  amname[] = "# @<>";
X	aval_t  addr;
X
X	for (addr = 0;  addr < len;  ++addr)  {
X		if (addr == start)
X			printf("START");
X		printf("\t%s\t%c",
X					 opnames[JTOP(listing->index)],
X					 amname[JTAM1(listing->index)]);
X		if (listing->val1 == AVAL_PROGID)
X			printf("ID");
X		else
X			printf("%4d", listing->val1);
X		printf(",%c", amname[JTAM2(listing->index)]);
X		if (listing->val2 == AVAL_PROGID)
X			printf("ID\n");
X		else
X			printf("%4d\n", listing->val2);
X		++listing;
X	}
X}
X
X
Xvoid  *tmalloc(int size)  {
X	void  *result;
X
X	result = (void *)malloc(size);
X	if (result == NULL)  {
X		char  errstr[40];
X
X		sprintf(errstr, "koth: malloc(%d) failed", size);
X		perror(errstr);
X		exit(1);
X	}
X	return(result);
X}
END_OF_FILE
if test 6232 -ne `wc -c <'cwmain.c'`; then
    echo shar: \"'cwmain.c'\" unpacked with wrong size!
fi
# end of 'cwmain.c'
fi
if test -f 'di_timer.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'di_timer.c'\"
else
echo shar: Extracting \"'di_timer.c'\" \(1527 characters\)
sed "s/^X//" >'di_timer.c' <<'END_OF_FILE'
X/*
X * di_timer.c
X */
X
X#ifdef  X11_DISP
X
X#include <stdio.h>
X#include <sys/types.h>
X#include <sys/time.h>
X#include <signal.h>
X#include <X11/Xlib.h>
X#include <X11/Xutil.h>
X#include "corewar.h"
X#include "cwdisp.h"
X
X#define  SEC_USEC  1000000
X
Xstatic int  timedelay;
Xstatic struct timeval  next_interrupt;
X
X/* Set up SIGALRM signals to arrive freq times per second. */
Xvoid  di_set_timer(float freq)  {
X	float  delay = 1.0 / freq;
X
X	timedelay = (int)(delay * (float)SEC_USEC);
X	gettimeofday(&next_interrupt, NULL);
X	next_interrupt.tv_usec += timedelay;
X}
X
X
Xvoid  di_unset_timer()  {
X}
X
X
Xint  di_timer_wait(Display *dpy)  {
X	int  dneeded, waited = TRUE;
X	struct timeval  cur_tv;
X
X	gettimeofday(&cur_tv, NULL);
X	dneeded = (next_interrupt.tv_usec - cur_tv.tv_usec) +
X		((next_interrupt.tv_sec - cur_tv.tv_sec) * SEC_USEC);
X	if (dneeded > 0)  {
X		XFlush(dpy);
X		gettimeofday(&cur_tv, NULL);
X		dneeded = (next_interrupt.tv_usec - cur_tv.tv_usec) +
X			((next_interrupt.tv_sec - cur_tv.tv_sec) * SEC_USEC);
X		if (dneeded > 0)  {
X			fd_set  rdfds;
X			int  fd = ConnectionNumber(dpy);
X
X			FD_ZERO(&rdfds);
X			FD_SET(fd, &rdfds);
X			timerclear(&cur_tv);
X			cur_tv.tv_usec = dneeded % SEC_USEC;
X			cur_tv.tv_sec = dneeded / SEC_USEC;
X			waited = select(fd+1, rdfds, NULL, NULL, cur_tv);
X			if (waited == 0)
X				waited = TRUE;
X			else
X				waited = FALSE;
X		}
X	}
X	if (waited && ((next_interrupt.tv_usec += timedelay) > SEC_USEC))  {
X		++next_interrupt.tv_sec;
X		next_interrupt.tv_usec -= SEC_USEC;
X	}
X	return(waited);
X}
X
X
X#endif  /* X11_DISP */
END_OF_FILE
if test 1527 -ne `wc -c <'di_timer.c'`; then
    echo shar: \"'di_timer.c'\" unpacked with wrong size!
fi
# end of 'di_timer.c'
fi
if test -f 'di_input.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'di_input.c'\"
else
echo shar: Extracting \"'di_input.c'\" \(5527 characters\)
sed "s/^X//" >'di_input.c' <<'END_OF_FILE'
X/* di_input.c */
X
X#ifdef  X11_DISP
X
X#include <stdio.h>
X#include <math.h>
X#include <X11/Xlib.h>
X#include <X11/Xutil.h>
X#include <X11/keysym.h>
X#include <X11/cursorfont.h>
X#include "corewar.h"
X#include "cwdisp.h"
X
X#define  MIN_SLOW  1.0    /* The min & max speeds, in cycles/second. */
X#define  MAX_SLOW  500.0
X
Xstatic int  last_cursor = -1, last_win = -1;
X#define  LC_INBUT  1
X#define  LC_NOBUT  0
X
Xstatic Cursor  inbut_cursor, nobut_cursor;
Xstatic void  scrollpress(int winnum, int y);
X
X
Xvoid  di_in_init()  {
X	inbut_cursor = XCreateFontCursor(di_dpy, XC_arrow);
X	nobut_cursor = XCreateFontCursor(di_dpy, XC_left_ptr);
X}
X
X
Xvoid  di_butpress(Display *dpy, Window win, XButtonPressedEvent *evt)  {
X	gbut_mpress(evt->window, evt->x, evt->y);
X}
X
X
Xvoid  di_butrelease(Display *dpy, Window win, XButtonReleasedEvent *evt)  {
X	int  butnum;
X
X	butnum = gbut_mrelease(evt->window, evt->x, evt->y);
X	if (butnum == GBUT_NOBUT)  {
X		XBell(dpy, 0);
X		return;
X	}
X	switch(butnum)  {
X	case DI_BSTOP:
X		if (di_state == DS_STOPPED)
X			di_changestate(dpy, win, DS_STEP);
X		else
X			di_changestate(dpy, win, DS_STOPPED);
X		break;
X	case DI_BSLOW:
X		if (evt->x == di_but[DI_BSLOW].x)
X			++evt->x;
X		if (evt->x == di_but[DI_BSLOW].x + di_but[DI_BSLOW].w - 1)
X			--evt->x;
X		di_slopos = evt->x - di_but[DI_BSLOW].x - 1;
X		/* A logarithmic scale. */
X		di_speed = (float)exp((double)di_slopos * log(MAX_SLOW) /
X													(double)(di_but[DI_BSLOW].w - 2));
X		di_changestate(dpy, win, DS_RUNSLOW);
X		di_set_timer(di_speed);
X		break;
X	case DI_BGO:
X		di_changestate(dpy, win, DS_RUNFAST);
X		break;
X	case DI_BQUIT:
X		di_exit(0);
X		break;
X	case DI_BRESTART:
X		di_reset();
X		break;
X	case DI_BWIN2OK:
X		di_killwin2(FALSE);
X		break;
X	case DI_BCOREPIC:
X		di_mkwin3((evt->x - di_co_xoff) / di_picsize +
X							100 * ((evt->y - di_co_yoff) / di_picsize));
X		break;
X	case GBUT_NOBUT:
X		XBell(dpy, 0);
X		break;
X	default:
X		if (butnum < DI_NBUT)
X			di_loadbut(butnum - DI_BPLAY(0));
X		else  {
X			switch(DI_B3BUT(butnum))  {
X			case DI_BWIN3OK:
X				di_killwin3(DI_B3WIN(butnum));
X				break;
X			case DI_BWIN3UP:
X				di_dis_newstart(DI_B3WIN(butnum), -1);
X				break;
X			case DI_BWIN3DOWN:
X				di_dis_newstart(DI_B3WIN(butnum), 1);
X				break;
X			case DI_BWIN3SCROLL:
X				scrollpress(DI_B3WIN(butnum), evt->y);
X				break;
X			}
X		}
X		break;
X	}
X}
X
X
Xstatic void  scrollpress(int winnum, int y)  {
X	win3  *w3p = di_win3list.next;
X	int  i, sbh, sbindex;
X	gbut_info  *info;
X	aval_t  newaddr;
X
X	for (i = 0;  i < winnum;  ++i)
X		w3p = w3p->next;
X	sbh = w3p->scrollbut.h - w3p->scrollbut.w;
X	sbindex = (sbh * w3p->startaddr + coresize/2) / coresize;
X	if (y < w3p->scrollbut.y + sbindex + di_butbw)  {
X		newaddr = w3p->startaddr - w3p->lines;
X		if (newaddr > coresize)
X			newaddr = 0;
X		di_dis_newstart(winnum, newaddr - w3p->startaddr);
X	} else if (y > w3p->scrollbut.y + w3p->scrollbut.w + sbindex - di_butbw)  {
X		newaddr = w3p->startaddr + w3p->lines;
X		if (newaddr >= coresize)
X			newaddr = coresize - 1;
X		di_dis_newstart(winnum, newaddr - w3p->startaddr);
X	}
X}
X
X
Xvoid  di_keypress(Display *dpy, Window win, XKeyPressedEvent *evt)  {
X	int  slen;
X	char  kbuf[STR_MAXLEN];
X	KeySym  keysym;
X
X	slen = XLookupString(evt, kbuf, STR_MAXLEN-1, &keysym, NULL);
X	kbuf[slen] = '\0';
X	if (kbuf[0] == '\r')
X		kbuf[0] = '\n';
X	if ((win == di_win2) && (di_win2w != 0) && (kbuf[0] != '\n'))
X		di_keypress2(dpy, win, evt);
X	else
X		gbut_kpress(win, kbuf);
X}
X
X
Xvoid  di_keyrelease(Display *dpy, Window win, XKeyReleasedEvent *evt)  {
X	int  butnum, slen;
X	char  kbuf[STR_MAXLEN];
X	KeySym  keysym;
X
X	slen = XLookupString(evt, kbuf, STR_MAXLEN-1, &keysym, NULL);
X	kbuf[slen] = '\0';
X	if (kbuf[0] == '\r')
X		kbuf[0] = '\n';
X	if ((win == di_win2) && (di_win2w != 0) && (kbuf[0] != '\n'))
X		return;
X	if (XPending(dpy))  {
X		XEvent  nextev;
X
X		XPeekEvent(dpy, &nextev);
X		if (nextev.type == KeyPress)  {
X			if (nextev.xkey.keycode == evt->keycode)  {
X				XNextEvent(dpy, &nextev);
X				return;
X			}
X		}
X	}
X	butnum = gbut_krelease(win, kbuf);
X	switch(butnum)  {
X	case DI_BSTOP:
X		if (di_state == DS_STOPPED)
X			di_changestate(dpy, win, DS_STEP);
X		else
X			di_changestate(dpy, win, DS_STOPPED);
X		break;
X	case DI_BWIN2OK:
X		di_killwin2(FALSE);
X		break;
X	case DI_BSLOW:
X		di_slopos = ((di_but[DI_BSLOW].w - 3) * (kbuf[0] - '1')) / 7;
X		/* A logarithmic scale. */
X		di_speed = (float)exp((double)di_slopos * log(MAX_SLOW) /
X													(double)(di_but[DI_BSLOW].w - 2));
X		di_changestate(dpy, win, DS_RUNSLOW);
X		di_set_timer(di_speed);
X		break;
X	case DI_BGO:
X		di_changestate(dpy, win, DS_RUNFAST);
X		break;
X	case DI_BQUIT:
X		di_exit(0);
X		break;
X	case DI_BCOREPIC:
X		di_mkwin3(0);
X		break;
X	case GBUT_NOBUT:
X		XBell(dpy, 0);
X		break;
X	default:
X		switch(DI_B3BUT(butnum))  {
X		case DI_BWIN3OK:
X			di_killwin3(DI_B3WIN(butnum));
X			break;
X		case DI_BWIN3UP:
X			di_dis_newstart(DI_B3WIN(butnum), -1);
X			break;
X		case DI_BWIN3DOWN:
X			di_dis_newstart(DI_B3WIN(butnum), 1);
X			break;
X		}
X		break;
X	}
X}
X
X
Xvoid  di_input_m(Display *dpy, Window win, XMotionEvent *evt)  {
X	gbut_mmove(win, evt->x, evt->y);
X	if ((win == di_win2) && (di_win2w != 0)) {
X		if (!di_curon)
X			di_cursor(dpy, win, di_curon = TRUE);
X	}
X}
X
X
Xvoid  gbut_inbutton(Window win)  {
X	if ((last_cursor != LC_INBUT) || (last_win != win))  {
X		last_cursor = LC_INBUT;
X		last_win = win;
X		XDefineCursor(di_dpy, win, inbut_cursor);
X	}
X}
X
X
Xvoid  gbut_outbutton(Window win)  {
X	if ((last_cursor != LC_NOBUT) || (last_win != win))  {
X		last_cursor = LC_NOBUT;
X		last_win = win;
X		XDefineCursor(di_dpy, win, nobut_cursor);
X	}
X}
X
X
X#endif  /* X11_DISP */
END_OF_FILE
if test 5527 -ne `wc -c <'di_input.c'`; then
    echo shar: \"'di_input.c'\" unpacked with wrong size!
fi
# end of 'di_input.c'
fi
if test -f 'di_dis.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'di_dis.c'\"
else
echo shar: Extracting \"'di_dis.c'\" \(21178 characters\)
sed "s/^X//" >'di_dis.c' <<'END_OF_FILE'
X/*
X * disp.c
X */
X
X#ifdef  X11_DISP
X
X#include <stdio.h>
X#include <signal.h>
X#include <sys/ioctl.h>
X#include <X11/Xlib.h>
X#include <X11/Xutil.h>
X#include "corewar.h"
X#include "cwdisp.h"
X
Xtypedef struct  {
X	win3  *winbuf;
X	int  winnum;
X} get_win3_return;
Xstatic void  create_win3(win3 *winbuf, int winnum);
Xstatic char  *disline(aval_t addr, core_el_t el);
Xstatic get_win3_return  get_win3(Window win);
Xstatic void  draw_orect(aval_t  addr, int len);
Xstatic void  erase_orect(aval_t addr, int len);
Xstatic void  new_ploc(aval_t  newaddr);
Xstatic void  outline(aval_t  addr, int format);
Xstatic void  draw_all_orect();
Xstatic void  draw_bigpic(Display *dpy, Window win,
X												 int x, int y, aval_t address);
Xstatic void  draw_nextmove(Display *dpy, Window win,
X													 int x, int y, int player);
Xstatic void  erase_nextmove(Display *dpy, Window win, int x, int y);
Xstatic int  sbut_check_func(int butnum, gbut_info *info,
X														int checktype, int x, int y);
X
X
Xint  di_numwin3 = 0;
Xwin3  di_win3list;
Xint  *di_indis;
Xstatic int  drawn_nextmove = AVAL_NOGOOD;
Xstatic win3  *sbut_down_win = NULL;
Xstatic int   sbut_down_loc, sbut_down_addr, sbut_down_index;
X
X#define icon_width 51
X#define icon_height 51
Xstatic char icon_bits[] = {
X   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x3f,
X   0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00,
X   0x1e, 0xc7, 0x03, 0x00, 0x00, 0x00, 0x80, 0xa3, 0x28, 0x0e, 0x00, 0x00,
X   0x00, 0xc0, 0xa2, 0x28, 0x1a, 0x00, 0x00, 0x00, 0xa0, 0xa2, 0x28, 0x2a,
X   0x00, 0x00, 0x00, 0x70, 0x1c, 0xc7, 0x71, 0x00, 0x00, 0x00, 0x10, 0x00,
X   0x00, 0x40, 0x00, 0x00, 0x00, 0x78, 0x1c, 0xc7, 0xf1, 0x00, 0x00, 0x00,
X   0x8c, 0xa2, 0x28, 0x8a, 0x01, 0x00, 0x00, 0x8c, 0xa2, 0x28, 0x8a, 0x01,
X   0x00, 0x00, 0x8c, 0xa2, 0x28, 0x8a, 0x01, 0x00, 0x00, 0x72, 0x1c, 0xc7,
X   0x71, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x72,
X   0x1c, 0xc7, 0x71, 0x02, 0x00, 0x00, 0x8a, 0xa2, 0x28, 0x8a, 0x02, 0x00,
X   0x00, 0x8a, 0xa2, 0x28, 0x8a, 0x02, 0x00, 0x00, 0x8a, 0xa2, 0x28, 0x8a,
X   0x02, 0x00, 0x00, 0x72, 0x1c, 0xc7, 0x71, 0x02, 0x00, 0x00, 0x02, 0x00,
X   0x00, 0x00, 0x02, 0x00, 0x00, 0x72, 0x1c, 0xc7, 0x71, 0x02, 0x00, 0x00,
X   0x8c, 0xa2, 0x28, 0x8a, 0x01, 0x00, 0x00, 0x8c, 0xa2, 0x28, 0x8a, 0x01,
X   0x00, 0x00, 0x8c, 0xa2, 0x28, 0x8a, 0x01, 0x00, 0x00, 0x78, 0x1c, 0xc7,
X   0xf1, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70,
X   0x1c, 0xc7, 0x71, 0x00, 0x00, 0x00, 0xb0, 0xa2, 0x28, 0x2a, 0x00, 0x00,
X   0x00, 0xf8, 0xa2, 0x28, 0x1a, 0x00, 0x00, 0x00, 0xfc, 0xa3, 0x28, 0x0e,
X   0x00, 0x00, 0x00, 0x3f, 0x1e, 0xc7, 0x03, 0x00, 0x00, 0x80, 0x1f, 0x1c,
X   0xc0, 0x01, 0x00, 0x00, 0xc0, 0x0f, 0xe0, 0x3f, 0x00, 0x00, 0x00, 0xe0,
X   0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x07, 0x00, 0x00, 0x00, 0x00,
X   0x00, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x01, 0x00, 0x00,
X   0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00,
X   0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
X   0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x0f, 0x00, 0x00, 0x00, 0x00,
X   0x00, 0xf0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00,
X   0x00, 0x00, 0x00, 0xfc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00,
X   0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
X   0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00,
X   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
X#define mask_width 51
X#define mask_height 51
Xstatic char mask_bits[] = {
X   0x00, 0x00, 0x00, 0xe0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff,
X   0x01, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x03, 0x00, 0x00, 0x00, 0x80,
X   0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0x1f, 0x00, 0x00,
X   0x00, 0xe0, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0x7f,
X   0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xf8, 0xff,
X   0xff, 0xff, 0x00, 0x00, 0x00, 0xfc, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00,
X   0xfe, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x03,
X   0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0xff, 0xff, 0xff,
X   0xff, 0x07, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0xff,
X   0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00,
X   0x00, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
X   0x07, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0xff, 0xff,
X   0xff, 0xff, 0x07, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00,
X   0xfe, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x03,
X   0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0xfc, 0xff, 0xff,
X   0xff, 0x01, 0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xf8,
X   0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0x7f, 0x00, 0x00,
X   0x00, 0xfc, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x1f,
X   0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0xc0, 0x3f, 0xfe,
X   0xff, 0x03, 0x00, 0x00, 0xe0, 0x1f, 0xfc, 0xff, 0x01, 0x00, 0x00, 0xf0,
X   0x1f, 0xe0, 0x3f, 0x00, 0x00, 0x00, 0xf8, 0x0f, 0x00, 0x00, 0x00, 0x00,
X   0x00, 0xfc, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x03, 0x00, 0x00,
X   0x00, 0x00, 0x00, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0x00,
X   0x00, 0x00, 0x00, 0x00, 0xc0, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
X   0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x1f, 0x00, 0x00, 0x00, 0x00,
X   0x00, 0xf8, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x07, 0x00, 0x00,
X   0x00, 0x00, 0x00, 0xfe, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x01,
X   0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
X   0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00,
X   0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
X
X
Xvoid  di_dis_init()  {
X	di_win3list.next = &di_win3list;
X	di_win3list.prev = &di_win3list;
X	di_indis = (int *)tmalloc(coresize * sizeof(int));
X	bzero(di_indis, coresize * sizeof(int));
X	di_picmap = (int *)tmalloc(coresize * sizeof(int));
X	bzero(di_picmap, coresize * sizeof(int));
X}
X
X
Xvoid  di_mkwin3(aval_t  location)  {
X	static int  init_needed = TRUE;
X	win3  *new_win3;
X
X	if (init_needed)  {
X		init_needed = FALSE;
X	}
X	new_win3 = (win3 *)tmalloc(sizeof(win3));
X	new_win3->prev = di_win3list.prev;
X	di_win3list.prev = new_win3;
X	new_win3->next = &di_win3list;
X	new_win3->prev->next = new_win3;
X	new_win3->startaddr = location;
X	new_win3->lines = 0;
X	create_win3(new_win3, di_numwin3++);
X}
X
X
Xvoid  di_redraw3(Display *dpy, Window win, int x, int y, int w, int h)  {
X	int  charsize = di_ffontstr->ascent + di_ffontstr->descent, cur_y;
X	char  *strout;
X	get_win3_return  gw3rr;
X	win3  *w3p;
X	int  i, len, winnum;
X	aval_t  addr;
X
X	gw3rr = get_win3(win);
X	winnum = gw3rr.winnum;
X	w3p = gw3rr.winbuf;
X	if (w3p->lines != 0)
X		erase_orect(w3p->startaddr, w3p->lines);
X	w3p->w = w;
X	w3p->h = h;
X	w3p->okbut.win = win;
X	w3p->okbut.x = 0;
X	w3p->okbut.y = h - di_but[DI_BGO].h;
X	w3p->okbut.w = w;
X	w3p->okbut.h = di_but[DI_BGO].h;
X	w3p->okbut.flags = GBUT_DRAWABLE | GBUT_PRESSABLE;
X	w3p->okbut.keystr = ":\n:";
X	w3p->okbut.drawfunc = di_draw_ctbut;
X	w3p->okbut.checkfunc = gbut_true;
X	w3p->okbut.packet = (void *)"OK";
X
X	w3p->upbut.win = win;
X	w3p->upbut.x = 0;
X	w3p->upbut.y = 0;
X	w3p->upbut.w = charsize + di_picsize*2;
X	w3p->upbut.h = charsize + di_picsize*2;
X	w3p->upbut.flags = GBUT_DRAWABLE | GBUT_PRESSABLE;
X	w3p->upbut.keystr = ":";
X	w3p->upbut.drawfunc = di_draw_upbut;
X	w3p->upbut.checkfunc = gbut_true;
X	w3p->upbut.packet = NULL;
X
X	w3p->downbut.win = win;
X	w3p->downbut.x = 0;
X	w3p->downbut.y = w3p->okbut.y - charsize - di_picsize*2;
X	w3p->downbut.w = charsize + di_picsize * 2;
X	w3p->downbut.h = charsize + di_picsize * 2;
X	w3p->downbut.flags = GBUT_DRAWABLE | GBUT_PRESSABLE;
X	w3p->downbut.keystr = ":";
X	w3p->downbut.drawfunc = di_draw_downbut;
X	w3p->downbut.checkfunc = gbut_true;
X	w3p->downbut.packet = NULL;
X
X	w3p->scrollbut.win = win;
X	w3p->scrollbut.x = 0;
X	w3p->scrollbut.y = w3p->upbut.y + w3p->upbut.h;
X	w3p->scrollbut.w = charsize + di_picsize * 2;
X	w3p->scrollbut.h = w3p->downbut.y - w3p->scrollbut.y;
X	w3p->scrollbut.flags = GBUT_DRAWABLE | GBUT_PRESSABLE;
X	w3p->scrollbut.keystr = ":";
X	w3p->scrollbut.drawfunc = di_draw_sbar;
X	w3p->scrollbut.checkfunc = sbut_check_func;
X	w3p->scrollbut.packet = (void *)w3p;
X
X	XFillRectangle(dpy, win, di_cybgc, 0, 0, w, h);
X	XSetFont(dpy, di_cytgc, di_ffont);
X	for (len = 0;  len < w3p->lines;  ++len)
X		--di_indis[(w3p->startaddr + len)%coresize];
X	for (len = 0, cur_y = di_butbw, addr = w3p->startaddr;
X			 cur_y + charsize + di_butbw < w3p->okbut.y;
X			 cur_y += charsize, ++len, ++addr)  {
X		if (addr >= coresize)
X			addr -= coresize;
X		++di_indis[addr];
X		strout = disline(addr, core[addr]);
X		XDrawString(dpy, win, di_cytgc,
X								di_picsize*5+charsize*3, cur_y + di_ffontstr->ascent,
X								strout, strlen(strout));
X		draw_bigpic(dpy, win, di_picsize*4+charsize*2, cur_y, addr);
X		if (addr == di_next_move)  {
X			draw_nextmove(dpy, win, di_picsize*3+charsize, cur_y, di_next_player);
X			drawn_nextmove = addr;
X		} else if (addr == drawn_nextmove)
X			erase_nextmove(dpy, win, di_picsize*3+charsize, cur_y);
X	}
X	w3p->lines = len;
X	XSetFont(dpy, di_cytgc, di_sfont);
X	gbut_create(DI_W3BUT(winnum, DI_BWIN3OK),
X							&(w3p->okbut));
X	gbut_create(DI_W3BUT(winnum, DI_BWIN3UP),
X							&(w3p->upbut));
X	gbut_create(DI_W3BUT(winnum, DI_BWIN3DOWN),
X							&(w3p->downbut));
X	gbut_create(DI_W3BUT(winnum, DI_BWIN3SCROLL),
X							&(w3p->scrollbut));
X	draw_all_orect();
X}
X
X
Xvoid  di_fixline(aval_t lineaddr)  {
X	Display  *dpy = di_dpy;
X	win3  *w3p = di_win3list.next;
X	int  y, cheight = (di_ffontstr->ascent + di_ffontstr->descent), winnum;
X	char  *strout;
X
X	strout = disline(lineaddr, core[lineaddr]);
X	XSetFont(dpy, di_cytgc, di_ffont);
X	for (winnum = 0;  winnum < di_numwin3;  ++winnum, w3p = w3p->next)  {
X		if (((lineaddr >= w3p->startaddr) &&
X				 (lineaddr < w3p->startaddr+w3p->lines)) ||
X				((lineaddr < w3p->startaddr) &&
X				 (lineaddr+coresize < w3p->startaddr+w3p->lines)))  {
X			if ((y = lineaddr - w3p->startaddr) < 0)
X				y += coresize;
X			y *= cheight;
X			y += di_butbw;
X			XDrawImageString(dpy, w3p->win, di_cytgc,
X											 di_picsize*5+cheight*3,
X											 y+di_ffontstr->ascent,
X											 strout, strlen(strout));
X			draw_bigpic(dpy, w3p->win,
X									di_picsize*4+cheight*2, y,
X									lineaddr);
X			if (lineaddr == di_next_move)  {
X				draw_nextmove(dpy, w3p->win, di_picsize*3+cheight, y, di_next_player);
X				drawn_nextmove = lineaddr;
X			} else if (lineaddr == drawn_nextmove)
X				erase_nextmove(dpy, w3p->win, di_picsize*3+cheight, y);
X		}
X	}
X	XSetFont(dpy, di_cytgc, di_sfont);
X}
X
X
Xstatic void  draw_nextmove(Display *dpy, Window win,
X													 int x, int y, int player)  {
X	XPoint  points[4];
X	int  cheight = di_ffontstr->ascent + di_ffontstr->descent;
X	int  tri_side = cheight / 2;
X	GC   solidgc = di_picgc[player*DI_PLSIZ+DI_XEQ];
X
X	points[0].x = x + tri_side;
X	points[0].y = y;
X	points[1].x = points[0].x + tri_side;
X	points[1].y = points[0].y + tri_side;
X	points[2].x = points[0].x;
X	points[2].y = points[1].y + tri_side;
X	points[3] = points[0];
X	if (di_color)
X		XSetForeground(dpy, solidgc, di_colors[5+player*2]);
X	XFillPolygon(dpy, win, solidgc,
X							 points, 4, Nonconvex, CoordModeOrigin);
X	if (di_color)
X		XDrawLines(dpy, win, solidgc, points, 4, CoordModeOrigin);
X	else
X		XDrawLines(dpy, win, di_cytgc, points, 4, CoordModeOrigin);
X	if (di_color)
X		XSetForeground(dpy, solidgc, di_colors[4+player*2]);
X}
X
X
Xstatic void  erase_nextmove(Display *dpy, Window win, int x, int y)  {
X	int  cheight = di_ffontstr->ascent + di_ffontstr->descent;
X
X	XFillRectangle(dpy, win, di_cybgc, x, y, cheight, cheight);
X}
X
X
Xstatic void  draw_bigpic(Display *dpy, Window win,
X												 int x, int y, aval_t  addr)  {
X	int  picsize = di_ffontstr->ascent + di_ffontstr->descent;
X	int  picnum = di_picmap[addr] & ~CP_M;
X	int  starty = (addr & 1 ? picsize : 0);
X
X	XCopyArea(dpy, di_bigpixmaps[picnum], win, di_cytgc,
X						0, starty, picsize, picsize, x, y);
X}
X
X
Xstatic char  *disline(aval_t addr, core_el_t el)  {
X	static char  amname[] = "# @<>";
X	static char  lineout[256];
X	static char  *linefmt[] = {"%04d   %s %c%4d,%c%4d  (%04d,%04d)",
X														 "%05d   %s %c%5d,%c%5d  (%05d,%05d)",
X														 "%06d   %s %c%6d,%c%6d  (%06d,%06d)"};
X	char  *linelist = linefmt[0];
X
X	addr %= coresize;
X	if (coresize >= 10000)
X		linelist = linefmt[1];
X	if (coresize >= 100000)
X		linelist = linefmt[2];
X	sprintf(lineout, linelist,
X					addr,
X					opnames[JTOP(el.index)],
X					amname[JTAM1(el.index)],
X					el.val1,
X					amname[JTAM2(el.index)],
X					el.val2,
X					(addr+el.val1)%coresize,
X					(addr+el.val2)%coresize);
X	return(lineout);
X}
X					
X
Xvoid  di_dis_newstart(int winnum, aval_t newloc)  {
X	win3  *w3p = di_win3list.next, *temp;
X	int  i, len, charsize = di_ffontstr->ascent + di_ffontstr->descent;
X	aval_t  addr;
X
X	for (i = 0;  i < winnum;  ++i)
X		w3p = w3p->next;
X	erase_orect(w3p->startaddr, w3p->lines);
X	for (len = 0, addr = w3p->startaddr;  len < w3p->lines;  ++len, ++addr)  {
X		if (addr >= coresize)
X			addr = 0;
X		--di_indis[addr];
X		if (addr == drawn_nextmove)
X			erase_nextmove(di_dpy, w3p->win,
X										 di_picsize*3+charsize, di_butbw + len*charsize);
X	}
X	w3p->startaddr = (w3p->startaddr + coresize + newloc) % coresize;
X	for (len = 0;  len < w3p->lines;  ++len)  {
X		++di_indis[(w3p->startaddr + len)%coresize];
X		di_fixline((w3p->startaddr + len)%coresize);
X	}
X	draw_all_orect();
X	gbut_draw(DI_W3BUT(winnum, DI_BWIN3SCROLL));
X}
X
X	
Xvoid  di_killwin3(int  winnum)  {
X	win3  *w3p = di_win3list.next, *temp;
X	int  i, len;
X
X	for (i = 0;  i < winnum;  ++i)
X		w3p = w3p->next;
X	for (len = 0;  len < w3p->lines;  ++len)
X		--di_indis[(w3p->startaddr + len)%coresize];
X	erase_orect(w3p->startaddr, w3p->lines);
X	for (i = winnum;  i < di_numwin3;  ++i)  {
X		gbut_destroy(DI_W3BUT(i, DI_BWIN3OK));
X		gbut_destroy(DI_W3BUT(i, DI_BWIN3UP));
X		gbut_destroy(DI_W3BUT(i, DI_BWIN3DOWN));
X		gbut_destroy(DI_W3BUT(i, DI_BWIN3SCROLL));
X	}
X	w3p->prev->next = w3p->next;
X	w3p->next->prev = w3p->prev;
X	temp = w3p->next;
X	XDestroyWindow(di_dpy, w3p->win);
X	gbut_badwindow(w3p->win);
X	free(w3p);
X	w3p = temp;
X	--di_numwin3;
X	for (i = winnum;  i < di_numwin3;  ++i, w3p = w3p->next)  {
X		gbut_create(DI_W3BUT(i, DI_BWIN3OK), &(w3p->okbut));
X		gbut_create(DI_W3BUT(i, DI_BWIN3UP), &(w3p->upbut));
X		gbut_create(DI_W3BUT(i, DI_BWIN3DOWN), &(w3p->downbut));
X		gbut_create(DI_W3BUT(i, DI_BWIN3SCROLL), &(w3p->scrollbut));
X	}
X	draw_all_orect();
X}
X
X
Xstatic get_win3_return  get_win3(Window win)  {
X	int  winnum = 0;
X	win3  *winbuf = di_win3list.next;
X	get_win3_return  result;
X
X	while (win != winbuf->win)  {
X		++winnum;
X		winbuf = winbuf->next;
X	}
X	result.winbuf = winbuf;
X	result.winnum = winnum;
X	return(result);
X}
X
X
X/*
X * You may notice that this is an exact copy of the function in disp.c.
X * Well, you're right.  I'm too lazy to re-figure out how to create a
X *   window.
X */
Xstatic void  create_win3(win3 *winbuf, int winnum)  {
X	Window  win;
X	int  win_x, win_y;  /* Window position on screen. */
X	unsigned  win_w, win_h;
X	Display  *dpy = di_dpy;
X	char  *display_name, *testline;
X	XSetWindowAttributes  xswa;
X	XSizeHints  xsh;
X	XWMHints  wm_hints;
X	XClassHint  class_hints;
X	XTextProperty  windowName, iconName;
X	XWindowAttributes  xwa;
X	unsigned  i, hintmask;
X	int  defscr = DefaultScreen(dpy);
X	XVisualInfo  xvi;
X	Pixmap  koth_pixmap, mask_pixmap;
X	XSizeHints  size_hints;
X	char  *cw_name = "Core Closeup";
X
X	hintmask = 0;
X	win_x = 0;
X	win_y = 0;
X	testline = disline(0, core[0]);
X	win_w = XTextWidth(di_ffontstr, testline, strlen(testline)) + di_picsize*6 +
X		(di_ffontstr->ascent + di_ffontstr->descent)*3;
X	win_h = win_w;
X	win = XCreateSimpleWindow(dpy, RootWindow(dpy, defscr), win_x, win_y,
X	                          win_w, win_h, 0, di_stdbg, di_stdfg);
X	koth_pixmap = XCreateBitmapFromData(dpy, win, icon_bits,
X	                                    icon_width, icon_height);
X	mask_pixmap = XCreateBitmapFromData(dpy, win, mask_bits,
X	                                    mask_width, mask_height);
X	size_hints.flags = PPosition | PSize | PMinSize | hintmask;
X	size_hints.min_width = 200;
X	size_hints.min_height = 150;
X#ifdef  X11R3
X	size_hints.x = win_x;
X	size_hints.y = win_y;
X	size_hints.width = win_w;
X	size_hints.height = win_h;
X	XSetStandardProperties(dpy, win, cw_name, cw_name, koth_pixmap,
X												 NULL, 0, &size_hints);
X#else  /* X11R4 or later. */
X	{
X		XWMHints  wm_hints;
X		XClassHint  class_hints;
X		XTextProperty windowName, iconName;
X		char  *dumb_argv[] = {NULL};
X
X		if (XStringListToTextProperty(&cw_name, 1, &windowName) == 0)  {
X			fprintf(stderr, "Cannot allocate windowName.\n");
X			exit(-1);
X		}
X		if (XStringListToTextProperty(&cw_name, 1, &iconName) == 0)  {
X			fprintf(stderr, "Cannot allocate windowName.\n");
X			exit(-1);
X		}
X		wm_hints.initial_state = NormalState;
X		wm_hints.input = TRUE;
X		wm_hints.icon_pixmap = koth_pixmap;
X		wm_hints.icon_mask = mask_pixmap;
X		wm_hints.flags = StateHint | IconPixmapHint | IconMaskHint | InputHint;
X		class_hints.res_name = "koth";
X		class_hints.res_class = "Basicwin";
X		XSetWMProperties(dpy, win, &windowName, &iconName, dumb_argv, 0,
X										 &size_hints, &wm_hints, &class_hints);
X	}
X#endif  X11R3
X	winbuf->win = win;
X	XSelectInput(dpy, win, ExposureMask | StructureNotifyMask |
X							 PointerMotionMask | ButtonPressMask | KeyPressMask |
X							 ButtonReleaseMask | KeyReleaseMask);
X	XMapWindow(dpy, win);
X	XGetWindowAttributes(dpy, win, &xwa);
X	winbuf->w = xwa.width;
X	winbuf->h = xwa.height;
X	di_redraw3(dpy, win, xwa.x,xwa.y, xwa.width,xwa.height);
X}
X
X
Xint  di_dis_cpcheck(int butnum, gbut_info *info, int checktype,
X										int x, int y)  {
X	new_ploc(((x-info->x)/di_picsize)+((y-info->y)/di_picsize)*100);
X	return(TRUE);
X}
X
X
Xvoid  di_dis_cpdraw(int butnum, gbut_info *info)  {
X	if (!(info->flags & GBUT_TWITCHED))
X		new_ploc(AVAL_NOGOOD);
X}
X
X
X#define  OSIZE  21
Xstatic void  new_ploc(aval_t  newaddr)  {
X	static int  oldaddr = AVAL_NOGOOD;
X	int  i;
X	win3  *w3p;
X
X	if (oldaddr == newaddr)
X		return;
X	if (oldaddr != AVAL_NOGOOD)
X		erase_orect(oldaddr, OSIZE);
X	oldaddr = newaddr;
X	if (newaddr != AVAL_NOGOOD)
X		draw_orect(newaddr, OSIZE);
X	draw_all_orect();
X}
X
X
Xstatic void  erase_orect(aval_t addr, int len)  {
X	int  i;
X
X	for (i = addr-100-1;  i <= addr-100+len;  ++i)
X		di_newoutline(i, 0);
X	di_newoutline(addr-1, 0);
X	di_newoutline(addr+len, 0);
X	for (i = addr+100-1;  i <= addr+100+len;  ++i)
X		di_newoutline(i, 0);
X}
X
X
Xstatic void  draw_all_orect()  {
X	int  winnum;
X	win3  *w3p;
X
X	w3p = di_win3list.next;
X	for (winnum = 0;  winnum < di_numwin3;  ++winnum, w3p = w3p->next)  {
X		draw_orect(w3p->startaddr, w3p->lines);
X	}
X}
X
X
Xstatic void  draw_orect(aval_t  addr, int len)  {
X	int  i, tmpval;
X	aval_t  tmpa;
X
X	di_newoutline(addr-100- 1,  CP_D|CP_R);
X	di_newoutline(addr-100+len, CP_D|CP_L);
X	di_newoutline(addr+100- 1,  CP_U|CP_R);
X	di_newoutline(addr+100+len, CP_U|CP_L);
X	for (i = addr-100;  i < addr-100+len;  ++i)
X		di_newoutline(i, CP_D);
X	di_newoutline(addr-1, CP_R);
X	di_newoutline(addr+len, CP_L);
X	for (i = addr+100;  i < addr+100+len;  ++i)
X		di_newoutline(i, CP_U);
X}
X	
X
Xvoid  di_drawoutline(aval_t addr, int format)  {
X	int  x,y,w,h;
X
X	addr = (addr + coresize)%coresize;
X	x = di_co_xoff + (addr%100)*di_picsize;
X	y = di_co_yoff + (addr/100)*di_picsize;
X	w = di_picsize;
X	h = di_picsize;
X	if (format & CP_D)  {
X		y += di_picsize/2;
X		h -= di_picsize/2;
X	}
X	if (format & CP_U)
X		h -= di_picsize/2;
X	if (format & CP_R)  {
X		x += di_picsize/2;
X		w -= di_picsize/2;
X	}
X	if (format & CP_L)
X		w -= di_picsize/2;
X	XFillRectangle(di_dpy, di_win, di_cybgc, x,y, w,h);
X	if (format & CP_D)  {
X		y += (di_picsize+1)/4;
X		h -= (di_picsize+1)/4;
X	}
X	if (format & CP_U)
X		h -= (di_picsize+1)/4;
X	if (format & CP_R)  {
X		x += (di_picsize+1)/4;
X		w -= (di_picsize+1)/4;
X	}
X	if (format & CP_L)
X		w -= (di_picsize+1)/4;
X	XFillRectangle(di_dpy, di_win, di_cytgc, x,y, w,h);
X}
X
X
Xstatic int  sbut_check_func(int butnum, gbut_info *info,
X														int checktype, int x, int y)  {
X	aval_t  newaddr;
X	int  sbh, newindex;
X	get_win3_return  gw3rr;
X
X	if (checktype == GBUT_CT_PRESS)  {
X		sbut_down_win = (win3 *)info->packet;
X		sbut_down_loc = y;
X		sbh = info->h - info->w;
X		sbut_down_addr = sbut_down_win->startaddr;
X		sbut_down_index = (sbh * sbut_down_addr + coresize/2) / coresize;
X		if ((y < info->y + di_butbw + sbut_down_index) ||
X				(y > info->y + info->w - di_butbw + sbut_down_index))
X			sbut_down_win = NULL;
X		return(TRUE);
X	}
X	if ((sbut_down_win == (win3 *)info->packet) &&
X			 (checktype != GBUT_CT_PMOVE))  {
X		sbut_down_win = NULL;
X		return(TRUE);
X	}
X	if ((win3 *)info->packet != sbut_down_win)
X		return(TRUE);
X	sbh = info->h - info->w;
X	if (y == sbut_down_loc)  {
X		newaddr = sbut_down_addr;
X		newindex = sbut_down_index;
X	} else  {
X		newindex = sbut_down_index + (y - sbut_down_loc);
X		if (newindex < 0)
X			newindex = 0;
X		if (newindex > sbh)
X			newindex = sbh;
X		newaddr = (newindex * (coresize-1)) / sbh;
X	}
X	if (newaddr != sbut_down_win->startaddr)  {
X		gw3rr = get_win3(sbut_down_win->win);
X		di_dis_newstart(gw3rr.winnum, newaddr-sbut_down_win->startaddr);
X	}
X	return(TRUE);
X}
X
X
X#endif  /* X11_DISP */
END_OF_FILE
if test 21178 -ne `wc -c <'di_dis.c'`; then
    echo shar: \"'di_dis.c'\" unpacked with wrong size!
fi
# end of 'di_dis.c'
fi
if test -f 'gbut.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'gbut.c'\"
else
echo shar: Extracting \"'gbut.c'\" \(8494 characters\)
sed "s/^X//" >'gbut.c' <<'END_OF_FILE'
X/*
X * gbut.c
X *
X * Generic button code.
X * Meant to be reusable.
X */
X
X#ifdef  X11_DISP
X
X#include <stdio.h>
X#include <X11/Xlib.h>
X#include <X11/Xutil.h>
X#include "gbut.h"
X
Xstatic Display *gdpy;
X
Xstatic gbut_info  **butlist;
Xstatic int  maxbuts, bpressed, kpressed, but_in, twitched;
Xstatic Window  last_mwin;
Xstatic int  last_mx = -1, last_my = -1, badwin = 0;
X
Xstatic gbut_info  deadbut = {0, 0,0,0,0, 0, NULL, NULL, NULL};
X
Xstatic int  mousein(Window win, int x, int y, int reason);
X
X
Xvoid  gbut_init(Display *dpy, Window win)  {
X	gdpy = dpy;
X	last_mwin = win;
X	maxbuts = 0;
X	bpressed = GBUT_NOBUT;
X	kpressed = GBUT_NOBUT;
X	but_in = GBUT_NOBUT;
X	twitched = GBUT_NOBUT;
X	butlist = NULL;
X}
X
X
Xvoid  gbut_badwindow(Window win)  {
X	badwin = win;
X}
X
X
Xvoid  gbut_create(int butnum, gbut_info *info)  {
X	if (info->win == badwin)
X		badwin = 0;
X	if (butnum >= maxbuts)  {
X		gbut_info  **newbutlist;
X		int  newmaxbuts, i;
X
X		newmaxbuts = butnum + 1;
X		newbutlist = (gbut_info **)malloc(newmaxbuts * sizeof(gbut_info *));
X		if (newbutlist == NULL)  {
X			fprintf(stderr, "Error: Could not allocate %d buttons.\n",
X							newmaxbuts);
X			exit(1);
X		}
X		if (butlist != NULL)  {
X			bcopy(butlist, newbutlist, maxbuts * sizeof(gbut_info *));
X			free(butlist);
X		}
X		butlist = newbutlist;
X		for (i = maxbuts;  i < newmaxbuts;  ++i)
X			butlist[i] = &deadbut;
X		maxbuts = newmaxbuts;
X	}
X	butlist[butnum] = info;
X	gbut_draw(butnum);
X	gbut_mmove(last_mwin, last_mx, last_my);
X}
X
X
Xvoid  gbut_destroy(int butnum)  {
X	butlist[butnum] = &deadbut;
X	if (but_in == butnum)
X		but_in = GBUT_NOBUT;
X	if (bpressed == butnum)
X		bpressed = GBUT_NOBUT;
X	if (kpressed == butnum)
X		kpressed = GBUT_NOBUT;
X	if (twitched == butnum)
X		twitched = GBUT_NOBUT;
X}
X
X
Xvoid  gbut_setflags(int butnum, unsigned newflags)  {
X	unsigned  oldflags = butlist[butnum]->flags;
X
X	newflags = ((oldflags & ~(newflags >> GBUT_MAXBITS)) | newflags) &
X		(GBUT_PRESSABLE|GBUT_DRAWABLE|GBUT_TWITCHABLE);
X	if (but_in == butnum)
X		but_in = GBUT_NOBUT;
X	if (mousein(last_mwin, last_mx, last_my, GBUT_CT_MOVE) == butnum)  {
X		but_in = butnum;
X		if (newflags & GBUT_TWITCHABLE)
X			newflags |= GBUT_TWITCHED;
X		if ((bpressed == butnum) && (newflags & GBUT_PRESSABLE))
X			newflags |= GBUT_PRESSED;
X	} else  {
X		if (bpressed == butnum)
X			bpressed = GBUT_NOBUT;
X		if (kpressed == butnum)
X			kpressed = GBUT_NOBUT;
X		if (twitched == butnum)
X			twitched = GBUT_NOBUT;
X	}
X	if ((kpressed == butnum) && !(newflags & GBUT_PRESSABLE))
X		kpressed = GBUT_NOBUT;
X	if ((bpressed == butnum) && !(newflags & GBUT_PRESSABLE))
X		bpressed = GBUT_NOBUT;
X	if ((twitched == butnum) && !(newflags & GBUT_TWITCHABLE))
X		twitched = GBUT_NOBUT;
X	if (newflags != oldflags)  {
X		butlist[butnum]->flags = newflags;
X		gbut_draw(butnum);
X	}
X}
X
X		
Xvoid  gbut_draw(int butnum)  {
X	if (butlist[butnum]->flags & GBUT_DRAWABLE)
X		butlist[butnum]->drawfunc(butnum, butlist[butnum]);
X}
X
X
Xvoid  gbut_redraw(Window win, int x, int y, int w, int h)  {
X	int  i;
X
X	for (i = 0;  i < maxbuts;  ++i)  {
X		if ((win == butlist[i]->win) &&
X				(x < butlist[i]->x + butlist[i]->w) &&
X				(x+w >= butlist[i]->x) &&
X				(y < butlist[i]->y + butlist[i]->h) &&
X				(y+h >= butlist[i]->y))  {
X			gbut_draw(i);
X		}
X	}
X}
X
X
Xint  gbut_mmove(Window win, int x, int y)  {
X	int  i, flags, butnum;
X
X	last_mwin = win;
X	last_mx = x;
X	last_my = y;
X	butnum = mousein(win, x, y, GBUT_CT_MOVE);
X	if (but_in == butnum)
X		return(butnum);
X	but_in = butnum;
X	if (twitched != GBUT_NOBUT)  {
X		butlist[twitched]->flags &= ~(GBUT_PRESSED | GBUT_TWITCHED);
X		gbut_draw(twitched);
X		twitched = GBUT_NOBUT;
X	}
X	if ((bpressed != GBUT_NOBUT) && (bpressed != butnum) &&
X			(butlist[bpressed]->flags & GBUT_PRESSED))  {
X		butlist[bpressed]->flags &= ~GBUT_PRESSED;
X		gbut_draw(bpressed);
X	}
X	if (butnum != GBUT_NOBUT)  {
X		flags = butlist[butnum]->flags;
X		if (flags & GBUT_TWITCHABLE)  {
X			twitched = butnum;
X			flags |= GBUT_TWITCHED;
X		}
X		if (bpressed == butnum)
X			flags |= GBUT_PRESSED;
X		if (flags != butlist[butnum]->flags)  {
X			butlist[butnum]->flags = flags;
X			gbut_draw(butnum);
X		}
X	}
X	return(butnum);
X}
X
X
Xint  gbut_mpress(Window win, int x, int y)  {
X	int  butnum, flags;
X
X	last_mwin = win;
X	last_mx = x;
X	last_my = y;
X	if (kpressed != GBUT_NOBUT)  {
X		butlist[kpressed]->flags &= ~GBUT_PRESSED;
X		gbut_draw(kpressed);
X		kpressed = GBUT_NOBUT;
X	}
X	if (bpressed != GBUT_NOBUT)  {
X		butlist[bpressed]->flags &= ~GBUT_PRESSED;
X		gbut_draw(bpressed);
X		bpressed = GBUT_NOBUT;
X	}
X	butnum = mousein(win, x, y, GBUT_CT_PRESS);
X	but_in = butnum;
X	if (butnum != twitched)  {
X		if (twitched != GBUT_NOBUT)  {
X			butlist[twitched]->flags &= ~GBUT_TWITCHED;
X			gbut_draw(twitched);
X		}
X		twitched = butnum;
X	}
X	if (butnum != GBUT_NOBUT)  {
X		flags = butlist[butnum]->flags;
X		if (flags & GBUT_PRESSABLE)  {
X			flags |= GBUT_PRESSED;
X			bpressed = butnum;
X		}
X		if (flags & GBUT_TWITCHABLE)  {
X			flags |= GBUT_TWITCHABLE;
X			twitched = butnum;
X		}
X		if (flags != butlist[butnum]->flags)  {
X			butlist[butnum]->flags = flags;
X			gbut_draw(butnum);
X		}
X	}
X	return(butnum);
X}
X
X
Xint  gbut_mrelease(Window win, int x, int y)  {
X	int  butnum, old_bpr;
X
X	last_mwin = win;
X	last_mx = x;
X	last_my = y;
X	if (kpressed != GBUT_NOBUT)  {
X		butlist[kpressed]->flags &= ~GBUT_PRESSED;
X		gbut_draw(kpressed);
X		kpressed = GBUT_NOBUT;
X	}
X	if ((old_bpr = bpressed) != GBUT_NOBUT)  {
X		butlist[bpressed]->flags &= ~GBUT_PRESSED;
X		gbut_draw(bpressed);
X		bpressed = GBUT_NOBUT;
X	}
X	butnum = mousein(win, x, y, GBUT_CT_RELEASE);
X	but_in = butnum;
X	if (butnum != twitched)  {
X		if (twitched != GBUT_NOBUT)  {
X			butlist[twitched]->flags &= ~GBUT_TWITCHED;
X			gbut_draw(twitched);
X		}
X		twitched = butnum;
X		if ((butnum != GBUT_NOBUT) &&
X				(butlist[butnum]->flags & GBUT_TWITCHABLE))  {
X			butlist[butnum]->flags |= GBUT_TWITCHED;
X			gbut_draw(butnum);
X		}
X	}
X	if (butnum == old_bpr)
X		return(butnum);
X	else
X		return(GBUT_NOBUT);
X}
X
X
Xint  gbut_kpress(Window win, char *keystr)  {
X	int  i, fset;
X	char  sstr[100] = ":";
X
X	if (bpressed != GBUT_NOBUT)  {
X		butlist[bpressed]->flags &= ~GBUT_PRESSED;
X		gbut_draw(bpressed);
X		bpressed = GBUT_NOBUT;
X	}
X	if (kpressed != GBUT_NOBUT)  {
X		butlist[kpressed]->flags &= ~GBUT_PRESSED;
X		gbut_draw(kpressed);
X		kpressed = GBUT_NOBUT;
X	}
X	strcpy(sstr+1, keystr);
X	strcat(sstr+1, ":");
X	for (i = 0;  i < maxbuts;  ++i)  {
X		if ((butlist[i]->win == win) && (butlist[i]->flags & GBUT_PRESSABLE) &&
X				strstr(butlist[i]->keystr, sstr))
X			kpressed = i;
X	}
X	if (kpressed != GBUT_NOBUT)  {
X		butlist[kpressed]->flags |= GBUT_PRESSED;
X		gbut_draw(kpressed);
X	}
X	return(kpressed);
X}
X	
X
Xint  gbut_krelease(Window win, char *keystr)  {
X	int  res;
X	char  sstr[100] = ":";
X
X	if ((res = kpressed) == GBUT_NOBUT)
X		return(GBUT_NOBUT);
X	else  {
X		butlist[kpressed]->flags &= ~GBUT_PRESSED;
X		gbut_draw(kpressed);
X		kpressed = GBUT_NOBUT;
X	}
X	strcpy(sstr+1, keystr);
X	strcat(sstr+1, ":");
X	if (strstr(butlist[res]->keystr, sstr))
X		return(res);
X	return(GBUT_NOBUT);
X}
X
X
Xint  gbut_true(int butnum, gbut_info *info,
X							 int checktype, int x, int y)  {
X	return(1);
X}
X
X
X/* mousein(win, x, y, reason) will return the button number that the mouse is
X *   presently inside of.  If the mouse is not in any button GBUT_NOBUT will
X *   be returned.
X * The checkfunc will be called only if the mouse is already inside the
X *   (x,y,w,h) boundaries of the button.  "reason" is one of GBUT_CT_PRESS,
X *   GBUT_CT_RELEASE, or GBUT_CT_MOVE, depending on the reason for the button
X *   to be checked.
X * Non-pressable buttons will never be returned.
X *
X * NOTE: This does a linear search through the buttons.  YUCK!  SLOW!  I'd
X *   like to recode this to do a three-dimensional binary search (the
X *   dimensions being window, x, and y) but that would take some seriously
X *   heavy-duty coding and I have a million other things to do first.
X */
Xstatic int  mousein(Window win, int x, int y, int reason)  {
X	int  i, fset, butnum = GBUT_NOBUT, checkr;
X	gbut_info  *info;
X
X	for (i = 0;  i < maxbuts;  ++i)  {
X		info = butlist[i];
X		if ((info->flags & GBUT_PRESSABLE) &&
X				(win == info->win) &&
X				(x >= info->x) && (x < info->x + info->w) &&
X				(y >= info->y) && (y < info->y + info->h))  {
X			if ((i == bpressed) && (reason == GBUT_CT_MOVE))
X				checkr = info->checkfunc(i, info, GBUT_CT_PMOVE, x, y);
X			else
X				checkr = info->checkfunc(i, info, reason, x, y);
X			if (checkr)  {
X				if (win != badwin)
X					gbut_inbutton(win);
X				return(i);
X			}
X		}
X	}
X	if (win != badwin)
X		gbut_outbutton(win);
X	return(GBUT_NOBUT);
X}
X
X
X#endif  /* X11_DISP */
END_OF_FILE
if test 8494 -ne `wc -c <'gbut.c'`; then
    echo shar: \"'gbut.c'\" unpacked with wrong size!
fi
# end of 'gbut.c'
fi
if test -f 'di_but.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'di_but.c'\"
else
echo shar: Extracting \"'di_but.c'\" \(7913 characters\)
sed "s/^X//" >'di_but.c' <<'END_OF_FILE'
X/*
X * di_but.c
X */
X
X#ifdef  X11_DISP
X
X#include <stdio.h>
X#include <X11/Xlib.h>
X#include <X11/Xutil.h>
X#include "corewar.h"
X#include "cwdisp.h"
X#include "gbut.h"
X
X
Xstatic void  button_gc(Display *dpy, int flags, GC *fg, GC *bg);
X
X
X/* A button with text centered in it.  The packet is a pointer to the
X *   text.
X */
Xvoid  di_draw_ctbut(int butnum, gbut_info *info)  {
X	Display *dpy = di_dpy;
X	GC  fg_butgc, bg_butgc;
X	char  *txtout = (char *)(info->packet);
X	int  txtwidth, txtlen = strlen(txtout);
X
X#ifdef  DEBUG
X	XSync(dpy, False);
X	fprintf(stderr, "Drawing %d\n", butnum);
X#endif  DEBUG
X	di_outline_box(dpy, info->win, info->x, info->y, info->w, info->h,
X								 info->flags & GBUT_PRESSED);
X	button_gc(dpy, info->flags, &fg_butgc, &bg_butgc);
X	txtwidth = XTextWidth(di_sfontstr, txtout, strlen(txtout));
X	XFillRectangle(dpy, info->win, bg_butgc,
X								 info->x+di_butbw, info->y+di_butbw,
X								 info->w-2*di_butbw, info->h-2*di_butbw);
X	XDrawString(dpy, info->win, fg_butgc, info->x + (info->w - txtwidth) / 2,
X							info->y + (info->h + di_sfontstr->ascent -
X												 di_sfontstr->descent)/2,
X							txtout, txtlen);
X#ifdef  DEBUG
X	XSync(dpy, False);
X	fprintf(stderr, "Drew %d\n", butnum);
X#endif  DEBUG
X}
X
X
X/* A button with an up arrow in it. */
Xvoid  di_draw_upbut(int butnum, gbut_info *info)  {
X	Display *dpy = di_dpy;
X	GC  fg_butgc, bg_butgc;
X	XPoint  points[4];
X
X#ifdef  DEBUG
X	XSync(dpy, False);
X	fprintf(stderr, "Drawing %d\n", butnum);
X#endif  DEBUG
X	di_outline_box(dpy, info->win, info->x, info->y, info->w, info->h,
X								 info->flags & GBUT_PRESSED);
X	button_gc(dpy, info->flags, &fg_butgc, &bg_butgc);
X	XFillRectangle(dpy, info->win, bg_butgc,
X								 info->x+di_butbw, info->y+di_butbw,
X								 info->w-2*di_butbw, info->h-2*di_butbw);
X	points[0].x = info->x + di_picsize;
X	points[0].y = info->y + info->h/2;
X	points[1].x = info->x + info->w/2;
X	points[1].y = info->y + di_picsize;
X	points[2].x = points[1].x + (points[1].x - points[0].x);
X	points[2].y = points[0].y;
X	points[3] = points[0];
X	XFillPolygon(dpy, info->win, fg_butgc, points, 3, Convex, CoordModeOrigin);
X	XDrawLines(dpy, info->win, fg_butgc, points, 4, CoordModeOrigin);
X#ifdef  DEBUG
X	XSync(dpy, False);
X	fprintf(stderr, "Drew %d\n", butnum);
X#endif  DEBUG
X}
X
X
X/* A button with a down arrow in it. */
Xvoid  di_draw_downbut(int butnum, gbut_info *info)  {
X	Display *dpy = di_dpy;
X	GC  fg_butgc, bg_butgc;
X	XPoint  points[4];
X
X#ifdef  DEBUG
X	XSync(dpy, False);
X	fprintf(stderr, "Drawing %d\n", butnum);
X#endif  DEBUG
X	di_outline_box(dpy, info->win, info->x, info->y, info->w, info->h,
X								 info->flags & GBUT_PRESSED);
X	button_gc(dpy, info->flags, &fg_butgc, &bg_butgc);
X	XFillRectangle(dpy, info->win, bg_butgc,
X								 info->x+di_butbw, info->y+di_butbw,
X								 info->w-2*di_butbw, info->h-2*di_butbw);
X	points[0].x = info->x + di_picsize;
X	points[0].y = info->y + info->h/2;
X	points[1].x = info->x + info->w/2;
X	points[1].y = info->y + info->h - di_picsize - 1;
X	points[2].x = points[1].x + (points[1].x - points[0].x);
X	points[2].y = points[0].y;
X	points[3] = points[0];
X	XFillPolygon(dpy, info->win, fg_butgc, points, 3, Convex, CoordModeOrigin);
X	XDrawLines(dpy, info->win, fg_butgc, points, 4, CoordModeOrigin);
X#ifdef  DEBUG
X	XSync(dpy, False);
X	fprintf(stderr, "Drew %d\n", butnum);
X#endif  DEBUG
X}
X
X
X/* The slow-fast positional button.  The bar is always three pixels wide;
X *   I don't like this, it's the only non-scaling aspect of the entire display.
X *   I want to think of a better looking bar.  Maybe diamond shaped?  Drawing
X *   speed isn't really an issue here since it's only redrawn when the user
X *   clicks on it.
X */
Xvoid  di_draw_sfbut(int butnum, gbut_info *info)  {
X	Display *dpy = di_dpy;
X	GC  fg_butgc, bg_butgc;
X	int  txtwidth, barloc = *(int *)(info->packet);
X	int  ytext;
X	XPoint  points[4];
X
X#ifdef  DEBUG
X	XSync(dpy, False);
X	fprintf(stderr, "Drawing %d\n", butnum);
X#endif  DEBUG
X	di_outline_box(dpy, info->win, info->x, info->y, info->w, info->h,
X								 info->flags & GBUT_PRESSED);
X	button_gc(dpy, info->flags, &fg_butgc, &bg_butgc);
X	XFillRectangle(dpy, info->win, bg_butgc,
X								 info->x+di_butbw, info->y+di_butbw,
X								 info->w-2*di_butbw, info->h-2*di_butbw);
X	points[0].x = info->x + info->w - di_butbw - 1;
X	points[0].y = info->y + di_butbw;
X	points[1].x = info->x + di_butbw;
X	points[1].y = info->y + info->h - di_butbw - 1;
X	points[2].x = points[0].x;
X	points[2].y = points[1].y;
X	points[3] = points[0];
X	XFillPolygon(dpy, info->win, fg_butgc, points, 3, Convex, CoordModeOrigin);
X	XDrawLines(dpy, info->win, fg_butgc, points, 4, CoordModeOrigin);
X	ytext = info->y + (info->h + di_sfontstr->ascent -
X										 di_sfontstr->descent) / 2;
X	XDrawString(dpy, info->win, fg_butgc, info->x + di_butbw * 2, ytext,
X							"Slow", 4);
X	txtwidth = XTextWidth(di_sfontstr, "Fast", 4);
X	XDrawString(dpy, info->win, bg_butgc,
X							info->x + info->w - txtwidth - di_butbw * 2, ytext, "Fast", 4);
X	if (di_state == DS_RUNSLOW)  {
X		int  x, y1, y2;
X
X		x = di_but[butnum].x + di_slopos + 1;
X		y1 = di_but[butnum].y + di_butbw;
X		y2 = di_but[butnum].y + di_but[butnum].h - di_butbw;
X		XDrawLine(dpy, info->win, bg_butgc, x-1, y1, x-1, y2);
X		XDrawLine(dpy, info->win, bg_butgc, x+1, y1, x+1, y2);
X		XDrawLine(dpy, info->win, fg_butgc, x, y1, x, y2);
X	}
X#ifdef  DEBUG
X	XSync(dpy, False);
X	fprintf(stderr, "Drew %d\n", butnum);
X#endif  DEBUG
X}
X
X
X/* Figure out what to use as foreground and background for the GCs. */
Xstatic void  button_gc(Display *dpy, int flags, GC *fg, GC *bg)  {
X	if (flags & GBUT_PRESSED)  {
X		*bg = di_butgc;
X		*fg = di_cybgc;
X	} else  {
X		*bg = di_cybgc;
X		*fg = di_butgc;
X	}
X	if (flags & GBUT_PRESSABLE)
X		XSetFillStyle(dpy, di_butgc, FillSolid);
X	else
X		XSetFillStyle(dpy, di_butgc, FillTiled);
X}
X
X
Xvoid  di_outline_box(Display *dpy, Window win,
X										 int x, int y, int w, int h, int bstate)  {
X	XPoint  points[7];
X	GC  topgc, bottomgc;
X
X	points[0].x = x + w - 1;
X	points[0].y = y;
X	points[1].x = x;
X	points[1].y = y;
X	points[2].x = x;
X	points[2].y = y + h - 1;
X	points[3].x = x + di_butbw - 1;
X	points[3].y = y + h - di_butbw;
X	points[4].x = points[3].x;
X	points[4].y = y + di_butbw - 1;
X	points[5].x = x + w - di_butbw;
X	points[5].y = points[4].y;
X	points[6] = points[0];
X	if (bstate == 0)  {
X		topgc = di_butlgc;
X		bottomgc = di_butdgc;
X	} else  {
X		topgc = di_butdgc;
X		bottomgc = di_butlgc;
X	}
X	XFillPolygon(dpy, win, topgc, points, 6, Nonconvex, CoordModeOrigin);
X	XDrawLines(dpy, win, topgc, points, 7, CoordModeOrigin);
X	points[1].x = points[0].x;
X	points[1].y = points[2].y;
X	points[4].x = points[5].x;
X	points[4].y = points[3].y;
X	XFillPolygon(dpy, win, bottomgc, points, 6, Nonconvex, CoordModeOrigin);
X	XDrawLines(dpy, win, bottomgc, points, 7, CoordModeOrigin);
X}
X
X
Xvoid  di_draw_sbar(int butnum, gbut_info *info)  {
X	Display  *dpy = di_dpy;
X	int  sbh, sbindex;
X	GC  gc;
X
X	di_outline_box(dpy, info->win, info->x, info->y, info->w, info->h, 1);
X	sbh = info->h - info->w;
X	sbindex = (sbh * ((win3 *)info->packet)->startaddr + coresize/2) / coresize;
X	di_outline_box(dpy, info->win,
X								 info->x + di_butbw, info->y + di_butbw + sbindex, 
X								 info->w - di_butbw*2, info->w - di_butbw*2,
X								 info->flags & GBUT_PRESSED);
X	gc = di_picgc[DI_EMPTY];
X	if (!di_color)
X		XSetTile(dpy, gc, di_grey75pixmap);
X	if (sbindex > 0)
X		XFillRectangle(dpy, info->win, gc,
X									 info->x + di_butbw, info->y + di_butbw,
X									 info->w-di_butbw*2, sbindex);
X	if (sbindex < sbh)
X		XFillRectangle(dpy, info->win, gc,
X									 info->x + di_butbw, info->y + info->w + sbindex - di_butbw,
X									 info->w-di_butbw*2, sbh-sbindex);
X	if (!di_color)
X		XSetTile(dpy, gc, di_grey50pixmap);
X	if (info->flags & GBUT_PRESSED)
X		gc = di_cytgc;
X	else
X		gc = di_cybgc;
X	XFillRectangle(dpy, info->win, gc,
X								 info->x + di_butbw*2, sbindex+info->y+di_butbw*2,
X								 info->w - di_butbw*4, info->w - di_butbw*4);
X}
X
X#endif  /* X11_DISP */
END_OF_FILE
if test 7913 -ne `wc -c <'di_but.c'`; then
    echo shar: \"'di_but.c'\" unpacked with wrong size!
fi
# end of 'di_but.c'
fi
if test -f 'gbut.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'gbut.h'\"
else
echo shar: Extracting \"'gbut.h'\" \(1797 characters\)
sed "s/^X//" >'gbut.h' <<'END_OF_FILE'
X/*
X * gbut.h
X */
X
X#ifndef  _GBUT_H_
X#define  _GBUT_H_
X
X#ifndef  TRUE
X#define  TRUE   1
X#define  FALSE  0
X#endif
X
Xtypedef struct gbut_info  {
X	Window  win;
X	int  x, y, w, h;
X	unsigned  flags;
X	char  *keystr;
X	void  (*drawfunc)(int butnum, struct gbut_info *info);
X	int   (*checkfunc)(int butnum, struct gbut_info *info,
X										 int checktype, int x, int y);
X	void  *packet;
X} gbut_info;
X#define  GBUT_DRAWABLE    0x01  /* R/W. */
X#define  GBUT_PRESSABLE   0x02  /* R/W. */
X#define  GBUT_TWITCHABLE  0x04  /* R/W. */
X#define  GBUT_PRESSED     0x08  /* Read only. */
X#define  GBUT_TWITCHED    0x10  /* Read only. */
X#define  GBUT_MAXBITS  5
X#define  GBUT_NODRAW     (GBUT_DRAWABLE<<GBUT_MAXBITS)    /* Write only. */
X#define  GBUT_NOPRESS    (GBUT_PRESSABLE<<GBUT_MAXBITS)   /* Write only. */
X#define  GBUT_NOTWITCH   (GBUT_TWITCHABLE<<GBUT_MAXBITS)  /* Write only. */
X
X#define  GBUT_CT_PRESS    0
X#define  GBUT_CT_RELEASE  1
X#define  GBUT_CT_MOVE     2
X#define  GBUT_CT_PMOVE    3
X
X#define  GBUT_NOBUT  (-1)
X
Xextern void  gbut_inbutton(Window win), gbut_outbutton(Window win);
Xextern void  gbut_badwindow(Window win);
Xextern void  gbut_init(Display *dpy, Window win);
Xextern void  gbut_create(int butnum, gbut_info *info);
Xextern void  gbut_destroy(int butnum);
Xextern void  gbut_setflags(int butnum, unsigned newflags);
Xextern void  gbut_draw(int butnum);
Xextern void  gbut_redraw(Window win, int x, int y, int w, int h);
Xextern int   gbut_mmove(Window win, int x, int y);
Xextern int   gbut_mpress(Window win, int x, int y);
Xextern int   gbut_mrelease(Window win, int x, int y);
Xextern int   gbut_kpress(Window win, char *kstring);
Xextern int   gbut_krelease(Window win, char *kstring);
Xextern int   gbut_true(int butnum, gbut_info *info,
X								int checktype, int x, int y);
X
X#endif  _GBUT_H_
END_OF_FILE
if test 1797 -ne `wc -c <'gbut.h'`; then
    echo shar: \"'gbut.h'\" unpacked with wrong size!
fi
# end of 'gbut.h'
fi
echo shar: End of shell archive.
exit 0
