Back to index

kdeartwork  4.3.2
Public Member Functions | Protected Member Functions | Private Types | Private Member Functions | Private Attributes
KFireSaver Class Reference

#include <firesaver.h>

Collaboration diagram for KFireSaver:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 KFireSaver (QWidget *parent=0)
 ~KFireSaver ()

Protected Member Functions

void initializeGL ()
void resizeGL (int, int)
void paintGL ()
void timerEvent (class QTimerEvent *)

Private Types

enum  enumFireworkType {
  Sphere = 0, NoFW = 1, Circle = 2, BiCircle = 3,
  AngelHairs = 4, Splitter = 5, Spirals = 6, SuperNova = 7,
  NoRender = 8
}
enum  enumShowType { Show = 0, Random = 1, Monotype = 2, Monochrome = 3 }

Private Member Functions

enumFireworkType pickType ()
int pickColour ()
void explodeFirework (Particle *fireWorkLeaderParticle)
void burnLogo (QImage *image)
void playSound (QString file)
bool loadTexture (QString file, unsigned int &textureID)
void freeTexture (unsigned int &textureID)
void readConfig ()

Private Attributes

QList< Particle * > particleList
QList< Particle * > starList
QList< QImage * > imageList
unsigned int currentTexture
unsigned int particleTexture
unsigned int starTexture
unsigned int flareTexture
unsigned int diastarTexture
KArtsDispatcher artsDispatcher
KArtsServer artsServer
QList< KPlayObject * > playObjectList
QString sound_explosion
QString sound_debris
class Writerwriter
float unitX
float unitY
double timeStampFrame
bool firstGLFrame
struct {
bool enableBottomFire
bool enableSound
bool enableNoOverhead
bool enableRealtime
bool enableCombos
bool enableLogos
bool enableReduceLogo
bool enableStars
bool enableStarFlickering
bool enableStarGradient
bool enableWritings
bool enableSphereLight
bool enableFlash
bool enableFade
bool enableMegaFlares
bool enableTrails
int fireworksFrequency
int particleSize
int logoFrequency
int starsNumber
int flashOpacity
int fadeAmount
int megaFlares
QColor bottomFireColor
int colorsCount
int colorsT [8]
int typesCount
enumFireworkType typesT [9]
parameters
struct {
showp

Detailed Description

Definition at line 46 of file firesaver.h.


Member Enumeration Documentation

Enumerator:
Sphere 
NoFW 
Circle 
BiCircle 
AngelHairs 
Splitter 
Spirals 
SuperNova 
NoRender 

Definition at line 59 of file firesaver.h.

       {
              Sphere = 0,
              NoFW = 1,
              Circle = 2,
              BiCircle = 3,
              AngelHairs = 4,
              Splitter = 5,
              Spirals = 6,
              SuperNova = 7,
              NoRender = 8
       };
enum KFireSaver::enumShowType [private]
Enumerator:
Show 
Random 
Monotype 
Monochrome 

Definition at line 146 of file firesaver.h.

                         {
           Show = 0,
           Random = 1,
           Monotype = 2,
           Monochrome = 3
       };

Constructor & Destructor Documentation

KFireSaver::KFireSaver ( QWidget *  parent = 0)

Definition at line 126 of file firesaver.cpp.

