home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d5xx / d502 / cells.lha / CELLS / CELLSSource.lzh / cGrid.c < prev    next >
C/C++ Source or Header  |  1991-04-20  |  7KB  |  315 lines

  1. /*
  2.  *  CELLS       An Implementation of the WireWorld cellular automata
  3.  *              as described in Scientific American, Jan 1990.
  4.  *
  5.  *              Copyright 1990 by Davide P. Cervone.
  6.  *  You may use this code, provided this copyright notice is kept intact.
  7.  *  See the CELLS.HELP file for complete information on distribution conditions.
  8.  */
  9.  
  10. /*
  11.  *  File:  cGrid.c              Handles grid updates and copies.
  12.  */
  13.  
  14.  
  15. #include "Cells.h"
  16.  
  17.  
  18. #define BLT_COPY    0xC0
  19.  
  20.  
  21. short CellSize;                             /* screen cell size in pixels */
  22. short GridX,GridY;                          /* position of visable area */
  23. short GridW = MAXGRIDW, GridH = MAXGRIDH;   /* size of visable area */
  24. short BoardX,BoardY, BoardW,BoardH;         /* size in pixels */
  25.  
  26.  
  27. /*
  28.  *  SetBoardSize()
  29.  *
  30.  *  Set the new cell size, and calculate the new grid and screen
  31.  *  positions of the active area.  Make sure we don't fall off the edge
  32.  *  of the grid.
  33.  */
  34.  
  35. void SetBoardSize(Size)
  36. int Size;
  37. {
  38.    short CenterX = GridX + GridW / 2,
  39.          CenterY = GridY + GridH / 2;
  40.  
  41.    CellSize = Size;
  42.  
  43.    GridW  = (BOARDW-1) / CellSize;
  44.    GridH  = (BOARDH-1) / CellSize;
  45.    BoardX = (BOARDW - CellSize * GridW) / 2;
  46.    BoardY = (BOARDH - CellSize * GridH) / 2;
  47.    BoardW = BoardX + GridW * CellSize - 1;
  48.    BoardH = BoardY + GridH * CellSize - 1;
  49.  
  50.    GridX = CenterX - GridW / 2;
  51.    GridY = CenterY - GridH / 2;
  52.    if (GridX < 0) GridX = 0;
  53.    if (GridY < 0) GridY = 0;
  54.    if (GridX + GridW > MAXGRIDW) GridX = MAXGRIDW - GridW;
  55.    if (GridY + GridH > MAXGRIDH) GridY = MAXGRIDH - GridH;
  56. }
  57.  
  58.  
  59. /*
  60.  *  UpdateScreen()
  61.  *
  62.  *  In double buffer mode, copy the off-screen bitmap to the screen.
  63.  */
  64.  
  65. void UpdateScreen()
  66. {
  67.    if (DBufMode)
  68.       BltBitMapRastPort(rp->BitMap,0,0,wrp,0,0,BOARDW,BOARDH,BLT_COPY);
  69. }
  70.  
  71.  
  72. /*
  73.  *  UpdateBuffer()
  74.  *
  75.  *  Copy the contents of the screen area into the double buffer area
  76.  */
  77.  
  78. void UpdateBuffer()
  79. {
  80.    BltBitMapRastPort(wrp->BitMap,WINDOWX,WINDOWY,rp,0,0,BOARDW,BOARDH,BLT_COPY);
  81. }
  82.  
  83.  
  84. /*
  85.  *  SetCell
  86.  *
  87.  *  If the cell position is within the grid bounds, set the grid array
  88.  *  element to the given state.
  89.  */
  90.  
  91. void SetCell(Array,X,Y,Pen)
  92. UBYTE Array[];
  93. short X,Y;
  94. int Pen;
  95. {
  96.    if (X >= 0 && X < MAXGRIDW && Y >= 0 && Y < MAXGRIDH)
  97.       Array[X+MAXGRIDW*Y] = Pen;
  98. }
  99.  
  100.  
  101. /*
  102.  *  CellColor()
  103.  *
  104.  *  If the position is within the grid bounds, return the state of
  105.  *  that cell, otherwise return BLANK.
  106.  */
  107.  
  108. int CellColor(Array,X,Y)
  109. UBYTE Array[];
  110. short X,Y;
  111. {
  112.    int Pen = BLANK;
  113.  
  114.    if (X >= 0 && X < MAXGRIDW && Y >= 0 && Y < MAXGRIDH)
  115.       Pen = Array[X+MAXGRIDW*Y];
  116.    return(Pen);
  117. }
  118.  
  119.  
  120. /*
  121.  *  ClearGrid()
  122.  *
  123.  *  Set all the cells in the given array to BLANK
  124.  */
  125.  
  126. void ClearGrid(Grid)
  127. UBYTE Grid[];
  128. {
  129.    register short i;
  130.    
  131.    for (i=0; i<ARRAYSIZE; i++) Grid[i] = BLANK;
  132. }
  133.  
  134.  
  135. /*
  136.  *  ZeroArray()
  137.  *
  138.  *  Set all the cells in the given array to zero
  139.  */
  140.  
  141. void ZeroGrid(Grid)
  142. UBYTE Grid[];
  143. {
  144.    register short i;
  145.    
  146.    for (i=0; i<ARRAYSIZE; i++) Grid[i] = 0;
  147. }
  148.  
  149.  
  150. /*
  151.  *  WipeGrid()
  152.  *
  153.  *  For every cell in the give array:
  154.  *    if the cell state is an electron state
  155.  *      if we are updating the screen, change the screen cell color
  156.  *      set the cell to the wire state
  157.  *  If we are updateing the screen, do so
  158.  */
  159.  
  160. void WipeGrid(Grid,ShowIt)
  161. UBYTE Grid[];
  162. int ShowIt;
  163. {
  164.    register short X,Y;
  165.    register UBYTE Pen;
  166.    
  167.    for (Y=0; Y<MAXGRIDH; Y++)
  168.    {
  169.       for (X=0; X<MAXGRIDW; X++)
  170.       {
  171.          Pen = CellColor(Grid,X,Y);
  172.          if (Pen == HEAD || Pen == TAIL)
  173.          {
  174.             if (ShowIt) ColorScreenCell(X-GridX,Y-GridY,WIRE);
  175.             SetCell(Grid,X,Y,WIRE);
  176.          }
  177.       }
  178.    }
  179.    if (ShowIt) UpdateScreen();
  180. }
  181.  
  182.  
  183. /*
  184.  *  CopyGrid()
  185.  *
  186.  *  Copy the contents of one grid array into another grid array
  187.  */
  188.  
  189. void CopyGrid(OldGrid,NewGrid)
  190. UBYTE *OldGrid,*NewGrid;
  191. {
  192.    register short i;
  193.    
  194.    for (i=0; i<ARRAYSIZE; i++) *NewGrid++ = *OldGrid++;
  195. }
  196.  
  197.  
  198. /*
  199.  *  ReplaceGrid()
  200.  *
  201.  *  Replace the destination grid cells by the source cells that are non-zero
  202.  *  (i.e., where they are defined).
  203.  */
  204.  
  205. void ReplaceGrid(SrcGrid,DstGrid)
  206. UBYTE *SrcGrid,*DstGrid;
  207. {
  208.    register short i;
  209.  
  210.    for (i=0; i<ARRAYSIZE; i++)
  211.    {
  212.       if (*SrcGrid) *DstGrid = *SrcGrid;
  213.       SrcGrid++; DstGrid++;
  214.    }
  215. }
  216.  
  217.  
  218. /*
  219.  *  RemoveGrid()
  220.  *
  221.  *  Clear the destination cells anywhere there is a non-zero cell in the
  222.  *  source grid
  223.  */
  224.  
  225. void RemoveGrid(SrcGrid,DstGrid)
  226. UBYTE *SrcGrid,*DstGrid;
  227. {
  228.    register short i;
  229.  
  230.    for (i=0; i<ARRAYSIZE; i++)
  231.    {
  232.       if (*SrcGrid) *DstGrid = BLANK;
  233.       SrcGrid++; DstGrid++;
  234.    }
  235. }
  236.  
  237.  
  238. /*
  239.  *  UpdateGrid()
  240.  *
  241.  *  Look through the active portion of the grid and for any new cells that
  242.  *  have changed their state, color the new cell on the screen, and update
  243.  *  the grid cells value.
  244.  */
  245.  
  246. void UpdateGrid(Grid,NewGrid)
  247. UBYTE Grid[],NewGrid[];
  248. {
  249.    register UBYTE Pen;
  250.    register short i;
  251.    register short X,Y;
  252.    
  253.    for (Y=0; Y<=MAXGRIDH; Y++)
  254.    {
  255.       for (X=0,i=X+MAXGRIDW*Y; X<=MAXGRIDW; X++,i++)
  256.       {
  257.          Pen = NewGrid[i];
  258.          if (Pen != Grid[i])
  259.          {
  260.             ColorScreenCell(X-GridX,Y-GridY,Pen);
  261.             Grid[i] = Pen;
  262.          }
  263.       }
  264.    }
  265.    UpdateScreen();
  266. }
  267.  
  268.  
  269. /*
  270.  *  GetBounds()
  271.  *
  272.  *  Initialize the bounds to outside the array, then
  273.  *  for each column in the grid
  274.  *    look through the column for a non-blank cell, if any
  275.  *  If some column was non-blank,
  276.  *    look through the columns (staring at the other side of the grid)
  277.  *      for the first column containing a non-blank cell
  278.  *    Starting at the top of the grid,
  279.  *      search each row (within the active columns) for the first non-blank row.
  280.  *    Do the same starting from the bottom of the grid.
  281.  *    calculate the width and height of the active grid area.
  282.  */
  283.  
  284. void GetBounds(Grid,x,y,w,h,blank)
  285. UBYTE Grid[];
  286. short *x,*y,*w,*h;
  287. UBYTE blank;
  288. {
  289.    register short X,Y;
  290.    register short i;
  291.    
  292.    *x = MAXGRIDW; *y = MAXGRIDH; *w = *h = 0;
  293.    for (X=0; X<MAXGRIDW; X++)
  294.       for (Y=0,i=X; Y<MAXGRIDH; Y++,i+=MAXGRIDW)
  295.          if (Grid[i] != blank) {*x = X; X = MAXGRIDW; Y = MAXGRIDH;}
  296.  
  297.    if (*x < MAXGRIDW)
  298.    {
  299.       for (X=MAXGRIDW-1; X>=*x; X--)
  300.          for (Y=0,i=X; Y<MAXGRIDH; Y++,i+=MAXGRIDW)
  301.             if (Grid[i] != blank) {*w = X; X = -1; Y = MAXGRIDH;}
  302.  
  303.       for (Y=0; Y<MAXGRIDH; Y++)
  304.          for (X=*x,i=X+MAXGRIDW*Y; X<=*w; X++,i++)
  305.             if (Grid[i] != blank) {*y = Y; X = MAXGRIDW; Y = MAXGRIDH;}
  306.  
  307.       for (Y=MAXGRIDH-1; Y>=*y; Y--)
  308.          for (X=*x,i=X+MAXGRIDW*Y; X<=*w; X++,i++)
  309.             if (Grid[i] != blank) {*h = Y; X = MAXGRIDW; Y = -1;}
  310.  
  311.       *w = *w - *x + 1;
  312.       *h = *h - *y + 1;
  313.    }
  314. }
  315.