X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=hacks%2Fpetri.c;h=b9da70ad7cec69c48d17fe10fdea1c9ed715dbc7;hb=9c9d475ff889ed8be02e8ce8c17da28b93278fca;hp=b4c748f65f36b7c572b2b9d64604ba0f6a7df905;hpb=72c1f4c1dc6ab07fe121a327ff1c30bf51ef74c1;p=xscreensaver diff --git a/hacks/petri.c b/hacks/petri.c index b4c748f6..b9da70ad 100644 --- a/hacks/petri.c +++ b/hacks/petri.c @@ -1,4 +1,4 @@ -/* petri, simulate mold in a petri dish. v2.6 +/* petri, simulate mold in a petri dish. v2.7 * by Dan Bornstein, danfuzz@milk.com * with help from Jamie Zawinski, jwz@jwz.org * Copyright (c) 1992-1999 Dan Bornstein. @@ -69,18 +69,16 @@ typedef struct cell_s { - short x; /* 0 - */ - short y; /* 2 */ - unsigned char col; /* 4 */ - unsigned char isnext; /* 5 */ - unsigned char nextcol; /* 6 */ - /* 7 */ - struct cell_s *next; /* 8 - */ - struct cell_s *prev; /* 12 */ - FLOAT speed; /* 16 - */ - FLOAT growth; /* 20 24 */ - FLOAT nextspeed; /* 24 32 - */ - /* 28 40 */ + unsigned char col; /* 0 */ + unsigned char isnext; /* 1 */ + unsigned char nextcol; /* 2 */ + /* 3 */ + struct cell_s *next; /* 4 */ + struct cell_s *prev; /* 8 - */ + FLOAT speed; /* 12 */ + FLOAT growth; /* 16 20 - */ + FLOAT nextspeed; /* 20 28 */ + /* 24 36 - */ } cell; static int arr_width; @@ -116,6 +114,10 @@ static FLOAT mindeathspeed; static FLOAT maxdeathspeed; static Bool originalcolors; +#define cell_x(c) (((c) - arr) % arr_width) +#define cell_y(c) (((c) - arr) / arr_width) + + static int random_life_value (void) { return (int) ((RAND_FLOAT * (maxlifespan - minlifespan)) + minlifespan); @@ -273,9 +275,16 @@ static void setup_display (void) count = get_integer_resource ("count", "Integer"); if (count < 2) count = 2; + + /* number of colors can't be greater than the half depth of the screen. */ if (count > (1L << (xgwa.depth-1))) count = (1L << (xgwa.depth-1)); + /* Actually, since cell->col is of type char, this has to be small. */ + if (count >= (1L << ((sizeof(arr[0].col) * 8) - 1))) + count = (1L << ((sizeof(arr[0].col) * 8) - 1)); + + if (originalcolors && (count > 8)) { count = 8; @@ -480,8 +489,6 @@ static void setup_arr (void) int row = y * arr_width; for (x = 0; x < arr_width; x++) { - arr[row+x].x = x; - arr[row+x].y = y; arr[row+x].speed = 0.0; arr[row+x].growth = 0.0; arr[row+x].col = 0; @@ -533,7 +540,7 @@ static void killcell (cell *c) c->next->prev = c->prev; c->prev = 0; c->speed = 0.0; - drawblock (c->x, c->y, c->col); + drawblock (cell_x(c), cell_y(c), c->col); } @@ -596,33 +603,42 @@ static void update (void) for (a = head->next; a != tail; a = a->next) { - static XPoint coords1[] = {{-1, 0}, { 1, 0}, {0, -1}, {0, 1}}; - static XPoint coords2[] = {{-1, -1}, {-1, 1}, {1, -1}, {1, 1}}; + static XPoint all_coords[] = {{-1, -1}, {-1, 1}, {1, -1}, {1, 1}, + {-1, 0}, { 1, 0}, {0, -1}, {0, 1}, + {99, 99}}; + XPoint *coords = 0; - int i; if (a->speed == 0) continue; a->growth += a->speed; - if (a->growth >= orthlim) - coords = coords1; if (a->growth >= diaglim) - coords = coords2; - - if (coords) - for (i = 0; i < 4; i++) - { - int x = a->x + coords[i].x; - int y = a->y + coords[i].y; - - if (x < 0) x = arr_width - 1; - else if (x >= arr_width) x = 0; - - if (y < 0) y = arr_height - 1; - else if (y >= arr_height) y = 0; + { + coords = all_coords; + } + else if (a->growth >= orthlim) + { + coords = &all_coords[4]; + } + else + { + continue; + } - newcell (&arr[y * arr_width + x], a->col, a->speed); - } + while (coords->x != 99) + { + int x = cell_x(a) + coords->x; + int y = cell_y(a) + coords->y; + coords++; + + if (x < 0) x = arr_width - 1; + else if (x >= arr_width) x = 0; + + if (y < 0) y = arr_height - 1; + else if (y >= arr_height) y = 0; + + newcell (&arr[y * arr_width + x], a->col, a->speed); + } if (a->growth >= diaglim) killcell (a); @@ -638,7 +654,7 @@ static void update (void) a->speed = a->nextspeed; a->growth = 0.0; a->col = a->nextcol; - drawblock (a->x, a->y, a->col + count); + drawblock (cell_x(a), cell_y(a), a->col + count); } } }