<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv=Content-Type content="text/html; charset=utf8">
<title>/usr/web/sources/contrib/arpunk/zombies.c - Plan 9 from Bell Labs</title>
<!-- THIS FILE IS AUTOMATICALLY GENERATED. -->
<!-- EDIT sources.tr INSTEAD. -->
</meta>
</head>
<body>
<p style="margin-top: 0; margin-bottom: 0.17in"></p>
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: center;">
<span style="font-size: 10pt"><a href="/plan9/">Plan 9 from Bell Labs</a>&rsquo;s /usr/web/sources/contrib/arpunk/zombies.c</span></p>
<p style="margin-top: 0; margin-bottom: 0.17in"></p>
<p style="margin-top: 0; margin-bottom: 0.17in"></p>
<center><font size=-1>
Copyright © 2009 Alcatel-Lucent.<br />
Distributed under the
<a href="/plan9/license.html">Lucent Public License version 1.02</a>.
<br />
<a href="/plan9/download.html">Download the Plan 9 distribution.</a>
</font>
</center>
<p style="margin-top: 0; margin-bottom: 0.17in"></p>
<table width="100%" cellspacing=0 border=0><tr><td align="center">
<table cellspacing=0 cellpadding=5 bgcolor="#eeeeff"><tr><td align="left">
<pre>
<!-- END HEADER -->
/* zombies */

#include &lt;u.h&gt;
#include &lt;libc.h&gt;
#include &lt;thread.h&gt;
#include &lt;draw.h&gt;
#include &lt;mouse.h&gt;

#define NCOLORS 200

#define MINX -1.0
#define MAXX 1.0
#define MINY -1.0
#define MAXY 1.0

typedef struct Pos Pos;
typedef struct Person Person;

int ppl = 400;
int wlkrs = 10;

struct Pos
{
	double x, y;
};

struct Person
{
	Pos;
	int speed, dead;
	int health;
	int die, ref, targref;
};

Person *persons;
Mousectl *mctl;
Image *col[NCOLORS];
Image *grey;
Image *red;
long sync;

/* stolen from packet.c */
u32int
randomcol(void)
{
	int c[3] = {0, 255, 0};
	int *j, t;
	
	c[2] = rand() % 256;
	j = c + rand() % 3;
	t = c[2];
	c[2] = *j;
	*j = t;
	if(rand()%2){
		t = c[1];
		c[1] = c[0];
		c[0] = t;
	}
	return (c[0] &lt;&lt; 24) | (c[1] &lt;&lt; 16) | (c[2] &lt;&lt; 8) | 0xFF;
}

Point
convert(Pos* p)
{
	return (Point){
		screen-&gt;r.min.x + (screen-&gt;r.max.x - screen-&gt;r.min.x) *
		((p-&gt;x - MINX) / (MAXX - MINX)),
		screen-&gt;r.min.y + (screen-&gt;r.max.y - screen-&gt;r.min.y) *
		((p-&gt;y - MINX) / (MAXX - MINX))};
}

Pos
deconvert(Point p)
{
	return (Pos){
		MINX + (MAXX - MINX) *
		((double)(p.x - screen-&gt;r.min.x) / (screen-&gt;r.max.x - screen-&gt;r.min.x)),
		MINY + (MAXY - MINY) *
		((double)(p.y - screen-&gt;r.min.y) / (screen-&gt;r.max.y - screen-&gt;r.min.y))};
}

void *
emallocz(int size)
{
	void *v;
	
	v = mallocz(size, 1);
	if(v == nil)
		sysfatal("malloc: %r");
	setmalloctag(v, getcallerpc(&amp;size));
	return v;
}

void
createperson(Pos p)
{
	int i, j;
	j = ppl;

	for(i = 0; i &lt; ppl; i++) {
		if(persons[i].Pos.x == p.x &amp;&amp; persons[i].Pos.y == p.y)
			return;
		if(persons[i].die == 3 &amp;&amp; j == ppl)
			j = i;
	}

	persons[j].Pos = p;
	persons[j].die = 0;
	persons[j].ref = 0;
	persons[j].targref = 0;
}

void
createworld(void)
{
	int i, j;

	for(i = 0; i &lt; NCOLORS; i++)
		col[i] = allocimage(display, Rect(0, 0, 1, 1), screen-&gt;chan, 1, randomcol());

	grey = allocimage(display, Rect(0, 0, 1, 1), screen-&gt;chan, 1, 0x888888FF);
	red = allocimage(display, Rect(0, 0, 1, 1), screen-&gt;chan, 1, 0xFF0000FF);
	
	persons = emallocz(sizeof(*persons) * ppl);

	for(i = 0; i &lt; ppl; i++) {
		persons[i].x = frand() * (MAXX - MINX) + MINX;
		persons[i].y = frand() * (MAXY - MINY) + MINY;
	}

	for(i = 0; i &lt; wlkrs; i++) {
		persons[i].dead = 1;
	}
}

