/* squares.c - Square particle module - Don Yang (uguu.org) v0.95 (9/9/98) This routine has bugs! Morphing to and from this system may be jerky sometimes, and might even produce erratic and corrupted particle systems. I don't know why it does that :P 09/05/98: InitSquares UninitSquares GetSquareParticle GetAllSquareParticles TranslateSquares 09/09/98: MorphSquares GetSquareParticle deleted */ /********************************* Header **********************************/ /* Includes */ #include #include #include"particle.h" #include"squares.h" /* Globals */ static int _far *SquareX; static int _far *SquareY; static int _far *SquareZ; static int lon, lat; /************************** GetAllSquareParticles ************************** Copy all particle coordinates. * * IN: (global) (SquareX[], SquareY[], SquareZ[]) = source. * (global) (lon, lat) = rotation. * (particle.c) NumberOfParticles = number of particles. * OUT: (particle.c) (ParticleX[], ParticleY[], ParticleZ[]) = target. */ void GetAllSquareParticles(void) { int e; e = (lat < 0) ? (lat + 360) : lat; Rotate(SquareX, SquareZ, ParticleX, ParticleZ, NumberOfParticles, lon); Rotate(SquareY, ParticleZ, ParticleY, ParticleZ, NumberOfParticles, e); /* (particle.c) */ } /* GetAllSquareParticles() */ /******************************* InitSquares ******************************* Initialize particles. Groups of 12 particles form squares, which are * distributed randomly in rectangular space. * * IN: (particles.c) NumberOfParticles = number of particles. * OUT: 0 = success. * (global) (SquareX[], SquareY[], SquareZ[]) = coordinates. * (global) (lon, lat) = rotations. * 1 = not enough memory. */ int InitSquares(void) { int i, x, y, z; /* Allocate memory */ SquareX = _fcalloc((size_t)NumberOfParticles, sizeof(int)); SquareY = _fcalloc((size_t)NumberOfParticles, sizeof(int)); SquareZ = _fcalloc((size_t)NumberOfParticles, sizeof(int)); if( SquareX == NULL || SquareY == NULL || SquareZ == NULL ) { _ffree(SquareX); _ffree(SquareY); _ffree(SquareZ); return 1; } /* Generate coordinates */ i = 0; while( (NumberOfParticles - i) >= 12 ) { x = Generate(rand(), SPACE_W); /* (particle.h) */ y = Generate(rand(), SPACE_H); z = Generate(rand(), SPACE_L); SquareZ[i] = SquareZ[i + 1] = SquareZ[i + 2] = SquareZ[i + 3] = SquareZ[i + 4] = SquareZ[i + 5] = SquareZ[i + 6] = SquareZ[i + 7] = SquareZ[i + 8] = SquareZ[i + 9] = SquareZ[i +10] = SquareZ[i +11] = z; SquareX[i+1] = SquareX[i+9] = x - (SPACE_W / SQUARE_RATIO2); SquareX[i+2] = SquareX[i+10] = x + (SPACE_W / SQUARE_RATIO2); SquareX[i] = SquareX[i+4] = SquareX[i+6] = SquareX[i+8] = x - (SPACE_W / SQUARE_RATIO1); SquareX[i+3] = SquareX[i+5] = SquareX[i+7] = SquareX[i+11] = x + (SPACE_W / SQUARE_RATIO1); SquareY[i+4] = SquareY[i+5] = y - (SPACE_H / SQUARE_RATIO2); SquareY[i+6] = SquareY[i+7] = y + (SPACE_H / SQUARE_RATIO2); SquareY[i] = SquareY[i+1] = SquareY[i+2] = SquareY[i+3] = y - (SPACE_H / SQUARE_RATIO1); SquareY[i+8] = SquareY[i+9] = SquareY[i+10] = SquareY[i+11] = y + (SPACE_H / SQUARE_RATIO1); i += 12; } while( i != NumberOfParticles ) { x = rand() % i; SquareX[i] = SquareX[x]; SquareY[i] = SquareY[x]; SquareZ[i] = SquareZ[x]; i++; } lon = lat = 0; return 0; } /* InitSquares() */ /******************************* MorphSquares ****************************** Blend particle systems. * * IN: frame = current morphing animation frame. * target = end animation frame. * (global) (SquareX[], SquareY[], SquareZ[]) = target. * (global) (lon, lat) = rotation. * (particle.c) NumberOfParticles = number of particles. * (particle.c) (ParticleX[], ParticleY[], ParticleZ[]) = source. * OUT: (particle.c) (ParticleX[], ParticleY[], ParticleZ[]) updated. */ void MorphSquares(int frame, int target) { int i, e, x, y, z; long cx, sx, cy, sy; e = (lat < 0) ? (lat + 360) : lat; cy = Cosine(lon); sy = Sine(lon); /* (particle.h) */ cx = Cosine(e); sx = Sine(e); for(i = 0; i < NumberOfParticles; i++) { /* Rotate in Y axis */ x = (int)(cy * SquareX[i] / SINE_SCALE - sy * SquareZ[i] / SINE_SCALE); z = (int)(cy * SquareZ[i] / SINE_SCALE + sy * SquareX[i] / SINE_SCALE); /* Rotate in X axis */ y = (int)(cx * SquareY[i] / SINE_SCALE - sx * z / SINE_SCALE); z = (int)(cx * z / SINE_SCALE + sx * SquareY[i] / SINE_SCALE); /* Morph */ ParticleX[i] = Morph(ParticleX[i], x, frame, target); /* (particle.h) */ ParticleY[i] = Morph(ParticleY[i], y, frame, target); ParticleZ[i] = Morph(ParticleZ[i], z, frame, target); } } /* MorphSquares() */ /***************************** TranslateSquares **************************** Move square particles. * * IN: (particle.c) NumberOfParticles = number of particles. * OUT: (global) (SquareX[], SquareY[], SquareZ[]) = square coordinates. * (global) (lon, lat) = square rotations. */ void TranslateSquares(void) { static int clat = 0, tlat = 0, frame = 0, target = 1, vc = 0; /* Change viewpoint */ lon = (lon == 0) ? 359 : (lon - 1); if( vc ) lat = Morph(clat, tlat, frame, target); /* (particle.h) */ /* Update motion */ frame++; if( frame == target ) { frame = 0; target = rand() % SQUARE_ERR; if( vc ) { vc = 0; target += SQUARE_IDLE; } else { lat = clat = tlat; tlat = Generate(rand(), SQUARE_MAX_LAT); /* (particle.h) */ vc = 1; target += SQUARE_TIME; } } } /* TranslateSquares() */ /****************************** UninitSquares ****************************** Uninitialize (reverses InitSquares). * * IN: (global) (SquareX[], SquareY[], SquareZ[]) = square coordinates. * OUT: None. */ void UninitSquares(void) { _ffree(SquareX); _ffree(SquareY); _ffree(SquareZ); } /* UninitSquares() */