home *** CD-ROM | disk | FTP | other *** search
/ Photo CD Demo 1 / Demo.bin / cellsim / v2_5 / src / celldata.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-04-01  |  8.8 KB  |  382 lines

  1. /*****
  2.  *
  3.  * File: celldata.c
  4.  *
  5.  * Cellsim, cellular automata simulator
  6.  *
  7.  * Handle data-structures so the other routines will not be too Sun-specific
  8.  *
  9.  *****/
  10.  
  11. #include "celldata.h"
  12.  
  13.  
  14. /*
  15.  *
  16.  * Cellsim copyright 1989, 1990 by Chris Langton and Dave Hiebeler
  17.  * (cgl@lanl.gov, hiebeler@heretic.lanl.gov)
  18.  *
  19.  * This package may be freely distributed, as long as you don't:
  20.  * - remove this notice
  21.  * - try to make money by doing so
  22.  * - prevent others from copying it freely
  23.  * - distribute modified versions without clearly documenting your changes
  24.  *   and notifying us
  25.  *
  26.  * Please contact either of the authors listed above if you have questions
  27.  * or feel an exception to any of the above restrictions is in order.
  28.  *
  29.  * If you make changes to the code, or have suggestions for changes,
  30.  * let us know!  If we use your suggestion, you will receive full credit
  31.  * of course.
  32.  */
  33.  
  34. /*****
  35.  * Cellsim history:
  36.  *
  37.  * Cellsim was originally written on Apollo workstations by Chris Langton.
  38.  *
  39.  * Sun versions:
  40.  *
  41.  * - version 1.0
  42.  *   by C. Ferenbaugh and C. Langton
  43.  *   released 09/02/88
  44.  *
  45.  * - version 1.5
  46.  *   by Dave Hiebeler and C. Langton  May - June 1989
  47.  *   released 07/03/89
  48.  *
  49.  * - version 2.0
  50.  *   by Dave Hiebeler and C. Langton  July - August 1989
  51.  *   never officially released (unofficially released 09/08/89)
  52.  *
  53.  * - version 2.5
  54.  *   by Dave Hiebeler and C. Langton  September '89 - February 1990
  55.  *   released 02/26/90
  56.  *****/
  57.  
  58.  
  59. /****************************************************************************\
  60. *                                                                            *
  61. *                            NOTE ON IMAGE ARRAYS                            *
  62. *                                                                            *
  63. * The arrays declared above have length (B+2) by B for the following reason: *
  64. * Extra rows above and below the B by B image array are used to hold the     *
  65. * bottom and top rows of the image, respectively.  Thus routines which need  *
  66. * to determine neighborhoods do not need to check wraparound conditions for  *
  67. * the top and bottom rows of the image.                                      *
  68. * The constants ABASE, BSQR, and BBUF point to the beginnings of the top     *
  69. * line of the image, the bottom line of the image, and the bottom buffer,    *
  70. * respectively.  In the current version of the program, all routines know    *
  71. * about this array structure.  Thus any changes to the array structure would *
  72. * require changes throughout the source code.                                *
  73. *                                                                            *
  74. \****************************************************************************/
  75.  
  76.  
  77.  
  78. /***** basic image functions *****/
  79.  
  80. init_data()
  81. {
  82.     int     i;
  83.  
  84.     /* open pixrects and get ptrs to associated data blocks */
  85.  
  86.     ca_handle = mem_create(B, B + 2, 8);/* current and image pixrects */
  87.     ia_handle = mem_create(B, B + 2, 8);
  88.  
  89.     a1data = mpr_d(ca_handle);
  90.     a2data = mpr_d(ia_handle);
  91.  
  92.     ca = (State *) a1data->md_image;    /* initialize current and image */
  93.     ia = (State *) a2data->md_image;    /* array pointers               */
  94.  
  95.     buffer[0] = ia_handle;        /* initialize buffer pointers */
  96.     bufptr[0] = ia;
  97.     for (i = 1; i < NBUFFERS; i++)
  98.     buffer[i] = NULL;
  99.  
  100.     sh_handle = mem_create(B, B + 2, 8);
  101.     sh = (State *) mpr_d(sh_handle)->md_image;
  102.  
  103. } /* init_data */
  104.  
  105.  
  106. /*
  107.  * This gets called when the user changes the image-size
  108.  */
  109. change_data()
  110. {
  111.     int i;
  112.     
  113.     pr_destroy(ca_handle);
  114.     pr_destroy(ia_handle);
  115.     ca_handle = mem_create(B, B + 2, 8);
  116.     ia_handle = mem_create(B, B + 2, 8);
  117.  
  118.     a1data = mpr_d(ca_handle);
  119.     a2data = mpr_d(ia_handle);
  120.  
  121.     ca = (State *) a1data->md_image;
  122.     ia = (State *) a2data->md_image;
  123.  
  124.     buffer[0] = ia_handle;
  125.     bufptr[0] = ia;
  126.     for (i = 1; i < NBUFFERS; i++) {
  127.     if (buffer[i])
  128.         pr_destroy(buffer[i]);
  129.     buffer[i] = NULL;
  130.     }
  131.  
  132.     pr_destroy(sh_handle);
  133.     sh_handle = mem_create(B, B + 2, 8);
  134.     sh = (State *) mpr_d(sh_handle)->md_image;
  135. }
  136.  
  137.  
  138. /*
  139.  * And all the cells with the maximum possible state.  This is used when
  140.  * the user changes the number of states in the simulator.
  141.  */
  142. and_states()
  143. {
  144.     unsigned char *a;
  145.     int i;
  146.  
  147.     a = ca + ABASE;
  148.     for (i=0; i < B*B; i++) {
  149.     *a &= S-1;
  150.     a++;
  151.     }
  152. }
  153.     
  154.  
  155. clear_data()
  156. {
  157.     pr_rop(ca_handle, 0, 0, B, B + 2, PIX_CLR, NULL, 0, 0);
  158. }
  159.  
  160.  
  161. invert_data()
  162. {
  163.     pr_rop(ca_handle, 0, 0, B, B + 2, (PIX_SRC ^ PIX_DST) | PIX_COLOR(AMASK),
  164.        NULL, 0, 0);
  165. }
  166.  
  167.  
  168. copy_data()
  169. {
  170.     pr_rop(ia_handle, 0, 0, B, B + 2, PIX_SRC, ca_handle, 0, 0);
  171. }
  172.  
  173.  
  174. swap_data()
  175. {                    /* swap current and image arrays */
  176.     pr_swap(ca, ca_handle, ia, ia_handle);
  177.     buffer[0] = ia_handle;
  178.     bufptr[0] = ia;
  179. }
  180.  
  181.  
  182. load_data(fp)                /* load the automaton from the given file */
  183.     FILE   *fp;
  184. {
  185.     State  *ap;
  186.     int     i, loadsize;
  187.  
  188.     if (use_2D_always) {
  189.     ap = ca + B;
  190.     loadsize = BSQR;
  191.     }
  192.     else {
  193.     ap = ca + ICBASE;
  194.     loadsize = ICSIZE;
  195.     }
  196.     fread(ap, sizeof(*ap), loadsize, fp);
  197.     for (i = B; i < B + BSQR; i++)
  198.     ca[i] &= AMASK;            /* mask out unwanted bits */
  199. }
  200.  
  201.  
  202. load_resize_data(fp, side, dx, dy)    /* load from file of different size */
  203.     FILE   *fp;
  204.     int     side, dx, dy;
  205. {
  206.     State  *ap;
  207.     int     i;
  208.     struct pixrect *temp;
  209.     int     size = side * side;
  210.  
  211.     if (DIM == 2) {            /* 2-d case */
  212.     temp = mem_create(side, side, 8);
  213.     ap = (State *) mpr_d(temp)->md_image;
  214.     fread(ap, sizeof(*ap), size, fp);
  215.     for (i = 0; i < size; i++)
  216.         ap[i] &= AMASK;        /* mask out unwanted bits */
  217.     if (side <= B)
  218.         pr_rop(ca_handle, dx, dy + 1, side, side, PIX_SRC, temp, 0, 0);
  219.     else
  220.         pr_rop(ca_handle, 0, 1, B, B, PIX_SRC, temp, dx, dy);
  221.     pr_destroy(temp);
  222.     } else {                /* 1-d case */
  223.     size = side;
  224.     temp = mem_create(side, 1, 8);
  225.     ap = (State *) mpr_d(temp)->md_image;
  226.     fread(ap, sizeof(*ap), size, fp);
  227.     for (i = 0; i < size; i++)
  228.         ap[i] &= AMASK;        /* mask out unwanted bits */
  229.     if (side <= B)
  230.         pr_rop(ca_handle, dx, B, side, 1, PIX_SRC, temp, 0, 0);
  231.     else
  232.         pr_rop(ca_handle, 0, B, B, 1, PIX_SRC, temp, dx, 0);
  233.     pr_destroy(temp);
  234.     }
  235. }
  236.  
  237.  
  238. save_resize_data(fp, side, dx, dy)    /* save to file of different size */
  239.     FILE   *fp;
  240.     int     side, dx, dy;
  241. {
  242.     State  *ap;
  243.     struct pixrect *temp;
  244.     int     size = side * side;
  245.  
  246.     if (DIM == 2) {            /* 2-d case */
  247.     temp = mem_create(side, side, 8);
  248.     ap = (State *) mpr_d(temp)->md_image;
  249.     if (side <= B)
  250.         pr_rop(temp, 0, 0, side, side, PIX_SRC, ca_handle, dx, dy + 1);
  251.     else
  252.         pr_rop(temp, dx, dy, B, B, PIX_SRC, ca_handle, 0, 1);
  253.     } else {                /* 1-d case */
  254.     size = side;
  255.     temp = mem_create(side, 1, 8);
  256.     ap = (State *) mpr_d(temp)->md_image;
  257.     if (side <= B)
  258.         pr_rop(temp, 0, 0, side, 1, PIX_SRC, ca_handle, dx, B);
  259.     else
  260.         pr_rop(temp, dx, 0, B, 1, PIX_SRC, ca_handle, 0, B);
  261.     }
  262.     fwrite(ap, sizeof(*ap), size, fp);
  263.     pr_destroy(temp);
  264. }
  265.  
  266.  
  267. /***** buffer functions *****/
  268.  
  269. copy_to_buffer(n)
  270.     int     n;
  271. {
  272.     if (buffer[n] == NULL) {
  273.     buffer[n] = mem_create(B, B + 2, 8);
  274.     bufptr[n] = (State *) (mpr_d(buffer[n])->md_image);
  275.     }
  276.     pr_rop(buffer[n], 0, 0, B, B + 2, PIX_SRC, ca_handle, 0, 0);
  277. }
  278.  
  279.  
  280. swap_to_buffer(n)
  281.     int     n;
  282. {
  283.     if (buffer[n] == NULL) {
  284.     show_msg("Buffer empty");
  285.     return;
  286.     }
  287.     pr_swap(ca, ca_handle, bufptr[n], buffer[n]);
  288.     if (n == 0) {
  289.     ia_handle = buffer[0];
  290.     ia = bufptr[0];
  291.     }
  292. }
  293.  
  294.  
  295. load_from_buffer(n)            /* load from the given buffer */
  296.     int     n;
  297. {
  298.     use_buffer(n, PIX_SRC);
  299. }
  300.  
  301.  
  302. xor_with_buffer(n)
  303.     int     n;
  304. {
  305.     use_buffer(n, PIX_SRC ^ PIX_DST);
  306. }
  307.  
  308.  
  309. or_with_buffer(n)
  310.     int     n;
  311. {
  312.     use_buffer(n, PIX_SRC | PIX_DST);
  313. }
  314.  
  315.  
  316. and_with_buffer(n)
  317.     int     n;
  318. {
  319.     use_buffer(n, PIX_SRC & PIX_DST);
  320. }
  321.  
  322.  
  323. use_buffer(n, op)            /* generalized buffer load */
  324.     int     n, op;
  325. {
  326.     if (buffer[n] == NULL) {
  327.     clear_msg();
  328.     show_msg("Buffer empty");
  329.     return;
  330.     }
  331.     pr_rop(ca_handle, 0, 0, B, B + 2, op | PIX_DONTCLIP, buffer[n], 0, 0);
  332. }
  333.  
  334.  
  335. /***** data shift routines *****/
  336.  
  337. hshift_data(dx)                /* horizontal shift */
  338.     int     dx;
  339. {
  340.     dx %= B;
  341.     if (dx == 0)
  342.     return;
  343.     if (dx < 0)
  344.     dx = B + dx;
  345.     pr_rop(sh_handle, 0, 0, dx, B + 2, PIX_SRC | PIX_DONTCLIP, ca_handle, B - dx, 0);
  346.     pr_rop(sh_handle, dx, 0, B - dx, B + 2, PIX_SRC | PIX_DONTCLIP, ca_handle, 0, 0);
  347.     pr_swap(ca, ca_handle, sh, sh_handle);
  348. }
  349.  
  350.  
  351. vshift_data(dy)                /* vertical shift */
  352.     int     dy;
  353. {
  354.     dy %= B;
  355.     if (dy == 0)
  356.     return;
  357.     if (dy < 0)
  358.     dy = B + dy;
  359.     pr_rop(sh_handle, 0, 1, B, dy, PIX_SRC | PIX_DONTCLIP, ca_handle, 0, 1 + B - dy);
  360.     pr_rop(sh_handle, 0, 1 + dy, B, B - dy, PIX_SRC | PIX_DONTCLIP, ca_handle, 0, 1);
  361.     pr_swap(ca, ca_handle, sh, sh_handle);
  362. }
  363.  
  364. /***** plane routines *****/
  365.  
  366. clear_planes(mask)
  367.     int     mask;
  368. {
  369.     mask &= AMASK;
  370.     pr_rop(ca_handle, 0, 0, B, B + 2, (PIX_DST & PIX_NOT(PIX_SRC)) | PIX_COLOR(mask),
  371.        NULL, 0, 0);
  372. }
  373.  
  374.  
  375. invert_planes(mask)
  376.     int     mask;
  377. {
  378.     mask &= AMASK;
  379.     pr_rop(ca_handle, 0, 0, B, B + 2, (PIX_SRC ^ PIX_DST) | PIX_COLOR(mask),
  380.        NULL, 0, 0);
  381. }
  382.