From: Miguel F. <mig...@us...> - 2002-12-25 04:59:18
|
Update of /cvsroot/xine/xine-lib/src/post/goom In directory sc8-pr-cvs1:/tmp/cvs-serv1423/goom Added Files: Makefile.am filters.c filters.h goom_config.h goom_core.c goom_core.h goom_tools.h graphic.c graphic.h ifs.c ifs.h ifs_display.c lines.c lines.h xine_goom.c Log Message: What a GOOM! Michael, please review the xine_goom.c code. i'm not sure about some post plugin concepts like "rewiring"... note: that code is quite cpu intensive, so i hardcoded it to 10fps. --- NEW FILE: Makefile.am --- ## ## Process this file with automake to produce Makefile.in ## AM_CFLAGS = @ANSI_FLAGS@ DEBUG_CFLAGS = @DEBUG_CFLAGS@ @ANSI_FLAGS@ LIBTOOL = $(SHELL) $(top_builddir)/libtool-nofpic libdir = $(XINE_PLUGINDIR)/post lib_LTLIBRARIES = xineplug_post_goom.la xineplug_post_goom_la_SOURCES = \ xine_goom.c \ goom_core.c goom_core.h \ goom_tools.h goom_config.h \ filters.c filters.h \ lines.c lines.h \ ifs_display.c ifs.c ifs.h \ graphic.c graphic.h xineplug_post_goom_la_LIBADD = $(XINE_LIB) xineplug_post_goom_la_LDFLAGS = -avoid-version -module @XINE_PLUGIN_MIN_SYMS@ debug: @$(MAKE) CFLAGS="$(DEBUG_CFLAGS)" install-debug: debug @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am mostlyclean-generic: -rm -f *~ \#* .*~ .\#* maintainer-clean-generic: -@echo "This command is intended for maintainers to use;" -@echo "it deletes files that may require special tools to rebuild." -rm -f Makefile.in --- NEW FILE: filters.c --- /* filter.c version 0.7 * contient les filtres applicable a un buffer * creation : 01/10/2000 * -ajout de sinFilter() * -ajout de zoomFilter() * -copie de zoomFilter() en zoomFilterRGB(), gérant les 3 couleurs * -optimisation de sinFilter (utilisant une table de sin) * -asm * -optimisation de la procedure de génération du buffer de transformation * la vitesse est maintenant comprise dans [0..128] au lieu de [0..100] */ //#define _DEBUG_PIXEL; #include "filters.h" #include "graphic.h" #include "goom_tools.h" #include <stdlib.h> #include <math.h> #include <stdio.h> #ifdef MMX #define USE_ASM #endif #ifdef POWERPC #define USE_ASM #endif #define EFFECT_DISTORS 4 extern volatile guint32 resolx; extern volatile guint32 c_resoly; guint32 mmx_zoom_size; #ifdef MMX void zoom_filter_mmx (int prevX, int prevY, unsigned int *expix1, unsigned int *expix2, int *brutS, int *brutD, int buffratio, int precalCoef[16][16]); #endif /* MMX */ #ifdef POWERPC extern unsigned int useAltivec; extern void ppc_zoom(unsigned int * frompixmap, unsigned int * topixmap, unsigned int sizex, unsigned int sizey, unsigned int * brutS, unsigned int * brutD, unsigned int buffratio,int precalCoef[16][16]); extern void ppc_zoom_altivec(void); unsigned int ppcsize4; #endif /* PowerPC */ signed int *brutS = 0, *freebrutS = 0; // source signed int *brutD = 0, *freebrutD = 0; // dest signed int *brutT = 0, *freebrutT = 0; // temp (en cours de génération) guint32 *expix1 = 0; // pointeur exporte vers p1 guint32 *expix2 = 0; // pointeur exporte vers p2 guint32 zoom_width; int prevX=0,prevY=0; static int sintable [0xffff] ; static int vitesse = 127; static char theMode = AMULETTE_MODE ; static int waveEffect = 0; static int hypercosEffect = 0; static int vPlaneEffect = 0; static int hPlaneEffect = 0; static char noisify = 2; static int middleX , middleY ; //static unsigned char sqrtperte = 16 ; /** modif by jeko : fixedpoint : buffration = (16:16) (donc 0<=buffration<=2^16) */ //static int buffratio = 0; int buffratio = 0; #define BUFFPOINTNB 16 #define BUFFPOINTMASK 0xffff #define BUFFINCR 0xff #define sqrtperte 16 // faire : a % sqrtperte <=> a & pertemask #define PERTEMASK 0xf // faire : a / sqrtperte <=> a >> PERTEDEC #define PERTEDEC 4 static int * firedec = 0 ; // retourne x>>s , en testant le signe de x inline int ShiftRight (int x, const unsigned char s) { if (x<0) return -(-x >> s) ; else return x >> s ; } /** modif d'optim by Jeko : precalcul des 4 coefs résultant des 2 pos */ int precalCoef[16][16]; void generatePrecalCoef () { static int firstime = 1; if (firstime) { int coefh,coefv; firstime = 0; // precalCoef = (int**) malloc (17*sizeof (int*)); for (coefh=0;coefh<16;coefh++) { // precalCoef [coefh] = (int *) malloc (17*sizeof (int)); for (coefv=0;coefv<16;coefv++) { int i; int diffcoeffh; int diffcoeffv; diffcoeffh = sqrtperte - coefh; diffcoeffv = sqrtperte - coefv; // coeffs[myPos] = ((px >> PERTEDEC) + prevX * (py >> PERTEDEC)) << 2; if (!(coefh || coefv)) i = 255 ; else { int i1,i2,i3,i4; i1 = diffcoeffh * diffcoeffv; i2 = coefh * diffcoeffv; i3 = diffcoeffh * coefv; i4 = coefh * coefv; if (i1) i1--; if (i2) i2--; if (i3) i3--; if (i4) i4--; i = (i1)|(i2<<8)|(i3<<16)|(i4<<24); } precalCoef [coefh][coefv] = i; } } } } /* calculer px et py en fonction de x,y,middleX,middleY et theMode px et py indique la nouvelle position (en sqrtperte ieme de pixel) (valeur * 16) */ inline void calculatePXandPY (int x, int y, int *px, int *py) { if (theMode == WATER_MODE) { static int wave = 0 ; static int wavesp = 0 ; int yy ; yy = y + RAND () % 4 - RAND () % 4 + wave / 10 ; if (yy < 0) yy = 0 ; if (yy >= c_resoly) yy = c_resoly - 1 ; *px = (x<<4) + firedec [yy] + (wave / 10) ; *py = (y<<4) + 132 - ((vitesse < 132) ? vitesse : 131) ; wavesp += RAND () % 3 - RAND () % 3 ; if (wave < -10) wavesp += 2 ; if (wave > 10) wavesp -= 2 ; wave += (wavesp / 10) + RAND () % 3 - RAND () % 3 ; if (wavesp > 100) wavesp = (wavesp * 9) / 10 ; } else { int dist=0 ,vx9,vy9; register int vx,vy ; int ppx,ppy; int fvitesse = vitesse << 4 ; if (noisify) { x += RAND() % noisify - RAND() % noisify ; y += RAND() % noisify - RAND() % noisify ; } vx = (x - middleX) << 9; vy = (y - middleY) << 9; if (hPlaneEffect) vx += hPlaneEffect * (y - middleY); // else vx = (x - middleX) << 9 ; if (vPlaneEffect) vy += vPlaneEffect * (x - middleX); // else vy = (y - middleY) << 9 ; if (waveEffect) { fvitesse *= 1024 + ShiftRight ( sintable [(unsigned short)(0xffff*dist*EFFECT_DISTORS)],6); fvitesse /= 1024 ; } if (hypercosEffect) { vx += ShiftRight(sintable [(-vy+dist)&0xffff],1); vy += ShiftRight(sintable [(vx+dist)&0xffff],1); } vx9 = ShiftRight(vx,9); vy9 = ShiftRight(vy,9); dist = vx9*vx9+vy9*vy9; switch (theMode) { case WAVE_MODE: fvitesse *= 1024 + ShiftRight ( sintable [(unsigned short)(0xffff*dist*EFFECT_DISTORS)],6); fvitesse /= 1024 ; break ; case CRYSTAL_BALL_MODE: fvitesse += (dist * EFFECT_DISTORS >> 10); break; case AMULETTE_MODE: fvitesse -= (dist * EFFECT_DISTORS >> 4); break; case SCRUNCH_MODE: fvitesse -= (dist * EFFECT_DISTORS >> 9); break; case HYPERCOS1_MODE: vx = vx + ShiftRight(sintable [(-vy+dist)&0xffff],1); vy = vy + ShiftRight(sintable [(vx+dist)&0xffff],1); break; case HYPERCOS2_MODE: vx = vx + ShiftRight(sintable [(-ShiftRight(vy,1)+dist)&0xffff],0); vy = vy + ShiftRight(sintable [(ShiftRight(vx,1)+dist)&0xffff],0); fvitesse = 128<<4; break; } if (fvitesse < -3024) fvitesse = -3024; if (vx<0) // pb avec decalage sur nb negatif ppx = - (-(vx * fvitesse) >> 16); /* 16 = 9 + 7 (7 = nb chiffre virgule de vitesse * (v = 128 => immobile) * 9 = nb chiffre virgule de vx) */ else ppx = ((vx * fvitesse) >> 16) ; if (vy<0) ppy = - (-(vy * fvitesse) >> 16) ; else ppy = ((vy * fvitesse) >> 16) ; *px=(middleX << 4)+ppx; *py=(middleY << 4)+ppy; } } //#define _DEBUG inline void setPixelRGB(Uint *buffer, Uint x, Uint y, Color c) { // buffer[ y*WIDTH + x ] = (c.r<<16)|(c.v<<8)|c.b #ifdef _DEBUG_PIXEL if ( x+y*resolx >= resolx * resoly) { fprintf (stderr,"setPixel ERROR : hors du tableau... %i, %i\n", x,y) ; //exit (1) ; } #endif //#ifdef USE_DGA // buffer[ y*resolx + x ] = (c.b<<16)|(c.v<<8)|c.r ; //#else //#ifdef COLOR_BGRA buffer[ y*resolx + x ] = (c.b<<(BLEU*8))|(c.v<<(VERT*8))|(c.r<<(ROUGE*8)) ; //#else // buffer[ y*resolx + x ] = (c.r<<16)|(c.v<<8)|c.b ; //#endif //#endif } inline void setPixelRGB_ (Uint *buffer, Uint x, Color c) { #ifdef _DEBUG if ( x >= resolx*c_resoly ) { printf ("setPixel ERROR : hors du tableau... %i\n", x) ; // exit (1) ; } #endif //#ifdef USE_DGA // buffer[ x ] = (c.b<<16)|(c.v<<8)|c.r ; //#else //#ifdef COLOR_BGRA // buffer[ x ] = (c.b<<24)|(c.v<<16)|(c.r<<8) ; //#else buffer[ x ] = (c.r<<(ROUGE*8))|(c.v<<(VERT*8))|c.b<<(BLEU*8) ; //#endif //#endif } inline void getPixelRGB (Uint *buffer, Uint x, Uint y, Color *c) { // register unsigned char *tmp8; unsigned int i; #ifdef _DEBUG if (x + y * resolx >= resolx * c_resoly) { printf ("getPixel ERROR : hors du tableau... %i, %i\n", x,y) ; // exit (1) ; } #endif //#ifdef __BIG_ENDIAN__ // c->b = *(unsigned char *)(tmp8 = (unsigned char*)(buffer + (x + y*resolx))); // c->r = *(unsigned char *)(++tmp8); // c->v = *(unsigned char *)(++tmp8); // c->b = *(unsigned char *)(++tmp8); //#else /* ATTENTION AU PETIT INDIEN */ i = *(buffer + (x + y*resolx)); c->b = (i>>(BLEU*8)) & 0xff; c->v = (i>>(VERT*8)) & 0xff; c->r = (i>>(ROUGE*8)) & 0xff; // *c = (Color) buffer[x+y*WIDTH] ; //#endif } inline void getPixelRGB_ (Uint *buffer, Uint x, Color *c) { register unsigned char *tmp8; #ifdef _DEBUG if ( x >= resolx * c_resoly ) { printf ("getPixel ERROR : hors du tableau... %i\n", x) ; // exit (1) ; } #endif #ifdef __BIG_ENDIAN__ c->b = *(unsigned char *)(tmp8 = (unsigned char*)(buffer + x)); c->r = *(unsigned char *)(++tmp8); c->v = *(unsigned char *)(++tmp8); c->b = *(unsigned char *)(++tmp8); #else /* ATTENTION AU PETIT INDIEN */ c->b = *(unsigned char *)(tmp8 = (unsigned char*)(buffer + x)); c->v = *(unsigned char *)(++tmp8); c->r = *(unsigned char *)(++tmp8); // *c = (Color) buffer[x+y*WIDTH] ; #endif } void c_zoom () { int myPos,myPos2; Color couleur; unsigned int ax = (prevX-1)<<PERTEDEC, ay = (prevY-1)<<PERTEDEC; int bufsize = prevX * prevY * 2; int bufwidth = prevX; for (myPos=0; myPos<bufsize; myPos+=2) { Color col1,col2,col3,col4; int c1,c2,c3,c4, px,py; int pos; int coeffs; int brutSmypos = brutS[myPos]; myPos2 = myPos + 1; px = brutSmypos + (((brutD[myPos] - brutSmypos)*buffratio) >> BUFFPOINTNB); brutSmypos = brutS[myPos2]; py = brutSmypos + (((brutD[myPos2] - brutSmypos)*buffratio) >> BUFFPOINTNB); if ((py>=ay) || (px>=ax)) { pos = coeffs = 0; } else { pos = ((px >> PERTEDEC) + prevX * (py >> PERTEDEC)); // coef en modulo 15 coeffs = precalCoef [px & PERTEMASK][py & PERTEMASK]; } getPixelRGB_(expix1,pos,&col1); getPixelRGB_(expix1,pos+1,&col2); getPixelRGB_(expix1,pos+bufwidth,&col3); getPixelRGB_(expix1,pos+bufwidth+1,&col4); c1 = coeffs; c2 = (c1 & 0x0000ff00) >> 8; c3 = (c1 & 0x00ff0000) >> 16; c4 = (c1 & 0xff000000) >> 24; c1 = c1 & 0xff; couleur.r = col1.r * c1 + col2.r * c2 + col3.r * c3 + col4.r * c4; if (couleur.r>5) couleur.r -= 5; couleur.r >>= 8 ; couleur.v = col1.v * c1 + col2.v * c2 + col3.v * c3 + col4.v * c4; if (couleur.v>5) couleur.v -= 5; couleur.v >>= 8 ; couleur.b = col1.b * c1 + col2.b * c2 + col3.b * c3 + col4.b * c4; if (couleur.b>5) couleur.b -= 5; couleur.b >>= 8 ; setPixelRGB_(expix2,myPos>>1,couleur); } } #ifdef USE_ASM static int use_asm = 1; void setAsmUse (int useIt) { use_asm = useIt; } int getAsmUse () { return use_asm; } #endif /*===============================================================*/ void zoomFilterFastRGB (Uint *pix1, Uint *pix2, ZoomFilterData *zf, Uint resx, Uint resy, int switchIncr, float switchMult) { register Uint x, y; static char reverse = 0 ; //vitesse inversé..(zoom out) static unsigned char pertedec = 8 ; static char firstTime = 1; expix1 = pix1 ; expix2 = pix2 ; /** changement de taille **/ if ((prevX != resx) || (prevY != resy)) { prevX = resx; prevY = resy; if (brutS) free (freebrutS) ; brutS = 0; if (brutD) free (freebrutD) ; brutD = 0; if (brutT) free (freebrutT) ; brutT = 0; middleX = resx / 2 ; middleY = resy - 1; firstTime = 1 ; if (firedec) free (firedec); firedec=0; } /** changement de config **/ if (zf) { reverse = zf->reverse ; vitesse = zf->vitesse ; if (reverse) vitesse = 256 - vitesse ; pertedec = zf->pertedec ; middleX = zf->middleX ; middleY = zf->middleY ; theMode = zf->mode ; hPlaneEffect = zf->hPlaneEffect; vPlaneEffect = zf->vPlaneEffect; waveEffect = zf->waveEffect; hypercosEffect = zf->hypercosEffect; noisify = zf->noisify; } /** generation d'un effet **/ if (firstTime || zf) { // generation d'une table de sinus if (firstTime) { unsigned short us ; int yofs; firstTime = 0; generatePrecalCoef (); freebrutS = (unsigned int *) malloc (resx*resy*2*sizeof(unsigned int)+128); brutS = (guint32 *)((1+((unsigned int)(freebrutS))/128)*128); freebrutD = (unsigned int *) malloc (resx*resy*2*sizeof(unsigned int)+128); brutD = (guint32 *)((1+((unsigned int)(freebrutD))/128)*128); freebrutT = (unsigned int *) malloc (resx*resy*2*sizeof(unsigned int)+128); brutT = (guint32 *)((1+((unsigned int)(freebrutT))/128)*128); /** modif here by jeko : plus de multiplications **/ { int yperte = 0; for (y=0, yofs=0; y<resy; y++,yofs+=resx) { int xofs = yofs << 1; int xperte = 0; for (x = 0; x<resx; x++) { brutS[xofs++] = xperte; brutS[xofs++] = yperte; xperte += sqrtperte; } yperte += sqrtperte; } buffratio = 0; } for (us=0; us<0xffff; us++) { sintable [us] = (int)(1024.0f * sin (us*2*3.31415f/0xffff)) ; } { int loopv ; firedec = (int *) malloc (prevY * sizeof(int)) ; for (loopv = prevY ; loopv != 0 ;) { static int decc = 0 ; static int spdc = 0 ; static int accel = 0 ; loopv -- ; firedec [loopv] = decc ; decc += spdc / 10 ; spdc = spdc + RAND () % 3 - RAND () % 3 ; if (decc > 4) spdc -= 1 ; if (decc < -4) spdc += 1 ; if (spdc > 30) spdc = spdc - RAND () % 3 + accel / 10 ; if (spdc < -30) spdc = spdc + RAND () % 3 + accel / 10 ; if (decc > 8 && spdc > 1 ) spdc -= RAND () % 3 - 2 ; if (decc < -8 && spdc < -1 ) spdc += RAND () % 3 + 2 ; if (decc > 8 || decc < -8) decc = decc * 8 / 9 ; accel += RAND () % 2 - RAND () % 2 ; if (accel > 20) accel -= 2 ; if (accel < -20) accel += 2 ; } } } // generation du buffer de trans { /* sauvegarde de l'etat actuel dans la nouvelle source */ y=prevX*prevY*2; for (x=0;x<y;x+=2) { int brutSmypos = brutS[x]; int x2 = x + 1; brutS[x] = brutSmypos + (((brutD[x] - brutSmypos)*buffratio) >> BUFFPOINTNB); brutSmypos = brutS[x2]; brutS[x2] = brutSmypos + (((brutD[x2] - brutSmypos)*buffratio) >> BUFFPOINTNB); } /* creation de la nouvelle destination */ for (y = 0 ; y < prevY ; y++) { for (x = 0; x < prevX ; x++) { int px,py; //unsigned char coefv,coefh; calculatePXandPY (x,y,&px, &py) ; if ((px == x << 4) && (py == y << 4)) { if (x > middleX) py += 2; else py -= 2; if (y > middleY) px += 2 ; else px -= 2; } brutD[(y*prevX+x)<<1] = px; brutD[((y*prevX+x)<<1)+1] = py; } } buffratio = 0; } } if (switchIncr != 0) { buffratio += switchIncr; if (buffratio > BUFFPOINTMASK) buffratio = BUFFPOINTMASK; } if (switchMult != 1.0f) { buffratio = (int)((float)BUFFPOINTMASK * (1.0f - switchMult) + (float)buffratio * switchMult); } zoom_width = prevX ; mmx_zoom_size = prevX * prevY ; #ifdef USE_ASM #ifdef MMX // mmx_zoom () ; if (use_asm) { zoom_filter_mmx (prevX, prevY, expix1, expix2, brutS, brutD, buffratio, precalCoef); } else { c_zoom (prevX, prevY); } #endif #ifdef POWERPC zoom_width = prevX; if (useAltivec) { //ppcsize4 = ((unsigned int)(prevX*prevY))/4; //ppc_zoom_altivec(); ppc_zoom(expix1,expix2,prevX,prevY, brutS, brutD, buffratio, precalCoef); // FIXME Altivec disabled since dynamic zooms } else { ppc_zoom(expix1,expix2,prevX,prevY, brutS, brutD, buffratio, precalCoef); } #endif #else c_zoom (prevX, prevY); #endif } void pointFilter(Uint *pix1, Color c, float t1, float t2, float t3, float t4, Uint cycle) { Uint x = (Uint)((int)middleX + (int)(t1*cos((float)cycle/t3))); Uint y = (Uint)((int)middleY + (int)(t2*sin((float)cycle/t4))); if ((x>1) && (y>1) && (x<resolx-2) && (y<c_resoly-2)) { setPixelRGB(pix1, x+1, y, c); setPixelRGB(pix1, x, y+1, c); setPixelRGB(pix1, x+1, y+1, WHITE); setPixelRGB(pix1, x+2, y+1, c); setPixelRGB(pix1, x+1, y+2, c); } } --- NEW FILE: filters.h --- #ifndef FILTERS_H #define FILTERS_H #include "goom_config.h" #include "graphic.h" #include "math.h" typedef struct { int vitesse ; /* 128 = vitesse nule... * 256 = en arriere hyper vite.. * 0 = en avant hype vite. */ unsigned char pertedec ; unsigned char sqrtperte ; int middleX,middleY ; /* milieu de l'effet */ char reverse ; /* inverse la vitesse */ char mode ; /* type d'effet à appliquer (cf les #define) */ /** @since June 2001 */ int hPlaneEffect ; /* deviation horitontale */ int vPlaneEffect ; /* deviation verticale */ /** @since April 2002 */ int waveEffect; /* applique une "surcouche" de wave effect */ int hypercosEffect; /* applique une "surcouche de hypercos effect */ char noisify ; /* ajoute un bruit a la transformation */ } ZoomFilterData ; #define NORMAL_MODE 0 #define WAVE_MODE 1 #define CRYSTAL_BALL_MODE 2 #define SCRUNCH_MODE 3 #define AMULETTE_MODE 4 #define WATER_MODE 5 #define HYPERCOS1_MODE 6 #define HYPERCOS2_MODE 7 void pointFilter(guint32 *pix1, Color c, float t1, float t2, float t3, float t4, guint32 cycle); /* filtre de zoom : * le contenu de pix1 est copie dans pix2. * zf : si non NULL, configure l'effet. * resx,resy : taille des buffers. */ void zoomFilterFastRGB (guint32 *pix1, guint32 *pix2, ZoomFilterData *zf, guint32 resx, guint32 resy, int switchIncr, float switchMult); /* filtre sin : le contenu de pix1 est copie dans pix2, avec l'effet appliqué cycle est la variable de temps. mode vaut SIN_MUL ou SIN_ADD rate est le pourcentage de l'effet appliqué lenght : la longueur d'onde (1..10) [5] speed : la vitesse (1..100) [10] */ /* void sinFilter(Uint *pix1,Uint *pix2, Uint cycle, Uint mode, Uint rate, char lenght, Uint speed); */ #define SIN_MUL 1 #define SIN_ADD 2 //#ifdef USE_ASM //void setAsmUse (int useIt); //#endif #endif --- NEW FILE: goom_config.h --- //#define VERSION "1.9dev5" //#define _DEBUG #define COLOR_BGRA //#define COLOR_ARGB #ifdef COLOR_BGRA /** position des composantes **/ #define ROUGE 2 #define BLEU 0 #define VERT 1 #define ALPHA 3 #else #define ROUGE 1 #define BLEU 3 #define VERT 2 #define ALPHA 0 #endif // target #define XMMS_PLUGIN //#define STANDALONE // for pc users with mmx processors. //#define MMX //#define POWERPC //#define VERBOSE #ifndef guint32 #define guint8 unsigned char #define guin16 unsigned short #define guint32 unsigned int #define gint8 signed char #define gint16 signed short int #define gint32 signed int #endif --- NEW FILE: goom_core.c --- #include <stdlib.h> #include <string.h> #include "goom_core.h" #include "goom_tools.h" #include "filters.h" #include "lines.h" #include "ifs.h" //#define VERBOSE #ifdef VERBOSE #include <stdio.h> #endif #define STOP_SPEED 128 #define TIME_BTW_CHG 300 /**-----------------------------------------------------** ** SHARED DATA ** **-----------------------------------------------------**/ static guint32 *pixel ; static guint32 *back ; static guint32 *p1,*p2,*tmp; static guint32 cycle; guint32 resolx, resoly, buffsize, c_black_height=0, /* hauteur des bande noires en bas et en haut */ c_offset=0, c_resoly=0; /* avec prise en compte de ca */ // effet de ligne.. static GMLine *gmline1 = NULL; static GMLine *gmline2 = NULL; void choose_a_goom_line (float *param1, float *param2, int *couleur, int *mode); void goom_init (guint32 resx, guint32 resy, int cinemascope) { #ifdef VERBOSE printf ("GOOM: init (%d, %d);\n", resx,resy); #endif if (cinemascope) c_black_height = resy/5; else c_black_height = 0; resolx = resx; resoly = resy; buffsize = resx * resy; c_offset = c_black_height * resx; c_resoly = resy - c_black_height * 2; pixel = (guint32 *) malloc (buffsize * sizeof(guint32) + 128); back = (guint32 *) malloc (buffsize * sizeof(guint32) + 128); RAND_INIT ((guint32)pixel) ; cycle = 0 ; p1 = (guint32 *)((1+((unsigned int)(pixel))/128)*128); p2 = (guint32 *)((1+((unsigned int)(back))/128)*128); init_ifs (resx,c_resoly); gmline1 = goom_lines_init (resx,c_resoly, GML_HLINE, c_resoly, GML_BLACK, GML_CIRCLE, 0.4f*(float)c_resoly, GML_VERT); gmline2 = goom_lines_init (resx,c_resoly, GML_HLINE, 0, GML_BLACK, GML_CIRCLE, 0.2f*(float)c_resoly, GML_RED); } void goom_set_resolution (guint32 resx, guint32 resy, int cinemascope) { free (pixel); free (back); if (cinemascope) c_black_height = resy/8; else c_black_height = 0; c_offset = c_black_height * resx; c_resoly = resy - c_black_height * 2; resolx = resx; resoly = resy; buffsize = resx * resy; pixel = (guint32 *) malloc (buffsize * sizeof(guint32) + 128); bzero(pixel,buffsize * sizeof(guint32) + 128); back = (guint32 *) malloc (buffsize * sizeof(guint32) + 128); bzero(back,buffsize * sizeof(guint32) + 128); p1 = (guint32 *)((1+((unsigned int)(pixel))/128)*128); p2 = (guint32 *)((1+((unsigned int)(back))/128)*128); init_ifs (resx,c_resoly); goom_lines_set_res (gmline1,resx,c_resoly); goom_lines_set_res (gmline2,resx,c_resoly); } guint32 * goom_update (gint16 data [2][512],int forceMode) { static int lockvar = 0 ; // pour empecher de nouveaux changements static int goomvar = 0 ; // boucle des gooms static int totalgoom = 0 ; // nombre de gooms par seconds static int agoom = 0 ; // un goom a eu lieu.. static int loopvar = 0 ; // mouvement des points static int speedvar = 0 ; // vitesse des particules // duree de la transition entre afficher les lignes ou pas #define DRAWLINES 70 static int lineMode = DRAWLINES ; // l'effet lineaire a dessiner static int nombreCDDC = 0; // nombre de Cycle Depuis Dernier Changement guint32 * return_val; guint32 pointWidth; guint32 pointHeight; int incvar ; // volume du son int accelvar ; // acceleration des particules int i ; float largfactor ; // elargissement de l'intervalle d'évolution des points static int ifs_incr = 1; // dessiner l'ifs (0 = non: > = increment) static int decay_ifs = 0; // disparition de l'ifs static int recay_ifs = 0; // dédisparition de l'ifs #define SWITCHMULT (19.0f/20.0f) #define SWITCHINCR 0xff static float switchMult = 1.0f; static int switchIncr = SWITCHINCR; /*static int lastgoom = 0;*/ static char goomlimit = 2 ; // sensibilité du goom static ZoomFilterData zfd = { 127, 8, 16, 1, 1, 0, NORMAL_MODE, 0, 0, 0, 0, 0}; ZoomFilterData *pzfd; /* test if the config has changed, update it if so */ pointWidth = (resolx * 2) / 5; pointHeight = ((c_resoly) * 2) / 5; /* ! etude du signal ... */ incvar = 0 ; for (i=0;i<512;i++) { if (incvar < data[0][i]) incvar = data[0][i] ; } accelvar = incvar / 5000 ; if (speedvar>5) { accelvar-- ; if (speedvar>20) accelvar -- ; if (speedvar>40) speedvar = 40 ; } accelvar -- ; speedvar += accelvar ; if (speedvar<0) speedvar=0; if (speedvar>40) speedvar = 40 ; /* ! calcul du deplacement des petits points ... */ largfactor = ((float)speedvar / 40.0f + (float)incvar / 50000.0f) / 1.5f ; if (largfactor>1.5f) largfactor = 1.5f ; if ((ifs_incr==1) && (iRAND(200)==0) && (decay_ifs<-300) && (agoom)) { decay_ifs = 200; } decay_ifs --; if (decay_ifs > 0) ifs_incr += 2; if (decay_ifs == 0) ifs_incr = 0; if ((ifs_incr==0) && (iRAND(200)==0) && (agoom) && (decay_ifs < -100)) { recay_ifs = 5; ifs_incr = 11; } if (recay_ifs) { ifs_incr -= 2; recay_ifs --; if (recay_ifs == 0) ifs_incr = 1; } if (ifs_incr > 0) ifs_update (p1+c_offset, p2+c_offset, resolx, c_resoly, ifs_incr); // (p1+c_offset)[resolx/2 + c_resoly/2 * resolx] = 0; if (ifs_incr != 1) { for (i = 1 ; i*15 <= speedvar + 15; i ++) { loopvar += speedvar + 1 ; pointFilter(p1+c_offset, YELLOW, ((pointWidth - 6.0f) * largfactor + 5.0f), ((pointHeight - 6.0f) * largfactor + 5.0f), i * 152.0f, 128.0f, loopvar + i*2032); pointFilter(p1+c_offset, ORANGE, ((pointWidth / 2) * largfactor) / i + 10.0f * i, ((pointHeight / 2) * largfactor) / i + 10.0f * i, 96.0f, i * 80.0f, loopvar / i); pointFilter(p1+c_offset, VIOLET, ((pointHeight / 3 + 5.0f) * largfactor) / i + 10.0f * i, ((pointHeight / 3 + 5.0f) * largfactor) / i + 10.0f * i, i + 122.0f, 134.0f, loopvar / i); pointFilter(p1+c_offset, BLACK, ((pointHeight / 3) * largfactor + 20.0f), ((pointHeight / 3) * largfactor + 20.0f), 58.0f, i * 66.0f, loopvar / i); pointFilter(p1+c_offset, WHITE, (pointHeight * largfactor + 10.0f * i) / i, (pointHeight * largfactor + 10.0f * i) / i, 66.0f, 74.0f, loopvar + i * 500); } } // par défaut pas de changement de zoom pzfd = NULL ; /* * Test forceMode */ #ifdef VERBOSE if (forceMode != 0) { printf ("forcemode = %d\n",forceMode); } #endif // diminuer de 1 le temps de lockage // note pour ceux qui n'ont pas suivis : le lockvar permet d'empecher un // changement d'etat du plugins juste apres un autre changement d'etat. oki ? if (--lockvar < 0) lockvar = 0 ; // temps du goom if (--agoom < 0) agoom = 0 ; // on verifie qu'il ne se pas un truc interressant avec le son. if ((accelvar>goomlimit) || (accelvar<-goomlimit) || (forceMode>0) || (nombreCDDC > TIME_BTW_CHG)) { // if (nombreCDDC > 300) { // } // UN GOOM !!! YAHOO ! totalgoom ++ ; agoom = 20 ; // mais pdt 20 cycles, il n'y en aura plus. // lineMode = (lineMode + 1)%40; // Tous les 10 gooms on change de mode lineaire // if (iRAND(12) == 0) // zfd.vitesse=STOP_SPEED-1; // if (iRAND(13) == 0) // zfd.vitesse=STOP_SPEED+1; // changement eventuel de mode switch (iRAND(28)) { case 0: case 10: zfd.hypercosEffect=iRAND(2); case 13: case 20: case 21: zfd.mode=WAVE_MODE; zfd.reverse=0; zfd.waveEffect= (iRAND(3)==0); if (iRAND(2)) zfd.vitesse = (zfd.vitesse + 127) >> 1; break; case 1: case 11: zfd.mode=CRYSTAL_BALL_MODE; zfd.waveEffect=0; zfd.hypercosEffect=0; break; case 2: case 12: zfd.mode=AMULETTE_MODE; zfd.waveEffect=(iRAND(3)==0); zfd.hypercosEffect=(iRAND(3)==0); break; case 3: zfd.mode = WATER_MODE ; zfd.waveEffect=0; zfd.hypercosEffect=0; break; case 4: case 14: zfd.mode=SCRUNCH_MODE; zfd.waveEffect=0; zfd.hypercosEffect=0; break; case 5: case 15: zfd.mode=HYPERCOS1_MODE; zfd.waveEffect=0; zfd.hypercosEffect=(iRAND(3)==0); break; case 6: case 16: zfd.mode=HYPERCOS2_MODE; zfd.waveEffect=0; zfd.hypercosEffect=0; break; case 7: case 17: zfd.mode=CRYSTAL_BALL_MODE; zfd.waveEffect=(iRAND(4)==0); zfd.hypercosEffect=iRAND(2); break; case 8: case 18: case 19: zfd.mode=SCRUNCH_MODE; zfd.waveEffect=1; zfd.hypercosEffect=1; break; default: zfd.mode=NORMAL_MODE; zfd.waveEffect=0; zfd.hypercosEffect=0; } } // tout ceci ne sera fait qu'en cas de non-blocage if (lockvar == 0) { // reperage de goom (acceleration forte de l'acceleration du volume) // -> coup de boost de la vitesse si besoin.. if ( (accelvar>goomlimit) || (accelvar<-goomlimit) ) { goomvar ++ ; //if (goomvar % 1 == 0) { guint32 vtmp ; guint32 newvit ; lockvar = 50; newvit = STOP_SPEED - speedvar / 2 ; // retablir le zoom avant.. if ((zfd.reverse) && (!(cycle%13)) && (rand ()%5==0)) { zfd.reverse = 0 ; zfd.vitesse = STOP_SPEED - 2 ; lockvar = 75 ; } if (iRAND (10) == 0) { zfd.reverse = 1; lockvar = 100; } if (iRAND(10) == 0) zfd.vitesse=STOP_SPEED-1; if (iRAND(12) == 0) zfd.vitesse=STOP_SPEED+1; // changement de milieu.. switch (iRAND(25)) { case 0: case 3: case 6: zfd.middleY = c_resoly - 1 ; zfd.middleX = resolx / 2 ; break ; case 1: case 4: zfd.middleX = resolx - 1 ; break ; case 2: case 5: zfd.middleX = 1 ; break ; default: zfd.middleY = c_resoly / 2 ; zfd.middleX = resolx / 2 ; } if (zfd.mode == WATER_MODE) { zfd.middleX = resolx / 2; zfd.middleY = c_resoly / 2; } switch (vtmp = (iRAND (15))) { case 0: zfd.vPlaneEffect = iRAND(3) - iRAND(3); zfd.hPlaneEffect = iRAND(3) - iRAND(3); break; case 3: zfd.vPlaneEffect = 0 ; zfd.hPlaneEffect = iRAND(8) - iRAND(8); break; case 4: case 5: case 6: case 7: zfd.vPlaneEffect = iRAND(5) - iRAND (5); zfd.hPlaneEffect = - zfd.vPlaneEffect; break; case 8: zfd.hPlaneEffect = 5 + iRAND (8); zfd.vPlaneEffect = - zfd.hPlaneEffect ; break; case 9: zfd.vPlaneEffect = 5 + iRAND (8); zfd.hPlaneEffect = - zfd.hPlaneEffect ; break; case 13: zfd.hPlaneEffect = 0; zfd.vPlaneEffect = iRAND(10) - iRAND(10); break; case 14: zfd.hPlaneEffect = iRAND(10) - iRAND(10); zfd.vPlaneEffect = iRAND(10) - iRAND(10); break; default: if (vtmp < 10) { zfd.vPlaneEffect = 0; zfd.hPlaneEffect = 0; } } if (iRAND (5) != 0) zfd.noisify = 0 ; else { zfd.noisify = iRAND (3) + 2 ; lockvar *= 2; } if (zfd.mode == AMULETTE_MODE) { zfd.vPlaneEffect = 0; zfd.hPlaneEffect = 0; zfd.noisify = 0; } if ((zfd.middleX == 1) || (zfd.middleX == resolx - 1)) { zfd.vPlaneEffect = 0 ; zfd.hPlaneEffect = iRAND (2) ? 0 : zfd.hPlaneEffect; } if (newvit < zfd.vitesse) // on accelere { pzfd = &zfd; if ( ( (newvit < STOP_SPEED - 7) && (zfd.vitesse < STOP_SPEED - 6) && (cycle % 3 == 0)) || (iRAND (40) == 0)) { zfd.vitesse = STOP_SPEED - iRAND(2) + iRAND(2) ; zfd.reverse = ! zfd.reverse ; } else { zfd.vitesse = (newvit + zfd.vitesse * 4) / 5 ; } lockvar += 50 ; } } if (lockvar > 150) { switchIncr = SWITCHINCR; switchMult = 1.0f; } } // mode mega-lent if (iRAND(700) == 0) { /* printf ("coup du sort...\n") ; */ pzfd = &zfd ; zfd.vitesse = STOP_SPEED - 1 ; zfd.pertedec = 8 ; zfd.sqrtperte = 16 ; goomvar = 1 ; lockvar += 50 ; switchIncr = SWITCHINCR; switchMult = 1.0f; } } // gros frein si la musique est calme if ((speedvar < 1) && (zfd.vitesse < STOP_SPEED - 4) && (cycle % 16 == 0)) { /* printf ("++slow part... %i\n", zfd.vitesse) ; */ pzfd = &zfd ; zfd.vitesse += 3 ; zfd.pertedec = 8 ; zfd.sqrtperte = 16 ; goomvar = 0 ; /* printf ("--slow part... %i\n", zfd.vitesse) ; */ } // baisser regulierement la vitesse... if ( (cycle % 73 == 0) && (zfd.vitesse < STOP_SPEED - 5)) { /* printf ("slow down...\n") ; */ pzfd = &zfd ; zfd.vitesse ++ ; } // arreter de decrémenter au bout d'un certain temps if ((cycle % 101 == 0) && (zfd.pertedec == 7)) { pzfd = &zfd ; zfd.pertedec=8 ; zfd.sqrtperte=16 ; } if ((forceMode > 0) && (forceMode <= NB_FX)) { pzfd=&zfd; pzfd->mode = forceMode - 1; } if (forceMode == -1) { pzfd = NULL; } if (pzfd != NULL) { static int exvit = 128; int dif; nombreCDDC = 0; switchIncr = SWITCHINCR; dif = zfd.vitesse - exvit; if (dif < 0) dif=-dif; if (dif > 2) { switchIncr *= (dif + 2) / 2; } exvit = zfd.vitesse; switchMult = 1.0f; if (((accelvar > goomlimit) && (totalgoom < 2))||(forceMode>0)) { switchIncr = 0; switchMult = SWITCHMULT; } } else { if (nombreCDDC > TIME_BTW_CHG) { pzfd = &zfd; nombreCDDC = 0; } else nombreCDDC ++; } #ifdef VERBOSE if (pzfd) { printf ("GOOM: pzfd->mode = %d\n", pzfd->mode); } #endif // si on est dans un goom : afficher les lignes... if (lineMode != DRAWLINES) { lineMode --; if (lineMode == -1) lineMode = 0; } if ((agoom > 0) && (totalgoom>2) && (cycle % 120 == 0) && (iRAND(3)==0)) { if (lineMode == 0) lineMode = DRAWLINES; else if (lineMode == DRAWLINES) { float param1,param2; int couleur; int mode; lineMode --; choose_a_goom_line (¶m1, ¶m2, &couleur, &mode); goom_lines_switch_to (gmline1, mode, param1, GML_BLACK); goom_lines_switch_to (gmline2, mode, param2, GML_BLACK); } } if ((lineMode != 0) || (agoom > 15)) { gmline2->power = gmline1->power; goom_lines_draw (gmline1,data[0],p1+c_offset); goom_lines_draw (gmline2,data[1],p1+c_offset); if (((cycle % 101)==9) && (iRAND (3)==1) && ((lineMode == 0) || (lineMode == DRAWLINES))) { float param1,param2; int couleur; int mode; choose_a_goom_line (¶m1, ¶m2, &couleur, &mode); goom_lines_switch_to (gmline1, mode, param1, couleur); goom_lines_switch_to (gmline2, mode, param2, 5-couleur); } } /* if (agoom > 15) goom_lines_draw (gmline,data, ( (zfd.middleX == resolx/2) && (zfd.middleY == c_resoly/2) && (zfd.mode != WATER_MODE) ) ? (lineMode/10) : 0, p2+c_offset,agoom-15); */ // Zoom here ! zoomFilterFastRGB (p1+c_offset, p2+c_offset, pzfd, resolx, c_resoly, switchIncr, switchMult) ; return_val = p2 ; tmp=p1; p1=p2; p2=tmp; // affichage et swappage des buffers.. cycle++; // tous les 100 cycles : vérifier si le taux de goom est correct // et le modifier sinon.. if (!(cycle%100)) { if (totalgoom>15) { // printf ("less gooms\n") ; goomlimit ++ ; } else { if ((totalgoom==0) && (goomlimit>1)) goomlimit -- ; } totalgoom = 0 ; } return return_val; } void goom_close () { if (pixel!=NULL) free (pixel) ; if (back!=NULL) free (back) ; pixel = back = NULL; RAND_CLOSE(); release_ifs (); goom_lines_free (&gmline1); goom_lines_free (&gmline2); } void choose_a_goom_line (float *param1, float *param2, int *couleur, int *mode) { *mode = iRAND (3); switch (*mode) { case GML_CIRCLE: if (iRAND (3)==0) { *param1 = *param2 = 0; } else if (iRAND(2)) { *param1 = 0.40f * c_resoly; *param2 = 0.20f * c_resoly; } else { *param1 = *param2 = c_resoly * 0.25; } break; case GML_HLINE: if (iRAND (4)) { *param1 = c_resoly / 7; *param2 = 6.0f * c_resoly / 7.0f; } else { *param1 = *param2 = c_resoly / 2.0f; } break; case GML_VLINE: if (iRAND (3)) { *param1 = resolx / 7.0f; *param2 = 6.0f * resolx / 7.0f; } else { *param1 = *param2 = resolx / 2.0f; } break; } *couleur = iRAND (6); } --- NEW FILE: goom_core.h --- #ifndef _GOOMCORE_H #define _GOOMCORE_H #include "goom_config.h" /* typedef union { guint32 val; struct { guint8 r; guint8 g; guint8 b; guint32 a; } rgba; } Pixel ; typedef Pixel * GoomBuffer; */ #define NB_FX 8 void goom_init (guint32 resx, guint32 resy, int cinemascope); void goom_set_resolution (guint32 resx, guint32 resy, int cinemascope); /* * forceMode == 0 : do nothing * forceMode == -1 : lock the FX * forceMode == 1..NB_FX : force a switch to FX n°forceMode */ guint32 * goom_update (gint16 data [2][512], int forceMode); void goom_close (); /* void goom_start (); void goom_stop (); */ #endif --- NEW FILE: goom_tools.h --- #ifndef _GOOMTOOLS_H #define _GOOMTOOLS_H #define NB_RAND 0x10000 /* in graphic.c */ extern int * rand_tab ; extern unsigned short rand_pos ; #define RAND_INIT(i) \ srand (i) ;\ if (!rand_tab)\ rand_tab = (int *) malloc (NB_RAND * sizeof(int)) ;\ rand_pos = 1 ;\ while (rand_pos != 0)\ rand_tab [rand_pos++] = rand () ; #define RAND()\ (rand_tab[rand_pos = rand_pos + 1]) #define RAND_CLOSE()\ free (rand_tab);\ rand_tab = 0; //#define iRAND(i) ((guint32)((float)i * RAND()/RAND_MAX)) #define iRAND(i) (RAND()%i) #endif --- NEW FILE: graphic.c --- #include "graphic.h" const Color BLACK = {0,0,0} ; const Color WHITE = {0xff,0xff,0xff} ; const Color RED = {0xff,0,0} ; const Color GREEN = {0,0xff,0} ; const Color BLUE = {0,0,0xff} ; const Color YELLOW = {0xff, 0xff, 0x33} ; const Color ORANGE = {0xff, 0xcc, 0x00} ; const Color VIOLET = {0x55, 0x00, 0xff} ; unsigned int SIZE ; unsigned int HEIGHT ; unsigned int WIDTH ; int * rand_tab = 0 ; unsigned short int rand_pos = 0 ; --- NEW FILE: graphic.h --- #ifndef GRAPHIC_H #define GRAPHIC_H typedef unsigned int Uint; typedef struct { unsigned short r,v,b; } Color; extern const Color BLACK; extern const Color WHITE; extern const Color RED; extern const Color BLUE; extern const Color GREEN; extern const Color YELLOW; extern const Color ORANGE; extern const Color VIOLET; inline void setPixelRGB (Uint *buffer, Uint x, Uint y, Color c) ; inline void getPixelRGB (Uint *buffer, Uint x, Uint y, Color *c) ; #endif /*GRAPHIC_H*/ --- NEW FILE: ifs.c --- /* -*- Mode: C; tab-width: 4 -*- */ /* ifs --- modified iterated functions system */ #if !defined( lint ) && !defined( SABER ) static const char sccsid[] = "@(#)ifs.c 5.00 2002/04/11 baffe"; #endif /*- * Copyright (c) 1997 by Massimino Pascal <Pas...@en...> * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, * provided that the above copyright notice appear in all copies and that * both that copyright notice and this permission notice appear in * supporting documentation. * * This file is provided AS IS with no warranties of any kind. The author * shall have no liability with respect to the infringement of copyrights, * trade secrets or any patents by this file or any part thereof. In no * event will the author be liable for any lost revenue or profits or * other special, indirect and consequential damages. * * If this mode is weird and you have an old MetroX server, it is buggy. * There is a free SuSE-enhanced MetroX X server that is fine. * * When shown ifs, Diana Rose (4 years old) said, "It looks like dancing." * * Revision History: * 11-Apr-2002: Make ifs.c system-indendant. (ifs.h added) * 01-Nov-2000: Allocation checks * 10-May-1997: jw...@jw...: turned into a standalone program. * Made it render into an offscreen bitmap and then copy * that onto the screen, to reduce flicker. */ //#ifdef STANDALONE #include <math.h> #include <stdlib.h> #include <stdio.h> #include "ifs.h" #define MODE_ifs #define PROGCLASS "IFS" #define HACK_INIT init_ifs #define HACK_DRAW draw_ifs #define ifs_opts xlockmore_opts #define DEFAULTS "*delay: 20000 \n" \ "*ncolors: 100 \n" #define SMOOTH_COLORS //#include "xlockmore.h" /* in xscreensaver distribution */ //#else /* STANDALONE */ //#include "xlock.h" /* in xlockmore distribution */ //#endif /* STANDALONE */ //#ifdef MODE_ifs //ModeSpecOpt ifs_opts = //{0, (XrmOptionDescRec *) NULL, 0, (argtype *) NULL, (OptionStruct *) NULL}; //#ifdef USE_MODULES //ModStruct ifs_description = //{"ifs", "init_ifs", "draw_ifs", "release_ifs", // "init_ifs", "init_ifs", (char *) NULL, &ifs_opts, // 1000, 1, 1, 1, 64, 1.0, "", // "Shows a modified iterated function system", 0, NULL}; //#endif #define LRAND() ((long) (rand() & 0x7fffffff)) #define NRAND(n) ((int) (LRAND() % (n))) #define MAXRAND (2147483648.0) /* unsigned 1<<31 as a float */ /*****************************************************/ typedef float DBL; typedef int F_PT; /* typedef float F_PT; */ /*****************************************************/ #define FIX 12 #define UNIT ( 1<<FIX ) #define MAX_SIMI 6 /* settings for a PC 120Mhz... */ #define MAX_DEPTH_2 10 #define MAX_DEPTH_3 6 #define MAX_DEPTH_4 4 #define MAX_DEPTH_5 3 #define DBL_To_F_PT(x) (F_PT)( (DBL)(UNIT)*(x) ) typedef struct Similitude_Struct SIMI; typedef struct Fractal_Struct FRACTAL; struct Similitude_Struct { DBL c_x, c_y; DBL r, r2, A, A2; F_PT Ct, St, Ct2, St2; F_PT Cx, Cy; F_PT R, R2; }; struct Fractal_Struct { int Nb_Simi; SIMI Components[5 * MAX_SIMI]; int Depth, Col; int Count, Speed; int Width, Height, Lx, Ly; DBL r_mean, dr_mean, dr2_mean; int Cur_Pt, Max_Pt; IFSPoint *Buffer1, *Buffer2; // Pixmap dbuf; // GC dbuf_gc; }; static FRACTAL *Root = (FRACTAL *) NULL, *Cur_F; /* Used by the Trace recursive method */ IFSPoint *Buf; static int Cur_Pt; /*****************************************************/ static DBL Gauss_Rand(DBL c, DBL A, DBL S) { DBL y; y = (DBL) LRAND() / MAXRAND; y = A * (1.0 - exp(-y * y * S)) / (1.0 - exp(-S)); if (NRAND(2)) return (c + y); return (c - y); } static DBL Half_Gauss_Rand(DBL c, DBL A, DBL S) { DBL y; y = (DBL) LRAND() / MAXRAND; y = A * (1.0 - exp(-y * y * S)) / (1.0 - exp(-S)); return (c + y); } static void Random_Simis(FRACTAL * F, SIMI * Cur, int i) { while (i--) { Cur->c_x = Gauss_Rand(0.0, .8, 4.0); Cur->c_y = Gauss_Rand(0.0, .8, 4.0); Cur->r = Gauss_Rand(F->r_mean, F->dr_mean, 3.0); Cur->r2 = Half_Gauss_Rand(0.0, F->dr2_mean, 2.0); Cur->A = Gauss_Rand(0.0, 360.0, 4.0) * (M_PI / 180.0); Cur->A2 = Gauss_Rand(0.0, 360.0, 4.0) * (M_PI / 180.0); Cur++; } } static void free_ifs_buffers(FRACTAL *Fractal) { if (Fractal->Buffer1 != NULL) { (void) free((void *) Fractal->Buffer1); Fractal->Buffer1 = (IFSPoint *) NULL; } if (Fractal->Buffer2 != NULL) { (void) free((void *) Fractal->Buffer2); Fractal->Buffer2 = (IFSPoint *) NULL; } } static void free_ifs(FRACTAL *Fractal) { free_ifs_buffers(Fractal); } /***************************************************************/ void init_ifs(int width, int height) { int i; FRACTAL *Fractal; // printf ("initing ifs\n"); if (Root == NULL) { Root = (FRACTAL *) malloc(sizeof(FRACTAL)); if (Root == NULL) return; Root->Buffer1 = (IFSPoint*)NULL; Root->Buffer2 = (IFSPoint*)NULL; } Fractal = Root; // fprintf (stderr,"--ifs freeing ex-buffers\n"); free_ifs_buffers(Fractal); // fprintf (stderr,"--ifs ok\n"); i = (NRAND(4)) + 2; /* Number of centers */ switch (i) { case 3: Fractal->Depth = MAX_DEPTH_3; Fractal->r_mean = .6; Fractal->dr_mean = .4; Fractal->dr2_mean = .3; break; case 4: Fractal->Depth = MAX_DEPTH_4; Fractal->r_mean = .5; Fractal->dr_mean = .4; Fractal->dr2_mean = .3; break; case 5: Fractal->Depth = MAX_DEPTH_5; Fractal->r_mean = .5; Fractal->dr_mean = .4; Fractal->dr2_mean = .3; break; default: case 2: Fractal->Depth = MAX_DEPTH_2; Fractal->r_mean = .7; Fractal->dr_mean = .3; Fractal->dr2_mean = .4; break; } // fprintf( stderr, "N=%d\n", i ); Fractal->Nb_Simi = i; Fractal->Max_Pt = Fractal->Nb_Simi - 1; for (i = 0; i <= Fractal->Depth + 2; ++i) Fractal->Max_Pt *= Fractal->Nb_Simi; if ((Fractal->Buffer1 = (IFSPoint *) calloc(Fractal->Max_Pt, sizeof (IFSPoint))) == NULL) { free_ifs(Fractal); return; } if ((Fractal->Buffer2 = (IFSPoint *) calloc(Fractal->Max_Pt, sizeof (IFSPoint))) == NULL) { free_ifs(Fractal); return; } // printf ("--ifs setting params\n"); Fractal->Speed = 6; Fractal->Width = width; /* modif by JeKo */ Fractal->Height = height; /* modif by JeKo */ Fractal->Cur_Pt = 0; Fractal->Count = 0; Fractal->Lx = (Fractal->Width - 1) / 2; Fractal->Ly = (Fractal->Height - 1) / 2; Fractal->Col = rand() % (width * height); /* modif by JeKo */ Random_Simis(Fractal, Fractal->Components, 5 * MAX_SIMI); /* #ifndef NO_DBUF if (Fractal->dbuf != None) XFreePixmap(display, Fractal->dbuf); Fractal->dbuf = XCreatePixmap(display, window, Fractal->Width, Fractal->Height, 1); /* Allocation checked * if (Fractal->dbuf != None) { XGCValues gcv; gcv.foreground = 0; gcv.background = 0; gcv.graphics_exposures = False; gcv.function = GXcopy; if (Fractal->dbuf_gc != None) XFreeGC(display, Fractal->dbuf_gc); if ((Fractal->dbuf_gc = XCreateGC(display, Fractal->dbuf, GCForeground | GCBackground | GCGraphicsExposures | GCFunction, &gcv)) == None) { XFreePixmap(display, Fractal->dbuf); Fractal->dbuf = None; } else { XFillRectangle(display, Fractal->dbuf, Fractal->dbuf_gc, 0, 0, Fractal->Width, Fractal->Height); XSetBackground(display, gc, MI_BLACK_PIXEL(mi)); XSetFunction(display, gc, GXcopy); } } #endif */ // MI_CLEARWINDOW(mi); /* don't want any exposure events from XCopyPlane */ // XSetGraphicsExposures(display, gc, False); } /***************************************************************/ /* Should be taken care of already... but just in case */ #if !defined( __GNUC__ ) && !defined(__cplusplus) && !defined(c_plusplus) #undef inline #define inline /* */ #endif static inline void Transform(SIMI * Simi, F_PT xo, F_PT yo, F_PT * x, F_PT * y) { F_PT xx, yy; xo = xo - Simi->Cx; xo = (xo * Simi->R) / UNIT; yo = yo - Simi->Cy; yo = (yo * Simi->R) / UNIT; xx = xo - Simi->Cx; xx = (xx * Simi->R2) / UNIT; yy = -yo - Simi->Cy; yy = (yy * Simi->R2) / UNIT; *x = ((xo * Simi->Ct - yo * Simi->St + xx * Simi->Ct2 - yy * Simi->St2) / UNIT) + Simi->Cx; *y = ((xo * Simi->St + yo * Simi->Ct + xx * Simi->St2 + yy * Simi->Ct2) / UNIT) + Simi->Cy; } /***************************************************************/ static void Trace(FRACTAL * F, F_PT xo, F_PT yo) { F_PT x, y, i; SIMI *Cur; Cur = Cur_F->Components; for (i = Cur_F->Nb_Simi; i; --i, Cur++) { Transform(Cur, xo, yo, &x, &y); Buf->x = F->Lx + (x * F->Lx / (UNIT * 2)); Buf->y = F->Ly - (y * F->Ly / (UNIT * 2)); Buf++; Cur_Pt++; if (F->Depth && ((x - xo) >> 4) && ((y - yo) >> 4)) { F->Depth--; Trace(F, x, y); F->Depth++; } } } static void Draw_Fractal(/*ModeInfo * mi*/) { FRACTAL *F = Root; int i, j; F_PT x, y, xo, yo; SIMI *Cur, *Simi; for (Cur = F->Components, i = F->Nb_Simi; i; --i, Cur++) { Cur->Cx = DBL_To_F_PT(Cur->c_x); Cur->Cy = DBL_To_F_PT(Cur->c_y); Cur->Ct = DBL_To_F_PT(cos(Cur->A)); Cur->St = DBL_To_F_PT(sin(Cur->A)); Cur->Ct2 = DBL_To_F_PT(cos(Cur->A2)); Cur->St2 = DBL_To_F_PT(sin(Cur->A2)); Cur->R = DBL_To_F_PT(Cur->r); Cur->R2 = DBL_To_F_PT(Cur->r2); } Cur_Pt = 0; Cur_F = F; Buf = F->Buffer2; for (Cur = F->Components, i = F->Nb_Simi; i; --i, Cur++) { xo = Cur->Cx; yo = Cur->Cy; for (Simi = F->Components, j = F->Nb_Simi; j; --j, Simi++) { if (Simi == Cur) continue; Transform(Simi, xo, yo, &x, &y); Trace(F, x, y); } } /* Erase previous */ /* if (F->Cur_Pt) { XSetForeground(display, gc, MI_BLACK_PIXEL(mi)); if (F->dbuf != None) { XSetForeground(display, F->dbuf_gc, 0); */ /* XDrawPoints(display, F->dbuf, F->dbuf_gc, F->Buffer1, F->Cur_Pt, CoordModeOrigin); */ /* XFillRectangle(display, F->dbuf, F->dbuf_gc, 0, 0, F->Width, F->Height); } else XDrawPoints(display, window, gc, F->Buffer1, F->Cur_Pt, CoordModeOrigin); } if (MI_NPIXELS(mi) < 2) XSetForeground(display, gc, MI_WHITE_PIXEL(mi)); else XSetForeground(display, gc, MI_PIXEL(mi, F->Col % MI_NPIXELS(mi))); if (Cur_Pt) { if (F->dbuf != None) { XSetForeground(display, F->dbuf_gc, 1); XDrawPoints(display, F->dbuf, F->dbuf_gc, F->Buffer2, Cur_Pt, CoordModeOrigin); } else XDrawPoints(display, window, gc, F->Buffer2, Cur_Pt, CoordModeOrigin); } if (F->dbuf != None) XCopyPlane(display, F->dbuf, window, gc, 0, 0, F->Width, F->Height, 0, 0, 1); */ F->Cur_Pt = Cur_Pt; Buf = F->Buffer1; F->Buffer1 = F->Buffer2; F->Buffer2 = Buf; } IFSPoint * draw_ifs(/*ModeInfo * mi*/ int *nbpt) { int i; DBL u, uu, v, vv, u0, u1, u2, u3; SIMI *S, *S1, *S2, *S3, *S4; FRACTAL *F; if (Root == NULL) return NULL; F = Root; //[/*MI_SCREEN(mi)*/0]; if (F->Buffer1 == NULL) return NULL; u = (DBL) (F->Count) * (DBL) (F->Speed) / 1000.0; uu = u * u; v = 1.0 - u; vv = v * v; u0 = vv * v; u1 = 3.0 * vv * u; u2 = 3.0 * v * uu; u3 = u * uu; S = F->Components; S1 = S + F->Nb_Simi; S2 = S1 + F->Nb_Simi; S3 = S2 + F->Nb_Simi; S4 = S3 + F->Nb_Simi; for (i = F->Nb_Simi; i; --i, S++, S1++, S2++, S3++, S4++) { S->c_x = u0 * S1->c_x + u1 * S2->c_x + u2 * S3->c_x + u3 * S4->c_x; S->c_y = u0 * S1->c_y + u1 * S2->c_y + u2 * S3->c_y + u3 * S4->c_y; S->r = u0 * S1->r + u1 * S2->r + u2 * S3->r + u3 * S4->r; S->r2 = u0 * S1->r2 + u1 * S2->r2 + u2 * S3->r2 + u3 * S4->r2; S->A = u0 * S1->A + u1 * S2->A + u2 * S3->A + u3 * S4->A; S->A2 = u0 * S1->A2 + u1 * S2->A2 + u2 * S3->A2 + u3 * S4->A2; } //MI_IS_DRAWN(mi) = True; Draw_Fractal(/*mi*/); if (F->Count >= 1000 / F->Speed) { S = F->Components; S1 = S + F->Nb_Simi; S2 = S1 + F->Nb_Simi; S3 = S2 + F->Nb_Simi; S4 = S3 + F->Nb_Simi; for (i = F->Nb_Simi; i; --i, S++, S1++, S2++, S3++, S4++) { S2->c_x = 2.0 * S4->c_x - S3->c_x; S2->c_y = 2.0 * S4->c_y - S3->c_y; S2->r = 2.0 * S4->r - S3->r; S2->r2 = 2.0 * S4->r2 - S3->r2; S2->A = 2.0 * S4->A - S3->A; S2->A2 = 2.0 * S4->A2 - S3->A2; *S1 = *S4; } Random_Simis(F, F->Components + 3 * F->Nb_Simi, F->Nb_Simi); Random_Simis(F, F->Components + 4 * F->Nb_Simi, F->Nb_Simi); F->Count = 0; } else F->Count++; F->Col++; /* #1 code added by JeKo */ (*nbpt) = Cur_Pt; return F->Buffer2; /* #1 end */ } /***************************************************************/ void release_ifs() { if (Root != NULL) { (void) free((void *) Root); Root = (FRACTAL *) NULL; } } //#endif /* MODE_ifs */ --- NEW FILE: ifs.h --- /* * File created 11 april 2002 by JeKo <je...@fr...> */ #ifndef IFS_H #define IFS_H #include "goom_config.h" typedef struct _ifsPoint { gint16 x,y; } IFSPoint; // init ifs for a (width)x(height) output. void init_ifs (int width, int height); // draw an ifs on the buffer (which size is width * height) // increment means that we draw 1/increment of the ifs's points void ifs_update (guint32 *buffer, guint32 *back, int width, int height, int increment); // free all ifs's data. void release_ifs (); /* DONT USE !!! deprecated * return a an array of points. * WARNING !!! do not free it !!! it also has an internal use.. */ IFSPoint * draw_ifs (int * nbPoints); #endif --- NEW FILE: ifs_display.c --- #include <stdlib.h> #include "ifs.h" #define DRAWMETHOD_NORMAL data[pos] = couleur #define DRAWMETHOD_PLUS(x) \ {\ int tra=0,i=0;\ unsigned char *bra = (unsigned char*)&back[pos];\ unsigned char *dra = (unsigned char*)&data[pos];\ unsigned char *cra = (unsigned char*)&couleur;\ for (;i<4;i++) {\ tra = *cra >> x;\ tra += *bra;\ if (tra>255) tra=255;\ *dra = tra;\ ++dra;++cra;++bra;\ }\ } #define DRAWMETHOD_OR data[pos]|=couleur #define DRAWMETHOD_DEMI data[pos]=((back[pos]&0xfefefefe) + (couleur & 0xfefefefe)) >> 1 #define DRAWMETHOD(x) {DRAWMETHOD_DEMI;DRAWMETHOD_PLUS(x);} void ifs_update (guint32 *data, guint32 *back, int width, int height, int increment) { static int couleur = 0xc0c0c0c0; static int v[4] = {2,4,3,2}; static int col[4] = {2,4,3,2}; #define MOD_MER 0 #define MOD_FEU 1 #define MOD_MERVER 2 static int mode = MOD_MERVER; static int justChanged = 0; static int cycle = 0; int cycle10; int nbpt; IFSPoint *points; int i; points = draw_ifs (&nbpt); cycle ++; if (cycle < 40) { cycle10 = cycle / 10; for (i = 0; i < nbpt; i+=increment) { int x = (int)points[i].x & 0x7fffffff; int y = (int)points[i].y & 0x7fffffff; if ((x < width) && (y < height)) { int pos = x + (int)(y * width); DRAWMETHOD(cycle10); } } } else { cycle10 = 7 - cycle / 10; for (i = 0; i < nbpt; i+=increment) { int x = (int)points[i].x & 0x7fffffff; int y = (int)points[i].y & 0x7fffffff; if ((x < width) && (y < height)) { int pos = x + (int)(y * width); DRAWMETHOD(cycle10); } } if (cycle >= 79) cycle = 0; } justChanged --; col[ALPHA] = couleur >> (ALPHA*8) & 0xff; col[BLEU] = couleur >> (BLEU*8) & 0xff; col[VERT] = couleur >> (VERT*8) & 0xff; col[ROUGE] = couleur >> (ROUGE*8) & 0xff; if (mode == MOD_MER) { col[BLEU] += v[BLEU]; if (col[BLEU]>255) { col[BLEU]=255; v[BLEU] = - (rand () % 4) - 1; } if (col[BLEU]<32) { col[BLEU]=32; v[BLEU] = (rand () % 4) + 1; } col[VERT] += v[VERT]; if (col[VERT]>200) { col[VERT]=200; v[VERT] = - (rand () % 3) - 2; } if (col[VERT]>col[BLEU]) { col[VERT]=col[BLEU]; v[VERT] = v[BLEU]; } if (col[VERT]<32) { col[VERT]=32; v[VERT] = (rand () % 3) + 2; } col[ROUGE] += v[ROUGE]; if (col[ROUGE]>64) { col[ROUGE]=64; v[ROUGE] = - (rand () % 4) - 1; } if (col[ROUGE]<0) { col[ROUGE]=0; v[ROUGE] = (rand () % 4) + 1; } col[ALPHA] += v[ALPHA]; if (col[ALPHA]>0) { col[ALPHA]=0; v[ALPHA] = - (rand () % 4) - 1; } if (col[ALPHA]<0) { col[ALPHA]=0; v[ALPHA] = (rand () % 4) + 1; } if (((col [VERT] > 32) && (col[ROUGE]<col[VERT] + 40) && (col[VERT]<col[ROUGE] + 20) && (col [BLEU] < 64) && (rand () % 20 == 0)) && (justChanged < 0)) { mode = rand()%3?MOD_FEU:MOD_MERVER; justChanged = 250; } } else if (mode == MOD_MERVER) { col[BLEU] += v[BLEU]; if (col[BLEU]>128) { col[BLEU]=128; v[BLEU] = - (rand () % 4) - 1; } if (col[BLEU]<16) { col[BLEU]=16; v[BLEU] = (rand () % 4) + 1; } col[VERT] += v[VERT]; if (col[VERT]>200) { col[VERT]=200; v[VERT] = - (rand () % 3) - 2; } if (col[VERT]>col[ALPHA]) { col[VERT]=col[ALPHA]; v[VERT] = v[ALPHA]; } if (col[VERT]<32) { col[VERT]=32; v[VERT] = (rand () % 3) + 2; } col[ROUGE] += v[ROUGE]; if (col[ROUGE]>128) { col[ROUGE]=128; v[ROUGE] = - (rand () % 4) - 1; } if (col[ROUGE]<0) { col[ROUGE]=0; v[ROUGE] = (rand () % 4) + 1; } col[ALPHA] += v[ALPHA]; if (col[ALPHA]>255) { col[ALPHA]=255; v[ALPHA] = - (rand () % 4) - 1; } if (col[ALPHA]<0) { col[ALPHA]=0; v[ALPHA] = (rand () % 4) + 1; } if (((col [VERT] > 32) && (col[ROUGE]<col[VERT] + 40) && (col[VERT]<col[ROUGE] + 20) && (col [BLEU] < 64) && (rand () % 20 == 0)) && (justChanged < 0)) { mode = rand()%3?MOD_FEU:MOD_MER; justChanged = 250; } } else if (mode == MOD_FEU) { col[BLEU] += v[BLEU]; if (col[BLEU]>64) { col[BLEU]=64; v[BLEU] = - (rand () % 4) - 1; } if (col[BLEU]<0) { col[BLEU]=0; v[BLEU] = (rand () % 4) + 1; } col[VERT] += v[VERT]; if (col[VERT]>200) { col[VERT]=200; v[VERT] = - (rand () % 3) - 2; } if (col[VERT]>col[ROUGE] + 20) { col[VERT]=col[ROUGE] + 20; v[VERT] = - (rand () % 3) - 2; v[ROUGE] = (rand () % 4) + 1; v[BLEU] = (rand () % 4) + 1; } if (col[VERT]<0) { col[VERT]=0; v[VERT] = (rand () % 3) + 2; } col[ROUGE] += v[ROUGE]; if (col[ROUGE]>255) { col[ROUGE]=255; v[ROUGE] = - (rand () % 4) - 1; } if (col[ROUGE]>col[VERT]+40) { col[ROUGE]=col[VERT]+40; v[ROUGE] = - (rand () % 4) - 1; } if (col[ROUGE]<0) { col[ROUGE]=0; v[ROUGE] = (rand () % 4) + 1; } col[ALPHA] += v[ALPHA]; if (col[ALPHA]>0) { col[ALPHA]=0; v[ALPHA] = - (rand () % 4) - 1; } if (col[ALPHA]<0) { col[ALPHA]=0; v[ALPHA] = (rand () % 4) + 1; } if (((col [ROUGE] < 64) && (col [VERT] > 32) && (col [VERT] < col [BLEU]) && (col [BLEU] > 32) && (rand () % 20 == 0)) && (justChanged < 0)) { mode = rand () % 2 ? MOD_MER : MOD_MERVER; justChanged = 250; } } couleur = (col[ALPHA]<<(ALPHA*8)) |(col[BLEU]<<(BLEU*8)) |(col[VERT]<<(VERT*8)) |(col[ROUGE]<<(ROUGE*8)); } --- NEW FILE: lines.c --- /* * lines.c * iTunesXPlugIn * * Created by guillaum on Tue Aug 14 2001. * Copyright (c) 2001 __CompanyName__. All rights reserved. * */ #include "lines.h" #include <math.h> #include <stdlib.h> #include <stdio.h> #include "goom_tools.h" extern unsigned int resolx,c_resoly; #define DRAWMETHOD_NORMAL *p = col #define DRAWMETHOD_PLUS \ {\ int dra=0,i=0;\ unsigned char *tra = (unsigned char*)p;\ unsigned char *cra = (unsigned char*)&col;\ for (;i<4;i++) {\ dra = *cra;\ dra += *tra;\ if (dra>255) dra=255;\ *tra = dra;\ ++tra;++cra;\ }\ } #define DRAWMETHOD_DEMIPLUS \ {\ int dra=0,i=0;\ unsigned char *tra = (unsigned char*)p;\ unsigned char *cra = (unsigned char*)&col;\ for (;i<4;i++) {\ dra = *cra >> 1;\ dra += *tra;\ if (dra>255) dra=255;\ *tra = dra;\ ++tra;++cra;\ }\ } #define DRAWMETHOD_OR *p|=col #define DRAWMETHOD {DRAWMETHOD_DEMIPLUS; DRAWMETHOD_OR;} static void draw_line (int *data, int x1,int y1,int x2,int y2, int col, int screenx, int screeny) { int x, y, dx, dy, yy, xx; int *p; // DATA32 *p; // DATA8 aaa, nr, ng, nb, rr, gg, bb, aa, na; /* clip to top edge */ if ((y1 < 0) && (y2 < 0)) return; if (y1 < 0) { x1 += (y1 * (x1 - x2)) / (y2 - y1); y1 = 0; } if (y2 < 0) { x2 += (y2 * (x1 - x2)) / (y2 - y1); y2 = 0; } /* clip to bottom edge */ if ((y1 >= screen... [truncated message content] |