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

plasma.c

Go to the documentation of this file.
00001 
00002 // <> has jitter when CircleScale is very slow
00003 //      tried some anti-aliasing, but didn't seem to help
00004 
00005 //#define DO_TIMER
00006 
00007 #include "Plasma.h"
00008 #include "genesis.h"
00009 #include "ram.h"
00010 #include "gebmutil.h"
00011 #include "errorlog.h"
00012 #include "proceng.h"
00013 #include "procutil.h"
00014 #include <stdlib.h>
00015 #include <string.h>
00016 #include <assert.h>
00017 #include <math.h>
00018 
00019 /*
00020 
00021 params:
00022 
00023         ( circle_step, roll_step, do_alpha, do_displacement, [palette_spec] )
00024 
00025 example :
00026 
00027 wbm:Wall3 Plasma(0.005, 0, f, f, trig, 128,128,128,255, 5.0,1.0,5.0,0.0, 0.0,0.5,0.0,0.0 );
00028 wbm:Wall3 Plasma(0.01,  1, f, t );
00029 
00030 */
00031 
00032 // work on these :
00033 #define SIZE_SCALE      (150.0)
00034 
00035 #define R_PAL_STEP      (0.07)
00036 #define G_PAL_STEP      (0.05)
00037 #define B_PAL_STEP      (0.1)
00038 
00039 // Plasma               : 0.001983 : 6.3 %
00040 //              about two millis
00041 //              == 500 fps !
00042 
00043 #ifdef DO_TIMER
00044 #include "timer.h"
00045 
00046 TIMER_VARS(Plasma);
00047 #endif
00048 
00049 #define BM_CREATE_WIDTH         (128)
00050 #define BM_CREATE_HEIGHT        (128)
00051 #define BM_MAX_WIDTH            (128)
00052 #define BM_MAX_HEIGHT           (128)
00053 #define BM_MIN_WIDTH            (128)
00054 #define BM_MIN_HEIGHT           (128)
00055         // <> to support more widths we would need to make tables for each width;
00056         //      really, we should do this, and also dynamically allocate all tables
00057         //      (make a ref count in _Create and decrement it in _Destroy)
00058 
00059 #define TAB_WIDTH       (BM_MAX_WIDTH * 2)
00060 #define TAB_HEIGHT      (BM_MAX_HEIGHT* 2)
00061 
00062 geBoolean PlasmaAnimator_CreatePalette(Procedural * Proc, double time);
00063 geBoolean PlasmaAnimator_CreatePlasma(Procedural * Proc, double time);
00064 
00065 /**************************************************************/
00066 
00067 Procedural *Plasma_Create(geBitmap **ppBitmap, const char *ParmStart);
00068 void            Plasma_Destroy(Procedural *Proc);
00069 geBoolean       Plasma_Animate(Procedural *Plasma, float ElapsedTime);
00070 
00071 static Procedural_Table Plasma_Table = 
00072 {
00073         Procedurals_Version,Procedurals_Tag,
00074         "Plasma",
00075         Plasma_Create,
00076         Plasma_Destroy,
00077         Plasma_Animate
00078 };
00079 
00080 Procedural_Table * Plasma_GetProcedural_Table(void)
00081 {
00082         return &Plasma_Table;
00083 }
00084 
00085 /**********************************************************/
00086 
00087 typedef struct Procedural
00088 {
00089         geBitmap * Bitmap;
00090         geBoolean PlasmaPalette,Displacer;
00091         geBitmap * DisplaceOriginal;
00092         
00093         double  circle1,circle2,circle3,circle4,
00094                         circle5,circle6,circle7,circle8;
00095         double roll;
00096         double R,G,B;
00097         double CircleScale;
00098         double RollStep;
00099 } Procedural;
00100 
00101 /****/
00102 
00103 Procedural *Plasma_Create(geBitmap **ppBitmap, const char *ParmStart)
00104 {
00105 Procedural * P;
00106 geBoolean DoAlpha = GE_FALSE;
00107 
00108         P = geRam_Allocate(sizeof(Procedural));
00109         if ( ! P )
00110                 return NULL;
00111         assert(P);
00112         memset(P,0,sizeof(Procedural));
00113 
00114         if ( ! *ppBitmap )
00115         {
00116                 *ppBitmap = geBitmap_Create(BM_CREATE_WIDTH,BM_CREATE_HEIGHT,1, GE_PIXELFORMAT_8BIT_PAL);
00117                 if ( ! *ppBitmap )
00118                 {
00119                         geRam_Free(P);
00120                         return NULL;
00121                 }
00122         }
00123         else
00124         {
00125                 if ( ! geBitmap_SetFormat(*ppBitmap,GE_PIXELFORMAT_8BIT_PAL,GE_FALSE,0,NULL) )
00126                 {
00127                         geRam_Free(P);
00128                         return NULL;
00129                 }
00130 
00131                 geBitmap_ClearMips(*ppBitmap);
00132                 geBitmap_CreateRef(*ppBitmap);
00133         }
00134 
00135         if (geBitmap_Width( *ppBitmap) > BM_MAX_WIDTH  ||
00136                 geBitmap_Height(*ppBitmap) > BM_MAX_HEIGHT ||
00137                 geBitmap_Width( *ppBitmap) < BM_MIN_WIDTH  ||
00138                 geBitmap_Height(*ppBitmap) < BM_MIN_HEIGHT )
00139         {
00140                 geErrorLog_AddString(-1,"Plasm_Create : target Bitmap width not in supported ranged", NULL);
00141                 geRam_Free(P);
00142                 return NULL;
00143         }
00144 
00145         P->Bitmap = *ppBitmap;
00146 
00147         if ( ! ParmStart || strlen(ParmStart) < 10 )
00148         {
00149                 P->PlasmaPalette = GE_TRUE;
00150                 
00151                 if ( ! PlasmaAnimator_CreatePalette(P,0.0) )
00152                 {
00153                         geRam_Free(P);
00154                         return NULL;
00155                 }
00156 
00157                 P->CircleScale = 1.0;
00158                 P->RollStep = 1.0;
00159 
00160 #if 0           
00161                 P->R = 1.0/6.0*PI;
00162                 P->G = 3.0/6.0*PI;
00163                 P->B = 5.0/6.0*PI;
00164 #else
00165                 P->R = (rand() % 6)/6.0*PI;
00166                 P->G = (rand() % 6)/6.0*PI;
00167                 P->B = (rand() % 6)/6.0*PI;
00168 #endif
00169         }
00170         else
00171         {
00172         char * pstr;
00173         char ParmWork[1024];
00174 
00175                 P->PlasmaPalette = GE_FALSE;
00176 
00177                 strcpy(ParmWork,ParmStart);
00178                 pstr = strtok(ParmWork," ,\n\r\r");
00179 
00180                 P->CircleScale = atof(pstr);
00181                 pstr = strtok(NULL," ,\n\r\r");
00182 
00183                 P->RollStep = atof(pstr);
00184                 pstr = strtok(NULL," ,\n\r\r");
00185 
00186                 DoAlpha = ((toupper(*pstr) == 'T') ? GE_TRUE : atol(pstr));
00187                 pstr = strtok(NULL," ,\n\r\r");
00188 
00189                 P->Displacer = ((toupper(*pstr) == 'T') ? GE_TRUE : atol(pstr));
00190                 pstr = strtok(NULL," ,\n\r\r");
00191 
00192                 if ( ! P->Displacer )
00193                 {
00194                         ParmStart += (int)(pstr - ParmWork);
00195 
00196                         if ( ! ProcUtil_SetPaletteFromString(P->Bitmap,(char **)&ParmStart) )
00197                         {
00198                                 geBitmap_Destroy(&(P->Bitmap));
00199                                 geRam_Free(P);
00200                                 return NULL;
00201                         }
00202                 }
00203         }
00204 
00205         if ( P->Displacer )
00206         {
00207                 P->DisplaceOriginal = geBitmap_Create(BM_CREATE_WIDTH,BM_CREATE_HEIGHT,1, GE_PIXELFORMAT_8BIT_PAL);
00208                 if ( ! P->DisplaceOriginal )
00209                 {
00210                         geBitmap_Destroy(&(P->Bitmap));
00211                         geRam_Free(P);
00212                         return NULL;
00213                 }
00214                 geBitmap_BlitBitmap(P->Bitmap,P->DisplaceOriginal);
00215         }
00216 
00217         if ( DoAlpha )
00218         {
00219                 // this is the beauty of 'set preferred format'
00220                 //      the only difference between Plasma with and without alpha
00221                 //      is this one call !!!
00222                 if ( ! geBitmap_SetPreferredFormat(P->Bitmap,GE_PIXELFORMAT_16BIT_4444_ARGB) )
00223                         return GE_FALSE;
00224         }
00225 
00226         P->circle1 = ( rand() % 10 ) * 0.1;
00227         P->circle2 = ( rand() % 10 ) * 0.1;
00228         P->circle3 = ( rand() % 10 ) * 0.1;
00229         P->circle4 = ( rand() % 10 ) * 0.1;
00230         P->circle5 = ( rand() % 10 ) * 0.1;
00231         P->circle6 = ( rand() % 10 ) * 0.1;
00232         P->circle7 = ( rand() % 10 ) * 0.1;
00233         P->circle8 = ( rand() % 10 ) * 0.1;
00234                         
00235         #ifdef DO_TIMER
00236                 timerFP = fopen("q:\\timer.log","at+");
00237                 Timer_Start();
00238         #endif
00239 
00240 return P;
00241 }
00242 
00243 void Plasma_Destroy(Procedural * P)
00244 {
00245         if ( ! P )
00246                 return;
00247 
00248         if ( P->Bitmap )
00249                 geBitmap_Destroy(&(P->Bitmap));
00250 
00251         if ( P->DisplaceOriginal )
00252                 geBitmap_Destroy(&(P->DisplaceOriginal));
00253 
00254         #ifdef DO_TIMER
00255         Timer_Stop();
00256         if ( timerFP )
00257         {
00258                 TIMER_REPORT(Plasma);
00259         }
00260         #endif
00261 
00262         geRam_Free(P);
00263 }
00264 
00265 geBoolean Plasma_Animate(Procedural * P,float time)
00266 {
00267         assert(P && P->Bitmap);
00268 
00269 #ifdef DO_TIMER
00270         TIMER_P(Plasma);
00271 #endif
00272 
00273         if ( P->PlasmaPalette )
00274         {
00275                 if ( ! PlasmaAnimator_CreatePalette(P,time) )
00276                         return GE_FALSE;
00277         }
00278 
00279         if ( ! PlasmaAnimator_CreatePlasma(P,time) )
00280                 return GE_FALSE;
00281         
00282 #ifdef DO_TIMER
00283         TIMER_Q(Plasma);
00284         TIMER_COUNT();
00285 #endif
00286 
00287 return GE_TRUE;
00288 }
00289 
00290 geBoolean PlasmaAnimator_CreatePalette(Procedural *P,double time)
00291 {
00292 geBitmap_Palette *Pal;
00293 void * PalData = NULL;
00294 gePixelFormat PalFormat;
00295 int PalSize;
00296 
00297         if ( ! (Pal = geBitmap_GetPalette(P->Bitmap)) )
00298         {
00299 
00300                 Pal = geBitmap_Palette_Create(GE_PIXELFORMAT_32BIT_ARGB,256);
00301                 if ( ! Pal )
00302                         goto fail;
00303 
00304                 if ( ! geBitmap_SetPalette(P->Bitmap,Pal) )
00305                         goto fail;
00306 
00307                 geBitmap_Palette_Destroy(&Pal);
00308                 
00309                 if ( ! (Pal = geBitmap_GetPalette(P->Bitmap)) )
00310                         return GE_FALSE;
00311         }
00312 
00313         if ( ! geBitmap_Palette_Lock(Pal,&PalData, &PalFormat, &PalSize) )
00314                 goto fail;
00315         if ( PalSize < 256 )
00316                 goto fail;
00317 
00318         {
00319         int p,r,g,b;
00320         uint8 * PalPtr;
00321         double R,G,B;
00322         float u;
00323 
00324                 R = P->R;
00325                 G = P->G;
00326                 B = P->B;
00327 
00328                 PalPtr = PalData;
00329                 for(p=0;p<256;p++)
00330                 {
00331                         u = (float)((PI/128.0) * p);
00332 
00333                         // <>
00334                         //#define mycol(u,a) (int)((max(0.0,cos((u)+(a))))*255.0)
00335                         #define mycol(u,a) (int)((cos((u)+(a))+1)*127.0)
00336 
00337                         r = mycol(u,R);
00338                         g = mycol(u,G);
00339                         b = mycol(u,B);
00340 
00341                         gePixelFormat_PutColor(PalFormat,&PalPtr,r,g,b,0xFF);
00342                 }
00343 
00344                 P->R += R_PAL_STEP * time * 30.0;
00345                 P->G -= G_PAL_STEP * time * 30.0;
00346                 P->B += B_PAL_STEP * time * 30.0;
00347         }
00348 
00349         PalData = NULL;
00350 
00351         if ( ! geBitmap_Palette_UnLock(Pal) )
00352                 return GE_FALSE;
00353 
00354         return GE_TRUE;
00355 
00356 fail:
00357 
00358         if ( PalData )
00359                 geBitmap_Palette_UnLock(Pal);
00360 
00361         return GE_FALSE;
00362 }
00363 
00364 /*****
00365 
00366 tab1 is the distance to the center of the (doubled) image (hence the corner of the original)
00367 tab2 is basically sin(tab1)
00368 (could save memory by making a sintable[255] instead of tab2)
00369 
00370 sintab1[256] is too granular ; would have to use 
00371         int tab1[]
00372 and sintab1[10000] or something
00373 
00374 tables take 128k for a max size of 128x128
00375 
00376 ******/
00377 
00378 static uint8 tab1[TAB_WIDTH * TAB_HEIGHT];
00379 static uint8 tab2[TAB_WIDTH * TAB_HEIGHT];
00380 static uint8 sintab1[256];
00381 static signed char dtable[256];
00382 static int calculated = 0;
00383 
00384 void CalculateTables(Procedural * Proc)
00385 {
00386 int x,y;
00387 uint8 *ptab1,*ptab2;
00388         if ( calculated )
00389                 return;
00390         calculated = 1;
00391         ptab1 = tab1;
00392         ptab2 = tab2;
00393         for(y=0;y<TAB_HEIGHT;y++)
00394         {
00395                 for(x=0;x<TAB_WIDTH;x++)
00396                 {
00397                 double d_to_center,r,dx,dy;
00398 
00399                 #if 1   // TILE the texture correctly!
00400                 #if 0
00401                         dx = (x%128);
00402                         dy = (y%128);
00403                         dx = 64.0 - dx;
00404                         dy = 64.0 - dy;
00405                 #else
00406                         dx = SIZE_SCALE * sin(x*PI/128.0);
00407                         dy = SIZE_SCALE * cos(y*PI/128.0);
00408                 #endif
00409                 #else
00410                         dx = (TAB_WIDTH *0.5) - x;
00411                         dy = (TAB_HEIGHT*0.5) - y;
00412                 #endif
00413 
00414                 #if 0   // <> weak anti-alias
00415                         dx += (( rand() % 50 ) * 0.01);
00416                         dy += (( rand() % 50 ) * 0.01);
00417                         r = (( rand() % 50 ) * 0.01);
00418                 #else
00419                         r = 0.4;
00420                 #endif
00421 
00422                         d_to_center = sqrt( 16.0 + dx*dx + dy*dy ) - 4.0;
00423                         *ptab1++ = (uint8)(d_to_center * 5.0 + r );
00424                         *ptab2++= (uint8)((sin(d_to_center/9.5)+1.0)*90.0 + r);
00425                 }
00426         }
00427 
00428         for(x=0;x<256;x++)
00429         {
00430                 sintab1[x] = (uint8)((sin(x/(5.0*9.5))+1.0)*90.0 + 0.5);
00431                 dtable[x] = (signed char)(sin(x*2.0*PI/256) * 16.0);
00432         }
00433 }
00434 
00435 int DoCircle(double * pCircle, double step, int w, int doCos);
00436 
00437 geBoolean PlasmaAnimator_CreatePlasma(Procedural * Proc,double time)
00438 {
00439 geBitmap *PlasmaLock=NULL;
00440 geBitmap_Info PlasmaInfo;
00441 uint8 *Bits,*bptr;
00442 int x,y,w,h,s;
00443 geBitmap *Bitmap;
00444 
00445         Bitmap = Proc->Bitmap;
00446         assert(Bitmap);
00447         
00448         CalculateTables(Proc);
00449 
00450         geBitmap_SetGammaCorrection(Bitmap, 1.0f, GE_FALSE);
00451 
00452         if ( ! geBitmap_LockForWriteFormat(Bitmap,&PlasmaLock,0,0,GE_PIXELFORMAT_8BIT_PAL) )
00453                 goto fail;
00454 
00455         if ( ! geBitmap_GetInfo(PlasmaLock,&PlasmaInfo,NULL) )
00456                 goto fail;
00457 
00458         Bits = geBitmap_GetBits(PlasmaLock);
00459 
00460         if ( ! Bits )
00461                 goto fail; 
00462 
00463         w = PlasmaInfo.Width;
00464         h = PlasmaInfo.Height;
00465         s = PlasmaInfo.Stride;
00466 
00467         // could do every other pixel & smooth
00468         // main advantage : smaller table
00469 
00470         {
00471         int     x1,y1,x2,y2,
00472                 x3,y3,x4,y4,
00473                 o1,o2,o3,o4;
00474         uint8 *ptab1,*ptab2;
00475         uint8 roll;
00476         double CircleScale;
00477 
00478                 CircleScale = Proc->CircleScale * time * 2.0;
00479 
00480                 x1 = DoCircle(&(Proc->circle1),0.3  * CircleScale,w,1);
00481                 y1 = DoCircle(&(Proc->circle2),0.2  * CircleScale,h,0);
00482                 y2 = DoCircle(&(Proc->circle4),0.1  * CircleScale,h,1);
00483                 x2 = DoCircle(&(Proc->circle3),0.85 * CircleScale,w,0);
00484                 x3 = DoCircle(&(Proc->circle5),0.4  * CircleScale,w,1);
00485                 y3 = DoCircle(&(Proc->circle6),0.15 * CircleScale,h,0);
00486                 x4 = DoCircle(&(Proc->circle7),0.35 * CircleScale,w,1);
00487                 y4 = DoCircle(&(Proc->circle8),0.05 * CircleScale,h,0);
00488 
00489                 o1 = x1 + TAB_WIDTH*y1;
00490                 o2 = x2 + TAB_WIDTH*y2;
00491                 o3 = x3 + TAB_WIDTH*y3;
00492                 o4 = x4 + TAB_WIDTH*y4;
00493 
00494                 roll = (uint8)( Proc->roll + 0.5);
00495                 Proc->roll += Proc->RollStep * time * 30.0;
00496                         // roll uses the fact that we work modulo 255
00497 
00498                 // this is the inner loop;
00499                 // it's very lean, but also not blazing fast, cuz
00500                 //  this is very bad on the cache
00501                 // we have we have FIVE different active segments of memory,
00502                 //      (bptr,ptab1+o1,ptab2+o2,ptab2+o3,ptab2+o4) all of which are
00503                 // too large to fit in the L1 cache, so each mem-hit is 4 clocks
00504 
00505                 if ( Proc->Displacer )
00506                 {
00507                 geBitmap *Source,*SourceLock;
00508                 geBitmap_Info SourceInfo;
00509                 void * SourceBits;
00510                 int ss;
00511                 uint8 * sptr;
00512                         // instensity is a displacement
00513                 
00514                         Source = Proc->DisplaceOriginal;
00515                         assert(Source);
00516 
00517                         if ( ! geBitmap_LockForReadNative(Source,&SourceLock,0,0) )
00518                                 goto fail;
00519 
00520                         if ( ! geBitmap_GetInfo(SourceLock,&SourceInfo,NULL) )
00521                                 goto fail;
00522 
00523                         if ( ! (SourceBits = geBitmap_GetBits(SourceLock)) )
00524                                 goto fail; 
00525 
00526                         assert( SourceInfo.Width == w);
00527                         assert( SourceInfo.Height == h);
00528                         ss = SourceInfo.Stride;
00529 
00530                         bptr = Bits;
00531                         sptr = SourceBits;
00532                         for(y=0;y<h;y++)
00533                         {
00534                                 ptab1 = tab1 + TAB_WIDTH*y;
00535                                 ptab2 = tab2 + TAB_WIDTH*y;
00536                                 for(x=0;x<w;x++)
00537                                 {
00538                                 int o,sx;
00539                                         o = ptab1[o1] + ptab2[o2] + ptab2[o3] + ptab2[o4];
00540                                         o = (o + roll)&0xFF;
00541                                         o = dtable[o];
00542                                         ptab1++;
00543                                         ptab2++;
00544 
00545                                         sx = x + o;
00546                                         if ( sx < 0 ) sx += w;
00547                                         else if ( sx >= w ) sx -= w;
00548                                         assert( sx >= 0 && sx < w );
00549                                         *bptr++ = sptr[sx];
00550                                 }
00551                                 bptr += (s-w);
00552                                 sptr += ss;
00553                         }
00554 
00555                         geBitmap_UnLock(SourceLock);
00556                 }
00557                 else
00558                 {
00559                         // classic style
00560 
00561                         bptr = Bits;
00562                         if ( PlasmaInfo.HasColorKey )
00563                         {
00564                         uint8 CK,pel;
00565                                 CK = (uint8)PlasmaInfo.ColorKey;
00566                                 if ( CK > 200 )
00567                                 {
00568                                         for(y=0;y<h;y++)
00569                                         {
00570                                                 ptab1 = tab1 + TAB_WIDTH*y;
00571                                                 ptab2 = tab2 + TAB_WIDTH*y;
00572                                                 for(x=w;x--;)
00573                                                 {
00574                                                         pel = roll + ptab1[o1] + 
00575                                                                         ptab2[o2] + ptab2[o3] + ptab2[o4];
00576 
00577                                                         *bptr++ = pel%CK;
00578                                                         ptab1++;
00579                                                         ptab2++;
00580                                                 }
00581                                                 bptr += (s-w);
00582                                         }
00583                                 }
00584                                 else
00585                                 {
00586                                         for(y=0;y<h;y++)
00587                                         {
00588                                                 ptab1 = tab1 + TAB_WIDTH*y;
00589                                                 ptab2 = tab2 + TAB_WIDTH*y;
00590                                                 for(x=w;x--;)
00591                                                 {
00592                                                         pel = roll + ptab1[o1] + 
00593                                                                         ptab2[o2] + ptab2[o3] + ptab2[o4];
00594 
00595                                                         if ( pel == CK )
00596                                                                 pel ^= 1;
00597 
00598                                                         *bptr++ = pel;
00599                                                         ptab1++;
00600                                                         ptab2++;
00601                                                 }
00602                                                 bptr += (s-w);
00603                                         }
00604                                 }
00605                         }
00606                         else
00607                         {
00608                                 for(y=0;y<h;y++)
00609                                 {
00610                                         ptab1 = tab1 + TAB_WIDTH*y;
00611                                         ptab2 = tab2 + TAB_WIDTH*y;
00612                                         for(x=w;x--;)
00613                                         {
00614                                                 *bptr++ = roll + ptab1[o1] + 
00615                                                                 ptab2[o2] + ptab2[o3] + ptab2[o4];
00616                                                 ptab1++;
00617                                                 ptab2++;
00618                                         }
00619                                         bptr += (s-w);
00620                                 }
00621                         }
00622                 }
00623         }
00624 
00625 /*
00626         if ( ! geBitmapUtil_SmoothBits(&PlasmaInfo,Bits,Bits,1) )
00627                 goto fail;
00628 */
00629 
00630         if ( ! geBitmap_UnLock(PlasmaLock) )
00631                 goto fail;
00632 
00633         return GE_TRUE;
00634 fail:
00635 
00636         if ( PlasmaLock )               geBitmap_UnLock(PlasmaLock);
00637 
00638         return GE_FALSE;
00639 }
00640 
00641 
00642 int DoCircle(double * pCircle, double step, int w, int doCos)
00643 {
00644 double cp,c,cn;
00645 double xp,x,xn;
00646 int ix,ixp,ixn;
00647         
00648         w--;
00649 
00650         // try to do temporal anti-aliasing
00651         // <> doesn't seem to help
00652 
00653         c = *pCircle;
00654         cp = c - step;
00655         cn = c + step;
00656 
00657         *pCircle += step;
00658 
00659         if ( doCos )
00660         {
00661                 x  = w*0.5*(1.0 + cos(c));
00662                 xp = w*0.5*(1.0 + cos(cp));
00663                 xn = w*0.5*(1.0 + cos(cn));
00664         }
00665         else
00666         {
00667                 x  = w*0.5*(1.0 + sin(c));
00668                 xp = w*0.5*(1.0 + sin(cp));
00669                 xn = w*0.5*(1.0 + sin(cn));
00670         }
00671 
00672         ixn = (int)xn;
00673         ixp = (int)xp;
00674         
00675         if ( ixp == ixn )
00676         {
00677                 ix = ixp;
00678         }
00679         else
00680         {
00681                 x += ( rand() % 50 ) * 0.01;
00682                 ix = (int)((x + ixp + ixn)*(1.0/3.0));
00683         }
00684 
00685         assert( ix >= 0 && ix <= w );
00686 
00687 return ix;
00688 }

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