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 >
Wrap
C/C++ Source or Header
|
1997-04-25
|
5KB
|
206 lines
/*
bomb - automatic interactive visual stimulation
Copyright (C) 1994 Scott Draves <spot@cs.cmu.edu>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* by nix@cs.cmu.edu
wave simulations
cell attributes:
value
velocity
stiffness is needed to do lenses
parameters:
global stiffness - fixed for now
damping - use "speed"
*/
#include "defs.h"
#define SPOTS 16
typedef struct {
float x,y;
float cx,cy; /* center */
float a; /* current angle from center */
float r; /* radius */
float speed; /* radians/sec */
int steps; /* how many steps (of the given speed) each
frame - move the spot faster without strobing */
int value;
} Spot;
static Spot spots[SPOTS];
void step_rule_wave(int frame, rule_t *p, image8_t *fb)
{
int x,y,bx,by,i,j;
board_t *sboard, *dboard;
board_t *svboard, *dvboard;
u_char *lp0, *lp1;
int stiffness = 64;
sboard = &board[dbuf];
dboard = &board[1-dbuf];
svboard = &board2[dbuf];
dvboard = &board2[1-dbuf];
dbuf = 1-dbuf;
/* torus */
for (y=0;y<=SMALL_YSIZE+1;y++) {
(*sboard)[0][y] = (*sboard)[SMALL_XSIZE][y];
(*sboard)[SMALL_XSIZE+1][y] = (*sboard)[1][y];
(*sboard)[0][y] = (*sboard)[SMALL_XSIZE][y];
(*sboard)[SMALL_XSIZE+1][y] = (*sboard)[1][y];
(*svboard)[0][y] = (*svboard)[SMALL_XSIZE][y];
(*svboard)[SMALL_XSIZE+1][y] = (*svboard)[1][y];
(*svboard)[0][y] = (*svboard)[SMALL_XSIZE][y];
(*svboard)[SMALL_XSIZE+1][y] = (*svboard)[1][y];
}
for (x=0;x<=SMALL_XSIZE+1;x++) {
(*sboard)[x][0] = (*sboard)[x][SMALL_YSIZE];
(*sboard)[x][SMALL_YSIZE+1] = (*sboard)[x][1];
(*sboard)[x][0] = (*sboard)[x][SMALL_YSIZE];
(*sboard)[x][SMALL_YSIZE+1] = (*sboard)[x][1];
(*svboard)[x][0] = (*svboard)[x][SMALL_YSIZE];
(*svboard)[x][SMALL_YSIZE+1] = (*svboard)[x][1];
(*svboard)[x][0] = (*svboard)[x][SMALL_YSIZE];
(*svboard)[x][SMALL_YSIZE+1] = (*svboard)[x][1];
}
for(y=1;y<=SMALL_YSIZE;y++) {
lp0 = fb->p + (fb->stride * (y - 1));
lp1 = lp0 + fb->stride * SMALL_YSIZE;
for(x=1;x<=SMALL_XSIZE;x++) {
int dt, t;
/* target is average of nearest neighbors */
dt = ((((*sboard)[x ][y-1]) +
((*sboard)[x-1][y ]) +
((*sboard)[x ][y+1]) +
((*sboard)[x+1][y ])) >> 2)
- (*sboard)[x][y];
t = (*svboard)[x][y] + ((stiffness * dt) >> 8);
t += (p->speed * t) >> 8;
if (t > p->mask)
t = p->mask;
else if (t < -p->mask)
t = -p->mask;
(*dvboard)[x][y] = t;
t = (*sboard)[x][y] + (*dvboard)[x][y];
(*dboard)[x][y] = t + ((p->speed * t) >> 8);
t += (p->mask >> 2);
/*
if (t<0) t = 0;
if (t > 255) t = 255;
*/
/*
t &= p->mask;
if (p->remap)
t = remap[t];
*/
t = remap[t & p->mask];
lp0[SMALL_XSIZE] = t;
*lp0++ = t;
lp1[SMALL_XSIZE] = t;
*lp1++ = t;
}
}
for (i=0; i<SPOTS; i++) {
Spot *s = spots + i;
for (j = 0; j < s->steps; j++) {
s->a += s->speed;
s->x = s->r * cos(s->a) + s->cx;
s->y = s->r * sin(s->a) + s->cy;
#if 0
if (s->x > 0 && s->x < SMALL_XSIZE
&& s->y > 0 && s->y < SMALL_YSIZE) {
int *pressure = &(*dboard)[(int)s->x][(int)s->y];
*pressure = p->mask;
}
#else
{
int tx = ((int)s->x) % SMALL_XSIZE;
int ty = ((int)s->y) % SMALL_YSIZE;
if (tx < 0) tx += SMALL_XSIZE;
if (ty < 0) tx += SMALL_YSIZE;
(*dboard)[tx][ty] = p->mask;
}
#endif
}
if (0 == R%20) {
float ncx, ncy;
/*
printf("spot %d: x:%f y:%f cx:%f cy:%f r:%f a:%f da:%f\n",
i, s->x, s->y, s->cx, s->cy, s->r, s->a, s->speed);
*/
/* pick a new center */
/* make it be colinear with cx,cy - x,y for G2 continuity */
/* this keeps the same radius */
ncx = s->x - s->cx + s->x;
ncy = s->y - s->cy + s->y;
#if 0
if (ncx > s->r/3 && ncx < (SMALL_XSIZE - s->r/3)
&& ncy > s->r/3 && ncy < (SMALL_YSIZE-s->r/3)) {
#endif
s->cx = ncx;
s->cy = ncy;
s->r = sqrt((s->x - s->cx)*(s->x - s->cx) +
(s->y - s->cy)*(s->y - s->cy));
s->a = atan2(s->y - s->cy, s->x - s->cx);
/* could make speed = c/radius to get constant velocity */
s->speed = -s->speed;
#if 0
}
#endif
/*
printf("spot %d: x:%f y:%f cx:%f cy:%f r:%f a:%f da:%f\n",
i, s->x, s->y, s->cx, s->cy, s->r, s->a, s->speed);
*/
}
}
}
void init_wave()
{
int i;
for(i=0;i<SPOTS;i++) {
Spot *s = spots + i;
s->x = R%SMALL_XSIZE;
s->y = R%SMALL_YSIZE;
s->cx = R%60 - 30 + s->x;
s->cy = R%60 - 30 + s->y;
s->r = sqrt((s->x - s->cx)*(s->x - s->cx) +
(s->y - s->cy)*(s->y - s->cy));
s->a = atan2(s->y - s->cy, s->x - s->cx);
s->speed = 0.0125;
s->steps = 8;
}
}