ref: d87fb23a937783e20bb1ff1d09899edf6cae39de
parent: 0741147eabb9c915c43d23215b2cb5399fcd07bb
author: rodri <[email protected]>
date: Thu Aug 26 16:04:59 EDT 2021
bring games/swar from 1ed sources.
--- a/sys/src/games/mkfile
+++ b/sys/src/games/mkfile
@@ -46,6 +46,7 @@
snes\
sokoban\
sudoku\
+ swar\
timmy\
v8e\
--- /dev/null
+++ b/sys/src/games/swar/accel.h
@@ -1,0 +1,16 @@
+512, 0,
+473, 196,
+362, 362,
+196, 473,
+0, 512,
+-196, 473,
+-362, 362,
+-473, 196,
+-512, 0,
+-473, -196,
+-362, -362,
+-196, -473,
+0, -512,
+196, -473,
+362, -362,
+473, -196,
--- /dev/null
+++ b/sys/src/games/swar/boom.icon
@@ -1,0 +1,67 @@
+"................ ................ ................ ................",
+"................ ................ ................ ................",
+"................ ................ ................ ................",
+"................ ................ ................ ................",
+"................ ................ ................ .......x........",
+"................ ................ ................ .....x.x........",
+"................ ........x....... .......x.x...... .....x.x..x.....",
+"........x....... ......x.x....... .......xxx...... .........xxx....",
+"......xxx....... ......xxx....... ......xx........ ......xx........",
+".......x........ ........xx...... .......xx....... .....xxxxx......",
+"................ ................ ................ ................",
+"................ ................ ................ ................",
+"................ ................ ................ ................",
+"................ ................ ................ ................",
+"................ ................ ................ ................",
+"................ ................ ................ ................",
+
+"................ ................ ................ ................",
+"................ ................ ................ x.x.......x....x",
+"................ ........xx...... ....x.xx.x....x. ..x........x....",
+"................ .........x...... ...xx..x....x... .x.x...xxx.x....",
+"......x......... ....x.xxx....... ..x.xx......x... ..xxxx..xx..x...",
+".....xxxxxx..... .....xxxx.x..... ..xx.xxxxx.x.x.. ..x.x..x.x..xx..",
+".....x.x..xx.... ...........x.... ...x....x.x..x.. .x....x..xxxx...",
+"...xxx.x.xx..... .....x.xx..x.... ...xxxxx..x.x... ....xx..xxxx..x.",
+".....x.x.xx..... ....xx.xx....... ..xx.xx.x.xx.... ..xxx.xx.xx.....",
+"......x.xx...... ....x..xx....... ..xx.xx.....x... ...x.xx...x.x...",
+"....x.x..xx..... .....xx.x.x..... ....xxx......... ..xxxx..x...x...",
+".....xx....x.... .........xx..... ...x....xxx..... ..x.x..xx.xxx...",
+"................ ........xx...... ....x..xx.x.x... ....xx.xx.x.....",
+"................ ................ ...x......x..... ...xxxxx.x...x..",
+"................ ................ ................ ...xxxx..x...x..",
+"................ ................ ................ ................",
+
+"................ ................ ................ ................",
+".......x..x..... .......x..x..... .......x..x..... .......x..x.....",
+"......x......... ......x......... ......x......... ................",
+"....x.x...x.x.x. ....x.x...x.x.x. ....x.x...x.x.x. ....x.....x.x.x.",
+"...xx.xx.xx.x.x. ...xx.xx.xx.x.x. ...xx.xx.xx.x.x. ...xx.xx.xx.x.x.",
+"..x..xxxx.xx.x.x ..x..xx.x.x..x.x ......x.x.x..x.x ........x.x..x.x",
+"...xx.x.x.x...x. ....x.x.x.....x. ....x.x.......x. ..............x.",
+"..x.x.x.x.xx.xx. ..x.x...x.xx.xx. ..x.x.....xx.xx. ..x.......xx.xx.",
+"...xx.xxxxx..x.. ...xx.x.xxx..x.. ...x..x......x.. ...x..x......x..",
+"...xxx.xxx.xxxx. ...xx...x..xxxx. ...xx...x..xx.x. ...xx.......x.x.",
+"x.x.xx.xx.x.x.x. x.x.xx.xx...x.x. x.x.x..xx...x.x. x...x.......x.x.",
+"....xx.xx.xx.x.. ....xx..x.xx.x.. ....xx..x.x..x.. ....x...x.x..x..",
+"...x...x...xx... ...x...x...xx... ...x...x....x... ...x...x....x...",
+"....xx...x..x... ....xx...x..x... ....xx...x...... ....xx...x......",
+"....x.x.x....... ....x.x.x....... ....x.x.x....... ....x.x.x.......",
+"................ ................ ................ ................",
+
+"................ ................ ................ ................",
+".......x..x..... .......x..x..... .......x..x..... .......x..x.....",
+"................ ................ ................ ................",
+"....x.....x.x.x. ....x.......x.x. ....x.......x.x. ....x.......x...",
+"...xx..x.x..x... ...x...x.x...... ...x...x........ ...x............",
+"........x.x..x.x ........x.x..x.x ........x.x....x ..........x....x",
+"................ ................ ................ ................",
+"..x.......x..xx. ..x..........xx. ..x..........xx. ..x...........x.",
+"...x..x......x.. ...x..x......x.. ................ ................",
+"...xx.........x. ...x..........x. ...x..........x. ...x..........x.",
+"x.............x. x............... x............... ................",
+"........x.x..x.. ........x.x..x.. ..........x..x.. ................",
+"...x...x....x... ...x...x....x... ...x...x....x... ...x...x....x...",
+"....x....x...... ....x....x...... .........x...... .........x......",
+"....x.x.x....... ....x...x....... ....x...x....... ....x...x.......",
+"................ ................ ................ ................",
--- /dev/null
+++ b/sys/src/games/swar/deathstar.icon
@@ -1,0 +1,16 @@
+". . . . . x x x x x x . . . . .",
+". . . x x x x x . . . . x . . .",
+". . . . . . . . . . . . . . . .",
+". x x x x x x x x x x x x x x .",
+". . x x x x x x x x . . . . x .",
+". . . . . . . . . . . . . . . .",
+"x x x x x x x x x x x x x x x x",
+". x x x x x x x x x . . . . . x",
+". . . . . . . . . . . . . . . .",
+"x x x x x x x x x x x x x x x x",
+". . . x x x x x . . . . . . . x",
+". . . . . . . . . . . . . . . .",
+". x x x x x x x x x x x x x x .",
+". . . . . . . . . . . . . . . .",
+". . . x . . . . . . . . x . . .",
+". . . . . x x x x x x . . . . .",
--- /dev/null
+++ b/sys/src/games/swar/missile.icon
@@ -1,0 +1,35 @@
+". . . x x . . . . . . x x . . . . . . x x . . . . . . x x . . .",
+". x x x . x x . . x x x . x x . . x x x . x x . . x x . . x x .",
+". x . . x . x . . x . . x . x . . x . . . x x . . x x . . . x .",
+"x x . . . . x x x x . . . x x x x . . x x . . x x x . x . x . x",
+"x x x x x . x x x x . x . x x x x . . . x x x x x x x . . . x x",
+". x . . . . x . . x . . . . x . . x . x x . x . . x x . . . x .",
+". x x . x x x . . x x . x x x . . x x x . x x . . x x x . x x .",
+". . . x x . . . . . . x x . . . . . . x x . . . . . . x x . . .",
+
+". . . x x . . . . . . x x . . . . . . x x . . . . . . x x . . .",
+". x x x . x x . . x x x x x x . . x x . x x x . . x x x x x x .",
+". x x x x x x . . x x x . x x . . x x x x . x . . x . x x x x .",
+"x . . x x x . x x . . . x . x x x . x x . x . x x x . . . . x x",
+"x . . . . x x x x x . x . x . x x . x x x . . x x . . . x x . x",
+". x . . . x x . . x . . . . x . . x . x x x x . . x . . x . x .",
+". x x . x x x . . x x . . x x . . x x x . x x . . x x . . x x .",
+". . . x x . . . . . . x x . . . . . . x x . . . . . . x x . . .",
+
+". . . x x . . . . . . x x . . . . . . x x . . . . . . x x . . .",
+". x x . . x x . . x x . x x x . . x x x x x x . . x x x x x x .",
+". x . x . . x . . x . . x x x . . x . . . x x . . x . x . x x .",
+"x . x x . x x x x x . x x . . x x x x . . . x x x x . x . x x x",
+"x . . x . x . x x . x x x x x x x x . x x . . x x . x . . . x x",
+". x . . . . x . . x x . . . x . . x x x x x x . . x . x x . x .",
+". x x . . x x . . x x . . x x . . x x . . x x . . x x . . x x .",
+". . . x x . . . . . . x x . . . . . . x x . . . . . . x x . . .",
+
+". . . x x . . . . . . x x . . . . . . x x . . . . . . x x . . .",
+". x x . . x x . . x x . . x x . . x x x . x x . . x x x . x x .",
+". x . . x x x . . x x . . . x . . x x x . . x . . x x x . . x .",
+"x x . x . . . x x x . x x . . x x x . x x . . x x . x x x . x x",
+"x . x x x . . x x . x . x x . x x x x . . . . x x x x . . . . x",
+". x . . x . x . . x . x . x x . . x . x . . x . . x x x x x x .",
+". x x x . x x . . x x x . x x . . x x x x x x . . x x x . x x .",
+". . . x x . . . . . . x x . . . . . . x x . . . . . . x x . . .",
--- /dev/null
+++ b/sys/src/games/swar/mkfile
@@ -1,0 +1,10 @@
+</$objtype/mkfile
+
+BIN=/$objtype/bin/games
+TARG=swar
+OFILES=\
+ swar.$O\
+
+HFILES=player0.icon player1.icon accel.h missile.icon deathstar.icon boom.icon
+
+</sys/src/cmd/mkone
--- /dev/null
+++ b/sys/src/games/swar/player0.icon
@@ -1,0 +1,47 @@
+". x . . . . . . . . . . . . x x . . . . . . . . . . . . x . . . . . . . . x . x x x . .",
+". x x . . . . . . . . . . . x . x . . . . . . . . . . x . x . . . . . x x x x . . x . .",
+". x . x . . . . . . . . x x . . x . . . . . . . . x x . . x . . . . . x x . . . x . . .",
+". x . . x x x x x . . . x x . . x . . . . . . . x x . . . x . . . x x . . . . . x . . .",
+"x x . . . . . . . x . x x . . . . x . . . . . . x . . . . x . . . x . . . . . . x . . .",
+"x x . . . . . . . . x . x . . . . . x x . . . x . . . . . . x . . . x x x . . . . x . .",
+"x x . . . . . . . x . x . . . . . . . . x . x . . . . . . . . x . . . . . x . . . x . .",
+". x . . x x x x x . . x . x x x . . . . . x . x x x x . . . . . x . . . . . x . . . x .",
+". x . x . . . . . . . x x . . . x x . . . x . . . . . x . . . . x . . . . . x . . . x .",
+". x x . . . . . . . . . . . . . . . x x x x . . . . . . x . . . x . . . . . . x . . x .",
+". x . . . . . . . . . . . . . . . . . . . . . . . . . . . x x x x . . . . . . . x x x .",
+
+". . . . x x x . . . . . . x x x . x . . . . . . . . x . . . . . . . . . . . . x x . . .",
+"x x x x x x x x x x x . . x . . x x x x . . . . . x . x . . . . . . . . . . x . x . . .",
+". x . . . . . . . x . . . . x . . . x x . . . . . x . . x x . . . . . . . . x . . x x .",
+". . x . . . . . x . . . . . x . . . . . x x . . . x . . . x x . . . . . . . x . . x x .",
+". . . x . . . x . . . . . . x . . . . . . x . . . x . . . . x . . . . . . x . . . . x x",
+". . . x . . . x . . . . . x . . . . x x x . . . x . . . . . . x . . . x x . . . . . x .",
+". . . x . . . x . . . . . x . . . x . . . . . x . . . . . . . . x . x . . . . . . . . x",
+". . . x . . . x . . . . x . . . x . . . . . x . . . . . x x x x . x . . . . . x x x . x",
+". . . x . . . x . . . . x . . . x . . . . . x . . . . x . . . . . x . . . x x . . . x x",
+". . . . x . x . . . . . x . . x . . . . . . x . . . x . . . . . . x x x x . . . . . . .",
+". . . . . x . . . . . . x x x . . . . . . . x x x x . . . . . . . . . . . . . . . . . .",
+
+". . . . . . . . . x . . . . . . . . . . . . x x x x . . . . . . . . x x x . . . . . . .",
+". . . . . . . . x x . x x x x . . . . . . . x . . . x . . . . . . . x . . x . . . . . .",
+". . . . . . . x . x . x . . . x x . . . x x x . . . . x . . . . . . x . . . x . . . . .",
+". . x x x x x . . x . x . . . . . x x x . x x . . . . . x x x x . . x . . . x . . . . .",
+". x . . . . . . . x x . x . . . . . . . . x . x . . . . . . . . x . . x . . . x . . . .",
+"x . . . . . . . . x x . . x x . . . . . x . . . x . . . . . . x . . . x . . . . x x x .",
+". x . . . . . . . x x . . . . x . . . . x x . . . x . . . . x . . . . . x . . . . . . x",
+". . x x x x x . . x . . . . . . x . . x x . . . . x . . . x x . . . . . x . . . . . x x",
+". . . . . . . x . x . . . . . . x . . x x . . . . x . . x x . . . . . . x . . . x x . .",
+". . . . . . . . x x . . . . . . x . x . . . . . . x . x . . . . . . . x . . x x x x . .",
+". . . . . . . . . x . . . . . . . x x . . . . . . . x . . . . . . . . x x x . x . . . .",
+
+". . . . . x . . . . . . . . . . . . x x x . . . . . . . . x x x x . . . . . . . . . . .",
+". . . . x . x . . . . . . . . . . x . . x . . . . . . . x . . . x . . . . . . . x x x x",
+". . . x . . . x . . . . . . . . x . . . x . . . . . . x . . . . x x x . . . x x . . . x",
+". . . x . . . x . . . . . . . . x . . . x . . x x x x . . . . . x x . x x x . . . . . x",
+". . . x . . . x . . . . . . . x . . . x . . x . . . . . . . . x . x . . . . . . . . x .",
+". . . x . . . x . . . . x x x . . . . x . . . x . . . . . . x . . . x . . . . . x x . .",
+". . . x . . . x . . . x . . . . . . x . . . . . x . . . . x . . . x x . . . . x . . . .",
+". . x . . . . . x . . x x . . . . . x . . . . . x x . . . x . . . . x x . . x . . . . .",
+". x . . . . . . . x . . . x x . . . x . . . . . . x x . . x . . . . x x . . x . . . . .",
+"x x x x x x x x x x x . . x x x x . . x . . . . . . . x . x . . . . . . x . x . . . . .",
+". . . . x x x . . . . . . . . x . x x x . . . . . . . . x . . . . . . . x x . . . . . .",
--- /dev/null
+++ b/sys/src/games/swar/player1.icon
@@ -1,0 +1,47 @@
+"x . . . . . . . . . . . . x x . . . . . . . . . . . . x . . . . . . . . x . x x x . . .",
+"x x . . . . . . . . . . . x x x . . . . . . . . . . x x x . . . . . x x x x x x x . . .",
+"x x x . . . . . . . . x x x x x . . . . . . . . x x x x x . . . . . x x x x x x x . . .",
+"x x x x x x x x . . . x x x x x . . . . . . . x x x x x x . . . x x x x x . x x . . . .",
+"x x x x x x x x x . x x x x x x x . . . . . . x x . x x x . . . x x x x x . x x . . . .",
+"x . . . . . . . . x . x x . . x x x x . . . x x x x . x x x . . . x x x x x . x x . . .",
+"x x x x x x x x x . x x x x x . . x x x . x x x x x x . x x x . . . . . x x . x x . . .",
+"x x x x x x x x . . x x x x x x x . . x x . x x x x x x . x x x . . . . . x x . x x . .",
+"x x x . . . . . . . x x x . . x x x x . x . . . . . x x x . x x . . . . . x x . x x . .",
+"x x . . . . . . . . . . . . . . . x x x x . . . . . . x x x . x . . . . . . x x . x . .",
+"x . . . . . . . . . . . . . . . . . . . . . . . . . . . x x x x . . . . . . . x x x . .",
+
+". . . x x x . . . . . . x x x . x . . . . . . . . x . . . . . . . . . . . . x x . . . .",
+"x x x x x x x x x x . . x x x x x x x . . . . . x x x . . . . . . . . . . x x x . . . .",
+"x x x x . x x x x . . . x x x x x x x . . . . . x x x x x . . . . . . . . x x x x x . .",
+". x x x . x x x . . . . . x x . x x x x x . . . x x x x x x . . . . . . . x x x x x . .",
+". . x x . x x . . . . . . x x . x x x x x . . . x x x . x x . . . . . . x x x x x x x .",
+". . x x . x x . . . . . x x . x x x x x . . . x x x . x x x x . . . x x x x . . x x . .",
+". . x x . x x . . . . . x x . x x . . . . . x x x . x x x x x x . x x x . . x x x x x .",
+". . x x . x x . . . . x x . x x . . . . . x x x . x x x x x x . x x . . x x x x x x x .",
+". . x x . x x . . . . x x . x x . . . . . x x . x x x . . . . . x . x x x x . . x x x .",
+". . . x . x . . . . . x . x x . . . . . . x . x x x . . . . . . x x x x . . . . . . . .",
+". . . . x . . . . . . x x x . . . . . . . x x x x . . . . . . . . . . . . . . . . . . .",
+
+". . . . . . . . x . . . . . . . . . . . . x x x x . . . . . . . . x x x . . . . . . . .",
+". . . . . . . x x . x x x x . . . . . . . x . x x x . . . . . . . x . x x . . . . . . .",
+". . . . . . x x x . x . x x x x . . x x x x x . x x x . . . . . . x x . x x . . . . . .",
+". x x x x x x x x . x x . . x x x x x x x x x x . x x x x x x . . x x . x x . . . . . .",
+"x x x x x x x x x x . x x x . . x x x x x . x x x . x x x x x x . . x x . x x . . . . .",
+". . . . . . . . x x . . x x x x . . x x . . . x x x . x x x x . . . x x . x x x x x . .",
+"x x x x x x x x x x . . . . x x x x x x x . . . x x x . x x . . . . . x x . x x x x x .",
+". x x x x x x x x . . . . . . x x x x x . . . . x x x x x x . . . . . x x . x x x x x .",
+". . . . . . x x x . . . . . . x x x x x . . . . x x x x x . . . . . x x x x x x x . . .",
+". . . . . . . x x . . . . . . x x x . . . . . . x x x . . . . . . . x x x x x x x . . .",
+". . . . . . . . x . . . . . . . x x . . . . . . . x . . . . . . . . x x x . x . . . . .",
+
+". . . . x . . . . . . . . . . . . x x x . . . . . . . . x x x x . . . . . . . . . . . .",
+". . . x . x . . . . . . . . . . x x . x . . . . . . . x x x . x . . . . . . . x x x x .",
+". . x x . x x . . . . . . . . x x . x x . . . . . . x x x . x x x x x . . x x x x . x .",
+". . x x . x x . . . . . . . . x x . x x . . x x x x x x . x x x x x x x x x x . . x x .",
+". . x x . x x . . . . . . . x x . x x . . x x x x x x . x x x . x x x x x . . x x x . .",
+". . x x . x x . . . . x x x x x . x x . . . x x x x . x x x . . . x x . . x x x x . . .",
+". . x x . x x . . . x x x x x . x x . . . . . x x . x x x . . . x x x x x x x . . . . .",
+". x x x . x x x . . x x x x x . x x . . . . . x x x x x x . . . . x x x x x . . . . . .",
+"x x x x . x x x x . . . x x x x x x x . . . . . x x x x x . . . . x x x x x . . . . . .",
+"x x x x x x x x x x . . x x x x x x x . . . . . . . x x x . . . . . . x x x . . . . . .",
+". . . x x x . . . . . . . . x . x x x . . . . . . . . x . . . . . . . x x . . . . . . .",
--- /dev/null
+++ b/sys/src/games/swar/swar.c
@@ -1,0 +1,430 @@
+/*
+ * swar -- jerq space war
+ * td&rob 84.01.01
+ *
+ * ported to 9front on 31jul2021
+ */
+#include <u.h>
+#include <libc.h>
+#include <draw.h>
+#include <event.h>
+int xc, yc;
+#define NOBJ (1+2+6*2)
+#define MSPEED (V/32) /* speed of missile relative to ship */
+#define SZ 512 /* maximum scaled coordinate */
+#define V 256 /* velocity scale factor */
+#define G (V*11585) /* 11585 is SZ**(3./2.) */
+#define ALIVE 1
+#define DEAD 2
+#define SUN 3
+#define BOOM 4
+#define HYPER 5
+#define SLEEP 40 /* ms per iteration */
+#define TUBA (2000/SLEEP) /* iterations until born again */
+#define HYTIME ((600+rand()%600)/SLEEP) /* iterations in hyperspace */
+char *starbits[]={
+#include "deathstar.icon"
+};
+Image *stardwg;
+Rectangle starrect={0, 0, 16, 16};
+char *p0bits[]={
+#include "player0.icon"
+};
+Image *p0dwg;
+Rectangle p0rect={0, 0, 44, 44};
+char *p1bits[]={
+#include "player1.icon"
+};
+Image *p1dwg;
+Rectangle p1rect={0, 0, 44, 44};
+char *misbits[]={
+#include "missile.icon"
+};
+Image *misdwg;
+Rectangle misrect={0, 0, 32, 32};
+char *boombits[]={
+#include "boom.icon"
+};
+Image *boomdwg;
+Rectangle boomrect={0, 0, 64, 64};
+struct obj{
+ int x, y;
+ int vx, vy; /* scaled by V */
+ int orientation;
+ int state;
+ int diameter;
+ Image *bp;
+ int curdwg;
+#define wrapped timer
+ int timer;
+}obj[NOBJ], iobj[]={
+ {0, 0, 0, 0, 0, SUN, 16},
+ { 300, 0, 0, 5*V, 8, ALIVE, 11, 0, 0, TUBA},
+ {-300, 0, 0, -5*V, 0, ALIVE, 11, 0, 0, TUBA},
+ {0, 0, 0, 0, 0, ALIVE, 8},
+};
+#define ATT (&obj[0])
+#define P0 (&obj[1])
+#define P1 (&obj[2])
+int score[3];
+#define NORIENTATION 16
+struct dv{
+ int x, y;
+}dv[NORIENTATION]={
+#include "accel.h"
+};
+
+int xc, yc, size;
+void kbdplayer(int c);
+void hyper(struct obj *o);
+void right(struct obj *o);
+void left(struct obj *o);
+void jerk(struct obj *o);
+int isqrt(int x);
+void fire(struct obj *o);
+void initobj(struct obj *o);
+void deathto(struct obj *o, int doboom);
+void boom(struct obj *o);
+void shards(struct obj *o);
+void move(struct obj *o);
+void blot(struct obj *o, int dwg);
+void collide(struct obj *o, struct obj *p);
+void newscore(struct obj *o, struct obj *p);
+void drawscore(char *str, int sc, int where);
+void doscore(void);
+Image *initbitmap(char *bits[], Rectangle r);
+
+#define sq(x) ((x)*(x))
+#define muldiv(a, b, c) ((a)*(b)/(c))
+
+int
+min(int a, int b)
+{
+ return a<b? a: b;
+}
+
+int
+abs(int a)
+{
+ return a<0? -a: a;
+}
+
+void
+redraw(void)
+{
+ draw(screen, screen->r, display->black, nil, ZP);
+ blot(ATT, ATT->orientation);
+ doscore();
+}
+
+void
+eresized(int)
+{
+ if(getwindow(display, Refnone) < 0)
+ sysfatal("resized");
+ xc=(screen->r.min.x+screen->r.max.x)/2;
+ yc=(screen->r.min.y+screen->r.max.y)/2;
+ size=min(screen->r.max.x-screen->r.min.x,
+ screen->r.max.y-screen->r.min.y)/2;
+ redraw();
+}
+
+void
+main(void)
+{
+ struct obj *o, *p;
+
+ initdraw(nil,nil,nil);
+ einit(Ekeyboard|Emouse);
+
+ iobj[0].bp = stardwg = initbitmap(starbits, starrect);
+ iobj[1].bp = p0dwg = initbitmap(p0bits, p0rect);
+ iobj[2].bp = p1dwg = initbitmap(p1bits, p1rect);
+ iobj[3].bp = misdwg = initbitmap(misbits, misrect);
+ boomdwg = initbitmap(boombits, boomrect);
+
+ xc=(screen->r.min.x+screen->r.max.x)/2;
+ yc=(screen->r.min.y+screen->r.max.y)/2;
+ size=min(screen->r.max.x-screen->r.min.x,
+ screen->r.max.y-screen->r.min.y)/2;
+
+ for(o=obj;o<=P1;o++)
+ initobj(o);
+
+ for(;o!=&obj[NOBJ];o++)
+ o->state=DEAD;
+
+ for(;;){
+ redraw();
+ for(o=obj;o!=&obj[NOBJ];o++){
+ switch(o->state){
+ case ALIVE:
+ case SUN:
+ for(p=o+1;p!=&obj[NOBJ];p++)
+ if(p->state!=DEAD)
+ collide(o, p);
+ if(o>P1)
+ left(o);
+ move(o);
+ break;
+ case HYPER:
+ if(--o->timer==0){
+ blot(o, o->curdwg);
+ o->state=ALIVE;
+ if(rand()%4==0){
+ deathto(o, 1);
+ newscore(ATT, o);
+ }
+ }else
+ move(o);
+ break;
+ case DEAD:
+ if((o==P0 || o==P1) && --o->timer==0)
+ initobj(o);
+ break;
+ case BOOM:
+ shards(o);
+ move(o);
+ break;
+ }
+ }
+ flushimage(display, 1);
+ while(ecanmouse()) emouse();
+ if(ecankbd()) kbdplayer(ekbd());
+ sleep(SLEEP);
+ }
+}
+void kbdplayer(int c){
+ switch(c){
+ case 'k': left(P0); break;
+ case 'o': jerk(P0); break;
+ case ';': right(P0); break;
+ case 'l': fire(P0); break;
+ case '.':
+ case ',': hyper(P0); break;
+ case 'a': left(P1); break;
+ case 'w': jerk(P1); break;
+ case 'd': right(P1); break;
+ case 's': fire(P1); break;
+ case 'z':
+ case 'x': hyper(P1); break;
+ case 'Q': exits(""); break;
+ }
+}
+void hyper(struct obj *o){
+ if(o->state!=ALIVE)
+ return;
+ o->state=HYPER;
+ o->timer=HYTIME;
+ blot(o, o->curdwg);
+}
+void right(struct obj *o){
+ if(++o->orientation==NORIENTATION)
+ o->orientation=0;
+}
+void left(struct obj *o){
+ if(--o->orientation<0)
+ o->orientation=NORIENTATION-1;
+}
+void jerk(struct obj *o){
+ o->vx+=dv[o->orientation].x/2;
+ o->vy+=dv[o->orientation].y/2;
+}
+int isqrt(int x){
+ int s, u;
+ if(x<=0)
+ return(0);
+ if(x>=32768L*(32768L/4))
+ return(2*isqrt(x/4)); /* avoid overflow */
+ for(s=2, u=4;u<x;s+=s, u*=4);
+ while((u=((x+s*s)/s)>>1)<s)
+ s=u;
+ return(s);
+}
+void fire(struct obj *o){
+ struct obj *m;
+ int vx, vy, vl;
+ if(o->state!=ALIVE)
+ return;
+ for(m=o+2;m<&obj[NOBJ];m+=2)
+ if(m->state==DEAD){
+ initobj(m);
+ m->state=ALIVE;
+ vl=isqrt(sq(o->vx)+sq(o->vy));
+ if(vl==0)
+ vl=V;
+ vx=muldiv(vl, dv[o->orientation].x, V);
+ vy=muldiv(vl, dv[o->orientation].y, V);
+ m->x=o->x+muldiv(vx, (o->diameter+m->diameter), vl);
+ m->y=o->y+muldiv(vy, (o->diameter+m->diameter), vl);
+ m->vx=o->vx+MSPEED*dv[o->orientation].x;
+ m->vy=o->vy+MSPEED*dv[o->orientation].y;
+ blot(m, m->orientation);
+ return;
+ }
+}
+void initobj(struct obj *o){
+ *o=(o>P1)?iobj[P1-obj+1]:iobj[o-obj];
+ if(o<=P1)
+ blot(o, o->orientation);
+}
+void deathto(struct obj *o, int doboom){
+ o->state=DEAD;
+ blot(o, o->curdwg);
+ if(doboom)
+ boom(o);
+}
+void boom(struct obj *o){
+ o->state=BOOM;
+ o->bp=boomdwg;
+ o->diameter=boomdwg->r.max.x/4;
+ blot(o, o->orientation=0);
+}
+void shards(struct obj *o){
+ if(++o->orientation==16){
+ blot(o, o->curdwg);
+ o->state=DEAD;
+ o->timer=TUBA;
+ }
+}
+void move(struct obj *o){
+ int r32;
+ int x, y;
+ if(o->state==DEAD || o->state==SUN)
+ return;
+ r32=o->x*o->x+o->y*o->y;
+ if(r32!=0){
+ r32*=isqrt(r32); /* pow(r, 3./2.) */
+ if(r32!=0){
+ o->vx-=G*o->x/r32;
+ o->vy-=G*o->y/r32;
+ }
+ }
+ x=o->x+o->vx/V;
+ y=o->y+o->vy/V;
+ if(x<-SZ || SZ<x){
+ if(o>P1 && o->wrapped){
+ Death:
+ deathto(o, 0);
+ return;
+ }
+ if(x<-SZ) x+=2*SZ; else x-=2*SZ;
+ o->wrapped++;
+ }
+ if(y<-SZ || SZ<y){
+ if(o>P1 && o->wrapped)
+ goto Death;
+ if(y<-SZ) y+=2*SZ; else y-=2*SZ;
+ o->wrapped++;
+ }
+ if(o->state!=HYPER)
+ blot(o, o->curdwg);
+ o->x=x, o->y=y;
+ if(o->state!=HYPER)
+ blot(o, o->orientation);
+}
+
+#define BLOTSIZE 5
+#define rescale(x) muldiv(x, size, SZ)
+
+void
+blot(struct obj *o, int dwg)
+{
+ Point p;
+ int dx = dwg % 4*o->diameter, dy = dwg / 4*o->diameter;
+
+ p = Pt(rescale(o->x)+xc-o->diameter/2, rescale(o->y)+yc-o->diameter/2);
+
+ draw(screen, rectaddpt(Rect(dx,dy,dx+o->diameter,dy+o->diameter),p), o->bp, nil, Pt(dx, dy));
+ o->curdwg = dwg;
+}
+
+void
+collide(struct obj *o, struct obj *p)
+{
+ int doneboom;
+ /* o<p always */
+ if(o->state!=HYPER && p->state!=HYPER
+ && sq(rescale(o->x-p->x))+sq(rescale(o->y-p->y))<
+ sq(o->diameter+p->diameter)/4){
+ newscore(o, p);
+ if(doneboom=o->state==ALIVE)
+ deathto(o, 1);
+ if(p->state==ALIVE)
+ deathto(p, !doneboom || (o==P0 && p==P1));
+ }
+}
+
+void
+newscore(struct obj *o, struct obj *p)
+{
+ doscore();
+ /* o<p always */
+ score[2]++;
+ if(o==P0 || p==P0)
+ score[1]++;
+ if(o==P1 || p==P1)
+ score[0]++;
+ doscore();
+}
+
+void
+drawscore(char *str, int sc, int where)
+{
+ static char buf[16];
+ char *p = buf+6;
+ int s;
+
+ while(*p++=*str++)
+ ;
+
+ p = buf+6;
+ s = abs(sc);
+ do{
+ *--p = s%10 + '0';
+ s /= 10;
+ }while(s);
+
+ if(sc < 0)
+ *--p = '-';
+
+ if(where == 2)
+ s = screen->r.min.x + 20;
+ else if(where == 1)
+ s = (screen->r.min.x + screen->r.max.x - stringwidth(font, p))/2;
+ else
+ s = screen->r.max.x - stringwidth(font, p) - 20;
+
+ draw(screen, Rpt(Pt(s, screen->r.min.y+5),Pt(s+stringwidth(font, p), screen->r.min.y+5+font->height)), display->black, nil, ZP);
+ string(screen, Pt(s, screen->r.min.y+5), display->white, ZP, font, p);
+}
+
+void
+doscore(void)
+{
+ drawscore(" MCI", score[0], 0);
+ drawscore(" AT&T", score[2], 1);
+ drawscore(" SPRINT", score[1], 2);
+}
+
+Image *
+initbitmap(char *bits[], Rectangle r)
+{
+ Point p;
+ char *bit;
+ Image *b=allocimage(display, r, screen->chan, 0, DTransparent);
+
+ if(b==0)
+ sysfatal("allocimage: %r");
+
+ for(p.y = r.min.y; p.y != r.max.y; p.y++){
+ bit = bits[p.y-r.min.y];
+ for(p.x = r.min.x; p.x != r.max.x; p.x++){
+ while(*bit==' ')
+ bit++;
+ if(*bit++=='x')
+ draw(b, Rpt(p,addpt(p,Pt(1,1))), display->white, nil, ZP);
+ }
+ }
+ return b;
+}