1 /* filter.c version 0.7
2 * contient les filtres applicable a un buffer
3 * creation : 01/10/2000
4 * -ajout de sinFilter()
5 * -ajout de zoomFilter()
6 * -copie de zoomFilter() en zoomFilterRGB(), gérant les 3 couleurs
7 * -optimisation de sinFilter (utilisant une table de sin)
9 * -optimisation de la procedure de génération du buffer de transformation
10 * la vitesse est maintenant comprise dans [0..128] au lieu de [0..100]
13 /*#define _DEBUG_PIXEL; */
21 #include "goom_tools.h"
34 #define EFFECT_DISTORS 4
36 #define EFFECT_DISTORS 10
40 extern volatile guint32 resolx;
41 extern volatile guint32 resoly;
47 guint32 mmx_zoom_size;
51 extern unsigned int useAltivec;
52 extern void ppc_zoom(void);
53 extern void ppc_zoom_altivec(void);
54 unsigned int ppcsize4;
57 unsigned int *coeffs = 0, *freecoeffs = 0;
58 guint32 *expix1 = 0; /* pointeur exporte vers p1 */
59 guint32 *expix2 = 0; /* pointeur exporte vers p2 */
65 static int sintable [0xffff] ;
66 static int vitesse = 127;
67 static char theMode = AMULETTE_MODE ;
68 static int vPlaneEffect = 0;
69 static int hPlaneEffect = 0;
70 static char noisify = 2;
71 static int middleX , middleY ;
72 static unsigned char sqrtperte = 16 ;
74 static int * firedec = 0 ;
77 /* retourne x>>s , en testant le signe de x */
78 inline int ShiftRight (int x, const unsigned char s)
87 calculer px et py en fonction de x,y,middleX,middleY et theMode
88 px et py indique la nouvelle position (en sqrtperte ieme de pixel)
91 void calculatePXandPY (int x, int y, int *px, int *py)
93 if (theMode == WATER_MODE)
96 static int wavesp = 0 ;
99 yy = y + RAND () % 4 + wave / 10 ;
102 if (yy >= resoly) yy = resoly - 1 ;
104 *px = (x<<4) + firedec [yy] + (wave / 10) ;
105 *py = (y<<4) + 132 - ((vitesse < 132) ? vitesse : 131) ;
107 wavesp += RAND () % 3;
108 wavesp -= RAND () % 3;
109 if (wave < -10) wavesp += 2 ;
110 if (wave > 10) wavesp -= 2 ;
111 wave += (wavesp / 10) + RAND () % 3;
113 if (wavesp > 100) wavesp = (wavesp * 9) / 10 ;
119 int fvitesse = vitesse << 4 ;
123 x += RAND() % noisify;
124 x -= RAND() % noisify;
125 y += RAND() % noisify;
126 y -= RAND() % noisify;
129 if (hPlaneEffect) vx = ((x - middleX) << 9) + hPlaneEffect * (y - middleY);
130 else vx = (x - middleX) << 9 ;
132 if (vPlaneEffect) vy = ((y - middleY) << 9) + vPlaneEffect * (x - middleX);
133 else vy = (y - middleY) << 9 ;
138 dist = ShiftRight(vx,9) * ShiftRight(vx,9) + ShiftRight(vy,9) * ShiftRight(vy,9);
139 fvitesse *= 1024 + ShiftRight (
140 sintable [(unsigned short)(0xffff*dist*EFFECT_DISTORS)],6);
143 case CRYSTAL_BALL_MODE:
144 dist = ShiftRight(vx,9) * ShiftRight(vx,9) + ShiftRight(vy,9) * ShiftRight(vy,9);
145 fvitesse += (dist * EFFECT_DISTORS >> 10);
148 dist = ShiftRight(vx,9) * ShiftRight(vx,9) + ShiftRight(vy,9) * ShiftRight(vy,9);
149 fvitesse -= (dist * EFFECT_DISTORS >> 4);
152 dist = ShiftRight(vx,9) * ShiftRight(vx,9) + ShiftRight(vy,9) * ShiftRight(vy,9);
153 fvitesse -= (dist * EFFECT_DISTORS >> 9);
156 if (vx<0) *px = (middleX << 4) - (-(vx * fvitesse) >> 16) ;
157 else *px = (middleX << 4) + ((vx * fvitesse) >> 16) ;
158 if (vy<0) *py = (middleY << 4) - (-(vy * fvitesse) >> 16) ;
159 else *py = (middleY << 4) + ((vy * fvitesse) >> 16) ;
165 inline void setPixelRGB(Uint *buffer, Uint x, Uint y, Color c)
167 /* buffer[ y*WIDTH + x ] = (c.r<<16)|(c.v<<8)|c.b */
169 if ( x+y*resolx >= resolx * resoly)
171 fprintf (stderr,"setPixel ERROR : hors du tableau... %i, %i\n", x,y) ;
177 buffer[ y*resolx + x ] = (c.b<<16)|(c.v<<8)|c.r ;
179 buffer[ y*resolx + x ] = (c.r<<16)|(c.v<<8)|c.b ;
184 inline void setPixelRGB_ (Uint *buffer, Uint x, Color c)
187 if ( x >= resolx*resoly )
189 printf ("setPixel ERROR : hors du tableau... %i, %i\n", x,y) ;
195 buffer[ x ] = (c.b<<16)|(c.v<<8)|c.r ;
197 buffer[ x ] = (c.r<<16)|(c.v<<8)|c.b ;
203 inline void getPixelRGB (Uint *buffer, Uint x, Uint y, Color *c)
205 register unsigned char *tmp8;
208 if (x + y * resolx >= resolx*resoly)
210 printf ("getPixel ERROR : hors du tableau... %i, %i\n", x,y) ;
215 #ifdef __BIG_ENDIAN__
216 c->b = *(unsigned char *)(tmp8 = (unsigned char*)(buffer + (x + y*resolx)));
217 c->r = *(unsigned char *)(++tmp8);
218 c->v = *(unsigned char *)(++tmp8);
219 c->b = *(unsigned char *)(++tmp8);
222 /* ATTENTION AU PETIT INDIEN */
223 c->b = *(unsigned char *)(tmp8 = (unsigned char*)(buffer + (x + y*resolx)));
224 c->v = *(unsigned char *)(++tmp8);
225 c->r = *(unsigned char *)(++tmp8);
226 /* *c = (Color) buffer[x+y*WIDTH] ; */
231 inline void getPixelRGB_ (Uint *buffer, Uint x, Color *c)
233 register unsigned char *tmp8;
236 if ( x >= resolx*resoly )
238 printf ("getPixel ERROR : hors du tableau... %i\n", x) ;
243 #ifdef __BIG_ENDIAN__
244 c->b = *(unsigned char *)(tmp8 = (unsigned char*)(buffer + x));
245 c->r = *(unsigned char *)(++tmp8);
246 c->v = *(unsigned char *)(++tmp8);
247 c->b = *(unsigned char *)(++tmp8);
250 /* ATTENTION AU PETIT INDIEN */
251 c->b = *(unsigned char *)(tmp8 = (unsigned char*)(buffer + x));
252 c->v = *(unsigned char *)(++tmp8);
253 c->r = *(unsigned char *)(++tmp8);
254 /* *c = (Color) buffer[x+y*WIDTH] ; */
259 /*===============================================================*/
260 void zoomFilterFastRGB (Uint *pix1,
263 Uint resx, Uint resy)
265 static guint32 prevX = 0, prevY = 0;
267 static char reverse = 0 ; /*vitesse inversé..(zoom out) */
268 /* static int perte = 100; // 100 = normal */
269 static unsigned char pertedec = 8 ;
270 static char firstTime = 1;
274 /* static unsigned int prevX = 0, prevY = 0; */
281 Color col1,col2,col3,col4;
284 static unsigned int *pos10 = 0;
285 static unsigned int *c1 = 0,
291 if ((prevX != resx) || (prevY != resy))
300 if (pos10) free (pos10) ;
303 if (coeffs) free (freecoeffs) ;
309 if (firedec) free (firedec);
315 reverse = zf->reverse ;
316 vitesse = zf->vitesse ;
318 vitesse = 256 - vitesse ;
320 sqrtperte = zf->sqrtperte ;
322 pertedec = zf->pertedec ;
323 middleX = zf->middleX ;
324 middleY = zf->middleY ;
326 hPlaneEffect = zf->hPlaneEffect;
327 vPlaneEffect = zf->vPlaneEffect;
328 noisify = zf->noisify;
334 /* generation d'une table de sinus */
341 freecoeffs = (unsigned int *)
342 malloc (resx*resy*2*sizeof(unsigned int)+128);
343 coeffs = (guint32 *)((1+((unsigned int)(freecoeffs))/128)*128);
346 pos10 = (unsigned int *) malloc (resx*resy*sizeof(unsigned int)) ;
347 c1 = (unsigned int *) malloc (resx*resy*sizeof(unsigned int)) ;
348 c2 = (unsigned int *) malloc (resx*resy*sizeof(unsigned int)) ;
349 c3 = (unsigned int *) malloc (resx*resy*sizeof(unsigned int)) ;
350 c4 = (unsigned int *) malloc (resx*resy*sizeof(unsigned int)) ;
352 for (us=0; us<0xffff; us++)
354 sintable [us] = (int)(1024.0f * sin (us*2*3.31415f/0xffff)) ;
359 firedec = (int *) malloc (prevY * sizeof(int)) ;
360 for (loopv = prevY ; loopv != 0 ;)
362 static int decc = 0 ;
363 static int spdc = 0 ;
364 static int accel = 0 ;
366 firedec [loopv] = decc ;
377 spdc = spdc - RAND () % 3 + accel / 10 ;
379 spdc = spdc + RAND () % 3 + accel / 10 ;
381 if (decc > 8 && spdc > 1 )
382 spdc -= RAND () % 3 - 2 ;
384 if (decc < -8 && spdc < -1 )
385 spdc += RAND () % 3 + 2 ;
387 if (decc > 8 || decc < -8)
388 decc = decc * 8 / 9 ;
390 accel += RAND () % 2;
391 accel -= RAND () % 2;
401 /* generation du buffer */
402 for (y = 0 ; y < prevY ; y++)
403 for (x = 0; x < prevX ; x++)
406 unsigned char coefv,coefh;
408 /* calculer px et py en fonction de */
409 /* x,y,middleX,middleY et theMode */
410 calculatePXandPY (x,y,&px, &py) ;
411 if ((px == x << 4) && (py == y << 4))
414 if ( (py<0) || (px<0) ||
415 (py>=(prevY-1)*sqrtperte) ||
416 (px>=(prevX-1)*sqrtperte))
419 coeffs[(y*prevX+x)*2]=0 ;
420 coeffs[(y*prevX+x)*2+1]=0;
435 npx10 = (px/sqrtperte) ;
436 npy10 = (py/sqrtperte) ;
438 /* if (npx10 >= prevX) fprintf(stderr,"error npx:%d",npx10);
439 if (npy10 >= prevY) fprintf(stderr,"error npy:%d",npy10);
441 coefh = px % sqrtperte ;
442 coefv = py % sqrtperte ;
445 coeffs[pos] = (npx10 + prevX * npy10) * 4;
447 if (!(coefh || coefv))
448 coeffs[pos+1] = (sqrtperte*sqrtperte-1) ;
454 coeffs[pos+1] |= (coefh * (sqrtperte-coefv)) << 8 ;
455 coeffs[pos+1] |= ((sqrtperte-coefh) * coefv) << 16 ;
456 coeffs[pos+1] |= (coefh * coefv)<<24 ;
459 pos10[pos]= npx10 + prevX * npy10 ;
461 if (!(coefh || coefv))
462 c1[pos] = sqrtperte*sqrtperte-1 ;
464 c1[pos] = (sqrtperte-coefh) * (sqrtperte-coefv);
466 c2[pos] = coefh * (sqrtperte-coefv) ;
467 c3[pos] = (sqrtperte-coefh) * coefv ;
468 c4[pos] = coefh * coefv ;
478 mmx_zoom_size = prevX * prevY ;
486 ppcsize4 = ((unsigned int)(prevX*prevY))/4;
491 ppcsize4 = ((unsigned int)(prevX*prevY));
496 for (position=0; position<prevX*prevY; position++)
498 getPixelRGB_(pix1,pos10[position],&col1);
499 getPixelRGB_(pix1,pos10[position]+1,&col2);
500 getPixelRGB_(pix1,pos10[position]+prevX,&col3);
501 getPixelRGB_(pix1,pos10[position]+prevX+1,&col4);
503 couleur.r = col1.r * c1[position]
504 + col2.r * c2[position]
505 + col3.r * c3[position]
506 + col4.r * c4[position];
507 couleur.r >>= pertedec ;
509 couleur.v = col1.v * c1[position]
510 + col2.v * c2[position]
511 + col3.v * c3[position]
512 + col4.v * c4[position];
513 couleur.v >>= pertedec ;
515 couleur.b = col1.b * c1[position]
516 + col2.b * c2[position]
517 + col3.b * c3[position]
518 + col4.b * c4[position];
519 couleur.b >>= pertedec ;
521 setPixelRGB_(pix2,position,couleur);
527 void pointFilter(Uint *pix1, Color c,
528 float t1, float t2, float t3, float t4,
531 Uint x = (Uint)((int)middleX + (int)(t1*cos((float)cycle/t3)));
532 Uint y = (Uint)((int)middleY + (int)(t2*sin((float)cycle/t4)));
533 if ((x>1) && (y>1) && (x<resolx-2) && (y<resoly-2))
535 setPixelRGB(pix1, x+1, y, c);
536 setPixelRGB(pix1, x, y+1, c);
537 setPixelRGB(pix1, x+1, y+1, WHITE);
538 setPixelRGB(pix1, x+2, y+1, c);
539 setPixelRGB(pix1, x+1, y+2, c);