void
rect(Pos *p, int size, Image *col)
{
	Point poi;
	Rectangle r;
	
	poi = convert(p);
	r = insetrect(Rpt(poi, poi), -size);
	draw(screen, r, col, nil, ZP);
}

void
domouse(void)
{
	static Mouse m;
	int lastbut, i;
	double dx, dy, d;
	Point poi;
	
	if(nbrecv(mctl-&gt;resizec, &amp;i) == 1)
		if(getwindow(display, Refnone) &lt; 0)
			sysfatal("getwindow: %r");

	lastbut = m.buttons;
	nbrecv(mctl-&gt;c, &amp;m);

	if(lastbut &amp; 4 &amp;&amp; !(m.buttons &amp; 4))
		for(i = 0; i &lt; ppl; i++){
			poi = convert(&amp;persons[i]);
			dx = poi.x - m.xy.x;
			dy = poi.y - m.xy.y;
			d = sqrt(dx * dx + dy * dy);
			if(d &lt; 5){
				persons[i].die = 1;
				break;
			}
		}

	if(lastbut &amp; 1 &amp;&amp; !(m.buttons &amp; 1))
		createperson(deconvert(m.xy));
}

void
movepersons()
{
	int i;

	sleep(600);

	for(i = 0; i &lt; ppl; i++) {
		persons[i].x = frand() * (MAXX - MINX) + MINX;
		persons[i].y = frand() * (MAXY - MINY) + MINY;
	}
}

void
timing()
{
	for(;;){
		semrelease(&amp;sync, 1);
		sleep(30);
	}
}

void
usage(void)
{
	fprint(2, "usage: %s [-D] [-z walkers] [-p ppl]\n", argv0);
	exits("usage");
}

void
threadmain(int argc, char **argv)
{
	int i, j;
	Person *n;

	ARGBEGIN {
	case 'D': break;
	case 'z': wlkrs = atoi(EARGF(usage())); break;
	case 'p': ppl = atoi(EARGF(usage())); break;
	default: usage();
	} ARGEND;

	initdraw(nil, nil, nil);
	mctl = initmouse(nil, screen);
	createworld();

	proccreate(timing, nil, mainstacksize);

	for(;;) {
		domouse();
		draw(screen, screen-&gt;r, display-&gt;white, nil, ZP);

		for(n = persons; n &lt; ppl + persons; n++) {
			if(!n-&gt;die || n-&gt;ref)
				rect(n, 3, n-&gt;die ? grey : display-&gt;black);

			if(n-&gt;dead)
				rect(n, 3, n-&gt;die ? grey : red);
		}

		movepersons();
		flushimage(display, 1);
		semacquire(&amp;sync, 1);
	}
}
<!-- BEGIN TAIL -->
</pre>
</td></tr></table>
</td></tr></table>
<p style="margin-top: 0; margin-bottom: 0.17in"></p>
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: center;">
<span style="font-size: 10pt"></span></p>
<p style="margin-top: 0; margin-bottom: 0.50in"></p>
<p style="margin-top: 0; margin-bottom: 0.33in"></p>
<center><table border="0"><tr>
<td valign="middle"><a href="http://www.alcatel-lucent.com/"><img border="0" src="/plan9/img/logo_ft.gif" alt="Bell Labs" />
</a></td>
<td valign="middle"><a href="http://www.opensource.org"><img border="0" alt="OSI certified" src="/plan9/img/osi-certified-60x50.gif" />
</a></td>
<td><img style="padding-right: 45px;" alt="Powered by Plan 9" src="/plan9/img/power36.gif" />
</td>
</tr></table></center>
<p style="margin-top: 0; margin-bottom: 0.17in"></p>
<center>
<span style="font-size: 10pt">(<a href="/plan9/">Return to Plan 9 Home Page</a>)</span>
</center>
<p style="margin-top: 0; margin-bottom: 0.17in"></p>
<center><font size=-1>
<span style="font-size: 10pt"><a href="http://www.lucent.com/copyright.html">Copyright</a></span>
<span style="font-size: 10pt">© 2009 Alcatel-Lucent.</span>
<span style="font-size: 10pt">All Rights Reserved.</span>
<br />
<span style="font-size: 10pt">Comments to</span>
<span style="font-size: 10pt"><a href="mailto:webmaster@plan9.bell-labs.com">webmaster@plan9.bell-labs.com</a>.</span>
</font></center>
</body>
</html>