summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/post/goom/Makefile.am39
-rw-r--r--src/post/goom/filters.c681
-rw-r--r--src/post/goom/filters.h80
-rw-r--r--src/post/goom/goom_config.h38
-rw-r--r--src/post/goom/goom_core.c717
-rw-r--r--src/post/goom/goom_core.h38
-rw-r--r--src/post/goom/goom_tools.h29
-rw-r--r--src/post/goom/graphic.c17
-rw-r--r--src/post/goom/graphic.h24
-rw-r--r--src/post/goom/ifs.c529
-rw-r--r--src/post/goom/ifs.h32
-rw-r--r--src/post/goom/ifs_display.c216
-rw-r--r--src/post/goom/lines.c465
-rw-r--r--src/post/goom/lines.h75
-rw-r--r--src/post/goom/xine_goom.c314
15 files changed, 3294 insertions, 0 deletions
diff --git a/src/post/goom/Makefile.am b/src/post/goom/Makefile.am
new file mode 100644
index 000000000..99a11335c
--- /dev/null
+++ b/src/post/goom/Makefile.am
@@ -0,0 +1,39 @@
+##
+## 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
+
diff --git a/src/post/goom/filters.c b/src/post/goom/filters.c
new file mode 100644
index 000000000..701619705
--- /dev/null
+++ b/src/post/goom/filters.c
@@ -0,0 +1,681 @@
+/* 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);
+ }
+}
diff --git a/src/post/goom/filters.h b/src/post/goom/filters.h
new file mode 100644
index 000000000..29727f11b
--- /dev/null
+++ b/src/post/goom/filters.h
@@ -0,0 +1,80 @@
+#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
diff --git a/src/post/goom/goom_config.h b/src/post/goom/goom_config.h
new file mode 100644
index 000000000..0cc304781
--- /dev/null
+++ b/src/post/goom/goom_config.h
@@ -0,0 +1,38 @@
+
+//#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
diff --git a/src/post/goom/goom_core.c b/src/post/goom/goom_core.c
new file mode 100644
index 000000000..9113f0a0f
--- /dev/null
+++ b/src/post/goom/goom_core.c
@@ -0,0 +1,717 @@
+#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 (&param1, &param2, &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 (&param1, &param2, &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);
+}
diff --git a/src/post/goom/goom_core.h b/src/post/goom/goom_core.h
new file mode 100644
index 000000000..c74adb5c0
--- /dev/null
+++ b/src/post/goom/goom_core.h
@@ -0,0 +1,38 @@
+#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
diff --git a/src/post/goom/goom_tools.h b/src/post/goom/goom_tools.h
new file mode 100644
index 000000000..d077c0cba
--- /dev/null
+++ b/src/post/goom/goom_tools.h
@@ -0,0 +1,29 @@
+#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
diff --git a/src/post/goom/graphic.c b/src/post/goom/graphic.c
new file mode 100644
index 000000000..4223c67bd
--- /dev/null
+++ b/src/post/goom/graphic.c
@@ -0,0 +1,17 @@
+#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 ;
diff --git a/src/post/goom/graphic.h b/src/post/goom/graphic.h
new file mode 100644
index 000000000..415dde73c
--- /dev/null
+++ b/src/post/goom/graphic.h
@@ -0,0 +1,24 @@
+#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*/
diff --git a/src/post/goom/ifs.c b/src/post/goom/ifs.c
new file mode 100644
index 000000000..a6941c517
--- /dev/null
+++ b/src/post/goom/ifs.c
@@ -0,0 +1,529 @@
+/* -*- 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 <Pascal.Massimon@ens.fr>
+ *
+ * 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: jwz@jwz.org: 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 */
diff --git a/src/post/goom/ifs.h b/src/post/goom/ifs.h
new file mode 100644
index 000000000..a5e9fdeec
--- /dev/null
+++ b/src/post/goom/ifs.h
@@ -0,0 +1,32 @@
+/*
+ * File created 11 april 2002 by JeKo <jeko@free.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
diff --git a/src/post/goom/ifs_display.c b/src/post/goom/ifs_display.c
new file mode 100644
index 000000000..94d79b7eb
--- /dev/null
+++ b/src/post/goom/ifs_display.c
@@ -0,0 +1,216 @@
+#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));
+}
diff --git a/src/post/goom/lines.c b/src/post/goom/lines.c
new file mode 100644
index 000000000..72ce65342
--- /dev/null
+++ b/src/post/goom/lines.c
@@ -0,0 +1,465 @@
+/*
+ * 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 >= screeny) && (y2 >= screeny))
+ return;
+ if (y1 >= screeny)
+ {
+ x1 -= ((screeny - y1) * (x1 - x2)) / (y2 - y1);
+ y1 = screeny - 1;
+ }
+ if (y2 >= screeny)
+ {
+ x2 -= ((screeny - y2) * (x1 - x2)) / (y2 - y1);
+ y2 = screeny - 1;
+ }
+ /* clip to left edge */
+ if ((x1 < 0) && (x2 < 0))
+ return;
+ if (x1 < 0)
+ {
+ y1 += (x1 * (y1 - y2)) / (x2 - x1);
+ x1 = 0;
+ }
+ if (x2 < 0)
+ {
+ y2 += (x2 * (y1 - y2)) / (x2 - x1);
+ x2 = 0;
+ }
+ /* clip to right edge */
+ if ((x1 >= screenx) && (x2 >= screenx))
+ return;
+ if (x1 >= screenx)
+ {
+ y1 -= ((screenx - x1) * (y1 - y2)) / (x2 - x1);
+ x1 = screenx - 1;
+ }
+ if (x2 >= screenx)
+ {
+ y2 -= ((screenx - x2) * (y1 - y2)) / (x2 - x1);
+ x2 = screenx - 1;
+ }
+ dx = x2 - x1;
+ dy = y2 - y1;
+ if (x1 > x2)
+ {
+ int tmp;
+
+ tmp = x1;
+ x1 = x2;
+ x2 = tmp;
+ tmp = y1;
+ y1 = y2;
+ y2 = tmp;
+ dx = x2 - x1;
+ dy = y2 - y1;
+ }
+
+ /* vertical line */
+ if (dx == 0)
+ {
+ if (y1 < y2)
+ {
+ p = &(data[(screenx * y1) + x1]);
+ for (y = y1; y <= y2; y++)
+ {
+ DRAWMETHOD;
+ p += screenx;
+ }
+ }
+ else
+ {
+ p = &(data[(screenx * y2) + x1]);
+ for (y = y2; y <= y1; y++)
+ {
+ DRAWMETHOD;
+ p += screenx;
+ }
+ }
+ return;
+ }
+ /* horizontal line */
+ if (dy == 0)
+ {
+ if (x1 < x2)
+ {
+ p = &(data[(screenx * y1) + x1]);
+ for (x = x1; x <= x2; x++)
+ {
+ DRAWMETHOD;
+ p++;
+ }
+ return;
+ }
+ else
+ {
+ p = &(data[(screenx * y1) + x2]);
+ for (x = x2; x <= x1; x++)
+ {
+ DRAWMETHOD;
+ p++;
+ }
+ return;
+ }
+ }
+ /* 1 */
+ /* \ */
+ /* \ */
+ /* 2 */
+ if (y2 > y1)
+ {
+ /* steep */
+ if (dy > dx)
+ {
+ dx = ((dx << 16) / dy);
+ x = x1 << 16;
+ for (y = y1; y <= y2; y++)
+ {
+ xx = x >> 16;
+ p = &(data[(screenx * y) + xx]);
+ DRAWMETHOD;
+ if (xx < (screenx - 1))
+ {
+ p++;
+// DRAWMETHOD;
+ }
+ x += dx;
+ }
+ return;
+ }
+ /* shallow */
+ else
+ {
+ dy = ((dy << 16) / dx);
+ y = y1 << 16;
+ for (x = x1; x <= x2; x++)
+ {
+ yy = y >> 16;
+ p = &(data[(screenx * yy) + x]);
+ DRAWMETHOD;
+ if (yy < (screeny - 1))
+ {
+ p += screeny;
+// DRAWMETHOD;
+ }
+ y += dy;
+ }
+ }
+ }
+ /* 2 */
+ /* / */
+ /* / */
+ /* 1 */
+ else
+ {
+ /* steep */
+ if (-dy > dx)
+ {
+ dx = ((dx << 16) / -dy);
+ x = (x1 + 1) << 16;
+ for (y = y1; y >= y2; y--)
+ {
+ xx = x >> 16;
+ p = &(data[(screenx * y) + xx]);
+ DRAWMETHOD;
+ if (xx < (screenx - 1))
+ {
+ p--;
+// DRAWMETHOD;
+ }
+ x += dx;
+ }
+ return;
+ }
+ /* shallow */
+ else
+ {
+ dy = ((dy << 16) / dx);
+ y = y1 << 16;
+ for (x = x1; x <= x2; x++)
+ {
+ yy = y >> 16;
+ p = &(data[(screenx * yy) + x]);
+ DRAWMETHOD;
+ if (yy < (screeny - 1))
+ {
+ p += screeny;
+// DRAWMETHOD;
+ }
+ y += dy;
+ }
+ return;
+ }
+ }
+}
+
+void genline (int id, float param, GMUnitPointer *l, int rx, int ry) {
+ int i;
+ switch (id) {
+ case GML_HLINE:
+ for (i = 0; i < 512; i++) {
+ l [i].x = ((float)i * rx) / 512.0f;
+ l [i].y = param;
+ l [i].angle = M_PI / 2.0f;
+ }
+ return;
+ case GML_VLINE:
+ for (i = 0; i < 512; i++) {
+ l [i].y = ((float)i * ry) / 512.0f;
+ l [i].x = param;
+ l [i].angle = 0.0f;
+ }
+ return;
+ case GML_CIRCLE:
+ for (i = 0; i < 512; i++) {
+ float cosa,sina;
+ l [i].angle = 2.0f*M_PI*(float)i / 512.0f;
+ cosa = param * cos(l[i].angle);
+ sina = param * sin(l[i].angle);
+ l [i].x = ((float)rx / 2.0f) + cosa;
+ l [i].y = (float)ry / 2.0f + sina;
+ }
+ return;
+ }
+}
+
+guint32 getcouleur (int mode) {
+ switch (mode) {
+ case GML_RED:
+ return (230 << (ROUGE * 8)) | (120 << (VERT * 8));
+ case GML_ORANGE_J:
+ return (120 << (VERT * 8)) | (252 << (ROUGE * 8));
+ case GML_ORANGE_V:
+ return (160 << (VERT * 8)) | (236 << (ROUGE * 8)) | (40 << (BLEU * 8));
+ case GML_BLEUBLANC:
+ return (40 << (BLEU * 8)) | (220 << (ROUGE * 8)) | (140 << (VERT * 8));
+ case GML_VERT:
+ return (200 << (VERT*8)) | (80 << (ROUGE*8));
+ case GML_BLEU:
+ return (250 << (BLEU*8)) | (30 << (VERT*8)) | (80 << (ROUGE*8));
+ case GML_BLACK:
+ return 0x10 << (BLEU*8);
+ }
+ return 0;
+}
+
+void goom_lines_set_res (GMLine *gml, int rx, int ry) {
+ if (gml != NULL) {
+
+ gml->screenX = rx;
+ gml->screenY = ry;
+
+ genline (gml->IDdest, gml->param, gml->points2, rx,ry);
+ }
+}
+
+
+void goom_lines_move (GMLine *l) {
+ int i;
+ unsigned char *c1,*c2;
+
+ for (i = 0; i < 512; i++) {
+ l->points [i].x = (l->points2 [i].x + 39.0f * l->points [i].x) / 40.0f;
+ l->points [i].y = (l->points2 [i].y + 39.0f * l->points [i].y) / 40.0f;
+ l->points [i].angle = (l->points2 [i].angle + 39.0f * l->points [i].angle) / 40.0f;
+ }
+
+ c1 = (unsigned char*)&l->color;
+ c2 = (unsigned char*)&l->color2;
+ for (i=0;i<4;i++) {
+ int cc1,cc2;
+ cc1 = *c1;
+ cc2 = *c2;
+ *c1 = (unsigned char) ((cc1 * 63 + cc2) >> 6 );
+ ++c1;++c2;
+ }
+
+ l->power += l->powinc;
+ if (l->power < -1.6f) {
+ l->power = -1.6f;
+ l->powinc = (float)(iRAND(20) + 10) / 600.0f;
+ }
+ if (l->power > 1.0f) {
+ l->power = 1.0f;
+ l->powinc = - (float)(iRAND(20) + 10) / 600.0f;
+ }
+}
+
+void goom_lines_switch_to (GMLine *gml, int IDdest, float param, int col) {
+ genline (IDdest, param, gml->points2, gml->screenX,gml->screenY);
+ gml->IDdest = IDdest;
+ gml->param = param;
+ gml->color2 = getcouleur (col);
+// printf ("couleur %d : %x\n",col,gml->color2);
+}
+
+inline unsigned char lighten(unsigned char value,float power)
+{
+ int val = value;
+ float t = exp ((float)val / 64.0f) + power;
+ if (t > 0) {
+ val = (int)(64.0f * log (t));
+ if (val > 255)
+ val = 255;
+ if (val < 0)
+ val=0;
+ return val;
+ }
+ else {
+ return 0;
+ }
+}
+
+void lightencolor (int *col, float power) {
+ unsigned char *color;
+ color = (unsigned char *)col;
+ * color = lighten(*color,power);
+ color++;
+ * color = lighten(*color,power);
+ color++;
+ * color = lighten(*color,power);
+ color++;
+ * color = lighten(*color,power);
+}
+
+GMLine* goom_lines_init (int rx,int ry,
+ int IDsrc, float paramS,int coulS,
+ int IDdest, float paramD, int coulD)
+{
+
+ GMLine *l = (GMLine*)malloc(sizeof(GMLine));
+
+ l->points = (GMUnitPointer*)malloc(512*sizeof(GMUnitPointer));
+ l->points2 = (GMUnitPointer*)malloc(512*sizeof(GMUnitPointer));
+ l->nbPoints = 512;
+
+ l->IDdest = IDdest;
+ l->param = paramD;
+
+ genline (IDsrc, paramS, l->points, rx,ry);
+ genline (IDdest, paramD, l->points2, rx,ry);
+
+ l->color = getcouleur (coulS);
+ l->color2 = getcouleur (coulD);
+
+ l->screenX = rx;
+ l->screenY = ry;
+
+ l->power = 0.0f;
+ l->powinc = 0.01f;
+
+ goom_lines_switch_to (l, IDdest, paramD, coulD);
+
+ return l;
+}
+
+void goom_lines_free (GMLine **l) {
+ free ((*l)->points);
+ free (*l);
+ l = NULL;
+}
+
+void goom_lines_draw(GMLine *line,
+ gint16 data [512],
+ unsigned int* p)
+
+{
+ if (line != NULL) {
+ int i,x1,y1;
+ guint32 color = line->color;
+ GMUnitPointer *pt = &(line->points[0]);
+
+ float cosa = cos(pt->angle) / 1000.0f;
+ float sina = sin(pt->angle) / 1000.0f;
+
+ lightencolor (&color, line->power);
+
+ x1 = (int) (pt->x + cosa * data[0]);
+ y1 = (int) (pt->y + sina * data[0]);
+
+ for (i=1;i<512;i++) {
+ int x2,y2;
+ GMUnitPointer *pt = &(line->points[i]);
+
+ float cosa = cos(pt->angle) / 1000.0f;
+ float sina = sin(pt->angle) / 1000.0f;
+
+ x2 = (int) (pt->x + cosa * data[i]);
+ y2 = (int) (pt->y + sina * data[i]);
+
+ draw_line (p, x1,y1,x2,y2,color,line->screenX,line->screenY);
+ x1=x2;
+ y1=y2;
+ }
+ goom_lines_move (line);
+ }
+}
+
diff --git a/src/post/goom/lines.h b/src/post/goom/lines.h
new file mode 100644
index 000000000..c0c12d73a
--- /dev/null
+++ b/src/post/goom/lines.h
@@ -0,0 +1,75 @@
+/*
+ * lines.h
+ * iGoom
+ *
+ * Created by guillaum on Tue Aug 14 2001.
+ * Copyright (c) 2001 ios. All rights reserved.
+ */
+
+#include "graphic.h"
+#include "goom_config.h"
+
+typedef struct _GMUNITPOINTER {
+ float x;
+ float y;
+ float angle;
+} GMUnitPointer;
+
+// tableau de points
+typedef struct _GMLINE {
+
+ GMUnitPointer *points;
+ GMUnitPointer *points2;
+ int IDdest;
+ float param;
+
+ int nbPoints;
+ guint32 color; /* pr l'instant je stocke la ouuleur
+ * a terme, on stockera le mode couleur.. et l'on animera
+ */
+ guint32 color2;
+
+ int screenX;
+ int screenY;
+
+ float power;
+ float powinc;
+} GMLine;
+
+// les ID possibles
+
+#define GML_CIRCLE 0
+// (param = radius)
+
+#define GML_HLINE 1
+// (param = y)
+
+#define GML_VLINE 2
+// (param = x)
+
+// les modes couleur possible (si tu mets un autre c'est noir)
+
+#define GML_BLEUBLANC 0
+#define GML_RED 1
+#define GML_ORANGE_V 2
+#define GML_ORANGE_J 3
+#define GML_VERT 4
+#define GML_BLEU 5
+#define GML_BLACK 6
+
+/* construit un effet de line (une ligne horitontale pour commencer) */
+GMLine *goom_lines_init (int rx, int ry,
+ int IDsrc, float paramS, int modeCoulSrc,
+ int IDdest, float paramD, int modeCoulDest);
+
+void goom_lines_switch_to (GMLine *gml, int IDdest, float param, int modeCoul);
+
+void goom_lines_set_res (GMLine *gml, int rx, int ry);
+
+void goom_lines_free (GMLine **gml);
+
+void goom_lines_draw (GMLine *gml,
+ gint16 data [512],
+ unsigned int* p);
+//void goom_lines_conf(gint16 config [25]);
+
diff --git a/src/post/goom/xine_goom.c b/src/post/goom/xine_goom.c
new file mode 100644
index 000000000..da3e35761
--- /dev/null
+++ b/src/post/goom/xine_goom.c
@@ -0,0 +1,314 @@
+/*
+ * Copyright (C) 2000-2002 the xine project
+ *
+ * This file is part of xine, a free video player.
+ *
+ * xine is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * xine is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * $Id: xine_goom.c,v 1.1 2002/12/25 04:59:14 miguelfreitas Exp $
+ *
+ * GOOM post plugin.
+ *
+ * first version by Mark Thomas
+ * ported to post plugin architecture by Miguel Freitas
+ * real work by goom author, JC Hoelt <jeko@free.fr>.
+ */
+
+#include <stdio.h>
+
+#include "xine_internal.h"
+#include "post.h"
+
+#include "goom_core.h"
+
+#define FPS 10
+#define DURATION 90000/FPS
+
+#define GOOM_WIDTH 320
+#define GOOM_HEIGHT 200
+
+typedef struct post_plugin_goom_s post_plugin_goom_t;
+
+struct post_plugin_goom_s {
+ post_plugin_t post;
+
+ /* private data */
+ xine_video_port_t *vo_port;
+
+ gint16 data [2][512];
+
+ int bits;
+ int channels;
+ int sample_rate;
+ int sample_counter;
+ int samples_per_frame;
+};
+
+/* plugin class initialization function */
+static void *goom_init_plugin(xine_t *xine, void *);
+
+
+/* plugin catalog information */
+plugin_info_t xine_plugin_info[] = {
+ /* type, API, "name", version, special_info, init_function */
+ { PLUGIN_POST, 1, "goom", XINE_VERSION_CODE, NULL, &goom_init_plugin },
+ { PLUGIN_NONE, 0, "", 0, NULL, NULL }
+};
+
+
+/* plugin class functions */
+static post_plugin_t *goom_open_plugin(post_class_t *class_gen, int inputs,
+ xine_audio_port_t **audio_target,
+ xine_video_port_t **video_target);
+static char *goom_get_identifier(post_class_t *class_gen);
+static char *goom_get_description(post_class_t *class_gen);
+static void goom_class_dispose(post_class_t *class_gen);
+
+/* plugin instance functions */
+static void goom_dispose(post_plugin_t *this_gen);
+
+/* rewire function */
+static int goom_rewire(xine_post_out_t *output, void *data);
+
+static int goom_port_open(xine_audio_port_t *this, xine_stream_t *stream,
+ uint32_t bits, uint32_t rate, int mode);
+
+static void goom_port_close(xine_audio_port_t *this, xine_stream_t *stream );
+
+static void goom_port_put_buffer (xine_audio_port_t *this, audio_buffer_t *buf, xine_stream_t *stream);
+
+static void *goom_init_plugin(xine_t *xine, void *data)
+{
+ post_class_t *class = (post_class_t *)malloc(sizeof(post_class_t));
+
+ if (!class)
+ return NULL;
+
+ class->open_plugin = goom_open_plugin;
+ class->get_identifier = goom_get_identifier;
+ class->get_description = goom_get_description;
+ class->dispose = goom_class_dispose;
+
+ return class;
+}
+
+
+static post_plugin_t *goom_open_plugin(post_class_t *class_gen, int inputs,
+ xine_audio_port_t **audio_target,
+ xine_video_port_t **video_target)
+{
+ post_plugin_goom_t *this = (post_plugin_goom_t *)malloc(sizeof(post_plugin_goom_t));
+ xine_post_in_t *input = (xine_post_in_t *)malloc(sizeof(xine_post_in_t));
+ xine_post_out_t *output = (xine_post_out_t *)malloc(sizeof(xine_post_out_t));
+ xine_post_out_t *outputv = (xine_post_out_t *)malloc(sizeof(xine_post_out_t));
+ post_audio_port_t *port;
+
+ if (!this || !input || !output || !outputv || !video_target || !video_target[0] ||
+ !audio_target || !audio_target[0] ) {
+ free(this);
+ free(input);
+ free(output);
+ free(outputv);
+ return NULL;
+ }
+
+ goom_init (GOOM_WIDTH, GOOM_HEIGHT, 0);
+ this->sample_counter = 0;
+ this->vo_port = video_target[0];
+
+ port = post_intercept_audio_port(audio_target[0]);
+ port->post = &this->post.xine_post;
+ port->port.open = goom_port_open;
+ port->port.close = goom_port_close;
+ port->port.put_buffer = goom_port_put_buffer;
+
+ input->name = "audio in";
+ input->type = XINE_POST_DATA_AUDIO;
+ input->data = (xine_audio_port_t *)&port->port;
+
+ output->name = "audio out";
+ output->type = XINE_POST_DATA_AUDIO;
+ output->data = (xine_audio_port_t **)&port->original_port;
+ output->rewire = goom_rewire;
+
+ outputv->name = "generated video";
+ outputv->type = XINE_POST_DATA_VIDEO;
+ outputv->data = (xine_video_port_t **)&this->vo_port;
+ outputv->rewire = NULL;
+
+ this->post.xine_post.audio_input = (xine_audio_port_t **)malloc(sizeof(xine_audio_port_t *) * 2);
+ this->post.xine_post.audio_input[0] = &port->port;
+ this->post.xine_post.audio_input[1] = NULL;
+ this->post.xine_post.video_input = (xine_video_port_t **)malloc(sizeof(xine_video_port_t *) * 1);
+ this->post.xine_post.video_input[0] = NULL;
+
+ this->post.input = xine_list_new();
+ this->post.output = xine_list_new();
+
+ xine_list_append_content(this->post.input, input);
+ xine_list_append_content(this->post.output, output);
+ xine_list_append_content(this->post.output, outputv);
+
+ this->post.dispose = goom_dispose;
+
+ return &this->post;
+}
+
+static char *goom_get_identifier(post_class_t *class_gen)
+{
+ return "goom";
+}
+
+static char *goom_get_description(post_class_t *class_gen)
+{
+ return "What a GOOM";
+}
+
+static void goom_class_dispose(post_class_t *class_gen)
+{
+ free(class_gen);
+}
+
+
+static void goom_dispose(post_plugin_t *this)
+{
+ goom_close();
+
+ free(this->xine_post.audio_input);
+ free(this->xine_post.video_input);
+ free(xine_list_first_content(this->input));
+ free(xine_list_first_content(this->output));
+ xine_list_free(this->input);
+ xine_list_free(this->output);
+ free(this);
+}
+
+
+static int goom_rewire(xine_post_out_t *output, void *data)
+{
+ if (!data)
+ return 0;
+ *(xine_audio_port_t **)output->data = (xine_audio_port_t *)data;
+ return 1;
+}
+
+static int mode_channels( int mode ) {
+ switch( mode ) {
+ case AO_CAP_MODE_MONO:
+ return 1;
+ case AO_CAP_MODE_STEREO:
+ return 2;
+ case AO_CAP_MODE_4CHANNEL:
+ return 4;
+ case AO_CAP_MODE_5CHANNEL:
+ return 5;
+ case AO_CAP_MODE_5_1CHANNEL:
+ return 6;
+ }
+ return 0;
+}
+
+static int goom_port_open(xine_audio_port_t *port_gen, xine_stream_t *stream,
+ uint32_t bits, uint32_t rate, int mode) {
+
+ post_audio_port_t *port = (post_audio_port_t *)port_gen;
+ post_plugin_goom_t *this = (post_plugin_goom_t *)port->post;
+
+ this->vo_port->open( this->vo_port, stream );
+
+ this->bits = bits;
+ this->channels = mode_channels(mode);
+ this->samples_per_frame = rate / FPS;
+ this->sample_rate = rate;
+ return port->original_port->open(port->original_port, stream, bits, rate, mode );
+}
+
+static void goom_port_close(xine_audio_port_t *port_gen, xine_stream_t *stream ) {
+
+ post_audio_port_t *port = (post_audio_port_t *)port_gen;
+ post_plugin_goom_t *this = (post_plugin_goom_t *)port->post;
+
+ this->vo_port->close( this->vo_port, stream );
+
+ port->original_port->close(port->original_port, stream );
+}
+
+static void goom_port_put_buffer (xine_audio_port_t *port_gen,
+ audio_buffer_t *buf, xine_stream_t *stream) {
+
+ post_audio_port_t *port = (post_audio_port_t *)port_gen;
+ post_plugin_goom_t *this = (post_plugin_goom_t *)port->post;
+ vo_frame_t *frame;
+ uint32_t *goom_frame;
+ int16_t *data;
+ int8_t *data8;
+ int i, j;
+
+ this->sample_counter += buf->num_frames;
+
+ if( this->sample_counter >= this->samples_per_frame &&
+ buf->num_frames >= 512 ) {
+
+ data = buf->mem;
+ data8 = (int8_t *)buf->mem;
+ j = (this->channels >= 2) ? 1 : 0;
+
+ if( this->bits == 8 ) {
+ for( i = 0; i < 512; i++, data8 += this->channels ) {
+ this->data[0][i] = (int16_t)data8[0] << 8;
+ this->data[1][i] = (int16_t)data8[j] << 8;
+ }
+ } else {
+ for( i = 0; i < 512; i++, data += this->channels ) {
+ this->data[0][i] = data[0];
+ this->data[1][i] = data[j];
+ }
+ }
+
+ goom_frame = goom_update (this->data, 0);
+
+ frame = this->vo_port->get_frame (this->vo_port, GOOM_WIDTH, GOOM_HEIGHT,
+ XINE_VO_ASPECT_SQUARE, XINE_IMGFMT_YUY2,
+ VO_BOTH_FIELDS);
+ frame->pts = buf->vpts;
+ frame->duration = 90000 * this->sample_counter / this->sample_rate;
+
+ /* FIXME: use accelerated color conversion */
+ for (i=0, j=0; i<GOOM_WIDTH * GOOM_HEIGHT; i+=2, j+=4) {
+ double r1 = (goom_frame[i] & 0xFF0000) >> 16;
+ double g1 = (goom_frame[i] & 0xFF00) >> 8;
+ double b1 = (goom_frame[i] & 0xFF);
+ double r2 = (goom_frame[i+1] & 0xFF0000) >> 16;
+ double g2 = (goom_frame[i+1] & 0xFF00) >> 8;
+ double b2 = (goom_frame[i+1] & 0xFF);
+ uint8_t y1 = (0.257 * r1) + (0.504 * g1) + (0.098 * b1) + 16;
+ uint8_t y2 = (0.257 * r2) + (0.504 * g2) + (0.098 * b2) + 16;
+ uint8_t u = -(0.074 * (r1 + r2)) - (0.1455 * (g1 + g2)) + (0.2195 * (b1 + b2)) + 128;
+ uint8_t v = (0.2195 * (r1 + r2)) - (0.184 * (g1 + g2)) - (0.0355 * (b1 + b2)) + 128;
+
+ frame -> base[0][j] = y1;
+ frame -> base[0][j+1] = u;
+ frame -> base[0][j+2] = y2;
+ frame -> base[0][j+3] = v;
+
+ }
+
+ frame->draw(frame, stream);
+ frame->free(frame);
+
+ this->sample_counter = 0;
+ }
+ port->original_port->put_buffer(port->original_port, buf, stream );
+}