aboutsummaryrefslogtreecommitdiff
path: root/elementaryca.c
blob: 52ee6fb7a646c66767ee36639c6921a43a866fe9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#include "m_pd.h"
#include <math.h>
#include <stdio.h>
#include <stdlib.h>

#define TRUE  1
#define FALSE 0
#define MAX_ARRAY_SIZE 256

//Already defined elsewhere ??
//typedef short boolean;

static t_class *eca_class;


typedef struct _eca {
  t_object  x_obj;
  t_int counter;
  boolean cells[256];
  t_int size;
  //t_int offset;
  t_outlet *on_cells;
  //t_outlet *firstcell;
  t_atom oncells[256];
  boolean ruletable[8];
  t_int rule;
  t_float inrule;
} t_eca;

void randomizeCells(t_eca *x) {
	int i;
	for (i=0;i<x->size;i++) {
	x->cells[i] = ((t_float) rand())/RAND_MAX*2;	
	}
}

void eca_activateMiddleCell(t_eca *x) {
	int i;
	post("activate middle cell");
	for (i=0;i<x->size;i++) {
	x->cells[i] = FALSE;	
	}
	x->cells[x->size/2] = TRUE;
}

void calculateCellStates(t_eca *x) {
	
	int i;
	
	boolean newstates[MAX_ARRAY_SIZE];
	newstates[0] = x->ruletable[x->cells[x->size-1]*4+x->cells[0]*2+x->cells[1]];
	newstates[x->size-1] = x->ruletable[x->cells[x->size-2]*4+x->cells[x->size-1]*2+x->cells[0]];
	for (i=1;i<x->size-1;i++) {
	newstates[i] = x->ruletable[x->cells[i-1]*4+x->cells[i]*2+x->cells[i+1]];
	}
	for (i=0;i<x->size;i++) {
	x->cells[i] = newstates[i];
	}
}

void eca_randomize(t_eca *x) {
post("Randomize called");	
randomizeCells(x);
}

void createRuleTable(t_eca *x,unsigned short decimalcode) {
	
	int i;
	post("Rule changed to %d",x->rule);
	//decimalcode to binary
	fast_d2b(decimalcode,x->ruletable);
	//for (i=0;i<8;i++) 
	//post("%d",x->ruletable[i]);
}

void eca_bang(t_eca *x)
{
t_atom *y;
int i;
int k = 0;
if ((t_int) x->inrule != x->rule) {
x->rule = (t_int) x->inrule/1;
createRuleTable(x,(unsigned short) x->rule);
}
//startpost("%d",x->counter);
for (i=0;i<x->size;i++) {
	if (x->cells[i]==TRUE)
	{
		//startpost("& $\\bullet$ ");
		SETFLOAT(&x->oncells[k],i);
//		SETFLOAT(&x->oncells[k],i+x->offset);
//		oncells[k] = y;
		k++;
	}
	//else startpost("& ");
	
	
}
//post("\\tabularnewline");
x->counter++;
//randomizeCells(x);
outlet_list(x->on_cells,&s_list, k, &x->oncells[0]);
calculateCellStates(x); // calculate for next step
//outlet_float(x->firstcell,x->cells[0]);
}



/*
 * take argument rule, size, init (0=random), (1=middlecell active)
 */
void *eca_new(t_floatarg rule,t_floatarg size,t_floatarg init)
{
  
  t_eca *x = (t_eca *)pd_new(eca_class);
  //inlet_new(&x->x_obj, &x->x_obj.ob_pd,gensym("list"), gensym("randomize"));
  if (size != 0)
  x->size = size;
  else (size = 16);
  //x->offset = offset;
  
  if (init == 0) randomizeCells(x);
  else if (init == 1) eca_activateMiddleCell(x);
  x->rule = rule;	
  x->inrule = rule;
  x->counter = 1;
  createRuleTable(x,(unsigned short) rule);
  x->on_cells = outlet_new(&x->x_obj,&s_list);
  //x->firstcell = outlet_new(&x->x_obj,&s_float);
  floatinlet_new(&x->x_obj, &x->inrule);  
  return (void *)x;
}