Plasma effect

Source code

/*========================================================================

  Color Plasma Effect - Version 1.0
  (c) QUAGLIOZZI ERIC - 2005-2007

   Usable for low res (72 dpi) and double res (144 dpi) bitmap using 8
   and 16 bit colors.
   ---------------------------------------------------------
   | Do not use with other resolutions, may system crash ! |
   ---------------------------------------------------------
 ======================================================================*/


//--------------------------- Macros and constants ----------------------

#if defined(_MSC_VER)     // If compiling with VC++...

    #define private        static __inline
    #define longint        __int64
    
#elif defined(__GNUC__)  // If compiling with GCC...

    #define private        static inline
    #define longint        long long int
    
#else

    #error "Unknown Compiler!"
    
#endif

//--------------------------- Types -------------------------------------


typedef unsigned long Call68KFuncType(const void * emulStateP, 
                                      unsigned long trapOrFunction,
                                      const void * argsOnStackP,
                                      unsigned long argsSizeAndwantA0);

typedef unsigned long NativeFuncType(const void * emulStateP,
                                     void * userData68KP,
                                     Call68KFuncType * call68KFuncP);



typedef struct {
    unsigned char RGB4[1024];
} RGBPalette;    


typedef struct {
    unsigned char Index[216];
} PalmOSInverse;    

typedef struct {
    unsigned char V[256];
} CosTB;    


typedef struct {
    char hb_object_header[14];
    short         Padding;            // Padding and debug
    short          w;                 // bitmap width
    short         h;                  // bitmap height
    short         bitdepth;           // Source: 1 = 8 bits, 2 = 16 bits
    short         density;            // Source: 1 = LowRes, 2 = DoubleRes
    unsigned char * pData;            // destination bitmap data
    RGBPalette    * pPalmOSPalette;   // palm os palette pointer
    RGBPalette    * pPlasmaPalette;   // plasma palette pointer
    PalmOSInverse * pPalmOSInverse;   // inverse palm os palette pointer
    CosTB         * pCosTB;           // cosinus table pointer
    unsigned char p1,p2,p3,p4;        // used to render plasma effect
    unsigned char c1,c2,c3,c4;
    unsigned char pi1,pi2,pi3,pi4;
} PlasmaHB;    




typedef struct _ParamsType
  {
    PlasmaHB    * pPlasmaHB;      // Access to Plasma HB++ object
  } ParamsType;


#define FixedPoint  12            // We use 20:12 fixed point computation


//--------------------------- Plasma Effect Function --------------------


unsigned long PlasmaEffect(const void * emulStateP, void * userData68KP,
                                           Call68KFuncType * call68KFuncP)
{
  ParamsType    * p;                         //params pointer
  PlasmaHB      * pPlasma;                   //hb++ object pointer
  RGBPalette    * PPal;                      //color palette pointer
  RGBPalette    * PlasmaPal;                 //plasma palette pointer
  PalmOSInverse * InvPal;                    //inverse palm os palette pointer
  CosTB         * CosTable;                  //cos table pointer
  unsigned char * Pdest;                     //Destination Pixel line pointer
  short           i, j;                      //Loops and index
  short           is;                        //Loops and index
  unsigned short  id;
  long            h,w,wl;         
  long            R,G,B;  
  long            Rp,Gp,Bp;
  long            RGB;
  unsigned char   t1, t2, t3, t4, col;       //for plasma effect
  unsigned short  icol;


  // Do local copy of params
  p=(ParamsType *) userData68KP;
  pPlasma = p->pPlasmaHB;
  PPal  = pPlasma->pPalmOSPalette;
  InvPal = pPlasma->pPalmOSInverse;
  PlasmaPal = pPlasma->pPlasmaPalette;
  CosTable = pPlasma->pCosTB;
  
  // Perform initialization
  w = pPlasma->w * pPlasma->density;
  h = pPlasma->h * pPlasma->density;
  wl = w << (pPlasma->bitdepth-1);
  if((wl & 0x00000001)!=0) wl++;  
  
  //Plasma Effect
  Pdest = pPlasma->pData;
  t1=pPlasma->p1;
  t2=pPlasma->p2;
  for (j=0; j<h; j++)
  {
    is=0;
    t3=pPlasma->p3;
    t4=pPlasma->p4;
    for (i=0; i<w; i++)
    {
        col=CosTable->V[t1]+CosTable->V[t2]+CosTable->V[t3]+CosTable->V[t4];
        icol = ((unsigned short)col)<<2;
        if (pPlasma->bitdepth==1)
            { //256 colors
              Pdest[is]= PlasmaPal->RGB4[icol];  // copy new color
            }
        else
            { //65536 colors
              R=PlasmaPal->RGB4[icol+1]>>3;
              G=PlasmaPal->RGB4[icol+2]>>2;
              B=PlasmaPal->RGB4[icol+3]>>3;
              Pdest[is] = (R<<3)|(G>>3);
              Pdest[is+1]= (G<<5)|(B);
            }
        t3=(t3+pPlasma->c3);
        t4=(t4+pPlasma->c4);
        // next pixel
        is += pPlasma->bitdepth;
    }
    t1=(t1+pPlasma->c1);
    t2=(t2+pPlasma->c2);
    // Next Ligne
    Pdest += wl;
  }
  //move all pattern
  pPlasma->p1+=pPlasma->pi1;
  pPlasma->p2+=pPlasma->pi2;
  pPlasma->p3+=pPlasma->pi3;
  pPlasma->p4+=pPlasma->pi4;
  return 0;
}

//========================================================================