<?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:[email protected]">[email protected]</a>.</span>
</font></center>
</body>
</html>