123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194 |
- #include <math.h>
- #include <stdlib.h>
- #include "ParticleEngine.h"
- CParticleEngine::CParticleEngine( ITileRenderer *renderer ) {
- m_cp = 0;
- for (int f=0; f<MAX_PARTICLES; f++) m_particles[f].lifeTime = 0; // dead
- m_renderer = renderer;
- };
- CParticleEngine::~CParticleEngine() {
- };
- void CParticleEngine::createSprayType( SParticleSprayType *target,
- int firstBlock,
- int blockCount,
- int gravity,
- int fraction,
- int lifeTime,
- int lifeTimeRandom,
- int size,
- int sizeRandom,
- int sizeInc,
- int sizeIncRandom,
- PARTICLERENDERFUNCTION_TYPE renderFunction,
- void *dataToRenderFunction,
- int angle,
- int angleRandom,
- int angleInc,
- int angleIncRandom,
- int type) {
- target->renderType = type;
- target->gravity = gravity;
- target->firstBlock = firstBlock;
- target->blockCount = blockCount;
- target->fraction = fraction;
- target->lifeTime = lifeTime;
- target->lifeTimeRandom = lifeTimeRandom;
- target->size = size;
- target->sizeRandom = sizeRandom;
- target->sizeInc = sizeInc;
- target->sizeIncRandom = sizeIncRandom;
- target->angle = angle;
- target->angleRandom = angleRandom;
- target->angleInc = angleInc;
- target->angleIncRandom = angleIncRandom;
-
- if (renderFunction) {
- target->renderFunction = renderFunction;
- target->dataToRenderFunction = dataToRenderFunction;
- } else {
- target->renderFunction = 0;
- target->renderFunction = 0;
- };
- };
- void CParticleEngine::spray( int count,
- int x, int y, int posrandom,
- int dx, int dy, int dirrandom,
- unsigned int userData,
- SParticleSprayType *spray ) {
- int l;
- int nx,ny;
- while (count) {
- SParticle *p = m_particles+m_cp;;
- m_cp++;
- if (m_cp>=MAX_PARTICLES) m_cp = 0;
- p->spray = spray;
- nx = (rand()&511) - 256;
- ny = (rand()&511) - 256;
-
- l = (int)(sqrtf( (float)(nx*nx+ ny*ny )));
- if (l==0) l = 1;
- // random vactor
- int v = (rand()&255);
- nx = nx*v / l;
- ny = ny*v / l;
- p->userData = userData;
-
- p->x = ((nx * posrandom)>>8) + x;
- p->y = ((ny * posrandom)>>8) + y;
- p->dx = ((nx * dirrandom)>>8) + dx;
- p->dy = ((ny * dirrandom)>>8) + dy;
-
- p->lifeTime = spray->lifeTime + (((rand()&255)*spray->lifeTimeRandom)>>8);
- p->tileIndex = spray->firstBlock + ((((rand()&511) * spray->blockCount)+256)>>9);
- p->size = spray->size + (((rand()&255)*spray->sizeRandom)>>8);
- p->sizeinc = spray->sizeInc + ((((rand()&511)-256)*spray->sizeIncRandom)>>8);
-
- p->angle = spray->angle + (((rand()&255)*spray->angleRandom)>>8);
- p->angleinc = spray->angleInc + ((((rand()&511)-256)*spray->angleIncRandom)>>8);
- count--;
- }
- };
- void CParticleEngine::run( int fixedFrameTime16Bit ) {
- SParticle *p = m_particles;
- SParticle *p_target = p + MAX_PARTICLES;
- int tx,ty, tsize;
- while (p!=p_target) {
- if (p->lifeTime>0) {
- p->lifeTime -= fixedFrameTime16Bit;
- if (p->lifeTime>0) {
- // gravitaatio, slowdown, jne..t‰nne.
- if (p->spray) {
- tx = ((((p->dx * p->spray->fraction)>>16) * fixedFrameTime16Bit)>>16);
- ty = ((((p->dy * p->spray->fraction)>>16) * fixedFrameTime16Bit)>>16);
- p->dx -= tx;
- p->dy -= ty;
- p->dy += ((p->spray->gravity*fixedFrameTime16Bit)>>16);
- };
- tx = ((p->dx * fixedFrameTime16Bit)>>16);
- ty = ((p->dy * fixedFrameTime16Bit)>>16);
- tsize = ((p->sizeinc * fixedFrameTime16Bit)>>16);
- p->x += tx;
- p->y += ty;
- p->size += tsize;
- p->angle += ((p->angleinc * fixedFrameTime16Bit)>>16);
- if (p->size<=0) p->lifeTime = 0; // die if zero sized
-
- };
- }
- p++;
- };
- };
- void CParticleEngine::draw() {
- // draw from latest, to least latest
- SParticle *p = m_particles;
-
- int count = m_cp -1;
-
- int a;
-
- while (1) {
- if (count<0) count = MAX_PARTICLES-1;
- if (count==m_cp) break;
- p = m_particles + count;
- if (p->lifeTime>0) {
- if (p->spray->renderFunction) {
- (p->spray->renderFunction)( p->spray->dataToRenderFunction, p );
- } else {
- a = (p->lifeTime>>6);
- if (a>255) a = 255;
- a = 255-a;
-
- m_renderer->renderTile( p->x - p->size/2, p->y - p->size/2,
- p->size, p->size,
- p->angle,p->spray->renderType,
- p->tileIndex | (a<<24),
- p->userData);
- }
- }
- count--;
- };
- };
|