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

smoke.c

Go to the documentation of this file.
00001 /****************************************************************************************/
00002 /*  Smoke.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 #define SMOOTH_WRAP GE_FALSE
00027 
00028 //====================================================================================
00029 //====================================================================================
00030 // 3D Smoke effect
00031 #define     NSMPARTICLES   1024
00032 
00033 typedef struct
00034 {
00035    // S15.16 fixed point
00036    int32                Velocity[3];
00037    int32                Position[3];
00038 } Smoke_Data;
00039 
00040 typedef struct Procedural
00041 {
00042         geBitmap                *Bitmap;
00043         geBitmap_Info   BitmapInfo;
00044 
00045         int32           Width;
00046         int32           Height;
00047         int32           Size;
00048 
00049         // Buffer of data about smoke particles
00050         Smoke_Data      Smbuf[NSMPARTICLES];
00051 
00052         int32           *ZBuffer;                               // 16.16 zbuffer
00053         float           *ZAge;                                  // ZBuffer age
00054 
00055         int32           NumParticles;
00056         float           x, y, z, vx, vy, vz;
00057 
00058         int32           PalIndex;
00059 } Procedural;
00060 
00061 void Smoke_Destroy(Procedural *Proc);
00062 geBoolean Smoke_Animate(Procedural *Smoke, float ElapsedTime);
00063 
00064 // Create a particle, based on Position and Velocity supplied, 
00065 // but with a small reandom deviation
00066 void  Smoke_FillParticle(Smoke_Data *particle,
00067                          float xp,
00068                          float yp,
00069                          float zp,
00070                          float xv,
00071                          float yv,
00072                          float zv);
00073 
00074 geBoolean Smoke_Shade(Procedural *Smoke);
00075 
00076 geBoolean Smoke_Update( Procedural *Smoke,
00077                                         int nparticles,
00078                                         float xp,
00079                                         float yp,
00080                                         float zp,
00081                                         float xv,
00082                                         float yv,
00083                                         float zv,
00084                                         int lightdir);
00085 
00086 int32 Smoke_GetPalIndexFromString(const char *Str);
00087 geBoolean Smoke_InitBitmap(Procedural *Proc, geBitmap **ppBitmap);
00088 geBoolean Smoke_InitPalette(Procedural *Proc);
00089 
00090 //====================================================================================
00091 //      Smoke_Create
00092 //====================================================================================
00093 Procedural *Smoke_Create(geBitmap **Bitmap, const char *StrParms)
00094 {
00095         Procedural      *Proc;
00096 
00097         assert(Bitmap);
00098         //assert(ParmStart);    // Unremark this when implemented!!!!!
00099 
00100         Proc = GE_RAM_ALLOCATE_STRUCT(Procedural);
00101 
00102         if (!Proc)
00103                 goto ExitWithError;
00104 
00105         memset(Proc, 0, sizeof(*Proc));
00106 
00107         {
00108                 char            *Token;
00109                 int32           TokenNum;
00110                 char            Parms[1024];
00111 
00112                 Proc->PalIndex = 0;
00113 
00114                 Proc->NumParticles = 128;
00115                 
00116                 Proc->x = 6.0f;
00117                 Proc->y = 64.0f;
00118                 Proc->z = 25.0f;
00119 
00120                 Proc->vx = 4.0f;
00121                 Proc->vy = 5.0f;
00122                 Proc->vz = 1.0f;
00123 
00124                 strcpy(Parms, StrParms);
00125                 
00126                 TokenNum = 0;
00127 
00128                 Token = strtok(Parms," \t,+\n\r");
00129 
00130                 while(Token)
00131                 {
00132                         switch(TokenNum)
00133                         {
00134                                 case 0:
00135                                         Proc->PalIndex = Smoke_GetPalIndexFromString(Token);
00136                                         break;
00137                                 case 1:
00138                                         Proc->NumParticles = atoi(Token);
00139                                         break;
00140                                 case 2:
00141                                         Proc->x = (float)atof(Token);
00142                                         break;
00143                                 case 3:
00144                                         Proc->y = (float)atof(Token);
00145                                         break;
00146                                 case 4:
00147                                         Proc->z = (float)atof(Token);
00148                                         break;
00149                                 case 5:
00150                                         Proc->vx = (float)atof(Token);
00151                                         break;
00152                                 case 6:
00153                                         Proc->vy = (float)atof(Token);
00154                                         break;
00155                                 case 7:
00156                                         Proc->vz = (float)atof(Token);
00157                                         break;
00158                         }
00159 
00160                         TokenNum++;
00161 
00162                         if (TokenNum >= 8)
00163                                 break;
00164 
00165                         Token = strtok(NULL," \t,+\n\r");
00166 
00167                 }
00168 
00169         }
00170 
00171         if (!Smoke_InitBitmap(Proc, Bitmap))
00172                 goto ExitWithError;
00173 
00174         if (Proc->x < 0.0f) 
00175                 Proc->x = 0.0f;
00176         if (Proc->x > Proc->Width-1) 
00177                 Proc->x = (float)Proc->Width-1;
00178         if (Proc->y < 0.0f) 
00179                 Proc->x = 0.0f;
00180         if (Proc->y > Proc->Height-1) 
00181                 Proc->y = (float)Proc->Height-1;
00182 
00183         if (!Smoke_Animate(Proc, 0.1f))
00184         {
00185                 goto ExitWithError;
00186         }
00187 
00188         return Proc;
00189 
00190         ExitWithError:
00191         {
00192                 if (Proc)
00193                         Smoke_Destroy(Proc);
00194 
00195                 return NULL;
00196         }
00197 }
00198 
00199 //====================================================================================
00200 //      Smoke_Destroy
00201 //====================================================================================
00202 void Smoke_Destroy(Procedural *Proc)
00203 {
00204         assert(Proc);
00205 
00206         if (Proc->ZBuffer)
00207         {
00208                 geRam_Free(Proc->ZBuffer);
00209                 Proc->ZBuffer = NULL;
00210         }
00211         
00212         if (Proc->ZAge)
00213         {
00214                 geRam_Free(Proc->ZAge);
00215                 Proc->ZAge = NULL;
00216         }
00217 
00218         if (Proc->Bitmap)
00219         {
00220                 geBitmap_Destroy(&Proc->Bitmap);
00221                 Proc->Bitmap = NULL;
00222         }
00223 
00224         geRam_Free(Proc);
00225 }
00226 
00227 //====================================================================================
00228 //      Smoke_Animate
00229 //====================================================================================
00230 geBoolean Smoke_Animate(Procedural *Smoke, float ElapsedTime)
00231 {
00232         if (!Smoke->Bitmap)
00233                 return GE_TRUE;
00234         
00235         if (!Smoke_Update(Smoke, Smoke->NumParticles, Smoke->x, Smoke->y, Smoke->z, Smoke->vx, Smoke->vy, Smoke->vz, 1))
00236                 return GE_FALSE;
00237 
00238         return GE_TRUE;
00239 }
00240 
00241 //====================================================================================
00242 //====================================================================================
00243 static Procedural_Table Smoke_Table = 
00244 {
00245         Procedurals_Version,Procedurals_Tag,
00246         "Smoke",
00247         Smoke_Create,
00248         Smoke_Destroy,
00249         Smoke_Animate
00250 };
00251 
00252 /*
00253 //====================================================================================
00254 //====================================================================================
00255 DllExport Procedural_Table *GetProcedural_Table()
00256 {
00257         return Smoke_GetProcedural_Table();
00258 }
00259 */
00260 
00261 //====================================================================================
00262 //====================================================================================
00263 Procedural_Table *Smoke_GetProcedural_Table(void)
00264 {
00265         return &Smoke_Table; 
00266 }
00267 
00268 //==================================================================================
00269 // Create a particle, based on Position and Velocity supplied, 
00270 // but with a small random deviation
00271 //==================================================================================
00272 void  Smoke_FillParticle(Smoke_Data *particle,
00273                          float xp,
00274                          float yp,
00275                          float zp,
00276                          float xv,
00277                          float yv,
00278                          float zv)
00279 {
00280    int   tmp;
00281 
00282    particle->Position[0] = (int32)((xp * 0x10000) + ((rand()&1) ? (rand() * xp) : (-rand() * xp)));
00283 
00284    tmp = rand() << 3;
00285    if(rand() & 1)
00286       tmp = -tmp;
00287 
00288    particle->Position[1] = (int32)(yp * 0x10000) + tmp;
00289 
00290    tmp = rand() << 1;
00291    if(rand() & 1)
00292       tmp = -tmp;
00293 
00294    particle->Position[2] = (int32)(zp * 0x10000) + tmp;
00295 
00296    tmp = rand() << 1;
00297    if(rand() & 1)
00298       tmp = -tmp;
00299    particle->Velocity[0] = (int32)(xv * 0x10000) + tmp;
00300 //   if(rand() & 1)
00301 //      particle->Velocity[0] = -particle->Velocity[0];
00302 
00303    particle->Velocity[1] = (int32)(yv * rand() );
00304    if(rand() & 1)
00305       particle->Velocity[1] = -particle->Velocity[1];
00306    particle->Velocity[2] = (int32)(zv * (rand() << 1));
00307    if(rand() & 1)
00308       particle->Velocity[2] = -particle->Velocity[2];
00309 }
00310 
00311 //==================================================================================
00312 //
00313 //==================================================================================
00314 geBoolean Smoke_Shade(Procedural *Smoke)
00315 {
00316         int32   *ZBuffer;
00317         float   *ZAge;
00318         uint8   *Bits;
00319         int             i;
00320 
00321         geBitmap        *Lock;
00322 
00323         if (!geBitmap_LockForWriteFormat(Smoke->Bitmap, &Lock, 0, 0, GE_PIXELFORMAT_8BIT_PAL))
00324                 goto Fail;
00325 
00326         if (!geBitmap_GetInfo(Lock, &(Smoke->BitmapInfo),NULL) )
00327                 goto Fail;
00328 
00329         if (Smoke->BitmapInfo.Format != GE_PIXELFORMAT_8BIT_PAL )
00330                 goto Fail;
00331 
00332         Bits = geBitmap_GetBits(Lock);
00333         ZBuffer = Smoke->ZBuffer;
00334         ZAge = Smoke->ZAge;
00335 
00336         // Shade the data for the smoke using the z buffer to provide
00337         // occlusion information.
00338         for(i=0;i != Smoke->Size-5; i++, ZBuffer++, ZAge++)
00339         {
00340                 int32   Result;
00341                 int32   Val;
00342 
00343                 if(*ZBuffer == 0)
00344                         continue;
00345 
00346                 Val = *ZBuffer;
00347 
00348                 Result = Val - *(ZBuffer-1);
00349                 Result >>= 16;
00350 
00351                 Result += 128;
00352                         
00353                 if(Result > 255)
00354                         Result = 255;
00355                 else if(Result < 0)
00356                         Result = 0;
00357 
00358                 // Age the smoke particle
00359                 Result *= (int32)*ZAge;
00360 
00361                 Bits[i] = min(Result + Bits[i], 255);
00362                 
00363                 if(Val > ZBuffer[1])
00364                         Bits[i+1] = max(Bits[i+1]-3,0);
00365                 if(Val > ZBuffer[2])
00366                         Bits[i+1] = max(Bits[i+2]-7,0);
00367                 if(Val > ZBuffer[3])
00368                         Bits[i+3] = max(Bits[i+3]-10,0);
00369                 if(Val > ZBuffer[4])
00370                         Bits[i+4] = max(Bits[i+4]-15,0);
00371                 if(Val > ZBuffer[5])
00372                         Bits[i+5] = max(Bits[i+5]-7,0);
00373         }
00374 
00375         // Smoth the bitmap
00376         for(i=0;i<2;i++)
00377         {
00378                 geBitmapUtil_SmoothBits(&Smoke->BitmapInfo, Bits, Bits, 1, SMOOTH_WRAP);
00379         }
00380 
00381         if (!geBitmap_UnLock(Lock))
00382                 goto Fail;
00383 
00384         return GE_TRUE;
00385 
00386         Fail:
00387         {
00388                 if (Lock )              
00389                         geBitmap_UnLock(Lock);
00390 
00391                 return GE_FALSE;
00392         }
00393 }
00394 
00395 //==================================================================================
00396 //==================================================================================
00397 geBoolean Smoke_Update( Procedural *Smoke,
00398                                         int nparticles,
00399                                         float xp,
00400                                         float yp,
00401                                         float zp,
00402                                         float xv,
00403                                         float yv,
00404                                         float zv,
00405                                         int lightdir)
00406 {
00407         int32           *ZBuffer;
00408         float           *ZAge;
00409         Smoke_Data      *Smbuf;
00410         int32           i;
00411 
00412         ZBuffer = Smoke->ZBuffer;
00413         ZAge = Smoke->ZAge;
00414         Smbuf = Smoke->Smbuf;
00415 
00416         // Zero the destination buffer
00417         memset(ZBuffer,0, Smoke->Size*sizeof(int32));
00418         memset(ZAge,0, Smoke->Size*sizeof(float));
00419 
00420         // Update Positions for all the particles in the smoke
00421         // and update the data in the destination buffer
00422         for(i=0;i<nparticles;i++)
00423         {
00424                 int   x,y;
00425                 
00426                 if(Smbuf[i].Velocity[0] < 0x1000)
00427                 {
00428                         // recreate the smoke particle if it is too old
00429                         Smoke_FillParticle(&Smbuf[i],xp,yp,zp,xv,yv,zv);
00430                         continue;
00431                 }
00432 
00433                 Smbuf[i].Position[0] += Smbuf[i].Velocity[0];
00434                 Smbuf[i].Position[1] += Smbuf[i].Velocity[1];
00435                 Smbuf[i].Position[2] += Smbuf[i].Velocity[2];
00436 
00437                 // Damp the Velocity by a percentage of itself
00438                 Smbuf[i].Velocity[0] -= (Smbuf[i].Velocity[0] >> 5);
00439                 Smbuf[i].Velocity[1] -= (Smbuf[i].Velocity[1] >> 5);
00440                 Smbuf[i].Velocity[1] -= 0x800;
00441                 Smbuf[i].Velocity[2] -= (Smbuf[i].Velocity[2] >> 5);
00442 
00443                 // Check if particle has moved off the texture map, and if so, recreate it
00444                 if((Smbuf[i].Position[0]>>16) > (Smoke->Width-1))
00445                         Smoke_FillParticle(&(Smbuf[i]),xp,yp,zp,xv,yv,zv);
00446                 else if ((Smbuf[i].Position[0]>>16) < 0)
00447                         Smoke_FillParticle(&(Smbuf[i]),xp,yp,zp,xv,yv,zv);
00448                 else if((Smbuf[i].Position[1]>>16) > (Smoke->Height-1) || (Smbuf[i].Position[1]>>16) < 0)
00449                         Smoke_FillParticle((&Smbuf[i]),xp,yp,zp,xv,yv,zv);
00450 
00451                 // Now plot this particle into the destination buffer if its Z is
00452                 // nearer than the one currently there
00453                 // Get integer coordinate
00454                 x = Smbuf[i].Position[0] >> 16;
00455                 y = Smbuf[i].Position[1] >> 16;
00456 
00457                 // Do Z buffer operation and age the particle.
00458                 if(Smbuf[i].Position[2] > ZBuffer[(y*Smoke->Width) + x])
00459                 {
00460                         ZBuffer[(y*Smoke->Width) + x] = Smbuf[i].Position[2];
00461                         ZAge[(y*Smoke->Width) + x] = Smbuf[i].Velocity[0] * (2.5f / 0x30000);
00462                 }
00463         }
00464 
00465         // Shade the smoke
00466         if (!Smoke_Shade(Smoke))
00467                 return GE_FALSE;
00468 
00469         return GE_TRUE;
00470 }
00471 
00472 typedef struct
00473 {
00474         float   f, a, r, g, b;
00475 } CPoint;
00476 
00477 static char PalStr[][256] = {
00478         "Smoke_PalSlime",
00479         "Smoke_PalFire",
00480         "Smoke_PalOrange",
00481         "Smoke_PalBlue",
00482 };
00483 
00484 #define PalStrTableSize (sizeof(PalStr) / sizeof(char[256]))
00485 
00486 static CPoint CPoints[PalStrTableSize][3] =
00487 {
00488         0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 
00489         30.0f, 70.0f, 0.0f, 30.0f, 0.0f, 
00490         180.0f, 255.0f, 255.0f, 255.0f, 25.0f,
00491         
00492         0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 
00493         30.0f, 70.0f, 40.0f, 0.0f, 0.0f, 
00494         180.0f, 255.0f, 255.0f, 255.0f, 25.0f,
00495 
00496         0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 
00497         30.0f, 70.0f, 70.0f, 10.0f, 0.0f, 
00498         180.0f, 255.0f, 255.0f, 255.0f, 25.0f,
00499         
00500         0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 
00501         30.0f, 60.0f, 5.0f, 5.0f, 30.0f, 
00502         180.0f, 255.0f, 100.0f, 100.0f, 165.0f
00503 };
00504 
00505 static uint16 Smoke_LerpColor(float c1, float c2, float Ratio)
00506 {
00507         float   Val;
00508 
00509         Val = c1+(c2 - c1)*Ratio;
00510 
00511         Val *= 8.0f;
00512 
00513         if (Val > 255.0f)
00514                 Val = 255.0f;
00515 
00516         return (uint16)Val;
00517 }
00518 
00519 //====================================================================================
00520 //      Smoke_GetPalIndexFromString
00521 //====================================================================================
00522 int32 Smoke_GetPalIndexFromString(const char *Str)
00523 {
00524         int32           i;
00525 
00526         for (i=0; i<PalStrTableSize; i++)
00527         {
00528                 if (!stricmp(Str, PalStr[i]))
00529                         return i;
00530         }
00531 
00532         return 0;
00533 }
00534 
00535 
00536 //====================================================================================
00537 //====================================================================================
00538 geBoolean Smoke_InitBitmap(Procedural *Proc, geBitmap **ppBitmap)
00539 {
00540         assert( ppBitmap);
00541 
00542         if ( ! *ppBitmap )
00543         {
00544                 *ppBitmap = geBitmap_Create(128, 128, 1, GE_PIXELFORMAT_8BIT_PAL);
00545                 
00546                 if ( ! *ppBitmap )
00547                         return GE_FALSE;
00548         }
00549         else
00550         {
00551                 geBitmap_CreateRef(*ppBitmap);
00552                 geBitmap_SetColorKey(*ppBitmap,GE_FALSE,0,0);
00553         }
00554 
00555         if (!geBitmap_SetFormat(*ppBitmap,GE_PIXELFORMAT_8BIT_PAL,GE_FALSE,0,NULL) )
00556                 return GE_FALSE;
00557 
00558         if (!geBitmap_ClearMips(*ppBitmap) )
00559                 return GE_FALSE;
00560 
00561         if (!geBitmap_SetPreferredFormat(*ppBitmap,GE_PIXELFORMAT_16BIT_4444_ARGB) )
00562                 return GE_FALSE;
00563 
00564         if (!geBitmapUtil_SetColor(*ppBitmap,0,0,0,0) )
00565                 return GE_FALSE;
00566 
00567         if (!geBitmap_GetInfo(*ppBitmap, &Proc->BitmapInfo, NULL))
00568                 return GE_FALSE;
00569 
00570         Proc->Bitmap = *ppBitmap;
00571 
00572         if (!Smoke_InitPalette(Proc))
00573                 return GE_FALSE;
00574 
00575         Proc->Width = Proc->BitmapInfo.Width;
00576         Proc->Height = Proc->BitmapInfo.Height;
00577         Proc->Size = Proc->Width*Proc->Height;
00578 
00579         Proc->ZBuffer = GE_RAM_ALLOCATE_ARRAY(int32, Proc->Size);
00580         
00581         if (!Proc->ZBuffer)
00582                 goto ExitWithError;
00583 
00584         Proc->ZAge = GE_RAM_ALLOCATE_ARRAY(float, Proc->Size);
00585 
00586         if (!Proc->ZAge)
00587                 goto ExitWithError;
00588 
00589         // Clear the buffers out
00590         memset(Proc->ZBuffer,0, Proc->Size*sizeof(int32));
00591         memset(Proc->ZAge,0, Proc->Size*sizeof(float));
00592         memset(Proc->Smbuf, 0, NSMPARTICLES*sizeof(Smoke_Data));
00593 
00594         return GE_TRUE;
00595         
00596         ExitWithError:
00597         {
00598                 if (Proc->ZBuffer)
00599                 {
00600                         geRam_Free(Proc->ZBuffer);
00601                         Proc->ZBuffer = NULL;
00602                 }
00603         
00604                 if (Proc->ZAge)
00605                 {
00606                         geRam_Free(Proc->ZAge);
00607                         Proc->ZAge = NULL;
00608                 }
00609         }
00610 
00611         return GE_FALSE;
00612 }
00613 
00614 //====================================================================================
00615 //====================================================================================
00616 geBoolean Smoke_InitPalette(Procedural *Proc)
00617 {
00618         geBitmap_Info   Info;
00619         geBitmap_Palette *Pal;
00620         void                    *PalData = NULL;
00621         gePixelFormat   PalFormat;
00622         int                             PalSize;
00623 
00624         Pal = geBitmap_Palette_Create(GE_PIXELFORMAT_32BIT_ARGB,256);
00625         if ( ! Pal )
00626                 goto fail;
00627         if ( ! geBitmap_SetPalette(Proc->Bitmap,Pal) )
00628                 goto fail;
00629         geBitmap_Palette_Destroy(&Pal);
00630 
00631         if (!geBitmap_GetInfo(Proc->Bitmap,&Info,NULL) )
00632                 goto fail;
00633 
00634         if (Info.Format != GE_PIXELFORMAT_8BIT_PAL )
00635                 goto fail;
00636 
00637         if (!(Pal = geBitmap_GetPalette(Proc->Bitmap)) )
00638                 goto fail;
00639 
00640         if (!geBitmap_Palette_Lock(Pal,&PalData, &PalFormat, &PalSize) )
00641                 goto fail;
00642         if ( PalSize < 256 )
00643                 goto fail;
00644 
00645         {
00646                 int32   i;
00647                 int32   NumControlPoints, Current;
00648                 CPoint  *pPoint;
00649 
00650                 // Fill the palette
00651                 NumControlPoints = 3;
00652                 
00653                 Current = 0;
00654 
00655                 pPoint = &CPoints[Proc->PalIndex][0];
00656 
00657                 for (i=0; i<256; i++)
00658                 {
00659                         float   Ratio;
00660                         int32   Next;
00661                         uint32  R,G,B,A;
00662                         uint8   *PalPtr;
00663 
00664                         Next = Current+1;
00665 
00666                         if (Next > NumControlPoints-1)
00667                                 Next = NumControlPoints-1;
00668 
00669                         Ratio = (float)(i-pPoint[Current].f)/pPoint[Next].f;
00670 
00671                         if (Ratio > 1.0f)
00672                                 Ratio = 1.0f;
00673                         else if (Ratio < 0.0f)
00674                                 Ratio = 0.0f;
00675 
00676                         PalPtr = ((uint8 *)PalData) + i * gePixelFormat_BytesPerPel(PalFormat);
00677 
00678                         A = (uint32)Smoke_LerpColor(pPoint[Current].a, pPoint[Next].a, Ratio);
00679                         R = (uint32)Smoke_LerpColor(pPoint[Current].r, pPoint[Next].r, Ratio);
00680                         G = (uint32)Smoke_LerpColor(pPoint[Current].g, pPoint[Next].g, Ratio);
00681                         B = (uint32)Smoke_LerpColor(pPoint[Current].b, pPoint[Next].b, Ratio);
00682 
00683                         gePixelFormat_PutColor(PalFormat,&PalPtr,R,G,B,A);
00684 
00685                         if ((float)i >= pPoint[Next].f)
00686                         {
00687                                 Current++;
00688 
00689                                 if (Current > NumControlPoints-1)
00690                                         Current = NumControlPoints-1;
00691                         }
00692                 }
00693         }
00694 
00695         PalData = NULL;
00696 
00697         if ( ! geBitmap_Palette_UnLock(Pal) )
00698                 return GE_FALSE;
00699 
00700         return GE_TRUE;
00701 
00702 fail:
00703 
00704         if ( PalData )
00705                 geBitmap_Palette_UnLock(Pal);
00706 
00707         return GE_FALSE;
00708 
00709 }

Generated on Tue Sep 30 12:36:22 2003 for GTestAndEngine by doxygen 1.3.2