converted bitstuffing algorithms to native borg frame buffer format, saving 124 bytes

This commit is contained in:
Christian Kroll 2011-03-31 21:38:28 +00:00
parent 07c9d27b75
commit 12a8e94db4
1 changed files with 148 additions and 157 deletions

View File

@ -23,7 +23,7 @@
#define XSIZE UNUM_COLS
#define YSIZE UNUM_ROWS
// optimizing for 8 bit archs while retaining compatibility with dimensions >255
// optimizing for 8 bit archs while retaining compatibility with dimensions >127
#if UNUM_COLS < 128 && UNUM_ROWS < 128
typedef uint8_t coord_t;
#else
@ -69,7 +69,9 @@ typedef unsigned int coord_t;
/******************************************************************************/
/******************************************************************************/
enum cell_e {dead=0, alive=1};
enum cell_e {
dead = 0, alive = 1
};
#ifdef NDEBUG
typedef uint8_t cell_t;
#else
@ -81,45 +83,41 @@ enum cell_e {dead=0, alive=1};
#define FIELD_XSIZE XSIZE
#define FIELD_YSIZE YSIZE
typedef cell_t field_t[FIELD_XSIZE][FIELD_YSIZE];
typedef cell_t field_t[FIELD_YSIZE][FIELD_XSIZE];
/******************************************************************************/
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;
pf[(y+FIELD_YSIZE) % FIELD_YSIZE][(x+FIELD_XSIZE) % FIELD_XSIZE] = 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];
return pf[(y+FIELD_YSIZE) % FIELD_YSIZE][(x+FIELD_XSIZE) % FIELD_XSIZE];
}
#else /* BITSTUFFED */
#define FIELD_XSIZE ((XSIZE+7)/8)
#define FIELD_XSIZE LINEBYTES
#define FIELD_YSIZE YSIZE
typedef uint8_t field_t[FIELD_XSIZE][FIELD_YSIZE];
typedef uint8_t field_t[FIELD_YSIZE][FIELD_XSIZE];
/******************************************************************************/
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);
if (value != dead) {
pf[y][x / 8] |= shl_table[x & 7];
} else {
t &= ~(1<<(x&7));
pf[y][x / 8] &= ~shl_table[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;
return ((pf[y][x / 8]) & (shl_table[x & 7])) ? alive : dead;
}
#endif
@ -131,8 +129,7 @@ uint8_t countsurroundingalive(field_t pf, coord_t x, coord_t y){
x += XSIZE;
y += YSIZE;
uint8_t i, ret = 0;
for (i = 8; i--;)
{
for (i = 8; i--;) {
// getcell(...) returns either 0 or 1
ret += getcell(pf, (x + offset[i+2]) % XSIZE, (y + offset[i]) % YSIZE);
}
@ -145,8 +142,8 @@ uint8_t countsurroundingalive(field_t pf, coord_t x, coord_t y){
void nextiteration(field_t dest, field_t src) {
coord_t x, y;
uint8_t tc;
for(y=0; y<YSIZE; ++y){
for(x=0; x<XSIZE; ++x){
for (y = YSIZE; y--;) {
for (x = XSIZE; x--;) {
tc = countsurroundingalive(src, x, y);
switch (tc) {
// case 0:
@ -172,7 +169,12 @@ void nextiteration(field_t dest, field_t src){
/******************************************************************************/
void printpf(field_t pf){
#ifdef BITSTUFFED
static void pfprint(field_t pf) {
memcpy(pixmap[NUMPLANE - 1], pf, sizeof(field_t));
}
#else
void pfprint(field_t pf) {
coord_t x,y;
for(y=YSIZE; y--;) {
for(x=XSIZE; x--;) {
@ -180,30 +182,21 @@ void printpf(field_t pf){
}
}
}
#endif
/******************************************************************************/
void pfcopy(field_t dest, field_t src){
coord_t x,y;
for(y=YSIZE; y--;){
for(x=XSIZE; x--;){
setcell(dest,x,y,getcell(src,x,y));
}
}
static void pfcopy(field_t dest, field_t src) {
memcpy(dest, src, sizeof(field_t));
}
/******************************************************************************/
static int pfcmp(field_t dest, field_t src) {
return memcmp(dest, src, sizeof(field_t));
}
#ifndef BITSTUFFED
uint8_t pfcmp(field_t dest, field_t src){
coord_t x,y;
for(y=YSIZE; y--;){
for(x=XSIZE; x--;){
if (getcell(src,x,y) != getcell(dest,x,y))
return 1;
}
}
return 0;
}
/******************************************************************************/
@ -217,34 +210,22 @@ uint8_t pfempty(field_t src){
}
return 1;
}
#else
uint8_t pfcmp(field_t dest, field_t src){
coord_t x,y;
for(y=0; y<FIELD_YSIZE; ++y){
for(x=0; x<FIELD_XSIZE; ++x){
if (src[x][y] != dest[x][y])
return 1;
}
}
return 0;
}
/******************************************************************************/
uint8_t pfempty(field_t src) {
coord_t x, y;
for (y = 0; y < FIELD_YSIZE; ++y) {
for (x = 0; x < FIELD_XSIZE; ++x) {
if (src[x][y]!=0)
if (src[y][x] != 0)
return 0;
}
}
return 1;
}
#endif
/******************************************************************************/
void insertglider(field_t pf) {
@ -260,24 +241,39 @@ void insertglider(field_t pf){
/******************************************************************************/
int gameoflife(){
static void pfinit(field_t pf)
{
coord_t x, y;
#ifndef BITSTUFFED
for (y = YSIZE; y--;) {
for (x = XSIZE; x--;) {
setcell(pf, x, y, (random8() & 1) ? alive : dead);
}
}
#else
for (y = 0; y < FIELD_YSIZE; ++y) {
for (x = 0; x < FIELD_XSIZE; ++x) {
pf[y][x] = random8();
}
}
#endif
}
/******************************************************************************/
void gameoflife() {
DEBUG_BYTE(0,0); // set debug bytes to zero
DEBUG_BYTE(1,0);
field_t pf1, pf2;
field_t ldbuf[LOOP_DETECT_BUFFER_SIZE] = {{{0}}}; // loop detect buffer
uint8_t ldbuf_idx = 0;
coord_t x,y;
uint16_t cycle;
//start:
/* initalise the field with random */
for(y=YSIZE; y--;){
for(x=XSIZE; x--;){
setcell(pf1,x,y,(random8()&1)?alive:dead);
}
}
/* initialize the field with random */
pfinit(pf1);
#ifdef GLIDER_TEST
/* initialise with glider */
/* initialize with glider */
for(y=YSIZE; y--;) {
for(x=XSIZE; x--;) {
setcell(pf1, x, y, dead);
@ -287,14 +283,13 @@ int gameoflife(){
#endif
/* the main part */
printpf(pf1);
pfprint(pf1);
for (cycle = 1; cycle < GOL_CYCLES; ++cycle) {
DEBUG_BYTE(0,(uint8_t)(GOL_CYCLES-cycle)&0xff);
DEBUG_BYTE(1, SREG);
DEBUG_BYTE(0, (uint8_t)(GOL_CYCLES-cycle) & 0xff); DEBUG_BYTE(1, SREG);
wait(GOL_DELAY);
pfcopy(pf2, pf1);
nextiteration(pf1, pf2);
printpf(pf1);
pfprint(pf1);
/* loop detection */
if (!pfcmp(pf1, pf2)) {
insertglider(pf1);
@ -302,7 +297,7 @@ int gameoflife(){
}
if (pfempty(pf1)) {
/* kill game */
return 0;
return;
}
/* */
uint8_t i;
@ -314,9 +309,5 @@ int gameoflife(){
}
pfcopy(ldbuf[ldbuf_idx], pf1);
ldbuf_idx = (ldbuf_idx + 1) % LOOP_DETECT_BUFFER_SIZE;
}
return 0;
}