aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Peach <mrpeach@users.sourceforge.net>2008-08-21 20:28:49 +0000
committerMartin Peach <mrpeach@users.sourceforge.net>2008-08-21 20:28:49 +0000
commit0bc25ae46ee8e0617090b51d5d4c85b0863e0852 (patch)
tree143f8b2c693e7df08be3fbc8231fb396b040cc7b
parent4845e4a619a1e059627e640e5dd6b3797ecc7d04 (diff)
A cellular automaton to do Conway's life and similar.
svn path=/trunk/externals/mrpeach/; revision=10258
-rw-r--r--life2x/life2x-help.pd716
-rw-r--r--life2x/life2x.c675
2 files changed, 1391 insertions, 0 deletions
diff --git a/life2x/life2x-help.pd b/life2x/life2x-help.pd
new file mode 100644
index 0000000..8b2d706
--- /dev/null
+++ b/life2x/life2x-help.pd
@@ -0,0 +1,716 @@
+#N canvas 374 0 898 909 10;
+#X obj 369 293 bng 15 250 50 0 empty empty single_step 17 7 0 10 -4160
+-4034 -4034;
+#X msg 124 46 dump;
+#X msg 103 25 clear;
+#X msg 250 172 reset;
+#X msg 271 193 return;
+#X msg 166 88 flipv;
+#X msg 145 67 fliph;
+#X msg 187 109 invert \$1;
+#X obj 259 94 tgl 15 0 empty empty empty 17 7 0 10 -4160 -4034 -1 0
+1;
+#X floatatom -9 224 2 0 0 0 - - -;
+#X floatatom 8 224 2 0 0 0 - - -;
+#X floatatom 25 224 2 0 0 0 - - -;
+#X floatatom 43 224 2 0 0 0 - - -;
+#X floatatom 60 224 2 0 0 0 - - -;
+#X floatatom 78 224 2 0 0 0 - - -;
+#X floatatom 95 224 2 0 0 0 - - -;
+#X floatatom 112 224 2 0 0 0 - - -;
+#X floatatom 130 224 2 0 0 0 - - -;
+#X floatatom 147 224 2 0 0 0 - - -;
+#X floatatom 165 224 2 0 0 0 - - -;
+#X floatatom 182 224 2 0 0 0 - - -;
+#X floatatom 199 224 2 0 0 0 - - -;
+#X floatatom 217 224 2 0 0 0 - - -;
+#X floatatom 234 224 2 0 0 0 - - -;
+#X floatatom 252 224 2 0 0 0 - - -;
+#X obj 398 337 life2x 16 16 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+;
+#X obj -1 204 unpack 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15;
+#X obj -43 187 r c0;
+#X obj 398 361 s c0;
+#X floatatom -9 266 2 0 0 0 - - -;
+#X floatatom 8 266 2 0 0 0 - - -;
+#X floatatom 25 266 2 0 0 0 - - -;
+#X floatatom 43 266 2 0 0 0 - - -;
+#X floatatom 60 266 2 0 0 0 - - -;
+#X floatatom 78 266 2 0 0 0 - - -;
+#X floatatom 95 266 2 0 0 0 - - -;
+#X floatatom 112 266 2 0 0 0 - - -;
+#X floatatom 130 266 2 0 0 0 - - -;
+#X floatatom 147 266 2 0 0 0 - - -;
+#X floatatom 165 266 2 0 0 0 - - -;
+#X floatatom 182 266 2 0 0 0 - - -;
+#X floatatom 199 266 2 0 0 0 - - -;
+#X floatatom 217 266 2 0 0 0 - - -;
+#X floatatom 234 266 2 0 0 0 - - -;
+#X floatatom 252 266 2 0 0 0 - - -;
+#X obj -9 246 unpack 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15;
+#X floatatom -10 309 2 0 0 0 - - -;
+#X floatatom 7 309 2 0 0 0 - - -;
+#X floatatom 24 309 2 0 0 0 - - -;
+#X floatatom 42 309 2 0 0 0 - - -;
+#X floatatom 59 309 2 0 0 0 - - -;
+#X floatatom 77 309 2 0 0 0 - - -;
+#X floatatom 94 309 2 0 0 0 - - -;
+#X floatatom 111 309 2 0 0 0 - - -;
+#X floatatom 129 309 2 0 0 0 - - -;
+#X floatatom 146 309 2 0 0 0 - - -;
+#X floatatom 164 309 2 0 0 0 - - -;
+#X floatatom 181 309 2 0 0 0 - - -;
+#X floatatom 198 309 2 0 0 0 - - -;
+#X floatatom 216 309 2 0 0 0 - - -;
+#X floatatom 233 309 2 0 0 0 - - -;
+#X floatatom 251 309 2 0 0 0 - - -;
+#X obj -10 289 unpack 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15;
+#X floatatom -10 351 2 0 0 0 - - -;
+#X floatatom 7 351 2 0 0 0 - - -;
+#X floatatom 24 351 2 0 0 0 - - -;
+#X floatatom 42 351 2 0 0 0 - - -;
+#X floatatom 59 351 2 0 0 0 - - -;
+#X floatatom 77 351 2 0 0 0 - - -;
+#X floatatom 94 351 2 0 0 0 - - -;
+#X floatatom 111 351 2 0 0 0 - - -;
+#X floatatom 129 351 2 0 0 0 - - -;
+#X floatatom 146 351 2 0 0 0 - - -;
+#X floatatom 164 351 2 0 0 0 - - -;
+#X floatatom 181 351 2 0 0 0 - - -;
+#X floatatom 198 351 2 0 0 0 - - -;
+#X floatatom 216 351 2 0 0 0 - - -;
+#X floatatom 233 351 2 0 0 0 - - -;
+#X floatatom 251 351 2 0 0 0 - - -;
+#X obj -10 331 unpack 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15;
+#X floatatom -10 393 2 0 0 0 - - -;
+#X floatatom 7 393 2 0 0 0 - - -;
+#X floatatom 24 393 2 0 0 0 - - -;
+#X floatatom 42 393 2 0 0 0 - - -;
+#X floatatom 59 393 2 0 0 0 - - -;
+#X floatatom 77 393 2 0 0 0 - - -;
+#X floatatom 94 393 2 0 0 0 - - -;
+#X floatatom 111 393 2 0 0 0 - - -;
+#X floatatom 129 393 2 0 0 0 - - -;
+#X floatatom 146 393 2 0 0 0 - - -;
+#X floatatom 164 393 2 0 0 0 - - -;
+#X floatatom 181 393 2 0 0 0 - - -;
+#X floatatom 198 393 2 0 0 0 - - -;
+#X floatatom 216 393 2 0 0 0 - - -;
+#X floatatom 233 393 2 0 0 0 - - -;
+#X floatatom 251 393 2 0 0 0 - - -;
+#X obj -10 373 unpack 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15;
+#X floatatom -10 435 2 0 0 0 - - -;
+#X floatatom 7 435 2 0 0 0 - - -;
+#X floatatom 24 435 2 0 0 0 - - -;
+#X floatatom 42 435 2 0 0 0 - - -;
+#X floatatom 59 435 2 0 0 0 - - -;
+#X floatatom 77 435 2 0 0 0 - - -;
+#X floatatom 94 435 2 0 0 0 - - -;
+#X floatatom 111 435 2 0 0 0 - - -;
+#X floatatom 129 435 2 0 0 0 - - -;
+#X floatatom 146 435 2 0 0 0 - - -;
+#X floatatom 164 435 2 0 0 0 - - -;
+#X floatatom 181 435 2 0 0 0 - - -;
+#X floatatom 198 435 2 0 0 0 - - -;
+#X floatatom 216 435 2 0 0 0 - - -;
+#X floatatom 233 435 2 0 0 0 - - -;
+#X floatatom 251 435 2 0 0 0 - - -;
+#X obj -10 415 unpack 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15;
+#X floatatom -10 477 2 0 0 0 - - -;
+#X floatatom 7 477 2 0 0 0 - - -;
+#X floatatom 24 477 2 0 0 0 - - -;
+#X floatatom 42 477 2 0 0 0 - - -;
+#X floatatom 59 477 2 0 0 0 - - -;
+#X floatatom 77 477 2 0 0 0 - - -;
+#X floatatom 94 477 2 0 0 0 - - -;
+#X floatatom 111 477 2 0 0 0 - - -;
+#X floatatom 129 477 2 0 0 0 - - -;
+#X floatatom 146 477 2 0 0 0 - - -;
+#X floatatom 164 477 2 0 0 0 - - -;
+#X floatatom 181 477 2 0 0 0 - - -;
+#X floatatom 198 477 2 0 0 0 - - -;
+#X floatatom 216 477 2 0 0 0 - - -;
+#X floatatom 233 477 2 0 0 0 - - -;
+#X floatatom 251 477 2 0 0 0 - - -;
+#X obj -10 457 unpack 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15;
+#X floatatom -10 518 2 0 0 0 - - -;
+#X floatatom 7 518 2 0 0 0 - - -;
+#X floatatom 24 518 2 0 0 0 - - -;
+#X floatatom 42 518 2 0 0 0 - - -;
+#X floatatom 59 518 2 0 0 0 - - -;
+#X floatatom 77 518 2 0 0 0 - - -;
+#X floatatom 94 518 2 0 0 0 - - -;
+#X floatatom 111 518 2 0 0 0 - - -;
+#X floatatom 129 518 2 0 0 0 - - -;
+#X floatatom 146 518 2 0 0 0 - - -;
+#X floatatom 164 518 2 0 0 0 - - -;
+#X floatatom 181 518 2 0 0 0 - - -;
+#X floatatom 198 518 2 0 0 0 - - -;
+#X floatatom 216 518 2 0 0 0 - - -;
+#X floatatom 233 518 2 0 0 0 - - -;
+#X floatatom 251 518 2 0 0 0 - - -;
+#X obj -10 498 unpack 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15;
+#X obj 415 384 s c1;
+#X obj 432 361 s c2;
+#X obj 449 384 s c3;
+#X obj 466 361 s c4;
+#X obj 483 384 s c5;
+#X obj 500 361 s c6;
+#X obj 517 384 s c7;
+#X obj 534 361 s c8;
+#X obj 551 384 s c9;
+#X obj 568 361 s c10;
+#X obj 585 384 s c11;
+#X obj 602 361 s c12;
+#X obj 619 384 s c13;
+#X obj 636 361 s c14;
+#X obj 653 384 s c15;
+#X obj -43 229 r c1;
+#X obj -44 272 r c2;
+#X obj -44 314 r c3;
+#X obj -44 356 r c4;
+#X obj -44 398 r c5;
+#X obj -44 440 r c6;
+#X obj -44 481 r c7;
+#X obj 448 270 metro 1000;
+#X obj 417 255 tgl 15 0 empty empty run -3 -8 0 10 -4160 -4034 -4034
+1 1;
+#X floatatom -11 560 2 0 0 0 - - -;
+#X floatatom 6 560 2 0 0 0 - - -;
+#X floatatom 23 560 2 0 0 0 - - -;
+#X floatatom 41 560 2 0 0 0 - - -;
+#X floatatom 58 560 2 0 0 0 - - -;
+#X floatatom 76 560 2 0 0 0 - - -;
+#X floatatom 93 560 2 0 0 0 - - -;
+#X floatatom 110 560 2 0 0 0 - - -;
+#X floatatom 128 560 2 0 0 0 - - -;
+#X floatatom 145 560 2 0 0 0 - - -;
+#X floatatom 163 560 2 0 0 0 - - -;
+#X floatatom 180 560 2 0 0 0 - - -;
+#X floatatom 197 560 2 0 0 0 - - -;
+#X floatatom 215 560 2 0 0 0 - - -;
+#X floatatom 232 560 2 0 0 0 - - -;
+#X floatatom 250 560 2 0 0 0 - - -;
+#X obj -11 540 unpack 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15;
+#X floatatom -11 602 2 0 0 0 - - -;
+#X floatatom 6 602 2 0 0 0 - - -;
+#X floatatom 23 602 2 0 0 0 - - -;
+#X floatatom 41 602 2 0 0 0 - - -;
+#X floatatom 58 602 2 0 0 0 - - -;
+#X floatatom 76 602 2 0 0 0 - - -;
+#X floatatom 93 602 2 0 0 0 - - -;
+#X floatatom 110 602 2 0 0 0 - - -;
+#X floatatom 128 602 2 0 0 0 - - -;
+#X floatatom 145 602 2 0 0 0 - - -;
+#X floatatom 163 602 2 0 0 0 - - -;
+#X floatatom 180 602 2 0 0 0 - - -;
+#X floatatom 197 602 2 0 0 0 - - -;
+#X floatatom 215 602 2 0 0 0 - - -;
+#X floatatom 232 602 2 0 0 0 - - -;
+#X floatatom 250 602 2 0 0 0 - - -;
+#X obj -11 582 unpack 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15;
+#X floatatom -12 645 2 0 0 0 - - -;
+#X floatatom 5 645 2 0 0 0 - - -;
+#X floatatom 22 645 2 0 0 0 - - -;
+#X floatatom 40 645 2 0 0 0 - - -;
+#X floatatom 57 645 2 0 0 0 - - -;
+#X floatatom 75 645 2 0 0 0 - - -;
+#X floatatom 92 645 2 0 0 0 - - -;
+#X floatatom 109 645 2 0 0 0 - - -;
+#X floatatom 127 645 2 0 0 0 - - -;
+#X floatatom 144 645 2 0 0 0 - - -;
+#X floatatom 162 645 2 0 0 0 - - -;
+#X floatatom 179 645 2 0 0 0 - - -;
+#X floatatom 196 645 2 0 0 0 - - -;
+#X floatatom 214 645 2 0 0 0 - - -;
+#X floatatom 231 645 2 0 0 0 - - -;
+#X floatatom 249 645 2 0 0 0 - - -;
+#X obj -12 625 unpack 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15;
+#X floatatom -12 687 2 0 0 0 - - -;
+#X floatatom 5 687 2 0 0 0 - - -;
+#X floatatom 22 687 2 0 0 0 - - -;
+#X floatatom 40 687 2 0 0 0 - - -;
+#X floatatom 57 687 2 0 0 0 - - -;
+#X floatatom 75 687 2 0 0 0 - - -;
+#X floatatom 92 687 2 0 0 0 - - -;
+#X floatatom 109 687 2 0 0 0 - - -;
+#X floatatom 127 687 2 0 0 0 - - -;
+#X floatatom 144 687 2 0 0 0 - - -;
+#X floatatom 162 687 2 0 0 0 - - -;
+#X floatatom 179 687 2 0 0 0 - - -;
+#X floatatom 196 687 2 0 0 0 - - -;
+#X floatatom 214 687 2 0 0 0 - - -;
+#X floatatom 231 687 2 0 0 0 - - -;
+#X floatatom 249 687 2 0 0 0 - - -;
+#X obj -12 667 unpack 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15;
+#X floatatom -12 729 2 0 0 0 - - -;
+#X floatatom 5 729 2 0 0 0 - - -;
+#X floatatom 22 729 2 0 0 0 - - -;
+#X floatatom 40 729 2 0 0 0 - - -;
+#X floatatom 57 729 2 0 0 0 - - -;
+#X floatatom 75 729 2 0 0 0 - - -;
+#X floatatom 92 729 2 0 0 0 - - -;
+#X floatatom 109 729 2 0 0 0 - - -;
+#X floatatom 127 729 2 0 0 0 - - -;
+#X floatatom 144 729 2 0 0 0 - - -;
+#X floatatom 162 729 2 0 0 0 - - -;
+#X floatatom 179 729 2 0 0 0 - - -;
+#X floatatom 196 729 2 0 0 0 - - -;
+#X floatatom 214 729 2 0 0 0 - - -;
+#X floatatom 231 729 2 0 0 0 - - -;
+#X floatatom 249 729 2 0 0 0 - - -;
+#X obj -12 709 unpack 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15;
+#X floatatom -12 771 2 0 0 0 - - -;
+#X floatatom 5 771 2 0 0 0 - - -;
+#X floatatom 22 771 2 0 0 0 - - -;
+#X floatatom 40 771 2 0 0 0 - - -;
+#X floatatom 57 771 2 0 0 0 - - -;
+#X floatatom 75 771 2 0 0 0 - - -;
+#X floatatom 92 771 2 0 0 0 - - -;
+#X floatatom 109 771 2 0 0 0 - - -;
+#X floatatom 127 771 2 0 0 0 - - -;
+#X floatatom 144 771 2 0 0 0 - - -;
+#X floatatom 162 771 2 0 0 0 - - -;
+#X floatatom 179 771 2 0 0 0 - - -;
+#X floatatom 196 771 2 0 0 0 - - -;
+#X floatatom 214 771 2 0 0 0 - - -;
+#X floatatom 231 771 2 0 0 0 - - -;
+#X floatatom 249 771 2 0 0 0 - - -;
+#X obj -12 751 unpack 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15;
+#X floatatom -12 813 2 0 0 0 - - -;
+#X floatatom 5 813 2 0 0 0 - - -;
+#X floatatom 22 813 2 0 0 0 - - -;
+#X floatatom 40 813 2 0 0 0 - - -;
+#X floatatom 57 813 2 0 0 0 - - -;
+#X floatatom 75 813 2 0 0 0 - - -;
+#X floatatom 92 813 2 0 0 0 - - -;
+#X floatatom 109 813 2 0 0 0 - - -;
+#X floatatom 127 813 2 0 0 0 - - -;
+#X floatatom 144 813 2 0 0 0 - - -;
+#X floatatom 162 813 2 0 0 0 - - -;
+#X floatatom 179 813 2 0 0 0 - - -;
+#X floatatom 196 813 2 0 0 0 - - -;
+#X floatatom 214 813 2 0 0 0 - - -;
+#X floatatom 231 813 2 0 0 0 - - -;
+#X floatatom 249 813 2 0 0 0 - - -;
+#X obj -12 793 unpack 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15;
+#X floatatom -12 854 2 0 0 0 - - -;
+#X floatatom 5 854 2 0 0 0 - - -;
+#X floatatom 22 854 2 0 0 0 - - -;
+#X floatatom 40 854 2 0 0 0 - - -;
+#X floatatom 57 854 2 0 0 0 - - -;
+#X floatatom 75 854 2 0 0 0 - - -;
+#X floatatom 92 854 2 0 0 0 - - -;
+#X floatatom 109 854 2 0 0 0 - - -;
+#X floatatom 127 854 2 0 0 0 - - -;
+#X floatatom 144 854 2 0 0 0 - - -;
+#X floatatom 162 854 2 0 0 0 - - -;
+#X floatatom 179 854 2 0 0 0 - - -;
+#X floatatom 196 854 2 0 0 0 - - -;
+#X floatatom 214 854 2 0 0 0 - - -;
+#X floatatom 231 854 2 0 0 0 - - -;
+#X floatatom 249 854 2 0 0 0 - - -;
+#X obj -12 834 unpack 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15;
+#X obj -45 523 r c8;
+#X obj -45 565 r c9;
+#X obj -46 608 r c10;
+#X obj -45 651 r c11;
+#X obj -45 692 r c12;
+#X obj -46 734 r c13;
+#X obj -46 776 r c14;
+#X obj -46 817 r c15;
+#X floatatom 268 114 5 0 0 0 - - -;
+#X msg 208 130 novar \$1;
+#X obj 704 407 nbx 5 14 -1e+37 1e+37 0 0 empty empty generation -65
+8 0 10 -4160 -4034 -4034 1885 256;
+#X obj 670 441 nbx 5 14 -1e+37 1e+37 0 0 empty empty delta -35 8 0
+10 -4160 -4034 -4034 0 256;
+#X obj 687 424 nbx 5 14 -1e+37 1e+37 0 0 empty empty alive -35 8 0
+10 -4160 -4034 -4034 15 256;
+#X obj 755 389 bng 15 250 50 0 empty empty dead 17 7 0 10 -258113 -262144
+-4034;
+#X obj 738 440 bng 15 250 50 0 empty empty no_variation 17 7 0 10 -258113
+-262144 -4034;
+#X obj 721 360 print dump_id_x_y;
+#X obj 448 197 pack 0 0;
+#X obj 466 162 t b f;
+#X obj 448 126 nbx 3 14 -99 99 0 0 empty empty x_shift -40 8 0 10 -4160
+-4034 -4034 0 256;
+#X obj 466 144 nbx 3 14 -99 99 0 0 empty empty y_shift -40 8 0 10 -4160
+-4034 -4034 0 256;
+#X msg 234 3 23/3;
+#X msg 349 271 rule \$1;
+#X obj 349 135 symbol;
+#X msg 270 39 012345678/;
+#X text 272 1 Rule for Conway life (default): A live cell survives
+if it has 2 or 3 neighbours. A dead cell becomes alive if it has 2
+neighbours.;
+#X text 343 38 Rule to freeze the current state;
+#X msg 291 60 23/36;
+#X text 328 60 "High Life" rule;
+#X msg 312 81 5678/35678;
+#X text 384 81 "Diamoeba" rule;
+#X text 433 320 creation arguments: number of columns \, number of
+rows;
+#X obj 582 256 nbx 5 14 1 1e+37 0 1 empty empty period_(ms) -70 8 0
+10 -4160 -4034 -4034 125 256;
+#X msg 335 104 /123;
+#X msg 292 214 shift \$1 \$2;
+#X obj 382 220 tgl 15 0 empty empty empty 17 7 0 10 -4160 -4034 -4034
+0 1;
+#X msg 313 235 thru \$1;
+#X text 401 219 If thru is on \, output state changes other than generations
+;
+#X msg 533 185 set \$1 \$2 \$3;
+#X obj 533 158 pack 0 0 0;
+#X floatatom 537 107 3 0 0 0 - - -;
+#X floatatom 561 107 3 0 0 0 - - -;
+#X floatatom 590 107 3 0 0 0 - - -;
+#X obj 533 134 f;
+#X obj 533 68 bng 15 250 50 0 empty empty set_cell 17 7 0 10 -4160
+-4034 -4034;
+#X text 587 89 state;
+#X text 535 89 col;
+#X text 558 89 row;
+#X msg 230 151 randomize \$1;
+#X msg 313 134 0.5;
+#X text -28 25 clear the array to 0:;
+#X text -38 151 randomly set a fraction of the array alive:;
+#X text -67 47 output locations of live cells:;
+#X text -2 69 flip array horizontal:;
+#X text 33 89 flip array vertical:;
+#X text 25 109 invert values for display:;
+#X text -40 130 generations of no variation before bang:;
+#X connect 0 0 25 0;
+#X connect 1 0 25 0;
+#X connect 2 0 25 0;
+#X connect 3 0 25 0;
+#X connect 4 0 25 0;
+#X connect 5 0 25 0;
+#X connect 6 0 25 0;
+#X connect 7 0 25 0;
+#X connect 8 0 7 0;
+#X connect 25 0 28 0;
+#X connect 25 1 148 0;
+#X connect 25 2 149 0;
+#X connect 25 3 150 0;
+#X connect 25 4 151 0;
+#X connect 25 5 152 0;
+#X connect 25 6 153 0;
+#X connect 25 7 154 0;
+#X connect 25 8 155 0;
+#X connect 25 9 156 0;
+#X connect 25 10 157 0;
+#X connect 25 11 158 0;
+#X connect 25 12 159 0;
+#X connect 25 13 160 0;
+#X connect 25 14 161 0;
+#X connect 25 15 162 0;
+#X connect 25 16 319 0;
+#X connect 25 17 320 0;
+#X connect 25 18 318 0;
+#X connect 25 19 323 0;
+#X connect 25 20 322 0;
+#X connect 25 20 356 0;
+#X connect 25 21 321 0;
+#X connect 26 0 9 0;
+#X connect 26 1 10 0;
+#X connect 26 2 11 0;
+#X connect 26 3 12 0;
+#X connect 26 4 13 0;
+#X connect 26 5 14 0;
+#X connect 26 6 15 0;
+#X connect 26 7 16 0;
+#X connect 26 8 17 0;
+#X connect 26 9 18 0;
+#X connect 26 10 19 0;
+#X connect 26 11 20 0;
+#X connect 26 12 21 0;
+#X connect 26 13 22 0;
+#X connect 26 14 23 0;
+#X connect 26 15 24 0;
+#X connect 27 0 26 0;
+#X connect 45 0 29 0;
+#X connect 45 1 30 0;
+#X connect 45 2 31 0;
+#X connect 45 3 32 0;
+#X connect 45 4 33 0;
+#X connect 45 5 34 0;
+#X connect 45 6 35 0;
+#X connect 45 7 36 0;
+#X connect 45 8 37 0;
+#X connect 45 9 38 0;
+#X connect 45 10 39 0;
+#X connect 45 11 40 0;
+#X connect 45 12 41 0;
+#X connect 45 13 42 0;
+#X connect 45 14 43 0;
+#X connect 45 15 44 0;
+#X connect 62 0 46 0;
+#X connect 62 1 47 0;
+#X connect 62 2 48 0;
+#X connect 62 3 49 0;
+#X connect 62 4 50 0;
+#X connect 62 5 51 0;
+#X connect 62 6 52 0;
+#X connect 62 7 53 0;
+#X connect 62 8 54 0;
+#X connect 62 9 55 0;
+#X connect 62 10 56 0;
+#X connect 62 11 57 0;
+#X connect 62 12 58 0;
+#X connect 62 13 59 0;
+#X connect 62 14 60 0;
+#X connect 62 15 61 0;
+#X connect 79 0 63 0;
+#X connect 79 1 64 0;
+#X connect 79 2 65 0;
+#X connect 79 3 66 0;
+#X connect 79 4 67 0;
+#X connect 79 5 68 0;
+#X connect 79 6 69 0;
+#X connect 79 7 70 0;
+#X connect 79 8 71 0;
+#X connect 79 9 72 0;
+#X connect 79 10 73 0;
+#X connect 79 11 74 0;
+#X connect 79 12 75 0;
+#X connect 79 13 76 0;
+#X connect 79 14 77 0;
+#X connect 79 15 78 0;
+#X connect 96 0 80 0;
+#X connect 96 1 81 0;
+#X connect 96 2 82 0;
+#X connect 96 3 83 0;
+#X connect 96 4 84 0;
+#X connect 96 5 85 0;
+#X connect 96 6 86 0;
+#X connect 96 7 87 0;
+#X connect 96 8 88 0;
+#X connect 96 9 89 0;
+#X connect 96 10 90 0;
+#X connect 96 11 91 0;
+#X connect 96 12 92 0;
+#X connect 96 13 93 0;
+#X connect 96 14 94 0;
+#X connect 96 15 95 0;
+#X connect 113 0 97 0;
+#X connect 113 1 98 0;
+#X connect 113 2 99 0;
+#X connect 113 3 100 0;
+#X connect 113 4 101 0;
+#X connect 113 5 102 0;
+#X connect 113 6 103 0;
+#X connect 113 7 104 0;
+#X connect 113 8 105 0;
+#X connect 113 9 106 0;
+#X connect 113 10 107 0;
+#X connect 113 11 108 0;
+#X connect 113 12 109 0;
+#X connect 113 13 110 0;
+#X connect 113 14 111 0;
+#X connect 113 15 112 0;
+#X connect 130 0 114 0;
+#X connect 130 1 115 0;
+#X connect 130 2 116 0;
+#X connect 130 3 117 0;
+#X connect 130 4 118 0;
+#X connect 130 5 119 0;
+#X connect 130 6 120 0;
+#X connect 130 7 121 0;
+#X connect 130 8 122 0;
+#X connect 130 9 123 0;
+#X connect 130 10 124 0;
+#X connect 130 11 125 0;
+#X connect 130 12 126 0;
+#X connect 130 13 127 0;
+#X connect 130 14 128 0;
+#X connect 130 15 129 0;
+#X connect 147 0 131 0;
+#X connect 147 1 132 0;
+#X connect 147 2 133 0;
+#X connect 147 3 134 0;
+#X connect 147 4 135 0;
+#X connect 147 5 136 0;
+#X connect 147 6 137 0;
+#X connect 147 7 138 0;
+#X connect 147 8 139 0;
+#X connect 147 9 140 0;
+#X connect 147 10 141 0;
+#X connect 147 11 142 0;
+#X connect 147 12 143 0;
+#X connect 147 13 144 0;
+#X connect 147 14 145 0;
+#X connect 147 15 146 0;
+#X connect 163 0 45 0;
+#X connect 164 0 62 0;
+#X connect 165 0 79 0;
+#X connect 166 0 96 0;
+#X connect 167 0 113 0;
+#X connect 168 0 130 0;
+#X connect 169 0 147 0;
+#X connect 170 0 25 0;
+#X connect 171 0 170 0;
+#X connect 188 0 172 0;
+#X connect 188 1 173 0;
+#X connect 188 2 174 0;
+#X connect 188 3 175 0;
+#X connect 188 4 176 0;
+#X connect 188 5 177 0;
+#X connect 188 6 178 0;
+#X connect 188 7 179 0;
+#X connect 188 8 180 0;
+#X connect 188 9 181 0;
+#X connect 188 10 182 0;
+#X connect 188 11 183 0;
+#X connect 188 12 184 0;
+#X connect 188 13 185 0;
+#X connect 188 14 186 0;
+#X connect 188 15 187 0;
+#X connect 205 0 189 0;
+#X connect 205 1 190 0;
+#X connect 205 2 191 0;
+#X connect 205 3 192 0;
+#X connect 205 4 193 0;
+#X connect 205 5 194 0;
+#X connect 205 6 195 0;
+#X connect 205 7 196 0;
+#X connect 205 8 197 0;
+#X connect 205 9 198 0;
+#X connect 205 10 199 0;
+#X connect 205 11 200 0;
+#X connect 205 12 201 0;
+#X connect 205 13 202 0;
+#X connect 205 14 203 0;
+#X connect 205 15 204 0;
+#X connect 222 0 206 0;
+#X connect 222 1 207 0;
+#X connect 222 2 208 0;
+#X connect 222 3 209 0;
+#X connect 222 4 210 0;
+#X connect 222 5 211 0;
+#X connect 222 6 212 0;
+#X connect 222 7 213 0;
+#X connect 222 8 214 0;
+#X connect 222 9 215 0;
+#X connect 222 10 216 0;
+#X connect 222 11 217 0;
+#X connect 222 12 218 0;
+#X connect 222 13 219 0;
+#X connect 222 14 220 0;
+#X connect 222 15 221 0;
+#X connect 239 0 223 0;
+#X connect 239 1 224 0;
+#X connect 239 2 225 0;
+#X connect 239 3 226 0;
+#X connect 239 4 227 0;
+#X connect 239 5 228 0;
+#X connect 239 6 229 0;
+#X connect 239 7 230 0;
+#X connect 239 8 231 0;
+#X connect 239 9 232 0;
+#X connect 239 10 233 0;
+#X connect 239 11 234 0;
+#X connect 239 12 235 0;
+#X connect 239 13 236 0;
+#X connect 239 14 237 0;
+#X connect 239 15 238 0;
+#X connect 256 0 240 0;
+#X connect 256 1 241 0;
+#X connect 256 2 242 0;
+#X connect 256 3 243 0;
+#X connect 256 4 244 0;
+#X connect 256 5 245 0;
+#X connect 256 6 246 0;
+#X connect 256 7 247 0;
+#X connect 256 8 248 0;
+#X connect 256 9 249 0;
+#X connect 256 10 250 0;
+#X connect 256 11 251 0;
+#X connect 256 12 252 0;
+#X connect 256 13 253 0;
+#X connect 256 14 254 0;
+#X connect 256 15 255 0;
+#X connect 273 0 257 0;
+#X connect 273 1 258 0;
+#X connect 273 2 259 0;
+#X connect 273 3 260 0;
+#X connect 273 4 261 0;
+#X connect 273 5 262 0;
+#X connect 273 6 263 0;
+#X connect 273 7 264 0;
+#X connect 273 8 265 0;
+#X connect 273 9 266 0;
+#X connect 273 10 267 0;
+#X connect 273 11 268 0;
+#X connect 273 12 269 0;
+#X connect 273 13 270 0;
+#X connect 273 14 271 0;
+#X connect 273 15 272 0;
+#X connect 290 0 274 0;
+#X connect 290 1 275 0;
+#X connect 290 2 276 0;
+#X connect 290 3 277 0;
+#X connect 290 4 278 0;
+#X connect 290 5 279 0;
+#X connect 290 6 280 0;
+#X connect 290 7 281 0;
+#X connect 290 8 282 0;
+#X connect 290 9 283 0;
+#X connect 290 10 284 0;
+#X connect 290 11 285 0;
+#X connect 290 12 286 0;
+#X connect 290 13 287 0;
+#X connect 290 14 288 0;
+#X connect 290 15 289 0;
+#X connect 307 0 291 0;
+#X connect 307 1 292 0;
+#X connect 307 2 293 0;
+#X connect 307 3 294 0;
+#X connect 307 4 295 0;
+#X connect 307 5 296 0;
+#X connect 307 6 297 0;
+#X connect 307 7 298 0;
+#X connect 307 8 299 0;
+#X connect 307 9 300 0;
+#X connect 307 10 301 0;
+#X connect 307 11 302 0;
+#X connect 307 12 303 0;
+#X connect 307 13 304 0;
+#X connect 307 14 305 0;
+#X connect 307 15 306 0;
+#X connect 308 0 188 0;
+#X connect 309 0 205 0;
+#X connect 310 0 222 0;
+#X connect 311 0 239 0;
+#X connect 312 0 256 0;
+#X connect 313 0 273 0;
+#X connect 314 0 290 0;
+#X connect 315 0 307 0;
+#X connect 316 0 317 0;
+#X connect 317 0 25 0;
+#X connect 324 0 341 0;
+#X connect 325 0 324 0;
+#X connect 325 1 324 1;
+#X connect 326 0 324 0;
+#X connect 327 0 325 0;
+#X connect 328 0 330 0;
+#X connect 329 0 25 0;
+#X connect 330 0 329 0;
+#X connect 331 0 330 0;
+#X connect 334 0 330 0;
+#X connect 336 0 330 0;
+#X connect 339 0 170 1;
+#X connect 340 0 330 0;
+#X connect 341 0 25 0;
+#X connect 342 0 343 0;
+#X connect 343 0 25 0;
+#X connect 345 0 25 0;
+#X connect 346 0 345 0;
+#X connect 347 0 350 1;
+#X connect 348 0 346 1;
+#X connect 349 0 346 2;
+#X connect 350 0 346 0;
+#X connect 351 0 350 0;
+#X connect 355 0 25 0;
+#X connect 356 0 355 0;
diff --git a/life2x/life2x.c b/life2x/life2x.c
new file mode 100644
index 0000000..fda90b8
--- /dev/null
+++ b/life2x/life2x.c
@@ -0,0 +1,675 @@
+/* Life2x.c -- The Game of Life (2D Cellular Automaton) ------- */
+/* © Bill Vorn 2002 */
+/* modified by Martin Peach September 2002 */
+/* implemented grey scale display*/
+/* change gen_ arrays to pointers for better memory peformance */
+/* <<better memory!>> */
+/* MP20060517 Windows version */
+/* MP 20080819 pd version with no graphics */
+
+#include "m_pd.h"
+#include <stdio.h> /* for sprintf() */
+#include <stdlib.h> /* for random() */
+#include <time.h> /* for clock() */
+
+#define MAXSIZE 1024
+#define DEFAULT_DIM 16
+
+static t_class *life2x_class;
+
+typedef struct life2x
+{
+ t_object x_obj;
+ char *gen_origin_ptr; /* [MAXSIZE]X[MAXSIZE]; */
+ char *gen_finale_ptr; /* [MAXSIZE][MAXSIZE]; */
+ char *gen_start_ptr; /* [MAXSIZE][MAXSIZE]; */
+ char *gen_shift_ptr; /* [MAXSIZE][MAXSIZE]; */
+ t_atom *l_column_list; /* values for one column */
+ long l_cellmax; /* number of bytes in gen */
+ long l_xcellnum;
+ long l_ycellnum;
+ long l_gennum;
+ long l_livenum;
+ long l_deltanum;
+ long l_lastdeltanum;
+ long l_novarinum;
+ long l_novar;
+ short l_deadflag;
+ short l_thruflag;
+ short l_xshift;
+ short l_yshift;
+ short l_invertflag;
+ t_outlet *l_genout;
+ t_outlet *l_liveout;
+ t_outlet *l_deltaout;
+ t_outlet **l_cellouts;
+ t_outlet *l_novariout;
+ t_outlet *l_deadout;
+ t_outlet *l_dumpout;
+ char l_survive[9]; /* rule for survival according to neighbour count */
+ char l_born[9]; /* rule for birth according to neighbour count */
+} t_life2x;
+
+static void life2x_bang(t_life2x *x);
+static void life2x_output_cells(t_life2x *x);
+static void life2x_set(t_life2x *x, t_floatarg xx, t_floatarg yy, t_floatarg state);
+static void life2x_clear(t_life2x *x);
+static void life2x_reset(t_life2x *x);
+static void life2x_return(t_life2x *x);
+static void life2x_dump(t_life2x *x);
+static void life2x_rule(t_life2x *x, t_symbol *s);
+static void life2x_randomize(t_life2x *x, t_floatarg f);
+static void life2x_thru(t_life2x *x, t_floatarg f);
+static void life2x_shift(t_life2x *x, t_floatarg f1, t_floatarg f2);
+static void life2x_flipv(t_life2x *x);
+static void life2x_fliph(t_life2x *x);
+static void life2x_invert(t_life2x *x, t_floatarg f);
+static void life2x_novar(t_life2x *x, t_floatarg f);
+static void life2x_free(t_life2x *x);
+static void *life2x_new(t_symbol *s, short ac, t_atom *av);
+
+void life2x_setup(void)
+{
+ life2x_class = class_new(gensym("life2x"),
+ (t_newmethod)life2x_new,
+ (t_method)life2x_free,
+ sizeof(t_life2x),
+ CLASS_DEFAULT,
+ A_GIMME,
+ 0);
+ class_addbang(life2x_class, life2x_bang);
+ class_addmethod(life2x_class, (t_method)life2x_clear, gensym("clear"), 0);
+ class_addmethod(life2x_class, (t_method)life2x_reset, gensym("reset"), 0);
+ class_addmethod(life2x_class, (t_method)life2x_return, gensym("return"), 0);
+ class_addmethod(life2x_class, (t_method)life2x_dump, gensym("dump"), 0);
+ class_addmethod(life2x_class, (t_method)life2x_rule, gensym("rule") ,A_DEFSYMBOL, 0);
+ class_addmethod(life2x_class, (t_method)life2x_randomize, gensym("randomize"), A_DEFFLOAT, 0);
+ class_addmethod(life2x_class, (t_method)life2x_thru, gensym("thru") ,A_DEFFLOAT, 0);
+ class_addmethod(life2x_class, (t_method)life2x_shift, gensym("shift"), A_DEFFLOAT, A_DEFFLOAT, 0);
+ class_addmethod(life2x_class, (t_method)life2x_set, gensym("set"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0);
+ class_addmethod(life2x_class, (t_method)life2x_flipv, gensym("flipv"), 0);
+ class_addmethod(life2x_class, (t_method)life2x_fliph, gensym("fliph"), 0);
+ class_addmethod(life2x_class, (t_method)life2x_invert, gensym("invert"), A_DEFFLOAT, 0);
+ class_addmethod(life2x_class, (t_method)life2x_novar, gensym("novar"), A_DEFFLOAT, 0);
+ return;
+}
+
+static void life2x_bang(t_life2x *x)
+{
+ short i, j, m, n, p, q;
+ short i_pre, i_post, j_pre, j_post;
+ short xmax, ymax;
+ unsigned long cellmax;
+ short xshft, yshft;
+ char c;
+ short cellval;
+ long gendiff, lastgendiff;
+ char *g_start, *g_origin, *g_final, *g_shift;
+ int c_live;
+
+ xmax = x->l_xcellnum - 1;
+ ymax = x->l_ycellnum - 1;
+ cellmax = x->l_xcellnum * x->l_ycellnum;
+ xshft = x->l_xshift;
+ yshft = x->l_yshift;
+
+ if (x->l_gennum == 0)
+ {
+ g_start = x->gen_start_ptr;
+ g_origin = x->gen_origin_ptr;
+ for (j = 0; j < cellmax; ++j) *g_start++ = *g_origin++;
+ }
+
+ for (j = 0; j <= ymax; j++)
+ {
+ j_pre = j-1;
+ if (j_pre < 0) j_pre = ymax;
+ j_post = j+1;
+ if (j_post > ymax) j_post = 0;
+ for (i = 0; i <= xmax; i++)
+ {
+ i_pre = i-1;
+ if (i_pre < 0) i_pre = xmax;
+ i_post = i+1;
+ if (i_post > xmax) i_post = 0;
+ /* check each neighbour */
+ cellval = (*(x->gen_origin_ptr+(j_pre*x->l_xcellnum)+(i_pre)) != 0)
+ +(*(x->gen_origin_ptr+(j_pre*x->l_xcellnum)+i) != 0)
+ +(*(x->gen_origin_ptr+(j_pre*x->l_xcellnum)+i_post) != 0)
+ +(*(x->gen_origin_ptr+(j*x->l_xcellnum)+i_pre) != 0)
+ +(*(x->gen_origin_ptr+(j*x->l_xcellnum)+i_post) != 0)
+ +(*(x->gen_origin_ptr+(j_post*x->l_xcellnum)+i_pre) != 0)
+ +(*(x->gen_origin_ptr+(j_post*x->l_xcellnum)+i) != 0)
+ +(*(x->gen_origin_ptr+(j_post*x->l_xcellnum)+i_post) != 0);
+
+ c = *(x->gen_origin_ptr+(j*x->l_xcellnum)+i); /* current value of cell */
+ g_final = (x->gen_finale_ptr+(j*x->l_xcellnum)+i);
+
+ /* apply the rule */
+ if (c == 0) c_live = x->l_born[cellval]; /* cell is born if it has the right number of neighbours */
+ else c_live = x->l_survive[cellval]; /* cell survives if it has the right number of neighbours */
+
+ if (c_live == 1)
+ {
+ if (c < 8) *g_final = c + 1;
+ else *g_final = 8;
+ }
+ else *g_final = 0;
+ }
+ }
+
+ if ((xshft != 0) || (yshft != 0))
+ { /* if there is a shift offset */
+ for (j = 0; j <= ymax; j++)
+ {
+ n = j + yshft;
+ if (n < 0) q = (n + ymax) + 1;
+ else if (n > ymax) q = (n - ymax) - 1;
+ else q = n;
+ for (i = 0; i <= xmax; i++)
+ {
+ m = i + xshft;
+ if (m < 0) p = (m + xmax) + 1;
+ else if (m > xmax) p = (m - xmax) - 1;
+ else p = m;
+ *(x->gen_shift_ptr+(q * x->l_xcellnum)+p) = *(x->gen_finale_ptr+(j * x->l_xcellnum)+i);
+ }
+ }
+ g_final = x->gen_finale_ptr;
+ g_shift = x->gen_shift_ptr;
+
+ for (j = 0; j <= cellmax; j++) *g_final++ = *g_shift++;
+ }
+
+ x->l_gennum = x->l_gennum + 1; /* increment generation # */
+ outlet_float(x->l_genout, x->l_gennum); /* output generation # */
+
+ life2x_output_cells(x);
+
+ gendiff = x->l_livenum - x->l_deltanum; /* compare # of live cells from last gen to current gen */
+ outlet_float(x->l_deltaout, gendiff); /* output delta # of live cells from last gen to current gen */
+ x->l_deltanum = x->l_livenum; /* store # of live cells from current gen */
+
+ outlet_float(x->l_liveout, x->l_livenum); /* output # of live cells in current generation */
+
+ lastgendiff = x->l_lastdeltanum;
+ if (gendiff == lastgendiff) x->l_novar--;
+ else x->l_novar = x->l_novarinum; /* reset countdown */
+ if (x->l_novar == 0)
+ {
+ outlet_bang(x->l_novariout);
+ x->l_novar = x->l_novarinum;
+ }
+ x->l_lastdeltanum = gendiff;
+
+ x->l_deadflag = 0;
+ for (j = 0; j < x->l_ycellnum; j++)
+ {
+ for (i = 0; i < x->l_xcellnum; i++)
+ {
+ g_final = (x->gen_finale_ptr+(j*x->l_xcellnum)+i);
+ g_origin = (x->gen_origin_ptr+(j*x->l_xcellnum)+i);
+ /* check for gen difference: */
+ if (*g_final != *g_origin) x->l_deadflag = 1;
+ *g_origin = *g_final; /* this generation becomes last generation */
+ }
+ }
+ /* check for dead world: */
+ if (x->l_deadflag == 0) outlet_bang(x->l_deadout);
+
+ return;
+}
+
+static void life2x_output_cells(t_life2x *x)
+{
+ char *g_final;
+ short i, j;
+ long d = 0;
+
+ for (i = 0; i < x->l_xcellnum; i++)
+ { /* output all cells state for each column */
+ for (j = 0; j < x->l_ycellnum; j++)
+ {
+ g_final = (x->gen_finale_ptr+(j*x->l_xcellnum)+i);
+ if (x->l_invertflag != 0) x->l_column_list[j].a_w.w_float = (10 - *g_final)%9;
+ else x->l_column_list[j].a_w.w_float = *g_final;
+ if (*g_final != 0) d++;
+ }
+ outlet_list(x->l_cellouts[x->l_xcellnum-1-i], &s_list, j, x->l_column_list);
+ }
+ x->l_livenum = d;
+
+ return;
+}
+
+static void life2x_set(t_life2x *x, t_floatarg xx, t_floatarg yy, t_floatarg state)
+{ /* a list of three floats to set the state of cell (xx,yy) */
+ short i, j, k;
+
+ if (xx < 0) i = 0;
+ if (xx >= x->l_xcellnum) i = x->l_xcellnum - 1;
+ else i = (short)xx;
+ if (yy < 0) j = 0;
+ if (yy > x->l_ycellnum) j = x->l_ycellnum - 1;
+ else j = (short)yy;
+
+ if (state < 0) k = 0;
+ if (state > 8) k = 8;
+ else k = (short)state;
+
+ *(x->gen_origin_ptr+(j*x->l_xcellnum+i)) = k;
+ *(x->gen_finale_ptr+(j*x->l_xcellnum+i)) = k;
+
+ if (x->l_thruflag != 0) life2x_output_cells(x);
+ return;
+}
+
+static void life2x_clear(t_life2x *x)
+{
+ short j;
+ char *g_origin, * g_final;
+
+ g_origin = x->gen_origin_ptr;
+ g_final = x->gen_finale_ptr;
+
+ for (j = 0; j < x->l_cellmax; ++j) *g_origin++ = *g_final++ = 0;
+
+ if (x->l_thruflag != 0) life2x_output_cells(x);
+
+ return;
+}
+
+static void life2x_reset(t_life2x *x)
+{
+ short j;
+ char *g_origin, * g_final;
+
+ g_origin = x->gen_origin_ptr;
+ g_final = x->gen_finale_ptr;
+ x->l_gennum = 0;
+
+ outlet_float (x->l_genout, x->l_gennum); /* output generation 0 */
+
+ for (j = 0; j < x->l_cellmax; ++j) *g_origin++ = *g_final++ = 0;
+
+ x->l_xshift = 0;
+ x->l_yshift = 0;
+ x->l_deltanum = 0;
+ x->l_novar = x->l_novarinum;
+
+ if (x->l_thruflag != 0) life2x_output_cells(x);
+
+ return;
+}
+
+static void life2x_return(t_life2x *x)
+{
+ short i, j;
+ char *g_origin, *g_start, *g_final;
+
+ x->l_gennum = 0;
+ outlet_float (x->l_genout, x->l_gennum); /* output generation 0 */
+
+ for (j = 0; j < x->l_ycellnum; j++)
+ {
+ for (i = 0; i < x->l_xcellnum; i++)
+ {
+ g_origin = (x->gen_origin_ptr+(j*x->l_xcellnum)+i);
+ g_start = (x->gen_start_ptr+(j*x->l_xcellnum)+i);
+ g_final = (x->gen_finale_ptr+(j*x->l_xcellnum)+i);
+
+ *g_origin = *g_start;
+ *g_final = *g_start;
+ }
+ }
+ if (x->l_thruflag != 0) life2x_output_cells(x);
+ return;
+}
+
+static void life2x_dump(t_life2x *x)
+{
+ short i, j, k;
+ unsigned long count = 0;
+ unsigned long outVal[3];
+ t_atom outList[3];
+ char *g_final = x->gen_finale_ptr;
+
+ for (j = 0; j < x->l_ycellnum; ++j)
+ {
+ for (i = 0; i < x->l_xcellnum; ++i)
+ {
+ if (*g_final++)
+ {
+ outVal[0] = count;
+ outVal[1] = i;
+ outVal[2] = j;
+ for (k = 0; k < 3; k++) SETFLOAT(&outList[k], outVal[k]);
+ outlet_list (x->l_dumpout, &s_list, 3, outList);
+ count++;
+ }
+ }
+ }
+ return;
+}
+
+static void life2x_rule(t_life2x *x, t_symbol *s)
+{
+ short i;
+ char survive[9];
+/* one entry for each possible neighbour count, set to one if cell survives with that many neighbours */
+ char born[9];
+/* one entry for each possible neighbour count, set to one if cell is born with that many neighbours */
+
+ for (i = 0; i < 9; ++i) survive[i] = born[i] = 0;
+
+ for (i = 0; s->s_name[i] != 0; ++i)
+ {
+ if (s->s_name[i] == '/') break;
+ if ((s->s_name[i] < 0x30)||(s->s_name[i] > 0x38))
+ {
+ error("life2x_rule: bad character in rule: %c", s->s_name[i]);
+ return;
+ }
+ survive[s->s_name[i]-0x30] = 1;
+ }
+ if (s->s_name[i] != '/')
+ {
+ error("life2x_rule: missing / separator");
+ return;
+ }
+ for (++i; s->s_name[i] != 0; ++i)
+ {
+ if ((s->s_name[i] < 0x30)||(s->s_name[i] > 0x38))
+ {
+ error("life2x_rule: bad character in rule: %c", s->s_name[i]);
+ return;
+ }
+ born[s->s_name[i]-0x30] = 1;
+ }
+ for (i = 0; i < 9; ++i)
+ { /* update the rule */
+ x->l_survive[i] = survive[i];
+ x->l_born[i] = born[i];
+ }
+ return;
+}
+
+static void life2x_randomize(t_life2x *x, t_floatarg f)
+{ /* set a random fraction of the array alive */
+ short i, j;
+ float threshold;
+
+ if (f > 1.0) f = 1.0;
+ else if (f < 0.0) f = 0.0;
+ threshold = RAND_MAX*f; /* RAND_MAX is 0x7FFFFFFF on linux */
+
+ for (j = 0; j < x->l_ycellnum; j++)
+ {
+ for (i = 0; i < x->l_xcellnum; i++)
+ {
+ if ((random() < threshold))
+ {
+ *(x->gen_origin_ptr+(j*x->l_xcellnum)+i) = 1;
+ *(x->gen_finale_ptr+(j*x->l_xcellnum)+i) = 1;
+ }
+ }
+ }
+ if (x->l_thruflag != 0) life2x_output_cells(x);
+ return;
+}
+
+static void life2x_thru(t_life2x *x, t_floatarg f)
+{
+ long n = (long)f;
+
+ x->l_thruflag = (n == 0)? 0: 1;
+ return;
+}
+
+static void life2x_shift(t_life2x *x, t_floatarg f1, t_floatarg f2)
+{
+ long n = (long)f1;
+
+ n %= x->l_xcellnum;
+ x->l_xshift = n;
+ n = (long)f2;
+ n %= x->l_ycellnum;
+ x->l_yshift = n;
+ return;
+}
+
+static void life2x_flipv(t_life2x *x)
+{
+ short a, i, j;
+
+ for (i = 0; i < x->l_xcellnum; ++i)
+ {
+ a = x->l_xcellnum - 1;
+ for (j = 0; j < x->l_xcellnum; ++j)
+ {
+ *(x->gen_shift_ptr+(a*x->l_xcellnum)+i) = *(x->gen_finale_ptr+(j*x->l_xcellnum)+i);
+ a--;
+ }
+ }
+ for (j = 0; j < x->l_ycellnum; ++j)
+ {
+ for (i = 0; i < x->l_xcellnum; ++i)
+ {
+ *(x->gen_finale_ptr+(j*x->l_xcellnum)+i) = *(x->gen_shift_ptr+(j*x->l_xcellnum)+i);
+ *(x->gen_origin_ptr+(j*x->l_xcellnum)+i) = *(x->gen_shift_ptr+(j*x->l_xcellnum)+i);
+ }
+ }
+
+ if (x->l_thruflag != 0) life2x_output_cells(x);
+
+ return;
+}
+
+static void life2x_fliph(t_life2x *x)
+{
+ short a, i, j;
+
+ for (j = 0; j < x->l_ycellnum - 1; ++j)
+ {
+ a = x->l_xcellnum - 1;
+ for (i = 0; i < x->l_xcellnum; ++i)
+ {
+ *(x->gen_shift_ptr+(j*x->l_xcellnum)+a) = *(x->gen_finale_ptr+(j*x->l_xcellnum)+i);
+ a--;
+ }
+ }
+ for (j = 0; j < x->l_ycellnum - 1; ++j)
+ {
+ for (i = 0; i < x->l_xcellnum - 1; ++i)
+ {
+ *(x->gen_finale_ptr+(j*x->l_xcellnum)+i) = *(x->gen_shift_ptr+(j*x->l_xcellnum)+i);
+ *(x->gen_origin_ptr+(j*x->l_xcellnum)+i) = *(x->gen_shift_ptr+(j*x->l_xcellnum)+i);
+ }
+ }
+
+ if (x->l_thruflag != 0) life2x_output_cells(x);
+
+ return;
+}
+
+static void life2x_invert(t_life2x *x, t_floatarg f)
+{
+ x->l_invertflag = (f == 0)? 0: 1;
+
+ if (x->l_thruflag != 0) life2x_output_cells(x);
+
+ return;
+}
+
+static void life2x_novar(t_life2x *x, t_floatarg f)
+{
+ long n = (long)f;
+
+ if (n < 0)
+ {
+ error("life2x: novar argument must be positive");
+ return;
+ }
+ else
+ {
+ x->l_novarinum = n;
+ x->l_novar = n;
+ }
+ return;
+}
+
+
+static void life2x_free(t_life2x *x)
+{
+ if (x->gen_origin_ptr != NULL) freebytes (x->gen_origin_ptr, x->l_cellmax);
+ if (x->gen_finale_ptr != NULL) freebytes (x->gen_finale_ptr, x->l_cellmax);
+ if (x->gen_start_ptr != NULL) freebytes (x->gen_start_ptr, x->l_cellmax);
+ if (x->gen_shift_ptr != NULL) freebytes (x->gen_shift_ptr, x->l_cellmax);
+ if (x->l_column_list != NULL) freebytes(x->l_column_list, x->l_ycellnum*sizeof (t_atom));
+ if (x->l_cellouts != NULL) freebytes(x->l_cellouts, x->l_xcellnum*sizeof (t_outlet*));
+ return;
+}
+
+
+static void *life2x_new(t_symbol *s, short ac, t_atom *av)
+{
+ t_life2x *x;
+ short i;
+ short j;
+ short xmax, ymax;
+
+ x = (t_life2x *)pd_new(life2x_class);
+
+ if (ac > 0)
+ { /* if there is at least 1 argument */
+ if (av[0].a_type == A_FLOAT)
+ { /* if first arg is an int */
+ x->l_xcellnum = av[0].a_w.w_float; /* arg sets # of horiz cells */
+ if (x->l_xcellnum < 4)
+ {
+ error("Life: first argument < 4, set to 4");
+ x->l_xcellnum = 4; /* min # of horiz cells */
+ }
+ if (x->l_xcellnum > MAXSIZE)
+ {
+ error("Life: first argument > %d, set to %d", MAXSIZE, MAXSIZE);
+ x->l_xcellnum = MAXSIZE; /* max # of horiz cells */
+ }
+ /* if 2 arguments */
+ if ((ac > 1) && (av[1].a_type == A_FLOAT))
+ { /* if 2nd arg is an int */
+ x->l_ycellnum = av[1].a_w.w_float; /* 2nd arg sets # of verti cells */
+ if (x->l_ycellnum < 4)
+ {
+ error("Life: 2nd argument < 4, set to 4");
+ x->l_ycellnum = 4; /* min # of verti cells */
+ }
+ if (x->l_ycellnum > MAXSIZE)
+ {
+ error("Life: 2nd argument > %d, set to %d", MAXSIZE, MAXSIZE);
+ x->l_ycellnum = MAXSIZE; /* max # of verti cells */
+ }
+ }
+ else if (ac > 1)
+ { /* if 2nd arg not an int */
+ error("Life: 2nd argument must be int");
+ x->l_ycellnum = DEFAULT_DIM; /* default # of verti cells */
+ }
+ else
+ { /* if no 2nd arg */
+ x->l_ycellnum = x->l_xcellnum; /* # of verti cells = # of horiz cells */
+ }
+ }
+ else
+ { /*if first arg not an int */
+ error("Life: first argument must be int");
+ x->l_xcellnum = DEFAULT_DIM; /* default # of horiz cells */
+ x->l_ycellnum = DEFAULT_DIM; /* default # of verti cells */
+ }
+ }
+ else
+ { /* if no arg */
+ x->l_xcellnum = DEFAULT_DIM; /* default # of horiz cells */
+ x->l_ycellnum = DEFAULT_DIM; /* default # of verti cells */
+ }
+
+ x->l_cellmax = x->l_xcellnum*x->l_ycellnum;
+ if ((x->gen_origin_ptr = getbytes(x->l_cellmax)) != NULL)
+ if ((x->gen_finale_ptr = getbytes(x->l_cellmax)) != NULL)
+ if ((x->gen_start_ptr = getbytes(x->l_cellmax)) != NULL)
+ x->gen_shift_ptr = getbytes(x->l_cellmax);
+ if
+ (
+ (x->gen_origin_ptr == NULL)
+ || (x->gen_finale_ptr == NULL)
+ || (x->gen_start_ptr == NULL)
+ || (x->gen_shift_ptr == NULL)
+ )
+ {
+ error ("Unable to allocate memory for the life array (%luX%lu needs %lu bytes)",
+ x->l_xcellnum, x->l_ycellnum, x->l_cellmax*4L);
+ life2x_free (x);
+ return x;
+ }
+
+ x->l_column_list = getbytes(x->l_ycellnum*sizeof (t_atom));
+ if (x->l_column_list == NULL)
+ {
+ error("life2x_new: Unable to allocate %lu bytes for column list",
+ x->l_ycellnum*sizeof (t_atom));
+ life2x_free (x);
+ return x;
+ }
+ for (j = 0; j < x->l_ycellnum; ++j) SETFLOAT(&x->l_column_list[j], 0);
+ /* (we can go faster later by making the atoms floats now) */
+
+ xmax = x->l_xcellnum - 1;
+ ymax = x->l_ycellnum - 1;
+
+ post("life new...(%d X %d)", x->l_xcellnum, x->l_ycellnum);
+ for (j = 0; j <= ymax; j++)
+ { /* sets all cells to 0 */
+ for (i = 0; i <= xmax; i++)
+ {
+ *(x->gen_origin_ptr+(j*x->l_xcellnum)+i) = 0;
+ *(x->gen_finale_ptr+(j*x->l_xcellnum)+i) = 0;
+ *(x->gen_start_ptr+(j*x->l_xcellnum)+i) = 0;
+ *(x->gen_shift_ptr+(j*x->l_xcellnum)+i) = 0;
+ }
+ }
+
+ x->l_xshift = 0;
+ x->l_yshift = 0;
+ x->l_deltanum = 0;
+ x->l_lastdeltanum = 0;
+ x->l_novarinum = 32;
+ x->l_novar = 32;
+
+ x->l_cellouts = getbytes(x->l_xcellnum*sizeof (t_outlet*));
+ if (x->l_cellouts == NULL)
+ {
+ error("life2x_new: Unable to allocate %lu bytes for column outlets",
+ x->l_xcellnum*sizeof (t_outlet*));
+ life2x_free (x);
+ return x;
+ }
+
+ for (i = xmax; i >= 0; i--) x->l_cellouts[i] = outlet_new(&x->x_obj, &s_list);/* create an outlet for each column */
+ x->l_deltaout = outlet_new(&x->x_obj, &s_float); /* create outlet for live cell diff from previous gen */
+ x->l_liveout = outlet_new(&x->x_obj, &s_float); /* sets outlet for # of live cells in current generation */
+ x->l_genout = outlet_new(&x->x_obj, &s_float); /* sets outlet for current generation # */
+ x->l_dumpout = outlet_new(&x->x_obj, &s_list); /* sets outlet for list dumping */
+ x->l_novariout = outlet_new(&x->x_obj, &s_bang); /* sets outlet for no variation period bang */
+ x->l_deadout = outlet_new(&x->x_obj, &s_bang); /* sets first outlet for dead world bang */
+ x->l_gennum = 0; /* sets first generation # */
+ outlet_float(x->l_genout, x->l_gennum);
+ x->l_thruflag = 1; /* sets thru mode on */
+ x->l_invertflag = 0; /* sets invert off */
+
+ /* set up default Conway rule */
+ life2x_rule(x, gensym("23/3")); /* survive if 2 or 3 neighbours / born if 3 neighbours */
+ srandom(clock()); /* seed the random number generator */
+ return (x);
+}
+
+/* end of life2x.c */