shithub: plan9front

Download patch

ref: d87fb23a937783e20bb1ff1d09899edf6cae39de
parent: 0741147eabb9c915c43d23215b2cb5399fcd07bb
author: rodri <rgl@antares-labs.eu>
date: Thu Aug 26 16:04:59 EDT 2021

bring games/swar from 1ed sources.

ape/diff: b/sys/src/games/swar/null: No such file or directory
--- a/sys/src/games/mkfile	Wed Aug 25 18:15:34 2021
+++ b/sys/src/games/mkfile	Thu Aug 26 16:04:59 2021
@@ -46,6 +46,7 @@
 	snes\
 	sokoban\
 	sudoku\
+	swar\
 	timmy\
 	v8e\
 
--- /dev/null	Mon Oct 18 12:05:45 2021
+++ b/sys/src/games/swar/accel.h	Thu Aug 26 16:04:59 2021
@@ -0,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	Mon Oct 18 12:05:45 2021
+++ b/sys/src/games/swar/boom.icon	Thu Aug 26 16:04:59 2021
@@ -0,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	Mon Oct 18 12:05:45 2021
+++ b/sys/src/games/swar/deathstar.icon	Thu Aug 26 16:04:59 2021
@@ -0,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	Mon Oct 18 12:05:45 2021
+++ b/sys/src/games/swar/missile.icon	Thu Aug 26 16:04:59 2021
@@ -0,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	Mon Oct 18 12:05:45 2021
+++ b/sys/src/games/swar/mkfile	Thu Aug 26 16:04:59 2021
@@ -0,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	Mon Oct 18 12:05:45 2021
+++ b/sys/src/games/swar/player0.icon	Thu Aug 26 16:04:59 2021
@@ -0,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	Mon Oct 18 12:05:45 2021
+++ b/sys/src/games/swar/player1.icon	Thu Aug 26 16:04:59 2021
@@ -0,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	Mon Oct 18 12:05:45 2021
+++ b/sys/src/games/swar/swar.c	Thu Aug 26 16:04:59 2021
@@ -0,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;
+}