-
Notifications
You must be signed in to change notification settings - Fork 0
/
life-unroll.c
85 lines (80 loc) · 2.25 KB
/
life-unroll.c
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
#include <avr/io.h>
#include "life-unroll.h"
static inline unsigned char life_round_byte(unsigned char prevbyte, unsigned char thisbyte, unsigned char nextbyte,
unsigned char prev_byte_count, unsigned char next_byte_count)
{
unsigned char bi;
unsigned char prev_col_count=0, this_col_count=0, next_col_count=0;
unsigned char outbyte = 0;
unsigned char count;
for (bi = 0; bi < 8; bi++) {
if (bi == 0) {
prev_col_count = prev_byte_count;
this_col_count = 0;
if (prevbyte & _BV(bi))
this_col_count++;
if (thisbyte & _BV(bi))
this_col_count++;
if (nextbyte & _BV(bi))
this_col_count++;
} else {
prev_col_count = this_col_count;
this_col_count = next_col_count;
}
if (bi == 7) {
next_col_count = next_byte_count;
} else {
next_col_count = 0;
if (prevbyte & _BV(bi+1))
next_col_count++;
if (thisbyte & _BV(bi+1))
next_col_count++;
if (nextbyte & _BV(bi+1))
next_col_count++;
}
count = prev_col_count + this_col_count + next_col_count;
if (thisbyte & _BV(bi)) {
// previously alive. count includes the current pixel.
if (count == (2+1) || count == (3+1))
outbyte |= _BV(bi);
} else {
// previously dead
if (count == 3)
outbyte |= _BV(bi);
}
}
return outbyte;
}
void life_round_line(unsigned char *prevline, unsigned char *thisline, unsigned char *nextline,
unsigned char count_on_left, unsigned char count_on_right,
unsigned char *thisline_out)
{
unsigned char prev_byte_count;
unsigned char next_byte_count;
unsigned char by;
for (by = 0; by < 8; by++) {
if (by == 0) {
prev_byte_count = count_on_left;
} else {
prev_byte_count = 0;
if (prevline[by-1] & _BV(7))
prev_byte_count++;
if (thisline[by-1] & _BV(7))
prev_byte_count++;
if (nextline[by-1] & _BV(7))
prev_byte_count++;
}
if (by == 7) {
next_byte_count = count_on_right;
} else {
next_byte_count = 0;
if (prevline[by+1] & _BV(0))
next_byte_count++;
if (thisline[by+1] & _BV(0))
next_byte_count++;
if (nextline[by+1] & _BV(0))
next_byte_count++;
}
thisline_out[by] = life_round_byte(prevline[by], thisline[by], nextline[by], prev_byte_count, next_byte_count);
}
}