       : QGLWidget( parent )
{
       // set random seed to initialize drand48() calls
       timeval tv;
       gettimeofday(&tv,NULL);
       srand48( (long)tv.tv_usec );

       readConfig();

       //initialize openGL context before managing GL calls
       makeCurrent();
       loadTexture( KStandardDirs::locate("data","kfiresaver/kfs_particle.png"), particleTexture );
       loadTexture( KStandardDirs::locate("data","kfiresaver/kfs_particle_flare.png"), flareTexture );
       loadTexture( KStandardDirs::locate("data","kfiresaver/kfs_particle_diastar.png"), diastarTexture );
       starTexture = particleTexture;

       //generate stars
       if (parameters.enableStars) {
              int number = parameters.starsNumber + 1;
              number *= 10 * number;
              for (int i=0 ; i<number ; i++)
              {
                     Particle * star = new Particle( Particle::StarParticle );
                     star->initializeValues();
                     star->texture = starTexture;
                     if (parameters.enableStarGradient)
                     {
                            GLfloat red = star->colour[0],
                                   green = star->colour[1],
                                   blue = star->colour[2],
                                   tint = 0.5 + star->ypos / FIELDWIDTH,
                                   merge = 0.3 + DRAND*0.7,
                                   mergen = 1 - merge;
                            star->colour[0] = red * merge + (1.0-tint) * mergen;
                            star->colour[1] = green * merge + tint * mergen;
                            star->colour[2] = blue * merge + tint * mergen;
                     }
                     starList.append( star );
              }
       }

       //generate bottom fire
       if (parameters.enableBottomFire) {
              float cRed = (float)parameters.bottomFireColor.red() / 255.0,
                    cGreen = (float)parameters.bottomFireColor.green() / 255.0,
                    cBlue = (float)parameters.bottomFireColor.blue() / 255.0;
              for (int i=0 ; i<NUMBER_OF_FIREPARTICLES ; i++)
              {
                     Particle* particle = new Particle( Particle::FireParticle );
                     particle->initializeValues();
                     particle->texture = particleTexture;
                     particle->zspeed *= 4.0;
                     particle->colour[0] = cRed * (0.6 + 0.4*DRAND);
                     particle->colour[1] = cGreen * (0.6 + 0.4*DRAND);
                     particle->colour[2] = cBlue * (0.6 + 0.4*DRAND);
                     particleList.append(particle);
              }
       }

       //get sound files
       if (parameters.enableSound) {
              sound_explosion = locate("data","kfiresaver/kfs_explode.ogg");
              sound_debris = locate("data","kfiresaver/kfs_debris.ogg");
       }

       //create the writer class that manages flying writings.
       if ( parameters.enableWritings )
              writer = new Writer("kfs_letters.desc");

       showp.forceBicolour =
       showp.forceColour =
       showp.forcePower =
       showp.forceType = false;
       showp.timeStamp = 0.0;
       startTimer(MSECPERIOD);

       //force initialization of "show" variables for the first time
       timerEvent(NULL);
}

Here is the call graph for this function:

Definition at line 208 of file firesaver.cpp.

{
       freeTexture( particleTexture );
       freeTexture( starTexture );
       particleList.clear();
       starList.clear();
       imageList.clear();
       playObjectList.clear();
       if ( parameters.enableWritings )
              delete writer;

       qDeleteAll(particleList);
       qDeleteAll(starList);
       qDeleteAll(imageList);
       qDeleteAll(playObjectList);
}

Here is the call graph for this function:


Member Function Documentation

void KFireSaver::burnLogo ( QImage *  image) [private]

Definition at line 897 of file firesaver.cpp.

{
       if (!image || image->isNull())
              return;
       int step = parameters.enableReduceLogo ? 2 : 1,
           imageW = image->width(),
           imageH = image->height(),
           offsetX = imageW / 2,
           offsetY = imageH / 2;
       float speed = FIELDW_4 / (imageW > imageH ? imageW : imageH),
             speedXOffs = 5 * (DRAND - DRAND),
             speedYOffs = DRAND + DRAND + 1;
       //if image is too big, lower sample points
       while ((imageW/step)>96 || (imageH/step)>96)
              step *= 2;
       for (int y=0 ; y<imageH ; y+=step)
       {
              for (int x=0 ; x<imageW ; x+=step)
              {
                     QRgb pixel = image->pixel(x,y);
                     if ( qAlpha(pixel) < 250 )
                            continue;
                     //if ( DRAND > 0.9 )
                     //     continue;

                     Particle* particle = new Particle( Particle::LogoParticle );
                     particle->initializeValues();
                     particle->texture = particleTexture;

                     float xI = (x - offsetX) ,
                           yI = (offsetY - y) ;
                     particle->xpos = xI * speed * 0.5;
                     particle->zpos = yI * speed * 0.5 + 5;
                     particle->xspeed = xI * speed + speedXOffs;
                     particle->zspeed = yI * speed + speedYOffs;

                     particle->colour[0] = qRed(pixel) / 255.0f;
                     particle->colour[1] = qGreen(pixel) / 255.0f;
                     particle->colour[2] = qBlue(pixel) / 255.0f;

                     particleList.append(particle);
              }
       }
       if (parameters.enableSound)
              playSound(sound_debris);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void KFireSaver::explodeFirework ( Particle fireWorkLeaderParticle) [private]

Definition at line 600 of file firesaver.cpp.

{
       GLfloat displace[3] = {0.0,0.0,0.0};
       float tmp1 = 0.0, tmp2 = 0.0, tmp3 = 0.0, tmp4 = 0.0, tmp5 = 0.0;

       // color of exploded particles
       bool bicolor = parameters.enableCombos && (showp.forceBicolour || DRAND > 0.95),
            flickers = false;
       int cscheme = showp.forceColour ? showp.colour : pickColour(),
           cscheme2 = showp.forceColour ? showp.colourSec : pickColour();

       // randomize type of exploding firework
       enumFireworkType fwType =
              showp.forceType ? (enumFireworkType) showp.type : pickType();

       // other options for generated particles
       int number = (int) ((DRAND + DRAND) * 150.0);
       float power = showp.forcePower ?
              showp.powerEnvelop * (0.8 + 0.3*DRAND) :
              DRAND * 11.0 + 2.0,
             powermin = DRAND * power;

       // now some rules ...
        //a splitter can't split up more than 2 times
       if (fwType == Splitter && leaderParticle->explosionsDepth > 1) {
              if (parameters.typesCount == 1)
                     return;
              if (showp.forceType)
                     fwType = showp.typeSec;
              if (fwType == Splitter)
                     while ( (fwType = pickType()) == Splitter );
       }

       // PRE-ADJUST parameters for the firework we're creating
       switch ( fwType )
       {
              //no need to handle this. it's the default configuration.
           case Sphere:
              break;

              //explosion whithout emitting particles, only a flash
           case NoFW:
              number = 1;
              power = powermin = 0;
              break;

              //splits up into 'number' orange pieces. tmp1 holds base_life
           case Splitter:
              cscheme = showp.forceColour ? showp.colour : 1;
              bicolor = false;
              number = 3 + (int) (DRAND * 4);
              power /= 2.0;
              powermin = power / 2.0;
              tmp1 = 0.4 + DRAND * 1.5;
              break;

              //randomize a couple of angles (phi - theta) for exploding circle
           case BiCircle:
              number *= 2;
           case Circle:
              power = DRAND * 5.0 + 4.0;
              tmp1 = DRAND * M_PI;
              tmp2 = DRAND * M_PI;
              tmp4 = cos(tmp2);    //c2
              tmp3 = sin(tmp2);    //s2
              tmp2 = cos(tmp1);    //c1
              tmp1 = sin(tmp1);    //s1
              break;

              //cascade of flickering orange particles
           case AngelHairs:
              cscheme = showp.forceColour ? showp.colour : 1;
              bicolor = false;
              flickers = true;
              power = 0.8 + DRAND * 1.9;
              powermin = DRAND*0.5;
              number = 100 + (int)(DRAND * 150);
              displace[0] = -leaderParticle->xspeed/2;
              displace[1] = -leaderParticle->yspeed/2;
              displace[2] = power;
              break;

              //behave as a standard spherical firework
           case Spirals:
              break;

              //not yet implemented, suppressing particles
           case SuperNova:
           case NoRender:
              number = 0;
              break;
       }

       //limit number of particles as we are getting to the capacity saturation
       float currentParticles = (float) particleList.count();
       const float particleCapacity = 15000;
       const float particleGap = 8000;
       if ( number > 10 && currentParticles > (particleCapacity - particleGap) )
       {
              //NoFW, Splitter and NoRender aren't limited.
              number = (int)( (float)number * (particleCapacity - currentParticles) / particleGap );
              if ( number < 10 )
                     number = 0;
       }

       int newExplosionsDepth = leaderParticle->explosionsDepth + 1;
       for (int i=0 ; i<number ; i++)
       {
              Particle * particle;
              if ( fwType == Spirals )
                     particle = new TurningParticle( Particle::FireWorkDebrisParticle );
              else
                     particle = new Particle( Particle::FireWorkDebrisParticle );

              particle->initializeValues (
                     bicolor && (i>number/2) ? cscheme2 : cscheme,
                     leaderParticle, powermin, power,
                     flickers, displace );
              particle->texture = particleTexture;
              particle->explosionsDepth = newExplosionsDepth;

              // POST-ADJUST particle coefficients adapting to current FireworkType
              switch ( fwType )
              {
                     //create a big, white particle, simulating explosion
                  case NoFW:
                     if (parameters.enableFade)
                            particle->startLife = particle->life = 0.030;
                     else
                            particle->startLife = particle->life = 0.075;
                     particle->texture = flareTexture;
                     particle->colour[0]=
                     particle->colour[1]=
                     particle->colour[2]=1.0;
                     particle->pixelSize = 50.0 + 75.0 * DRAND;
                     particle->zacc = 0;
                     break;

                     //default. no need to change parameters, only create the
                     //'sphere light' as the first big particle if set.
                  case Sphere:
                     if (i==0 && parameters.enableSphereLight && number > 40) {
                            particle->texture = flareTexture;
                            particle->xspeed = leaderParticle->xspeed;
                            particle->yspeed = leaderParticle->yspeed;
                            particle->zspeed = 0.0;
                            particle->colour[0] /= 2.0;
                            particle->colour[1] /= 2.0;
                            particle->colour[2] /= 2.0;
                            float impression = power * (float)number/5.0;
                            particle->pixelSize = 25.0 * DRAND + impression;
                            if (parameters.enableFade) {
                                   particle->startLife = particle->life = 0.040;
                            } else {
                                   particle->startLife = 1.3;
                                   particle->life = 1.8;
                            }
                     }
                     break;

                     //
                  case Splitter:
                     particle->particleType = Particle::FireWorkLeaderParticle;
                     particle->pixelSize *= 3.0;
                     particle->startLife = particle->life = tmp1 * (0.75 + DRAND/3.0);
                     if (particle->zspeed < 0)
                            particle->zspeed = -particle->zspeed;
                     break;

                  case Circle:
                  case BiCircle:
                     tmp5 = 2 * M_PI * DRAND;
                     //MMX can be useful.. if you know how to use it :-)
                     if ( fwType == BiCircle && i > number/2 ) {
                            GLfloat ey = cos(tmp5),
                                   ez = sin(tmp5);
                            particle->xspeed = power * (                tmp3*ez );
                            particle->yspeed = power * ( tmp2*ey - tmp1*tmp4*ez );
                            particle->zspeed = power * ( tmp1*ey + tmp2*tmp4*ez );
                     } else {
                            GLfloat ex = sin(tmp5),
                                   ey = cos(tmp5);
                            particle->xspeed = power * (       tmp4*ex           );
                            particle->yspeed = power * (  tmp1*tmp3*ex + tmp2*ey );
                            particle->zspeed = power * ( -tmp2*tmp3*ex + tmp1*ey );
                     }
                     break;

                  case AngelHairs:
                     particle->zacc = -9.807 * (0.05 + DRAND*0.20);
                     particle->life = 2.0 + DRAND*2.5;
                     particle->startLife = particle->life - 1;
                     if (particle->zspeed < 0)
                            particle->zspeed *= -1;
                     //particle->pixelSize = 5.0;
                     break;

                  case Spirals:
                     particle->texture = diastarTexture;
                     break;

                     //discard cases
                  case SuperNova:
                  case NoRender:
                     break;
              }
              particleList.append(particle);
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void KFireSaver::freeTexture ( unsigned int &  textureID) [private]

Definition at line 1001 of file firesaver.cpp.

{
       if ( textureID > 0 )
           glDeleteTextures( 1, &textureID );
       textureID = 0;
}

Here is the caller graph for this function:

void KFireSaver::initializeGL ( ) [protected]

Definition at line 226 of file firesaver.cpp.

{
       glDisable(GL_DEPTH_TEST);
       glEnable(GL_BLEND);
       glBlendFunc(GL_SRC_ALPHA,GL_ONE);
       glShadeModel( GL_SMOOTH );

       resizeGL( 640, 480 );
}

Here is the call graph for this function:

bool KFireSaver::loadTexture ( QString  file,
unsigned int &  textureID 
) [private]

Definition at line 976 of file firesaver.cpp.

{
       //reset texture ID to the default EMPTY value
       textureID = 0;

       //load image
       QImage tmp;
       if ( !tmp.load( fileName ) )
              return false;

       //convert it to suitable format (flipped RGBA)
       QImage texture = QGLWidget::convertToGLFormat( tmp );
       if ( texture.isNull() )
              return false;

       //get texture number and bind loaded image to that texture
       glGenTextures( 1, &textureID );
       glBindTexture( GL_TEXTURE_2D, textureID );
       glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
       glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
       glTexImage2D( GL_TEXTURE_2D, 0, 4 /* 3 ??? */, texture.width(), texture.height(),
              0, GL_RGBA, GL_UNSIGNED_BYTE, texture.bits() );
       return true;
}

Here is the caller graph for this function:

void KFireSaver::paintGL ( ) [protected]

Definition at line 267 of file firesaver.cpp.

{
       /* calculate TIME ELAPSED between current and previous frame */

       timeval tv;
       gettimeofday(&tv,NULL);
       double timeCurrent = (double)tv.tv_sec + (double)tv.tv_usec/1000000.0;
       double timeDiff = (MSECPERIOD / 1000.0);
       if (parameters.enableRealtime)
       {
              timeDiff = timeCurrent - timeStampFrame;
              timeStampFrame = timeCurrent;
              timeDiff = (timeDiff > 0.5) ? 0.5 : (timeDiff < 0.005) ? 0.005 : timeDiff;
       }

       /* CLEAR SCREEN: to do it there are 2 ways */

       glLoadIdentity();
       glTranslatef( 0, 0, -50.0 );
       glDisable( GL_TEXTURE_2D );

       if ( !parameters.enableFade || firstGLFrame )
       {      // quick - clear the OpenGL color buffer
              glClearColor( 0.0, 0.0, 0.0, 1.0 );
              glClear( GL_COLOR_BUFFER_BIT );
              firstGLFrame = false;
       }
       else
       {      // good looking
              /* superpose a semi-transparent black rectangle so we
                 can see a sort of 'tail' for each particle drawn. */
              const GLfloat conv_tab[10] = {
                     0.50, 0.33, 0.22, 0.15, 0.10,
                     0.07, 0.05, 0.03, 0.02, 0.01 };
              glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
              glColor4f(0.0,0.0,0.0, conv_tab[parameters.fadeAmount]);
              glBegin( GL_TRIANGLE_STRIP );
                glVertex2f( FIELDW_2, FIELDW_2 );
                glVertex2f( -FIELDW_2, FIELDW_2 );
                glVertex2f( FIELDW_2, -FIELDW_2 );
                glVertex2f( -FIELDW_2, -FIELDW_2 );
              glEnd();
              glBlendFunc(GL_SRC_ALPHA,GL_ONE);
       }

       /* render STARS */

       if (parameters.enableStars) {
              if ( starTexture ) {
                     glEnable( GL_TEXTURE_2D );
                     glBindTexture( GL_TEXTURE_2D, currentTexture = starTexture );
              } else
                     glDisable( GL_TEXTURE_2D );

              glBegin( GL_QUADS );
              bool   flickers = parameters.enableStarFlickering;
              float  alpha = flickers ? 0.5 : 1.0;
              Particle * star = starList.first();
              for (; star; star = starList.next())
              {
                     if (flickers && DRAND<0.6)
                            continue;

                     GLfloat sizeX = star->pixelSize * unitX,
                            sizeY = star->pixelSize * unitY,
                            pLeft = star->xpos - sizeX,
                            pRight = star->xpos + sizeX,
                            pTop = star->ypos + sizeY,
                            pBottom = star->ypos - sizeY;
                     glColor4f(star->colour[0], star->colour[1], star->colour[2], alpha);
                     glTexCoord2f( 0, 0 );       // Bottom Left
                     glVertex2f( pLeft, pBottom );
                     glTexCoord2f( 0, 1 );       // Top Left
                     glVertex2f( pLeft, pTop );
                     glTexCoord2f( 1, 1 );       // Top Right
                     glVertex2f( pRight, pTop );
                     glTexCoord2f( 1, 0 );       // Bottom Right
                     glVertex2f( pRight, pBottom );
              }
              glEnd();
       }

       /* render FIREWORKS */

       glBegin( GL_QUADS );
       bool playedExplodeSound = false;
       bool flashedScreen = false;
       Particle * particle = particleList.first();
       for (; particle; particle = particleList.next())
       {
              //bind the texture for current particle (if not already bound)
              if ( !particle->texture ) {
                     glEnd();
                     glDisable( GL_TEXTURE_2D );
                     glBegin( GL_QUADS );
                     currentTexture = 0;
              } else if ( particle->texture != currentTexture ) {
                     glEnd();
                     glEnable( GL_TEXTURE_2D );
                     glBindTexture( GL_TEXTURE_2D, currentTexture = particle->texture );
                     glBegin( GL_QUADS );
              }

              //perspective projection (done by hand to make it funnier than opengl's :-)
              float mfactor = PERSP_MAG_FACTOR * particle->ypos;
              if ( mfactor < -246.0 ) {
                     particleList.remove();
                     particleList.prev();
                     continue;
              }
              float sfactor = 256.0 / (256.0 + mfactor),
                    posx = sfactor * particle->xpos,
                    posy = sfactor * particle->zpos - 4.0;
              //size computation (magnify if enableMegaFlares is set)
              if ( parameters.enableMegaFlares ) {
                     mfactor = parameters.megaFlares*particle->ypos;
                     if ( mfactor < -255.0 || mfactor > 512.0 ) {
                            particleList.remove();
                            particleList.prev();
                            continue;
                     }
                     sfactor = 256.0 / (256.0 + mfactor);
                     if ( sfactor > 64 )
                            sfactor = 76.8 - sfactor / 5.0;
              }
              float size = sfactor * particle->pixelSize,
                    sizeX = size * unitX,
                    sizeY = size * unitY;

              //determine brightness (alpha component) for the particle
              if ( particle->useLife ) {
                     float life = particle->life,
                           startLife = particle->startLife;
                     //bright changes with the following curve: "2*k - k^2" (or "k(2-k)")
                     if ( life > startLife )
                            particle->colour[3] = startLife + 1 - life;
                     else
                            particle->colour[3] = life / startLife;
                     //apply flickering if enabled
                     if (particle->flicker < 0) {
                            particle->colour[3] = 0.2;
                            if (++particle->flicker >= 0)
                                   particle->flicker = FLICKER_FRAMES_DELAY;
                     } else if (particle->flicker > 0) {
                            if ( life <= startLife )
                                   particle->colour[3] = 1.0;
                            if (--particle->flicker <= 0)
                                   particle->flicker = -FLICKER_FRAMES_DELAY;
                     }
                     glColor4fv( particle->colour );
              } else
                     glColor3fv( particle->colour );

              //draw particle
              float pLeft = posx - sizeX,
                    pTop = posy + sizeY,
                    pRight = posx + sizeX,
                    pBottom = posy - sizeY;
              glTexCoord2f( 0, 0 );       // Bottom Left
              glVertex2f( pLeft, pBottom );
              glTexCoord2f( 0, 1 );       // Top Left
              glVertex2f( pLeft, pTop );
              glTexCoord2f( 1, 1 );       // Top Right
              glVertex2f( pRight, pTop );
              glTexCoord2f( 1, 0 );       // Bottom Right
              glVertex2f( pRight, pBottom );

              //phisically update parameters of the particle
              particle->updateParameters( timeDiff );

              //check for particle death / explosion
              switch (particle->particleType)
              {
                     //a Fireparticle is restarted when in right conditions
                  case Particle::FireParticle:
                     if ( posx < -FIELDW_2 || posx > FIELDW_2 ||
                            (particle->zpos < -10.0 && posy < -FIELDW_2) )
                     {
                            particle->initializeValues();
                            if ( DRAND > 0.9995 )
                                   particle->zspeed *= 4;
                     }
                     break;

                     //a leader explodes when his z speed drops to zero
                     //or, if it uses life, at death
                  case Particle::FireWorkLeaderParticle:
                     if ((particle->zspeed <= 0.0f && !particle->useLife) ||
                         (particle->useLife && particle->life <= 0.0) )
                     {
                            // play sound if enabled (and once per frame)
                            if (parameters.enableSound && !playedExplodeSound)
                            {
                                   playSound(sound_explosion);
                                   playedExplodeSound = true;
                            }
                            // flash screen if enabled
                            if (parameters.enableFlash && !flashedScreen) {
                                   glEnd();
                                   glDisable( GL_TEXTURE_2D );
                                   glColor4f( 1,1,1, parameters.flashOpacity / 10.0 );
                                   glBegin( GL_TRIANGLE_STRIP );
                                   glVertex2f( FIELDW_2, FIELDW_2 );
                                   glVertex2f( -FIELDW_2, FIELDW_2 );
                                   glVertex2f( FIELDW_2, -FIELDW_2 );
                                   glVertex2f( -FIELDW_2, -FIELDW_2 );
                                   glEnd();
                                   if ( particleTexture )
                                          glEnable( GL_TEXTURE_2D );
                                   glBegin( GL_QUADS );
                                   flashedScreen = true;
                            }
                            // generating children and removing parent
                            int elementIndex = particleList.at();
                            explodeFirework(particle);
                            particleList.remove(elementIndex);
                            particleList.prev();
                     } else if ( parameters.enableTrails && DRAND < 0.4 ) {
                            // leave trail behind the particle (it'a small and slow red debris)
                            Particle * p = new Particle( Particle::FireWorkDebrisParticle );
                            p->initializeValues( 0, particle, 1, 1 );
                            p->texture = particleTexture;
                            p->xspeed /= 4;
                            p->yspeed /= 4;
                            p->zspeed /= 8;
                            p->zacc /= 4;
                            p->pixelSize = 2;
                            p->colour[0] /= 2;
                            int elementIndex = particleList.at();
                            particleList.append( p );
                            particleList.at( elementIndex );
                     }
                     break;

                     //remove if dead or outside field
                  default:
                     if (particle->life <= 0.0 || posx<-FIELDW_2 || posx>FIELDW_2 || posy<-FIELDW_2) {
                            particleList.remove();
                            particleList.prev();
                     }
                     break;
              }
       }
       glEnd();

       /* render WRITINGS */

       if ( parameters.enableWritings )
       {
              int chance = (int) (1000.0 * DRAND);
              if ( !chance ) {
                     static const QString someStrings[] = {
                            i18n("www.kde.org"),
                            i18n("Conquer your desktop!"),
                            i18n("KFIRESAVER 3D"),
                            i18n("Thank you for using KDE"),
                     };
                     int n = (int)(4.0 * DRAND);
                     writer->spawnWords( someStrings[n], Writer::Fun1 );
              }
              writer->render( timeDiff );
       }

       /* generate a new FIREWORK_LEADER */

       int random = (int) ((float)parameters.fireworksFrequency * DRAND);
       if (showp.ShowType == Show)
       {
              //double the chances ('frequency') to raise a new leaderParticle
              //but envelop it under a sine function
              float step = (showp.timeStamp - timeCurrent) / showp.timeGap;
              if (DRAND > sin(M_PI*step))
                     random = -1;
              if (showp.type == AngelHairs && DRAND < 0.5)
                     random = -1;
       }
       if ( !random )
       {
              Particle * particle = new Particle( Particle::FireWorkLeaderParticle );
              particle->initializeValues();
              particle->texture = flareTexture;
              particleList.append( particle );
       }

       /* explode a logo */

       int logoImages = imageList.count();
       if ( logoImages > 0 ) {
              random = (int) (parameters.logoFrequency * logoImages * 200.0 * DRAND);
              if ( random < logoImages )
              {
                     if (parameters.enableFlash && !flashedScreen) {
                            glDisable( GL_TEXTURE_2D );
                            glColor4f( 1,1,1, parameters.flashOpacity / 10.0 );
                            glBegin( GL_TRIANGLE_STRIP );
                            glVertex2f( FIELDW_2, FIELDW_2 );
                            glVertex2f( -FIELDW_2, FIELDW_2 );
                            glVertex2f( FIELDW_2, -FIELDW_2 );
                            glVertex2f( -FIELDW_2, -FIELDW_2 );
                            glEnd();
                     }
                     burnLogo( imageList.at(random) );
              }
       }
}

Here is the call graph for this function:

int KFireSaver::pickColour ( ) [inline, private]

Definition at line 586 of file firesaver.cpp.

{
       int color = (int) (DRAND * parameters.colorsCount);
       return parameters.colorsT[ color ];
}

Here is the caller graph for this function:

Definition at line 593 of file firesaver.cpp.

{
       int type = (int) (DRAND * parameters.typesCount);
       return parameters.typesT[ type ];
}

Here is the caller graph for this function:

void KFireSaver::playSound ( QString  file) [private]

Definition at line 944 of file firesaver.cpp.

{
       //flush inactive players
       KPlayObject * playObject = playObjectList.first();
       while ( playObject )
       {
              if ( playObject->state() != Arts::posPlaying )
              {
                     playObjectList.remove();
                     playObject = playObjectList.current();
              } else
                     playObject = playObjectList.next();
       }

       //discart this sound if the player queue is already full (4 channels playing)
       if ( playObjectList.count() >= 6 )
              return;

       // not needed when all of the files are in the distribution
       //if (!QFile::exists(file))
              //return;

       KPlayObjectFactory factory(artsServer.server());
       playObject = factory.createPlayObject(KUrl(file), true);

       if (playObject && !playObject->isNull())
       {
              playObject->play();
              playObjectList.append(playObject);
       }
}

Here is the caller graph for this function:

void KFireSaver::readConfig ( ) [private]

Definition at line 1008 of file firesaver.cpp.

{
       KConfig config("kfiresaverrc",true,false);

       // show
       config.setGroup( "Show" );
       showp.ShowType = (enum enumShowType)config.readEntry( "ShowType", 1 );
       parameters.fireworksFrequency = 11 - config.readEntry( "FireworksFrequency", 7 );
       if ( parameters.fireworksFrequency < 1 )
              parameters.fireworksFrequency = 1;
       if ( parameters.fireworksFrequency > 11 )
              parameters.fireworksFrequency = 11;
       parameters.fireworksFrequency *= (parameters.fireworksFrequency + 1); //*karl gauss's sum*
       parameters.particleSize = config.readEntry( "ParticlesSize", 0 );
       if ( parameters.particleSize < -5 )
              parameters.particleSize = -5;
       if ( parameters.particleSize > 5 )
              parameters.particleSize = 5;
       if ( parameters.enableBottomFire = config.readEntry( "enable-BottomFire", true ) )
       {
              QColor blue = Qt::darkBlue;
              parameters.bottomFireColor = config.readEntry( "BottomFireColor", blue );
       }
       parameters.enableSound = config.readEntry( "enable-Sounds", false );
       parameters.enableNoOverhead = config.readEntry( "enable-NoOverhead", true );
       parameters.enableRealtime = config.readEntry( "enable-FrameSkip", true );

       // fireworks
       config.setGroup( "Fireworks" );
       parameters.typesCount = 0;
       if ( config.readEntry( "use-Classic", true ) )
              parameters.typesT[parameters.typesCount++] = Sphere;
       if ( config.readEntry( "use-Explosion", false ) )
              parameters.typesT[parameters.typesCount++] = NoFW;
       if ( config.readEntry( "use-FlameRing", false ) )
              parameters.typesT[parameters.typesCount++] = Circle;
       if ( config.readEntry( "use-FlameWorld", false ) )
              parameters.typesT[parameters.typesCount++] = BiCircle;
       if ( config.readEntry( "use-Fall", false ) )
              parameters.typesT[parameters.typesCount++] = AngelHairs;
       if ( config.readEntry( "use-Splitter", false ) )
              parameters.typesT[parameters.typesCount++] = Splitter;
       if ( config.readEntry( "use-Spirals", false ) )
              parameters.typesT[parameters.typesCount++] = Spirals;
       if ( config.readEntry( "use-SuperNova", false ) )
              parameters.typesT[parameters.typesCount++] = SuperNova;
       if ( !parameters.typesCount ) {
              kWarning() << "KFireSaver3D: Warning, no fireworks enabled in config file" ;
              kWarning() << "    enabling 'Classic Spherical'" ;
              parameters.typesCount = 1;
              parameters.typesT[0] = Sphere;
       }
       parameters.typesT[ parameters.typesCount ] =
              parameters.typesT[ parameters.typesCount-1 ];
       parameters.colorsCount = 0;
       if ( config.readEntry( "use-Red", false ) )
              parameters.colorsT[parameters.colorsCount++] = 0;
       if ( config.readEntry( "use-Orange", true ) )
              parameters.colorsT[parameters.colorsCount++] = 1;
       if ( config.readEntry( "use-Green", false ) )
              parameters.colorsT[parameters.colorsCount++] = 2;
       if ( config.readEntry( "use-Blue", false ) )
              parameters.colorsT[parameters.colorsCount++] = 3;
       if ( config.readEntry( "use-White", true ) )
              parameters.colorsT[parameters.colorsCount++] = 4;
       if ( config.readEntry( "use-Purple", false ) )
              parameters.colorsT[parameters.colorsCount++] = 5;
       if ( config.readEntry( "use-DeepGreen", true ) )
              parameters.colorsT[parameters.colorsCount++] = 6;
       if ( !parameters.colorsCount )
       {
              kWarning() << "KFireSaver3D: Warning enable at least one color" ;
              kWarning() << "    enabling 'Blinding White'" ;
              parameters.colorsCount = 1;
              parameters.colorsT[0] = 4;
       }
       parameters.colorsT[ parameters.colorsCount ] =
              parameters.colorsT[ parameters.colorsCount-1 ];
       parameters.enableCombos = config.readEntry( "use-Multicolor", true );

       // specials
       config.setGroup( "Specials" );
       if ( parameters.enableLogos = config.readEntry( "enable-Logos", true ) )
       {
              QImage tempImage;
              tempImage.setAlphaBuffer( true );
              if ( config.readEntry( "LogosTux", true ) )
                     if ( tempImage.load(locate("data","kfiresaver/kfs_tux.png")) )
                            imageList.append( new QImage(tempImage) );
              if ( config.readEntry( "LogosKonqui", true ) )
                     if ( tempImage.load(locate("data","kfiresaver/kfs_kde.png")) )
                            imageList.append( new QImage(tempImage) );
              if ( config.readEntry( "LogosKDEIcons", true ) ) {
                     const QString icons[] = {
                            "media-floppy", "media-optical", "drive-harddisk", "kmix",
                            "network-wired", "computer", "user-home", "konqueror",
                            "internet-mail", "graphics-viewer-document", "user-identity" };
                     for ( int i = 0; i < 11; i++ )
                            imageList.append( new QImage(DesktopIcon(icons[i],64).convertToImage()) );
              }
              parameters.enableReduceLogo = config.readEntry( "LogosReduceDetail", true );
              parameters.logoFrequency = 11 - config.readEntry( "LogosFrequency", 4 );
              if ( parameters.logoFrequency < 1 )
                     parameters.logoFrequency = 1;
              if ( parameters.logoFrequency > 11 )
                     parameters.logoFrequency = 11;
       }
       if ( parameters.enableStars = config.readEntry( "enable-Stars", true ) )
       {
              parameters.enableStarFlickering = config.readEntry( "StarsFlicker", false );
              parameters.enableStarGradient = config.readEntry( "StarsGradient", true );
              parameters.starsNumber = config.readEntry( "StarsNumber", 4 );
              if ( parameters.starsNumber < 0 )
                     parameters.starsNumber = 0;
              if ( parameters.starsNumber > 10 )
                     parameters.starsNumber = 10;
       }
       parameters.enableWritings = config.readEntry( "enable-Writings", true );

       // effects
       config.setGroup( "Effects" );
       parameters.enableSphereLight = config.readEntry( "enable-SphericalLight", true );
       if ( parameters.enableFlash = config.readEntry( "enable-Flash", false ) )
       {
              parameters.flashOpacity = config.readEntry( "FlashOpacity", 5 );
              if ( parameters.flashOpacity < 0 )
                     parameters.flashOpacity = 0;
              if ( parameters.flashOpacity > 10 )
                     parameters.flashOpacity = 10;
       }
       if ( parameters.enableFade = config.readEntry( "enable-Fade", false ) )
       {
              parameters.fadeAmount = config.readEntry( "FadeIntensity", 3 );
              if ( parameters.fadeAmount < 0 )
                     parameters.fadeAmount = 0;
              if ( parameters.fadeAmount > 9 )
                     parameters.fadeAmount = 9;
       }
       if ( parameters.enableMegaFlares = config.readEntry( "enable-Flares", true ) )
       {
              parameters.megaFlares = config.readEntry( "FlaresDimension", 5 );
              if ( parameters.megaFlares < 0 )
                     parameters.megaFlares = 0;
              if ( parameters.megaFlares > 10 )
                     parameters.megaFlares = 10;
              parameters.megaFlares += 4;
              parameters.megaFlares *= 2;
       }
       parameters.enableTrails = config.readEntry( "enable-Trail", false );
}

Here is the caller graph for this function:

void KFireSaver::resizeGL ( int  width,
int  height 
) [protected]

Definition at line 237 of file firesaver.cpp.

{
       glViewport( 0, 0, width, height );

       glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        glOrtho( -FIELDW_2, FIELDW_2, -FIELDW_2, FIELDW_2, 5.0, 60.0 );

       glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();

       float ratio = (float)width / (float)height,
             numH = 750 - 90 * parameters.particleSize,
             numW = 1000 - 120 * parameters.particleSize;
       if ( ratio >= (4.0/3.0) ) {
              unitX = FIELDWIDTH / (numH * ratio);
              unitY = FIELDWIDTH / numH;
       } else {
              unitX = FIELDWIDTH / numW;
              unitY = FIELDWIDTH / (numW / ratio);
       }

       timeval tv;
       gettimeofday(&tv,NULL);
       timeStampFrame = (double)tv.tv_sec + (double)tv.tv_usec/1000000.0;

       firstGLFrame = true;
}

Here is the caller graph for this function:

void KFireSaver::timerEvent ( class QTimerEvent *  ) [protected]

Definition at line 810 of file firesaver.cpp.

{
       timeval tv;
       gettimeofday(&tv,NULL);
       double currentTime = (double)tv.tv_sec + (double)tv.tv_usec/1000000.0;

       bool   chooseType = false,
              chooseColor = false,
              chooseOthers = false,
              updateTimings = false;
       bool   firstTime = showp.timeStamp == 0.0;
       bool   endOfScene = currentTime >= showp.timeStamp;

       if (firstTime)
       switch (showp.ShowType)
       {
           case Monotype:
              /* first time choose the type, color and attributes will
                 be chosen randomly for every firework which explodes*/
              showp.forceType = true;
              chooseType = true;
              break;

           case Monochrome:
              /* first time choose the color, type and attributes will
                 be chosen randomly for every firework which explodes*/
              showp.forceColour = true;
              chooseColor =
              chooseOthers = true;
              break;

           default: break;
       }

       if (endOfScene || firstTime)
       switch (showp.ShowType)
       {
           case Show:
              /* if a scene ended, randomize global parameters for the
                 whole next scene */
              showp.forceType = true;
              showp.forceColour = true;
              showp.forcePower = true;
              chooseOthers =
              chooseColor =
              chooseType = true;
              updateTimings = true;
              break;

           default: break;
       }

       if ( chooseType )
       {
              showp.type = pickType();
              if (parameters.typesCount < 2)
                     showp.typeSec = NoRender;
              else
                     while ((showp.typeSec = pickType()) == showp.type);
       }
       if ( chooseColor ) {
              showp.colour = pickColour();
              showp.colourSec = pickColour();
       }
       if ( chooseOthers )
       {
              showp.powerEnvelop = DRAND * 8.0 + 3.0;
              if (DRAND > 0.9)
              {
                     showp.forceBicolour = true;
                     showp.colourSec = pickColour();
              } else
                     showp.forceBicolour = false;
       }
       if ( firstTime || updateTimings )
       {
              if (DRAND < 0.2)
                     showp.timeGap = 1.0 + DRAND * 2.0;
              else
                     showp.timeGap = 3.0 + DRAND * 10.0;
              showp.timeStamp = currentTime + showp.timeGap;
              showp.timeGap /= 1.5; //hack to introduce delay in sine func
       }

       updateGL();
}

Here is the call graph for this function:

Here is the caller graph for this function:


Member Data Documentation

KArtsDispatcher KFireSaver::artsDispatcher [private]

Definition at line 99 of file firesaver.h.

KArtsServer KFireSaver::artsServer [private]

Definition at line 100 of file firesaver.h.

unsigned int KFireSaver::currentTexture [private]

Definition at line 92 of file firesaver.h.

unsigned int KFireSaver::diastarTexture [private]

Definition at line 92 of file firesaver.h.

bool KFireSaver::firstGLFrame [private]

Definition at line 110 of file firesaver.h.

unsigned int KFireSaver::flareTexture [private]

Definition at line 92 of file firesaver.h.

QList<QImage *> KFireSaver::imageList [private]

Definition at line 88 of file firesaver.h.

struct { ... } KFireSaver::parameters [private]
QList<Particle *> KFireSaver::particleList [private]

Definition at line 83 of file firesaver.h.

unsigned int KFireSaver::particleTexture [private]

Definition at line 92 of file firesaver.h.

QList<KPlayObject *> KFireSaver::playObjectList [private]

Definition at line 101 of file firesaver.h.

struct { ... } KFireSaver::showp [private]
QString KFireSaver::sound_debris [private]

Definition at line 102 of file firesaver.h.

QString KFireSaver::sound_explosion [private]

Definition at line 102 of file firesaver.h.

QList<Particle *> KFireSaver::starList [private]

Definition at line 83 of file firesaver.h.

unsigned int KFireSaver::starTexture [private]

Definition at line 92 of file firesaver.h.

double KFireSaver::timeStampFrame [private]

Definition at line 109 of file firesaver.h.

float KFireSaver::unitX [private]

Definition at line 107 of file firesaver.h.

float KFireSaver::unitY [private]

Definition at line 107 of file firesaver.h.

class Writer* KFireSaver::writer [private]

Definition at line 106 of file firesaver.h.


The documentation for this class was generated from the following files: