/** * Conways Game of life * Author: Daniel Otte * License: GPLv3 * * */ #include #ifdef AVR #include #include /* for debugging */ #endif #include "../config.h" #include "../random/prng.h" #include "../pixel.h" #include "../util.h" /******************************************************************************/ #undef DEBUG #define XSIZE UNUM_COLS #define YSIZE UNUM_ROWS // optimizing for 8 bit archs while retaining compatibility with dimensions >255 #if UNUM_COLS < 256 && UNUM_ROWS < 256 typedef uint8_t coord_t; #else typedef unsigned int coord_t; #endif /* * last line is for debug information */ #ifdef DEBUG #undef YSIZE #define YSIZE (UNUM_ROWS-1) #define DEBUG_ROW (UNUM_ROWS-1) #define DEBUG_BIT(pos, val) \ setpixel((pixel){(pos)%XSIZE,DEBUG_ROW+(pos)/XSIZE},(val)?3:0) #define DEBUG_BYTE(s,v) \ DEBUG_BIT((s)*8+0, (v)&(1<<0)); \ DEBUG_BIT((s)*8+1, (v)&(1<<1)); \ DEBUG_BIT((s)*8+2, (v)&(1<<2)); \ DEBUG_BIT((s)*8+3, (v)&(1<<3)); \ DEBUG_BIT((s)*8+4, (v)&(1<<4)); \ DEBUG_BIT((s)*8+5, (v)&(1<<5)); \ DEBUG_BIT((s)*8+6, (v)&(1<<6)); \ DEBUG_BIT((s)*8+7, (v)&(1<<7)) #else #define DEBUG_BIT(s,v) #define DEBUG_BYTE(s,v) #endif //#define GLIDER_TEST #define BITSTUFFED #define LOOP_DETECT_BUFFER_SIZE 8U #ifndef GOL_DELAY #define GOL_DELAY 1 /* milliseconds */ #endif #ifndef GOL_CYCLES #define GOL_CYCLES (2*60*3) #endif /******************************************************************************/ /******************************************************************************/ enum cell_e {dead=0, alive=1}; #ifdef NDEBUG typedef uint8_t cell_t; #else typedef enum cell_e cell_t; #endif #ifndef BITSTUFFED #define FIELD_XSIZE XSIZE #define FIELD_YSIZE YSIZE typedef cell_t field_t[FIELD_XSIZE][FIELD_YSIZE]; /******************************************************************************/ void setcell(field_t pf, coord_t x, coord_t y, cell_t value){ pf[(x+FIELD_XSIZE)%FIELD_XSIZE][(y+FIELD_YSIZE)%FIELD_YSIZE] = value; } /******************************************************************************/ cell_t getcell(field_t pf, coord_t x, coord_t y){ return pf[(x+FIELD_XSIZE)%FIELD_XSIZE][(y+FIELD_YSIZE)%FIELD_YSIZE]; } #else /* BITSTUFFED */ #define FIELD_XSIZE ((XSIZE+7)/8) #define FIELD_YSIZE YSIZE typedef uint8_t field_t[FIELD_XSIZE][FIELD_YSIZE]; /******************************************************************************/ void setcell(field_t pf, coord_t x, coord_t y, cell_t value){ uint8_t t; t = pf[x/8][y]; if(value==alive){ t |= 1<<(x&7); } else { t &= ~(1<<(x&7)); } pf[x/8][y] = t; } /******************************************************************************/ static cell_t getcell(field_t pf, coord_t x, coord_t y){ return ((pf[x/8][y])&(1<<(x&7)))?alive:dead; } #endif /******************************************************************************/ uint8_t countsurroundingalive(field_t pf, coord_t x, coord_t y){ static int8_t const offset[] = {-1, -1, 0, +1, +1, +1, 0, -1, -1, -1}; uint8_t i, ret=0; for (i = 8; i--;) { // getcell(...) returns either 0 or 1 ret += getcell(pf,(XSIZE+x+offset[i+2])%XSIZE, (YSIZE+y+offset[i])%YSIZE); } return ret; } /******************************************************************************/ void nextiteration(field_t dest, field_t src){ coord_t x,y; uint8_t tc; for(y=0; y