Main Page | Alphabetical List | Compound List | File List | Compound Members | File Members

ElectricFx.c

Go to the documentation of this file.
00001 /****************************************************************************************/
00002 /*  ElectricFx.c                                                                        */
00003 /*                                                                                      */
00004 /*  Author: John Pollard                                                                */
00005 /*  Description:                                                                        */
00006 /*                                                                                      */
00007 /*  Copyright (c) 1997, 1999, Eclipse Entertainment; All rights reserved.               */
00008 /*                                                                                      */
00009 /*  See the accompanying file LICENSE.TXT for terms on the use of this library.         */
00010 /*  This library is distributed in the hope that it will be useful but WITHOUT          */
00011 /*  ANY WARRANTY OF ANY KIND and without any implied warranty of MERCHANTABILITY        */
00012 /*  or FITNESS FOR ANY PURPOSE.  Refer to LICENSE.TXT for more details.                 */
00013 /*                                                                                      */
00014 /****************************************************************************************/
00015 #include <Assert.h>
00016 #include <Stdlib.h>
00017 
00018 #include <Math.h>
00019 
00020 #include "Procedural.h"
00021 #include "String.h"
00022 #include "Bitmap.h"
00023 #include "Ram.h"
00024 #include "gebmutil.h"
00025 
00026 #include "Errorlog.h"
00027 
00028 #define SMOOTH_WRAP GE_TRUE
00029 
00030 #define         PI              (3.14159f)
00031 #define         PI_2    (PI*2)
00032 
00033 #define         ELECTRICFX_MAX_FX_TYPES 128
00034 #define         ELECTRICFX_MAX_VECS             128
00035 
00036 #define         TOKEN_SEPERATOR         " ,"
00037 //#define               TOKEN_SEPERATOR         " \t,+\n\r"
00038 
00039 //====================================================================================
00040 //====================================================================================
00041 typedef struct
00042 {
00043         int32           x, y;
00044 } ElectricFx_Vec2d;
00045 
00046 typedef enum
00047 {
00048         Fx_Line = 0,
00049         Fx_LineSpin,
00050         Fx_Sparkle,
00051         Fx_EnergySpin
00052 } ElectricFx_Type;
00053 
00054 typedef struct
00055 {
00056         ElectricFx_Type Type;                   // Type of fx
00057         char                    Str[256];               // String name
00058         int32                   NumVecs;                // Number of vecs required to run fx
00059 } ElectricFx_TypeData;
00060 
00061 typedef struct
00062 {
00063         ElectricFx_TypeData             *TypeData;
00064         ElectricFx_Vec2d                Vecs[2];
00065 
00066         float                                   Rotation;
00067 } ElectricFx_Fx;
00068 
00069 ElectricFx_TypeData FxTypeDataTable[] = 
00070 {
00071         {Fx_Line, "Fx_Line", 2},
00072         {Fx_LineSpin, "Fx_LineSpin", 1},
00073         {Fx_Sparkle, "Fx_Spark", 1},
00074         {Fx_EnergySpin, "Fx_EnergySpin", 1}
00075 };
00076 
00077 typedef struct Procedural
00078 {
00079         geBitmap                        *Bitmap;
00080         geBitmap_Info           BitmapInfo;
00081 
00082         int32                           Width;
00083         int32                           Height;
00084         int32                           Size;
00085         int32                           WMask;
00086         int32                           HMask;
00087 
00088         uint8                           *ZBuffer;                               
00089 
00090         uint16                          CLut[256];
00091 
00092         int32                           PalIndex;
00093 
00094         int32                           NumFx;
00095         ElectricFx_Fx           Fx[ELECTRICFX_MAX_FX_TYPES];
00096 
00097 } Procedural;
00098 
00099 static int32 FxTypeDataTableSize = (sizeof(FxTypeDataTable)/sizeof(ElectricFx_TypeData));
00100 
00101 void            ElectricFx_Destroy(Procedural *Proc);
00102 geBoolean       ElectricFx_Animate(Procedural *Fx, float ElapsedTime);
00103 geBoolean       ElectricFx_Shade(Procedural *Fx);
00104 void            ElectricFx_Update(Procedural *Fx, float Time);
00105 
00106 ElectricFx_TypeData *ElectricFx_GetFxTypeDataFromString(const char *Str);
00107 int32 ElectricFx_GetPalIndexFromString(const char *Str);
00108 geBoolean       ElectricFx_FxParseData(ElectricFx_Fx *Fx);
00109 
00110 geBoolean       ElectricFx_InitPalette(Procedural *Proc);
00111 geBoolean       ElectricFx_InitBitmap(Procedural *Fx, geBitmap **ppBitmap);
00112 
00113 //====================================================================================
00114 //      ElectricFx_Create
00115 //====================================================================================
00116 Procedural *ElectricFx_Create(geBitmap **Bitmap, const char *StrParms)
00117 {
00118         Procedural      *Proc;
00119 
00120         assert(Bitmap);
00121         assert(StrParms);
00122 
00123         Proc = GE_RAM_ALLOCATE_STRUCT(Procedural);
00124 
00125         if (!Proc)
00126                 goto ExitWithError;
00127 
00128         memset(Proc, 0, sizeof(*Proc));
00129 
00130         // Parse the params...
00131         {
00132                 char            *Token;
00133                 char            Parms[1024];
00134 
00135                 strcpy(Parms, StrParms);
00136                 
00137                 Token = strtok(Parms, TOKEN_SEPERATOR);
00138 
00139                 if (!Token)             // If nothing was passed in, then default it to something cool
00140                 {
00141                         //strcpy(Parms, "Fx_PalSlime, Fx_Line, 0, 0, 127, 127, 127, 0, 127, 0");
00142                         strcpy(Parms, "Fx_PalSlime, Fx_EnergySpin, 63, 63");
00143 
00144                         Token = strtok(Parms, TOKEN_SEPERATOR);
00145 
00146                         assert(Token);
00147                 }
00148 
00149                 Proc->PalIndex = ElectricFx_GetPalIndexFromString(Token);
00150 
00151                 Token = strtok(NULL, TOKEN_SEPERATOR);
00152 
00153                 //if (!Token)
00154                 
00155                 while(Token)
00156                 {
00157                         ElectricFx_Fx   *Fx;
00158 
00159                         if (Proc->NumFx >= ELECTRICFX_MAX_FX_TYPES)
00160                                 break;          // No more room for more fx...
00161 
00162                         Fx = &Proc->Fx[Proc->NumFx++];
00163 
00164                         Fx->TypeData = ElectricFx_GetFxTypeDataFromString(Token);
00165 
00166                         if (!Fx->TypeData)
00167                         {
00168                                 geErrorLog_AddString(-1, "ElectricFx_Create:  Invalid FxType:", Token);
00169                                 goto ExitWithError;
00170                         }
00171 
00172                         if (!ElectricFx_FxParseData(Fx))
00173                         {
00174                                 geErrorLog_AddString(-1, "ElectricFx_Create:  ElectricFx_FxParseData failed.", NULL);
00175                                 goto ExitWithError;
00176                         }
00177 
00178                         Token = strtok(NULL, TOKEN_SEPERATOR);
00179                 }
00180         }
00181 
00182         if (!ElectricFx_InitBitmap(Proc, Bitmap))
00183                 goto ExitWithError;
00184 
00185         if (!ElectricFx_Animate(Proc, 0.1f))
00186         {
00187                 goto ExitWithError;
00188         }
00189 
00190         return Proc;
00191 
00192         ExitWithError:
00193         {
00194                 if (Proc)
00195                         ElectricFx_Destroy(Proc);
00196 
00197                 return NULL;
00198         }
00199 }
00200 
00201 //====================================================================================
00202 //      ElectricFx_Destroy
00203 //====================================================================================
00204 void ElectricFx_Destroy(Procedural *Proc)
00205 {
00206         assert(Proc);
00207 
00208         if (Proc->ZBuffer)
00209         {
00210                 geRam_Free(Proc->ZBuffer);
00211                 Proc->ZBuffer = NULL;
00212         }
00213         
00214         if (Proc->Bitmap)
00215         {
00216                 geBitmap_Destroy(&Proc->Bitmap);
00217                 Proc->Bitmap = NULL;
00218         }
00219 
00220         geRam_Free(Proc);
00221 }
00222 
00223 //====================================================================================
00224 //      ElectricFx_Animate
00225 //====================================================================================
00226 geBoolean ElectricFx_Animate(Procedural *Fx, float ElapsedTime)
00227 {
00228         if (!Fx->Bitmap)
00229                 return GE_TRUE;
00230 
00231         ElectricFx_Update(Fx, ElapsedTime);
00232 
00233         // Shade the Fx
00234         if (!ElectricFx_Shade(Fx))
00235                 return GE_FALSE;
00236 
00237         return GE_TRUE;
00238 }
00239 
00240 //====================================================================================
00241 //====================================================================================
00242 static Procedural_Table ElectricFx_Table = 
00243 {
00244         Procedurals_Version,Procedurals_Tag,
00245         "ElectricFx",
00246         ElectricFx_Create,
00247         ElectricFx_Destroy,
00248         ElectricFx_Animate
00249 };
00250 
00251 /*
00252 //====================================================================================
00253 //====================================================================================
00254 DllExport Procedural_Table *GetProcedural_Table()
00255 {
00256         return ElectricFx_GetProcedural_Table();
00257 }
00258 */
00259 
00260 //====================================================================================
00261 //====================================================================================
00262 Procedural_Table *ElectricFx_GetProcedural_Table(void)
00263 {
00264         return &ElectricFx_Table; 
00265 }
00266 
00268 //                                                                         //
00269 // sgn() - This function is used by Line() to determine the sign of a long //
00270 //                                                                         //
00272 
00273 int sgn (long a) 
00274 {
00275         if (a > 0) 
00276                 return +1;
00277         else if (a < 0) 
00278                 return -1;
00279         else 
00280                 return 0;
00281 }
00282 
00283 
00285 //                                                                         //
00286 // round() - This function is used by Line() to round a long to the        //
00287 //           nearest integer.                                              //
00288 //                                                                         //
00290 
00291 int round (long a) 
00292 {
00293         if ( (a - (int)a) < 0.5) 
00294                 return (int)floor(a);
00295         else 
00296                 return (int)ceil(a);
00297 }
00298 
00299 
00302 void ElectricFx_PutZ(Procedural *Fx, int x, int y, int ZVal, float ZAge) 
00303 {
00304         Fx->ZBuffer[(y&Fx->HMask)*Fx->Width+(x&Fx->WMask)] = ZVal;
00305 }
00306 
00307 
00309 //                                                                         //
00310 // Line() - This draws a line from a,b to c,d of color col.                //
00311 //          This function will be explained in more detail in tut3new.zip  //
00312 //                                                                         //
00314 void ElectricFx_ZLine(Procedural *Fx, int a, int b, int c, int d, int32 ZVal, float ZAge) 
00315 {
00316 
00317         long    u,s,v,d1x,d1y,d2x,d2y,m,n;
00318         int             i;
00319 
00320         u   = c-a;                      // x2-x1
00321         v   = d-b;                      // y2-y1
00322         d1x = sgn(u);           // d1x is the sign of u (x2-x1) (VALUE -1,0,1)
00323         d1y = sgn(v);           // d1y is the sign of v (y2-y1) (VALUE -1,0,1)
00324         d2x = sgn(u);           // d2x is the sign of u (x2-x1) (VALUE -1,0,1)
00325         d2y = 0;
00326         m   = abs(u);           // m is the distance between x1 and x2
00327         n   = abs(v);           // n is the distance between y1 and y2
00328 
00329         if (m<=n)                       // if the x distance is greater than the y distance
00330         {     
00331                 d2x = 0;
00332                 d2y = sgn(v);   // d2y is the sign of v (x2-x1) (VALUE -1,0,1)
00333                 m   = abs(v);   // m is the distance between y1 and y2
00334                 n   = abs(u);   // n is the distance between x1 and x2
00335         }
00336 
00337         s = (int)(m>>1);                                                // s is the m distance (either x or y) divided by 2
00338 
00339         for (i=round(m); i>0; i--)                              // repeat this loop until it
00340         { 
00341                                                                                         // is = to m (y or x distance)
00342                 ElectricFx_PutZ(Fx, a, b, ZVal, ZAge);// plot a pixel at the original x1, y1
00343 
00344                 s += n;                                                         // add n (dis of x or y) to s (dis of x of y)
00345                 if (s >= m)                                                     // if s is >= m (distance between y1 and y2)
00346                 {  
00347                         s -= m;
00348                         a += d1x;
00349                         b += d1y;
00350                 }
00351                 else 
00352                 {
00353                         a += d2x;
00354                         b += d2y;
00355                 }
00356         }
00357 
00358 }
00359 
00360 
00363 void ElectricFx_ZLine2(Procedural *Fx, int x1, int y1, int x2, int y2, int32 ZVal, float ZAge) 
00364 {
00365 
00366         int             x, y, xlength, ylength, dx, dy;
00367         float   xslope, yslope;
00368 
00369         xlength = abs(x1-x2);
00370 
00371         if ((x1-x2)  < 0) dx = -1;
00372         if ((x1-x2) == 0) dx =  0;
00373         if ((x1-x2)  > 0) dx = +1;
00374 
00375         ylength = abs(y1-y2);
00376         if ((y1-y2)  < 0) dy = -1;
00377         if ((y1-y2) == 0) dy =  0;
00378         if ((y1-y2)  > 0) dy = +1;
00379 
00380         if (dy == 0) 
00381         {
00382                 if (dx < 0)
00383                         for (x=x1; x<x2+1; x++)
00384                                 ElectricFx_PutZ(Fx, x, y1, ZVal, ZAge);
00385                 if (dx > 0)
00386                         for (x=x2; x<x1+1; x++)
00387                                 ElectricFx_PutZ(Fx, x, y1, ZVal, ZAge);
00388         }
00389 
00390         if (dx == 0) 
00391         {
00392                 if (dy < 0)
00393                         for (y=y1; y<y2+1; y++)
00394                                 ElectricFx_PutZ(Fx, x1, y, ZVal, ZAge);
00395                 if (dy > 0)
00396                         for (y=y2; y<y1+1; y++)
00397                                 ElectricFx_PutZ(Fx, x1, y, ZVal, ZAge);
00398         }
00399 
00400         if ((xlength != 0) && (ylength != 0)) 
00401         {
00402                 xslope = (float)xlength/(float)ylength;
00403                 yslope = (float)ylength/(float)xlength;
00404         }
00405         else 
00406         {
00407                 xslope = 0.0f;
00408                 yslope = 0.0f;
00409         }
00410 
00411         if ((xslope != 0) && (yslope != 0) && (yslope/xslope < 1) && (yslope/xslope > -1)) 
00412         {
00413                 if (dx < 0)
00414                 {
00415                         for (x=x1; x<x2+1; x++) 
00416                         {
00417                                 y = round((int)(yslope*x));
00418                                 ElectricFx_PutZ(Fx, x, y, ZVal, ZAge);
00419                         }
00420                 }
00421                 if (dx > 0)
00422                 {
00423                         for (x=x2; x<x1+1; x++) 
00424                         {
00425                                 y = round((int)(yslope*x));
00426                                 ElectricFx_PutZ(Fx, x, y, ZVal, ZAge);
00427                         }
00428                 }
00429         }
00430         else 
00431         {
00432                 if (dy < 0)
00433                 {
00434                         for (y=x1; y<x2+1; y++) 
00435                         {
00436                                 x = round((int)(xslope*y));
00437                                 ElectricFx_PutZ(Fx, x, y, ZVal, ZAge);
00438                         }
00439                 }
00440                 if (dy > 0)
00441                 {
00442                         for (y=x2; y<x1+1; y++) 
00443                         {
00444                                 x = round((int)(xslope*y));
00445                                 ElectricFx_PutZ(Fx, x, y, ZVal, ZAge);
00446                         }
00447                 }
00448         }
00449 
00450 }
00451 
00452 //==================================================================================
00453 //      ElectricFx_ElectricZLine_r
00454 //==================================================================================
00455 void ElectricFx_ElectricZLine_r(        Procedural *Fx, 
00456                                                         int32 x1, int32 y1, 
00457                                                         int32 x2, int32 y2, 
00458                                                         int32 ZVal, float ZAge,
00459                                                         int32 Recursion)
00460 {
00461         if (Recursion > 0)
00462         {
00463                 int32   MidX, MidY;
00464 
00465                 MidX = (x1+x2)>>1;
00466                 MidY = (y1+y2)>>1;
00467 
00468                 MidX += 8 - (rand()&15);
00469                 MidY += 8 - (rand()&15);
00470                 /*
00471                 if (MidX < 0)
00472                         MidX = 0;
00473                 else if (MidX >= Fx->Width)
00474                         MidX = Fx->Width-1;
00475         
00476                 if (MidY < 0)
00477                         MidY = 0;
00478                 else if (MidY >= Fx->Height)
00479                         MidY = Fx->Height-1;
00480                 */
00481 
00482                 ElectricFx_ElectricZLine_r(Fx, x1, y1, MidX, MidY, ZVal, ZAge, Recursion>>1);
00483                 ElectricFx_ElectricZLine_r(Fx, MidX, MidY, x2, y2, ZVal, ZAge, Recursion>>1);
00484         }
00485         else
00486         {
00487                 ElectricFx_ZLine(Fx, x1, y1, x2, y2, ZVal, ZAge);
00488         }
00489 }
00490 
00491 //==================================================================================
00492 //
00493 //==================================================================================
00494 geBoolean ElectricFx_Shade(Procedural *Fx)
00495 {
00496         uint8           *ZBuffer;
00497         uint8           *Bits;
00498         int32           i;
00499         geBitmap        *Lock;
00500 
00501         if (!geBitmap_LockForWriteFormat(Fx->Bitmap, &Lock, 0, 0, GE_PIXELFORMAT_8BIT_PAL))
00502                 goto Fail;
00503 
00504         if (!geBitmap_GetInfo(Lock, &(Fx->BitmapInfo),NULL) )
00505                 goto Fail;
00506 
00507         if (Fx->BitmapInfo.Format != GE_PIXELFORMAT_8BIT_PAL )
00508                 goto Fail;
00509 
00510         Bits = geBitmap_GetBits(Lock);
00511         ZBuffer = Fx->ZBuffer;
00512 
00513         // Shade the data for the Fx using the z buffer to provide
00514         // occlusion information.
00515         for(i=0;i < Fx->Size-5; i++, ZBuffer++)
00516         {
00517                 int32   Result;
00518                 int32   Val;
00519 
00520                 if(*ZBuffer == 0)
00521                         continue;
00522 
00523         #if 1
00524                 Val = (int32)*ZBuffer;
00525 
00526                 Result = Val;// - *(ZBuffer-1);
00527 
00528                 Bits[i] = min(Result + Bits[i], 255);
00529                 
00530                 if(Val > ZBuffer[1])
00531                         Bits[i+1] = max(Bits[i+1]-3,0);
00532                 if(Val > ZBuffer[2])
00533                         Bits[i+1] = max(Bits[i+2]-7,0);
00534                 if(Val > ZBuffer[3])
00535                         Bits[i+3] = max(Bits[i+3]-10,0);
00536                 if(Val > ZBuffer[4])
00537                         Bits[i+4] = max(Bits[i+4]-15,0);
00538                 if(Val > ZBuffer[5])
00539                         Bits[i+5] = max(Bits[i+5]-7,0);
00540         #else
00541                 Val = *ZBuffer;
00542 
00543                 Result = Val;
00544 
00545                 Bits[i] = min(Result + Bits[i], 255);
00546         #endif
00547 
00548         }
00549 
00550         // Smoth the bitmap
00551         for(i=0;i<2;i++)
00552         {
00553                 geBitmapUtil_SmoothBits(&Fx->BitmapInfo, Bits, Bits, 1, SMOOTH_WRAP);
00554         }
00555 
00556         if ( ! geBitmap_UnLock(Lock) )
00557                 goto Fail;
00558 
00559         return GE_TRUE;
00560 
00561         Fail:
00562         {
00563                 if (Lock )              
00564                         geBitmap_UnLock(Lock);
00565 
00566                 return GE_FALSE;
00567         }
00568 
00569 }
00570 
00571 //==================================================================================
00572 //==================================================================================
00573 void ElectricFx_Update(Procedural *EFx, float Time)
00574 {
00575         uint8                   *ZBuffer;
00576         ElectricFx_Fx   *Fx;
00577         int32                   i;
00578 
00579         ZBuffer = EFx->ZBuffer;
00580 
00581         // Zero the destination buffer
00582         memset(ZBuffer,0, EFx->Size*sizeof(uint8));
00583 
00584         Fx = EFx->Fx;
00585 
00586         for (i=0; i< EFx->NumFx; i++, Fx++)
00587         {
00588                 assert(Fx->TypeData);
00589 
00590                 switch(Fx->TypeData->Type)
00591                 {
00592                         case Fx_Line:
00593                         {
00594                                 ElectricFx_Vec2d        *pVec1, *pVec2;
00595 
00596                                 pVec1 = &Fx->Vecs[0];
00597                                 pVec2 = &Fx->Vecs[1];
00598                                 
00599                                 ElectricFx_ElectricZLine_r(EFx, pVec1->x, pVec1->y, pVec2->x, pVec2->y, 54, 1.0f, 16);
00600                                 break;
00601                         }
00602 
00603                         case Fx_Sparkle:
00604                         {
00605                                 int32   i;
00606 
00607                                 for (i=0; i<3; i++)
00608                                 {
00609                                         int32           x, y;
00610                                         float           r;
00611 
00612                                         r = ((float)i/6.0f)*PI_2;
00613 
00614                                         r += 2.0f - ((float)rand()/RAND_MAX)*4.0f;
00615                                 
00616                                         x = (int32)(cos(r)*60.0f);
00617                                         y = (int32)(sin(r)*60.0f);
00618 
00619                                         x += Fx->Vecs[0].x;
00620                                         y += Fx->Vecs[0].y;
00621 
00622                                         ElectricFx_ElectricZLine_r(EFx, Fx->Vecs[0].x, Fx->Vecs[0].y, x, y, 64, 1.0f, 4);
00623                                 }
00624                                 break;
00625                         }
00626 
00627                         case Fx_EnergySpin:
00628                         {
00629                                 int32                           j;
00630                                 ElectricFx_Vec2d        *pVec;
00631 
00632                                 pVec = Fx->Vecs;
00633 
00634                                 for (j=0; j<Fx->TypeData->NumVecs; j++, pVec++)
00635                                 {
00636                                         int32   i, x, y;
00637                                         float   r;
00638 
00639                                         for (i=0; i<3; i++)
00640                                         {
00641                                                 float   Val;
00642 
00643                                                 r = Fx->Rotation;
00644                                 
00645                                                 Val = ((float)i/3) * PI_2;
00646 
00647                                                 r += Val;
00648                                 
00649                                                 x = (int32)(cos(r)*63.0f);
00650                                                 y = (int32)(sin(r)*63.0f);
00651 
00652                                                 x += pVec->x;
00653                                                 y += pVec->y;
00654 
00655                                                 ElectricFx_ElectricZLine_r(EFx, pVec->x, pVec->y, x, y, 74, 1.0f, 8);
00656                                         }
00657                                 }
00658 
00659                                 Fx->Rotation += 2.0f*Time;              // 2 radians per sec
00660 
00661                                 if (Fx->Rotation > PI_2)
00662                                         Fx->Rotation -= PI_2;
00663 
00664                                 break;
00665                         }
00666                         default:
00667                         {
00668                                 break;
00669                         }
00670                 }
00671         }
00672 }
00673 
00674 typedef struct
00675 {
00676         float   f, a, r, g, b;
00677 } CPoint;
00678 
00679 static char PalStr[][256] = {
00680         "Fx_PalSlime",
00681         "Fx_PalFire",
00682         "Fx_PalOrange",
00683         "Fx_PalBlue",
00684 };
00685 
00686 #define PalStrTableSize (sizeof(PalStr) / sizeof(char[256]))
00687 
00688 static CPoint CPoints[PalStrTableSize][3] =
00689 {
00690         0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 
00691         30.0f, 70.0f, 0.0f, 30.0f, 0.0f, 
00692         180.0f, 255.0f, 255.0f, 255.0f, 25.0f,
00693         
00694         0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 
00695         30.0f, 70.0f, 40.0f, 0.0f, 0.0f, 
00696         180.0f, 255.0f, 255.0f, 255.0f, 25.0f,
00697 
00698         0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 
00699         30.0f, 70.0f, 70.0f, 10.0f, 0.0f, 
00700         180.0f, 255.0f, 255.0f, 255.0f, 25.0f,
00701         
00702         0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 
00703         30.0f, 60.0f, 5.0f, 5.0f, 30.0f, 
00704         180.0f, 255.0f, 100.0f, 100.0f, 165.0f
00705 };
00706 
00707 static uint16 LerpColor(float c1, float c2, float Ratio)
00708 {
00709         float   Val;
00710 
00711         Val = c1+(c2 - c1)*Ratio;
00712 
00713         Val *= 8.0f;
00714 
00715         if (Val > 255.0f)
00716                 Val = 255.0f;
00717 
00718         return (uint16)Val;
00719 }
00720 
00721 //====================================================================================
00722 //      ElectricFx_GetPalIndexFromString
00723 //====================================================================================
00724 int32 ElectricFx_GetPalIndexFromString(const char *Str)
00725 {
00726         int32           i;
00727 
00728         for (i=0; i<PalStrTableSize; i++)
00729         {
00730                 if (!stricmp(Str, PalStr[i]))
00731                         return i;
00732         }
00733 
00734         return 0;
00735 }
00736 
00737 //====================================================================================
00738 //      ElectricFx_GetFxTypeDataFromString
00739 //====================================================================================
00740 ElectricFx_TypeData     *ElectricFx_GetFxTypeDataFromString(const char *Str)
00741 {
00742         int32           i;
00743 
00744         for (i=0; i<FxTypeDataTableSize; i++)
00745         {
00746                 if (!stricmp(Str, FxTypeDataTable[i].Str))
00747                         return &FxTypeDataTable[i];
00748         }
00749 
00750         return NULL;
00751 }
00752 
00753 //====================================================================================
00754 //      ElectricFx_FxParseData
00755 //====================================================================================
00756 geBoolean ElectricFx_FxParseData(ElectricFx_Fx *Fx)
00757 {
00758         int32   VecNum;
00759         char    *Token;
00760 
00761         assert(Fx);
00762 
00763         VecNum = 0;
00764         
00765         while (1)
00766         {
00767                 // Parse the first token
00768                 Token = strtok(NULL, TOKEN_SEPERATOR);
00769 
00770                 assert(ElectricFx_GetFxTypeDataFromString(Token) == NULL);
00771 
00772                 if (!Token)
00773                         return GE_FALSE;
00774 
00775                 Fx->Vecs[VecNum].x = atoi(Token);
00776                 
00777                 // Parse the second token
00778                 Token = strtok(NULL, TOKEN_SEPERATOR);
00779 
00780                 assert(ElectricFx_GetFxTypeDataFromString(Token) == NULL);
00781 
00782                 if (!Token)
00783                         return GE_FALSE;
00784 
00785                 Fx->Vecs[VecNum].y = atoi(Token);
00786 
00787                 VecNum++;
00788 
00789                 if (VecNum >= Fx->TypeData->NumVecs)
00790                         break;
00791         }
00792         
00793         return GE_TRUE;
00794 }
00795 
00796 //====================================================================================
00797 //====================================================================================
00798 geBoolean ElectricFx_InitBitmap(Procedural *Fx, geBitmap **ppBitmap)
00799 {
00800         assert( ppBitmap);
00801 
00802         if ( ! *ppBitmap )
00803         {
00804                 *ppBitmap = geBitmap_Create(128, 128, 1, GE_PIXELFORMAT_8BIT_PAL);
00805                 
00806                 if ( ! *ppBitmap )
00807                         return GE_FALSE;
00808         }
00809         else
00810         {
00811                 geBitmap_CreateRef(*ppBitmap);
00812         }
00813 
00814         if (!geBitmap_SetFormat(*ppBitmap,GE_PIXELFORMAT_8BIT_PAL,GE_TRUE,255,NULL) )
00815                 return GE_FALSE;
00816 
00817         if (!geBitmap_ClearMips(*ppBitmap) )
00818                 return GE_FALSE;
00819 
00820         if (!geBitmap_SetPreferredFormat(*ppBitmap,GE_PIXELFORMAT_16BIT_4444_ARGB) )
00821                 return GE_FALSE;
00822 
00823         if (!geBitmapUtil_SetColor(*ppBitmap,0,0,0,0) )
00824                 return GE_FALSE;
00825 
00826         if (!geBitmap_GetInfo(*ppBitmap, &Fx->BitmapInfo, NULL))
00827                 return GE_FALSE;
00828 
00829         Fx->Bitmap = *ppBitmap;
00830 
00831         if (!ElectricFx_InitPalette(Fx))
00832                 return GE_FALSE;
00833 
00834         Fx->Width = Fx->BitmapInfo.Width;
00835         Fx->Height = Fx->BitmapInfo.Height;
00836         Fx->Size = Fx->Width*Fx->Height;
00837 
00838         Fx->WMask = Fx->Width-1;
00839         Fx->HMask = Fx->Height-1;
00840 
00841         Fx->ZBuffer = GE_RAM_ALLOCATE_ARRAY(uint8, Fx->Size);
00842 
00843         if (!Fx->ZBuffer)
00844                 return GE_FALSE;
00845 
00846         // Clear the buffers out
00847         memset(Fx->ZBuffer,0, Fx->Size*sizeof(uint8));
00848 
00849         return GE_TRUE;
00850 }
00851 
00852 //====================================================================================
00853 //====================================================================================
00854 geBoolean ElectricFx_InitPalette(Procedural *Proc)
00855 {
00856         geBitmap_Info   Info;
00857         geBitmap_Palette *Pal;
00858         void                    *PalData = NULL;
00859         gePixelFormat   PalFormat;
00860         int                             PalSize;
00861 
00862         Pal = geBitmap_Palette_Create(GE_PIXELFORMAT_32BIT_ARGB,256);
00863         if ( ! Pal )
00864                 goto fail;
00865         if ( ! geBitmap_SetPalette(Proc->Bitmap,Pal) )
00866                 goto fail;
00867         geBitmap_Palette_Destroy(&Pal);
00868 
00869         if (!geBitmap_GetInfo(Proc->Bitmap,&Info,NULL) )
00870                 goto fail;
00871 
00872         if (Info.Format != GE_PIXELFORMAT_8BIT_PAL )
00873                 goto fail;
00874 
00875         if (!(Pal = geBitmap_GetPalette(Proc->Bitmap)) )
00876                 goto fail;
00877 
00878         if (!geBitmap_Palette_Lock(Pal,&PalData, &PalFormat, &PalSize) )
00879                 goto fail;
00880         if ( PalSize < 256 )
00881                 goto fail;
00882 
00883         {
00884                 int32   i;
00885                 int32   NumControlPoints, Current;
00886                 CPoint  *pPoint;
00887 
00888                 // Fill the palette
00889                 NumControlPoints = 3;
00890                 
00891                 Current = 0;
00892 
00893                 pPoint = &CPoints[Proc->PalIndex][0];
00894 
00895                 for (i=0; i<256; i++)
00896                 {
00897                         float   Ratio;
00898                         int32   Next;
00899                         uint32  R,G,B,A;
00900                         uint8   *PalPtr;
00901 
00902                         Next = Current+1;
00903 
00904                         if (Next > NumControlPoints-1)
00905                                 Next = NumControlPoints-1;
00906 
00907                         Ratio = (float)(i-pPoint[Current].f)/pPoint[Next].f;
00908 
00909                         if (Ratio > 1.0f)
00910                                 Ratio = 1.0f;
00911                         else if (Ratio < 0.0f)
00912                                 Ratio = 0.0f;
00913 
00914                         PalPtr = ((uint8 *)PalData) + i * gePixelFormat_BytesPerPel(PalFormat);
00915 
00916                         A = (uint32)LerpColor(pPoint[Current].a, pPoint[Next].a, Ratio);
00917                         R = (uint32)LerpColor(pPoint[Current].r, pPoint[Next].r, Ratio);
00918                         G = (uint32)LerpColor(pPoint[Current].g, pPoint[Next].g, Ratio);
00919                         B = (uint32)LerpColor(pPoint[Current].b, pPoint[Next].b, Ratio);
00920 
00921                         gePixelFormat_PutColor(PalFormat,&PalPtr,R,G,B,A);
00922 
00923                         if ((float)i >= pPoint[Next].f)
00924                         {
00925                                 Current++;
00926 
00927                                 if (Current > NumControlPoints-1)
00928                                         Current = NumControlPoints-1;
00929                         }
00930                 }
00931         }
00932 
00933         PalData = NULL;
00934 
00935         if ( ! geBitmap_Palette_UnLock(Pal) )
00936                 return GE_FALSE;
00937 
00938         return GE_TRUE;
00939 
00940 fail:
00941 
00942         if ( PalData )
00943                 geBitmap_Palette_UnLock(Pal);
00944 
00945         return GE_FALSE;
00946 
00947 }

Generated on Tue Sep 30 12:35:41 2003 for GTestAndEngine by doxygen 1.3.2