home *** CD-ROM | disk | FTP | other *** search
- /*****
- *
- * File: celldata.c
- *
- * Cellsim, cellular automata simulator
- *
- * Handle data-structures so the other routines will not be too Sun-specific
- *
- *****/
-
- #include "celldata.h"
-
-
- /*
- *
- * Cellsim copyright 1989, 1990 by Chris Langton and Dave Hiebeler
- * (cgl@lanl.gov, hiebeler@heretic.lanl.gov)
- *
- * This package may be freely distributed, as long as you don't:
- * - remove this notice
- * - try to make money by doing so
- * - prevent others from copying it freely
- * - distribute modified versions without clearly documenting your changes
- * and notifying us
- *
- * Please contact either of the authors listed above if you have questions
- * or feel an exception to any of the above restrictions is in order.
- *
- * If you make changes to the code, or have suggestions for changes,
- * let us know! If we use your suggestion, you will receive full credit
- * of course.
- */
-
- /*****
- * Cellsim history:
- *
- * Cellsim was originally written on Apollo workstations by Chris Langton.
- *
- * Sun versions:
- *
- * - version 1.0
- * by C. Ferenbaugh and C. Langton
- * released 09/02/88
- *
- * - version 1.5
- * by Dave Hiebeler and C. Langton May - June 1989
- * released 07/03/89
- *
- * - version 2.0
- * by Dave Hiebeler and C. Langton July - August 1989
- * never officially released (unofficially released 09/08/89)
- *
- * - version 2.5
- * by Dave Hiebeler and C. Langton September '89 - February 1990
- * released 02/26/90
- *****/
-
-
- /****************************************************************************\
- * *
- * NOTE ON IMAGE ARRAYS *
- * *
- * The arrays declared above have length (B+2) by B for the following reason: *
- * Extra rows above and below the B by B image array are used to hold the *
- * bottom and top rows of the image, respectively. Thus routines which need *
- * to determine neighborhoods do not need to check wraparound conditions for *
- * the top and bottom rows of the image. *
- * The constants ABASE, BSQR, and BBUF point to the beginnings of the top *
- * line of the image, the bottom line of the image, and the bottom buffer, *
- * respectively. In the current version of the program, all routines know *
- * about this array structure. Thus any changes to the array structure would *
- * require changes throughout the source code. *
- * *
- \****************************************************************************/
-
-
-
- /***** basic image functions *****/
-
- init_data()
- {
- int i;
-
- /* open pixrects and get ptrs to associated data blocks */
-
- ca_handle = mem_create(B, B + 2, 8);/* current and image pixrects */
- ia_handle = mem_create(B, B + 2, 8);
-
- a1data = mpr_d(ca_handle);
- a2data = mpr_d(ia_handle);
-
- ca = (State *) a1data->md_image; /* initialize current and image */
- ia = (State *) a2data->md_image; /* array pointers */
-
- buffer[0] = ia_handle; /* initialize buffer pointers */
- bufptr[0] = ia;
- for (i = 1; i < NBUFFERS; i++)
- buffer[i] = NULL;
-
- sh_handle = mem_create(B, B + 2, 8);
- sh = (State *) mpr_d(sh_handle)->md_image;
-
- } /* init_data */
-
-
- /*
- * This gets called when the user changes the image-size
- */
- change_data()
- {
- int i;
-
- pr_destroy(ca_handle);
- pr_destroy(ia_handle);
- ca_handle = mem_create(B, B + 2, 8);
- ia_handle = mem_create(B, B + 2, 8);
-
- a1data = mpr_d(ca_handle);
- a2data = mpr_d(ia_handle);
-
- ca = (State *) a1data->md_image;
- ia = (State *) a2data->md_image;
-
- buffer[0] = ia_handle;
- bufptr[0] = ia;
- for (i = 1; i < NBUFFERS; i++) {
- if (buffer[i])
- pr_destroy(buffer[i]);
- buffer[i] = NULL;
- }
-
- pr_destroy(sh_handle);
- sh_handle = mem_create(B, B + 2, 8);
- sh = (State *) mpr_d(sh_handle)->md_image;
- }
-
-
- /*
- * And all the cells with the maximum possible state. This is used when
- * the user changes the number of states in the simulator.
- */
- and_states()
- {
- unsigned char *a;
- int i;
-
- a = ca + ABASE;
- for (i=0; i < B*B; i++) {
- *a &= S-1;
- a++;
- }
- }
-
-
- clear_data()
- {
- pr_rop(ca_handle, 0, 0, B, B + 2, PIX_CLR, NULL, 0, 0);
- }
-
-
- invert_data()
- {
- pr_rop(ca_handle, 0, 0, B, B + 2, (PIX_SRC ^ PIX_DST) | PIX_COLOR(AMASK),
- NULL, 0, 0);
- }
-
-
- copy_data()
- {
- pr_rop(ia_handle, 0, 0, B, B + 2, PIX_SRC, ca_handle, 0, 0);
- }
-
-
- swap_data()
- { /* swap current and image arrays */
- pr_swap(ca, ca_handle, ia, ia_handle);
- buffer[0] = ia_handle;
- bufptr[0] = ia;
- }
-
-
- load_data(fp) /* load the automaton from the given file */
- FILE *fp;
- {
- State *ap;
- int i, loadsize;
-
- if (use_2D_always) {
- ap = ca + B;
- loadsize = BSQR;
- }
- else {
- ap = ca + ICBASE;
- loadsize = ICSIZE;
- }
- fread(ap, sizeof(*ap), loadsize, fp);
- for (i = B; i < B + BSQR; i++)
- ca[i] &= AMASK; /* mask out unwanted bits */
- }
-
-
- load_resize_data(fp, side, dx, dy) /* load from file of different size */
- FILE *fp;
- int side, dx, dy;
- {
- State *ap;
- int i;
- struct pixrect *temp;
- int size = side * side;
-
- if (DIM == 2) { /* 2-d case */
- temp = mem_create(side, side, 8);
- ap = (State *) mpr_d(temp)->md_image;
- fread(ap, sizeof(*ap), size, fp);
- for (i = 0; i < size; i++)
- ap[i] &= AMASK; /* mask out unwanted bits */
- if (side <= B)
- pr_rop(ca_handle, dx, dy + 1, side, side, PIX_SRC, temp, 0, 0);
- else
- pr_rop(ca_handle, 0, 1, B, B, PIX_SRC, temp, dx, dy);
- pr_destroy(temp);
- } else { /* 1-d case */
- size = side;
- temp = mem_create(side, 1, 8);
- ap = (State *) mpr_d(temp)->md_image;
- fread(ap, sizeof(*ap), size, fp);
- for (i = 0; i < size; i++)
- ap[i] &= AMASK; /* mask out unwanted bits */
- if (side <= B)
- pr_rop(ca_handle, dx, B, side, 1, PIX_SRC, temp, 0, 0);
- else
- pr_rop(ca_handle, 0, B, B, 1, PIX_SRC, temp, dx, 0);
- pr_destroy(temp);
- }
- }
-
-
- save_resize_data(fp, side, dx, dy) /* save to file of different size */
- FILE *fp;
- int side, dx, dy;
- {
- State *ap;
- struct pixrect *temp;
- int size = side * side;
-
- if (DIM == 2) { /* 2-d case */
- temp = mem_create(side, side, 8);
- ap = (State *) mpr_d(temp)->md_image;
- if (side <= B)
- pr_rop(temp, 0, 0, side, side, PIX_SRC, ca_handle, dx, dy + 1);
- else
- pr_rop(temp, dx, dy, B, B, PIX_SRC, ca_handle, 0, 1);
- } else { /* 1-d case */
- size = side;
- temp = mem_create(side, 1, 8);
- ap = (State *) mpr_d(temp)->md_image;
- if (side <= B)
- pr_rop(temp, 0, 0, side, 1, PIX_SRC, ca_handle, dx, B);
- else
- pr_rop(temp, dx, 0, B, 1, PIX_SRC, ca_handle, 0, B);
- }
- fwrite(ap, sizeof(*ap), size, fp);
- pr_destroy(temp);
- }
-
-
- /***** buffer functions *****/
-
- copy_to_buffer(n)
- int n;
- {
- if (buffer[n] == NULL) {
- buffer[n] = mem_create(B, B + 2, 8);
- bufptr[n] = (State *) (mpr_d(buffer[n])->md_image);
- }
- pr_rop(buffer[n], 0, 0, B, B + 2, PIX_SRC, ca_handle, 0, 0);
- }
-
-
- swap_to_buffer(n)
- int n;
- {
- if (buffer[n] == NULL) {
- show_msg("Buffer empty");
- return;
- }
- pr_swap(ca, ca_handle, bufptr[n], buffer[n]);
- if (n == 0) {
- ia_handle = buffer[0];
- ia = bufptr[0];
- }
- }
-
-
- load_from_buffer(n) /* load from the given buffer */
- int n;
- {
- use_buffer(n, PIX_SRC);
- }
-
-
- xor_with_buffer(n)
- int n;
- {
- use_buffer(n, PIX_SRC ^ PIX_DST);
- }
-
-
- or_with_buffer(n)
- int n;
- {
- use_buffer(n, PIX_SRC | PIX_DST);
- }
-
-
- and_with_buffer(n)
- int n;
- {
- use_buffer(n, PIX_SRC & PIX_DST);
- }
-
-
- use_buffer(n, op) /* generalized buffer load */
- int n, op;
- {
- if (buffer[n] == NULL) {
- clear_msg();
- show_msg("Buffer empty");
- return;
- }
- pr_rop(ca_handle, 0, 0, B, B + 2, op | PIX_DONTCLIP, buffer[n], 0, 0);
- }
-
-
- /***** data shift routines *****/
-
- hshift_data(dx) /* horizontal shift */
- int dx;
- {
- dx %= B;
- if (dx == 0)
- return;
- if (dx < 0)
- dx = B + dx;
- pr_rop(sh_handle, 0, 0, dx, B + 2, PIX_SRC | PIX_DONTCLIP, ca_handle, B - dx, 0);
- pr_rop(sh_handle, dx, 0, B - dx, B + 2, PIX_SRC | PIX_DONTCLIP, ca_handle, 0, 0);
- pr_swap(ca, ca_handle, sh, sh_handle);
- }
-
-
- vshift_data(dy) /* vertical shift */
- int dy;
- {
- dy %= B;
- if (dy == 0)
- return;
- if (dy < 0)
- dy = B + dy;
- pr_rop(sh_handle, 0, 1, B, dy, PIX_SRC | PIX_DONTCLIP, ca_handle, 0, 1 + B - dy);
- pr_rop(sh_handle, 0, 1 + dy, B, B - dy, PIX_SRC | PIX_DONTCLIP, ca_handle, 0, 1);
- pr_swap(ca, ca_handle, sh, sh_handle);
- }
-
- /***** plane routines *****/
-
- clear_planes(mask)
- int mask;
- {
- mask &= AMASK;
- pr_rop(ca_handle, 0, 0, B, B + 2, (PIX_DST & PIX_NOT(PIX_SRC)) | PIX_COLOR(mask),
- NULL, 0, 0);
- }
-
-
- invert_planes(mask)
- int mask;
- {
- mask &= AMASK;
- pr_rop(ca_handle, 0, 0, B, B + 2, (PIX_SRC ^ PIX_DST) | PIX_COLOR(mask),
- NULL, 0, 0);
- }
-