/*! * \file lifeutil.c * * \brief Support routines for Conway's Game of Life. * * $Copyright: (C) 2003 Tony Finch $ * * $dotat: life/lifeutil.c,v 1.6 2003/12/17 10:02:19 fanf2 Exp $ */ #include #include #include #include "life.h" void life_alloc(life_ctx *ctx, size_t size) { free(ctx->old); ctx->old = NULL; if(ctx->size > size) return; ctx->old = ctx->space; ctx->size = size; ctx->space = malloc(sizeof(life_cells) * size); ctx->new = ctx->space; if(ctx->space == NULL) err(1, "malloc"); } void life_init(life_ctx *ctx, void *aux, life_pos minx, life_pos miny, life_pos maxx, life_pos maxy) { ctx->cells = ctx->end = ctx->new = NULL; ctx->workdone = ctx->generation = 0; ctx->space = ctx->old = NULL; ctx->size = 0; ctx->minx = minx; ctx->miny = miny; ctx->maxx = maxx; ctx->maxy = maxy; ctx->aux = aux; life_alloc(ctx, 1024); } void life_debug(life_ctx *ctx) { life_cells *this; unsigned long population; int bit; this = ctx->cells; population = 0; do { if(this->pos < 0) printf("%12d\n", this->pos); else { printf("%12d %08x\n", this->pos, this->bmp); for(bit = 0; bit < WORDSIZE; bit++) if(this->bmp & 1 << bit) ++population; } } while(this++->pos != -1); printf("population %lu\n", population); } void life_step(life_ctx *ctx) { size_t required; ctx->end = life(ctx->cells, ctx->new, ctx); ctx->workdone += ctx->end - ctx->new; ctx->generation++; life_draw_flush(ctx); ctx->cells = ctx->new; required = (ctx->end - ctx->new) * 3; if(ctx->end + required < ctx->space + ctx->size) ctx->new = ctx->end; else if(ctx->space + required < ctx->cells) ctx->new = ctx->space; else life_alloc(ctx, ctx->size * 4); } void life_draw(life_ctx *ctx) { life_cells *this; life_pos y; life_draw_clear(ctx); for(this = ctx->cells; this->pos != -1; this++) if(this->pos < 0) y = this->pos; else life_draw_bmp(ctx, this->pos, y, 0, this->bmp); life_draw_flush(ctx); } void life_draw_bmp_cellwise(life_ctx *ctx, life_pos x, life_pos y, life_bmp old, life_bmp new) { life_bmp dead, live, mask; int bit, width; if(y < ctx->miny || y >= ctx->maxy) return; x -= ctx->minx; y -= ctx->miny; width = ctx->maxx - ctx->minx; dead = old & ~new; live = ~old & new; if(x + WORDSIZE >= width) { if(x >= width) return; mask = ~0 >> (x + WORDSIZE - width); dead &= mask; live &= mask; } else if(x < 0) { if(x + WORDSIZE < 0) return; mask = ~0 << -x; dead &= mask; live &= mask; } if(dead == 0 && live == 0) return; for(bit = 0; bit < WORDSIZE; bit++) if(dead & 1<end - 2; while(p->pos > 0) p--; return(p->pos + 1); } /* EOF lifeutil.c */