#include #include "..\2dfw\fw.h" #include "main.h" #include "explosn.h" typedef struct { int xpos; int ypos; short xspeed; short yspeed; short life; } particle; typedef struct { int particlesAlive; int age; particle particles[MAX_PARTICLES]; } explosion; explosion Explosions[MAX_EXPLOSIONS]; void startExplosion ( int xpos, int ypos ) { int CurrentExplosion; int CurrentParticle; explosion* explosionPtr; explosion* oldestPtr; particle* particlePtr; int foundone = 0; explosionPtr = Explosions; for ( CurrentExplosion = 0; CurrentExplosion < MAX_EXPLOSIONS; CurrentExplosion++ ) { if ( explosionPtr->particlesAlive == 0 ) { foundone = 1; break; } explosionPtr++; } // We dont have a spare one so lets replace the oldest one if ( foundone == 0 ) { oldestPtr = Explosions; explosionPtr = Explosions; for ( CurrentExplosion = 0; CurrentExplosion < MAX_EXPLOSIONS; CurrentExplosion++ ) { if ( oldestPtr->age < explosionPtr->age ) { oldestPtr = explosionPtr; } explosionPtr++; } explosionPtr = oldestPtr; } // now we can initialise our explosion explosionPtr->particlesAlive = MAX_PARTICLES; explosionPtr->age = 1; particlePtr = explosionPtr->particles; for ( CurrentParticle = 0; CurrentParticle < MAX_PARTICLES; CurrentParticle++ ) { particlePtr->xpos = xpos; particlePtr->ypos = ypos; particlePtr->xspeed = ( 16383 - rand())/128; particlePtr->yspeed = ( 16383 - rand())/128; particlePtr->life = (rand()>>7)+120; particlePtr++; } } void showExplosions ( void ) { int CurrentExplosion; int CurrentParticle; int oldXPos; int oldYPos; int combinedSpeed; GsLINE particleLine; explosion* explosionPtr; particle* particlePtr; explosionPtr = Explosions; for ( CurrentExplosion = 0; CurrentExplosion < MAX_EXPLOSIONS; CurrentExplosion++ ) { if ( explosionPtr->particlesAlive != 0 ) { // OK.. we have a live one.. so animate it explosionPtr->age++; particlePtr = explosionPtr->particles; for ( CurrentParticle = 0; CurrentParticle < MAX_PARTICLES; CurrentParticle++ ) { if ( particlePtr->life != 0 ) { particleLine.attribute = 0x00000000; particleLine.x0 = (short) (particlePtr->xpos>>STAGE_SHIFT); particleLine.y0 = (short) (particlePtr->ypos>>STAGE_SHIFT); combinedSpeed = 255 << (particlePtr->life>>3); particleLine.r = (combinedSpeed & 0xff0000)>>16; particleLine.g = particleLine.r+(combinedSpeed & 0x00ff00)>>8; particleLine.b = particleLine.r+particleLine.g+(combinedSpeed & 0x0000ff); oldXPos = particlePtr->xpos; oldYPos = particlePtr->ypos; particlePtr->xpos += particlePtr->xspeed; particlePtr->ypos += particlePtr->yspeed; if ( particlePtr->xspeed > 0 ) { particlePtr->xspeed -= 4; if ( particlePtr->xspeed < 0 ) particlePtr->xspeed = 0; } else { particlePtr->xspeed += 4; if ( particlePtr->xspeed > 0 ) particlePtr->xspeed = 0; } particlePtr->yspeed += 4; if ( particlePtr->yspeed > 50 ) particlePtr->yspeed -= 4; particlePtr->life--; if ( particlePtr->life == 0 ) { explosionPtr->particlesAlive--; } // Dont forget to actually display the particle particleLine.x1 = (short) (particlePtr->xpos>>STAGE_SHIFT); particleLine.y1 = (short) (particlePtr->ypos>>STAGE_SHIFT); GsSortLine ( &particleLine, fwDirectGetWot (), 0 ); } particlePtr++; } } // else // explosionPtr->age = 0; explosionPtr++; } } void showExplosions2 ( void ) { int CurrentExplosion; int CurrentParticle; int oldXPos; int oldYPos; int combinedSpeed; GsLINE* particleLine; explosion* Exp; particle* Part; particleLine = (GsLINE*)getScratchAddr(0); Exp = Explosions; for ( CurrentExplosion = 0; CurrentExplosion < MAX_EXPLOSIONS; CurrentExplosion++ ) { if ( Exp->particlesAlive != 0 ) { // OK.. we have a live one.. so animate it // First copy the particles into DCache // printf ( "copying from : %i to %i\n", Exp->particles, getScratchAddr(0)); memcpy ( (getScratchAddr(0)+sizeof(GsLINE)), Exp->particles, sizeof (particle)*MAX_PARTICLES); // memcpy ( Exp->particles, getScratchAddr(0), sizeof (particle)*MAX_PARTICLES); Part = (particle*)(getScratchAddr(0)+sizeof(GsLINE)); for ( CurrentParticle = 0; CurrentParticle < MAX_PARTICLES; CurrentParticle++ ) { // printf ( "particle %i - life %i\n", CurrentParticle, Part->life ); if ( Part->life != 0 ) { particleLine->attribute = 0x00000000; particleLine->x0 = (short) (Part->xpos>>STAGE_SHIFT); particleLine->y0 = (short) (Part->ypos>>STAGE_SHIFT); combinedSpeed = 255 << (Part->life>>3); particleLine->r = (combinedSpeed & 0xff0000)>>16; particleLine->g = particleLine->r+(combinedSpeed & 0x00ff00)>>8; particleLine->b = particleLine->r+particleLine->g+(combinedSpeed & 0x0000ff); oldXPos = Part->xpos; oldYPos = Part->ypos; Part->xpos += Part->xspeed; Part->ypos += Part->yspeed; if ( Part->xspeed > 0 ) { Part->xspeed -= 4; if ( Part->xspeed < 0 ) Part->xspeed = 0; } else { Part->xspeed += 4; if ( Part->xspeed > 0 ) Part->xspeed = 0; } Part->yspeed += 4; if ( Part->yspeed > 50 ) Part->yspeed -= 4; Part->life--; if ( Part->life == 0 ) { Exp->particlesAlive--; } // Dont forget to actually display the particle particleLine->x1 = (short) (Part->xpos>>STAGE_SHIFT); particleLine->y1 = (short) (Part->ypos>>STAGE_SHIFT); GsSortLine ( particleLine, fwDirectGetWot (), 0 ); } Part++; } // Copy the particles back into memory from DCache memcpy ( Exp->particles, (getScratchAddr(0)+sizeof(GsLINE)), sizeof (particle)*MAX_PARTICLES); // memcpy ( getScratchAddr(0), Exp->particles, sizeof(particle)*MAX_PARTICLES); } Exp++; } }