home *** CD-ROM | disk | FTP | other *** search
/ Dream 52 / Amiga_Dream_52.iso / Linux / Divers / bomb.tar.gz / bomb.tar / bomb / wave.c < prev    next >
C/C++ Source or Header  |  1997-04-25  |  5KB  |  206 lines

  1. /*
  2.     bomb - automatic interactive visual stimulation
  3.     Copyright (C) 1994  Scott Draves <spot@cs.cmu.edu>
  4.  
  5.     This program is free software; you can redistribute it and/or modify
  6.     it under the terms of the GNU General Public License as published by
  7.     the Free Software Foundation; either version 2 of the License, or
  8.     (at your option) any later version.
  9.  
  10.     This program is distributed in the hope that it will be useful,
  11.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.     GNU General Public License for more details.
  14.  
  15.     You should have received a copy of the GNU General Public License
  16.     along with this program; if not, write to the Free Software
  17.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18. */
  19.  
  20. /* by nix@cs.cmu.edu
  21.  
  22.  wave simulations
  23.  
  24. cell attributes: 
  25.  value
  26.  velocity
  27.  stiffness is needed to do lenses
  28. parameters: 
  29.  global stiffness - fixed for now
  30.  damping - use "speed"
  31.  
  32.  */
  33.  
  34. #include "defs.h"
  35.  
  36. #define SPOTS 16
  37.  
  38. typedef struct {
  39.     float x,y;
  40.     float cx,cy;    /* center */
  41.     float a;        /* current angle from center */
  42.     float r;        /* radius */
  43.     float speed;    /* radians/sec */
  44.     int steps;        /* how many steps (of the given speed) each
  45.                frame - move the spot faster without strobing */
  46.     int value;
  47. } Spot;
  48.  
  49. static Spot spots[SPOTS];
  50.  
  51. void step_rule_wave(int frame, rule_t *p, image8_t *fb)
  52. {
  53.    int x,y,bx,by,i,j;
  54.    board_t *sboard, *dboard;
  55.    board_t *svboard, *dvboard;
  56.    u_char *lp0, *lp1;
  57.    int stiffness = 64;
  58.  
  59.    sboard = &board[dbuf];
  60.    dboard = &board[1-dbuf];
  61.    svboard = &board2[dbuf];
  62.    dvboard = &board2[1-dbuf];
  63.    dbuf = 1-dbuf;
  64.  
  65.    /* torus */
  66.    for (y=0;y<=SMALL_YSIZE+1;y++) {
  67.       (*sboard)[0][y] = (*sboard)[SMALL_XSIZE][y];
  68.       (*sboard)[SMALL_XSIZE+1][y] = (*sboard)[1][y];
  69.       (*sboard)[0][y] = (*sboard)[SMALL_XSIZE][y];
  70.       (*sboard)[SMALL_XSIZE+1][y] = (*sboard)[1][y];
  71.       (*svboard)[0][y] = (*svboard)[SMALL_XSIZE][y];
  72.       (*svboard)[SMALL_XSIZE+1][y] = (*svboard)[1][y];
  73.       (*svboard)[0][y] = (*svboard)[SMALL_XSIZE][y];
  74.       (*svboard)[SMALL_XSIZE+1][y] = (*svboard)[1][y];
  75.    }
  76.    for (x=0;x<=SMALL_XSIZE+1;x++) {
  77.       (*sboard)[x][0] = (*sboard)[x][SMALL_YSIZE];
  78.       (*sboard)[x][SMALL_YSIZE+1] = (*sboard)[x][1];
  79.       (*sboard)[x][0] = (*sboard)[x][SMALL_YSIZE];
  80.       (*sboard)[x][SMALL_YSIZE+1] = (*sboard)[x][1];
  81.       (*svboard)[x][0] = (*svboard)[x][SMALL_YSIZE];
  82.       (*svboard)[x][SMALL_YSIZE+1] = (*svboard)[x][1];
  83.       (*svboard)[x][0] = (*svboard)[x][SMALL_YSIZE];
  84.       (*svboard)[x][SMALL_YSIZE+1] = (*svboard)[x][1];
  85.    }
  86.  
  87.    for(y=1;y<=SMALL_YSIZE;y++) {
  88.       lp0 = fb->p + (fb->stride * (y - 1));
  89.       lp1 = lp0 + fb->stride * SMALL_YSIZE;
  90.       for(x=1;x<=SMALL_XSIZE;x++) {
  91.      int dt, t;
  92.      /* target is average of nearest neighbors */
  93.      dt = ((((*sboard)[x  ][y-1]) +
  94.             ((*sboard)[x-1][y  ]) +
  95.             ((*sboard)[x  ][y+1]) +
  96.             ((*sboard)[x+1][y  ])) >> 2)
  97.          - (*sboard)[x][y];
  98.  
  99.      t = (*svboard)[x][y] + ((stiffness * dt) >> 8);
  100.      t += (p->speed * t) >> 8;
  101.      if (t > p->mask)
  102.         t = p->mask;
  103.      else if (t < -p->mask)
  104.         t = -p->mask;
  105.  
  106.      (*dvboard)[x][y] = t;
  107.  
  108.      t = (*sboard)[x][y] + (*dvboard)[x][y];
  109.      (*dboard)[x][y] = t + ((p->speed * t) >> 8);
  110.  
  111.      t += (p->mask >> 2);
  112.  
  113. /*
  114.      if (t<0) t = 0;
  115.      if (t > 255) t = 255;
  116.  */
  117.      /* 
  118.      t &= p->mask;
  119.      if (p->remap)
  120.         t = remap[t];
  121.           */
  122.      t = remap[t & p->mask];
  123.  
  124.      lp0[SMALL_XSIZE] = t;
  125.      *lp0++ = t;
  126.      lp1[SMALL_XSIZE] = t;
  127.      *lp1++ = t;
  128.       }
  129.    }
  130.  
  131.    for (i=0; i<SPOTS; i++) {
  132.       Spot *s = spots + i;
  133.       for (j = 0; j < s->steps; j++) {
  134.      s->a += s->speed;
  135.      s->x = s->r * cos(s->a) + s->cx;
  136.      s->y = s->r * sin(s->a) + s->cy;
  137.  
  138. #if 0
  139.      if (s->x > 0 && s->x < SMALL_XSIZE
  140.          && s->y > 0 && s->y < SMALL_YSIZE) {
  141.         int *pressure = &(*dboard)[(int)s->x][(int)s->y];
  142.         *pressure = p->mask;
  143.      }
  144. #else
  145.          {
  146.          int tx = ((int)s->x) % SMALL_XSIZE;
  147.          int ty = ((int)s->y) % SMALL_YSIZE;
  148.          if (tx < 0) tx += SMALL_XSIZE;
  149.          if (ty < 0) tx += SMALL_YSIZE;
  150.          (*dboard)[tx][ty] = p->mask;
  151.      }
  152. #endif
  153.       }
  154.       if (0 == R%20) {
  155.      float ncx, ncy;
  156.      /*
  157.         printf("spot %d: x:%f y:%f cx:%f cy:%f r:%f a:%f da:%f\n",
  158.         i, s->x, s->y, s->cx, s->cy, s->r, s->a, s->speed);
  159.         */
  160.      /* pick a new center */
  161.      /* make it be colinear with cx,cy - x,y for G2 continuity */
  162.      /* this keeps the same radius */
  163.      ncx = s->x - s->cx + s->x;
  164.      ncy = s->y - s->cy + s->y;
  165. #if 0
  166.      if (ncx > s->r/3 && ncx < (SMALL_XSIZE - s->r/3)
  167.          && ncy > s->r/3 && ncy < (SMALL_YSIZE-s->r/3)) {
  168. #endif
  169.         s->cx = ncx;
  170.         s->cy = ncy;
  171.         s->r = sqrt((s->x - s->cx)*(s->x - s->cx) +
  172.             (s->y - s->cy)*(s->y - s->cy));
  173.  
  174.         s->a = atan2(s->y - s->cy, s->x - s->cx);
  175.         /* could make speed = c/radius to get constant velocity */
  176.         s->speed = -s->speed;
  177. #if 0
  178.      }
  179. #endif
  180.  
  181.      /*
  182.         printf("spot %d: x:%f y:%f cx:%f cy:%f r:%f a:%f da:%f\n",
  183.         i, s->x, s->y, s->cx, s->cy, s->r, s->a, s->speed);
  184.         */
  185.       }
  186.  
  187.    }
  188. }
  189.  
  190. void init_wave()
  191. {
  192.    int i;
  193.    for(i=0;i<SPOTS;i++) {
  194.       Spot *s = spots + i;
  195.       s->x = R%SMALL_XSIZE;
  196.       s->y = R%SMALL_YSIZE;
  197.       s->cx = R%60 - 30 + s->x;
  198.       s->cy = R%60 - 30 + s->y;
  199.       s->r = sqrt((s->x - s->cx)*(s->x - s->cx) +
  200.           (s->y - s->cy)*(s->y - s->cy));
  201.       s->a = atan2(s->y - s->cy, s->x - s->cx);
  202.       s->speed = 0.0125;
  203.       s->steps = 8;
  204.    }
  205. }
  206.