/* * An implementation of Conway's Game of Life. */ #include "life.h" static const char * const life_info[] = { "@(#) $Copyright: (C) 2003 Tony Finch (dot@dotat.at) $", "@(#) $dotat: life/life.c,v 1.37 2003/12/18 23:31:12 fanf2 Exp $" }; life_cells * life(life_cells *this, life_cells *new, void *ctx) { life_bmp prevL, thisL, nextL, prevR, thisR, nextR; life_bmp rear1, rear2, midd1, midd2, fore1, fore2; life_bmp bmp, count1, count2, count4a, count4b; life_cells *prev, *next; life_pos x, y; prevL = thisL = nextL = rear1 = rear2 = 0; prev = next = this; new->pos = -1; for(;;) { if(new->pos > -1) ++new; if(prev == next) { if(next->pos == -1) return(new->pos = -1, ++new); y = next++->pos - 1; } else { if(prev->pos == y++) prev++; if(this->pos == y) this++; if(next->pos == y+1) next++; } new->pos = y; for(;;) { x = prev->pos; if(x < this->pos) x = this->pos; if(x < next->pos) x = next->pos; if(x < 0) break; for(;;) { if(prev->pos == x) { prevR = prev++->bmp; if(this->pos == x) thisR = this++->bmp; else thisR = 0; if(next->pos == x) nextR = next++->bmp; else nextR = 0; } else { prevR = 0; if(this->pos == x) { thisR = this++->bmp; if(next->pos == x) nextR = next++->bmp; else nextR = 0; } else { thisR = 0; if(next->pos == x) { nextR = next++->bmp; } else { nextR = 0; if(rear1 == 0 && rear2 == 0 && prevL == 0 && thisL == 0 && nextL == 0) break; } } } ADD3(fore1,fore2, prevL << 1 | prevR >> WORDSIZE-1, thisL << 1 | thisR >> WORDSIZE-1, nextL << 1 | nextR >> WORDSIZE-1); ADD2(midd1,midd2, prevL,nextL); ADD3(count1,count2, fore1,midd1,rear1); ADD3(count2,count4a, count2,fore2,rear2); ADD2(count2,count4b, count2,midd2); bmp = (count1 | thisL) & count2 & ~count4a & ~count4b; life_draw_bmp(ctx, x+WORDSIZE, y, thisL, bmp); if(bmp) ++new, new->pos = x+WORDSIZE, new->bmp = bmp; ADD3(rear1,rear2, prevL << WORDSIZE-1 | prevR >> 1, thisL << WORDSIZE-1 | thisR >> 1, nextL << WORDSIZE-1 | nextR >> 1); prevL = prevR; thisL = thisR; nextL = nextR; x -= WORDSIZE; } } } }