ParticleEngine.cpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. #include <math.h>
  2. #include <stdlib.h>
  3. #include "ParticleEngine.h"
  4. CParticleEngine::CParticleEngine( ITileRenderer *renderer ) {
  5. m_cp = 0;
  6. for (int f=0; f<MAX_PARTICLES; f++) m_particles[f].lifeTime = 0; // dead
  7. m_renderer = renderer;
  8. };
  9. CParticleEngine::~CParticleEngine() {
  10. };
  11. void CParticleEngine::createSprayType( SParticleSprayType *target,
  12. int firstBlock,
  13. int blockCount,
  14. int gravity,
  15. int fraction,
  16. int lifeTime,
  17. int lifeTimeRandom,
  18. int size,
  19. int sizeRandom,
  20. int sizeInc,
  21. int sizeIncRandom,
  22. PARTICLERENDERFUNCTION_TYPE renderFunction,
  23. void *dataToRenderFunction,
  24. int angle,
  25. int angleRandom,
  26. int angleInc,
  27. int angleIncRandom,
  28. int type) {
  29. target->renderType = type;
  30. target->gravity = gravity;
  31. target->firstBlock = firstBlock;
  32. target->blockCount = blockCount;
  33. target->fraction = fraction;
  34. target->lifeTime = lifeTime;
  35. target->lifeTimeRandom = lifeTimeRandom;
  36. target->size = size;
  37. target->sizeRandom = sizeRandom;
  38. target->sizeInc = sizeInc;
  39. target->sizeIncRandom = sizeIncRandom;
  40. target->angle = angle;
  41. target->angleRandom = angleRandom;
  42. target->angleInc = angleInc;
  43. target->angleIncRandom = angleIncRandom;
  44. if (renderFunction) {
  45. target->renderFunction = renderFunction;
  46. target->dataToRenderFunction = dataToRenderFunction;
  47. } else {
  48. target->renderFunction = 0;
  49. target->renderFunction = 0;
  50. };
  51. };
  52. void CParticleEngine::spray( int count,
  53. int x, int y, int posrandom,
  54. int dx, int dy, int dirrandom,
  55. unsigned int userData,
  56. SParticleSprayType *spray ) {
  57. int l;
  58. int nx,ny;
  59. while (count) {
  60. SParticle *p = m_particles+m_cp;;
  61. m_cp++;
  62. if (m_cp>=MAX_PARTICLES) m_cp = 0;
  63. p->spray = spray;
  64. nx = (rand()&511) - 256;
  65. ny = (rand()&511) - 256;
  66. l = (int)(sqrtf( (float)(nx*nx+ ny*ny )));
  67. if (l==0) l = 1;
  68. // random vactor
  69. int v = (rand()&255);
  70. nx = nx*v / l;
  71. ny = ny*v / l;
  72. p->userData = userData;
  73. p->x = ((nx * posrandom)>>8) + x;
  74. p->y = ((ny * posrandom)>>8) + y;
  75. p->dx = ((nx * dirrandom)>>8) + dx;
  76. p->dy = ((ny * dirrandom)>>8) + dy;
  77. p->lifeTime = spray->lifeTime + (((rand()&255)*spray->lifeTimeRandom)>>8);
  78. p->tileIndex = spray->firstBlock + ((((rand()&511) * spray->blockCount)+256)>>9);
  79. p->size = spray->size + (((rand()&255)*spray->sizeRandom)>>8);
  80. p->sizeinc = spray->sizeInc + ((((rand()&511)-256)*spray->sizeIncRandom)>>8);
  81. p->angle = spray->angle + (((rand()&255)*spray->angleRandom)>>8);
  82. p->angleinc = spray->angleInc + ((((rand()&511)-256)*spray->angleIncRandom)>>8);
  83. count--;
  84. }
  85. };
  86. void CParticleEngine::run( int fixedFrameTime16Bit ) {
  87. SParticle *p = m_particles;
  88. SParticle *p_target = p + MAX_PARTICLES;
  89. int tx,ty, tsize;
  90. while (p!=p_target) {
  91. if (p->lifeTime>0) {
  92. p->lifeTime -= fixedFrameTime16Bit;
  93. if (p->lifeTime>0) {
  94. // gravitaatio, slowdown, jne..t‰nne.
  95. if (p->spray) {
  96. tx = ((((p->dx * p->spray->fraction)>>16) * fixedFrameTime16Bit)>>16);
  97. ty = ((((p->dy * p->spray->fraction)>>16) * fixedFrameTime16Bit)>>16);
  98. p->dx -= tx;
  99. p->dy -= ty;
  100. p->dy += ((p->spray->gravity*fixedFrameTime16Bit)>>16);
  101. };
  102. tx = ((p->dx * fixedFrameTime16Bit)>>16);
  103. ty = ((p->dy * fixedFrameTime16Bit)>>16);
  104. tsize = ((p->sizeinc * fixedFrameTime16Bit)>>16);
  105. p->x += tx;
  106. p->y += ty;
  107. p->size += tsize;
  108. p->angle += ((p->angleinc * fixedFrameTime16Bit)>>16);
  109. if (p->size<=0) p->lifeTime = 0; // die if zero sized
  110. };
  111. }
  112. p++;
  113. };
  114. };
  115. void CParticleEngine::draw() {
  116. // draw from latest, to least latest
  117. SParticle *p = m_particles;
  118. int count = m_cp -1;
  119. int a;
  120. while (1) {
  121. if (count<0) count = MAX_PARTICLES-1;
  122. if (count==m_cp) break;
  123. p = m_particles + count;
  124. if (p->lifeTime>0) {
  125. if (p->spray->renderFunction) {
  126. (p->spray->renderFunction)( p->spray->dataToRenderFunction, p );
  127. } else {
  128. a = (p->lifeTime>>6);
  129. if (a>255) a = 255;
  130. a = 255-a;
  131. m_renderer->renderTile( p->x - p->size/2, p->y - p->size/2,
  132. p->size, p->size,
  133. p->angle,p->spray->renderType,
  134. p->tileIndex | (a<<24),
  135. p->userData);
  136. }
  137. }
  138. count--;
  139. };
  140. };